/// User:PerfektesChaos/js/preferencesGadgetOptions/d.js
/// 2021-10-08 [email protected]
// Preferences utilities, gadget options and configuration form
// ResourceLoader: compatible;
// dependencies: user.options, mediawiki.user, mediawiki.util
/// Fingerprint: #0#0#
/// @license GPL [//www.mediawiki.org/w/COPYING] (+GFDL, LGPL, CC-BY-SA)
/// <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 = -2.1,
Signature = "preferencesGadgetOptions",
PREGO = { signature: "ext.gadget." + Signature,
special: "Blankpage",
type: Signature,
vsn: Version,
api: { },
cache: { },
date: { },
dialog: { },
hook: { },
lang: { },
option: { },
page: { } };
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*/
// Requires: JavaScript 1.3 (String.charCodeAt String.replace)
// MediaWiki 1.26 (mw.storage, mw.libs, jQuery core)
function fire() {
// Environment initialized
// Precondition:
// user.options and basic resources have been loaded
// Postcondition:
// Ready to be used
// Uses:
// > .type
// < .doc
// < .lang.user
// < .local
// mw.user.isAnon()
// mw.loader.using()
// .hook.fire()
// .finalize()
// (.cache.first)
// Remark: Used as event handler -- 'this' is not PREGO
// 2018-05-02 [email protected]
PREGO.doc = "[[w:en:User:PerfektesChaos/js/" + PREGO.type
+ "]]";
PREGO.lang.user = { "als" : [ "de", "fr" ],
"bar" : [ "de" ],
"br" : [ "fr" ],
"cel" : [ "fr" ],
"dsb" : [ "hsb", "de" ],
"fro" : [ "fr" ],
"frp" : [ "fr" ],
"frr" : [ "de", "nl" ],
"fur" : [ "it" ],
"fy" : [ "nl" ],
"gsw" : [ "de" ],
"hsb" : [ "dsb", "de" ],
"ksh" : [ "de" ],
"lb" : [ "de" ],
"li" : [ "nl" ],
"lij" : [ "it" ],
"lld" : [ "it" ],
"lmo" : [ "it" ],
"nap" : [ "it" ],
"nds" : [ "de", "nl" ],
"nn" : [ "no", "da", "sv" ],
"no" : [ "nn", "da", "sv" ],
"oc" : [ "fr" ],
"pdc" : [ "de" ],
"pdt" : [ "de" ],
"pfl" : [ "de" ],
"pms" : [ "it" ],
"sc" : [ "it" ],
"sli" : [ "de" ],
"stq" : [ "de" ],
"vec" : [ "it" ],
"vls" : [ "nl" ],
"vmf" : [ "de" ],
"wa" : [ "fr" ]
//"simple": Universal fallback "en"
}; // 2017-11-11 [email protected]
PREGO.local = mw.user.isAnon();
if ( PREGO.local ) {
mw.loader.using( [ "mediawiki.storage" ],
PREGO.cache.first );
} else {
PREGO.finalize();
}
PREGO.hook.fire();
} // fire()
function first() {
// Autorun
// Uses:
// > .signature
// > .type
// > mw.libs
// >< PREGO
// mw.loader.getState()
// mw.loader.state()
// mw.loader.using()
// 2018-08-24 [email protected]
var launch, prev, rls;
if ( mw.loader.getState( PREGO.signature ) !== "ready" ) {
rls = { };
rls[ PREGO.signature ] = "ready";
mw.loader.state( rls );
if ( typeof mw.libs[ PREGO.type ] !== "object" ||
! mw.libs[ PREGO.type ] ) {
mw.libs[ PREGO.type ] = PREGO;
launch = true;
} else {
prev = mw.libs[ PREGO.type ];
launch = ( typeof prev.vsn === "undefined" );
if ( launch ) {
$.extend( prev, PREGO );
PREGO = prev;
}
}
if ( launch ) {
mw.loader.using( [ "user",
"user.options",
"mediawiki.user" ],
fire );
}
}
} // first()
PREGO.api.failed = function ( about, add, aborted ) {
// API attempt failed
// Precondition:
// about -- reason
// add -- object with details
// aborted -- callback error function (optional), or false
// Postcondition:
// message is displayed
// Uses:
// mw.hook()
// (.api.flop)
// Remark: Used as event handler -- 'this' is not PREGO.api
// 2013-12-19 [email protected]
var s = "API error";
if ( about ) {
s = s + "\n\n" + about;
}
if ( add ) {
if ( add.error ) {
if ( add.error.info ) {
s = s + ":\n" + add.error.info;
}
}
}
s = s + "\n\n* Login session might have been expired.";
if ( typeof aborted === "function" ) {
aborted.call( PREGO, s );
}
mw.hook( "wikipage.content" ).add( function () {
PREGO.api.flop( s );
} );
}; // .api.failed()
PREGO.api.fiat = function ( api, apply ) {
// Store one element in queue as preference
// Postcondition:
// api -- mw.Api object
// apply -- request details
// [0] preference (without "userjs-")
// [1] value
// [2] callback function (optional)
// [3] error function (optional)
// [4] jQuery object of option/gadget
// mw.user.tokens.get()
// (.api.follow)
// (.api.failed)
// 2021-10-08 [email protected]
var pars = { "action": "options",
"token": mw.user.tokens.get( "csrfToken" ),
"optionname": apply[ 0 ] };
if ( apply[ 1 ] !== null ) {
pars.optionvalue = apply[ 1 ];
}
api.post( pars )
.done( function ( d, t, j ) {
PREGO.api.follow( true,
apply[ 4 ] );
if ( apply[ 2 ] ) {
apply[ 2 ].call( null, d, t, j );
}
} )
.fail( function ( d, t, j ) {
PREGO.api.failed( d );
PREGO.api.follow( false,
apply[ 4 ] );
if ( apply[ 3 ] ) {
apply[ 3 ].call( null, d, t, j );
}
} );
}; // .api.fiat()
PREGO.api.fire = function ( assign, apply, any, after, aborted, at ) {
// Initiate storing an option value on server
// Precondition:
// assign -- string with option/gadget identification
// apply -- string value, or null for deletion
// any -- assign is mediawiki option name, or false
// after -- callback function (optional), or false
// aborted -- error function (optional), or false
// at -- issued by gadget dialog form
// Postcondition:
// Returns false if valid, else error message on parameter fault
// Uses:
// this
// > .page.$throbber
// > mw.util.$content
// >< .api.queue
// .page.fragment()
// .page.factory()
// mw.loader.using()
// (.api.forward)
// 2021-10-08 [email protected]
var $api = false,
r, s, task;
if ( typeof assign === "string" ) {
if ( /[^a-zA-Z0-9_-]/.test( assign ) ) {
r = "invalid character in key 'assign'";
} else if ( apply === null
|| typeof apply === "string" ) {
r = false;
} else {
r = "invalid type for value 'apply'";
}
} else {
r = "key 'assign' not a string";
}
if ( ! r ) {
if ( at ) {
s = "#" + PREGO.page.fragment( assign );
$api = mw.util.$content.find( s );
if ( $api.length ) {
$api.empty();
if ( ! PREGO.page.$throbber ) {
PREGO.page.factory( "$throbber" );
}
$api.append( PREGO.page.$throbber.clone() );
}
}
task = [ ( any ? assign : "userjs-" + assign ),
apply,
false,
false,
$api ];
if ( typeof after === "function" ) {
task[ 2 ] = after;
}
if ( typeof aborted === "function" ) {
task[ 3 ] = aborted;
}
if ( this.queue ) {
this.queue.push( task );
} else {
this.queue = [ task ];
}
mw.loader.using( [ "mediawiki.api" ],
this.forward );
}
return r;
}; // .api.fire()
PREGO.api.fix = function ( arrived, assign, advanced, after, assume ) {
// Update mw object and notify user by callback
// Precondition:
// arrived -- JSON result of ajax query
// assign -- string with option identification
// advanced -- assign is mediawiki option name, or false
// 0 -- mediawiki option
// 1 -- userjs single value
// 2 -- Gadgets
// after -- callback function (optional)
// assume -- fallback value, if undefined or failure
// Uses:
// mw.user.options.set()
// .get()
// .fetch()
// Remark: Used as event handler -- 'this' is not PREGO.api
// 2013-09-19 [email protected]
var q = arrived.query,
s;
if ( q ) {
q = q.userinfo;
if ( q ) {
q = q.options;
if ( q ) {
s = ( advanced ? "userjs-" + assign : assign );
q = q[ s ];
mw.user.options.set( s, q );
if ( typeof after === "function" ) {
switch ( advanced ) {
case 1:
q = PREGO.get( assign, assume );
break;
case 2:
q = PREGO.fetch( assign, assume );
break;
} // switch advanced
after.call( PREGO, q );
}
}
}
}
}; // .api.fix()
PREGO.api.flop = function ( about ) {
// Display error message
// about -- message
// Uses:
// > .type
// > mw.util.$content
// Remark: Used as event handler -- 'this' is not PREGO.api
// 2013-12-29 [email protected]
var $div = $( "<div>" ),
$span = $( "<span>" );
$div.attr( "class", "error" );
$span.text( "<span>" + PREGO.type + "<br />" + about + "</span>" );
$div.append( $span );
mw.util.$content.prepend( $div );
}; // .api.flop()
PREGO.api.follow = function ( achieved, $apply ) {
// Confirm success
// Precondition:
// achieved -- true: success
// $apply -- container for icons
// 2015-09-25 [email protected]
var src;
if ( $apply && $apply.length ) {
src = ( achieved ? "$stored" : "$denied" );
$apply.empty();
if ( ! PREGO.page[ src ] ) {
PREGO.page.factory( src );
}
$apply.append( PREGO.page[ src ].clone() );
}
}; // .api.follow()
PREGO.api.forward = function () {
// Store all elements in queue as preferences
// Uses:
// > mw.Api
// >< .api.queue
// [0] preference (without "userjs-")
// [1] value
// [2] callback function (optional)
// [3] error function (optional)
// .api.fiat()
// Remark: Used as event handler -- 'this' is not PREGO.api
// 2021-10-08 [email protected]
var i, n, request;
if ( PREGO.api.queue ) {
n = PREGO.api.queue.length;
if ( n > 0 ) {
request = new mw.Api();
for ( i = 0; i < n; i++ ) {
PREGO.api.fiat( request, PREGO.api.queue[ i ] );
} // for i
}
PREGO.api.queue = false;
}
}; // .api.forward()
PREGO.api.fresh = function ( assign, advanced, assume, after, aborted ) {
// Retrieve current option value and update mw object
// Precondition:
// assign -- string with option identification
// advanced -- assign is mediawiki option name, or false
// 0 -- mediawiki option
// 1 -- userjs single value
// 2 -- Gadgets
// assume -- fallback value, if undefined or failure
// after -- callback function, or else
// aborted -- error callback function (optional), or false
// Uses:
// > mw.Api
// (.api.freshed)
// (.api.failed)
// 2013-09-21 [email protected]
var q = new mw.Api();
q.get( { "action": "query",
"meta": "userinfo",
"uiprop": "options" } )
.done( function ( arrived ) {
PREGO.api.fix( arrived, assign, advanced, after, assume );
} )
.fail( function ( about, add ) {
PREGO.api.failed( about, add, aborted );
} );
}; // .api.fresh()
PREGO.cache.first = function () {
// Initialize anonymous localStorage
// Precondition:
// mediawiki.storage is available
// Postcondition:
// Uses:
// > .type
// < .cache.data
// mw.storage.get{}
// JSON.parse()
// mw.user.options.set()
// .finalize()
// Remark: Used as event handler -- 'this' is not PREGO.cache
// 2016-10-11 [email protected]
var s = mw.storage.get( PREGO.type );
if ( s ) {
try {
PREGO.cache.data = JSON.parse( s );
} catch(e) {
// why ever * corrupted by anyone
PREGO.cache.data = false;
}
if ( typeof PREGO.cache.data === "object"
&& PREGO.cache.data ) {
if ( typeof PREGO.cache.data.userjs === "object"
&& PREGO.cache.data.userjs ) {
for ( s in PREGO.cache.data.userjs ) {
mw.user.options.set( "userjs-" + s,
PREGO.cache.data.userjs[ s ] );
} // for s in userjs
} else {
PREGO.cache.data.userjs = false;
}
// other components and preferences might follow
} else {
PREGO.cache.data = { };
}
}
PREGO.finalize();
}; // .cache.first()
PREGO.cache.fill = function ( assign, apply ) {
// Store user option with localStorage
// Precondition:
// assign -- string with option/gadget identification
// apply -- JSONified value
// Postcondition:
// Returns boolean on success
// Uses:
// this
// > .cache.data
// > .type
// > mw.util.$content
// JSON.stringify()
// mw.storage.set()
// .page.fragment()
// .api.follow()
// 2015-09-25 [email protected]
var r = this.data,
s;
if ( r ) {
if ( typeof this.data.userjs !== "object"
|| ! this.data.userjs ) {
this.data.userjs = { };
}
this.data.userjs[ assign ] = apply;
r = mw.storage.set( PREGO.type,
JSON.stringify( this.data ) );
s = "#" + PREGO.page.fragment( assign );
PREGO.api.follow( r, mw.util.$content.find( s ) );
}
return r;
}; // .cache.fill()
PREGO.cache.free = function ( assign ) {
// Store user option with localStorage
// Precondition:
// assign -- string with option/gadget identification
// apply -- JSONified value
// Postcondition:
// Returns boolean on success
// Uses:
// this
// > .cache.data
// > .type
// JSON.stringify()
// mw.storage.set()
// 2015-09-12 [email protected]
var r = this.data;
if ( r ) {
if ( typeof r.userjs === "object" &&
typeof r.userjs[ assign ] !== "undefined" ) {
delete this.data.userjs.assign;
r = mw.storage.set( PREGO.type,
JSON.stringify( this.data ) );
} else {
r = true;
}
} else {
r = false;
}
return r;
}; // .cache.free()
PREGO.date.format8601 = function ( age ) {
// Format Date object according to ISO8601
// Precondition:
// age -- Date object (since 1970)
// Postcondition:
// Returns string (human readable format)
// 2013-09-16 [email protected]
var jY = age.getUTCFullYear(),
jM = age.getUTCMonth() + 1,
jD = age.getUTCDate(),
kH = age.getUTCHours(),
kM = age.getUTCMinutes(),
kS = age.getUTCSeconds(),
kX = age.getUTCMilliseconds();
if ( jM < 10 ) {
jM = "0" + jM;
}
if ( jD < 10 ) {
jD = "0" + jD;
}
if ( kH < 10 ) {
kH = "0" + kH;
}
if ( kM < 10 ) {
kM = "0" + kM;
}
if ( kS < 10 ) {
kS = "0" + kS;
}
if ( kX < 100 ) {
if ( kX < 10 ) {
kX = "00" + kX;
} else {
kX = "0" + kX;
}
}
return jY + "-" + jM + "-" + jD
+ " "
+ kH + ":" + kM + ":" + kS + "."+ kX
+ "Z";
}; // .date.format8601()
PREGO.date.from8601 = function ( age ) {
// Retrieve Date object from ISO8601 string (human readable format)
// Precondition:
// age -- string (since 1970)
// Postcondition:
// Returns Date object
// 2013-09-28 [email protected]
return new Date( parseInt( age.substr( 0, 4 ), 10 ),
parseInt( age.substr( 5, 2 ), 10 ) - 1,
parseInt( age.substr( 8, 2 ), 10 ),
parseInt( age.substr( 11, 2 ), 10 ),
parseInt( age.substr( 14, 2 ), 10 ),
parseInt( age.substr( 17, 2 ), 10 ),
parseInt( age.substr( 20, 3 ), 10 ) );
}; // .date.from8601()
PREGO.dialog.factory = function ( about ) {
// Create form
// Precondition:
// about -- object with gadget description
// > .$item
// > .opts
// > .script
// > .fiat
// < .selector
// < .$pop
// document.ready
// Uses:
// > .page.$optsForm
// > .page.$btnClose
// > .page.$btnSubmit
// > .page.ltr
// .page.factory()
// .option.factory()
// .page.fragment()
// .page.feature()
// (.dialog.forward)
// 2019-02-13 [email protected]
var i, n, $e;
if ( typeof about.opts === "object" && about.opts ) {
n = about.opts.length;
if ( n ) {
about.selector = PREGO.type + "-form_" + about.script;
if ( ! PREGO.page.$optsForm ) {
PREGO.page.factory( "$optsForm" );
}
about.$pop = PREGO.page.$optsForm.clone();
about.$pop.attr( "id", about.selector );
if ( ! PREGO.page.$btnClose ) {
PREGO.page.factory( "$btnClose" );
}
$e = PREGO.page.$btnClose.clone();
$e.click( function () { PREGO.dialog.flat( about );
} );
about.$pop.append( $e );
for ( i = 0; i < n; i++ ) {
PREGO.option.factory( about.selector,
about.opts[ i ],
about.$pop );
} // for i
if ( ! PREGO.page.$btnSubmit ) {
PREGO.page.factory( "$btnSubmit" );
}
about.$submit = PREGO.page.$btnSubmit.clone();
about.$submit.click( function () {
PREGO.dialog.forward( about );
} );
$e = $( "<div>");
$e.append( about.$submit );
about.$pop.append( $e );
$e = $( "<span>" );
$e.attr( { "class": PREGO.page.fragment(),
"id": PREGO.page.fragment( about.script )
} );
if ( PREGO.page.ltr ) {
$e.css( "margin-left", "2em" );
about.$submit.after( $e );
} else {
$e.css( "margin-right", "2em" );
about.$submit.before( $e );
}
if ( typeof about.fiat === "function" ) {
about.fiat.call( about, about.$submit );
}
} else {
$e = $( "<div>");
$e.attr( "class", "error" );
$e.text( "empty .opts in config" );
about.$pop.append( $e );
}
}
about.$item.append( about.$pop );
}; // .dialog.factory()
PREGO.dialog.fetch = function ( about ) {
// Retrieve object with all current values in form
// Precondition:
// about -- object with gadget description
// Postcondition:
// Returns all current values as of user.options.userjs
// Uses:
// .option.fetch()
// 2014-02-20 [email protected]
var i, n, o, v, r;
if ( about.opts ) {
r = { };
n = about.opts.length;
for ( i = 0; i < n; i++ ) {
o = about.opts[ i ];
v = undefined;
switch ( o.type ) {
case "checkbox" :
v = o.$checkbox.prop( "checked" );
break;
case "radio" :
case "multi" :
case "select" :
v = PREGO.option.fetch( o );
break;
case "text" :
v = $.trim( o.$text.val() );
break;
} // switch .type
if ( v !== undefined ) {
r[ o.signature ] = v;
}
} // for i
} else {
r = null;
}
return r;
}; // .dialog.fetch()
PREGO.dialog.fired = function ( about ) {
// Expand form, create if not yet built
// Precondition:
// about -- object with gadget spec
// Uses:
// .dialog.fresh()
// .dialog.factory()
// 2019-02-13 [email protected]
if ( about.opts && typeof about.opts === "object" ) {
PREGO.dialog.fresh( about );
}
if ( about.$pop ) {
about.$pop.css( "display", "block" );
} else {
PREGO.dialog.factory( about );
}
about.$button.css( "display", "none" );
}; // .dialog.fired()
PREGO.dialog.flat = function ( about ) {
// Hide form
// Precondition:
// about -- object with gadget spec
// Uses:
// .page.fragment()
// 2019-02-13 [email protected]
about.$pop.css( "display", "none" );
about.$button.css( "display", "inline" );
about.$pop.find( "." + PREGO.page.fragment() ).empty();
}; // .dialog.flat()
PREGO.dialog.forward = function ( about ) {
// Perform storage; request API start
// Precondition:
// about -- object with gadget spec
// Uses:
// .dialog.fetch()
// .forward()
// 2019-02-13 [email protected]
var failure, fed, values;
values = PREGO.dialog.fetch( about );
if ( values ) {
if ( typeof about.fed === "function" ) {
fed = about.fed;
} else {
fed = false;
}
if ( typeof about.failure === "function" ) {
failure = about.failure;
} else {
failure = false;
}
PREGO.forward( about.script, values, fed, failure );
if ( typeof about.filled === "function" ) {
about.filled.call( about, values );
}
}
}; // .dialog.forward()
PREGO.dialog.fresh = function ( about ) {
// Preset all option values from user.options
// Precondition:
// about -- object with gadget description
// Uses:
// .fetch()
// 2014-02-20 [email protected]
var userjs = PREGO.fetch( about.script ),
i, k, n, o, p, v;
if ( userjs ) {
n = about.opts.length;
for ( i = 0; i < n; i++ ) {
o = about.opts[ i ];
v = userjs[ o.signature ];
if ( v !== undefined ) {
switch ( o.type ) {
case "checkbox" :
case "radio" :
case "text" :
o.val = v;
break;
case "multi" :
if ( typeof o.poly === "object" && o.poly &&
typeof v === "object" && v ) {
for ( k = 0; k < p.length; k++ ) {
p[ k ].val = v[ k ];
} // for k
}
break;
} // switch .type
}
} // for i
}
}; // .dialog.fresh()
PREGO.dialog.further = function ( about ) {
// Equip item with control for options
// Precondition:
// about -- object with gadget description
// > .$item
// > .opts
// > .script
// >< .$button
// Postcondition:
// about.$button has been set and added
// Uses:
// > .page.$btnOpts
// > .type
// > window.location.hash
// .page.factory()
// .dialog.fired()
// 2019-02-13 [email protected]
if ( about.$item && about.opts && ! about.$button ) {
if ( ! PREGO.page.$btnOpts ) {
PREGO.page.factory( "$btnOpts" );
}
about.$button = PREGO.page.$btnOpts.clone();
about.$button.attr( "id",
PREGO.type + "-opt_" + about.script );
about.$button.click( function () {
PREGO.dialog.fired( about );
} );
if ( window.location.hash === "#" + about.script ) {
window.location.hash = "";
this.fired( about );
}
about.$item.append( about.$button );
}
}; // .dialog.further()
PREGO.hook.fetch = function ( assigned, action, assume ) {
// Request for a "Gadgets" object stored by .form() or .forward()
// Precondition:
// assigned -- string with gadget identification
// action -- callback function
// assume -- fallback value object, if undefined or failure
// Postcondition:
// Fires object, could be null
// Uses:
// PREGO.fetch()
// 2018-05-02 [email protected]
if ( typeof action === "function" ) {
action( PREGO.fetch( assigned, assume ) );
}
}; // .hook.fetch()
PREGO.hook.fire = function () {
// Start hook listeners
// Uses:
// > .type
// mw.hook()
// (.hook.fetch)
// (.form)
// (.forward)
// (.hook.$button)
// 2018-05-02 [email protected]
mw.hook( PREGO.type + ".fetch" ).add( PREGO.hook.fetch );
mw.hook( PREGO.type + ".form" ).add( PREGO.form );
mw.hook( PREGO.type + ".forward" ).add( PREGO.forward );
mw.hook( PREGO.type + ".$button" ).add( PREGO.hook.$button );
}; // .hook.fire()
PREGO.hook.$button = function ( action, assign ) {
// Request for a [options button] design
// Precondition:
// action -- callback function
// assign -- optional string with gadget name
// Postcondition:
// Fires jQuery object
// Uses:
// PREGO.$button()
// 2018-05-02 [email protected]
if ( typeof action === "function" ) {
action( PREGO.$button( assign ) );
}
}; // .hook.$button()
PREGO.lang.factory = function () {
// Create translation sequence, if not yet available
// Uses:
// this
// > .lang.user
// >< .lang.polyglott
// < .lang.multi
// mw.config.get()
// jQuery.inArray()
// 2014-02-20 [email protected]
var i, s, u;
if ( typeof this.polyglott !== "object" ) {
s = mw.config.get( "wgUserLanguage" ).toLowerCase();
this.polyglott = [ s ];
if ( s.length > 4 ) { // Remove RFC 1766 subtag from code
if ( s.charCodeAt( 2 ) === 45 ) { // '-'
this.polyglott.push( s.substr( 0, 2 ) );
}
}
if ( typeof this.user[ s ] === "object" ) {
u = this.user[ s ];
for ( i = 0; i < u.length; i++ ) {
s = u[ i ];
if ( $.inArray( s, this.polyglott ) < 0 ) {
this.polyglott.push( s );
}
} // for i
}
if ( $.inArray( "en", this.polyglott ) < 0 ) {
this.polyglott.push( "en" );
}
this.multi = this.polyglott.length;
}
}; // .lang.factory()
PREGO.lang.fetch = function ( apply ) {
// Retrieve string from definition, may be translated
// Precondition:
// apply -- string or object
// Postcondition:
// Returns string
// Uses:
// this
// > .lang.multi
// > .lang.polyglott
// .lang.factory()
// 2014-02-20 [email protected]
var r = "??????????????",
i, s;
switch ( typeof apply ) {
case "string" :
r = apply;
break;
case "object" :
if ( apply ) {
this.factory();
for ( i = 0; i < this.multi; i++ ) {
s = this.polyglott[ i ];
if ( typeof apply[ s ] === "string" ) {
r = apply[ s ];
break; // for i
}
} // for i
}
break;
case "undefined" :
break;
default :
r = apply + "";
} // switch typeof apply
return r;
}; // .lang.fetch()
PREGO.option.factory = function ( assigned, access, $append ) {
// Create one option entry in form
// Precondition:
// assigned -- string with gadget selector
// access -- object with option description
// $append -- jQuery element to append to
// Uses:
// this
// .option.flag()
// .option.faculty()
// .option.flipper()
// .option.field()
// 2014-02-20 [email protected]
var $div, $opt;
if ( access.signature ) {
access.selector = assigned + "_" + access.signature;
$opt = $( "<div>" );
$opt.attr( "id", access.selector );
switch ( access.type ) {
case "html" :
$opt.append( $( access.source ) );
break;
case "checkbox" :
this.flag( access, $opt );
break;
case "radio" :
case "multi" :
this.faculty( access, $opt );
break;
case "select" :
this.flipper( access, $opt );
break;
case "text" :
this.field( access, $opt );
break;
default :
$div = $( "<div>" );
$div.attr( "class", "error" );
$div.text( "Invalid type: " + access.type );
$opt.append( $div );
} // switch .type
$append.append( $opt );
} else {
$div = $( "<div>" );
$div.attr( "class", "error" );
$div.text( "Invalid ID" );
$append.append( $div );
}
}; // .option.factory()
PREGO.option.faculty = function ( access, $append ) {
// Create multiple item option control, radio or checkboxes
// Precondition:
// access -- object with option description
// $append -- jQuery element to append to
// Uses:
// > .page.ltr
// .lang.fetch()
// 2018-05-15 [email protected]
var lone = ( access.type === "radio" ),
sel = access.selector + "_multiple",
$div = $( "<div>" ),
$label = $( "<label>" ),
$sub = $( "<div>" ),
live, i, k, n, o, v, $group;
if ( typeof access.show === "undefined" ) {
$sub.attr( "class", "error" );
$sub.text( access.selector );
} else {
$sub.text( PREGO.lang.fetch( access.show ) );
}
$label.attr( "for", sel )
.append( $sub );
$div.append( $label );
if ( typeof access.poly === "object" ) {
n = access.poly.length;
if ( n ) {
$group = $( "<div>" );
$group.css( "margin-"
+ ( PREGO.page.ltr ? "left" : "right" ),
"3em" );
if ( lone || typeof access.val === "object" ) {
v = access.val;
} else {
v = [ access.val ];
}
for ( i = 0; i < n; i++ ) {
o = access.poly[ i ];
if ( typeof o === "object" && o ) {
sel = access.selector + "_" + i;
o.$item = $( "<input>" );
o.$item.attr( { type: access.type,
id: sel,
name: access.selector } );
if ( lone ) {
live = ( o.val === v );
} else {
live = false;
for ( k = 0; k < v.length; k++ ) {
if ( o.val === v[ k ] ) {
live = true;
break; // for k
}
} // for k
}
if ( live ) {
o.$item.prop( "checked", true );
}
$group.append( o.$item );
$sub = $( "<span>" );
if ( typeof o.show === "undefined" ) {
$sub.attr( "class", "error" )
.text( ".poly[" + i + "].show missing" );
} else {
$sub.text( PREGO.lang.fetch( o.show ) );
}
$label = $( "<label>" );
$label.attr( "for", sel )
.append( $sub )
.css( "margin-"
+ ( PREGO.page.ltr ? "left" : "right" ),
".5em" )
.append( $( "<br />" ) );
} else {
$label = $( "<span>" );
$label.attr( "class", "error" )
.text( ".poly[" + i + "] is not an object" );
}
$group.append( $label );
} // for i
$div.append( $group );
} else {
$sub = $( "<div>" );
$sub.attr( "class", "error" )
.text( "empty .poly" );
$div.append( $sub );
}
} else {
$sub = $( "<div>" );
$sub.attr( "class", "error" )
.text( "missing/invalid .poly" );
$div.append( $sub );
}
$append.append( $div );
}; // .option.faculty()
PREGO.option.fetch = function ( access ) {
// Retrieve current values in multi-control/multi-value option
// Precondition:
// access -- object with option description
// Postcondition:
// Returns single or multi-select value (Array)
// Uses:
// > .type
// 2014-02-20 [email protected]
var i, lone, n, o, swing,
r; // r = undefined
if ( typeof access.poly === "object" ) {
n = access.poly.length;
if ( n ) {
switch ( access.type ) {
case "radio" :
lone = true; // fall through
case "multi" :
swing = "checked";
break;
case "select" :
lone = access.lone;
swing = "selected";
break;
default :
mw.log( {loud:true},
PREGO.type
+ " *** Error .option.fetch() " + access.type,
3,
access );
} // switch access.type
if ( ! lone ) {
r = [ ];
}
for ( i = 0; i < n; i++ ) {
o = access.poly[ i ];
if ( o && typeof o === "object" ) {
if ( o.$item ) {
if ( o.$item.prop( swing ) ) {
if ( lone ) {
r = o.val;
break; // for i
} else {
r.push( o.val );
}
}
}
}
} // for i
}
}
return r;
}; // .option.fetch()
PREGO.option.field = function ( access, $append ) {
// Create text field control
// Precondition:
// access -- object with option description
// $append -- jQuery element to append to
// Uses:
// .lang.fetch()
// .page.fiat()
// 2017-05-15 [email protected]
var sel = access.selector + "_text",
$div = $( "<div>" ),
shift, style, $label, $span;
access.$text = $( "<input>" );
access.$text.addClass( "mw-ui-input" )
.attr( { id: sel,
type: "text" } )
.css( { "width": "auto" } );
access.backup = ( access.val ? $.trim( access.val )
: "" );
if ( access.backup ) {
access.$text.val( access.backup );
}
if ( ! access.ime ) {
access.$text.addClass( "noime" );
}
if ( typeof access.minimum === "number" ) {
if ( access.minimum > 0 ) {
access.$text.attr( "size", access.minimum );
}
}
if ( typeof access.maxlength === "number" ) {
if ( access.maxlength > 0 ) {
access.$text.attr( "maxlength", access.maxlength );
}
}
if ( typeof access.field === "function" ) {
access.field.call( access, access.$text );
}
if ( typeof access.show !== "undefined" ) {
$span = PREGO.page.fiat( PREGO.lang.fetch( access.show ) );
style = "margin-" + ( PREGO.page.ltr ? "right" : "left" );
shift = $span.css( style );
if ( typeof shift === "string" ) {
if ( /^0*[a-z]*$/.test( shift ) ) {
shift = false;
}
}
if ( ! shift ) {
$span.css( style, "1em" );
}
$label = $( "<label>" );
$label.attr( "for", sel )
.append( $span );
$div.append( $label );
}
$div.append( access.$text );
if ( typeof access.suffix !== "undefined" ) {
$span = PREGO.page.fiat( PREGO.lang.fetch( access.suffix ) );
style = "margin-" + ( PREGO.page.ltr ? "left" : "right" );
shift = $span.css( style );
if ( typeof shift === "string" ) {
if ( /^0*[a-z]*$/.test( shift ) ) {
shift = false;
}
}
if ( ! shift ) {
$span.css( style, "1em" );
}
$label = $( "<label>" );
$label.attr( "for", sel )
.append( $span );
$div.append( $label );
}
$append.append( $div );
}; // .option.field()
PREGO.option.find = function ( about, ask ) {
// Retrieve option object by identification
// Precondition:
// about -- object with gadget description
// ask -- string with option identification
// Postcondition:
// Returns option object if found, else false
// 2013-09-16 [email protected]
var r = false,
i, n, o;
if ( about.opts ) {
n = about.opts.length;
for ( i = 0; i < n; i++ ) {
o = about.opts[ i ];
if ( o && o.script === ask ) {
r = o;
break; // for i
}
} // for i
}
return r;
}; // .option.find()
PREGO.option.flag = function ( access, $append ) {
// Create binary checkbox option control
// Precondition:
// access -- object with option description
// $append -- jQuery element to append to
// Uses:
// > .page.ltr
// .lang.fetch()
// 2018-05-15 [email protected]
var sel = access.selector + "_checkbox",
$label = $( "<label>" );
access.$checkbox = $( "<input>" );
access.$checkbox.attr( { id: sel,
type: "checkbox" } );
access.backup = ( access.val ? true : false );
if ( access.backup ) {
access.$checkbox.prop( "checked", true );
}
$append.append( access.$checkbox );
$label.attr( "for", sel )
.css( "margin-" + ( PREGO.page.ltr ? "left" : "right" ),
".5em" );
if ( typeof access.show === "undefined" ) {
$label.text( access.signature );
} else {
$label.text( PREGO.lang.fetch( access.show ) );
}
$append.append( $label );
}; // .option.flag()
PREGO.option.flipper = function ( access, $append ) {
// Create dropdown selction control, multiple or not
// Precondition:
// access -- object with option description
// $append -- jQuery element to append to
// Uses:
// > .page.ltr
// PREGO.lang.fetch()
// 2017-02-08 [email protected]
var errs = false,
sel = access.selector + "_poly",
$div = $( "<div>" ),
$label = $( "<label>" ),
$sub = $( "<div>" ),
live, i, k, n, o, s, v, $select;
if ( typeof access.show === "undefined" ) {
$sub.attr( "class", "error" )
.text( access.selector );
} else {
$sub.text( PREGO.lang.fetch( access.show ) );
}
$label.attr( "for", sel )
.append( $sub );
$div.append( $label );
if ( typeof access.poly === "object" ) {
n = access.poly.length;
if ( n ) {
$select = $( "<select>" );
$select.attr( "id", sel )
.css( "margin-"
+ ( PREGO.page.ltr ? "left" : "right" ),
"3em" );
if ( typeof access.max === "number" && access.max ) {
$select.attr( "size", access.max );
}
if ( access.lone ) {
v = access.val;
} else {
$select.attr( "multiple", true );
if ( typeof access.val === "object" ) {
v = access.val;
} else {
v = [ access.val ];
}
}
for ( i = 0; i < n; i++ ) {
o = access.poly[ i ];
if ( typeof o === "object" ) {
o.$item = $( "<option>" );
if ( access.lone ) {
live = ( o.val === v );
} else {
live = false;
for ( k = 0; k < v.length; k++ ) {
if ( o.val === v[ k ] ) {
live = true;
break;
}
} // for k
}
if ( live ) {
o.$item.prop( "selected", true );
}
if ( typeof o.show === "undefined" ) {
s = o.val + "";
} else {
s = PREGO.lang.fetch( o.show );
}
o.$item.text( s );
$select.append( o.$item );
} else if ( errs ) {
errs.push( i );
} else {
errs = [ i ];
}
} // for i
$div.append( $select );
if ( errs ) {
$sub = $( "<div>" );
$sub.attr( "class", "error" );
n = errs.length;
s = ".poly[" + ( n > 1 ? " " : "" );
for ( i = 0; i < n; i++ ) {
if ( i > 1 ) {
s = s + ", ";
}
s = s + i;
} // for i
if ( n === 1 ) {
s = s + "] is not an object";
} else {
s = s + " ] are no objects";
}
$sub.text( s );
$div.append( $sub );
}
} else {
$sub = $( "<div>" );
$sub.attr( "class", "error" );
$sub.text( "empty .poly" );
$div.append( $sub );
}
} else {
$sub = $( "<div>" );
$sub.attr( "class", "error" );
$sub.text( "missing/invalid .poly" );
$div.append( $sub );
}
$append.append( $div );
}; // .option.flipper()
PREGO.page.factory = function ( acquire ) {
// Ensure initialization on the fly. Generate GUI elements.
// Precondition:
// acquire -- request
// false -- general
// "Blankpage"
// "Gadgets"
// "$btnClose",
// "$btnOpts",
// "$btnSubmit" -- button
// "$optsForm" -- wrap for any options form
// Uses:
// this
// > .config
// > .type
// > Version
// > mw.util.$content
// >< .page.ltr
// >< .page.gallery
// >< .page.$btnClose
// >< .page.$btnOpts
// >< .page.$btnSubmit
// >< .page.$optsForm
// >< .page.$sectionUser
// >< .page.$throbber
// >< .page.$stored
// >< .page.$denied
// .page.fancy()
// mw.config.get()
// 2018-05-15 [email protected]
var i, permit, q, s, $e, $v;
if ( ! this.gallery ) {
this.gallery = {
"$btnOpts" : [ "Nuvola_apps_kcmsystem.svg",
"7a", true, true ],
"$throbber" : [ "Ajax-loader.gif",
"de", false, false, "API..." ],
"$stored" : [ "Symbol_OK.png",
"62", true, false, "Okay" ],
"$denied" : [ "Boos.png",
"38", true, false, ":-(" ]
};
}
switch ( acquire ) {
case false :
if ( typeof this.ltr !== "boolean" ) {
// PREGO.page.find(); Special:Gadgets only
if ( typeof PREGO.config === "object"
&& PREGO.config ) {
permit = [ "$btnClose",
"$btnOpts",
"$btnSubmit",
"$optsForm",
"$sectionUser" ];
for ( i = 0; i < permit.length; i++ ) {
s = permit[ i ];
$e = PREGO.config[ s ];
if ( $e
&& typeof $e === "object"
&& typeof $e.clone === "function" ) {
this[ s ] = PREGO.config[ s ].clone();
}
} // for i
}
this.ltr = ( $( window.document ).find( "html" )
.attr( "dir" )
!== "rtl" );
}
break;
case "Blankpage" :
q = mw.config.get( "wgFormattedNamespaces" );
$v = $( "#firstHeading,#section_0" );
if ( ! $v.length ) {
$v = $( "h1" );
}
$v.eq( 0 ).text( q[ "2" ] + ": " + q[ "2300" ] )
.attr( "title", Version );
$v = mw.util.$content.find( "#mw-content-text" );
$v.empty();
$e = $( "<div>" );
$e.attr( { "id": PREGO.type + "-user" } );
$v.prepend( $e );
this.$sectionUser = $e;
$v = $( "head" );
$e = $v.find( "title" );
$e.remove();
$e = $( "<title>" );
$e.text( PREGO.type );
$v.prepend( $e );
break;
/* 2016-10 unreachable
case "Gadgets" :
$e = $( "<div>" );
$e.attr( "id", PREGO.type + "-user" )
.css( { "border": "solid 2px #80FFFF",
"margin": "1em",
"padding": "1em" } );
$v = $( "<h2>" );
s = mw.config.get( "wgFormattedNamespaces" );
$v.text( s[ "2" ] );
$e.append( $v );
mw.util.$content.append( $e );
this.$sectionUser = $e;
break;
*/
case "$btnClose" :
case "$btnOpts" :
case "$btnSubmit" :
if ( ! this[ acquire ] ) {
$e = $( "<button>" );
$e.attr( "type", "button" );
switch ( acquire ) {
case "$btnClose" :
$e.css( { "background-color": "#FF0000",
"color": "#FFFFFF",
"font-size": "8px",
"font-weight": "bolder",
"float": ( this.ltr ? "right" :
"left" ),
"height": "16px",
"padding": "0",
"text-align": "center",
"vertical-align": "middle",
"width": "16px"
} );
$v = $( "<span>" );
$v.text( "X" );
break;
case "$btnOpts" :
$e.css( { "background-color": "#80FFFF",
"margin-bottom": ".5em" } );
$e.css( "margin-" + ( this.ltr ? "left"
: "right" ),
"1em" );
$e.attr( "title", "Option..." );
$v = this.fancy( acquire, 20 );
break;
case "$btnSubmit" :
$e.css( { "color": "#00A000",
"font-size": "200%",
"font-weight": "bolder",
"margin-top": "5px" } );
$e.attr( "title", "...API...>>" );
$v = $( "<span>" );
$v.text( "+" );
break;
} // switch acquire
$e.append( $v );
this[ acquire ] = $e;
}
break;
case "$optsForm" :
if ( ! this.$optsForm ) {
$e = $( "<div>" );
$e.attr( "class", PREGO.type + "-optsForm" )
.css( { "border": "solid 1px #80FFFF",
"margin": ".5em",
"padding": ".5em" } );
this.$optsForm = $e;
}
break;
case "$throbber" :
case "$stored" :
case "$denied" :
if ( ! this[ acquire ] ) {
this[ acquire ] = this.fancy( acquire, 18 );
}
break;
} // switch acquire
}; // .page.factory()
PREGO.page.fancy = function ( access, amount ) {
// Create thumb image
// Precondition:
// access -- image identifier
// amount -- number of pixels
// Postcondition:
// Returns jQuery object <img>
// this
// > .page.gallery
// 2013-12-26 [email protected]
var src = "//upload.wikimedia.org/wikipedia/commons/",
picture = this.gallery[ access ],
s, $r;
if ( picture ) {
if ( picture[ 2 ] ) {
src = src + "thumb/";
}
s = picture[ 1 ];
src = src + s.substr(0, 1) + "/" + s + "/"
+ picture[ 0 ];
if ( picture[ 2 ] ) {
src = src + "/" + amount + "px-" + picture[ 0 ];
if ( picture[ 3 ] ) {
src = src + ".png";
}
}
$r = $( "<img />" );
$r.attr( "src", src );
if ( picture[ 4 ] ) {
$r.attr( "alt", picture[ 4 ] );
}
} else {
$r = $( "<span>" );
$r.text( "???" + access + "???" );
}
return $r;
}; // .page.fancy()
PREGO.page.feature = function ( about ) {
// Create user defined gadget item on page
// Precondition:
// about -- object with gadget description
// Postcondition:
// about.$item has been set
// Uses:
// this
// > .page.$sectionUser
// > .page.$list
// > .type
// .lang.fetch()
// .page.first()
// 2021-10-08 [email protected]
var e, i, n, p, say, $a, $span, $span2;
if ( typeof this.$sectionUser === "undefined" ) {
this.first();
}
if ( typeof this.$list === "object" ) {
if ( typeof about.show === "undefined" ) {
say = about.script;
} else {
say = PREGO.lang.fetch( about.show );
}
$span = $( "<span>" );
$span2 = $( "<span>" );
$span2.html( say );
if ( typeof about.support === "undefined" ) {
$span.append( $span2 );
} else {
$a = $( "<a>" );
$a.attr( { href: PREGO.lang.fetch( about.support ),
target: "_blank" } )
.append( $span2 );
$span.append( $a );
}
if ( typeof about.suffix !== "undefined" ) {
$span2 = $( "<span>" );
$span2.html( PREGO.lang.fetch( about.suffix ) );
$span.append( " " );
$span.append( $span2 );
}
about.$item = $( "<li>" );
about.$item.attr( "id", about.script );
about.$item.append( $span );
say = say.toLowerCase().replace( /-_.,;/, " " );
p = [ say, about.$item ];
if ( this.gadgets ) {
n = this.gadgets.length;
for ( i = 0; i < n; i++ ) {
e = this.gadgets[ i ];
if ( say < e[ 0 ] ) {
e[ 1 ].before( about.$item );
break; // for i
}
} // for i
e = [ say, about.$item ];
if ( i === n ) {
this.$list.append( about.$item );
this.gadgets.push( p );
} else {
this.gadgets.splice( i, 0, p );
}
} else {
this.$list.append( about.$item );
this.gadgets = [ p ];
}
} else {
about.$item = true;
}
}; // .page.feature()
PREGO.page.features = function () {
// Insert one or more gadget items on page
// Precondition:
// preferences page
// Uses:
// > .page.queue
// >< .page.launched
// .page.factory()
// .page.feature()
// .dialog.further()
// Remark: Used as event handler -- 'this' is not PREGO.page
// 2019-02-13 [email protected]
var gadget, i, n;
if ( ! PREGO.page.launched ) {
PREGO.page.launched = true;
PREGO.page.factory( false );
}
n = PREGO.page.queue.length;
for ( i = 0; i < n; i++ ) {
gadget = PREGO.page.queue[ i ];
if ( gadget && typeof gadget === "object" ) {
if ( typeof gadget.script === "string" ) {
PREGO.page.queue[ i ] = gadget.script;
} else {
PREGO.page.queue[ i ] = i;
}
if ( typeof gadget.$item !== "object" ) {
PREGO.page.feature( gadget );
if ( gadget.$item && gadget.$item !== true
&& gadget.opts &&
typeof gadget.opts === "object" ) {
PREGO.dialog.further( gadget );
}
}
}
} // for i
}; // .page.features()
PREGO.page.fiat = function ( adjust ) {
// Create text field control
// Precondition:
// adjust -- string with possible HTML
// Postcondition:
// Returns jQuery object
// 2013-10-06 [email protected]
var $r;
if ( adjust.charCodeAt(0) === 60 ) { // '<'
$r = $( adjust );
} else {
$r = $( "<span>" );
$r.text( adjust );
}
return $r;
}; // .page.fiat()
/* 2016-10 unreachable page
PREGO.page.find = function () {
// Initialize "Gadgets" page server definition items
// Precondition:
// "Gadgets" page ready
// Uses:
// this
// > mw.util.$content
// < .page.items
// 2016-10-08 [email protected]
var $items = mw.util.$content.find( "li" ),
n = $items.length,
i, k, s, $li, $links;
this.items = { };
for ( i = 0; i < n; i++ ) {
$li = $items.eq( i );
$links = $li.find( "a" );
for ( k = 0; k < $links.length; k++ ) {
s = $links.eq( k ).attr( "title" );
if ( s ) {
if ( s.indexOf( "MediaWiki:Gadget-" ) === 0 ) {
this.items[ s.substr( 17 ) ] = $li;
break; // for k
}
}
} // for k
} // for i
}; // .page.find()
*/
PREGO.page.first = function () {
// Initialize page and page section
// Precondition:
// Special page ready
// Uses:
// this
// > .special
// > .page.$sectionUser
// > .type
// < .page.$list
// .page.factory()
// 2016-10-08 [email protected]
this.factory( PREGO.special );
if ( typeof this.$sectionUser === "object" ) {
this.$list = $( "<ul />" );
this.$list.attr( "id", PREGO.type + "-list" );
this.$sectionUser.append( this.$list );
}
}; // .page.first()
PREGO.page.fragment = function ( assign ) {
// Create identifier for gadget storage submission buttons
// Precondition:
// assign -- string of particular gadget, or nothing
// Postcondition:
// Returns string with identifier
// Uses:
// > .type
// 2015-09-25 [email protected]
var r = PREGO.type + "-SUBMIT";
if ( assign ) {
r = r + "_" + assign;
}
return r;
}; // .page.fragment()
PREGO.factory = function ( apply, adjacent ) {
// Encode/decode any value
// Precondition:
// apply -- value, of any type; or encoded string
// adjacent -- value type for storing, false for retrieving
// Postcondition:
// Returns string for storing, or retrieved value
// Uses:
// parseInt()
// JSON.stringify()
// .date.format8601()
// .date.from8601()
// JSON.parse()
// 2014-10-01 [email protected]
var r;
if ( adjacent ) { // storing
r = adjacent + "|";
switch ( r ) {
case "boolean|" :
if ( apply ) {
r = "boolean|true";
}
break;
case "Boolean|" :
if ( apply.valueOf() ) {
r = "boolean|true";
}
break;
case "number|" :
case "Number|" :
case "string|" :
case "String|" :
r = r.toLowerCase() + apply;
break;
case "object|" :
if ( r ) {
r = r + JSON.stringify( apply );
} else {
r = "null|";
}
break;
case "date|" :
case "Date|" :
r = "date|" + PREGO.date.format8601( apply );
break;
default :
r = "undefined|";
} // switch typeof apply
} else if ( typeof apply === "string" ) { // retrieving
r = apply.indexOf( "|" );
if ( r > 0 ) {
switch ( apply.substr( 0, r ) ) {
case "boolean" :
r = ( apply === "boolean|true" );
break;
case "number" :
r = parseInt( apply.substr( r + 1 ), 10 );
break;
case "string" :
r = apply.substr( r + 1 );
break;
case "null" :
r = null;
break;
case "object" :
r = JSON.parse( apply.substr( r + 1 ) );
break;
case "date" :
r = PREGO.date.from8601( apply.substr( r + 1 ) );
break;
case "undefined" :
r = undefined;
break;
default :
r = apply;
} // switch typeID
} else {
r = apply;
}
} else {
r = undefined;
}
return r;
}; // .factory()
PREGO.fetch = function ( assign, assume, again, aborted ) {
// Retrieve a "Gadgets" object stored by .form() or .forward()
// Precondition:
// assign -- string with gadget identification
// assume -- fallback value object, if undefined or failure
// kept unchanged; also default for single values
// again -- update value from server (optional)
// callback function, or true
// aborted -- error callback function (optional), or false
// Postcondition:
// Returns object, could be null
// Uses:
// this
// > .local
// .api.fresh()
// mw.user.options.get()
// JSON.parse()
// 2015-09-12 [email protected]
var o, r, s;
if ( typeof assign === "string" ) {
if ( again && ! this.local ) {
this.api.fresh( assign, 2, assume, again, aborted );
}
r = mw.user.options.get( "userjs-" + assign );
if ( r ) {
if ( typeof r === "string" ) {
o = JSON.parse( r );
if ( assume && typeof assume === "object" ) {
r = { };
for ( s in assume ) {
r[ s ] = assume[ s ];
} // for s in assume
for ( s in o ) {
r[ s ] = o[ s ];
} // for s in o
} else {
r = o;
}
}
} else if ( r === undefined ) {
r = ( assume ? assume : null );
}
} else {
r = ( assume ? assume : null );
}
return r;
}; // .fetch()
PREGO.finalize = function () {
// Ready for use, communicate
// Uses:
// this
// > .type
// mw.hook()
// 2016-03-18 [email protected]
mw.hook( this.type + ".ready" ).fire( this );
}; // .finalize()
PREGO.form = function ( about ) {
// Show gadget (entry, and dialog) on "Gadgets" page
// Precondition:
// about -- object with gadget description, or false
// Postcondition:
// Returns false if valid, else error message on parameter fault
// Uses:
// > .special
// > .type
// >< .page.queue
// >< .page.launched
// mw.config.get()
// .page.features()
// mw.loader.load()
// mw.hook()
// (.page.features)
// 2019-02-13 [email protected]
var r = false,
s = mw.config.get( "wgCanonicalSpecialPageName" );
if ( s === PREGO.special ) {
if ( s === "Blankpage" ) {
s = mw.config.get( "wgTitle" );
r = ( s.indexOf( "/" + PREGO.type, 3 ) > 0 );
}
if ( r && typeof about === "object" ) {
if ( typeof PREGO.page.queue === "object" ) {
PREGO.page.queue.push( about );
if ( PREGO.page.launched ) {
PREGO.page.features();
}
} else {
PREGO.page.queue = [ about ];
PREGO.page.launched = false;
mw.loader.load( [ "mediawiki.ui.input" ] );
mw.hook( "wikipage.content" ).add( PREGO.page.features );
}
}
}
return r;
}; // .form()
PREGO.forward = function ( assign, apply, after, aborted ) {
// Store a "Gadgets" options object
// Precondition:
// assign -- string with gadget identification
// apply -- options object (not null)
// after -- callback function (optional), or false
// aborted -- error callback function (optional), or false
// Postcondition:
// Returns false if valid, else error message on parameter fault
// Uses:
// > .local
// JSON.stringify()
// .cache.fill()
// .api.fire()
// mw.user.options.set()
// 2018-05-05 [email protected]
var r, store;
if ( typeof assign === "string" &&
typeof apply === "object" && apply ) {
store = JSON.stringify( apply );
if ( PREGO.local ) {
PREGO.cache.fill( assign, store );
} else {
PREGO.api.fire( assign,
store,
false,
after,
aborted,
true );
}
mw.user.options.set( "userjs-" + assign, store );
r = false;
} else {
r = "ERROR * mw.libs." + PREGO.type + ".forward()"
+ " * invalid arg";
}
return r;
}; // .forward()
PREGO.get = function ( assign, assume, again, aborted ) {
// Retrieve a typesafe USERJS option value stored by .put()
// Precondition:
// assign -- string with option identification
// assume -- fallback value, if undefined or failure
// again -- update value from server
// callback function, or true
// aborted -- error callback function (optional), or false
// Postcondition:
// Returns value, of any type
// Uses:
// this
// > .local
// mw.user.options.get()
// .api.fresh()
// .factory()
// 2015-09-12 [email protected]
var r;
if ( typeof assign === "string" ) {
r = mw.user.options.get( "userjs-" + assign );
if ( this.local ) {
if ( typeof r !== "string" ) {
r = undefined;
}
} else if ( again ) {
this.api.fresh( assign, 1, assume, again, aborted );
}
if ( r ) {
r = this.factory( r, false );
}
}
if ( r === undefined ) {
r = assume;
}
return r;
}; // .get()
PREGO.put = function ( assign, apply, after, aborted ) {
// Store a typesafe USERJS option value
// Precondition:
// assign -- string with option identification
// apply -- value, of any type
// after -- callback function (optional), or false
// aborted -- error callback function (optional), or false
// Postcondition:
// Returns false if valid, else error message on parameter fault
// Uses:
// this
// > .local
// .factory()
// .cache.fill()
// .api.fire()
// mw.user.options.set()
// 2015-09-12 [email protected]
var s = $.type( apply ),
r;
if ( ! apply && s === "object" ) {
s = "null";
}
s = this.factory( apply, s );
if ( this.local ) {
this.cache.fill( assign, s );
r = false;
} else {
r = this.api.fire( assign, s, false, after, aborted );
if ( r && s === "object" ) {
r = false;
}
}
mw.user.options.set( "userjs-" + assign, s );
return r;
}; // .put()
PREGO.remove = function ( assign, after, aborted ) {
// Remove a preference entry
// Precondition:
// assign -- string with option identification
// after -- callback function (optional), or false
// aborted -- error callback function (optional), or false
// Postcondition:
// Returns false if valid, else error message on parameter fault
// Uses:
// this
// > .local
// .api.fire()
// mw.user.options.get()
// mw.user.options.set()
// 2015-09-12 [email protected]
var r, s, v;
if ( this.local ) {
this.cache.free( assign );
} else {
r = this.api.fire( assign, null, false, after, aborted );
}
if ( ! r ) {
s = "userjs-" + assign;
v = mw.user.options.get( s );
if ( v !== null && v !== undefined ) {
mw.user.options.set( s, null );
}
}
return r;
}; // .remove()
PREGO.string = function ( assign, apply, after, aborted ) {
// Store a string value of a MEDIAWIKI preference
// Note that "false" causes other behaviour than false.
// Precondition:
// assign -- string with option name
// apply -- string value
// after -- callback function (optional), or false
// aborted -- error callback function (optional), or false
// Postcondition:
// Returns false if valid, else error message on parameter fault
// Uses:
// this
// > .type
// .api.fire()
// mw.user.options.set()
// 2013-09-19 [email protected]
var r;
if ( typeof assign === "string" &&
typeof apply === "string" ) {
r = this.api.fire( assign, apply, true, after, aborted );
mw.user.options.set( assign, apply );
} else {
r = "ERROR * mw.libs." + PREGO.type + ".string()"
+ " * invalid arg";
}
return r;
}; // .string()
PREGO.translation = function ( available ) {
// Retrieve best translation from object
// Precondition:
// available -- object with items accessible by language code
// Postcondition:
// Returns component with best matching language code
// Uses:
// this
// > .lang.polyglott
// > .lang.multi
// .lang.factory()
// 2014-03-20 [email protected]
var r = false,
i, slang;
if ( typeof this.lang.polyglott !== "object" ) {
this.lang.factory();
}
if ( typeof available === "object" &&
available ) {
for ( i = 0; i < this.lang.multi; i++ ) {
slang = this.lang.polyglott[ i ];
if ( typeof available[ slang ] !== "undefined" ) {
r = available[ slang ];
break; // for i
}
} // for i
}
return r;
}; // .translation()
PREGO.translator = function () {
// Retrieve Array with possible language codes
// Postcondition:
// Returns Array with possible language codes, sorted best first
// Uses:
// this
// > .lang.polyglott
// .lang.factory()
// 2014-03-19 [email protected]
if ( typeof this.lang.polyglott !== "object" ) {
this.lang.factory();
}
return this.lang.polyglott;
}; // .translator()
PREGO.update = function ( assign, after, aborted ) {
// Update the value of a MEDIAWIKI preference
// Precondition:
// assign -- string with option name
// after -- callback function after update
// aborted -- error callback function (optional), or false
// Postcondition:
// Returns false if valid, else error message on parameter fault
// Uses:
// this
// > .type
// mw.user.options.get()
// .api.fresh()
// 2013-09-28 [email protected]
var r;
if ( typeof assign === "string" ) {
this.api.fresh( assign,
0,
mw.user.options.get( assign ),
after,
aborted );
r = false;
} else {
r = "ERROR * mw.libs." + PREGO.type + ".update()"
+ " * invalid arg";
}
return r;
}; // .update()
PREGO.$button = function ( assign ) {
// Retrieve current [options button] design
// Precondition:
// assign -- optional string with gadget name
// Postcondition:
// Returns jQuery object
// Uses:
// > .special
// > .type
// > .page.$btnOpts
// mw.config.get()
// mw.util.getUrl()
// .page.factory()
// 2016-10-09 [email protected]
var shift = mw.config.get( "wgDBname" ) + "Gadgets",
special = ( PREGO.special === "Blankpage" ?
"Blankpage/" + PREGO.type :
PREGO.special ),
src = window.location.protocol + "//"
+ window.location.host
+ mw.util.getUrl( "Special:" + special ),
$btn;
if ( assign ) {
src = src + "#" + assign;
}
if ( ! PREGO.page.$btnOpts ) {
PREGO.page.factory( "$btnOpts" );
}
$btn = PREGO.page.$btnOpts.clone();
$btn.click( function () {
window.open( src, shift );
// Returns always false, stop the bubbling
return false;
} );
return $btn;
}; // .$button()
first();
}( window.mediaWiki, window.jQuery ) );
// Emacs
// Local Variables:
// coding: utf-8-dos
// fill-column: 80
// End:
/// EOF </nowiki> preferencesGadgetOptions/d.js