From 31a455a25b09b1d69121daf332075450af3baa46 Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Sun, 29 Sep 2024 15:18:38 -0400 Subject: [PATCH 01/24] State-preserving atomic move integration --- source | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/source b/source index 0639bb4821c..6dbc735ddbc 100644 --- a/source +++ b/source @@ -3224,6 +3224,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • append() method
  • appendChild() method
  • cloneNode() method
  • +
  • moveBefore() method
  • importNode() method
  • preventDefault() method
  • id attribute
  • @@ -10932,6 +10933,17 @@ partial interface Document { set of not restored reason details, initially empty.

    +

    Each Document has a state-preserving atomic move in progress boolean, which is initially + false.

    + +

    This is set by moveBefore() when a + Document is performing a state-preserving atomic move; it is used to exempt certain + insertion steps and removing steps (and their kin), from running, if they + would ordinarily reset state that needs to be preserved.

    +

    The DocumentOrShadowRoot interface

    DOM defines the state-preserving atomic move + in progress is true, then return.

    +
  • If insertedNode's parent is a media element that has no src attribute and whose networkState has the value HTMLSourceElement : HTMLElement { steps, given removedNode and oldParent, are:

      +
    1. If insertedNode's node document's state-preserving atomic move + in progress is true, then return.

    2. +
    3. If removedNode's next sibling was an img element and oldParent is a picture element, then, count this as a relevant mutation for the img element.

    4. @@ -29441,6 +29461,10 @@ interface HTMLImageElement : HTMLElement { steps, given insertedNode, are:

        +
      1. If insertedNode's node document's state-preserving atomic move + in progress is true, then return.

      2. +
      3. If insertedNode's parent is a picture element, then, count this as a relevant mutation for insertedNode.

      4. @@ -29450,6 +29474,10 @@ interface HTMLImageElement : HTMLElement { steps, given removedNode and oldParent, are:

          +
        1. If insertedNode's node document's state-preserving atomic move + in progress is true, then return.

        2. +
        3. If oldParent is a picture element, then, count this as a relevant mutation for removedNode.

        @@ -30950,7 +30978,9 @@ was an English <a href="/wiki/Music_hall">music hall</a> singer, ...

        The img or source HTML element insertion steps or HTML element removing steps count the mutation as a relevant mutation.

        + mutations">relevant mutation, when the element's node document's state-preserving atomic move + in progress is false.

      5. The element's parent is a picture element and a source element that is a previous sibling has its srcset, HTMLIFrameElement : HTMLElement {

      The iframe HTML element removing steps, given - removedNode, are to destroy a child navigable given - removedNode.

      + removedNode, are:

      + +
        +
      1. If insertedNode's node document's state-preserving atomic move + in progress is true, then return.

      2. + +
      3. Destroy a child navigable given removedNode.

        +

      This happens without any unload events firing (the element's content document is state-preserving atomic move + in progress is true, then return.

      +
    5. Ensure details exclusivity by closing the given element if needed given insertedNode.

    @@ -81166,6 +81170,10 @@ dictionary ToggleEventInit : EventInit {
  • Let target be the element's node document.

  • +
  • If target's state-preserving atomic move + in progress is true, then return.

  • +
  • If target is not fully active, then return.

  • If target's active sandboxing flag set has the @@ -138774,6 +138782,10 @@ interface HTMLFrameSetElement : HTMLElement { insertedNode, are:

      +
    1. If insertedNode's node document's state-preserving atomic move + in progress is true, then return.

    2. +
    3. If insertedNode is not in a document tree, then return.

    4. If insertedNode's root's HTMLFrameSetElement : HTMLElement {

    The frame HTML element removing steps, given removedNode, - are to destroy a child navigable given removedNode.

    + are:

    + +
      +
    1. If insertedNode's node document's state-preserving atomic move + in progress is true, then return.

    2. + +
    3. Destroy a child navigable given removedNode.

    4. +

    Whenever a frame element with a non-null content navigable has its src attribute set, changed, or removed, the user From cbae5b240d1c27c3a05c5c907a4c004775dfabc8 Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Sun, 29 Sep 2024 23:40:11 -0400 Subject: [PATCH 03/24] Add HTML element moving steps override --- source | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/source b/source index 07310a4a8df..bf943e74554 100644 --- a/source +++ b/source @@ -1773,8 +1773,9 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute data-x="control">controls or U+0020 SPACE).

    An HTML element can have specific HTML element insertion steps, HTML element - post-connection steps, and HTML element removing steps, all defined for the - element's local name.

    + post-connection steps, HTML element removing steps, and HTML element moving + steps all defined for the element's local + name.

    The insertion steps for the HTML Standard, given insertedNode, are defined as the following:

    @@ -1861,6 +1862,31 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute popover algorithm given removedNode, false, false, and false.

  • +

    The moving steps for the HTML Standard, given + movedNode, are defined as the following:

    + +
      +
    1. If movedNode is an element whose namespace is the HTML namespace, and this + standard defines HTML element moving steps for movedNode's local name, then run the corresponding HTML + element moving steps given movedNode.

    2. + +
    3. +

      If movedNode is a form-associated element or the ancestor of a + form-associated element, then:

      + +
        +
      1. If the form-associated element's parser inserted flag is set, + then return.

      2. + +
      3. Reset the form owner of the form-associated element.

      4. +
      +
    4. +
    + + +

    A node is inserted into a document when the insertion steps are invoked @@ -3264,6 +3290,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute

  • The insertion steps,
  • The post-connection steps, removing steps, + moving steps, adopting steps, and children changed steps hooks for elements
  • The change, append, remove, replace, get an attribute by namespace and local name, set value, and remove an attribute by namespace and local name algorithms for attributes
  • From 749d57de0b75ebf24622e926b6a2c236863476c0 Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Mon, 30 Sep 2024 00:13:35 -0400 Subject: [PATCH 04/24] media + option + optgroup --- source | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/source b/source index bf943e74554..d30656b9e12 100644 --- a/source +++ b/source @@ -36620,13 +36620,15 @@ interface MediaError { other node is the node after pointer. Initially, let pointer be the position between the candidate node and the next node, if there are any, or the end of the list, if it is the last node.

    -

    As nodes are inserted and removed into the media element, +

    As nodes are inserted, removed, and movedinto the media element, pointer must be updated as follows:

    -
    If a new node is inserted between the two - nodes that define pointer
    +
    If a new node is inserted or moved between the two nodes that define + pointer
    Let pointer be the point between the node before pointer and the new node. In other words, insertions at pointer go after pointer.
    @@ -53899,6 +53901,17 @@ interface HTMLSelectElement : HTMLElement { select element's selectedness setting algorithm.

    +

    The option HTML element moving steps, given movedNode and + oldParent, are:

    + +
      +
    1. Run the option HTML element removing steps given + movedNode and oldParent.

    2. + +
    3. Run the option HTML element insertion steps given + movedNode.

    4. +
    +

    The optgroup HTML element removing steps, given removedNode and oldParent, are:

    @@ -53908,6 +53921,14 @@ interface HTMLSelectElement : HTMLElement { algorithm.

    +

    The optgroup HTML element moving steps, given movedNode + and oldParent, are:

    + +
      +
    1. Run the optgroup HTML element removing steps given + movedNode and oldParent.

    2. +
    +

    If an option element in the list of options asks for a reset, then run that select element's selectedness setting algorithm.

    From 80edc73043ea9bf5e7b16e34ccc0f6961f0a48aa Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Mon, 30 Sep 2024 00:18:00 -0400 Subject: [PATCH 05/24] Revert most or all usages of state-preserving atomic move in progress flag --- source | 56 +++++++------------------------------------------------- 1 file changed, 7 insertions(+), 49 deletions(-) diff --git a/source b/source index d30656b9e12..9b2fe82c025 100644 --- a/source +++ b/source @@ -10971,6 +10971,9 @@ partial interface Document { data-x="concept-node-remove-ext">removing steps (and their kin), from running, if they would ordinarily reset state that needs to be preserved.

    +

    TODO(domfarolino): Before merging, probably remove this flag since we're going with + the HTML element moving steps infrastructure instead.

    +

    The DocumentOrShadowRoot interface

    DOM defines the state-preserving atomic move - in progress is true, then return.

    -
  • If insertedNode's parent is a media element that has no src attribute and whose networkState has the value HTMLSourceElement : HTMLElement { steps, given removedNode and oldParent, are:

      -
    1. If insertedNode's node document's state-preserving atomic move - in progress is true, then return.

    2. -
    3. If removedNode's next sibling was an img element and oldParent is a picture element, then, count this as a relevant mutation for the img element.

    4. @@ -29488,10 +29483,6 @@ interface HTMLImageElement : HTMLElement { steps, given insertedNode, are:

        -
      1. If insertedNode's node document's state-preserving atomic move - in progress is true, then return.

      2. -
      3. If insertedNode's parent is a picture element, then, count this as a relevant mutation for insertedNode.

      4. @@ -29501,10 +29492,6 @@ interface HTMLImageElement : HTMLElement { steps, given removedNode and oldParent, are:

          -
        1. If insertedNode's node document's state-preserving atomic move - in progress is true, then return.

        2. -
        3. If oldParent is a picture element, then, count this as a relevant mutation for removedNode.

        @@ -31005,9 +30992,7 @@ was an English <a href="/wiki/Music_hall">music hall</a> singer, ...

        The img or source HTML element insertion steps or HTML element removing steps count the mutation as a relevant mutation, when the element's node document's state-preserving atomic move - in progress is false.

        + mutations">relevant mutation.

      5. The element's parent is a picture element and a source element that is a previous sibling has its srcset, HTMLIFrameElement : HTMLElement {

      The iframe HTML element removing steps, given - removedNode, are:

      - -
        -
      1. If insertedNode's node document's state-preserving atomic move - in progress is true, then return.

      2. - -
      3. Destroy a child navigable given removedNode.

        -
      + removedNode, are to destroy a child navigable given + removedNode.

      This happens without any unload events firing (the element's content document is state-preserving atomic move - in progress is true, then return.

      -
    5. Ensure details exclusivity by closing the given element if needed given insertedNode.

    @@ -81218,10 +81192,6 @@ dictionary ToggleEventInit : EventInit {
  • Let target be the element's node document.

  • -
  • If target's state-preserving atomic move - in progress is true, then return.

  • -
  • If target is not fully active, then return.

  • If target's active sandboxing flag set has the @@ -138830,10 +138800,6 @@ interface HTMLFrameSetElement : HTMLElement { insertedNode, are:

      -
    1. If insertedNode's node document's state-preserving atomic move - in progress is true, then return.

    2. -
    3. If insertedNode is not in a document tree, then return.

    4. If insertedNode's root's HTMLFrameSetElement : HTMLElement {

    The frame HTML element removing steps, given removedNode, - are:

    - -
      -
    1. If insertedNode's node document's state-preserving atomic move - in progress is true, then return.

    2. - -
    3. Destroy a child navigable given removedNode.

    4. -
    + are to destroy a child navigable given removedNode.

    Whenever a frame element with a non-null content navigable has its src attribute set, changed, or removed, the user From 9be6d21372be53e7a22c0f6912bc98972a373c8c Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Mon, 30 Sep 2024 00:19:05 -0400 Subject: [PATCH 06/24] Spacing --- source | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source b/source index 9b2fe82c025..b6a08135ea2 100644 --- a/source +++ b/source @@ -36600,7 +36600,7 @@ interface MediaError {

    As nodes are inserted, removed, and movedinto the media element, + data-x="concept-node-move-ext">moved into the media element, pointer must be updated as follows:

    From 31cf29870cd5f46cc961de039f1315556ff36d7b Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Mon, 30 Sep 2024 00:28:01 -0400 Subject: [PATCH 07/24] Remove extra newlines --- source | 2 -- 1 file changed, 2 deletions(-) diff --git a/source b/source index b6a08135ea2..82d31329e46 100644 --- a/source +++ b/source @@ -1885,8 +1885,6 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • - -

    A node is inserted into a document when the insertion steps are invoked From f8db9426ec42f7c2c17e55582cdd6c12ba263ea5 Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Wed, 2 Oct 2024 16:48:47 +0100 Subject: [PATCH 08/24] Use move steps instead of the flag --- source | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/source b/source index 82d31329e46..c1c48ad657a 100644 --- a/source +++ b/source @@ -1872,6 +1872,25 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute data-x="concept-element-local-name">local name, then run the corresponding HTML element moving steps given movedNode.

    +
  • +

    If movedNode is a custom element, then:

    + +

      +
    1. If the element has an author-provided connectedMoveCallback, then + call it with no arguments.

    2. + +
    3. +

      Otherwise:

      +
        +
      1. Call movedNode's disconnectedCallback, with no + arguments.

      2. +
      3. Call movedNode's connectedCallback, with no + arguments.

      4. +
      +
    4. +
    +
  • +
  • If movedNode is a form-associated element or the ancestor of a form-associated element, then:

    From c53b01c80a03fc5b074b522fd2c1a0498a172631 Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Tue, 8 Oct 2024 15:01:16 -0400 Subject: [PATCH 09/24] Add `` and `` relevant mutations back --- source | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/source b/source index c1c48ad657a..e97677985e8 100644 --- a/source +++ b/source @@ -29219,8 +29219,8 @@ interface HTMLSourceElement : HTMLElement {
    -

    The source HTML element insertion - steps, given insertedNode, are:

    +

    The source HTML element insertion steps, given + insertedNode, are:

    1. If insertedNode's parent is a media element that has no HTMLSourceElement : HTMLElement { mutation for the img element.

    -

    The source HTML element removing - steps, given removedNode and oldParent, are:

    +

    The source HTML element moving steps, given movedNode and + oldParent, are:

    + +
      +
    1. If movedNode's next sibling was an img element and + oldParent is a picture element, then, count this as a relevant mutation for the img element.

    2. +
    + +

    The source HTML element removing steps, given removedNode + and oldParent, are:

    1. If removedNode's next sibling was an img element and @@ -29496,8 +29505,8 @@ interface HTMLImageElement : HTMLElement { page layout from shifting around after the image loads.

    -

    The img HTML element insertion - steps, given insertedNode, are:

    +

    The img HTML element insertion steps, given insertedNode, + are:

    1. If insertedNode's parent is a picture element, then, count this as @@ -29505,8 +29514,16 @@ interface HTMLImageElement : HTMLElement { insertedNode.

    -

    The img HTML element removing - steps, given removedNode and oldParent, are:

    +

    The img HTML element moving steps, given movedNode and + oldParent, are:

    + +
      +
    1. If oldParent is a picture element, then, count this as a + relevant mutation for movedNode.

    2. +
    + +

    The img HTML element removing steps, given movedNode and + oldParent, are:

    1. If oldParent is a picture element, then, count this as a @@ -31007,9 +31024,9 @@ was an English <a href="/wiki/Music_hall">music hall</a> singer, ...

      The element's referrerpolicy attribute's state is changed.

    2. -
    3. The img or source HTML element insertion steps or - HTML element removing steps count the mutation as a relevant mutation.

    4. +
    5. The img or source HTML element insertion steps, + HTML element removing steps, and HTML element moving steps count the + mutation as a relevant mutation.

    6. The element's parent is a picture element and a source element that is a previous sibling has its srcset, Date: Wed, 9 Oct 2024 10:13:06 +0100 Subject: [PATCH 10/24] Move enqueing to DOM spec, but include fallback --- source | 54 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/source b/source index e97677985e8..b70da66895c 100644 --- a/source +++ b/source @@ -1872,25 +1872,6 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute data-x="concept-element-local-name">local name, then run the corresponding HTML element moving steps given movedNode.

    7. -
    8. -

      If movedNode is a custom element, then:

      - -

        -
      1. If the element has an author-provided connectedMoveCallback, then - call it with no arguments.

      2. - -
      3. -

        Otherwise:

        -
          -
        1. Call movedNode's disconnectedCallback, with no - arguments.

        2. -
        3. Call movedNode's connectedCallback, with no - arguments.

        4. -
        -
      4. -
      -
    9. -
    10. If movedNode is a form-associated element or the ancestor of a form-associated element, then:

      @@ -72684,6 +72665,7 @@ document.body.append(parent); data-x="concept-custom-element-definition-lifecycle-callbacks">lifecycle callbacks
      A map, whose keys are the strings "connectedCallback", "disconnectedCallback", "adoptedCallback", + "connectedMoveCallback", "attributeChangedCallback", "formAssociatedCallback", "formDisabledCallback", @@ -73360,7 +73342,10 @@ customElements.define("x-foo", class extends HTMLElement {
    11. When it becomes disconnected, its disconnectedCallback is called, with no arguments.

    12. -
    13. When it is adopted into a new document, its

      When it is moved, its connectedMoveCallback is called, with no arguments.

    14. + +
    15. When it is adopted into a new document, its adoptedCallback is called, given the old document and new document as arguments.

    16. @@ -73502,6 +73487,35 @@ customElements.define("x-foo", class extends HTMLElement { data-x="concept-custom-element-definition-lifecycle-callbacks">lifecycle callbacks with key callbackName.

    17. +
    18. +

      If callbackName is "connectedMoveCallback" and + callback is null, then: + +

        +
      1. Let disconnectedCallback be the value of the entry in definition's + lifecycle callbacks + with key "disconnectedCallback".

      2. + +
      3. Let connectedCallback be the value of the entry in definition's + lifecycle callbacks + with key "connectedCallback".

      4. + +
      5. If connectedCallback and disconnectedCallback are null, then + return.

      6. + +
      7. +

        Set callback to the following steps:

        +
          +
        1. If disconnectedCallback is not null, then call + disconnectedCallback with no arguments.

        2. + +
        3. If connectedCallback is not null, then call + connectedCallback with no arguments.

        4. +
        +
      8. +
      +
    19. +
    20. If callback is null, then return.

    21. From 0912c4228622ee818f3c3a8acbc88fa4ea893e93 Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Wed, 9 Oct 2024 10:28:25 -0400 Subject: [PATCH 11/24] Listed form element owner reset --- source | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source b/source index b70da66895c..bd7f87ee6e6 100644 --- a/source +++ b/source @@ -56422,8 +56422,8 @@ interface HTMLLegendElement : HTMLElement { form attribute and an element with an ID is inserted into or removed from the - Document, then the user agent must reset the form owner of that - form-associated element.

      + Document, or its HTML element moving steps are run, then the user agent + must reset the form owner of that form-associated element.

      The form owner is also reset by the HTML Standard's insertion steps and Date: Wed, 9 Oct 2024 10:31:31 -0400 Subject: [PATCH 12/24] Form owner reset note --- source | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source b/source index bd7f87ee6e6..9b14d7b186d 100644 --- a/source +++ b/source @@ -56425,9 +56425,8 @@ interface HTMLLegendElement : HTMLElement { Document, or its HTML element moving steps are run, then the user agent must reset the form owner of that form-associated element.

      -

      The form owner is also reset by the HTML Standard's insertion steps and removing steps.

      +

      The form owner is also reset by the HTML element insertion steps, + HTML element removing steps, and HTML element moving steps.

      To reset the form owner of a form-associated element element:

      From 7270c092c6f602c0f00a8ddc21d09a152094225f Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Thu, 10 Oct 2024 10:02:01 -0400 Subject: [PATCH 13/24] Remove Document flag --- source | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/source b/source index 9b14d7b186d..7a24a19fe4d 100644 --- a/source +++ b/source @@ -10958,20 +10958,6 @@ partial interface Document { set of not restored reason details, initially empty.

      -

      Each Document has a state-preserving atomic move in progress boolean, which is initially - false.

      - -

      This is set by moveBefore() when a - Document is performing a state-preserving atomic move; it is used to exempt certain - insertion steps and removing steps (and their kin), from running, if they - would ordinarily reset state that needs to be preserved.

      - -

      TODO(domfarolino): Before merging, probably remove this flag since we're going with - the HTML element moving steps infrastructure instead.

      -

      The DocumentOrShadowRoot interface

      DOM defines the local name, then run the corresponding HTML element moving steps given movedNode.

    22. +
    23. If movedNode is a shadow-including inclusive ancestor of + movedNode's node document's + focused area's DOM anchor, then + set movedNode's node document should reapply focusing steps + to true.

    24. +
    25. If movedNode is a form-associated element or the ancestor of a form-associated element, then:

      @@ -79926,6 +79932,9 @@ dictionary ToggleEventInit : EventInit { anchor of a focusable area of the currently focused area of a top-level traversable, it is focused.

      +

      Each Document has a boolean should reapply focusing steps, initially + false. +

      The focus chain of a focusable area subject is the ordered @@ -80508,6 +80517,20 @@ dictionary ToggleEventInit : EventInit { navigable's active document.

    26. +
    27. +

      If new focus target is a focusable area whose + DOM anchor's node document's + should reapply focusing steps is true, then set new focus target's + DOM anchor's node document's + focused area to + DOM anchor's node document's viewport and set + DOM anchor's node document's + should reapply focusing steps to false.

      + +

      This ensures that focus events are fired when an + element is moved in the DOM. +

    28. +
    29. If new focus target is a focusable area and its DOM anchor is inert, then return.

    30. From 114946e81481cafdf24033ef0d0c8d93c769158e Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Mon, 4 Nov 2024 13:08:03 +0000 Subject: [PATCH 15/24] Revert "Reset focus when refocusing document with a moved element" This reverts commit f6e9fbeb08c1553bcf3c553f8057c5ba518884f0. --- source | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/source b/source index ae1ad157807..7a24a19fe4d 100644 --- a/source +++ b/source @@ -1872,12 +1872,6 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute data-x="concept-element-local-name">local name, then run the corresponding HTML element moving steps given movedNode.

      -
    31. If movedNode is a shadow-including inclusive ancestor of - movedNode's node document's - focused area's DOM anchor, then - set movedNode's node document should reapply focusing steps - to true.

    32. -
    33. If movedNode is a form-associated element or the ancestor of a form-associated element, then:

      @@ -79932,9 +79926,6 @@ dictionary ToggleEventInit : EventInit { anchor of a focusable area of the currently focused area of a top-level traversable, it is focused.

      -

      Each Document has a boolean should reapply focusing steps, initially - false. -

      The focus chain of a focusable area subject is the ordered @@ -80517,20 +80508,6 @@ dictionary ToggleEventInit : EventInit { navigable's active document.

    34. -
    35. -

      If new focus target is a focusable area whose - DOM anchor's node document's - should reapply focusing steps is true, then set new focus target's - DOM anchor's node document's - focused area to - DOM anchor's node document's viewport and set - DOM anchor's node document's - should reapply focusing steps to false.

      - -

      This ensures that focus events are fired when an - element is moved in the DOM. -

    36. -
    37. If new focus target is a focusable area and its DOM anchor is inert, then return.

    38. From 0aec3af6f97cc42286d3fb4d875eda6e7b687c47 Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Thu, 28 Nov 2024 11:12:12 -0500 Subject: [PATCH 16/24] Remove legacy parser-inserted check, and add form owner reset conditions from removing steps --- source | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source b/source index 7a24a19fe4d..1db6ba08752 100644 --- a/source +++ b/source @@ -1877,10 +1877,10 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute form-associated element, then:

        -
      1. If the form-associated element's parser inserted flag is set, - then return.

      2. - -
      3. Reset the form owner of the form-associated element.

      4. +
      5. If the form-associated element has a form owner and the + form-associated element and its form owner are no longer in the same + tree, then reset the form owner of the form-associated + element.

    From 6c6e281840581288b7257d4aeb0a163321c86ce7 Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Thu, 28 Nov 2024 11:27:23 -0500 Subject: [PATCH 17/24] Other annevk comments --- source | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source b/source index 1db6ba08752..5ee7c26b471 100644 --- a/source +++ b/source @@ -29489,7 +29489,7 @@ interface HTMLImageElement : HTMLElement { relevant mutation for movedNode.

  • -

    The img HTML element removing steps, given movedNode and +

    The img HTML element removing steps, given removedNode and oldParent, are:

      @@ -73330,7 +73330,7 @@ customElements.define("x-foo", class extends HTMLElement {
    1. When it is moved, its connectedMoveCallback is called, with no arguments.

    2. -
    3. When it is adopted into a new document, its

      When it is adopted into a new document, its adoptedCallback is called, given the old document and new document as arguments.

    4. @@ -73474,7 +73474,7 @@ customElements.define("x-foo", class extends HTMLElement {
    5. If callbackName is "connectedMoveCallback" and - callback is null, then: + callback is null:

      1. Let disconnectedCallback be the value of the entry in definition's From 27ff5522aac7444edb5d58acbadaa263599ce98d Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Thu, 28 Nov 2024 12:05:10 -0500 Subject: [PATCH 18/24] More nits --- source | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source b/source index 5ee7c26b471..7ad4ce2b479 100644 --- a/source +++ b/source @@ -73504,7 +73504,7 @@ customElements.define("x-foo", class extends HTMLElement {

      2. If callback is null, then return.

      3. -

        If callbackName is "attributeChangedCallback", then:

        +

        If callbackName is "attributeChangedCallback":

        1. Let attributeName be the first element of args.

        2. From 2cc804bc0534a1080ce097f581a9d193556a44d1 Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Tue, 3 Dec 2024 10:30:10 +0000 Subject: [PATCH 19/24] Add hook and example for connectedMoveCallback --- source | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/source b/source index 7ad4ce2b479..c6f54f4c475 100644 --- a/source +++ b/source @@ -72129,7 +72129,8 @@ console.log(plasticButton.outerHTML); // will output '<button is="plastic-but responsibility of conveying button semantics (including the ability to be disabled) might look something like this:

          -
          class TacoButton extends HTMLElement {
          +  
          class TacoButton extends HTMLElement {
             static observedAttributes = ["disabled"];
           
             constructor() {
          @@ -72442,6 +72443,73 @@ document.body.append(parent);
           // CChild connectedCallback: isConnected = false
          +
          Preserving custom element state when moved
          + + + +

          When manipulating the DOM tree, an element can be moved in the tree while connected. This applies to custom + elements as well. By default, the "disconnectedCallback" and "connectedCallback" would be called on the element, one after the other. This is + done to maintain compatibility with existing custom elements that predate the moveBefore method. This means that by default, custom elements + reset their state as if they were removed and re-inserted. In the example above, the impact would be that the + observer would be disconnected and re-connected, and the tab index would be reset.

          + +

          To opt in to a state-preserving behavior while moveing, the author can implement a "connectedMoveCallback". The existence of this callback, even if empty, would + supercede the default behavior of calling "disconnectedCallback" and "connectedCallback". "connectedMoveCallback" can also be + an appropriate place to execute logic that depends on the element's ancestors. For example:

          + +
          class TacoButton extends HTMLElement {
          +    static observedAttributes = ["disabled"];
          +
          +    constructor() {
          +      super();
          +      this._internals = this.attachInternals();
          +      this._internals.role = "button";
          +
          +      this._observer = new MutationObserver(() => {
          +        this._internals.ariaLabel = this.textContent;
          +      });
          +    }
          +
          +    _notifyMain() {
          +      if (this.parentElement.tagName === "MAIN") {
          +        // Execute logic that depends on ancestors.
          +      }
          +    }
          +
          +    connectedCallback() {
          +      this.setAttribute("tabindex", "0");
          +
          +      this._observer.observe(this, {
          +        childList: true,
          +        characterData: true,
          +        subtree: true
          +      });
          +
          +      this._notifyMain();
          +    }
          +
          +    disconnectedCallback() {
          +      this._observer.disconnect();
          +    }
          +
          +  // Implementing this function would avoid resetting the tab index or re-registering the
          +  // mutation observer when this element is moved inside the DOM without being disconnected.
          +    connectedMoveCallback() {
          +      // The parent can change during a state-preserving move.
          +      this._notifyMain();
          +    }
          +  }
          + + + +

          Core concepts

          A custom element is an element that is ElementDefinitionOptions {

        3. Let lifecycleCallbacks be the ordered map «[ "connectedCallback" → null, "disconnectedCallback" → - null, "adoptedCallback" → null, "attributeChangedCallback" → null ]».

          + null, "connectedMoveCallback" → null, "adoptedCallback" → null, "attributeChangedCallback" → + null ]».

        4. For each callbackName of the keys of From 9ee16730d46344d4805b81177ce72bf1b813b897 Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Tue, 3 Dec 2024 10:38:29 +0000 Subject: [PATCH 20/24] Remove newlines --- source | 3 --- 1 file changed, 3 deletions(-) diff --git a/source b/source index c6f54f4c475..15bdfad1375 100644 --- a/source +++ b/source @@ -72507,9 +72507,6 @@ document.body.append(parent); } }

        5. - - -

          Core concepts

          A custom element is an element that is Date: Tue, 17 Dec 2024 11:20:41 -0500 Subject: [PATCH 21/24] Formatting and wrapping --- source | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source b/source index 15bdfad1375..128eb64954a 100644 --- a/source +++ b/source @@ -73556,12 +73556,13 @@ customElements.define("x-foo", class extends HTMLElement {

        6. Set callback to the following steps:

          +
          1. If disconnectedCallback is not null, then call disconnectedCallback with no arguments.

          2. -
          3. If connectedCallback is not null, then call - connectedCallback with no arguments.

          4. +
          5. If connectedCallback is not null, then call connectedCallback + with no arguments.

        From ded78da47acd8de2f64d16b29ececa13a27a46ae Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Tue, 17 Dec 2024 11:47:35 -0500 Subject: [PATCH 22/24] Correct a few links and formatting things --- source | 66 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/source b/source index 128eb64954a..fdc69a531cc 100644 --- a/source +++ b/source @@ -3248,7 +3248,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
      4. append() method
      5. appendChild() method
      6. cloneNode() method
      7. -
      8. moveBefore() method
      9. +
      10. moveBefore() method
      11. importNode() method
      12. preventDefault() method
      13. id attribute
      14. @@ -72452,60 +72452,60 @@ document.body.append(parent); elements as well. By default, the "disconnectedCallback" and "connectedCallback" would be called on the element, one after the other. This is done to maintain compatibility with existing custom elements that predate the moveBefore method. This means that by default, custom elements + data-x="dom-ParentNode-moveBefore">moveBefore()
        method. This means that by default, custom elements reset their state as if they were removed and re-inserted. In the example above, the impact would be that the observer would be disconnected and re-connected, and the tab index would be reset.

        To opt in to a state-preserving behavior while moveing, the author can implement a "moving, the author can implement a "connectedMoveCallback". The existence of this callback, even if empty, would supercede the default behavior of calling "disconnectedCallback" and "connectedCallback". "connectedMoveCallback" can also be an appropriate place to execute logic that depends on the element's ancestors. For example:

        class TacoButton extends HTMLElement {
        -    static observedAttributes = ["disabled"];
        +  static observedAttributes = ["disabled"];
         
        -    constructor() {
        -      super();
        -      this._internals = this.attachInternals();
        -      this._internals.role = "button";
        +  constructor() {
        +    super();
        +    this._internals = this.attachInternals();
        +    this._internals.role = "button";
         
        -      this._observer = new MutationObserver(() => {
        -        this._internals.ariaLabel = this.textContent;
        -      });
        -    }
        +    this._observer = new MutationObserver(() => {
        +      this._internals.ariaLabel = this.textContent;
        +    });
        +  }
         
        -    _notifyMain() {
        -      if (this.parentElement.tagName === "MAIN") {
        -        // Execute logic that depends on ancestors.
        -      }
        +  _notifyMain() {
        +    if (this.parentElement.tagName === "MAIN") {
        +      // Execute logic that depends on ancestors.
             }
        +  }
         
        -    connectedCallback() {
        -      this.setAttribute("tabindex", "0");
        +  connectedCallback() {
        +    this.setAttribute("tabindex", "0");
         
        -      this._observer.observe(this, {
        -        childList: true,
        -        characterData: true,
        -        subtree: true
        -      });
        +    this._observer.observe(this, {
        +      childList: true,
        +      characterData: true,
        +      subtree: true
        +    });
         
        -      this._notifyMain();
        -    }
        +    this._notifyMain();
        +  }
         
        -    disconnectedCallback() {
        -      this._observer.disconnect();
        -    }
        +  disconnectedCallback() {
        +    this._observer.disconnect();
        +  }
         
           // Implementing this function would avoid resetting the tab index or re-registering the
           // mutation observer when this element is moved inside the DOM without being disconnected.
        -    connectedMoveCallback() {
        -      // The parent can change during a state-preserving move.
        -      this._notifyMain();
        -    }
        -  }
        + connectedMoveCallback() { + // The parent can change during a state-preserving move. + this._notifyMain(); + } +}

        Core concepts

        From 261d8f6024338926b3612f2ae36fe1ee727572fd Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Fri, 20 Dec 2024 17:15:56 -0500 Subject: [PATCH 23/24] Change callback ordering --- source | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source b/source index fdc69a531cc..fd958976466 100644 --- a/source +++ b/source @@ -72944,9 +72944,9 @@ dictionary ElementDefinitionOptions {
      15. Let lifecycleCallbacks be the ordered map «[ "connectedCallback" → null, "disconnectedCallback" → - null, "connectedMoveCallback" → null, "adoptedCallback" → null, "attributeChangedCallback" → - null ]».

        + null, "adoptedCallback" → null, "connectedMoveCallback" → null, "attributeChangedCallback" → null ]».

      16. For each callbackName of the keys of From 622dd40605cfc8db3f76951b946bddfb4253dde8 Mon Sep 17 00:00:00 2001 From: Dominic Farolino Date: Fri, 20 Dec 2024 17:22:35 -0500 Subject: [PATCH 24/24] Wrapping and formatting nits --- source | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/source b/source index fd958976466..e4218a49149 100644 --- a/source +++ b/source @@ -29485,8 +29485,8 @@ interface HTMLImageElement : HTMLElement { oldParent, are:

          -
        1. If oldParent is a picture element, then, count this as a - relevant mutation for movedNode.

        2. +
        3. If oldParent is a picture element, then, count this as a relevant mutation for movedNode.

        The img HTML element removing steps, given removedNode and @@ -36605,9 +36605,7 @@ interface MediaError { pointer must be updated as follows:

        -
        If a new node is inserted or moved between the two nodes that define - pointer
        +
        If a new node is inserted or moved between the two nodes that define pointer
        Let pointer be the point between the node before pointer and the new node. In other words, insertions at pointer go after pointer.
        @@ -72452,8 +72450,8 @@ document.body.append(parent); elements as well. By default, the "disconnectedCallback" and "connectedCallback" would be called on the element, one after the other. This is done to maintain compatibility with existing custom elements that predate the moveBefore() method. This means that by default, custom elements - reset their state as if they were removed and re-inserted. In the example moveBefore()
        method. This means that by default, custom + elements reset their state as if they were removed and re-inserted. In the example above, the impact would be that the observer would be disconnected and re-connected, and the tab index would be reset.

        @@ -72461,10 +72459,10 @@ document.body.append(parent); data-x="concept-node-move-ext">moving, the author can implement a "connectedMoveCallback". The existence of this callback, even if empty, would supercede the default behavior of calling "disconnectedCallback" and "connectedCallback". "connectedMoveCallback" can also be - an appropriate place to execute logic that depends on the element's ancestors. For example:

        + data-x="">connectedCallback
        ". "connectedMoveCallback" can also be an + appropriate place to execute logic that depends on the element's ancestors. For example:

        -
        class TacoButton extends HTMLElement {
        +  
        class TacoButton extends HTMLElement {
           static observedAttributes = ["disabled"];
         
           constructor() {
        @@ -72714,8 +72712,8 @@ document.body.append(parent);
            
        A collection of lifecycle callbacks
        A map, whose keys are the strings "connectedCallback", - "disconnectedCallback", "adoptedCallback", - "connectedMoveCallback", + "disconnectedCallback", "adoptedCallback", "connectedMoveCallback", "attributeChangedCallback", "formAssociatedCallback", "formDisabledCallback",