Extension:EmbedSandbox

This experiment has been supplanted by Extension:EmbedScript


 * MediaWiki extension code: https://github.com/brion/EmbedSandbox
 * embedded code demos:
 * piechart: https://github.com/brion/EmbedPiechart
 * turtle graphics: https://github.com/brion/EmbedTurtle

Cross-origin embedding
Gadgets and other custom user / site JavaScript today are very powerful, but because they have full access to the wiki's documents and session they are potentially dangerous. Using someone else's script could turn out to do something like hijack your account to make other edits on your behalf!

Using an to embed a script hosted on another domain allows the browser environment's security systems to work for us, severely restricting access to the hosting wiki from code in the embedded context.

Using the window.postMessage facility, wide browser compatibility can be achieved in adding a limited messaging layer between the wiki and the embeddings. Both the hosting site and the embed code within the iframe can verify the origin of the messages as being from the other window, and only that data exchange is allowed.

In my initial example, JSON data stored within the &lt;embedsandbox> tag is passed into the frame on loading, so it can be used as source data to draw a pie chart.

Cross-origin for local code
If code is locally stored/created on the wiki, how can we sandbox it too?

One way is to have a remote embedding page whose sole purpose is to load code from another domain and run it there.

Using redirects to randomly-generated subdomains could ensure that every script has a separate security context.

JSON blob
Initial example uses a JSON blob. Invocation looks like this:

 {"data":[23,40,67],"labels":["small","medium","large"]}

The JSON blob is attached as a data attribute to the actual iframe, and code on the host end sends that data along with an activation message to the iframe's content window once it's initialized.

The embed code pulls the data out and draws some pie slices using the Raphael.js graphics library.

SVG extension
Next step will be to use a static SVG image as a data wrapper; this image can then be saved by the host environment and used as a static image before activating the embedded code.

For example:
 * take an SVG of a map of Europe, make sure all the countries can be located by a unique id or a class.
 * write JS code to run a flashcard-style name / map match game, pulling names from attributes or such
 * invoke the combination:

The same script could be used with a map of North America, or Africa, or cantons of Switzerland.

Possibly scripts could be combined to assist with localization?

Raster image + data
Raster images may be more appropriate for some styles.

View
Viewing would be the default mode, either hitting at page load or after a click-through activation.

(If activation, then a static SVG or raster image needs to be available as a placeholder.)

Some may be interactive such as maps, games, simulations. Others may be static. Even traditionally static things like charts and graphs may be made dynamic by allowing the scale, chart type, etc to be modified.

Edit
When integrated into a visual editor, or triggered in some way from regular view mode or from a special editing toolbar, it could often be useful to allow scripts to provide their own editing modes to modify the underlying data (JSON blob) or image file (SVG or raster base).

For the pie chart example, modifying the data, adding rows, changing labels, switching colors would be suitable for the edit mode. It would be the embedding host's responsibility to actually save data back (eg slurping JSON data back to the page, or uploading an updated SVG or PNG file back into the system), as long as the embed client can provide the data when asked.

The same techniques could be used for customizing a SVG map for the data needed in a game, or to provide general editor tools for graphics? For instance something like Extension:SVGEdit could be implemented on top of this style of embedding, and could sit alongside other such editing tools as a peer.