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 Decorator Brainstorming: Difference between revisions

From WHATWG Wiki
Jump to navigation Jump to search
(→‎Overview: Triggers)
(→‎Implementation Approaches: divide shadow-DOM approaches, add aspect-oriented approach)
 
(11 intermediate revisions by the same user not shown)
Line 15: Line 15:
A decorator may come from an untrusted source. In case the decorated element is a component, that component may come from an untrusted source as well, which may be different than the decorator's.
A decorator may come from an untrusted source. In case the decorated element is a component, that component may come from an untrusted source as well, which may be different than the decorator's.


Therefore, an approach that merges a decorator with a component's shadow tree, e.g., via <tt>&lt;inherited&gt;</tt> is undesirable. Similarly, collecting decorator's under a component's <tt>ShadowRoot</tt> does not work.
=== Priority Inversion ===
 
An XBL-style <tt>&lt;inherited&gt;</tt> places the decorator(s) on top of the main component, making the decorator the root of the tree. This makes the decorator the "more important" part in the relation. Indeed, a decorator might omit the <tt>&lt;inherited&gt;</tt> element, hiding the component (and other decorators) entirely.
 
[[User:Rolandsteiner|RolandSteiner]] Decorators therefore should be rendered "around" the element or component. Cases where a tighter coupling is required are probably better handled by composition.


=== Priority Inversion ===
=== Decorating Component Parts ===


An XBL-style <tt>&lt;inherited&gt;</tt> places the decorator(s) on top of the main component, making the decorator the root of the tree. This inverts the priority that should exist between a decorator and the main component. Indeed, a decorator might omit the <tt>&lt;inherited&gt;</tt> element, hiding the component (and other decorators) entirely.
In some cases it may be desirable to have the ability to decorate specific parts of a component. E.g., the caps-lock indicator in an <tt>&lt;input&gt;</tt> field could be considered a decorator.


Decorators therefore should be rendered "around" the element or component. Cases where a tighter coupling is required are probably better handled by composition.
However, this clashes with the desire to not make the internals of components public. To reconcile this we'd need a better model of how to declare component parts, whether "aspect-oriented components" or something different.


== Triggers ==
== Triggers ==
Line 33: Line 37:


If we can achieve decorator-assignment via generic CSS rules, this can handle all cases above.
If we can achieve decorator-assignment via generic CSS rules, this can handle all cases above.
== Questions ==
=== Recursiveness ===
Can a decorator be decorated itself?
=== Styling ===
Can a decorator affect the styling of the decorated element?
=== Layout ===
Can a decorator affect the layout of the decorated element and/or surrounding elements? For example, consider an element that is given a specific height and width:
* If the purpose of the dimensions is to fit, e.g., an image, then changing those dimensions to fit the decorator seems ill-advised
* If the purpose of the dimensions is for precise layouting, then shifting surrounding elements to fit the decorator seems ill-advised
(However, given that which decorators to consider is in the hands of the page author the above are only minor considerations.)
=== Multiple Decorators ===
It seems useful and straight-forward to allow multiple decorators on a single element. However, assigning decorators, e.g., via a CSS <tt>binding</tt> property and using the CSS cascade would leave only the decorator stemming from the most specific rule.
= Binding Approaches =
== CSS ==
=== XBL Approach ===
XBL uses a CSS attribute <tt>binding</tt> to assign bindings to elements, as well as allowing elements to add bindings explicitly via <tt>element.addBinding()</tt>. While XBL specifies implicit bindings, as would be used by decorators, the natural vehicle to apply decorators - CSS - only seems to allow one (?).
=== CSS Decorator Properties ===
Allow decorators to specify a CSS <tt>decorator-&lt;xyz&gt;</tt> property with the values <tt>none</tt> and <tt>apply</tt>. Rules can then switch individual decorators on or off.
==== Advantages ====
* allows decorators to be switched on or off based on rules
==== Disadvantages ====
* requires probably controversial CSS extension
* does not define where decorator is rendered
* does not allow classification which decorators are applicable to which elements
=== CSS Decorator Pseudo-elements ===
Allow decorators to specify a CSS pseudo-element or - probably better - an ID that can be accessed via a pseudo-element function <tt>::decorator()</tt>.
==== Advantages ====
* potentially easier to get acceptance for <tt>::decorator()</tt> than for decorator properties.
* pseudo-element kinda makes sense, since the decorator can be considered becoming part of the decorated element
* allows further styling of the decorator
* classification what decorators can be applied to which elements in the realm of the possible (make 'illegal' decorators fail in the CSS selector matching).
==== Disadvantages ====
* what are the properties for the pseudo-element?
* how to turn off a set pseudo-element again?
= Implementation Approaches =
== Pure CSS ==
In this approach, the decorator is defined purely in CSS. To this end we'd need to extend the layout capabilities of CSS to allow the creation and arrangement of arbitrary render boxes.
=== Advantages ===
* Does not create inter-dependence between DOM and CSS applying decorators - everything is handled by CSS.
* Trivially allows for the application of decorators via generic CSS rules.
* Extending the layout capabilities of CSS can be useful - and has been asked for - in general.
=== Disadvantages ===
* Expressiveness seems limited.
* Open questions regarding interactivity, how to bind event listeners, etc.
* Long standardization to get there.
== Component-like shadow DOM, rendered as overlay ==
The decorators are declared similar to components and have their own DOM tree. A component is rendered in the specified position separately from the main DOM as an overlay to the "normal" rendering.
=== Advantages ===
* Expressiveness and scriptability of DOM
* Uses tools we already have or develop for components, no interaction between decorator and regular element rendering
=== Disadvantages ===
* Creates a inter-dependency between DOM and the triggers (e.g., CSS), but less of an issue than with XBL-inheritance approaches
* Overlays are quite limited in capabilities
== Component-like shadow DOM, with inheritance ==
The decorators are declared similar to components and have their own DOM tree. A component is rendered in the specified position separately from the main DOM.
=== Advantages ===
* Expressiveness and scriptability of DOM
* Uses tools we already have or develop for components, no interaction between decorator and regular element rendering
=== Disadvantages ===
* Creates a inter-dependency between DOM and the triggers (e.g., CSS)
* "Heavier" in application.
* (Re-)raises questions about (explicit or implicit) XBL-like inheritance, overriding and/or hiding of previously applied shadow trees
== Aspect-oriented components ==
Components are assembled from parts, which are essentially "micro-templates". Sub-classes and decorators can override any or all of those parts. What is rendered is an auto-flattening of all final parts.
=== Advantages ===
* Defines inner structure of components, makes individual parts decoratable/replaceable
* Parts can serve as pseudo-element targets naturally
* Individual parts should be responsible for a limited subset of the host element's children, reducing the potential conflict area between multiple parts vying for the same host elements
=== Disadvantages ===
* Best trigger mechanism undefined (questionable whether CSS is a good fit)
* Probably very heavy in application.
* Requires discipline from authors to set up effectively
* Scripts may hold references to elements in parts that "go away" on updates (may not be a problem in practice)
== In-between ==
Determine decorators in terms of CSS layout, but define that layout in terms of a DOM and open it up to scripting - e.g., auto-instantiate the DOM when a content-generating pseudo-element is used.
=== Advantages ===
* Simplicity of CSS application, but allowing for scripting
* Details what is currently "hidden"
=== Disadvantages ===
* Performance questions
* Content-generating pseudo-classes may not fit a single DOM template
* Defining things in terms of DOM may block future additions to CSS that then would no longer fit that definition (and thus break pages)
* Performant implementation may require multiple renderers per node

Latest revision as of 01:06, 29 October 2011

Overview

Considerations

Dynamic

A decorator can be applied and removed dynamically, as opposed to a component, which is applied statically and cannot change. Furthermore, an element can have 0-n decorators, but just 0-1 components.

Interface

A decorator cannot add additional interfaces to the decorated element.

Confinement

A decorator may come from an untrusted source. In case the decorated element is a component, that component may come from an untrusted source as well, which may be different than the decorator's.

Priority Inversion

An XBL-style <inherited> places the decorator(s) on top of the main component, making the decorator the root of the tree. This makes the decorator the "more important" part in the relation. Indeed, a decorator might omit the <inherited> element, hiding the component (and other decorators) entirely.

RolandSteiner Decorators therefore should be rendered "around" the element or component. Cases where a tighter coupling is required are probably better handled by composition.

Decorating Component Parts

In some cases it may be desirable to have the ability to decorate specific parts of a component. E.g., the caps-lock indicator in an <input> field could be considered a decorator.

However, this clashes with the desire to not make the internals of components public. To reconcile this we'd need a better model of how to declare component parts, whether "aspect-oriented components" or something different.

Triggers

We consider the following triggers for the application of decorators:

  • element tag names
  • attributes
  • ARIA roles
  • general CSS

If we can achieve decorator-assignment via generic CSS rules, this can handle all cases above.

Questions

Recursiveness

Can a decorator be decorated itself?

Styling

Can a decorator affect the styling of the decorated element?

Layout

Can a decorator affect the layout of the decorated element and/or surrounding elements? For example, consider an element that is given a specific height and width:

  • If the purpose of the dimensions is to fit, e.g., an image, then changing those dimensions to fit the decorator seems ill-advised
  • If the purpose of the dimensions is for precise layouting, then shifting surrounding elements to fit the decorator seems ill-advised

(However, given that which decorators to consider is in the hands of the page author the above are only minor considerations.)

Multiple Decorators

It seems useful and straight-forward to allow multiple decorators on a single element. However, assigning decorators, e.g., via a CSS binding property and using the CSS cascade would leave only the decorator stemming from the most specific rule.

Binding Approaches

CSS

XBL Approach

XBL uses a CSS attribute binding to assign bindings to elements, as well as allowing elements to add bindings explicitly via element.addBinding(). While XBL specifies implicit bindings, as would be used by decorators, the natural vehicle to apply decorators - CSS - only seems to allow one (?).

CSS Decorator Properties

Allow decorators to specify a CSS decorator-<xyz> property with the values none and apply. Rules can then switch individual decorators on or off.

Advantages

  • allows decorators to be switched on or off based on rules

Disadvantages

  • requires probably controversial CSS extension
  • does not define where decorator is rendered
  • does not allow classification which decorators are applicable to which elements

CSS Decorator Pseudo-elements

Allow decorators to specify a CSS pseudo-element or - probably better - an ID that can be accessed via a pseudo-element function ::decorator().

Advantages

  • potentially easier to get acceptance for ::decorator() than for decorator properties.
  • pseudo-element kinda makes sense, since the decorator can be considered becoming part of the decorated element
  • allows further styling of the decorator
  • classification what decorators can be applied to which elements in the realm of the possible (make 'illegal' decorators fail in the CSS selector matching).

Disadvantages

  • what are the properties for the pseudo-element?
  • how to turn off a set pseudo-element again?

Implementation Approaches

Pure CSS

In this approach, the decorator is defined purely in CSS. To this end we'd need to extend the layout capabilities of CSS to allow the creation and arrangement of arbitrary render boxes.

Advantages

  • Does not create inter-dependence between DOM and CSS applying decorators - everything is handled by CSS.
  • Trivially allows for the application of decorators via generic CSS rules.
  • Extending the layout capabilities of CSS can be useful - and has been asked for - in general.

Disadvantages

  • Expressiveness seems limited.
  • Open questions regarding interactivity, how to bind event listeners, etc.
  • Long standardization to get there.

Component-like shadow DOM, rendered as overlay

The decorators are declared similar to components and have their own DOM tree. A component is rendered in the specified position separately from the main DOM as an overlay to the "normal" rendering.

Advantages

  • Expressiveness and scriptability of DOM
  • Uses tools we already have or develop for components, no interaction between decorator and regular element rendering

Disadvantages

  • Creates a inter-dependency between DOM and the triggers (e.g., CSS), but less of an issue than with XBL-inheritance approaches
  • Overlays are quite limited in capabilities

Component-like shadow DOM, with inheritance

The decorators are declared similar to components and have their own DOM tree. A component is rendered in the specified position separately from the main DOM.

Advantages

  • Expressiveness and scriptability of DOM
  • Uses tools we already have or develop for components, no interaction between decorator and regular element rendering

Disadvantages

  • Creates a inter-dependency between DOM and the triggers (e.g., CSS)
  • "Heavier" in application.
  • (Re-)raises questions about (explicit or implicit) XBL-like inheritance, overriding and/or hiding of previously applied shadow trees

Aspect-oriented components

Components are assembled from parts, which are essentially "micro-templates". Sub-classes and decorators can override any or all of those parts. What is rendered is an auto-flattening of all final parts.

Advantages

  • Defines inner structure of components, makes individual parts decoratable/replaceable
  • Parts can serve as pseudo-element targets naturally
  • Individual parts should be responsible for a limited subset of the host element's children, reducing the potential conflict area between multiple parts vying for the same host elements

Disadvantages

  • Best trigger mechanism undefined (questionable whether CSS is a good fit)
  • Probably very heavy in application.
  • Requires discipline from authors to set up effectively
  • Scripts may hold references to elements in parts that "go away" on updates (may not be a problem in practice)

In-between

Determine decorators in terms of CSS layout, but define that layout in terms of a DOM and open it up to scripting - e.g., auto-instantiate the DOM when a content-generating pseudo-element is used.

Advantages

  • Simplicity of CSS application, but allowing for scripting
  • Details what is currently "hidden"

Disadvantages

  • Performance questions
  • Content-generating pseudo-classes may not fit a single DOM template
  • Defining things in terms of DOM may block future additions to CSS that then would no longer fit that definition (and thus break pages)
  • Performant implementation may require multiple renderers per node