/// jsonXMLutils.js
// Help on pages with JSON or XML code
/// 2018-08-26 [email protected]
// ResourceLoader: compatible;
// dependencies: user, mediawiki.util
// Documentation: [[w:en:User:PerfektesChaos/js/jsonXMLutils]]
/// Fingerprint: #0#0#
/// <nowiki>
/*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 [email protected]
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 [email protected]
var s = Env.wgTitle.replace( /\/.*$/, "" );
return '<?mediawiki "{{XML-Warnung|' + s + '}}"?>\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 [email protected]
var s = Env.wgTitle.replace( /\/.*$/, "" );
return '<?mediawiki "{{XML|' + s + '}}"?>\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: "<code>label</code>"
+ " 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 <code>params</code>"
+ " nicht gefunden" },
PP_ParamDup: { en: "ERROR: Duplicated parameter name",
de: "FEHLER: Doppelter Parametername" },
PP_PipeSymbol: { en: "STRANGE!"
+ " Pipe symbol <code>|</code>"
+ " in parameter name."
+ " This will not work on transclusion.",
de: "WIRR!"
+ " Pipe-Symbol <code>|</code>"
+ " im Parameternamen."
+ " Das wird bei der Einbindung"
+ " nicht funktionieren." },
PP_QuotMark: { en: "STRANGE!"
+ " Quotation mark <code>\"</code>"
+ " in parameter name.",
de: "WIRR!"
+ " Begrenzer <code>\"</code>"
+ " 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 <code>string/</code>",
de: "VERALTET (Parameter <code>type</code>):"
+ " vorangestelltes"
+ " <code>string/</code> entfernen" },
PP_TypeUnknown: { en: "WARNING: Parameter 'type'"
+ " value not recognized",
de: "WARNUNG: Parameter <code>type</code> *"
+ " Wert nicht erkannt" },
PP_UnknownItem: { en: "WARNING: Could not recognize",
de: "WARNUNG: Komponente nicht erkannt" }
}; // 2015-01-11 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
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( "<pre>" + adjust + "</pre>" );
}
},
source = "<syntaxhighlight lang='" + assign + "'"
+ " id='" + Sign + "-hilite-" + assign + "'>"
+ adjust + "</syntaxhighlight>";
if ( failed === false ) {
failed = function () { };
} else if ( typeof failed !== "function" ) {
failed = function () { after( "<pre>" + adjust + "</pre>" ); };
}
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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
var $img;
if ( ! $around.children().length ) {
$img = $( "<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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
var p, params, s, sign, story;
if ( TData.templateData ) {
s = ' <TemplateUsage output="collapse">\n'
+ ' <Group>\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 + ' <Parameter name="' + sign + '"';
p = params[ sign ];
story = TData.feature( p, "label" );
if ( story ) {
s = s + ' label="'
+ story.replace( /</g, "<" )
.replace( />/g, ">" )
+ '"';
}
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 + ' <Help>'
+ story.replace( /</g, "<" )
.replace( />/g, ">" )
+ '</Help>\n';
}
if ( typeof p[ "default" ] === "string" ) {
story = p[ "default" ].replace( /^\s+/, "" )
.replace( /\s+$/, "" );
if ( story ) {
s = s + ' <Default>'
+ story.replace( /</g, "<" )
+ '</Default>\n';
}
}
if ( typeof p.autovalue === "string" ) {
story = p.autovalue.replace( /^\s+/, "" )
.replace( /\s+$/, "" );
if ( story ) {
s = s + ' <Autovalue>'
+ story.replace( /</g, "<" )
+ '</Autovalue>\n';
}
}
s = s + ' </Parameter>\n';
}
} // for in .params
}
s = s
+ ' </Group>\n'
+ ' </TemplateUsage>';
if ( ! Env.wgDBname ) {
Env.wgDBname = mw.config.get( "wgDBname" );
}
if ( typeof TData[ Env.wgDBname ] === "function" ) {
s = TData[ Env.wgDBname ]( "2xml", s );
}
s = '<?xml version="1.0" encoding="utf-8"?>\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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
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 = "<strong style='color:#FF0000'>"
+ "ERROR in JSON"
+ "</strong>";
}
}
}
}
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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
if ( typeof this.$div === "object" ) {
this.$div.empty();
} else {
this.$div = $( "<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 [email protected]
var $r = $( "<button />" );
$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 [email protected]
var $div = $( "<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 = $( "<span>" );
$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 [email protected]
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 [email protected]
}
this.fields( apply,
[ "description", "params", "sets",
"maps", "format", "paramOrder", "title" ],
"<templatedata>" );
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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
var m = 0,
details, n, strange, subject,
$code, $div, $h2, $li1, $li2, $span, $ul1, $ul2, $r;
if ( typeof this.complaints === "object" ) {
$r = $( "<div />" );
$r.attr( { "id": Sign + "-JSON-report" } );
$h2 = $( "<h2 />" );
$h2.text( I18N.fair( "PP_H2", true ) );
$r.append( $h2 );
$ul1 = $( "<ul />" );
for ( strange in this.complaints ) {
details = this.complaints[ strange ];
$li1 = $( "<li />" );
$span = $( "<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 = $( "<ul />" );
for ( subject in details ) {
$li2 = $( "<li />" );
n = details[ subject ];
if ( n > 1 ) {
$span = $( "<span />" );
$span.css( { "margin-right": "2em" } );
$span.text( n + "×" );
$li2.append( $span );
}
$code = $( "<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 />" );
$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 [email protected]
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, " " )
.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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
return "{{TemplateData|JSON=\n"
+ adjust + "\n}}";
}; // 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 [email protected]
var $div = TData.$fold(),
s;
TDtxt.$textarea = $( "<textarea>" );
TDtxt.$textarea.attr( { rows: 10 } );
if ( TData.learn ) {
s = TDtxt.fishing();
if ( s ) {
TDtxt.$textarea.val( s );
}
}
$div.append( TDtxt.$textarea );
TDtxt.$button = $( "<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 [email protected]
var s = TDtxt.$textarea.val(),
o = { params: { } },
p = o.params,
g, i, re;
TData.$throbber = $( "<span>" );
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 [email protected]
var $ta = TData.$field(),
r = false,
got, i, k, re, s, story;
if ( $ta ) {
story = $ta.val();
i = story.indexOf( "{{{" );
k = story.lastIndexOf( "}}}" );
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 [email protected]
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 [email protected]
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 </nowiki> jsonXMLutils.js