From 3821c8a7e22690933c99488e5c31177638269000 Mon Sep 17 00:00:00 2001 From: Joey Arhar Date: Wed, 2 Apr 2025 13:55:41 -0700 Subject: [PATCH 1/7] Add ToggleEvent.invoker This adds a new Element attribute to ToggleEvent called invoker. The ToggleEvent's invoker attribute is set to the element which invoked the element which the ToggleEvent is being fired on. Invokers can be set up as a parameter passed to element.showPopover(), an element with the popovertarget attribute, or an element with the commandfor attribute. Fixes https://github.com/whatwg/html/issues/9111 --- source | 97 +++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 69 insertions(+), 28 deletions(-) diff --git a/source b/source index 48daf9ac1af..6d098543a4f 100644 --- a/source +++ b/source @@ -60380,7 +60380,8 @@ fur
  • Otherwise, if submitter has a value, then set result to that value.

  • -
  • Close the dialog subject with result.

  • +
  • Close the dialog subject with result and + null.

  • Return.

  • @@ -62294,7 +62295,7 @@ interface HTMLDialogElement : HTMLElement {

    The showModal() method steps are to show a modal - dialog given this.

    + dialog given this and null.

    The close(returnValue) method steps are: @@ -62302,7 +62303,8 @@ interface HTMLDialogElement : HTMLElement {

    1. If returnValue is not given, then set it to null.

    2. -
    3. Close the dialog this with returnValue.

    4. +
    5. Close the dialog this with returnValue and + null.

    The HTMLDialogElement : HTMLElement { removedNode's node document's open dialogs list.

    -

    To show a modal dialog given a dialog element subject:

    +

    To show a modal dialog given a dialog element subject and an + Element or null invoker:

    1. If subject has an open attribute and @@ -62465,9 +62468,10 @@ interface HTMLDialogElement : HTMLElement { data-x="event-beforetoggle">beforetoggle, using ToggleEvent, with the cancelable attribute initialized to true, the oldState attribute initialized to "closed", and the newState - attribute initialized to "open" at subject is false, then - return.

    2. + data-x="">closed", the newState + attribute initialized to "open", and the invoker attribute set to invoker at + subject is false, then return.

    3. If subject has an open attribute, then return.

    4. @@ -62478,7 +62482,7 @@ interface HTMLDialogElement : HTMLElement { state, then return.

    5. Queue a dialog toggle event task given subject, "closed", and "open".

    6. + data-x="">closed", "open", and invoker.

    7. Add an open attribute to subject, whose value is the empty string.

    8. @@ -62590,14 +62594,15 @@ interface HTMLDialogElement : HTMLElement {
    9. Let value be invoker's value.

    10. -
    11. Close the dialog element with value.

    12. +
    13. Close the dialog element with value and + invoker.

  • If command is the Show Modal state and element does not have an open attribute, then - show a modal dialog given element.

  • + show a modal dialog given element and invoker.

    @@ -62624,7 +62629,8 @@ interface HTMLDialogElement : HTMLElement {

    When a dialog element subject is to be closed, with null or a string result, run these steps:

    + dialog">closed, with null or a string result and an Element or null + invoker, run these steps:

    1. If subject does not have an open @@ -62633,14 +62639,16 @@ interface HTMLDialogElement : HTMLElement {

    2. Fire an event named beforetoggle, using ToggleEvent, with the oldState attribute initialized to "open" and the newState attribute - initialized to "closed" at subject.

    3. + data-x="">open", the newState attribute + initialized to "closed", and the invoker attribute set to invoker at + subject.

    4. If subject does not have an open attribute, then return.

    5. Queue a dialog toggle event task given subject, "open", and "closed".

    6. + data-x="">open", "closed", and invoker.

    7. Remove subject's open attribute.

    8. @@ -62699,7 +62707,8 @@ interface HTMLDialogElement : HTMLElement {

      To queue a dialog toggle event task given a dialog element - element, a string oldState, and a string newState: + element, a string oldState, a string newState, and an + Element or null invoker:

      1. @@ -62724,8 +62733,10 @@ interface HTMLDialogElement : HTMLElement {
      2. Fire an event named toggle at element, using ToggleEvent, with the oldState attribute initialized to - oldState and the newState attribute - initialized to newState.

      3. + oldState, the newState attribute + initialized to newState, and the invoker attribute initialized to + invoker.

      4. Set element's dialog toggle task tracker to null.

      @@ -80513,6 +80524,7 @@ interface ToggleEvent : Event { constructor(DOMString type, optional ToggleEventInit eventInitDict = {}); readonly attribute DOMString oldState; readonly attribute DOMString newState; + readonly attribute Element invoker; }; dictionary ToggleEventInit : EventInit { @@ -80536,6 +80548,16 @@ dictionary ToggleEventInit : EventInit {

      Set to "open" when transitioning from closed to open, or set to "closed" when transitioning from open to closed.

      + +
      event.invoker
      + +
      +

      Set to the element which initiated the toggle, which can be set up with the popovertarget and commandfor attributes. If there is no invoker element, + then it is set to null.

      +

      The ToggleEventInit : EventInit { data-x="dom-ToggleEvent-newState">newState attributes must return the values they are initialized to.

      +

      The invoker getter steps are to return the result of + retargeting invoker against this's currentTarget.

      + +

      DOM standard issue #1328 + tracks how to better standardize associated event data in a way which makes sense on Events. + Currently an event attribute initialized to a value cannot also have a getter, and so an internal + slot (or map of additional fields) is required to properly specify this.

      +

      A toggle task tracker is a struct which has:

      @@ -86750,9 +86783,10 @@ dictionary DragEventInit : MouseEventInit { data-x="event-beforetoggle">beforetoggle, using ToggleEvent, with the cancelable attribute initialized to true, the oldState attribute initialized to "closed", and the newState - attribute initialized to "open" at element is false, then - run cleanupShowingFlag and return.

      + data-x="">closed", the newState attribute + initialized to "open" at element, and the invoker attribute initialized to invoker is + false, then run cleanupShowingFlag and return.

    9. If the result of running check popover validity given element, false, @@ -86949,13 +86983,14 @@ dictionary DragEventInit : MouseEventInit { previously focused element to originallyFocusedElement.

    10. Queue a popover toggle event task given element, "closed", and "open".

    11. + data-x="">closed", "open", and invoker.

    12. Run cleanupShowingFlag.

    To queue a popover toggle event task given an element element, a string - oldState, and a string newState: + oldState, a string newState, and an Element or null + invoker:

    1. @@ -86980,8 +87015,10 @@ dictionary DragEventInit : MouseEventInit {
    2. Fire an event named toggle at element, using ToggleEvent, with the oldState attribute initialized to - oldState and the newState attribute - initialized to newState.

    3. + oldState, the newState attribute + initialized to newState, and the invoker attribute initialized to + invoker.

    4. Set element's popover toggle task tracker to null.

    @@ -87063,6 +87100,8 @@ dictionary DragEventInit : MouseEventInit { showing auto popover list's last item is element, otherwise false.

    +
  • Let invoker be element's popover invoker.

  • +
  • Set element's popover invoker to null.

  • @@ -87072,8 +87111,10 @@ dictionary DragEventInit : MouseEventInit {
  • Fire an event named beforetoggle, using ToggleEvent, with the oldState attribute initialized to "open" and the newState - attribute initialized to "closed" at element.

  • + data-x="">open", the newState + attribute initialized to "closed", and the invoker attribute set to invoker at + element.

  • If autoPopoverListContainsElement is true and document's showing auto popover list's last item is not element, then run DragEventInit : MouseEventInit { data-x="popover-hidden-state">hidden.

  • If fireEvents is true, then queue a popover toggle event task - given element, "open", and "closed".

  • + given element, "open", "closed", and + invoker.

  • Let previouslyFocusedElement be element's previously focused element.

  • From 2703548a6275e95eadf591754ffa3e5b53eaebbd Mon Sep 17 00:00:00 2001 From: Joey Arhar Date: Thu, 3 Apr 2025 08:57:55 -0700 Subject: [PATCH 2/7] rename invoker to source --- source | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source b/source index 6d098543a4f..c40c4be50f6 100644 --- a/source +++ b/source @@ -62470,7 +62470,7 @@ interface HTMLDialogElement : HTMLElement { data-x="dom-ToggleEvent-oldState">oldState attribute initialized to "closed", the newState attribute initialized to "open", and the invoker attribute set to invoker at + data-x="dom-ToggleEvent-source">source attribute set to invoker at subject is false, then return.

  • If subject has an open attribute, @@ -62641,7 +62641,7 @@ interface HTMLDialogElement : HTMLElement { data-x="dom-ToggleEvent-oldState">oldState attribute initialized to "open", the newState attribute initialized to "closed", and the invoker attribute set to invoker at + data-x="dom-ToggleEvent-source">source attribute set to invoker at subject.

  • If subject does not have an open @@ -62735,7 +62735,7 @@ interface HTMLDialogElement : HTMLElement { the oldState attribute initialized to oldState, the newState attribute initialized to newState, and the invoker attribute initialized to + data-x="dom-ToggleEvent-source">source attribute initialized to invoker.

  • Set element's dialog toggle task tracker to null.

  • @@ -80524,7 +80524,7 @@ interface ToggleEvent : Event { constructor(DOMString type, optional ToggleEventInit eventInitDict = {}); readonly attribute DOMString oldState; readonly attribute DOMString newState; - readonly attribute Element invoker; + readonly attribute Element source; }; dictionary ToggleEventInit : EventInit { @@ -80550,12 +80550,12 @@ dictionary ToggleEventInit : EventInit {
    event.invoker
    + data-x="dom-ToggleEvent-source">source

    Set to the element which initiated the toggle, which can be set up with the popovertarget and commandfor attributes. If there is no invoker element, + data-x="attr-button-commandfor">commandfor attributes. If there is no source element, then it is set to null.

    @@ -80566,9 +80566,9 @@ dictionary ToggleEventInit : EventInit { initialized to.

    The invoker getter steps are to return the result of + data-x="dom-ToggleEvent-source">source getter steps are to return the result of retargeting invoker against this's source against this's currentTarget.

    DOM standard issue #1328 @@ -86785,7 +86785,7 @@ dictionary DragEventInit : MouseEventInit { data-x="dom-ToggleEvent-oldState">oldState attribute initialized to "closed", the newState attribute initialized to "open" at element, and the invoker attribute initialized to invoker is + data-x="dom-ToggleEvent-source">source attribute initialized to invoker is false, then run cleanupShowingFlag and return.

  • @@ -87017,7 +87017,7 @@ dictionary DragEventInit : MouseEventInit { the oldState attribute initialized to oldState, the newState attribute initialized to newState, and the invoker attribute initialized to + data-x="dom-ToggleEvent-source">source attribute initialized to invoker.

  • Set element's popover toggle task tracker to null.

  • @@ -87113,7 +87113,7 @@ dictionary DragEventInit : MouseEventInit { data-x="dom-ToggleEvent-oldState">oldState attribute initialized to "open", the newState attribute initialized to "closed", and the invoker attribute set to invoker at + data-x="dom-ToggleEvent-source">source attribute set to invoker at element.

  • If autoPopoverListContainsElement is true and document's From b3331a6cd1f1714e05c7366f7a8835bc1b923e29 Mon Sep 17 00:00:00 2001 From: Joey Arhar Date: Tue, 22 Apr 2025 15:59:22 -0700 Subject: [PATCH 3/7] Add invoker parameter to hide popover algorithm --- source | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/source b/source index 2038ccdb9e3..ed871b64074 100644 --- a/source +++ b/source @@ -1851,7 +1851,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute

  • If removedNode's popover attribute is not in the no popover state, then run the hide - popover algorithm given removedNode, false, false, and false.

  • + popover algorithm given removedNode, false, false, false, and null.

    The moving steps for the HTML Standard, given @@ -53745,7 +53745,8 @@ interface HTMLButtonElement : HTMLElement {

    1. If the result of running check popover validity given target, true, false, and null is true, then run the - hide popover algorithm given target, true, true, and false.

    2. + hide popover algorithm given target, true, true, false, and + element.

    @@ -53762,7 +53763,7 @@ interface HTMLButtonElement : HTMLElement {
  • Otheriwse, if the result of running check popover validity given target, true, false, and null is true, then run the hide popover algorithm given target, true, - true, and false.

  • + true, false, and element.

    @@ -86778,7 +86779,7 @@ dictionary DragEventInit : MouseEventInit {
  • If element's popover visibility state is in the showing state and oldValue and value are in different states, then run the hide popover - algorithm given element, true, true, and false.

  • + algorithm given element, true, true, false, and null.

    @@ -87020,7 +87021,7 @@ dictionary DragEventInit : MouseEventInit {
  • closeAction being to hide a popover given element, true, true, - and false.

  • + false, and null.

  • getEnabledState being to return true.

  • @@ -87103,13 +87104,14 @@ dictionary DragEventInit : MouseEventInit { method steps are:

      -
    1. Run the hide popover algorithm given this, true, true, and - true.

    2. +
    3. Run the hide popover algorithm given this, true, true, true, and + null.

    To hide a popover given an HTML element element, a boolean focusPreviousElement, a - boolean fireEvents, and a boolean throwExceptions:

    + boolean fireEvents, a boolean throwExceptions, and an HTML element or null invoker:

    1. If the result of running check popover validity given element, @@ -87169,8 +87171,6 @@ dictionary DragEventInit : MouseEventInit { showing auto popover list's last item is element, otherwise false.

    2. -
    3. Let invoker be element's popover invoker.

    4. -
    5. Set element's popover invoker to null.

    6. @@ -87258,7 +87258,8 @@ dictionary DragEventInit : MouseEventInit {
    7. If this's popover visibility state is showing, and force is null or false, then run - the hide popover algorithm given this, true, true, and true.

    8. + the hide popover algorithm given this, true, true, true, and + null.

    9. Otherwise, if force is null or true, then run show popover given this, true, and invoker.

    10. @@ -87375,8 +87376,8 @@ dictionary DragEventInit : MouseEventInit {
    11. Assert: popoverList is not empty.

    12. Run the hide popover algorithm given the last item in - popoverList, focusPreviousElement, fireEvents, and - false.

    13. + popoverList, focusPreviousElement, fireEvents, false, and + null.

    @@ -87749,7 +87750,7 @@ dictionary DragEventInit : MouseEventInit {
    1. Run the hide popover algorithm given popoverList's last item, - focusPreviousElement, fireEvents, and false.

    2. + focusPreviousElement, fireEvents, false, and null.

    @@ -87875,7 +87876,7 @@ dictionary DragEventInit : MouseEventInit {
  • If popover's popover visibility state is showing, then run the hide popover algorithm - given popover, true, true, and false.

  • + given popover, true, true, false, and node.

  • Otherwise, if popover's popover visibility state is hidden and the result of running check popover From f88886b4eeb05943117bffc9220bd9f14f40935b Mon Sep 17 00:00:00 2001 From: Joey Arhar Date: Thu, 29 May 2025 10:38:53 -0700 Subject: [PATCH 4/7] address comments --- source | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source b/source index 8cb3d8e56dc..88a231aef2c 100644 --- a/source +++ b/source @@ -1850,7 +1850,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute

  • If removedNode's popover attribute is not in - the No popover state, then run the hide + the No Popover State, then run the hide popover algorithm given removedNode, false, false, false, and null.

  • @@ -62502,7 +62502,7 @@ interface HTMLDialogElement : HTMLElement { data-x="dom-ToggleEvent-oldState">oldState attribute initialized to "closed", the newState attribute initialized to "open", and the source attribute set to invoker at + data-x="dom-ToggleEvent-source">source attribute initialized to invoker at subject is false, then return.

  • If subject has an open attribute, @@ -62672,7 +62672,7 @@ interface HTMLDialogElement : HTMLElement { data-x="dom-ToggleEvent-oldState">oldState attribute initialized to "open", the newState attribute initialized to "closed", and the source attribute set to invoker at + data-x="dom-ToggleEvent-source">source attribute initialized to invoker at subject.

  • If subject does not have an open @@ -62768,7 +62768,7 @@ interface HTMLDialogElement : HTMLElement {

    To queue a dialog toggle event task given a dialog element element, a string oldState, a string newState, and an - Element or null invoker: + Element or null source:

    1. @@ -62796,7 +62796,7 @@ interface HTMLDialogElement : HTMLElement { oldState, the newState attribute initialized to newState, and the source attribute initialized to - invoker.

    2. + source.

    3. Set element's dialog toggle task tracker to null.

    @@ -86971,7 +86971,7 @@ dictionary DragEventInit : MouseEventInit {

    To queue a popover toggle event task given an element element, a string oldState, a string newState, and an Element or null - invoker: + source:

    1. @@ -86999,7 +86999,7 @@ dictionary DragEventInit : MouseEventInit { oldState, the newState attribute initialized to newState, and the source attribute initialized to - invoker.

    2. + source.

    3. Set element's popover toggle task tracker to null.

    From 88438af9f050aac7a228618f7994a699a21d1844 Mon Sep 17 00:00:00 2001 From: Joey Arhar Date: Thu, 29 May 2025 14:15:15 -0700 Subject: [PATCH 5/7] fix missing parameters --- source | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source b/source index 88a231aef2c..b730b40377f 100644 --- a/source +++ b/source @@ -62297,7 +62297,7 @@ interface HTMLDialogElement : HTMLElement { return.

  • Queue a dialog toggle event task given this, "closed", and "open".

  • + data-x="">closed", "open", and null.

  • Add an open attribute to this, whose value is the empty string.

  • @@ -62355,7 +62355,7 @@ interface HTMLDialogElement : HTMLElement {
  • If returnValue is not given, then set it to null.

  • Request to close the dialog this - with returnValue.

  • + with returnValue and null.

    From 29afa58ff257fa1e7b9f8f5fe49bbb6132530f4f Mon Sep 17 00:00:00 2001 From: Joey Arhar Date: Fri, 30 May 2025 18:11:02 -0700 Subject: [PATCH 6/7] asdf --- source | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/source b/source index b730b40377f..ece0f5852f5 100644 --- a/source +++ b/source @@ -62477,7 +62477,7 @@ interface HTMLDialogElement : HTMLElement {

    To show a modal dialog given a dialog element subject and an - Element or null invoker:

    + Element or null source:

    1. If subject has an open attribute and @@ -62502,7 +62502,7 @@ interface HTMLDialogElement : HTMLElement { data-x="dom-ToggleEvent-oldState">oldState attribute initialized to "closed", the newState attribute initialized to "open", and the source attribute initialized to invoker at + data-x="dom-ToggleEvent-source">source attribute initialized to source at subject is false, then return.

    2. If subject has an open attribute, @@ -62514,7 +62514,7 @@ interface HTMLDialogElement : HTMLElement { state, then return.

    3. Queue a dialog toggle event task given subject, "closed", "open", and invoker.

    4. + data-x="">closed", "open", and source.

    5. Add an open attribute to subject, whose value is the empty string.

    6. @@ -62661,7 +62661,7 @@ interface HTMLDialogElement : HTMLElement {

      When a dialog element subject is to be closed, with null or a string result and an Element or null - invoker, run these steps:

      + source, run these steps:

      1. If subject does not have an open @@ -62672,14 +62672,14 @@ interface HTMLDialogElement : HTMLElement { data-x="dom-ToggleEvent-oldState">oldState attribute initialized to "open", the newState attribute initialized to "closed", and the source attribute initialized to invoker at + data-x="dom-ToggleEvent-source">source attribute initialized to source at subject.

      2. If subject does not have an open attribute, then return.

      3. Queue a dialog toggle event task given subject, "open", "closed", and invoker.

      4. + data-x="">open", "closed", and source.

      5. Remove subject's open attribute.

      6. @@ -62695,12 +62695,12 @@ interface HTMLDialogElement : HTMLElement {
      7. Remove subject from subject's node document's open dialogs list.

      8. -
      9. If result is not null, then set the

        If result is not null, then set subject's returnValue attribute to result.

      10. -
      11. Set the request close return value to null.

      12. +
      13. Set subject's request close return value to null.

      14. -
      15. Set the request close source element to null.

      16. +
      17. Set subject's request close source element to null.

      18. If subject's previously focused element is not null, then:

        @@ -62739,7 +62739,7 @@ interface HTMLDialogElement : HTMLElement {

        To request to close dialog element subject, given null or a string returnValue and null or an - Element invoker:

        + Element source:

        1. If subject does not have an open @@ -62755,7 +62755,7 @@ interface HTMLDialogElement : HTMLElement { returnValue.

        2. Set subject's request close source element to - invoker.

        3. + source.

        4. Request to close subject's close watcher with false.

        5. @@ -87022,7 +87022,7 @@ dictionary DragEventInit : MouseEventInit {

          To hide a popover given an HTML element element, a boolean focusPreviousElement, a boolean fireEvents, a boolean throwExceptions, and an HTML element or null invoker:

          + elements">HTML element or null source:

          1. If the result of running check popover validity given element, @@ -87090,7 +87090,7 @@ dictionary DragEventInit : MouseEventInit { data-x="dom-ToggleEvent-oldState">oldState attribute initialized to "open", the newState attribute initialized to "closed", and the source attribute set to invoker at + data-x="dom-ToggleEvent-source">source attribute set to source at element.

          2. If autoPopoverListContainsElement is true and document's @@ -87127,7 +87127,7 @@ dictionary DragEventInit : MouseEventInit {

          3. If fireEvents is true, then queue a popover toggle event task given element, "open", "closed", and - invoker.

          4. + source.

          5. Let previouslyFocusedElement be element's previously focused element.

          6. From c4045308089ce09f61c57a565a2439b2490343c5 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Mon, 2 Jun 2025 13:27:53 +0900 Subject: [PATCH 7/7] Final nits --- source | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source b/source index ece0f5852f5..f33586e7bb9 100644 --- a/source +++ b/source @@ -62430,10 +62430,10 @@ interface HTMLDialogElement : HTMLElement { which is a close watcher or null, initially null.

            Each dialog element has a request close return value, which is a - string, initially null.

            + string or null, initially null.

            Each dialog element has a request close source element, which is an - Element, initially null.

            + Element or null, initially null.

            Each dialog element has an enable close watcher for request close boolean,