Skip to content

Commit 9d0a68d

Browse files
authored
selector-specificity: view-transitions-2 (#1324)
1 parent d150a3a commit 9d0a68d

File tree

5 files changed

+38
-29
lines changed

5 files changed

+38
-29
lines changed

packages/selector-specificity/CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changes to Selector Specificity
22

3+
### Unreleased (patch)
4+
5+
- Add support for:
6+
- `:active-view-transition`
7+
- `:active-view-transition-type(foo)`
8+
39
### 3.0.2
410

511
_February 19, 2024_
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"use strict";var e=require("postcss-selector-parser");function selectorSpecificity(s){if(!s)return{a:0,b:0,c:0};let t=0,c=0,i=0;if("universal"==s.type)return{a:0,b:0,c:0};if("id"===s.type)t+=1;else if("tag"===s.type)i+=1;else if("class"===s.type)c+=1;else if("attribute"===s.type)c+=1;else if(isPseudoElement(s))switch(s.value.toLowerCase()){case"::slotted":if(i+=1,s.nodes&&s.nodes.length>0){const e=specificityOfMostSpecificListItem(s.nodes);t+=e.a,c+=e.b,i+=e.c}break;case"::view-transition-group":case"::view-transition-image-pair":case"::view-transition-old":case"::view-transition-new":return s.nodes&&1===s.nodes.length&&"selector"===s.nodes[0].type&&selectorNodeContainsOnlyUniversal(s.nodes[0])?{a:0,b:0,c:0}:{a:0,b:0,c:1};default:i+=1}else if(e.isPseudoClass(s))switch(s.value.toLowerCase()){case":-webkit-any":case":any":default:c+=1;break;case":-moz-any":case":has":case":is":case":matches":case":not":if(s.nodes&&s.nodes.length>0){const e=specificityOfMostSpecificListItem(s.nodes);t+=e.a,c+=e.b,i+=e.c}break;case":where":break;case":nth-child":case":nth-last-child":if(c+=1,s.nodes&&s.nodes.length>0){const n=s.nodes[0].nodes.findIndex((e=>"tag"===e.type&&"of"===e.value.toLowerCase()));if(n>-1){const o=[e.selector({nodes:s.nodes[0].nodes.slice(n+1),value:""})];s.nodes.length>1&&o.push(...s.nodes.slice(1));const a=specificityOfMostSpecificListItem(o);t+=a.a,c+=a.b,i+=a.c}}break;case":local":case":global":s.nodes&&s.nodes.length>0&&s.nodes.forEach((e=>{const s=selectorSpecificity(e);t+=s.a,c+=s.b,i+=s.c}));break;case":host":case":host-context":if(c+=1,s.nodes&&s.nodes.length>0){const e=specificityOfMostSpecificListItem(s.nodes);t+=e.a,c+=e.b,i+=e.c}break;case":active-view-transition":return s.nodes&&1===s.nodes.length&&"selector"===s.nodes[0].type&&selectorNodeContainsOnlyUniversal(s.nodes[0])?{a:0,b:1,c:0}:{a:0,b:2,c:0}}else e.isContainer(s)&&s.nodes.length>0&&s.nodes.forEach((e=>{const s=selectorSpecificity(e);t+=s.a,c+=s.b,i+=s.c}));return{a:t,b:c,c:i}}function specificityOfMostSpecificListItem(e){let s={a:0,b:0,c:0};return e.forEach((e=>{const t=selectorSpecificity(e);t.a>s.a?s=t:t.a<s.a||(t.b>s.b?s=t:t.b<s.b||t.c>s.c&&(s=t))})),s}function isPseudoElement(s){return e.isPseudoElement(s)}function selectorNodeContainsOnlyUniversal(e){if(!e)return!1;if(!e.nodes)return!1;const s=e.nodes.filter((e=>"comment"!==e.type));return 1===s.length&&"universal"===s[0].type}exports.compare=function compare(e,s){return e.a===s.a?e.b===s.b?e.c-s.c:e.b-s.b:e.a-s.a},exports.selectorSpecificity=selectorSpecificity;
1+
"use strict";var e=require("postcss-selector-parser");function selectorSpecificity(s){if(!s)return{a:0,b:0,c:0};let t=0,i=0,c=0;if("universal"==s.type)return{a:0,b:0,c:0};if("id"===s.type)t+=1;else if("tag"===s.type)c+=1;else if("class"===s.type)i+=1;else if("attribute"===s.type)i+=1;else if(isPseudoElement(s))switch(s.value.toLowerCase()){case"::slotted":if(c+=1,s.nodes&&s.nodes.length>0){const e=specificityOfMostSpecificListItem(s.nodes);t+=e.a,i+=e.b,c+=e.c}break;case"::view-transition-group":case"::view-transition-image-pair":case"::view-transition-old":case"::view-transition-new":return s.nodes&&1===s.nodes.length&&"selector"===s.nodes[0].type&&selectorNodeContainsNothingOrOnlyUniversal(s.nodes[0])?{a:0,b:0,c:0}:{a:0,b:0,c:1};default:c+=1}else if(e.isPseudoClass(s))switch(s.value.toLowerCase()){case":-webkit-any":case":any":default:i+=1;break;case":-moz-any":case":has":case":is":case":matches":case":not":if(s.nodes&&s.nodes.length>0){const e=specificityOfMostSpecificListItem(s.nodes);t+=e.a,i+=e.b,c+=e.c}break;case":where":break;case":nth-child":case":nth-last-child":if(i+=1,s.nodes&&s.nodes.length>0){const n=s.nodes[0].nodes.findIndex((e=>"tag"===e.type&&"of"===e.value.toLowerCase()));if(n>-1){const o=[e.selector({nodes:s.nodes[0].nodes.slice(n+1),value:""})];s.nodes.length>1&&o.push(...s.nodes.slice(1));const a=specificityOfMostSpecificListItem(o);t+=a.a,i+=a.b,c+=a.c}}break;case":local":case":global":s.nodes&&s.nodes.length>0&&s.nodes.forEach((e=>{const s=selectorSpecificity(e);t+=s.a,i+=s.b,c+=s.c}));break;case":host":case":host-context":if(i+=1,s.nodes&&s.nodes.length>0){const e=specificityOfMostSpecificListItem(s.nodes);t+=e.a,i+=e.b,c+=e.c}break;case":active-view-transition":case":active-view-transition-type":return{a:0,b:1,c:0}}else e.isContainer(s)&&s.nodes.length>0&&s.nodes.forEach((e=>{const s=selectorSpecificity(e);t+=s.a,i+=s.b,c+=s.c}));return{a:t,b:i,c:c}}function specificityOfMostSpecificListItem(e){let s={a:0,b:0,c:0};return e.forEach((e=>{const t=selectorSpecificity(e);t.a>s.a?s=t:t.a<s.a||(t.b>s.b?s=t:t.b<s.b||t.c>s.c&&(s=t))})),s}function isPseudoElement(s){return e.isPseudoElement(s)}function selectorNodeContainsNothingOrOnlyUniversal(e){if(!e)return!1;if(!e.nodes)return!1;const s=e.nodes.filter((e=>"comment"!==e.type));return 0===s.length||1===s.length&&"universal"===s[0].type}exports.compare=function compare(e,s){return e.a===s.a?e.b===s.b?e.c-s.c:e.b-s.b:e.a-s.a},exports.selectorSpecificity=selectorSpecificity;
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
import e from"postcss-selector-parser";function compare(e,s){return e.a===s.a?e.b===s.b?e.c-s.c:e.b-s.b:e.a-s.a}function selectorSpecificity(s){if(!s)return{a:0,b:0,c:0};let t=0,n=0,c=0;if("universal"==s.type)return{a:0,b:0,c:0};if("id"===s.type)t+=1;else if("tag"===s.type)c+=1;else if("class"===s.type)n+=1;else if("attribute"===s.type)n+=1;else if(isPseudoElement(s))switch(s.value.toLowerCase()){case"::slotted":if(c+=1,s.nodes&&s.nodes.length>0){const e=specificityOfMostSpecificListItem(s.nodes);t+=e.a,n+=e.b,c+=e.c}break;case"::view-transition-group":case"::view-transition-image-pair":case"::view-transition-old":case"::view-transition-new":return s.nodes&&1===s.nodes.length&&"selector"===s.nodes[0].type&&selectorNodeContainsOnlyUniversal(s.nodes[0])?{a:0,b:0,c:0}:{a:0,b:0,c:1};default:c+=1}else if(e.isPseudoClass(s))switch(s.value.toLowerCase()){case":-webkit-any":case":any":default:n+=1;break;case":-moz-any":case":has":case":is":case":matches":case":not":if(s.nodes&&s.nodes.length>0){const e=specificityOfMostSpecificListItem(s.nodes);t+=e.a,n+=e.b,c+=e.c}break;case":where":break;case":nth-child":case":nth-last-child":if(n+=1,s.nodes&&s.nodes.length>0){const i=s.nodes[0].nodes.findIndex((e=>"tag"===e.type&&"of"===e.value.toLowerCase()));if(i>-1){const o=[e.selector({nodes:s.nodes[0].nodes.slice(i+1),value:""})];s.nodes.length>1&&o.push(...s.nodes.slice(1));const a=specificityOfMostSpecificListItem(o);t+=a.a,n+=a.b,c+=a.c}}break;case":local":case":global":s.nodes&&s.nodes.length>0&&s.nodes.forEach((e=>{const s=selectorSpecificity(e);t+=s.a,n+=s.b,c+=s.c}));break;case":host":case":host-context":if(n+=1,s.nodes&&s.nodes.length>0){const e=specificityOfMostSpecificListItem(s.nodes);t+=e.a,n+=e.b,c+=e.c}break;case":active-view-transition":return s.nodes&&1===s.nodes.length&&"selector"===s.nodes[0].type&&selectorNodeContainsOnlyUniversal(s.nodes[0])?{a:0,b:1,c:0}:{a:0,b:2,c:0}}else e.isContainer(s)&&s.nodes.length>0&&s.nodes.forEach((e=>{const s=selectorSpecificity(e);t+=s.a,n+=s.b,c+=s.c}));return{a:t,b:n,c:c}}function specificityOfMostSpecificListItem(e){let s={a:0,b:0,c:0};return e.forEach((e=>{const t=selectorSpecificity(e);t.a>s.a?s=t:t.a<s.a||(t.b>s.b?s=t:t.b<s.b||t.c>s.c&&(s=t))})),s}function isPseudoElement(s){return e.isPseudoElement(s)}function selectorNodeContainsOnlyUniversal(e){if(!e)return!1;if(!e.nodes)return!1;const s=e.nodes.filter((e=>"comment"!==e.type));return 1===s.length&&"universal"===s[0].type}export{compare,selectorSpecificity};
1+
import e from"postcss-selector-parser";function compare(e,s){return e.a===s.a?e.b===s.b?e.c-s.c:e.b-s.b:e.a-s.a}function selectorSpecificity(s){if(!s)return{a:0,b:0,c:0};let t=0,i=0,c=0;if("universal"==s.type)return{a:0,b:0,c:0};if("id"===s.type)t+=1;else if("tag"===s.type)c+=1;else if("class"===s.type)i+=1;else if("attribute"===s.type)i+=1;else if(isPseudoElement(s))switch(s.value.toLowerCase()){case"::slotted":if(c+=1,s.nodes&&s.nodes.length>0){const e=specificityOfMostSpecificListItem(s.nodes);t+=e.a,i+=e.b,c+=e.c}break;case"::view-transition-group":case"::view-transition-image-pair":case"::view-transition-old":case"::view-transition-new":return s.nodes&&1===s.nodes.length&&"selector"===s.nodes[0].type&&selectorNodeContainsNothingOrOnlyUniversal(s.nodes[0])?{a:0,b:0,c:0}:{a:0,b:0,c:1};default:c+=1}else if(e.isPseudoClass(s))switch(s.value.toLowerCase()){case":-webkit-any":case":any":default:i+=1;break;case":-moz-any":case":has":case":is":case":matches":case":not":if(s.nodes&&s.nodes.length>0){const e=specificityOfMostSpecificListItem(s.nodes);t+=e.a,i+=e.b,c+=e.c}break;case":where":break;case":nth-child":case":nth-last-child":if(i+=1,s.nodes&&s.nodes.length>0){const n=s.nodes[0].nodes.findIndex((e=>"tag"===e.type&&"of"===e.value.toLowerCase()));if(n>-1){const o=[e.selector({nodes:s.nodes[0].nodes.slice(n+1),value:""})];s.nodes.length>1&&o.push(...s.nodes.slice(1));const a=specificityOfMostSpecificListItem(o);t+=a.a,i+=a.b,c+=a.c}}break;case":local":case":global":s.nodes&&s.nodes.length>0&&s.nodes.forEach((e=>{const s=selectorSpecificity(e);t+=s.a,i+=s.b,c+=s.c}));break;case":host":case":host-context":if(i+=1,s.nodes&&s.nodes.length>0){const e=specificityOfMostSpecificListItem(s.nodes);t+=e.a,i+=e.b,c+=e.c}break;case":active-view-transition":case":active-view-transition-type":return{a:0,b:1,c:0}}else e.isContainer(s)&&s.nodes.length>0&&s.nodes.forEach((e=>{const s=selectorSpecificity(e);t+=s.a,i+=s.b,c+=s.c}));return{a:t,b:i,c:c}}function specificityOfMostSpecificListItem(e){let s={a:0,b:0,c:0};return e.forEach((e=>{const t=selectorSpecificity(e);t.a>s.a?s=t:t.a<s.a||(t.b>s.b?s=t:t.b<s.b||t.c>s.c&&(s=t))})),s}function isPseudoElement(s){return e.isPseudoElement(s)}function selectorNodeContainsNothingOrOnlyUniversal(e){if(!e)return!1;if(!e.nodes)return!1;const s=e.nodes.filter((e=>"comment"!==e.type));return 0===s.length||1===s.length&&"universal"===s[0].type}export{compare,selectorSpecificity};

packages/selector-specificity/src/index.ts

+14-18
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export function selectorSpecificity(node: Node): Specificity {
8282
node.nodes &&
8383
node.nodes.length === 1 &&
8484
node.nodes[0].type === 'selector' &&
85-
selectorNodeContainsOnlyUniversal(node.nodes[0])
85+
selectorNodeContainsNothingOrOnlyUniversal(node.nodes[0])
8686
) {
8787
return {
8888
a: 0,
@@ -206,26 +206,18 @@ export function selectorSpecificity(node: Node): Specificity {
206206
}
207207

208208
break;
209-
210209
case ':active-view-transition':
211210
// see : https://drafts.csswg.org/css-view-transitions-2/#the-active-view-transition-pseudo
212-
213-
if (
214-
node.nodes &&
215-
node.nodes.length === 1 &&
216-
node.nodes[0].type === 'selector' &&
217-
selectorNodeContainsOnlyUniversal(node.nodes[0])
218-
) {
219-
return {
220-
a: 0,
221-
b: 1,
222-
c: 0,
223-
};
224-
}
225-
226211
return {
227212
a: 0,
228-
b: 2,
213+
b: 1,
214+
c: 0,
215+
};
216+
case ':active-view-transition-type':
217+
// see : https://drafts.csswg.org/css-view-transitions-2/#the-active-view-transition-type-pseudo
218+
return {
219+
a: 0,
220+
b: 1,
229221
c: 0,
230222
};
231223

@@ -286,7 +278,7 @@ function isPseudoElement(node: Node): boolean {
286278
return parser.isPseudoElement(node);
287279
}
288280

289-
function selectorNodeContainsOnlyUniversal(node: Selector): boolean {
281+
function selectorNodeContainsNothingOrOnlyUniversal(node: Selector): boolean {
290282
if (!node) {
291283
return false;
292284
}
@@ -299,6 +291,10 @@ function selectorNodeContainsOnlyUniversal(node: Selector): boolean {
299291
return x.type !== 'comment';
300292
});
301293

294+
if (relevantNodes.length === 0) {
295+
return true;
296+
}
297+
302298
if (relevantNodes.length !== 1) {
303299
return false;
304300
}

packages/selector-specificity/test/test.mjs

+16-9
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ assert.deepEqual(calculate(':is(#a + #a + #a, #b + #b + #b.b)'), { a: 3, b: 1, c
106106

107107
assert.deepEqual(calculate('::view-transition'), { a: 0, b: 0, c: 1 });
108108
assert.deepEqual(calculate('::view-transition-group(foo)'), { a: 0, b: 0, c: 1 });
109+
assert.deepEqual(calculate('::view-transition-group()'), { a: 0, b: 0, c: 0 });
109110
assert.deepEqual(calculate('::view-transition-group(*)'), { a: 0, b: 0, c: 0 });
110111
assert.deepEqual(calculate('::view-transition-group(*.foo)'), { a: 0, b: 0, c: 1 });
111112
assert.deepEqual(calculate('::view-transition-group(foo.foo)'), { a: 0, b: 0, c: 1 });
@@ -120,28 +121,34 @@ assert.deepEqual(calculate('::view-transition-image-pair(.foo.fooz)'), { a: 0, b
120121
assert.deepEqual(calculate('::view-transition-image-pair(foo.foo.fooz)'), { a: 0, b: 0, c: 1 });
121122
assert.deepEqual(calculate('::view-transition-image-pair(*.foo.fooz)'), { a: 0, b: 0, c: 1 });
122123
assert.deepEqual(calculate('::view-transition-old(foo)'), { a: 0, b: 0, c: 1 });
124+
assert.deepEqual(calculate('::view-transition-old()'), { a: 0, b: 0, c: 0 });
123125
assert.deepEqual(calculate('::view-transition-old(*)'), { a: 0, b: 0, c: 0 });
124126
assert.deepEqual(calculate('::view-transition-old(*.foo)'), { a: 0, b: 0, c: 1 });
125127
assert.deepEqual(calculate('::view-transition-old(foo.foo)'), { a: 0, b: 0, c: 1 });
126128
assert.deepEqual(calculate('::view-transition-old(.foo.fooz)'), { a: 0, b: 0, c: 1 });
127129
assert.deepEqual(calculate('::view-transition-old(foo.foo.fooz)'), { a: 0, b: 0, c: 1 });
128130
assert.deepEqual(calculate('::view-transition-old(*.foo.fooz)'), { a: 0, b: 0, c: 1 });
129131
assert.deepEqual(calculate('::view-transition-new(foo)'), { a: 0, b: 0, c: 1 });
132+
assert.deepEqual(calculate('::view-transition-new()'), { a: 0, b: 0, c: 0 });
130133
assert.deepEqual(calculate('::view-transition-new(*)'), { a: 0, b: 0, c: 0 });
131134
assert.deepEqual(calculate('::view-transition-new(*.foo)'), { a: 0, b: 0, c: 1 });
132135
assert.deepEqual(calculate('::view-transition-new(foo.foo)'), { a: 0, b: 0, c: 1 });
133136
assert.deepEqual(calculate('::view-transition-new(.foo.fooz)'), { a: 0, b: 0, c: 1 });
134137
assert.deepEqual(calculate('::view-transition-new(foo.foo.fooz)'), { a: 0, b: 0, c: 1 });
135138
assert.deepEqual(calculate('::view-transition-new(*.foo.fooz)'), { a: 0, b: 0, c: 1 });
136139

137-
assert.deepEqual(calculate(':active-view-transition(*)'), { a: 0, b: 1, c: 0 });
138-
assert.deepEqual(calculate(':active-view-transition(foo)'), { a: 0, b: 2, c: 0 });
139-
assert.deepEqual(calculate(':active-view-transition(.foo)'), { a: 0, b: 2, c: 0 });
140-
assert.deepEqual(calculate(':active-view-transition(.foo.bar)'), { a: 0, b: 2, c: 0 });
141-
assert.deepEqual(calculate(':active-view-transition(.foo .bar)'), { a: 0, b: 2, c: 0 });
142-
assert.deepEqual(calculate(':active-view-transition(foo, bar)'), { a: 0, b: 2, c: 0 });
140+
assert.deepEqual(calculate(':active-view-transition'), { a: 0, b: 1, c: 0 });
141+
assert.deepEqual(calculate(':active-view-transition-type(foo)'), { a: 0, b: 1, c: 0 });
142+
assert.deepEqual(calculate(':active-view-transition-type(.foo)'), { a: 0, b: 1, c: 0 });
143+
assert.deepEqual(calculate(':active-view-transition-type(.foo.bar)'), { a: 0, b: 1, c: 0 });
144+
assert.deepEqual(calculate(':active-view-transition-type(.foo .bar)'), { a: 0, b: 1, c: 0 });
145+
assert.deepEqual(calculate(':active-view-transition-type(foo, bar)'), { a: 0, b: 1, c: 0 });
143146

144-
// Invalid CSS, must be either `*` or a list of one or more custom idents
147+
// Invalid CSS.
145148
// We should still calculate some specificity.
146-
assert.deepEqual(calculate(':active-view-transition(*, bar)'), { a: 0, b: 2, c: 0 });
147-
assert.deepEqual(calculate(':active-view-transition(*, *)'), { a: 0, b: 2, c: 0 });
149+
assert.deepEqual(calculate(':active-view-transition(*)'), { a: 0, b: 1, c: 0 });
150+
assert.deepEqual(calculate(':active-view-transition(*, bar)'), { a: 0, b: 1, c: 0 });
151+
assert.deepEqual(calculate(':active-view-transition(*, *)'), { a: 0, b: 1, c: 0 });
152+
assert.deepEqual(calculate(':active-view-transition-type(*)'), { a: 0, b: 1, c: 0 });
153+
assert.deepEqual(calculate(':active-view-transition-type(*, bar)'), { a: 0, b: 1, c: 0 });
154+
assert.deepEqual(calculate(':active-view-transition-type(*, *)'), { a: 0, b: 1, c: 0 });

0 commit comments

Comments
 (0)