Skip to content

Commit 0c1fc38

Browse files
committed
[css-shadow-parts-1] Add algorithm description. Fixes w3c#2650
1 parent 450d671 commit 0c1fc38

1 file changed

Lines changed: 59 additions & 33 deletions

File tree

css-shadow-parts-1/Overview.bs

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@ Introduction {#intro}
2424
=====================
2525

2626
Issue: This spec is intentionally a rough sketch at the moment.
27-
It should contain all the details necessary to evaluate the proposal,
28-
but is intentionally avoiding precise algorithms at the moment,
29-
to aid in easy comprehension
30-
and to, hopefully, discourage implementation from this sketch.
27+
It should contain all the details necessary to evaluate the proposal.
3128

3229
Shadow DOM allows authors to separate their page into "components",
3330
subtrees of markup whose details are only relevant to the component itself,
@@ -121,34 +118,64 @@ as authors can use ''::part()'' without fear of accidental over-styling.
121118

122119
Exposing a Shadow Element: {#exposing}
123120
=============================================================
124-
Each <a>shadow root</a> has a <dfn export for="shadow root">shadow part map</dfn>
121+
Elements in a <a>shadow tree</a> may be exposed for styling by stylesheets outside the tree
122+
using the part and partmap attributes.
123+
124+
Each element has a <dfn export for="element">part name list</dfn>
125+
which is an [=ordered sets=] of tokens.
126+
127+
Each element has a <dfn export for="element">part name map</dfn>
125128
which is an <a>ordered map</a>,
129+
with keys that are tokens
130+
and values that are [=ordered sets=] of tokens.
131+
132+
Each <a>shadow root</a> can be thought of as having a <dfn export for="shadow root">part element map</dfn>
126133
with keys that are [=strings=]
127134
and values that are [=ordered sets=] of elements.
128135

129-
The <a>shadow part map</a> contains all the entries named or forwarded by the elements in its <a>shadow tree</a>,
130-
as described below.
136+
The part element map is described
137+
only as part of the algorithm for calculating style in this spec.
138+
It is not exposed via the DOM,
139+
as calculating it may be expensive
140+
and exposing it could allow access to elements inside closed shadow roots.
141+
142+
Part element maps are affected by the addition and removal of elements
143+
and changes to the part name lists and part name maps of elements in the DOM.
144+
145+
To calculate the part element map of a shadow root, |r|:
146+
147+
<ol>
148+
<li>For each element, |el| within |r|
149+
<ol>
150+
<li>For each |name| in |el|'s part name list,
151+
add |el| to |r|'s part element map
152+
under the key |name|.
153+
<li>If |el| is a shadow host itself, let |er| be its shadow root:
154+
<ol>
155+
<li>Calculate |er|'s part element map.
156+
<li>For each key, |outerName|, in |r|'s part name map
157+
and for each token |innerName| under that key
158+
look up |innerName| in |er|'s shadow part element map
159+
to get a (possibly empty) set of elements
160+
and add these elements to |r|'s part element map under |outerName|
161+
</ol>
162+
</ol>
163+
</ol>
164+
165+
166+
Issue: Include wild-card forwarding in algortihm.
131167

132-
Issue: Factor this out into an algorithm.
168+
Issue: When doing prefixed-wildcard forwarding, should probably automatically exclude sub-parts that are manually forwarded. With that, would be good to have a syntax to block forwarding of a sub-part (currently would require `foo => nonsense-name`).
133169

134-
Issue: The value in the map is a set of elements, not individual elements; need to properly append.
170+
Issue: There is no need for the part element map values to be ordered, can we drop that?
135171

136172
Naming a Shadow Element: the <{html-global/part}> attribute {#part-attr}
137173
------------------------------------------------------------------------
138174

139175
Any element in a shadow tree can have a <dfn element-attr for=html-global>part</dfn> attribute.
140176
This is used to expose the element outside of the <a>shadow tree</a>.
141177

142-
The part attribute is parsed as a space-separated list of part names.
143-
Each part name is:
144-
145-
<dl class=switch>
146-
: <code>ident</code>
147-
:: Adds «[ ident → el ]» to the <a>shadow part map</a> of the <a>shadow root</a> containing the element.
148-
149-
: anything else
150-
:: Ignored for error-recovery / future compat.
151-
</dl>
178+
The part attribute is parsed as a space-separated list of tokens representing the part names of this element.
152179

153180
Note: It's okay to give a part multiple names.
154181
The "part name" should be considered similar to a class,
@@ -158,33 +185,32 @@ Forwarding a Shadow Element: the <{html-global/partmap}> attribute {#partmap-att
158185
----------------------------------------------------------------------------------
159186
Any element in a shadow tree can have a <dfn element-attr for=html-global>partmap</dfn> attribute.
160187
If the element is a shadow host,
161-
this is used to expose elements from inside this host's <a>shadow tree</a> to outside this host's containing <a>shadow tree</a>.
188+
this is used to allow styling of parts from hosts inside the <a>shadow tree</a>
189+
by rules outside this the <a>shadow tree</a>
190+
(as if they were elements in the same tree as the host,
191+
named by a part attribute).
162192

163193
The partmap attribute is parsed as a comma-separated list of part mappings.
164194
Each part mapping is one of:
165195

166196
<dl class=switch>
167-
: <code>ident1 => ident2</code>
168-
:: If el is a <a>shadow host</a>,
169-
and it's <a>shadow root's</a> <a>shadow part map</a> |partMap| [=map/contains=] ident1,
170-
then this adds «[ ident2 → |partMap|[ident1] ]» to the <a>shadow part map</a> of the <a>shadow root</a> containing el.
197+
: <code>outerIdent => innerIdent</code>
198+
:: this adds «[ outerIdent → innerIdent ]» to el's <a>part name map</a>.
171199

172200
: <code>ident</code>
173201
:: Is equivalent to <code>ident => ident</code>.
174202

175-
: <code>* => prefix*</code>
176-
:: If el is a <a>shadow host</a>,
177-
then [=map/for each=] |ident| → |subEl| in el's <a>shadow root's</a> <a>shadow part map</a>,
178-
«[ prefix + |ident| → |subEl| ]» is added to the <a>shadow part map</a> of the <a>shadow root</a> containing el.
179-
180203
: anything else
181204
:: Ignored for error-recovery / future compat.
182205
</dl>
183206

184-
Issue: When doing prefixed-wildcard forwarding, should probably automatically exclude sub-parts that are manually forwarded. With that, would be good to have a syntax to block forwarding of a sub-part (currently would require `foo => nonsense-name`).
185-
186207
Note: It's okay to map a sub-part to several names.
187208

209+
Issue: Decide whether we use "outer => inner" or vice-versa.
210+
211+
Issue: Decide whether to allow "ident1 => ident2 ident3 ..."
212+
as shorthand for "ident1 => ident2, ident1 => ident3, ...".
213+
188214
Exposing More Widely: the <{html-global/theme}> attribute {#theme-attr}
189215
-----------------------------------------------------------------------
190216

@@ -221,7 +247,7 @@ The syntaxes of them are:
221247

222248
The ''::part()'' pseudo-element only matches anything
223249
when the <a>originating element</a> is a <a>shadow host</a>.
224-
If the <a>originating element's</a> <a>shadow root's</a> <a>shadow part map</a>
250+
If the <a>originating element's</a> <a>shadow root's</a> <a>part element map</a>
225251
[=map/contains=] the specified <<ident>>,
226252
''::part()'' matches the element or elements keyed to that <<ident>>.
227253
Otherwise, it matches nothing.
@@ -272,7 +298,7 @@ but never match additional <a>shadow-part pseudo-elements</a>.
272298

273299
If the <code>&lt;x-panel></code>'s internal confirm button had used something like
274300
<code>part="confirm-button, * => confirm-*"</code>
275-
to forward the button's internal parts up into the panel's own <a>shadow part map</a>,
301+
to forward the button's internal parts up into the panel's own <a>part element map</a>,
276302
then a selector like
277303
''x-panel::part(confirm-label)''
278304
would select just the one button's label,

0 commit comments

Comments
 (0)