Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const yourConfig = {
- [Stylelint plugins](https://github.com/csstools/postcss-plugins/tree/main/plugins-stylelint)
- [cli's](https://github.com/csstools/postcss-plugins/tree/main/cli)
- [sites](https://github.com/csstools/postcss-plugins/tree/main/sites)
- [PostCSS recipes](https://github.com/csstools/postcss-plugins/tree/main/postcss-recipes)

## Our current focus

Expand Down
10 changes: 9 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/postcss-custom-media/dist/cascade-layers.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import type { Node, Root } from 'postcss';
export declare function collectCascadeLayerOrder(root: Root): WeakMap<Node, number>;
export declare function cascadeLayerNumberForNode(node: Node, layers: WeakMap<Node, number>): number | undefined;
export declare function cascadeLayerNumberForNode(node: Node, layers: WeakMap<Node, number>): number;
2 changes: 1 addition & 1 deletion plugins/postcss-custom-media/dist/index.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion plugins/postcss-custom-media/dist/index.mjs

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions plugins/postcss-custom-media/src/cascade-layers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,19 +103,19 @@ export function collectCascadeLayerOrder(root: Root) {
return out;
}

// -1 : node was not found
// 0 : node was not found
// any number : node was found, higher numbers have higher priority
// Infinity : node wasn't layered, highest priority
export function cascadeLayerNumberForNode(node: Node, layers: WeakMap<Node, number>) {
// a very large number : node wasn't layered, highest priority
export function cascadeLayerNumberForNode(node: Node, layers: WeakMap<Node, number>): number {
if (node.parent && node.parent.type === 'atrule' && (node.parent as AtRule).name.toLowerCase() === 'layer') {
if (!layers.has(node.parent)) {
return -1;
return 0;
}

return layers.get(node.parent);
return layers.get(node.parent)! + 1;
}

return Infinity;
return 10_000_000;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Infinity worked, but limited what was possible.
You can't do Infinity - 100 or Infinity * 10.

}

function normalizeLayerName(layerName: string, counter: number) {
Expand Down
3 changes: 3 additions & 0 deletions plugins/postcss-custom-properties/.tape.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ postcssTape(plugin)({
preserve: false
}
},
'specificity': {
message: 'supports different specificities of html and :root selectors'
},
'examples/example': {
message: 'minimal example',
},
Expand Down
5 changes: 5 additions & 0 deletions plugins/postcss-custom-properties/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changes to PostCSS Custom Properties

### Unreleased (minor)

- Added: support for `:where(html)` and `:where(:root)` selectors
- Fixed: cascade layers support

### 13.2.1

_July 3, 2023_
Expand Down
2 changes: 1 addition & 1 deletion plugins/postcss-custom-properties/dist/cascade-layers.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import type { Node, Root } from 'postcss';
export declare function collectCascadeLayerOrder(root: Root): WeakMap<Node, number>;
export declare function cascadeLayerNumberForNode(node: Node, layers: WeakMap<Node, number>): number | undefined;
export declare function cascadeLayerNumberForNode(node: Node, layers: WeakMap<Node, number>): number;
2 changes: 1 addition & 1 deletion plugins/postcss-custom-properties/dist/index.cjs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"use strict";var e=require("postcss-value-parser"),r=require("@csstools/cascade-layer-name-parser");const t=r.parse("csstools-implicit-layer")[0];function collectCascadeLayerOrder(e){const n=new Map,o=new Map,s=[];e.walkAtRules((e=>{var a;if("layer"!==e.name.toLowerCase())return;{let r=e.parent;for(;r;){if("atrule"!==r.type||"layer"!==r.name.toLowerCase()){if(r===e.root())break;return}r=r.parent}}let l;if(e.nodes)l=normalizeLayerName(e.params,1);else{if(!e.params.trim())return;l=e.params}let i=r.parse(l);if(null!=(a=i)&&a.length){{let r=e.parent;for(;r&&"atrule"===r.type&&"layer"===r.name.toLowerCase();){const e=o.get(r);e?(i=i.map((r=>e.concat(r))),r=r.parent):r=r.parent}}if(r.addLayerToModel(s,i),e.nodes){const r=i[0].concat(t);n.set(e,r),o.set(e,i[0])}}}));for(const e of n.values())r.addLayerToModel(s,[e]);const a=new WeakMap;for(const[e,r]of n)a.set(e,s.findIndex((e=>r.equal(e))));return a}function cascadeLayerNumberForNode(e,r){return e.parent&&"atrule"===e.parent.type&&"layer"===e.parent.name.toLowerCase()?r.has(e.parent)?r.get(e.parent):-1:1/0}function normalizeLayerName(e,r){return e.trim()?e:"csstools-anon-layer--"+r++}const n=/(!\s*)?postcss-custom-properties:\s*off\b/i,o=new WeakMap;function isBlockIgnored(e){if(!e||!e.nodes)return!1;if(o.has(e))return o.get(e);const r=e.some((e=>isIgnoreComment(e,n)));return o.set(e,r),r}const s=/(!\s*)?postcss-custom-properties:\s*ignore\s+next\b/i;function isDeclarationIgnored(e){return!!e&&(!!isBlockIgnored(e.parent)||isIgnoreComment(e.prev(),s))}function isIgnoreComment(e,r){return!!e&&"comment"===e.type&&r.test(e.text)}const a=new Set(["layer"]);function isProcessableRule(e){if(!isHtmlRule(e)&&!isRootRule(e))return!1;let r=e.parent;for(;r;){if("atrule"===r.type&&!a.has(r.name.toLowerCase()))return!1;r=r.parent}return!0}const l=/^html$/i,i=/^:root$/i;function isHtmlRule(e){return e.selectors.some((e=>l.test(e)))&&e.nodes&&e.nodes.length}function isRootRule(e){return e.selectors.some((e=>i.test(e)))&&e.nodes&&e.nodes.length}const c=/^var$/i;function isVarFunction(e){return"function"===e.type&&c.test(e.value)&&Object(e.nodes).length>0}function removeCyclicReferences(e,r){const t=new Set;let n=r;for(;e.size>0;)try{toposort(Array.from(e.keys()),n);break}catch(r){if(!r._graphNode)throw r;e.delete(r._graphNode),t.add(r._graphNode),n=n.filter((e=>-1===e.indexOf(r._graphNode)))}return t}function toposort(e,r){let t=e.length;const n=new Array(t),o={};let s=t;const a=makeOutgoingEdges(r),l=makeNodesHash(e);for(;s--;)o[s]||visit(e[s],s,new Set);return n;function visit(e,r,s){if(s.has(e)){const r=new Error("Cyclic dependency"+JSON.stringify(e));throw r._graphNode=e,r}if(!l.has(e))return;if(o[r])return;o[r]=!0;let i=a.get(e)||new Set;if(i=Array.from(i),r=i.length){s.add(e);do{const e=i[--r];visit(e,l.get(e),s)}while(r);s.delete(e)}n[--t]=e}}function makeOutgoingEdges(e){const r=new Map;for(let t=0,n=e.length;t<n;t++){const n=e[t];r.has(n[0])||r.set(n[0],new Set),r.has(n[1])||r.set(n[1],new Set),r.get(n[0]).add(n[1])}return r}function makeNodesHash(e){const r=new Map;for(let t=0,n=e.length;t<n;t++)r.set(e[t],t);return r}function getCustomPropertiesFromRoot(r){const t=new Map,n=new Map,o=new Map,s=new Map,a=new Map,l=collectCascadeLayerOrder(r);r.walkRules((e=>{isProcessableRule(e)&&(isBlockIgnored(e)||(isHtmlRule(e)?e.each((e=>{if("decl"!==e.type)return;if(!e.variable||isDeclarationIgnored(e))return;if("initial"===e.value.toLowerCase().trim())return;const r=cascadeLayerNumberForNode(e,l),n=s.get(e.prop)??-1;r&&r>=n&&(s.set(e.prop,r),t.set(e.prop,e.value))})):isRootRule(e)&&e.each((e=>{if("decl"!==e.type)return;if(!e.variable||isDeclarationIgnored(e))return;if("initial"===e.value.toLowerCase().trim())return;const r=cascadeLayerNumberForNode(e,l),t=a.get(e.prop)??-1;r&&r>=t&&(a.set(e.prop,r),n.set(e.prop,e.value))}))))}));for(const[e,r]of t.entries())o.set(e,r);for(const[e,r]of n.entries())o.set(e,r);const i=[],c=new Map;for(const[r,t]of o.entries()){const n=e(t);e.walk(n.nodes,(e=>{if(isVarFunction(e)){const[t]=e.nodes.filter((e=>"word"===e.type));i.push([t.value,r])}})),c.set(r,e(t))}return removeCyclicReferences(c,i),c}function transformValueAST(r,t){if(r.nodes&&r.nodes.length){const n=new Map;r.nodes.forEach((e=>{n.set(e,r)})),e.walk(r.nodes,(e=>{"nodes"in e&&e.nodes.length&&e.nodes.forEach((r=>{n.set(r,e)}))})),e.walk(r.nodes,(r=>{if(!isVarFunction(r))return;const[o,...s]=r.nodes.filter((e=>"div"!==e.type)),{value:a}=o,l=n.get(r);if(!l)return;const i=l.nodes.indexOf(r);if(-1===i)return;let c=!1;s&&e.walk(s,(e=>{if(isVarFunction(e)){const[r]=e.nodes.filter((e=>"word"===e.type));if(t.has(r.value))return;return c=!0,!1}}));let u=[];if(t.has(a)){var p;u=(null==(p=t.get(a))?void 0:p.nodes)??[]}else{if(!s.length||c)return;u=r.nodes.slice(r.nodes.indexOf(s[0]))}u.length?(l.nodes.splice(i,1,...u),l.nodes.forEach((e=>n.set(e,l)))):(l.nodes.splice(i,1,{type:"comment",value:"",sourceIndex:r.sourceIndex,sourceEndIndex:r.sourceEndIndex}),l.nodes.forEach((e=>n.set(e,l))))}),!0)}return r.toString()}var transformProperties=(r,t,n)=>{if(isTransformableDecl(r)&&!isDeclarationIgnored(r)){const a=r.value;let l=transformValueAST(e(a),t);const i=new Set;for(;l.includes("--")&&l.toLowerCase().includes("var(")&&!i.has(l);){i.add(l);l=transformValueAST(e(l),t)}if(l!==a){if(parentHasExactFallback(r,l))return void(n.preserve||r.remove());if(n.preserve){var o;const e=r.cloneBefore({value:l});hasTrailingComment(e)&&null!=(o=e.raws)&&o.value&&(e.raws.value.value=e.value.replace(u,"$1"),e.raws.value.raw=e.raws.value.value+e.raws.value.raw.replace(u,"$2"))}else{var s;r.value=l,hasTrailingComment(r)&&null!=(s=r.raws)&&s.value&&(r.raws.value.value=r.value.replace(u,"$1"),r.raws.value.raw=r.raws.value.value+r.raws.value.raw.replace(u,"$2"))}}}};const isTransformableDecl=e=>!e.variable&&e.value.includes("--")&&e.value.toLowerCase().includes("var("),hasTrailingComment=e=>{var r,t;return"value"in Object(Object(e.raws).value)&&"raw"in((null==(r=e.raws)?void 0:r.value)??{})&&u.test((null==(t=e.raws.value)?void 0:t.raw)??"")},u=/^([\W\w]+)(\s*\/\*[\W\w]+?\*\/)$/;function parentHasExactFallback(e,r){if(!e||!e.parent)return!1;let t=!1;const n=e.parent.index(e);return e.parent.each(((o,s)=>o!==e&&(!(s>=n)&&void("decl"===o.type&&o.prop.toLowerCase()===e.prop.toLowerCase()&&o.value===r&&(t=!0))))),t}function hasSupportsAtRuleAncestor(e){let r=e.parent;for(;r;)if("atrule"===r.type){if("supports"===r.name.toLowerCase()&&/([^\w]var\()|(\(top: var\(--f\))/i.test(r.params))return!0;r=r.parent}else r=r.parent;return!1}const creator=r=>{const t=!("preserve"in Object(r))||Boolean(null==r?void 0:r.preserve);if("importFrom"in Object(r))throw new Error('[postcss-custom-properties] "importFrom" is no longer supported');if("exportTo"in Object(r))throw new Error('[postcss-custom-properties] "exportTo" is no longer supported');return{postcssPlugin:"postcss-custom-properties",prepare:()=>{let r=new Map;return{Once:e=>{r=getCustomPropertiesFromRoot(e)},Declaration:n=>{if(hasSupportsAtRuleAncestor(n))return;let o=r;if(t&&n.parent){let t=!1;n.parent.each((s=>{n!==s&&"decl"===s.type&&s.variable&&!isDeclarationIgnored(s)&&(t||(o=new Map(r),t=!0),"initial"!==s.value.toLowerCase().trim()?o.set(s.prop,e(s.value)):o.delete(s.prop))}))}transformProperties(n,o,{preserve:t})}}}}};creator.postcss=!0,module.exports=creator;
"use strict";var e=require("postcss-value-parser"),r=require("@csstools/cascade-layer-name-parser");const t=r.parse("csstools-implicit-layer")[0];function collectCascadeLayerOrder(e){const n=new Map,o=new Map,s=[];e.walkAtRules((e=>{var a;if("layer"!==e.name.toLowerCase())return;{let r=e.parent;for(;r;){if("atrule"!==r.type||"layer"!==r.name.toLowerCase()){if(r===e.root())break;return}r=r.parent}}let l;if(e.nodes)l=normalizeLayerName(e.params,1);else{if(!e.params.trim())return;l=e.params}let i=r.parse(l);if(null!=(a=i)&&a.length){{let r=e.parent;for(;r&&"atrule"===r.type&&"layer"===r.name.toLowerCase();){const e=o.get(r);e?(i=i.map((r=>e.concat(r))),r=r.parent):r=r.parent}}if(r.addLayerToModel(s,i),e.nodes){const r=i[0].concat(t);n.set(e,r),o.set(e,i[0])}}}));for(const e of n.values())r.addLayerToModel(s,[e]);const a=new WeakMap;for(const[e,r]of n)a.set(e,s.findIndex((e=>r.equal(e))));return a}function normalizeLayerName(e,r){return e.trim()?e:"csstools-anon-layer--"+r++}const n=/(!\s*)?postcss-custom-properties:\s*off\b/i,o=new WeakMap;function isBlockIgnored(e){if(!e||!e.nodes)return!1;if(o.has(e))return o.get(e);const r=e.some((e=>isIgnoreComment(e,n)));return o.set(e,r),r}const s=/(!\s*)?postcss-custom-properties:\s*ignore\s+next\b/i;function isDeclarationIgnored(e){return!!e&&(!!isBlockIgnored(e.parent)||isIgnoreComment(e.prev(),s))}function isIgnoreComment(e,r){return!!e&&"comment"===e.type&&r.test(e.text)}const a=new Set(["layer"]);function isProcessableRule(e){let r=e.parent;for(;r;){if("atrule"===r.type&&!a.has(r.name.toLowerCase()))return!1;r=r.parent}return!0}const l=/^html$/i,i=/^:where\(html\)$/i,c=/^:root$/i,u=/^:where\(:root\)$/i,p=/(html|:root)/i,f=/^var$/i;function isVarFunction(e){return"function"===e.type&&f.test(e.value)&&Object(e.nodes).length>0}function removeCyclicReferences(e,r){const t=new Set;let n=r;for(;e.size>0;)try{toposort(Array.from(e.keys()),n);break}catch(r){if(!r._graphNode)throw r;e.delete(r._graphNode),t.add(r._graphNode),n=n.filter((e=>-1===e.indexOf(r._graphNode)))}return t}function toposort(e,r){let t=e.length;const n=new Array(t),o={};let s=t;const a=makeOutgoingEdges(r),l=makeNodesHash(e);for(;s--;)o[s]||visit(e[s],s,new Set);return n;function visit(e,r,s){if(s.has(e)){const r=new Error("Cyclic dependency"+JSON.stringify(e));throw r._graphNode=e,r}if(!l.has(e))return;if(o[r])return;o[r]=!0;let i=a.get(e)||new Set;if(i=Array.from(i),r=i.length){s.add(e);do{const e=i[--r];visit(e,l.get(e),s)}while(r);s.delete(e)}n[--t]=e}}function makeOutgoingEdges(e){const r=new Map;for(let t=0,n=e.length;t<n;t++){const n=e[t];r.has(n[0])||r.set(n[0],new Set),r.has(n[1])||r.set(n[1],new Set),r.get(n[0]).add(n[1])}return r}function makeNodesHash(e){const r=new Map;for(let t=0,n=e.length;t<n;t++)r.set(e[t],t);return r}function getCustomPropertiesFromRoot(r){const t=new Map,n=new Map,o=collectCascadeLayerOrder(r);r.walkRules((e=>{var r;p.test(e.selector)&&null!=(r=e.nodes)&&r.length&&isProcessableRule(e)&&(isBlockIgnored(e)||e.selectors.forEach((r=>{let s=-1;if(i.test(r)||u.test(r))s=0;else if(l.test(r))s=1;else{if(!c.test(r))return;s=2}const a=(f=o,((p=e).parent&&"atrule"===p.parent.type&&"layer"===p.parent.name.toLowerCase()?f.has(p.parent)?f.get(p.parent)+1:0:1e7)+10+s);var p,f;e.each((e=>{if("decl"!==e.type)return;if(!e.variable||isDeclarationIgnored(e))return;if("initial"===e.value.toLowerCase().trim())return;const r=n.get(e.prop)??-1;a>=r&&(n.set(e.prop,a),t.set(e.prop,e.value))}))})))}));const s=[],a=new Map;for(const[r,n]of t.entries()){const t=e(n);e.walk(t.nodes,(e=>{if(isVarFunction(e)){const[t]=e.nodes.filter((e=>"word"===e.type));s.push([t.value,r])}})),a.set(r,e(n))}return removeCyclicReferences(a,s),a}function transformValueAST(r,t){if(r.nodes&&r.nodes.length){const n=new Map;r.nodes.forEach((e=>{n.set(e,r)})),e.walk(r.nodes,(e=>{"nodes"in e&&e.nodes.length&&e.nodes.forEach((r=>{n.set(r,e)}))})),e.walk(r.nodes,(r=>{if(!isVarFunction(r))return;const[o,...s]=r.nodes.filter((e=>"div"!==e.type)),{value:a}=o,l=n.get(r);if(!l)return;const i=l.nodes.indexOf(r);if(-1===i)return;let c=!1;s&&e.walk(s,(e=>{if(isVarFunction(e)){const[r]=e.nodes.filter((e=>"word"===e.type));if(t.has(r.value))return;return c=!0,!1}}));let u=[];if(t.has(a)){var p;u=(null==(p=t.get(a))?void 0:p.nodes)??[]}else{if(!s.length||c)return;u=r.nodes.slice(r.nodes.indexOf(s[0]))}u.length?(l.nodes.splice(i,1,...u),l.nodes.forEach((e=>n.set(e,l)))):(l.nodes.splice(i,1,{type:"comment",value:"",sourceIndex:r.sourceIndex,sourceEndIndex:r.sourceEndIndex}),l.nodes.forEach((e=>n.set(e,l))))}),!0)}return r.toString()}var transformProperties=(r,t,n)=>{if(isTransformableDecl(r)&&!isDeclarationIgnored(r)){const a=r.value;let l=transformValueAST(e(a),t);const i=new Set;for(;l.includes("--")&&l.toLowerCase().includes("var(")&&!i.has(l);){i.add(l);l=transformValueAST(e(l),t)}if(l!==a){if(parentHasExactFallback(r,l))return void(n.preserve||r.remove());if(n.preserve){var o;const e=r.cloneBefore({value:l});hasTrailingComment(e)&&null!=(o=e.raws)&&o.value&&(e.raws.value.value=e.value.replace(d,"$1"),e.raws.value.raw=e.raws.value.value+e.raws.value.raw.replace(d,"$2"))}else{var s;r.value=l,hasTrailingComment(r)&&null!=(s=r.raws)&&s.value&&(r.raws.value.value=r.value.replace(d,"$1"),r.raws.value.raw=r.raws.value.value+r.raws.value.raw.replace(d,"$2"))}}}};const isTransformableDecl=e=>!e.variable&&e.value.includes("--")&&e.value.toLowerCase().includes("var("),hasTrailingComment=e=>{var r,t;return"value"in Object(Object(e.raws).value)&&"raw"in((null==(r=e.raws)?void 0:r.value)??{})&&d.test((null==(t=e.raws.value)?void 0:t.raw)??"")},d=/^([\W\w]+)(\s*\/\*[\W\w]+?\*\/)$/;function parentHasExactFallback(e,r){if(!e||!e.parent)return!1;let t=!1;const n=e.parent.index(e);return e.parent.each(((o,s)=>o!==e&&(!(s>=n)&&void("decl"===o.type&&o.prop.toLowerCase()===e.prop.toLowerCase()&&o.value===r&&(t=!0))))),t}function hasSupportsAtRuleAncestor(e){let r=e.parent;for(;r;)if("atrule"===r.type){if("supports"===r.name.toLowerCase()&&/([^\w]var\()|(\(top: var\(--f\))/i.test(r.params))return!0;r=r.parent}else r=r.parent;return!1}const creator=r=>{const t=!("preserve"in Object(r))||Boolean(null==r?void 0:r.preserve);if("importFrom"in Object(r))throw new Error('[postcss-custom-properties] "importFrom" is no longer supported');if("exportTo"in Object(r))throw new Error('[postcss-custom-properties] "exportTo" is no longer supported');return{postcssPlugin:"postcss-custom-properties",prepare:()=>{let r=new Map;return{Once:e=>{r=getCustomPropertiesFromRoot(e)},Declaration:n=>{if(hasSupportsAtRuleAncestor(n))return;let o=r;if(t&&n.parent){let t=!1;n.parent.each((s=>{n!==s&&"decl"===s.type&&s.variable&&!isDeclarationIgnored(s)&&(t||(o=new Map(r),t=!0),"initial"!==s.value.toLowerCase().trim()?o.set(s.prop,e(s.value)):o.delete(s.prop))}))}transformProperties(n,o,{preserve:t})}}}}};creator.postcss=!0,module.exports=creator;
Loading