Skip to content
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

Add logic for reflecting IDREF attributes #7934

Merged
merged 7 commits into from
Jun 10, 2022
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
273 changes: 272 additions & 1 deletion source
Original file line number Diff line number Diff line change
Expand Up @@ -2714,6 +2714,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li><dfn data-x-href="https://webidl.spec.whatwg.org/#include">include</dfn></li>
<li><dfn data-x-href="https://webidl.spec.whatwg.org/#dfn-inherit">inherit</dfn></li>
<li><dfn data-x-href="https://webidl.spec.whatwg.org/#dfn-interface-prototype-object">interface prototype object</dfn></li>
<li><dfn data-x-href="https://webidl.spec.whatwg.org/#implements">implements</dfn></li>
<li><dfn data-x-href="https://webidl.spec.whatwg.org/#es-platform-objects">[[Realm]] field of a platform object</dfn></li>
<li><dfn data-x-href="https://webidl.spec.whatwg.org/#dfn-callback-context">callback context</dfn></li>
<li><dfn data-x-href="https://webidl.spec.whatwg.org/#dfn-frozen-array-type">frozen array</dfn> and
Expand Down Expand Up @@ -3052,6 +3053,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#concept-tree-root">root</dfn> and <dfn data-x-href="https://dom.spec.whatwg.org/#concept-shadow-including-root">shadow-including root</dfn> concepts</li>
<li>The <dfn data-x-href="https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor">inclusive ancestor</dfn>,
<dfn data-x-href="https://dom.spec.whatwg.org/#concept-tree-descendant">descendant</dfn>,
<dfn data-x="concept-shadow-including-ancestor" data-x-href="https://dom.spec.whatwg.org/#concept-shadow-including-ancestor">shadow-including ancestor</dfn>,
<dfn data-x-href="https://dom.spec.whatwg.org/#concept-shadow-including-descendant">shadow-including descendant</dfn>,
<dfn data-x-href="https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-descendant">shadow-including inclusive descendant</dfn>, and
<dfn data-x-href="https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-ancestor">shadow-including inclusive ancestor</dfn> concepts</li>
Expand Down Expand Up @@ -7566,8 +7568,277 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
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>

</div>
<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 for="Element"
export>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 data-export=""><var>attr</var>-associated
mrego marked this conversation as resolved.
Show resolved Hide resolved
element</dfn>. To compute the <span><var>attr</var>-associated element</span> for such an
element <var>element</var>:</p>

<ol>
<li>
<p>If <var>element</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
<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>
</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
criteria:</p>

<ul class="brief">
<li><var>candidate</var>'s <span>root</span> is the same as <var>element</var>'s
<span>root</span>,</li>
<li><var>candidate</var>'s <span data-x="concept-ID">ID</span> is the value of the content
attribute, and</li>
<li><var>candidate</var> <span>implements</span> <var>T</var>.</li>
</ul>

<p>If no such element exists, then return null.</p>
</li>

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

<p class="note">Other parts of this specification, or other specifications using attribute
reflection, are expected to consult the <span><var>attr</var>-associated element</span>. An
mrego marked this conversation as resolved.
Show resolved Hide resolved
element's <span>explicitly set <var>attr</var>-element</span> is an internal implementation
detail of the <span><var>attr</var>-associated element</span> and is not to be used
mrego marked this conversation as resolved.
Show resolved Hide resolved
directly.</p>
mrego marked this conversation as resolved.
Show resolved Hide resolved
</li>
mrego marked this conversation as resolved.
Show resolved Hide resolved

<li><p>On getting, the IDL attribute must return this element's <span><var>attr</var>-associated
mrego marked this conversation as resolved.
Show resolved Hide resolved
element</span>.</p></li>
mrego marked this conversation as resolved.
Show resolved Hide resolved

<li>
<p>On setting, the IDL attribute must perform the following steps:</p>
<ol>
<li><p>Let <var>id</var> be the empty string.</p></li>

<li><p>If the given value:</p>
mrego marked this conversation as resolved.
Show resolved Hide resolved
<ul class="brief">
<li>has the same <span>root</span> as this element, and</li>
<li>has an <code data-x="attr-id">id</code> attribute, and</li>
<li>is the first element in this element's <span>node tree</span> whose <span
data-x="concept-ID">ID</span> is the value of that <code data-x="attr-id">id</code>
attribute,</li>
</ul>
<p>then set <var>id</var> to the given value's <span data-x="concept-ID">ID</span>.</p>

<li><p>Set the content attribute's value for this element to <var>id</var>.</p></li>

<li><p>Set this element's <span>explicitly set <var>attr</var>-element</span> to be a weak
mrego marked this conversation as resolved.
Show resolved Hide resolved
reference to the given value.</p></li>
</ol>
</li>

<li>
<p>The following <span data-x="concept-element-attributes-change-ext">attribute change
mrego marked this conversation as resolved.
Show resolved Hide resolved
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>

<li><p>Set <var>element</var>'s <span>explicitly set <var>attr</var>-element</span> to
null.</p></li>
</ol>
</li>
</ul>

<p>If a reflecting IDL attribute <var>attr</var> has the type <code
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>

<ul>
<li><p>Elements of the type this IDL attribute appears on have <dfn for="Element"
export>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>

mrego marked this conversation as resolved.
Show resolved Hide resolved
<li><p>Elements 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
data-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>

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

<li>
<p>If <var>element</var>'s <span>explicitly set <var>attr</var>-elements</span> is not
null, then:</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>
<ol>
<li><p>If <var>attrElement</var> is not a <span>descendant</span> of any of <var>element</var>'s <span
mrego marked this conversation as resolved.
Show resolved Hide resolved
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>
</li>
</ol>
</li>
<li>
<p>Otherwise:</p>
<ol>
<li><p>If the content attribute is not present on <var>element</var>, 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>
<ol>
<li>
<p>Let <var>candidate</var> be the first element, in <span>tree order</span>, that meets the
following criteria:</p>

<ul class="brief">
<li><var>candidate</var>'s <span>root</span> is the same as <var>element</var>'s
<span>root</span>,</li>
<li><var>candidate</var>'s <span data-x="concept-ID">ID</span> is <var>id</var>, and</li>
<li><var>candidate</var> <span>implements</span> <var>T</var>.</li>
</ul>

<p>If no such element exists, then <span>continue</span>.</p>
</li>

<li><p><span data-x="list append">Append</span> <var>candidate</var> to
<var>elements</var>.</p></li>
</ol>
</li>
</ol>
</li>

<li><p>Return <var>elements</var>.</p></li>
</ol>

mrego marked this conversation as resolved.
Show resolved Hide resolved
<p class="note">Other parts of this specification, or other specifications using attribute
reflection, are expected to consult the <span><var>attr</var>-associated elements</span>. An
element's <span>explicitly set <var>attr</var>-elements</span> is an internal implementation
detail of the <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>
</li>

<li>
<p>On getting, the IDL attribute must perform the following steps:</p>

<ol>
<li><p>Let <var>elements</var> be this element's <span><var>attr</var>-associated
elements</span>.</p></li>

<li><p>If the contents of <var>elements</var> is equal to the contents of this element's
<span>cached <var>attr</var>-associated elements</span>, then return this element's
<span>cached <var>attr</var>-associated elements</span>.</p></li>

<li><p>Let <var>elementsAsFrozenArray</var> be <var>elements</var>, <span
data-x="concept-idl-convert">converted</span> to a <code
data-x="">FrozenArray&lt;<var>T</var>&gt;?</code>.</p></li>

<li><p>Set this element's <span>cached <var>attr</var>-associated elements</span> to
<var>elementsAsFrozenArray</var>.</p></li>

<li><p>Return <var>elementsAsFrozenArray</var>.</p></li>
</ol>

<p class="note">This extra caching layer is necessary to preserve the invariant that <code
data-x="">element.reflectedElements === element.reflectedElements</code>.</p>
</li>

<li>
<p>On setting, the IDL attribute must perform the following steps:</p>
<ol>
<li>
<p>If the given value is null:</p>
<ol>
<li><p>Set this element's <span>explicitly set <var>attr</var>-elements</span> to
null.</p></li>

<li><p>Remove the content attribute from this element.</p></li>

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

<li><p>Let <var>value</var> be an empty string.</p></li>

<li>
<p><span data-x="list iterate">For each</span> <var>element</var> in the given value:</p>
<ol>
<li><p>If <var>value</var> is empty and <var>elements</var> is non-empty, then <span
data-x="list append">append</span> a weak reference to <var>element</var> to
<var>elements</var> and <span>continue</span>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be slightly nicer as two nested steps. On first glance I missed the "continue" which made the next step quite confusing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried to do this, but not totally sure if that was what you were looking for, please check.


<li><p><span data-x="list append">Append</span> a weak reference to <var>element</var> to
<var>elements</var>.</p></li>

<li>
<p>If <var>element</var>:</p>

<ul class="brief">
<li>does not have the same <span>root</span> as this element, or</li>
<li>has no <code data-x="attr-id">id</code> attribute, or</li>
<li>is not the first element in this element's <span>node tree</span> whose <span
data-x="concept-ID">ID</span> is the value of that <code data-x="attr-id">id</code>
attribute,</li>
</ul>

<p>then set <var>value</var> to the empty string, and <span>continue</span>.</p>
</li>

<li><p>Let <var>id</var> be <var>element</var>'s <span
data-x="concept-ID">ID</span>.</p></li>

<li><p>If <var>value</var> is not the empty string, then append U+0020 SPACE to
<var>value</var>.</p></li>

<li><p>Append <var>id</var> to <var>value</var>.</p></li>
</ol>
</li>

<li><p>Set the content attribute's value for this element to <var>value</var>.</p></li>

<li><p>Set this element's <span>explicitly set <var>attr</var>-elements</span> to
<var>elements</var>.</p></li>
</ol>
</li>

<li>
<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 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>

<li><p>Set <var>element</var>'s <span>explicitly set <var>attr</var>-elements</span> to
null.</p></li>
</ol>
</li>
</ul>

</div>

<h4>Collections</h4>

Expand Down