diff --git a/source b/source index 0639bb4821c..7dcd5a9b44a 100644 --- a/source +++ b/source @@ -3203,7 +3203,8 @@ 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 @@ -3319,8 +3320,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)
  • @@ -3341,6 +3343,8 @@ 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
  • @@ -12044,9 +12048,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.

      @@ -12067,6 +12068,24 @@ 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. If registry is null, then set registry to current global + object's custom element + registry.

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

      shadowrootclonable
      shadowrootserializable
      +
      shadowrootcustomelements
      Accessibility considerations:
      For authors.
      @@ -64057,6 +64077,7 @@ interface HTMLTemplateElement : HTMLElement { [CEReactions] attribute boolean shadowRootDelegatesFocus; [CEReactions] attribute boolean shadowRootClonable; [CEReactions] attribute boolean shadowRootSerializable; + [CEReactions] attribute DOMString shadowRootCustomElements; };
      Uses HTMLTemplateElement.
      @@ -64105,6 +64126,10 @@ interface HTMLTemplateElement : HTMLElement { data-x="attr-template-shadowrootserializable">shadowrootserializable content attribute is a boolean attribute.

      +

      The shadowrootcustomelements + content attribute is a boolean attribute.

      +

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

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

      +

      The shadowRootCustomElements IDL attribute + must reflect the shadowrootcustomelements content + attribute.

      + +

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

      +

      The cloning steps for template @@ -72562,8 +72596,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 document's browsing context is - null, then return null.

      4. +
      5. If registry 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 +

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

        +

        The customElements attribute of the Window interface must return the CustomElementRegistry object for that @@ -72668,11 +72703,17 @@ document.body.append(parent);

        [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);
        +
        +  [CEReactions, NewObject] HTMLElement createElement(DOMString name);
        +  [CEReactions, NewObject] Node cloneSubtree(Node root);
        +  undefined initializeSubtree((Element or ShadowRoot) root);
         };
         
         callback CustomElementConstructor = HTMLElement ();
        @@ -72681,6 +72722,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 parentNode: + +

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

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

        3. If parentNode's browsing context is + null, then return null.

        4. + +
        5. Return parentNode's relevant global object's custom element registry.

        6. +
        +
      -
      window.customElements.define(name, - constructor)
      +
      registry = window.customElements
      +
      Returns the global 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.createElement(name)
      +
      +

      Returns an HTML element with name as its local + name and registry as its registry.

      + +

      If name does not match the Name production an + "InvalidCharacterError" DOMException will be thrown.

      +
      + +
      registry.cloneSubtree(root)
      +
      Returns a copy of root, changing the registry from root's inclusive + descendants from null (if any) to registry in the process.
      + +
      registry.initializeSubtree(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 is not this's relevant global object's + custom element registry, then throw a + "NotSupportedError" DOMException.

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

      4. @@ -72915,22 +73006,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. 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.

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

      12. +
      13. 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. - +

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

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

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

      18. +
      + +

      The get(name) method steps are:

      @@ -73025,9 +73127,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 @@ -73059,6 +73161,59 @@ console.assert(el instanceof SpiderMan); // upgraded!

        +

        The createElement(name) + method steps are:

        + +
          +
        1. If name does not match the XML Name production, + then throw an "InvalidCharacterError" + DOMException.

        2. + +
        3. Return the result of creating an element given + this's relevant global object's associated Document, name, the + HTML namespace, null, null, true, and this.

        4. +
        + +

        The cloneSubtree(root) + method steps are:

        + +
          +
        1. If root is a Document or ShadowRoot object, then + throw a "NotSupportedError" DOMException.

        2. + +
        3. Return the result of cloning a node given + root with subtree set to true + and fallbackRegistry set + this.

        4. +
        + +

        The initializeSubtree(root) + method steps are:

        + +
          +
        1. +

          For each inclusive descendant inclusiveDescendant of + root:

          + +
            +
          1. If inclusiveDescendant is an Element node whose custom element registry is null, then set + inclusiveDescendant's custom element + registry to this.

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

          4. +
          +
        2. +
        + +

        Upgrades

        To upgrade an element, given as input a @@ -73130,8 +73285,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. @@ -73173,10 +73334,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.

          @@ -73232,15 +73401,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. @@ -73594,9 +73764,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. @@ -129197,8 +129368,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 @@ -130103,7 +130277,8 @@ document.body.appendChild(text);

        15. 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:

          @@ -130127,6 +130302,10 @@ document.body.appendChild(text); shadow.

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

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

      @@ -133931,6 +134110,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 + " shadowrootcustomelements=""".

    14. +
    15. Append ">".

    16. Append the value of running the HTML fragment serialization algorithm with @@ -134364,9 +134548,10 @@ console.assert(container.firstChild instanceof SuperP); transitions.

    17. -
    18. -

      Let root be a new html element with no attributes.

      -
    19. +
    20. Let root be the result of creating an + element given the Document node created above, "html", + the HTML namespace, null, null, false, and context's custom element registry.

    21. Append the element root to the Document node created @@ -141654,7 +141839,8 @@ interface External { shadowrootmode; shadowrootdelegatesfocus; shadowrootclonable; - shadowrootserializable + shadowrootserializable; + shadowrootcustomelements HTMLTemplateElement @@ -143116,6 +143302,11 @@ interface External { template Sets clonable on a declarative shadow root Boolean attribute + + shadowrootcustomelements + template + Enables declarative shadow roots to indicate they will use a custom element registry + Boolean attribute shadowrootdelegatesfocus template