-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP dialog closedby attribute spec #10157
Changes from all commits
0d4ebaa
46abb8f
914cc6d
4a0554d
96a4138
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61158,6 +61158,7 @@ interface <dfn interface>HTMLDetailsElement</dfn> : <span>HTMLElement</span> { | |
<dd><span>Flow content</span>.</dd> | ||
<dt><span data-x="concept-element-attributes">Content attributes</span>:</dt> | ||
<dd><span>Global attributes</span></dd> | ||
<dd><code data-x="attr-dialog-closedby">closedby</code></dd> | ||
<dd><code data-x="attr-dialog-open">open</code></dd> | ||
<dt><span | ||
data-x="concept-element-accessibility-considerations">Accessibility considerations</span>:</dt> | ||
|
@@ -61171,6 +61172,7 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> { | |
|
||
[<span>CEReactions</span>] attribute boolean <span data-x="dom-dialog-open">open</span>; | ||
attribute DOMString <span data-x="dom-dialog-returnValue">returnValue</span>; | ||
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-dialog-closedBy">closedBy</span>; | ||
[<span>CEReactions</span>] undefined <span data-x="dom-dialog-show">show</span>(); | ||
[<span>CEReactions</span>] undefined <span data-x="dom-dialog-showModal">showModal</span>(); | ||
[<span>CEReactions</span>] undefined <span data-x="dom-dialog-close">close</span>(optional DOMString returnValue); | ||
|
@@ -61266,6 +61268,38 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> { | |
is a <span>boolean attribute</span>. When specified, it indicates that the <code>dialog</code> | ||
element is active and that the user can interact with it.</p> | ||
|
||
<p>The <dfn element-attr for="dialog"><code data-x="attr-dialog-closedby">closedby</code></dfn> | ||
content attribute is an <span>enumerated attribute</span> with the following keywords and | ||
states:</p> | ||
|
||
<table> | ||
<thead> | ||
<tr> | ||
<th>Keyword | ||
<th>State | ||
<th>Brief description | ||
<tbody> | ||
<tr> | ||
<td><dfn attr-value for="dialog/closedby"><code data-x="attr-closedby-any">any</code></dfn> | ||
<td><dfn data-x="attr-closedby-any-state">Any</dfn> | ||
<td><span data-x="close request">Close requests</span> or clicking outside closes the dialog. | ||
<tr> | ||
<td><dfn attr-value for="dialog/closedby"><code data-x="attr-closedby-closerequest">closerequest</code></dfn> | ||
<td><dfn data-x="attr-closedby-closerequest-state">Close Request</dfn> | ||
<td><span data-x="close request">Close requests</span> close the dialog. | ||
<tr> | ||
<td><dfn attr-value for="dialog/closedby"><code data-x="attr-closedby-none">none</code></dfn> | ||
<td><dfn data-x="attr-closedby-none-state">None</dfn> | ||
<td>Nothing automatically closes the dialog. | ||
</table> | ||
|
||
<p>The <code data-x="attr-dialog-closedby">closedby</code> attribute's <i data-x="invalid value | ||
default">invalid value default</i> and <i data-x="missing value default">missing value | ||
default</i> are both the <dfn data-x="attr-closedby-auto-state">Auto</dfn> state. The <span | ||
data-x="attr-closedby-auto-state">auto</span> state matches <span | ||
data-x="attr-closedby-closerequest-state">closerequest</span> when the element is modal; | ||
otherwise <span data-x="attr-closedby-none-state">none</span>.</p> | ||
|
||
<div w-nodev> | ||
|
||
<p>A <code>dialog</code> element without an <code data-x="attr-dialog-open">open</code> attribute | ||
|
@@ -61343,6 +61377,27 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> { | |
<li><p>Add an <code data-x="attr-dialog-open">open</code> attribute to <span>this</span>, whose | ||
value is the empty string.</p></li> | ||
|
||
<li> | ||
<p>Set <span>this</span>'s <span data-x="dialog-close-watcher">close watcher</span> to the | ||
result of <span data-x="establish a close watcher">establishing a close watcher</span> given | ||
<span>this</span>'s <span>relevant global object</span>, with:</p> | ||
|
||
<ul> | ||
<li><p><i data-x="create-close-watcher-cancelAction">cancelAction</i> being to return the | ||
result of <span data-x="concept-event-fire">firing an event</span> named <code | ||
data-x="event-cancel">cancel</code> at <span>this</span>, with the <code | ||
data-x="dom-Event-cancelable">cancelable</code> attribute initialized to true.</p></li> | ||
|
||
<li><p><i data-x="create-close-watcher-closeAction">closeAction</i> being to <span>close the | ||
dialog</span> given <span>this</span> and null.</p></li> | ||
|
||
<li><p><i data-x="create-close-watcher-enabled">enabled</i> being true if <span>this</span>'s | ||
<code data-x="attr-dialog-closedby">closedby</code> attribute state is <span | ||
data-x="attr-closedby-any-state">Any</span> or <span | ||
data-x="attr-closedby-closerequest-state">Close Request</span>; otherwise false.</p></li> | ||
</ul> | ||
</li> | ||
|
||
<li><p>Set <span>this</span>'s <span>previously focused element</span> to the | ||
<span>focused</span> element.</p></li> | ||
|
||
|
@@ -61409,6 +61464,12 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> { | |
|
||
<li><p><i data-x="create-close-watcher-closeAction">closeAction</i> being to <span>close the | ||
dialog</span> given <span>this</span> and null.</p></li> | ||
|
||
<li><p><i data-x="create-close-watcher-enabled">enabled</i> being true if <span>this</span>'s | ||
<code data-x="attr-dialog-closedby">closedby</code> attribute is in the <span | ||
data-x="attr-closedby-any-state">Any</span>, <span | ||
data-x="attr-closedby-closerequest-state">Close Request</span>, or <span | ||
data-x="attr-closedby-auto-state">Auto</span> state; otherwise false.</p></li> | ||
</ul> | ||
</li> | ||
|
||
|
@@ -61599,6 +61660,9 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> { | |
|
||
<hr> | ||
|
||
<p>The <code>Document</code> has a <dfn>dialog pointerdown target</dfn>, which is an <span | ||
data-x="HTMLDialogElement">HTML dialog element</span> or null, initially null.</p> | ||
|
||
<p>Each <code>dialog</code> element has a <dfn data-x="dialog-close-watcher">close watcher</dfn>, | ||
which is a <span>close watcher</span> or null, initially null.</p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to make a PR for this spec like the popover one to call this function. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'd be best to have a single hook from pointer events into HTML, I think. So we should either combine this with light dismiss open popovers or create a wrapper algorithm around both of them. |
||
|
||
|
@@ -61613,8 +61677,42 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> { | |
attribute set this element to the currently <span>focused</span> element during the <span | ||
data-x="show popover">show popover algorithm</span>.</p> | ||
|
||
<p>The following <span data-x="concept-element-attributes-change-ext">attribute change | ||
steps</span>, given <var>element</var>, <var>localName</var>, <var>oldValue</var>, | ||
<var>value</var>, and <var>namespace</var>, are used for <span data-x="HTMLDialogElement">HTML | ||
dialog elements</span>:</p> | ||
|
||
<ol> | ||
<li><p>If <var>namespace</var> is not null, then return.</p></li> | ||
|
||
<li><p>If <var>localName</var> is not <code data-x="attr-dialog-closedby">closedby</code>, then | ||
return.</p></li> | ||
|
||
<li><p>If <var>element</var> has no <span data-x="attr-dialog-open">open</span> attribute, then | ||
return.</p></li> | ||
|
||
<li><p>If <var>oldValue</var> and <var>value</var> are in the same <span | ||
data-x="attr-dialog-closedby">state</span>, then return.</p></li> | ||
|
||
<li><p><span>Assert</span>: <var>element</var>'s <span data-x="dialog-close-watcher">close | ||
watcher</span> is not null.</p></li> | ||
|
||
<li><p>If <var>value</var> is in the <span data-x="attr-closedby-any-state">Any</span> state, | ||
or <span data-x="attr-closedby-closerequest-state">Close Request</span> state, | ||
or <span data-x="attr-closedby-auto-state">Auto</span> state and <var>element</var>'s <span>is | ||
modal</span> flag is true, then let <var>enabled</var> to true; otherwise false.</p></li> | ||
|
||
<li><p>Set <var>element</var>'s <span data-x="dialog-close-watcher">close watcher</span>'s <span | ||
data-x="close-watcher-enabled">enabled</span> boolean to <var>enabled</var>.</p></li> | ||
</ol> | ||
|
||
<hr> | ||
|
||
<p>The <dfn attribute for="HTMLDialogElement"><code | ||
data-x="dom-dialog-closedBy">closedBy</code></dfn> IDL attribute must <span>reflect</span> the | ||
<code data-x="attr-dialog-closedby">closedby</code> content attribute, <span>limited to only | ||
known values</span>.</p> | ||
|
||
<p>The <dfn attribute for="HTMLDialogElement"><code data-x="dom-dialog-open">open</code></dfn> IDL | ||
attribute must <span>reflect</span> the <code data-x="attr-dialog-open">open</code> content | ||
attribute.</p> | ||
|
@@ -61635,7 +61733,110 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> { | |
</dialog></code></pre> | ||
</div> | ||
|
||
<h4><dfn>Dialog light dismiss</dfn></h4> | ||
|
||
<p class="note">"Light dismiss" means that clicking outside of a dialog whose <code | ||
data-x="attr-dialog-closedby">closedby</code> attribute is in the <span | ||
data-x="attr-closedby-any-state">any</span> state will close the dialog. This is in addition to | ||
how such dialogs respond to <span data-x="close request">close requests</span>.</p> | ||
|
||
<p>To <dfn>light dismiss open dialogs</dfn>, given an <code>Event</code> <var>event</var>:</p> | ||
|
||
<ol> | ||
<li><p><span>Assert</span>: <var>event</var>'s <code | ||
data-x="dom-Event-isTrusted">isTrusted</code> attribute is true.</p></li> | ||
|
||
<li><p>Let <var>target</var> be <var>event</var>'s <span | ||
data-x="concept-event-target">target</span>.</p></li> | ||
|
||
<li><p>Let <var>document</var> be <var>target</var>'s <span>node document</span>.</p></li> | ||
|
||
<li><p>If <var>document</var>'s <span>showing any dialog list</span> is empty, then | ||
return.</p></li> | ||
|
||
<li><p>If <var>event</var> is a <code>PointerEvent</code> and <var>event</var>'s <code | ||
data-x="dom-Event-type">type</code> is "<code data-x="event-pointerdown">pointerdown</code>", | ||
then: set <var>document</var>'s <span>dialog pointerdown target</span> to the result of running | ||
<span>topmost clicked dialog</span> given <var>target</var>.</p></li> | ||
|
||
<li> | ||
<p>If <var>event</var> is a <code>PointerEvent</code> and <var>event</var>'s <code | ||
data-x="dom-Event-type">type</code> is "<code data-x="event-pointerup">pointerup</code>", | ||
then:</p> | ||
|
||
<ol> | ||
<li><p>Let <var>clickedDialog</var> be the result of running <span>topmost clicked | ||
dialog</span> given <var>target</var>.</p></li> | ||
|
||
<li><p>Let <var>topDialog</var> be <var>document</var>'s <span>showing any dialog | ||
list</span>'s last element.</p></li> | ||
|
||
<li><p>Let <var>clickedTopDialog</var> be <var>clickedDialog</var> is <var>topDialog</var>, or | ||
<var>clickedDialog</var> is <span>dialog pointerdown target</span></p></li> | ||
|
||
<li><p>Set <var>document</var>'s <span>dialog pointerdown target</span> to null.</p></li> | ||
|
||
<li><p>If <var>clickedTopDialog</var>, then return.</p></li> | ||
|
||
<li><p>Perform <span>close the dialog</span> given <var>topDialog</var>.</p></li> | ||
</ol> | ||
</li> | ||
</ol> | ||
|
||
<p class="XXX"><span>Light dismiss open dialogs</span> will be called by the <a | ||
href="https://github.com/w3c/pointerevents">Pointer Events spec</a> when the user clicks | ||
or touches anywhere on the page.</p> | ||
|
||
<p>To find the <dfn>topmost clicked dialog</dfn>, given a <code>Node</code> <var>node</var>:</p> | ||
|
||
<ol> | ||
<li><p>Let <var>clickedDialog</var> be the result of running <span>nearest inclusive open | ||
dialog</span> given <var>node</var>.</p></li> | ||
|
||
<li><p>Return <var>clickedDialog</var>.</p></li> | ||
</ol> | ||
|
||
<p>To get the <dfn id="any-dialog-list">showing any dialog list</dfn> for a | ||
<code>Document</code> <var>document</var>:</p> | ||
|
||
<ol> | ||
<li><p>Let <var>dialogs</var> be « ».</p></li> | ||
|
||
<li><p><span data-x="list iterate">For each</span> <code>Element</code> <var>element</var> in | ||
<var>document</var>'s <span>top layer</span>: if <var>element</var> is a <code | ||
data-x="HTMLDialogElement">dialog element</code>, <var>element</var>'s <code | ||
data-x="attr-dialog-closedby">closedby</code> attribute is in the <span | ||
data-x="attr-closedby-any-state">any state</span> and <var>element</var> has an <code | ||
data-x="attr-dialog-open">open</code> attribute, then <span data-x="list append">append</span> | ||
<var>element</var> to <var>dialogs</var>.</p></li> | ||
|
||
<li><p>Return <var>dialogs</var>.</p></li> | ||
</ol> | ||
|
||
<p>To find the <dfn>nearest inclusive open dialog</dfn> given a <code>Node</code> | ||
<var>node</var>, perform the following steps. They return an <span | ||
data-x="HTMLDialogElement">HTML dialog element</span> or null.</p> | ||
|
||
<ol> | ||
<li><p>Let <var>currentNode</var> be <var>node</var>.</p></li> | ||
|
||
<li> | ||
<p>While <var>currentNode</var> is not null:</p> | ||
|
||
<ol> | ||
<li><p>If <var>currentNode</var> is an <span data-x="HTMLDialogElement">HTML dialog | ||
element</span>, <var>currentNode</var>'s <code data-x="attr-dialog-closedby">closedby</code> | ||
attribute is in the <span data-x="attr-closedby-any-state">any</span> state and | ||
<var>currentNode</var> has an <code data-x="attr-dialog-open">open</code> attribute, then | ||
return <var>currentNode</var>.</p></li> | ||
|
||
<li><p>Set <var>currentNode</var> to <var>currentNode</var>'s parent in the <span>flat | ||
tree</span>.</p></li> | ||
</ol> | ||
</li> | ||
|
||
<li><p>Return null.</p></li> | ||
</ol> | ||
|
||
|
||
<h3 split-filename="scripting">Scripting</h3> | ||
|
@@ -82112,6 +82313,8 @@ body { display:none } | |
|
||
<li><p>An <dfn data-x="close-watcher-is-running-cancel">is running cancel action</dfn> | ||
boolean.</p></li> | ||
|
||
<li><p>An <dfn data-x="close-watcher-enabled">enabled</dfn> boolean.</p></li> | ||
</ul> | ||
|
||
<p>A <span>close watcher</span> <var>closeWatcher</var> <dfn data-x="close-watcher-active">is | ||
|
@@ -82122,8 +82325,10 @@ body { display:none } | |
<hr> | ||
|
||
<p>To <dfn>establish a close watcher</dfn> given a <code>Window</code> <var>window</var>, a list | ||
of steps <dfn data-x="create-close-watcher-cancelAction"><var>cancelAction</var></dfn>, and a | ||
list of steps <dfn data-x="create-close-watcher-closeAction"><var>closeAction</var></dfn>:</p> | ||
of steps <dfn data-x="create-close-watcher-cancelAction"><var>cancelAction</var></dfn>, a | ||
list of steps <dfn data-x="create-close-watcher-closeAction"><var>closeAction</var></dfn>, | ||
and an optional boolean <dfn data-x="create-close-watcher-enabled"><var>enabled</var></dfn> | ||
(default true):</p> | ||
|
||
<ol> | ||
<li><p><span>Assert</span>: <var>window</var>'s <span | ||
|
@@ -82145,6 +82350,9 @@ body { display:none } | |
|
||
<dt><span data-x="close-watcher-is-running-cancel">is running cancel action</span></dt> | ||
<dd>false</dd> | ||
|
||
<dt><span data-x="close-watcher-enabled">enabled</span></dt> | ||
<dd><var>enabled</var></dd> | ||
</dl> | ||
</li> | ||
|
||
|
@@ -82184,6 +82392,9 @@ body { display:none } | |
<li><p>If <var>closeWatcher</var> <span data-x="close-watcher-active">is not active</span>, then | ||
return true.</p></li> | ||
|
||
<li><p>If <var>closeWatcher</var>'s <span data-x="close-watcher-enabled">enabled</span> is false, | ||
then return true.</p></li> | ||
|
||
<li><p>If <var>closeWatcher</var>'s <span data-x="close-watcher-is-running-cancel">is running | ||
cancel action</span> is true, then return true.</p></li> | ||
|
||
|
@@ -82239,6 +82450,9 @@ body { display:none } | |
<li><p>If <var>closeWatcher</var> <span data-x="close-watcher-active">is not active</span>, then | ||
return.</p></li> | ||
|
||
<li><p>If <var>closeWatcher</var>'s <span data-x="close-watcher-enabled">enabled</span> is false, | ||
then return true.</p></li> | ||
|
||
<li><p>If <var>closeWatcher</var>'s <span data-x="close-watcher-window">window</span>'s <span | ||
data-x="concept-document-window">associated <code>Document</code></span> is not <span>fully | ||
active</span>, then return.</p></li> | ||
|
@@ -82286,7 +82500,8 @@ body { display:none } | |
in reverse order:</p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The groups not empty check should probably be a check that there's a group with an enabled close watcher in? And |
||
|
||
<ol> | ||
<li><p>Set <var>processedACloseWatcher</var> to true.</p></li> | ||
<li><p>If <var>closeWatcher</var>'s <span data-x="close-watcher-enabled">enabled</span> is | ||
true, set <var>processedACloseWatcher</var> to true.</p></li> | ||
|
||
<li><p>Let <var>shouldProceed</var> be the result of <span | ||
data-x="close-watcher-request-close">requesting to close</span> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to close the dialog here or do we actually want to do cancel and close (aka requestClose())?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to fire cancel and then fire close as a follow up if not cancelled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
openui/open-ui#950 (reply in thread) - Based on this comment, I need to change this to be cancel + close not just close.