Extension:Ajax

Ajax allows to run Ajax applets by visiting a special page which embeds a JavaScript page from the system message space. The page with the applets are built on the fly by a minimal preprocessor. This adapts the JavaScript according to defined system messages and makes data from the request available to the script. The extension itself does not use Ajax but prepares the necessary infrastructure for localization and adaption of such solutions. The name is somewhat of an misnomer, but is chosen to signal very clearly to the reader its intended usage.

''Note: This extension is experimental, it is still under development and it is not safe enough for general use on an open wiki. If you use it you should upgrade as soon as possible.''

Installation
As is standard with other MediaWiki extensions, you may install this extension by extracting the extension somewhere (usually the extensions folder), and adding require_once( '/path/to/Ajax/Ajax.php' ); to LocalSettings.php.

Usage
The special page is called as any other special page, but with an additional JavaScript-page from the MediaWiki-space. Typically a call would be  where the JavaScript is expected to be found on the page   and the title for the page should be on page. The suffix must be present, if not the special page will give an error message. Likewise the title page must be present.

The special page uses a very limited cpp-like language to augment JavaScript. It concists of the pragmas #ARGV, #DEFINE and #INCLUDE, and the control structures #IFDEF, #IFNDEF, #ELSE and #ENDIF. Each such pragma should be on a separate line. The parser is strictly line oriented and is not able to detect interactions with the surrounding JavaScript code.

Note that all pragmas interacts with system messages, and that the namespace MediaWiki therefore should be protected from all you don't trust. Usually this namespace has an implicit protection and is only available to sysops, if you don't trust your sysops then you can't use this extension.

Argv
A request can have parameters, which can be imported into the script, that is, a special construct can import it and bind it to a JavaScript variable. The process is initiated through using the pragma #ARGV, optionally in combination with keywords for type and source. The first set of keywords will trigger use of internal data type conversion functions, the later will trigger checks on how the data was delivered. In addition a variable name must be specified, the parameter name enclosed in angled brackets, and possibly a pattern to clean more diversed parameters.


 * Description

Strings will be filtered through htmlspecialchars, and any backslashes (\) and single (') and double quotes (") will have those escaped.

Define
A system message can be defined as a variable, that is, a special construct can import the system message for the interface language or the content language and bind it to a JavaScript variable. The process is initiated through using the pragma #DEFINE, optionally in combination with the keywords CONTENT or INTERFACE. Those keywords will limit the lookup of system messages to the defined languages, that is the languages used for the content or the interface. In addition a variable name must be specified and the name of a system message enclosed in angled brackets.


 * Description

System messages containing backslashes (\) and single (') and double quotes (") will have those escaped.

Include
A system message can be included, that is, a special construct can import the system message for the interface language or the content language if it comes from a page with a proper JavaScript suffix. The process is initiated through using the pragma #INCLUDE, optionally in combination with the keywords CONTENT or INTERFACE. Those keywords will limit the lookup of system messages to the defined languages. In addition the name of a system message enclosed in angled brackets.


 * Description

Note that the message name should have a proper js-suffix. If there is no such message to include, then a special code is included that will give an alert with the message name. There is no simple unified solution to how to do this, most likely critical code should be wrapped in #IFDEF.

Control structure
A few control structures are available for conditional evaluation of code, given the existence of system messages for the interface language or the content language. The process is initiated through using the pragma #IFDEF or #IFNDEF, optionally in combination with the keywords CONTENT or INTERFACE. Those keywords will limit the lookup of system messages to the defined languages. In addition the name of a system message enclosed in angled brackets. The controlled portion of the control structure is then run till #ELSE is found, in case the operation is negated, or the #ENDIF is found, in case further prosessing of this control structure is stopped.


 * Description

Debug
As the code can be buggy, and the preprocessing will not make the debugging simpler the resulting code can be dumped by setting the action parameter to debug. The code after preprocessing will then be shown on the special page (debug) instead of evaluated (view).

Hello world
A typical "Hello world" has a simple solution with this extension. If coded as usual on Wikipedia it would include code for detecting a host page, code for querying system messages, and then finally code for rendering the result. With the previous pragmas this will be simplified.


 * Example

In the first line the binding between a JavaScript variable and a system message is defined. This variable is then used in the second line.

An example "Hello World" applet is available at Rallar.org: Hello World.

Bootstrap
A common construct is to localize some system messages, get some localized libraries and finally get the bulk of the code.


 * Example

This localizes all messages and adapts the later main code. This is either loaded from the local wiki or loaded from an external wiki.

An example "Weather data" applet is available at Rallar.org: Weather data.

Security issues
This kind of extension has a fundamental security problem because they allow inclusion of material on the page, possibly within executable code. To avoid this the extension can only be configured for general use by sysops, or on an individual level by a single user loading pages from his own user space. The latter has the assumption that a single user knows what he is doing, if doing anything evil he will only harm himself, and therefor it is probably safe to let him play with the extension. If he wants to make his code generally available he must ask a sysop to move the actual pages. This covers the bulk of the code and should produce a fairly safe environment. It is fairly safe to assume that whoever edits will try to make functional code, and also that it will be cleaned up fairly fast if there is something strange going on.

A minor part of the page is adapted through the request, the private data, and this opens a wormhole of possible attacks. It is the possibility to store code on the page that creates the problems. The main protection against this is to enforce validation of content from the outside before it reaches the page. This is done through type checks and pattern matching. If these checks fails then the page gives an error report and will not produce any code.

Bugs/Todo

 * Testing of cached messages should be more effective, but this has to be fixed in the main core
 * Caching added, but has not been thoroughly tested
 * Can't use pages from user space
 * Transclusion does not work, and should probably be replaced by a tag function (note that this will not allow inclusion of user data)
 * Should be possible to declare defines and argv as "const"
 * Should be possible to reuse sets of patterns