From 5bf215a3901c4cf9eb5fe4129d1577acccd3921e Mon Sep 17 00:00:00 2001 From: Romain Menke <11521496+romainmenke@users.noreply.github.com> Date: Thu, 23 Nov 2023 18:01:55 +0100 Subject: [PATCH] specificity: `:active-view-transition` (#1180) --- packages/selector-specificity/CHANGELOG.md | 6 +++ packages/selector-specificity/dist/index.cjs | 2 +- packages/selector-specificity/dist/index.mjs | 2 +- packages/selector-specificity/src/index.ts | 54 ++++++++++++++------ packages/selector-specificity/test/test.mjs | 9 ++++ 5 files changed, 55 insertions(+), 18 deletions(-) diff --git a/packages/selector-specificity/CHANGELOG.md b/packages/selector-specificity/CHANGELOG.md index 770a6b9fa..cda6afd42 100644 --- a/packages/selector-specificity/CHANGELOG.md +++ b/packages/selector-specificity/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes to Selector Specificity +### Unreleased (patch) + +- Add support for: + - `:active-view-transition(*)` + - `:active-view-transition(name)` + ### 3.0.0 _July 3, 2023_ diff --git a/packages/selector-specificity/dist/index.cjs b/packages/selector-specificity/dist/index.cjs index 4633d0fc3..7139faff7 100644 --- a/packages/selector-specificity/dist/index.cjs +++ b/packages/selector-specificity/dist/index.cjs @@ -1 +1 @@ -"use strict";var e=require("postcss-selector-parser");const s=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(s,(e=>String.fromCharCode(e.charCodeAt(0)+32)))}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(toLowerCaseAZ(s.value)){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":if(s.nodes&&1===s.nodes.length&&"selector"===s.nodes[0].type&&selectorNodeContainsOnlyUniversal(s.nodes[0]))return{a:0,b:0,c:0};i+=1;break;default:i+=1}else if(e.isPseudoClass(s))switch(toLowerCaseAZ(s.value)){case":-moz-any":case":-webkit-any":case":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"===toLowerCaseAZ(e.value)));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;default:c+=1}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.as.b?s=t:t.bs.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; +"use strict";var e=require("postcss-selector-parser");const s=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(s,(e=>String.fromCharCode(e.charCodeAt(0)+32)))}function selectorSpecificity(s){if(!s)return{a:0,b:0,c:0};let t=0,c=0,n=0;if("universal"==s.type)return{a:0,b:0,c:0};if("id"===s.type)t+=1;else if("tag"===s.type)n+=1;else if("class"===s.type)c+=1;else if("attribute"===s.type)c+=1;else if(isPseudoElement(s))switch(toLowerCaseAZ(s.value)){case"::slotted":if(n+=1,s.nodes&&s.nodes.length>0){const e=specificityOfMostSpecificListItem(s.nodes);t+=e.a,c+=e.b,n+=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:n+=1}else if(e.isPseudoClass(s))switch(toLowerCaseAZ(s.value)){case":-moz-any":case":-webkit-any":case":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,n+=e.c}break;case":where":break;case":nth-child":case":nth-last-child":if(c+=1,s.nodes&&s.nodes.length>0){const i=s.nodes[0].nodes.findIndex((e=>"tag"===e.type&&"of"===toLowerCaseAZ(e.value)));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,c+=a.b,n+=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,n+=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,n+=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};default:c+=1}else e.isContainer(s)&&s.nodes.length>0&&s.nodes.forEach((e=>{const s=selectorSpecificity(e);t+=s.a,c+=s.b,n+=s.c}));return{a:t,b:c,c:n}}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.as.b?s=t:t.bs.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; diff --git a/packages/selector-specificity/dist/index.mjs b/packages/selector-specificity/dist/index.mjs index 8ac79c745..83be7cda6 100644 --- a/packages/selector-specificity/dist/index.mjs +++ b/packages/selector-specificity/dist/index.mjs @@ -1 +1 @@ -import e from"postcss-selector-parser";const s=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(s,(e=>String.fromCharCode(e.charCodeAt(0)+32)))}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,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(toLowerCaseAZ(s.value)){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":if(s.nodes&&1===s.nodes.length&&"selector"===s.nodes[0].type&&selectorNodeContainsOnlyUniversal(s.nodes[0]))return{a:0,b:0,c:0};i+=1;break;default:i+=1}else if(e.isPseudoClass(s))switch(toLowerCaseAZ(s.value)){case":-moz-any":case":-webkit-any":case":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"===toLowerCaseAZ(e.value)));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;default:c+=1}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.as.b?s=t:t.bs.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}; +import e from"postcss-selector-parser";const s=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(s,(e=>String.fromCharCode(e.charCodeAt(0)+32)))}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(toLowerCaseAZ(s.value)){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(toLowerCaseAZ(s.value)){case":-moz-any":case":-webkit-any":case":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 o=s.nodes[0].nodes.findIndex((e=>"tag"===e.type&&"of"===toLowerCaseAZ(e.value)));if(o>-1){const i=[e.selector({nodes:s.nodes[0].nodes.slice(o+1),value:""})];s.nodes.length>1&&i.push(...s.nodes.slice(1));const a=specificityOfMostSpecificListItem(i);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};default:n+=1}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.as.b?s=t:t.bs.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}; diff --git a/packages/selector-specificity/src/index.ts b/packages/selector-specificity/src/index.ts index 4885c512b..bb91c95af 100644 --- a/packages/selector-specificity/src/index.ts +++ b/packages/selector-specificity/src/index.ts @@ -79,24 +79,24 @@ export function selectorSpecificity(node: Node): Specificity { case '::view-transition-new': // https://drafts.csswg.org/css-view-transitions-1/#named-view-transition-pseudo - { - if ( - node.nodes && - node.nodes.length === 1 && - node.nodes[0].type === 'selector' && - selectorNodeContainsOnlyUniversal(node.nodes[0]) - ) { - return { - a: 0, - b: 0, - c: 0, - }; - } else { - c += 1; - } + if ( + node.nodes && + node.nodes.length === 1 && + node.nodes[0].type === 'selector' && + selectorNodeContainsOnlyUniversal(node.nodes[0]) + ) { + return { + a: 0, + b: 0, + c: 0, + }; } - break; + return { + a: 0, + b: 0, + c: 1, + }; default: c += 1; @@ -204,6 +204,28 @@ export function selectorSpecificity(node: Node): Specificity { break; + case ':active-view-transition': + // see : https://drafts.csswg.org/css-view-transitions-2/#the-active-view-transition-pseudo + + if ( + node.nodes && + node.nodes.length === 1 && + node.nodes[0].type === 'selector' && + selectorNodeContainsOnlyUniversal(node.nodes[0]) + ) { + return { + a: 0, + b: 1, + c: 0, + }; + } + + return { + a: 0, + b: 2, + c: 0, + }; + default: b += 1; } diff --git a/packages/selector-specificity/test/test.mjs b/packages/selector-specificity/test/test.mjs index 519e70b67..d6d39a511 100644 --- a/packages/selector-specificity/test/test.mjs +++ b/packages/selector-specificity/test/test.mjs @@ -113,3 +113,12 @@ assert.deepEqual(calculate('::view-transition-old(foo)'), { a: 0, b: 0, c: 1 }); assert.deepEqual(calculate('::view-transition-old(*)'), { a: 0, b: 0, c: 0 }); assert.deepEqual(calculate('::view-transition-new(foo)'), { a: 0, b: 0, c: 1 }); assert.deepEqual(calculate('::view-transition-new(*)'), { a: 0, b: 0, c: 0 }); + +assert.deepEqual(calculate(':active-view-transition(*)'), { a: 0, b: 1, c: 0 }); +assert.deepEqual(calculate(':active-view-transition(foo)'), { a: 0, b: 2, c: 0 }); +assert.deepEqual(calculate(':active-view-transition(foo, bar)'), { a: 0, b: 2, c: 0 }); + +// Invalid CSS, must be either `*` or a list of one or more custom idents +// We should still calculate some specificity. +assert.deepEqual(calculate(':active-view-transition(*, bar)'), { a: 0, b: 2, c: 0 }); +assert.deepEqual(calculate(':active-view-transition(*, *)'), { a: 0, b: 2, c: 0 });