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 all 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
306 changes: 304 additions & 2 deletions 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,308 @@ 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>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"
mrego marked this conversation as resolved.
Show resolved Hide resolved
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>

<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 an element's <span><var>attr</var>-associated
mrego marked this conversation as resolved.
Show resolved Hide resolved
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
mrego marked this conversation as resolved.
Show resolved Hide resolved
used directly.</p>
</li>
mrego marked this conversation as resolved.
Show resolved Hide resolved

<li><p>The getter steps are to return <span>this</span>'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>The setter steps are:</p>
<ol>
<li>
<p>If the given value is null, then:</p>

mrego marked this conversation as resolved.
Show resolved Hide resolved
<ol>
<li><p>Set <span>this</span>'s <span>explicitly set <var>attr</var>-element</span> to
null.</p></li>

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

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

<li><p>Let <var>id</var> be the empty string.</p></li>

mrego marked this conversation as resolved.
Show resolved Hide resolved
<li>
<p>If the given value:</p>

<ul class="brief">
<li>has the same <span>root</span> as <span>this</span>, and</li>
<li>has an <code data-x="attr-id">id</code> attribute, and</li>
mrego marked this conversation as resolved.
Show resolved Hide resolved
<li>is the first element in <span>this</span>'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>

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

<li><p>Set <span>this</span>'s <span>explicitly set <var>attr</var>-element</span> to a weak
reference to the given value.</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
mrego marked this conversation as resolved.
Show resolved Hide resolved
<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>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
data-x="">FrozenArray&lt;<var>T</var>&gt;?</code>. 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 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>

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

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

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

<li>
<p>The getter steps are:</p>

<ol>
<li><p>Let <var>elements</var> be <span>this</span>'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 <span>this</span>'s
<span>cached <var>attr</var>-associated elements</span>, then return <span>this</span>'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 <span>this</span>'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>The setter steps are:</p>
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.

<ol>
<li>
<p>If the given value is null:</p>

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

<li><p>Remove the content attribute from <span>this</span>.</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:</p>

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

<li><p><span>Continue</span>.</p></li>
</ol>
</li>

<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 <span>this</span>, or</li>
<li>has no <code data-x="attr-id">id</code> attribute, or</li>
<li>is not the first element in <span>this</span>'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 <span>this</span> to <var>value</var>.</p></li>

<li><p>Set <span>this</span>'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 Expand Up @@ -62071,7 +62373,7 @@ callback <dfn callback>BlobCallback</dfn> = undefined (<span>Blob</span>? blob);
<code>canvas</code> element.</p></li>

<li><p>Set the <span data-x="offscreencanvas-placeholder">placeholder <code>canvas</code>
element</span> of <var>offscreenCanvas</var> to be a weak reference to this <code>canvas</code>
element</span> of <var>offscreenCanvas</var> to a weak reference to this <code>canvas</code>
element.</p></li>

<li><p>Set this <code>canvas</code> element's <span data-x="concept-canvas-context-mode">context
Expand Down