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).
Custom Elements: Difference between revisions
(add ARIA issues) |
|||
(9 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
This page documents | This page documents open technical issues with [https://w3c.github.io/webcomponents/spec/custom/ Custom Elements] based on [https://lists.w3.org/Archives/Public/public-webapps/2015JanMar/ [email protected] from January to March 2015]. | ||
== Rough consensus == | == Rough consensus == | ||
Line 7: | Line 7: | ||
* ES6-style classes (Spec/Chrome: mutating prototype) | * ES6-style classes (Spec/Chrome: mutating prototype) | ||
* Subclassing of HTMLElement and SVGElement | * Subclassing of HTMLElement and SVGElement | ||
* | * An API to tie a class to a local name (e.g. <code>registerElement()</code>) | ||
* Lifecycle callbacks for: | * Lifecycle callbacks for: mutation of an attribute | ||
== | == Open issues == | ||
* Upgrading | |||
* Lifecycle callbacks | |||
* | * Subclassing existing elements (<code>is=""</code>) | ||
* | * Using symbols rather than strings | ||
== Upgrading == | === Upgrading === | ||
Upgrading is the concept of going from a piece of markup, such as <code><my-div data-teehee="💩"></my-div></code>, to an object in a tree. | Upgrading is the concept of going from a piece of markup, such as <code><my-div data-teehee="💩"></my-div></code>, to an object in a tree. | ||
Line 56: | Line 52: | ||
* Nested event loop. | * Nested event loop. | ||
* Does not work with asynchronously loaded assets. | * Does not work with asynchronously loaded assets. | ||
* Unclear how it works with cloning. | |||
|- | |- | ||
! Almost-synchronous constructor ([https://lists.w3.org/Archives/Public/public-webapps/2014JanMar/0098.html "Jonas"]) | ! Almost-synchronous constructor ([https://lists.w3.org/Archives/Public/public-webapps/2014JanMar/0098.html "Jonas"]) | ||
Line 62: | Line 59: | ||
* Potential performance issues. | * Potential performance issues. | ||
* Complicated? | * Complicated? | ||
* Unclear how it works with cloning. | |||
|} | |} | ||
(Written under the assumption that mutating the prototype of the basic element is no longer considered viable.) | (Written under the assumption that mutating the prototype of the basic element is no longer considered viable.) | ||
== Subclassing existing elements == | === Lifecycle callbacks === | ||
Currently Custom Elements exposes "insertion into a document" and "removal from a document". However, the primitives the DOM exposes are "insert" and "remove". | |||
=== Subclassing existing elements === | |||
Subclassing existing elements is hard as implementation-wise identity is both object-based and name/namespace based. See also [https://annevankesteren.nl/2015/01/dom-element-constructors DOM: element constructors]. | |||
A hack was invented to make this work: <code><button is="my-button"></code>. This relies on not changing name/namespace. However, this goes against the design goal of custom elements to give web developers control over the markup. And breaks down the moment you want a custom or modified shadow DOM. | |||
To make subclassing of built-in elements work and in general improve built-in elements we need to: | |||
* Figure out built-in elements: https://github.com/domenic/html-as-custom-elements | |||
* Browsers need to change from <code>localName</code>-based checks to <code>crossGlobalIsInstanceOf</code>-based checks (while retaining performance). | |||
This hack did allow for somewhat improved accessibility for trivial components, but that would quickly break down and not scale to anything more complex. It would also provide slightly better integration with the HTML parser. For example, extending <code><template></code> for [https://blog.polymer-project.org/howto/2014/09/11/template-is-autobinding/ data binding] or as a way to specify [http://jsbin.com/xuheb/3/edit?html,output shadow trees in HTML]. | |||
=== Use symbols to identify lifecycle callbacks === | |||
It has been suggested that we should use symbols rather than names ending in <code>Callback</code> to avoid collisions with libraries. | |||
== New features (v2) == | |||
=== Additional lifecycle callbacks === | |||
( | There's a proposal in various bugs to offer these lifecycle callbacks as well: | ||
* Adopting so when moving nodes across documents adjustments can be made (e.g. an <code><img></code> has its animation restarted). This callback needs to be passed the old and new document. | |||
* Cloning so <code>cloneNode()</code> can have similar semantics for custom elements as it does for e.g. <code><input></code>. For cloning we want the browser to create a clone (via the constructor) and copy all content attributes. Then the callback is passed the clone, a document, and the clone children flag (note that these are only needed for children not part of a tree, for elements such as <code><template></code>, children part of the tree are handled by the browser). | |||
== ARIA integration == | === ARIA integration === | ||
https://lists.w3.org/Archives/Public/public-webapps/2014JulSep/0355.html | https://lists.w3.org/Archives/Public/public-webapps/2014JulSep/0355.html | ||
[[Category:Spec coordination]] | [[Category:Spec coordination]] |
Latest revision as of 10:59, 1 August 2016
This page documents open technical issues with Custom Elements based on [email protected] from January to March 2015.
Rough consensus
There appears to be rough consensus for:
- ES6-style classes (Spec/Chrome: mutating prototype)
- Subclassing of HTMLElement and SVGElement
- An API to tie a class to a local name (e.g.
registerElement()
) - Lifecycle callbacks for: mutation of an attribute
Open issues
- Upgrading
- Lifecycle callbacks
- Subclassing existing elements (
is=""
) - Using symbols rather than strings
Upgrading
Upgrading is the concept of going from a piece of markup, such as <my-div data-teehee="💩"></my-div>
, to an object in a tree.
Tactic | Explanation | Drawbacks |
---|---|---|
Spec/Chrome | A basic element is created by the parser and then its prototype is mutated at a later stage followed by a callback. |
|
Brain transplant ("Dmitry") | A basic element is created by the parser and a callback registered by the developer is invoked at a later point to turn that basic element into a custom element. |
|
Dummy replacement | A dummy element is created by the parser and replaced at a later point by an actual instance of the custom element created by invoking the constructor registered by the developer. |
|
Synchronous constructor | The constructor registered by the developer is invoked by the parser at the point the custom element is created and inserted into the tree. |
|
Almost-synchronous constructor ("Jonas") | The parser does bookkeeping of where custom elements need to be inserted and does it at a later synchronization point. |
|
(Written under the assumption that mutating the prototype of the basic element is no longer considered viable.)
Lifecycle callbacks
Currently Custom Elements exposes "insertion into a document" and "removal from a document". However, the primitives the DOM exposes are "insert" and "remove".
Subclassing existing elements
Subclassing existing elements is hard as implementation-wise identity is both object-based and name/namespace based. See also DOM: element constructors.
A hack was invented to make this work: <button is="my-button">
. This relies on not changing name/namespace. However, this goes against the design goal of custom elements to give web developers control over the markup. And breaks down the moment you want a custom or modified shadow DOM.
To make subclassing of built-in elements work and in general improve built-in elements we need to:
- Figure out built-in elements: https://github.com/domenic/html-as-custom-elements
- Browsers need to change from
localName
-based checks tocrossGlobalIsInstanceOf
-based checks (while retaining performance).
This hack did allow for somewhat improved accessibility for trivial components, but that would quickly break down and not scale to anything more complex. It would also provide slightly better integration with the HTML parser. For example, extending <template>
for data binding or as a way to specify shadow trees in HTML.
Use symbols to identify lifecycle callbacks
It has been suggested that we should use symbols rather than names ending in Callback
to avoid collisions with libraries.
New features (v2)
Additional lifecycle callbacks
There's a proposal in various bugs to offer these lifecycle callbacks as well:
- Adopting so when moving nodes across documents adjustments can be made (e.g. an
<img>
has its animation restarted). This callback needs to be passed the old and new document. - Cloning so
cloneNode()
can have similar semantics for custom elements as it does for e.g.<input>
. For cloning we want the browser to create a clone (via the constructor) and copy all content attributes. Then the callback is passed the clone, a document, and the clone children flag (note that these are only needed for children not part of a tree, for elements such as<template>
, children part of the tree are handled by the browser).
ARIA integration
https://lists.w3.org/Archives/Public/public-webapps/2014JulSep/0355.html