- From: Hans Schmucker <hansschmucker@gmail.com>
- Date: Sun, 30 May 2010 22:14:08 +0200
- To: www-svg@w3.org
I've created what is essentially a wish list for SVG DOM 2's node creation facility. The target was to create something that's fit for a wide range of scenarios and uses while making simple use possible with a minimum amount of overhead. For example using this you can create template JS-objects, include whatever namespaces you want, import the response from an XMLHttpRequest as SVG and lots more. But if you just want to create a g node, it's still as easy as saying createFragment("g") Is this an approach that you'd think could work or is it too hackish? ========= function createFragment ========= createFragment is intended to create SVG fragments that are detached from the document. There are four basic ways it can be called: SVGElement createFragment( SVGElement ) SVGElement createFragment( XML ) SVGElement createFragment( XMLString ) SVGElement|SVGElementMap createFragment( Array/ArrayContent ) createFragment can be either called on any node or on the document element, in which case its behaviour is identical to a call on the root element of the document, Note that namespaces are interpreted as if the resulting SVG had been written into the document at that point. Additional namespaces may be given using the xmlns: constructs on the root node. There is no special variant createFragmentNS since createFragment always resolves namespace prefixes. ===== createFragment( SVGElement ) ===== Will create a new fragment that is identical to the given SVGElement (and its child nodes). Specifically node types and attributes are copied. Event Listeners and other complex properties are not. var svg=document.createFragment(existing_SVGElement); ===== createFragment( XML ) ===== In E4X enabled useragents, an XML snippet can be provided, which will be interpreted according to the namespaces at the current node. The point is that any form of XML should be able to serve as template, no matter if its a responseXML, an E4X snippet or whatever. var svg=document.createFragment( <g transform="rotate(45)" id="container"> <image xlink:href="foo.png"> <image xlink:href=" foo.png" /> Hello World </image> </g> ); ===== createFragment( XMLString ) ===== This is identical to createFragment( XML ), however the XML is not specified via E4X, but as a String instead. It is primarily intended for backwards compatibility with browsers that do not support E4X. An XMLString is required to have "<" as its first character after trimming var svg=document.createFragment( ' <g transform="rotate(45)" id="container">'+ ' <image xlink:href="foo.png">'+ ' <image xlink:href=" foo.png" />'+ ' Hello World'+ ' </image>'+ ' </g>' ); ===== createFragment( Array/ArrayContent ) ===== JSON-like notation for insertion of a dynamic SVG snippet. This mode is used if argument 1 is either an Array or a String not starting with "\s*<". Each element (except text nodes) is represented by an Array that at least contains a string with the tag name. There are three different types of elements in this tree: 1. Arrays Arrays are interpreted as element templates. 2. Strings Strings are interpreted as textnode templates, except at the top level (createFragment is not meant for the creation of simple text nodes) 3. SVGElements Passing in an existing SVG element will create a copy at this point in the document fragment == Array element templates == Each Array element template must at the very least contain a string with its tagname (including namespace prefixes if required). Note that namespaces are interpreted as if this element were attached directly to the document. The tag name may not include whitespace. ["svg:g"] The list of arguments passed to createFragment is treated automatically as an Array unless the first element is itself an Array. So createFragment(["g"]) is equivalent to createFragment("g") This string can optionally include attributes, seperated by whitespace. There may be any amount of whitespace between name, "=" and value. Leading and trailing whitespace is trimmed ["g foo = bar"] Attribute values that contain whitespace must be enclosed in either single or double quotes. Attribute name may likewise be enclosed: ["g 'foo'=\" Hello World \" "] ["g 'foo'=Hello World"] is invalid and should throw and error. For class and id definition a shorthand notation is allowed. Multiple class defintions add up to a space seperated string, while multiple id definitions will discard every but the last one. Neither one can contain whitespace. ["g #foo #foo2 .bar .bar2"] is equivalent to ["g id=foo2 class='bar bar2'"] Additionally, nodes can contain a special shorthand property that will not change the node itself, but cause a change in return value behavior: $ ["g $identity"] If any such such identity node templates are encountered, createFragment returns an object where for each $... marked node there is a property pointing to that node, or if multiple nodes with the same $... marker were encountered an Array containing them. The root element will automatically be marked $root. A tree containing ["g"] as root element and ["g $ident1"], ["g $ident2"], ["g $ident2"] somwhere inside the tree will return (# meaning references to these nodes) { "root": #1, "ident1": #2, "ident2": [ #3, #4 ] } = Attribute Collections = An array element template may contain any number of objects that contain attribute maps. If an attribute is declared in multiple maps, the last occurence takes precedence. This is so that developers can create seperate objects for rarely changing attributes. Any object that is not an Array is interpreted as attribute map. ["g" {"id":"foo","class":bar"},{"class":"bar2"}] = Child nodes = Child nodes are specified as one or more Arrays: ["g",[ ["image"], ["g",[ ["image"] ]] ]] Allowing multiple childNode lists is primarily intended for reusing of parts var seperator=[ ["rect"], ["image"] ]; createFragment( "g", [ ["image"], ], seperator, [ ["image"], ], seperator, [ ["image"], ], ] -- Hans Schmucker Mannheim Germany hansschmucker@gmail.com http://www.tapper-ware.net
Received on Sunday, 30 May 2010 23:44:56 UTC