1. 6.11 The popup attribute
      1. 6.11.1 The pop-up target attributes
      2. 6.11.2 pop-up light dismiss
      3. 6.11.3 The defaultopen attribute

6.11 The popup attribute

All Element s may have the popup content attribute set. When specified, the element won't be rendered until it becomes shown, at which point it will be rendered on top of other page content.

The popup attribute is an enumerated attribute . The following table lists the states for this attribute:

State Keywords Description
Auto state auto Closes other pop-ups when opened; has light dismiss .
The empty string
Hint state hint Closes other hint pop-ups when opened; has light dismiss .
Manual state manual Does not close other pop-ups; does not light dismiss .

The popUp IDL attribute must reflect the popup attribute.

The attribute may be omitted. The invalid value default and the missing value default are both the manual state .

When the popup attribute is not set an an element, then the element's popup attribute is considered to be in the no pop-up state .

Every element which has the popup attribute not in the no pop-up state has an additional pop-up visibility state with these potential values:

The pop-up visibility transitioning state and :open pseudo selectors exist to allow pop-ups to animate open or closed because animating between display:none and other display values is not possible.

The following is an example of an animated pop-up:

<div popup="auto" id="foo">
  A fancy pop-up with no Javascript
</div>
<style>
  [popup] {
    opacity: 0;
    transform: translate(-100px,100px);
    transition: all 1.5s;
  }
  [popup]:open {
    transform: translate(0,0);
    opacity: 1;
  }
</style>

The Document has a pop-up stack , which is a stack , initially empty.

The Document has a currently-showing hint pop-up , which is an Element or null, initially null.

The Document has pop-ups waiting to hide , which is a set , initially empty.

The Document has all open pop-ups , which is a set , initially empty.

The Document has a pop-up mousedown target , which is an Element or null, initially null.

Every element which has the popup attribute not in the no pop-up state has the following members:

The following attribute change steps are used for the popup attribute:

  1. If localName is not popup , return.

  2. If oldValue is in the no pop-up state , return.

  3. If value is not in the no pop-up state , return.

  4. Run the hide pop-up algorithm given element , true, and false.

The showPopUp() method steps are:

  1. If this 's popup attribute is in the no pop-up state , then throw a " NotSupportedError " DOMException .

  2. If this 's pop-up visibility state is not hidden , then throw a " InvalidStateError " DOMException .

  3. If this is not connected , then throw a " InvalidStateError " DOMException .

  4. Let show event be an Event named show .

  5. Fire show event at this .

  6. If show event 's canceled flag is true, then return.

  7. The below validity checks are repeated because firing the show event could have disconnected this element or changed its popup attribute.

    If this is not connected , return.

  8. If this 's popup attribute is in the no pop-up state , return.

  9. If this 's pop-up visibility state is showing , return.

  10. Let document be this 's node document .

  11. Let should restore focus be false.

  12. If this 's popup attribute is in the hint state , then run the following steps:

    1. If document 's currently-showing hint pop-up is not null, then run hidePopUp on document 's currently-showing hint pop-up .

    2. Let ancestor be the result of running the nearest open ancestral pop-up algorithm with node set to this and inclusive set to false.

    3. If ancestor is not null, then run hide all pop-ups until with endpoint set to ancestor , focus previous element set to false, hide immediately set to false, and hide unrelated set to true.

  13. If this 's popup attribute is in the auto state , then run the following steps:

    1. Let ancestor be the result of running the nearest open ancestral pop-up algorithm with node set to this and inclusive set to false.

    2. Run hide all pop-ups until with endpoint set to ancestor , focus previous element set to false, hide immediately set to false, and hide unrelated set to true.

  14. If this 's popup attribute is in the auto state or in the hint state , then run the following steps:

    1. The validity checks below are repeated because running hide all pop-ups until above could have fired the hide event, and an event handler could have disconnected this element or changed its popup attribute.

      If this 's popup attribute is in the no pop-up state , then return.

    2. If this 's pop-up visibility state is not hidden , then return.

    3. If this is not connected , then return.

    4. This ensures that focus is returned to the previously-focused element only for the first pop-up in a stack.

      If the result of running topmost pop-up auto or hint on document is null, then set should restore focus to true. Otherwise, set should restore focus to false.

  15. If this 's popup attribute is in the auto state , then push this onto document 's pop-up stack .

  16. If this 's popup attribute is in the hint state , then set document 's currently-showing hint pop-up to this .

  17. Add this to document 's all open pop-ups .

  18. Stop this from waiting for any animations to resolve before running pop-up hide finish if needed .

  19. Set this 's pop-up previously focused element to null.

  20. Let originally focused element the focused element.

  21. Add this to document 's top layer .

  22. Set this 's pop-up visibility state to transitioning .

  23. Update the rendering for document .

  24. Set this 's pop-up visibility state to showing .

  25. Run the hide pop-up algorithm with element set to this , focus previous element set to true, and hide immediately set to false.

  26. Run the pop-up focusing steps for this .

  27. If should restore focus is true and this 's popup attribute is not in the no pop-up state and originally focused element is not the focused element, then set this 's pop-up previously focused element to originally focused element .

The hidePopUp() method steps are:

  1. If this 's popup attribute is in the no pop-up state , then throw a " NotSupportedError " DOMException .

  2. If this 's pop-up visibility state is not showing , then throw a " InvalidStateError " DOMException .

  3. Run the hide pop-up algorithm with element set to this , focus previous element set to true, and hide immediately set to false.

element . showPopUp ()
Shows the pop-up element by adding it to the top layer.
element . hidePopUp ()
Hides the pop-up element by applying 'display:none' to it.

To hide a pop-up given an Element element , a boolean focus previous element , and a boolean hide immediately :

  1. Let document be element 's node document .

  2. If element 's popup attribute is in the auto state or the hint state :

    1. Run hide all pop-ups until with endpoint set to element , focus previous element set to focus previous element , hide immediately set to hide immediately , and hide unrelated set to false.

    2. These validity checks are repeated because running hide all pop-ups until above could have fired the hide event, and an event handler could have disconnected this element or changed its popup attribute.

      If element 's popup attribute is in the no pop-up state , return.

    3. If element is not connected , return.

    4. If element 's pop-up visibility state is not showing , return.

    5. If element 's popup attribute is in the auto state , pop the top value from document 's pop-up stack .

    6. If element 's popup attribute is in the hint state , set document 's currently-showing hint pop-up to null.

  3. Remove element from document 's all open pop-ups .

  4. Add element to document 's pop-ups waiting to hide .

  5. Let previous animations be the result of running getAnimations on element .

  6. Set element 's pop-up invoker to null.

  7. Set element 's pop-up visibility state to transitioning .

  8. If hide immediately is true:

    1. Queue a global task on the user interaction task source given element 's relevant global object to fire an event named hide at element .

    2. Run pop-up hide finish if needed on element .

    3. Return.

  9. Fire an event named hide at element .

  10. If element is not connected , return.

  11. If element 's popup attribute is in the no pop-up state , return.

  12. If element 's pop-up visibility state is transitioning , return.

  13. Let animations be a set containing the result of running getAnimations on element .

  14. Remove all items in animations which exist in previous animations .

  15. If animations is empty, run pop-up hide finish if needed on element .

  16. Let previously focused element be element 's previously focused element .

  17. If previously focused element is not null:

    1. Set element 's previously focused element to null.

    2. If focus previous element is true, run focus on previously focused element with preventScroll set to true.

  18. If animations is not empty:

    1. Wait for each animation in animations to resolve as either canceled or finished .

    2. Run pop-up hide finish if needed on element .

To finish hiding a pop-up if needed , given an Element element :

  1. Remove element from element 's node document 's pop-ups waiting to hide .

  2. Remove element from the top layer .

  3. Set element 's pop-up visibility state to hidden .

  4. Stop element from waiting for any animations to resolve before running this algorithm.

To hide all pop-ups until , given an Element endpoint , a boolean focus previous element , a boolean hide immediately , and a boolean hide unrelated :

  1. Let document be endpoint 's node document .

  2. If hide immediately is true, then run the following steps:

    1. For each element waiting to hide in document 's pop-ups waiting to hide , run the following steps:

      1. Run pop-up hide finish if needed with element set to element waiting to hide .

    2. Clear document 's pop-ups waiting to hide .

  3. If endpoint 's popup attribute is in the hint state and hide unrelated is true, then run the following steps:

    1. If document 's currently-showing hint pop-up is not equal to endpoint , then run the hide pop-up algorithm with element set to endpoint , focus previous element set to focus previous element , and hide immediately set to hide immediately .

    2. While document 's pop-up stack is not empty, run the following steps:

      1. Run the hide pop-up algorithm with element set to endpoint , focus previous element set to focus previous element , and hide immediately set to hide immediately .

  4. If endpoint 's popup attribute is in the auto state or endpoint is null, then run the following steps:

    1. Let hint ancestor be null.

    2. If document's currently-showing hint pop-up is not null:

      1. Let hint ancestor be the result of running the nearest open ancestral pop-up algorithm with node set to document 's currently-showing hint pop-up and inclusive set to false.

      2. If hint ancestor is null and hide unrelated is true, then run the hide pop-up algorithm with element set to document 's currently-showing hint pop-up , focus previous element set to focus previous element and hide immediately set to hide immediately .

    3. While document 's pop-up stack is not empty:

      1. If document 's pop-up stack 's top element is hint ancestor , then run the hide pop-up algorithm with element set to document 's currently-showing hint pop-up with focus previous element set to focus previous element and hide immediately set to hide immediately .

      2. If document 's pop-up stack 's top element is equal to endpoint , break .

      3. Run the hide pop-up algorithm with element set to document 's pop-up stack 's top element, focus previous element set to focus previous element , and hide immediately set to hide immediately .

The hide all pop-ups until algorithm is used in several cases to hide all pop-ups that don't stay open when something happens. For example, during light-dismiss of a pop-up, this algorithm ensures that we close only the pop-ups that aren't related to the Node clicked by the user. The interaction between popup=auto and popup=hint is captured here, where a popup=hint that is "nested" inside a popup=auto is only hidden at the appropriate time.

To find the nearest open ancestral pop-up , given a Node node and a boolean inclusive , perform the following steps. They return an Element or null.

  1. Let document be node 's node document .

  2. Let hint showing be document 's currently-showing hint pop-up .

  3. Let anchors to pop-ups be an empty map .

  4. For each pop-up in document 's pop-up stack :

    1. Let anchor be the result of getting the pop-up anchor element of pop-up .

    2. If anchor is not null, map anchor to pop-up in anchors to pop-ups .

  5. If hint showing is not null:

    1. Let anchor be the result of running getting the pop-up anchor element of hint showing .

    2. If anchor is not null, map anchor to hint showing in anchors to pop-ups .

  6. Let pop-up positions be an empty map .

  7. Let index be 0.

  8. For each pop-up in document 's pop-up stack :

    1. Map pop-up to index in pop-up positions .

    2. Increment index by 1.

  9. If hint showing is not null:

    1. Map hint showing to index in pop-up positions .

    2. Increment index by 1.

  10. Let new element be true if node 's popup attribute is not in the no pop-up state and node 's pop-up visibility state is not showing .

  11. If new element is true, then:

    1. Map node to index in pop-up positions .

  12. Let upper bound be 2147483647.

  13. If pop-up positions has a value for node , set upper bound to pop-up position 's value for node .

  14. If hint showing is not null and new element is true, set upper bound to pop-up position 's value for hint showing .

  15. If inclusive is true:

    1. Let current node be node .

    2. While current node has a parent node within the flat tree :

      1. If current node 's popup attribute is not in the no pop-up state and current node 's pop-up visibility state is showing and current node 's popup attribute is not in the manual state

        :
        1. Let current element plus one be pop-up position 's value for current node plus 1.

        2. If current element plus one is greater than upper bound , then set upper bound to current element plus one .

      2. Let target pop-up be current node 's pop-up target element .

      3. If target pop-up 's popup attribute is not null and target pop-up 's pop-up visibility state is showing and target pop-up 's popup attribute is not in the manual state :

        1. Let target pop-up plus one be pop-up position 's value for target pop-up plus 1.

        2. If target pop-up plus one is greater than upper bound , then set upper bound to target pop-up plus one .

      4. Set current node to the parent node of current node within the flat tree .

  16. Let seen be an empty set .

  17. Return the result of running the nearest open ancestral pop-up recursive algorithm with node , pop-up positions , anchors to pop-ups , upper bound , and seen .

To find the nearest open ancestral pop-up recursively , given a Node node , a map pop-up positions , a map anchors to pop-ups , an integer upper bound , and a set seen , perform the following steps. They return an Element or null.

  1. If node is null, return null.

  2. If seen contains node , return null.

  3. Add node to seen .

  4. Let ancestor be null.

  5. Let position be -1.

  6. Let update be to run the following steps on pop-up :

    1. If pop-up is not null and pop-up 's pop-up visibility state is not showing and pop-up 's popup attribute is not is not in the manual state :

      1. Let new position be pop-up position 's value for pop-up .

      2. If new position is greater than position and new position is less than upper bound :

        1. Set ancestor to pop-up .

        2. Set position to new position .

  7. Let recurse and update be to run the following steps on node :

    1. Let nearest open ancestor be the result of running nearest open ancestral pop-up recursive with node , pop-up positions , anchors to pop-ups , upper bound , and seen .

    2. Run update with pop-up set to nearest open ancestor .

  8. Run update with node .

  9. If pop-up positions has a value for node :

    1. Run recurse and update with node 's pop-up anchor element .

    2. Run recurse and update with node 's pop-up invoker .

  10. If node has a pop-up target element , then run recurse and update with node 's pop-up target element .

  11. If anchors to pop-ups has a value for node , then run recurse and update with anchors to pop-ups 's value for node .

  12. Run recurse and update on node 's parent node in the flat tree .

  13. Return ancestor .

To get the pop-up anchor element of an Element element , perform the following steps. They return an Element or null.

  1. If element 's popup attribute is in the no pop-up state , then return null.

  2. Let anchor attribute be the result of running get an attribute by name on element with qualifiedName set to 'anchor'.

  3. If anchor attribute is null, then return null.

  4. Return the result of running getElementById on element 's root with elementId set to anchor attribute .

To find the topmost pop-up auto or hint given a Document document , perform the following steps. They return an Element or null.

  1. If document 's currently-showing hint pop-up is not null, then return document 's currently-showing hint pop-up .

  2. If document 's pop-up stack is not empty, then return document 's pop-up stack 's last element.

  3. Return null.

To perform the pop-up focusing steps for an Element subject :

  1. Let control be the result of running pop-up focusable area on subject .

  2. Run the focusing steps for control .

  3. Let top document be the active document of control 's node document 's browsing context 's top-level browsing context .

  4. If control 's node document 's origin is not the same as the origin of top document , then return.

  5. Empty top document 's autofocus candidates .

  6. Set top document 's autofocus processed flag to true.

To get the pop-up focusable area given an element subject , perform the following steps. They return an Element or null.

  1. If subject has the autofocus attribute, then return subject .

  2. For each node in the flat tree within subject :

    1. If node is a dialog element or node 's popup attribute is not in the no pop-up state , then continue without traversing into the child nodes of node .

    2. If node is not focusable , continue.

    3. If node does not have the autofocus attribute, continue.

    4. Return node .

  3. Return null.

6.11.1 The pop-up target attributes

DOM interface :

interface mixin PopUpTargetElement {
  [CEReactions] attribute DOMString? popUpToggleTarget;
  [CEReactions] attribute DOMString? popUpHideTarget;
  [CEReactions] attribute DOMString? popUpShowTarget;
};

Supported elements may have the following content attributes, known as the pop-up target attributes :

The following shows how popupshowtarget can be used to open a pop-up:

<div popup=auto id="foo">
  This is a pop-up!
</div>
<button popupshowtarget="foo">
  Show a pop-up
</button>

The following shows how popuptoggletarget can open and close a manual pop-up, which can't be closed with light dismiss:

<div popup=manual id="foo">
  This is a pop-up!
</div>
<button popuptoggletarget="foo">
  Show or hide a pop-up
</button>

The pop-up target attributes allow certain types of buttons to show and hide element with the popup attribute. If a pop-up target attribute is specified, then that attribute's value must be the ID of element with the popup attribute.

The popUpToggleTarget IDL attribute must reflect the popuptoggletarget attribute.

The popUpHideTarget IDL attribute must reflect the popuphidetarget attribute.

The popUpShowTarget IDL attribute must reflect the popupshowtarget attribute.

The pop-up target attributes are only supported on the following elements:

To run the pop-up target attribute activation behavior given a Node node :

  1. If node has the disabled attribute, then return.

  2. If node is not supported by the pop-up target attributes , then return.

  3. Let pop-up be node 's pop-up target element .

  4. If pop-up is null, then return.

  5. If node doesn't have the popuptoggletarget attribute:

    1. If node has the popupshowtarget attribute and pop-up 's pop-up visibility state is showing , then return.

    2. If node has the popuphidetarget attribute and pop-up 's pop-up visibility state is hidden , then return.

    3. If node doesn't have the popupshowtarget attribute and node doesn't have the popuphidetarget attribute, then return.

  6. If node has a form owner and node is in any of the following states, then return:

    1. node is a button element in the submit state .

    2. node is an input element in the submit state .

    3. node is an input element in the image state .

  7. If pop-up 's pop-up visibility state is showing , then run the hide pop-up algorithm with element set to pop-up , focus previous element set to true, and hide immediately set to false.

  8. Otherwise, run the following steps:

    1. Set pop-up 's pop-up invoker to node .

    2. Run showPopUp on pop-up .

To get the pop-up target element given a Node node , perform the following steps. They return an Element or null.

  1. If node is not supported , then return null.

  2. Let idref be null.

  3. If node has the popuptoggletarget attribute, then set idref to the value of node 's popuptoggletarget attribute.

  4. Otherwise, if node has the popupshowtarget attribute, then set idref to the value of node 's popupshowtarget attribute.

  5. Otherwise, if node has the popuphidetarget attribute, then set idref to the value of node 's popuphidetarget attribute.

  6. If idref is null, then return null.

  7. Let popup element be the result of running getElementById on node 's root with idref .

  8. If popup element is null, then return null.

  9. If popup element ' popup attribute is in the no pop-up state , then return null.

  10. Return popup element .

6.11.2 pop-up light dismiss

"Light dismiss" means that pressing the escape key or clicking outside of a pop-up whose popup attribute is in the auto or hint states will close the pop-up.

When a Document document receives an Event event in the capture phase, run the following steps:

  1. Let topmost popup be the result of running topmost pop-up auto or hint on document .

  2. If topmost popup is null, then return.

  3. Let target be event 's target .

  4. If target is null, then return.

  5. If event is a mousedown event then:

    1. Set document 's pop-up mousedown target to the result of running nearest open ancestral pop-up with node set to target and inclusive set to true.

  6. If event is a mouseup event then:

    1. Let ancestor be the result of running nearest open ancestral pop-up with node set to target and inclusive set to true.

    2. Let same target be true if ancestor is document 's pop-up mousedown target .

    3. Set document 's pop-up mousedown target to null.

    4. If same target is true, then run hide all pop-ups until with endpoint set to ancestor , focus previous element set to false, hide immediately set to false, and hide unrelated set to true.

  7. If event is a keydown event for the Escape key:

    1. Run the hide pop-up algorithm with element set to topmost popup , focus previous element set to true, and hide immediately set to false.

  8. If event is a focus event, then:

    1. Let ancestor be the result of running nearest open ancestral pop-up with node set to target and inclusive set to true.

    2. Run hide all pop-ups until with endpoint set to ancestor , focus previous element set to false, hide immediately set to false, and hide unrelated set to true.

6.11.3 The defaultopen attribute

All Element s may have the defaultopen content attribute set. When specified on a pop-up element, it makes the element shown automatically when the page is loaded. defaultopen is a boolean attribute .

The defaultOpen IDL attribute must reflect the defaultopen attribute.