User:PerfektesChaos/js/jsonDebug/d.js

/// User:PerfektesChaos/js/jsonDebug/d.js // Show JSON errors analysis live /// 2018-08-24 PerfektesChaos@de.wikipedia // ResourceLoader:  compatible; //   dependencies: user, mw.API /// Fingerprint: #0#0# /// @license GPL [//www.mediawiki.org/w/COPYING] (+GFDL, LGPL, CC-BY-SA) /// /* global window: false                                               */ /* jshint forin: false, bitwise:true, curly:true, eqeqeq:true, latedef:true, laxbreak:true, nocomma:true, strict:true, undef:true, unused:true          */

( function ( mw, $ ) {  "use strict";   var Version   = -1.2,       Signature = "jsonDebug",       JSOND = { site:    "w:en",                 store:   "User:PerfektesChaos/js/" + Signature,                 sel:     "json-code-lint",                 src:     "div,pre",                 using:   null }, /*       PREGO = { app:       false,                 signature: "preferencesGadgetOptions",                 site:      "w:en",                 store:     "User:PerfektesChaos/js/" },       REPOS = { requests: false },       UI    = { bad:      { "background-color": "#F0F080",                             "border":           "#FF0000 1px solid",                             "color":            "#FF0000",                             "font-family":      "monospace",                             "font-size":        "80%",                             "font-weight":      "normal",                             "padding":          "0.3em" }, code:    { "margin-top":       "1em", "max-width":       "95%", "width":           "95%" }, css:     { "background-color": "#D0D0D0", "border":          "#808080 1px solid", "clear":           "both", "margin-bottom":   "1rem", "max-width":       "95%", "padding":         "1em" }, normal:  10, $button: false }, VALID = { jsonlint: false, reLineNum: "line ([0-9]+)" }, ZEBRA = { codemirror: false };

/*  function features( apply ) { // Config hook has been fired // Precondition: //   apply  -- hook payload // Uses: // 2018-03-01 PerfektesChaos@de.wikipedia if ( typeof apply ===  "object"           &&     apply ) { }  }   // features

JSOND.feed = function ( ask ) { // External access interface // Precondition: //   ask  -- string with JSON source code // Uses: //   >  JSOND.using //    < JSOND.source //   mw.loader.using //   JSOND.feeder //   (JSOND.feeder) // 2018-03-01 PerfektesChaos@de.wikipedia var s;     if ( typeof ask  ===  "string" ) { s = ask.trim; if ( s ) { JSOND.source = s;           if ( JSOND.using ) { mw.loader.using( JSOND.using, JSOND.feeder ); } else { JSOND.feeder; }        }      }   };   // JSOND.feed

JSOND.feeder = function { // External access, ensure DOM // Precondition: //   Standard modules have been loaded // Uses: //   (JSOND.feeding) // 2018-03-01 PerfektesChaos@de.wikipedia $( JSOND.feeding ); };  // JSOND.feeder

JSOND.feeding = function { // Perform external access // Precondition: //   DOM ready //   Standard modules have been loaded // Uses: //   >  JSOND.source //   JSOND.flip(JSOND.flip) // 2018-03-01 PerfektesChaos@de.wikipedia VALID.fire( JSOND.source ); JSOND.flip; };  // JSOND.feeding

JSOND.fire = function { // Start execution // Precondition: //   all  -- true, if entire content is JSON //   Standard modules have been loaded // Uses: //   >  Signature //    < JSOND.support //   mw.hook //   PREGO.feed //   (JSOND.fresh) // 2018-03-18 PerfektesChaos@de.wikipedia /*     PREGO.feed; mw.hook( Signature + ".config" ).add( JSOND.features ); JSOND.support = Signature + "-button"; mw.hook( "wikipage.content" ).add( JSOND.fresh ); };  // JSOND.fire

JSOND.fired = function ( event ) { // Button has been pressed // Precondition: //   event  -- jQuery event object // Uses: //   >  JSOND.large //   >  UI.live //   >  UI.$source //   >  JSOND.sel //   >  JSOND.src //    < JSOND.source //   JSOND.flip //   VALID.fire // 2018-03-18 PerfektesChaos@de.wikipedia var $button, $json; event.stopPropagation; JSOND.flip; JSOND.source = false; if ( JSOND.large ) { if ( UI.live ) { JSOND.source = UI.$source.val; } else { JSOND.source = UI.$source.text; }     } else { $button = $( event.target ); $json  = $button.next; $button.attr( { disabled: true } ); if ( $json.hasClass( JSOND.sel )  &&              $json.filter( JSOND.src ) ) { JSOND.source = $json.text; }     }      if ( JSOND.source ) { JSOND.source = JSOND.source.trim; VALID.fire( JSOND.source ); }  };   // JSOND.fired

JSOND.first = function { // Autorun on loading // Uses: //   >  Signature //   >  JSOND.using //   >  JSOND.site //   >  JSOND.store //   >  Version //    < JSOND.signature //    < JSOND.large //   mw.loader.getState //   mw.loader.state //   mw.config.get //   mw.loader.using //   JSOND.fire //   mw.hook //   (JSOND.fire) //   (JSOND.feed) // 2018-08-24 PerfektesChaos@de.wikipedia var env, pub, rls; JSOND.signature = "ext.gadget." + Signature; if ( mw.loader.getState( JSOND.signature ) !==  "ready" ) { env = mw.config.get( [ "wgAction",                               "wgPageContentModel" ] ); rls = { }; rls[ JSOND.signature ] = "ready"; mw.loader.state( rls ); JSOND.large = ( env.wgPageContentModel.toLowerCase.indexOf( "json" )                  >=  0 ); switch ( env.wgAction ) { case "view": case "edit": case "submit": case "parsermigration-edit": if ( JSOND.using ) { mw.loader.using( JSOND.using, JSOND.fire ); } else { JSOND.fire; }              break; }  // switch wgAction pub = { doc: "" + JSOND.site + ":" + JSOND.store + "", feed: JSOND.feed, type: Signature, vsn: Version }; mw.hook( Signature + ".ready" ).fire( pub ); }  };   // JSOND.first

JSOND.flip = function { // Enable all buttons // Uses: //   >  UI.$area //   >  JSOND.support // 2018-03-01 PerfektesChaos@de.wikipedia UI.$area.find( "." + JSOND.support ).attr( { disabled: false } ); };  // JSOND.flip

JSOND.fresh = function ( $area ) { // Handler when content area has changed // Precondition: //   $area  -- jQuery element of content area //   (DOM ready) // Uses: //   >  JSOND.large //   >  JSOND.sel //   >  JSOND.src //   >< UI.$button //    < UI.$area //    < UI.live //    < UI.$source //   JSOND.furnish //   (JSOND.furnish) // 2018-03-18 PerfektesChaos@de.wikipedia var $e; UI.$area = $area; if ( JSOND.large ) { $e     = UI.$area.find( "#wpTextbox1" ); UI.live = $e.length; if ( UI.live ) { UI.$source = $e; } else { UI.$source = false; $e = UI.$area.children;  // if ( $e.length === 1 ) { $e = $e.children; if ( $e.length === 1 &&                    $e.hasClass( "mw-highlight" ) ) { $e = $e.children;   // if ( $e.length === 1 &&                       ! $e.children.length  &&                       $e.filter( "pre" ).length ) { UI.$source = $e; }              }            }         }         if ( UI.$source  &&  ! JSOND.$button ) { UI.$button = JSOND.furnish( 0, $area.get( 0 ) ); } else if ( JSOND.$button ) { JSOND.$button.remove; JSOND.$button = false; }     } else { UI.$area.find( "." + JSOND.support ).remove; UI.$area.find( "." + JSOND.sel ) .filter( JSOND.src ) .each( JSOND.furnish ); }  };   // JSOND.fresh

JSOND.furnish = function ( at, area ) { // Create button before JSON content // Precondition: //   at    -- sequence number //   area  -- DOM element of content // Postcondition: //   Returns jQuery // Uses: //   >  Signature //   >  JSOND.support //   (JSOND.fired) // 2018-03-18 PerfektesChaos@de.wikipedia var $r = $( " " ).addClass( JSOND.support ) .click( JSOND.fired ) .css( { "margin-left": "0.5em",                                      "margin-right": "0.5em" } ) .text( Signature ); $( area ).before( $r ); return $r; };  // JSOND.furnish

/*  PREGO.feed = function  { // Provide PREGO // Precondition: //   mediawiki.Title has been loaded // Uses: //   >  PREGO.signature //   >  PREGO.site //   >  PREGO.store //   mw.loader.getState //   REPOS.fire // 2018-03-01 PerfektesChaos@de.wikipedia var s = "ext.gadget." + PREGO.signature; if ( mw.loader.getState( s ) !==  "ready" ) { REPOS.fire( PREGO.site,                    PREGO.store + "/" + PREGO.signature,                     "/r.js",                     { action: "raw",                       ctype:  "text/javascript",                       bcache: 1,                       maxage: 604813 } ); }  };   // PREGO.feed

REPOS.fire = function ( at, access, append, alter ) { // Load from external URL // Precondition: //   at      -- Wikimedia Foundation site code, or not //   access  -- string with basic page name //   append  -- string with subpage, or not //   alter   -- parameter object, or MIME string, or not // Uses: //   >< REPOS.requests //   REPOS.foundation //   mw.loader.load // 2018-03-21 PerfektesChaos@de.wikipedia var source, syntax; if ( typeof REPOS.requests !==  "object" ) { REPOS.requests = { }; }     if ( typeof REPOS.requests[ access ]  !==  "boolean" ) { REPOS.requests[ access ] = true; if ( append ) { source = access + append; } else { source = access; }        if ( at ) { source = REPOS.foundation( at, source, alter ); if ( typeof alter ===  "object"                 &&     alter   &&                 typeof alter.ctype  ===  "string" ) { syntax = alter.ctype; }        } else { syntax = alter; }        mw.loader.load( source, syntax ); }  };   // REPOS.fire

REPOS.foundation = function ( at, access, alter ) { // Create URL within Wikimedia Foundation // Precondition: //   at      -- site code, or not //   access  -- string with page name //   alter   -- parameter object, or not // Postcondition: //   Returns full URL // 2018-03-21 PerfektesChaos@de.wikipedia var s = access, r = encodeURI( s ); if ( typeof alter ===  "object"           &&     alter ) { r = "/w/index.php?title=" + r;        if ( access.substr( -3 ) === ".js" ) { alter.ctype = "text/javascript"; } else if ( access.substr( -4 ) === ".css" ) { alter.ctype = "text/css"; }        alter.action = "raw"; for ( s in alter ) { r = r + "&" + s + "=" + encodeURI( alter[ s ] ); }  // for s in alter } else { r = "/wiki/" + r;     } if ( typeof at ===  "string"           &&     at ) { switch ( at ) { case "meta": r = "meta.wikimedia.org" + r;              break; case "mw": r = "www.mediawiki.org" + r;              break; case "w:en": r = "en.wikipedia.org" + r;              break; default: r = window.location.host + r;        }   // switch at         r = "https://" + r;      } return r;  };   // REPOS.foundation

UI.factory = function { // Equip page with box // Uses: //   >  UI.signature //   >  UI.css //   >  JSOND.store //   >  JSOND.site //   >  Signature //   >  Version //   >  UI.bad //   >  UI.$area //    < UI.$wrapper //    < UI.$warn //    < UI.$code //   REPOS.foundation //   (UI.flip) // 2018-03-21 PerfektesChaos@de.wikipedia var ltr  = ( $( "html" ).attr( "dir" )  !==  "rtl" ), $head = $( " " ), $e; UI.$wrapper = $( " " ).addClass( UI.signature ); UI.$wrapper.css( { "clear":      "both",                         "font-size":   "1rem",                         "font-style":  "normal",                         "font-weight": "normal",                         "max-width":   "100%",                         "width":       "100%" } ); if ( typeof UI.css ===  "object"           &&     UI.css ) { UI.$wrapper.css( UI.css ); }     if ( typeof JSOND.store  ===  "string"           &&     JSOND.store ) { $e = $( "" ).attr( { href:  REPOS.foundation( JSOND.site, JSOND.store ),                                target: Signature,                                 title:  "Tool info / doc" } ); } else { $e = $( " " ); }     $e.css( { "font-family": "monospace",                "font-size":   "1.6em",                "font-weight": "bold" } ) .text( Signature ); $head.append( $e ); $e = $( " " ).css( { "font-size":   "smaller",                                "margin-left":  "2em",                                "margin-right": "2em" } ) .text( Version + "" ); $head.append( $e ) .css( { "float": ( ltr ? "left": "right" ) } ); UI.$wrapper.append( $head ); $e = $( " " ).click( UI.flip ) .css( { "color":      "#FF0000",                                  "float":       ( ltr ? "right": "left" ),                                 "font-weight": "bold",                                  "padding":     "0.2em" } ) .text( "X" ); UI.$wrapper.append( $e ); UI.$area.prepend( UI.$wrapper ); $e = $( " " ).css( { "clear": "both" } ); UI.$wrapper.append( $e ); UI.$warn = $( " " ).addClass( Signature + "-warn" ) .css( { "clear":   "both",                                     "overflow": "auto" } ) .hide; if ( typeof UI.bad ===  "object"           &&     UI.bad ) { UI.$warn.css( UI.bad ); }     UI.$wrapper.append( UI.$warn ); UI.$code = $( " " ).addClass( Signature + "-code" ) .attr( { disabled: true } ) .css( { "overflow": "auto" } ) .hide; if ( typeof UI.code ===  "object"           &&     UI.code ) { UI.$code.css( UI.code ); }     UI.$wrapper.append( UI.$code ); };  // UI.factory

UI.fire = function ( apply, alert ) { // Start presentation // Precondition: //   apply  -- string with JSON source code, or false //   alert  -- string with error report, or false // Uses: //   >  Signature //   >  UI.$warn //   >  UI.$code //   >  UI.$area //   >  UI.normal //   >< VALID.reLineNum //    < UI.signature //    < UI.$wrapper //   UI.factory //   ZEBRA.fire // 2018-03-01 PerfektesChaos@de.wikipedia var got, k, n;     UI.signature = Signature + "-wrapper"; UI.$wrapper = UI.$area.find( "." + UI.signature ); if ( ! UI.$wrapper.length ) { UI.factory; }     if ( ! apply  || ! alert ) { UI.$warn.hide; if ( ! apply ) { UI.$code.hide; }     }      UI.$area.scrollTop( 0 ); UI.$wrapper.show; if ( apply ) { if ( alert ) { UI.$warn.show .text( alert ); if ( typeof VALID.reLineNum ===  "string" ) { VALID.reLineNum = new RegExp( VALID.reLineNum ); }           if ( typeof VALID.reLineNum  ===  "object" ) { got = alert.match( VALID.reLineNum ); if ( got ) { k = parseInt( got[ 1 ], 10 ); if ( k > 1 ) { k--; }              }            }         }         n = apply.split( "\n" ).length; if ( n > UI.normal ) { n = UI.normal; }        UI.$code.attr( "rows", n ) .show .val( apply ); ZEBRA.fire( apply, k ); }  };   // UI.fire

UI.flip = function { // Hide box // Uses: //   >  UI.$wrapper //   JSOND.flip // 2018-03-01 PerfektesChaos@de.wikipedia UI.$wrapper.hide; JSOND.flip; };  // UI.flip

VALID.fiat = function { // Execute validation // Precondition: //   jsonlint has been loaded // Uses: //   >  VALID.jsonlint //   >  VALID.source //    < VALID.scream //   VALID.jsonlint.parse //   UI.fire // 2018-03-01 PerfektesChaos@de.wikipedia VALID.scream = false; try { VALID.jsonlint.parse( VALID.source ); } catch ( e ) { VALID.scream = e.message; }     UI.fire( VALID.source, VALID.scream ); };  // VALID.fiat

VALID.fire = function ( apply ) { // Start validation and presentation // Precondition: //   apply  -- string with JSON source code //   DOM ready //   mediawiki.Title has been loaded // Uses: //   >  JSOND.site //   >  JSOND.store //   >  Signature //   >< VALID.jsonlint //    < VALID.source //   UI.fire //   ZEBRA.first //   VALID.fiat //   REPOS.fire //   mw.hook //   (VALID.furnish) // 2018-03-21 PerfektesChaos@de.wikipedia UI.fire; ZEBRA.first; VALID.source = apply; if ( VALID.jsonlint ) { VALID.fiat; } else if ( VALID.jsonlint === false ) { VALID.jsonlint = null; REPOS.fire( JSOND.site,                    JSOND.store + "/jsonlint.js",                     false,                     { action: "raw",                       ctype:  "text/javascript",                       bcache: 1,                       maxage: 604800 } ); mw.hook( Signature + ".jsonlint" ).add( VALID.furnish ); }  };   // VALID.fire

VALID.furnish = function ( application ) { // jsonlint has been loaded // Precondition: //   application  -- jsonlint object // Uses: //    < VALID.jsonlint //   VALID.fiat // 2018-03-01 PerfektesChaos@de.wikipedia if ( application &&           typeof application  ===  "object"  &&           typeof application.parse  ===  "function" ) { VALID.jsonlint = application; VALID.fiat; }  };   // VALID.furnish

ZEBRA.config = { autofocus:  true, gutters:    [ "CodeMirror-linenumbers" ], lineNumbers: true, mode:       "javascript", readOnly:   true, tabSize:    2, theme :     Signature };

ZEBRA.fiat = function ( apply ) { // Execute enhanced presentation // Precondition: //   apply  -- mode function for javascript, if not yet defined //   CodeMirror ready and initialized // Uses: //   >  ZEBRA.codemirror //   >  UI.$code //   >  ZEBRA.config //   >  ZEBRA.source //   >  ZEBRA.invalid //   >< ZEBRA.editor // 2018-03-01 PerfektesChaos@de.wikipedia if ( typeof apply ===  "object"           &&     apply   &&           typeof apply.mode  ===  "function" ) { ZEBRA.codemirror.defineMode( "javascript", apply.mode ); }     if ( ZEBRA.editor ) { ZEBRA.editor.toTextArea; }     ZEBRA.editor = ZEBRA.codemirror.fromTextArea( UI.$code.get( 0 ),                                                    ZEBRA.config ); ZEBRA.editor.setSize( null, UI.$code.height ); ZEBRA.editor.setValue( ZEBRA.source ); if ( ZEBRA.invalid ) { ZEBRA.focus( ZEBRA.invalid ); }  };   // ZEBRA.fiat

ZEBRA.fire = function ( apply, at ) { // Request presentation // Precondition: //   apply  -- string with JSON source code //   at     -- line number with error, or false // Uses: //   >  ZEBRA.codemirror //    < ZEBRA.source //    < ZEBRA.invalid //   mw.loader.using //   ZEBRA.fiat //   (ZEBRA.furnish) // 2018-03-01 PerfektesChaos@de.wikipedia ZEBRA.source = apply; ZEBRA.invalid = at || false; if ( ZEBRA.codemirror ) { ZEBRA.fiat; } else { mw.loader.using( [ "ext.CodeMirror" ],                         ZEBRA.furnish ); }  };   // ZEBRA.fire

ZEBRA.first = function { // Pre-emptive loading of CodeMirror data // Uses: //   >  JSOND.site //   >  JSOND.store //   >< ZEBRA.codemirror //   mw.loader.load //   REPOS.fire // 2018-03-21 PerfektesChaos@de.wikipedia if ( ZEBRA.codemirror === false ) { ZEBRA.codemirror = null; mw.loader.load( [ "ext.CodeMirror" ] ); REPOS.fire( JSOND.site,                    JSOND.store + ".css",                     false,                     { action: "raw",                       ctype:  "text/css",                       bcache: 1,                       maxage: 604800 } ); REPOS.fire( JSOND.site,                    JSOND.store + "/codemirrorJavascript.js",                     false,                     { action: "raw",                       ctype:  "text/javascript",                       bcache: 1,                       maxage: 604800 } ); }  };   // ZEBRA.first

ZEBRA.focus = function ( at ) { // Highlight and focus particular line // Precondition: //   at  -- line number with error // Uses: //   >  Signature //   >  ZEBRA.editor // 2018-03-01 PerfektesChaos@de.wikipedia ZEBRA.editor.addLineClass( at,                                "background",                                 Signature + "-line-error" ); ZEBRA.editor.setCursor( at ); };  // ZEBRA.focus

ZEBRA.furnish = function { // Establish CodeMirror environment // Precondition: //   CodeMirror supposed to have been loaded // Uses: //   >  window.CodeMirror //   >< ZEBRA.codemirror //    < ZEBRA.editor //   mw.hook //   (ZEBRA.fiat) // 2018-03-01 PerfektesChaos@de.wikipedia if ( ! ZEBRA.codemirror &&           typeof window.CodeMirror  !==  "undefined"           &&     window.CodeMirror ) { ZEBRA.codemirror = window.CodeMirror; ZEBRA.editor    = false; }     if ( ZEBRA.codemirror ) { mw.hook( Signature + ".cm-mode-js" ).add( ZEBRA.fiat ); }  };   // ZEBRA.furnish

JSOND.first; }( window.mediaWiki, window.jQuery ) );

// Emacs // Local Variables: // coding: utf-8-dos // fill-column: 80 // End:

/// EOF  jsonDebug/d.js