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

On Mon, Aug 1, 2011 at 6:33 PM, Maciej Stachowiak <mjs@apple.com> wrote:
>
> 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.

I'm not sure if it's better to include the children as a var-args
list, or as an array. Certainly when typing things normally var-args
saves you the "[" and "]", but when coding, if you've built the child
list dynamically and have an array, you have to make awkward .apply
calls.

> 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.

This doesn't explain why a factory method is better than explicit
constructors though? The above could be written as

new HTMLParagraphElement(null, "foo", ...);

However I'm not sure what to do in situations where we don't have an
explicit interface for an element, such as both <ins> and <del> both
using HTMLModElement, and the long list of elements which only use
HTMLElement as interface. cc'ing Alex Russel who is often a strong
advocate for constructors over factory functions and who might have
thought about this problem.

/ Jonas

Received on Tuesday, 2 August 2011 07:37:59 UTC