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

Behavior Attachment: Difference between revisions

From WHATWG Wiki
Jump to navigation Jump to search
No edit summary
Line 33: Line 33:
Two interesting symptoms emerge after analysis of the approaches:
Two interesting symptoms emerge after analysis of the approaches:


* Parallel object hierarchies. Since there is no way to incorporate a DOM element into object hierarchy, Javascript objects typically expose behavior-specific APIs, while using DOM objects as building blocks underneath. This extra layer of indirection has a negative impact on framework interoperability and is generally a [http://en.wikipedia.org/wiki/Leaky_abstraction leaky abstraction].
* '''Parallel object hierarchies'''. Since there is no way to incorporate a DOM element into object hierarchy, Javascript objects typically expose behavior-specific APIs, while using DOM objects as building blocks underneath. This extra layer of indirection has a negative impact on framework interoperability and is generally a [http://en.wikipedia.org/wiki/Leaky_abstraction leaky abstraction].
* Dynamic-sounding techniques for permanently attaching behavior. In the absence of a way to instantiate a DOM element with a new behavior attached, many frameworks use decoration/mixin-like patterns in its place. However the semantics and effect of application is one-way in most cases, indicating that the actual intent is to attach behavior as close to element instantiation as possible.
* '''Dynamic-sounding techniques for permanently attaching behavior'''. In the absence of a way to instantiate a DOM element with a new behavior attached, many frameworks use decoration/mixin-like patterns in its place. However the semantics and effect of application is one-way in most cases, indicating that the actual intent is to attach behavior as close to element instantiation as possible.


Behavior attachment is also used by browsers extensions, where an extension script, running in the context of the document, may attach extra behavior (including UI), to give the user more functionality within a document. Typical examples of such extensions are:
Behavior attachment is also used by browsers extensions, where an extension script, running in the context of the document, may attach extra behavior (including UI), to give the user more functionality within a document. Typical examples of such extensions are:

Revision as of 23:31, 7 July 2011

WORK IN PROGRESS

HTML, as exists today, does not provide an organized way of attaching behavior to a DOM element. While you can add individual scripting methods, properties and event handlers to it, there is no way to do this atomically and with proper encapsulation.

Behavior Attachment in the Wild

This deficiency is addressed at a library level, with every Javascript framework attempting to solve this problem. Here is a quick overview of approaches:

Library Behavior Attachment Implementation
Dijit (Dojo's UI Library) Creates a parallel object hierarchy to create illusion of homogenous object space, with full wrappers around DOM objects. Relies on inheritance-style approach by assigning each DOM element a dojoType attribute in markup, then traversing DOM and attaching corresponding behavior.
Google Web Toolkit Also uses parallel object hierarchy to shield the user from behavior attachment deficiency, relying on inheritance for compartmentalization and reuse.
JQuery UI A good balance of insulation from DOM objects with just-in-time wrapping. Progressive enhancement is the adopted technique of applying behavior. The behavior is transient and often an API is provide to detach it. It's interesting that the API is very late-bound and based on passing strings as method names.
Prototype Uses prototype inheritance chain to bestow new properties/methods on a DOM element. The changes are purely additive and imply permanent change in context of document’s lifetime.
Sencha Aggressive insulation from DOM with a Javascript objects as proxies, simple inheritance model (even maps ids of the underlying DOM elements to the variable names).
SproutCore Again, Javascript objects as proxies, extensive inheritance-based hierarchy of UI objects.

Two interesting symptoms emerge after analysis of the approaches:

  • Parallel object hierarchies. Since there is no way to incorporate a DOM element into object hierarchy, Javascript objects typically expose behavior-specific APIs, while using DOM objects as building blocks underneath. This extra layer of indirection has a negative impact on framework interoperability and is generally a leaky abstraction.
  • Dynamic-sounding techniques for permanently attaching behavior. In the absence of a way to instantiate a DOM element with a new behavior attached, many frameworks use decoration/mixin-like patterns in its place. However the semantics and effect of application is one-way in most cases, indicating that the actual intent is to attach behavior as close to element instantiation as possible.

Behavior attachment is also used by browsers extensions, where an extension script, running in the context of the document, may attach extra behavior (including UI), to give the user more functionality within a document. Typical examples of such extensions are:

The main challenge for these extensions is to add and remove behavior to DOM elements (including extra DOM elements) to an existing document with least disruption, preferably in a way where the scripts of the document aren’t ever aware of these behavior attachments.

Behavior Attachment Methods

To better understand the intent of behavior attachment, we can split these examples in the wild into two general groups:

  • A decorator behavior attachment, where transient behaviors are given to or taken away from an element, modifying aspects of its properties, but leave the identity of an element intact; and
  • An element behavior attachment, where the behavior is permanently associated with the element and creates a new type of element.

Inheritance and Shadow DOM

What if an inherited element already has a shadow DOM subtree? In this case, the descendant has two options:

  • Use inherited element. The inherited DOM subtree will be inserted in place of this element. Neither descendant nor ancestor will be able to access each other's subtrees.
  • Disregard the inherited shadow subtree. The inherited DOM subtree will still be created and continue to exist, but it will not be rendered (a "ghost tree"). This is necessary to ensure that the ancestor element's behavior is not affected with override.

Interaction of Element and Decorator Behavior Attachment

Since both behavior attachment methods can exists in the same document, we must provide a way for the two to coexist on the same element.

  • When a decorator is applied with an element with a shadow DOM subtree, the element subtree is treated as inherited.
  • Order of content application: the content elements contained in the inherited shadow DOM tree are applied last. This way, if both descendant or decorator claim a direct child, it will appear to the inherited tree as if there's nothing there.

Comparison Between Decorator and Element Behavior Attachment

Decorator Element
Purpose Give existing content new behavior and/or appearance. Create new content building blocks.
Paradigm Aspect-Oriented Programming Object-Oriented Programming
Compartmentalization and Reuse Vehicle Aspect Inheritance
Symptoms
  • It is expected that an element may abruptly enter or exit association with the behavior.
  • There is a desire to not intrude on the original properties of an element.
  • There is only one behavior that is typically associated with an element.
  • There is a desire to minimize the time when an element has no associated behavior.
Examples of Use
  • Add special UI treatment to all vcards in a document.
  • Create an extension to provide extra download options for certain types of links.
  • Implement built-in HTML controls: input/textarea, media, etc.
  • Define an element to represent a customizable calendar view.
  • Define a button row control with application-specific grouping logic (see GMail button bars).
Identity Does not change the identity of the element. Creates a new type of element.
Lifetime Transient, added and removed dynamically. Permanent, originates with the element’s creation and exists through the lifetime.
Environment Foreign document or limited control of content. Full control of content.
Defining Traits
  • Unobtrusive
  • Dynamic
  • Composable
  • Interoperable
Shadow Tree Each decorator must have its own shadow subtree, and the aggregate shadow tree of an element is composed out of these subtrees. Only one tree, initialized as the element is created. Inherited shadow trees can be reused, nested in the element's tree.
DOM API Should avoid adding any extra methods or properties to the DOM element that’s being decorated. Explicitly interested in exposing methods or properties on the DOM element as its API.

Analysis of Existing Specifications and Implementations

What does XBL2 do?

  • There are two ways to bind: using binding element (inline or via external document) and using CSS. The former somewhat matches the notion to be element behavior, and the latter is the decorator behavior. However, there is no distinct difference in the attachment mechanism.
  • Inheritance is entirely self-contained, using “extends” attribute. However, the prototype chain of the implementation object is fixed up to follow inherited bindings.
  • There is a fair bit of machinery specified to marry the aspect and inheritance concepts seamlessly.
  • There is no notion of extending DOM elements.

What does XBL1 do?

What does HTC do?

  • HTC does not have the concept of shadow DOM, but the specified behavior is firmly an element behavior attachment.

What does sXBL do?

  • It appears that the spec is abandoned, but the gist is similar to XBL2, except there is only one shadow tree, direct access to shadow subtree, and a binding model that seems to indicate element behavior attachment, but using decorator API.