1 line
2.2 KiB
JavaScript
1 line
2.2 KiB
JavaScript
"use strict";var e=require("@csstools/css-tokenizer"),o=require("@csstools/css-parser-algorithms"),a=require("@csstools/css-color-parser");const t=/\bcolor-gamut\b/i;function hasConditionalAncestor(e){let o=e.parent;for(;o;)if("atrule"===o.type){if("media"===o.name.toLowerCase()&&t.test(o.params))return!0;o=o.parent}else o=o.parent;return!1}function hasOverrideOrFallback(e){var o;const a=e.prop.toLowerCase();let t=!1,s=!1;const r=(null==(o=e.parent)?void 0:o.nodes)??[],n=r.indexOf(e);for(let e=0;e<r.length;e++){if(e===n)continue;const o=r[e];if("decl"===o.type&&o.prop.toLowerCase()===a){if(!(e<n)){t=!0;break}s=!0,e=n}}return{hasOverride:t,hasFallback:s}}const s=/\b(?:color|lab|lch|oklab|oklch)\(/i,r=/^(?:color|lab|lch|oklab|oklch)$/i,creator=()=>({postcssPlugin:"postcss-gamut-mapping",prepare(){const t=new WeakMap;return{OnceExit:(n,{postcss:l})=>{n.walkDecls((n=>{const i=n.value;if(!s.test(i))return;if(!n.parent||hasConditionalAncestor(n))return;const{hasOverride:c,hasFallback:p}=hasOverrideOrFallback(n);if(c)return;const u=t.get(n.parent)||{conditionalRules:[],propNames:new Set,lastConditionParams:{media:void 0},lastConditionalRule:void 0};t.set(n.parent,u);let d=!1;const m=o.replaceComponentValues(o.parseCommaSeparatedListOfComponentValues(e.tokenize({css:i})),(e=>{if(!o.isFunctionNode(e)||!r.test(e.getName()))return;const t=a.color(e);return!t||t.syntaxFlags.has(a.SyntaxFlag.HasNoneKeywords)||a.colorDataFitsRGB_Gamut(t)?void 0:(d||a.colorDataFitsDisplayP3_Gamut(t)||(d=!0),a.serializeRGB(t,!0))})),f=o.stringify(m);if(f===i)return;const v=`(color-gamut: ${d?"rec2020":"p3"})`;if(u.lastConditionParams.media!==v&&(u.lastConditionalRule=void 0),u.lastConditionalRule)return p||n.cloneBefore({value:f}),u.lastConditionalRule.append(n.clone()),void n.remove();p||n.cloneBefore({value:f});const h=l.atRule({name:"media",params:v,source:n.parent.source,raws:{before:"\n\n",after:"\n"}}),C=n.parent.clone();C.removeAll(),C.raws.before="\n",C.append(n.clone()),n.remove(),u.lastConditionParams.media=h.params,u.lastConditionalRule=C,h.append(C),u.conditionalRules.push(h)})),n.walk((e=>{const o=t.get(e);o&&0!==o.conditionalRules.length&&o.conditionalRules.reverse().forEach((o=>{e.after(o)}))}))}}}});creator.postcss=!0,module.exports=creator;
|