diff --git a/assets/styles/respec-complement.css b/assets/styles/respec-complement.css index 045b2122..5bc00001 100644 --- a/assets/styles/respec-complement.css +++ b/assets/styles/respec-complement.css @@ -43,3 +43,48 @@ div.algorithm { opacity:0.8; text-align:right; } + +var { + font-size: 0.8em; + color: #005A9C; + font-style: normal; +} + +/* + * From https://resources.whatwg.org/standard.css + * Styles used in https://resources.whatwg.org/dfn.js + */ +body.dfnEnabled dfn { cursor: pointer; } +.dfnPanel { + display: inline; + position: absolute; + z-index: 35; + height: auto; + width: auto; + padding: 0.5em 0.75em; + font: small Helvetica Neue, sans-serif, Droid Sans Fallback; + background: #DDDDDD; + color: black; + border: outset 0.2em; +} +.dfnPanel * { margin: 0; padding: 0; font: inherit; text-indent: 0; } +.dfnPanel :link, .dfnPanel :visited { color: black; } +.dfnPanel p:not(.spec-link) { font-weight: bolder; } +.dfnPanel * + p { margin-top: 0.25em; } +.dfnPanel li { list-style-position: inside; } + +/* Additional fixes */ +.dfnPanel a[href] { border-bottom: none; } +.dfnPanel a[href]:hover { border-bottom: 1px solid #707070; } + +/* + * From https://resources.whatwg.org/standard.css + */ +.brief { margin-top: 1em; margin-bottom: 1em; line-height: 1.1; } +.brief > li { margin: 0; padding: 0; } +.brief > li > p, .brief > li > ol, .brief > li > ul, .brief > li > dl { + margin-top: 0; + margin-bottom: 0; + padding-top: 0; + padding-bottom: 0; +} diff --git a/assets/images/import-link-list.png b/publish/imports/WD-html-imports-20160225/import-link-list.png similarity index 100% rename from assets/images/import-link-list.png rename to publish/imports/WD-html-imports-20160225/import-link-list.png diff --git a/publish/imports/WD-html-imports-20160225/index.html b/publish/imports/WD-html-imports-20160225/index.html new file mode 100644 index 00000000..fda3a68d --- /dev/null +++ b/publish/imports/WD-html-imports-20160225/index.html @@ -0,0 +1,915 @@ + + + + + HTML Imports + + + + + + +

Abstract

+

HTML Imports are a way to include and reuse HTML documents in other HTML documents.

+

Status of This Document

+ + + +

+ This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/. +

+ + + + + + +

+ This document was published by the Web Platform Working Group as a Working Draft. + + This document is intended to become a W3C Recommendation. + + + If you wish to make comments regarding this document, please send them to + public-webapps@w3.org + (subscribe, + archives). + + + + + + + All comments are welcome. + + +

+ + + + +

+ Publication as a Working Draft does not imply endorsement by the W3C + Membership. This is a draft document and may be updated, replaced or obsoleted by other + documents at any time. It is inappropriate to cite this document as other than work in + progress. +

+ + + +

+ + This document was produced by + + a group + operating under the + 5 February 2004 W3C Patent + Policy. + + + + + W3C maintains a public list of any patent + disclosures + + made in connection with the deliverables of + + the group; that page also includes + + instructions for disclosing a patent. An individual who has actual knowledge of a patent + which the individual believes contains + Essential + Claim(s) must disclose the information in accordance with + section + 6 of the W3C Patent Policy. + + +

+ +

This document is governed by the 1 September 2015 W3C Process Document. +

+ + + + + + +

Table of Contents

+ + + +
+

1. About this Document

+ +

All diagrams, examples, notes, are non-normative, as well as sections explicitly marked as non-normative. Everything else in this specification is normative.

+ +

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC2119. For readability, these words do not appear in all uppercase letters in this specification.

+ +

Any point, at which a conforming UA must make decisions about the state or reaction to the state of the conceptual model, is captured as algorithm. The algorithms are defined in terms of processing equivalence. The processing equivalence is a constraint imposed on the algorithm implementers, requiring the output of the both UA-implemented and the specified algorithm to be exactly the same for all inputs.

+
+ +
+

2. Dependencies

+ +

This document relies on the following specifications:

+ + +
+ +
+

3. Terminology

+ +

HTML Imports, or just imports from here on, are HTML documents that are linked as external resources from another HTML document. The document that links to an import is called an import referrer. For any given import, an import referrer ancestor is its import referrer or any import referrer ancestor of its import referrer. There are one or more import referrers and import referrer ancestors for each import because same import can be referred from multiple import referrers.

+ +

An import referrer that is not an import, thus is not associated with any import referrer, is called a master document. Each import is associated with one master document: if the referrer of the import is a master document, it is the master document of the import. Otherwise, the master document of the import referrer is the master document of the import.

+ +

The URL of an import is called the import location.

+ +

In each import referrer, an import is represented as a Document, called the imported document.

+ +

+

The imported documents don't have browsing context. (See bug 26682.)

+ +

The set of all imports associated with the master document forms an import map of the master document. The maps stores imports as its items with their import locations as keys. The import map is empty at beginning. New items are added to the map as import fetching algorithm specifies.

+ +
+

3.1 Import Dependent

+ +

To track requested imports, each document has an import link list. Each of its item consists of link, a link element and location, a URL. +Also, the item is optionally marked as branch. +The list is initially empty, and items are added to it as specified by the import request algorithm.

+ +

Each imported document has an import parent: If the import link list of document A contains a branch item whose location points document B, A is an import parent of B. + +

Each imported document also has one or more import ancestors: Document A is an import ancestor of another document B if A is import parent of B. Being an import ancestor is transitive: If A is an import parent of B and B is an import parent of C, A is an import parent of C as well. + +

An imported document also has one or more import predecessors. An import predecessor is a document. If the URL of document A is located before the URL of document B in the import link list of B's import parent, and the located link is marked as a branch, then A is import predecessor of B.

+ +

The import ancestor predecessors of document A is defined as follows: If document B is an import predecessor of document C, and C is an import ancestor of A, B is an import ancestor predecessors of A.

+ +

The Document that is in either import ancestor predecessors or import predecessors of document A, or is linked from branch item of A's import link list, is the import dependent of A.

+ +
+

The import link list and the import dependent constrains the order of script execution in imports. It is intend to give a deterministic order of script execution which is defined by the order of link element in each import. The edges of each node is ordered in terms of import link list. The import predecessors selection is aware of the order.

+ +

The linking structure of import link lists forms a directed graph. Each node of the graph is a document and its edge is a link. Branches are intended to form a spanning tree of the graph. This tree gives the deterministic order of the script execution.

+ +
+ +
Fig. 1 + An example of import link lists. +
+
+ +

+In the figure, +

+ + +

The difference between the import referrer and the import parent is that import referrer reflects the state of the node tree and that the import parent is built by the algorithm described in this document.

+ +
+
+
+ + + +
+

5. Extensions to HTMLLinkElement Interface

+ +

+partial interface HTMLLinkElement {
+    readonly attribute Document? import;
+};
+
+ +

On getting, the import attribute must return null, if:

+ +

Otherwise, the attribute must return the imported document for the import, represented by the link element.

+ +

The same object must be returned each time.

+ +
+

Here's how one could access the imported document, mentioned in the previous example:

+

+var link = document.querySelector('link[rel=import]');
+var heart = link.import;
+// Access DOM of the document in /imports/heart.html
+var pulse = heart.querySelector('div.pulse');
+
+
+ +

An import in the context of the Document of an HTML parser or XML Parser is said to be an import that is blocking scripts if the element was created by that Document's parser, or and the element is a link of type import when the element was created by the parser, and the link is not marked as async, and the the import is yet to be completely loaded, and, the last time the event loop has reached step 1, the element was in that Document, and the user agent hasn't given up on that import yet. A user agent may give up on an import at any time.

+ + +
+

+Giving up an import before it loads, even if the import eventually does still load, means that the script might end up operating with incorrect information. For example, if an import registers a custom element and a script relies on the availability of this element, the script will find that this element is unavailable if the user agent gives up early. Implementers have to balance the likelihood of a script using incorrect information with the performance impact of doing nothing while waiting for a slow network request to finish. +

+
+ +

A Document has an import that is blocking scripts if there is an import that is blocking scripts in the Document's import dependent. +A Document has no import that is blocking scripts if it does not have an import that is blocking scripts as defined in the previous paragraph.

+ +
+

The state of "has an import that is blocking scripts" can change each time an existing import is completely loaded or new import loading is started. HTML parser has changes to unblock it for each of such timings.

+
+
+ +
+

6. Extensions to Document Interface

+ +

Additions to document.open() method

+ +

Add following step as the first step of the definition:

+ +
+
    +
  1. Throws an InvalidStateError exception if the Document is an import.
  2. +
+
+ +

Additions to document.write() method

+ +

Add following step as the first step of the definition:

+ +
+
    +
  1. Throws an InvalidStateError exception if the Document is an import.
  2. +
+
+ +

Additions to document.close() method

+ +

Add following step as the first step of the definition:

+ +
+
    +
  1. Throws an InvalidStateError exception if the Document is an import.
  2. +
+
+ +
+ +
+

7. Loading Imports

+ +
+

7.1 Updating Branch

+ +

After a link is added to the import link list, the update marking algorithm must be run with the master document. which is equivalent to running these steps:

+ +
+
Input
+
DOCUMENT, the Document
+
+ +
    +
  1. If the DOCUMENT is the master document, unmark branch of all the links in the import link list of DOCUMENT and every import that is associated to DOCUMENT.
  2. +
  3. Let LIST be an import link list of DOCUMENT.
  4. +
  5. For each ITEM in the LIST:
  6. +
    1. +
    2. Let LOCATION be a location of ITEM.
    3. +
    4. Let IMPORT be an import whose URL is same as LOCATION.
    5. +
    6. If there is no other link whose location is same as LOCATION and which is marked as a branch, mark ITEM as a branch.
    7. +
    8. If ITEM is marked as a branch and IMPORT is not null, invoke update marking algorithm with IMPORT.
    9. +
  7. +
+ +
+ +
+

7.2 Requesting Import

+ +

When user agents attempt to obtain a linked import, they must also run the import request algorithm, which is equivalent to running these steps:

+ +
+
+
Input
+
LINK, the link element that creates an external resource link to the import.
+
LOCATION, the URL of the linked resource.
+
+
    +
  1. If the async attribute of LINK is true, mark LINK as async. +
  2. Let DOCUMENT be a document of LINK. +
  3. Let LIST be an import link list of DOCUMENT. +
  4. Let ITEM be LINK and LOCATION:
  5. +
    1. +
    2. Add ITEM at the end of LIST. +
    3. Invoke update marking algorithm with the master document. +
  6. +
+
+ +
+ +
+

7.3 Fetching Import

+ +

All imports linked from documents that is the master document or the one in the import map must be fetched using the import fetching algorithm described below, instead of the one that HTML specifies to obtain a linked resouce.

+ +

The import fetching algorithm must be equivalent to running these steps:

+
+
+
Input
+
LINK, a link element which makes the external resource link to the import.
+
LOCATION, the import location
+
Output
+
IMPORT, the imported document.
+
+
    +
  1. If LOCATION is already in the import map: +
      +
    1. Let IMPORT be the imported document for LOCATION and stop.
    2. +
  2. +
  3. Fetch a resource from LOCATION with request's origin set to the origin of the master document, the mode to CORS and the credentials mode to same-origin. +
      +
    1. If fetched response type is error or the response has a header whose name is Content-Disposition: +
        +
      • Add LOCATION and null to the import map and stop. +
    2. +
    3. Let IMPORT be a new Document, the document's address of which is LOCATION
    4. +
    5. Let PARSER be a new HTML parser, associated with IMPORT
    6. +
    7. Add LOCATION and IMPORT to the import map.
    8. +
    9. For each task that the networking task source places on the task queue while fetching: +
        +
      1. Fill PARSER's input byte stream with the fetched bytes
      2. +
      3. Let PARSER process the input byte stream with utf-8 as a known definite encoding
      4. +
    10. +
    11. When no more bytes are available: +
        +
      1. Queue a task from the networking task source for PARSER to process implied EOF character
      2. +
      +
  4. +
+
+ +
+All of loaded imports and imports under loading are in the import link list, thus every import which is linked from imports in the list will also be loaded using the import fetching algorithm, with LOCATION be the import location of the import. +
+ +

+The loading attempt must be considered successful if IMPORT is not null on the algorithm completion, and failed otherwise. +

+ +

Every import that is not marked as async delays the load event in the Document. + +

+

The link element fires a simple event called load +for successful loading attempt. For failed attempt, it fires a simple event named error.

+

As an import delays the load event, the Document isn't completely loaded until loading attempts of all of its linked imports are finished.

+
+ +
+ +
+

7.4 Imports and Content Security Policy

+ +

+Content Security Policy must restrict import loading through the script-src directive. +

+ +

+Each import must be restricted by the Content Security Policy of the master document. +For example, if Content Security Header Field is sent to an import, the user agent must enforce the policy of the master document to the imported document. +

+ +
+
+ +
+

8. Parsing Imports

+ +

Parsing behaviour of imports is defined as a set of changes to the HTML Parsing.

+ +
+

8.1 Additions to Prepare A Script Algorithm

+ +

In step 15 of prepare a script algorithm, modify the last part of condition which begins with If element does not have a src attribute to read:

+
+

... and the Document of the HTML parser or XML parser that created the script element has a style sheet that is blocking scripts or has an import that is blocking scripts

+
+ +
+ +
+

8.2 Additions to Tree Construction Algorithm

+ +

At the DOCTYPE part of section 12.2.5.4.1 The "initial" insertion mode, modify text if the document is not an iframe srcdoc document... as follows + +

+

if the document is not an iframe src document nor an import...

+
+ +

In sub-condition named Otherwise of condition An end tag whose name is "script" in "text" insertion mode, modify step 3 to read:

+
+
    +
  1. If the parser's Document has a style sheet that is blocking scripts or has an import that is blocking scripts or the script's "ready to be parser-executed" flag is not set: spin the event loop until the parser's Document has no style sheet that is blocking scripts and has no import that is blocking scripts and the script's "ready to be parser-executed" flag is set.
  2. +
+
+ +
+ +
+

8.3 Additions to Parsing XHTML Documents

+ +

Modify step 3 of steps that run following preparing the script element to read:

+
+
    +
  1. Spin the event loop until the parser's Document has no style sheet that is blocking scripts and has no import that is blocking scripts and the pending parsing-blocking script's "ready to be parser-executed" flag is set.

  2. +
+
+ +
+
+ +
+

9. Scripting in Imports

+ +
+

9.1 Additions to Script Enabling Criteria

+ +

Add following condition to the list of Enabling and disabling scripting criteria:

+ +
+ +
+ +
+ +
+

9.2 Additions to document.currentScript

+ +

+Modify the definition of document.currentScript +as follows: +

+
+The currentScript attribute, on getting, +must return the value to which it was most recently initialized in the document or the import map of the document. +When the Document is created, the currentScript must be initialized to null. +If the Document is an imported document, its currentScript is always null. +
+ +
+
+ +
+

10. Style processing with Imports

+ +

The contents of the style elements and +the external resources of the link elements in imports must be considered as input sources of the style processing model of the master document.

+ + + +
+

10.2 Order of Appearances and Imports

+ +

The order of appearances of declarations which come from different documents are determined by the import link tree. If node documents of two declarations differ, compare the tree order of these documents in the import link tree. The last one wins.

+ +
+
+ +
+

11. Events in Imports

+ +

Events in imports is defined as a set of changes to the HTML Events.

+ +
+

11.1 Additions to Event Handlers

+ +

+Modify the event handler content attribute's +script creation criteria by expanding the first paragraph: + +

+

When an event handler content attribute is set, if the element is owned by a Document that is in a browsing context or +in an import map, ...

+
+ +
+
+ +
+

A. Acknowledgements

+ +

David Hyatt developed XBL 1.0, and Ian Hickson co-wrote XBL 2.0. These documents provided tremendous insight into the problem of behavior attachment and greatly influenced this specification.

+ +

Alex Russell and his considerable forethought triggered a new wave of enthusiasm around the subject of behavior attachment and how it can be applied practically on the Web.

+ +

Dominic Cooney and Roland Steiner worked tirelessly to scope the problem within the confines of the Web platform and provided a solid foundation for this document.

+ +

The editor would also like to thank Alex Komoroske, Angelina Fabbro, Anne van Kesteren, Boris Zbarsky, Brian Kardell, Daniel Buchner, Edward O'Connor, Eric Bidelman, Erik Arvidsson, Elliott Sprehn, Gabor Krizsanits, Hayato Ito, James Simonsen, Jonas Sicking, Ken Shirriff, Neel Goyal, Olli Pettay, Rafael Weinstein, Scott Miles, Steve Orvell, Tab Atkins, William Chan, and William Chen for their comments and contributions to this specification.

+ +

This list is too short. There's a lot of work left to do. Please contribute by reviewing and filing bugs—and don't forget to ask the editor to add your name into this section.

+ +
+ + + \ No newline at end of file diff --git a/publish/imports/WD-html-imports-20160225/respec-complement.css b/publish/imports/WD-html-imports-20160225/respec-complement.css new file mode 100644 index 00000000..abb24626 --- /dev/null +++ b/publish/imports/WD-html-imports-20160225/respec-complement.css @@ -0,0 +1,51 @@ +span.shadow-boundary { + color: Gray; +} + +table { + border: 1px solid #ccc; +} + +table code { + background-color: transparent; +} + +td, th { + padding: 0.5em; + vertical-align: top; +} + +td { + border-bottom: 1px solid #ddd; +} + +tr:last-of-type td { + border-bottom: none; +} + +th { + text-align: left; + background-color: #eee; +} + +div.algorithm { + padding: 0 0 0 20px; + border-left: .5em solid #EAF7F9; +} + +#bug-assist-form { + position: fixed; + width: 10em; + top: 5em; + right: 1em; + font-family: Tahoma,sans-serif; + font-size: 11px; + opacity:0.8; + text-align:right; +} + +var { + font-size: 0.8em; + color: #005A9C; + font-style: normal; +} diff --git a/spec/custom/W3CTRMANIFEST b/spec/custom/W3CTRMANIFEST new file mode 100644 index 00000000..1ed8dc4f --- /dev/null +++ b/spec/custom/W3CTRMANIFEST @@ -0,0 +1 @@ +index.html?specStatus=WD;shortName=custom-elements;useExperimentalStyles=false respec diff --git a/spec/custom/custom-elements-whole-world.svg b/spec/custom/custom-elements-whole-world.svg deleted file mode 100644 index a0dfa28e..00000000 --- a/spec/custom/custom-elements-whole-world.svg +++ /dev/null @@ -1,246 +0,0 @@ - - - - - - - - - element registration - algorithm - - - - - - - - - definition construction - algorithm - - - - - - - - - element upgrade - algorithm - - - - - - - - - custom element - constructor generation - algorithm - - - - - - - - - document.createElement - document.createElementNS - - - - - - - - - element is created - - - - - - - - - set custom element - prototype - - - - - - - - - element Attached - - - - - - - - - element Detached - - - - - - - - - attribute changed - - - - - - - - - enqueue a lifecycle - callback - - - - - - - - - an element is popped from - the stack of open elements - - - - - - - - - generated constructor - - - - - - - - - transition from user - agent code to script - - - - - - - - - microtask checkpoint - - - - - - - - - invoke lifecycle - callbacks - - - - - - - - - process base element - queue - - - - - - - - - transfer a lifecycle - callback - - - - - - - - - document.registerElement - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spec/custom/index.html b/spec/custom/index.html index 0c456c6b..8a06fa53 100644 --- a/spec/custom/index.html +++ b/spec/custom/index.html @@ -1,862 +1,1167 @@ + Custom Elements - - - - - - + + + + + + -
+
- +

This specification describes the method for enabling the author to define and use new types of DOM elements in a document. It will eventually be upstreamed into [[!WHATWG-DOM]], [[!HTML]], and [[!WEBIDL]]. Sections which explicitly modify existing parts of these specifications are denoted with "DOM+", "HTML+", or "Web IDL+" in their titles.

-

Custom Elements

-

W3C Editor's Draft

-
-
This version
-
https://w3c.github.io/webcomponents/spec/custom/
-
Latest published version
-
https://www.w3.org/TR/custom-elements/ -
Latest editor's draft
-
https://w3c.github.io/webcomponents/spec/custom/
-
Previous version
-
https://www.w3.org/TR/custom-elements/
-
Revision history
-
https://github.com/w3c/webcomponents/commits/gh-pages/spec/custom/
-
Participate
-
Discuss on public-webapps@w3.org (Web Platform Working Group)
-
Bugs filed
-
https://github.com/w3c/webcomponents/labels/custom-elements
-
Editor
-
Dimitri Glazkov, Google, <>
-
+
- +
-
+ -
+ -

Abstract

+
-

This specification describes the method for enabling the author to define and use new types of DOM elements in a document.

+

Any point, at which a conforming UA must make decisions about the state or reaction to the state of the conceptual model, is captured as algorithm. The algorithms are defined in terms of processing equivalence. The processing equivalence is a constraint imposed on the algorithm implementors, requiring the output of the both UA-implemented and the specified algorithm to be exactly the same for all inputs.

-

Status of This Document

+

The IDL fragments in this specification must be interpreted as required for conforming IDL fragments, as described in the Web IDL specification [[!WEBIDL]].

+
-

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

+
+

HTML+: Custom elements

-

This document was published by the Web Platform Working Group as an Editor's Draft. If you wish to make comments regarding this document, please send them to public-webapps@w3.org (subscribe, archives). All feedback is welcome.

+

This section should be inserted into the section The elements of HTML, probably as a subsection following "Scripting" and before "Common idioms without dedicated elements".

-

Publication as an Editor's Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

+
+

Introduction

-

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

+

Custom elements provide a way for authors to build their own fully-featured DOM elements. Although authors could always use non-standard tag names in their documents, with application-specific behavior added after the fact by scripting or similar, such elements have historically been non-conforming and not very functional. By defining a custom element, authors can inform the parser how to properly construct an element and how elements of that class should react to changes.

-

This document is governed by the 1 September 2015 W3C Process Document.

+

Custom elements are part of a larger effort to "rationalize the platform," by explaining existing platform features (like the elements of HTML) in terms of lower-level author-exposed extensibility points (like custom element registration). Although today there are many limitations on the capabilities of custom elements—both functionally and semantically—that prevent them from fully explaining the behaviors of HTML's existing elements, we hope to shrink this gap over time.

-
-

Table of Contents

-
    -
  1. About this Document
  2. -
  3. Dependencies
  4. -
  5. Motivations
  6. -
  7. Concepts
  8. -
  9. Custom Element Lifecycle -
      -
    1. Enqueueing and Invoking Callbacks
    2. -
    3. Types of Callbacks
    4. -
  10. -
  11. Creating and Passing Registries
  12. -
  13. Registering Custom Elements -
      -
    1. Extensions to Document Interface
    2. -
    3. Unresolved Element Pseudoclass
    4. -
  14. -
  15. Instantiating Custom Elements -
      -
    1. Extensions to Document Interface
    2. -
  16. -
  17. Parsing Custom Elements
  18. -
  19. Custom Elements and ECMAScript 6
  20. -
  21. Custom Element Semantics -
      -
    1. Custom Tag Example
    2. -
    3. Type Extension Example
    4. -
    5. Custom Element Semantics - Conclusion
    6. -
    -
  22. -
  23. Appendix A: All Algorithms in One Diagram
  24. -
  25. Acknowledgements
  26. -
+
+

Creating a custom tag

+ +

For the purposes of illustrating how to create a custom tag, let's define a custom element that encapsulates rendering a small icon for a country flag. Our goal is to be able to use it like so:

+ +
+<flag-icon country="nl"></flag-icon>
+ +

To do this, we first declare a class for the custom element, extending HTMLElement:

+ +
+class FlagIcon extends HTMLElement {
+  constructor() {
+    super()
+    this._countryCode = null
+  }
+
+  static get observedAttributes() { return ["country"]; }
+
+  attributeChangedCallback(name, newValue) {
+    // name will always be "country" due to observedAttributes
+    this._countryCode = newValue
+    this._updateRendering()
+  }
+  connectedCallback() {
+    this._updateRendering()
+  }
+
+  get country() {
+    return this._countryCode
+  }
+  set country(v) {
+    this.setAttribute("country", v)
+  }
+
+  _updateRendering() {
+    // Left as an exercise for the reader. But, you'll probably want to
+    // check this.ownerDocument.defaultView to see if we've been
+    // inserted into a document with a browsing context, and avoid
+    // doing any work if not.
+  }
+}
+ +

We then need to use this class to define the element:

+ +
+customElements.define("flag-icon", FlagIcon);
+ +

At this point, our above code will work! The parser, whenever it sees the flag-icon tag, will construct a new instance of our FlagIcon class, and tell our code about its new country attribute, which we then use to set the element's internal state and update its rendering (when appropriate).

+ +

You can also create flag-icon elements directly, using the DOM API:

+ +
+const flagIcon = document.createElement("flag-icon")
+flagIcon.country = "jp"
+document.body.appendChild(flagIcon)
+ +

Finally, we can also use the custom element constructor itself. That is, the above code is equivalent to:

+ +
+const flagIcon = new FlagIcon()
+flagIcon.country = "jp"
+document.body.appendChild(flagIcon)
-
+
+

Creating a type extension

+ +

Type extensions are a distinct kind of custom element, which are registered slightly differently and used very differently. They exist to allow reuse of behaviors from the existing elements of HTML, by extending those elements with new custom functionality. This is important since many of the existing behaviors of HTML elements can unfortunately not be duplicated by using purely custom tags. Instead, type extensions allow the installation of custom construction behavior, lifecycle hooks, and prototype chain onto onto existing elements, essentially "mixing in" these capabilities on top of the already-existing element.

+ +

Type extensions require a distinct syntax from custom tags because user agents and other software key off an element's local name in order to identify the element's basic nature. That is, the concept of type extensions building on top of existing behavior depends crucially on the extended elements retaining their original local name.

+ +

In this example, we'll be creating a type extension named plastic-button, which behaves like a normal button but gets fancy animation effects added whenever you click on it. We start by defining a class, just like before, although this time we extend HTMLButtonElement instead of HTMLElement:

+ +
+class PlasticButton extends HTMLButtonElement {
+  constructor() {
+    super()
+
+    this.addEventListener("click", () => {
+      // Draw some fancy animation effects!
+    })
+  }
+}
+ +

When registering our custom element, we have to also specify the extends option:

+ +
+customElements.define("plastic-button", PlasticButton, { extends: "button" });
+ +

In general, the name of the element being extended cannot be determined simply by looking at what element interface it extends, as many elements share the same interface (such as q and blockquote both sharing HTMLQuoteElement).

+ +

To use our type extension, we use the is attribute on a button element:

-

About this Document

+
+<button is="plastic-button">Click Me!</button>
-

All diagrams, examples, notes, are non-normative, as well as sections explicitly marked as non-normative. Everything else in this specification is normative.

+

Trying to use a type extension as a custom tag will not work; that is, <plastic-button>Click me?</plastic-button> will simply create a HTMLUnknownElement with no special behavior.

-

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC2119. For readability, these words do not appear in all uppercase letters in this specification.

+

If you need to create a type extension programmatically, you can use the following form of createElement:

-

Any point, at which a conforming UA must make decisions about the state or reaction to the state of the conceptual model, is captured as algorithm. The algorithms are defined in terms of processing equivalence. The processing equivalence is a constraint imposed on the algorithm implementors, requiring the output of the both UA-implemented and the specified algorithm to be exactly the same for all inputs.

+
+const plasticButton = document.createElement("button", { is: "plastic-button" })
+plasticButton.textContent = "Click me!"
-

Dependencies

+

And as before, the constructor will also work:

-

This document relies on the following specifications:

+
+const plasticButton2 = new PlasticButton()
+console.log(plasticButton2.localName);          // will output "button"
+console.log(plasticButton2.getAttribute("is")); // will output "plastic-button"
+ +

Notably, all the of the ways in which button is special apply to such "plastic buttons" as well: their focus behavior, ability to participate in form submission, the disabled attribute, and so on.

+
+
+ +
+

Requirements for custom element constructors

+ +

When authoring custom element constructors, developers are bound by the following conformance requirements:

    -
  • CSS Level 2 Revision 1
  • -
  • DOM Living Standard
  • -
  • HTML Living Standard
  • -
  • ECMAScript Language Specification
  • -
  • Web IDL
  • +
  • A parameter-less call to super() must be the first statement in the constructor body, to establish the correct prototype chain and this value before any further code is run.
  • +
  • A return statement must not appear anywhere inside the constructor body, unless it is a simple early-return (return or return this).
  • +
  • The element's attributes and children must not be inspected, as in the non-upgrade case none will be present, and relying on upgrades makes the element less usable.
  • +
  • The element must not gain any attributes or children, as this violates the expectations of consumers who use the createElement or createElementNS methods.
  • +
  • In general, work should be deferred to connectedCallback as much as possible—especially work involving fetching resources or rendering. However, note that connectedCallback can be called more than once, so any initialization work that is truly one-time will need a guard to prevent it from running twice.
  • +
  • In general, the constructor should be used to set up initial state and default values, and to set up event listeners.
-
+

Core concepts

+ +

Formally, a custom element is an element whose constructor and prototype are defined by the author, instead of by the user agent. The developer-supplied constructor function is called the custom element constructor.

-

Motivations

+

Two distinct types of custom elements can be registered:

-
-

There are two motivations that fueled the development of this specification:

    -
  1. Provide a way for Web developers to build their own, fully-featured DOM elements. Though it was long possible to create DOM elements with any tag names in HTML, these elements weren't very functional. By giving Web developers the means to both inform the parser on how to properly construct an element and to react to lifecycle changes of an element, the specification eliminates the need for DOM-as-a-render-view scaffolding that has to exist today in most web frameworks or libraries.
  2. -
  3. Rationalize the platform. The specification ensures that all of its new features and abilities are in concert with how the relevant bits of the Web platform work today, so that these new features could be used to explain the functionality of existing Web platform features, such as HTML elements.
  4. +
  5. A custom tag, which is registered with no extends option. These types of custom elements have local name equal to their registered name.
  6. +
  7. A type extension, which is registered with an extends option. These types of custom elements have local name equal to the value passed in their extends option, and their registered name is used as the value of the is attribute.
-

Most of the effort went into finding the right balance between the two motivations, driven by the hope that these motivations do not run counter to each other, but are rather complementary parts of the same larger story. For example, though the scope of the spec is currently limited to only creating custom elements by authors, it is designed to shorten the distance to a much more ambitious goal of rationalizing all HTML, SVG, and MathML elements into one coherent system.

-
-

Concepts

+

After a custom element is created, changing the value of the is attribute does not change the element's behavior.

-

Custom element is platform object whose interface is defined by the author. The interface prototype object of a custom element's interface is called the custom element prototype.

+

A valid custom element name is a sequence of characters name that meets all of the following requirements:

-

The custom element type identifies a custom element interface and is a sequence of characters that must match the NCName production, must contain a U+002D HYPHEN-MINUS character, and must not contain any uppercase ASCII letters. The custom element type must not be one of the following values:

    -
  • annotation-xml
  • -
  • color-profile
  • -
  • font-face
  • -
  • font-face-src
  • -
  • font-face-uri
  • -
  • font-face-format
  • -
  • font-face-name
  • -
  • missing-glyph
  • +
  • +

    name must match the PotentialCustomElementName production:

    + +
    +
    PotentialCustomElementName ::=
    +
    [a-z] (PCENChar)* '-' (PCENChar)*
    + +
    PCENChar ::=
    +
    "-" | "." | [0-9] | "_" | [a-z] | #xB7 | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x300-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x203F-#x2040] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
    +
    + +

    This uses the EBNF notation from the XML specification. [[!XML]]

    +
  • +
  • +

    name must not be any of the following:

    +
      +
    • annotation-xml
    • +
    • color-profile
    • +
    • font-face
    • +
    • font-face-src
    • +
    • font-face-uri
    • +
    • font-face-format
    • +
    • font-face-name
    • +
    • missing-glyph
    • +
    +

    The list of names above is the summary of all hyphen-containing element names from the applicable specifications, namely SVG and MathML. [[SVG11]] [[MathML]]

    +
-
-The list of names above is the summary of all hyphen-containing element names from the applicable specifications, namely SVG and MathML. +
+

These requirements ensure a number of goals for valid custom element names:

+ +
    +
  • They start with a lowercase ASCII letter, ensuring that the HTML parser will treat them as tags instead of as text.
  • +
  • They do not contain any uppercase ASCII letters, ensuring that the user agent can always treat HTML elements ASCII-case-insensitively.
  • +
  • They contain a hyphen, used for namespacing and to ensure forward compatibility (since no elements will be added to HTML, SVG, or MathML with hyphen-containing tag names in the future).
  • +
  • They can always be created with document.createElement and document.createElementNS, which have restrictions that go beyond the parser's.
  • +
+ +

Apart from these restrictions, a large variety of names is allowed, to give maximum flexibility for use cases like <math-α> or <emotion-😍>.

-

The element definition describes a custom element and consists of:

+

A custom element definition describes a custom element and consists of:

+ -

At the time of creation, a document could be associated with a registry. A registry is a set of element definitions.

+

Each custom element definition's construction stack is manipulated by the upgrade an element algorithm and the HTMLElement constructor. Each entry in the list will be either an element or an already constructed marker.

-

Element registration is a process of adding an element definition to a registry. One element definition can only be registered with one registry.

+
-

If a document has a registry associated with it, then for this document and a given element definition in the registry, the custom element's interface must be the element interface for local name and namespace values of custom element type and the namespace of the element definition, respectively.

+
+

The CustomElementsRegistry interface

-
-Effectively, the registry is consulted whenever a new DOM element is created, whether imperatively or by a parser. Whenever a matching element definition is found in the registry, the information in this definition is used to create a new instance of a custom element. -
+

Each Window object is associated with a unique instance of a CustomElementsRegistry object, allocated when the Window object is created.

-

If a document does not have a registry associated with it, all attempts at element registration will fail.

+

Custom element registries are associated with Window objects, instead of Document objects, since each custom element constructor inherits from the HTMLElement interface, and there is exactly one HTMLElement interface per Window object.

-

The exact nature of creating registries, their association with documents, and element registration are defined further in this specification.

+

The customElements attribute of the Window interface must return the CustomElementsRegistry object for that Window object.

-

Custom Element Lifecycle

+
+interface CustomElementsRegistry {
+  void define(DOMString name, Function constructor, optional ElementRegistrationOptions options);
+};
 
-

A custom element can go through these changes during its lifetime:

- +dictionary ElementRegistrationOptions { + DOMString extends; +}; +
-

Various callbacks can be invoked when a custom element goes through some of these changes. These callbacks are stored internally as a collection of key-value pairs and called lifecycle callbacks.

+
+
+
window . customElements . define(name, constructor)
+
Defines a new custom element, mapping the given name to the given constructor as a custom tag.
-

To transfer a callback named name from an object property named property to lifecycle callbacks, the user agent must run the following steps:

-
-
-
Input
-
NAME, name of the callback
-
PROPERTY, name of the property
-
OBJECT, the object from which PROPERTY is being transferred
-
LIFECYCLE, the lifecycle callbacks
-
Output
-
None
-
-
    -
  1. Let CALLBACK be the result of getting a property named PROPERTY of OBJECT
  2. -
  3. If CALLBACK exists and is a callable object, add CALLBACK to LIFECYCLE, associated with the key NAME.
  4. -
+
window . customElements . define(name, constructor, { extends: baseTagName })
+
Defines a new custom element, mapping the given name to the given constructor as a type extension for the supplied base tag.
+
-

Enqueuing and Invoking Callbacks

+

Every CustomElementsRegistry has a set of custom element definitions, initially empty. In general, algorithms in this specification look up elements in the registry by any of name, local name, or constructor.

-

To facilitate invoking callbacks, each unit of related similar-origin browsing contexts has a processing stack, which is initially empty. Each item in the stack is an element queue, which is initially empty as well. Each item in the element queue is a custom element.

+

A CustomElementsRegistry's list of defined local names is the list containing all of the local names of the custom element definitions in the registry.

-

Each custom element has an associated callback queue and an element is being created flag. The flag is initially set to false and the callback queue is initially empty. Each item in the queue consists of the callback itself and zero or more string values that are used as callback arguments.

+

Every CustomElementsRegistry has an upgrade candidates map, which tracks undefined potentially-custom elements. Each entry has a key that is a valid custom element name and a value that is a sorted element queue. It is is initially empty.

-

To invoke callbacks in an element queue, the user agent must run these steps or their equivalent:

+

Element definition is a process of adding a custom element definition to the CustomElementsRegistry. This is accomplished by the define method. When invoked, the define(name, constructor, options) method must run these steps:

-
-
-
Input
-
QUEUE, an element queue
-
Output
-
None
-
    -
  1. For each custom element ELEMENT in QUEUE: -
      -
    1. Let CALLBACKS be the ELEMENT's callback queue
    2. -
    3. Repeat until CALLBACKS is empty: +
    4. If IsConstructor(constructor) is false, throw a TypeError and abort these steps.
    5. + +
    6. If the context object is an HTML document, let name be converted to ASCII lowercase.
    7. + +
    8. If name is not a valid custom element name, throw a SyntaxError and abort these steps.
    9. + +
    10. If this CustomElementsRegistry contains an entry with name name, throw a NotSupportedError and abort these steps.
    11. + +
    12. If this CustomElementsRegistry contains an entry with contructor constructor, throw a NotSupportedError and abort these steps.
    13. + +
    14. Let localName be name.
    15. + +
    16. Let extends be the value of the extends member of options, or null if no such member exists.
    17. + +
    18. +

      If extends is not null:

      +
        -
      1. Remove the first item from CALLBACKS and let CALLBACK be this item
      2. -
      3. Invoke CALLBACK with ELEMENT as callback this value and, if present, using string values in CALLBACK as arguments
      4. -
    19. -
  2. -
-
+
  • If the context object is an HTML document, let extends be converted to ASCII lowercase.
  • -

    Any time a script calls a method, reads or sets a property that is implemented by the user agent, the following actions must occur:

    - +
  • If there is no element interface for extends and the HTML namespace, throw a NotSupportedError and abort these steps.
  • -
    As described, these actions wrap every user agent-implemented method or property accessor. The intended effect is that any lifecycle callbacks, enqueued as a result of running these methods or accessors are invoked prior to returning control back to script. If a method or accessor is known to never enqueue a lifecycle callback, the user agent could choose not to wrap it as a performance optimization.
    +
  • Set localName to extends.
  • + + -

    In addition to an element queue, there is also a sorted element queue. The custom elements are kept in the order of increasing custom element order.

    +
  • Let observedAttributesIterable be Get(constructor, "observedAttributes"). Rethrow any exceptions.
  • -

    The custom element order is a sum of document custom element order and import tree order, in which the import tree order is scaled so that its lowest value is always larger than the highest possible value of document custom element order.

    +
  • If observedAttributesIterable is undefined, let observedAttributes be an empty sequence<DOMString>. Otherwise, let observedAttributes be the result of converting observedAttributesIterable to a sequence<DOMString>. Rethrow any exceptions. -

    The document custom element order is a numerical value, associated with every custom element. This value is as a result of custom element's document keeping a numerical value that is incremented and assigned to custom element as its custom element order whenever the following occurs:

    - +
  • Let prototype be Get(constructor, "prototype"). Rethrow any exceptions.
  • -

    The import tree order of a given custom element of an import link tree is determined by tree order in an import link tree that was flattened by replacing every import link with the content of its imported document.

    +
  • If Type(prototype) is not Object, throw a TypeError exception.
  • -

    The highest stable order is the value that is immediately preceding the custom element order of an element in the first encountered import, in tree order, that has not yet completely loaded. If there is no such element, the highest stable order is the highest custom element order in the flattened import link tree.

    +
  • Let connectedCallback be Get(prototype, "connectedCallback"). Rethrow any exceptions.
  • -
    -

    Because imports load asynchronously, we need to divide a sorted element queue into the part where things have settled down (all imports have loaded), and the part where the loading is still happening, and thus the actual sorting order is not yet determined. For example, suppose you have the following document structure:

    +
  • If connectedCallback is not undefined, and IsCallable(connectedCallback) is false, throw a TypeError exception.
  • -
    
    -index.html:
    -<link rel="import" href="import.html">
    -...
    -<me-second></me-second>
    -...
    +    
  • Let disconnectedCallback be Get(prototype, "disconnectedCallback"). Rethrow any exceptions.
  • -import.html: -<me-first></me-first> +
  • If disconnectedCallback is not undefined, and IsCallable(disconnectedCallback) is false, throw a TypeError exception.
  • -
    +
  • Let attributeChangedCallback be Get(prototype, "attributeChangedCallback"). Rethrow any exceptions.
  • -

    The order of custom elements in the flattened import link tree is me-first (1), me-second (2). However, it's very likely that the parser will find out about me-second sooner than me-first, since the latter requires loading the import.html. While the network stack is doing its job, the highest stable order stays at the beginning position. When import.html is ready, the order jumps all the way to me-second (2).

    +
  • If attributeChangedCallback is not undefined, and IsCallable(attributeChangedCallback) is false, throw a TypeError exception.
  • -
    +
  • Let definition be a new custom element definition with name name, local name localName, constructor constructor, prototype prototype, observed attributes observedAttributes, and lifecycle callbacks connectedCallback, disconnectedCallback, and attributeChangedCallback (stored with their corresponding name).
  • -

    Each unit of related similar-origin browsing contexts has an initially-empty sorted element queue, called base element queue.

    +
  • Add definition to this CustomElementsRegistry.
  • -

    Whenever a base element queue becomes non-empty, the user agent must queue a microtask to process base element queue for the unit of related similar-origin browsing contexts to which the scripts' browsing context belongs.

    +
  • Let map be this CustomElementsRegistry's upgrade candidates map.
  • -

    To prevent reentrance while processing base element queue, each unit of related similar-origin contexts has a processing base element queue flag, which must initially be false.

    +
  • Let candidates be the sorted element queue which is the value of the entry in map with key name.
  • -

    To process base element queue, a conforming user agent must run the following steps or their equivalent:

    +
  • For each element candidate in candidates, enqueue a custom element upgrade given candidate and definition.
  • + +
  • Set the value of the entry in map whose key is name to an empty sorted element queue.
  • + + +

    Because element definition can occur at any time, a non-custom element could be created that might in the future become a custom element after an appropriate definition is registered. Such elements are called undefined potentially-custom elements. If such a definition is ever registered, the element will be upgraded, becoming a custom element.

    + +

    To upgrade an element, given as input a custom element definition definition and an element element, run the following steps:

    -
    -
    -
    Input
    -
    ENVIRONMENT, the unit of related similar-origin browsing contexts
    -
    Output
    -
    None
    -
      -
    1. Let PROCESSING be the processing base element queue flag
    2. -
    3. If PROCESSING is true, stop.
    4. -
    5. Set PROCESSING to true.
    6. -
    7. Invoke callbacks in ENVIRONMENT's base element queue up to the highest stable order, inclusively
    8. -
    9. Set PROCESSING to false.
    10. +
    11. Add element to the end of definition's construction stack.
    12. + +
    13. Let C be definition's constructor.
    14. + +
    15. Let constructResult be Construct(C).
    16. + +
    17. Remove element from the end of definition's construction stack.
    18. + +
    19. If constructResult is an abrupt completion, return constructResult (i.e., re-throw the exception).
    20. + +
    21. +

      If SameValue(constructResult.[[\value]], element) is false, throw a InvalidStateError and terminate these steps.

      + +

      This can occur if C constructs another instance of the same custom element before calling super(), or if C uses JavaScript's return-override feature to return an arbitrary object from the constructor.

      +
    22. + +
    23. Set element's defined flag.
    -
    -

    In the unit of related similar-origin browsing contexts to which the scripts' browsing context belongs, the current element queue is the element queue at the top of the processing stack or the base element queue if the processing stack is empty.

    +
    +
    -

    To enqueue a lifecycle callback, the user must run the following steps or their equivalent:

    +
    + +
    +

    Miscellaneous patches

    + +
    +

    HTML+: The Window object

    + +

    HTML's Window object definition must be extended as follows:

    + +
    +partial interface Window {
    +    readonly attribute CustomElementsRegistry customElements;
    +};
    +
    + +

    As is conventional for HTML, the actual definition of this property is elsewhere in the specification (cf. location and history). We have it above in the section "The CustomElementsRegistry interface".

    +
    + +
    +

    HTML+: Element interfaces

    + +

    HTML currently does not do a great job of defining DOM's element interface concept. There is a definition hidden inside the parser, but it isn't explicit that this also covers other element creation cases. We should create a section that is more explicit, and it should roughly contain the following (including the note afterward):

    + +

    The element interface for an element with name name in the HTML namespace is determined as follows:

    -
    -
    -
    Input
    -
    NAME, name of the callback
    -
    ELEMENT, the custom element for which the callback is enqueued
    -
    Output
    -
    None
    -
      -
    1. Let DEFINITION be ELEMENT's definition
    2. -
    3. If DEFINITION does not exist, let CALLBACK be null and stop.
    4. -
    5. Let CALLBACKS be the lifecycle callbacks from DEFINITION -
    6. Let CALLBACK be the callback, associated with the key NAME in CALLBACKS
    7. -
    8. If there is no such callback, stop.
    9. -
    10. Add CALLBACK to ELEMENT's callback queue
    11. -
    12. If element is being created flag is false, add ELEMENT to current element queue.
    13. +
    14. If this specification defines an interface appropriate for the element type corresponding to the tag name name, return that interface.
    15. +
    16. If other applicable specifications define such an appropriate interface for name, return the interface they define.
    17. +
    18. If name is a valid custom element name, return HTMLElement.
    19. +
    20. Otherwise, return HTMLUnknownElement.
    -
    -

    Types of Callbacks

    +

    + The use of HTMLElement instead of HTMLUnknownElement in the case of valid custom element names is done to ensure that any potential future upgrades only cause a linear transition of the element's prototype chain, from HTMLElement to a subclass, instead of a lateral one, from HTMLUnknownElement to an unrelated subclass. +

    -

    The following callbacks are recognized:

    -
    -
    createdCallback
    -
    This callback is invoked after custom element instance is created and its definition is registered. The actual timing of this callback is defined further in this specification.
    -
    The custom element prototype must be set just prior to invoking callback.
    -
    For the duration of this callback invocation, the element is being created flag must be set to true. In all other cases, the flag must be set to false.
    -
    If the created callback exists for an element, all other callbacks must not be enqueued until after this created callback's invocation had started.
    -
    attachedCallback
    -
    Unless specified otherwise, this callback must be enqueued whenever custom element is inserted into a document and this document has a browsing context.
    -
    detachedCallback
    -
    Unless specified otherwise, this callback must be enqueued whenever custom element is removed from the document and this document has a browsing context.
    -
    attributeChangedCallback
    -
    Unless specified otherwise, this callback must be enqueued whenever custom element's attribute is added, changed or removed. Depending on the type of attribute modification, the following additional strings are added to the queue item: -
    -
    attribute is set
    -
    attribute local name, null, new attribute value, and the attribute namespace.
    -
    attribute is changed
    -
    attribute local name, old attribute value, new attribute value, and the attribute namespace.
    -
    attribute is removed -
    attribute local name, old attribute value, null, and the attribute namespace.
    -
    -
    +
    -

    To set custom element prototype on a custom element, a conforming user agent must run the following steps or their equivalent:

    +
    +

    DOM+: Elements

    + +

    The Element interface section will need to be modified as follows. The paragraph listing the values associated with an element should be modified to read as follows, including the note afterward:

    + +

    Elements have an associated namespace, namespace prefix, local name, and defined flag. When an element is created, all of these values are set. An element whose defined flag is set is said to be defined.

    + +

    + As detailed elsewhere in this specification, all elements that are not custom elements are already defined upon their creation. Custom elements become defined once their constructor has been called, either synchronously or during the upgrade process. +

    + +

    Additionally, after the talk about qualified names but before the discussion of attributes, the following algorithm should be inserted:

    + +

    To create an element, given a document, localName, prefix, namespace, typeExtension, an optional synchronous custom elements flag, and an optional auto-upgrade custom elements flag, run the following steps:

    -
    -
    -
    Input
    -
    ELEMENT, element
    -
    Output
    -
    None
    -
      -
    1. Let PROTOTYPE be the custom element prototype in ELEMENT's definition
    2. -
    3. Set the value of the [[Prototype]] internal property of ELEMENT to PROTOTYPE.
    4. -
    5. If ELEMENT is in a document and this document has a browsing context: -
        -
      1. Enqueue attached callback for ELEMENT
      2. -
    6. +
    7. Let registry be null.
    8. + +
    9. If document has a browsing context, set registry to document's associated Window's CustomElementRegistry object.
    10. + +
    11. +

      If typeExtension is not null:

      + +
        +
      1. If registry is null, throw a NotSupportedError and abort these steps.
      2. + +
      3. If namespace is not the HTML namespace, throw a TypeError exception and abort these steps.
      4. + +
      5. Let interface be the element interface for localName and the HTML namespace.
      6. + +
      7. +

        If there is an the entry in registry with name typeExtension, let definition be that entry, and perform the following subsubsteps:

        + +
          +
        1. If definition's local name is not localName, throw a TypeError exception and abort these steps.
        2. + +
        3. Let result be a new element that implements interface, with no attributes, namespace set to the HTML namespace, namespace prefix set to prefix, local name set to localName, defined flag unset, and node document set to document.
        4. + +
        5. Set an attribute value for result using "is" and type.
        6. + +
        7. Enqueue a custom element upgrade given result and definition.
        8. + +
        9. Return result.
        10. +
        +
      8. + +
      9. +

        Otherwise:

        + +
          +
        1. Let result be a new element that implements interface, with no attributes, namespace set to the HTML namespace, namespace prefix set to prefix, local name set to localName, defined flag unset, and node document set to document.
        2. + +
        3. Set an attribute value for result using "is" and type.
        4. + +
        5. Let upgrade queue be the sorted element queue that is the value of the entry in registry's upgrade candidates map with key typeExtension, creating an empty sorted element queue if no such entry exists.
        6. + +
        7. Enqueue result in upgrade queue.
        8. +
        +
      10. +
      +
    12. + +
    13. +

      Otherwise, if registry is not null, namespace is the HTML namespace, and registry contains an entry with local name localName, let definition be that entry, and perform the following substeps:

      + +
        +
      1. +

        If synchronous custom elements flag is set:

        + +
          +
        1. Let C be definition's constructor.
        2. + +
        3. Let result be Construct(C). Rethrow any exceptions.
        4. + +
        5. +

          If result does not implement the HTMLElement interface, throw a TypeError exception and abort these steps.

          + +

          This is meant to be a brand check to ensure that the object was allocated by the HTMLElement constructor. Eventually Web IDL may give us a more precise way to do brand checks.

          +
        6. + +
        7. Set result's defined flag.
        8. + +
        9. Return result.
        10. +
        +
      2. + +
      3. +

        Otherwise:

        + +
          +
        1. Let result be a new element that implements the HTMLElement interface, with no attributes, namespace set to the HTML namespace, namespace prefix set to prefix, local name set to localName, defined flag unset, and node document set document.
        2. + +
        3. Enqueue a custom element upgrade given result and definition.
        4. + +
        5. Return result.
        6. +
        +
      4. +
      +
    14. + +
    15. +

      Otherwise:

      + +
        +
      1. Let interface be the element interface for localName and namespace.
      2. + +
      3. Let result be a new element that implements interface, with no attributes, namespace set to namespace, namespace prefix set to prefix, local name set to localName, defined flag set, and node document set to the context object.
      4. + +
      5. +

        If registry is not null, namespace is the HTML namespace, localName is a valid custom element name, and the auto-upgrade custom elements flag is set:

        + +
          +
        1. Unset result's defined flag.
        2. + +
        3. Let upgrade queue be the sorted element queue that is the value of the entry in registry's upgrade candidates map with key localName, creating an empty sorted element queue if no such entry exists.
        4. + +
        5. Enqueue result in upgrade queue.
        6. +
        +
      6. + +
      7. Return result.
      8. +
      +
    -
    +
    + +
    +

    DOM+: Cloning

    -

    Creating and Passing Registries

    +

    The clone a node algorithm will need to be modified as follows. A new case, separate from the main switch, will be needed to generate copy for Elements. It should use create an element, given document, node's local name, node's namespace prefix, node's namespace, and the value of node's is attribute (if present). The synchronous custom elements flag and auto-upgrade custom elements flag should both be unset.

    -

    When an HTML Document is loaded in a browsing context, a new registry must be created and associated with this document.

    +
    + +
    -

    A new document instance must be associated with an existing registry in these cases:

    +
    +

    Custom element lifecycle

    +

    A custom element can go through these changes during its lifetime:

    -

    In all other cases, new documents must not have a registry.

    +

    Various callbacks can be invoked when a custom element goes through some of these changes. These callbacks are stored internally as a collection of lifecycle callbacks. They can be looked up by name, which is one of connectedCallback, disconnectedCallback, or attributeChangedCallback.

    -

    Registering Custom Elements

    +
    +

    Enqueuing and invoking callbacks

    + +

    To facilitate invoking callbacks, each unit of related similar-origin browsing contexts has a processing stack, which is initially empty. Each item in the stack is an element queue, which is initially empty as well. Each item in the element queue is a custom element.

    + +

    Custom elements have an associated custom element action queue, initially empty. Each item in the custom element action queue is of one of two types:

    -

    Because element registration can occur at any time, a custom element could be created before its definition is registered. Such custom element instances are called unresolved elements. When an unresolved element is created, and if its element interface was not defined by HTML or other applicable specifications, the unresolved element's element interface must be:

    -
    -The effect of this statement is that any HTML (or SVG) element with the local name that is a valid custom element type will have HTMLElement (or SVGElement) as element interface, rather than HTMLUnknownElement. -
    +

    To enqueue a custom element callback action, given a custom element element, a callback name callbackName, and a list of arguments args, run the following steps:

    -

    Each registry has an associated map of all instances of unresolved elements for a given pair of custom element type and namespace. This data structure is called the upgrade candidates map and is initially empty. Each value item in this map is a sorted element queue.

    +
      +
    1. +

      Let registry be element's node document's associated Window's CustomElementRegistry object.

      -

      Whenever an unresolved element is created, it must be added to the respective sorted element queue in upgrade candidates map.

      +

      This algorithm can only be called in scenarios where element's node document has a browsing context.

      +
    2. -

      Registering an element definition is the responsibility of the element registration algorithm, which must be equivalent to running these steps:

      +
    3. + Let definition be the the entry in registry with entry name equal to element's local name. -
      -
      -
      Input
      -
      DOCUMENT, the document
      -
      TYPE, the custom element type of the element being registered
      -
      PROTOTYPE, the custom element prototype
      -
      NAME, a local name, optional
      -
      Output
      -
      ERROR, a variable that holds one of these values: None, InvalidType, InvalidName, NoRegistry, or DuplicateDefinition
      -
      -
        -
      1. Let ERROR and DEFINITION be the result of running definition construction algorithm with DOCUMENT, TYPE, PROTOTYPE, and NAME as arguments
      2. -
      3. If ERROR is not None, stop.
      4. -
      5. Let REGISTRY be DOCUMENT's registry
      6. -
      7. If REGISTRY does not exist, set ERROR to NoRegistry and stop.
      8. -
      9. Add DEFINITION to REGISTRY
      10. -
      11. Let MAP be REGISTRY's upgrade candidates map
      12. -
      13. Run element upgrade algorithm with MAP and DEFINITION as arguments.
      14. +

        This algorithm can only be called when such a definition exists.

        + + +
      15. Let callbacks be definition's lifecycle callbacks.
      16. + +
      17. Let callback be callback in callbacks named callbackName.
      18. + +
      19. If callback is undefined, abort these steps.
      20. + +
      21. +

        If callbackName is "attributeChangedCallback":

        + +
          +
        1. Let attributeName be the the first element of args.
        2. +
        3. If definition's observed attributes does not contain attributeName, abort these steps.
        4. +
        +
      22. + +
      23. Add a callback action to element's custom element action queue, with callback function callback and arguments args.
      24. + +
      25. If element's element is being created flag is false, add element to the current element queue.
      -
      -

      The definition construction algorithm creates an element definition and must be equivalent to running these steps:

      +

      To enqueue a custom element upgrade, given an element element and custom element definition definition, run the following steps:

      -
      -
      -
      Input
      -
      DOCUMENT, the document
      -
      TYPE, the custom element type of the element being registered
      -
      PROTOTYPE, the custom element prototype
      -
      NAME, a local name, optional
      -
      Output
      -
      DEFINITION, the element definition
      -
      ERROR, a variable that holds one of these values: None, InvalidType, InvalidName, or DuplicateDefinition
      -
        -
      1. Let ERROR be None
      2. -
      3. Convert TYPE to ASCII lowercase
      4. -
      5. If DOCUMENT is an HTML document, convert NAME to ASCII lowercase
      6. -
      7. If TYPE is an invalid custom element type, set ERROR to InvalidType and stop.
      8. -
      9. Let NAMESPACE be HTML Namespace
      10. -
      11. Let IS-SVG be the result of running SVGElement inheritance detection algorithm with PROTOTYPE and the global environment of DOCUMENT as arguments
      12. -
      13. If IS-SVG is true, set NAMESPACE to SVG Namespace
      14. -
      15. If there already exists a definition with the same TYPE, set ERROR to DuplicateDefinition and stop.
      16. -
      17. If NAME was provided and is not null: -
          -
        1. Let BASE be the element interface for NAME and NAMESPACE
        2. -
        3. If BASE does not exist or is an interface for a custom element, set ERROR to InvalidName and stop.
        4. -
      18. -
      19. Otherwise: -
          -
        1. If NAMESPACE is SVG Namespace, set ERROR to InvalidName and stop.
        2. -
        3. Let NAME be TYPE
        4. -
      20. -
      21. Let LIFECYCLE be lifecycle callbacks
      22. -
      23. Transfer callback named createdCallback to LIFECYCLE from property named createdCallback on PROTOTYPE
      24. -
      25. Transfer callback named attachedCallback to LIFECYCLE from property named attachedCallback on PROTOTYPE
      26. -
      27. Transfer callback named detachedCallback to LIFECYCLE from property named detachedCallback on PROTOTYPE
      28. -
      29. Transfer callback named attributeChangedCallback to LIFECYCLE from property named attributeChangedCallback on PROTOTYPE
      30. -
      31. Let DEFINITION be an element definition with custom element type set to TYPE, local name to NAME, namespace to NAMESPACE, custom element prototype to PROTOTYPE, and lifecycle callbacks to LIFECYCLE.
      32. +
      33. Add an upgrade action to element's custom element action queue, with custom element definition definition.
      34. + +
      35. If element's element is being created flag is false, add element to the current element queue.
      -
      -

      The SVGElement inheritance detection algorithm must run these steps:

      +

      To invoke custom element actions in an element queue queue, run the following steps:

      -
      -
      -
      Input
      -
      DESCENDANT, an object whose inheritance is being detected
      -
      ENVIRONMENT, a global environment
      -
      Output
      -
      RESULT, true, if DESCENDANT inherits from SVGElement or false otherwise
      -
        -
      1. Set RESULT to true
      2. -
      3. Let SVG-PROTOTYPE be the SVGElement's interface prototype object for ENVIRONMENT
      4. -
      5. Let PROTOTYPE be DESCENDANT
      6. -
      7. Repeat until PROTOTYPE is undefined: -
          -
        1. If PROTOTYPE strictly equals to SVG-PROTOTYPE, stop and return RESULT.
        2. -
        3. Let PROTOTYPE be the result of getting a prototype of PROTOTYPE
        4. -
        -
      8. Set RESULT to false
      9. -
      10. Return RESULT.
      11. +
      12. +

        For each custom element element in queue:

        + +
          +
        1. Let actions be element's custom element action queue.
        2. +
        3. +

          Repeat until actions is empty:

          + +
            +
          1. +

            Remove the first element of actions, letting action be the result. Switch on action's type:

            + +
            +
            upgrade action
            +
            Upgrade element using action's custom element definition.
            + +
            callback action
            +
            Invoke action's callback function with action's arguments, and with element as the callback this value.
            +
            + +

            If this throws any exception, report the exception.

            +
          2. +
          +
        4. +
        +
      -
      +

      Any time a script calls a method, reads or sets a property that is implemented by the user agent, the following actions MUST occur:

      + + +
      As described, these actions wrap every user agent-implemented method or property accessor. The intended effect is that any lifecycle callbacks, enqueued as a result of running these methods or accessors are invoked prior to returning control back to script. If a method or accessor is known to never enqueue a custom element action, the user agent could choose not to wrap it as a performance optimization.
      + +

      Custom elements have an associated element is being created flag, initially false.

      + +

      In addition to an element queue, there is also a sorted element queue. The custom elements are kept in the order of increasing custom element order.

      + +

      The custom element order is a numerical value, associated with every custom element. This value is assigned as a result of custom element's document keeping a numerical value that is incremented and assigned to custom element as its custom element order whenever the following occurs:

      + + +

      Each unit of related similar-origin browsing contexts has an initially-empty sorted element queue, called base element queue.

      + +

      Whenever a base element queue becomes non-empty, the user agent MUST queue a microtask to process base element queue for the unit of related similar-origin browsing contexts to which the scripts' browsing context belongs.

      + +

      To prevent reentrance while processing base element queue, each unit of related similar-origin contexts has a processing base element queue flag, which MUST initially be false.

      -

      The element upgrade algorithm upgrades unresolved elements whose definition is now registered and must be equivalent to running these steps:

      +

      To process base element queue, a conforming user agent MUST run the following steps or their equivalent:

      Input
      -
      Let MAP, an upgrade candidates map
      -
      DEFINITION, element definition
      +
      ENVIRONMENT, the unit of related similar-origin browsing contexts
      Output
      None
      -
        -
      1. Let TYPE be the custom element type in DEFINITION
      2. -
      3. Let CANDIDATES be the sorted element queue for TYPE and NAMESPACE in MAP
      4. -
      5. For each item ELEMENT in CANDIDATES: -
          -
        1. Enqueue created callback for ELEMENT
        2. -
      6. -
      7. Set CANDIDATES to empty sorted element queue.
      8. +
          +
        1. Let PROCESSING be the processing base element queue flag
        2. +
        3. If PROCESSING is true, stop.
        4. +
        5. Set PROCESSING to true.
        6. +
        7. Invoke custom element actions in ENVIRONMENT's base element queue
        8. +
        9. Set PROCESSING to false.
      -

      Extensions to Document Interface

      +

      In the unit of related similar-origin browsing contexts to which the scripts' browsing context belongs, the current element queue is the element queue at the top of the processing stack or the base element queue if the processing stack is empty.

      -

      The registerElement method of the Document interface provides a way to register a custom element and returns its custom element constructor.

      +
    +
    +

    DOM+: Mutation algorithms

    -
    
    -partial interface Document {
    -    Function registerElement(DOMString type, optional ElementRegistrationOptions options);
    -};
    +

    The mutation algorithms sections need to be modified as follows to properly enqueue custom element callbacks.

    -dictionary ElementRegistrationOptions { - object? prototype = null; - DOMString? extends = null; -}; +

    Modify the insert algorithm as follows. Replace step 6.2 with:

    -
    +
      +
    1. +

      For each inclusive descendant inclusiveDescendant of node, in tree order, run these subsubsteps:

      -

      When called, the registerElement method must run these steps:

      +
        +
      1. Run the insertion steps with inclusiveDescendant and parent.
      2. -
        -
        -
        Input
        -
        DOCUMENT, method's context object, a document
        -
        TYPE, the custom element type of the element being registered
        -
        PROTOTYPE, the custom element prototype, optional
        -
        EXTENDS, the local name of an HTML or SVG element that is being extended, optional
        -
        Output
        -
        CONSTRUCTOR, the custom element constructor
        -
        -
          -
        1. If PROTOTYPE is null, let PROTOTYPE be the result of invoking Object.create with HTMLElement's interface prototype object as only argument
        2. -
        3. Let NAME be EXTENDS
        4. -
        5. Let ERROR be the result of running the element registration algorithm with DOCUMENT, TYPE, PROTOTYPE, and NAME as arguments
        6. -
        7. If ERROR is InvalidType, throw a SyntaxError and stop.
        8. -
        9. If ERROR is not None, throw a NotSupportedError and stop.
        10. -
        11. Return result of running custom element constructor generation algorithm with DOCUMENT and PROTOTYPE as arguments.
        12. +
        13. If inclusiveDescendant is a custom element, and was previously not in a composed document, but now is, enqueue a custom element callback action with inclusiveDescendant, callback name "connectedCallback", and an empty argument list.
        14. +
        +
      - -
      -

      ElementRegistrationOptions is an abstraction that enables using function objects and ES6 classes as the second argument of document.registerElement method.

      -
      +

      Modify the remove algorithm as follows. Replace step 9 with:

      -
      -

      In order to register a custom element with a prototype, other than HTMLElement or SVGElement, the caller of document.registerElement has to first build a proper prototype object that inherits from HTMLElement. Here's a simple example of how one could do this:

      -
      
      -document.registerElement('x-foo', {
      -    prototype: Object.create(HTMLParagraphElement.prototype, {
      -        firstMember: {
      -            get: function() { return "foo"; },
      -            enumerable: true,
      -            configurable: true
      -        },
      -        // specify more members for your prototype.
      -        // ...
      -    }),
      -    extends: 'p'
      -});
      -
      -
      -

      Note the use of extends option to specify that the element is being registered as a type extension -- that is, this element does not introduce a new tag (like the custom tag elements do), but rather extends an existing element of type HTMLParagraphElement. Here's how one could instantiate this element:

      -
      
      -<p is="x-foo">Paragraph of amazement</p>
      -
      -Or imperatively, in JavaScript: -
      
      -var foo = document.createElement('p', 'x-foo');
      -
      -
      -

      Elements with SVGElement prototype deserve a special mention: using custom tag approach results in ignored elements in SVG. Thus, your SVG-based custom elements would almost always be type extensions.

      +
        +
      1. +

        For each inclusive descendant inclusiveDescendant of node, in tree order, run these substeps:

        -

        Unresolved Element Pseudoclass

        +
          +
        1. Run the removing steps with inclusiveDescendant and parent.
        2. -

          The :unresolved pseudoclass must match all custom elements whose created callback has not yet been invoked.

          +
        3. If inclusiveDescendant is a custom element, and was previously in a composed document, but now is not, enqueue a custom element callback action with inclusiveDescendant, callback name "disconnectedCallback", and an empty argument list.
        4. +
        +
      2. +
      -
      -

      The :unresolved pseudoclass could be used to mitigate the Flash of Unstyled Content (FOUC) issues with custom elements. -

      +

      Modify the change an attribute algorithm as follows. Add an additional step after step 1:

      -

      Instantiating Custom Elements

      +
        +
      1. If element is a custom element, enqueue a custom element callback action with element, callback name "attributeChangedCallback", and an argument list containing attribute's local name, attribute's value, value, and attribute's namespace.
      2. +
      -

      The custom element type is given to a custom element at the time of its instantiation in one of the two ways:

      -
        -
      1. As the local name of the custom element. These types of custom element types are called custom tags.
      2. -
      3. As the value of the is attribute of the custom element. custom element types given this way are called type extensions.
      4. +

        Modify the append an attribute algorithm as follows. Add an additional step after step 1:

        + +
          +
        1. If element is a custom element, enqueue a custom element callback action with element, callback name "attributeChangedCallback", and an argument list containing attribute's local name, null, attribute's value, and attribute's namespace.
        -

        After a custom element is instantiated, changing the value of the is attribute must not affect this element's custom element type.

        +

        Modify the remove an attribute algorithm as follows. Add an additional step after step 1:

        -

        If both types of custom element types are provided at the time of element's instantiation, the custom tag must win over the type extension. +

          +
        1. If element is a custom element, enqueue a custom element callback action with element, callback name "attributeChangedCallback", and an argument list containing attribute's local name, attribute's value, null, and attribute's namespace.
        2. +
        -

        All custom elements must be constructable with a function object, called custom element constructor. This constructor must be created with the custom element constructor generation algorithm, which must be equivalent to running these steps:

        -
        -
        -
        Input
        -
        PROTOTYPE, the custom element prototype.
        -
        DOCUMENT, the owner document for new custom element
        -
        Output
        -
        CONSTRUCTOR, the custom element constructor
        -
        -
          -
        1. If PROTOTYPE is already an interface prototype object for any interface object or PROTOTYPE has a non-configurable property named constructor, throw a NotSupportedError and stop.
        2. -
        3. Let DEFINITION be an element definition that has PROTOTYPE as custom element prototype
        4. -
        5. Let CONSTRUCTOR be the interface object whose interface prototype object is PROTOTYPE and when called as a constructor, executes these steps: -
            -
          1. Let ELEMENT be the context object
          2. -
          3. Let TYPE be the custom element type in DEFINITION
          4. -
          5. Let NAME be the local name in DEFINITION
          6. -
          7. Let NAMESPACE be the namespace in DEFINITION
          8. -
          9. Set ELEMENT's local name to NAME, namespace to the NAMESPACE, and node document to DOCUMENT
          10. -
          11. If TYPE is not the same as NAME, set the value of ELEMENT's is attribute to TYPE
          12. -
          13. Enqueue created callback for ELEMENT
          14. -
          15. Return ELEMENT.
          16. -
        6. +

          Modify the replace an attribute algorithm as follows. Add an additional step after step 1:

          + +
            +
          1. If element is a custom element, enqueue a custom element callback action with element, callback name "attributeChangedCallback", and an argument list containing oldAttr's local name, oldAttr's value, newAttr's value, and oldAttr's namespace.
          -
        -

        Extensions to Document Interface

        +
    +
    -

    To allow creating both custom tag and type extension-style custom elements, the createElement or createElementNS methods have overloads with a typeExtension argument:

    +
    -
    
    -partial interface Document {
    -    Element createElement(DOMString localName, DOMString typeExtension);
    -    Element createElementNS(DOMString? namespace, DOMString qualifiedName, DOMString typeExtension);
    -};
    -
    -

    +
    +

    Instantiating custom clements

    -
    +
    +

    HTML+: The HTMLElement constructor

    -

    Instead of step 3 in createElement and step 9 in createElementNS (the steps that determine element interface, both methods must run the following -steps:

    -
      -
    1. Let TYPE be typeExtension, or localName if typeExtension is not present
    2. -
    3. If an element definition with matching localName, namespace, and TYPE is not registered with token's document, set TYPE to localName
    4. -
    5. Let interface be the element interface for TYPE as local name and namespace (HTML Namespace for createElement)
    6. -
    +

    The HTMLElement interface gains following annotation:

    + +
    +[Constructor]
    +
    + +

    We then add the following definition:

    + +The HTMLElement constructor, when invoked, must perform the following steps: -

    Additionally, both createElement or createElementNS methods must run the following steps just before returning the result:

      -
    1. If TYPE is not the same as localName, set the value of ELEMENT's is attribute to TYPE
    2. -
    3. Enqueue created callback for ELEMENT
    4. -
    -
    +
  • Let realm be the result of GetFunctionRealm(the currently executing HTMLElement function).
  • -

    Parsing Custom Elements

    +
  • Let registry be realm's [[\GlobalObject]]'s CustomElementRegistry object.
  • -

    To enable instantiating custom elements during tree construction, a conforming UA must run enqueue created callback whenever creating a custom element.

    +
  • Let definition be the entry in registry with constructor equal to NewTarget. If there is no such definition, throw a TypeError and abort these steps.
  • -
    -

    This modification to tree construction has the consequence of custom elements being created when parsing HTML documents or fragments.

    -
    +
  • +

    If definition's construction stack is empty, perform the following substeps:

    -

    Custom Elements and ECMAScript 6

    +
      +
    1. Let localName be the definition's local name.
    2. -
      -

      Once the ECMAScript Standard Edition 6 is released, this section will be integrated into the respective areas of this specification. Until then, here is an overview of how ECMAScript 6 and Custom Elements integrate.

      +
    3. Return a new element that implements HTMLElement, with no attributes, namespace set to the HTML namespace, local name set to localName, and node document set to document.
    4. +
    -

    If the user agent implements the @@create method, this specification would stop treating the ElementRegistrationOptions options argument in registerElement as a dictionary, and instead view it as a the custom element constructor.

    +

    This occurs when author script constructs a new custom element directly, e.g. via new MyCustomElement().

    +
  • -

    Instead of generating a constructor, the user agent will now mutate this argument to have a new @@create method that creates a new element object.

    +
  • Let instance be the last entry in definition's construction stack.
  • -

    Since the registerElement's second argument is now a constructor function, the element definition should change to hold that constructor function, rather than the custom element prototype.

    +
  • +

    If instance is an already constructed marker, throw an InvalidStateError and abort these steps.

    -

    To accommodate this change, the element registration algorithm to the following steps:

    - +

    This can occur when the author code inside the custom element constructor invokes super() multiple times.

    +
  • + +
  • Let prototype be definition's prototype.
  • + +
  • Perform element.[[\SetPrototypeOf]](prototype). Rethrow any exceptions.
  • + +
  • Replace the last entry in definition's construction stack with an already constructed marker.
  • + +
  • +

    Return instance.

    + +

    This step is normally reached when upgrading a custom element; the existing element is returned, so that the super() call inside the custom element constructor assigns that existing element to this.

    +
  • + + +

    For now, the HTMLElement constructor cannot be invoked directly. It only works when used via a super() call inside a custom element constructor.

    + +
    + +
    +

    DOM+: Document methods

    + +

    To allow creating both custom tag and type extension-style custom elements, the createElement or createElementNS methods gain optional typeExtension arguments. Their new definitions are:

    + +
    +partial interface Document {
    +    Element createElement(DOMString localName, optional ElementCreationOptions options);
    +    Element createElementNS(DOMString? namespace, DOMString qualifiedName, optional ElementCreationOptions options);
    +};
    +
    +dictionary ElementCreationOptions {
    +    DOMString is;
    +    boolean upgrade = false;
    +};
    +
    + +
    + +The createElement(localName, options) method, when invoked, must run these steps: -
    -
    -
    Input
    -
    DOCUMENT, the document
    -
    TYPE, the custom element type of the element being registered
    -
    FUNCTION, the custom element constructor
    -
    NAME, a local name, optional
    -
    Output
    -
    ERROR, a variable that holds one of these values: None, InvalidType, InvalidName, NoRegistry, or DuplicateDefinition
    -
      -
    1. Let ERROR and DEFINITION be the result of running definition construction algorithm with DOCUMENT, TYPE, PROTOTYPE, and NAME as arguments
    2. -
    3. If ERROR is not None, stop.
    4. -
    5. Let REGISTRY be DOCUMENT's registry
    6. -
    7. If REGISTRY does not exist, set ERROR to NoRegistry and stop.
    8. -
    9. Add DEFINITION to REGISTRY
    10. -
    11. Let MAP be REGISTRY's upgrade candidates map
    12. -
    13. Run element upgrade algorithm with MAP and DEFINITION as arguments.
    14. +
    15. If localName does not match the Name production, throw an InvalidCharacterError exception.
    16. + +
    17. If the context object is an HTML document, let localName be converted to ASCII lowercase.
    18. + +
    19. Let typeExtension be the value of the is member of options, or null if no such member exists.
    20. + +
    21. Return the result of creating an element given the context object, localName, null, the HTML namespace, typeExtension, with the synchronous custom elements flag set, and with the auto-upgrade custom elements flag set if the upgrade member of options is true. Rethrow any exceptions.
    -
    -
    -

    The steps run when calling registerElement will change to:

    -
    +The createElementNS(namespace, qualifiedName, options) method, when invoked, must run these steps: -
    -
    -
    Input
    -
    DOCUMENT, method's context object, a document
    -
    TYPE, the custom element type of the element being registered
    -
    FUNCTION, the custom element constructor, optional
    -
    EXTENDS, the local name of an HTML or SVG element that is being extended, optional
    -
    Output
    -
    CONSTRUCTOR, the custom element constructor
    -
      -
    1. If FUNCTION is null: -
        -
      1. Let FUNCTION be the result of calling FunctionAllocate with HTMLElement as the functionPrototype and true as strict
      2. -
      3. Let PROTOTYPE be the result of calling ObjectCreate with HTMLElement's interface prototype object as only argument
      4. -
      5. Call DefinePropertyOrThrow(PROTOTYPE, "constructor", PropertyDescriptor{[[Value]]: FUNCTION, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false})
      6. -
      7. Call DefinePropertyOrThrow(FUNCTION, "prototype", PropertyDescriptor{[[Value]]: PROTOTYPE, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false})
      8. -
    2. -
    3. Otherwise: -
        -
      1. Let PROTOTYPE be the result of Get(FUNCTION, "prototype")
      2. -
    4. - -
    5. Let NAME be EXTENDS
    6. -
    7. Let ERROR be the result of running the element registration algorithm with DOCUMENT, TYPE, PROTOTYPE, and NAME as arguments
    8. -
    9. If ERROR is InvalidType, throw a SyntaxError and stop.
    10. -
    11. If ERROR is not None, throw a NotSupportedError and stop.
    12. -
    13. Return result of running custom element constructor generation algorithm with PROTOTYPE, FUNCTION, and DOCUMENT as arguments.
    14. +
    15. Let namespace, prefix, and localName be the result of passing namespace and qualifiedName to validate and extract. Rethrow any exceptions.
    16. + +
    17. Let typeExtension be the value of the is member of options, or null if no such member exists.
    18. + +
    19. Return the result of creating an element given the context object, localName, prefix, namespace, typeExtension, with the synchronous custom elements flag set, and with the auto-upgrade custom elements flag set if the upgrade member of options is true. Rethrow any exceptions.
    +
    -

    Similarly, the custom element constructor generation algorithm will change as follows:

    +
    + +
    +

    HTML+: Parsing HTML documents

    + +

    The create an element for a token algorithm should be adjusted by replacing step 1 with the following steps, and adjusting further steps to refer to element instead of "the element" or "the newly created element".

    -
    -
    -
    Input
    -
    PROTOTYPE, the custom element prototype
    -
    FUNCTION, the custom element constructor
    -
    DOCUMENT, the owner document for new custom element
    -
    Output
    -
    FUNCTION, the mutated custom element constructor
    -
      -
    1. If FUNCTION is already an interface object for any interface, throw a NotSupportedError and stop.
    2. -
    3. Let DEFINITION be an element definition that has PROTOTYPE as custom element prototype
    4. -
    5. Let CREATE be a function which when called, executes these steps: -
        -
      1. Let ELEMENT be the context object
      2. -
      3. Let TYPE be the custom element type in DEFINITION
      4. -
      5. Let NAME be the local name in DEFINITION
      6. -
      7. Let NAMESPACE be the namespace in DEFINITION
      8. -
      9. Set ELEMENT's local name to NAME, namespace to the NAMESPACE, and node document to DOCUMENT
      10. -
      11. If TYPE is not the same as NAME, set the value of ELEMENT's is attribute to TYPE
      12. -
      13. Enqueue created callback for ELEMENT
      14. -
      15. Return ELEMENT.
      16. -
    6. -
    7. Call DefinePropertyOrThrow(FUNCTION, @@create, PropertyDescriptor{[[Value]]: CREATE, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false})
    8. -
    9. Return FUNCTION.
    10. +
    11. Let document be intended parent's node document.
    12. + +
    13. Let localName be the tag name of the token.
    14. + +
    15. Let typeExtension be null.
    16. + +
    17. Let will execute script be false.
    18. + +
    19. +

      If given namespace is the HTML namespace, and document has a browsing context, and localName is in the list of defined local names for document's associated Window's CustomElementRegistry object:

      + +
        +
      1. Set typeExtension to the value of the "is" attribute in the given token, if such an attribute exists.
      2. + +
      3. Set will execute script to true if the parser was not originally created for the HTML fragment parsing algorithm.
      4. +
      +
    20. + +
    21. +

      If will execute script is true:

      + +
        +
      1. Increment the parser's script nesting level.
      2. + +
      3. Set the parser pause flag to true.
      4. + +
      5. If the JavaScript execution context stack is empty, perform a microtask checkpoint.
      6. +
      +
    22. + +
    23. +

      Let element be the result of creating an element given document, localName, null, given namespace, and typeExtension. If will execute script is true, set the synchronous custom elements flag and the auto-upgrade custom elements flag; otherwise, leave them unset.

      + +

      This will cause custom element constructors to run, if will execute script is true. However, even if this causes new characters to be inserted into the tokenizer, the parser will not be executed reentrantly, since the parser pause flag is true. Similarly, blowing away the document is not possible, since the script nesting level is greater than zero.

      + +

      If this step throws an exception, report the exception, and let element be instead a new element that implements HTMLUnknownElement, with no attributes, namespace set to given namespace, namespace prefix set to null, defined flag set, and node document set to document. This is not a custom element.

      +
    24. + +
    25. +

      Append each attribute in the given token to element.

      + +

      This can enqueue a custom element callback action for the attributeChangedCallback, which might run immediately (in the next step).

      +
    26. + +
    27. +

      If will execute script is true:

      + +
        +
      1. Invoke custom element actions (for which queue!?! just for element maybe!?)
      2. + +
      3. Decrement the script nesting level by one.
      4. + +
      5. If the parser's script nesting level is zero, then set the parser pause flag to false.
      6. +
      +
    -
    -

    Custom Element Semantics

    -

    The default semantics of a custom element is dependent upon the form in which it is instantiated:

    +
    + +
    +

    HTML+: Parsing XHTML documents

    + +

    It turns out there's not actually a spec for the XML parser. Awesome! (Not actually awesome.) The HTML Standard has a nice vague paragraph about "This Document must then be populated with DOM nodes that represent the tree structure of the input passed..." which should get something like the following inserted (probably by inserting it after the first sentence, then splitting the mutation events/observers prose into a new paragraph).

    + +

    When creating DOM nodes representing elements, the create an element for a token algorithm or some equivalent that operates on appropriate XML datastructures must be used, to ensure the proper element interfaces are created and that custom elements are set up correctly.

    + +
    + + + +
    +

    Additions to CSS

    + +

    The following should be added to some relevant CSS specification. Or maybe it would belong in HTML? It looks like it's mostly a collaboration so far?

    + +
    +

    The Defined Element Pseudo-class: ':defined'

    + +

    The ':defined' pseudo-class applies to elements that are defined.

    + +

    +The ':defined' pseudo-class can be used to mitigate the flash of unstyled content [[FOUC]] issues with custom elements. +

    +
    +
    + +
    +

    Custom Element Semantics

    +

    The default semantics of a custom element is dependent upon the form in which it is instantiated:

    -

    Custom Tag Example

    +
    +

    Custom Tag Example

    For example, a custom tag could be named taco-button, but the name alone does not express the semantics of a HTML button element simply due to its name. As instantiated a custom tag conveys a similar amount of semantics as an HTML div or span element:

    -
    <!-- taco-button represents a span with a fancy name -->
    -<taco-button></taco-button>
    +
    <!-- taco-button represents a span with a fancy name -->
    +<taco-button></taco-button>
     

    The addition of visual styling and scripted events to the taco-button could provide hints as to its semantics and expected interaction behaviours — for some users — but for the semantics to be formally expressed developers must convey the semantics using ARIA roles, states and properties.

    The addition of a tabindex attribute to the custom element provides interaction (the element is included in the focus order) and property/state semantics (it exposes information that it is focusable and if it currently has focus).

    -
    
    +
     <!-- taco-button represents a focusable span with a fancy name -->
    -<taco-button tabindex="0">Eat Me</taco-button>
    +<taco-button tabindex="0">Eat Me</taco-button>
     
    -

    The addition of a label, using aria-label, to the custom element provides an Accessible Name for the element.

    -
    
    +

    The addition of a label, using aria-label, to the custom element provides an Accessible Name for the element.

    +
     <!-- taco-button represents a focusable span with a fancy name and a text label -->
    -<taco-button tabindex="0" aria-label="Eat Me">Eat Me</taco-button>
    +<taco-button tabindex="0" aria-label="Eat Me">Eat Me</taco-button>
     

    The addition of keyboard event handlers to the custom element provides the means for keyboard users to operate the control, but does not convey the presence of the functionality.

    -
    
    -<!-- taco-button represents focusable span with a fancy name, a text label and button like event handling -->
    +
    +<!-- taco-button represents focusable span with a fancy name,
    +    a text label and button like event handling -->
     <taco-button tabindex="0" onclick="alert('tasty eh?');"
    -onkeypress="if(event.keyCode==32||event.keyCode==13){alert('tasty eh?');};">Eat Me</taco-button>
    +onkeypress="if(event.keyCode==32||event.keyCode==13){alert('tasty eh?');};"
    +>Eat Me</taco-button>
     
    -

    The addition of inline event handlers are for demonstration purposes only. The event handlers could be added by the lifecycle callbacks imperatively, or maybe even not used at all. This example demonstrates one method for developers to ensure that a custom control is operable for keyboard users and meets the WCAG 2.0 criteria "All functionality of the content is operable through a keyboard interface".

    +

    The addition of inline event handlers are for demonstration purposes only. The event handlers could be added by the lifecycle callbacks imperatively, or maybe even not used at all. This example demonstrates one method for developers to ensure that a custom control is operable for keyboard users and meets the WCAG 2.0 [[WCAG20]] criteria "All functionality of the content is operable through a keyboard interface".

    The addition of an ARIA role="button" conveys the custom element's role semantics, which enables users to successfully interact with the control using the expected button interaction behaviours (pressing the space or enter keys to activate).

    -
    
    -<!-- taco-button represents a focusable button with a text label and button like event handling -->
    +
    +<!-- taco-button represents a focusable button with a text label
    +    and button like event handling -->
     <taco-button role="button" tabindex="0" onclick="alert('tasty eh?');"
    -onkeypress="if(event.keyCode==32||event.keyCode==13){alert('tasty eh?');};">Eat Me</taco-button>
    +onkeypress="if(event.keyCode==32||event.keyCode==13){alert('tasty eh?');};" +>Eat Me</taco-button>

    The developer may provide a disabled state for the custom element. This could be implemented by removing the tabindex attribute so the element is no longer included in the focus order and removing the functionality so that interacting with the element does nothing. Also the visual styling may also be modified to visually indicate it the element is disabled.

    -
    
    -<!-- grayed out non focusable taco-button with functionality removed, to indicate the button is in a disabled state  -->
    +
    +<!-- grayed out non focusable taco-button with functionality removed,
    +     to indicate the button is in a disabled state  -->
     <taco-button role="button" tabindex="0" onclick="alert('tasty eh?');"
    -onkeypress="if(event.keyCode==32||event.keyCode==13){alert('tasty eh?');};">Eat Me</taco-button>
    +onkeypress="if(event.keyCode==32||event.keyCode==13){alert('tasty eh?');};" +>Eat Me</taco-button>

    Removing the focusability and functionality of the custom element and modifying its style does not unambiguously express that it is in a disabled state. To unambiguously express the disabled state add aria-disabled="true".

    A disabled attribute would not work here as the custom tag is not based on an HTML element that supports its use.

    -
    
    -<!-- taco-button represents a focusable button with a text label and button like event handling -->
    +
    +<!-- taco-button represents a focusable button with a text label
    +       and button like event handling -->
     <taco-button role="button" tabindex="0" onclick="alert('tasty eh?');"
    -onkeypress="if(event.keyCode==32||event.keyCode==13){alert('tasty eh?');};" aria-disabled="true">Eat Me</taco-button>
    - -

    Type Extension Example

    + onkeypress="if(event.keyCode==32||event.keyCode==13){alert('tasty eh?');};" + aria-disabled="true">Eat Me</taco-button>
    +
    +
    +

    Type Extension Example

    A type extension, for example could extend the HTML button element. As instantiated it would inherit the button element's name, role, states and properties, built in focus and keyboard interaction behaviours.

    -
    <!-- tequila-button represents a button with an accessible name of "Drink Me!" -->
    -<button is="tequila-button">Drink Me!</button>
    +
    <!-- tequila-button represents a button with an accessible name of "Drink Me!" -->
    +<button is="tequila-button">Drink Me!</button>
     

    To implement the desired tequila-button feature, all that is required is the addition of an event handler. The rest of the semantics and interaction behaviour are provided by the browser as part of its implementation of the button element.

    -
    <!-- tequila-button represents a button -->
    -<button is="tequila-button" onclick="alert('smooth!');">Drink Me!</button>
    +
    <!-- tequila-button represents a button -->
    +<button is="tequila-button" onclick="alert('smooth!');">Drink Me!</button>
     

    To implement the disabled state on the tequila-button, all that is required is the addition of the HTML disabled attribute. The semantics, style and interaction behaviour are implemented by the browser.

    -
    <!-- tequila-button represents a button -->
    -<button is="tequila-button" onclick="alert('smooth!');" disabled>Drink Me!</button>
    +
    <!-- tequila-button represents a button -->
    +<button is="tequila-button" onclick="alert('smooth!');" disabled>Drink Me!</button>
     
    -

    Custom Element Semantics — Conclusion

    -

    The simplest and most robust method to create custom elements that are usable and accessible is to implement custom elements as type extensions. This method provides a custom element with built in semantics and interaction behaviours that developers can use as a foundation.

    -

    Use ARIA, where needed, to provide semantics for custom elements and follow the ARIA Design Patterns when implementing ARIA attributes and UI interaction behaviours. Ensure that custom tag or type extension custom elements meet the criteria listed in the Custom Control Accessible Development Checklist. Use ARIA in accordance with the Document conformance requirements for use of ARIA attributes in HTML.

    +
    +
    +

    Custom Element Semantics — Conclusion

    +

    The simplest and most robust method to create custom elements that are usable and accessible is to implement custom elements as type extensions. This method provides a custom element with built in semantics and interaction behaviours that developers can use as a foundation.

    +

    Use ARIA [[WAI-ARIA-1.1]], where needed, to provide semantics for custom elements and follow the ARIA Design Patterns [[WAI-ARIA-PRACTICES]] when implementing ARIA attributes and UI interaction behaviours. Ensure that custom tag or type extension custom elements meet the criteria listed in the Custom Control Accessible Development Checklist [[ARIA-IN-HTML]]. Use ARIA in accordance with the Document conformance requirements for use of ARIA attributes in HTML.

    Further Reading for Developers

    - -

    Appendix A: All Algorithms in One Diagram

    - -
    -

    To help navigate through various parts of the spec and their interactions, here is a diagram that attempts to put all algorithms actions that trigger them in one space. Click on each box to go to the corresponding algorithm or action.

    - -
    - -
    Fig. All algorithms in one diagram
    -
    - -
    -
    +
    +
    -

    Acknowledgements

    +

    Acknowledgments

    David Hyatt developed XBL 1.0, and Ian Hickson co-wrote XBL 2.0. These documents provided tremendous insight into the problem of behavior attachment and greatly influenced this specification.

    Alex Russell and his considerable forethought triggered a new wave of enthusiasm around the subject of behavior attachment and how it can be applied practically on the Web.

    Dominic Cooney, Hajime Morrita, and Roland Steiner worked tirelessly to scope the problem within the confines of the Web platform and provided a solid foundation for this document.

    -

    Steve Faulkner, The Paciello Group, for writing the content for the Custom Element Semantics section

    +

    Steve Faulkner, The Paciello Group, for writing the content of the section .

    + +
    +

    The <flag-icon> example was inspired by a custom element by Steven Skelton. (MIT)

    +
    -

    The editor would also like to thank Alex Komoroske, Anne van Kesteren, Boris Zbarsky, Daniel Buchner, Edward O'Connor, Erik Arvidsson, Elliott Sprehn, Hayato Ito, Jonas Sicking, Olli Pettay, Rafael Weinstein, Scott Miles, Simon Pieters, Steve Orvell, Tab Atkins, and William Chen for their comments and contributions to this specification.

    +

    The editor would also like to thank +Alex Komoroske, +Andres Rios, +Anne van Kesteren, +Boris Zbarsky, +Daniel Buchner, +Edward O'Connor, +Erik Arvidsson, +Elliott Sprehn, +Hayato Ito, +Jan Miksovsky, +Jonas Sicking, +Olli Pettay, +Rafael Weinstein, +Ryosuke Niwa, +Scott Miles, +Simon Pieters, +Steve Orvell, +Tab Atkins, +and +William Chen + +for their comments and contributions to this specification.

    This list is too short. There's a lot of work left to do. Please contribute by reviewing and filing bugs—and don't forget to ask the editor to add your name into this section.

    diff --git a/spec/imports/W3CTRMANIFEST b/spec/imports/W3CTRMANIFEST new file mode 100644 index 00000000..b8e3cdcd --- /dev/null +++ b/spec/imports/W3CTRMANIFEST @@ -0,0 +1,2 @@ +index.html?specStatus=WD;shortName=html-imports;useExperimentalStyles=false respec +import-link-list.png diff --git a/spec/imports/import-link-list.png b/spec/imports/import-link-list.png new file mode 100644 index 00000000..16e9e89f Binary files /dev/null and b/spec/imports/import-link-list.png differ diff --git a/spec/imports/index.html b/spec/imports/index.html index 211107b2..f433655b 100644 --- a/spec/imports/index.html +++ b/spec/imports/index.html @@ -1,231 +1,180 @@ - + -HTML Imports - - - - - - + + HTML Imports + + + - -
    - - - -

    HTML Imports

    -

    W3C Editor's Draft

    -
    -
    This version
    -
    http://w3c.github.io/webcomponents/spec/imports/
    -
    Latest version
    -
    http://www.w3.org/TR/html-imports/
    -
    Latest editor's draft
    -
    http://w3c.github.io/webcomponents/spec/imports/
    -
    Previous version
    -
    none
    -
    Revision history
    -
    https://github.com/w3c/webcomponents/commits/gh-pages/spec/imports/
    -
    Participate
    -
    Discuss on public-webapps@w3.org (Web Platform Working Group)
    -
    Bugs filed
    -
    https://github.com/w3c/webcomponents/labels/html-imports
    -
    Editor
    -
    Dimitri Glazkov, Google, <>
    -
    Hajime Morrita, Google, <>
    -
    - - - -
    - -

    Abstract

    - -

    HTML Imports are a way to include and reuse HTML documents in other HTML documents.

    - -

    Status of This Document

    - -

    This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

    - -

    This document was published by the Web Platform Working Group as an Editor's Draft. If you wish to make comments regarding this document, please send them to public-webapps@w3.org (subscribe, archives). All feedback is welcome.

    Publication as an Editor's Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

    - -

    This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

    - -

    This document is governed by the 1 September 2015 W3C Process Document.

    - -
    - -
    -

    Table of Contents

    -
      -
    1. About this Document -
    2. Dependencies -
    3. Terminology -
        -
      1. Import Dependent -
      -
    4. Link Type "import" -
    5. Extensions to HTMLLinkElement interface -
    6. Extensions to Document interface -
    7. Loading Imports -
        -
      1. Updating Branch -
      2. Requesting Import -
      3. Fetching Import -
      4. Imports and Content Security Policy -
      -
    8. Parsing Imports -
        -
      1. Additions to Prepare A Script Algorithm -
      2. Additions to Tree Construction Algorithm -
      3. Additions to Parsing XHTML Documents -
      -
    9. Scripting in Imports -
        -
      1. Additions to Script Enabling Criteria -
      2. Additions to document.currentScript -
      -
    10. Style processing with Imports -
        -
      1. Import Link Tree
      2. -
      3. Order of appearances and Imports
      4. -
      -
    11. Events in Imports -
        -
      1. Additions to Event Handlers -
      -
    12. Acknowledgements -
    +
    +

    HTML Imports are a way to include and reuse HTML documents in other HTML documents [[!HTML]].

    -
    -

    About this Document

    - -

    All diagrams, examples, notes, are non-normative, as well as sections explicitly marked as non-normative. Everything else in this specification is normative.

    - -

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC2119. For readability, these words do not appear in all uppercase letters in this specification.

    - -

    Any point, at which a conforming UA must make decisions about the state or reaction to the state of the conceptual model, is captured as algorithm. The algorithms are defined in terms of processing equivalence. The processing equivalence is a constraint imposed on the algorithm implementers, requiring the output of the both UA-implemented and the specified algorithm to be exactly the same for all inputs.

    - -

    Dependencies

    +
    +
    -

    This document relies on the following specifications:

    +
    - +

    Any point, at which a conforming UA must make decisions about the state or reaction to the state of the conceptual model, is captured as algorithm. The algorithms are defined in terms of processing equivalence. The processing equivalence is a constraint imposed on the algorithm implementers, requiring the output of the both UA-implemented and the specified algorithm to be exactly the same for all inputs.

    +
    -

    Terminology

    +
    +

    Terminology

    -

    HTML Imports, or just imports from here on, are HTML documents that are linked as external resources from another HTML document. The document that links to an import is called an import referrer. For any given import, an import referrer ancestor is its import referrer or any import referrer ancestor of its import referrer. There are one or more import referrers and import referrer ancestors for each import because same import can be referred from multiple import referrers.

    +

    HTML Imports, or just imports from here on, are HTML documents [[!HTML]] that are linked as external resources from another HTML document. The document that links to an import is called an import referrer. For any given import, an import referrer ancestor is its import referrer or any import referrer ancestor of its import referrer. There are one or more import referrers and import referrer ancestors for each import because same import can be referred from multiple import referrers.

    -

    An import referrer that is not an import, thus is not associated with any import referrer, is called a master document. Each import is associated with one master document: if the referrer of the import is a master document, it is the master document of the import. Otherwise, the master document of the import referrer is the master document of the import.

    +

    An import referrer that is not an import, thus is not associated with any import referrer, is called a master document. Each import is associated with one master document: if the referrer of the import is a master document, it is the master document of the import. Otherwise, the master document of the import referrer is the master document of the import.

    -

    The URL of an import is called the import location.

    +

    The URL of an import is called the import location.

    -

    In each import referrer, an import is represented as a Document, called the imported document.

    +

    In each import referrer, an import is represented as a Document [[!WHATWG-DOM]], called the imported document.

    -

    +

    The imported documents don't have browsing context.

    -

    The set of all imports associated with the master document forms an import map of the master document. The maps stores imports as its items with their import locations as keys. The import map is empty at beginning. New items are added to the map as import fetching algorithm specifies.

    +

    The set of all import associated with the master document forms an import map of the master document. The maps stores import as its items with their import locations as keys. The import map is empty at beginning. New items are added to the map as import fetching algorithm specifies.

    -

    Import Dependent

    +
    +

    Import Dependent

    -

    To track requested imports, each document has an import link list. Each of its item consists of link, a link element and location, a URL. +

    To track requested imports, each document has an import link list. Each of its item consists of link, a link element and location, a URL. Also, the item is optionally marked as branch. -The list is initially empty, and items are added to it as specified by the import request algorithm.

    +The list is initially empty, and items are added to it as specified by the import request algorithm.

    -

    Each imported document has an import parent: If the import link list of document A contains a branch item whose location points document B, A is an import parent of B. +

    Each imported document has an import parent: If the import link list of document A contains a branch item whose location points document B, A is an import parent of B.

    -

    Each imported document also has one or more import ancestors: Document A is an import ancestor of another document B if A is import parent of B. Being an import ancestor is transitive: If A is an import parent of B and B is an import parent of C, A is an import parent of C as well. +

    Each imported document also has one or more import ancestors: Document A is an import ancestor of another document B if A is import parent of B. Being an import ancestor is transitive: If A is an import parent of B and B is an import parent of C, A is an import parent of C as well.

    -

    An imported document also has one or more import predecessors. An import predecessor is a document. If the URL of document A is located before the URL of document B in the import link list of B's import parent, and the located link is marked as a branch, then A is import predecessor of B.

    +

    An imported document also has one or more import predecessors. An import predecessor is a document. If the URL of document A is located before the URL of document B in the import link list of B's import parent, and the located link is marked as a branch, then A is import predecessor of B.

    -

    The import ancestor predecessors of document A is defined as follows: If document B is an import predecessor of document C, and C is an import ancestor of A, B is an import ancestor predecessors of A.

    +

    The import ancestor predecessors of document A is defined as follows: If document B is an import predecessor of document C, and C is an import ancestor of A, B is an import ancestor predecessors of A.

    -

    The Document that is in either import ancestor predecessors or import predecessors of document A, or is linked from branch item of A's import link list, is the import dependent of A.

    +

    The Document that is in either import ancestor predecessors or import predecessors of document A, or is linked from branch item of A's import link list, is the import dependent of A.

    -

    The import link list and the import dependent constrains the order of script execution in imports. It is intend to give a deterministic order of script execution which is defined by the order of link element in each import. The edges of each node is ordered in terms of import link list. The import predecessors selection is aware of the order.

    +

    The import link list and the import dependent constrains the order of script execution in imports. It is intend to give a deterministic order of script execution which is defined by the order of link element in each import. The edges of each node is ordered in terms of import link list. The import predecessors selection is aware of the order.

    -

    The linking structure of import link lists forms a directed graph. Each node of the graph is a document and its edge is a link. Branches are intended to form a spanning tree of the graph. This tree gives the deterministic order of the script execution.

    +

    The linking structure of import link lists forms a directed graph. Each node of the graph is a document and its edge is a link. Branches are intended to form a spanning tree of the graph. This tree gives the deterministic order of the script execution.

    - -
    - An example of import link lists. -
    + +
    An example of import link lists

    -In the figure, +In ,

    -

    The difference between the import referrer and the import parent is that import referrer reflects the state of the node tree and that the import parent is built by the algorithm described in this document.

    +

    The difference between the import referrer and the import parent is that import referrer reflects the state of the node tree and that the import parent is built by the algorithm described in this document.

    +
    +
    - + -
    -

    The following document has one import, located at /imports/heart.html:

    +
    + + +
    -

    Extensions to HTMLLinkElement Interface

    +
    +

    Extensions to HTMLLinkElement Interface

    -
    
    -partial interface HTMLLinkElement {
    -    readonly attribute Document? import;
    +
    +partial interface HTMLLinkElement {
    +    readonly attribute Document? import;
     };
    -
    +
    -

    On getting, the import attribute must return null, if:

    +

    On getting, the import attribute MUST return null, if:

    -

    Otherwise, the attribute must return the imported document for the import, represented by the link element.

    +

    Otherwise, the attribute MUST return the imported document for the import, represented by the link element.

    -

    The same object must be returned each time.

    +

    The same object MUST be returned each time.

    -
    -

    Here's how one could access the imported document, mentioned in the previous example:

    -
    
    +
    + + -

    An import in the context of the Document of an HTML parser or XML Parser is said to be an import that is blocking scripts if the element was created by that Document's parser, or and the element is a link of type import when the element was created by the parser, and the link is not marked as async, and the the import is yet to be completely loaded, and, the last time the event loop has reached step 1, the element was in that Document, and the user agent hasn't given up on that import yet. A user agent may give up on an import at any time.

    +

    An import in the context of the Document of an HTML parser or XML Parser is said to be an import that is blocking scripts if the element was created by that Document's parser, or and the element is a link of type import when the element was created by the parser, and the link is not marked as async, and the the import is yet to be completely loaded, and, the last time the event loop has reached step 1, the element was in that Document, and the user agent hasn't given up on that import yet. A user agent MAY give up on an import at any time.

    -
    -

    +

    Giving up an import before it loads, even if the import eventually does still load, means that the script might end up operating with incorrect information. For example, if an import registers a custom element and a script relies on the availability of this element, the script will find that this element is unavailable if the user agent gives up early. Implementers have to balance the likelihood of a script using incorrect information with the performance impact of doing nothing while waiting for a slow network request to finish.

    -
    -

    A Document has an import that is blocking scripts if there is an import that is blocking scripts in the Document's import dependent. -A Document has no import that is blocking scripts if it does not have an import that is blocking scripts as defined in the previous paragraph.

    +

    A Document has an import that is blocking scripts if there is an import that is blocking scripts in the Document's import dependent. +A Document has no import that is blocking scripts if it does not have an import that is blocking scripts as defined in the previous paragraph.

    -
    -

    The state of "has an import that is blocking scripts" can change each time an existing import is completely loaded or new import loading is started. HTML parser has changes to unblock it for each of such timings.

    -
    +

    The state of "has an import that is blocking scripts" can change each time an existing import is completely loaded or new import loading is started. HTML parser has changes to unblock it for each of such timings.

    +

    +
    -

    Extensions to Document Interface

    +
    +

    Extensions to Document Interface

    -

    Additions to document.open() method

    +
    +

    Additions to document.open() method

    Add following step as the first step of the definition:

      -
    1. Throws an InvalidStateError exception if the Document is an import.
    2. +
    3. Throws an InvalidStateError exception if the Document is an import.
    - -

    Additions to document.write() method

    +
    +
    +

    Additions to document.write() method

    Add following step as the first step of the definition:

      -
    1. Throws an InvalidStateError exception if the Document is an import.
    2. +
    3. Throws an InvalidStateError exception if the Document is an import.
    - -

    Additions to document.close() method

    +
    +
    +

    Additions to document.close() method

    Add following step as the first step of the definition:

      -
    1. Throws an InvalidStateError exception if the Document is an import.
    2. +
    3. Throws an InvalidStateError exception if the Document is an import.
    -

    Loading Imports

    +
    +
    -

    Updating Branch

    +
    +

    Loading Imports

    -

    After a link is added to the import link list, the update marking algorithm must be run with the master document. which is equivalent to running these steps:

    +
    +

    Updating Branch

    + +

    After a link is added to the import link list, the update marking algorithm MUST be run with the master document. which is equivalent to running these steps:

    Input
    -
    DOCUMENT, the Document
    +
    DOCUMENT, the Document
      -
    1. If the DOCUMENT is the master document, unmark branch of all the links in the import link list of DOCUMENT and every import that is associated to DOCUMENT.
    2. -
    3. Let LIST be an import link list of DOCUMENT.
    4. +
    5. If the DOCUMENT is the master document, unmark branch of all the links in the import link list of DOCUMENT and every import that is associated to DOCUMENT.
    6. +
    7. Let LIST be an import link list of DOCUMENT.
    8. For each ITEM in the LIST:
      1. -
      2. Let LOCATION be a location of ITEM.
      3. -
      4. Let IMPORT be an import whose URL is same as LOCATION.
      5. -
      6. If there is no other link whose location is same as LOCATION and which is marked as a branch, mark ITEM as a branch.
      7. -
      8. If ITEM is marked as a branch and IMPORT is not null, invoke update marking algorithm with IMPORT.
      9. +
      10. Let LOCATION be a location of ITEM.
      11. +
      12. Let IMPORT be an import whose URL is same as LOCATION.
      13. +
      14. If there is no other link whose location is same as LOCATION and which is marked as a branch, mark ITEM as a branch.
      15. +
      16. If ITEM is marked as a branch and IMPORT is not null, invoke update marking algorithm with IMPORT.
    -

    Requesting Import

    +
    + +
    +

    Requesting Import

    -

    When user agents attempt to obtain a linked import, they must also run the import request algorithm, which is equivalent to running these steps:

    +

    When user agents attempt to obtain a linked import, they MUST also run the import request algorithm, which is equivalent to running these steps:

    Input
    -
    LINK, the link element that creates an external resource link to the import.
    -
    LOCATION, the URL of the linked resource.
    +
    LINK, the link element that creates an external resource link to the import.
    +
    LOCATION, the URL of the linked resource.
    -
      -
    1. If the async attribute of LINK is true, mark LINK as async. +
        +
      1. If the async attribute of LINK is true, mark LINK as async.
      2. Let DOCUMENT be a document of LINK. -
      3. Let LIST be an import link list of DOCUMENT. +
      4. Let LIST be an import link list of DOCUMENT.
      5. Let ITEM be LINK and LOCATION:
        1. Add ITEM at the end of LIST. -
        2. Invoke update marking algorithm with the master document. +
        3. Invoke update marking algorithm with the master document.
    -

    Fetching Import

    +
    + +
    +

    Fetching Import

    -

    All imports linked from documents that is the master document or the one in the import map must be fetched using the import fetching algorithm described below, instead of the one that HTML specifies to obtain a linked resouce.

    +

    All import linked from documents that is the master document or the one in the import map MUST be fetched using the import fetching algorithm described below, instead of the one that HTML specifies to obtain a linked resouce.

    -

    The import fetching algorithm must be equivalent to running these steps:

    +

    The import fetching algorithm MUST be equivalent to running these steps:

    Input
    -
    LINK, a link element which makes the external resource link to the import.
    -
    LOCATION, the import location
    +
    LINK, a link element which makes the external resource link to the import.
    +
    LOCATION, the import location
    Output
    -
    IMPORT, the imported document.
    +
    IMPORT, the imported document.
    -
      -
    1. If LOCATION is already in the import map:
    2. -
      1. -
      2. Let IMPORT be the imported document for LOCATION and stop.
      3. +
          +
        1. If LOCATION is already in the import map: +
            +
          1. Let IMPORT be the imported document for LOCATION and stop.
        2. -
        3. Fetch a resource from LOCATION with request's origin set to the origin of the master document, the mode to CORS and the credentials mode to same-origin.
        4. +
        5. Fetch a resource [[!Fetch]] from LOCATION with request's origin set to the origin of the master document, the mode to CORS and the credentials mode to same-origin.
            -
          1. If fetched response type is error or the response has a header whose name is Content-Disposition:
          2. -
    -
    -All of loaded imports and imports under loading are in the import link list, thus every import which is linked from imports in the list will also be loaded using the import fetching algorithm, with LOCATION be the import location of the import. -
    +

    +All of loaded imports and imports under loading are in the import link list, thus every import which is linked from imports in the list will also be loaded using the import fetching algorithm, with LOCATION be the import location of the import. +

    -The loading attempt must be considered successful if IMPORT is not null on the algorithm completion, and failed otherwise. +The loading attempt MUST be considered successful if IMPORT is not null on the algorithm completion, and failed otherwise.

    -

    Every import that is not marked as async delays the load event in the Document. +

    Every import that is not marked as async delays the load event in the Document. -

    -

    The link element fires a simple event called load -for successful loading attempt. For failed attempt, it fires a simple event named error.

    -

    As an import delays the load event, the Document isn't completely loaded until loading attempts of all of its linked imports are finished.

    +
    +

    The link element fires a simple event called load +for successful loading attempt. For failed attempt, it fires a simple event named error.

    +

    As an import delays the load event, the Document isn't completely loaded until loading attempts of all of its linked imports are finished.

    -

    Imports and Content Security Policy

    +
    + +
    +

    Imports and Content Security Policy

    -Content Security Policy must restrict import loading through the script-src directive. +Content Security Policy [[!CSP3]] MUST restrict import loading through the script-src directive.

    -Each import must be restricted by the Content Security Policy of the master document. -For example, if Content Security Header Field is sent to an import, the user agent must enforce the policy of the master document to the imported document. +Each import MUST be restricted by the Content Security Policy of the master document. +For example, if Content Security Header Field is sent to an import, the user agent MUST enforce the policy of the master document to the imported document.

    -

    Parsing Imports

    +
    +
    -

    Parsing behaviour of imports is defined as a set of changes to the HTML Parsing.

    +
    +

    Parsing Imports

    -

    Additions to Prepare A Script Algorithm

    +

    Parsing behaviour of import is defined as a set of changes to the HTML Parsing.

    -

    In step 15 of prepare a script algorithm, modify the last part of condition which begins with If element does not have a src attribute to read:

    - +
    +

    Additions to Prepare A Script Algorithm

    -

    Additions to Tree Construction Algorithm

    +

    In step 15 of prepare a script algorithm, modify the last part of condition which begins with If element does not have a src attribute to read:

    +
    +

    ... and the Document of the HTML parser or XML parser that created the script element has a style sheet that is blocking scripts or has an import that is blocking scripts

    +
    -

    At the DOCTYPE part of section 12.2.5.4.1 The "initial" insertion mode, modify text if the document is not an iframe srcdoc document... as follows +

    -
    -

    if the document is not an iframe src document nor an import...

    -
    +
    +

    Additions to Tree Construction Algorithm

    -

    In sub-condition named Otherwise of condition An end tag whose name is "script" in "text" insertion mode, modify step 3 to read:

    -
    +

    At the DOCTYPE part of section 12.2.5.4.1 The "initial" insertion mode, modify text if the document is not an iframe srcdoc document... as follows + +

    +

    if the document is not an iframe src document nor an import...

    +
    + +

    In sub-condition named Otherwise of condition An end tag whose name is "script" in "text" insertion mode, modify step 3 to read:

    +
      -
    1. If the parser's Document has a style sheet that is blocking scripts or has an import that is blocking scripts or the script's "ready to be parser-executed" flag is not set: spin the event loop until the parser's Document has no style sheet that is blocking scripts and has no import that is blocking scripts and the script's "ready to be parser-executed" flag is set.
    2. +
    3. If the parser's Document has a style sheet that is blocking scripts or has an import that is blocking scripts or the script's "ready to be parser-executed" flag is not set: spin the event loop until the parser's Document has no style sheet that is blocking scripts and has no import that is blocking scripts and the script's "ready to be parser-executed" flag is set.
    -
    +
    + +
    -

    Additions to Parsing XHTML Documents

    +
    +

    Additions to Parsing XHTML Documents

    -

    Modify step 3 of steps that run following preparing the script element to read:

    - +
    + +
    +
    -

    Scripting in Imports

    +
    +

    Scripting in Imports

    -

    Additions to Script Enabling Criteria

    +
    +

    Additions to Script Enabling Criteria

    -

    Add following condition to the list of Enabling and disabling scripting criteria:

    +

    Add following condition to the list of Enabling and disabling scripting criteria:

    -
    +
    -
    +
    -

    Additions to document.currentScript

    +
    + +
    +

    Additions to document.currentScript

    -Modify the definition of document.currentScript +Modify the definition of document.currentScript as follows:

    -
    -The currentScript attribute, on getting, -must return the value to which it was most recently initialized in the document or the import map of the document. -When the Document is created, the currentScript must be initialized to null. -If the Document is an imported document, its currentScript is always null. -
    +
    +The currentScript attribute, on getting, +MUST return the value to which it was most recently initialized in the document or the import map of the document. +When the Document is created, the currentScript MUST be initialized to null. +If the Document is an imported document, its currentScript is always null. +
    -

    Style processing with Imports

    +
    + -

    The contents of the style elements and -the external resources of the link elements in imports must be considered as input sources of the style processing model of the master document.

    +
    +

    Style processing with Imports

    - +

    The contents of the style elements and +the external resources of the link elements in import MUST be considered as input sources of the style processing model [[!CSS2]] of the master document.

    -

    A set of imports that are associated with a master document forms an import link tree, a tree structure. Following import link tree forming algorithm, being applied with null as PARENT, master document as TREE and all of its imports as POOL, defines the import link tree:

    + -
    -The import link tree algorithm defines a order of imports using a depth first traversal. This import link tree is different from the one formed by import link list. The former is based on the document tree of each import. The later is built through import loading process and isn'taffected by document tree mutation. -
    +

    +The import link tree algorithm defines a order of imports using a depth first traversal. This import link tree is different from the one formed by import link list. The former is based on the document tree of each import. The later is built through import loading process and isn't affected by document tree mutation. +

    + +
    -

    Order of Appearances and Imports

    +
    +

    Order of Appearances and Imports

    -

    The order of appearances of declarations which come from different documents are determined by the import link tree. If node documents of two declarations differ, compare the tree order of these documents in the import link tree. The last one wins.

    +

    The order of appearances of declarations [[!CSS-CASCADE-3]] which come from different documents are determined by the import link tree. If node documents of two declarations differ, compare the tree order of these documents in the import link tree. The last one wins.

    -

    Events in Imports

    +
    + -

    Events in imports is defined as a set of changes to the HTML Events.

    +
    +

    Events in Imports

    -

    Additions to Event Handlers

    +

    Events in import is defined as a set of changes to the HTML Events.

    + +
    +

    Additions to Event Handlers

    -Modify the event handler content attribute's +Modify the event handler content attribute's script creation criteria by expanding the first paragraph:

    -

    When an event handler content attribute is set, if the element is owned by a Document that is in a browsing context or -in an import map, ...

    +

    When an event handler content attribute is set, if the element is owned by a Document that is in a browsing context or +in an import map, …

    -

    Acknowledgements

    +
    +
    + +
    +

    Custom Element Processing

    + +

    This specification redefines custom element order to be the sum of [[!CUSTOM-ELEMENTS]]'s custom element order and import tree order, in which the import tree order is scaled so that its lowest value is always larger than the highest possible value of [[!CUSTOM-ELEMENTS]]'s custom element order.

    + +

    The import tree order of a given custom element of an import link tree is determined by tree order in an import link tree that was flattened by replacing every import link with the content of its imported document.

    + +

    The highest stable order is the value that is immediately preceding the custom element order of an element in the first encountered import, in tree order, that has not yet completely loaded. If there is no such element, the highest stable order is the highest custom element order in the flattened import link tree. When processing the base element queue, user agents should only invoke callbacks up to the highest stable order, inclusively.

    + + +
    +

    Because imports load asynchronously, we need to divide a sorted element queue into the part where things have settled down (all imports have loaded), and the part where the loading is still happening, and thus the actual sorting order is not yet determined. For example, suppose you have the following document structure:

    + +
    +

    index.html:

    +
    +<link rel="import" href="import.html">
    +...
    +<me-second></me-second>
    +...
    +
    + +

    import.html:

    +
    <me-first></me-first>
    +
    + +

    The order of custom elements in the flattened import link tree is me-first (1), me-second (2). However, it's very likely that the parser will find out about me-second sooner than me-first, since the latter requires loading the import.html. While the network stack is doing its job, the highest stable order stays at the beginning position. When import.html is ready, the order jumps all the way to me-second (2).

    + +
    + +
    + +
    +

    Acknowledgments

    David Hyatt developed XBL 1.0, and Ian Hickson co-wrote XBL 2.0. These documents provided tremendous insight into the problem of behavior attachment and greatly influenced this specification.

    diff --git a/spec/shadow/autolink-config.js b/spec/shadow/autolink-config.js index 5abc4b9e..40896d44 100644 --- a/spec/shadow/autolink-config.js +++ b/spec/shadow/autolink-config.js @@ -23,6 +23,8 @@ var autolinkConfig = { 'event': '#events', 'eventPhase': '#dom-event-eventphase', 'getElementById': '#dom-nonelementparentnode-getelementbyid', + 'get the parent': '#get-the-parent', + 'host': '#concept-documentfragment-host', 'inclusive ancestor': '#concept-tree-inclusive-ancestor', 'interface Document': '#interface-document', 'interface DocumentFragment': '#interface-documentfragment', @@ -51,7 +53,6 @@ var autolinkConfig = { 'Global attributes': '#global-attributes', 'HTML': '', 'HTML elements': '#semantics', - 'HTML fragment serialization algorithm': '#html-fragment-serialization-algorithm', 'HTMLUnknownElement': '#htmlunknownelement', 'activeElement': '#dom-document-activeelement', 'audio element': '#the-audio-element', @@ -67,6 +68,7 @@ var autolinkConfig = { 'fallback content': '#fallback-content', 'fieldset element': '#the-fieldset-element', 'flow content': '#flow-content', + 'focusable area': '#focusable-area', 'focusable': '#focusable-area', 'form element': '#the-form-element', 'form submission': '#form-submission', @@ -84,8 +86,8 @@ var autolinkConfig = { 'object element': '#the-object-element', 'progress element': '#the-progress-element', 'reflect': '#reflect', + 'root element of a document object': '#root-element-of-a-document-object', 'sequential focus navigation': '#sequential-focus-navigation', - 'sequential focus navigation order': '#sequential-focus-navigation-order', 'style': '#the-style-attribute', 'tabindex': '#attr-tabindex', 'textarea element': '#the-textarea-element', @@ -173,6 +175,8 @@ var autolinkConfig = { }, 'https://w3c.github.io/DOM-Parsing/': { + 'fragment parsing algorithm': '#dfn-concept-fragment-serialization-algorithm', + 'fragment serializing algorithm': '#dfn-concept-fragment-serializing-algorithm', 'parse fragment': '#concept-parse-fragment' } diff --git a/spec/shadow/index.html b/spec/shadow/index.html index 687e7130..84176a1b 100644 --- a/spec/shadow/index.html +++ b/spec/shadow/index.html @@ -7,10 +7,18 @@ +