Skip to content

Commit

Permalink
WIP dialog closedby attribute spec
Browse files Browse the repository at this point in the history
  • Loading branch information
lukewarlow committed May 7, 2024
1 parent f499167 commit 0d4ebaa
Showing 1 changed file with 254 additions and 11 deletions.
265 changes: 254 additions & 11 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>;
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);
Expand Down Expand Up @@ -61266,6 +61268,39 @@ 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">closerequest</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
<tr>
<td>No corresponding keyword
<td><dfn data-x="attr-closedby-auto-state">auto</dfn>
<td>Same as <span data-x="attr-closedby-closerequest-state">closerequest</span> when modal or <span data-x="attr-closedby-none-state">none</span> when not
</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 <span data-x="attr-closedby-auto-state">auto</span> state.</p>

<div w-nodev>

<p>A <code>dialog</code> element without an <code data-x="attr-dialog-open">open</code> attribute
Expand Down Expand Up @@ -61343,6 +61378,29 @@ 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>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">closerequest</span> then:</p>

<ol>
<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>
</ul>
</li>
</ol>
</li>

<li><p>Set <span>this</span>'s <span>previously focused element</span> to the
<span>focused</span> element.</p></li>

Expand Down Expand Up @@ -61397,19 +61455,25 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> {
to the top layer</span> given <span>this</span>.</p></li>

<li id="canceling-dialogs">
<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>
<p>If <span>this</span>'s <code data-x="attr-dialog-closedby">closedby</code> attribute state
is not <span data-x="attr-closedby-none-state">none</span> then:</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>
<ol>
<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>

<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>
</ul>
<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>
</ul>
</li>
</ol>
</li>

<li><p>Set <span>this</span>'s <span>previously focused element</span> to the
Expand Down Expand Up @@ -61466,6 +61530,48 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> {
<li><p>Set <var>topDocument</var>'s <span>autofocus processed flag</span> to true.</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>

<p>The <code>dialog</code> <span>HTML element removing steps</span>, given <var>removedNode</var>
and <var>oldParent</var>, are:</p>

Expand Down Expand Up @@ -61599,6 +61705,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>

Expand All @@ -61613,8 +61722,79 @@ 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>If <var>value</var> is in the <span data-x="attr-closedby-none-state">none state</span>
or <span data-x="attr-closedby-auto-state">auto state</span> and <var>element</var>'s <span>is
modal</span> flag is false then:</p>
<ol>
<li>
<p>If <var>element</var>'s <span data-x="dialog-close-watcher">close watcher</span> is not
null, then:</p>

<ol>
<li><p><span data-x="close-watcher-destroy">Destroy</span> <var>element</var>'s <span
data-x="dialog-close-watcher">close watcher</span>.</p></li>

<li><p>Set <var>element</var>'s <span data-x="dialog-close-watcher">close watcher</span> to
null.</p></li>
</ol>
</li>
</ol>
</li>
<li><p>If <var>value</var> is in the <span
data-x="attr-closedby-closerequest-state">closerequest state</span>, <span
data-x="attr-closedby-any-state">any state</span>, or <span
data-x="attr-closedby-auto-state">auto state</span> and <var>element</var>'s <span>is
modal</span> flag is true then:</p>
<ol>
<li>
<p>If <var>element</var>'s <span data-x="dialog-close-watcher">close watcher</span> is null,
then:</p>

<ol>
<li><p>Set <var>element</var>'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 <var>element</var>'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 <var>element</var>, 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 <var>element</var> and null.</p></li>
</ul>
</li>
</ol>
</li>
</ol>
</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>
Expand All @@ -61635,6 +61815,69 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> {
&lt;/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></li>
</ol>




Expand Down

0 comments on commit 0d4ebaa

Please sign in to comment.