Community Central
Community Central

importScriptURI vs. $.getScript

Hi Kangaroo! I'm going to revert the edit where you replaced $.getScript with importScriptURI. importScriptURI returns null when the script is already loaded. So to play it safe, you would have to write:

var script = importScriptURI('SomeScript.js'),
    scriptLoaded = function () {
        alert('SomeScript.js has loaded');
    };
if (script) {
    script.onload = scriptLoaded;
} else {
    scriptLoaded();
}

Other scripts might load SomeScript.js as well, so simply assigning a value to script.onload is risky:

var script = importScriptURI('SomeScript.js'),
    scriptLoaded = function () {
        alert('SomeScript.js has loaded');
    };
if (script) {
    if (script.addEventListener) {
        script.addEventListener('load', scriptLoaded, false);
    } else {
        script.attachEvent('onload', scriptLoaded);
    }
} else {
    scriptLoaded();
}

$.getScript covers all of the above:

$.getScript('SomeScript.js', function () {
    alert('SomeScript.js has loaded');
});

-- pecoes 05:09, August 24, 2012 (UTC)

ImportArticles misleadingly generic function name

ImportArticles sounds pretty generic for something that really only supports CSS and JS. Why use that name? Wouldn't something like ImportCSSorJS have been better? -- Fandyllic (talk · contr) 24 Aug 2012 6:53 AM Pacific

Hi Fandyllic! Haven't heard from you in ages! How are you?
Anyway: You should probably post that question in the Blog that introduced importArticles: w:User_blog:DaNASCAT/Update_Your_CSS_and_JavaScript_To_Speed_Up_Your_Wiki. My guess is - and I haven't really studied the ResourceLoader yet - that importArticles is used for a lot more than loading scripts and stylesheets... That's just a guess though. -- pecoes 15:44, August 24, 2012 (UTC)
From a user perspective, it can be a little confusing since it is mainly a way to add scripts or styles to a wiki. However, at a deeper level, these scripts and styles are actually articles, so in essence you are importing articles that contain scripts or styles. Kyle Florence (talk) 17:41, August 24, 2012 (UTC)

Using importArticles in MediaWiki 1.16.5

If you would like to use importArticles syntax in a MediaWiki 1.16.5 Wiki then you can place the following code at the top of your MediaWiki:Common.js page.

if (!window.importArticles) {
window.importArticle = window.importArticles = function (/*assets*/) {
	"use strict";
	var loader, asset, i, l, j, url, results = [], 
	    baseurl = 'http://community.wikia.com/load.php?mode=articles&missingCallback=importArticleMissing&only=',
	    sitename = 'w:c:' + (/^[A-Za-z\.+-]+:\/\/(.+?)\.wikia\.com$/).exec(wgServer)[1] + ':';
	for (i = 0, l = arguments.length ; i < l ; ++i) {
		asset = arguments[i];
		if (!$.isPlainObject(asset)) continue;
		if (!asset.articles) asset.articles = asset.article && [asset.article];
		if (!asset.articles || !asset.type || !asset.articles.length) continue;
		loader = ({script:importScriptURI, style:importStylesheetURI})[asset.type];
		if (typeof(loader) !== 'function') continue;
		j = asset.articles.length;
		while (j--) {
			asset.articles[j] += '';
			if (asset.articles[j].substr(0, 4) !== 'w:c:') {
				if (asset.articles[j].substr(0,2) === 'w:') {
					asset.articles[j] = asset.articles[j].substr(2);
				} else {
					asset.articles[j] = sitename + asset.articles[j];
				}
			}
			asset.articles[j] = asset.articles[j].replace(/ /g, '_');
		}
		url = baseurl + asset.type + 's&articles='
		    + encodeURIComponent(asset.articles.join('|'));
		results.push(loader(url));
	}
	return results;
};
(function(GlobalNotification) {
	"use strict";
	// 1.19 uses .show() for everything, 1.16 has .warn() + .notify()
	if (!GlobalNotification.warn) return;
	var files = {}, list = [];
	window.importArticleMissing = function(fail) {
		if (files[fail] !== 1) {
			list.push(fail);
			files[fail] = 1;
		}
		GlobalNotification.warn('importArticles could not import: "' + list.join('", "') + '"');
	};
	window.mw = { loader: { state: $.noop } };
})(window.GlobalNotification);
}

You can use this code in your global.js, wikia.js or monobook.js so that you can 'fast-load' your personal scripts across all Wikis without it breaking when you visit a 1.16.5 Wiki.

  • WARNING: importArticles cannot interwiki import from the Wiki you are on. importArticle({type:'script', article:'w:c:dev:DisplayClock/code.js'}); will work on every wiki except the dev wiki itself (where the script is located), you'll just get an error there.

importArticles in user scripts

I'm getting the impression that it's best to avoid importArticles in user scripts altogether. Especially in global ones because - as Kyle said - the speed advantage melts away since every wiki you go to has to create its own minified merge of your scripts.

So my suggestion would be to "anchor" all user scripts to Community Central. This is what my own global.js currently looks like:

((window.mw = window.mw || {}).loader = window.mw.loader || {}).state = window.mw.loader.state || function(){};
function importScripts () {
    $.getScript(
        'http://community.wikia.com/load.php?debug=false&only=scripts&mode=articles&articles=' +
        Array.prototype.join.call(arguments, '|')
    );
}
function importStylesheets () {
    $(document.head).append('<link rel="stylesheet" type="text/css" href="' +
        'http://community.wikia.com/load.php?debug=false&only=styles&mode=articles&articles=' +
        Array.prototype.join.call(arguments, '|') +
    '" />');
}

importScripts(
    'w:c:dev:Sine/code.js',
    'w:c:dev:FastDelete/code.js',
    'w:c:dev:AjaxUndo/code.js',
    'w:c:dev:PurgeButton/code.js',
    'w:c:dev:AjaxRC/code.js',
    'w:c:dev:InactiveUsers/code.js',
    'w:c:wikimarks:Client.js'
);

What do you guys think? -- pecoes 13:03, September 01, 2012 (UTC)

Can you clarify on what the benefit of "anchoring" the load.php to a single wiki is? The minified merge thing just happens *once* right? I.e. the first time you visit a new wiki, it has to create that merge. But on subsequent page loads, it's already done and doesn't need to happen again (for some time)? If that's the case, isn't the benefit of this "anchoring" thing rather minimal? — Mathmagician (message wall) 18:40, September 11, 2012 (UTC)
Where do you see the downside of this method? -- pecoes 18:46, September 11, 2012 (UTC)
I don't see a downside per se, I'm just not seeing very much of an upside. Isn't this just writing extra code for essentially no reason? — Mathmagician (message wall) 21:12, September 12, 2012 (UTC)
*sigh* At the time I wrote the code above, the help page stated:

Fast loading personal scripts may actually be slower when using importScriptPage because your browser will not be able to use its cache effectively. importArticles invokes load.php on the current Wiki which means that whenever you change to a different Wiki, the whole set of scripts is downloaded again. Using importScriptPage will download directly from the target wiki instead of the current one so your browser can cache the pages and only load them once.

Kyle removed that passage in the mean time and just a few hours ago Wladekb posted in the blog that scripts are cached for 10 minutes only. That makes the code I posted above moot. I updated the help page with that bit of info. -- pecoes 21:23, September 12, 2012 (UTC)

(Reset indent) Interesting. I wonder why they chose 10 minutes? It would nice for us if they gave the load.php url parameter(s) sorta like index.php's maxage and smaxage so that end-users have the option of controlling the caching a bit more. — Mathmagician (message wall) 04:47, September 13, 2012 (UTC)