A user account is required in order to edit this wiki, but we've had to disable public user registrations due to spam.

To request an account, ask an autoconfirmed user on Chat (such as one of these permanent autoconfirmed members).

Component Model Brainstorming

From WHATWG Wiki
Jump to navigation Jump to search

These are just some free-style thoughts at the moment.

DOM as the API

Any DOM element has a uniform set of ways to communicate with it: attributes, events, and children. The component model should aim to replicate the same set of ways as built-in functionality. This means that a binding should be able to detect and react to the following changes in DOM:

  • modifying attributes
  • changing state (active/selected, etc.)
  • adding/removing children
  • modifying children attributes
  • changing children state

The way we implement this however is important. To guarantee performance, we should avoid Mutation Events 2.0.


API ideas for reference.

Hitchhiker's Guide Strawman

  • Every element has a shadow property. This property expect a DOM node.
    • The subtree of this node becomes element's shadow subtree upon setting the shadow property.
  • Every element has an output property. This property can be set to:
    • null or any element not in the document tree, which makes all direct children of an element not render
    • a sub-element in shadow subtree, which makes all direct children of an element render as children of that sub-element
    • the element itself, which makes all direct children render as they would without a shadow subtree.
      • the shadow subtree is rendered as if its root is the additional first (or last?) direct child of the element.
  • In CSS, you can address elements inside of the shadow by using ::shadow pseudo-attribute, which directs selector into the shadow tree.
    • For example, div.foo::shadow p will match all paragraph elements inside of the shadow tree, assigned to div.foo.
  • That's it. There is no templating, no multiple output ports, no forwarding, no nothing. It's bare minimum and meant to be that way.

Attack of the Clones Strawman

  • Templates behave like stencils. Once an instance is created, there's no perceptible connection between the template and the instance.
    • The instance is the shadow subtree on the bound element.
  • Binding metadata is part of the shadow subtree, where metadata is attribute forwarding, pseudo, output ports, etc.
    • There may be "copy-on-write"-style optimization possibilities.
  • The metadata is expressed as rules, where each rule describes how DOM information is relayed from bound element to the shadow subtree.
    • Each rule has a condition, associated with it.
    • Node rules describe how the children of the bound element are presented in the shadow subtree.
      • Node rule conditions are expressed as collapsed ranges (insertion points). Even better, it's a boundary point
      • Any time a node is added to the bound element, the condition for each rules is evaluated sequentially against this node until the match is found.
      • The same happens when the bound element is attached to the document.
        • If no match is found, the node is considered to be "twilight" and does not render (same behavior as appending a DOM node to an input element).
      • Mutations of the shadow subtree may invalidate node rules
        • For example, the elements anchoring the insertion point (parent, next or previous sibling) are moved.
        • The validity of the insertion point is determined only when the rules are evaluated.


  • Trapped light nodes: if light node distribution in shadow subtree is rule based, you can have a situation when the node is distributed to an insertion point by a rule, then the rule changes or is invalidated by a subtree mutation, the node remains in its position, but no longer has any matching rules. How big of a problem is this?
  • Reflow surprises: Similar to trapped light nodes, once the rules and the actual distribution don't match, re-flattening the shadow subtree will produce a different result. For instance, in WebKit, render tree will hold the flattened subtree. If the scripts flips to display:none and back on the bound element, the render tree will be destroyed and rebuilt, which will cause the node rules to be re-applied and thus change the position of the light nodes.
    • There may be a need for some guarantees of stability around insertion points and shadow subtree mutation.
  • Non-dynamic rules: Changing this attribute results in node redistribution, which is not the case for this strawman (see Dynamicity of Rules use case).

The Bladerunner Strawman

  • There are two distinct types of shadow DOM: element and decorator. Element shadow is given to the element at element construction and is managed by element's own behavior. Decorator shadows can be added to/removed from the element at runtime.
  • Only element shadow can have output ports. Unlike element shadows, decorator shadows can't have output ports. Decorators can't affect redistribution of children.
  • Only subclasses of the element can override element shadow DOM. In order to override the shadow DOM of the element, you must subclass the element, thus introducing a new custom element. This obviously implies that a DOM element can be subclassed -- a feature that is not part of any DOM spec.
  • There is no chaining or inheritance across element shadows. Since an element can only have one shadow DOM subtree bound to it, there are only two options for the element:
    • accept existing shadow subtree of the superclass (with no access to it), or
    • provide its own.
  • Any of the shadows can be marked visible or hidden from the outside. Implementor of the shadow subtree can choose to mark it public. Public shadow subtrees are accessible from DOM via an array.