User:PerfektesChaos/js/loadResourceFile/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. |
Documentation for this user script can be added at User:PerfektesChaos/js/loadResourceFile/d. |
/// User:PerfektesChaos/js/loadResourceFile/d.js
/// 2018-08-24 PerfektesChaos@de.wikipedia
// 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 PerfektesChaos@de.wikipedia
"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 PerfektesChaos@de.wikipedia
// ///////////////////////////////////////////////////////////////////
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
var r;
lang.favorite();
switch ( lang.slang ) {
case "de" :
r = "de.wiki.x.io";
break;
default:
r = "en.wiki.x.io";
} // 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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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( "http://en.wiki.x.io"
+ "/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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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 PerfektesChaos@de.wikipedia
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