Skip to content

Revamped Scoped Custom Element Registries #10854

Closed
0 of 2 issues completed
whatwg/dom
#1341
Closed
@annevk

Description

@annevk

https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Scoped-Custom-Element-Registries.md is a good proposal, but it ties the functionality too much to shadow roots. This is Ryosuke and I's proposed improvement attempting to account for feedback given in various Web Components issues on this topic: https://github.com/WICG/webcomponents/issues?q=is%3Aissue+label%3A%22scoped+custom+element+registry%22.

First, the IDL, illustrating the new members:

interface CustomElementRegistry {
  constructor();

  ...
  undefined initialize((Element or ShadowRoot) root);
};

partial interface Document {
  [CEReactions, NewObject] Element createElement(DOMString localName, optional (DOMString or ElementCreationOptions) options = {});
  [CEReactions, NewObject] Element createElementNS(DOMString? namespace, DOMString qualifiedName, optional (DOMString or ElementCreationOptions) options = {});
  [CEReactions, NewObject] Node importNode(Node node, optional (boolean or ImportNodeOptions) options = false);
}

dictionary ElementCreationOptions {
  CustomElementRegistry customElementRegistry;
}

dictionary ImportNodeOptions {
  CustomElementRegistry customElementRegistry;
  selfOnly = false;
}

partial interface Element {
  readonly attribute CustomElementRegistry? customElementRegistry;
};

dictionary ShadowRootInit { // used by Element.prototype.attachShadow
  ...
  CustomElementRegistry customElementRegistry;
};

partial interface DocumentOrShadowRoot {
  readonly attribute CustomElementRegistry? customElementRegistry;
};

partial interface HTMLTemplateElement {
  [CEReactions] attribute DOMString shadowRootCustomElementRegistry;
}

Here’s a summary of how the proposal evolved:

  • CustomElementRegistry still gains a constructor.
  • ShadowRoot still supports a CustomElementRegistry, exposed through a customElementRegistry getter.
    • It seems important for the shadow root to be able to be independent from its host in terms of registries.
    • Interaction with declarative shadow DOM WICG/webcomponents#914 has a proposal for declarative shadow trees to be able to disable inheriting from the global registry. This adopts that with the shadowrootcustomelements attribute, which is reflected as a string for forward compatibility.
    • ElementInternals gains initializeShadowRoot() CustomElementRegistry gains initialize() so a declarative shadow root (or any element) can have its CustomElementRegistry set (when it’s null).
    • The attachShadow() member is now called customElementRegistry for consistency.
  • Element should support an associated CustomElementRegistry, exposed through a customElementRegistry getter. This impacts elements created through innerHTML and future such methods, such as setHTMLUnsafe(). This will allow using non-global CustomElementRegistry outside of shadow roots.
    • setHTMLUnsafe() in the future could maybe also set its own CustomElementRegistry. Given the ergonomics of that it makes sense to expose it directly on Element as well.
  • document.createElement(), document.createElementNS(), and document.importNode() are updated to account for registries.

I’ll create specification PRs as well to allow for review of the processing model changes. We believe this resolves the remaining issues with the latest iteration of the initial proposal.

I'd like to briefly go over this in the December 19 WHATNOT meeting and will also be available then to answer any questions. Marking agenda+ therefore.

cc @rniwa @justinfagnani @whatwg/components


Minor issue tracker:

  • Instead of inventing a new createElement() we should attempt to reuse the existing one on document (with a new customElements member) as we're not quite ready to reinvent how to best do element-creation.
  • Should initializeSubtree() perform upgrades in the connected case? (If yes, it should probably also update the scoped document set.) (No.)
  • Is there a better name for initializeSubtree()? (Also consider the names already exposed on this object.) Just initialize.
  • importNode() is better after all as we need a document anyway. So we should go with a document.importNode(node, { subtree, customElements }) overload.

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    addition/proposalNew features or enhancementsneeds implementer interestMoving the issue forward requires implementers to express interesttopic: custom elementsRelates to custom elements (as defined in DOM and HTML)topic: shadowRelates to shadow trees (as defined in DOM)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions