ResourceLoader/Migration guide (users)

Through time the core JavaScript functions and HTML output improves functionality, introduces new methods, deprecates or changes in other aspects. This document intends to highlight the most common problems that need to be fixed.


 * For an overview of what is currently available in ResourceLoader, check out ResourceLoader/Modules.
 * See also ResourceLoader/Legacy JavaScript for a table with replacements for mediawiki.legacy functions (wikibits, ajax.js etc.).
 * Problems with gadgets? Check if it's listed below. If so, ask a sysop to update it on your wiki.
 * You can help with the migration on Wikimedia projects. See the 2011 Resource Walker, which also has useful tools to ease migration.

= MediaWiki 1.28 =

Background
Since early 2011, gadgets with styles (both "only styles" and "styles and scripts") had their styles loaded twice. T42284 and https://gerrit.wikimedia.org/r/308096 address this bug.

What's new
This bug was addressed by adding support in the Gadgets extension for the ResourceLoader "type" feature. This allows gadget developers to configure how the module should be loaded Gadgets with only styles, default to. Gadgets with only scripts default to. Gadgets with both scripts and styles currently default to loading twice (just like the bug was fixed). When this happens, a warning is shown in the console that asks the developer to provide the desired type.
 * type=styles: Load module styles via . (Loads early, applies styles before skin and page are ready, also works when JavaScript is disabled.)
 * type=general: Load module scripts and/or styles via . (Applies styles after the skin and page are ready, right before JS execution, has better caching.)

Once we've given gadget developers enough time to migrate, we make  the default for gadgets with both scripts and styles.

How to migrate
If you're seeing this warning, it means your gadget contains both scripts and styles. Here is what to do: As you can see, in most cases the solution is "type=general." And in a few weeks, this will become the default and we will never again load styles twice.
 * 1) If the styles in your gadget are there to provide styling for things created by the gadget, add " " to your gadget definition ("MediaWiki:Gadgets-definition").
 * 2) If the styles in your gadget are there to provide styling for things that are part of the skin or on the page, then the scripts and styles do not belong together in the same gadget. Convert the gadget to two separate gadgets. One gadget that is styles-only, and the other with the scripts. If the scripts gadget also has some styles, be sure to set " " on that one.

The reason we will do this in a few weeks and not now, is because of point 2 above. Changing these mixed gadgets to type=general now would cause some styles to load too late and cause a "flash of unstyled content".

= MediaWiki 1.27 =

Legacy default: mediawiki.util
The option was removed. This option allowed third-party MediaWiki administrators to re-enable the unconditional preload of  by default for all users (for backwards compatibility). It was disabled by default since MediaWiki 1.26, and has been disabled on Wikimedia wikis since 2014. Extensions, skins, gadgets and scripts that use the  module must express a dependency on it.

bits.wikimedia.org
The internal Wikimedia domain "bits.wikimedia.org" was deprecated sometime mid-2015. The following common paths should be migrated to avoid breakage once the domain is decommissioned (T107430).
 * →  . Moved back to local domains, alongside   and others.
 * → : Moved to local domain, sharing a hostname-agonistic Varnish cache.
 * → : Specific versions can now be accessed through the regular script path. Wikimedia's multiversion entry point automatically serves the the file from to the wikis' current MediaWiki version. (T99096)
 * → : Specific versions can now be accessed through the regular script path. Wikimedia's multiversion entry point automatically serves the the file from to the wikis' current MediaWiki version. (T99096)

= MediaWiki 1.26 =

Legacy gadgets
Gadgets are now required to use ResourceLoader. For many Gadgets, migrating to ResourceLoader will be as easy as adding  to its definition on MediaWiki:Gadgets-definition. If after adding that, the gadget is not working properly, consult the rest of this page to look for functionality that may have been removed since the gadget was last maintained. If you run into any issues or find features that don't work without a clear way of making it work, please reach out to MediaWiki developers and fellow gadget authors on the |talk page, via IRC, or on the wikitech-l mailing list.

Global variables are not global
When ResourceLoader loads a gadget script, it is not executed in global context. This means that local variables you define in the script are actually local, and not assumed to be also global. They are local to the function your code is wrapped in. It's best to modularize your code to avoid using globals, see "Globals" in MediaWiki's JavaScript coding conventions. However, if you need to export a variable to the global scope, you can explicitly assign them as  properties. For example:

Code within your gadget can access foo and bar. Code outside the gadget (or code evaluated as separate programs, such as legacy onclick handlers), can only access Quux..

, ResourceLoader debug mode still executes scripts in global scope (T64605), so your code may seem to work fine in debug mode but be broken in regular mode.

Font mw-geshi
The font-size of  was often too small by default due to a font-family CSS bug. This was fixed in MediaWiki 1.26 (see (T28204).

The,  ,   and related classes no longer exist. Related code such as the following can be safely removed:

Inline scripts
To inject JavaScript inline, use  to wrap the JavaScript code in an anonymous function that can access MediaWiki-related objects properly, and   to add the results to the page source for execution.

For example:

= MediaWiki 1.24 =

Internet Explorer
Browser support for Internet Explorer 6 and 7 changed from Grade A to Grade C. This means JavaScript is no longer executed in these browser versions. See Compatibility for details.

= MediaWiki 1.20 =

New diff styles
This version introduces a new diff view, greatly improved in clarity especially for whitespace and other small changes and colour-blind users. If your wiki has custom CSS for the diffs, they may be in conflict with the new style (as happened on [//pt.wikipedia.org/w/index.php?title=MediaWiki%3ACommon.css&diff=29858952&oldid=28922245&uselang=en ptwiki] and [//sr.wikipedia.org/w/index.php?diff=5578051&oldid=5533214&uselang=en srwiki]). You are recommended to remove the old code (or if still wanted by some users, update it to work with the new layout and create a gadget for it so that users can opt-in to it still).

= MediaWiki 1.19 =

wikitable style updates
As of MediaWiki 1.19 a few bugs have been fixed with the  class (see 30485 and 33434 for more info). If your wiki maintains a legacy synonym of this class (e.g. " ") you need to update its CSS to match the current style in core.

The current style as of 1.19 can be found [//github.com/wikimedia/mediawiki/blob/1.19.24/skins/common/shared.css here]. Copy those rules to your wiki and replace "wikitable" with the synonym ([//nl.wikipedia.org/w/index.php?title=MediaWiki:Common.css&diff=29814645&oldid=29702942 example for nl.wikipedia]).

If your wiki doesn't keep something like this, then no update is necessary and everything should take care of itself.

File page checkered background
The checkered background often applied to transparent file namespace pages is now part of the software. Local rules like the following should be removed (because they are redundant, and actually cause an additional unnecessary HTTP request for the image)

Trackbacks
Trackbacks were removed from MediaWiki core, so any styling targeting  can be removed.

= MediaWiki 1.18 =

Protocol-relative urls

 * This change only applies to Wikimedia Foundation wikis.

As of MediaWiki 1.18 there is native support for protocol-relative wiki installations. This means that a wiki could be accessible from both http://example.org and https://example.org. To make it possible to a share a common cache for as much as possible, we make use of a technique called protocol-relative urls. Although browsers have supports this for ages, script writers generally aren't very familiar with it until fairly recently. Briefly explained, this means that  when on " https://example.org " will be automatically expanded by the browser to https://meta.wikimedia.org. This is much like (for example)  or , which are are automatically expanded to " http://mediawiki.org/w/foobar.jpg ".

Depending on how the scripts were written this may require some changes to be made to your scripts. If you use the following method to detect whether the script is executed on a certain wiki, this change will break your script: because wgServer is now " ". For a few years there has been another config variable, called " ". You should use that instead to differentiate wikis, like: If you must use wgServer, then simply change it to:

"Enabled by default" (Gadgets extension)
As of the version of the Gadgets extension at the MW 1.18 branchpoint, there is a new feature that allows a gadget to be opt-out instead of opt-in based. By setting " " (or adding " " to an existing section) the gadget will be enabled by default for everybody, unless a user has specifically opted out by unticking the checkbox on Special:Preferences.

Note that this also loads it for all anonymous users. Gadgets that are only for logged-in users should be additionally restricted by, for example, requiring certain user rights.

See also Extension:Gadgets.

mw.util.wikiScript
The actual paths have not changed, but getting the path to the API and index.php has become a lot easier. This also makes the code more portable as it has no hardcoded wiki-specific paths.

This is how it used to go in many gadgets.

Instead use something like one of the following:

You may also want to use  to automatically escape and create things properly in the query string:

You can even use the  option of, that abstracts away the need to deal with the query string entirely:

= MediaWiki 1.17 =

jQuery

 * See also jQuery

As of 1.17 the jQuery library is loaded by default on all MediaWiki pages. Each MediaWiki release will keep it up to date with the latest version of jQuery. If you used to load jQuery from within your script, (e.g. from ajax.googleapis.com), make sure you remove that. If you load jQuery more than once on a page, it overwrites the earlier version. Other scripts break because they may not work with an older version of jQuery.

Also, by overwriting the jQuery object, any plugins that were bound to that object are also lost.

Global identifier " " has been deprecated. Use  or   instead.

Tabs (vector)
In 1.17 the HTML construction for the navigation tabs has changed from  to. The most common situation in which this causes problems is where scripts assume the presence of the span element when, for example, customizing the tab for "Main Page". Before 1.17 this usually meant that wikis had a different implementation for Monobook and one for Vector (or only one for each and the other was distorted).

Please use or refer to Snippets/Main Page tab for a script that will work in both Vector and Monobook for 1.17.

Adding portlet links
The legacy function  has been rewritten in the mediaWiki JS Utility library as. The syntax and argument order is fully backwards compatible. The differences
 * Support for all core skins now
 * Support for simple id-selector as 'nextNode' (see documentation for details).

Some wikis may have re-defined / overwritten the  function to support a few extra skins. This is no longer needed. The function definition should be removed and calls adjusted to.

The legacy version of  has been preserved as-is in case some edge cases would behave differently (for that reason the   does not redirect to mw.util.addPortlinkLink)

Toolbar
The legacy array  has been refactored into the   library. The global array still exists in wikibits to avoid fatal errors but is no longer used due to race conditions. Code may run too late when the toolbar already exists. Using  will work always, even if the toolbar has already been created.

See mw.toolbar Documentation.

Note that mw.toolbar, just like the old mwCustomEditButtons array, are associated with the classic toolbar. The current default wikitext editor is WikiEditor, which has its own API. See Extension:WikiEditor/Toolbar customization for more information.

Sajax
The legacy functions such as  have been deprecated. Instead, use  or   (from the mediawiki.api module).
 * mediawiki.api documentation
 * jQuery.ajax documentation

Client testing
Checking which browser, platform, layout engine etc. has should now be done with jQuery.client.
 * ,  etc. are deprecated
 * No need to  etc.

Sysop script
New in MediaWiki 1.17 is a user groups module that can automatically load scripts and styles from the MediaWiki namespace for a particular user group. For example, if the wiki has MediaWiki:Group-sysop.js, this script is automatically loaded for all users in that group.

This should obsolete customisations wikis may have with regards to loading MediaWiki:Sysop.js with importScript inside Common.js.

mw.loader
If you need certain scripts like jQuery UI's dialog or datepicker, instead of doing something like:

Instead use this:

Or if you need to delay initialization until document.ready:

Migrating user scripts
Contrary to, Wikibits.js functions such as   tend to be widespread among user script. Larger wikis may want to implement their own  function in MediaWiki:Common.js to make migration simpler. MediaWiki:Common.js is loaded as part of the "site" module which is guaranteed to load before the "user" module.

Dependencies
When a script depends on another module, such as  or , you will need to declare this as a "dependency". This is because modules are loaded on-demand and asynchronously (in consecutive order: all at the same time), so a script needs to make sure a module has been loaded before it can use its methods. On-site modules, like gadgets, have a registry to declare these dependencies. For user scripts, one has to wrap code with.

While this has been required since 2011, many scripts have continued to work without declaring their dependencies. Scripts may have worked before by accident as long as at least one user script (that used the same methods) did declare their dependencies and happened to load earlier.

With MediaWiki 1.19, page view performance has been optimised to use fewer modules by default. This makes it increasingly more important to declare the dependencies. Otherwise, your script may fail because any of the 1000+ modules you might refer to in your code would not be loaded yet. Loading everything all the time would be much too slow.

The only two base modules that are always present are  and.

In practice
Use  to declare any modules that you need before executing the contents of "function". You can pass multiple modules as an array of strings.

Global wg variables
As of MediaWiki 1.17, the global config variables are deprecated. Rationale to clear the global namespace, working towards a reality where most of the core libraries will be object oriented as part of the  object. Configuration is managed through an instance of  in. It is also supporting the behavior of more script executing in their own local/private scope as opposed to the global scope.

Legacy globals will be kept for backwards compatibly, but people should start migrating so that they may removed in a future version of MediaWiki (Bug 33837).

More info: ResourceLoader/Default modules

Ready, onload, hook
Check JavaScript deprecation overview for " ". Use  instead, or   for short.

Headings overflow hidden
for any of h1, h2, h3, h4, h5 and/or h6 can be safely removed from stylesheets as this is now part of the core.

Italic redirects
Links to redirects appear italicized on Special:AllPages, Special:PrefixIndex, Special:Watchlist/edit and in category listings

.allpagesredirect, .redirect-in-category, .watchlistredir { font-style: italic; }

wpSummary
Per 20276, 's   is now set in Vector as well (instead of just Monobook).

UsabilityInitiative no more
As of 1.17 the functionality developed by the UsabilityInitiative has been extracted to stand-alone extensions. Buttons like "#pt-optin-try" no longer exist. You can enable/disable these functions like other extensions via Special:Preferences.

Scripts and styles doing things like "HideUsabilityOptIn": should therefore be deleted entirely as the button no longer exists.

Preformatted JS/CSS pages
It's no longer useful to wrap these pages in  or    etc. In newer versions of MediaWiki, these pages are rendered as code automatically (including syntax highlighting when available). See also bug 4801.

Table sorter
The old table sorter in  was removed in favour of.

Variables such as, and functions like   and   no longer exist.

= MediaWiki 1.16 and before =

importScript
As of 2008, the function  is part of MediaWiki. Wikis that have defined this function themselves may remove that. It will automatically use the new function. This also goes for,   and.

Make sure that before removing such local function though that the function signature is compatible with the core function and that there are no additional locally implemented arguments or features that core doesn't have (or vice versa). When in doubt, either keep it untouched or replace the function body with a compatibility call to the new core functionality (thus re-routing it instead of removing it entirely).

addPortletLink
As of 2008, the function  is part of MediaWiki. Many wikis and gadgets have created functions like,  ,   etc. these should be removed as they most likely don't support different skins (ie. only Monobook, not Vector or older skins). Be sure to check the syntax as there is no way of knowing the creator of those local functions used the same parameter order.
 * Note: The global function was deprecated in 2012 and moved to the mediawiki.util module as

appendCSS
As of 2008, the function  is part of MediaWiki. Wikis that have defined this function themselves may remove that. It will automatically use the new function.
 * Note: The global function was deprecated in 2012 and moved to the mediawiki.util module as

html lang
This bugfix is obsolete as MediaWiki does this correctly by default. (example)

wikitable
The  CSS class is part of MediaWiki. Wikis that previously defined this class in their  should remove it. Do check if the wiki has any customisations that should be retained (e.g. different background-color, or font-size).

plainlinks
The  CSS class is part of MediaWiki. Wikis that previously defined this class in their  should remove it.

Many wikis defined this functionality under a different name:. Once any usage is replaced with "plainlinks", it may also be removed. (Search with .)

mw-plusminus
The CSS classes,  , and   are now implemented by MediaWiki.

External URLs
Icons for protocols like [ HTTP], IRC, etc. and file types like [ PDF] are now supported by MediaWiki.

Tooltip and accesskeys
Scripts like  are ignored. It was deprecated in 2009. The function akeytt no longer exists. Tooltips and accesskeys are now supported from core. The most common values that wikis used with ta[] are the same that have now been integrated into the core (ie. "." for "my user page"). They can still be modified, if really needed, by sysops in MediaWiki-messages (no need for JavaScript workarounds anymore).

As of MediaWiki 1.19 the global dummy placeholder  was removed from. Code trying to add members to it will likely emit an exception.

= Good practices = Anything not related to a particular MediaWiki version that should be noted as it is often done in a way that could or must be better.

Avoid document.write
Do not use, will cause blank pages; instead, use jQuery to modify the document (adding elements, changing things etc.) and the import functions to load external resources. (importStylesheet, importScript, mw.loader.load, $.getScript).

Example: replace with

Event binding
Binding events and callback functions is very tricky and it is hard to implement it in good cross-browser way that supports all browsers MediaWiki supports too.

As a good practice it is recommended to use jQuery methods for event binding. See the JavaScript deprecation overview on "addHandler" for examples on more info for this.

Encoding and escaping
When working with regexes, user input and/or urls always encode and escape!


 * Regexes:  (provided by mediawiki.RegExp module)
 * HTML:  (provided by default)
 * URL:  (for normal values),   for page titles, does not escape colons  and slashes (/). (provided by mediawiki.util module)

Prototyping
Do not extend native JavaScript constructors with non-standard methods (e.g.,  ,   etc.). Depend on the  module to preload (in older browsers) standard polyfills for JavaScript 1.8 and ECMAScript 5 methods. See also Annotated ES5 specification and es5-shim.

Getting URL parameter values
Functions like getURLParamValue, getParamVal, getParamValue, etc. are very common across wikis. Some are better than others (i.e. what if a parameter appears twice? (it should return the last one), does it ignore anything after the #tag?). As of 1.17  is available everywhere and takes these factors into account. Perform a full-text all-namespace search for these function names. If they are widely used perhaps make a note about it in the local village pump. Any site-wide scripts should be updated to use the mw.util function. If there are any serious problems with the local implementation (like not escaping the value for regex), it may be wise to redirect the function:

Avoid use of !important
CSS stands for Cascading Style Sheets. Cascading means what comes later overwrites what came earlier. In most cases there is no need to use. See the following example: Text inside  will now be green.

Keep gadgets central
Gadgets that are highly used across wiki (like Gadget-LiveClock.js) should be kept central (ie. Meta-Wiki or MediaWiki.org). The following is a list of gadgets that are centrally stored and
 * made compatible with 1.17
 * work in Monobook and Vector
 * wiki independent (ie. can be loaded on Commons, Wikipedia, Wiktionary or John Doe's Wiki without problems)

Sysops: To update a gadget on your wiki:
 * Check on your wiki and find the gadget in question.
 * The part after the pipe is the scriptname (eg. "").
 * Go to (eg. MediaWiki:Gadget-UTCLiveClock.js)
 * Remove everything and replace with the code in they grey area below the scriptname in the list. For an example on how this is done, check out [ LiveClock on Simple Wikipedia].

Gadgets

 * UTCLiveClock
 * contribsrange
 * modrollback
 * QPreview
 * ShortDiff
 * lastdiff Check Snippets/Last revision action
 * HotCat
 * WikiMiniAtlas
 * Navigation Popups (MediaWiki:Gadget-popups.js and MediaWiki:Gadget-popups.css respectively)

jQuery optimization

 * Optimization for jQuery
 * jQuery for Performance & Common mistakes
 * http://www.smashingmagazine.com/2008/09/16/jquery-examples-and-best-practices/

Use API instead of index.php
XML retrieved by invoking GET and POST methods on index.php is incompatible with HTML 5, which is the default as of 1.16 (and WMF sites since 17th of September, 2012). You should update code to use api.php, JSON format and jQuery.ajax immediately. Use the ResourceLoader modules that do this for you to simplify interactng with the API, including mediawiki.api.

A temporary fix for problems with DOM parsing of XML retrieved via AJAX: For example the method  on a XML object from Mozilla's DOMParser stopped to work as before. Replacing the  with   might work without many other changes to your code. Updating your script to the above mentioned methods is strongly recommended, however.

Conventions

 * Manual:Coding conventions/JavaScript - keep if statements with brackets, use proper indention (block B in block A is indented more, visualize the tree), etc.
 * Manual:Coding conventions/CSS - combine selectors, remove stuff now in core, etc.