diff --git a/source b/source index 1c026f8bd68..9a8f8689683 100644 --- a/source +++ b/source @@ -9677,16 +9677,51 @@ interface HTMLUnknownElement : HTMLElement { }; via new MyCustomElement().

-
  • Let instance be the last entry in definition's

    Let element be the last entry in definition's construction stack.

  • -

    If instance is an already +

    If element is an already constructed marker, then throw an "InvalidStateError" DOMException and abort these steps.

    -

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

    +
    +

    This can occur when the author code inside the custom element + constructor non-conformantly creates another + instance of the class being constructed, before calling super():

    + +
    let doSillyThing = false;
    +
    +class DontDoThis extends HTMLElement {
    +  constructor() {
    +    if (doSillyThing) {
    +      doSillyThing = false;
    +      new DontDoThis();
    +      // Now the construction stack will contain an already constructed marker.
    +    }
    +
    +    // This will then fail with an "InvalidStateError" DOMException:
    +    super();
    +  }
    +}
    +
    + +
    +

    This can also occur when author code inside the custom element constructor non-conformantly calls super() + twice, since per the JavaScript specification, this actually executes the superclass + constructor (i.e. this algorithm) twice, before throwing an error: + +

    class DontDoThisEither extends HTMLElement {
    +  constructor() {
    +    super();
    +
    +    // This will throw, but not until it has already called into the HTMLElement constructor
    +    super();
    +  }
    +}
    +
  • Perform element.[[SetPrototypeOf]](prototype). Rethrow any @@ -9698,7 +9733,7 @@ interface HTMLUnknownElement : HTMLElement { }; marker.

  • -

    Return instance.

    +

    Return element.

    This step is normally reached when upgrading a custom element; the existing element is @@ -66074,10 +66109,11 @@ console.log(plasticButton2.getAttribute("is")); // will output "plastic-button"<

    A construction stack
    -
    A list, initially empty, that 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.
    +
    A list, initially empty, that 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.

    To look up a custom element definition, given a document, @@ -66388,8 +66424,24 @@ fetch(articleURL)

  • Let constructResult be Construct(C).

  • -
  • Remove element from the end of definition's construction stack.

  • +
  • +

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

    + +
    +

    Assuming C calls super() (as it should), and that the call succeeds, this will be the + already + constructed marker that replaced the element we pushed at the beginning + of this algorithm. (The HTMLElement + constructor carries out this replacement.)

    + +

    If C does not call super() (i.e. it is not conformant), or if any step in the HTMLElement constructor throws, then this entry + will still be element.

    +
    +
  • If constructResult is an abrupt completion, then return constructResult (i.e., rethrow the exception).