diff --git a/source b/source index 48daf9ac1af..1b67a526b0b 100644 --- a/source +++ b/source @@ -3198,7 +3198,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • node document concept
  • document type concept
  • host concept
  • -
  • The shadow root concept, and its delegates focus, available to element internals, clonable, and serializable.
  • +
  • The shadow root concept, and its delegates focus, available to element internals, clonable, serializable, custom element registry, and keep custom element registry null.
  • The shadow host concept
  • HTMLCollection interface, its length attribute, and its @@ -3307,6 +3307,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • The encoding (herein the character encoding), mode, + custom element registry, allow declarative shadow roots, and content type of a Document
  • The distinction between XML documents and @@ -3316,8 +3317,9 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute no-quirks mode
  • The algorithm clone a node with its arguments document, - subtree, and - parent, and the concept of + subtree, + parent, and + fallbackRegistry, and the concept of cloning steps
  • The concept of base URL change steps and the definition of what happens when an element is affected by a base URL change
  • The concept of an element's unique identifier (ID)
  • @@ -3338,6 +3340,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • An element's namespace, namespace prefix, local name, + custom element registry, custom element definition, and is value
  • @@ -12060,9 +12063,6 @@ console.assert(el.constructor === Element); overridden constructor steps:

      -
    1. Let registry be current global object's custom element registry.

    2. -
    3. If NewTarget is equal to the active function object, then throw a TypeError.

      @@ -12083,6 +12083,25 @@ document.createElement("bad-1"); // (2)
    4. +
    5. Let registry be null.

    6. + +
    7. +

      If the surrounding agent's active custom element constructor + map[NewTarget] exists:

      + +
        +
      1. Set registry to the surrounding agent's active custom + element constructor map[NewTarget].

      2. + +
      3. Remove the surrounding agent's + active custom element constructor map[NewTarget].

      4. +
      +
    8. + +
    9. Otherwise, set registry to current global object's associated Document's custom element registry.

    10. +
    11. Let definition be the item in registry's custom element definition set with shadowrootdelegatesfocus

      shadowrootclonable
      shadowrootserializable
      +
      shadowrootcustomelementregistry
      Accessibility considerations:
      For authors.
      @@ -64766,6 +64786,7 @@ interface HTMLTemplateElement : HTMLElement { [CEReactions] attribute boolean shadowRootDelegatesFocus; [CEReactions] attribute boolean shadowRootClonable; [CEReactions] attribute boolean shadowRootSerializable; + [CEReactions] attribute DOMString shadowRootCustomElementRegistry; };
      Uses HTMLTemplateElement.
      @@ -64814,6 +64835,10 @@ interface HTMLTemplateElement : HTMLElement { data-x="attr-template-shadowrootserializable">shadowrootserializable content attribute is a boolean attribute.

      +

      The shadowrootcustomelementregistry + content attribute is a boolean attribute.

      +

      The template contents of a template element are not children of the element itself.

      @@ -64966,6 +64991,15 @@ interface HTMLTemplateElement : HTMLElement { must reflect the shadowrootserializable content attribute.

      +

      The shadowRootCustomElementRegistry + IDL attribute must reflect the shadowrootcustomelementregistry + content attribute.

      + +

      The IDL attribute does intentionally not have a boolean type so it can be + extended.

      +

      The cloning steps for template @@ -73498,8 +73532,8 @@ document.body.append(parent);

      -

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

      +

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

      A Controls attachShadow().
      -

      To look up a custom element definition, given a document, - namespace, localName, and is, perform the following steps. They - will return either a custom element definition or null:

      +

      To look up a custom element definition, given null or a + CustomElementRegistry object registry, string-or-null + namespace, string localName, and string-or-null is, perform the + following steps. They will return either a custom element definition or null:

        -
      1. If namespace is not the HTML namespace, then return null.

      2. +
      3. If registry is null, then return null.

      4. -
      5. If document's browsing context is - null, then return null.

      6. - -
      7. Let registry be document's relevant global object's - custom element registry.

      8. +
      9. If namespace is not the HTML namespace, then return null.

      10. If registry's custom element definition set contains an item with The CustomElementRegistry interface -

        Each Window object has an associated custom element registry (a - CustomElementRegistry object). It is set to a new - CustomElementRegistry object when the Window object is created.

        - -

        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 customElements attribute of the - Window interface must return the CustomElementRegistry object for that - Window object.

        +

        Each similar-origin window agent has an associated active custom element constructor map, which is a map of constructors to CustomElementRegistry objects.

        + +

        The Window customElements getter steps are to return + this's associated + Document's custom element + registry.

        [Exposed=Window]
         interface CustomElementRegistry {
        -  [CEReactions] undefined define(DOMString name, CustomElementConstructor constructor, optional ElementDefinitionOptions options = {});
        -  (CustomElementConstructor or undefined) get(DOMString name);
        -  DOMString? getName(CustomElementConstructor constructor);
        -  Promise<CustomElementConstructor> whenDefined(DOMString name);
        -  [CEReactions] undefined upgrade(Node root);
        +  constructor();
        +
        +  [CEReactions] undefined define(DOMString name, CustomElementConstructor constructor, optional ElementDefinitionOptions options = {});
        +  (CustomElementConstructor or undefined) get(DOMString name);
        +  DOMString? getName(CustomElementConstructor constructor);
        +  Promise<CustomElementConstructor> whenDefined(DOMString name);
        +  [CEReactions] undefined upgrade(Node root);
        +  undefined initialize((Node) root);
         };
         
         callback CustomElementConstructor = HTMLElement ();
        @@ -73617,6 +73646,12 @@ dictionary ElementDefinitionOptions {
           DOMString extends;
         };
        +

        Every CustomElementRegistry has an is + scoped, a boolean, initially false.

        + +

        Every CustomElementRegistry has a scoped + document set, a set of Document objects, initially « ».

        +

        Every CustomElementRegistry has a custom element definition set, a set of custom element definitions, initially « ». Lookup of items in this set uses their ElementDefinitionOptions { element names to promises. It is used to implement the whenDefined() method.

        +

        To look up a custom element registry, given an Element object, + ShadowRoot object, or Document object node:

        + +
          +
        1. If node is an Element object, then return node's custom element registry.

        2. + +
        3. If node is a ShadowRoot object, then return node's + custom element registry.

        4. + +
        5. Return node's custom element + registry.

        6. +
        +
        -
        window.customElements.define(name, - constructor)
        +
        registry = window.customElements
        +
        Returns the global's associated Document's CustomElementRegistry + object.
        + +
        registry = new CustomElementRegistry()
        +
        Constructs a new CustomElementRegistry object, for scoped usage.
        +
        registry.define(name, + constructor)
        Defines a new custom element, mapping the given name to the given constructor as an autonomous custom element.
        - -
        window.customElements.define(name, constructor, +
        registry.define(name, constructor, { extends: baseLocalName })
        -
        Defines a new custom element, mapping the given name to the given constructor as a customized built-in element for the element type identified by the supplied baseLocalName. A "NotSupportedError" DOMException will be thrown upon trying to extend a custom element or - an unknown element.
        - -
        window.customElements.get(name)
        + an unknown element, or when registry is not a global + CustomElementRegistry object. +
        registry.get(name)
        Retrieves the custom element constructor defined for the given name. Returns undefined if there is no custom element definition with the given name.
        -
        window.customElements.getName(constructor)
        - +
        registry.getName(constructor)
        Retrieves the given name for a custom element defined for the given constructor. Returns null if there is no custom element definition with the given constructor.
        -
        window.customElements.whenDefined(name)
        - +
        registry.whenDefined(name)
        Returns a promise that will be fulfilled with the custom element's constructor when a custom element becomes defined with the given name. (If such a custom element is already defined, the returned promise will be immediately fulfilled.) Returns a promise rejected with a "SyntaxError" DOMException if not given a valid custom element name.
        -
        window.customElements.upgrade(root)
        - +
        registry.upgrade(root)
        Tries to upgrade all shadow-including inclusive descendant elements of root, even if they are not connected.
        + +
        registry.initialize(root)
        +
        Each inclusive descendant of root with a null registry will have it + updated to this CustomElementRegistry object.
        +

        The new CustomElementRegistry() constructor + steps are to set this's is scoped to true.

        +

        Element definition is a process of adding a custom element definition to the CustomElementRegistry. This is accomplished by the define() method. The ElementDefinitionOptions {

        If extends is not null:

          +
        1. If this's is scoped is true, then throw a + "NotSupportedError" DOMException.

        2. +
        3. If extends is a valid custom element name, then throw a "NotSupportedError" DOMException.

        4. @@ -73852,22 +73913,14 @@ dictionary ElementDefinitionOptions {
        5. Append definition to this's custom element definition set.

        6. -
        7. Let document be this's relevant global object's associated Document.

        8. +
        9. If this's is scoped is true, then for each document + of this's scoped document set: upgrade particular elements within + a document given document and localName.

        10. -
        11. Let upgradeCandidates be all elements that are shadow-including descendants of document, whose namespace - is the HTML namespace and whose local name is localName, in - shadow-including tree order. Additionally, if extends is non-null, only - include elements whose is - value is equal to name.

        12. - -
        13. For each element element of upgradeCandidates, enqueue a - custom element upgrade reaction given element and - definition.

        14. - - +
        15. Otherwise, upgrade particular elements within a document given + this's relevant global object's associated Document, localName, + and name.

        16. If this's when-defined promise map[name] shadow-including descendants of document, whose namespace + is the HTML namespace and whose local name is localName, in + shadow-including tree order. Additionally, if name is not + localName, only include elements whose is value is equal to name.

        17. + +
        18. For each element element of upgradeCandidates: enqueue a + custom element upgrade reaction given element and + definition.

        19. +
        + +

        The get(name) method steps are:

        @@ -73962,9 +74034,9 @@ fetch(articleURL)
        -

        When invoked, the upgrade(root) method must run - these steps:

        +

        The upgrade(root) method steps + are:

        1. Let candidates be a list of all of root's @@ -73996,6 +74068,43 @@ console.assert(el instanceof SpiderMan); // upgraded!

          +

          The initialize(root) method + steps are:

          + +
            +
          1. If root is a Document node whose custom element registry is null, then set + root's custom element registry + to this.

          2. + +
          3. Otherwise, if root is a ShadowRoot node whose custom element registry is null, then set + root's custom element + registry to this.

          4. + +
          5. +

            For each inclusive descendant inclusiveDescendant of root: + if inclusiveDescendant is an Element node whose custom element registry is null:

            + +
              +
            1. Set inclusiveDescendant's custom element registry to + this.

            2. + +
            3. If this's is scoped is true, then append inclusiveDescendant's node document to + this's scoped document set.

            4. +
            +
          6. +
          + +

          Once the custom element registry of a node is initialized to a + CustomElementRegistry object, it intentionally cannot be changed any further. This + simplifies reasoning about code and allows implementations to optimize.

          + +

          Upgrades

          To upgrade an element, given as input a @@ -74067,8 +74176,14 @@ customElements.define("x-foo", class extends HTMLElement {

        2. Let C be definition's constructor.

        3. +
        4. Let registry be element's custom element registry.

        5. + +
        6. Set the surrounding agent's active custom + element constructor map[C] to registry.

        7. +
        8. -

          Run the following substeps while catching any exceptions:

          +

          Run the following steps while catching any exceptions:

          1. @@ -74110,10 +74225,18 @@ customElements.define("x-foo", class extends HTMLElement {
          -

          Then, perform the following substep, regardless of whether the above steps threw an exception +

          Then, perform the following steps, regardless of whether the above steps threw an exception or not:

            +
          1. +

            Remove registry's relevant global + object's active custom element constructor map[C].

            + +

            This is a no-op if C immediately calls super() as it ought to do.

            +
          2. +
          3. Remove the last entry from the end of definition's construction stack.

            @@ -74169,15 +74292,16 @@ customElements.define("x-foo", class extends HTMLElement { element state to "custom".

          -

          To try to upgrade an element, given as input an - element element, run the following steps:

          +

          To try to upgrade an element given an element + element:

          1. Let definition be the result of looking up a custom element definition given element's node - document, element's namespace, element's local name, and - element's is - value.

          2. + definition">looking up a custom element definition given element's custom element registry, element's + namespace, element's local name, and element's is value.

          3. If definition is not null, then enqueue a custom element upgrade reaction given element and definition.

          4. @@ -74564,9 +74688,10 @@ customElements.define("x-foo", class extends HTMLElement { DOMException.

          5. Let definition be the result of looking up a custom element definition given this's node - document, its namespace, its local name, and null as the is value.

          6. + definition">looking up a custom element definition given this's custom element registry, this's + namespace, this's local name, and null.

          7. If definition is null, then throw an "NotSupportedError" DOMException.

          8. @@ -99638,6 +99763,9 @@ interface NotRestoredReasons {
            allow declarative shadow roots
            true
            + +
            custom element registry
            +
            A new {{CustomElementRegistry}} object.
            @@ -106198,6 +106326,9 @@ location.href = '#foo';
            allow declarative shadow roots
            true
            + +
            custom element registry
            +
            A new {{CustomElementRegistry}} object.
            @@ -130629,8 +130760,11 @@ dictionary StorageEventInit : EventInit {
          9. Let is be the value of the "is" attribute in the given token, if such an attribute exists, or null otherwise.

          10. +
          11. Let registry be the result of looking up a custom element registry given intended parent.

          12. +
          13. Let definition be the result of looking up a custom element definition given document, given + definition">looking up a custom element definition given registry, given namespace, local name, and is.

          14. Let willExecuteScript be true if definition is non-null and the @@ -130655,7 +130789,7 @@ dictionary StorageEventInit : EventInit {

          15. Let element be the result of creating an element given document, localName, given namespace, - null, is, and willExecuteScript.

            + null, is, willExecuteScript, and registry.

            This will cause custom element constructors to run, if willExecuteScript is true. However, since we @@ -131536,7 +131670,8 @@ document.body.appendChild(text);

          16. Attach a shadow root with declarative shadow host element, mode, clonable, - serializable, delegatesFocus, and "named".

            + serializable, delegatesFocus, "named", and + registry.

            If an exception is thrown, then catch it and:

            @@ -131560,6 +131695,11 @@ document.body.appendChild(text); shadow.

          17. Set shadow's available to element internals to true.

          18. + +
          19. If template start tag has a shadowrootcustomelementregistry + attribute, then set shadow's keep custom element registry null to + true.

        @@ -135364,6 +135504,11 @@ document.body.appendChild(text);
      11. If shadow's clonable is set, then append " shadowrootclonable=""".

      12. +
      13. If current node's custom + element registry is not shadow's custom element registry, then append + " shadowrootcustomelementregistry=""".

      14. +
      15. Append ">".

      16. Append the value of running the HTML fragment serialization algorithm with @@ -135777,8 +135922,9 @@ console.assert(container.firstChild instanceof SuperP);

      17. Let root be the result of creating an - element given document, "html", and the HTML - namespace.

      18. + element given document, "html", the HTML + namespace, null, null, false, and context's custom element registry.

      19. Append root to document.

      20. @@ -143047,7 +143193,8 @@ interface External { shadowrootmode; shadowrootdelegatesfocus; shadowrootclonable; - shadowrootserializable + shadowrootserializable; + shadowrootcustomelementregistry HTMLTemplateElement @@ -144531,6 +144678,11 @@ interface External { template Sets clonable on a declarative shadow root Boolean attribute + + shadowrootcustomelementregistry + template + Enables declarative shadow roots to indicate they will use a custom element registry + Boolean attribute shadowrootdelegatesfocus template