[whatwg] Declarative Inert DOM (e.g. the <template> element)

On Thu, Nov 17, 2011 at 11:15 AM, Rafael Weinstein <rafaelw at chromium.org> wrote:
> Problem:
>
> Dynamic web pages often need to author and deliver fragments of DOM
> which *may* be used at some point during the page's lifetime, but have
> them be "inert" until they are needed.
>
> In this context, "inert" means not only that the fragment isn't
> rendered, but also that:
>
> -Resources don't load
> -Scripts & plugins don't run
> -Audio/Video don't play
> -Attributes aren't normalized
> -getElementById & querySelector don't match inert elements
> (etc)
>
>
> What are web pages doing now (all client-side templating libraries
> have *some* solution for this)?
>
> They hide these inert structures in various ways:
> -text literals within js files
> -hidden text areas
> -script tags with non-script file types
> -comment tags
> -elements marked as display: none
>
>
> Why isn't this good enough:
>
> All of these approaches either:
> -Force the treatment of the inert fragment as text which must be
> parsed and encourages the use of innerHTML (and often leads to XSS)
> -Or don't meet the requirements for "inert" listed above.
>
> In addition, because the approaches are non-standard, they interact
> badly with the HTML tool-chain and/or have encoding limitations
> (script does not allow "</script>", etc...).
>
>
> (Very hand-wavvy) Proposal:
>
> <template>
> ?<div>
> ?<span>Hello, world (at some point)</span>
> ?</div>
> </template>
>
> For parsing, the template element's contents are treated as HTML, but
> aren't subjected to normalization or placement/lifting rules.
>
> Big question: by what mechanism are these elements inert?
>
> One idea:
>
> Elements which are descendants of a template element have no default
> view (similar to elements in a document that does not have a view).
>
> Pro:
> -Elements are what their tagName suggests.
> -Their API is consistent between the inert state and the live state.
> -Inert elements are usable by simply placing them elsewhere in the DOM
> (by simply moving them to be descendants of a document)
>
> Con:
> -Will we need to spec the behavior of all elements while in this state?

I like this approach. While it does require some work in finding which
elements have effect outside of the <template> which needs to be
suppressed, I think it's the most useful and least surprising solution
for page developers. Implementation-wise really should not be hard to
implement if given a list of behaviors that should be suppressed.

It also makes the implementation of instantiation easy since all you
need to do is clone the elements using the existing clone mechanism
and you're ready to go.

We can and should still implement the instantiate method that you are
describing below.

> An alternate approach:
>
> The parsing of the template element's contents creates
> HTMLInertElements (or HTMLUnknownElements) which only have tagName &
> get/setAttribute. <template> gets a method called "instantiate()"
> which returns a DocumentFragment containing the corresponding elements
> made "live".
>
> Comments? Other options?

I think loosing the normal API on these elements creates a lot of
surprise for authors. It also breaks a lot of invariants for
implementors. Internally we currently can rely on that if an element
has .localName == "input" and is in the XHTML namespace, we know
exactly what class is used to implement it and what interfaces it
supports. This is something we rely on extensively.

/ Jonas

Received on Friday, 18 November 2011 13:29:07 UTC