Skip to content

Commit

Permalink
Make computation of directionality account for shadow trees
Browse files Browse the repository at this point in the history
This specifies (with some additional detail) the proposal in #3699 (comment). This changes three things:

* the inheritance of directionality,
* the inheritance of language, and
* the computation of dir=auto to account for shadow trees.

This builds on the work in #9452 and #9554 to refactor this section, and builds on work by Brian Kardell, Eric Meyer, and others in #7424 and in #9166 and work by fantasai, rniwa, smaug, MyIdShin, Brian Kardell, and others in #3699.

Fixes #3699.
  • Loading branch information
dbaron authored Oct 6, 2023
1 parent 2d526af commit 11dc4c7
Showing 1 changed file with 135 additions and 46 deletions.
181 changes: 135 additions & 46 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -13283,7 +13283,8 @@ Transport Protocol">HTTP&lt;/abbr> today.&lt;/p></code></pre> <!-- DO NOT REWRAP
<ref>XML</ref></p>

<p>If these attributes are omitted from an element, then the language of this element is the same
as the language of its parent element, if any.</p>
as the language of its parent element, if any (except for <code>slot</code> elements in a
<span>shadow tree</span>).</p>

<p>The <code data-x="attr-lang">lang</code> attribute in no namespace may be used on any <span
data-x="HTML elements">HTML element</span>.</p>
Expand Down Expand Up @@ -13314,28 +13315,36 @@ Transport Protocol">HTTP&lt;/abbr> today.&lt;/p></code></pre> <!-- DO NOT REWRAP

<hr>

<p>To determine the <dfn export for="Node">language</dfn> of a node, user agents must look at the
nearest ancestor element (including the element itself if the node is an element) that has a <span
data-x="attr-xml-lang"><code data-x="">lang</code> attribute in the <span>XML
namespace</span></span> set or is an <span data-x="HTML elements">HTML element</span> and has a
<code data-x="attr-lang">lang</code> in no namespace attribute set. That attribute specifies the
language of the node (regardless of its value).</p>

<p>If both the <code data-x="attr-lang">lang</code> attribute in no namespace and the <span
data-x="attr-xml-lang"><code data-x="">lang</code> attribute in the <span>XML
namespace</span></span> are set on an element, user agents must use the <span
data-x="attr-xml-lang"><code data-x="">lang</code> attribute in the <span>XML
namespace</span></span>, and the <code data-x="attr-lang">lang</code> attribute in no namespace
must be <span data-x="ignore">ignored</span> for the purposes of determining the element's
language.</p>
<p>To determine the <dfn export for="Node">language</dfn> of a node, user agents must use the
first appropriate step in the following list:</p>

<dl class="switch">
<dt>If the node is an element that has a <span data-x="attr-xml-lang"><code data-x="">lang</code>
attribute in the <span>XML namespace</span></span> set</dt>
<dd><p>Use the value of that attribute.</p></dd>

<dt>If the node is an <span data-x="HTML elements">HTML element</span> and has a <code
data-x="attr-lang">lang</code> in no namespace attribute set.</dt>
<dd><p>Use the value of that attribute.</p></dd>

<p>If node's <span data-x="inclusive ancestor">inclusive ancestors</span> do not have either
attribute set, but there is a <span>pragma-set default language</span> set, then that is the
language of the node. If there is no <span>pragma-set default language</span> set, then language
information from a higher-level protocol (such as HTTP), if any, must be used as the final
fallback language instead. In the absence of any such language information, and in cases where the
higher-level protocol reports multiple languages, the language of the node is unknown, and the
corresponding language tag is the empty string.</p>
<dt>If the node's parent is a <span>shadow root</span></dt>
<dt>If the node is a <code>slot</code> element whose <span>root</span> is a <span>shadow
root</span></dt>
<dd><p>Use the <span>language</span> of that <span>shadow root</span>'s <span
data-x="concept-DocumentFragment-host">host</span>.</p></dd>

<!-- this assumes that if there's an ancestor element, the parent must be an element -->
<dt>If the node's <span>parent element</span> is not null</dt>
<dd><p>Use the <span>language</span> of that <span>parent element</span>.</p></dd>

<dt>Otherwise</dt>
<dd><p>If there is a <span>pragma-set default language</span> set, then that is the language of
the node. If there is no <span>pragma-set default language</span> set, then language information
from a higher-level protocol (such as HTTP), if any, must be used as the final fallback language
instead. In the absence of any such language information, and in cases where the higher-level
protocol reports multiple languages, the language of the node is unknown, and the corresponding
language tag is the empty string.</p></dd>
</dl>

<p>If the resulting value is not a recognized language tag, then it must be treated as an unknown
language having the given language tag, distinct from all other languages. For the purposes of
Expand Down Expand Up @@ -13551,7 +13560,17 @@ Transport Protocol">HTTP&lt;/abbr> today.&lt;/p></code></pre> <!-- DO NOT REWRAP
<dd><p>Return '<span data-x="concept-rtl">rtl</span>'.</p></dd>

<dt><span data-x="attr-dir-auto-state">auto</span></dt>
<dd><p>Return the <span>auto directionality</span> of <var>element</var>.</p></dd>
<dd>
<ol>
<li><p>Let <var>result</var> be the <span>auto directionality</span> of
<var>element</var>.</p></li>

<li><p>If <var>result</var> is null, then return the <span>parent directionality</span> of
<var>element</var>.</p></li>

<li><p>Return <var>result</var>.</p></li>
</ol>
</dd>

<dt><span data-x="attr-dir-undefined-state">undefined</span></dt>
<dd>
Expand Down Expand Up @@ -13594,47 +13613,106 @@ Transport Protocol">HTTP&lt;/abbr> today.&lt;/p></code></pre> <!-- DO NOT REWRAP
<li><p>If <var>element</var>'s <span data-x="concept-fe-value">value</span> is not the empty
string, then return '<span data-x="concept-ltr">ltr</span>'.</p></li>

<li><p>Return the <span>parent directionality</span> of <var>element</var>.</p></li>
<li><p>Return null.</p></li>
</ol>
</li>

<li><p>Let <var>codePoint</var> be null.</p></li>
<li>
<p>If <var>element</var> is a <code>slot</code> element whose <span>root</span> is a
<span>shadow root</span> and <var>element</var>'s <span>assigned nodes</span> are not empty:</p>

<ol>
<li>
<p><span data-x="list iterate">For each</span> node <var>child</var> of <var>element</var>'s
<span>assigned nodes</span>:</p>

<ol>
<li><p>Let <var>childDirection</var> be null.</p></li>

<li><p>If <var>child</var> is a <code>Text</code> node, then set <var>childDirection</var> to
the <span>text node directionality</span> of <var>child</var>.</p></li>

<li>
<p>Otherwise:</p>

<ol>
<li><p><span>Assert</span>: <var>child</var> is an <code>Element</code> node.</p></li>

<li><p>Set <var>childDirection</var> to the <span>auto directionality</span> of
<var>child</var>.</p></li>
</ol>
</li>

<li><p>If <var>childDirection</var> is not null, then return
<var>childDirection</var>.</p></li>
</ol>
</li>

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

<li>
<p>For each <code>Text</code> node <var>text</var> that is a descendant of <var>element</var>,
in <span>tree order</span>:</p>
<p><span data-x="list iterate">For each</span> node <var>descendant</var> of
<var>element</var>'s <span data-x="descendant">descendants</span>, in <span>tree
order</span>:</p>

<ol>
<li>
<p>If <var>text</var> has an ancestor element that is a descendant of <var>element</var> and
is also one of</p>
<p>If <var>descendant</var> has an ancestor element that is a descendant of <var>element</var>
and is also one of</p>

<ul class="brief">
<li>a <code>bdi</code> element</li>
<li>a <code>script</code> element</li>
<li>a <code>style</code> element</li>
<li>a <code>textarea</code> element</li>
<li>a <code>slot</code> element whose <span>root</span> is a <span>shadow
root</span></li>
<li>an element whose <code data-x="attr-dir">dir</code> attribute is not in the <span
data-x="attr-dir-undefined-state">undefined</span> state</li>
</ul>

<p>then <span>continue</span>.</p>
</li>

<li><p>If <var>text</var>'s <span data-x="concept-cd-data">data</span> does not contain a code
point whose bidirectional character type is L, AL, or R, then <span>continue</span>.
<ref>BIDI</ref></p></li>
<li>
<p>If <var>descendant</var> is a <code>slot</code> element whose <span>root</span> is a
<span>shadow root</span>, then:</p>

<li><p>Set <var>codePoint</var> to the first code point in <var>text</var>'s <span
data-x="concept-cd-data">data</span> whose bidirectional character type is L, AL, or
R.</p></li>
<ol>
<li><p>Let <var>result</var> be the <span>auto directionality</span> of
<var>descendant</var>.</p></li>.

<li><p>If <var>result</var> is not null, then return <var>result</var>.</p></li>

<li><p><span>Break</span>.</p></li>
<li><p>Return '<span data-x="concept-ltr">ltr</span>'.</p></li>
</ol>
</li>

<li><p>If <var>descendant</var> is not a <code>Text</code> node, then
<span>continue</span>.</p></li>

<li><p>Let <var>result</var> be the <span>text node directionality</span> of
<var>descendant</var>.</li>

<li><p>If <var>result</var> is not null, then return <var>result</var>.</p></li>
</ol>
</li>

<li><p>If <var>codePoint</var> is null, then return the <span>parent directionality</span> of
<var>element</var>.</p></li>
<li><p>Return null.</p></li>
</ol>

<p>To compute the <dfn>text node directionality</dfn> given a <code>Text</code> node
<var>text</var>:</p>

<ol>
<li><p>If <var>text</var>'s <span data-x="concept-cd-data">data</span> does not contain a code
point whose bidirectional character type is L, AL, or R, then return null.
<ref>BIDI</ref></p></li>

<li><p>Let <var>codePoint</var> be the first code point in <var>text</var>'s <span
data-x="concept-cd-data">data</span> whose bidirectional character type is L, AL, or R.</p></li>

<li><p>If <var>codePoint</var> is of bidirectional character type AL or R, then return '<span
data-x="concept-rtl">rtl</span>'.</p></li>
Expand All @@ -13646,11 +13724,21 @@ Transport Protocol">HTTP&lt;/abbr> today.&lt;/p></code></pre> <!-- DO NOT REWRAP
<p>To compute the <dfn>parent directionality</dfn> given an element <var>element</var>:</p>

<ol>
<li><p>If <var>element</var> has no <span>parent element</span>, then return '<span
data-x="concept-ltr">ltr</span>'.</p></li>
<li><p>If <var>element</var> is a <code>slot</code> element whose <span>root</span> is a
<span>shadow root</span>, then return the <span data-x="the directionality">directionality</span>
of <var>element</var>'s <span>root</span>'s <span
data-x="concept-DocumentFragment-host">host</span>.</p></li>

<li><p>Let <var>parentNode</var> be <var>element</var>'s parent node.</p></li>

<li><p>If <var>parentNode</var> is a <span>shadow root</span>, then return the <span data-x="the
directionality">directionality</span> of <var>parentNode</var>'s <span
data-x="concept-DocumentFragment-host">host</span>.</p></li>

<li><p>If <var>parentNode</var> is an element, then return the <span data-x="the
directionality">directionality</span> of <var>parentNode</var>.</p></li>

<li><p>Return <span data-x="the directionality">directionality</span> of <var>element</var>'s
<span data-x="parent element">parent</span>.</p></li>
<li><p>Return '<span data-x="concept-ltr">ltr</span>'.</p></li>
</ol>

<div w-nodev>
Expand Down Expand Up @@ -129391,15 +129479,16 @@ br[clear=all i], br[clear=both i] { clear: both; }</code></pre>

<pre><code class="css">@namespace "http://www.w3.org/1999/xhtml";

[dir]:dir(ltr), bdi:dir(ltr), input[type=tel i]:dir(ltr) { direction: ltr; }
[dir]:dir(rtl), bdi:dir(rtl) { direction: rtl; }
[dir]:dir(ltr), slot:dir(ltr), bdi:dir(ltr), input[type=tel i]:dir(ltr) { direction: ltr; }
[dir]:dir(rtl), slot:dir(rtl), bdi:dir(rtl) { direction: rtl; }

address, blockquote, center, div, figure, figcaption, footer, form, header, hr,
legend, listing, main, p, plaintext, pre, summary, xmp, article, aside, h1, h2,
h3, h4, h5, h6, hgroup, nav, section, search, table, caption, colgroup, col,
thead, tbody, tfoot, tr, td, th, dir, dd, dl, dt, menu, ol, ul, li, bdi, output,
[dir=ltr i], [dir=rtl i], [dir=auto i] {
unicode-bidi: isolate; <!-- anything that's similar to display:block, plus <bdi>, <output>, and dir="" -->
slot, [dir=ltr i], [dir=rtl i], [dir=auto i] {
unicode-bidi: isolate; <!-- anything that's similar to display:block, plus
<bdi>, <output>, <slot>, and dir="" -->
}

bdo, bdo[dir] { unicode-bidi: isolate-override; } <!-- bdo[dir] rule is to override the otherwise higher-specificity attribute selectors in the previous rule -->
Expand Down

0 comments on commit 11dc4c7

Please sign in to comment.