Skip to content

Commit e0cf318

Browse files
authored
Add name attribute for grouping details elements
This allows grouping into exclusive accordions. See https://open-ui.org/components/accordion.explainer/.
1 parent 85547bd commit e0cf318

File tree

1 file changed

+261
-16
lines changed

1 file changed

+261
-16
lines changed

source

Lines changed: 261 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10698,6 +10698,14 @@ partial interface <dfn id="document" data-lt="">Document</dfn> {
1069810698
<p class="note">This is only populated for "<code data-x="">about:</code>"-schemed
1069910699
<code>Document</code>s.</p>
1070010700

10701+
<p>Each <code>Document</code> has a <dfn data-x="concept-document-fire-mutation-events-flag">fire
10702+
mutation events flag</dfn>, which is a boolean, initially true.</p>
10703+
10704+
<p class="note">This is intended to suppress firing of DOM Mutation Events in cases when they
10705+
would normally fire. The specification describing mutation events is not actively maintained so
10706+
it does not look at this flag, but implementations are expected to act as though it did.
10707+
<ref>UIEVENTS</ref></p>
10708+
1070110709
<h4>The <code>DocumentOrShadowRoot</code> interface</h4>
1070210710

1070310711
<p><cite>DOM</cite> defines the <code data-x="DOM
@@ -59911,6 +59919,7 @@ dictionary <dfn dictionary>FormDataEventInit</dfn> : <span>EventInit</span> {
5991159919
<dd>One <code>summary</code> element followed by <span>flow content</span>.</dd>
5991259920
<dt><span data-x="concept-element-attributes">Content attributes</span>:</dt>
5991359921
<dd><span>Global attributes</span></dd>
59922+
<dd><code data-x="attr-details-name">name</code></dd>
5991459923
<dd><code data-x="attr-details-open">open</code></dd>
5991559924
<dt><span
5991659925
data-x="concept-element-accessibility-considerations">Accessibility considerations</span>:</dt>
@@ -59922,6 +59931,7 @@ dictionary <dfn dictionary>FormDataEventInit</dfn> : <span>EventInit</span> {
5992259931
interface <dfn interface>HTMLDetailsElement</dfn> : <span>HTMLElement</span> {
5992359932
[<span>HTMLConstructor</span>] constructor();
5992459933

59934+
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-details-name">name</span>;
5992559935
[<span>CEReactions</span>] attribute boolean <span data-x="dom-details-open">open</span>;
5992659936
};</code></pre>
5992759937
</dd>
@@ -59942,6 +59952,31 @@ interface <dfn interface>HTMLDetailsElement</dfn> : <span>HTMLElement</span> {
5994259952
<p>The rest of the element's contents <span>represents</span> the additional information or
5994359953
controls.</p>
5994459954

59955+
<p>The <dfn element-attr for="details"><code data-x="attr-details-name">name</code></dfn> content
59956+
attribute gives the name of the group of related <code>details</code> elements that the element is
59957+
a member of. Opening one member of this group causes other members of the group to close. If the
59958+
attribute is specified, its value must not be the empty string.</p>
59959+
59960+
<p>A document must not contain more than one <code>details</code> element in the same
59961+
<span>details name group</span> that has the <code data-x="attr-details-open">open</code>
59962+
attribute present. Authors must not use script to add <code>details</code> elements to a document
59963+
in a way that would cause a <span>details name group</span> to have more than one
59964+
<code>details</code> element with the <code data-x="attr-details-open">open</code> attribute
59965+
present.</p>
59966+
59967+
<p class="note">The group of elements that is created by a common <code
59968+
data-x="attr-details-name">name</code> attribute is exclusive, meaning that at most one of the
59969+
<code>details</code> elements can be open at once. While this exclusivity is enforced by user
59970+
agents, the resulting enforcement immediately changes the <code
59971+
data-x="attr-details-open">open</code> attributes in the markup. This requirement on authors
59972+
forbids such misleading markup.</p>
59973+
59974+
<p>Documents that use the <code data-x="attr-details-name">name</code> attribute to group multiple
59975+
related <code>details</code> elements should keep those related elements together in a containing
59976+
element (such as a <code>section</code> element).</p>
59977+
59978+
<p class="note">Keeping related elements together can be important for accessibility.</p>
59979+
5994559980
<p>The <dfn element-attr for="details"><code data-x="attr-details-open">open</code></dfn> content
5994659981
attribute is a <span>boolean attribute</span>. If present, it indicates that both the summary and
5994759982
the additional information is to be shown to the user. If the attribute is absent, only the
@@ -59968,25 +60003,68 @@ interface <dfn interface>HTMLDetailsElement</dfn> : <span>HTMLElement</span> {
5996860003
exists, user agents can still provide this ability through some other user interface
5996960004
affordance.</p>
5997060005

60006+
<p>The <dfn>details name group</dfn> that contains a <code>details</code> element <var>a</var>
60007+
also contains all the other <code>details</code> elements <var>b</var> that fulfill all of the
60008+
following conditions:</p>
60009+
60010+
<ul>
60011+
<li>Both <var>a</var> and <var>b</var> are in the same <span>tree</span>.</li>
60012+
60013+
<li>They both have a <code data-x="attr-details-name">name</code> attribute, their <code
60014+
data-x="attr-details-name">name</code> attributes are not the empty string, and the value of
60015+
<var>a</var>'s <code data-x="attr-details-name">name</code> attribute equals the value of
60016+
<var>b</var>'s <code data-x="attr-details-name">name</code> attribute.</li>
60017+
</ul>
60018+
5997160019
<p>Every <code>details</code> element has a <dfn>details toggle task tracker</dfn>, which is a
5997260020
<span>toggle task tracker</span> or null, initially null.</p>
5997360021

59974-
<p>Whenever the <code data-x="attr-details-open">open</code> attribute is added to or removed from
59975-
a <code>details</code> element, the user agent must run the following steps, which are known as
59976-
the <dfn>details notification task steps</dfn>, for this <code>details</code> element:</p>
59977-
59978-
<p class="note">When the <code data-x="attr-details-open">open</code> attribute is toggled several
59979-
times in succession, the resulting tasks essentially get coalesced so that only one event is
59980-
fired.</p>
60022+
<p>The following <span data-x="concept-element-attributes-change-ext">attribute change
60023+
steps</span>, given <var>element</var>, <var>localName</var>, <var>oldValue</var>,
60024+
<var>value</var>, and <var>namespace</var>, are used for all <code>details</code> elements:</p>
5998160025

5998260026
<ol>
59983-
<li><p>If the <code data-x="attr-details-open">open</code> attribute is added, <span>queue a
59984-
details toggle event task</span> given the <code>details</code> element, "<code
59985-
data-x="">closed</code>", and "<code data-x="">open</code>".</p></li>
60027+
<li><p>If <var>namespace</var> is not null, then return.</p></li>
60028+
60029+
<li><p>If <var>localName</var> is <code data-x="attr-details-name">name</code>, then <span>ensure
60030+
details exclusivity by closing the given element if needed</span> given
60031+
<var>element</var>.</p></li>
5998660032

59987-
<li><p>Otherwise, <span>queue a details toggle event task</span> given the <code>details</code>
59988-
element, "<code data-x="">open</code>", and "<code data-x="">closed</code>".</p></li>
60033+
<li><p>If <var>localName</var> is <code data-x="attr-details-open">open</code>, then:
60034+
<ol>
60035+
<li>
60036+
<p>If one of <var>oldValue</var> or <var>value</var> is null and the other is not null,
60037+
run the following steps, which are known as the <dfn>details notification task steps</dfn>, for
60038+
this <code>details</code> element:</p>
5998960039

60040+
<p class="note">When the <code data-x="attr-details-open">open</code> attribute is toggled
60041+
several times in succession, the resulting tasks essentially get coalesced so that only one
60042+
event is fired.</p>
60043+
60044+
<ol>
60045+
<li><p>If <var>oldValue</var> is null, <span>queue a details toggle event task</span> given
60046+
the <code>details</code> element, "<code data-x="">closed</code>", and "<code
60047+
data-x="">open</code>".</p></li>
60048+
60049+
<li><p>Otherwise, <span>queue a details toggle event task</span> given the
60050+
<code>details</code> element, "<code data-x="">open</code>", and "<code
60051+
data-x="">closed</code>".</p></li>
60052+
</ol>
60053+
</li>
60054+
60055+
<li><p>If <var>oldValue</var> is null and <var>value</var> is not null, then <span>ensure
60056+
details exclusivity by closing other elements if needed</span> given
60057+
<var>element</var>.</p></li>
60058+
</ol>
60059+
</li>
60060+
</ol>
60061+
60062+
<p>The <code>details</code> <span data-x="html element insertion steps">HTML element insertion
60063+
steps</span>, given <var>insertedNode</var>, are:</p>
60064+
60065+
<ol>
60066+
<li><p><span>Ensure details exclusivity by closing the given element if needed</span> given
60067+
<var>insertedNode</var>.</p></li>
5999060068
</ol>
5999160069

5999260070
<p>To <dfn>queue a details toggle event task</dfn> given a <code>details</code> element
@@ -60028,9 +60106,105 @@ interface <dfn interface>HTMLDetailsElement</dfn> : <span>HTMLElement</span> {
6002860106
to <var>oldState</var>.</p></li>
6002960107
</ol>
6003060108

60031-
<p>The <dfn attribute for="HTMLDetailsElement"><code data-x="dom-details-open">open</code></dfn>
60032-
IDL attribute must <span>reflect</span> the <code data-x="attr-details-open">open</code> content
60033-
attribute.</p>
60109+
<p>To <dfn>ensure details exclusivity by closing other elements if needed</dfn> given a
60110+
<code>details</code> element <var>element</var>:</p>
60111+
60112+
<ol>
60113+
<li><p><span>Assert</span>: <var>element</var> has an <code
60114+
data-x="attr-details-open">open</code> attribute.</p></li>
60115+
60116+
<!-- This step is an optimization, but it may also make things clearer. -->
60117+
<li><p>If <var>element</var> does not have a <code data-x="attr-details-name">name</code>
60118+
attribute, or its <code data-x="attr-details-name">name</code> attribute is the empty string,
60119+
then return.</p></li>
60120+
60121+
<li><p>Let <var>document</var> be <var>element</var>'s <span>node document</span>.</p></li>
60122+
60123+
<li><p>Let <var>oldFlag</var> be the value of <var>document</var>'s <span
60124+
data-x="concept-document-fire-mutation-events-flag">fire mutation events flag</span>.</p></li>
60125+
60126+
<li><p>Set <var>document</var>'s <span data-x="concept-document-fire-mutation-events-flag">fire
60127+
mutation events flag</span> to false.</p></li>
60128+
60129+
<li><p>Let <var>groupMembers</var> be a list of elements, containing all elements in
60130+
<var>element</var>'s <span>details name group</span> except for <var>element</var>, in <span>tree
60131+
order</span>.</p></li>
60132+
60133+
<li>
60134+
<p><span data-x="list iterate">For each</span> element <var>otherElement</var> of
60135+
<var>groupMembers</var>:</p>
60136+
<ol>
60137+
<li>
60138+
<p>If the <code data-x="attr-details-open">open</code> attribute is set on
60139+
<var>otherElement</var>, then:</p>
60140+
60141+
<ol>
60142+
<li><p><span>Assert</span>: <var>otherElement</var> is the only element in
60143+
<var>groupMembers</var> that has the <code data-x="attr-details-open">open</code> attribute
60144+
set.</p></li>
60145+
60146+
<li><p><span data-x="concept-element-attributes-remove">Remove</span> the <code
60147+
data-x="attr-details-open">open</code> attribute on <var>otherElement</var>.</p></li>
60148+
60149+
<li><p><span>Break</span>.</p></li>
60150+
</ol>
60151+
</ol>
60152+
</li>
60153+
60154+
<li><p>Set <var>document</var>'s <span data-x="concept-document-fire-mutation-events-flag">fire
60155+
mutation events flag</span> to <var>oldFlag</var>.</p></li>
60156+
</ol>
60157+
60158+
<p>To <dfn>ensure details exclusivity by closing the given element if needed</dfn> given a
60159+
<code>details</code> element <var>element</var>:</p>
60160+
60161+
<ol>
60162+
<li><p>If <var>element</var> does not have an <code data-x="attr-details-open">open</code>
60163+
attribute, then return.</p></li>
60164+
60165+
<!-- This step is an optimization, but it may also make things clearer. -->
60166+
<li><p>If <var>element</var> does not have a <code data-x="attr-details-name">name</code>
60167+
attribute, or its <code data-x="attr-details-name">name</code> attribute is the empty string,
60168+
then return.</p></li>
60169+
60170+
<li><p>Let <var>document</var> be <var>element</var>'s <span>node document</span>.</p></li>
60171+
60172+
<li><p>Let <var>oldFlag</var> be the value of <var>document</var>'s <span
60173+
data-x="concept-document-fire-mutation-events-flag">fire mutation events flag</span>.</p></li>
60174+
60175+
<li><p>Set <var>document</var>'s <span data-x="concept-document-fire-mutation-events-flag">fire
60176+
mutation events flag</span> to false.</p></li>
60177+
60178+
<li><p>Let <var>groupMembers</var> be a list of elements, containing all elements in
60179+
<var>element</var>'s <span>details name group</span> except for <var>element</var>, in <span>tree
60180+
order</span>.</p></li>
60181+
60182+
<li>
60183+
<p><span data-x="list iterate">For each</span> element <var>otherElement</var> of
60184+
<var>groupMembers</var>:</p>
60185+
60186+
<ol>
60187+
<li>
60188+
<p>If the <code data-x="attr-details-open">open</code> attribute is set on
60189+
<var>otherElement</var>, then:</p>
60190+
60191+
<ol>
60192+
<li><p><span data-x="concept-element-attributes-remove">Remove</span> the <code
60193+
data-x="attr-details-open">open</code> attribute on <var>element</var>.</p></li>
60194+
60195+
<li><p><span>Break</span>.</p></li>
60196+
</ol>
60197+
</li>
60198+
</ol>
60199+
</li>
60200+
60201+
<li><p>Set <var>document</var>'s <span data-x="concept-document-fire-mutation-events-flag">fire
60202+
mutation events flag</span> to <var>oldFlag</var>.</p></li>
60203+
</ol>
60204+
60205+
<p>The <dfn attribute for="HTMLDetailsElement"><code data-x="dom-details-name">name</code></dfn>
60206+
and <dfn attribute for="HTMLDetailsElement"><code data-x="dom-details-open">open</code></dfn>
60207+
IDL attributes must <span>reflect</span> the respective content attributes of the same name.</p>
6003460208

6003560209
</div>
6003660210

@@ -60107,6 +60281,62 @@ interface <dfn interface>HTMLDetailsElement</dfn> : <span>HTMLElement</span> {
6010760281

6010860282
</div>
6010960283

60284+
<div class="example" id="example-details-exclusive-accordion">
60285+
<p>The following example shows the <code data-x="attr-details-name">name</code> attribute of the
60286+
<code>details</code> element being used to create an exclusive accordion, a set of
60287+
<code>details</code> elements where a user action to open one <code>details</code> element causes
60288+
any open <code>details</code> to close.</p>
60289+
60290+
<pre><code class="html">&lt;section class="characteristics">
60291+
&lt;details name="frame-characteristics">
60292+
&lt;summary>Material&lt;/summary>
60293+
The picture frame is made of solid oak wood.
60294+
&lt;/details>
60295+
&lt;details name="frame-characteristics">
60296+
&lt;summary>Size&lt;/summary>
60297+
The picture frame fits a photo 40cm tall and 30cm wide.
60298+
The frame is 45cm tall, 35cm wide, and 2cm thick.
60299+
&lt;/details>
60300+
&lt;details name="frame-characteristics">
60301+
&lt;summary>Color&lt;/summary>
60302+
The picture frame is available in its natural wood
60303+
color, or with black stain.
60304+
&lt;/details>
60305+
&lt;/section></code></pre>
60306+
</div>
60307+
60308+
<div class="example" id="example-details-exclusive-accordion-setting-open">
60309+
<p>The following example shows what happens when the <code data-x="attr-details-open">open</code>
60310+
attribute is set on a <code>details</code> element that is part of a set of elements using the
60311+
<code data-x="attr-details-name">name</code> attribute to create an exclusive accordion.</p>
60312+
60313+
<p>Given the initial markup:</p>
60314+
60315+
<pre><code class="html">&lt;section class="characteristics">
60316+
&lt;details name="frame-characteristics" id="d1" open>...&lt;/details>
60317+
&lt;details name="frame-characteristics" id="d2">...&lt;/details>
60318+
&lt;details name="frame-characteristics" id="d3">...&lt;/details>
60319+
&lt;/section></code></pre>
60320+
60321+
<p>and the script:</p>
60322+
60323+
<pre><code class="js">document.getElementById("d2").setAttribute("open", "");</code></pre>
60324+
60325+
<p>then the resulting tree after the script executes will be equivalent to the markup:</p>
60326+
60327+
<pre><code class="html">&lt;section class="characteristics">
60328+
&lt;details name="frame-characteristics" id="d1">...&lt;/details>
60329+
&lt;details name="frame-characteristics" id="d2" open>...&lt;/details>
60330+
&lt;details name="frame-characteristics" id="d3">...&lt;/details>
60331+
&lt;/section></code></pre>
60332+
60333+
<p>because setting the <code data-x="attr-details-open">open</code> attribute on <code
60334+
data-x="">d2</code> removes it from <code data-x="">d1</code>.</p>
60335+
60336+
<p>The same happens when the user activates the <code>summary</code> element inside of <code
60337+
data-x="">d2</code>.</p>
60338+
</div>
60339+
6011060340
<div class="example">
6011160341

6011260342
<p>Because the <code data-x="attr-details-open">open</code> attribute is added and removed
@@ -108878,8 +109108,17 @@ document.body.appendChild(frame)</code></pre>
108878109108
<span>erase all event listeners and handlers</span> given <var>document</var>'s <span>relevant
108879109109
global object</span>.</p></li>
108880109110

109111+
<li>Let <var>oldFlag</var> be the value of <var>document</var>'s <span
109112+
data-x="concept-document-fire-mutation-events-flag">fire mutation events flag</span>.</li>
109113+
109114+
<li>Set <var>document</var>'s <span data-x="concept-document-fire-mutation-events-flag">fire
109115+
mutation events flag</span> to false.</li>
109116+
108881109117
<li><p><span data-x="concept-node-replace-all">Replace all</span> with null within
108882-
<var>document</var>, without firing any mutation events.</p></li>
109118+
<var>document</var>.</p></li>
109119+
109120+
<li>Set <var>document</var>'s <span data-x="concept-document-fire-mutation-events-flag">fire
109121+
mutation events flag</span> to <var>oldFlag</var>.</li>
108883109122

108884109123
<li>
108885109124
<p>If <var>document</var> is <span>fully active</span>, then:</p>
@@ -134246,6 +134485,7 @@ interface <dfn interface>External</dfn> {
134246134485
<td><code>summary</code>*;
134247134486
<span data-x="Flow content">flow</span></td>
134248134487
<td><span data-x="global attributes">globals</span>;
134488+
<code data-x="attr-details-name">name</code>;
134249134489
<code data-x="attr-details-open">open</code></td>
134250134490
<td><code>HTMLDetailsElement</code></td>
134251134491
</tr>
@@ -136517,6 +136757,11 @@ interface <dfn interface>External</dfn> {
136517136757
<span data-x="attr-fe-name">form-associated custom elements</span>
136518136758
<td> Name of the element to use for <span>form submission</span> and in the <code data-x="dom-form-elements">form.elements</code> API <!--or: Name of the element to use in the <code data-x="dom-form-elements">form.elements</code> API. -->
136519136759
<td> <a href="#attribute-text">Text</a>*
136760+
<tr>
136761+
<th> <code data-x="">name</code>
136762+
<td> <code data-x="attr-details-name">details</code>
136763+
<td> Name of group of mutually-exclusive <code>details</code> elements
136764+
<td> <a href="#attribute-text">Text</a>*
136520136765
<tr>
136521136766
<th> <code data-x="">name</code>
136522136767
<td> <code data-x="attr-form-name">form</code>

0 commit comments

Comments
 (0)