@@ -4015,10 +4015,13 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
4015
4015
<li><dfn data-x-href="https://w3c.github.io/aria/#aria-label"><code data-x="attr-aria-label">aria-label</code></dfn></li>
4016
4016
</ul>
4017
4017
4018
- <p>Finally, the following terms are defined in the ARIA specification: <ref spec=ARIA></p>
4018
+ <p>The following terms are defined in the ARIA specification: <ref spec=ARIA></p>
4019
4019
4020
4020
<ul class="brief">
4021
4021
<li><dfn data-x-href="https://w3c.github.io/aria/#dfn-accessible-name" data-x="concept-accessible-name">accessible name</dfn></li>
4022
+ <li>The <dfn data-x-href="https://w3c.github.io/aria/#AccessibilityMixin"><code>AccessibilityMixin</code></dfn> interface, with its associated
4023
+ <dfn data-x-href="https://w3c.github.io/aria/#dfn-get-the-accessibility-idl-attribute">get the accessibility IDL attribute</dfn> and
4024
+ <dfn data-x-href="https://w3c.github.io/aria/#dfn-set-the-accessibility-idl-attribute">set the accessibility IDL attribute</dfn> hooks</li>
4022
4025
</ul>
4023
4026
4024
4027
</dd>
@@ -12840,8 +12843,38 @@ interface <dfn>DOMStringMap</dfn> {
12840
12843
<h4 id="wai-aria">Requirements related to ARIA and to platform accessibility APIs</h4>
12841
12844
12842
12845
<p>User agent requirements for implementing Accessibility API semantics on <span>HTML
12843
- elements</span> are defined in <cite>HTML Accessibility API Mappings</cite>. <ref
12844
- spec=HTMLAAM></p>
12846
+ elements</span> are defined in <cite>HTML Accessibility API Mappings</cite>. In addition to the
12847
+ rules there, for a <span>custom element</span> <var>element</var>, the default WAI-ARIA role
12848
+ semantics are determined as follows: <ref spec=HTMLAAM></p>
12849
+
12850
+ <ol>
12851
+ <li><p>Let <var>map</var> be <var>element</var>'s <span>native accessibility semantics
12852
+ map</span>.</p></li>
12853
+
12854
+ <li><p>If <var>map</var>["<code data-x="">role</code>"] <span data-x="map exists">exists</span>,
12855
+ then return it.</p></li>
12856
+
12857
+ <li><p>Otherwise, return no role.</p></li>
12858
+ </ol>
12859
+
12860
+ <p>Similarly, for a <span>custom element</span> <var>element</var>, the default WAI-ARIA state and
12861
+ property semantics, for a state or property named <var>stateOrProperty</var>, are determined as
12862
+ follows:</p>
12863
+
12864
+ <ol>
12865
+ <li><p>Let <var>map</var> be <var>element</var>'s <span>native accessibility semantics
12866
+ map</span>.</p></li>
12867
+
12868
+ <li><p>If <var>map</var>[<var>stateOrProperty</var>] <span data-x="map exists">exists</span>,
12869
+ then return it.</p></li>
12870
+
12871
+ <li><p>Otherwise, return the default value for <var>stateOrProperty</var>.</p></li>
12872
+ </ol>
12873
+
12874
+ <p>For an example of this in action, see <a href="#custom-elements-accessibility-example">the
12875
+ custom elements section</a>.</p>
12876
+
12877
+ <hr>
12845
12878
12846
12879
<p>Conformance checker requirements for checking use of ARIA <code
12847
12880
data-x="attr-aria-role">role</code> and <code data-x="attr-aria-*">aria-*</code> attributes on
@@ -66455,6 +66488,61 @@ customElements.define('my-checkbox', MyCheckbox);</code></pre>
66455
66488
</form>
66456
66489
</code></pre>
66457
66490
66491
+ <h5 id="custom-elements-accessibility-example">Creating a custom element with default accessible roles, states, and properties</h5>
66492
+
66493
+ <!-- NON-NORMATIVE SECTION -->
66494
+
66495
+ <p>By using the appropriate properties of <code>ElementInternals</code>, your custom element can
66496
+ have default accessibility semantics. The following code expands our form-associated checkbox from
66497
+ the previous section to properly set its default role and checkedness, as viewed by accessibility
66498
+ technology:</p>
66499
+
66500
+ <pre><code class="js" data-x="">class MyCheckbox extends HTMLElement {
66501
+ static get formAssociated() { return true; }
66502
+
66503
+ constructor() {
66504
+ super();
66505
+ this._internals = this.attachInternals();
66506
+ this._checked = false;
66507
+ this.addEventListener('click', this._onClick.bind(this));
66508
+
66509
+ <mark> this._internals.role = "checkbox";
66510
+ this._internals.ariaChecked = false;</mark>
66511
+ }
66512
+
66513
+ get form() { return this._internals.form; }
66514
+ get name() { return this.getAttribute('name'); }
66515
+ get type() { return this.localName; }
66516
+
66517
+ get checked() { return this._checked; }
66518
+ set checked(flag) {
66519
+ this._checked = !!flag;
66520
+ this._internals.setFormValue(this._checked ? 'on' : null);
66521
+ <mark> this._internals.ariaChecked = this._checked;</mark>
66522
+ }
66523
+
66524
+ _onClick(event) {
66525
+ this.checked = !this._checked;
66526
+ }
66527
+ }
66528
+ customElements.define('my-checkbox', MyCheckbox);</code></pre>
66529
+
66530
+ <p>Note that, like for built-in elements, these are only defaults, and can be overridden by the
66531
+ page author using the <code data-x="attr-aria-role">role</code> and <code
66532
+ data-x="attr-aria-*">aria-*</code> attributes:</p>
66533
+
66534
+ <pre class="bad"><code class="html" data-x=""><!-- This markup is non-conforming -->
66535
+ <input type="checkbox" checked role="button" aria-checked="false">
66536
+
66537
+ <my-checkbox role="button" aria-checked="false">
66538
+ <script>
66539
+ document.querySelector('my-checkbox').checked = true;
66540
+ </script></code></pre>
66541
+
66542
+ <p>Custom element authors are encouraged to state what aspects of their accessibility semantics
66543
+ are strong native semantics, i.e., should not be overriden by users of the custom element. In our
66544
+ example, the author of the <code data-x="">my-checkbox</code> element would state that its role
66545
+ and aria-checked values are strong native semantics, thus discouraging code such as the above.</p>
66458
66546
66459
66547
<h5 id="custom-elements-customized-builtin-example">Creating a customized built-in element</h5>
66460
66548
@@ -67987,6 +68075,8 @@ interface <dfn>ElementInternals</dfn> {
67987
68075
readonly attribute <span>NodeList</span> <span data-x="dom-ElementInternals-labels">labels</span>;
67988
68076
};
67989
68077
68078
+ ElementInternals includes <span>AccessibilityMixin</span>;
68079
+
67990
68080
dictionary <dfn>ValidityStateFlags</dfn> {
67991
68081
boolean valueMissing = false;
67992
68082
boolean typeMismatch = false;
@@ -68058,8 +68148,8 @@ dictionary <dfn>ValidityStateFlags</dfn> {
68058
68148
<code data-x="dom-ElementInternals-checkValidity">checkValidity()</code></dt>
68059
68149
<dd><p>Returns true if <var>internals</var>'s
68060
68150
<span data-x="internals-target">target element</span> has no validity problems; false otherwise.
68061
- Fires an <code data-x="event-invalid">invalid</code> event at the element in the latter case.
68062
- </p></dd>
68151
+ Fires an <code data-x="event-invalid">invalid</code> event at the element in the latter
68152
+ case. </p></dd>
68063
68153
68064
68154
<dt><var>valid</var> = <var>internals</var> .
68065
68155
<code data-x="dom-ElementInternals-reportValidity">reportValidity()</code></dt>
@@ -68070,8 +68160,19 @@ dictionary <dfn>ValidityStateFlags</dfn> {
68070
68160
68071
68161
<dt><var>internals</var> . <code data-x="dom-ElementInternals-labels">labels</code></dt>
68072
68162
<dd><p>Returns a <code>NodeList</code> of all the <code>label</code> elements that
68073
- <var>internals</var>'s <span data-x="internals-target">target element</span> is associated with.
68074
- </p></dd>
68163
+ <var>internals</var>'s <span data-x="internals-target">target element</span> is associated
68164
+ with.</p></dd>
68165
+
68166
+ <dt><var>internals</var> . <a href="#dom-ElementInternals-accessibility-idl-get"><code>role</code></a> [ = <var>value</var> ]</dt>
68167
+ <dd><p>Sets or retrieves the default ARIA role for <var>internals</var>'s <span
68168
+ data-x="internals-target">target element</span>, which will be used unless the page author
68169
+ overrides it using the <code data-x="attr-aria-role">role</code> attribute.</p></dd>
68170
+
68171
+ <dt><var>internals</var> . <a href="#dom-ElementInternals-accessibility-idl-get"><code>aria*</code></a> [ = <var>value</var> ]</dt>
68172
+ <dd><p>Sets or retrieves various default ARIA states or property values for
68173
+ <var>internals</var>'s <span data-x="internals-target">target element</span>, which will be used
68174
+ unless the page author overrides them using the <code data-x="attr-aria-*">aria-*</code>
68175
+ attributes.</p></dd>
68075
68176
68076
68177
</dl>
68077
68178
@@ -68282,6 +68383,57 @@ dictionary <dfn>ValidityStateFlags</dfn> {
68282
68383
68283
68384
</div>
68284
68385
68386
+ <hr>
68387
+
68388
+ <p w-nohtml>By using the <code data-x="">role</code> and <code data-x="">aria*</code> properties
68389
+ of <code>ElementInternals</code>, custom element can set default accessibile roles, states, and
68390
+ property values for their custom element, similar to how native elements behave. See <a
68391
+ href="#custom-elements-accessibility-example">the example above</a> for more details.</p>
68392
+
68393
+ <div w-nodev>
68394
+
68395
+ <p>Each <span>custom element</span> has a <dfn>native accessibility semantics map</dfn>, which is
68396
+ a <span>map</span>. See the <a href="#wai-aria">Requirements related to ARIA and to platform
68397
+ accessibility APIs</a> section for information on how this impacts platform accessibility
68398
+ APIs.</p>
68399
+
68400
+ <p><code>ElementInternals</code> includes the <code>AccessibilityMixin</code> mixin. The IDL
68401
+ attributes provided by this mixin are used to manipulate the <span
68402
+ data-x="internals-target">target element</span>'s <span>native accessibility semantics
68403
+ map</span>, as follows:</p>
68404
+
68405
+ <p id="dom-ElementInternals-accessibility-idl">To <span>get the accessibility IDL attribute</span>
68406
+ for <code>ElementInternals</code>, given <var>internals</var>, <var>idlAttribute</var>, and
68407
+ <var>contentAttribute</var>:</p>
68408
+
68409
+ <ol>
68410
+ <li><p>Let <var>map</var> be this <code>ElementInternals</code>'s <span
68411
+ data-x="internals-target">target element</span>'s <span>native accessibility semantics
68412
+ map</span>.</p></li>
68413
+
68414
+ <li><p>If <var>map</var>[<var>contentAttribute</var>] <span data-x="map exists">exists</span>,
68415
+ then return it.</p></li>
68416
+
68417
+ <li><p>Return null.</p></li>
68418
+ </ol>
68419
+
68420
+ <p>To <span>set the accessibility IDL attribute</span> for <code>ElementInternals</code>, given
68421
+ <var>internals</var>, <var>idlAttribute</var>, <var>contentAttribute</var>, and
68422
+ <var>value</var>:</p>
68423
+
68424
+ <ol>
68425
+ <li><p>Let <var>map</var> be this <code>ElementInternals</code>'s <span
68426
+ data-x="internals-target">target element</span>'s <span>native accessibility semantics
68427
+ map</span>.</p></li>
68428
+
68429
+ <li><p>If <var>value</var> is null, then <span data-x="map remove">remove</span>
68430
+ <var>map</var>[<var>contentAttribute</var>].</p></li>
68431
+
68432
+ <li><p>Otherwise, set <var>map</var>[<var>contentAttribute</var>] to <var>value</var>.</p></li>
68433
+ </ol>
68434
+
68435
+ </div>
68436
+
68285
68437
<h3 split-filename="semantics-other" id="common-idioms">Common idioms without dedicated elements</h3>
68286
68438
68287
68439
<h4 id="rel-up">Bread crumb navigation</h4>
0 commit comments