diff --git a/plugin-packs/postcss-bundler/.tape.mjs b/plugin-packs/postcss-bundler/.tape.mjs index affd39a7e..4521bae5e 100644 --- a/plugin-packs/postcss-bundler/.tape.mjs +++ b/plugin-packs/postcss-bundler/.tape.mjs @@ -25,7 +25,7 @@ const testCases = { }, 'ignore': { message: "ignores incorrect syntax", - warnings: 3, + warnings: 4, }, 'regexp': { message: "regexp sanity checks", @@ -45,28 +45,25 @@ const testCases = { } switch (dirent.path.split(path.sep).join(path.posix.sep)) { - case 'test/css-import-tests/003-should-fail/001-core-features/before-other-styles/002': - testCases[key].warnings = 1; - break; case 'test/css-import-tests/002-sub-features/004-at-supports/007': testCases[key].warnings = 1; break; - case 'test/css-import-tests/002-sub-features/003-at-layer/011': + case 'test/css-import-tests/002-sub-features/001-data-urls/004': testCases[key].warnings = 1; break; - case 'test/css-import-tests/002-sub-features/001-data-urls/004': + case 'test/css-import-tests/001-core-features/url-fragments/004': testCases[key].warnings = 1; break; - case 'test/css-import-tests/001-core-features/namespace/002': + case 'test/css-import-tests/001-core-features/url-fragments/005': testCases[key].warnings = 1; break; - case 'test/css-import-tests/001-core-features/before-other-styles/001': + case 'test/css-import-tests/001-core-features/forwards-compat/004': testCases[key].warnings = 1; break; - case 'test/css-import-tests/001-core-features/before-other-styles/002': + case 'test/css-import-tests/002-sub-features/003-at-layer/013': testCases[key].warnings = 1; break; - case 'test/css-import-tests/001-core-features/url-fragments/004': + case 'test/css-import-tests/002-sub-features/004-at-supports/012': testCases[key].warnings = 1; break; default: diff --git a/plugin-packs/postcss-bundler/CHANGELOG.md b/plugin-packs/postcss-bundler/CHANGELOG.md index e472dd299..234deaf2b 100644 --- a/plugin-packs/postcss-bundler/CHANGELOG.md +++ b/plugin-packs/postcss-bundler/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Bundler +### Unreleased (patch) + +- Fix layer statements that precede `@import` statements which link to external resources + ### 1.0.6 _October 5, 2023_ diff --git a/plugin-packs/postcss-bundler/dist/index.cjs b/plugin-packs/postcss-bundler/dist/index.cjs index bdd024613..f5245dab4 100644 --- a/plugin-packs/postcss-bundler/dist/index.cjs +++ b/plugin-packs/postcss-bundler/dist/index.cjs @@ -1 +1 @@ -"use strict";var e=require("@csstools/css-parser-algorithms"),t=require("@csstools/css-tokenizer"),r=require("path"),s=require("module"),n=require("fs/promises"),o=require("@csstools/postcss-rebase-url");function isWarning(e){return"warning"===e.type}function isCharsetStatement(e){return"charset"===e.type}function isImportStatement(e){return"import"===e.type}const i=/^data:text\/css(?:;(base64|plain))?,/i,a=/^data:text\/css;base64,/i,u=/^data:text\/css;plain,/i;function isValidDataURL(e){return!!e&&i.test(e)}const l=/^charset$/i,p=/^import$/i,c=/^url$/i,d=/^layer$/i,m=/^supports$/i;function parseAtImport(r){const s=t.tokenize({css:r});if(2===s.length&&(s[0][0]===t.TokenType.String||s[0][0]===t.TokenType.URL)){let e=s[0][4].value;return e=stripHash(e),!!e&&{uri:e,fullUri:s[0][1]}}const n=e.parseListOfComponentValues(s);let o,i,a,u="",l="";for(let r=0;r{o.push(...parseStatements(e,t,r,s,n))})),o;let i=[];return t.each((t=>{let a;"atrule"===t.type&&(p.test(t.name)?a=parseImport(e,t,r,s,n):l.test(t.name)&&(a=parseCharset(e,t,r,s,n))),a?(i.length&&(o.push({type:"nodes",nodes:i,conditions:[...s],from:n,importingNode:r}),i=[]),o.push(a)):i.push(t)})),i.length&&o.push({type:"nodes",nodes:i,conditions:[...s],from:n,importingNode:r}),o}function parseCharset(e,t,r,s,n){return t.prev()?e.warn("@charset must precede all other statements",{node:t}):{type:"charset",node:t,conditions:[...s],from:n,importingNode:r}}function parseImport(e,t,r,s,n){let o=t.prev(),i=!1;for(;o;){if("comment"!==o.type){if("atrule"===o.type&&p.test(o.name)){i=!0;break}break}o=o.prev()}if(!i)for(;o;){if(!("comment"===o.type||"atrule"===o.type&&l.test(o.name)||"atrule"===o.type&&d.test(o.name)&&!o.nodes))return e.warn("@import must precede all other statements (besides @charset or empty @layer)",{node:t});o=o.prev()}if(t.nodes)return e.warn("It looks like you didn't end your @import statement correctly. Child nodes are attached to it.",{node:t});const a={type:"import",uri:"",fullUri:"",node:t,conditions:[...s],from:n,importingNode:r},u=parseAtImport(t.params);if(!u)return e.warn(`Invalid @import statement in '${t.toString()}'`,{node:t});const{layer:c,media:m,supports:f,uri:h,fullUri:y}=u;return a.uri=h,a.fullUri=y,void 0===c&&void 0===m&&void 0===f||a.conditions.push({layer:c,media:m,supports:f}),a}function resolveId(e,t,s,n){let o="";if(s.startsWith("node_modules:"))try{o=t.resolve(s.slice(13))}catch(t){throw e.error(`Failed to find '${s}'`)}else o=r.resolve(n,s);return o}function createRequire(e,t){var n;let o;if(null==(n=e.source)||null==(n=n.input)||!n.file)return t.warn("The current PostCSS AST Node is lacking a source file reference. This is most likely a bug in a PostCSS plugin.",{node:e}),[];o=e.source.input.file;const i=r.dirname(o);return[s.createRequire(i),o,i]}async function loadContent(e){return isValidDataURL(e)?(t=e,a.test(t)?Buffer.from(t.slice(21),"base64").toString():u.test(t)?decodeURIComponent(t.slice(20)):decodeURIComponent(t.slice(14))):n.readFile(e,"utf-8");var t}const noopPlugin=()=>({postcssPlugin:"noop-plugin",Once(){}});async function parseStyles(e,t,r,s,n,o){const i=parseStatements(e,t,r,s,n);{let t,r,s;const n=[];for(const a of i)isImportStatement(a)&&isProcessableURL(a.uri)&&(t&&r&&s||([t,r,s]=createRequire(a.node,e),t&&r&&s))&&n.push(resolveImportId(e,a,o,t,r,s));await Promise.all(n)}let a=null;const u=[],l=[];return i.forEach((e=>{isCharsetStatement(e)?a=handleCharset(e,a):isImportStatement(e)?e.children?e.children.forEach((e=>{isImportStatement(e)?u.push(e):isCharsetStatement(e)?a=handleCharset(e,a):l.push(e)})):u.push(e):"nodes"===e.type&&l.push(e)})),a?[a,...u.concat(l)]:u.concat(l)}async function resolveImportId(e,t,r,s,n,o){if(isValidDataURL(t.uri))return void(t.children=await loadImportContent(e,t,t.uri,r));if(isValidDataURL(t.from[t.from.length-1]))return t.children=[],void e.warn(`Unable to import '${t.uri}' from a stylesheet that is embedded in a data url`,{node:t.node});const i=resolveId(t.node,s,t.uri,o);e.messages.push({type:"dependency",plugin:"postcss-bundler",file:i,parent:n});const a=await loadImportContent(e,t,i,r);t.children=a??[]}async function loadImportContent(e,t,r,s){var n,o;const{conditions:i,from:a,node:u}=t;if(a.includes(r))return;let p;try{p=await loadContent(r)}catch{throw u.error(`Failed to find '${t.uri}'`)}const c=await s([noopPlugin()]).process(p,{from:r,parser:(null==(n=e.opts.syntax)?void 0:n.parse)??e.opts.parser??void 0}),d=c.root;return e.messages=e.messages.concat(c.messages),"atrule"===(null==(o=d.first)?void 0:o.type)&&l.test(d.first.name)?d.first.after(s.comment({text:`${t.uri}`,source:u.source})):d.prepend(s.comment({text:`${t.uri}`,source:u.source})),parseStyles(e,d,u,i,[...a,r],s)}function isProcessableURL(e){if(/^(?:[a-z]+:)?\/\//i.test(e))return!1;try{if(new URL(e,"https://example.com").search)return!1}catch{}return!0}function handleCharset(e,t=null){if(!t)return e;var r,s;if(e.node.params.toLowerCase()!==t.node.params.toLowerCase())throw e.node.error(`Incompatible @charset statements:\n ${e.node.params} specified in ${null==(r=e.node.source)?void 0:r.input.file}\n ${t.node.params} specified in ${null==(s=t.node.source)?void 0:s.input.file}`);return t}function formatImportPrelude(e,t,r){const s=[];if(void 0!==e){let t="layer";e&&(t="layer("+e+")"),s.push(t)}return void 0!==r&&s.push("supports("+r+")"),void 0!==t&&s.push(t),s.join(" ")}function applyConditions(e,t){e.forEach(((r,s)=>{var n;if(isWarning(r)||isCharsetStatement(r)||null==(n=r.conditions)||!n.length)return;if(isImportStatement(r)){r.conditions.reverse();const e=r.conditions.pop();let t=`${r.fullUri} ${formatImportPrelude(e.layer,e.media,e.supports)}`;for(const e of r.conditions)t=`'data:text/css;base64,${Buffer.from(`@import ${t}`).toString("base64")}' ${formatImportPrelude(e.layer,e.media,e.supports)}`;return void(r.node.params=t)}const o=r.nodes;if(!o.length)return;const i=o[0].parent;if(!i)return;const a=[];for(const e of r.conditions){if(void 0!==e.media){var u;const s=t({name:"media",params:e.media,source:(null==(u=r.importingNode)?void 0:u.source)??i.source});a.push(s)}if(void 0!==e.supports){var l;const s=t({name:"supports",params:"("+e.supports+")",source:(null==(l=r.importingNode)?void 0:l.source)??i.source});a.push(s)}if(void 0!==e.layer){var p;const s=t({name:"layer",params:e.layer,source:(null==(p=r.importingNode)?void 0:p.source)??i.source});a.push(s)}}const c=a[0];if(!c)return;for(let e=0;e{e.parent=void 0})),d.append(o),e[s]={type:"nodes",nodes:[c],conditions:r.conditions,from:r.from,importingNode:r.importingNode}}))}function applyStyles(e,t){t.nodes=[],e.forEach((e=>{isCharsetStatement(e)||isImportStatement(e)?(e.node.parent=void 0,t.append(e.node)):"nodes"===e.type&&e.nodes.forEach((e=>{e.parent=void 0,t.append(e)}))}))}noopPlugin.postcss=!0;const creator$1=()=>({postcssPlugin:"postcss-bundler",async Once(e,{result:t,atRule:r,postcss:s}){const n=await parseStyles(t,e,null,[],[],s);applyConditions(n,r),applyStyles(n,e)}});creator$1.postcss=!0;const creator=()=>({postcssPlugin:"postcss-bundler",plugins:[creator$1(),o()]});creator.postcss=!0,module.exports=creator; +"use strict";var e=require("@csstools/css-parser-algorithms"),t=require("@csstools/css-tokenizer"),s=require("path"),o=require("module"),n=require("fs/promises"),r=require("@csstools/postcss-rebase-url");function isWarning(e){return"warning"===e.type}function isNodesStatement(e){return"nodes"===e.type}function isImportStatement(e){return"import"===e.type}function isPreImportStatement(e){return"pre-import"===e.type}const i=/^data:text\/css(?:;(base64|plain))?,/i,a=/^data:text\/css;base64,/i,c=/^data:text\/css;plain,/i;function isValidDataURL(e){return!!e&&i.test(e)}const l=/^charset$/i,u=/^import$/i,p=/^url$/i,m=/^layer$/i,d=/^supports$/i;function parseAtImport(s){const o=t.tokenize({css:s});if(2===o.length&&(o[0][0]===t.TokenType.String||o[0][0]===t.TokenType.URL)){let e=o[0][4].value;return e=stripHash(e),!!e&&{uri:e,fullUri:o[0][1]}}const n=e.parseListOfComponentValues(o);let r,i,a,c="",l="";for(let s=0;s{const i=parseStylesheet(e,t,s,o,n);var a,c;if(r.charset&&i.charset&&r.charset.params.toLowerCase()!==i.charset.params.toLowerCase())throw i.charset.error(`Incompatible @charset statements:\n ${i.charset.params} specified in ${null==(a=i.charset.source)?void 0:a.input.file}\n ${r.charset.params} specified in ${null==(c=r.charset.source)?void 0:c.input.file}`);!r.charset&&i.charset&&(r.charset=i.charset),r.statements.push(...i.statements)})),r;let i,a,c=[],p=[];for(let r=0;r({postcssPlugin:"noop-plugin",Once(){}});async function parseStyles(e,t,s,o,n,r){const i=parseStylesheet(e,t,s,o,n);{let t,s,o;const n=[];for(const a of i.statements)isImportStatement(a)&&isProcessableURL(a.uri)&&(t&&s&&o||([t,s,o]=createRequire(a.node,e),t&&s&&o))&&n.push(resolveImportId(e,a,r,t,s,o));n.length&&await Promise.all(n)}for(let e=0;e{var n;if(isWarning(s)||isPreImportStatement(s)||null==(n=s.conditions)||!n.length)return;if(isImportStatement(s))return void(s.node.params=base64EncodedConditionalImport(s.fullUri,s.conditions));const r=s.nodes;if(!r.length)return;const i=r[0].parent;if(!i)return;const a=[];for(const e of s.conditions){if(void 0!==e.media){var c;const o=t({name:"media",params:e.media,source:(null==(c=s.importingNode)?void 0:c.source)??i.source});a.push(o)}if(void 0!==e.supports){var l;const o=t({name:"supports",params:"("+e.supports+")",source:(null==(l=s.importingNode)?void 0:l.source)??i.source});a.push(o)}if(void 0!==e.layer){var u;const o=t({name:"layer",params:e.layer,source:(null==(u=s.importingNode)?void 0:u.source)??i.source});a.push(o)}}const p=a[0];if(!p)return;for(let e=0;e{e.parent=void 0})),m.append(r),e.statements[o]={type:"nodes",nodes:[p],conditions:s.conditions,from:s.from,importingNode:s.importingNode}}))}function applyStyles(e,t){t.nodes=[],e.charset&&(e.charset.parent=void 0,t.append(e.charset)),e.statements.forEach((e=>{isImportStatement(e)?(e.node.parent=void 0,t.append(e.node)):isNodesStatement(e)&&e.nodes.forEach((e=>{e.parent=void 0,t.append(e)}))}))}function postProcess(e,t){let s=-1,o=-1,n=-1;for(let t=0;t({postcssPlugin:"postcss-bundler",async Once(e,{result:t,atRule:s,postcss:o}){const n=await parseStyles(t,e,null,[],[],o);postProcess(n,s),applyConditions(n,s),applyStyles(n,e)}});creator$1.postcss=!0;const creator=()=>({postcssPlugin:"postcss-bundler",plugins:[creator$1(),r()]});creator.postcss=!0,module.exports=creator; diff --git a/plugin-packs/postcss-bundler/dist/index.mjs b/plugin-packs/postcss-bundler/dist/index.mjs index bd0679a2b..21eec07af 100644 --- a/plugin-packs/postcss-bundler/dist/index.mjs +++ b/plugin-packs/postcss-bundler/dist/index.mjs @@ -1 +1 @@ -import{parseListOfComponentValues as e,isWhitespaceNode as t,isCommentNode as r,isTokenNode as o,isFunctionNode as s,stringify as n}from"@csstools/css-parser-algorithms";import{tokenize as i,TokenType as a}from"@csstools/css-tokenizer";import u from"path";import l from"module";import p from"fs/promises";import c from"@csstools/postcss-rebase-url";function isWarning(e){return"warning"===e.type}function isCharsetStatement(e){return"charset"===e.type}function isImportStatement(e){return"import"===e.type}const d=/^data:text\/css(?:;(base64|plain))?,/i,m=/^data:text\/css;base64,/i,f=/^data:text\/css;plain,/i;function isValidDataURL(e){return!!e&&d.test(e)}const h=/^charset$/i,v=/^import$/i,y=/^url$/i,g=/^layer$/i,S=/^supports$/i;function parseAtImport(u){const l=i({css:u});if(2===l.length&&(l[0][0]===a.String||l[0][0]===a.URL)){let e=l[0][4].value;return e=stripHash(e),!!e&&{uri:e,fullUri:l[0][1]}}const p=e(l);let c,d,m,f="",h="";for(let e=0;e{n.push(...parseStatements(e,t,r,o,s))})),n;let i=[];return t.each((t=>{let a;"atrule"===t.type&&(v.test(t.name)?a=parseImport(e,t,r,o,s):h.test(t.name)&&(a=parseCharset(e,t,r,o,s))),a?(i.length&&(n.push({type:"nodes",nodes:i,conditions:[...o],from:s,importingNode:r}),i=[]),n.push(a)):i.push(t)})),i.length&&n.push({type:"nodes",nodes:i,conditions:[...o],from:s,importingNode:r}),n}function parseCharset(e,t,r,o,s){return t.prev()?e.warn("@charset must precede all other statements",{node:t}):{type:"charset",node:t,conditions:[...o],from:s,importingNode:r}}function parseImport(e,t,r,o,s){let n=t.prev(),i=!1;for(;n;){if("comment"!==n.type){if("atrule"===n.type&&v.test(n.name)){i=!0;break}break}n=n.prev()}if(!i)for(;n;){if(!("comment"===n.type||"atrule"===n.type&&h.test(n.name)||"atrule"===n.type&&g.test(n.name)&&!n.nodes))return e.warn("@import must precede all other statements (besides @charset or empty @layer)",{node:t});n=n.prev()}if(t.nodes)return e.warn("It looks like you didn't end your @import statement correctly. Child nodes are attached to it.",{node:t});const a={type:"import",uri:"",fullUri:"",node:t,conditions:[...o],from:s,importingNode:r},u=parseAtImport(t.params);if(!u)return e.warn(`Invalid @import statement in '${t.toString()}'`,{node:t});const{layer:l,media:p,supports:c,uri:d,fullUri:m}=u;return a.uri=d,a.fullUri=m,void 0===l&&void 0===p&&void 0===c||a.conditions.push({layer:l,media:p,supports:c}),a}function resolveId(e,t,r,o){let s="";if(r.startsWith("node_modules:"))try{s=t.resolve(r.slice(13))}catch(t){throw e.error(`Failed to find '${r}'`)}else s=u.resolve(o,r);return s}function createRequire(e,t){var r;let o;if(null==(r=e.source)||null==(r=r.input)||!r.file)return t.warn("The current PostCSS AST Node is lacking a source file reference. This is most likely a bug in a PostCSS plugin.",{node:e}),[];o=e.source.input.file;const s=u.dirname(o);return[l.createRequire(s),o,s]}async function loadContent(e){return isValidDataURL(e)?(t=e,m.test(t)?Buffer.from(t.slice(21),"base64").toString():f.test(t)?decodeURIComponent(t.slice(20)):decodeURIComponent(t.slice(14))):p.readFile(e,"utf-8");var t}const noopPlugin=()=>({postcssPlugin:"noop-plugin",Once(){}});async function parseStyles(e,t,r,o,s,n){const i=parseStatements(e,t,r,o,s);{let t,r,o;const s=[];for(const a of i)isImportStatement(a)&&isProcessableURL(a.uri)&&(t&&r&&o||([t,r,o]=createRequire(a.node,e),t&&r&&o))&&s.push(resolveImportId(e,a,n,t,r,o));await Promise.all(s)}let a=null;const u=[],l=[];return i.forEach((e=>{isCharsetStatement(e)?a=handleCharset(e,a):isImportStatement(e)?e.children?e.children.forEach((e=>{isImportStatement(e)?u.push(e):isCharsetStatement(e)?a=handleCharset(e,a):l.push(e)})):u.push(e):"nodes"===e.type&&l.push(e)})),a?[a,...u.concat(l)]:u.concat(l)}async function resolveImportId(e,t,r,o,s,n){if(isValidDataURL(t.uri))return void(t.children=await loadImportContent(e,t,t.uri,r));if(isValidDataURL(t.from[t.from.length-1]))return t.children=[],void e.warn(`Unable to import '${t.uri}' from a stylesheet that is embedded in a data url`,{node:t.node});const i=resolveId(t.node,o,t.uri,n);e.messages.push({type:"dependency",plugin:"postcss-bundler",file:i,parent:s});const a=await loadImportContent(e,t,i,r);t.children=a??[]}async function loadImportContent(e,t,r,o){var s,n;const{conditions:i,from:a,node:u}=t;if(a.includes(r))return;let l;try{l=await loadContent(r)}catch{throw u.error(`Failed to find '${t.uri}'`)}const p=await o([noopPlugin()]).process(l,{from:r,parser:(null==(s=e.opts.syntax)?void 0:s.parse)??e.opts.parser??void 0}),c=p.root;return e.messages=e.messages.concat(p.messages),"atrule"===(null==(n=c.first)?void 0:n.type)&&h.test(c.first.name)?c.first.after(o.comment({text:`${t.uri}`,source:u.source})):c.prepend(o.comment({text:`${t.uri}`,source:u.source})),parseStyles(e,c,u,i,[...a,r],o)}function isProcessableURL(e){if(/^(?:[a-z]+:)?\/\//i.test(e))return!1;try{if(new URL(e,"https://example.com").search)return!1}catch{}return!0}function handleCharset(e,t=null){if(!t)return e;var r,o;if(e.node.params.toLowerCase()!==t.node.params.toLowerCase())throw e.node.error(`Incompatible @charset statements:\n ${e.node.params} specified in ${null==(r=e.node.source)?void 0:r.input.file}\n ${t.node.params} specified in ${null==(o=t.node.source)?void 0:o.input.file}`);return t}function formatImportPrelude(e,t,r){const o=[];if(void 0!==e){let t="layer";e&&(t="layer("+e+")"),o.push(t)}return void 0!==r&&o.push("supports("+r+")"),void 0!==t&&o.push(t),o.join(" ")}function applyConditions(e,t){e.forEach(((r,o)=>{var s;if(isWarning(r)||isCharsetStatement(r)||null==(s=r.conditions)||!s.length)return;if(isImportStatement(r)){r.conditions.reverse();const e=r.conditions.pop();let t=`${r.fullUri} ${formatImportPrelude(e.layer,e.media,e.supports)}`;for(const e of r.conditions)t=`'data:text/css;base64,${Buffer.from(`@import ${t}`).toString("base64")}' ${formatImportPrelude(e.layer,e.media,e.supports)}`;return void(r.node.params=t)}const n=r.nodes;if(!n.length)return;const i=n[0].parent;if(!i)return;const a=[];for(const e of r.conditions){if(void 0!==e.media){var u;const o=t({name:"media",params:e.media,source:(null==(u=r.importingNode)?void 0:u.source)??i.source});a.push(o)}if(void 0!==e.supports){var l;const o=t({name:"supports",params:"("+e.supports+")",source:(null==(l=r.importingNode)?void 0:l.source)??i.source});a.push(o)}if(void 0!==e.layer){var p;const o=t({name:"layer",params:e.layer,source:(null==(p=r.importingNode)?void 0:p.source)??i.source});a.push(o)}}const c=a[0];if(!c)return;for(let e=0;e{e.parent=void 0})),d.append(n),e[o]={type:"nodes",nodes:[c],conditions:r.conditions,from:r.from,importingNode:r.importingNode}}))}function applyStyles(e,t){t.nodes=[],e.forEach((e=>{isCharsetStatement(e)||isImportStatement(e)?(e.node.parent=void 0,t.append(e.node)):"nodes"===e.type&&e.nodes.forEach((e=>{e.parent=void 0,t.append(e)}))}))}noopPlugin.postcss=!0;const creator$1=()=>({postcssPlugin:"postcss-bundler",async Once(e,{result:t,atRule:r,postcss:o}){const s=await parseStyles(t,e,null,[],[],o);applyConditions(s,r),applyStyles(s,e)}});creator$1.postcss=!0;const creator=()=>({postcssPlugin:"postcss-bundler",plugins:[creator$1(),c()]});creator.postcss=!0;export{creator as default}; +import{parseListOfComponentValues as e,isWhitespaceNode as t,isCommentNode as s,isTokenNode as o,isFunctionNode as n,stringify as r}from"@csstools/css-parser-algorithms";import{tokenize as i,TokenType as a}from"@csstools/css-tokenizer";import c from"path";import l from"module";import p from"fs/promises";import u from"@csstools/postcss-rebase-url";function isWarning(e){return"warning"===e.type}function isNodesStatement(e){return"nodes"===e.type}function isImportStatement(e){return"import"===e.type}function isPreImportStatement(e){return"pre-import"===e.type}const m=/^data:text\/css(?:;(base64|plain))?,/i,d=/^data:text\/css;base64,/i,f=/^data:text\/css;plain,/i;function isValidDataURL(e){return!!e&&m.test(e)}const h=/^charset$/i,y=/^import$/i,g=/^url$/i,v=/^layer$/i,I=/^supports$/i;function parseAtImport(c){const l=i({css:c});if(2===l.length&&(l[0][0]===a.String||l[0][0]===a.URL)){let e=l[0][4].value;return e=stripHash(e),!!e&&{uri:e,fullUri:l[0][1]}}const p=e(l);let u,m,d,f="",h="";for(let e=0;e{const i=parseStylesheet(e,t,s,o,n);var a,c;if(r.charset&&i.charset&&r.charset.params.toLowerCase()!==i.charset.params.toLowerCase())throw i.charset.error(`Incompatible @charset statements:\n ${i.charset.params} specified in ${null==(a=i.charset.source)?void 0:a.input.file}\n ${r.charset.params} specified in ${null==(c=r.charset.source)?void 0:c.input.file}`);!r.charset&&i.charset&&(r.charset=i.charset),r.statements.push(...i.statements)})),r;let i,a,c=[],l=[];for(let r=0;r({postcssPlugin:"noop-plugin",Once(){}});async function parseStyles(e,t,s,o,n,r){const i=parseStylesheet(e,t,s,o,n);{let t,s,o;const n=[];for(const a of i.statements)isImportStatement(a)&&isProcessableURL(a.uri)&&(t&&s&&o||([t,s,o]=createRequire(a.node,e),t&&s&&o))&&n.push(resolveImportId(e,a,r,t,s,o));n.length&&await Promise.all(n)}for(let e=0;e{var n;if(isWarning(s)||isPreImportStatement(s)||null==(n=s.conditions)||!n.length)return;if(isImportStatement(s))return void(s.node.params=base64EncodedConditionalImport(s.fullUri,s.conditions));const r=s.nodes;if(!r.length)return;const i=r[0].parent;if(!i)return;const a=[];for(const e of s.conditions){if(void 0!==e.media){var c;const o=t({name:"media",params:e.media,source:(null==(c=s.importingNode)?void 0:c.source)??i.source});a.push(o)}if(void 0!==e.supports){var l;const o=t({name:"supports",params:"("+e.supports+")",source:(null==(l=s.importingNode)?void 0:l.source)??i.source});a.push(o)}if(void 0!==e.layer){var p;const o=t({name:"layer",params:e.layer,source:(null==(p=s.importingNode)?void 0:p.source)??i.source});a.push(o)}}const u=a[0];if(!u)return;for(let e=0;e{e.parent=void 0})),m.append(r),e.statements[o]={type:"nodes",nodes:[u],conditions:s.conditions,from:s.from,importingNode:s.importingNode}}))}function applyStyles(e,t){t.nodes=[],e.charset&&(e.charset.parent=void 0,t.append(e.charset)),e.statements.forEach((e=>{isImportStatement(e)?(e.node.parent=void 0,t.append(e.node)):isNodesStatement(e)&&e.nodes.forEach((e=>{e.parent=void 0,t.append(e)}))}))}function postProcess(e,t){let s=-1,o=-1,n=-1;for(let t=0;t({postcssPlugin:"postcss-bundler",async Once(e,{result:t,atRule:s,postcss:o}){const n=await parseStyles(t,e,null,[],[],o);postProcess(n,s),applyConditions(n,s),applyStyles(n,e)}});creator$1.postcss=!0;const creator=()=>({postcssPlugin:"postcss-bundler",plugins:[creator$1(),u()]});creator.postcss=!0;export{creator as default}; diff --git a/plugin-packs/postcss-bundler/dist/postcss-import/lib/apply-conditions.d.ts b/plugin-packs/postcss-bundler/dist/postcss-import/lib/apply-conditions.d.ts index 450069752..76feb6286 100644 --- a/plugin-packs/postcss-bundler/dist/postcss-import/lib/apply-conditions.d.ts +++ b/plugin-packs/postcss-bundler/dist/postcss-import/lib/apply-conditions.d.ts @@ -1,3 +1,3 @@ import type { AtRule, AtRuleProps } from 'postcss'; -import { Statement } from './statement'; -export declare function applyConditions(bundle: Array, atRule: (defaults?: AtRuleProps) => AtRule): void; +import { Stylesheet } from './statement'; +export declare function applyConditions(stylesheet: Stylesheet, atRule: (defaults?: AtRuleProps) => AtRule): void; diff --git a/plugin-packs/postcss-bundler/dist/postcss-import/lib/apply-styles.d.ts b/plugin-packs/postcss-bundler/dist/postcss-import/lib/apply-styles.d.ts index b538e915c..24534276e 100644 --- a/plugin-packs/postcss-bundler/dist/postcss-import/lib/apply-styles.d.ts +++ b/plugin-packs/postcss-bundler/dist/postcss-import/lib/apply-styles.d.ts @@ -1,3 +1,3 @@ import type { Document, Root } from 'postcss'; -import { Statement } from './statement'; -export declare function applyStyles(bundle: Array, styles: Root | Document): void; +import { Stylesheet } from './statement'; +export declare function applyStyles(stylesheet: Stylesheet, styles: Root | Document): void; diff --git a/plugin-packs/postcss-bundler/dist/postcss-import/lib/base64-encoded-import.d.ts b/plugin-packs/postcss-bundler/dist/postcss-import/lib/base64-encoded-import.d.ts new file mode 100644 index 000000000..8e8284439 --- /dev/null +++ b/plugin-packs/postcss-bundler/dist/postcss-import/lib/base64-encoded-import.d.ts @@ -0,0 +1,2 @@ +import { Condition } from './conditions'; +export declare function base64EncodedConditionalImport(prelude: string, conditions: Array): string; diff --git a/plugin-packs/postcss-bundler/dist/postcss-import/lib/parse-styles.d.ts b/plugin-packs/postcss-bundler/dist/postcss-import/lib/parse-styles.d.ts index 86beb9c50..4ff88c005 100644 --- a/plugin-packs/postcss-bundler/dist/postcss-import/lib/parse-styles.d.ts +++ b/plugin-packs/postcss-bundler/dist/postcss-import/lib/parse-styles.d.ts @@ -1,4 +1,4 @@ import type { Document, Postcss, Result, Root, AtRule } from 'postcss'; -import { Statement } from './statement'; +import { Stylesheet } from './statement'; import { Condition } from './conditions'; -export declare function parseStyles(result: Result, styles: Root | Document, importingNode: AtRule | null, conditions: Array, from: Array, postcss: Postcss): Promise; +export declare function parseStyles(result: Result, styles: Root | Document, importingNode: AtRule | null, conditions: Array, from: Array, postcss: Postcss): Promise; diff --git a/plugin-packs/postcss-bundler/dist/postcss-import/lib/parse-statements.d.ts b/plugin-packs/postcss-bundler/dist/postcss-import/lib/parse-stylesheet.d.ts similarity index 51% rename from plugin-packs/postcss-bundler/dist/postcss-import/lib/parse-statements.d.ts rename to plugin-packs/postcss-bundler/dist/postcss-import/lib/parse-stylesheet.d.ts index 4a2bdb2bd..55813909a 100644 --- a/plugin-packs/postcss-bundler/dist/postcss-import/lib/parse-statements.d.ts +++ b/plugin-packs/postcss-bundler/dist/postcss-import/lib/parse-stylesheet.d.ts @@ -1,4 +1,4 @@ import type { AtRule, Document, Result, Root } from 'postcss'; import { Condition } from './conditions'; -import { Statement } from './statement'; -export declare function parseStatements(result: Result, styles: Root | Document, importingNode: AtRule | null, conditions: Array, from: Array): Array; +import { Stylesheet } from './statement'; +export declare function parseStylesheet(result: Result, styles: Root | Document, importingNode: AtRule | null, conditions: Array, from: Array): Stylesheet; diff --git a/plugin-packs/postcss-bundler/dist/postcss-import/lib/post-process.d.ts b/plugin-packs/postcss-bundler/dist/postcss-import/lib/post-process.d.ts new file mode 100644 index 000000000..68c59c20b --- /dev/null +++ b/plugin-packs/postcss-bundler/dist/postcss-import/lib/post-process.d.ts @@ -0,0 +1,3 @@ +import type { AtRule, AtRuleProps } from 'postcss'; +import { Stylesheet } from './statement'; +export declare function postProcess(stylesheet: Stylesheet, atRule: (defaults?: AtRuleProps) => AtRule): void; diff --git a/plugin-packs/postcss-bundler/dist/postcss-import/lib/statement.d.ts b/plugin-packs/postcss-bundler/dist/postcss-import/lib/statement.d.ts index a5bf2629c..08d95ad17 100644 --- a/plugin-packs/postcss-bundler/dist/postcss-import/lib/statement.d.ts +++ b/plugin-packs/postcss-bundler/dist/postcss-import/lib/statement.d.ts @@ -1,34 +1,38 @@ import type { AtRule, ChildNode, Warning } from 'postcss'; import { Condition } from './conditions'; -export type Statement = ImportStatement | CharsetStatement | NodesStatement | Warning; +export type Stylesheet = { + charset?: AtRule; + statements: Array; +}; +export type Statement = ImportStatement | PreImportStatement | NodesStatement | Warning; export type NodesStatement = { - type: string; + type: 'nodes'; nodes: Array; conditions: Array; from: Array; parent?: Statement; importingNode: AtRule | null; }; -export type CharsetStatement = { - type: string; +export type ImportStatement = { + type: 'import'; + uri: string; + fullUri: string; node: AtRule; conditions: Array; from: Array; parent?: Statement; + stylesheet?: Stylesheet; importingNode: AtRule | null; }; -export type ImportStatement = { - type: string; - uri: string; - fullUri: string; - node: AtRule; +export type PreImportStatement = { + type: 'pre-import'; + node: ChildNode; conditions: Array; from: Array; parent?: Statement; - children?: Array; importingNode: AtRule | null; }; export declare function isWarning(stmt: Statement): stmt is Warning; export declare function isNodesStatement(stmt: Statement): stmt is NodesStatement; -export declare function isCharsetStatement(stmt: Statement): stmt is CharsetStatement; export declare function isImportStatement(stmt: Statement): stmt is ImportStatement; +export declare function isPreImportStatement(stmt: Statement): stmt is PreImportStatement; diff --git a/plugin-packs/postcss-bundler/src/postcss-import/index.ts b/plugin-packs/postcss-bundler/src/postcss-import/index.ts index 1a5853840..7e4211e3d 100644 --- a/plugin-packs/postcss-bundler/src/postcss-import/index.ts +++ b/plugin-packs/postcss-bundler/src/postcss-import/index.ts @@ -2,6 +2,7 @@ import type { PluginCreator } from 'postcss'; import { parseStyles } from './lib/parse-styles'; import { applyConditions } from './lib/apply-conditions'; import { applyStyles } from './lib/apply-styles'; +import { postProcess } from './lib/post-process'; /** postcss-bundler plugin options */ export type pluginOptions = never; @@ -19,6 +20,8 @@ const creator: PluginCreator = () => { postcss, ); + postProcess(bundle, atRule); + applyConditions(bundle, atRule); applyStyles(bundle, styles); }, diff --git a/plugin-packs/postcss-bundler/src/postcss-import/lib/apply-conditions.ts b/plugin-packs/postcss-bundler/src/postcss-import/lib/apply-conditions.ts index b43436937..7fcfc49f7 100644 --- a/plugin-packs/postcss-bundler/src/postcss-import/lib/apply-conditions.ts +++ b/plugin-packs/postcss-bundler/src/postcss-import/lib/apply-conditions.ts @@ -1,34 +1,15 @@ import type { AtRule, AtRuleProps } from 'postcss'; -import { Statement, isCharsetStatement, isImportStatement, isWarning } from './statement'; -import { formatImportPrelude } from './format-import-prelude'; +import { Stylesheet, isImportStatement, isPreImportStatement, isWarning } from './statement'; +import { base64EncodedConditionalImport } from './base64-encoded-import'; -export function applyConditions(bundle: Array, atRule: (defaults?: AtRuleProps) => AtRule) { - bundle.forEach((stmt, index) => { - if (isWarning(stmt) || isCharsetStatement(stmt) || !stmt.conditions?.length) { +export function applyConditions(stylesheet: Stylesheet, atRule: (defaults?: AtRuleProps) => AtRule) { + stylesheet.statements.forEach((stmt, index) => { + if (isWarning(stmt) || isPreImportStatement(stmt) || !stmt.conditions?.length) { return; } if (isImportStatement(stmt)) { - stmt.conditions.reverse(); - const first = stmt.conditions.pop()!; - let params = `${stmt.fullUri} ${formatImportPrelude( - first.layer, - first.media, - first.supports, - )}`; - - for (const condition of stmt.conditions) { - params = `'data:text/css;base64,${Buffer.from( - `@import ${params}`, - ).toString('base64')}' ${formatImportPrelude( - condition.layer, - condition.media, - condition.supports, - )}`; - } - - stmt.node.params = params; - + stmt.node.params = base64EncodedConditionalImport(stmt.fullUri, stmt.conditions); return; } @@ -98,7 +79,7 @@ export function applyConditions(bundle: Array, atRule: (defaults?: At // wrap new rules with media query and/or layer at rule innerAtRule.append(nodes); - bundle[index] = { + stylesheet.statements[index] = { type: 'nodes', nodes: [outerAtRule], conditions: stmt.conditions, diff --git a/plugin-packs/postcss-bundler/src/postcss-import/lib/apply-styles.ts b/plugin-packs/postcss-bundler/src/postcss-import/lib/apply-styles.ts index cee15000c..8bf26ceff 100644 --- a/plugin-packs/postcss-bundler/src/postcss-import/lib/apply-styles.ts +++ b/plugin-packs/postcss-bundler/src/postcss-import/lib/apply-styles.ts @@ -1,16 +1,21 @@ import type { Document, Root } from 'postcss'; -import { Statement, isCharsetStatement, isImportStatement } from './statement'; +import { Stylesheet, isImportStatement, isNodesStatement } from './statement'; -export function applyStyles(bundle: Array, styles: Root | Document) { +export function applyStyles(stylesheet: Stylesheet, styles: Root | Document) { styles.nodes = []; + if (stylesheet.charset) { + stylesheet.charset.parent = undefined; + styles.append(stylesheet.charset); + } + // Strip additional statements. - bundle.forEach(stmt => { - if (isCharsetStatement(stmt) || isImportStatement(stmt)) { + stylesheet.statements.forEach((stmt) => { + if (isImportStatement(stmt)) { stmt.node.parent = undefined; styles.append(stmt.node); - } else if (stmt.type === 'nodes') { - stmt.nodes.forEach(node => { + } else if (isNodesStatement(stmt)) { + stmt.nodes.forEach((node) => { node.parent = undefined; styles.append(node); }); diff --git a/plugin-packs/postcss-bundler/src/postcss-import/lib/base64-encoded-import.ts b/plugin-packs/postcss-bundler/src/postcss-import/lib/base64-encoded-import.ts new file mode 100644 index 000000000..64978db90 --- /dev/null +++ b/plugin-packs/postcss-bundler/src/postcss-import/lib/base64-encoded-import.ts @@ -0,0 +1,29 @@ +import { Condition } from './conditions'; +import { formatImportPrelude } from './format-import-prelude'; + +// Base64 encode an import with conditions +// The order of conditions is important and is interleaved with cascade layer declarations +// Each group of conditions and cascade layers needs to be interpreted in order +// To achieve this we create a list of base64 encoded imports, where each import contains a stylesheet with another import. +// Each import can define a single group of conditions and a single cascade layer. +export function base64EncodedConditionalImport(prelude: string, conditions: Array): string { + conditions.reverse(); + const first = conditions.pop()!; + let params = `${prelude} ${formatImportPrelude( + first.layer, + first.media, + first.supports, + )}`; + + for (const condition of conditions) { + params = `'data:text/css;base64,${Buffer.from( + `@import ${params}`, + ).toString('base64')}' ${formatImportPrelude( + condition.layer, + condition.media, + condition.supports, + )}`; + } + + return params; +} diff --git a/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-at-import.ts b/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-at-import.ts index e7792da91..42dabc64e 100644 --- a/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-at-import.ts +++ b/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-at-import.ts @@ -69,6 +69,7 @@ export function parseAtImport(params: string) : false | { uri: string; fullUri: } if ( + !uri && isTokenNode(childComponentValue) && childComponentValue.value[0] === TokenType.String ) { diff --git a/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-statements.ts b/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-statements.ts deleted file mode 100644 index 53332db89..000000000 --- a/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-statements.ts +++ /dev/null @@ -1,158 +0,0 @@ -import type { AtRule, ChildNode, Document, Result, Root, Warning } from 'postcss'; -import { Condition } from './conditions'; -import { CharsetStatement, ImportStatement, Statement } from './statement'; -import { IS_CHARSET, IS_IMPORT, IS_LAYER } from './names'; -import { parseAtImport } from './parse-at-import'; - -export function parseStatements(result: Result, styles: Root | Document, importingNode: AtRule | null, conditions: Array, from: Array): Array { - const statements: Array = []; - - if (styles.type === 'document') { - styles.each((root) => { - statements.push( - ...parseStatements(result, root, importingNode, conditions, from), - ); - }); - - return statements; - } - - let nodes: Array = []; - - styles.each(node => { - let stmt; - if (node.type === 'atrule') { - if (IS_IMPORT.test(node.name)) { - stmt = parseImport(result, node, importingNode, conditions, from); - } else if (IS_CHARSET.test(node.name)) { - stmt = parseCharset(result, node, importingNode, conditions, from); - } - } - - if (stmt) { - if (nodes.length) { - statements.push({ - type: 'nodes', - nodes, - conditions: [...conditions], - from, - importingNode, - }); - nodes = []; - } - statements.push(stmt); - } else { - nodes.push(node); - } - }); - - if (nodes.length) { - statements.push({ - type: 'nodes', - nodes, - conditions: [...conditions], - from, - importingNode, - }); - } - - return statements; -} - -function parseCharset(result: Result, atRule: AtRule, importingNode: AtRule | null, conditions: Array, from: Array): Warning | CharsetStatement { - if (atRule.prev()) { - return result.warn('@charset must precede all other statements', { - node: atRule, - }); - } - - return { - type: 'charset', - node: atRule, - conditions: [...conditions], - from, - importingNode, - }; -} - -function parseImport(result: Result, atRule: AtRule, importingNode: AtRule | null, conditions: Array, from: Array): Warning | ImportStatement { - let prev = atRule.prev(); - let prevIsImport = false; - - // `@import` statements may follow other `@import` statements. - while (prev) { - if (prev.type === 'comment') { - prev = prev.prev(); - continue; - } - - if (prev.type === 'atrule' && IS_IMPORT.test(prev.name)) { - // If the previous rule is an `@import` rule is always valid when that preceding rule is valid. - // And equally also always invalid when it is invalid. - prevIsImport = true; - break; - } - - break; - } - - if (!prevIsImport) { - // All `@import` statements may be preceded by `@charset` or `@layer` statements. - // But the `@import` statements must be consecutive. - while (prev) { - if ( - prev.type === 'comment' || - (prev.type === 'atrule' && IS_CHARSET.test(prev.name)) || - (prev.type === 'atrule' && IS_LAYER.test(prev.name) && !prev.nodes) - ) { - prev = prev.prev(); - continue; - } - - return result.warn( - '@import must precede all other statements (besides @charset or empty @layer)', - { node: atRule }, - ); - } - } - - if (atRule.nodes) { - return result.warn( - 'It looks like you didn\'t end your @import statement correctly. ' + - 'Child nodes are attached to it.', - { node: atRule }, - ); - } - - const stmt = { - type: 'import', - uri: '', - fullUri: '', - node: atRule, - conditions: [...conditions], - from, - importingNode, - }; - - const parsed = parseAtImport(atRule.params); - if (!parsed) { - return result.warn(`Invalid @import statement in '${atRule.toString()}'`, { - node: atRule, - }); - } - - const { layer, media, supports, uri, fullUri } = parsed; - - stmt.uri = uri; - stmt.fullUri = fullUri; - - if (typeof layer !== 'undefined' || typeof media !== 'undefined' || typeof supports !== 'undefined') { - stmt.conditions.push({ - layer, - media, - supports, - }); - } - - return stmt; -} diff --git a/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-styles.ts b/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-styles.ts index 25295d715..b3d9a431a 100644 --- a/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-styles.ts +++ b/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-styles.ts @@ -1,8 +1,8 @@ import type { Document, Postcss, Result, Root, AtRule } from 'postcss'; -import { CharsetStatement, ImportStatement, Statement, isCharsetStatement, isImportStatement } from './statement'; +import { ImportStatement, Stylesheet, isImportStatement } from './statement'; import { Condition } from './conditions'; import { isValidDataURL } from './data-url'; -import { parseStatements } from './parse-statements'; +import { parseStylesheet } from './parse-stylesheet'; import { createRequire, resolveId } from './resolve-id'; import { loadContent } from './load-content'; import noopPlugin from './noop-plugin'; @@ -15,8 +15,8 @@ export async function parseStyles( conditions: Array, from: Array, postcss: Postcss, -) { - const statements = parseStatements(result, styles, importingNode, conditions, from); +): Promise { + const stylesheet = parseStylesheet(result, styles, importingNode, conditions, from); { // Lazy because the current stylesheet might not contain any further @import statements @@ -25,7 +25,7 @@ export async function parseStyles( let base: string | undefined; const jobs: Array> = []; - for (const stmt of statements) { + for (const stmt of stylesheet.statements) { if (!isImportStatement(stmt) || !isProcessableURL(stmt.uri)) { continue; } @@ -40,42 +40,37 @@ export async function parseStyles( jobs.push(resolveImportId(result, stmt, postcss, require, sourceFile, base)); } - await Promise.all(jobs); + if (jobs.length) { + await Promise.all(jobs); + } } - let charset: CharsetStatement | null = null; - const imports: Array = []; - const bundle: Array = []; - - // squash statements and their children - statements.forEach(stmt => { - if (isCharsetStatement(stmt)) { - charset = handleCharset(stmt, charset); - } else if (isImportStatement(stmt)) { - if (stmt.children) { - stmt.children.forEach((child) => { - if (isImportStatement(child)) { - imports.push(child); - } else if (isCharsetStatement(child)) { - charset = handleCharset(child, charset); - } else { - bundle.push(child); - } - }); - } else { - imports.push(stmt); + for (let i = 0; i < stylesheet.statements.length; i++) { + const stmt = stylesheet.statements[i]; + + if (isImportStatement(stmt) && stmt.stylesheet) { + if (stylesheet.charset && stmt.stylesheet.charset && stylesheet.charset.params.toLowerCase() !== stmt.stylesheet.charset.params.toLowerCase()) { + throw stmt.stylesheet.charset.error( + 'Incompatible @charset statements:\n' + + ` ${stmt.stylesheet.charset.params} specified in ${stmt.stylesheet.charset.source?.input.file}\n` + + ` ${stylesheet.charset.params} specified in ${stylesheet.charset.source?.input.file}`, + ); + } else if (!stylesheet.charset && !!stmt.stylesheet.charset) { + stylesheet.charset = stmt.stylesheet.charset; } - } else if (stmt.type === 'nodes') { - bundle.push(stmt); + + stylesheet.statements.splice(i, 1, ...stmt.stylesheet.statements); + i--; + continue; } - }); + } - return charset ? [charset, ...imports.concat(bundle)] : imports.concat(bundle); + return stylesheet; } async function resolveImportId(result: Result, stmt: ImportStatement, postcss: Postcss, require: NodeRequire, sourceFile: string, base: string) { if (isValidDataURL(stmt.uri)) { - stmt.children = await loadImportContent( + stmt.stylesheet = await loadImportContent( result, stmt, stmt.uri, @@ -86,7 +81,7 @@ async function resolveImportId(result: Result, stmt: ImportStatement, postcss: P } else if (isValidDataURL(stmt.from[stmt.from.length - 1])) { // Data urls can't be used as a base url to resolve imports. // Skip inlining and warn. - stmt.children = []; + stmt.stylesheet = { statements: [] }; result.warn( `Unable to import '${stmt.uri}' from a stylesheet that is embedded in a data url`, { @@ -105,8 +100,7 @@ async function resolveImportId(result: Result, stmt: ImportStatement, postcss: P parent: sourceFile, }); - const importedContent = await loadImportContent(result, stmt, resolved, postcss); - stmt.children = importedContent ?? []; + stmt.stylesheet = await loadImportContent(result, stmt, resolved, postcss); } async function loadImportContent( @@ -114,10 +108,10 @@ async function loadImportContent( stmt: ImportStatement, filename: string, postcss: Postcss, -) { +): Promise { const { conditions, from, node } = stmt; if (from.includes(filename)) { - return; + return { statements: [] }; } let content: string; @@ -178,19 +172,3 @@ function isProcessableURL(uri: string): boolean { return true; } - -function handleCharset(stmt: CharsetStatement, ref: CharsetStatement | null = null): CharsetStatement { - if (!ref) { - return stmt; - } else if ( - stmt.node.params.toLowerCase() !== ref.node.params.toLowerCase() - ) { - throw stmt.node.error( - `Incompatible @charset statements: - ${stmt.node.params} specified in ${stmt.node.source?.input.file} - ${ref.node.params} specified in ${ref.node.source?.input.file}`, - ); - } - - return ref; -} diff --git a/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-stylesheet.ts b/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-stylesheet.ts new file mode 100644 index 000000000..7655d5088 --- /dev/null +++ b/plugin-packs/postcss-bundler/src/postcss-import/lib/parse-stylesheet.ts @@ -0,0 +1,245 @@ +import type { AtRule, ChildNode, Document, Result, Root, Warning } from 'postcss'; +import { Condition } from './conditions'; +import { Stylesheet, ImportStatement, Statement } from './statement'; +import { IS_CHARSET, IS_IMPORT, IS_LAYER } from './names'; +import { parseAtImport } from './parse-at-import'; + +export function parseStylesheet(result: Result, styles: Root | Document, importingNode: AtRule | null, conditions: Array, from: Array): Stylesheet { + const stylesheet: Stylesheet = { + statements: [], + }; + + if (styles.type === 'document') { + styles.each((root) => { + const subStylesheet = parseStylesheet(result, root, importingNode, conditions, from); + + if (stylesheet.charset && subStylesheet.charset && stylesheet.charset.params.toLowerCase() !== subStylesheet.charset.params.toLowerCase()) { + throw subStylesheet.charset.error( + 'Incompatible @charset statements:\n' + + ` ${subStylesheet.charset.params} specified in ${subStylesheet.charset.source?.input.file}\n` + + ` ${stylesheet.charset.params} specified in ${stylesheet.charset.source?.input.file}`, + ); + } else if (!stylesheet.charset && !!subStylesheet.charset) { + stylesheet.charset = subStylesheet.charset; + } + + stylesheet.statements.push(...subStylesheet.statements); + }); + + return stylesheet; + } + + let charset: AtRule | undefined; + let beforeImports: Array = []; + let imports: Array = []; + let afterImports: Statement | undefined; + + for (let i = 0; i < styles.nodes.length; i++) { + const node = styles.nodes[i]; + + if (i === 0 && node.type === 'atrule' && IS_CHARSET.test(node.name)) { + charset = node; + continue; + } + + if (!imports.length && (node.type === 'comment' || (node.type === 'atrule' && IS_LAYER.test(node.name) && !node.nodes))) { + [i, beforeImports] = consumeBeforeImports(styles.nodes, conditions, i, importingNode, from); + continue; + } + + if (!imports.length && node.type === 'atrule' && IS_IMPORT.test(node.name)) { + [i, imports] = consumeImports(result, styles.nodes, conditions, i, importingNode, from); + continue; + } + + afterImports = { + type: 'nodes', + nodes: styles.nodes.slice(i), + conditions: [...conditions], + from, + importingNode, + }; + + break; + } + + const statements: Array = []; + + if (beforeImports.length) { + statements.push(...beforeImports); + } + + if (imports.length) { + statements.push(...imports); + } + + if (afterImports) { + statements.push(afterImports); + } + + return { + charset, + statements, + }; +} + +function consumeImports(result: Result, nodes: Array, conditions: Array, cursor: number, importingNode: AtRule | null, from: Array): [number, Array] { + const statements: Array = []; + + let i = cursor; + const l = nodes.length; + for (i; i < l; i++) { + const node = nodes[i]; + if (node.type === 'comment') { + const [j, commentsStmt] = consumeComments(nodes, i, importingNode, from); + statements.push(commentsStmt); + + i = j; + continue; + } + + if (node.type === 'atrule' && IS_IMPORT.test(node.name)) { + statements.push(parseImport(result, node, importingNode, conditions, from)); + continue; + } + + break; + } + + return [ + i - 1, + statements, + ]; +} + +function consumeBeforeImports(nodes: Array, conditions: Array, cursor: number, importingNode: AtRule | null, from: Array): [number, Array] { + const statements: Array = []; + + let i = cursor; + const l = nodes.length; + for (i; i < l; i++) { + const node = nodes[i]; + if (node.type === 'comment') { + const [j, commentsStmt] = consumeComments(nodes, i, importingNode, from); + statements.push(commentsStmt); + + i = j; + continue; + } + + if (node.type === 'atrule' && IS_LAYER.test(node.name) && !node.nodes) { + if (conditions.length) { + statements.push({ + type: 'pre-import', + node: node, + conditions: [...conditions], + from, + importingNode, + }); + + continue; + } else { + + const [j, layerStmt] = consumeLayers(nodes, conditions, i, importingNode, from); + statements.push(layerStmt); + + i = j; + continue; + } + } + + break; + } + + return [ + i - 1, + statements, + ]; +} + +function consumeComments(nodes: Array, cursor: number, importingNode: AtRule | null, from: Array): [number, Statement] { + const comments: Array = []; + + let i = cursor; + const l = nodes.length; + for (i; i < l; i++) { + const node = nodes[i]; + comments.push(node); + + const next = nodes[i + 1]; + if (next?.type === 'comment') { + continue; + } + + break; + } + + return [ + i, + { + type: 'nodes', + nodes: comments, + conditions: [], + from, + importingNode, + }, + ]; +} + +function consumeLayers(nodes: Array, conditions: Array, cursor: number, importingNode: AtRule | null, from: Array): [number, Statement] { + const layers: Array = []; + + let i = cursor; + const l = nodes.length; + for (i; i < l; i++) { + const node = nodes[i]; + layers.push(node); + + const next = nodes[i + 1]; + if (next && next.type === 'atrule' && IS_LAYER.test(next.name) && !next.nodes) { + continue; + } + + break; + } + + return [ + i, + { + type: 'nodes', + nodes: layers, + conditions: [...conditions], + from, + importingNode, + }, + ]; +} + +function parseImport(result: Result, atRule: AtRule, importingNode: AtRule | null, conditions: Array, from: Array): Warning | ImportStatement { + const parsed = parseAtImport(atRule.params); + if (!parsed) { + return result.warn(`Invalid @import statement in '${atRule.toString()}'`, { + node: atRule, + }); + } + + const stmt: ImportStatement = { + type: 'import', + uri: parsed.uri, + fullUri: parsed.fullUri, + node: atRule, + conditions: [...conditions], + from, + importingNode, + }; + + if (typeof parsed.layer !== 'undefined' || typeof parsed.media !== 'undefined' || typeof parsed.supports !== 'undefined') { + stmt.conditions.push({ + layer: parsed.layer, + media: parsed.media, + supports: parsed.supports, + }); + } + + return stmt; +} diff --git a/plugin-packs/postcss-bundler/src/postcss-import/lib/post-process.ts b/plugin-packs/postcss-bundler/src/postcss-import/lib/post-process.ts new file mode 100644 index 000000000..8d41f8cbb --- /dev/null +++ b/plugin-packs/postcss-bundler/src/postcss-import/lib/post-process.ts @@ -0,0 +1,91 @@ +import type { AtRule, AtRuleProps } from 'postcss'; +import { ImportStatement, NodesStatement, Stylesheet, isImportStatement, isNodesStatement, isPreImportStatement } from './statement'; + +export function postProcess(stylesheet: Stylesheet, atRule: (defaults?: AtRuleProps) => AtRule) { + let indexOfFirstImport = -1; + let indexOfFirstPreImport = -1; + let indexOfFirstMeaningfulNode = -1; + + for (let i = 0; i < stylesheet.statements.length; i++) { + const stmt = stylesheet.statements[i]; + + if (isImportStatement(stmt)) { + indexOfFirstImport = i; + if (indexOfFirstImport !== -1 && indexOfFirstPreImport !== -1 && indexOfFirstMeaningfulNode !== -1) { + break; + } + + continue; + } + + if (isPreImportStatement(stmt)) { + indexOfFirstPreImport = i; + if (indexOfFirstImport !== -1 && indexOfFirstPreImport !== -1 && indexOfFirstMeaningfulNode !== -1) { + break; + } + + continue; + } + + if (isNodesStatement(stmt)) { + for (let j = 0; j < stmt.nodes.length; j++) { + const node = stmt.nodes[j]; + if (node.type === 'comment') { + continue; + } + + indexOfFirstMeaningfulNode = i; + } + + if (indexOfFirstImport !== -1 && indexOfFirstPreImport !== -1 && indexOfFirstMeaningfulNode !== -1) { + break; + } + + continue; + } + } + + if (indexOfFirstPreImport !== -1) { + for (let i = 0; i < stylesheet.statements.length; i++) { + const stmt = stylesheet.statements[i]; + + if (isPreImportStatement(stmt)) { + if ( + i < indexOfFirstImport && + ( + i < indexOfFirstMeaningfulNode || + indexOfFirstMeaningfulNode === -1 + ) + ) { + const params = 'data:text/css;base64,' + Buffer.from(stmt.node.toString()).toString('base64'); + + const importStmt: ImportStatement = { + type: 'import', + uri: params, + fullUri: '\'' + params + '\'', + node: atRule({ + name: 'import', + params: '\'' + params + '\'', + source: stmt.node.source, + }), + conditions: stmt.conditions, + from: stmt.from, + importingNode: stmt.importingNode, + }; + + stylesheet.statements.splice(i, 1, importStmt); + } else { + const nodesStmt: NodesStatement = { + type: 'nodes', + nodes: [stmt.node], + conditions: stmt.conditions, + from: stmt.from, + importingNode: stmt.importingNode, + }; + + stylesheet.statements.splice(i, 1, nodesStmt); + } + } + } + } +} diff --git a/plugin-packs/postcss-bundler/src/postcss-import/lib/statement.ts b/plugin-packs/postcss-bundler/src/postcss-import/lib/statement.ts index 661b69e31..b2b6d82fe 100644 --- a/plugin-packs/postcss-bundler/src/postcss-import/lib/statement.ts +++ b/plugin-packs/postcss-bundler/src/postcss-import/lib/statement.ts @@ -1,10 +1,15 @@ import type { AtRule, ChildNode, Warning } from 'postcss'; import { Condition } from './conditions'; -export type Statement = ImportStatement | CharsetStatement | NodesStatement | Warning; +export type Stylesheet = { + charset?: AtRule; + statements: Array; +} + +export type Statement = ImportStatement | PreImportStatement | NodesStatement | Warning; export type NodesStatement = { - type: string + type: 'nodes' nodes: Array conditions: Array from: Array @@ -14,27 +19,27 @@ export type NodesStatement = { importingNode: AtRule | null } -export type CharsetStatement = { - type: string +export type ImportStatement = { + type: 'import' + uri: string + fullUri: string node: AtRule conditions: Array from: Array parent?: Statement + stylesheet?: Stylesheet importingNode: AtRule | null } -export type ImportStatement = { - type: string - uri: string - fullUri: string - node: AtRule +export type PreImportStatement = { + type: 'pre-import' + node: ChildNode conditions: Array from: Array parent?: Statement - children?: Array importingNode: AtRule | null } @@ -47,10 +52,10 @@ export function isNodesStatement(stmt: Statement): stmt is NodesStatement { return stmt.type === 'nodes'; } -export function isCharsetStatement(stmt: Statement): stmt is CharsetStatement { - return stmt.type === 'charset'; -} - export function isImportStatement(stmt: Statement): stmt is ImportStatement { return stmt.type === 'import'; } + +export function isPreImportStatement(stmt: Statement): stmt is PreImportStatement { + return stmt.type === 'pre-import'; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/001/foldername-that-is-a-domain/example.com/a.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/001/foldername-that-is-a-domain/example.com/a.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/001/foldername-that-is-a-domain/example.com/a.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/001/foldername-that-is-a-domain/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/001/foldername-that-is-a-domain/style.css new file mode 100644 index 000000000..9ce8b60e8 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/001/foldername-that-is-a-domain/style.css @@ -0,0 +1 @@ +@import url("example.com/a.css"); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/001/foldername-that-is-a-domain/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/001/foldername-that-is-a-domain/style.expect.css new file mode 100644 index 000000000..8dd258dfb --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/001/foldername-that-is-a-domain/style.expect.css @@ -0,0 +1,4 @@ +/* example.com/a.css */ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/before-other-styles/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/before-other-styles/001/style.expect.css index bbd050154..de31c4caa 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/before-other-styles/001/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/before-other-styles/001/style.expect.css @@ -1,3 +1,5 @@ .box { background-color: green; } + +@import url("./red.css"); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/before-other-styles/002/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/before-other-styles/002/style.expect.css index e51d21492..b29d35fb1 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/before-other-styles/002/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/before-other-styles/002/style.expect.css @@ -3,3 +3,5 @@ background-color: green; } } + +@import url("./red.css"); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/001/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/001/green.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/001/green.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/001/red.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/001/red.css new file mode 100644 index 000000000..47b0ac01e --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/001/red.css @@ -0,0 +1,3 @@ +.box { + background-color: red; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/001/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/001/style.css new file mode 100644 index 000000000..e2a95b1bd --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/001/style.css @@ -0,0 +1,2 @@ +@import url(red.css) does-not-exist(foo); +@import url(green.css); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/001/style.expect.css new file mode 100644 index 000000000..e210aaf86 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/001/style.expect.css @@ -0,0 +1,10 @@ +/* red.css */ +@media does-not-exist(foo) { + .box { + background-color: red; +} +} +/* green.css */ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/beige.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/beige.css new file mode 100644 index 000000000..481e7eb4b --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/beige.css @@ -0,0 +1,3 @@ +.box { + background-color: beige; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/green.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/green.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/red.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/red.css new file mode 100644 index 000000000..47b0ac01e --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/red.css @@ -0,0 +1,3 @@ +.box { + background-color: red; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/style.css new file mode 100644 index 000000000..997406c1d --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/style.css @@ -0,0 +1,3 @@ +@import url(beige.css); +@import url(red.css) does-not-exist(foo); +@import url(green.css); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/style.expect.css new file mode 100644 index 000000000..00453b5c2 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/002/style.expect.css @@ -0,0 +1,14 @@ +/* beige.css */ +.box { + background-color: beige; +} +/* red.css */ +@media does-not-exist(foo) { + .box { + background-color: red; +} +} +/* green.css */ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/003/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/003/green.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/003/green.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/003/red.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/003/red.css new file mode 100644 index 000000000..47b0ac01e --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/003/red.css @@ -0,0 +1,3 @@ +.box { + background-color: red; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/003/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/003/style.css new file mode 100644 index 000000000..58d688432 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/003/style.css @@ -0,0 +1,2 @@ +@import url(green.css); +@import url(red.css) does-not-exist(foo); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/003/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/003/style.expect.css new file mode 100644 index 000000000..69403d6f4 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/003/style.expect.css @@ -0,0 +1,10 @@ +/* green.css */ +.box { + background-color: green; +} +/* red.css */ +@media does-not-exist(foo) { + .box { + background-color: red; +} +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/004/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/004/green.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/004/green.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/004/red.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/004/red.css new file mode 100644 index 000000000..47b0ac01e --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/004/red.css @@ -0,0 +1,3 @@ +.box { + background-color: red; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/004/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/004/style.css new file mode 100644 index 000000000..aa7372b78 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/004/style.css @@ -0,0 +1,2 @@ +@import url(green.css); +@import url('red.css' url-mod); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/004/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/004/style.expect.css new file mode 100644 index 000000000..4d17baf2b --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/forwards-compat/004/style.expect.css @@ -0,0 +1,4 @@ +/* green.css */ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/namespace/002/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/namespace/002/style.expect.css index 0a53f84b9..107414626 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/namespace/002/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/namespace/002/style.expect.css @@ -4,3 +4,4 @@ } /* ./a.css */ @namespace url(http://www.w3.org/1999/xhtml); +@import url("./red.css"); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/008/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/008/style.css new file mode 100644 index 000000000..a2fdfb13e --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/008/style.css @@ -0,0 +1,5 @@ +@import url("./styles/green.css"); + +.box { + background-image: var(--background-image); +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/008/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/008/style.expect.css new file mode 100644 index 000000000..23dcdcc37 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/008/style.expect.css @@ -0,0 +1,15 @@ +/* ./styles/green.css */ + +@property --background-image { + syntax: ' | none'; + inherits: true; + initial-value: none; +} + +.box { + --background-image: url(styles/green.png); +} + +.box { + background-image: var(--background-image); +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/008/styles/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/008/styles/green.css new file mode 100644 index 000000000..e749a61c7 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/008/styles/green.css @@ -0,0 +1,9 @@ +@property --background-image { + syntax: ' | none'; + inherits: true; + initial-value: none; +} + +.box { + --background-image: url(./green.png); +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/008/styles/green.png b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/008/styles/green.png new file mode 100644 index 000000000..3171cfbaf Binary files /dev/null and b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/008/styles/green.png differ diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/009/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/009/style.css new file mode 100644 index 000000000..0b5f458f9 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/009/style.css @@ -0,0 +1,5 @@ +@import url("./styles/green.css"); + +.box { + --background-image: url(./green.png); +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/009/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/009/style.expect.css new file mode 100644 index 000000000..87b0b0dda --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/009/style.expect.css @@ -0,0 +1,15 @@ +/* ./styles/green.css */ + +@property --background-image { + syntax: '*'; + inherits: true; + initial-value: none; +} + +.box { + background-image: var(--background-image); +} + +.box { + --background-image: url(./green.png); +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/009/styles/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/009/styles/green.css new file mode 100644 index 000000000..7ed951a8e --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/009/styles/green.css @@ -0,0 +1,9 @@ +@property --background-image { + syntax: '*'; + inherits: true; + initial-value: none; +} + +.box { + background-image: var(--background-image); +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/009/styles/green.png b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/009/styles/green.png new file mode 100644 index 000000000..3171cfbaf Binary files /dev/null and b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/009/styles/green.png differ diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/010/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/010/style.css new file mode 100644 index 000000000..0b5f458f9 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/010/style.css @@ -0,0 +1,5 @@ +@import url("./styles/green.css"); + +.box { + --background-image: url(./green.png); +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/010/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/010/style.expect.css new file mode 100644 index 000000000..00b2990b6 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/010/style.expect.css @@ -0,0 +1,7 @@ +/* ./styles/green.css */ +.box { + background-image: var(--background-image); +} +.box { + --background-image: url(./green.png); +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/010/styles/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/010/styles/green.css new file mode 100644 index 000000000..8e5d882d5 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/010/styles/green.css @@ -0,0 +1,3 @@ +.box { + background-image: var(--background-image); +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/010/styles/green.png b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/010/styles/green.png new file mode 100644 index 000000000..3171cfbaf Binary files /dev/null and b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/010/styles/green.png differ diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/011/example.com/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/011/example.com/green.css new file mode 100644 index 000000000..2d0baeba2 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/011/example.com/green.css @@ -0,0 +1,3 @@ +.box { + background-image: url('./green.png'); +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/011/example.com/green.png b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/011/example.com/green.png new file mode 100644 index 000000000..3171cfbaf Binary files /dev/null and b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/011/example.com/green.png differ diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/011/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/011/style.css new file mode 100644 index 000000000..c10c5848d --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/011/style.css @@ -0,0 +1 @@ +@import url("./example.com/green.css"); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/011/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/011/style.expect.css new file mode 100644 index 000000000..a0b71cd7c --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/subresource/011/style.expect.css @@ -0,0 +1,4 @@ +/* ./example.com/green.css */ +.box { + background-image: url("example.com/green.png"); +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/a.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/a.css new file mode 100644 index 000000000..47b0ac01e --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/a.css @@ -0,0 +1,3 @@ +.box { + background-color: red; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/b.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/b.css new file mode 100644 index 000000000..47b0ac01e --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/b.css @@ -0,0 +1,3 @@ +.box { + background-color: red; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/green.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/green.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/style.css new file mode 100644 index 000000000..8b4981ee6 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/style.css @@ -0,0 +1,2 @@ +@import url("green.css"); +@import url("#a.css"); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/style.expect.css new file mode 100644 index 000000000..4d17baf2b --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/001-core-features/url-fragments/005/style.expect.css @@ -0,0 +1,4 @@ +/* green.css */ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/001-data-urls/005/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/001-data-urls/005/style.expect.css index 2ececda9a..20c290baa 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/001-data-urls/005/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/001-data-urls/005/style.expect.css @@ -1,2 +1,2 @@ -@import url(http://localhost:8080/a.css); /* data:text/css,%40import%20url(http%3A%2F%2Flocalhost%3A8080%2Fa.css)%3B */ +@import url(http://localhost:8080/a.css); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/001/default/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/001/default/style.expect.css index b17e33be4..c7932b607 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/001/default/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/001/default/style.expect.css @@ -1,5 +1,5 @@ +/* a.css */ @media screen { - /* a.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/002/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/002/style.expect.css index 3c0dc6fd3..139be8025 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/002/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/002/style.expect.css @@ -1,11 +1,11 @@ +/* a.css */ @media screen { - /* a.css */ .box { background-color: green; } } +/* b.css */ @media print { - /* b.css */ .box { background-color: red; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/003/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/003/style.expect.css index a7b99d90f..9894faa07 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/003/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/003/style.expect.css @@ -1,9 +1,7 @@ -@media screen { - /* a.css */ -} +/* a.css */ +/* b.css */ @media screen { @media (min-width: 1px) { - /* b.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/004/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/004/style.expect.css index 72c1b91c6..9024f4427 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/004/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/004/style.expect.css @@ -2,12 +2,10 @@ .box { background-color: green; } -@media print { - /* a.css */ -} +/* a.css */ +/* b.css */ @media print { @media print { - /* b.css */ .box { background-color: red; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/005/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/005/style.expect.css index d4ba1aec8..56ef0ddae 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/005/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/005/style.expect.css @@ -2,12 +2,10 @@ .box { background-color: green; } -@media (max-width: 1px) { - /* a.css */ -} +/* a.css */ +/* b.css */ @media (max-width: 1px) { @media (max-width: 1px) { - /* b.css */ .box { background-color: red; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/006/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/006/style.expect.css index 6870278bb..def9c0850 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/006/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/006/style.expect.css @@ -1,9 +1,7 @@ -@media (min-height: 1px) { - /* a.css */ -} +/* a.css */ +/* b.css */ @media (min-height: 1px) { @media (min-width: 1px) { - /* b.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/007/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/007/style.expect.css index 99a525030..1a6eab8a8 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/007/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/007/style.expect.css @@ -1,9 +1,7 @@ -@media all { - /* a.css */ -} +/* a.css */ +/* b.css */ @media all { @media screen { - /* b.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/008/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/008/style.expect.css index 80c3dc93f..77d0273ef 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/008/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/008/style.expect.css @@ -1,13 +1,9 @@ -@media all { - @layer alpha { - /* a.css */ - } -} +/* a.css */ +/* green.css */ @media all { @layer alpha { @media print { @layer alpha { - /* green.css */ .box { background-color: green; } @@ -15,16 +11,12 @@ } } } -@media all { - @layer beta { - /* b.css */ - } -} +/* b.css */ +/* red.css */ @media all { @layer beta { @media print { @layer beta { - /* red.css */ .box { background-color: red; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/009/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/009/style.expect.css index 6ab2d626e..1c4781d1e 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/009/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/009/style.expect.css @@ -1,4 +1,2 @@ +/* ./a.css */ @import 'data:text/css;base64,QGltcG9ydCB1cmwoImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9ncmVlbi5jc3MiKSAobWluLXdpZHRoOiAxcHgp' (min-height: 1px); -@media (min-width: 1px){ - /* ./a.css */ -} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/010/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/010/style.expect.css index f84ed2db9..d87676f81 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/010/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/010/style.expect.css @@ -1,6 +1,3 @@ - +/* ./a.css */ @import url("http://localhost:8080/green.css") not print and (min-width: 1px); @import 'data:text/css;base64,QGltcG9ydCB1cmwoImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9yZWQuY3NzIikgbm90IHByaW50IGFuZCAobWluLXdpZHRoOiAxcHgp' not screen and (min-height: 1px); -@media not print and (min-width: 1px){ -/* ./a.css */ -} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/011/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/011/style.expect.css index fe759e6c4..3da320613 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/011/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/011/style.expect.css @@ -1,5 +1,3 @@ @import url("http://localhost:8080/green.css"); +/* ./a.css */ @import 'data:text/css;base64,QGltcG9ydCB1cmwoImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9yZWQuY3NzIikgc2NyZWVuIGFuZCAobm90IChtaW4td2lkdGg6IDFweCkp' not print and (min-height: 1px); -@media screen and (not (min-width: 1px)){ - /* ./a.css */ -} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/012/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/012/style.expect.css index c8427d736..135bc2958 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/012/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/012/style.expect.css @@ -1,4 +1,2 @@ +/* ./a.css */ @import 'data:text/css;base64,QGltcG9ydCB1cmwoImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9ncmVlbi5jc3MiKSBub3QgcHJpbnQgYW5kIChtaW4td2lkdGg6IDFweCk=' not screen and (max-height: 1px); -@media not print and (min-width: 1px){ - /* ./a.css */ -} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/013/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/013/style.expect.css index 04b853774..70a128840 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/013/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/013/style.expect.css @@ -1,17 +1,15 @@ -@media not print and (min-width: 1px) { /* a.css */ -} -@media not print and (min-width: 1px) { /* green.css */ -.box { +@media not print and (min-width: 1px) { + .box { background-color: green; } } -@media not print and (min-width: 1px) { -@media not screen and (min-height: 1px) { /* red.css */ -.box { +@media not print and (min-width: 1px) { + @media not screen and (min-height: 1px) { + .box { background-color: red; } -} + } } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/014/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/014/style.expect.css index c36df5461..193be70e3 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/014/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/014/style.expect.css @@ -1,11 +1,4 @@ - +/* ./a.css */ +/* ./b.css */ @import 'data:text/css;base64,QGltcG9ydCB1cmwoImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9ncmVlbi5jc3MiKSBub3QgcHJpbnQgYW5kIChtaW4td2lkdGg6IDFweCk=' not print and (min-color: 1); @import 'data:text/css;base64,QGltcG9ydCAnZGF0YTp0ZXh0L2NzcztiYXNlNjQsUUdsdGNHOXlkQ0IxY213b0ltaDBkSEE2THk5c2IyTmhiR2h2YzNRNk9EQTRNQzl5WldRdVkzTnpJaWtnYm05MElIQnlhVzUwSUdGdVpDQW9iV2x1TFhkcFpIUm9PaUF4Y0hncCcgbm90IHNjcmVlbiBhbmQgKG1pbi1oZWlnaHQ6IDFweCk=' not print and (min-color: 1); -@media not print and (min-width: 1px){ - /* ./a.css */ -} -@media not print and (min-width: 1px){ - @media not print and (min-color: 1){ -/* ./b.css */ - } -} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/015/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/015/style.expect.css index fca1c9fcf..840af196e 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/015/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/015/style.expect.css @@ -1,4 +1,2 @@ +/* ./a.css */ @import 'data:text/css;base64,QGltcG9ydCB1cmwoImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9ncmVlbi5jc3MiKSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDFweCk=' screen and (min-height: 1px); -@media screen and (min-width: 1px){ - /* ./a.css */ -} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/016/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/016/style.expect.css index 2e61a20cc..9020ccd97 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/016/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/016/style.expect.css @@ -1,4 +1,2 @@ +/* ./a.css */ @import 'data:text/css;base64,QGltcG9ydCB1cmwoImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9ncmVlbi5jc3MiKSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDFweCk=' all and (min-height: 1px); -@media screen and (min-width: 1px){ - /* ./a.css */ -} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/017/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/017/style.expect.css index 19c593e31..4fe95ed41 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/017/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/017/style.expect.css @@ -1,4 +1,2 @@ +/* ./a.css */ @import 'data:text/css;base64,QGltcG9ydCB1cmwoImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9ncmVlbi5jc3MiKSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDFweCk=' not print and (min-height: 1px); -@media screen and (min-width: 1px){ - /* ./a.css */ -} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/018/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/018/style.expect.css index a14c85360..c3ce1a654 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/018/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/018/style.expect.css @@ -1,4 +1,2 @@ +/* ./a.css */ @import 'data:text/css;base64,QGltcG9ydCB1cmwoImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9ncmVlbi5jc3MiKSBub3QgcHJpbnQgYW5kIChtaW4td2lkdGg6IDFweCk=' all and (min-height: 1px); -@media not print and (min-width: 1px){ - /* ./a.css */ -} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/at-keyframes/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/at-keyframes/001/style.expect.css index 93775dcf6..269609e3f 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/at-keyframes/001/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/at-keyframes/001/style.expect.css @@ -1,7 +1,7 @@ -@media screen { - /* a.css */ +@media screen { + .box { animation: BOX; animation-duration: 0s; @@ -15,10 +15,10 @@ } } -@media print { - /* b.css */ +@media print { + .box { animation: BOX; animation-duration: 0s; diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/cycles/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/cycles/001/style.expect.css index 672f63d5a..f0c61b4b5 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/cycles/001/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/002-at-media/cycles/001/style.expect.css @@ -3,33 +3,25 @@ .box { background-color: green; } -@media all { /* a.css */ -} +/* red.css */ @media all { - /* red.css */ .box { background-color: red; } } /* c.css */ -@media not print { /* a.css */ -} +/* red.css */ @media not print { - /* red.css */ .box { background-color: red; } } -@media not print { - @media screen { /* b.css */ - } -} +/* green.css */ @media not print { @media screen { - /* green.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/001/style.expect.css index 4b3f589b9..9307b40c8 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/001/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/001/style.expect.css @@ -1,17 +1,17 @@ +/* a.css */ @layer a { - /* a.css */ .box { background-color: red; } } +/* b.css */ @layer b { - /* b.css */ .box { background-color: green; } } +/* a.css */ @layer a { - /* a.css */ .box { background-color: red; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/002/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/002/style.expect.css index 3ba0d3899..36b67c17f 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/002/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/002/style.expect.css @@ -1,19 +1,19 @@ +/* a.css */ @media print { @layer a { - /* a.css */ .box { background-color: green; } } } +/* b.css */ @layer b { - /* b.css */ .box { background-color: red; } } +/* a.css */ @layer a { - /* a.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/005/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/005/style.expect.css index ff7761f1e..003828800 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/005/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/005/style.expect.css @@ -1,13 +1,9 @@ -@media (min-width: 1px) { - @layer a { - /* a.css */ - } -} +/* a.css */ +/* b.css */ @media (min-width: 1px) { @layer a { @media (width: 1px) { @layer b { - /* b.css */ .box { background-color: red; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/006/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/006/style.expect.css index 771baf022..409f3b521 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/006/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/006/style.expect.css @@ -1,13 +1,9 @@ -@media (min-width: 1px) { - @layer a { - /* a.css */ - } -} +/* a.css */ +/* b.css */ @media (min-width: 1px) { @layer a { @media (min-width: 1px) { @layer b { - /* b.css */ .box { background-color: red; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/008/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/008/style.expect.css index bd8e99931..dfd6446f6 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/008/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/008/style.expect.css @@ -1,14 +1,10 @@ -@layer { - /* a.css */ -} +/* b.css */ @layer { @layer { -/* b.css */ - .box { background-color: red; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/010/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/010/style.expect.css index ab9af588f..1bb9ae759 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/010/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/010/style.expect.css @@ -1,17 +1,17 @@ +/* a.css */ @layer { - /* a.css */ .box { background-color: green; } } +/* b.css */ @layer { - /* b.css */ .box { background-color: red; } } +/* a.css */ @layer { - /* a.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/011/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/011/style.expect.css index d3d24e4ac..46c69f6ec 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/011/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/011/style.expect.css @@ -3,3 +3,4 @@ background-color: green; } @layer a; +@import url("red.css"); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/012/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/012/style.expect.css index f6941040c..d20006790 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/012/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/012/style.expect.css @@ -1,6 +1,6 @@ @layer a; +/* green.css */ @layer b{ - /* green.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/013/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/013/green.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/013/green.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/013/red.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/013/red.css new file mode 100644 index 000000000..47b0ac01e --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/013/red.css @@ -0,0 +1,3 @@ +.box { + background-color: red; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/013/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/013/style.css new file mode 100644 index 000000000..a82901755 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/013/style.css @@ -0,0 +1,2 @@ +@import url("green.css"); +@import layer(foo) url("red.css"); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/013/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/013/style.expect.css new file mode 100644 index 000000000..4d17baf2b --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/013/style.expect.css @@ -0,0 +1,4 @@ +/* green.css */ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/a.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/a.css new file mode 100644 index 000000000..241c7075a --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/a.css @@ -0,0 +1 @@ +@layer b, a; diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/b.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/b.css new file mode 100644 index 000000000..700a9396f --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/b.css @@ -0,0 +1,5 @@ +/* a comment */ + +@layer a, b; + +@import url("http://localhost:8080/green.css"); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/green.css new file mode 100644 index 000000000..47f69e132 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/green.css @@ -0,0 +1,11 @@ +@layer b { + .box { + background-color: green; + } +} + +@layer a { + .box { + background-color: red; + } +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/style.css new file mode 100644 index 000000000..338d293a7 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/style.css @@ -0,0 +1,2 @@ +@import url("./a.css") print; +@import url("./b.css") screen; diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/style.expect.css new file mode 100644 index 000000000..f41ac3b32 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/014/style.expect.css @@ -0,0 +1,6 @@ +/* ./a.css */ +@import 'data:text/css;base64,QGxheWVyIGIsIGE=' print; +/* ./b.css */ +/* a comment */ +@import 'data:text/css;base64,QGxheWVyIGEsIGI=' screen; +@import url("http://localhost:8080/green.css") screen; diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/at-keyframes/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/at-keyframes/001/style.expect.css index 496b23b30..b94bd465a 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/at-keyframes/001/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/at-keyframes/001/style.expect.css @@ -12,10 +12,10 @@ } } -@layer { - /* b.css */ +@layer { + .box { animation: BOX; animation-duration: 0s; diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/at-keyframes/002/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/at-keyframes/002/style.expect.css index 8405d3561..e6a7238cf 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/at-keyframes/002/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/at-keyframes/002/style.expect.css @@ -1,9 +1,8 @@ @layer a, b; +/* a.css */ @layer b{ -/* a.css */ - .box { animation: BOX; animation-duration: 0s; @@ -16,11 +15,10 @@ } } } +/* b.css */ @layer a{ -/* b.css */ - .box { animation: BOX; animation-duration: 0s; diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/001/style.expect.css index 74f6f31b9..d1f5a875d 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/001/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/001/style.expect.css @@ -1,11 +1,11 @@ +/* red.css */ @layer { - /* red.css */ .box { background-color: red; } } +/* a.css */ @layer { - /* a.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/002/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/002/green.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/002/green.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/002/red.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/002/red.css new file mode 100644 index 000000000..47b0ac01e --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/002/red.css @@ -0,0 +1,3 @@ +.box { + background-color: red; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/002/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/002/style.css new file mode 100644 index 000000000..460f8ba17 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/002/style.css @@ -0,0 +1,3 @@ +@import url("./red.css") layer(black); +@import url("./green.css") layer(black); + diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/002/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/002/style.expect.css new file mode 100644 index 000000000..943309ded --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/002/style.expect.css @@ -0,0 +1,13 @@ +/* ./red.css */ +@layer black { + .box { + background-color: red; +} +} +/* ./green.css */ +@layer black { + .box { + background-color: green; +} +} + diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/003/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/003/green.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/003/green.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/003/red.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/003/red.css new file mode 100644 index 000000000..47b0ac01e --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/003/red.css @@ -0,0 +1,3 @@ +.box { + background-color: red; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/003/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/003/style.css new file mode 100644 index 000000000..cc40685cf --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/003/style.css @@ -0,0 +1,4 @@ +@layer blacK; + +@import url("./green.css") layer(blacK); +@import url("./red.css") layer(blacK); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/003/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/003/style.expect.css new file mode 100644 index 000000000..ac5039eae --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/case-sensitivity/003/style.expect.css @@ -0,0 +1,13 @@ +@layer blacK; +/* ./green.css */ +@layer blacK{ + .box { + background-color: green; +} +} +/* ./red.css */ +@layer blacK{ + .box { + background-color: red; +} +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/cycles/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/cycles/001/style.expect.css index 4e1398d78..d6ffe627d 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/cycles/001/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/cycles/001/style.expect.css @@ -1,37 +1,33 @@ /* b.css */ -@layer { /* green.css */ -.box { +@layer { + .box { background-color: green; } } /* a.css */ -@layer { /* red.css */ -.box { +@layer { + .box { background-color: red; } } /* c.css */ -@layer { /* a.css */ -} -@layer { -@layer { /* red.css */ -.box { +@layer { + @layer { + .box { background-color: red; } + } } -} -@layer { /* b.css */ -} -@layer { -@layer { /* green.css */ -.box { +@layer { + @layer { + .box { background-color: green; } -} + } } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/a.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/a.css new file mode 100644 index 000000000..fc1e4ecd2 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/a.css @@ -0,0 +1 @@ +@layer a; diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/b.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/b.css new file mode 100644 index 000000000..0d61d1764 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/b.css @@ -0,0 +1 @@ +@layer b; diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/c.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/c.css new file mode 100644 index 000000000..241c7075a --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/c.css @@ -0,0 +1 @@ +@layer b, a; diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/green.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/green.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/red.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/red.css new file mode 100644 index 000000000..47b0ac01e --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/red.css @@ -0,0 +1,3 @@ +.box { + background-color: red; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/style.css new file mode 100644 index 000000000..678d718eb --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/style.css @@ -0,0 +1,5 @@ +@import url("a.css"); +@import url("b.css"); +@import url("http://localhost:8080/c.css"); +@import url("green.css") layer(b); +@import url("red.css") layer(a); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/style.expect.css new file mode 100644 index 000000000..893619be6 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/mixed-importables/001/style.expect.css @@ -0,0 +1,17 @@ +/* a.css */ +@layer a; +/* b.css */ +@layer b; +@import url("http://localhost:8080/c.css"); +/* green.css */ +@layer b{ + .box { + background-color: green; +} +} +/* red.css */ +@layer a{ + .box { + background-color: red; +} +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/url-fragments/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/url-fragments/001/style.expect.css index 042fff1f5..c56e453f9 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/url-fragments/001/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/003-at-layer/url-fragments/001/style.expect.css @@ -1,17 +1,17 @@ +/* ./a.css */ @layer { - /* ./a.css */ .box { background-color: green; } } +/* ./b.css */ @layer { - /* ./b.css */ .box { background-color: red; } } +/* ./a.css */ @layer { - /* ./a.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/001/style.expect.css index 8adad68f7..a98e1f677 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/001/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/001/style.expect.css @@ -1,5 +1,5 @@ +/* a.css */ @supports (display: block) { - /* a.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/002/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/002/style.expect.css index 8978a66d8..233dde115 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/002/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/002/style.expect.css @@ -1,9 +1,7 @@ -@supports (display: block) { - /* a.css */ -} +/* a.css */ +/* b.css */ @supports (display: block) { @supports (width: 10px) { - /* b.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/003/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/003/style.expect.css index 2a1160f9a..53d293c25 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/003/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/003/style.expect.css @@ -1,9 +1,7 @@ -@supports ((display: block) or (display: inline)) { - /* a.css */ -} +/* a.css */ +/* b.css */ @supports ((display: block) or (display: inline)) { @supports (width: 10px) { - /* b.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/004/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/004/style.expect.css index 29100eeac..98df14ffc 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/004/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/004/style.expect.css @@ -1,13 +1,9 @@ -@supports (display: block) { - @layer a { - /* a.css */ - } -} +/* a.css */ +/* b.css */ @supports (display: block) { @layer a { @supports (width: 10px) { @layer b { - /* b.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/005/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/005/style.expect.css index 84803f283..9d804295b 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/005/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/005/style.expect.css @@ -1,13 +1,9 @@ -@supports (display: block) { - @layer alpha { - /* a.css */ - } -} +/* a.css */ +/* green.css */ @supports (display: block) { @layer alpha { @supports (foo: bar) { @layer alpha { - /* green.css */ .box { background-color: green; } @@ -15,16 +11,12 @@ } } } -@supports (display: block) { - @layer beta { - /* b.css */ - } -} +/* b.css */ +/* red.css */ @supports (display: block) { @layer beta { @supports (foo: bar) { @layer beta { - /* red.css */ .box { background-color: red; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/006/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/006/style.expect.css index 2dec1b18a..337a59882 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/006/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/006/style.expect.css @@ -1,18 +1,5 @@ - +/* ./a.css */ +/* ./b.css */ +/* ./c.css */ @import 'data:text/css;base64,QGltcG9ydCAnZGF0YTp0ZXh0L2NzcztiYXNlNjQsUUdsdGNHOXlkQ0IxY213b0ltaDBkSEE2THk5c2IyTmhiR2h2YzNRNk9EQTRNQzluY21WbGJpNWpjM01pS1NCdWIzUWdjSEpwYm5RZ1lXNWtJQ2h0YVc0dGQybGtkR2c2SURGd2VDaz0nIGxheWVyKGZvbyk=' supports(display: grid); @import 'data:text/css;base64,QGltcG9ydCAnZGF0YTp0ZXh0L2NzcztiYXNlNjQsUUdsdGNHOXlkQ0FuWkdGMFlUcDBaWGgwTDJOemN6dGlZWE5sTmpRc1VVZHNkR05IT1hsa1EwSXhZMjEzYjBsdGFEQmtTRUUyVEhrNWMySXlUbWhpUjJoMll6TlJOazlFUVRSTlF6bDVXbGRSZFZrelRucEphV3RuWW0wNU1FbElRbmxoVnpVd1NVZEdkVnBEUVc5aVYyeDFURmhrY0ZwSVVtOVBhVUY0WTBobmNDY2dibTkwSUhOamNtVmxiaUJoYm1RZ0tHMXBiaTFvWldsbmFIUTZJREZ3ZUNrPScgbGF5ZXIoZm9vKQ==' supports(display: grid); -@media not print and (min-width: 1px){ - /* ./a.css */ -} -@media not print and (min-width: 1px){ - @supports (display: grid){ - /* ./b.css */ - } -} -@media not print and (min-width: 1px){ - @supports (display: grid){ - @layer foo{ -/* ./c.css */ - } - } -} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/008/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/008/style.expect.css index 681157288..c28e30bf4 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/008/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/008/style.expect.css @@ -2,14 +2,14 @@ .box { background-color: green; } +/* red.css */ @media (min-width: 1px) supports(display: block) { - /* red.css */ .box { background-color: red; } } +/* red.css */ @media screen supports(display: block) { - /* red.css */ .box { background-color: red; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/009/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/009/green.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/009/green.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/009/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/009/style.css new file mode 100644 index 000000000..04a416b53 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/009/style.css @@ -0,0 +1 @@ +@import url("green.css") layer(b) supports(display: block) screen; diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/009/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/009/style.expect.css new file mode 100644 index 000000000..5b651e599 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/009/style.expect.css @@ -0,0 +1,10 @@ +/* green.css */ +@media screen { + @supports (display: block) { + @layer b { + .box { + background-color: green; +} + } + } +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/010/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/010/green.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/010/green.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/010/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/010/style.css new file mode 100644 index 000000000..71f3bbb63 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/010/style.css @@ -0,0 +1,4 @@ +@import url("green.css") + layer + supports(display: block) + (min-width: 10px); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/010/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/010/style.expect.css new file mode 100644 index 000000000..fe46817a6 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/010/style.expect.css @@ -0,0 +1,10 @@ +/* green.css */ +@media (min-width: 10px) { + @supports (display: block) { + @layer { + .box { + background-color: green; +} + } + } +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/011/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/011/green.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/011/green.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/011/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/011/style.css new file mode 100644 index 000000000..64a22f8ad --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/011/style.css @@ -0,0 +1,4 @@ +@import url("green.css") + layer + supports(selector(&)) + (min-width: 10px); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/011/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/011/style.expect.css new file mode 100644 index 000000000..2c04ca933 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/011/style.expect.css @@ -0,0 +1,10 @@ +/* green.css */ +@media (min-width: 10px) { + @supports (selector(&)) { + @layer { + .box { + background-color: green; +} + } + } +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/012/green.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/012/green.css new file mode 100644 index 000000000..bbd050154 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/012/green.css @@ -0,0 +1,3 @@ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/012/red.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/012/red.css new file mode 100644 index 000000000..47b0ac01e --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/012/red.css @@ -0,0 +1,3 @@ +.box { + background-color: red; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/012/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/012/style.css new file mode 100644 index 000000000..cc2b24f55 --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/012/style.css @@ -0,0 +1,2 @@ +@import url("green.css"); +@import supports(selector(&)) url("red.css"); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/012/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/012/style.expect.css new file mode 100644 index 000000000..4d17baf2b --- /dev/null +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/012/style.expect.css @@ -0,0 +1,4 @@ +/* green.css */ +.box { + background-color: green; +} diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/case-sensitivity/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/case-sensitivity/001/style.expect.css index 27777d243..b418d272c 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/case-sensitivity/001/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/002-sub-features/004-at-supports/case-sensitivity/001/style.expect.css @@ -2,8 +2,8 @@ .box { background-color: red; } +/* a.css */ @supports (display: flex) { - /* a.css */ .box { background-color: green; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/003-should-fail/001-core-features/before-other-styles/002/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/003-should-fail/001-core-features/before-other-styles/002/style.expect.css index 83d2cb9fc..708333a94 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/003-should-fail/001-core-features/before-other-styles/002/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/003-should-fail/001-core-features/before-other-styles/002/style.expect.css @@ -1 +1,3 @@ @unknown foo; + +@import url("./green.css"); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/002-url-queries/001/style.css b/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/002-url-queries/001/style.css index dfdbca03a..c4cd54de2 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/002-url-queries/001/style.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/002-url-queries/001/style.css @@ -1 +1,2 @@ +@import url("./a.css"); @import url("./a.css?background-color=green"); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/002-url-queries/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/002-url-queries/001/style.expect.css index dfdbca03a..c089daa78 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/002-url-queries/001/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/002-url-queries/001/style.expect.css @@ -1 +1,5 @@ +/* ./a.css */ +.box { + background-color: red; +} @import url("./a.css?background-color=green"); diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/003-mixed-importables/001/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/003-mixed-importables/001/style.expect.css index 60708cc7b..893619be6 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/003-mixed-importables/001/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/003-mixed-importables/001/style.expect.css @@ -1,17 +1,16 @@ - -@import url("http://localhost:8080/c.css"); /* a.css */ @layer a; /* b.css */ @layer b; +@import url("http://localhost:8080/c.css"); +/* green.css */ @layer b{ - /* green.css */ .box { background-color: green; } } +/* red.css */ @layer a{ - /* red.css */ .box { background-color: red; } diff --git a/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/003-mixed-importables/002/style.expect.css b/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/003-mixed-importables/002/style.expect.css index 713b4195b..e348bce57 100644 --- a/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/003-mixed-importables/002/style.expect.css +++ b/plugin-packs/postcss-bundler/test/css-import-tests/004-unimplementable/003-mixed-importables/002/style.expect.css @@ -1,5 +1,3 @@ - -@import url("http://localhost:8080/b.css"); /* a.css */ .box { @@ -15,3 +13,5 @@ background-color: red; } } + +@import url("http://localhost:8080/b.css"); diff --git a/plugin-packs/postcss-bundler/test/ignore.css b/plugin-packs/postcss-bundler/test/ignore.css index d6c115bae..149b64750 100644 --- a/plugin-packs/postcss-bundler/test/ignore.css +++ b/plugin-packs/postcss-bundler/test/ignore.css @@ -1,3 +1,4 @@ @import layer(foo) "imports/basic.css"; @import supports(foo) "imports/basic.css"; @import url('imports/basic.css' url-mod); +@import url('imports/basic.css' 'imports/basic.css'); diff --git a/plugin-packs/postcss-bundler/test/regexp.expect.css b/plugin-packs/postcss-bundler/test/regexp.expect.css index f1fdae522..166442e08 100644 --- a/plugin-packs/postcss-bundler/test/regexp.expect.css +++ b/plugin-packs/postcss-bundler/test/regexp.expect.css @@ -1,9 +1,7 @@ -/* various sanity checks for regexp in the code base */ +/* various sanity checks for regexp in the code base *//* imports/basic.css */ @media zlayer(foo) { -/* imports/basic.css */ - .foo { background: url("images/green.png"); } @@ -23,12 +21,10 @@ .search { background: url("images/green.png?foo=bar"); } -} +}/* imports/basic.css */ @media layerz(foo) { -/* imports/basic.css */ - .foo { background: url("images/green.png"); } @@ -48,12 +44,10 @@ .search { background: url("images/green.png?foo=bar"); } -} +}/* imports/basic.css */ @media zsupports(foo) { -/* imports/basic.css */ - .foo { background: url("images/green.png"); } @@ -73,12 +67,10 @@ .search { background: url("images/green.png?foo=bar"); } -} +}/* imports/basic.css */ @media supportsz(foo) { -/* imports/basic.css */ - .foo { background: url("images/green.png"); } diff --git a/plugin-packs/postcss-preset-env/test/postcss-import/styles.expect.css b/plugin-packs/postcss-preset-env/test/postcss-import/styles.expect.css index 7fe7334a1..50c7b1ad2 100644 --- a/plugin-packs/postcss-preset-env/test/postcss-import/styles.expect.css +++ b/plugin-packs/postcss-preset-env/test/postcss-import/styles.expect.css @@ -1,15 +1,12 @@ - -/* ./imports/extensions.css */ -/* ./imports/components.css */ /* ./imports/extensions.css */ :root { --color-red: red; --color-blue: blue; } +/* ./imports/components.css */ button:not(.does-not-exist):not(#\#), input[type="submit"]:not(#\#) { text-align: left; } -/* ./imports/components.css */ button:not(.does-not-exist):not(#\#):not(#\#), input[type="submit"]:not(#\#):not(#\#) { color: red; color: var(--color-red); diff --git a/plugins-stylelint/no-invalid-at-import-rules-when-bundling/CHANGELOG.md b/plugins-stylelint/no-invalid-at-import-rules-when-bundling/CHANGELOG.md index a852a02fd..a6484c779 100644 --- a/plugins-stylelint/no-invalid-at-import-rules-when-bundling/CHANGELOG.md +++ b/plugins-stylelint/no-invalid-at-import-rules-when-bundling/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +### Unreleased (minor) + +- Add validation for `@import` statement order relative to other statements + ### 1.0.0 _September 5, 2023_ diff --git a/plugins-stylelint/no-invalid-at-import-rules-when-bundling/index.js b/plugins-stylelint/no-invalid-at-import-rules-when-bundling/index.js index 66ff6f9e3..5ebca4015 100644 --- a/plugins-stylelint/no-invalid-at-import-rules-when-bundling/index.js +++ b/plugins-stylelint/no-invalid-at-import-rules-when-bundling/index.js @@ -16,7 +16,53 @@ const ruleFunction = (primaryOption) => { let localImportCounter = 0; + let didSeeImports = false; + let didSeeOtherNodes = false; + for (let i = 0; i < postcssRoot.nodes.length; i++) { + const node = postcssRoot.nodes[i]; + if (i === 0 && node.type === 'atrule' && /^charset$/i.test(node.name)) { + continue; + } + + if (node.type === 'comment') { + continue; + } + + if (!didSeeImports && isLayerNode(node)) { + continue; + } + + if (!didSeeOtherNodes && isImportNode(node)) { + didSeeImports = true; + continue; + } + + didSeeOtherNodes = true; + + if (isImportNode(node)) { + stylelint.utils.report({ + message: '`@import` statements must be precede all other nodes except for `@charset` or `@layer` and all `@import` statements must be consecutive.', + node: node, + index: 0, + endIndex: node.toString().length - 1, + result: postcssResult, + ruleName, + }); + } + } + postcssRoot.walkAtRules(/^import$/i, (atRule) => { + if ('nodes' in atRule) { + stylelint.utils.report({ + message: '`@import` statements must not have any child nodes.', + node: atRule, + index: 0, + endIndex: atRule.toString().length - 1, + result: postcssResult, + ruleName, + }); + } + const parsed = parseAtImport(atRule.params); if (!parsed) { // Invalid `@import` statement, best left to a Stylelint core rule @@ -57,7 +103,7 @@ const ruleFunction = (primaryOption) => { if (remote) { if (localImportCounter > 0) { stylelint.utils.report({ - message: 'Imports for remote resources after a local import will not be bundled correctly. Move these to the top of the file.', + message: '`@import` statements for remote resources after a local import will not be bundled correctly. Move these to the top of the file.', node: atRule, index: atRuleParamIndex(atRule) + uriSourceIndices[0], endIndex: atRuleParamIndex(atRule) + uriSourceIndices[1] + 1, @@ -97,6 +143,14 @@ const ruleFunction = (primaryOption) => { }; }; +function isLayerNode(node) { + return node.type === 'atrule' && /^layer$/i.test(node.name) && !('nodes' in node); +} + +function isImportNode(node) { + return node.type === 'atrule' && /^import$/i.test(node.name); +} + function atRuleParamIndex(atRule) { // Initial 1 is for the `@` let index = 1 + atRule.name.length; diff --git a/plugins-stylelint/no-invalid-at-import-rules-when-bundling/index.test.js b/plugins-stylelint/no-invalid-at-import-rules-when-bundling/index.test.js index ab0032d37..5cb702cad 100644 --- a/plugins-stylelint/no-invalid-at-import-rules-when-bundling/index.test.js +++ b/plugins-stylelint/no-invalid-at-import-rules-when-bundling/index.test.js @@ -28,6 +28,9 @@ testRule({ { code: '@import "foo.css"; @import "node_modules:bar.css";', }, + { + code: '@layer foo; @import "foo.css";', + }, ], reject: [ @@ -64,7 +67,7 @@ testRule({ @import "https://example.com/bar.css"; `, description: 'Remote resources after a local import will not be bundled correctly', - message: 'Imports for remote resources after a local import will not be bundled correctly. Move these to the top of the file.', + message: '`@import` statements for remote resources after a local import will not be bundled correctly. Move these to the top of the file.', line: 3, column: 13, endLine: 3, @@ -76,7 +79,7 @@ testRule({ @import "//example.com/bar.css"; `, description: 'Remote resources after a local import will not be bundled correctly', - message: 'Imports for remote resources after a local import will not be bundled correctly. Move these to the top of the file.', + message: '`@import` statements for remote resources after a local import will not be bundled correctly. Move these to the top of the file.', line: 3, column: 13, endLine: 3, @@ -91,6 +94,42 @@ testRule({ endLine: 1, endColumn: 18, }, + { + code: '@import "foo.css" { color: green; }', + description: 'Child nodes are not allowed', + message: '`@import` statements must not have any child nodes.', + line: 1, + column: 1, + endLine: 1, + endColumn: 35, + }, + { + code: '@import "foo.css" {}', + description: 'Child nodes are not allowed', + message: '`@import` statements must not have any child nodes.', + line: 1, + column: 1, + endLine: 1, + endColumn: 20, + }, + { + code: '@layer foo {} @import "foo.css";', + description: 'Order', + message: '`@import` statements must be precede all other nodes except for `@charset` or `@layer` and all `@import` statements must be consecutive.', + line: 1, + column: 15, + endLine: 1, + endColumn: 31, + }, + { + code: '@import "foo.css"; .bar {} @import "bar.css";', + description: 'Order', + message: '`@import` statements must be precede all other nodes except for `@charset` or `@layer` and all `@import` statements must be consecutive.', + line: 1, + column: 28, + endLine: 1, + endColumn: 44, + }, ], }); diff --git a/plugins-stylelint/no-invalid-at-import-rules-when-bundling/parse-at-import.js b/plugins-stylelint/no-invalid-at-import-rules-when-bundling/parse-at-import.js index 2caf8c413..72225d989 100644 --- a/plugins-stylelint/no-invalid-at-import-rules-when-bundling/parse-at-import.js +++ b/plugins-stylelint/no-invalid-at-import-rules-when-bundling/parse-at-import.js @@ -1,7 +1,7 @@ const parserAlgorithms = require('@csstools/css-parser-algorithms'); const tokenizer = require('@csstools/css-tokenizer'); -const { isCommentNode, isFunctionNode, isTokenNode, isWhitespaceNode, parseCommaSeparatedListOfComponentValues, parseListOfComponentValues, stringify, sourceIndices } = parserAlgorithms; +const { isCommentNode, isFunctionNode, isTokenNode, isWhitespaceNode, parseListOfComponentValues, stringify, sourceIndices } = parserAlgorithms; const { TokenType, tokenize } = tokenizer; const IS_LAYER = /^layer$/i; @@ -16,14 +16,13 @@ module.exports = function parseAtImport(params) { let uri = ''; let uriSourceIndices; let fullUri = ''; - const layer = []; + let layer; let layerSourceIndices = []; - const media = []; + let media; let mediaSourceIndices = []; - const supports = []; + let supports; let supportsSourceIndices = []; - PARSING_LOOP: for (let i = 0; i < componentValues.length; i++) { const componentValue = componentValues[i]; if (isWhitespaceNode(componentValue) || isCommentNode(componentValue)) { @@ -62,17 +61,24 @@ module.exports = function parseAtImport(params) { } if ( + !uri && isTokenNode(childComponentValue) && childComponentValue.value[0] === TokenType.String ) { uri = childComponentValue.value[4].value; fullUri = stringify([[componentValue]]); uriSourceIndices = sourceIndices(componentValue); - continue PARSING_LOOP; + continue; } return false; } + + continue; + } + + if (!uri) { + return false; } if ( @@ -80,11 +86,11 @@ module.exports = function parseAtImport(params) { componentValue.value[0] === TokenType.Ident && IS_LAYER.test(componentValue.value[4].value) ) { - if (layer.length > 0 || supports.length > 0) { + if (typeof layer !== 'undefined' || typeof supports !== 'undefined') { return false; } - layer.push(''); + layer = ''; layerSourceIndices = sourceIndices(componentValue); continue; } @@ -93,11 +99,11 @@ module.exports = function parseAtImport(params) { isFunctionNode(componentValue) && IS_LAYER.test(componentValue.getName()) ) { - if (layer.length > 0 || supports.length > 0) { + if (typeof layer !== 'undefined' || typeof supports !== 'undefined') { return false; } - layer.push(stringify([trim(componentValue.value)])); + layer = stringify([componentValue.value]); layerSourceIndices = sourceIndices(componentValue); continue; } @@ -106,21 +112,16 @@ module.exports = function parseAtImport(params) { isFunctionNode(componentValue) && IS_SUPPORTS.test(componentValue.getName()) ) { - if (supports.length > 0) { + if (typeof supports !== 'undefined') { return false; } - supports.push(stringify([trim(componentValue.value)])); + supports = stringify([componentValue.value]); supportsSourceIndices = sourceIndices(componentValue); continue; } - const remainder = trim(componentValues.slice(i)); - const remainderTokens = remainder.flatMap(x => x.tokens()); - const list = parseCommaSeparatedListOfComponentValues(remainderTokens); - const serializedList = list.map((x) => stringify([trim(x)])); - media.push(...serializedList); - mediaSourceIndices = sourceIndices(remainder); + media = stringify([componentValues.slice(i)]); break; } @@ -143,33 +144,6 @@ module.exports = function parseAtImport(params) { }; }; -function trim(componentValues) { - let start = 0; - let end = componentValues.length; - - for (let i = 0; i < componentValues.length; i++) { - const componentValue = componentValues[i]; - if (isWhitespaceNode(componentValue) || isCommentNode(componentValue)) { - continue; - } - - start = i; - break; - } - - for (let i = componentValues.length - 1; i >= 0; i--) { - const componentValue = componentValues[i]; - if (isWhitespaceNode(componentValue) || isCommentNode(componentValue)) { - continue; - } - - end = i + 1; - break; - } - - return componentValues.slice(start, end); -} - function stripHash(str) { if (str.startsWith('#')) { return str; diff --git a/plugins/postcss-cascade-layers/test/warnings.with-postcss-import.expect.css b/plugins/postcss-cascade-layers/test/warnings.with-postcss-import.expect.css index 2de29015e..2a0876389 100644 --- a/plugins/postcss-cascade-layers/test/warnings.with-postcss-import.expect.css +++ b/plugins/postcss-cascade-layers/test/warnings.with-postcss-import.expect.css @@ -1,10 +1,4 @@ - - -/* imports/theme.css */ - -/* imports/theme-overrides.css *//* [postcss-cascade-layers]: To use the @import at-rule with layer, the postcss-import plugin is also required. This plugin alone will not support importing layers. */ - -/* imports/theme.css */ +/* [postcss-cascade-layers]: To use the @import at-rule with layer, the postcss-import plugin is also required. This plugin alone will not support importing layers. *//* imports/theme.css */ .theme-styles { color:red; } @@ -12,9 +6,7 @@ .theme-styles { color: pink; } -} - -/* imports/theme-overrides.css */ +}/* imports/theme-overrides.css */ .theme-styles:not(#\#) { color:blue; } @@ -22,14 +14,10 @@ .theme-styles:not(#\#) { color: cyan; } -} - -/* [postcss-cascade-layers]: handling "revert-layer" is unsupported by this plugin and will cause style differences between browser versions. */ +}/* [postcss-cascade-layers]: handling "revert-layer" is unsupported by this plugin and will cause style differences between browser versions. */ .foo:not(#\#):not(#\#) { color: revert-layer; - } - -/* [postcss-cascade-layers]: handling different layer orders in conditional rules is unsupported by this plugin and will cause style differences between browser versions. */ + }/* [postcss-cascade-layers]: handling different layer orders in conditional rules is unsupported by this plugin and will cause style differences between browser versions. */ @media (min-width: 10px) { .foo:not(#\#):not(#\#):not(#\#) { color: red;