User:PerfektesChaos/js/preferencesGadgetOptions/d.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
![]() | This user script seems to have a documentation page at User:PerfektesChaos/js/preferencesGadgetOptions/d. |
/// User:PerfektesChaos/js/preferencesGadgetOptions/d.js
/// 2021-10-08 PerfektesChaos@de.wikipedia
// 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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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