Skip to content

Commit 704a238

Browse files
authored
Reduce the amount of generated fallback css (batch 1) (#835)
* css-blank-pseudo * css-has-pseudo * postcss-tape * css-prefers-color-scheme * postcss-attribute-case-insensitive * cleanup * postcss-color-functional-notation * more tests * more tests * postcss-color-hex-alpha * cleanup * postcss-color-rebeccapurple * postcss-dir-pseudo-class * npm install * fix
1 parent fe24c28 commit 704a238

File tree

149 files changed

+2200
-739
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+2200
-739
lines changed

experimental/css-has-pseudo/.tape.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import postcssTape from '../../packages/postcss-tape/dist/index.mjs';
1+
import { postcssTape } from '../../packages/postcss-tape/dist/index.mjs';
22
import plugin from '@csstools/css-has-pseudo-experimental';
33

44
postcssTape(plugin)({

experimental/postcss-nesting/.tape.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import postcssTape from '../../packages/postcss-tape/dist/index.mjs';
1+
import { postcssTape } from '../../packages/postcss-tape/dist/index.mjs';
22
import plugin from '@csstools/postcss-nesting-experimental';
33

44
const mixinPluginRule = () => {

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/postcss-tape/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ _Internal package_
55
See [.tape.mjs](https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-base-plugin/.tape.mjs) in the base plugin for a minimal example.
66

77
```js
8-
import postcssTape from '../../packages/postcss-tape/dist/index.mjs';
8+
import { postcssTape } from '../../packages/postcss-tape/dist/index.mjs';
99
import plugin from '@csstools/postcss-base-plugin';
1010

1111
postcssTape(plugin)({
@@ -30,7 +30,7 @@ Browse the source code and tests here or see tests in plugins for more usage det
3030

3131
## After node 20 is released do a find/replace to migrate fully to workspaces :
3232

33-
- `import postcssTape from '../../packages/postcss-tape/dist/index.mjs';`
34-
- `import postcssTape from '@csstools/postcss-tape';`
33+
- `import { postcssTape } from '../../packages/postcss-tape/dist/index.mjs';`
34+
- `import { postcssTape } from '@csstools/postcss-tape';`
3535

3636
Then add `@csstools/postcss-tape` the each `package.json` as a dev dependency.

packages/postcss-tape/dist/index.cjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"use strict";var n=require("path"),e=require("fs"),o=require("assert"),s=require("postcss"),t=require("postcss-8.4"),r=require("postcss-html");function formatGitHubActionAnnotation(e,o="error",s={}){let t="::"+o;const r=Object.keys(s).map((e=>{let o=String(s[e]);return"file"===e&&process.env.GITHUB_WORKSPACE&&(o=n.relative(process.env.GITHUB_WORKSPACE,n.resolve(o))),`${e}=${t=o,t.replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/]/g,"%5D").replace(/;/g,"%3B")}`;var t})).join(",");return r&&(t+=` ${r}`),`${t}::${i=e||"",i.replace(/\r/g,"%0D").replace(/\n/g,"%0A")}`;var i}const i="----------------------------------------";function formatCSSAssertError(n,e,o,s=!1){let t="";if(t+=`\n${n}\n\n`,e.message&&(t+=`message :\n ${e.message}\n\n`),e.options)try{t+=`options :\n${JSON.stringify(e.options,null,2)}\n\n`}catch(n){}return t+=`output changed :\n${prettyDiff(o.message)}\n`,s||(t+="\n"+i),t}function formatWarningsAssertError(n,e,o,s,t=!1){let r="";if(r+=`\n${n}\n\n`,e.message&&(r+=`message :\n ${e.message}\n\n`),e.options)try{r+=`options :\n${JSON.stringify(e.options,null,2)}\n\n`}catch(n){}return r+=`unexpected or missing warnings :\n+ actual ${o.length}\n- expected ${s}\n`,t||(o.forEach((n=>{r+=`\n[${n.plugin}]: ${n.text}`})),o.length&&(r+="\n"),r+="\n"+i),r}function prettyDiff(n){return n.replace(/[^\\](\\n)/gm,((n,e)=>n.replace(e," "))).replace(/(\\t)/gm,((n,e)=>n.replace(e," "))).replace(/\+$/gm,"").replace(/^Expected values to be strictly equal:\n/,"")}const noopPlugin=()=>({postcssPlugin:"noop-plugin",Rule(){}});function reduceInformationInCssSyntaxError(n){"CssSyntaxError"!==n.name||process.env.DEBUG||(delete n.source,n.input&&delete n.input.source,delete n.postcssNode)}noopPlugin.postcss=!0;const c=process.env.GITHUB_ACTIONS&&"true"===process.env.ENABLE_ANNOTATIONS_FOR_NODE&&"true"===process.env.ENABLE_ANNOTATIONS_FOR_OS;function postcssSyntax(n){return n.postcssSyntaxHTML?r():null}module.exports=function runner(r){let a=!1;{!0!==r.postcss&&(a=!0,c?console.log(formatGitHubActionAnnotation('postcss flag not set to "true" on exported plugin object',"error",{file:"./package.json",line:1,col:1})):console.error(`\npostcss flag not set to "true"\n\n${i}`));const n=r();n.postcssPlugin&&"string"==typeof n.postcssPlugin||(a=!0,c?console.log(formatGitHubActionAnnotation('plugin name not set via "postcssPlugin"',"error",{file:"./package.json",line:1,col:1})):console.error(`\nplugin name not set via "postcssPlugin"\n\n${i}`));const o=JSON.parse(e.readFileSync("./package.json").toString());o.keywords&&o.keywords.includes("postcss-plugin")||(a=!0,c?console.log(formatGitHubActionAnnotation('package.json does not include "postcss-plugin" keyword',"error",{file:"./package.json",line:1,col:1})):console.error(`\npackage.json does not include "postcss-plugin" keyword\n\n${i}`));const s=["css-has-pseudo","css-blank-pseudo","css-prefers-color-scheme","@csstools/css-has-pseudo-experimental"].includes(o.name);o.name.startsWith("postcss-")||o.name.startsWith("@csstools/postcss-")||s||(a=!0,c?console.log(formatGitHubActionAnnotation('plugin name in package.json does not start with "postcss-"',"error",{file:"./package.json",line:1,col:1})):console.error(`\nplugin name in package.json does not start with "postcss-"\n\n${i}`)),Object.keys(Object(o.dependencies)).includes("postcss")&&!("postcssTapeSelfTest"in r)&&(a=!0,c?console.log(formatGitHubActionAnnotation("postcss should only be a peer and/or dev dependency","error",{file:"./package.json",line:1,col:1})):console.error(`\npostcss should only be a peer and/or dev dependency\n\n${i}`))}return async l=>{const p=new Set;for(const u in l){const g=l[u];g.before&&await g.before();const f=n.join(".","test",u.split(":")[0]),d=n.join(".","test",u.replace(/:/g,"."));let m="css";g.postcssSyntaxHTML&&(m="html");const S=`${f}.${m}`;let A=`${d}.expect.${m}`,$=`${d}.result.${m}`;g.expect&&(A=n.join(".","test",g.expect)),g.result&&($=n.join(".","test",g.result));const y=g.plugins??[r(g.options)],w=await e.promises.readFile(S,"utf8");let h,b="";try{b=await e.promises.readFile(A,"utf8")}catch(e){a=!0,b=!1,c?console.log(formatGitHubActionAnnotation(`${u}\n\nmissing or broken "expect" file: "${n.parse(A).base}"`,"error",{file:S,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nmissing or broken "expect" file: "${n.parse(A).base}"\n\n${i}`))}let x=!1;try{h=await s(y).process(w,{from:S,to:$,map:{inline:!1,annotation:!1},syntax:postcssSyntax(g)})}catch(n){if(reduceInformationInCssSyntaxError(n),x=!0,g.exception&&g.exception.test(n.message))continue;throw n}!x&&g.exception&&(a=!0,c?console.log(formatGitHubActionAnnotation(`${u}\n\nexpected an exception but got none`,"error",{file:S,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nexpected an exception but got none\n\n${i}`)));const E=h.css.toString();if(await e.promises.writeFile($,E,"utf8"),process.env.REWRITE_EXPECTS&&e.promises.writeFile(A,E,"utf8"),!1!==b){try{o.strict.strictEqual(E,b)}catch(n){a=!0,c?console.log(formatGitHubActionAnnotation(formatCSSAssertError(u,g,n,!0),"error",{file:A,line:1,col:1})):(p.add(u),console.error(formatCSSAssertError(u,g,n)))}try{if(!g.postcssSyntaxHTML&&h.map.toJSON().sources.includes("<no source>"))throw new Error("Sourcemap is broken")}catch(n){a=!0;const e='\nThis is most likely a newly created PostCSS AST Node without a value for "source".\nsee :\n- https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#24-set-nodesource-for-new-nodes\n- https://postcss.org/api/#node-source';c?console.log(formatGitHubActionAnnotation(`${u}\n\nbroken source map: ${JSON.stringify(h.map.toJSON().sources)}\n${e}`,"error",{file:S,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nbroken source map: ${JSON.stringify(h.map.toJSON().sources)}\n${e}\n\n${i}`))}g.after&&await g.after();try{const n=await e.promises.readFile($,"utf8");if((await s([noopPlugin()]).process(n,{from:$,to:$,map:{inline:!1,annotation:!1},syntax:postcssSyntax(g)})).warnings().length)throw new Error("Unexpected warnings on second pass")}catch(n){a=!0,c?console.log(formatGitHubActionAnnotation(`${u}\n\nresult was not parsable with PostCSS.`,"error",{file:A,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nresult was not parsable with PostCSS.\n\n${i}`))}if(s([noopPlugin()]).version!==t([noopPlugin()]).version){const n=await t(y).process(w,{from:S,to:$,map:{inline:!1,annotation:!1}});try{o.strict.strictEqual(n.css.toString(),E)}catch(n){reduceInformationInCssSyntaxError(n),a=!0,c?console.log(formatGitHubActionAnnotation("testing older PostCSS:\n"+formatCSSAssertError(u,g,n,!0),"error",{file:A,line:1,col:1})):(p.add(u),console.error("testing older PostCSS:\n"+formatCSSAssertError(u,g,n)))}}try{(h.warnings().length||g.warnings)&&o.strict.strictEqual(h.warnings().length,g.warnings)}catch(n){a=!0,c?console.log(formatGitHubActionAnnotation(formatWarningsAssertError(u,g,h.warnings(),g.warnings,!0),"error",{file:A,line:1,col:1})):(p.add(u),console.error(formatWarningsAssertError(u,g,h.warnings(),g.warnings)))}}}if(p.size){console.error("\nunexpected failures:");for(const n of p.values())console.error(" - "+n)}a&&process.exit(1),console.warn("pass "+r().postcssPlugin)}};
1+
"use strict";var e=require("path"),n=require("fs"),o=require("assert"),s=require("postcss"),t=require("postcss-8.4"),r=require("postcss-html");function formatGitHubActionAnnotation(n,o="error",s={}){let t="::"+o;const r=Object.keys(s).map((n=>{let o=String(s[n]);return"file"===n&&process.env.GITHUB_WORKSPACE&&(o=e.relative(process.env.GITHUB_WORKSPACE,e.resolve(o))),`${n}=${t=o,t.replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/]/g,"%5D").replace(/;/g,"%3B")}`;var t})).join(",");return r&&(t+=` ${r}`),`${t}::${c=n||"",c.replace(/\r/g,"%0D").replace(/\n/g,"%0A")}`;var c}const c="----------------------------------------";function formatCSSAssertError(e,n,o,s=!1){let t="";if(t+=`\n${e}\n\n`,n.message&&(t+=`message :\n ${n.message}\n\n`),n.options)try{t+=`options :\n${JSON.stringify(n.options,null,2)}\n\n`}catch(e){}return t+=`output changed :\n${prettyDiff(o.message)}\n`,s||(t+="\n"+c),t}function formatWarningsAssertError(e,n,o,s,t=!1){let r="";if(r+=`\n${e}\n\n`,n.message&&(r+=`message :\n ${n.message}\n\n`),n.options)try{r+=`options :\n${JSON.stringify(n.options,null,2)}\n\n`}catch(e){}return r+=`unexpected or missing warnings :\n+ actual ${o.length}\n- expected ${s}\n`,t||(o.forEach((e=>{r+=`\n[${e.plugin}]: ${e.text}`})),o.length&&(r+="\n"),r+="\n"+c),r}function prettyDiff(e){return e.replace(/[^\\](\\n)/gm,((e,n)=>e.replace(n," "))).replace(/(\\t)/gm,((e,n)=>e.replace(n," "))).replace(/\+$/gm,"").replace(/^Expected values to be strictly equal:\n/,"")}const noopPlugin=()=>({postcssPlugin:"noop-plugin",Rule(){}});function reduceInformationInCssSyntaxError(e){"CssSyntaxError"!==e.name||process.env.DEBUG||(delete e.source,e.input&&delete e.input.source,delete e.postcssNode)}noopPlugin.postcss=!0;const i=process.env.GITHUB_ACTIONS&&"true"===process.env.ENABLE_ANNOTATIONS_FOR_NODE&&"true"===process.env.ENABLE_ANNOTATIONS_FOR_OS;function postcssSyntax(e){return e.postcssSyntaxHTML?r():null}const a={postcssPlugin:"declaration-cloner",Declaration(e){"to-clone"===e.prop&&e.cloneBefore({prop:"cloned"})}},l={postcssPlugin:"rule-cloner",prepare(){const e=new WeakSet;return{Rule(n){e.has(n)||"to-clone"===n.selector&&(e.add(n),n.cloneBefore({selector:"cloned"}))}}}};exports.declarationClonerPlugin=a,exports.postcssTape=function postcssTape(r){let a=!1;{!0!==r.postcss&&(a=!0,i?console.log(formatGitHubActionAnnotation('postcss flag not set to "true" on exported plugin object',"error",{file:"./package.json",line:1,col:1})):console.error(`\npostcss flag not set to "true"\n\n${c}`));const e=r();e.postcssPlugin&&"string"==typeof e.postcssPlugin||(a=!0,i?console.log(formatGitHubActionAnnotation('plugin name not set via "postcssPlugin"',"error",{file:"./package.json",line:1,col:1})):console.error(`\nplugin name not set via "postcssPlugin"\n\n${c}`));const o=JSON.parse(n.readFileSync("./package.json").toString());o.keywords&&o.keywords.includes("postcss-plugin")||(a=!0,i?console.log(formatGitHubActionAnnotation('package.json does not include "postcss-plugin" keyword',"error",{file:"./package.json",line:1,col:1})):console.error(`\npackage.json does not include "postcss-plugin" keyword\n\n${c}`));const s=["css-has-pseudo","css-blank-pseudo","css-prefers-color-scheme","@csstools/css-has-pseudo-experimental"].includes(o.name);o.name.startsWith("postcss-")||o.name.startsWith("@csstools/postcss-")||s||(a=!0,i?console.log(formatGitHubActionAnnotation('plugin name in package.json does not start with "postcss-"',"error",{file:"./package.json",line:1,col:1})):console.error(`\nplugin name in package.json does not start with "postcss-"\n\n${c}`)),Object.keys(Object(o.dependencies)).includes("postcss")&&!("postcssTapeSelfTest"in r)&&(a=!0,i?console.log(formatGitHubActionAnnotation("postcss should only be a peer and/or dev dependency","error",{file:"./package.json",line:1,col:1})):console.error(`\npostcss should only be a peer and/or dev dependency\n\n${c}`))}return async l=>{const p=new Set;for(const u in l){const g=l[u];g.before&&await g.before();const f=e.join(".","test",u.split(":")[0]),d=e.join(".","test",u.replace(/:/g,"."));let m="css";g.postcssSyntaxHTML&&(m="html");const S=`${f}.${m}`;let A=`${d}.expect.${m}`,$=`${d}.result.${m}`;g.expect&&(A=e.join(".","test",g.expect)),g.result&&($=e.join(".","test",g.result));const w=g.plugins??[r(g.options)],y=await n.promises.readFile(S,"utf8");let h,b="";try{b=await n.promises.readFile(A,"utf8")}catch(n){a=!0,b=!1,i?console.log(formatGitHubActionAnnotation(`${u}\n\nmissing or broken "expect" file: "${e.parse(A).base}"`,"error",{file:S,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nmissing or broken "expect" file: "${e.parse(A).base}"\n\n${c}`))}let x=!1;try{h=await s(w).process(y,{from:S,to:$,map:{inline:!1,annotation:!1},syntax:postcssSyntax(g)})}catch(e){if(reduceInformationInCssSyntaxError(e),x=!0,g.exception&&g.exception.test(e.message))continue;throw e}!x&&g.exception&&(a=!0,i?console.log(formatGitHubActionAnnotation(`${u}\n\nexpected an exception but got none`,"error",{file:S,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nexpected an exception but got none\n\n${c}`)));const E=h.css.toString();if(await n.promises.writeFile($,E,"utf8"),process.env.REWRITE_EXPECTS&&n.promises.writeFile(A,E,"utf8"),!1!==b){try{o.strict.strictEqual(E,b)}catch(e){a=!0,i?console.log(formatGitHubActionAnnotation(formatCSSAssertError(u,g,e,!0),"error",{file:A,line:1,col:1})):(p.add(u),console.error(formatCSSAssertError(u,g,e)))}try{if(!g.postcssSyntaxHTML&&h.map.toJSON().sources.includes("<no source>"))throw new Error("Sourcemap is broken")}catch(e){a=!0;const n='\nThis is most likely a newly created PostCSS AST Node without a value for "source".\nsee :\n- https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#24-set-nodesource-for-new-nodes\n- https://postcss.org/api/#node-source';i?console.log(formatGitHubActionAnnotation(`${u}\n\nbroken source map: ${JSON.stringify(h.map.toJSON().sources)}\n${n}`,"error",{file:S,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nbroken source map: ${JSON.stringify(h.map.toJSON().sources)}\n${n}\n\n${c}`))}g.after&&await g.after();try{const e=await n.promises.readFile($,"utf8");if((await s([noopPlugin()]).process(e,{from:$,to:$,map:{inline:!1,annotation:!1},syntax:postcssSyntax(g)})).warnings().length)throw new Error("Unexpected warnings on second pass")}catch(e){a=!0,i?console.log(formatGitHubActionAnnotation(`${u}\n\nresult was not parsable with PostCSS.`,"error",{file:A,line:1,col:1})):(p.add(u),console.error(`\n${u}\n\nresult was not parsable with PostCSS.\n\n${c}`))}if(s([noopPlugin()]).version!==t([noopPlugin()]).version){const e=await t(w).process(y,{from:S,to:$,map:{inline:!1,annotation:!1}});try{o.strict.strictEqual(e.css.toString(),E)}catch(e){reduceInformationInCssSyntaxError(e),a=!0,i?console.log(formatGitHubActionAnnotation("testing older PostCSS:\n"+formatCSSAssertError(u,g,e,!0),"error",{file:A,line:1,col:1})):(p.add(u),console.error("testing older PostCSS:\n"+formatCSSAssertError(u,g,e)))}}try{(h.warnings().length||g.warnings)&&o.strict.strictEqual(h.warnings().length,g.warnings)}catch(e){a=!0,i?console.log(formatGitHubActionAnnotation(formatWarningsAssertError(u,g,h.warnings(),g.warnings,!0),"error",{file:A,line:1,col:1})):(p.add(u),console.error(formatWarningsAssertError(u,g,h.warnings(),g.warnings)))}}}if(p.size){console.error("\nunexpected failures:");for(const e of p.values())console.error(" - "+e)}a&&process.exit(1),console.warn("pass "+r().postcssPlugin)}},exports.ruleClonerPlugin=l;

packages/postcss-tape/dist/index.d.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,15 @@ type TestCaseOptions = {
1111
after?: () => void | Promise<void>;
1212
postcssSyntaxHTML?: boolean;
1313
};
14-
export default function runner(currentPlugin: PluginCreator<unknown>): (options: Record<string, TestCaseOptions>) => Promise<void>;
14+
export declare function postcssTape(currentPlugin: PluginCreator<unknown>): (options: Record<string, TestCaseOptions>) => Promise<void>;
15+
export declare const declarationClonerPlugin: {
16+
postcssPlugin: string;
17+
Declaration(decl: any): void;
18+
};
19+
export declare const ruleClonerPlugin: {
20+
postcssPlugin: string;
21+
prepare(): {
22+
Rule(rule: any): void;
23+
};
24+
};
1525
export {};

0 commit comments

Comments
 (0)