Skip to content

Commit

Permalink
Make reflect work for ElementInternals
Browse files Browse the repository at this point in the history
  • Loading branch information
annevk committed Dec 12, 2022
1 parent 66bc0c4 commit 02193b2
Showing 1 changed file with 78 additions and 76 deletions.
154 changes: 78 additions & 76 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -7554,16 +7554,31 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute

<h4>Reflecting content attributes in IDL attributes</h4>

<p>Some IDL attributes are defined to <dfn>reflect</dfn> a particular content attribute. This
means that on getting, the IDL attribute returns the current value of the content attribute, and
on setting, the IDL attribute changes the value of the content attribute to the given value.</p>
<p>IDL attributes of <span data-x="reflect target">reflect targets</span> can be defined to
<dfn>reflect</dfn> a particular content attribute. This means that on getting, the IDL attribute
returns the current value of the content attribute, and on setting, the IDL attribute changes the
value of the content attribute to the given value.</p>

<p>A <dfn>reflect target</dfn> is an element or <code>ElementInternals</code> object.</p>

<div w-nodev>

<p>In general, on getting, if the content attribute is not present, the IDL attribute must act as
if the content attribute's value is the empty string; and on setting, if the content attribute is
not present, it must first be added.</p>

<p>For <code>ElementInternals</code> objects the content attributes are the <span data-x="map
key">keys</span> of their <span data-x="internals-target">target element</span>'s <span>native
accessibility semantics map</span>. Any manipulation of content attributes as part of the
<span>reflect</span> algorithms ends up impacting that map accordingly.</p>

<p class="note">This results in somewhat redundant data structures for
<code>ElementInternals</code> objects as their <span data-x="internals-target">target
element</span>'s <span>native accessibility semantics map</span> cannot be directly manipulated
and as such reflection is only happening in a single direction. This approach was nevertheless
chosen to make it less error-prone to define IDL attributes shared between <span data-x="reflect
target">reflect targets</span>.</p>

<p>IDL attributes of type <code data-x="idl-DOMString">DOMString</code> or <code data-x=""><span
data-x="idl-DOMString">DOMString</span>?</code> that reflect <span data-x="enumerated
attribute">enumerated</span> content attributes can be <dfn>limited to only known values</dfn>.
Expand All @@ -7582,7 +7597,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<span>limited to only known values</span>:</p>

<ol>
<li><p>If the content attribute is not in any state (e.g. the attribute is missing and there
<li><p>If the content attribute is not in any state (e.g., the attribute is missing and there
is no <i data-x="missing value default">missing value default</i>), or the content attribute
is in a state with no associated keyword value, then return the empty string.</p></li>

Expand Down Expand Up @@ -7786,37 +7801,47 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute

<p>If a reflecting IDL attribute has the type <code>DOMTokenList</code>, then on getting it must
return a <code>DOMTokenList</code> object whose associated element is the element in question and
whose associated attribute's local name is the name of the attribute in question.</p>
whose associated attribute's local name is the name of the attribute in question. IDL attributes
of this type are not supported for <code>ElementInternals</code> objects.</p>
<!-- Supporting ElementInternals is doable, but would require corresponding changes to
DOMTokenList. -->

<p>If a reflecting IDL attribute <var>attr</var> has the type <code
data-x=""><var>T</var>?</code>, where <var>T</var> is either <code>Element</code> or an
interface that inherits from <code>Element</code>, then:

<ul>
<li><p>Elements of the type this IDL attribute appears on have an <dfn>explicitly set
<var>attr</var>-element</dfn>, which is a weak reference to an element or null. It is initially
null.</p></li>
<li><p><span data-x="reflect target">Reflect targets</span> of the type this IDL attribute
appears on have an <dfn>explicitly set <var>attr</var>-element</dfn>, which is a weak reference
to an element or null. It is initially null.</p></li>

<li>
<p>Elements of the type this IDL attribute appears on have an <dfn for="Element"
export><var>attr</var>-associated element</dfn>. To compute the <span><var>attr</var>-associated
element</span> for such an element <var>element</var>:</p>
<p><span data-x="reflect target">Reflect targets</span> of the type this IDL attribute appears
on have an <dfn for="Element,ElementInternals" export><var>attr</var>-associated element</dfn>.
To compute the <span><var>attr</var>-associated element</span> for such a <span>reflect
target</span> <var>reflectTarget</var>:</p>

<ol>
<li><p>Let <var>element</var> be <var>reflectTarget</var> if it is an element; otherwise
<var>reflectTarget</var>'s <span data-x="internals-target">target element</span>.</p></li>

<li>
<p>If <var>element</var>'s <span>explicitly set <var>attr</var>-element</span> is not null:</p>
<p>If <var>reflectTarget</var>'s <span>explicitly set <var>attr</var>-element</span> is not
null:</p>

<ul>
<li><p>If <var>element</var>'s <span>explicitly set <var>attr</var>-element</span> is a
<li><p>If <var>reflectTarget</var>'s <span>explicitly set <var>attr</var>-element</span> is a
<span>descendant</span> of any of <var>element</var>'s <span
data-x="concept-shadow-including-ancestor">shadow-including ancestors</span>, then return
<var>element</var>'s <span>explicitly set <var>attr</var>-element</span>.</p></li>
<li><p>Otherwise, return null.</p></li>
<var>reflectTarget</var>'s <span>explicitly set <var>attr</var>-element</span>.</p></li>

<li><p>Return null.</p></li>
</ul>
</li>

<li>
<p>Otherwise, if the content attribute is present on <var>element</var>, then return the first
element <var>candidate</var>, in <span>tree order</span>, that meets the following
<p>Otherwise, if the content attribute is present on <var>reflectTarget</var>, return the
first element <var>candidate</var>, in <span>tree order</span>, that meets the following
criteria:</p>

<ul class="brief">
Expand All @@ -7834,10 +7859,10 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
</ol>

<p class="note">Other parts of this specification, or other specifications using attribute
reflection, are expected to consult an element's <span><var>attr</var>-associated
element</span>. An element's <span>explicitly set <var>attr</var>-element</span> is an internal
implementation detail of its <span><var>attr</var>-associated element</span> and is not to be
used directly.</p>
reflection, are expected to consult a <span>reflect target</span>'s
<span><var>attr</var>-associated element</span>. A <span>reflect target</span>'s
<span>explicitly set <var>attr</var>-element</span> is an internal implementation detail of its
<span><var>attr</var>-associated element</span> and is not to be used directly.</p>
</li>

<li><p>The getter steps are to return <span>this</span>'s <span><var>attr</var>-associated
Expand Down Expand Up @@ -7871,6 +7896,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
steps</span>, given <var>element</var>, <var>localName</var>, <var>oldValue</var>,
<var>value</var>, and <var>namespace</var>, are used to synchronize between the content
attribute and the IDL attribute:</p>

<ol>
<li><p>If <var>localName</var> is not the content attribute's local name, or
<var>namespace</var> is not null, then return.</p></li>
Expand All @@ -7885,36 +7911,41 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
data-x="">FrozenArray&lt;<var>T</var>&gt;?</code>, where <var>T</var> is either
<code>Element</code> or an interface that inherits from <code>Element</code>, then:</p>

<!-- TODO: indentation here is wrong -->
<ul>
<li><p>Elements of the type this IDL attribute appears on have <dfn>explicitly set
<var>attr</var>-elements</dfn>, which is either a <span>list</span> of weak references to elements
or null. It is initially null.</p></li>
<li><p><span data-x="reflect target">Reflect targets</span> of the type this IDL attribute appears
on have <dfn>explicitly set <var>attr</var>-elements</dfn>, which is either a <span>list</span> of
weak references to elements or null. It is initially null.</p></li>

<li><p>Elements of the type this IDL attribute appears on have <dfn>cached
<var>attr</var>-associated elements</dfn>, which is a <code
<li><p><span data-x="reflect target">Reflect targets</span> of the type this IDL attribute appears
on have <dfn>cached <var>attr</var>-associated elements</dfn>, which is a <code
data-x="">FrozenArray&lt;<var>T</var>&gt;?</code>. It is initially null.</p></li>

<li>
<p>Elements of the type this IDL attribute appears on have <dfn for="Element"
export><var>attr</var>-associated elements</dfn>. To compute the <span><var>attr</var>-associated
elements</span> for such an element <var>element</var>:</p>
<p><span data-x="reflect target">Reflect targets</span> of the type this IDL attribute appears on
have <dfn for="Element,ElementInternals" export><var>attr</var>-associated elements</dfn>. To
compute the <span><var>attr</var>-associated elements</span> for such a <span>reflect
target</span> <var>reflectTarget</var>:</p>

<ol>
<li><p>Let <var>elements</var> be an empty <span>list</span>.</p></li>

<li><p>Let <var>element</var> be <var>reflectTarget</var> if it is an element; otherwise
<var>reflectTarget</var>'s <span data-x="internals-target">target element</span>.</p></li>

<li>
<p>If <var>element</var>'s <span>explicitly set <var>attr</var>-elements</span> is not
null, then:</p>
<p>If <var>reflectTarget</var>'s <span>explicitly set <var>attr</var>-elements</span> is not
null:</p>

<ol>
<li>
<p><span data-x="list iterate">For each</span> <var>attrElement</var> in the <var>element</var>'s
<span>explicitly set <var>attr</var>-elements</span>:</p>
<p><span data-x="list iterate">For each</span> <var>attrElement</var> in
<var>reflectTarget</var>'s <span>explicitly set <var>attr</var>-elements</span>:</p>

<ol>
<li><p>If <var>attrElement</var> is not a <span>descendant</span> of any of <var>element</var>'s <span
data-x="concept-shadow-including-ancestor">shadow-including ancestors</span>, then
<span>continue</span>.</p></li>
<li><p>If <var>attrElement</var> is not a <span>descendant</span> of any of
<var>element</var>'s <span data-x="concept-shadow-including-ancestor">shadow-including
ancestors</span>, then <span>continue</span>.</p></li>

<li><p><span data-x="list append">Append</span> <var>attrElement</var> to <var>elements</var>.</p></li>
</ol>
Expand All @@ -7925,13 +7956,15 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li>
<p>Otherwise:</p>
<ol>
<li><p>If the content attribute is not present on <var>element</var>, return null.</p></li>
<li><p>If the content attribute is not present on <var>reflectTarget</var>, then return
null.</p></li>

<li><p>Let <var>tokens</var> be the content attribute's value, <span data-x="split a string on
ASCII whitespace">split on ASCII whitespace</span>.

<li>
<p><span data-x="list iterate">For each</span> <var>id</var> in <var>tokens</var>:</p>
<p><span data-x="list iterate">For each</span> <var>id</var> of <var>tokens</var>:</p>

<ol>
<li>
<p>Let <var>candidate</var> be the first element, in <span>tree order</span>, that meets the
Expand All @@ -7958,13 +7991,15 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
</ol>

<p class="note">Other parts of this specification, or other specifications using attribute
reflection, are expected to consult an element's <span><var>attr</var>-associated
elements</span>. An element's <span>explicitly set <var>attr</var>-elements</span> is an internal
implementation detail of its <span><var>attr</var>-associated elements</span> and is not to be
used directly. Similarly, the element's <span>cached <var>attr</var>-associated elements</span>
is an internal implementation detail of the IDL attribute's getter.</p>
reflection, are expected to consult a <span>reflect target</span>'s
<span><var>attr</var>-associated elements</span>. A <span>reflect target</span>'s
<span>explicitly set <var>attr</var>-elements</span> is an internal implementation detail of its
<span><var>attr</var>-associated elements</span> and is not to be used directly. Similarly, a
<span>reflect target</span>'s <span>cached <var>attr</var>-associated elements</span> is an
internal implementation detail of the IDL attribute's getter.</p>
</li>

<!-- TODO: indentation here is wrong -->
<li>
<p>The getter steps are:</p>

Expand Down Expand Up @@ -70916,39 +70951,6 @@ dictionary <dfn dictionary>ValidityStateFlags</dfn> {
to platform accessibility APIs</a> section for information on how this impacts platform
accessibility APIs.</p>

<p><code>ElementInternals</code> includes the <code>ARIAMixin</code> mixin. The accessors provided
by this mixin are used to manipulate the <span data-x="internals-target">target element</span>'s
<span>native accessibility semantics map</span>, as follows:</p>

<p id="dom-ElementInternals-accessibility-idl">The <span><code>ARIAMixin</code> getter
steps</span> for <code>ElementInternals</code>, given <var>internals</var>,
<var>idlAttribute</var>, and <var>contentAttribute</var>, are:</p>

<ol>
<li><p>Let <var>map</var> be <var>internals</var>'s <span data-x="internals-target">target
element</span>'s <span>native accessibility semantics map</span>.</p></li>

<li><p>If <var>map</var>[<var>contentAttribute</var>] <span data-x="map exists">exists</span>,
then return it.</p></li>

<li><p>Return null.</p></li>
</ol>

<p>The <span><code>ARIAMixin</code> setter steps</span> for <code>ElementInternals</code>, given
<var>internals</var>, <var>idlAttribute</var>, <var>contentAttribute</var>, and
<var>value</var>, are:</p>

<ol>
<li><p>Let <var>map</var> be <var>internals</var>'s <span data-x="internals-target">target
element</span>'s <span>native accessibility semantics map</span>.</p></li>

<li><p>If <var>value</var> is null, then <span data-x="map remove">remove</span>
<var>map</var>[<var>contentAttribute</var>].</p></li>

<li><p>Otherwise, <span data-x="map set">set</span> <var>map</var>[<var>contentAttribute</var>]
to <var>value</var>.</p></li>
</ol>

</div>

<h3 split-filename="semantics-other" id="common-idioms">Common idioms without dedicated elements</h3>
Expand Down

0 comments on commit 02193b2

Please sign in to comment.