Shape Type
Click on Shape for Details

Scriptbridge Blendup

A single SVG document can be referenced multiple times within a hosting HTML document, and each instance will have its own DOM and scripting context, in addition to the scripting context of the host document. Using Javascript, it is possible to communicate between the HTML hosting document and each of the SVG document instances. Mixing different document types in this way is commonly referred to as a "compound document", and when script or declarative links are used to make them interoperate with one another, I call it a "blendup" (like a mashup, but with multiple type of documents and intercommunication between them).

Setting up the script context, which I refer to as a "scriptbridge", is very easy (just view the source), though currently you have to use a couple of different methods to nail it down. Once the scriptbridge is established, you can call functions in the SVG scripting context from HTML, and vice versa. Through the HTML host document, you can even communicate between different instances of the same SVG document, as demonstrated in the example above. Here, the user can select a shape type and a target canvas (SVG instance) to insert the shape into, using an HTML form. Each instance receives the function call, and dynamically generates a random shape of the right type; if the same command is sent to both instances, each will still create a unique element with its own random characteristics. Clicking on any shape send that shape to the HTML scripting context, where the details of the shape are displayed, and the shape is automatically inserted into the other SVG document instance.

Bugs and Oddities

This example shows a very interesting bug: when an element is sent via script from one referenced SVG document to the parent HTML document, then sent from there to a second referenced SVG document, and inserted into that second document with the 'appendChild()' method, it is removed from the first (origin) document, just as if it were all the same document! This effect happens in Firefox and Opera, though not in Safari, where it simply isn't inserted into the second document (the error reported is "WRONG_DOCUMENT_ERR: DOM Exception 4", which is as I would expect). When the node is cloned instead, and the clone inserted in the second SVG document, it behaves as expected in all three browsers (see the working scriptbridge example for more details).

I don't actually have a strong opinion about which behavior is better, though the DOM3 Core specification does state that the following DOMException must be raised: "WRONG_DOCUMENT_ERR: Raised if newChild was created from a different document than the one that created this node." However, that specification offers no rationale for this behavior. One possibility is security concerns, though what those concerns are is not clear; another possible reason is that it would require coordination between different documents for removing and inserting the element, though this does not seem like much of an implementation burden; another possibility involves having the proper namespace on the element for the document that it is being inserted into, but again this does not seem problematic since both the element and the new document will contain details about their own namespace. This last seems the most plausible, since the definition for DOMException lists WRONG_DOCUMENT_ERR as the exception, "If a Node is used in a different document than the one that created it (that doesn't support it)." However, this seems to mean that the exception should only be raised if the new document doesn't support the element that is being supported (whatever "doesn't support" means in the context).

See the thread on www-dom regarding this.