Commons:JavaScript styleguide
To keep the growing JavaScript code base on Commons readable, compact, well documented, free of redundancies, and as cross-browser compatible as possible a few rules have to be enforced.
Other reads:
- JavaScript code conventions for MediaWiki core
- Migration guide / What's new in MediaWiki JS
- JSPERF on MediaWiki.org
- JS/API/UI Extension Developer Library
Use whitespaces around operators
[edit]Whitespaces around operators increase code readability and make complex expressions easier to grasp.
Do not allow content change through URL-parameters
[edit]Something like automated deletion submits or edits should not be possible by URL. This is exploitable. Instead, use temporary cookies, the API, click-event-binding on elements. Changing the view i.e. starting a slideshow via URL should not cause harm.
Do not use the for-in loop on arrays
[edit]Use traditional for enumeration. Especially when looping over arrays returned by the getElementsBy…
function family the usage of for-in will render you script non-working on Safari browsers.
You may use:
$.each(array, function(''index'', ''element'') {
// Do something
// ''return;'' to skip (=continue) -- ''return false;'' to quit (=break)
});
Use jQuery event hook
[edit]When hooking an event handler to a DOM tree object use the functions jQuery('selector').on('eventname', function (e) { });
The usage of .mylistener
(please replace with your preferred, unique name) allows convenient unbinding without affecting other scripts. You could also use a named function instead of an anonymous one. This is especially useful while debugging. Most events have shortcuts like $('a').click(function (e) { });
. To prevent the default behaviour, use e.preventDefault()
. Do not try to assign function pointer to onevent properties directly!
Use mw.loader.load
[edit]When including other JavaScript files, it is best to use mw.loader.load. mw.loader.load
loads scripts asynchronously, so it won't slow down page loading as much. If you need to ensure that a dependency loads before some other code, use a hook or mw.loader.using.
Declare your variables
[edit]While some browsers let you get away with using new variable without declaring them with var
before, don't do it. Not properly declaring variables creates a slew of problems, trust me!
Use ES5
[edit]Gadgets and automatically-loaded JavaScript files (like MediaWiki:Common.js and Special:MyPage/common.js) must be written in ECMAScript version 5. Userscripts not loaded as a gadget can use ES6, but won't work correctly on Internet Explorer 11. Until support for Internet Explorer is dropped from MediaWiki, use ES5-compatible syntax wherever possible.
Don't be dumb about performance
[edit]JavaScript is slow, but there is no need to make it slower. When constructing for loops avoid complex functions in the loop header which will be executed at each iteration.
Bad:
// Performs a query to find all DIV elements each iteration
for (var i = 0; NavFrame = document.getElementsByTagName('div')[i]; i++ ) {
Aside from performance, this bad example will not fully iterate arrays with undefined, 0, or "" elements!
Good:
// Performs a query to find all DIV elements only once
var NavFrameList = document.getElementsByTagName("div");
for( var i = 0; i < NavFrameList.length; i++ ) {
NavFrame = NavFrameList[i];
Better:
var NavFrameList = document.getElementsByTagName("div");
for (var i = 0, len = NavFrameList.length; i < len; i++ ) {
NavFrame = NavFrameList[i];
This way, the object length doesn't have to be calculated each iteration. It also avoids infinite loops in case you're working on a (live) HTMLCollection
object.
How to construct URIs
[edit]If your script needs to construct a URI, always use mw.util.getUrl (make sure you add the mediawiki.util
to the list of dependencies of your script).
- Why
- A call to the CheckUsage tool through a URI for File:Forest & Bird headquarters.jpg, without encoding the page name: this looks for something named "Forest_".
- The same call with the page name properly encoded as "Forest_%26_Bird_headquarters.jpg" finds the uses of that image.
The same is true for all URI parameters, not just file names, but also user names or any other parameter.
You can use the function encodeURIComponent
to ensure that URI parameters are properly encoded. Or use jQuery.param
if you can to encode multiple parameters for a query string.
For example:
var foo = '//tools.wmflabs.org/example/foo.php?filename=' + encodeURIComponent(myVariable);
var bar = '//tools.wmflabs.org/example/bar.php?' + $.param({
filename: myVariable,
mode: 'list',
limit: 25
});
Add the talk page to Category:User scripts
[edit]Then other people will be able to find and use it.
Take a look at MediaWiki:Common.js
[edit]Make yourself familiar with the helper functions provided by Mediawiki and Commons. Avoid code duplication! When you discover a bug in a helper function or need extended functionality contact a developer, a fix of a global helper function will benefit more users than a local workaround.
If you were to use Ajax, for new scripts don't use the legacy ajax "Sjax" functions, like sajax_init_object(). Use jQuery's $.ajax instead (or its derivatives such as $.get, $.load or $.getJSON). Read more about those here. A few examples on MediaWiki.