/// User:PerfektesChaos/js/loadResourceFile/d.js
/// 2018-08-24 [email protected]
// Load local resource (CSS, JavaScript) files into current page.
// ResourceLoader: compatible;
// dependencies: user, user.options, mediawiki.util
/// Fingerprint: #0#0#
/// @license GPL [//www.mediawiki.org/w/COPYING] (+GFDL, LGPL, CC-BY-SA)
/// <nowiki>
/* global window: false */
/* jshint forin:false,
bitwise:true, curly:true, eqeqeq:true, latedef:true,
laxbreak:true,
nocomma:true, strict:true, undef:true, unused:true */
( function ( mw, $ ) {
"use strict";
var VSN = -1.6,
LRF = "loadResourceFile",
basics, config, gui, lang, prego;
if ( typeof mw.libs[ LRF ] !== "object" || ! mw.libs[ LRF ] ) {
mw.libs[ LRF ] = { };
}
mw.libs[ LRF ].type = LRF;
LRF = mw.libs[ LRF ];
if ( LRF.loaded ) {
return;
}
// User options:
// .portlet
// .set
// .store
/*
* 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.4 ("in")
// MediaWiki 1.20 (mw .libs, jQuery core)
basics = { };
config = { support: "User:PerfektesChaos/js/" + LRF.type };
gui = { };
lang = { };
LRF.doc = "[[w:en:" + config.support + "]]";
LRF.vsn = VSN;
lang.texts = {
// 2014-01-04 [email protected]
"show": {"en": "Load CSS/JS file",
"de": "Lade CSS/JS-Datei"},
"sucks": {"en": "Local folder not yet defined",
"de": "Lokales Verzeichnis noch nicht definiert"},
"^show": {"en": "Load-Resource-File",
"de": "Load-Resource-File"},
"^suffix": {"en": "– Load"
+ " local resource (CSS, JavaScript) files"
+ " into current page.",
"de": "– Lade lokale Dateien mit"
+ " CSS oder JavaScript"
+ " in die aktuelle Seite"},
"^^charset": {"en": "Character encoding",
"de": "Zeichenkodierung"},
"^^charset+":{"en": "utf-8 (default), iso-8859-1",
"de": "utf-8 (Vorgabe), iso-8859-1"},
"^^path": {"en": "Local directory path",
"de": "Lokales Verzeichnis"},
"^^path+": {"en": "<div>Store on Wiki server<br />"
+ " (invisible for other users)</div>",
"de": "<div>"
+ "Speichern auf dem Wiki-Server<br />"
+ " (unsichtbar für andere Benutzer)"
+ "</div>"},
"^^portlet": {"en": "Create portlet link",
"de": "Portlet-Link einfügen"},
"^^portlet+":{"en": "<div style='margin-left:3em'>"
+ "Space sparated list"
+ " of canonical specialpage names<br />"
+ "Empty list:"
+ " all supported pages<br />"
+ "<code>0</code> –"
+ " Do not create portlet link.</>",
"de": "<div style='margin-left:3em'>"
+ "Leerzeichen-getrennte Liste"
+ " von kanonischen Namen<br />"
+ "Leere Liste: Immer Portlet-Link<br />"
+ "<code>0</code> –"
+ " keine Portlet-Links</div>"}
}; // lang.texts
lang.user = {
"de" : "de",
"als" : "de",
"bar" : "de",
"dsb" : "de",
"frr" : "de",
"gsw" : "de",
"hsb" : "de",
"ksh" : "de",
"lb" : "de",
"nds" : "de",
"pdc" : "de",
"pdt" : "de",
"pfl" : "de",
"sli" : "de",
"stq" : "de",
"vmf" : "de"
}; // lang.user 2012-12-19 [email protected]
// ///////////////////////////////////////////////////////////////////
function bbLoadFile( app, doc, $ ) {
// Build basic file load functions
// Precondition:
// app -- application object
// doc -- window.document, or nil
// $ -- jQuery, or nil
// 2013-12-05
var later = false; // document ready
function file( absolute, accept, asyncInhibit ) {
// Load script if doc ready, or prepare statement
// Precondition:
// absolute -- (local) path
// accept -- charset string, if any
// asyncInhibit -- force synchronous loading
// Postcondition:
// Return string, with HTML statement to be written
// or SPC if already appended
// or "" if nothing done
// Uses:
// > later
// > doc
// $()
// 2013-12-05
var o,
s = absolute.toLowerCase();
if ( $ ) {
if ( s.slice( -3 ) === ".js" ) {
o = { "src": "file:/" + absolute,
"type": "text/javascript"
};
if ( accept ) {
o.charset = accept;
}
if ( ! ( later || asyncInhibit ) ) {
o.async = "async";
}
s = ( later ? "body" : "head" );
$( s ).append( $( "<script />", o ) );
} else if ( s.slice( -4 ) === ".css" ) {
o = { "href": "file:/" + absolute,
"rel": "stylesheet",
"type": "text/css"
};
if ( accept ) {
o.charset = accept;
}
$( "head" ).append( $( "<link />", o ) );
}
} else if ( doc ) { // jQuery not yet available; use DOM
/*
if ( s.slice( -3 ) === ".js" ) {
e = doc.createElement( "script" );
e.setAttribute( "type", "text/javascript" );
e.setAttribute( "src", "file:/" + absolute );
if ( later ) {
doc.body.appendChild( e );
} else {
doc.head.appendChild( e );
}
} else if ( s.slice( -4 ) === ".css" ) {
e = doc.createElement( "link" );
e.setAttribute( "rel", "stylesheet" );
e.setAttribute( "type", "text/css" );
e.setAttribute( "href", "file:/" + absolute );
doc.head.appendChild( e );
}
*/
}
} // file()
app.files = function ( apply, access, accept ) {
// Try to load resources from local environment
// Precondition:
// apply -- identifier string, or Array with identifiers
// access -- string (optional), absolute file system base
// accept -- charset string, if any
// Uses:
// > .storage
// > .set
// file()
// $.isArray()
// 2013-12-05
var i,
s = typeof apply,
set,
start;
if ( typeof access === "string" ) {
start = access;
} else if ( this.storage ) {
start = this.storage;
} else {
start = "/";
}
if ( start.search( /\/$/ ) < 0 ) {
start = start + "/";
}
if ( typeof accept === "string" ) {
set = accept;
} else if ( this.set ) {
set = this.set;
} else {
set = false;
}
if ( s === "string" ) {
file( start + apply, set );
} else if ( s === "object" ) {
if ( $.isArray( apply ) ) {
for ( i = 0; i < apply.length; i++ ) {
s = apply[ i ];
if ( typeof s === "string" ) {
file( start + s, set );
}
} // for i
}
}
}; // app.files()
function finished() {
// Completed document loading
// Precondition:
// document ready
// Uses:
// < later
// 2013-12-05
later = true;
} // finished()
app.folder = function ( access ) {
// Set base folder for ressources
// Precondition:
// access -- string with absolute file system path
// Uses:
// < .storage
// 2013-12-05
if ( typeof access === "string" ) {
this.storage = access;
}
}; // app.folder()
app.font = function ( accept ) {
// Set default charset for ressources
// Precondition:
// accept -- string with charset
// Uses:
// < .set
// 2013-12-05
if ( typeof accept === "string" ) {
this.set = accept;
}
}; // app.font()
$( finished ); // document ready
app.low = true;
} // bbLoadFile()
// ///////////////////////////////////////////////////////////////////
function fire() {
// Start possible actions on current page
// Precondition:
// Current page is special page
// Uses:
// > basics.low
// > .set
// > .portlet
// > prego
// > config.lazy
// > .afterLoad
// < gui.portlet
// bbLoadFile()
// config.foreign()
// config.fetch()
// config.form()
// mw.loader.state()
// (gui.factory)
// (.afterLoad)
// Remark: May be used as event handler -- 'this' is not accessed
// 2018-08-24 [email protected]
var rls;
if ( ! basics.low ) {
bbLoadFile( basics, null, $ );
}
if ( typeof LRF.set === "string" ) {
config.foreign( LRF.set );
}
config.fetch();
gui.portlet = LRF.portlet;
if ( gui.portlet === undefined ||
gui.portlet === true ) {
gui.portlet = { };
}
if ( typeof config.lazy === "boolean" && ! config.lazy ) {
gui.portlet = false;
}
if ( gui.portlet
&& typeof gui.portlet === "object" ) {
$( gui.factory );
}
if ( mw.config.get( "wgCanonicalSpecialPageName" ) === "Gadgets"
&& prego ) {
config.form();
}
rls = { };
rls[ "ext.gadget." + LRF.type ] = "ready";
mw.loader.state( rls );
if ( typeof LRF.afterLoad === "function" ) {
LRF.afterLoad();
}
} // fire()
// ///////////////////////////////////////////////////////////////////
config.favorite = function () {
// Detect support page in user language
// Uses:
// this
// > lang.slang
// > config.support
// lang.favorite()
// 2013-12-14 [email protected]
var r;
lang.favorite();
switch ( lang.slang ) {
case "de" :
r = "de.wikipedia.org";
break;
default:
r = "en.wikipedia.org";
} // switch .slang
return "//" + r + "/wiki/" + this.support;
}; // config.favorite()
config.fetch = function () {
// Retrieve preferences and overwrite presets
// Uses:
// this
// > config.supply
// > .type
// < prego
// < config.stored
// < config.lazy
// config.foreign()
// mw.libs.preferencesGadgetOptions.fetch()
// 2013-12-14 [email protected]
var vals;
prego = mw.libs[ this.supply ];
if ( prego ) {
vals = prego.fetch( LRF.type );
if ( vals && typeof vals === "object" ) {
if ( typeof vals.charset === "string" ) {
vals.charset = $.trim( vals.charset );
if ( vals.charset !== "" ) {
config.foreign( vals.charset );
}
}
if ( typeof vals.path === "string" ) {
this.stored = $.trim( vals.path );
if ( this.stored === "" ) {
this.stored = false;
}
}
if ( typeof vals.portlet === "boolean" ) {
config.lazy = vals.portlet;
}
}
}
}; // config.fetch()
config.filled = function ( assigned ) {
// New preferences have been sent to server
// Precondition:
// assigned -- object with final form data, to be stored
// Remark: May be used as event handler -- 'this' is not accessed
// 2013-12-14 [email protected]
if ( typeof assigned === "object" && assigned ) {
if ( typeof assigned.path === "string" ) {
config.folder( assigned.path );
}
}
}; // config.filled()
config.filter = function ( access ) {
// Retrieve volatile basic path
// Precondition:
// access -- string with folder path, or not
// Postcondition:
// Returns string with folder path, or not
// Uses:
// this
// config.folder()
// 2013-12-14 [email protected]
var r = false;
if ( typeof access === "string" ) {
r = $.trim( access ).replace( /\\/g, "/" );
if ( r === "" ) {
r = false;
}
}
if ( ! r ) {
r = this.folder();
}
return r;
}; // config.filter()
config.fire = function () {
// Prepare ResourceLoader availability
// Uses:
// this
// < config.supply
// mw.loader.getState()
// mw.loader.state()
// mw.loader.load()
// 2018-08-24 [email protected]
var rls, signature;
this.supply = "preferencesGadgetOptions";
signature = "ext.gadget." + this.supply;
if ( ! mw.loader.getState( signature ) ) {
rls = { };
rls[ signature ] = "loading";
mw.loader.state( rls );
mw.loader.load( "https://en.wikipedia.org"
+ "/w/index.php?title="
+ "User:PerfektesChaos/js/" + this.supply
+ "/r.js"
+ "&action=raw&bcache=1&maxage=604805"
+ "&ctype=text/javascript",
"text/javascript" );
}
}; // config.fire()
config.firing = function () {
// Intermediate loading process step
// Precondition:
// MW ressources are available
// Uses:
// > .config.supply
// mw.hook()
// (fire)
// Remark: Used as event handler -- 'this' is not config
// 2015-10-04 [email protected]
mw.hook( config.supply + ".ready" ).add( fire );
}; // .firing()
config.folder = function ( assign ) {
// Retrieve or store basic path
// Precondition:
// assign -- string with folder path, to be stored
// Postcondition:
// Returns string with folder path
// Uses:
// this
// > .store
// > .type
// >< localStorage
// < config.storage
// 2013-12-14 [email protected]
var s,
sign = LRF.type + ".store",
r = "";
if ( typeof assign === "string" ) {
r = $.trim( assign ).replace( /\\/g, "/" );
if ( typeof window.localStorage === "object" ) {
if ( r === "" ) {
window.localStorage.removeItem( sign );
this.stored = false;
} else {
window.localStorage.setItem( sign, r );
this.stored = r;
}
}
} else {
if ( typeof LRF.store === "string" ) {
r = LRF.store;
}
if ( typeof this.stored === "string" ) {
r = this.stored;
}
r = r.replace( /\\/g, "/" );
if ( typeof window.localStorage === "object" ) {
s = window.localStorage.getItem( sign );
if ( typeof s === "string" ) {
r = $.trim( s ).replace( /\\/g, "/" );
}
window.localStorage.setItem( sign, r );
}
}
this.storage = r;
return r;
}; // config.folder()
config.foreign = function ( assign ) {
// Retrieve or memorize default character set
// Precondition:
// assign -- string with character set, to be stored
// Postcondition:
// Returns string with character set, or false
// Uses:
// this
// >< .set
// 2013-12-14 [email protected]
var r = config.set;
if ( typeof assign === "string" ) {
config.set = $.trim( assign );
}
return ( r ? r : false );
}; // config.foreign()
config.form = function () {
// Equip Special:Gadgets page with entry and form
// Uses:
// > .type
// > lang.slang
// > lang.texts
// > config.set
// > gui.portlet
// lang.favorite()
// config.fetch()
// config.favorite()
// config.folder()
// prego.form()
// (.config.filled)
// mw.libs.preferencesGadgetOptions.form()
// 2013-12-14 [email protected]
var dialog,
sl,
text = lang.texts;
lang.favorite();
sl = lang.slang;
this.fetch();
dialog = { script: LRF.type,
show: text[ "^show" ][ sl ],
support: this.favorite(),
suffix: text[ "^suffix" ][ sl ],
filled: this.filled,
opts: [ { signature: "path",
type: "text",
show: text[ "^^path" ][ sl ],
suffix: text[ "^^path+" ][ sl ],
val: this.folder()
},
{ signature: "charset",
type: "text",
show: text[ "^^charset" ][ sl ],
suffix: text[ "^^charset+" ][ sl ],
val: ( this.set ? this.set : "" )
},
{ signature: "portlet",
type: "checkbox",
show: text[ "^^portlet" ][ sl ],
suffix: text[ "^^portlet+" ][ sl ],
val: ( gui.portlet ? true : false )
}
] };
prego.form( dialog );
}; // config.form()
gui.factory = function () {
// Insert portlet link
// Uses:
// > lang.slang
// > lang.texts
// > gui.portlet
// -- object with portlet requirements
// .scope -- container id
// .show -- label
// .shortcut -- access key
// .stick -- id to sort before in container
// > .type
// > .vsn
// lang.favorite()
// jQuery.trim()
// config.foreign()
// config.folder()
// mw.util.addPortletLink()
// (.find)
// Remark: May be used as event handler -- 'this' is not accessed
// 2013-12-14 [email protected]
var dom,
$link,
s,
show,
signal,
scope = "p-tb",
shortcut = null,
stick = null;
lang.favorite();
show = lang.texts.show[ lang.slang ];
s = gui.portlet.scope;
if ( typeof s === "string" ) {
s = $.trim( s );
if ( s.length ) {
scope = s;
}
}
s = gui.portlet.shortcut;
if ( typeof s === "string" ) {
s = $.trim( s );
if ( s.length ) {
shortcut = s;
}
}
s = gui.portlet.show;
if ( typeof s === "string" ) {
s = $.trim( s );
if ( s.length ) {
show = s;
}
}
s = gui.portlet.stick;
if ( typeof s === "string" ) {
s = $.trim( s );
if ( s.length ) {
stick = s;
}
}
s = config.foreign();
signal = show + "\n"
+ config.folder() + "\n"
+ ( s ? s + "\n" : "" )
+ LRF.type + " " + LRF.vsn;
dom = mw.util.addPortletLink( scope,
"#",
show,
"t-" + LRF.type,
signal,
shortcut,
stick );
$link = $( dom ).find ( "a" );
$link.click( LRF.find );
}; // gui.factory()
gui.file = function ( access ) {
// Launch hidden input gadget
// Precondition:
// access -- current local path
// Uses:
// this
// > .type
// < gui.$input
// < gui.$file
// < gui.storage
// (.found)
// 2013-12-14 [email protected]
if ( ! this.$input ) {
this.$input = $( "<input />",
{ type: "file",
id: LRF.type,
accept: ".css,.js",
multiple: true
} );
this.$input.hide();
}
$( "#" + LRF.type ).remove();
this.$file = this.$input.clone();
this.$file.change( this.found );
$( "body" ).append( this.$file );
this.storage = access;
this.$file = this.$file[ 0 ];
this.$file.click();
}; // gui.file()
gui.found = function () {
// Load interactively selected files
// Uses:
// > gui.$file
// > config.set
// basics.files()
// Remark: May be used as event handler -- 'this' is not accessed
// 2013-12-25 [email protected]
var collection, entry, s,
bag = gui.$file.files;
if ( bag ) {
collection = [ ];
for ( s in bag ) {
entry = bag[ s ];
if ( typeof entry.name === "string" ) {
collection.push( entry.name );
}
} // for s in bag
basics.files( collection, gui.storage, config.set );
}
gui.$file.remove();
}; // gui.found()
lang.favorite = function () {
// Guess user language
// Uses:
// this
// > lang.user
// >< lang.slang
// mw.config.get()
// 2012-12-19 [email protected]
var s;
if ( ! this.slang ) {
s = mw.config.get( "wgUserLanguage" ).toLowerCase();
if ( s.length > 4 ) { // Remove RFC 1766 subtag from code
if ( s.charCodeAt( 2 ) === 45 ) { // '-'
s = s.substr( 0, 2 );
}
}
s = this.user[ s ];
this.slang = ( s ? s : "en" );
}
}; // lang.favorite()
LRF.find = function ( access ) {
// Launch interactive file selection
// Precondition:
// access -- optional string with local path, overrides setting
// Uses:
// > config.storage
// > lang.slang
// > lang.texts.sucks
// config.filter()
// gui.file()
// lang.favorite()
// Remark: May be used as event handler -- 'this' is not accessed
// 2013-12-14 [email protected]
var storage = config.filter( access );
if ( storage ) {
gui.file( storage );
} else {
lang.favorite();
window.alert( lang.texts.sucks[ lang.slang ] );
}
}; // .find()
LRF.folder = function ( access ) {
// Retrieve or store current basic path
// Precondition:
// access -- string (optional) with folder path, to be stored
// empty string falls back to default setting
// Postcondition:
// Returns string with folder path
// Uses:
// config.folder()
// 2013-12-27 [email protected]
return config.folder( access );
}; // .folder()
LRF.loadFiles = function ( apply, access, accept ) {
// Try to load resources from local environment
// Precondition:
// apply -- identifier string, or Array with identifiers
// access -- string (optional), absolute file system base
// accept -- charset string, if any
// Uses:
// config.filter()
// config.foreign()
// basics.files()
// lang.favorite()
// 2013-12-14 [email protected]
var set,
storage = config.filter( access );
if ( storage ) {
switch ( typeof accept ) {
case "boolean" :
case "string" :
set = accept;
break;
default:
set = config.foreign();
} // switch typeof accept
basics.files( apply, storage, set );
} else {
lang.favorite();
window.alert( lang.texts.sucks[ lang.slang ] );
}
}; // .loadFiles()
LRF.setCharset = function ( accept ) {
// Set default charset
// Precondition:
// accept -- string with charset, to be stored
// empty to return to default = UTF-8
// Uses:
// config.foreign()
// 2013-12-14 [email protected]
config.foreign( ( accept ? accept : "" ) );
}; // .setCharset()
LRF.loaded = true;
config.fire();
mw.loader.using( [ "user",
"user.options",
"mediawiki.util" ],
config.firing );
}( window.mediaWiki, window.jQuery ) );
// Emacs
// Local Variables:
// coding: utf-8-dos
// fill-column: 80
// End:
/// EOF </nowiki> loadResourceFile/d.js