From 34f9019340fa9c7712b3155903adec654e80320f Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Fri, 26 Oct 2018 10:46:23 +0200 Subject: [PATCH 1/3] Always enqueue an element regardless of callback Tests: ... Fixes https://github.com/w3c/webcomponents/issues/760. --- source | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/source b/source index 60dd4e6a220..e0e6542114b 100644 --- a/source +++ b/source @@ -67033,24 +67033,28 @@ customElements.define("x-foo", class extends HTMLElement { data-x="concept-custom-element-definition-lifecycle-callbacks">lifecycle callbacks with key callbackName.

-
  • If callback is null, then return

  • -
  • -

    If callbackName is "attributeChangedCallback", then:

    +

    If callback is non-null, then:

      -
    1. Let attributeName be the first element of args.

    2. +
    3. +

      If callbackName is "attributeChangedCallback", then:

      + +
        +
      1. Let attributeName be the first element of args.

      2. -
      3. If definition's observed attributes does - not contain attributeName, then return.

      4. +
      5. If definition's observed attributes + does not contain attributeName, then return.

      6. +
      +
    4. + +
    5. Add a new callback reaction to element's custom element + reaction queue, with callback function callback and arguments + args.

  • -
  • Add a new callback reaction to element's custom element - reaction queue, with callback function callback and arguments - args.

  • -
  • Enqueue an element on the appropriate element queue given element.

  • From 2b3d3bb2fea93305d828d8cce4cece0a8ba41b7c Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Tue, 30 Oct 2018 10:16:59 +0100 Subject: [PATCH 2/3] always enqueue --- source | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/source b/source index e0e6542114b..1d9d04867b5 100644 --- a/source +++ b/source @@ -67037,6 +67037,8 @@ customElements.define("x-foo", class extends HTMLElement {

    If callback is non-null, then:

      +
    1. Let skip be false.

    2. +
    3. If callbackName is "attributeChangedCallback", then:

      @@ -67045,13 +67047,13 @@ customElements.define("x-foo", class extends HTMLElement {
    4. If definition's observed attributes - does not contain attributeName, then return.

    5. + does not contain attributeName, then set skip to true.

    -
  • Add a new callback reaction to element's custom element - reaction queue, with callback function callback and arguments - args.

  • +
  • If skip is false, then add a new callback reaction to + element's custom element reaction queue, with callback function + callback and arguments args.

  • @@ -67059,6 +67061,32 @@ customElements.define("x-foo", class extends HTMLElement { element.

    +
    +

    Unfortunately due to the nature of the queueing these reactions there can be somewhat + unexpected corner cases: + +

    class CParent extends HTMLElement {
    +  connectedCallback() {
    +    const child = this.childNodes[0];
    +    this.removeChild(child);
    +  }
    +}
    +customElements.define("c-parent", CParent);
    +
    +class CChild extends HTMLElement {
    +  connectedCallback() {
    +    console.log("CChild connectedCallback isConnected=" + this.isConnected.toString());
    +  }
    +}
    +customElements.define("c-child", CChild);
    +
    +const container = document.createElement("div");
    +container.innerHTML = "<c-parent><c-child></c-child></c-parent>";
    +customElements.upgrade(container);
    +document.body.appendChild(container);
    +// CChild connectedCallback isConnected=false
    +
    +

    To enqueue a custom element upgrade reaction, given an element element and custom element definition definition, run the following steps:

    @@ -122328,6 +122356,7 @@ INSERT INTERFACES HERE Tom Pike, Tom Schuster, Tomasz Jakut, + Tomek Wytrębowicz, Tommy Thorsen, Tony Ross, Tooru Fujisawa, From c165c788bfe4459b022fd7b80c4f2185229bb750 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Thu, 1 Nov 2018 09:57:28 +0100 Subject: [PATCH 3/3] feedback from Tomek and Domenic --- source | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/source b/source index 1d9d04867b5..208098e13f0 100644 --- a/source +++ b/source @@ -67062,20 +67062,20 @@ customElements.define("x-foo", class extends HTMLElement {
    -

    Unfortunately due to the nature of the queueing these reactions there can be somewhat - unexpected corner cases: +

    An element's connectedCallback can be queued before the element is + disconnected, but as the callback queue is still processed, it results in a connectedCallback for an element that is no longer connected:

    class CParent extends HTMLElement {
       connectedCallback() {
    -    const child = this.childNodes[0];
    -    this.removeChild(child);
    +    this.firstChild.remove();
       }
     }
     customElements.define("c-parent", CParent);
     
     class CChild extends HTMLElement {
       connectedCallback() {
    -    console.log("CChild connectedCallback isConnected=" + this.isConnected.toString());
    +    console.log("CChild connectedCallback: isConnected =", this.isConnected);
       }
     }
     customElements.define("c-child", CChild);
    @@ -67084,7 +67084,9 @@ const container = document.createElement("div");
     container.innerHTML = "<c-parent><c-child></c-child></c-parent>";
     customElements.upgrade(container);
     document.body.appendChild(container);
    -// CChild connectedCallback isConnected=false
    + +// Logs: +// CChild connectedCallback: isConnected = false

    To enqueue a custom element upgrade reaction, given an element