JS2 Overview

JS2 is a PHP-based JavaScript embedder which provides a simple interface for including JavaScript in pages from MediaWiki and extension code, and provides a unified approach to translation of user messages in JavaScript-based interfaces. It contains a script loader that minimizes page loading times by minifying, compressing, and grouping JavaScript files. It can also dynamic load JavaScript as it is needed, rather than the traditional approach of loading all JavaScript immediately.

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 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 js to include localized msgs. 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 mwLoad(['set', 'of' 'class'], function{ //code to run now that the classes are loaded}); function. ( more on that later once its fully supported for wiki-title namespace )

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( json_key_msg_pairs ).

note the json variable you pass to loadGM must 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?

 * 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 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 may look "no fun" but its ~probably~ better than the alternatives.

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, 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.

Configuration vars

 * NOTE you should definitely "enable" the file cache and or have your wiki behind a proxy
 * if not this results in minnification, localization and gziping on every javascript request (not fun)
 * if you can't enable the file cache its better to use JS2 without the script-loader. (its built in a way that it can fallback to normal js includes)