Skip to content

Commit 14eac43

Browse files
committed
::details-content and ::part() are element-backed
Before this commit, ::details-content was not defined as element-backed, and all pseudos could be compounded to ::part(). Both are now defined as element-backed and can be compounded with pseudos that do not expose structural informations. w3c/csswg-drafts#10786 resolved on making these pseudos invalid at parse time but this is still unspecified.
1 parent eaa6b18 commit 14eac43

File tree

3 files changed

+61
-23
lines changed

3 files changed

+61
-23
lines changed

__tests__/value.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4389,6 +4389,17 @@ describe('<selector-list>', () => {
43894389
'::before:not(:not(:only-child))',
43904390
'::before:not(type)',
43914391
'::before:not(:hover > type)',
4392+
'::part(name):only-child',
4393+
'::part(name):empty',
4394+
'::part(name):nth-child(1)',
4395+
'::part(name):host',
4396+
'::part(name):host(:hover)',
4397+
'::part(name):host-context(:hover)',
4398+
'::part(name):scope',
4399+
'::part(name):not(:only-child)',
4400+
'::part(name):not(type)',
4401+
'::part(name):has(:hover)',
4402+
'::part(name):not(:has(:hover))',
43924403
// Invalid functional pseudo argument
43934404
':has(:not(:has(type)))',
43944405
':current(:not(type > type))',
@@ -4402,6 +4413,7 @@ describe('<selector-list>', () => {
44024413
// Invalid sub-pseudo-element
44034414
'::marker::before',
44044415
'::marker::highlight(name)',
4416+
'::part(name)::part(name)',
44054417
// Invalid pseudo-element combination (no internal structure)
44064418
'::before span',
44074419
'::before + span',
@@ -4451,20 +4463,17 @@ describe('<selector-list>', () => {
44514463
['::marker:only-child'],
44524464
['::marker:nth-child(1 of :hover)'],
44534465
['::marker:not(:only-child, :not(:nth-child(1 of :hover)))'],
4454-
['::part(name):empty'],
4455-
['::part(name):only-child'],
4456-
['::part(name):nth-child(1)'],
4457-
['::part(name):has(type)'],
4458-
['::part(name):is(type)'],
4459-
['::part(name):not(type)'],
4466+
['::part(name):current'],
4467+
['::part(name):active-view-transition-type(name)'],
4468+
['::part(name):not(:current)'],
44604469
// Sub-pseudo-element
44614470
['::after::marker'],
44624471
['::before::marker'],
44634472
['::first-letter::prefix'],
44644473
['::first-letter::suffix'],
44654474
['::before:hover::marker:focus', '::before:hover::marker:focus'],
44664475
['::part(name)::marker'],
4467-
['::part(name)::part(name)'],
4476+
['::part(name)::slotted(type)'],
44684477
['::slotted(type)::marker'],
44694478
['::slotted(type)::part(name)'],
44704479
// Nesting selector

lib/parse/preprocess.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,7 @@ function preParseCompoundSelector(node) {
200200
pseudos.logical[node.definition.name]
201201
&& findParent(
202202
node,
203-
node =>
204-
node.parent?.definition.name === '<pseudo-compound-selector>'
205-
// ::part(name):not(type) must be valid (but match nothing)
206-
&& node.children[0].value[1][1].name !== 'part',
203+
node => node.parent?.definition.name === '<pseudo-compound-selector>',
207204
node => node.definition.name === '<subclass-selector>'))
208205
) {
209206
return error(node)

lib/values/pseudos.js

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,25 @@ const viewTransitions = {
207207
},
208208
}
209209

210+
/**
211+
* @see {@link https://drafts.csswg.org/css-pseudo-4/#element-backed}
212+
*/
213+
const elemental = {
214+
functions: {
215+
'part': {
216+
classes: [/* filled at the bottom of the file */],
217+
elements: [/* filled at the bottom of the file */],
218+
value: '<ident>+',
219+
},
220+
},
221+
identifiers: {
222+
'details-content': {
223+
classes: [/* filled at the bottom of the file */],
224+
elements: [/* filled at the bottom of the file */],
225+
},
226+
},
227+
}
228+
210229
/**
211230
* @see {@link https://drafts.csswg.org/css-pseudo-4/#highlight-selectors}
212231
*/
@@ -245,21 +264,17 @@ const highlight = {
245264
const treeAbiding = {
246265
functions: {
247266
...viewTransitions.elements.functions,
248-
'part': {
249-
classes: [/* filled at the bottom of the file */],
250-
elements: [/* filled at the bottom of the file */],
251-
value: '<ident>+',
252-
},
267+
...elemental.functions,
253268
'picker': { value: '<form-control-identifier>+' },
254269
'scroll-button': { classes: ['disabled'], value: "'*' | <scroll-button-direction>" },
255270
},
256271
identifiers: {
272+
...elemental.identifiers,
257273
...viewTransitions.elements.identifiers,
258274
'after': { classes: ['empty'], elements: ['marker'] },
259275
'backdrop': {},
260276
'before': { classes: ['empty'], elements: ['marker'] },
261277
'checkmark': {},
262-
'details-content': {},
263278
'file-selector-button': {},
264279
'marker': { classes: indexedNames },
265280
'picker-icon': {},
@@ -374,12 +389,29 @@ const elements = {
374389
},
375390
}
376391

377-
treeAbiding.functions.part.classes.push(
378-
...classes.identifiers,
379-
...Object.keys(classes.functions))
380-
treeAbiding.functions.part.elements.push(
381-
...Object.keys(elements.functions),
382-
...Object.keys(elements.identifiers))
392+
const pseudoClassNames = [
393+
...classes.identifiers.filter(name =>
394+
!structural.identifiers.includes(name)
395+
&& name !== 'host'
396+
&& name !== 'scope'
397+
),
398+
...Object.keys(classes.functions).filter(name =>
399+
!structural.functions[name]
400+
&& !name.startsWith('host')),
401+
]
402+
const pseudoElementNames = [
403+
...Object.keys(elements.functions).filter(name => name !== 'part'),
404+
...Object.keys(elements.identifiers),
405+
]
406+
407+
Object.values(elemental.functions).forEach(({ classes, elements }) => {
408+
classes.push(...pseudoClassNames)
409+
elements.push(...pseudoElementNames)
410+
})
411+
Object.values(elemental.identifiers).forEach(({ classes, elements }) => {
412+
classes.push(...pseudoClassNames)
413+
elements.push(...pseudoElementNames)
414+
})
383415

384416
export {
385417
classes,

0 commit comments

Comments
 (0)