2 lines
9.2 KiB
JavaScript
2 lines
9.2 KiB
JavaScript
|
import e from"postcss-selector-parser";import{selectorSpecificity as t}from"@csstools/selector-specificity";const n=e.pseudo({value:":is"});function sortCompoundSelectorsInsideComplexSelector(t){if(!t||!t.nodes)return;const r=[];let o=[];for(let s=0;s<t.nodes.length;s++)if("combinator"!==t.nodes[s].type)if(e.isPseudoElement(t.nodes[s]))r.push(o),o=[t.nodes[s]];else{if("tag"===t.nodes[s].type&&o.find((e=>"tag"===e.type))){const r=n.clone({}),o=t.nodes[s];o.replaceWith(r),r.append(e.selector({nodes:[o],value:void 0}))}o.push(t.nodes[s])}else r.push(o),r.push([t.nodes[s]]),o=[];r.push(o);const s=[];for(let e=0;e<r.length;e++){const t=r[e];t.sort(((e,t)=>"selector"===e.type&&"selector"===t.type&&e.nodes.length&&t.nodes.length?selectorTypeOrder(e.nodes[0])-selectorTypeOrder(t.nodes[0]):"selector"===e.type&&e.nodes.length?selectorTypeOrder(e.nodes[0])-selectorTypeOrder(t):"selector"===t.type&&t.nodes.length?selectorTypeOrder(e)-selectorTypeOrder(t.nodes[0]):selectorTypeOrder(e)-selectorTypeOrder(t)));for(let e=0;e<t.length;e++)s.push(t[e])}for(let e=s.length-1;e>=0;e--)s[e].remove(),t.prepend(s[e])}function selectorTypeOrder(t){return e.isPseudoElement(t)?r.pseudoElement:r[t.type]}const r={universal:0,tag:1,pseudoElement:2,id:3,class:4,attribute:5,pseudo:6,selector:7,string:8,root:9,comment:10};function ampersandToScope(t,n){let r,o=t.parent;for(;o;){if("rule"===o.type)return;o=o.parent}try{r=e().astSync(t.selector)}catch(e){return void t.warn(n,`Failed to parse selector : "${t.selector}" with message: "${e.message}"`)}r&&(r.walkNesting((t=>{const n=t.parent;t.replaceWith(e.pseudo({value:":scope"})),n&&sortCompoundSelectorsInsideComplexSelector(n)})),t.selector=r.toString())}function cleanupParent(e){if(!e.nodes.length)return void e.remove();const t=e.nodes.filter((e=>"comment"===e.type));t.length===e.nodes.length&&e.replaceWith(...t)}function shiftNodesBeforeParent(e,t){const n=t.index(e);if(n){const e=t.cloneBefore().removeAll().append(t.nodes.slice(0,n));e.raws.semicolon=!0,cleanupParent(e)}t.before(e),t.raws.semicolon=!0}function combinationsWithSizeN(e,t){if(t<2)throw new Error("n must be greater than 1");if(e.length<2)throw new Error("s must be greater than 1");if(Math.pow(e.length,t)>1e4)throw new Error("Too many combinations when trying to resolve a nested selector with lists, reduce the complexity of your selectors");const n=[];for(let e=0;e<t;e++)n[e]=0;const r=[];for(;;){const o=[];for(let s=t-1;s>=0;s--){let t=n[s];if(t>=e.length){if(t=0,n[s]=0,0===s)return r;n[s-1]+=1}o[s]=e[t]}r.push(o),n[n.length-1]++}}function nodesAreEquallySpecific(n){const r=n.map((t=>e().astSync(t))).map((e=>t(e))),o=r[0];for(let e=1;e<r.length;e++)if(o.a!==r[e].a||o.b!==r[e].b||o.c!==r[e].c)return!1;return!0}function mergeSelectors(t,n,r){let o=[];o=nodesAreEquallySpecific(t)||r.noIsPseudoSelector?t.map((t=>e().astSync(t))):[e().astSync(`:is(${t.join(",")})`)];const s=[];for(let t=0;t<n.length;t++){let i,l=n[t];{const t=e().astSync(l);let n=!1;t.walk((e=>{"nesting"===e.type&&(n=!0)}));const r=t.nodes[0];let o=!1;r.each((e=>"combinator"===e.type&&(o=!0,!1))),n?o&&r.insertBefore(r.at(0),e.nesting({})):(r.insertBefore(r.at(0),e.combinator({value:" "})),r.insertBefore(r.at(0),e.nesting({}))),l=t.toString()}let c=[],a=0;if(e().astSync(l).walkNesting((()=>{a++})),a>1&&o.length>1)c=combinationsWithSizeN(o,a),i=c.length;else{i=o.length;for(let e=0;e<o.length;e++){c.push([]);for(let t=0;t<a;t++)c[e].push(o[e])}}for(let t=0;t<i;t++){let n=0;const o=e().astSync(l);o.walk((o=>{if("nesting"!==o.type)return;let s=c[t][n];n++,"root"===s.type&&1===s.nodes.length&&(s=s.nodes[0]);const i=e().astSync(`:is(${s.toString()})`),l=isSimpleSelector(s.nodes[0]),a=isCompoundSelector(s.nodes[0]),p=isSimpleSelector(o),u=isCompoundSelector(o);if(l&&p)return void o.replaceWith(s.clone());if((l||a)&&(p||u)){const e=o.parent;return l&&"selector"===s.type?o.replaceWith(s.clone().nodes[0]):o.replaceWith(...s.clone().nodes),void(e&&e.nodes.length>1&&sortCompoundSelectorsInsideComplexSelector(e))}if(l){const e=o.parent;return o.replaceWith(s.clone().nodes[0]),void(e&&sortCom
|