User:Saftzie/global.js
ShoutWiki — express yourself and be heard!
Jump to navigation
Jump to search
Note: After saving, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
(function ($) {
'use strict';
var
global;
// short-circuit running this file, Wikia-style, usually for debugging
if (/(?:\?|&)useuserjs=0(?:&|$)/.test(location.search)) {
throw 'Exiting on useuserjs=0';
}
// define load states for global/common/skin js
(window.user = window.user || {}).state = user.state || {};
// global.js
global = user.state.global = user.state.global || {
last: null,
defer: $.Deferred()
};
if (global.last === 'global') {
throw 'Exiting on repeat load'; // prevent repeat loading
}
global.last = 'global';
}(jQuery));
//----------------------------------------------------------------------
// define user.util module
(window.user = window.user || {}).util = user.util || (function () {
'use strict';
var
self = {
// drop-in for mw.util.getParamValue
getParamValue: function (key) {
if (typeof key === 'string') {
return (query[key] !== undefined) ? query[key] : null;
} else {
throw new TypeError('key is not a string');
}
}
},
query, s, t, i;
// init getParamValue
query = {};
s = location.search.substr(1).split('&');
for ( i = 0 ; i < s.length ; ++i ) {
t = s[i].split('=');
if (t[1]) {
query[t[0]] = decodeURIComponent(t[1].replace(/\+/g, ' '));
}
}
return self;
}());
//----------------------------------------------------------------------
/**
* Description:
* Load scripts/stylesheets from wiki articles
*
* Version 1.0: 15 May 2015
* Original version for Wikipedia use
* Version 2.0: 6 Jul 2016
* Rewrite with jQuery.Deferred; Implement using
* Version 2.1: 5 Sep 2016
* ArticlePath/ScriptPath switch; Additional logging
*/
(window.user = window.user || {}).loader = user.loader || (function (mw, $) {
'use strict';
var
self = {
message: new Date().toISOString() + ' Initializing',
version: '2.1: 5 Sep 2016',
useCanPath: false, // canonical vs "pretty" article path
load: load,
using: using
},
// use "pretty" path so .css names show in style inspector
urlBase1 = mw.config.get('wgArticlePath') +
'?action=raw&ctype=$2',
// use canonical path when, e.g., the web server blocks pretty paths
// like WikiMedia blocks action=raw for any title with "." in it
urlBase2 = mw.config.get('wgScriptPath') +
'/index.php?title=$1&action=raw&ctype=$2',
wikiDomain = mw.config.get('wgServerName').split('.'),
wikiSubdomain = [],
registry = {},
useCanPath; // instance version of self.useCanPath
// get a single title, either JavaScript or CSS
// return a promise, possibly used by $.when
function getTitle(title, wiki) {
var
type, url, t;
if (/css$/.test(title)) {
type = 'text/css';
} else if (/js$/.test(title)) {
type = 'text/javascript';
} else {
self.message += '\n' + new Date().toISOString() +
' Invalid type: "' + title + '" must be css or js';
return $.Deferred().reject().promise();
}
if (useCanPath) {
// "wiki" encode the article title, skips encoding some characters
url = urlBase2
.replace('$2', type)
.replace('$1', title.replace(/\s/g, '_')
.replace(/[^$,/:;@]/g, function (c) {
return encodeURIComponent(c);
})
);
} else {
url = urlBase1
.replace('$2', type)
.replace('$1', encodeURI(title.replace(/\s/g, '_'))
.replace(/\?/g, '%3F') // title "?" must be encoded
);
}
if (wiki !== wikiSubdomain) {
url = '//' + wiki + wikiDomain + url;
}
switch (type) {
case 'text/css':
t = document.createElement('link');
t.rel = 'stylesheet';
t.href = url;
$('head').append(t);
t = $.Deferred().resolve().promise();
self.message += '\n' + new Date().toISOString() +
' getTitle :: Added link element: ' + title;
break;
case 'text/javascript':
t = $.ajax(url, {
cache: true,
crossDomain: true,
dataType: 'script'
}).promise();
self.message += '\n' + new Date().toISOString() +
' getTitle :: loading script: ' + title;
t.done(function () {
self.message += '\n' + new Date().toISOString() +
' jQuery :: load succeeded: ' + title;
}).fail(function () {
self.message += '\n' + new Date().toISOString() +
' jQuery :: load failed: ' + title;
});
break;
}
return t;
}
// load wiki articles as scripts or styles
// articles = string or array of strings
// which are titles of articles to load
// JavaScript articles terminate with js
// stylesheet articles terminate with css
// titles can be prepended with the form "u:<host>:"
// to designate a different host in the same domain
// path (optional, default: self.useCanPath) = Boolean
// to use canonical or "pretty" article path
// return an array of promises
function load(articles, path) {
var
d = [], // the array of promises, one element per title
wiki, title, t, i;
// enforce Boolean condition on self.useCanPath
if ((self.useCanPath !== true) &&
(self.useCanPath !== false)) {
self.useCanPath = false;
}
// enforce Boolean condition on path argument
if ((path === true) || (path === false)) {
useCanPath = path;
} else {
useCanPath = self.useCanPath;
}
if (typeof articles === 'string') {
articles = [articles];
} else if (!$.isArray(articles)) {
self.message += '\n' + new Date().toISOString() +
' load :: articles is not an array: ' + typeof articles;
return [$.Deferred().reject().promise()];
}
for ( i = 0; i < articles.length; ++i ) {
title = articles[i];
if (typeof title === 'string' ) {
t = title.split(':');
if ((t.length > 2) && (t[0] === 'u')) {
wiki = t[1];
title = t.splice(2).join(':');
} else {
wiki = wikiSubdomain;
}
t = wiki + ':' + title;
if (registry[t]) {
self.message += '\n' + new Date().toISOString() +
' load :: already registered: ' + title;
} else {
registry[t] = getTitle(title, wiki);
}
d[i] = registry[t];
} else {
self.message += '\n' + new Date().toISOString() +
' load :: title ' + i + ' is not a string: ' + typeof title;
d[i] = $.Deferred().reject().promise();
}
}
return d;
}
// load wiki articles as scripts or styles
// on the condition that the prerequisites are loaded
// prereqs = string or array of strings
// which are titles to load before articles
// articles = string or array of strings
// which are titles of articles to load
// path (optional, default: self.useCanPath) = Boolean
// to use canonical or "pretty" article path
// return a promise
function using(prereqs, articles, path) {
if (typeof prereqs === 'string') {
prereqs = [prereqs];
} else if (!$.isArray(prereqs)) {
self.message += '\n' + new Date().toISOString() +
' using :: prereqs is not an array: ' + typeof prereqs;
return $.Deferred().reject().promise();
}
if (typeof articles === 'string') {
articles = [articles];
} else if (!$.isArray(articles)) {
self.message += '\n' + new Date().toISOString() +
' using :: articles is not an array: ' + typeof articles;
return $.Deferred().reject().promise();
}
// load the articles when the prereqs complete
// when() wants a list of individual arguments, not an array, so apply it
return $.when.apply(null, load(prereqs, path)).done(function () {
// when() resolves when the prereqs are loaded, not when they've run
// so enqueue load(articles) to give prereqs a chance to run
setTimeout(load, 0, articles, path);
}).promise();
}
// break the current qualified name
// into subdomain and domain names
while (wikiDomain.length > 2) {
wikiSubdomain.push(wikiDomain.shift());
}
wikiSubdomain = wikiSubdomain.join('.');
wikiDomain = '.' + wikiDomain.join('.');
self.message += '\n' + new Date().toISOString() +
' subdomain = ' + wikiSubdomain +
', domain = ' + wikiDomain;
return self;
}(mediaWiki, jQuery));
//----------------------------------------------------------------------
// main procedure
(function (mw, $) {
'use strict';
var
wgCanonicalSpecialPageName = mw.config.get('wgCanonicalSpecialPageName'),
wgNamespaceNumber = mw.config.get('wgNamespaceNumber'),
blankSpecial = user.util.getParamValue('blankspecial'),
idDiv = user.util.getParamValue('divid'),
js = user.util.getParamValue('js'),
articles = [];
// add a div to Special:BlankPage to make other stuff easier
if ((wgCanonicalSpecialPageName === 'Blankpage') &&
(blankSpecial === 'userjs')) {
if (idDiv !== null) {
$('#mw-content-text').empty().append('<div id="' + idDiv + '"></div>');
}
if (js !== null) {
user.loader.load([js]);
// only MediaWiki-supplied skins supported
$('#firstHeading').text(js);
}
}
articles.push('u:www:User:Saftzie/ui.wikimarks.css'); // [[User:Saftzie/ui.wikimarks.css]]
articles.push('u:www:User:Saftzie/ui.wikimarks.js'); // [[User:Saftzie/ui.wikimarks.js]]
articles.push('u:www:User:Saftzie/ui.clock.css'); // [[User:Saftzie/ui.clock.css]]
articles.push('u:www:User:Saftzie/ui.clock.js'); // [[User:Saftzie/ui.clock.js]]
if ((wgNamespaceNumber === 2) || (wgNamespaceNumber === 3) ||
(wgCanonicalSpecialPageName === 'Contributions')) {
articles.push('u:www:User:Saftzie/UserInfo.js'); // [[User:Saftzie/UserInfo.js]]
}
if ($('#wpTextbox1').length) {
articles.push('u:www:User:Saftzie/ui.tabinsert.js'); // [[User:Saftzie/ui.tabinsert.js]]
}
if (articles.length) {
user.loader.load(articles);
}
// enforce global -> common -> skin js serialization
user.state.global.defer.resolve(); // common.js is next
}(mediaWiki, jQuery));