Commons:JavaScript styleguide

From Wikimedia Commons, the free media repository
Jump to: navigation, search

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:

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 importScript(pageName)[edit]

When including other javascript files do not use the document.write("<script>... construct, use the more compact and readable importScript(pageName) function.

Use var[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!

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

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 = '//toolserver.org/~example/foo.php?filename=' + encodeURIComponent(myVariable);
var bar = '//toolserver.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.org.