JS2 Overview

JS2 is a new phase of javascript for mediawiki. It contains a script loader that minimizes page loading times by minifying, compressing, and grouping JavaScript files. It provides a unified approach to translation of user messages in JavaScript-based interfaces. It includes javascript helpers for dynamically loading JavaScript libraries that provide interfaces as needed rather than the traditional approach of loading all JavaScript in-line. And finally it promotes structuring javascript as highly modular reusable components, with clean separation of configuration, invocation binding and interface code.

Primary motivation
We need a script server to package language text into JavaScript. When a user invokes an interface component, say the add media wizard, we don't want to pull the entire interface code base and all the messages at once. Instead we just want to grab enough to display the current interface interaction. Once the user click on some tab, say the ‘archive.org search’, we then want to import the code to run the archive.org search and the localized messages specific to that interface component. In other words we don't want to package all the message text in the html output of the initial page because JavaScript interactions can result in many different interfaces being invoked from that context and we only want to load what is absolutely necessary on initial page display/load.

Another example: say you're on a view page. Then click “edit” on a section and we want to do that edit in-line (without going to another page). We now want to load the toolbar JavaScript all its dependences and localized msg text in a single gziped, minified and indefinitely-client-cached by SVN revision request. (Then we want to grab the actual section wiki-text via the API.)

How to use the ScriptLoader in your extension
You can use the ScriptLoader in your extension with some small modifications:

How to use the ScriptLoader as a gadget developer
As a gadget developer once JS2 is deployed you can write your JavaScript code to include localized messages. It also lets you group a large set of wikipage JavaScript files in a single request and have all the files be gziped, minified and localized.

Say for example you have quite a few:


 * You would probably want to include the urid parameter with a unique id per that script set. When developing if you include ?debug=true you will get a fresh set of the script each time.
 * More advanced usage would involve defined classes and associated JavaScript files, and make use of the  function. (More on that later once its fully supported for wiki-title namespace.)

How to include localized messages in your JavaScript
The include msgs for your JavaScript interface must be loaded. Ideally near the header and with one call to.

How does that get translated?

 * Right now you must also manually put the msg in your php localization file (unless your working on the core mwEmbed script set).
 * For mwEmbed scripts and eventually the extensions the translatewiki.net scripts should copy your English key msg into the the php file where its translated with the normal mediaWiki translation system. Then when you load your script via the scriptloader your msg_key will contain the localized msg text.

JavaScript messages text limitations
Right now we only support basic $1 replace… Things get tricky with contextual wiki-text type replacements. We aim to support a few more translation transformation types. This will involve packing the language replacement php code into something JavaScript can use to do contextual replacements.

For example with 1st 2nd numbers in English we have a mod 10 rule with 11th being an exception. If any of the msgs included the template to format numbers; then we would have php send out a json var something like:

Then the JavaScript parses the msg text and runs some code to interpret the JSON representation then does the dynamic replacement in the msg text.

The above code may look “no fun” but its probably better than the alternatives.

How to structure your JavaScript application
Js2 applications are ideally structured across a few files.

Lets again consider the example of in-line editing.

For every page we include some core helper functions the wikibits.js of JS2 is presently stored in mv_embed.js. Two functions we are using here are js2AddOnloadHook, mwLoad


 * js2AddOnloadHook is the JS2 version of addOnloadHook. It ensures jquery is available and binds it to $j – to avoid conflicting with other JavaScript libraries that use $; you can still use $ if you wrap your code in the jQuery context (like all the jQuery plugins do).
 * mwLoad function lets us load classes. It will only load classes that are not yet defined. It uses the scriptloader to map class names to JavaScript files and group requests. Say one widget on the page already loaded $j.ui and $j.slider then your app needs $j.ui, $j.slider and $j.fish, your mwLoad call will know to only send a request to the script server for $j.fish. (or directly load the $j.fish.js if scriptloader is off). Once the class are ready it fires the callback (the second argument)

Example
So for our in-line editing example:

In some file we include on all view pages say inlineSectionEdit.js (remember we add JS code with the ScriptLoader so the snippet of code is not a separate request). We include something like the following:

This keeps the core JavaScript to a minimum and loads things as needed and stores the complexity in the reusable JavaScript classes. You can see this method used on scripts in the root of the js2 folder. For info on how configuration could work see: bug 20720 comment about script order