User:PerfektesChaos/js/jsonXMLutils/d.js

/// jsonXMLutils.js // Help on pages with JSON or XML code /// 2018-08-26 PerfektesChaos@de.wikipedia // ResourceLoader: compatible; //   dependencies: user, mediawiki.util // Documentation:  w:en:User:PerfektesChaos/js/jsonXMLutils /// Fingerprint:   #0#0# /// /*global window:false, JSON: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.8,       Sign      = "jsonXMLutils",       Shop      = "w:en:User:PerfektesChaos/js/",       Spooling  = "//upload.wikimedia.org/wikipedia/commons"                   + "/d/de/Ajax-loader.gif",   // throbber URL       Editor    = {  },       Hilite    = {  },       I18N      = {  },       TData     = {  },       TDJPP     = {  },       TDtxt     = {  },       Env, JXU;

//---

TData.vorlagenmeister =  "|dewiki|dewikivoyage|huwiki|"; TDJPP.templateJSON    =  "|dewiki|";

Hilite.dewiki =  function ( assign ) { // Adapt highlighted source code to local wiki project // Precondition: //   assign  -- string, with language code as of GeSHi //   mediawiki.util loaded // Uses: //   >  Hilite.$highlight //   mw.util.addCSS // 2015-01-11 PerfektesChaos@de.wikipedia var style, $box; if ( assign === "xml" ) { style =  ".source-xml {" +    "font-size: 90%;" + "}";        $box  = $( "#intro-xml-page" ); mw.util.addCSS( style ); $box.detach; $box.css( { "margin-bottom": "1em",                    "margin-top":    "1em",                     "position":      "relative",                     "top":           "auto"                   } ); Hilite.$highlight.eq( 0 ).before( $box ); $( "#mw-content-text" ).empty; }  };   // Hilite.dewiki

TData.dewiki =  function ( action, adjust ) { // Adapt created XML code to local wiki project // Precondition: //   action  -- string, with "2xml" //   adjust  -- string, with JSON source // Uses: //   >  Env // 2015-01-11 PerfektesChaos@de.wikipedia var s = Env.wgTitle.replace( /\/.*$/, "" ); return '<?mediawiki ""?>\n' + adjust; };  // TDJPP.dewiki

TData.huwiki =  function ( action, adjust ) { // Adapt created XML code to local wiki project // Precondition: //   action  -- string, with "2xml" //   adjust  -- string, with JSON source // Uses: //   >  Env // 2015-01-20 PerfektesChaos@de.wikipedia var s = Env.wgTitle.replace( /\/.*$/, "" ); return '<?mediawiki ""?>\n' + adjust; };  // TDJPP.huwiki

TDJPP.otherLanguages = [ "simple", "tokipona" ];

I18N.texts = { btn_Submit:       { en: "Submit", de: "Anwenden" }, btn_TD_0:         { en: "TemplateData generation", de: "TemplateData generieren" }, btn_TD_00:        { en: "TemplateData generator", de: "TemplateData Generator" }, btn_TD_PP:        { en: "TemplateData pretty print", de: "TemplateData formatieren" }, btn_TD2XML:       { en: "TemplateData to XML", de: "TemplateData zu XML" }, btn_XML2TD:       { en: "XML to TemplateData", de: "XML zu TemplateData" }, PP_DescInvalid:   { en: "ERROR:" + " description text is not a string", de: "FEHLER: Beschreibungstext" + " ist keine Zeichenkette" }, PP_EqualSign:     { en: "STRANGE!" + " Equal sign '=' in parameter name." + " This will not work on transclusion.", de: "WIRR!" + " Gleichheitszeichen '='" + " im Parameternamen." + " Das wird bei der Einbindung" + " nicht funktionieren." },     PP_H2:             { en: "Recommendations and errors", de: "Empfehlungen und Fehlermeldungen" }, PP_InvalidType:   { en: "ERROR: Invalid type of a component", de: "FEHLER: Unerlaubter Datentyp" + " einer Komponente." },     PP_LabelLong:      { en: "label seems to be rather long", de: " " + " scheint recht lang zu sein." },     PP_LanguageCode:   { en: "WARNING: Invalid language code", de: "WARNUNG: Fehlerhafter Sprachcode" }, PP_Lethal:        { en: "ERROR: Severe problem detected", de: "FEHLER: Erhebliches Problem gefunden" }, PP_Lethals:       { en: "ERROR: Severe problems detected", de: "FEHLER: Erhebliche Probleme gefunden" }, PP_MandParams:    { en: "ERROR: mandatory 'params' missing", de: "FEHLER:" + " Pflichtparameter " + " nicht gefunden" }, PP_ParamDup:      { en: "ERROR: Duplicated parameter name", de: "FEHLER: Doppelter Parametername" }, PP_PipeSymbol:    { en: "STRANGE!" + " Pipe symbol " + " in parameter name." + " This will not work on transclusion.", de: "WIRR!" + " Pipe-Symbol " + " im Parameternamen." + " Das wird bei der Einbindung" + " nicht funktionieren." },     PP_QuotMark:       { en: "STRANGE!" + " Quotation mark " + " in parameter name.", de: "WIRR!" + " Begrenzer " + " im Parameternamen." },     PP_RequiredAuto:   { en: "CONFLICT" + " Both 'required' and 'autovalue'.", de: "Konfllkt:" + " Sowohl 'required'" + " als auch 'autovalue'." },     PP_ShortDesc:      { en: "description quite short", de: "Der Beschreibungstext" + " scheint recht kurz zu sein." },     PP_TypeDeprecated: { en: "DEPRECATED: Parameter 'type';" + " remove ", de: "VERALTET (Parameter ):" + " vorangestelltes" + "  entfernen" }, PP_TypeUnknown:   { en: "WARNING: Parameter 'type'" + " value not recognized", de: "WARNUNG: Parameter  *" + " Wert nicht erkannt" }, PP_UnknownItem:   { en: "WARNING: Could not recognize", de: "WARNUNG: Komponente nicht erkannt" } };  // 2015-01-11 PerfektesChaos@de.wikipedia

I18N.translate = { // fallback languages "als" :      "de", "bar" :      "de", "dsb" :      "de", "frr" :      "de", "gsw" :      "de", "hsb" :      "de", "ksh" :      "de", "lb" :       "de", "nds" :      "de", "pdc" :      "de", "pdt" :      "de", "pfl" :      "de", "sli" :      "de", "stq" :      "de", "vmf" :      "de" };

//---

function face { // Initialize environment and application object, if user defined // Precondition: //   module 'user' loaded // Postcondition: //     // Uses: //   >  mw.libs //   >  Sign //   >  Version //   >  Shop //   >< JXU // 2014-12-27 PerfektesChaos@de.wikipedia if ( typeof mw.libs[ Sign ] ===  "object"   &&           mw.libs[ Sign ]   &&           ! JXU ) { JXU    = mw.libs[ Sign ]; JXU.vsn = Version; JXU.doc = "" + Shop + Sign + ""; }  }   // face

function facet( applied ) { // Check for user option // Precondition: //   applied  -- option keyword //   module 'user' loaded // Postcondition: //   Returns value, or undefined // Uses: //   >  JXU //   face // 2014-12-27 PerfektesChaos@de.wikipedia var r;  // = undefined face; if ( JXU  &&   typeof JXU[ applied ]  !==  "undefined" ) { r = JXU[ applied ]; }     return r;   }   // facet

//---

Editor.fiat = function { // Start CodeEditor // Uses: //   >  Editor.sourcemods //   mw.loader.load //   mw.config.set // 2014-12-27 PerfektesChaos@de.wikipedia mw.loader.load( Editor.sourcemods + "mode-xml.js" ); // Editor.finish   require mw.config.set("wgCodeEditorCurrentLanguage", "xml"); };  // Editor.fiat

Editor.fire = function { // Prepare CodeEditor // Uses: //    < Editor.sourcebase //    < Editor.sourcemods //   mw.loader.using //   (Editor.fiat) // 2014-12-27 PerfektesChaos@de.wikipedia this.sourcebase = "mediawiki/extensions/CodeEditor"; this.sourcebase = this.sourcebase.replace( /\//g, "%2F" ); this.sourcebase = "https://git.wikimedia.org/raw/" + this.sourcebase + "/HEAD/"; this.sourcemods = "modules/ace/"; this.sourcemods = this.sourcemods.replace( /\//g, "%2F" ); this.sourcemods = this.sourcebase + this.sourcemods; mw.loader.using( [ "ext.codeEditor",                        "ext.codeEditor.ace",                         "jquery.ui",                         "ext.wikiEditor" ],                       Editor.fiat ); };  // Editor.fire

//---

Hilite.fair =  function ( adjust, assign, after, abort ) { // Fetch highlighted source code // Precondition: //   adjust  -- string, with source code //   assign  -- string, with language code as of pygments //   after   -- function, called later with the formatted string //   abort   -- optional function, called on failure //              false to die silently //   mediawiki.api loaded // Postcondition: //   Calls, function with formatted JSON source code // Uses: //   >< Hilite.api //   mw.Api // 2018-08-26 PerfektesChaos@de.wikipedia var failed = abort, fine  = function ( a ) { if ( typeof a ===  "object"   &&                            typeof a.parse  ===  "object"   &&                            typeof a.parse.text  ===  "object"   &&                            typeof a.parse.text[ "*" ]  ===  "string" ) { after( a.parse.text[ "*" ] ); } else if ( typeof abort ===  "function" ) { abort( "API: Strange answer" ); } else { after( " " + adjust + " " ); }                  },          source = " "; if ( failed === false ) { failed = function { }; } else if ( typeof failed !==  "function" ) { failed = function { after( " " + adjust + " " ); }; }     if ( typeof Hilite.api  !==  "object" ) { Hilite.api = new mw.Api; }     Hilite.api.post( { action:       "parse",                         contentmodel: "wikitext",                         disablepp:    true,                         prop:         "text",                         text:         source                       } ) .done( fine ) .fail( failed ); mw.loader.load( [ "ext.pygments" ] ); };  // Hilite.fair

Hilite.fetch =  function  { // Fetch highlighted XML source code // Precondition: //   mediawiki.api mediawiki.util loaded // Uses: //   >  Hilite.source //   Hilite.fair //   mw.util.addCSS //   (Hilite.fetched) // Remark: Used as event handler -- 'this' is not Hilite // 2014-12-30 PerfektesChaos@de.wikipedia var style =   ".mw-code {" +   "padding-top: 0.5em;" + "}"                  + ".source-xml {" +   "font-size:      90%;" +   "overflow:       auto;" +   "padding-bottom: 1em;" + "}";     Hilite.fair( Hilite.source, "xml", Hilite.fetched, false ); mw.util.addCSS( style ); };  // Hilite.fetch

Hilite.fetched =  function ( arrived ) { // Fetched highlighted XML source code after query // Precondition: //   arrived  -- string, with HTML // Uses: //   >  Hilite.remove //   >  Env //    < Hilite.$highlight // Remark: Used as event handler -- 'this' is not Hilite // 2015-01-11 PerfektesChaos@de.wikipedia var i, $h1; for ( i = 0; i < Hilite.remove.length;  i++ ) { Hilite.remove[ i ].remove; }  // for i      Hilite.$highlight = $( arrived ); $h1 = $( "#firstHeading" ); $h1.after( Hilite.$highlight ); if ( ! Env.wgDBname ) { Env.wgDBname = mw.config.get( "wgDBname" ); }     if ( typeof Hilite[ Env.wgDBname ]  ===  "function" ) { Hilite[ Env.wgDBname ]( "xml" ); }  };   // Hilite.fetched

Hilite.fire = function { // Start XML source code highlighting // Precondition: //   mediawiki.api mediawiki.util loaded // Uses: //   >  mw.util.$content //    < Hilite.remove //    < Hilite.source //   mw.loader.using //   (Hilite.fetch) // Remark: Used as event handler -- 'this' is not Hilite // 2015-01-11 PerfektesChaos@de.wikipedia var large = facet( "hiliteLarge" ), $paras = mw.util.$content.find( "p,pre" ), i, j, s, segment, start, $para; Hilite.remove = [ ]; Hilite.source = false; for ( i = 0; i < $paras.length;  i++ ) { $para  = $paras.eq( i ); segment = $para.text; if ( segment ) { j = segment.indexOf( "<" ); if ( ! j ) { start = segment; } else if ( j > 0 ) { start = segment.substr( j ); s    = segment.substr( 0, j ).replace( /\s+/g, "" ); j    = s.length; }           if ( ! j ) { if ( start.substr( 0, 2 ) !==  "<?"   ||   large ) { if ( Hilite.source ) { Hilite.source = Hilite.source + "\n" + segment; } else { Hilite.source = segment; }              }               Hilite.remove.push( $para ); }        }      }   // for i      if ( Hilite.source ) { mw.loader.using( [ "mediawiki.api",                           "ext.geshi.language.xml",                            "ext.geshi.local" ],                          Hilite.fetch ); }  };   // Hilite.fire

Hilite.flow = function ( $around ) { // Create and show throbber // Precondition: //   $around  -- jQuery container object // Postcondition: //   throbber visible // Uses: //   >  Spooling // 2015-01-12 PerfektesChaos@de.wikipedia var $img; if ( ! $around.children.length ) { $img = $( " " ); $img.attr( { src:   Spooling,                      id:     "ajax_throbber",                      height: "20",                      alt:    "Ajax" } ); $img.css( { "margin-left": "10px" } ); $around.append( $img ); }     $around.show; };  // Hilite.flow

//---

I18N.facility = function ( available ) { // Localize in user language, GUI only // Precondition: //   available  -- translation object // Postcondition: //   Returns string, or undefined // Uses: //   >  I18N.translate //   >< Env //   mw.config.get // 2014-12-16 PerfektesChaos@de.wikipedia var i, r, slang; if ( ! Env.userLang ) { Env.userLang = mw.config.get( "wgUserLanguage" ).toLowerCase; }     slang = Env.userLang; if ( typeof available[ slang ] ===  "string" ) { r = available[ slang ]; } else { i = slang.indexOf( "-", 2 ); if ( i > 0 ) { slang = slang.substr( 0, i ); if ( typeof available[ slang ] ===  "string" ) { r = available[ slang ]; }        }      }      if ( ! r ) { if ( typeof I18N.translate[ slang ] ===  "string" ) { slang = I18N.translate[ slang ]; if ( typeof available[ slang ] ===  "string" ) { r = available[ slang ]; }        }         if ( ! r ) { r = available.en; }     }      return r;   };   // I18N.facility

I18N.fair = function ( access, adapt, alter ) { // Localization // Precondition: //   access  -- configuration keyword //   adapt   -- false, if project (language) dependant //              else user language dependant //   alter   -- default string (en) // Postcondition: //   Returns value, or keyword 'access' // Uses: //   >  JXU //   >  I18N.texts //   >< Env //   face //   I18N.facility //   mw.config.get // 2014-12-20 PerfektesChaos@de.wikipedia var el, r, say; if ( alter ) { r = alter; } else { r = access; }     face; if ( JXU  &&           typeof JXU.config  ===  "object"   &&           JXU.config   &&           typeof JXU.config[ access ]  ===  "object" ) { el = JXU.config[ access ]; }     if ( ! el ) { el = I18N.texts[ access ]; }     if ( el ) { if ( adapt ) { say = I18N.facility( el ); if ( say ) { r = say; } else if ( typeof alter !==  "string" ) { r = "???" + access + "???"; }        } else { if ( ! Env.wgDBname ) { Env.wgDBname = mw.config.get( "wgDBname" ); }           if ( typeof el[ Env.wgDBname ]  ===  "string" ) { r = el[ Env.wgDBname ]; } else { if ( ! Env.wgContentLanguage ) { Env.wgContentLanguage = mw.config.get( "wgContentLanguage" ); }              if ( typeof el[ Env.wgContentLanguage ]  ===  "string" ) { r = el[ Env.wgContentLanguage ]; }           }         }      } else if ( adapt ) { r = "???" + access + "???"; }     return r;   };   // I18N.fair

//---

TData.fire = function { // Start TemplateData handling // Precondition: //   mediawiki.api loaded // Uses: //   >  Env //   (TData.feed) //   (TData.fault) // Remark: Used as event handler -- 'this' is not TData // 2015-01-11 PerfektesChaos@de.wikipedia var rq = { action: "templatedata" }; rq.titles = "Template:" + Env.wgTitle.replace( /\/.*$/, "" ); TData.api = new mw.Api; TData.api.get( rq ).done( TData.feed ) .fail( TData.fault ); };  // TData.fire

TData.factory = function { // Create Vorlagenmeister XML from TemplateData JSON // Uses: //   >  TData.templateData //   >  Env //   >  TData.$throbber //    < TData.lead //   TData.feature //   TDJPP.fence //   Hilite.fair //   Hilite.flow //   (TData.fiat) // Remark: Used as event handler -- 'this' is not TData // 2015-01-20 PerfektesChaos@de.wikipedia var p, params, s, sign, story; if ( TData.templateData ) { s = ' \n' + '  \n'; if ( typeof TData.templateData.params ===  "object"   &&              TData.templateData.params ) { params = TData.templateData.params; for ( sign in params ) { if ( sign  &&                    typeof params[ sign ]  ===  "object" ) { s    = s + '     /g, "&gt;" )                           + '"'; }                 if ( typeof p.required  ===  "boolean"   &&                       p.required ) { s = s + ' null="false"'; }                 if ( typeof p.type  ===  "string" ) { story = TDJPP.fence( p.type, false ); if ( story !== "unknown" ) { s = s + ' type="' + story + '"'; }                 }                  s = s + '>\n'; story = TData.feature( p, "description" ); if ( story ) { s = s + '      ' + story.replace( //g, "&#62;" ) + '\n'; }                 if ( typeof p[ "default" ]  ===  "string" ) { story = p[ "default" ].replace( /^\s+/, "" ) .replace( /\s+$/, "" ); if ( story ) { s = s + '      ' + story.replace( /\n'; }                 }                  if ( typeof p.autovalue  ===  "string" ) { story = p.autovalue.replace( /^\s+/, "" ) .replace( /\s+$/, "" ); if ( story ) { s = s + '      ' + story.replace( /\n'; }                 }                  s = s + '     \n'; }           }   // for  in .params }        s = s             + '   \n' + ' '; if ( ! Env.wgDBname ) { Env.wgDBname = mw.config.get( "wgDBname" ); }        if ( typeof TData[ Env.wgDBname ]  ===  "function" ) { s = TData[ Env.wgDBname ]( "2xml", s ); }        s = '\n' + s;         Hilite.fair( s, "xml", TData.fiat, false ); Hilite.flow( TData.$throbber ); TData.lead = true; }  };   // TData.factory

TData.fault = function ( arrived ) { // Error on ajax query // Precondition: //   arrived  -- result of ajax query // Uses: //   window.console.log // Remark: Used as event handler -- 'this' is not TData // 2015-01-11 PerfektesChaos@de.wikipedia window.console.log( arrived ); window.console.dir( arrived ); };  // TData.fault

TData.feature = function ( assembly, access ) { // Retrieve best fit of interface in project language // Precondition: //   assembly  -- parameter //   access    -- component name // Postcondition: //   Returns value, or keyword 'access' // Uses: //   >< Env // 2015-01-11 PerfektesChaos@de.wikipedia var r, s, slang, t;     switch ( typeof assembly[ access ] ) { case "object" : if ( typeof Env.wgContentLanguage !==  "string" ) { Env.wgContentLanguage = mw.config.get( "wgContentLanguage" ); }           t = assembly[ access ]; if ( t ) { if ( typeof t[ Env.wgContentLanguage ] ===  "string" ) { r = t[ Env.wgContentLanguage ]; }              if ( ! r ) { slang = Env.wgContentLanguage + "-"; for ( s in t ) { if ( ! s.indexOf( slang ) ) { r = t[ s ]; if ( r ) { break;  // for s in t                        } }                 }   // for s in t               } }           break; case "string" : r = assembly[ access ]; break; }  // switch typeof component if ( r ) { r = r.replace( /^\s+/, "" ) .replace( /\s+$/, "" ) .replace( /\\/g, "\\" ); }     return r;   };   // TData.feature

TData.feed = function ( arrived ) { // Ajax query successful // Precondition: //   arrived  -- JSON result of ajax query // Uses: //   >  Env //   >  TData.vorlagenmeister //    < TData.learn //    < TData.live //    < TData.lmx //   TData.fault //   jQuery //   (TData.furnish) // Remark: Used as event handler -- 'this' is not TData // 2015-01-19 PerfektesChaos@de.wikipedia var page, suitable; if ( typeof arrived.pages ===  "object" ) { TData.templateData = false; for ( page in arrived.pages ) { if ( TData.templateData ) { TData.fault( arrived );  // STRANGE. Multiple. } else { TData.templateData = arrived.pages[ page ]; }        }   // for page in arrived.pages suitable   = "|edit|submit|"; TData.learn = ( suitable.indexOf( Env.wgAction ) >=  0 ); if ( TData.templateData ) { TData.live = true; if ( ! Env.wgDBname ) { Env.wgDBname = mw.config.get( "wgDBname" ); }           suitable = "|" + Env.wgDBname + "|"; TData.lmx = ( TData.vorlagenmeister.indexOf( suitable )                         >=  0   ||                          facet( "vorlagenmeister" ) ); }        $( TData.furnish ); } else { TData.fault( arrived ); }  };   // TData.feed

TData.fetch = function { // Retrieve JSON object from edit form // Precondition: //   DOM.ready // Uses: //   >  mw.util.$content //   TData.$field //   JSON.parse //   TDJPP.flush // 2015-01-20 PerfektesChaos@de.wikipedia var $ta = TData.$field, got, r, s;     if ( $ta ) { s  = $ta.val; got = /<\s*templatedata\s*>/i.exec( s ); if ( got ) { s  = s.substr( got.index + got[ 0 ].length ); got = /}\s*<\s*\/\s*templatedata\s*>/i.exec( s ); if ( got ) { s = s.substr( 0, got.index + 1 ); try { r = JSON.parse( s ); } catch ( e ) { TDJPP.flush; r = "" + "ERROR in JSON" + " ";              }            }         }      }      return r;   };   // TData.fetch

TData.fiat = function ( arrived ) { // Show highlighted generated XML code // Precondition: //   arrived  -- string, with HTML // Uses: //   >  TData.$throbber //   TData.$fold // Remark: Used as event handler -- 'this' is not TData // 2015-01-12 PerfektesChaos@de.wikipedia var $highlight = $( arrived ), $div      = TData.$fold; $div.append( $highlight ); TData.$throbber.hide; };  // TData.fiat

TData.$field = function { // Retrieve $textarea object from edit form // Precondition: //   DOM.ready // Postcondition: //   Returns jQuery object, with $textarea, or false // Uses: //   this //   >  mw.util.$content //   >< TData.$textarea // 2015-01-20 PerfektesChaos@de.wikipedia var $r = false, $form; if ( this.$textarea ) { $r = this.$textarea; } else { $form = mw.util.$content.find( "#editform" ); if ( $form.length ) { this.$textarea = $form.find( "#wpTextbox1" ); if ( this.$textarea.length ) { $r = this.$textarea; } else { this.$textarea = false; }        }      }      return $r; };  // TData.$field

TData.fine = function { // Show pretty printed highlighted JSON // Uses: //   >  TData.templateData //   >  TData.$throbber //   >< TData.lead //   mw.loader.load //   TData.fetch //   TDJPP.facility //   Hilite.fair //   Hilite.flow //   (TData.finish) // Remark: Used as event handler -- 'this' is not TData // 2015-01-20 PerfektesChaos@de.wikipedia var td; if ( TData.templateData &&  TData.lead ) { td        = TData.templateData; TData.lead = false; } else if ( TData.learn ) { td = TData.fetch; }     if ( td ) { Hilite.fair( TDJPP.facility( td, 3 ),                     "javascript",                      TData.finish,                      false ); Hilite.flow( TData.$throbber ); }  };   // TData.fine

TData.finish = function ( arrived ) { // Show highlighted pretty printed JSON code // Precondition: //   arrived  -- string, with HTML // Uses: //   >  TData.$throbber //   TData.$fold //   TDJPP.$failures // Remark: Used as event handler -- 'this' is not TData // 2015-01-20 PerfektesChaos@de.wikipedia var $highlight = $( arrived ), $div      = TData.$fold, $report   = TDJPP.$failures; if ( $report ) { $div.append( $report ); }     $div.append( $highlight ); TData.$throbber.hide; };  // TData.finish

TData.$fold = function { // Create or clear code area // Postcondition: //   Returns empty jQuery code block // Uses: //   this //   >  Sign //   >< TData.$div // 2015-01-20 PerfektesChaos@de.wikipedia if ( typeof this.$div ===  "object" ) { this.$div.empty; } else { this.$div = $( " " ); this.$div.attr( { "id": Sign + "-code" } ); this.$div.css( { "margin-bottom": "1em",                         "margin-top":    "1em" } ); if ( this.learn ) { $( "#mw-content-text" ).prepend( this.$div ); } else { $( "#mw-content-text" ).append( this.$div ); }     }      return this.$div; };  // TData.$fold

TData.$form = function ( apply, $append ) { // Create and insert button // Precondition: //   apply    -- object, with specification //   $append  -- jQuery object, to append to      //    DOM.ready // Postcondition: //   Returns jQuery button object // Uses: //   >  Sign //   I18N.fair // 2015-01-21 PerfektesChaos@de.wikipedia var $r = $( " " ); $r.attr( { "id": Sign + "-" + apply.sign } ); $r.click( apply.click ); $r.css( { "margin-left": "2em" } ); if ( apply.i18n ) { $r.text( I18N.fair( apply.i18n, true, apply.i18n ) ); }     $append.append( $r ); return $r; };  // TData.$form

TData.furnish = function { // Equip page with appropriate buttons // Precondition: //   DOM.ready // Uses: //   >  TData.live //   >  TData.lmx //   >  TData.learn //   >  Sign //   >  TData.templateData //    < TData.$throbber //    < TData.lead //   TData.$form //   (TData.fine) //   (TData.factory) //   (TData.fire) // Remark: Used as event handler -- 'this' is not TData // 2015-01-24 PerfektesChaos@de.wikipedia var $div = $( " " ), button, $root; if ( TData.learn ) { $root = $( ".tdg-editscreen-main-helplink" ); if ( ! $root.length ) { $root = false; }     }      if ( ! $root ) { $root = $( "#mw-content-text" ); }     $div.css( { "margin-bottom": "1em",                  "margin-top":    "1em" } ); $root.after( $div ); if ( TData.live ) { button = { click: TData.fine, i18n: "btn_TD_PP", sign: "btn_TD_PP" };        TData.$form( button, $div ); if ( TData.lmx ) { button = { click: TData.factory, i18n: "btn_TD2XML", sign: "btn_TD2XML" };           TData.$form( button, $div ); }     }      button = { click: TDtxt.fire, sign: "btn_TD_0" };     if ( TData.live ) { button.i18n = "btn_TD_00"; } else { button.i18n = "btn_TD_0"; }     TData.$form( button, $div ); TData.$throbber = $( " " ); $div.append( TData.$throbber ); TData.lead = true; };  // TData.furnish

//---

TDJPP.facility = function ( apply, adjust ) { // Start TemplateData JSON pretty printing // Precondition: //   apply   -- TemplateData object (JSON) //   adjust  -- handling of empty and basic fields //              0: as is in object apply //              1: ignore empty fields //              2: ensure basic fields //              3: ensure basic fields, discard other empty fields //              4: create all fields, even empty // Postcondition: //   Returns string, with formatted JSON source code // Uses: //   >  Env //   >  TDJPP.templateJSON //   TDJPP.flush //   TDJPP.description //   TDJPP.params //   TDJPP.sets //   TDJPP.format //   TDJPP.further //   TDJPP.fields // 2018-08-24 PerfektesChaos@de.wikipedia var i = 0, k = 2, m = ( typeof adjust === "number" ?  adjust  :  0 ), r = "", s;     TDJPP.flush; s = this.description( apply, k, m ); if ( s ) { r = s;        i = k;      } s = this.params( apply, k, i, m ); if ( s ) { if ( r ) { r = r + ",\n "; }        r = r + s;         i = k;      } s = this.sets( apply, k, i, m ); if ( s ) { if ( r ) { r = r + ",\n "; }        r = r + s;      } s = this.format( apply, k, i, m ); if ( s ) { if ( r ) { r = r + ",\n "; }        r = r + s;      } r = "{ " + r + "\n}"; if ( ! Env.wgDBname ) { Env.wgDBname = mw.config.get( "wgDBname" ); }     s = "|" + Env.wgDBname + "|"; if ( typeof this[ Env.wgDBname ] ===  "function" ) { r = this[ Env.wgDBname ]( r ); } else if ( TDJPP.templateJSON.indexOf( s ) >=  0 ) { r = this.further( r ); // 2018-08-24 PerfektesChaos@de.wikipedia }     this.fields( apply,                   [ "description", "params", "sets",                     "maps", "format", "paramOrder", "title" ],                   " " ); return r;  };   // TDJPP.facility

TDJPP.bad = [ "DescInvalid", "InvalidType", "MandParams", "ParamDup", "UnknownItem" ];  // Fatal errors TDJPP.extension = { "description":      [ true,  40, "ShortDesc" ], "label":            [ false, 25, "LabelLong" ], "param.description": [ true, 5, "ShortDesc" ] };  // string length

TDJPP.aliases = function ( array, adjust ) { // Pretty printing of TemplateData aliases Array // Precondition: //   array   -- Array of strings //   adjust  -- >=4: create empty basic field // Postcondition: //   Returns string, with formatted JSON source code // Uses: // 2014-12-27 PerfektesChaos@de.wikipedia var r = "", i;     if ( typeof array.length === "number"  &&           array.length ) { for ( i = 0; i < array.length;  i++ ) { if ( i ) { r = r + ", "; }           r = r + this.fair( "" + array[ i ] ); }  // for i         r = "[ " + r + " ]"; } else if ( adjust >= 4 ) { r = "[ ]"; }     return r;   };   // TDJPP.aliases

TDJPP.description = function ( apply, align, adjust ) { // Pretty printing of TemplateData description component // Precondition: //   apply   -- TemplateData object //   align   -- number of spaces to indent consecutive lines //   adjust  -- >1: create empty basic field // Postcondition: //   Returns string, with formatted JSON source code // Uses: //   TDJPP.folder //   TDJPP.failed // 2015-01-11 PerfektesChaos@de.wikipedia var s = typeof apply.description, r;     switch ( s ) { case "object" : case "string" : r = this.folder( apply.description,                            adjust,                             align + 15,                             "description" ); break; case "undefined" : if ( adjust > 1 ) { r = '""'; }           break; default: this.failed( "InvalidType", ".description: " + s ); r = '"[' + s + ']"'; }  // switch typeof description if ( r ) { r = '"description": ' + r;     } else { r = ""; }     return r;   };   // TDJPP.description

TDJPP.param = function ( apply, access, align, after, adjust ) { // Pretty printing of single TemplateData parameter component // Precondition: //   apply   -- TemplateData object //   access  -- string, with name of param //   align   -- maximum name length //              <0: line break //   after   -- break and spaces to indent consecutive lines //   adjust  -- handling of empty and basic fields // Postcondition: //   Returns string, with formatted JSON source code // Uses: //   TDJPP.failed //   TDJPP.fields //   TDJPP.folder //   TDJPP.fence //   TDJPP.fair //   TDJPP.aliases //   TDJPP.fill // 2016-01-29 PerfektesChaos@de.wikipedia var e  =  [ "label", "description", "type", "required", "suggested", "default", "autovalue", "example", "inherits", "deprecated", "aliases" ], max = 0, r  = "", i, n, p, s, slot, v;     if ( access.indexOf( '"' )  >=  0 ) {         this.failed( "QuotMark", access );      } else if ( access.indexOf( "=" )  >=  0 ) {         this.failed( "EqualSign", access );      } else if ( access.indexOf( "|" )  >=  0 ) {         this.failed( "PipeSymbol", access );      }      if ( typeof apply.params[ access ]  ===  "object" ) {         p = apply.params[ access ];      }      if ( p ) {         this.fields( p,  e,  "params:" + access );         for ( i = 0;  i < e.length;  i++ ) {            s  = e[ i ];            if ( typeof p[ s ]  !==  "undefined" ) {               v = p[ s ];               if ( v  ||  adjust >= 3 ) {                  switch ( s ) {                     case "label" :                        v = this.folder( v, adjust, after, 0, s );                        break;                     case "description" :                     case "example" : slot = "param." + s;                       v    = this.folder( v, adjust, after, 0, slot ); break; case "type" : v = this.fence( "" + v, true ); // fall through case "default" : case "autovalue" : case "inherits" : v = this.fair( "" + v ); break; case "required" : if ( v  &&                             typeof p.autovalue  ===  "string"   &&                             p.autovalue ) { this.failed( "RequiredAuto", access ); }  // fall through case "suggested" : if ( typeof v ===  "boolean" ) { v = ( v ? "true" : "false" ); } else { v = "true"; }                       break; case "deprecated" : if ( typeof v ===  "boolean" ) { v = ( v ? "true" : "false" ); } else { v = "" + v;                       } break; case "aliases" : if ( typeof v ===  "object" ) { v = this.aliases( v ); } else { v = "[ ]"; }                       break; }  // switch s               } } else { v = undefined; }           if ( ! v  &&  adjust >= 2 ) { switch ( s ) { case "label" : case "description" : v = '""'; break; case "type" : v = '"unknown"'; break; case "required" : v = "false"; break; }  // switch s            } if ( v ) { e[ i ] = [ s, v ]; n = s.length; if ( n > max ) { max = n;              } }        }   // for i         for ( i = 0;  i < e.length;  i++ ) { p = e[ i ]; if ( typeof p ===  "object" ) { if ( r ) { if ( i ) { r = r + ","; }                 r = r + after; if ( i ) { r = r + " "; }              }               s = p[ 0 ]; r = r + this.fair( s ) +  ":" + this.fill( max - s.length + 1 ) + p[ 1 ]; }        }   // for i         r = "{ " + r + " }"; if ( align < 0 ) { r = after + r;        } else { r = this.fill( align - access.length + 1 ) +  r;         } } else { this.failed( "InvalidType", "params:" + access ); r = ' "?? InvalidType ??"'; }     r = this.fair( access ) + ":" + r;      return r;   };   // TDJPP.param

TDJPP.params = function ( apply, align, adjust ) { // Pretty printing of TemplateData params component // Precondition: //   apply   -- TemplateData object //   align   -- number of spaces to indent consecutive lines //   adjust  -- handling of empty and basic fields // Postcondition: //   Returns string, with formatted JSON source code // Uses: //   $.inArray //   TDJPP.failed //   TDJPP.fill // 2015-01-20 PerfektesChaos@de.wikipedia var max = 0, r  = "", i, k, n, ord, s, shift; if ( typeof apply.params ===  "object"   &&   apply.params ) { if ( typeof apply.paramOrder === "object"  &&              apply.paramOrder   &&              apply.paramOrder.length ) { ord = apply.paramOrder; } else { ord = [ ]; for ( s in apply.params ) { s = "" + s;              if ( $.inArray( s, ord )  <  0 ) { ord.push( s ); } else { this.failed( "ParamDup", s ); }           }   // for s in apply.params }        for ( i = 0;  i < ord.length;  i++ ) { n = ord[ i ].length; if ( n > max ) { max = n;           } }  // for i         n = align; if ( max > 3 ) { k = -1; n += 6; s = this.fill( align + 3 ); } else { k = max; n += max + 16; s = this.fill( align + 12 ); }        shift = "\n" + this.fill( n ); for ( i = 0; i < ord.length;  i++ ) { if ( i ) { r = r + ",\n" + s;           } r = r + this.param( apply, ord[ i ], k, shift, adjust ); }  // for i      } else { this.failed( "MandParams", "?!?!" ); }     r = '"params": {' + ( k < 0 ?  "\n     "  :  " " ) + r + "\n" + this.fill( align + 10 ) +  "}"; return r;  };   // TDJPP.params

TDJPP.sets = function ( apply, align, adjust ) { // Pretty printing of TemplateData sets component // Precondition: //   apply   -- TemplateData object //   align   -- number of spaces to indent consecutive lines //   adjust  -- 4: create field in any case // Postcondition: //   Returns string, with formatted JSON source code // Uses: //   TDJPP.fair // 2015-01-11 PerfektesChaos@de.wikipedia var r = "", i;     if ( typeof apply.sets === "object"           &&     apply.sets  &&           typeof apply.sets.length === "number"  &&           apply.sets.length ) { for ( i = 0; i < apply.sets.length;  i++ ) { if ( i ) { r = r + ", "; }           r = r + this.fair( apply.sets[ i ] ); }  // for i         r = '"sets": [ ' + r + " ]"; } else if ( adjust >= 4 ) { r = '"sets": [ ]'; }     return r;   };   // TDJPP.sets

TDJPP.format = function ( apply /*, align */ ) { // Pretty printing of TemplateData sets component // Precondition: //   apply   -- TemplateData object //   align   -- number of spaces to indent consecutive lines // Postcondition: //   Returns string, with formatted JSON source code // Uses: //   TDJPP.fair // 2016-02-07 PerfektesChaos@de.wikipedia var r;     if ( typeof apply.format === "string"           &&     apply.format ) { if ( /\bblock\b/i.test( apply.format ) ) { r = '"block"'; } else { r = '"inline"'; }        r = '"format": ' + r;      } else { r = ""; }     return r;   };   // TDJPP.format

TDJPP.failed = function ( alert, add ) { // Register complaint // Precondition: //   alert  -- string, with keyword //   add    -- string, with additional information // Postcondition: //   Memorized issue // Uses: //   this //   >< TDJPP.complaints // 2014-12-27 PerfektesChaos@de.wikipedia var cClass; if ( typeof this.complaints !==  "object" ) { this.complaints = { }; }     if ( typeof this.complaints[ alert ]  !==  "object" ) { this.complaints[ alert ] = { }; }     cClass = this.complaints[ alert ]; if ( typeof cClass[ add ] ===  "number" ) { cClass[ add ] = cClass[ add ]++; } else { cClass[ add ] = 1; }  };   // TDJPP.failed

TDJPP.$failures = function { // Retrieve report // Precondition: //   TDJPP.facility has been executed before // Postcondition: //   Returns jQuery object, or false // Uses: //   this //   >  TDJPP.complaints //   >  TDJPP.bad //   I18N.fair //   $.inArray // 2015-01-11 PerfektesChaos@de.wikipedia var m = 0, details, n, strange, subject, $code, $div, $h2, $li1, $li2, $span, $ul1, $ul2, $r; if ( typeof this.complaints ===  "object" ) { $r = $( " " ); $r.attr( { "id": Sign + "-JSON-report" } ); $h2 = $( " " ); $h2.text( I18N.fair( "PP_H2", true ) ); $r.append( $h2 ); $ul1 = $( " " ); for ( strange in this.complaints ) { details = this.complaints[ strange ]; $li1   = $( " " ); $span  = $( " " ); if ( $.inArray( strange, TDJPP.bad ) >=  0 ) { m++; $span.css( { "color":      "#FF0000",                            "font-weight": "bold" } ); }           $span.html( I18N.fair( "PP_" + strange,  true ) ); $li1.append( $span ); $ul2 = $( " " ); for ( subject in details ) { $li2 = $( " " ); n   = details[ subject ]; if ( n > 1 ) { $span = $( " " ); $span.css( { "margin-right": "2em" } ); $span.text( n + "&times;" ); $li2.append( $span ); }              $code = $( " " ); $code.text( subject ); $li2.append( $code ); $ul2.append( $li2 ); }  // for subject in strange $li1.append( $ul2 ); $ul1.append( $li1 ); }  // for strange in complaints if ( m ) { $div = $( " " ); $div.css( { "border":     "#FF0000 3px solid",                        "color":       "#FF0000",                        "font-weight": "bold",                        "padding":     "1em" } ); $div.text( I18N.fair( "PP_Lethal" + ( m > 1 ?  "s"  :  "" ), true ) ); $r.append( $div ); }        $r.append( $ul1 ); } else { $r = false; }     return $r; };  // TDJPP.$failures

TDJPP.fair = function ( adapt, about ) { // Escape and trim and quote string // Precondition: //   adapt  -- string //   about  -- string, kind of component // Postcondition: //   Returns string, with formatted JSON source string // Uses: //   this //   TDJPP.extension //   TDJPP.failed // 2015-01-22 PerfektesChaos@de.wikipedia var l, m, n, o;     if ( typeof TDJPP.extension[ about ]  ===  "object" ) { n = adapt.length; o = TDJPP.extension[ about ]; m = o[ 1 ]; if ( o[ 0 ] ) { l = ( n < m ); } else { l = ( n > m ); }        if ( l ) { this.failed( o[ 2 ], adapt ); }     }      return "\"" + adapt.replace( /^\s+/,    "" )                         .replace( /\s+$/,    "" )                         .replace( /\n/g,     "\\n" )                         .replace( / /g, "&#160;" )                         .replace( /\s+/g,    " " )                         .replace( /\"/g,     '\\"' ) + "\""; };  // TDJPP.fair

TDJPP.fence = function ( attribute, alert ) { // Analyze type attribute // Precondition: //   attribute  -- string, with found value //   alert      -- true, to issue complaints // Postcondition: //   Returns normalized string // Uses: //   TDJPP.failed // 2015-01-15 PerfektesChaos@de.wikipedia var r = attribute.replace( /^\s+/, "" ) .replace( /\s+$/, "" ) .toLowerCase, s = "|boolean|content|date|line|number|string" + "|unbalanced-wikitext|unknown" + "|wiki-file-name|wiki-page-name|wiki-user-name|"; if ( ! r.indexOf( "string/" ) ) { if ( alert ) { this.failed( "TypeDeprecated", r ); }        r = r.substr( 7 ); }     if ( s.indexOf( "|" + r + "|" )  <  0 ) { if ( alert ) { this.failed( "TypeUnknown", r ); }        r = "unknown"; }     return r;   };   // TDJPP.fence

TDJPP.fields = function ( apply, array, about ) { // Make sure that object contains no unexpected components // Precondition: //   apply   -- object to be examined //   array   -- Array, with strings of permitted names //   about   -- string, informative // Postcondition: //   Charges filed // Uses: //   TDJPP.failed //   $.inArray // 2015-01-11 PerfektesChaos@de.wikipedia var s;     for ( s in apply ) { if ( $.inArray( s, array ) <  0 ) { this.failed( "UnknownItem",                        s + " @ " + about ); }     }   // for s in array };  // TDJPP.fields

TDJPP.fill = function ( amount ) { // Number of spaces // Precondition: //   amount   -- number, with count of characters // Postcondition: //   Returns string, of requested length // 2014-12-27 PerfektesChaos@de.wikipedia var r = "", i;     for ( i = 0;  i < amount;  i++ ) { r = r + " "; }  // for i      return r;   };   // TDJPP.fill

TDJPP.flush = function { // CLenup, clear recent complaints // Postcondition: //   complaints cleared // Uses: //    < TDJPP.complaints // 2014-12-27 PerfektesChaos@de.wikipedia this.complaints = false; };  // TDJPP.flush

TDJPP.folder = function ( apply, adjust, align, ahead, about ) { // Pretty printing of TemplateData interface component // Precondition: //   apply   -- JSON interface text component //              string, or object, even null //   adjust  -- true: create at least empty string //   align   -- number of spaces to indent consecutive lines, //              or string, beginning with comma //   ahead   -- number of spaces to indent component //   about   -- string, kind of component // Postcondition: //   Returns string, with formatted JSON source code // Uses: //   this //   TDJPP.foreign //   TDJPP.fill //   TDJPP.fair // 2015-01-11 PerfektesChaos@de.wikipedia var i, poly, r, s;     switch ( typeof apply ) { case "object" : if ( apply ) { poly = this.foreign( apply, about ); switch ( typeof poly ) { case "object" : r = "{ "; s = ""; for ( i = 0; i < poly.length;  i++ ) { r = r + s + poly[ i ]; if ( ! s ) { if ( typeof align === "number" ) { s = ",\n" + this.fill( align ); } else { s = align; }                       }                     }   // for i                     r = r + " }"; break; case "string" : r = poly; break; }  // switch typeof poly }           break; case "string" : r = this.fair( apply, about ); break; }  // switch typeof apply if ( ! r ) { r = false; }     if ( ! r ) { if ( r === "" &&  adjust ) { r = '""'; } else { r = '"' + apply + '"'; }     }      if ( ahead ) { r = this.fill( ahead ) + r;     } return r;  };   // TDJPP.folder

TDJPP.foreign = function ( assigned, about ) { // Process language related text entry // Precondition: //   assigned  -- object with   { "lang": "v" } //   about     -- string, kind of component // Postcondition: //   Returns Array, with formatted strings   '"lang": "v"' //           or string "v" if only one entry and empty language // Uses: //   this //   >  TDJPP.otherLanguages //   TDJPP.failed //   $.inArray //   TDJPP.fair // 2015-01-23 PerfektesChaos@de.wikipedia var max = 0, r  = [ ], re1 = new RegExp( " +\n", "g" ), re2 = new RegExp( " +", "g" ), entry, i, n, slang, story, start; for ( slang in assigned ) { story = assigned[ slang ]; if ( typeof slang ===  "string" ) { slang = slang.replace( /^\s+/, "" ) .replace( /\s+$/, "" ) .toLowerCase; start = slang; if ( ! /^[a-z]{2,8}$/.test( slang )  &&                 ! /^[a-z]{2,3}-[a-z]{2,9}(?:-[a-z]+)$/.test( slang ) ) { this.failed( "LanguageCode", slang ); } else if ( /^[a-z]{4,8}$/.test( slang ) ) { if ( $.inArray( slang, this.otherLanguages ) <  0 ) { this.failed( "LanguageCode", slang ); }           }         } else { slang = "" + slang; this.failed( "LanguageCode", slang ); }        slang = this.fair( slang ); if ( typeof story ===  "string" ) { story = story.replace( /^\s+/, "" ) .replace( /\s+$/, "" ) .replace( /\t/g,  " " ) .replace( /\r\n/g, "\n" ) .replace( re1,    "\n" ) .replace( re2,    " " ); } else { story = "" + story; this.failed( "DescInvalid", slang ); }        n = slang.length; if ( n > max ) { max = n;        } story = this.fair( story, about ); r.push( [ n, slang, story ] ); }  // for slang in assigned for ( i = 0; i < r.length;  i++ ) { entry = r[ i ]; slang = entry[ 1 ] + ": "; for ( n = entry[ 0 ]; n < max;  n++ ) { slang = slang + " "; }  // for n         r[ i ] = slang + entry[ 2 ]; }  // for i      if ( r.length === 1  &&  start === "" ) { r = story; }     return r;   };   // TDJPP.foreign

TDJPP.further =  function ( adjust ) { // Adapt JSON source code to advanced wiki project // Precondition: //   adjust  -- string, with JSON source // 2018-08-24 PerfektesChaos@de.wikipedia return ""; };  // TDJPP.further

//---

TDtxt.fire = function { // Start TemplateData creation handling // Precondition: //   DOM.ready // Uses: //   >  TData.learn //   >  Sign //    < TDtxt.$textarea //    < TDtxt.$button //   TData.$fold //   TDtxt.fishing //   (TDtxt.finish) // Remark: Used as event handler -- 'this' is not TDtxt // 2015-01-20 PerfektesChaos@de.wikipedia var $div = TData.$fold, s;     TDtxt.$textarea = $( " " ); TDtxt.$textarea.attr( { rows: 10 } ); if ( TData.learn ) { s = TDtxt.fishing; if ( s ) { TDtxt.$textarea.val( s ); }     }      $div.append( TDtxt.$textarea ); TDtxt.$button = $( " " ); TDtxt.$button.attr( { "id": Sign + "-submit" } ); TDtxt.$button.click( TDtxt.finish ); TDtxt.$button.css( { "margin-bottom": "2em",                          "margin-top":    "5px",                           "text-align":    "center" } ); TDtxt.$button.text( I18N.fair( "btn_Submit", true, "Submit" ) ); $div.append( TDtxt.$button ); };  // TDtxt.fire

TDtxt.finish = function { // Submit text input // Uses: //   >  TDtxt.$textarea //   >  TDtxt.$button //    < TData.$throbber //   TDtxt.fishing //   TDJPP.facility //   Hilite.fair //   (TData.finish) // Remark: Used as event handler -- 'this' is not TDtxt // 2015-01-21 PerfektesChaos@de.wikipedia var s = TDtxt.$textarea.val, o = { params: { }  }, p = o.params, g, i, re; TData.$throbber = $( " " ); TData.$throbber.css( { "margin-left": "1em",                             "margin-right": "1em" } ); TDtxt.$button.after( TData.$throbber ); Hilite.flow( TData.$throbber ); TDtxt.$button.attr( { disabled: true } ); TDtxt.$textarea.attr( { disabled: true } ); re = "}"; re = new RegExp( re ); if ( re.test( s ) ) { s = TDtxt.fishing; } else { re = "\\{\\{[^}]*\\}\\}"; re = new RegExp( re, "g" ); s = s.replace( re, "" ); }     s = s.replace( /\|/g, "\n" ); g = s.split( "\n" ); for ( i = 0; i < g.length;  i++ ) { s = g[ i ]; s = s.replace( /^\s+/, "" ) .replace( /=.*$/, "" ) .replace( /\s+$/, "" ); if ( s ) { p[ s ] = { }; }     }   // for i      Hilite.fair( TDJPP.facility( o, 3 ),                   "javascript",                   TData.finish,                   false ); };  // TDtxt.finish

TDtxt.fishing = function { // Guess list of parameters from textarea // Precondition: //   mediawiki.api loaded // Postcondition: //   Returns Array, with parameter names, or false // Uses: //   this //   >  TData.learn //   TDtxt.field //   $.inArray // 2015-01-20 PerfektesChaos@de.wikipedia var $ta = TData.$field, r  = false, got, i, k, re, s, story; if ( $ta ) { story = $ta.val; i    = story.indexOf( "" ); if ( i >= 0 &&   k > i ) { story = story.substr( 0, k + 3 ) .substr( i ); do { i = story.lastIndexOf( "{{{" ); if ( i >= 0 ) { k = story.indexOf( "}}}", i ); if ( k < 0 ) { story = story.substr( 0, i ); } else { s    = story.substring( i + 3,  k ); story = story.substr( 0, i ) + story.substr( k + 3 ); k    = s.indexOf( "|" ); if ( k >= 0 ) { s = s.substr( 0, k ); }                    s = s.replace( /^\s+/, "" ) .replace( /\s+$/, "" ); if ( s ) { if ( ! re ) { re = "\\{\\{[^}]*\\}\\}"; re = new RegExp( re, "g" ); }                       s  = s.replace( re, "" ); }                    if ( s ) { if ( got ) { if ( $.inArray( s, got ) < 0 ) { got.push( s ); }                       } else { got = [ s ]; }                    }                  }               }            } while ( i >= 0 ); if ( got ) { got.sort; r = ""; for ( i = 0; i < got.length;  i++ ) { r = r + "|" + got[ i ] + "=\n"; }  // for i            } }     }      return r;   };   // TDtxt.fishing

//---

function fire { // Initialize if appropriate // Precondition: //   mediawiki.util loaded // Uses: //    < Env //   mw.config.get //   mw.util.getParamValue //   Hilite.fire //   Editor.fire //   mw.loader.using //   (TData.fire) // 2015-01-11 PerfektesChaos@de.wikipedia Env =  mw.config.get( [ "wgAction",                               "wgNamespaceNumber",                               "wgTitle" ] ); if ( Env.wgNamespaceNumber === 10 ) { Env.oldid = mw.util.getParamValue( "oldid" ); if ( ! Env.oldid ) { if ( Env.wgTitle.search( /\/XML$/ ) >  0 ) { switch ( Env.wgAction ) { case "view" : Env.diff = mw.util.getParamValue( "diff" ); if ( ! Env.diff ) { $( Hilite.fire ); }                    break; case "edit" : case "submit" : Editor.fire; break; }  // switch wgAction }           mw.loader.using( [ "mediawiki.api" ],                             TData.fire ); }     }   }   // fire

function first { // Autorun on load // Uses: //   >  Sign //   mw.loader.getState //   mw.loader.state //   mw.loader.using //   (fire) // 2018-08-24 PerfektesChaos@de.wikipedia var signature = "user.PerfektesChaos." + Sign, rls; if ( mw.loader.getState( signature ) !==  "ready" ) { rls = { }; rls[ signature ] = "ready"; mw.loader.state( rls ); mw.loader.using( [ "mediawiki.util",                           "user" ],                          fire ); }  }   // first

first; }( window.mediaWiki, window.jQuery ) ); /// EOF  jsonXMLutils.js