JS2 Overview

Primary Motivation:
We need a script server to package language text into javascript. When a user invokes a 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 applications being run from that context and we only want to load what is absolutely necessary on initial page display/load.

Another example say your 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 include localized msgs in your Javascript
The include msgs for your javascript interface must be loaded. ideally near the header and with one call to loadGM.

note the json variable you pass to loadGM has to be valid JSON (not javascript) or php will complain. (valid json uses " for keys and values no newlines, javascript concatenations or comments)

How Does that get Translated?
Once you put your msg into the js, the magic translatewiki.net scripts run they will 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 Msg 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 parse the msg text and runs some code to interpret the json representation then does the dynamic replacement in the msg text.

the above code does not look fun...

 * Alternatively we try to avoid these templates usage in javascript msg (current "strategy")
 * Package in msgs with action results with the interface on the php side.
 * - This sucks because:
 * we can't as easily use the data api's directly / have to proxy all the data requests and do costly HTML generation server side. (obviously its creeper to just send the clients the data and have them do the dynamic transformations locally)
 * any interface improvements involve both php and js modification
 * its tricky with highly dynamic interfaces generated via javascript applications

Also bug thread: bug 19190

How to structure your Javascript Application
Ideally we want to keep initial page javascript load to a minimum.

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 and 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 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 everything 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.

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