diff --git a/source b/source index 8e840db7d48..58eb191628f 100644 --- a/source +++ b/source @@ -65658,8 +65658,8 @@ document.body.appendChild(flagIcon) what element interface it extends, as many elements share the same interface (such as q and blockquote both sharing HTMLQuoteElement).

-

To use our customized built-in element, we use the is attribute on a button element:

+

To construct our customized built-in element from parsed HTML source text, we use + the is attribute on a button element:

<button is="plastic-button">Click Me!</button>
@@ -65668,8 +65668,8 @@ document.body.appendChild(flagIcon) me?</plastic-button> will simply create an HTMLElement with no special behavior.

-

If you need to create a type-extended element programmatically, you can use the following form - of createElement():

+

If you need to create a customized built-in element programmatically, you can use the following + form of createElement():

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

And as before, the constructor will also work:

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

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 Note that when creating a customized built-in element programmatically, the is attribute will not be present in the DOM, since it was not explicitly + set. However, it will be added to the output when + serializing:

+ +
console.assert(!plasticButton.hasAttribute("is"));
+console.log(plasticButton.outerHTML); // will output '<button is="plastic-button"></button>'
+ +

Regardless of how it is created, 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.

@@ -109718,6 +109727,14 @@ document.body.appendChild(text); createElement(), tagname will be lowercase.

+

If current node's is value is not null, and the element does not have an is attribute in its attribute list, then append the string " is="", followed by current node's is value escaped as described below in attribute mode, + followed by a U+0022 QUOTATION MARK character (").

+

For each attribute that the element has, append a U+0020 SPACE character, the attribute's serialized name as described below, a U+003D EQUALS SIGN character (=), a U+0022 QUOTATION MARK character ("), the @@ -109960,6 +109977,63 @@ Hello.</pre> data-x="">Hello.".

+

Because of the special role of the is attribute in signaling the creation of customized built-in elements, in that it provides a mechanism for parsed + HTML to set the element's is + value, we special-case its handling during serialization.This ensures that an element's + is value is preserved + through serialize-parse roundtrips.

+ +
+

When creating a customized built-in element via the parser, a developer uses the is attribute directly; in such cases serialize-parse roundtrips work fine.

+ +
<script>
+window.SuperP = class extends HTMLParagraphElement {};
+customElements.define("super-p", SuperP, { extends: "p" });
+</script>
+
+<div id="container"><p is="super-p">Superb!</p></div>
+
+<script>
+console.log(container.innerHTML); // <p is="super-p">
+container.innerHTML = container.innerHTML;
+console.log(container.innerHTML); // <p is="super-p">
+console.assert(container.firstChild instanceof SuperP);
+</script>
+ +

But when creating a customized built-in element via its constructor or via createElement(), the is + attribute is not added. Instead, the is value (which is what the custom elements machinery uses) is set + without intermediating through an attribute.

+ +
<script>
+container.innerHTML = "";
+const p = document.createElement("p", { is: "super-p" });
+container.appendChild(p);
+
+// The is attribute is not present in the DOM:
+console.assert(!p.hasAttribute("is"));
+
+// But the element is still a super-p:
+console.assert(p instanceof SuperP);
+</script>
+ +

To ensure that serialize-parse roundtrips still work, the serialization process explicitly + writes out the element's is + value as an is attribute:

+ +
<script>
+console.log(container.innerHTML); // <p is="super-p">
+container.innerHTML = container.innerHTML;
+console.log(container.innerHTML); // <p is="super-p">
+console.assert(container.firstChild instanceof SuperP);
+</script>
+
+

Escaping a string (for the purposes of the algorithm above) consists of running the following steps: