diff --git a/source b/source index a92d86863c1..7c5444592cf 100644 --- a/source +++ b/source @@ -1864,6 +1864,14 @@ 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, false, and null.

  • + +
  • If removedNode is an HTML element with a + non-null active interest target, then reset interest state for + removedNode.

  • + +
  • If removedNode is an element with a non-null active interest + source, then reset interest state for removedNode's active + interest source.

  • @@ -1882,6 +1890,16 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute form owner and movedNode and its form owner are no longer in the same tree, then reset the form owner of movedNode.

    + +
  • If movedNode is an HTML element with a + non-null active interest target and movedNode and its active + interest target are no longer in the same tree, then reset interest + state for movedNode.

  • + +
  • If movedNode is an element with a non-null active interest source + and movedNode and its active interest source are no longer in the same + tree, then reset interest state for movedNode's active + interest source.

  • @@ -4073,6 +4091,8 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute devolved widget state.
  • The 'pointer-events' property
  • The 'user-select' property
  • +
  • The 'interest-delay-start' and + 'interest-delay-end' properties
  • The algorithm to HTMLDivElement : HTMLElement {

    hreflang
    type
    referrerpolicy
    +
    interestfor
    Accessibility considerations:
    If the element has an href attribute: HTMLAnchorElement : HTMLElement { // also has obsolete members }; -HTMLAnchorElement includes HTMLHyperlinkElementUtils; +HTMLAnchorElement includes HTMLHyperlinkElementUtils; +HTMLAnchorElement includes InterestForAttribute;
    Uses HTMLAnchorElement.
    @@ -43594,6 +43616,7 @@ interface HTMLMapElement : HTMLElement {
    ping
    rel
    referrerpolicy
    +
    interestfor
    Accessibility considerations:
    If the element has an href attribute: HTMLAreaElement : HTMLElement { // also has obsolete members }; -HTMLAreaElement includes HTMLHyperlinkElementUtils; +HTMLAreaElement includes HTMLHyperlinkElementUtils; +HTMLAreaElement includes InterestForAttribute;
    Uses HTMLAreaElement.
    @@ -55364,6 +55388,7 @@ You cannot submit this form when the field is incorrect.
    name
    popovertarget
    popovertargetaction
    +
    interestfor
    type
    value
    HTMLButtonElement : HTMLElement { readonly attribute NodeList labels; }; +HTMLButtonElement includes InterestForAttribute; HTMLButtonElement includes PopoverTargetAttributes;
    Uses HTMLButtonElement.
    @@ -79069,6 +79095,19 @@ Demos: +
    :interest-source
    +
    +

    The :interest-source pseudo-class + must match any HTML element whose active interest + target is non-null.

    +
    + +
    :interest-target
    +
    +

    The :interest-target pseudo-class + must match any element whose active interest source is non-null.

    +
    +
    :target
    @@ -85173,13 +85212,21 @@ dictionary CommandEventInit : EventInit { target be null.

  • -

    If blur event target is not null, fire a focus event - named blur at blur event target, with - related blur target as the related target.

    +

    If blur event target is not null:

    -

    In some cases, e.g., if entry is - an area element's shape, a scrollable region, or a viewport, no - event is fired.

    +
      +
    1. +

      Fire a focus event named blur at blur + event target, with related blur target as the related target.

      + +

      In some cases, e.g., if entry + is an area element's shape, a scrollable region, or a viewport, no + event is fired.

      +
    2. + +
    3. Handle interest change for blur event target and + false.

    4. +
  • @@ -85223,12 +85270,21 @@ dictionary CommandEventInit : EventInit { focus target be null.

  • -

    If focus event target is not null, fire a focus event - named focus at focus event target, with - related focus target as the related target.

    +

    If focus event target is not null:

    + +
      +
    1. +

      Fire a focus event named focus at + focus event target, with related focus target as the related + target.

      -

      In some cases, e.g. if entry is an area - element's shape, a scrollable region, or a viewport, no event is fired.

      +

      In some cases, e.g., if entry is an area + element's shape, a scrollable region, or a viewport, no event is fired.

      +
    2. + +
    3. Handle interest change for focus event target and + true.

    4. +
  • @@ -87509,6 +87565,24 @@ body { display:none } listener might have caused document to no longer be fully active.

    +
  • +

    For each element source in document's active interest sources + set, in reverse order:

    + +
      +
    1. Lose interest in source given source's active + interest target.

    2. + +
    3. +

      If document is not fully active, then return.

      + +

      This step is necessary because loseinterest event listeners might have caused + document to no longer be fully active.

      +
    4. +
    +
  • +
  • Let closedSomething be the result of processing close watchers on document's relevant global object.

  • @@ -90809,6 +90883,10 @@ dictionary DragEventInit : MouseEventInit {
  • Set element's popover close watcher to null.

  • + +
  • If element's active interest source is not null, then + lose interest in element's active interest source + with element.

  • @@ -91724,6 +91802,521 @@ dictionary DragEventInit : MouseEventInit {
    +

    The interestfor attribute

    + +

    The interestfor attribute allows authors to set up a + relationship between the triggering element and a separate target element such as a popover. + With this arrangement, when the user shows interest in the triggering element (e.g., by hovering + or focusing it), the target element will have an interest + event fired on it. If the target is a popover with a popover visibility state of + hidden, this will show the popover. When the user loses + interest (e.g., by no longer hovering or focusing the interest source or target) a loseinterest event is fired. If the target is a popover with a + popover visibility state of showing, it + will be hidden.

    + +

    If specified, the interestfor attribute value must be + the ID of an element in the same tree as the + element with the interestfor attribute.

    + + DOM interface: +
    interface mixin InterestForAttribute {
    +  [CEReactions, Reflect="interestfor"] attribute Element? interestForElement;
    +};
    + +
    +

    The following demonstrates how one might show a tooltip for a button using the + interestfor attribute to associate the button with + a popover representing the tooltip.

    + +
    <button interestfor=tooltip>
    + Hover or focus me to show the tooltip
    +</button>
    +
    +<div popover=hint id=tooltip>
    + I will appear when the user shows interest in the button
    +</div>
    +
    + +

    Every HTML element has an element-or-null active + interest target, initially null.

    + +

    Every Document has an active interest sources set, a set of + HTML elements, initially the empty set.

    + +

    The active interest sources set holds all of the HTML + elements in the document that have a non-null active interest target, in the + order that interest was gained.

    + +

    Every HTML element has a pending gain interest + handle and a pending lose interest handle, which are both a unique internal + value or null, initially null.

    + +

    These handles are used to abort steps that run after a timeout, effectively + canceling the tasks.

    + +

    Every element has an element-or-null active interest source, initially null.

    + +

    When non-null, an element's active interest target is a cached result + of getting the interestfor-associated element and the target's active interest + source points back to the source. This is a convenience that makes it easier to handle + tree modifications that break the association between source and target.

    + +

    The InterestEvent interface

    + +
    [Exposed=Window]
    +interface InterestEvent : Event {
    +  constructor(DOMString type, InterestEventInit eventInitDict);
    +  readonly attribute Element source;
    +};
    +
    +dictionary InterestEventInit : EventInit {
    +  required Element source;
    +};
    + +
    +
    event.source
    + +
    +

    Set to the element that triggered interest.

    +
    +
    + +

    The source attribute must return the value it was + initialized to.

    + +

    Processing model

    + +
    +

    To handle interest change for an element element and a boolean + show:

    + +
      +
    1. +

      If show is true:

      + +
        +
      1. +

        For each element upstream in element's recursive active + interest sources:

        + +
          +
        1. +

          Set upstream's pending lose interest handle to null.

          + +

          This effectively cancels any pending task to lose interest for + upstream. User interactions such as hovering or focusing an interest target or + its descendants prevent those tasks for running, so that interest isn't lost while the user + is interacting with the target.

          +
        2. +
        +
      2. +
      +
    2. + +
    3. If element is not an a, area, or button + element, then return.

    4. + +
    5. Let target be the result of running element's get the interestfor-associated + element.

    6. + +
    7. If target is null, then return.

    8. + +
    9. Let global be element's relevant global + object.

    10. + +
    11. Let delayProperty be 'interest-delay-start' if show is + true, otherwise 'interest-delay-end'.

    12. + +
    13. Let delay be the computed value of delayProperty on + element, interpreted as a number of milliseconds.

    14. + +
    15. If delay is negative, infinite, or NaN, then return.

    16. + +
    17. Let uniqueHandle be null.

    18. + +
    19. Let task be null.

    20. + +
    21. +

      If show is true, set task to a task that runs the following + substeps:

      + +
        +
      1. Assert: uniqueHandle is a unique internal value, + not null.

      2. + +
      3. If uniqueHandle is not element's pending gain interest + handle, then abort these steps.

      4. + +
      5. Set element's pending gain interest handle to null.

      6. + +
      7. If the interest ready check for element and target + returns false, then abort these steps.

      8. + +
      9. Gain interest in element with target.

      10. +
      +
    22. + +
    23. +

      Otherwise, set task to a task that runs the following + substeps:

      + +
        +
      1. Assert: uniqueHandle is a unique internal value, + not null.

      2. + +
      3. If uniqueHandle is not element's pending lose interest + handle, then abort these steps.

      4. + +
      5. Set element's pending lose interest handle to null.

      6. + +
      7. If the interest ready check for element and target + returns false, then abort these steps.

      8. + +
      9. Lose interest in element with target.

      10. +
      +
    24. + +
    25. Assert: task is a task.

    26. + +
    27. Let completionStep be an algorithm step which queues a global task on the timer task source given + global to run task.

    28. + +
    29. Set uniqueHandle to the result of running steps after a timeout given global, "interest change", timeout, and + completionStep.

    30. + +
    31. If show is true, set element's pending gain interest + handle to uniqueHandle.

    32. + +
    33. Otherwise, set element's pending lose interest handle to + uniqueHandle.

    34. +
    +
    + +
    +

    To find the recursive active interest sources given an element element, + perform the following steps. They return a list of zero or more elements.

    + +
      +
    1. Let sources be an empty list.

    2. + +
    3. Let pending be an empty queue.

    4. + +
    5. Enqueue element in pending.

    6. + +
    7. +

      While pending is not empty:

      + +
        +
      1. Let current be the result of dequeuing from + pending.

      2. + +
      3. +

        While current is not null:

        + +
          +
        1. Let source be current's active interest + source.

        2. + +
        3. +

          If source is not null, source is not element, and + sources does not contain + source:

          + +
            +
          1. Append source to + sources.

          2. + +
          3. Enqueue source in pending.

          4. +
          +
        4. + +
        5. Set current to current's parent element.

        6. +
        +
      4. +
      +
    8. + +
    9. Return sources.

    10. +
    +
    + +

    The recursive active interest sources algorithm finds all elements + whose active interest target contains (inclusively) a given element, as well as any + elements that indirect interest sources through the same condition applied recursively. In effect, + all "upstream" interest sources in a graph of active interest target relations are found. Because + cycles are possible, it is defined iteratively to avoid infinite loops.

    + +
    +

    The interest ready check for an HTML element + source and an element target returns true if all of the following are true, + and false otherwise:

    + + +
    + +
    +

    To gain interest in an HTML element + source given an element target:

    + +
      +
    1. Assert: source is an a, area, or button + element.

    2. + +
    3. Assert: the result of running source's get the interestfor-associated element is + target.

    4. + +
    5. +

      If source's active interest target is not null:

      + +
        +
      1. +

        If source's active interest target is target, then set + source's pending lose interest handle to null and return.

        + +

        Interest has already been gained for the correct target and there is nothing + to do except to cancel pending tasks.

        +
      2. + +
      3. +

        If the result of losing interest in source + given source's active interest target is false, then return.

        + +

        This fires the loseinterest event.

        +
      4. + +
      5. If the interest ready check for source and target + returns false, then return.

      6. +
      +
    6. + +
    7. Assert: source's active interest target is null.

    8. + +
    9. +

      If target's active interest source is not null:

      + +
        +
      1. +

        If the result of losing interest in target's + active interest source given target is false, then return.

        + +

        This fires the loseinterest event.

        +
      2. + +
      3. If the interest ready check for source and target + returns false, then return.

      4. +
      +
    10. + +
    11. Assert: target's active interest source is null.

    12. + +
    13. Let continue be the result of firing an + event named interest at target, using + InterestEvent, with the cancelable + attribute initialized to true, and the source + attribute initialized to source.

    14. + +
    15. If continue is false, then return.

    16. + +
    17. If the interest ready check for source and target + returns false, then return.

    18. + +
    19. Set source's active interest target to target.

    20. + +
    21. Append source to source's + node document's active interest sources set.

    22. + +
    23. Set target's active interest source to source.

    24. + +
    25. If target's popover visibility state is + hidden, then run show popover given + target, false, and source.

    26. +
    +
    + +
    +

    To lose interest in an HTML element + source given an element target:

    + +
      +
    1. Assert: source is an a, area, or button + element.

    2. + +
    3. Assert: the result of running source's get the interestfor-associated element is + target.

    4. + +
    5. Let continue be the result of firing an + event named loseinterest at target, using + InterestEvent, with the cancelable and + composed attributes initialized to true, and the + source attribute initialized to + source.

    6. + +
    7. If continue is false, then return false.

    8. + +
    9. Reset interest state for source.

    10. + +
    11. If target's popover visibility state is showing, then hide + popover given source, false, true, and false.

    12. + +
    13. Return true.

    14. +
    +
    + +
    +

    To reset interest state for an HTML element + source:

    + +
      +
    1. Let target be source's active interest + target.

    2. + +
    3. Set source's active interest target to null.

    4. + +
    5. Remove source from source's + node document's active interest sources set.

    6. + +
    7. Set target's active interest source to null.

    8. + +
    9. Set source's pending gain interest handle to null.

    10. + +
    11. Set source's pending lose interest handle to null.

    12. +
    +
    + +
    +

    The following attribute change + steps, given element, localName, oldValue, + value, and namespace, are used for a, area, and + button elements:

    + +
      +
    1. If namespace is not null, then return.

    2. + +
    3. If localName is not interestfor, then + return.

    4. + +
    5. If value is oldValue, then return.

    6. + +
    7. If element's active interest target is not null, then reset + interest state for element.

    8. +
    +
    + +
    +

    The following attribute change + steps, given element, localName, oldValue, + value, and namespace, are used for all elements:

    + +
      +
    1. If namespace is not null, then return.

    2. + +
    3. If localName is not id, then return.

    4. + +
    5. If value is oldValue, then return.

    6. + +
    7. If element's active interest source is not null, then reset + interest state for element's active interest source.

    8. +
    +
    + +

    User interaction

    + +
    +

    When the user designates an element + element with a pointing device, the user agent must queue a task on the + user interaction task source to handle interest change for + element and true.

    +
    + +
    +

    When the user no longer designates an element + element with a pointing device, the user agent must queue a task on the + user interaction task source to handle interest change for + element and false.

    +
    + +

    The tasks queued on the user interaction task source above must be queued after + any tasks that fire events such as mouseover and mouseout, or that affect the :hover pseudo-class.

    + +

    Canceling events such as mouseover and mouseout does not prevent the above tasks from running.

    + +
    +

    When the user long presses an element element on a touch device, the user agent must + queue a task on the user interaction task source to run the following + steps:

    + +
      +
    1. Fire any relevant events, per UI Events or other relevant specifications. + UIEVENTS

    2. + +
    3. Let event be the Event object for any contextmenu event fired, or null if no such event was + fired.

    4. + +
    5. Let showContextMenu be true if event is not null and its + canceled flag is not set.

    6. + +
    7. If element is not an a, area, or button + element, then abort these steps.

    8. + +
    9. Let target be the result of running element's get the interestfor-associated + element.

    10. + +
    11. If target is null, then abort these steps.

    12. + +
    13. +

      Let gainInterestIfReady be the following step:

      + +
        +
      1. If the interest ready check for element and target + returns true, then gain interest in element with + target.

      2. +
      +
    14. + +
    15. If showContextMenu is true, then provide an option in the context menu that, + when selected, queues a task on the user interaction + task source to run gainInterestIfReady.

    16. + +
    17. +

      Otherwise, run gainInterestIfReady.

      + +

      There is no delay before gaining interest as the long press gesture already has + an inherent delay.

      +
    18. +
    +
    + +

    Keyboard interactions are handled in the focus update steps.

    + +

    For input modalities other than pointing devices, touch, and keyboards, the user agent should + provide the ability for the user to indicate interest.

    +

    Loading web pages

    @@ -152957,6 +153550,13 @@ interface External { script Integrity metadata used in Subresource Integrity checks SRI Text + + interestfor + a; + area; + button + Targets another element to be invoked when the user shows interest + ID* is HTML elements @@ -154764,6 +155364,12 @@ INSERT INTERFACES HERE Elements Fired when the user changes the contenteditable element's content, or the form control's value. See also the change event for form controls. + + interest + InterestEvent + Elements + Fired at the target of an interestfor attribute when the user shows interest in the element with the interestfor attribute, e.g., by hovering or focusing. + invalid Event @@ -154782,6 +155388,12 @@ INSERT INTERFACES HERE Window, elements Fired at the Window when the document has finished loading; fired at an element containing a resource (e.g. img, embed) when its resource has finished loading + + loseinterest + InterestEvent + Elements + Fired at the target of an interestfor attribute when the user loses interest, e.g., by hovering or focusing something else. + message MessageEvent