Element.create(): a proposal for more convenient element creation

In an IRC discussion with Ian Hickson and Tab Atkins, we can up with the following idea for convenient element creation:

Element.create(tagName, attributeMap, children…)

   Creates an element with the specified tag, attributes, and children.

   tagName - tag name as a string; by default it does "smart" selection of SVG, HTML or MathML namespace. Authors can also use an html: svg: or mathml: prefix to override these defaults. (And further, you can use xmlns in attribute map to use a custom namespace.)
   attributeMap - JS object-as-dictonary or whatever dictionary type is appropriate to the language, or null for no attributes
   children… - veridic parameter, can include nodes, strings, or arrays. Strings are converted to text nodes. Arrays are unpacked and treated as lists of nodes/strings. Array support is for cases where you want to have a call-site that may take a veriable-length list, with possible prefix and suffix.

Examples:

Element.create("a", {href: "http://google.com/"}, "Google"}

Element.create("p", null, 
                            "Please consider these instructions ",
                            Element.create("em", {class: "intense"}, "very"),
                            "carefully")

Element.create('svg:a', {href: 'example.html'}, 'Click Me! Yay bad link text!');

Element.create('select', {multi: ''}, optionArray);

The default namespace mapping would be HTML, with possibly SVG or MathML elements that don't localName-collide with HTML elements mapping to their default namespace.


Why Element.create() instead of new Element()? It's a factory method. In general it returns instances of many different classes. new Foo() carries a strong expectation of returning a direct instance of Foo, not one of several subclasses.

We could also add new Text('foo') for the cases where you want to create a text node without an element around it.

Regards,
Maciej

Received on Tuesday, 2 August 2011 01:34:16 UTC