diff --git a/package-lock.json b/package-lock.json index 700228b2c..473a2a3ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12565,7 +12565,7 @@ ], "license": "MIT-0", "dependencies": { - "@csstools/selector-specificity": "^3.0.1", + "@csstools/selector-resolve-nested": "^1.0.0", "postcss-selector-parser": "^6.0.13" }, "devDependencies": { diff --git a/plugin-packs/postcss-preset-env/dist/index.cjs b/plugin-packs/postcss-preset-env/dist/index.cjs index 3324a9415..902284b05 100644 --- a/plugin-packs/postcss-preset-env/dist/index.cjs +++ b/plugin-packs/postcss-preset-env/dist/index.cjs @@ -1 +1 @@ -"use strict";var s=require("autoprefixer"),e=require("cssdb"),o=require("browserslist"),t=require("@csstools/postcss-initial"),i=require("postcss-pseudo-class-any-link"),r=require("css-blank-pseudo"),a=require("postcss-page-break"),c=require("@csstools/postcss-cascade-layers"),n=require("postcss-attribute-case-insensitive"),p=require("postcss-clamp"),l=require("@csstools/postcss-color-function"),u=require("postcss-color-functional-notation"),m=require("@csstools/postcss-color-mix-function"),d=require("postcss-custom-media"),g=require("postcss-custom-properties"),f=require("postcss-custom-selectors"),b=require("postcss-dir-pseudo-class"),h=require("@csstools/postcss-normalize-display-values"),v=require("postcss-double-position-gradients"),N=require("@csstools/postcss-exponential-functions"),y=require("@csstools/postcss-logical-float-and-clear"),k=require("postcss-focus-visible"),w=require("postcss-focus-within"),q=require("@csstools/postcss-font-format-keywords"),x=require("postcss-font-variant"),F=require("@csstools/postcss-gamut-mapping"),O=require("postcss-gap-properties"),$=require("@csstools/postcss-gradients-interpolation-method"),S=require("css-has-pseudo"),P=require("postcss-color-hex-alpha"),C=require("@csstools/postcss-hwb-function"),I=require("@csstools/postcss-ic-unit"),L=require("postcss-image-set-function"),E=require("@csstools/postcss-is-pseudo-class"),B=require("postcss-lab-function"),U=require("@csstools/postcss-logical-overflow"),A=require("@csstools/postcss-logical-overscroll-behavior"),_=require("postcss-logical"),j=require("@csstools/postcss-logical-resize"),M=require("@csstools/postcss-logical-viewport-units"),z=require("@csstools/postcss-media-queries-aspect-ratio-number-values"),D=require("@csstools/postcss-media-minmax"),R=require("@csstools/postcss-nested-calc"),V=require("postcss-nesting"),T=require("postcss-selector-not"),H=require("@csstools/postcss-oklab-function"),W=require("postcss-opacity-percentage"),G=require("postcss-overflow-shorthand"),K=require("postcss-replace-overflow-wrap"),Z=require("postcss-place"),Q=require("css-prefers-color-scheme"),J=require("@csstools/postcss-progressive-custom-properties"),X=require("postcss-color-rebeccapurple"),Y=require("@csstools/postcss-relative-color-syntax"),ss=require("@csstools/postcss-scope-pseudo-class"),es=require("@csstools/postcss-stepped-value-functions"),os=require("@csstools/postcss-text-decoration-shorthand"),ts=require("@csstools/postcss-trigonometric-functions"),is=require("@csstools/postcss-unset-value");const rs={"blank-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-blank-pseudo/README.md#browser","focus-visible-pseudo-class":"https://github.com/WICG/focus-visible","focus-within-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-focus-within/README.md#browser","has-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-has-pseudo/README.md#browser","prefers-color-scheme-query":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-prefers-color-scheme/README.md#browser"},as=["blank-pseudo-class","focus-visible-pseudo-class","focus-within-pseudo-class","has-pseudo-class","prefers-color-scheme-query"];function logFeaturesList(s,e,o){if(e.debug){o.log("Enabling the following feature(s):");const t=[],i=[];!1!==e.autoprefixer&&i.push(" autoprefixer"),s.forEach((s=>{s.id.startsWith("before")||s.id.startsWith("after")?i.push(` ${s.id} (injected via options)`):i.push(` ${s.id}`),void 0!==rs[s.id]&&t.push(s.id)})),i.sort(((s,e)=>s.localeCompare(e))),t.sort(((s,e)=>s.localeCompare(e))),i.forEach((s=>o.log(s))),t.length&&(o.log("These feature(s) need a browser library to work:"),t.forEach((s=>o.log(` ${s}: ${rs[s]}`))))}}function initializeSharedOptions(s){if("preserve"in s){const e={};return e.preserve=s.preserve,e}return!1}function clamp(s,e,o){return Math.max(s,Math.min(e,o))}const cs=2,ns=5;function stageFromOptions(s,e){let o=cs;if(void 0===s.stage)return e.log(`Using features from Stage ${o} (default)`),o;if(!1===s.stage)o=ns;else{let e=parseInt(s.stage,10);Number.isNaN(e)&&(e=0),o=clamp(0,e,ns)}return o===ns?e.log('Stage has been disabled, features will be handled via the "features" option.'):e.log(`Using features from Stage ${o}`),o}const ps=Symbol("insertBefore"),ls=Symbol("insertAfter"),us=Symbol("insertOrder"),ms=Symbol("plugin");function getTransformedInsertions(s,e,o){if("insertBefore"!==o&&"insertAfter"!==o)return[];const t="insertBefore"===o?ps:ls,i=[];for(const o in e){if(!Object.hasOwnProperty.call(e,o))continue;if(!s.find((s=>s.id===o)))continue;let r=e[o];Array.isArray(r)||(r=[r]);for(let s=0;sfeatureIsInsertedOrHasAPlugin(s))).sort(((s,e)=>featureIsLess(s,e)))}const ks=["and_chr","and_ff","android","chrome","edge","firefox","ie","ios_saf","op_mini","op_mob","opera","safari","samsung"];function getUnsupportedBrowsersByFeature(s){if(!s)return[];if(!("browser_support"in s))return["> 0%"];const e=[];return ks.forEach((o=>{if("op_mini"===o&&void 0===s.browser_support[o])return void e.push("op_mini all");const t=s.browser_support[o];"string"==typeof t&&ws.test(t)?e.push(`${o} < ${s.browser_support[o]}`):e.push(`${o} >= 1`)})),e}const ws=/^[0-9|.]+$/;function getOptionsForBrowsersByFeature(s,e,o,t,i){switch(e.id){case"is-pseudo-class":return{onComplexSelector:"warning"};case"nesting-rules":if(needsOptionFor(o.find((s=>"is-pseudo-class"===s.id)),s))return i.log('Disabling :is on "nesting-rules" due to lack of browser support.'),{noIsPseudoSelector:!0};return{};case"any-link-pseudo-class":if(s.find((s=>s.startsWith("ie ")||s.startsWith("edge "))))return i.log('Adding area[href] fallbacks for ":any-link" support in Edge and IE.'),{subFeatures:{areaHrefNeedsFixing:!0}};return{};case"logical-properties-and-values":case"float-clear-logical-values":case"logical-resize":case"logical-viewport-units":case"logical-overflow":case"logical-overscroll-behavior":return"logical"in t?t.logical:{};default:return{}}}function needsOptionFor(s,e){const t=getUnsupportedBrowsersByFeature(s),i=o(t,{ignoreUnknownVersions:!0});return!!e.some((s=>i.some((e=>e===s))))}function formatPolyfillableFeature(s){const e=getUnsupportedBrowsersByFeature(s);if(s[ps]||s[ls]){let o=s.id;return o=s.insertBefore?`before-${o}`:`after-${o}`,{browsers:e,vendors_implementations:s.vendors_implementations,plugin:s[ms],id:o,stage:ns+1}}return{browsers:e,vendors_implementations:s.vendors_implementations,plugin:ys.get(s.id),id:s.id,stage:s.stage}}function formatStagedFeature(s,e,o,t,i,r,a){let c,n;return c=getOptionsForBrowsersByFeature(e,t,s,r,a),!0===o[t.id]?i&&(c=Object.assign({},c,i)):c=i?Object.assign({},c,i,o[t.id]):Object.assign({},c,o[t.id]),"progressive-custom-properties"!==t.id&&(c.enableProgressiveCustomProperties=!1),"overflow-wrap-property"===t.id&&"preserve"in c&&(c.method=c.preserve?"copy":"replace"),n=t.plugin.postcss&&"function"==typeof t.plugin?t.plugin(c):t.plugin&&t.plugin.default&&"function"==typeof t.plugin.default&&t.plugin.default.postcss?t.plugin.default(c):t.plugin,{browsers:t.browsers,vendors_implementations:t.vendors_implementations,plugin:n,pluginOptions:c,id:t.id}}function intOrZero(s){const e=parseInt(s,10);return Number.isNaN(e)?0:e}const qs=new Set(["progressive-custom-properties"]);function listFeatures(s,e,t,i){const r=Object(e.features),a="enableClientSidePolyfills"in e&&e.enableClientSidePolyfills,c=Object(e.insertBefore),n=Object(e.insertAfter),p=e.browsers?void 0:e.env,l=e.browsers,u=clamp(0,intOrZero(e.minimumVendorImplementations),3);u>0&&i.log(`Using features with ${u} or more vendor implementations`);const m=stageFromOptions(e,i),d=prepareFeaturesList([...s,{id:"progressive-custom-properties"}],c,n).map((s=>formatPolyfillableFeature(s))).filter((s=>!!qs.has(s.id)||(0===u||(!(!s[ps]&&!s[ls])||(u<=s.vendors_implementations||(r[s.id]?(i.log(` ${s.id} does not meet the required vendor implementations but has been enabled by options`),!0):(i.log(` ${s.id} with ${s.vendors_implementations} vendor implementations has been disabled`),!1))))))),g=o(l,{env:p,ignoreUnknownVersions:!0}).filter((s=>ks.includes(s.split(" ")[0])));return d.filter((s=>{if(qs.has(s.id))return!0;const e=s.stage>=m,o=a||!as.includes(s.id),t=!1===r[s.id],c=r[s.id]?r[s.id]:e&&o;return t?i.log(` ${s.id} has been disabled by options`):e?o||i.log(` ${s.id} has been disabled by "enableClientSidePolyfills: false".`):c?i.log(` ${s.id} does not meet the required stage but has been enabled by options`):i.log(` ${s.id} with stage ${s.stage} has been disabled`),c})).map((o=>formatStagedFeature(s,g,r,o,t,e,i))).filter((s=>{if(qs.has(s.id))return!0;if(s.id in r)return r[s.id];const e=o(s.browsers,{ignoreUnknownVersions:!0}),t=g.some((s=>e.some((e=>e===s))));return t||i.log(`${s.id} disabled due to browser support`),t}))}class Logger{constructor(){this.logs=[]}log(s){this.logs.push(s)}resetLogger(){this.logs.length=0}dumpLogs(s){s&&s.warn(this.logs.join("\n")),this.resetLogger()}}var xs=[{packageName:"css-blank-pseudo",id:"blank-pseudo-class",importName:"postcssBlankPseudo"},{packageName:"css-has-pseudo",id:"has-pseudo-class",importName:"postcssHasPseudo"},{packageName:"css-prefers-color-scheme",id:"prefers-color-scheme-query",importName:"postcssPrefersColorScheme"},{packageName:"postcss-attribute-case-insensitive",id:"case-insensitive-attributes",importName:"postcssAttributeCaseInsensitive"},{packageName:"postcss-clamp",id:"clamp",importName:"postcssClamp"},{packageName:"@csstools/postcss-color-mix-function",id:"color-mix",importName:"postcssColorMixFunction"},{packageName:"@csstools/postcss-color-function",id:"color-function",importName:"postcssColorFunction"},{packageName:"postcss-color-functional-notation",id:"color-functional-notation",importName:"postcssColorFunctionalNotation"},{packageName:"postcss-color-hex-alpha",id:"hexadecimal-alpha-notation",importName:"postcssColorHexAlpha"},{packageName:"postcss-color-rebeccapurple",id:"rebeccapurple-color",importName:"postcssColorRebeccapurple"},{packageName:"postcss-custom-media",id:"custom-media-queries",importName:"postcssCustomMedia"},{packageName:"postcss-custom-properties",id:"custom-properties",importName:"postcssCustomProperties"},{packageName:"postcss-custom-selectors",id:"custom-selectors",importName:"postcssCustomSelectors"},{packageName:"postcss-dir-pseudo-class",id:"dir-pseudo-class",importName:"postcssDirPseudoClass"},{packageName:"postcss-double-position-gradients",id:"double-position-gradients",importName:"postcssDoublePositionGradients"},{packageName:"@csstools/postcss-exponential-functions",id:"exponential-functions",importName:"postcssExponentialFunctions"},{packageName:"postcss-focus-visible",id:"focus-visible-pseudo-class",importName:"postcssFocusVisible"},{packageName:"postcss-focus-within",id:"focus-within-pseudo-class",importName:"postcssFocusWithin"},{packageName:"@csstools/postcss-font-format-keywords",id:"font-format-keywords",importName:"postcssFontFormatKeywords"},{packageName:"postcss-font-variant",id:"font-variant-property",importName:"postcssFontVariant"},{packageName:"@csstools/postcss-gamut-mapping",id:"gamut-mapping",importName:"postcssGamutMapping"},{packageName:"postcss-gap-properties",id:"gap-properties",importName:"postcssGapProperties"},{packageName:"@csstools/postcss-gradients-interpolation-method",id:"gradients-interpolation-method",importName:"postcssGradientsInterpolationMethod"},{packageName:"@csstools/postcss-hwb-function",id:"hwb-function",importName:"postcssHWBFunction"},{packageName:"@csstools/postcss-ic-unit",id:"ic-unit",importName:"postcssICUnit"},{packageName:"postcss-image-set-function",id:"image-set-function",importName:"postcssImageSetFunction"},{packageName:"@csstools/postcss-initial",id:"all-property",importName:"postcssInitial"},{packageName:"@csstools/postcss-is-pseudo-class",id:"is-pseudo-class",importName:"postcssIsPseudoClass"},{packageName:"@csstools/postcss-scope-pseudo-class",id:"scope-pseudo-class",importName:"postcssScopePseudoClass"},{packageName:"postcss-lab-function",id:"lab-function",importName:"postcssLabFunction"},{packageName:"postcss-logical",id:"logical-properties-and-values",importName:"postcssLogical"},{packageName:"@csstools/postcss-logical-float-and-clear",id:"float-clear-logical-values",importName:"postcssLogicalFloatAndClear"},{packageName:"@csstools/postcss-logical-overflow",id:"logical-overflow",importName:"postcssLogicalOverflow"},{packageName:"@csstools/postcss-logical-overscroll-behavior",id:"logical-overscroll-behavior",importName:"postcssLogicalOverscrollBehavor"},{packageName:"@csstools/postcss-logical-resize",id:"logical-resize",importName:"postcssLogicalResize"},{packageName:"@csstools/postcss-logical-viewport-units",id:"logical-viewport-units",importName:"postcssLogicalViewportUnits"},{packageName:"@csstools/postcss-media-minmax",id:"media-query-ranges",importName:"postcssMediaMinmax"},{packageName:"@csstools/postcss-media-queries-aspect-ratio-number-values",id:"media-queries-aspect-ratio-number-values",importName:"postcssMediaQueriesAspectRatioNumberValues"},{packageName:"postcss-nesting",id:"nesting-rules",importName:"postcssNesting"},{packageName:"@csstools/postcss-normalize-display-values",id:"display-two-values",importName:"postcssNormalizeDisplayValues"},{packageName:"@csstools/postcss-oklab-function",id:"oklab-function",importName:"postcssOKLabFunction"},{packageName:"@csstools/postcss-relative-color-syntax",id:"relative-color-syntax",importName:"postcssRelativeColorSyntax"},{packageName:"postcss-opacity-percentage",id:"opacity-percentage",importName:"postcssOpacityPercentage"},{packageName:"postcss-overflow-shorthand",id:"overflow-property",importName:"postcssOverflowShorthand"},{packageName:"postcss-page-break",id:"break-properties",importName:"postcssPageBreak"},{packageName:"postcss-place",id:"place-properties",importName:"postcssPlace"},{packageName:"postcss-pseudo-class-any-link",id:"any-link-pseudo-class",importName:"postcssPseudoClassAnyLink"},{packageName:"postcss-replace-overflow-wrap",id:"overflow-wrap-property",importName:"postcssReplaceOverflowWrap"},{packageName:"postcss-selector-not",id:"not-pseudo-class",importName:"postcssSelectorNot"},{packageName:"@csstools/postcss-stepped-value-functions",id:"stepped-value-functions",importName:"postcssSteppedValueFunctions"},{packageName:"postcss-system-ui-font-family",importedPackage:"../patch/postcss-system-ui-font-family.mjs",id:"system-ui-font-family",importName:"postcssFontFamilySystemUI"},{packageName:"@csstools/postcss-unset-value",id:"unset-value",importName:"postcssUnsetValue"},{packageName:"@csstools/postcss-cascade-layers",id:"cascade-layers",importName:"postcssCascadeLayers"},{packageName:"@csstools/postcss-trigonometric-functions",id:"trigonometric-functions",importName:"postcssTrigonometricFunctions"},{packageName:"@csstools/postcss-nested-calc",id:"nested-calc",importName:"postcssNestedCalc"},{packageName:"@csstools/postcss-text-decoration-shorthand",id:"text-decoration-shorthand",importName:"postcssTextDecorationShorthand"},{packageName:"@csstools/postcss-progressive-custom-properties",id:"progressive-custom-properties",importName:"postcssProgressiveCustomProperties",omitTypedOptions:!0,omitDocs:!0}];function getPackageNamesToIds(){const s={};return xs.forEach((e=>{s[e.packageName]=e.id})),s}function pluginIdHelp(s,e,o){const t=xs.map((s=>s.id)),i=xs.map((s=>s.packageName)),r=getPackageNamesToIds();s.forEach((s=>{if(t.includes(s))return;const a=[...t.map((e=>[e,levenshteinDistance(s,e)])),...i.map((e=>[r[e],levenshteinDistance(s,e)]))].sort(((s,e)=>s[1]-e[1])).filter((s=>s[1]<10)),c=new Set;for(let s=0;s=3));s++);if(!c.size)return void e.warn(o,`Unknown feature: "${s}", see the list of features https://github.com/csstools/postcss-plugins/blob/main/plugin-packs/postcss-preset-env/FEATURES.md`);let n='"';n+=Array.from(c).join('", "'),n+='"',e.warn(o,`Unknown feature: "${s}", did you mean one of: ${n}`)}))}function levenshteinDistance(s,e){if(!s.length)return e.length;if(!e.length)return s.length;const o=[];for(let t=0;t<=e.length;t++){o[t]=[t];for(let i=1;i<=s.length;i++)o[t][i]=0===t?i:Math.min(o[t-1][i]+1,o[t][i-1]+1,o[t-1][i-1]+(s[i-1]===e[t-1]?0:1))}return o[e.length][s.length]}const creator=o=>{const t=new Logger,i=Object(o),r=Object.keys(Object(i.features)),a=i.browsers?void 0:i.env,c=i.browsers,n=initializeSharedOptions(i),p=listFeatures(e,i,n,t),l=p.map((s=>s.plugin));!1!==i.autoprefixer&&l.push(s(Object.assign({env:a,overrideBrowserslist:c},i.autoprefixer))),logFeaturesList(p,i,t);const internalPlugin=()=>({postcssPlugin:"postcss-preset-env",OnceExit:function(s,{result:e}){pluginIdHelp(r,s,e),i.debug&&t.dumpLogs(e),t.resetLogger()}});return internalPlugin.postcss=!0,{postcssPlugin:"postcss-preset-env",plugins:[...l,internalPlugin()]}};creator.postcss=!0,module.exports=creator; +"use strict";var s=require("autoprefixer"),e=require("cssdb"),o=require("browserslist"),t=require("@csstools/postcss-initial"),i=require("postcss-pseudo-class-any-link"),r=require("css-blank-pseudo"),a=require("postcss-page-break"),c=require("@csstools/postcss-cascade-layers"),p=require("postcss-attribute-case-insensitive"),n=require("postcss-clamp"),l=require("@csstools/postcss-color-function"),u=require("postcss-color-functional-notation"),m=require("@csstools/postcss-color-mix-function"),d=require("postcss-custom-media"),g=require("postcss-custom-properties"),f=require("postcss-custom-selectors"),b=require("postcss-dir-pseudo-class"),h=require("@csstools/postcss-normalize-display-values"),v=require("postcss-double-position-gradients"),N=require("@csstools/postcss-exponential-functions"),y=require("@csstools/postcss-logical-float-and-clear"),k=require("postcss-focus-visible"),w=require("postcss-focus-within"),q=require("@csstools/postcss-font-format-keywords"),x=require("postcss-font-variant"),F=require("@csstools/postcss-gamut-mapping"),$=require("postcss-gap-properties"),O=require("@csstools/postcss-gradients-interpolation-method"),S=require("css-has-pseudo"),P=require("postcss-color-hex-alpha"),C=require("@csstools/postcss-hwb-function"),I=require("@csstools/postcss-ic-unit"),L=require("postcss-image-set-function"),E=require("@csstools/postcss-is-pseudo-class"),A=require("postcss-lab-function"),B=require("@csstools/postcss-logical-overflow"),U=require("@csstools/postcss-logical-overscroll-behavior"),_=require("postcss-logical"),j=require("@csstools/postcss-logical-resize"),M=require("@csstools/postcss-logical-viewport-units"),z=require("@csstools/postcss-media-queries-aspect-ratio-number-values"),D=require("@csstools/postcss-media-minmax"),R=require("@csstools/postcss-nested-calc"),T=require("postcss-nesting"),V=require("postcss-selector-not"),H=require("@csstools/postcss-oklab-function"),W=require("postcss-opacity-percentage"),G=require("postcss-overflow-shorthand"),K=require("postcss-replace-overflow-wrap"),Z=require("postcss-place"),Q=require("css-prefers-color-scheme"),J=require("@csstools/postcss-progressive-custom-properties"),X=require("postcss-color-rebeccapurple"),Y=require("@csstools/postcss-relative-color-syntax"),ss=require("@csstools/postcss-scope-pseudo-class"),es=require("@csstools/postcss-stepped-value-functions"),os=require("@csstools/postcss-text-decoration-shorthand"),ts=require("@csstools/postcss-trigonometric-functions"),is=require("@csstools/postcss-unset-value");const rs={"blank-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-blank-pseudo/README.md#browser","focus-visible-pseudo-class":"https://github.com/WICG/focus-visible","focus-within-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-focus-within/README.md#browser","has-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-has-pseudo/README.md#browser","prefers-color-scheme-query":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-prefers-color-scheme/README.md#browser"},as=["blank-pseudo-class","focus-visible-pseudo-class","focus-within-pseudo-class","has-pseudo-class","prefers-color-scheme-query"];function logFeaturesList(s,e,o){if(e.debug){o.log("Enabling the following feature(s):");const t=[],i=[];!1!==e.autoprefixer&&i.push(" autoprefixer"),s.forEach((s=>{s.id.startsWith("before")||s.id.startsWith("after")?i.push(` ${s.id} (injected via options)`):i.push(` ${s.id}`),void 0!==rs[s.id]&&t.push(s.id)})),i.sort(((s,e)=>s.localeCompare(e))),t.sort(((s,e)=>s.localeCompare(e))),i.forEach((s=>o.log(s))),t.length&&(o.log("These feature(s) need a browser library to work:"),t.forEach((s=>o.log(` ${s}: ${rs[s]}`))))}}function initializeSharedOptions(s){if("preserve"in s){const e={};return e.preserve=s.preserve,e}return!1}function clamp(s,e,o){return Math.max(s,Math.min(e,o))}const cs=2,ps=5;function stageFromOptions(s,e){let o=cs;if(void 0===s.stage)return e.log(`Using features from Stage ${o} (default)`),o;if(!1===s.stage)o=ps;else{let e=parseInt(s.stage,10);Number.isNaN(e)&&(e=0),o=clamp(0,e,ps)}return o===ps?e.log('Stage has been disabled, features will be handled via the "features" option.'):e.log(`Using features from Stage ${o}`),o}const ns=Symbol("insertBefore"),ls=Symbol("insertAfter"),us=Symbol("insertOrder"),ms=Symbol("plugin");function getTransformedInsertions(s,e,o){if("insertBefore"!==o&&"insertAfter"!==o)return[];const t="insertBefore"===o?ns:ls,i=[];for(const o in e){if(!Object.hasOwnProperty.call(e,o))continue;if(!s.find((s=>s.id===o)))continue;let r=e[o];Array.isArray(r)||(r=[r]);for(let s=0;sfeatureIsInsertedOrHasAPlugin(s))).sort(((s,e)=>featureIsLess(s,e)))}function getOptionsForBrowsersByFeature(s,e,o,t,i){switch(e.id){case"is-pseudo-class":return{onComplexSelector:"warning"};case"any-link-pseudo-class":if(s.find((s=>s.startsWith("ie ")||s.startsWith("edge "))))return i.log('Adding area[href] fallbacks for ":any-link" support in Edge and IE.'),{subFeatures:{areaHrefNeedsFixing:!0}};return{};case"logical-properties-and-values":case"float-clear-logical-values":case"logical-resize":case"logical-viewport-units":case"logical-overflow":case"logical-overscroll-behavior":return"logical"in t?t.logical:{};default:return{}}}const ks=["and_chr","and_ff","android","chrome","edge","firefox","ie","ios_saf","op_mini","op_mob","opera","safari","samsung"];function getUnsupportedBrowsersByFeature(s){if(!s)return[];if(!("browser_support"in s))return["> 0%"];const e=[];return ks.forEach((o=>{if("op_mini"===o&&void 0===s.browser_support[o])return void e.push("op_mini all");const t=s.browser_support[o];"string"==typeof t&&ws.test(t)?e.push(`${o} < ${s.browser_support[o]}`):e.push(`${o} >= 1`)})),e}const ws=/^[0-9|.]+$/;function formatPolyfillableFeature(s){const e=getUnsupportedBrowsersByFeature(s);if(s[ns]||s[ls]){let o=s.id;return o=s.insertBefore?`before-${o}`:`after-${o}`,{browsers:e,vendors_implementations:s.vendors_implementations,plugin:s[ms],id:o,stage:ps+1}}return{browsers:e,vendors_implementations:s.vendors_implementations,plugin:ys.get(s.id),id:s.id,stage:s.stage}}function formatStagedFeature(s,e,o,t,i,r,a){let c,p;return c=getOptionsForBrowsersByFeature(e,t,0,r,a),!0===o[t.id]?i&&(c=Object.assign({},c,i)):c=i?Object.assign({},c,i,o[t.id]):Object.assign({},c,o[t.id]),"progressive-custom-properties"!==t.id&&(c.enableProgressiveCustomProperties=!1),"overflow-wrap-property"===t.id&&"preserve"in c&&(c.method=c.preserve?"copy":"replace"),p=t.plugin.postcss&&"function"==typeof t.plugin?t.plugin(c):t.plugin&&t.plugin.default&&"function"==typeof t.plugin.default&&t.plugin.default.postcss?t.plugin.default(c):t.plugin,{browsers:t.browsers,vendors_implementations:t.vendors_implementations,plugin:p,pluginOptions:c,id:t.id}}function intOrZero(s){const e=parseInt(s,10);return Number.isNaN(e)?0:e}const qs=new Set(["progressive-custom-properties"]);function listFeatures(s,e,t,i){const r=Object(e.features),a="enableClientSidePolyfills"in e&&e.enableClientSidePolyfills,c=Object(e.insertBefore),p=Object(e.insertAfter),n=e.browsers?void 0:e.env,l=e.browsers,u=clamp(0,intOrZero(e.minimumVendorImplementations),3);u>0&&i.log(`Using features with ${u} or more vendor implementations`);const m=stageFromOptions(e,i),d=prepareFeaturesList([...s,{id:"progressive-custom-properties"}],c,p).map((s=>formatPolyfillableFeature(s))).filter((s=>!!qs.has(s.id)||(0===u||(!(!s[ns]&&!s[ls])||(u<=s.vendors_implementations||(r[s.id]?(i.log(` ${s.id} does not meet the required vendor implementations but has been enabled by options`),!0):(i.log(` ${s.id} with ${s.vendors_implementations} vendor implementations has been disabled`),!1))))))),g=o(l,{env:n,ignoreUnknownVersions:!0}).filter((s=>ks.includes(s.split(" ")[0])));return d.filter((s=>{if(qs.has(s.id))return!0;const e=s.stage>=m,o=a||!as.includes(s.id),t=!1===r[s.id],c=r[s.id]?r[s.id]:e&&o;return t?i.log(` ${s.id} has been disabled by options`):e?o||i.log(` ${s.id} has been disabled by "enableClientSidePolyfills: false".`):c?i.log(` ${s.id} does not meet the required stage but has been enabled by options`):i.log(` ${s.id} with stage ${s.stage} has been disabled`),c})).map((s=>formatStagedFeature(0,g,r,s,t,e,i))).filter((s=>{if(qs.has(s.id))return!0;if(s.id in r)return r[s.id];const e=o(s.browsers,{ignoreUnknownVersions:!0}),t=g.some((s=>e.some((e=>e===s))));return t||i.log(`${s.id} disabled due to browser support`),t}))}class Logger{constructor(){this.logs=[]}log(s){this.logs.push(s)}resetLogger(){this.logs.length=0}dumpLogs(s){s&&s.warn(this.logs.join("\n")),this.resetLogger()}}var xs=[{packageName:"css-blank-pseudo",id:"blank-pseudo-class",importName:"postcssBlankPseudo"},{packageName:"css-has-pseudo",id:"has-pseudo-class",importName:"postcssHasPseudo"},{packageName:"css-prefers-color-scheme",id:"prefers-color-scheme-query",importName:"postcssPrefersColorScheme"},{packageName:"postcss-attribute-case-insensitive",id:"case-insensitive-attributes",importName:"postcssAttributeCaseInsensitive"},{packageName:"postcss-clamp",id:"clamp",importName:"postcssClamp"},{packageName:"@csstools/postcss-color-mix-function",id:"color-mix",importName:"postcssColorMixFunction"},{packageName:"@csstools/postcss-color-function",id:"color-function",importName:"postcssColorFunction"},{packageName:"postcss-color-functional-notation",id:"color-functional-notation",importName:"postcssColorFunctionalNotation"},{packageName:"postcss-color-hex-alpha",id:"hexadecimal-alpha-notation",importName:"postcssColorHexAlpha"},{packageName:"postcss-color-rebeccapurple",id:"rebeccapurple-color",importName:"postcssColorRebeccapurple"},{packageName:"postcss-custom-media",id:"custom-media-queries",importName:"postcssCustomMedia"},{packageName:"postcss-custom-properties",id:"custom-properties",importName:"postcssCustomProperties"},{packageName:"postcss-custom-selectors",id:"custom-selectors",importName:"postcssCustomSelectors"},{packageName:"postcss-dir-pseudo-class",id:"dir-pseudo-class",importName:"postcssDirPseudoClass"},{packageName:"postcss-double-position-gradients",id:"double-position-gradients",importName:"postcssDoublePositionGradients"},{packageName:"@csstools/postcss-exponential-functions",id:"exponential-functions",importName:"postcssExponentialFunctions"},{packageName:"postcss-focus-visible",id:"focus-visible-pseudo-class",importName:"postcssFocusVisible"},{packageName:"postcss-focus-within",id:"focus-within-pseudo-class",importName:"postcssFocusWithin"},{packageName:"@csstools/postcss-font-format-keywords",id:"font-format-keywords",importName:"postcssFontFormatKeywords"},{packageName:"postcss-font-variant",id:"font-variant-property",importName:"postcssFontVariant"},{packageName:"@csstools/postcss-gamut-mapping",id:"gamut-mapping",importName:"postcssGamutMapping"},{packageName:"postcss-gap-properties",id:"gap-properties",importName:"postcssGapProperties"},{packageName:"@csstools/postcss-gradients-interpolation-method",id:"gradients-interpolation-method",importName:"postcssGradientsInterpolationMethod"},{packageName:"@csstools/postcss-hwb-function",id:"hwb-function",importName:"postcssHWBFunction"},{packageName:"@csstools/postcss-ic-unit",id:"ic-unit",importName:"postcssICUnit"},{packageName:"postcss-image-set-function",id:"image-set-function",importName:"postcssImageSetFunction"},{packageName:"@csstools/postcss-initial",id:"all-property",importName:"postcssInitial"},{packageName:"@csstools/postcss-is-pseudo-class",id:"is-pseudo-class",importName:"postcssIsPseudoClass"},{packageName:"@csstools/postcss-scope-pseudo-class",id:"scope-pseudo-class",importName:"postcssScopePseudoClass"},{packageName:"postcss-lab-function",id:"lab-function",importName:"postcssLabFunction"},{packageName:"postcss-logical",id:"logical-properties-and-values",importName:"postcssLogical"},{packageName:"@csstools/postcss-logical-float-and-clear",id:"float-clear-logical-values",importName:"postcssLogicalFloatAndClear"},{packageName:"@csstools/postcss-logical-overflow",id:"logical-overflow",importName:"postcssLogicalOverflow"},{packageName:"@csstools/postcss-logical-overscroll-behavior",id:"logical-overscroll-behavior",importName:"postcssLogicalOverscrollBehavor"},{packageName:"@csstools/postcss-logical-resize",id:"logical-resize",importName:"postcssLogicalResize"},{packageName:"@csstools/postcss-logical-viewport-units",id:"logical-viewport-units",importName:"postcssLogicalViewportUnits"},{packageName:"@csstools/postcss-media-minmax",id:"media-query-ranges",importName:"postcssMediaMinmax"},{packageName:"@csstools/postcss-media-queries-aspect-ratio-number-values",id:"media-queries-aspect-ratio-number-values",importName:"postcssMediaQueriesAspectRatioNumberValues"},{packageName:"postcss-nesting",id:"nesting-rules",importName:"postcssNesting"},{packageName:"@csstools/postcss-normalize-display-values",id:"display-two-values",importName:"postcssNormalizeDisplayValues"},{packageName:"@csstools/postcss-oklab-function",id:"oklab-function",importName:"postcssOKLabFunction"},{packageName:"@csstools/postcss-relative-color-syntax",id:"relative-color-syntax",importName:"postcssRelativeColorSyntax"},{packageName:"postcss-opacity-percentage",id:"opacity-percentage",importName:"postcssOpacityPercentage"},{packageName:"postcss-overflow-shorthand",id:"overflow-property",importName:"postcssOverflowShorthand"},{packageName:"postcss-page-break",id:"break-properties",importName:"postcssPageBreak"},{packageName:"postcss-place",id:"place-properties",importName:"postcssPlace"},{packageName:"postcss-pseudo-class-any-link",id:"any-link-pseudo-class",importName:"postcssPseudoClassAnyLink"},{packageName:"postcss-replace-overflow-wrap",id:"overflow-wrap-property",importName:"postcssReplaceOverflowWrap"},{packageName:"postcss-selector-not",id:"not-pseudo-class",importName:"postcssSelectorNot"},{packageName:"@csstools/postcss-stepped-value-functions",id:"stepped-value-functions",importName:"postcssSteppedValueFunctions"},{packageName:"postcss-system-ui-font-family",importedPackage:"../patch/postcss-system-ui-font-family.mjs",id:"system-ui-font-family",importName:"postcssFontFamilySystemUI"},{packageName:"@csstools/postcss-unset-value",id:"unset-value",importName:"postcssUnsetValue"},{packageName:"@csstools/postcss-cascade-layers",id:"cascade-layers",importName:"postcssCascadeLayers"},{packageName:"@csstools/postcss-trigonometric-functions",id:"trigonometric-functions",importName:"postcssTrigonometricFunctions"},{packageName:"@csstools/postcss-nested-calc",id:"nested-calc",importName:"postcssNestedCalc"},{packageName:"@csstools/postcss-text-decoration-shorthand",id:"text-decoration-shorthand",importName:"postcssTextDecorationShorthand"},{packageName:"@csstools/postcss-progressive-custom-properties",id:"progressive-custom-properties",importName:"postcssProgressiveCustomProperties",omitTypedOptions:!0,omitDocs:!0}];function getPackageNamesToIds(){const s={};return xs.forEach((e=>{s[e.packageName]=e.id})),s}function pluginIdHelp(s,e,o){const t=xs.map((s=>s.id)),i=xs.map((s=>s.packageName)),r=getPackageNamesToIds();s.forEach((s=>{if(t.includes(s))return;const a=[...t.map((e=>[e,levenshteinDistance(s,e)])),...i.map((e=>[r[e],levenshteinDistance(s,e)]))].sort(((s,e)=>s[1]-e[1])).filter((s=>s[1]<10)),c=new Set;for(let s=0;s=3));s++);if(!c.size)return void e.warn(o,`Unknown feature: "${s}", see the list of features https://github.com/csstools/postcss-plugins/blob/main/plugin-packs/postcss-preset-env/FEATURES.md`);let p='"';p+=Array.from(c).join('", "'),p+='"',e.warn(o,`Unknown feature: "${s}", did you mean one of: ${p}`)}))}function levenshteinDistance(s,e){if(!s.length)return e.length;if(!e.length)return s.length;const o=[];for(let t=0;t<=e.length;t++){o[t]=[t];for(let i=1;i<=s.length;i++)o[t][i]=0===t?i:Math.min(o[t-1][i]+1,o[t][i-1]+1,o[t-1][i-1]+(s[i-1]===e[t-1]?0:1))}return o[e.length][s.length]}const creator=o=>{const t=new Logger,i=Object(o),r=Object.keys(Object(i.features)),a=i.browsers?void 0:i.env,c=i.browsers,p=initializeSharedOptions(i),n=listFeatures(e,i,p,t),l=n.map((s=>s.plugin));!1!==i.autoprefixer&&l.push(s(Object.assign({env:a,overrideBrowserslist:c},i.autoprefixer))),logFeaturesList(n,i,t);const internalPlugin=()=>({postcssPlugin:"postcss-preset-env",OnceExit:function(s,{result:e}){pluginIdHelp(r,s,e),i.debug&&t.dumpLogs(e),t.resetLogger()}});return internalPlugin.postcss=!0,{postcssPlugin:"postcss-preset-env",plugins:[...l,internalPlugin()]}};creator.postcss=!0,module.exports=creator; diff --git a/plugin-packs/postcss-preset-env/dist/index.mjs b/plugin-packs/postcss-preset-env/dist/index.mjs index 802365520..42455aec8 100644 --- a/plugin-packs/postcss-preset-env/dist/index.mjs +++ b/plugin-packs/postcss-preset-env/dist/index.mjs @@ -1 +1 @@ -import s from"autoprefixer";import o from"cssdb";import e from"browserslist";import t from"@csstools/postcss-initial";import i from"postcss-pseudo-class-any-link";import r from"css-blank-pseudo";import a from"postcss-page-break";import p from"@csstools/postcss-cascade-layers";import c from"postcss-attribute-case-insensitive";import n from"postcss-clamp";import l from"@csstools/postcss-color-function";import m from"postcss-color-functional-notation";import u from"@csstools/postcss-color-mix-function";import d from"postcss-custom-media";import f from"postcss-custom-properties";import g from"postcss-custom-selectors";import b from"postcss-dir-pseudo-class";import h from"@csstools/postcss-normalize-display-values";import v from"postcss-double-position-gradients";import N from"@csstools/postcss-exponential-functions";import y from"@csstools/postcss-logical-float-and-clear";import k from"postcss-focus-visible";import w from"postcss-focus-within";import x from"@csstools/postcss-font-format-keywords";import F from"postcss-font-variant";import O from"@csstools/postcss-gamut-mapping";import $ from"postcss-gap-properties";import S from"@csstools/postcss-gradients-interpolation-method";import P from"css-has-pseudo";import C from"postcss-color-hex-alpha";import I from"@csstools/postcss-hwb-function";import L from"@csstools/postcss-ic-unit";import E from"postcss-image-set-function";import B from"@csstools/postcss-is-pseudo-class";import U from"postcss-lab-function";import A from"@csstools/postcss-logical-overflow";import _ from"@csstools/postcss-logical-overscroll-behavior";import q from"postcss-logical";import j from"@csstools/postcss-logical-resize";import M from"@csstools/postcss-logical-viewport-units";import z from"@csstools/postcss-media-queries-aspect-ratio-number-values";import D from"@csstools/postcss-media-minmax";import R from"@csstools/postcss-nested-calc";import V from"postcss-nesting";import T from"postcss-selector-not";import H from"@csstools/postcss-oklab-function";import W from"postcss-opacity-percentage";import G from"postcss-overflow-shorthand";import K from"postcss-replace-overflow-wrap";import Z from"postcss-place";import Q from"css-prefers-color-scheme";import J from"@csstools/postcss-progressive-custom-properties";import X from"postcss-color-rebeccapurple";import Y from"@csstools/postcss-relative-color-syntax";import ss from"@csstools/postcss-scope-pseudo-class";import os from"@csstools/postcss-stepped-value-functions";import es from"@csstools/postcss-text-decoration-shorthand";import ts from"@csstools/postcss-trigonometric-functions";import is from"@csstools/postcss-unset-value";const rs={"blank-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-blank-pseudo/README.md#browser","focus-visible-pseudo-class":"https://github.com/WICG/focus-visible","focus-within-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-focus-within/README.md#browser","has-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-has-pseudo/README.md#browser","prefers-color-scheme-query":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-prefers-color-scheme/README.md#browser"},as=["blank-pseudo-class","focus-visible-pseudo-class","focus-within-pseudo-class","has-pseudo-class","prefers-color-scheme-query"];function logFeaturesList(s,o,e){if(o.debug){e.log("Enabling the following feature(s):");const t=[],i=[];!1!==o.autoprefixer&&i.push(" autoprefixer"),s.forEach((s=>{s.id.startsWith("before")||s.id.startsWith("after")?i.push(` ${s.id} (injected via options)`):i.push(` ${s.id}`),void 0!==rs[s.id]&&t.push(s.id)})),i.sort(((s,o)=>s.localeCompare(o))),t.sort(((s,o)=>s.localeCompare(o))),i.forEach((s=>e.log(s))),t.length&&(e.log("These feature(s) need a browser library to work:"),t.forEach((s=>e.log(` ${s}: ${rs[s]}`))))}}function initializeSharedOptions(s){if("preserve"in s){const o={};return o.preserve=s.preserve,o}return!1}function clamp(s,o,e){return Math.max(s,Math.min(o,e))}const ps=2,cs=5;function stageFromOptions(s,o){let e=ps;if(void 0===s.stage)return o.log(`Using features from Stage ${e} (default)`),e;if(!1===s.stage)e=cs;else{let o=parseInt(s.stage,10);Number.isNaN(o)&&(o=0),e=clamp(0,o,cs)}return e===cs?o.log('Stage has been disabled, features will be handled via the "features" option.'):o.log(`Using features from Stage ${e}`),e}const ns=Symbol("insertBefore"),ls=Symbol("insertAfter"),ms=Symbol("insertOrder"),us=Symbol("plugin");function getTransformedInsertions(s,o,e){if("insertBefore"!==e&&"insertAfter"!==e)return[];const t="insertBefore"===e?ns:ls,i=[];for(const e in o){if(!Object.hasOwnProperty.call(o,e))continue;if(!s.find((s=>s.id===e)))continue;let r=o[e];Array.isArray(r)||(r=[r]);for(let s=0;sfeatureIsInsertedOrHasAPlugin(s))).sort(((s,o)=>featureIsLess(s,o)))}const ks=["and_chr","and_ff","android","chrome","edge","firefox","ie","ios_saf","op_mini","op_mob","opera","safari","samsung"];function getUnsupportedBrowsersByFeature(s){if(!s)return[];if(!("browser_support"in s))return["> 0%"];const o=[];return ks.forEach((e=>{if("op_mini"===e&&void 0===s.browser_support[e])return void o.push("op_mini all");const t=s.browser_support[e];"string"==typeof t&&ws.test(t)?o.push(`${e} < ${s.browser_support[e]}`):o.push(`${e} >= 1`)})),o}const ws=/^[0-9|.]+$/;function getOptionsForBrowsersByFeature(s,o,e,t,i){switch(o.id){case"is-pseudo-class":return{onComplexSelector:"warning"};case"nesting-rules":if(needsOptionFor(e.find((s=>"is-pseudo-class"===s.id)),s))return i.log('Disabling :is on "nesting-rules" due to lack of browser support.'),{noIsPseudoSelector:!0};return{};case"any-link-pseudo-class":if(s.find((s=>s.startsWith("ie ")||s.startsWith("edge "))))return i.log('Adding area[href] fallbacks for ":any-link" support in Edge and IE.'),{subFeatures:{areaHrefNeedsFixing:!0}};return{};case"logical-properties-and-values":case"float-clear-logical-values":case"logical-resize":case"logical-viewport-units":case"logical-overflow":case"logical-overscroll-behavior":return"logical"in t?t.logical:{};default:return{}}}function needsOptionFor(s,o){const t=getUnsupportedBrowsersByFeature(s),i=e(t,{ignoreUnknownVersions:!0});return!!o.some((s=>i.some((o=>o===s))))}function formatPolyfillableFeature(s){const o=getUnsupportedBrowsersByFeature(s);if(s[ns]||s[ls]){let e=s.id;return e=s.insertBefore?`before-${e}`:`after-${e}`,{browsers:o,vendors_implementations:s.vendors_implementations,plugin:s[us],id:e,stage:cs+1}}return{browsers:o,vendors_implementations:s.vendors_implementations,plugin:ys.get(s.id),id:s.id,stage:s.stage}}function formatStagedFeature(s,o,e,t,i,r,a){let p,c;return p=getOptionsForBrowsersByFeature(o,t,s,r,a),!0===e[t.id]?i&&(p=Object.assign({},p,i)):p=i?Object.assign({},p,i,e[t.id]):Object.assign({},p,e[t.id]),"progressive-custom-properties"!==t.id&&(p.enableProgressiveCustomProperties=!1),"overflow-wrap-property"===t.id&&"preserve"in p&&(p.method=p.preserve?"copy":"replace"),c=t.plugin.postcss&&"function"==typeof t.plugin?t.plugin(p):t.plugin&&t.plugin.default&&"function"==typeof t.plugin.default&&t.plugin.default.postcss?t.plugin.default(p):t.plugin,{browsers:t.browsers,vendors_implementations:t.vendors_implementations,plugin:c,pluginOptions:p,id:t.id}}function intOrZero(s){const o=parseInt(s,10);return Number.isNaN(o)?0:o}const xs=new Set(["progressive-custom-properties"]);function listFeatures(s,o,t,i){const r=Object(o.features),a="enableClientSidePolyfills"in o&&o.enableClientSidePolyfills,p=Object(o.insertBefore),c=Object(o.insertAfter),n=o.browsers?void 0:o.env,l=o.browsers,m=clamp(0,intOrZero(o.minimumVendorImplementations),3);m>0&&i.log(`Using features with ${m} or more vendor implementations`);const u=stageFromOptions(o,i),d=prepareFeaturesList([...s,{id:"progressive-custom-properties"}],p,c).map((s=>formatPolyfillableFeature(s))).filter((s=>!!xs.has(s.id)||(0===m||(!(!s[ns]&&!s[ls])||(m<=s.vendors_implementations||(r[s.id]?(i.log(` ${s.id} does not meet the required vendor implementations but has been enabled by options`),!0):(i.log(` ${s.id} with ${s.vendors_implementations} vendor implementations has been disabled`),!1))))))),f=e(l,{env:n,ignoreUnknownVersions:!0}).filter((s=>ks.includes(s.split(" ")[0])));return d.filter((s=>{if(xs.has(s.id))return!0;const o=s.stage>=u,e=a||!as.includes(s.id),t=!1===r[s.id],p=r[s.id]?r[s.id]:o&&e;return t?i.log(` ${s.id} has been disabled by options`):o?e||i.log(` ${s.id} has been disabled by "enableClientSidePolyfills: false".`):p?i.log(` ${s.id} does not meet the required stage but has been enabled by options`):i.log(` ${s.id} with stage ${s.stage} has been disabled`),p})).map((e=>formatStagedFeature(s,f,r,e,t,o,i))).filter((s=>{if(xs.has(s.id))return!0;if(s.id in r)return r[s.id];const o=e(s.browsers,{ignoreUnknownVersions:!0}),t=f.some((s=>o.some((o=>o===s))));return t||i.log(`${s.id} disabled due to browser support`),t}))}class Logger{constructor(){this.logs=[]}log(s){this.logs.push(s)}resetLogger(){this.logs.length=0}dumpLogs(s){s&&s.warn(this.logs.join("\n")),this.resetLogger()}}var Fs=[{packageName:"css-blank-pseudo",id:"blank-pseudo-class",importName:"postcssBlankPseudo"},{packageName:"css-has-pseudo",id:"has-pseudo-class",importName:"postcssHasPseudo"},{packageName:"css-prefers-color-scheme",id:"prefers-color-scheme-query",importName:"postcssPrefersColorScheme"},{packageName:"postcss-attribute-case-insensitive",id:"case-insensitive-attributes",importName:"postcssAttributeCaseInsensitive"},{packageName:"postcss-clamp",id:"clamp",importName:"postcssClamp"},{packageName:"@csstools/postcss-color-mix-function",id:"color-mix",importName:"postcssColorMixFunction"},{packageName:"@csstools/postcss-color-function",id:"color-function",importName:"postcssColorFunction"},{packageName:"postcss-color-functional-notation",id:"color-functional-notation",importName:"postcssColorFunctionalNotation"},{packageName:"postcss-color-hex-alpha",id:"hexadecimal-alpha-notation",importName:"postcssColorHexAlpha"},{packageName:"postcss-color-rebeccapurple",id:"rebeccapurple-color",importName:"postcssColorRebeccapurple"},{packageName:"postcss-custom-media",id:"custom-media-queries",importName:"postcssCustomMedia"},{packageName:"postcss-custom-properties",id:"custom-properties",importName:"postcssCustomProperties"},{packageName:"postcss-custom-selectors",id:"custom-selectors",importName:"postcssCustomSelectors"},{packageName:"postcss-dir-pseudo-class",id:"dir-pseudo-class",importName:"postcssDirPseudoClass"},{packageName:"postcss-double-position-gradients",id:"double-position-gradients",importName:"postcssDoublePositionGradients"},{packageName:"@csstools/postcss-exponential-functions",id:"exponential-functions",importName:"postcssExponentialFunctions"},{packageName:"postcss-focus-visible",id:"focus-visible-pseudo-class",importName:"postcssFocusVisible"},{packageName:"postcss-focus-within",id:"focus-within-pseudo-class",importName:"postcssFocusWithin"},{packageName:"@csstools/postcss-font-format-keywords",id:"font-format-keywords",importName:"postcssFontFormatKeywords"},{packageName:"postcss-font-variant",id:"font-variant-property",importName:"postcssFontVariant"},{packageName:"@csstools/postcss-gamut-mapping",id:"gamut-mapping",importName:"postcssGamutMapping"},{packageName:"postcss-gap-properties",id:"gap-properties",importName:"postcssGapProperties"},{packageName:"@csstools/postcss-gradients-interpolation-method",id:"gradients-interpolation-method",importName:"postcssGradientsInterpolationMethod"},{packageName:"@csstools/postcss-hwb-function",id:"hwb-function",importName:"postcssHWBFunction"},{packageName:"@csstools/postcss-ic-unit",id:"ic-unit",importName:"postcssICUnit"},{packageName:"postcss-image-set-function",id:"image-set-function",importName:"postcssImageSetFunction"},{packageName:"@csstools/postcss-initial",id:"all-property",importName:"postcssInitial"},{packageName:"@csstools/postcss-is-pseudo-class",id:"is-pseudo-class",importName:"postcssIsPseudoClass"},{packageName:"@csstools/postcss-scope-pseudo-class",id:"scope-pseudo-class",importName:"postcssScopePseudoClass"},{packageName:"postcss-lab-function",id:"lab-function",importName:"postcssLabFunction"},{packageName:"postcss-logical",id:"logical-properties-and-values",importName:"postcssLogical"},{packageName:"@csstools/postcss-logical-float-and-clear",id:"float-clear-logical-values",importName:"postcssLogicalFloatAndClear"},{packageName:"@csstools/postcss-logical-overflow",id:"logical-overflow",importName:"postcssLogicalOverflow"},{packageName:"@csstools/postcss-logical-overscroll-behavior",id:"logical-overscroll-behavior",importName:"postcssLogicalOverscrollBehavor"},{packageName:"@csstools/postcss-logical-resize",id:"logical-resize",importName:"postcssLogicalResize"},{packageName:"@csstools/postcss-logical-viewport-units",id:"logical-viewport-units",importName:"postcssLogicalViewportUnits"},{packageName:"@csstools/postcss-media-minmax",id:"media-query-ranges",importName:"postcssMediaMinmax"},{packageName:"@csstools/postcss-media-queries-aspect-ratio-number-values",id:"media-queries-aspect-ratio-number-values",importName:"postcssMediaQueriesAspectRatioNumberValues"},{packageName:"postcss-nesting",id:"nesting-rules",importName:"postcssNesting"},{packageName:"@csstools/postcss-normalize-display-values",id:"display-two-values",importName:"postcssNormalizeDisplayValues"},{packageName:"@csstools/postcss-oklab-function",id:"oklab-function",importName:"postcssOKLabFunction"},{packageName:"@csstools/postcss-relative-color-syntax",id:"relative-color-syntax",importName:"postcssRelativeColorSyntax"},{packageName:"postcss-opacity-percentage",id:"opacity-percentage",importName:"postcssOpacityPercentage"},{packageName:"postcss-overflow-shorthand",id:"overflow-property",importName:"postcssOverflowShorthand"},{packageName:"postcss-page-break",id:"break-properties",importName:"postcssPageBreak"},{packageName:"postcss-place",id:"place-properties",importName:"postcssPlace"},{packageName:"postcss-pseudo-class-any-link",id:"any-link-pseudo-class",importName:"postcssPseudoClassAnyLink"},{packageName:"postcss-replace-overflow-wrap",id:"overflow-wrap-property",importName:"postcssReplaceOverflowWrap"},{packageName:"postcss-selector-not",id:"not-pseudo-class",importName:"postcssSelectorNot"},{packageName:"@csstools/postcss-stepped-value-functions",id:"stepped-value-functions",importName:"postcssSteppedValueFunctions"},{packageName:"postcss-system-ui-font-family",importedPackage:"../patch/postcss-system-ui-font-family.mjs",id:"system-ui-font-family",importName:"postcssFontFamilySystemUI"},{packageName:"@csstools/postcss-unset-value",id:"unset-value",importName:"postcssUnsetValue"},{packageName:"@csstools/postcss-cascade-layers",id:"cascade-layers",importName:"postcssCascadeLayers"},{packageName:"@csstools/postcss-trigonometric-functions",id:"trigonometric-functions",importName:"postcssTrigonometricFunctions"},{packageName:"@csstools/postcss-nested-calc",id:"nested-calc",importName:"postcssNestedCalc"},{packageName:"@csstools/postcss-text-decoration-shorthand",id:"text-decoration-shorthand",importName:"postcssTextDecorationShorthand"},{packageName:"@csstools/postcss-progressive-custom-properties",id:"progressive-custom-properties",importName:"postcssProgressiveCustomProperties",omitTypedOptions:!0,omitDocs:!0}];function getPackageNamesToIds(){const s={};return Fs.forEach((o=>{s[o.packageName]=o.id})),s}function pluginIdHelp(s,o,e){const t=Fs.map((s=>s.id)),i=Fs.map((s=>s.packageName)),r=getPackageNamesToIds();s.forEach((s=>{if(t.includes(s))return;const a=[...t.map((o=>[o,levenshteinDistance(s,o)])),...i.map((o=>[r[o],levenshteinDistance(s,o)]))].sort(((s,o)=>s[1]-o[1])).filter((s=>s[1]<10)),p=new Set;for(let s=0;s=3));s++);if(!p.size)return void o.warn(e,`Unknown feature: "${s}", see the list of features https://github.com/csstools/postcss-plugins/blob/main/plugin-packs/postcss-preset-env/FEATURES.md`);let c='"';c+=Array.from(p).join('", "'),c+='"',o.warn(e,`Unknown feature: "${s}", did you mean one of: ${c}`)}))}function levenshteinDistance(s,o){if(!s.length)return o.length;if(!o.length)return s.length;const e=[];for(let t=0;t<=o.length;t++){e[t]=[t];for(let i=1;i<=s.length;i++)e[t][i]=0===t?i:Math.min(e[t-1][i]+1,e[t][i-1]+1,e[t-1][i-1]+(s[i-1]===o[t-1]?0:1))}return e[o.length][s.length]}const creator=e=>{const t=new Logger,i=Object(e),r=Object.keys(Object(i.features)),a=i.browsers?void 0:i.env,p=i.browsers,c=initializeSharedOptions(i),n=listFeatures(o,i,c,t),l=n.map((s=>s.plugin));!1!==i.autoprefixer&&l.push(s(Object.assign({env:a,overrideBrowserslist:p},i.autoprefixer))),logFeaturesList(n,i,t);const internalPlugin=()=>({postcssPlugin:"postcss-preset-env",OnceExit:function(s,{result:o}){pluginIdHelp(r,s,o),i.debug&&t.dumpLogs(o),t.resetLogger()}});return internalPlugin.postcss=!0,{postcssPlugin:"postcss-preset-env",plugins:[...l,internalPlugin()]}};creator.postcss=!0;export{creator as default}; +import s from"autoprefixer";import o from"cssdb";import e from"browserslist";import t from"@csstools/postcss-initial";import i from"postcss-pseudo-class-any-link";import r from"css-blank-pseudo";import a from"postcss-page-break";import p from"@csstools/postcss-cascade-layers";import c from"postcss-attribute-case-insensitive";import n from"postcss-clamp";import l from"@csstools/postcss-color-function";import m from"postcss-color-functional-notation";import u from"@csstools/postcss-color-mix-function";import d from"postcss-custom-media";import f from"postcss-custom-properties";import g from"postcss-custom-selectors";import b from"postcss-dir-pseudo-class";import h from"@csstools/postcss-normalize-display-values";import v from"postcss-double-position-gradients";import N from"@csstools/postcss-exponential-functions";import y from"@csstools/postcss-logical-float-and-clear";import k from"postcss-focus-visible";import w from"postcss-focus-within";import x from"@csstools/postcss-font-format-keywords";import F from"postcss-font-variant";import $ from"@csstools/postcss-gamut-mapping";import O from"postcss-gap-properties";import S from"@csstools/postcss-gradients-interpolation-method";import P from"css-has-pseudo";import C from"postcss-color-hex-alpha";import I from"@csstools/postcss-hwb-function";import L from"@csstools/postcss-ic-unit";import E from"postcss-image-set-function";import A from"@csstools/postcss-is-pseudo-class";import B from"postcss-lab-function";import U from"@csstools/postcss-logical-overflow";import _ from"@csstools/postcss-logical-overscroll-behavior";import q from"postcss-logical";import j from"@csstools/postcss-logical-resize";import M from"@csstools/postcss-logical-viewport-units";import z from"@csstools/postcss-media-queries-aspect-ratio-number-values";import D from"@csstools/postcss-media-minmax";import R from"@csstools/postcss-nested-calc";import T from"postcss-nesting";import V from"postcss-selector-not";import H from"@csstools/postcss-oklab-function";import W from"postcss-opacity-percentage";import G from"postcss-overflow-shorthand";import K from"postcss-replace-overflow-wrap";import Z from"postcss-place";import Q from"css-prefers-color-scheme";import J from"@csstools/postcss-progressive-custom-properties";import X from"postcss-color-rebeccapurple";import Y from"@csstools/postcss-relative-color-syntax";import ss from"@csstools/postcss-scope-pseudo-class";import os from"@csstools/postcss-stepped-value-functions";import es from"@csstools/postcss-text-decoration-shorthand";import ts from"@csstools/postcss-trigonometric-functions";import is from"@csstools/postcss-unset-value";const rs={"blank-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-blank-pseudo/README.md#browser","focus-visible-pseudo-class":"https://github.com/WICG/focus-visible","focus-within-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-focus-within/README.md#browser","has-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-has-pseudo/README.md#browser","prefers-color-scheme-query":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-prefers-color-scheme/README.md#browser"},as=["blank-pseudo-class","focus-visible-pseudo-class","focus-within-pseudo-class","has-pseudo-class","prefers-color-scheme-query"];function logFeaturesList(s,o,e){if(o.debug){e.log("Enabling the following feature(s):");const t=[],i=[];!1!==o.autoprefixer&&i.push(" autoprefixer"),s.forEach((s=>{s.id.startsWith("before")||s.id.startsWith("after")?i.push(` ${s.id} (injected via options)`):i.push(` ${s.id}`),void 0!==rs[s.id]&&t.push(s.id)})),i.sort(((s,o)=>s.localeCompare(o))),t.sort(((s,o)=>s.localeCompare(o))),i.forEach((s=>e.log(s))),t.length&&(e.log("These feature(s) need a browser library to work:"),t.forEach((s=>e.log(` ${s}: ${rs[s]}`))))}}function initializeSharedOptions(s){if("preserve"in s){const o={};return o.preserve=s.preserve,o}return!1}function clamp(s,o,e){return Math.max(s,Math.min(o,e))}const ps=2,cs=5;function stageFromOptions(s,o){let e=ps;if(void 0===s.stage)return o.log(`Using features from Stage ${e} (default)`),e;if(!1===s.stage)e=cs;else{let o=parseInt(s.stage,10);Number.isNaN(o)&&(o=0),e=clamp(0,o,cs)}return e===cs?o.log('Stage has been disabled, features will be handled via the "features" option.'):o.log(`Using features from Stage ${e}`),e}const ns=Symbol("insertBefore"),ls=Symbol("insertAfter"),ms=Symbol("insertOrder"),us=Symbol("plugin");function getTransformedInsertions(s,o,e){if("insertBefore"!==e&&"insertAfter"!==e)return[];const t="insertBefore"===e?ns:ls,i=[];for(const e in o){if(!Object.hasOwnProperty.call(o,e))continue;if(!s.find((s=>s.id===e)))continue;let r=o[e];Array.isArray(r)||(r=[r]);for(let s=0;sfeatureIsInsertedOrHasAPlugin(s))).sort(((s,o)=>featureIsLess(s,o)))}function getOptionsForBrowsersByFeature(s,o,e,t,i){switch(o.id){case"is-pseudo-class":return{onComplexSelector:"warning"};case"any-link-pseudo-class":if(s.find((s=>s.startsWith("ie ")||s.startsWith("edge "))))return i.log('Adding area[href] fallbacks for ":any-link" support in Edge and IE.'),{subFeatures:{areaHrefNeedsFixing:!0}};return{};case"logical-properties-and-values":case"float-clear-logical-values":case"logical-resize":case"logical-viewport-units":case"logical-overflow":case"logical-overscroll-behavior":return"logical"in t?t.logical:{};default:return{}}}const ks=["and_chr","and_ff","android","chrome","edge","firefox","ie","ios_saf","op_mini","op_mob","opera","safari","samsung"];function getUnsupportedBrowsersByFeature(s){if(!s)return[];if(!("browser_support"in s))return["> 0%"];const o=[];return ks.forEach((e=>{if("op_mini"===e&&void 0===s.browser_support[e])return void o.push("op_mini all");const t=s.browser_support[e];"string"==typeof t&&ws.test(t)?o.push(`${e} < ${s.browser_support[e]}`):o.push(`${e} >= 1`)})),o}const ws=/^[0-9|.]+$/;function formatPolyfillableFeature(s){const o=getUnsupportedBrowsersByFeature(s);if(s[ns]||s[ls]){let e=s.id;return e=s.insertBefore?`before-${e}`:`after-${e}`,{browsers:o,vendors_implementations:s.vendors_implementations,plugin:s[us],id:e,stage:cs+1}}return{browsers:o,vendors_implementations:s.vendors_implementations,plugin:ys.get(s.id),id:s.id,stage:s.stage}}function formatStagedFeature(s,o,e,t,i,r,a){let p,c;return p=getOptionsForBrowsersByFeature(o,t,0,r,a),!0===e[t.id]?i&&(p=Object.assign({},p,i)):p=i?Object.assign({},p,i,e[t.id]):Object.assign({},p,e[t.id]),"progressive-custom-properties"!==t.id&&(p.enableProgressiveCustomProperties=!1),"overflow-wrap-property"===t.id&&"preserve"in p&&(p.method=p.preserve?"copy":"replace"),c=t.plugin.postcss&&"function"==typeof t.plugin?t.plugin(p):t.plugin&&t.plugin.default&&"function"==typeof t.plugin.default&&t.plugin.default.postcss?t.plugin.default(p):t.plugin,{browsers:t.browsers,vendors_implementations:t.vendors_implementations,plugin:c,pluginOptions:p,id:t.id}}function intOrZero(s){const o=parseInt(s,10);return Number.isNaN(o)?0:o}const xs=new Set(["progressive-custom-properties"]);function listFeatures(s,o,t,i){const r=Object(o.features),a="enableClientSidePolyfills"in o&&o.enableClientSidePolyfills,p=Object(o.insertBefore),c=Object(o.insertAfter),n=o.browsers?void 0:o.env,l=o.browsers,m=clamp(0,intOrZero(o.minimumVendorImplementations),3);m>0&&i.log(`Using features with ${m} or more vendor implementations`);const u=stageFromOptions(o,i),d=prepareFeaturesList([...s,{id:"progressive-custom-properties"}],p,c).map((s=>formatPolyfillableFeature(s))).filter((s=>!!xs.has(s.id)||(0===m||(!(!s[ns]&&!s[ls])||(m<=s.vendors_implementations||(r[s.id]?(i.log(` ${s.id} does not meet the required vendor implementations but has been enabled by options`),!0):(i.log(` ${s.id} with ${s.vendors_implementations} vendor implementations has been disabled`),!1))))))),f=e(l,{env:n,ignoreUnknownVersions:!0}).filter((s=>ks.includes(s.split(" ")[0])));return d.filter((s=>{if(xs.has(s.id))return!0;const o=s.stage>=u,e=a||!as.includes(s.id),t=!1===r[s.id],p=r[s.id]?r[s.id]:o&&e;return t?i.log(` ${s.id} has been disabled by options`):o?e||i.log(` ${s.id} has been disabled by "enableClientSidePolyfills: false".`):p?i.log(` ${s.id} does not meet the required stage but has been enabled by options`):i.log(` ${s.id} with stage ${s.stage} has been disabled`),p})).map((s=>formatStagedFeature(0,f,r,s,t,o,i))).filter((s=>{if(xs.has(s.id))return!0;if(s.id in r)return r[s.id];const o=e(s.browsers,{ignoreUnknownVersions:!0}),t=f.some((s=>o.some((o=>o===s))));return t||i.log(`${s.id} disabled due to browser support`),t}))}class Logger{constructor(){this.logs=[]}log(s){this.logs.push(s)}resetLogger(){this.logs.length=0}dumpLogs(s){s&&s.warn(this.logs.join("\n")),this.resetLogger()}}var Fs=[{packageName:"css-blank-pseudo",id:"blank-pseudo-class",importName:"postcssBlankPseudo"},{packageName:"css-has-pseudo",id:"has-pseudo-class",importName:"postcssHasPseudo"},{packageName:"css-prefers-color-scheme",id:"prefers-color-scheme-query",importName:"postcssPrefersColorScheme"},{packageName:"postcss-attribute-case-insensitive",id:"case-insensitive-attributes",importName:"postcssAttributeCaseInsensitive"},{packageName:"postcss-clamp",id:"clamp",importName:"postcssClamp"},{packageName:"@csstools/postcss-color-mix-function",id:"color-mix",importName:"postcssColorMixFunction"},{packageName:"@csstools/postcss-color-function",id:"color-function",importName:"postcssColorFunction"},{packageName:"postcss-color-functional-notation",id:"color-functional-notation",importName:"postcssColorFunctionalNotation"},{packageName:"postcss-color-hex-alpha",id:"hexadecimal-alpha-notation",importName:"postcssColorHexAlpha"},{packageName:"postcss-color-rebeccapurple",id:"rebeccapurple-color",importName:"postcssColorRebeccapurple"},{packageName:"postcss-custom-media",id:"custom-media-queries",importName:"postcssCustomMedia"},{packageName:"postcss-custom-properties",id:"custom-properties",importName:"postcssCustomProperties"},{packageName:"postcss-custom-selectors",id:"custom-selectors",importName:"postcssCustomSelectors"},{packageName:"postcss-dir-pseudo-class",id:"dir-pseudo-class",importName:"postcssDirPseudoClass"},{packageName:"postcss-double-position-gradients",id:"double-position-gradients",importName:"postcssDoublePositionGradients"},{packageName:"@csstools/postcss-exponential-functions",id:"exponential-functions",importName:"postcssExponentialFunctions"},{packageName:"postcss-focus-visible",id:"focus-visible-pseudo-class",importName:"postcssFocusVisible"},{packageName:"postcss-focus-within",id:"focus-within-pseudo-class",importName:"postcssFocusWithin"},{packageName:"@csstools/postcss-font-format-keywords",id:"font-format-keywords",importName:"postcssFontFormatKeywords"},{packageName:"postcss-font-variant",id:"font-variant-property",importName:"postcssFontVariant"},{packageName:"@csstools/postcss-gamut-mapping",id:"gamut-mapping",importName:"postcssGamutMapping"},{packageName:"postcss-gap-properties",id:"gap-properties",importName:"postcssGapProperties"},{packageName:"@csstools/postcss-gradients-interpolation-method",id:"gradients-interpolation-method",importName:"postcssGradientsInterpolationMethod"},{packageName:"@csstools/postcss-hwb-function",id:"hwb-function",importName:"postcssHWBFunction"},{packageName:"@csstools/postcss-ic-unit",id:"ic-unit",importName:"postcssICUnit"},{packageName:"postcss-image-set-function",id:"image-set-function",importName:"postcssImageSetFunction"},{packageName:"@csstools/postcss-initial",id:"all-property",importName:"postcssInitial"},{packageName:"@csstools/postcss-is-pseudo-class",id:"is-pseudo-class",importName:"postcssIsPseudoClass"},{packageName:"@csstools/postcss-scope-pseudo-class",id:"scope-pseudo-class",importName:"postcssScopePseudoClass"},{packageName:"postcss-lab-function",id:"lab-function",importName:"postcssLabFunction"},{packageName:"postcss-logical",id:"logical-properties-and-values",importName:"postcssLogical"},{packageName:"@csstools/postcss-logical-float-and-clear",id:"float-clear-logical-values",importName:"postcssLogicalFloatAndClear"},{packageName:"@csstools/postcss-logical-overflow",id:"logical-overflow",importName:"postcssLogicalOverflow"},{packageName:"@csstools/postcss-logical-overscroll-behavior",id:"logical-overscroll-behavior",importName:"postcssLogicalOverscrollBehavor"},{packageName:"@csstools/postcss-logical-resize",id:"logical-resize",importName:"postcssLogicalResize"},{packageName:"@csstools/postcss-logical-viewport-units",id:"logical-viewport-units",importName:"postcssLogicalViewportUnits"},{packageName:"@csstools/postcss-media-minmax",id:"media-query-ranges",importName:"postcssMediaMinmax"},{packageName:"@csstools/postcss-media-queries-aspect-ratio-number-values",id:"media-queries-aspect-ratio-number-values",importName:"postcssMediaQueriesAspectRatioNumberValues"},{packageName:"postcss-nesting",id:"nesting-rules",importName:"postcssNesting"},{packageName:"@csstools/postcss-normalize-display-values",id:"display-two-values",importName:"postcssNormalizeDisplayValues"},{packageName:"@csstools/postcss-oklab-function",id:"oklab-function",importName:"postcssOKLabFunction"},{packageName:"@csstools/postcss-relative-color-syntax",id:"relative-color-syntax",importName:"postcssRelativeColorSyntax"},{packageName:"postcss-opacity-percentage",id:"opacity-percentage",importName:"postcssOpacityPercentage"},{packageName:"postcss-overflow-shorthand",id:"overflow-property",importName:"postcssOverflowShorthand"},{packageName:"postcss-page-break",id:"break-properties",importName:"postcssPageBreak"},{packageName:"postcss-place",id:"place-properties",importName:"postcssPlace"},{packageName:"postcss-pseudo-class-any-link",id:"any-link-pseudo-class",importName:"postcssPseudoClassAnyLink"},{packageName:"postcss-replace-overflow-wrap",id:"overflow-wrap-property",importName:"postcssReplaceOverflowWrap"},{packageName:"postcss-selector-not",id:"not-pseudo-class",importName:"postcssSelectorNot"},{packageName:"@csstools/postcss-stepped-value-functions",id:"stepped-value-functions",importName:"postcssSteppedValueFunctions"},{packageName:"postcss-system-ui-font-family",importedPackage:"../patch/postcss-system-ui-font-family.mjs",id:"system-ui-font-family",importName:"postcssFontFamilySystemUI"},{packageName:"@csstools/postcss-unset-value",id:"unset-value",importName:"postcssUnsetValue"},{packageName:"@csstools/postcss-cascade-layers",id:"cascade-layers",importName:"postcssCascadeLayers"},{packageName:"@csstools/postcss-trigonometric-functions",id:"trigonometric-functions",importName:"postcssTrigonometricFunctions"},{packageName:"@csstools/postcss-nested-calc",id:"nested-calc",importName:"postcssNestedCalc"},{packageName:"@csstools/postcss-text-decoration-shorthand",id:"text-decoration-shorthand",importName:"postcssTextDecorationShorthand"},{packageName:"@csstools/postcss-progressive-custom-properties",id:"progressive-custom-properties",importName:"postcssProgressiveCustomProperties",omitTypedOptions:!0,omitDocs:!0}];function getPackageNamesToIds(){const s={};return Fs.forEach((o=>{s[o.packageName]=o.id})),s}function pluginIdHelp(s,o,e){const t=Fs.map((s=>s.id)),i=Fs.map((s=>s.packageName)),r=getPackageNamesToIds();s.forEach((s=>{if(t.includes(s))return;const a=[...t.map((o=>[o,levenshteinDistance(s,o)])),...i.map((o=>[r[o],levenshteinDistance(s,o)]))].sort(((s,o)=>s[1]-o[1])).filter((s=>s[1]<10)),p=new Set;for(let s=0;s=3));s++);if(!p.size)return void o.warn(e,`Unknown feature: "${s}", see the list of features https://github.com/csstools/postcss-plugins/blob/main/plugin-packs/postcss-preset-env/FEATURES.md`);let c='"';c+=Array.from(p).join('", "'),c+='"',o.warn(e,`Unknown feature: "${s}", did you mean one of: ${c}`)}))}function levenshteinDistance(s,o){if(!s.length)return o.length;if(!o.length)return s.length;const e=[];for(let t=0;t<=o.length;t++){e[t]=[t];for(let i=1;i<=s.length;i++)e[t][i]=0===t?i:Math.min(e[t-1][i]+1,e[t][i-1]+1,e[t-1][i-1]+(s[i-1]===o[t-1]?0:1))}return e[o.length][s.length]}const creator=e=>{const t=new Logger,i=Object(e),r=Object.keys(Object(i.features)),a=i.browsers?void 0:i.env,p=i.browsers,c=initializeSharedOptions(i),n=listFeatures(o,i,c,t),l=n.map((s=>s.plugin));!1!==i.autoprefixer&&l.push(s(Object.assign({env:a,overrideBrowserslist:p},i.autoprefixer))),logFeaturesList(n,i,t);const internalPlugin=()=>({postcssPlugin:"postcss-preset-env",OnceExit:function(s,{result:o}){pluginIdHelp(r,s,o),i.debug&&t.dumpLogs(o),t.resetLogger()}});return internalPlugin.postcss=!0,{postcssPlugin:"postcss-preset-env",plugins:[...l,internalPlugin()]}};creator.postcss=!0;export{creator as default}; diff --git a/plugin-packs/postcss-preset-env/src/lib/get-options-for-browsers-by-feature.mjs b/plugin-packs/postcss-preset-env/src/lib/get-options-for-browsers-by-feature.mjs index a928c9263..a2614027f 100644 --- a/plugin-packs/postcss-preset-env/src/lib/get-options-for-browsers-by-feature.mjs +++ b/plugin-packs/postcss-preset-env/src/lib/get-options-for-browsers-by-feature.mjs @@ -1,6 +1,3 @@ -import browserslist from 'browserslist'; -import { getUnsupportedBrowsersByFeature } from './get-unsupported-browsers-by-feature.mjs'; - // add extra options for certain browsers by feature export default function getOptionsForBrowsersByFeature(supportedBrowsers, feature, cssdbList, options, logger) { switch (feature.id) { @@ -10,25 +7,6 @@ export default function getOptionsForBrowsersByFeature(supportedBrowsers, featur return { onComplexSelector: 'warning', }; - case 'nesting-rules': - { - // TODO : remove this in a next major release - - // Nesting rules can transform selectors to use :is pseudo. - // This is more spec compliant but it's not supported by all browsers. - // If we can't use :is pseudo according to preset-env options, we add an extra option to avoid :is pseudo. - const feature = cssdbList.find(feature => feature.id === 'is-pseudo-class'); - - if (needsOptionFor(feature, supportedBrowsers)) { - logger.log('Disabling :is on "nesting-rules" due to lack of browser support.'); - return { - noIsPseudoSelector: true, - }; - } - } - - return {}; - case 'any-link-pseudo-class': { const hasIEOrEdge = supportedBrowsers.find((browserslistEntry) => { @@ -64,18 +42,3 @@ export default function getOptionsForBrowsersByFeature(supportedBrowsers, featur return {}; } } - -function needsOptionFor(feature, supportedBrowsers) { - const unsupportedIn = getUnsupportedBrowsersByFeature(feature); - const unsupportedBrowsers = browserslist(unsupportedIn, { - ignoreUnknownVersions: true, - }); - - if (supportedBrowsers.some((supportedBrowser) => { - return unsupportedBrowsers.some(polyfillBrowser => polyfillBrowser === supportedBrowser); - })) { - return true; - } - - return false; -} diff --git a/plugin-packs/postcss-preset-env/test/_tape.mjs b/plugin-packs/postcss-preset-env/test/_tape.mjs index 895dc1ac1..cd294c467 100644 --- a/plugin-packs/postcss-preset-env/test/_tape.mjs +++ b/plugin-packs/postcss-preset-env/test/_tape.mjs @@ -64,18 +64,6 @@ postcssTape(plugin)({ browsers: 'op_mini all', }, }, - 'basic:ch88-ff78:no-is-pseudo': { - message: ':is pseudo for nesting can be disable with modern browsers { browsers: "chrome >= 88, firefox >= 78", stage: 0, features: { nesting-rules: { noIsPseudoSelector: true } } } usage', - options: { - browsers: 'chrome >= 88, firefox >= 78', - stage: 0, - features: { - 'nesting-rules': { - noIsPseudoSelector: true, - }, - }, - }, - }, 'basic:ch88-ff78-saf10': { message: 'does not use :is pseudo for nesting with an older browser { browsers: "chrome >= 88, firefox >= 78, safari >= 10", stage: 0 } usage', options: { @@ -142,17 +130,6 @@ postcssTape(plugin)({ }, }, }, - 'basic:nesting:noIsPseudoSelector:false': { - message: 'supports { stage: false, features: { "nesting-rules": { "noIsPseudoSelector": false } } } usage', - options: { - stage: false, - features: { - 'nesting-rules': { - noIsPseudoSelector: false, - }, - }, - }, - }, 'basic:nesting:false': { message: 'supports { stage: 0, features: { "nesting-rules": false } } usage', options: { diff --git a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css index dca5a0138..dee6a5dec 100644 --- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css @@ -58,7 +58,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.false.expect.css index 1844eb728..d397dd42a 100644 --- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.false.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.false.expect.css @@ -58,7 +58,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css index 2f066cd8c..fc9d55ba5 100644 --- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css @@ -59,7 +59,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css b/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css index dd1f3fccc..7614d1536 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css @@ -51,7 +51,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.ch88-ff78-saf10.expect.css b/plugin-packs/postcss-preset-env/test/basic.ch88-ff78-saf10.expect.css index 1c4125b1e..71631ff88 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ch88-ff78-saf10.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ch88-ff78-saf10.expect.css @@ -58,7 +58,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.expect.css b/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.expect.css index 885aad03e..44d23bcda 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.expect.css @@ -58,7 +58,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.no-is-pseudo.expect.css b/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.no-is-pseudo.expect.css deleted file mode 100644 index 885aad03e..000000000 --- a/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.no-is-pseudo.expect.css +++ /dev/null @@ -1,565 +0,0 @@ -:root { - --order: 1; -} - -.test-custom-property-fallbacks { - --firebrick: rgb(179, 35, 35); -} - -.test-custom-properties { - order: var(--order); -} - -.test-image-set-function { - background-image: url(img/test.png); - background-image: -webkit-image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); - background-image: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); - order: 2; -} - -@media (min-resolution: 192dpi) { - -.test-image-set-function { - background-image: url(img/test-2x.png); -} -} - -.test-logical-properties-and-values { - margin-left: 1px; - margin-right: 2px; - order: 3; - padding-top: 4px; - padding-bottom: 4px; -} - -.test-logical-resize { - resize: horizontal; -} - -.test-logical-viewport-units { - width: calc(10vw + 5px); - width: calc(10vi + 5px); -} - -.test-nesting-rules { - order: 4; - - order: 6; -} - -.test-nesting-rules p { - order: 5; - } - -.test-nesting-rules, -#test-is-pseudo { - order: 7; - - order: 9; -} - -.test-nesting-rules + p, #test-is-pseudo + p { - order: 8; - } - -@media (max-width: 30em) { - .test-custom-media-queries { - order: 10; - } -} - -@media (min-width: 480px) and (max-width: 767.98px) { - .test-media-query-ranges { - order: 11; - } -} - -@media (prefers-color-scheme: dark) { - body { - background-color: black; - color: white; - } -} - -h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.does-not-exist), h3.test-custom-selectors:not(.does-not-exist), h4.test-custom-selectors:not(.does-not-exist), h5.test-custom-selectors:not(.does-not-exist), h6.test-custom-selectors:not(.does-not-exist), .test-custom-selectors.heading-7 { - order:12; -} - -.test-case-insensitive-attributes[frame=hsides i] { - order: 13; -} - -.test-rebeccapurple-color { - color: rebeccapurple; - order: 14; -} - -.test-hexadecimal-alpha-notation { - background-color: #f3f3f3f3; - color: #0003; - order: 15; -} - -.test-color-functional-notation { - color: rgb(70% 13.5% 13.5% / 50%); - order: 16; -} - -.test-lab-function { - background-color: rgb(179, 35, 35); - color: rgba(179, 34, 35, 0.5); - order: 17; -} - -.test-system-ui-font-family { - font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif; - order: 18; -} - -.test-font-variant-property { - font-feature-settings: "smcp"; - font-variant-caps: small-caps; - order: 19; -} - -.test-all-property { - all: initial; - order: 20; -} - -.test-matches-pseudo-class:matches(:first-child, .special) { - order: 21; -} - -.test-not-pseudo-class:not(:first-child):not(.special) { - order: 22; -} - -.test-any-link-pseudo-class:any-link { - order: 23; -} - -[dir="rtl"] .test-dir-pseudo-class { - order: 24; -} - -.test-overflow-wrap-property { - order: 25; - overflow-wrap: break-word; -} - -.test-focus-visible-pseudo-class:focus-visible { - order: 26; -} - -.test-double-position-gradients { - background-image: conic-gradient(yellowgreen 40%, gold 0deg,gold 75%, #f06 0deg); - background-image: conic-gradient(yellowgreen 40%, gold 0deg 75%, #f06 0deg); -} - -.test-blank-pseudo-class:blank { - background-color: yellow; -} - -.test-has-pseudo-class:has(.inner-class) { - background-color: yellow; -} - -.a:focus, .a:hover, .b:focus, .b:hover { - order: 27; -} - -.a.c > .b + .d { - order: 28; -} - -.test-hwb-function { - background-color: rgba(0, 196, 255, 0.5); -} - -.test-opacity-percent { - opacity: 42%; -} - -.clamp-same-unit { - width: clamp(10px, 64px, 80px); -} - -.complex-clamp { - width: clamp(calc(100% - 10px), min(10px, 100%), max(40px, 4em)); -} - -.clamp-different-units { - width: clamp(10%, 2px, 4rem); -} - -.mixed-clamp { - grid-template-columns: clamp(22rem, 40%, 32rem) minmax(0, 1fr); - margin: clamp(1rem, 2%, 3rem) 4vh; -} - -.calc-clamp { - margin: 0 40px 0 calc(-1 * clamp(32px, 16vw, 64px)); -} - -.multiple-calc-clamp { - margin: calc(-1 * clamp(1px, 2vw, 3px)) calc(-1 * clamp(4px, 5vw, 6px)); -} - -.nested-clamp { - font-size: clamp(clamp(1rem, 2vw, 3rem), 4vw, 5rem); -} - -@font-face { - font-family: 'A'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: url(a) format("woff2"); -} - -.block-flow { - display: block; - display: block flow; -} - -.block-flow-root { - display: flow-root; - display: block flow-root; -} - -.inline-flow { - display: inline; - display: inline flow; -} - -.inline-flow-root { - display: inline-block; - display: inline flow-root; -} - -.run-in-flow { - display: run-in; - display: run-in flow; -} - -.list-item-block-flow { - display: list-item; - display: list-item block flow; -} - -.inline-flow-list-item { - display: inline list-item; - display: inline flow list-item; -} - -.block-flex { - display: flex; - display: block flex; -} - -.inline-flex { - display: inline-flex; - display: inline flex; -} - -.block-grid { - display: grid; - display: block grid; -} - -.inline-grid { - display: inline-grid; - display: inline grid; -} - -.inline-ruby { - display: ruby; - display: inline ruby; -} - -.block-table { - display: table; - display: block table; -} - -.inline-table { - display: inline-table; - display: inline table; -} - -.table-cell-flow { - display: table-cell; - display: table-cell flow; -} - -.table-caption-flow { - display: table-caption; - display: table-caption flow; -} - -.ruby-base-flow { - display: ruby-base; - display: ruby-base flow; -} - -.ruby-text-flow { - display: ruby-text; - display: ruby-text flow; -} - -.logical-float { - float: left; -} - -.color-function { - prop-1: rgb(0, 129, 96); - prop-2: 'color(display-p3 0.02472 0.01150 0.00574 / 1)'; - prop-3: rgb(7, 3, 1); - prop-4: rgb(7, 3, 1); - prop-5: color(display-p3 1 1 1 1); -} - -.oklab { - color-1: rgb(73, 71, 69); - color-2: rgb(121, 34, 67); - color-3: rgba(121, 34, 67, 0.5); - color-4: rgb(121, 34, 67); - color-5: rgba(121, 34, 67, 0.5); - color-6: rgb(177, 102, 126); - color-7: oklab(60% 0.1 0 foo); - color-8: rgb(125, 35, 41); - color-9: rgb(198, 93, 7); - color-10: rgb(157, 147, 24); - color-11: rgb(104, 166, 57); - color-12: rgb(98, 172, 239); -} - -.oklch { - color-1: rgb(126, 37, 15); - color-2: rgb(126, 37, 15); - color-3: rgba(126, 37, 15, 0.5); - color-4: rgb(126, 37, 15); - color-5: rgba(126, 37, 15, 0.5); - color-6: rgb(197, 84, 124); - - color-7: rgb(0, 149, 131); - color-8: rgb(0, 149, 131); - color-9: rgb(0, 149, 131); - color-10: rgb(0, 149, 131); - color-11: rgb(0, 149, 131); - - color-12: rgb(188, 101, 59); - color-13: rgb(188, 101, 59); - color-14: rgb(188, 101, 59); - color-15: rgb(188, 101, 59); - color-16: rgb(188, 101, 59); - color-17: oklch(60% 0.1250 0.785398unknown); -} - -@media (color-gamut: p3) { -.oklch { - - color-7: color(display-p3 0.19244 0.58461 0.51559); - color-8: color(display-p3 0.19244 0.58461 0.51559); - color-9: color(display-p3 0.19244 0.58461 0.51559); - color-10: color(display-p3 0.19244 0.58461 0.51559); - color-11: color(display-p3 0.19244 0.58461 0.51559); -} -} - -.ic-unit { - --value-2ic: initial; - text-indent: 2em; - content: var(--value-2ic); - left: var(--non-existing, 2em); - width: calc(8em + 20px); - height: 10px; - margin: 0.5em 1em .2em; - padding: 2 ic; -} - -.unset { - clip: unset; -} - -.mod { - padding: 8px 3px 1px calc(3px + 50%); - transform: rotate(-50deg); - width: 2px; -} - -.rem { - padding: 8px 3px 1px calc(3px + 50%); - transform: rotate(-50deg); -} - -.round { - top: 3px; - right: 3px; - bottom: 3px; - left: 2px; - padding-left: 2px; -} - -.trigonometric { - left: 0.70711; - left: 0.70711; - left: 1; - left: 30deg; - left: 60deg; - left: 84.28941deg; - left: -45deg; - left: 90deg; - left: 135deg; - left: 0.99863; -} - -.trigonometric-ignore-not-a-function { - left: sin; - left: cos; - left: tan; - left: asin; - left: acos; - left: atan; - left: atan2; -} - -.trigonometric-ignore-no-arguments { - left: sin(); - left: cos(); - left: tan(); - left: asin(); - left: acos(); - left: atan(); - left: atan2(); -} - -[data-view-size=m] .view { - background: red; - } - -.nested-calc { - order: calc(1 * calc(8 / 3 + calc(5 * 10))); -} - -.text-decoration-shorthand { - text-decoration: 3px wavy pink overline; -} - -.stage__container { - left: var(--size, 1rem); -} - -:scope { - content: "plain :scope"; -} - -@scope (.foo) { - :scope { - content: ":scope in @scope"; - } -} - -:scope { - @scope (.foo) { - content: ":scope in @scope, but with nesting"; - } -} - -@media (min-aspect-ratio: 177/100) { - /* media query aspect ratio : */ -} - -.color-mix { - color-1: rgba(0, 0, 255, 0.65); - color-2: rgba(0, 0, 255, 0.65); - color-3: rgba(0, 0, 255, 0.65); - color-4: rgba(122, 0, 182, 0.65); - color-5: rgba(149, 0, 122, 0.65); - color-6: rgba(179, 0, 255, 0.65); -} - -@media (color-gamut: p3) { -.color-mix { - color-4: color(display-p3 0.4447 0 0.71665 / 0.65); - color-5: color(display-p3 0.55417 0 0.48083 / 0.65); -} -} - -.gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.3004), color(display-p3 1.15167 0.57912 -0.3946), color(display-p3 1.06645 0.68611 -0.4296), color(display-p3 0.94738 0.78766 -0.4263), color(display-p3 0.79233 0.87807 -0.3707), color(display-p3 0.59026 0.95319 -0.1467), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.5392 1.05733 0.93686), color(display-p3 -0.5777 1.04644 1.15396) 100%); -} - -@media (color-gamut: rec2020) { -.gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); -} -} - -@supports (color: color(display-p3 0 0 0)) { -.gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 181, 255), rgb(172, 194, 255), rgb(155, 205, 255), rgb(126, 217, 255), rgb(99, 228, 255), rgb(94, 237, 237) 100%); -} - -@media (color-gamut: rec2020) { -.gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); -} -} -} - -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { -.gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); -} -} - -.test-css-color-5-interop { - color-1: rgb(196, 129, 72); - color-2: color(from rgb(196, 129, 72) a98-rgb r g b / none); - color-3: rgb(234, 133, 82); - color-4: color(from rgb(234, 133, 82) prophoto-rgb r g none); - color-5: rgb(179, 157, 51); - color-6: rgb(179, 35, 35); - color-7: rgb(163, 57, 39); - color-8: rgb(141, 0, 0); - color-9: rgb(130, 31, 0); -} - -@media (color-gamut: p3) { -.test-css-color-5-interop { - color-8: color(display-p3 0.50566 0.0781 0); - color-9: color(display-p3 0.48896 0.1211 0); -} -} - -.test-property-with-var { - --opacity: 1; - color: rgba(87 107 149 / var(--opacity)); -} - -.exponential-functions { - width: 8px; -} - -.out-of-gamut { - --color: rgb(0, 249, 66); -} - -.issue-1244--a { - background-image: -ms-linear-gradient(180deg, red 0%, blue 100%); -} - -.issue-1244--b { - background-image: linear-gradient(180deg, red 0%, blue 100%); -} - -.issue-1244--c { - background-image: linear-gradient(180deg, red 0%, blue 100%); -} diff --git a/plugin-packs/postcss-preset-env/test/basic.expect.css b/plugin-packs/postcss-preset-env/test/basic.expect.css index 381032af4..4346a0170 100644 --- a/plugin-packs/postcss-preset-env/test/basic.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.expect.css @@ -59,7 +59,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css b/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css index 3553abac9..9162e82f9 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css @@ -57,7 +57,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css b/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css index 129f19b7c..690b2578d 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css @@ -56,7 +56,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css b/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css index 6920b4ab8..222ec88cd 100644 --- a/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css @@ -59,7 +59,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css b/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css index d8fb9f9ac..bfde6f501 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css @@ -69,7 +69,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { -ms-flex-order: 8; order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.nesting.noIsPseudoSelector.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.nesting.noIsPseudoSelector.false.expect.css deleted file mode 100644 index cdff486ff..000000000 --- a/plugin-packs/postcss-preset-env/test/basic.nesting.noIsPseudoSelector.false.expect.css +++ /dev/null @@ -1,496 +0,0 @@ -:root { - --order: 1; -} - -.test-custom-property-fallbacks { - --firebrick: lab(40% 56.6 39); -} - -.test-custom-properties { - order: var(--order); -} - -.test-image-set-function { - background-image: -webkit-image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); - background-image: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); - order: 2; -} - -.test-logical-properties-and-values { - margin-inline-start: 1px; - margin-inline-end: 2px; - order: 3; - padding-block: 4px; -} - -.test-logical-resize { - resize: inline; -} - -.test-logical-viewport-units { - width: calc(10vi + 5px); -} - -.test-nesting-rules { - order: 4; - - order: 6; -} - -.test-nesting-rules p { - order: 5; - } - -.test-nesting-rules, -#test-is-pseudo { - order: 7; - - order: 9; -} - -:is(.test-nesting-rules,#test-is-pseudo) + p { - order: 8; - } - -@custom-media --narrow-window (max-width: 30em); - -@media (--narrow-window) { - .test-custom-media-queries { - order: 10; - } -} - -@media (480px <= width < 768px) { - .test-media-query-ranges { - order: 11; - } -} - -@custom-media --dark-mode (prefers-color-scheme: dark); - -@media (--dark-mode) { - body { - background-color: black; - color: white; - } -} - -@custom-selector :--heading h1, h2, h3, h4, h5, h6, .heading-7; - -.test-custom-selectors:--heading { - order:12; -} - -.test-case-insensitive-attributes[frame=hsides i] { - order: 13; -} - -.test-rebeccapurple-color { - color: rebeccapurple; - order: 14; -} - -.test-hexadecimal-alpha-notation { - background-color: #f3f3f3f3; - color: #0003; - order: 15; -} - -.test-color-functional-notation { - color: rgb(70% 13.5% 13.5% / 50%); - order: 16; -} - -.test-lab-function { - background-color: lab(40% 56.6 39); - color: lch(40% 68.8 34.5 / 50%); - order: 17; -} - -.test-system-ui-font-family { - font-family: system-ui; - order: 18; -} - -.test-font-variant-property { - font-variant-caps: small-caps; - order: 19; -} - -.test-all-property { - all: initial; - order: 20; -} - -.test-matches-pseudo-class:matches(:first-child, .special) { - order: 21; -} - -.test-not-pseudo-class:not(:first-child, .special) { - order: 22; -} - -.test-any-link-pseudo-class:-moz-any-link { - order: 23; -} - -.test-any-link-pseudo-class:any-link { - order: 23; -} - -.test-dir-pseudo-class:dir(rtl) { - order: 24; -} - -.test-overflow-wrap-property { - order: 25; - overflow-wrap: break-word; -} - -.test-focus-visible-pseudo-class:focus-visible { - order: 26; -} - -.test-double-position-gradients { - background-image: conic-gradient(yellowgreen 40%, gold 0deg 75%, #f06 0deg); -} - -.test-blank-pseudo-class:blank { - background-color: yellow; -} - -.test-has-pseudo-class:has(.inner-class) { - background-color: yellow; -} - -:is(.a, .b):is(:focus, :hover) { - order: 27; -} - -:is(.a > .b) + :is(.c > .d) { - order: 28; -} - -.test-hwb-function { - background-color: hwb(194 0% 0% / .5); -} - -.test-opacity-percent { - opacity: 42%; -} - -.clamp-same-unit { - width: clamp(10px, 64px, 80px); -} - -.complex-clamp { - width: clamp(calc(100% - 10px), min(10px, 100%), max(40px, 4em)); -} - -.clamp-different-units { - width: clamp(10%, 2px, 4rem); -} - -.mixed-clamp { - grid-template-columns: clamp(22rem, 40%, 32rem) minmax(0, 1fr); - margin: clamp(1rem, 2%, 3rem) 4vh; -} - -.calc-clamp { - margin: 0 40px 0 calc(-1 * clamp(32px, 16vw, 64px)); -} - -.multiple-calc-clamp { - margin: calc(-1 * clamp(1px, 2vw, 3px)) calc(-1 * clamp(4px, 5vw, 6px)); -} - -.nested-clamp { - font-size: clamp(clamp(1rem, 2vw, 3rem), 4vw, 5rem); -} - -@font-face { - font-family: 'A'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: url(a) format(woff2); -} - -.block-flow { - display: block flow; -} - -.block-flow-root { - display: block flow-root; -} - -.inline-flow { - display: inline flow; -} - -.inline-flow-root { - display: inline flow-root; -} - -.run-in-flow { - display: run-in flow; -} - -.list-item-block-flow { - display: list-item block flow; -} - -.inline-flow-list-item { - display: inline flow list-item; -} - -.block-flex { - display: block flex; -} - -.inline-flex { - display: inline flex; -} - -.block-grid { - display: block grid; -} - -.inline-grid { - display: inline grid; -} - -.inline-ruby { - display: inline ruby; -} - -.block-table { - display: block table; -} - -.inline-table { - display: inline table; -} - -.table-cell-flow { - display: table-cell flow; -} - -.table-caption-flow { - display: table-caption flow; -} - -.ruby-base-flow { - display: ruby-base flow; -} - -.ruby-text-flow { - display: ruby-text flow; -} - -.logical-float { - float: inline-start; -} - -.color-function { - prop-1: color(display-p3 0.00000 0.51872 0.36985); - prop-2: 'color(display-p3 0.02472 0.01150 0.00574 / 1)'; - prop-3: color(display-p3 0.02472 0.01150 0.00574 / 1); - prop-4: color(display-p3 0.02472 0.01150 0.00574 / calc(33 / 22)); - prop-5: color(display-p3 1 1 1 1); -} - -.oklab { - color-1: oklab(40% 0.001236 0.0039); - color-2: oklab(40% 0.1236 0.0039 / 1); - color-3: oklab(40% 0.1236 0.0039 / .5); - color-4: oklab(40% 0.1236 0.0039 / 100%); - color-5: oklab(40% 0.1236 0.0039 / 50%); - color-6: oklab(60% 0.1 0); - color-7: oklab(60% 0.1 0 foo); - color-8: oklab(40.101% 0.1147 0.0453); - color-9: oklab(59.686% 0.1009 0.1192); - color-10: oklab(65.125% -0.0320 0.1274); - color-11: oklab(66.016% -0.1084 0.1114); - color-12: oklab(72.322% -0.0465 -0.1150); -} - -.oklch { - color-1: oklch(40% 0.1268735435 34.568626); - color-2: oklch(40% 0.1268735435 34.568626 / 1); - color-3: oklch(40% 0.1268735435 34.568626 / .5); - color-4: oklch(40% 0.1268735435 34.568626 / 100%); - color-5: oklch(40% 0.1268735435 34.568626 / 50%); - color-6: oklch(60% 0.150 0); - - color-7: oklch(60% 0.1250 180); - color-8: oklch(60% 0.1250 180deg); - color-9: oklch(60% 0.1250 0.5turn); - color-10: oklch(60% 0.1250 200grad); - color-11: oklch(60% 0.1250 3.14159rad); - - color-12: oklch(60% 0.1250 45); - color-13: oklch(60% 0.1250 45deg); - color-14: oklch(60% 0.1250 0.125turn); - color-15: oklch(60% 0.1250 50grad); - color-16: oklch(60% 0.1250 0.785398rad); - color-17: oklch(60% 0.1250 0.785398unknown); -} - -.ic-unit { - --value-2ic: initial; - text-indent: 2ic; - content: var(--value-2ic); - left: var(--non-existing, 2ic); - width: calc(8ic + 20px); - height: 10px; - margin: 0.5ic 1ic .2ic; - padding: 2 ic; -} - -.unset { - clip: unset; -} - -.mod { - padding: 8px mod(18px, 5px) 1px calc(mod(15px, 6px) + 50%); - transform: rotate(mod(-140deg, -90deg)); - width: mod(mod(-18px, 5px), 5px); -} - -.rem { - padding: 8px rem(18px, 5px) 1px calc(rem(15px, 6px) + 50%); - transform: rotate(rem(-140deg, -90deg)); -} - -.round { - top: round(2.5px, 1px); - right: round(nearest, 2.5px, 1px); - bottom: round(up, 2.5px, 1px); - left: round(down, 2.5px, 1px); - padding-left: round(to-zero, 2.5px, 1px); -} - -.trigonometric { - left: sin(45deg); - left: cos(45deg); - left: tan(45deg); - left: asin(0.5); - left: acos(0.5); - left: atan(10); - left: atan2(-1, 1); - left: asin(sin(pi / 2)); - left: atan2(infinity, -infinity); - left: sin((1deg * 3) + .25turn); -} - -.trigonometric-ignore-not-a-function { - left: sin; - left: cos; - left: tan; - left: asin; - left: acos; - left: atan; - left: atan2; -} - -.trigonometric-ignore-no-arguments { - left: sin(); - left: cos(); - left: tan(); - left: asin(); - left: acos(); - left: atan(); - left: atan2(); -} - -@custom-selector :--view-m [data-view-size=m]; - -:--view-m .view { - background: red; - } - -.nested-calc { - order: calc(1 * calc(8 / 3 + calc(5 * 10))); -} - -.text-decoration-shorthand { - -webkit-text-decoration: 3px wavy pink overline; - text-decoration: 3px wavy pink overline; -} - -.stage__container { - inset-inline-start: var(--size, 1rem); -} - -:scope { - content: "plain :scope"; -} - -@scope (.foo) { - :scope { - content: ":scope in @scope"; - } -} - -:scope { - @scope (.foo) { - content: ":scope in @scope, but with nesting"; - } -} - -@media (min-aspect-ratio: 1.77) { - /* media query aspect ratio : */ -} - -.color-mix { - color-1: color-mix(in srgb, rgb(255 0 0 / 0), blue 65%); - color-2: color-mix(in lab, rgb(255 0 0 / 0), blue 65%); - color-3: color-mix(in xyz, rgb(255 0 0 / 0), blue 65%); - color-4: color-mix(in oklch, rgb(255 0 0 / 0), blue 65%); - color-5: color-mix(in lch, rgb(255 0 0 / 0), blue 65%); - color-6: color-mix(in hsl, rgb(255 0 0 / 0), blue 65%); -} - -.gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); -} - -.test-css-color-5-interop { - color-1: color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / alpha); - color-2: color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / none); - color-3: color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g b); - color-4: color(from color(prophoto-rgb 0.7 0.5 0.3) prophoto-rgb r g none); - color-5: hwb(from hwb(50deg 20% 30%) h w b); - color-6: lab(from lab(40% 56.6 39) l a b); - color-7: lch(from lch(40% 56.6 39) l c h); - color-8: oklab(from oklab(40% 0.566 0.39) l a b); - color-9: oklch(from oklch(40% 0.566 39deg) l c h); -} - -.test-property-with-var { - --opacity: 1; - color: rgba(87 107 149 / var(--opacity)); -} - -.exponential-functions { - width: calc(1px * pow(2, 3)); -} - -.out-of-gamut { - --color: color(display-p3 0 1 0); -} - -.issue-1244--a { - background-image: -ms-linear-gradient(180deg, red 0%, blue 100%); -} - -.issue-1244--b { - background-image: linear-gradient(180deg, red 0%, blue 100%); -} - -.issue-1244--c { - background-image: linear-gradient(180deg, red 0%, blue 100%); -} diff --git a/plugin-packs/postcss-preset-env/test/basic.nesting.true.expect.css b/plugin-packs/postcss-preset-env/test/basic.nesting.true.expect.css index 0fe1b5e6c..cdff486ff 100644 --- a/plugin-packs/postcss-preset-env/test/basic.nesting.true.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.nesting.true.expect.css @@ -48,7 +48,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +:is(.test-nesting-rules,#test-is-pseudo) + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.op_mini.expect.css b/plugin-packs/postcss-preset-env/test/basic.op_mini.expect.css index 9e113c553..c952d8f73 100644 --- a/plugin-packs/postcss-preset-env/test/basic.op_mini.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.op_mini.expect.css @@ -58,7 +58,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css index d67ebbbae..766cdf248 100644 --- a/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css @@ -87,7 +87,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { -webkit-box-ordinal-group: 9; -webkit-order: 8; -moz-box-ordinal-group: 9; diff --git a/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css b/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css index ed4337b37..fd8474c8a 100644 --- a/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css @@ -102,7 +102,14 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { + -webkit-box-ordinal-group: 9; + -webkit-order: 8; + -moz-box-ordinal-group: 9; + order: 8; + } + +:is(.test-nesting-rules,#test-is-pseudo) + p { -webkit-box-ordinal-group: 9; -webkit-order: 8; -moz-box-ordinal-group: 9; diff --git a/plugin-packs/postcss-preset-env/test/basic.stage0-ff49.expect.css b/plugin-packs/postcss-preset-env/test/basic.stage0-ff49.expect.css index 47534b483..2d5eccb3f 100644 --- a/plugin-packs/postcss-preset-env/test/basic.stage0-ff49.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.stage0-ff49.expect.css @@ -57,7 +57,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.stage0-ff66.expect.css b/plugin-packs/postcss-preset-env/test/basic.stage0-ff66.expect.css index 553a8b1ac..2ca8ba813 100644 --- a/plugin-packs/postcss-preset-env/test/basic.stage0-ff66.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.stage0-ff66.expect.css @@ -56,7 +56,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css b/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css index f159105cf..fa8a1ea50 100644 --- a/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css @@ -59,7 +59,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.vendors-1.expect.css b/plugin-packs/postcss-preset-env/test/basic.vendors-1.expect.css index efd955537..97ada6490 100644 --- a/plugin-packs/postcss-preset-env/test/basic.vendors-1.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.vendors-1.expect.css @@ -59,7 +59,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.vendors-2.expect.css b/plugin-packs/postcss-preset-env/test/basic.vendors-2.expect.css index efd955537..97ada6490 100644 --- a/plugin-packs/postcss-preset-env/test/basic.vendors-2.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.vendors-2.expect.css @@ -59,7 +59,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/basic.vendors-3.expect.css b/plugin-packs/postcss-preset-env/test/basic.vendors-3.expect.css index ebec60e6a..f610bda0d 100644 --- a/plugin-packs/postcss-preset-env/test/basic.vendors-3.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.vendors-3.expect.css @@ -59,7 +59,7 @@ order: 9; } -.test-nesting-rules + p, #test-is-pseudo + p { +.test-nesting-rules:not(#does-not-exist) + p,#test-is-pseudo + p { order: 8; } diff --git a/plugin-packs/postcss-preset-env/test/layers-basic.expect.css b/plugin-packs/postcss-preset-env/test/layers-basic.expect.css index 02b774efe..3376f9052 100644 --- a/plugin-packs/postcss-preset-env/test/layers-basic.expect.css +++ b/plugin-packs/postcss-preset-env/test/layers-basic.expect.css @@ -97,7 +97,7 @@ order: 9; } -.test-nesting-rules:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) + p, #test-is-pseudo:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) + p { +.test-nesting-rules:not(#does-not-exist):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) + p,#test-is-pseudo:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) + p { -webkit-box-ordinal-group: 9; -webkit-order: 8; -moz-box-ordinal-group: 9; diff --git a/plugin-packs/postcss-preset-env/test/layers-basic.preserve.true.expect.css b/plugin-packs/postcss-preset-env/test/layers-basic.preserve.true.expect.css index c94bb05ff..9aa4771bd 100644 --- a/plugin-packs/postcss-preset-env/test/layers-basic.preserve.true.expect.css +++ b/plugin-packs/postcss-preset-env/test/layers-basic.preserve.true.expect.css @@ -11,6 +11,14 @@ order: 5.1; } + :is(.test-nesting-rules p):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { + is-layer: C_D; + -webkit-box-ordinal-group: 6; + -webkit-order: 5.1; + -moz-box-ordinal-group: 6; + order: 5.1; + } + :root:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { is-layer: C; --order: 1; @@ -106,7 +114,14 @@ order: 9; } -.test-nesting-rules:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) + p, #test-is-pseudo:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) + p { +.test-nesting-rules:not(#does-not-exist):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) + p,#test-is-pseudo:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) + p { + -webkit-box-ordinal-group: 9; + -webkit-order: 8; + -moz-box-ordinal-group: 9; + order: 8; + } + +:is(.test-nesting-rules,#test-is-pseudo):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) + p { -webkit-box-ordinal-group: 9; -webkit-order: 8; -moz-box-ordinal-group: 9; diff --git a/plugins/css-has-pseudo/test/plugin-order-nesting.after.expect.css b/plugins/css-has-pseudo/test/plugin-order-nesting.after.expect.css index ee5b192d5..4226a2ca3 100644 --- a/plugins/css-has-pseudo/test/plugin-order-nesting.after.expect.css +++ b/plugins/css-has-pseudo/test/plugin-order-nesting.after.expect.css @@ -3,10 +3,10 @@ order: 1; } -.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-1q-w-2x-31-2v-15-1m-2u-33-2r-39-37]:not(does-not-exist):not(does-not-exist) { +.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-w-1q-w-2x-31-2v-15-1m-2u-33-2r-39-37]:not(does-not-exist):not(does-not-exist) { order: 2; } -.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-1q-w-2x-31-2v-15-w-1m-2w-2p-37-14-1q-w-1a-37-33-31-2t-15]:not(does-not-exist):not(does-not-exist) { +.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-w-1q-w-2x-31-2v-15-w-1m-2w-2p-37-14-w-1q-w-1a-37-33-31-2t-15]:not(does-not-exist):not(does-not-exist) { order: 3; } diff --git a/plugins/css-has-pseudo/test/plugin-order-nesting.after.preserve.expect.css b/plugins/css-has-pseudo/test/plugin-order-nesting.after.preserve.expect.css index d1e585c5e..c3d9e159d 100644 --- a/plugins/css-has-pseudo/test/plugin-order-nesting.after.preserve.expect.css +++ b/plugins/css-has-pseudo/test/plugin-order-nesting.after.preserve.expect.css @@ -7,18 +7,18 @@ a:has(.b) { order: 1; } -.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-1q-w-2x-31-2v-15-1m-2u-33-2r-39-37]:not(does-not-exist):not(does-not-exist) { +.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-w-1q-w-2x-31-2v-15-1m-2u-33-2r-39-37]:not(does-not-exist):not(does-not-exist) { order: 2; } -a:has(> img):focus { +a:has( > img):focus { order: 2; } -.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-1q-w-2x-31-2v-15-w-1m-2w-2p-37-14-1q-w-1a-37-33-31-2t-15]:not(does-not-exist):not(does-not-exist) { +.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-w-1q-w-2x-31-2v-15-w-1m-2w-2p-37-14-w-1q-w-1a-37-33-31-2t-15]:not(does-not-exist):not(does-not-exist) { order: 3; } -a:has(> img) :has(> .some) { +a:has( > img) :has( > .some) { order: 3; } diff --git a/plugins/css-has-pseudo/test/plugin-order-nesting.before.expect.css b/plugins/css-has-pseudo/test/plugin-order-nesting.before.expect.css index ee5b192d5..4226a2ca3 100644 --- a/plugins/css-has-pseudo/test/plugin-order-nesting.before.expect.css +++ b/plugins/css-has-pseudo/test/plugin-order-nesting.before.expect.css @@ -3,10 +3,10 @@ order: 1; } -.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-1q-w-2x-31-2v-15-1m-2u-33-2r-39-37]:not(does-not-exist):not(does-not-exist) { +.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-w-1q-w-2x-31-2v-15-1m-2u-33-2r-39-37]:not(does-not-exist):not(does-not-exist) { order: 2; } -.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-1q-w-2x-31-2v-15-w-1m-2w-2p-37-14-1q-w-1a-37-33-31-2t-15]:not(does-not-exist):not(does-not-exist) { +.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-w-1q-w-2x-31-2v-15-w-1m-2w-2p-37-14-w-1q-w-1a-37-33-31-2t-15]:not(does-not-exist):not(does-not-exist) { order: 3; } diff --git a/plugins/css-has-pseudo/test/plugin-order-nesting.before.preserve.expect.css b/plugins/css-has-pseudo/test/plugin-order-nesting.before.preserve.expect.css index d1e585c5e..c3d9e159d 100644 --- a/plugins/css-has-pseudo/test/plugin-order-nesting.before.preserve.expect.css +++ b/plugins/css-has-pseudo/test/plugin-order-nesting.before.preserve.expect.css @@ -7,18 +7,18 @@ a:has(.b) { order: 1; } -.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-1q-w-2x-31-2v-15-1m-2u-33-2r-39-37]:not(does-not-exist):not(does-not-exist) { +.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-w-1q-w-2x-31-2v-15-1m-2u-33-2r-39-37]:not(does-not-exist):not(does-not-exist) { order: 2; } -a:has(> img):focus { +a:has( > img):focus { order: 2; } -.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-1q-w-2x-31-2v-15-w-1m-2w-2p-37-14-1q-w-1a-37-33-31-2t-15]:not(does-not-exist):not(does-not-exist) { +.js-has-pseudo [csstools-has-2p-1m-2w-2p-37-14-w-1q-w-2x-31-2v-15-w-1m-2w-2p-37-14-w-1q-w-1a-37-33-31-2t-15]:not(does-not-exist):not(does-not-exist) { order: 3; } -a:has(> img) :has(> .some) { +a:has( > img) :has( > .some) { order: 3; } diff --git a/plugins/postcss-nesting/README.md b/plugins/postcss-nesting/README.md index e6b538459..0b81a80f6 100644 --- a/plugins/postcss-nesting/README.md +++ b/plugins/postcss-nesting/README.md @@ -36,7 +36,7 @@ you might want to use [PostCSS Nested] instead. .foo:hover { color: green; } -.foo > .bar { +.foo > .bar { color: blue; } @media (prefers-color-scheme: dark) { @@ -81,123 +81,10 @@ instructions for: Previous iterations of the [CSS Nesting specification] required using `@nest` for certain selectors. `@nest` was removed from the specification completely. -Future versions of this plugin will error if you use `@nest`. We advice everyone to migrate their codebase **now** to nested CSS without `@nest`. We published a [Stylelint Plugin](https://github.com/csstools/postcss-plugins/tree/main/plugins-stylelint/no-at-nest-rule#csstoolsstylelint-no-at-nest-rule) to help you migrate. -example warning: -> `@nest` was removed from the CSS Nesting specification and will be removed from PostCSS Nesting in the next major version. -> Change `@nest foo & {}` to `foo & {}` to migrate to the latest standard. - -You can silence this warning with a new `silenceAtNestWarning` plugin option. - -```js -postcssNesting({ - silenceAtNestWarning: true -}) -``` - -## Options - -### noIsPseudoSelector - -#### Specificity - -Before : - -```css -#alpha, -.beta { - &:hover { - order: 1; - } -} -``` - -After **without** the option : - -```js -postcssNesting() -``` - -```css -:is(#alpha,.beta):hover { - order: 1; -} -``` - -_`.beta:hover` has specificity as if `.beta` where an id selector, matching the specification._ - -[specificity: 1, 1, 0](https://polypane.app/css-specificity-calculator/#selector=%3Ais(%23alpha%2C.beta)%3Ahover) - -After **with** the option : - -```js -postcssNesting({ - noIsPseudoSelector: true -}) -``` - -```css -#alpha:hover, .beta:hover { - order: 1; -} -``` - -_`.beta:hover` has specificity as if `.beta` where a class selector, conflicting with the specification._ - -[specificity: 0, 2, 0](https://polypane.app/css-specificity-calculator/#selector=.beta%3Ahover) - - -#### Complex selectors - -Before : - -```css -.alpha > .beta { - & + & { - order: 2; - } -} -``` - -After **without** the option : - -```js -postcssNesting() -``` - -```css -:is(.alpha > .beta) + :is(.alpha > .beta) { - order: 2; -} -``` - -After **with** the option : - -```js -postcssNesting({ - noIsPseudoSelector: true -}) -``` - -```css -.alpha > .beta + .alpha > .beta { - order: 2; -} -``` - -_this is a different selector than expected as `.beta + .alpha` matches `.beta` followed by `.alpha`._
-_avoid these cases when you disable `:is()`_
-_writing the selector without nesting is advised here_ - -```css -/* without nesting */ -.alpha > .beta + .beta { - order: 2; -} -``` [cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test [css-url]: https://cssdb.org/#nesting-rules diff --git a/plugins/postcss-nesting/dist/index.cjs b/plugins/postcss-nesting/dist/index.cjs index 2990b02ab..a64ccb287 100644 --- a/plugins/postcss-nesting/dist/index.cjs +++ b/plugins/postcss-nesting/dist/index.cjs @@ -1 +1 @@ -"use strict";var e=require("postcss-selector-parser"),t=require("@csstools/selector-specificity");const n=e.pseudo({value:":is"});function sortCompoundSelectorsInsideComplexSelector(t){if(!t||!t.nodes)return;const r=[];let o=[];for(let s=0;s"tag"===e.type))){const r=n.clone({}),o=t.nodes[s];o.replaceWith(r),r.append(e.selector({nodes:[o],value:void 0}))}o.push(t.nodes[s])}else r.push(o),r.push([t.nodes[s]]),o=[];r.push(o);const s=[];for(let e=0;e"selector"===e.type&&"selector"===t.type&&e.nodes.length&&t.nodes.length?selectorTypeOrder(e.nodes[0])-selectorTypeOrder(t.nodes[0]):"selector"===e.type&&e.nodes.length?selectorTypeOrder(e.nodes[0])-selectorTypeOrder(t):"selector"===t.type&&t.nodes.length?selectorTypeOrder(e)-selectorTypeOrder(t.nodes[0]):selectorTypeOrder(e)-selectorTypeOrder(t)));for(let e=0;e=0;e--)s[e].remove(),t.prepend(s[e])}function selectorTypeOrder(t){return e.isPseudoElement(t)?r.pseudoElement:r[t.type]}const r={universal:0,tag:1,pseudoElement:2,id:3,class:4,attribute:5,pseudo:6,selector:7,string:8,root:9,comment:10};function ampersandToScope(t,n){let r,o=t.parent;for(;o;){if("rule"===o.type)return;o=o.parent}try{r=e().astSync(t.selector)}catch(e){return void t.warn(n,`Failed to parse selector : "${t.selector}" with message: "${e instanceof Error?e.message:e}"`)}r&&(r.walkNesting((t=>{const n=t.parent;t.replaceWith(e.pseudo({value:":scope"})),n&&sortCompoundSelectorsInsideComplexSelector(n)})),t.selector=r.toString())}function cleanupParent(e){if(!e.nodes.length)return void e.remove();const t=e.nodes.filter((e=>"comment"===e.type));t.length===e.nodes.length&&e.replaceWith(...t)}function shiftNodesBeforeParent(e,t){const n=t.index(e);if(n){const e=t.cloneBefore().removeAll().append(t.nodes.slice(0,n));e.raws.semicolon=!0,cleanupParent(e)}t.before(e),t.raws.semicolon=!0}function combinationsWithSizeN(e,t){if(t<2)throw new Error("n must be greater than 1");if(e.length<2)throw new Error("s must be greater than 1");if(Math.pow(e.length,t)>1e4)throw new Error("Too many combinations when trying to resolve a nested selector with lists, reduce the complexity of your selectors");const n=[];for(let e=0;e=0;s--){let t=n[s];if(t>=e.length){if(t=0,n[s]=0,0===s)return r;n[s-1]+=1}o[s]=e[t]}r.push(o),n[n.length-1]++}}function nodesAreEquallySpecific(n){const r=n.map((t=>e().astSync(t))).map((e=>t.selectorSpecificity(e))),o=r[0];for(let e=1;ee().astSync(t))):[e().astSync(`:is(${t.join(",")})`)];const s=[];for(let t=0;t{"nesting"===e.type&&(n=!0)}));const r=t.nodes[0];let o=!1;r.each((e=>"combinator"===e.type&&(o=!0,!1))),n?o&&r.insertBefore(r.at(0),e.nesting({})):(r.insertBefore(r.at(0),e.combinator({value:" "})),r.insertBefore(r.at(0),e.nesting({}))),l=t.toString()}let c=[],a=0;if(e().astSync(l).walkNesting((()=>{a++})),a>1&&o.length>1)c=combinationsWithSizeN(o,a),i=c.length;else{i=o.length;for(let e=0;e{if("nesting"!==o.type)return;let s=c[t][n];n++,"root"===s.type&&1===s.nodes.length&&(s=s.nodes[0]);const i=e().astSync(`:is(${s.toString()})`),l=isSimpleSelector(s.nodes[0]),a=isCompoundSelector(s.nodes[0]),u=isSimpleSelector(o),p=isCompoundSelector(o);if(l&&u)return void o.replaceWith(s.clone());if((l||a)&&(u||p)){const e=o.parent;return l&&"selector"===s.type?o.replaceWith(s.clone().nodes[0]):o.replaceWith(...s.clone().nodes),void(e&&e.nodes.length>1&&sortCompoundSelectorsInsideComplexSelector(e))}if(l){const e=o.parent;return o.replaceWith(s.clone().nodes[0]),void(e&&sortCompoundSelectorsInsideComplexSelector(e))}if(a){const e=o.parent;return o.replaceWith(...s.clone().nodes),void(e&&sortCompoundSelectorsInsideComplexSelector(e))}if(nestingIsFirstAndOnlyInSelectorWithEitherSpaceOrChildCombinator(o)){const e=o.parent;return o.replaceWith(...s.clone().nodes),void(e&&sortCompoundSelectorsInsideComplexSelector(e))}if(nestingIsNotInsideCompoundSelector(o)){const e=o.parent;return o.replaceWith(...s.clone().nodes),void(e&&sortCompoundSelectorsInsideComplexSelector(e))}const d=o.parent;r.noIsPseudoSelector?o.replaceWith(...s.clone().nodes):o.replaceWith(...i.clone({}).nodes),d&&sortCompoundSelectorsInsideComplexSelector(d)})),s.push(o.toString())}}return s}function isSimpleSelector(e){return"combinator"!==e.type&&!(e.parent&&e.parent.nodes.length>1)}function isCompoundSelector(e,t=null){if(isSimpleSelector(e))return!1;if(!e.parent)return!1;if(!!e.parent.nodes.find((e=>"combinator"===e.type)))return!1;return!(!!e.parent.nodes.find((e=>"nesting"===e.type))&&t&&!isCompoundSelector(t))}function nestingIsFirstAndOnlyInSelectorWithEitherSpaceOrChildCombinator(e){if(!e.parent)return!1;if(0!==e.parent.nodes.indexOf(e))return!1;for(let t=1;t"!==e.parent.nodes[t].value)return!1;return!0}function nestingIsNotInsideCompoundSelector(e){if(isSimpleSelector(e))return!0;if(!e.parent)return!1;for(let t=0;t{if("decl"===n.type)return t===r-1?void(t=r):(n.remove(),e.insertAfter(t,n),void(t=e.index(n)));if("atrule"===n.type&&"mixin"===n.name.toLowerCase()){let o=n.prev();for(;o;){if("rule"===o.type||"atrule"===o.type)return;o=o.prev()}return t===r-1?void(t=r):(n.remove(),e.insertAfter(t,n),void(t=e.index(n)))}if("comment"===n.type){const o=n.next();if(o&&("comment"===o.type||"rule"===o.type||"atrule"===o.type&&"mixin"!==o.name.toLowerCase()))return;return t===r-1?void(t=r):(n.remove(),e.insertAfter(t,n),void(t=e.index(n)))}}))}function transformRuleWithinRule(e,t,n,r){let o=[];try{o=mergeSelectors(t.selectors,e.selectors,r)}catch(r){return void e.warn(n,`Failed to parse selectors : "${t.selector}" / "${e.selector}" with message: "${r instanceof Error?r.message:r}"`)}if(!o.length)return;groupDeclarations(t),shiftNodesBeforeParent(e,t),e.selectors=o;"rule"===e.type&&"rule"===t.type&&e.selector===t.selector&&e.append(...t.nodes),cleanupParent(t)}function isValidRuleWithinRule(e){return e.selectors.every((e=>-1===e.indexOf("|")))}function comma(e){const t=[];let n="",r=!1,o=0,s=!1,i=!1;for(const l of e)i?i=!1:"\\"===l?i=!0:s?l===s&&(s=!1):'"'===l||"'"===l?s=l:"("===l?o+=1:")"===l?o>0&&(o-=1):0===o&&","===l&&(r=!0),r?(""!==n&&t.push(n.trim()),n="",r=!1):n+=l;return t.push(n.trim()),t}function transformNestRuleWithinRule(e,t,n,r,o){let s=[];try{s=mergeSelectors(t.selectors,comma(e.params),o)}catch(r){return void e.warn(n,`Failed to parse selectors : "${t.selector}" / "${e.params}" with message: "${r instanceof Error?r.message:r}"`)}if(!s.length)return;shiftNodesBeforeParent(e,t);const i=t.clone().removeAll().append(e.nodes);i.raws.semicolon=!0,i.selectors=s,e.replaceWith(i),cleanupParent(t),r(i,n,o)}function isValidNestRuleWithinRule(e){return comma(e.params).every((e=>e.split("&").length>=2&&-1===e.indexOf("|")))}var o=["container","document","media","supports","layer","starting-style"];function atruleWithinRule(e,t,n,r,o){if(groupDeclarations(t),shiftNodesBeforeParent(e,t),e.nodes){const s=t.clone().removeAll().append(e.nodes);e.append(s),cleanupParent(t),r(s,n,o)}else cleanupParent(t)}function isAtruleWithinRule(e){return o.includes(e.name)}function transformAtruleWithinAtrule(e,t){var n,r;groupDeclarations(t),shiftNodesBeforeParent(e,t),e.params=(n=t.params,r=e.params,comma(n).map((e=>comma(r).map((t=>`${e} and ${t}`)).join(", "))).join(", ")),cleanupParent(t)}function isAtruleWithinAtrule(e,t){return o.includes(e.name)&&e.name===t.name}function isAtRule(e){return e&&"atrule"===e.type}function isNestRule(e){return e&&isAtRule(e)&&"nest"===e.name}function isRule(e){return e&&"rule"===e.type}function walk(e,t,n){e.each((r=>{const o=r.parent;isNestRule(r)&&!n.silenceAtNestWarning&&e.warn(t,`\`@nest\` was removed from the CSS Nesting specification and will be removed from PostCSS Nesting in the next major version.\nChange \`@nest ${r.params} {}\` to \`${r.params} {}\` to migrate to the latest standard.`),isRule(r)&&isRule(o)&&isValidRuleWithinRule(r)?transformRuleWithinRule(r,o,t,n):isNestRule(r)&&isRule(o)&&isValidNestRuleWithinRule(r)?transformNestRuleWithinRule(r,o,t,walk,n):isAtRule(r)&&isRule(o)&&isAtruleWithinRule(r)?atruleWithinRule(r,o,t,walk,n):isAtRule(r)&&isAtRule(o)&&isAtruleWithinAtrule(r,o)&&transformAtruleWithinAtrule(r,o),"nodes"in r&&r.nodes.length&&walk(r,t,n)}))}const creator=e=>{const t=Object.assign({noIsPseudoSelector:!1,silenceAtNestWarning:!1},e);return{postcssPlugin:"postcss-nesting",Rule(e,{result:n}){walk(e,n,t),e.selector.includes("&")&&ersandToScope(e,n)}}};creator.postcss=!0,module.exports=creator; +"use strict";var e=require("postcss-selector-parser"),t=require("@csstools/selector-resolve-nested");function ampersandToScope(t,r){let n,o=t.parent;for(;o;){if("rule"===o.type)return;o=o.parent}try{n=e().astSync(t.selector)}catch(e){return void t.warn(r,`Failed to parse selector : "${t.selector}" with message: "${e instanceof Error?e.message:e}"`)}n&&(n.walkNesting((t=>{t.replaceWith(e.pseudo({value:":scope"}))})),t.selector=n.toString())}function cleanupParent(e){if(!e.nodes.length)return void e.remove();const t=e.nodes.filter((e=>"comment"===e.type));t.length===e.nodes.length&&e.replaceWith(...t)}function groupDeclarations(e){let t=-1;e.each(((r,n)=>{if("decl"===r.type)return t===n-1?void(t=n):(r.remove(),e.insertAfter(t,r),void(t=e.index(r)));if("atrule"===r.type&&"mixin"===r.name.toLowerCase()){let o=r.prev();for(;o;){if("rule"===o.type||"atrule"===o.type)return;o=o.prev()}return t===n-1?void(t=n):(r.remove(),e.insertAfter(t,r),void(t=e.index(r)))}if("comment"===r.type){const o=r.next();if(o&&("comment"===o.type||"rule"===o.type||"atrule"===o.type&&"mixin"!==o.name.toLowerCase()))return;return t===n-1?void(t=n):(r.remove(),e.insertAfter(t,r),void(t=e.index(r)))}}))}const r=e();function mergeSelectors(e,n,o,s){let i;try{i=t.resolveNestedSelector(r.astSync(n),r.astSync(o))}catch(t){return e.warn(s,`Failed to parse selectors : "${o}" / "${n}" with message: "${t instanceof Error?t.message:t}"`),!1}return!!i&&i.toString()}function shiftNodesBeforeParent(e,t){const r=t.index(e);if(r){const e=t.cloneBefore().removeAll().append(t.nodes.slice(0,r));e.raws.semicolon=!0,cleanupParent(e)}t.before(e),t.raws.semicolon=!0}function transformRuleWithinRule(e,t,r){const n=mergeSelectors(e,e.selector,t.selector,r);if(!n)return;groupDeclarations(t),shiftNodesBeforeParent(e,t),e.selector=n;"rule"===e.type&&"rule"===t.type&&e.selector===t.selector&&e.append(...t.nodes),cleanupParent(t)}function isValidRuleWithinRule(e){return e.selectors.every((e=>-1===e.indexOf("|")))}var n=["container","document","media","supports","layer","starting-style"];function atruleWithinRule(e,t,r,n){if(groupDeclarations(t),shiftNodesBeforeParent(e,t),e.nodes){const o=t.clone().removeAll().append(e.nodes),s=mergeSelectors(e,"&",t.selector,r);s&&(o.selector=s),e.append(o),cleanupParent(t),n(o,r)}else cleanupParent(t)}function isAtruleWithinRule(e){return n.includes(e.name)}function comma(e){const t=[];let r="",n=!1,o=0,s=!1,i=!1;for(const l of e)i?i=!1:"\\"===l?i=!0:s?l===s&&(s=!1):'"'===l||"'"===l?s=l:"("===l?o+=1:")"===l?o>0&&(o-=1):0===o&&","===l&&(n=!0),n?(""!==r&&t.push(r.trim()),r="",n=!1):r+=l;return t.push(r.trim()),t}function transformAtruleWithinAtrule(e,t){var r,n;groupDeclarations(t),shiftNodesBeforeParent(e,t),e.params=(r=t.params,n=e.params,comma(r).map((e=>comma(n).map((t=>`${e} and ${t}`)).join(", "))).join(", ")),cleanupParent(t)}function isAtruleWithinAtrule(e,t){return n.includes(e.name)&&e.name===t.name}function isAtRule(e){return e&&"atrule"===e.type}function isRule(e){return e&&"rule"===e.type}function walk(e,t){e.each((e=>{const r=e.parent;isRule(e)&&isRule(r)&&isValidRuleWithinRule(e)?transformRuleWithinRule(e,r,t):isAtRule(e)&&isRule(r)&&isAtruleWithinRule(e)?atruleWithinRule(e,r,t,walk):isAtRule(e)&&isAtRule(r)&&isAtruleWithinAtrule(e,r)&&transformAtruleWithinAtrule(e,r),"nodes"in e&&e.nodes.length&&walk(e,t)}))}const creator=e=>{if(Object.assign({noIsPseudoSelector:!1},e).noIsPseudoSelector)throw new Error("The `noIsPseudoSelector` option is no longer supported. Migrate your CSS to use the latest CSS nesting syntax.");return{postcssPlugin:"postcss-nesting",Rule(e,{result:t}){walk(e,t),e.selector.includes("&")&&ersandToScope(e,t)},AtRule:{nest(e){throw e.error(`\`@nest\` was removed from the CSS Nesting specification and will be removed from PostCSS Nesting in the next major version.\nChange \`@nest ${e.params} {}\` to \`${e.params} {}\` to migrate to the latest standard.`)}}}};creator.postcss=!0,module.exports=creator; diff --git a/plugins/postcss-nesting/dist/index.d.ts b/plugins/postcss-nesting/dist/index.d.ts index c441b4179..4cc0fef90 100644 --- a/plugins/postcss-nesting/dist/index.d.ts +++ b/plugins/postcss-nesting/dist/index.d.ts @@ -5,10 +5,8 @@ export default creator; /** postcss-nesting plugin options */ export declare type pluginOptions = { - /** Avoid the `:is()` pseudo class as much as possible. default: false */ + /** This option was removed. You must migrate your CSS to the latest speciation to continue using this plugin. */ noIsPseudoSelector?: boolean; - /** Silence the `@nest` warning. */ - silenceAtNestWarning?: boolean; }; export { } diff --git a/plugins/postcss-nesting/dist/index.mjs b/plugins/postcss-nesting/dist/index.mjs index 593ade047..ab0db2707 100644 --- a/plugins/postcss-nesting/dist/index.mjs +++ b/plugins/postcss-nesting/dist/index.mjs @@ -1 +1 @@ -import e from"postcss-selector-parser";import{selectorSpecificity as t}from"@csstools/selector-specificity";const n=e.pseudo({value:":is"});function sortCompoundSelectorsInsideComplexSelector(t){if(!t||!t.nodes)return;const r=[];let o=[];for(let s=0;s"tag"===e.type))){const r=n.clone({}),o=t.nodes[s];o.replaceWith(r),r.append(e.selector({nodes:[o],value:void 0}))}o.push(t.nodes[s])}else r.push(o),r.push([t.nodes[s]]),o=[];r.push(o);const s=[];for(let e=0;e"selector"===e.type&&"selector"===t.type&&e.nodes.length&&t.nodes.length?selectorTypeOrder(e.nodes[0])-selectorTypeOrder(t.nodes[0]):"selector"===e.type&&e.nodes.length?selectorTypeOrder(e.nodes[0])-selectorTypeOrder(t):"selector"===t.type&&t.nodes.length?selectorTypeOrder(e)-selectorTypeOrder(t.nodes[0]):selectorTypeOrder(e)-selectorTypeOrder(t)));for(let e=0;e=0;e--)s[e].remove(),t.prepend(s[e])}function selectorTypeOrder(t){return e.isPseudoElement(t)?r.pseudoElement:r[t.type]}const r={universal:0,tag:1,pseudoElement:2,id:3,class:4,attribute:5,pseudo:6,selector:7,string:8,root:9,comment:10};function ampersandToScope(t,n){let r,o=t.parent;for(;o;){if("rule"===o.type)return;o=o.parent}try{r=e().astSync(t.selector)}catch(e){return void t.warn(n,`Failed to parse selector : "${t.selector}" with message: "${e instanceof Error?e.message:e}"`)}r&&(r.walkNesting((t=>{const n=t.parent;t.replaceWith(e.pseudo({value:":scope"})),n&&sortCompoundSelectorsInsideComplexSelector(n)})),t.selector=r.toString())}function cleanupParent(e){if(!e.nodes.length)return void e.remove();const t=e.nodes.filter((e=>"comment"===e.type));t.length===e.nodes.length&&e.replaceWith(...t)}function shiftNodesBeforeParent(e,t){const n=t.index(e);if(n){const e=t.cloneBefore().removeAll().append(t.nodes.slice(0,n));e.raws.semicolon=!0,cleanupParent(e)}t.before(e),t.raws.semicolon=!0}function combinationsWithSizeN(e,t){if(t<2)throw new Error("n must be greater than 1");if(e.length<2)throw new Error("s must be greater than 1");if(Math.pow(e.length,t)>1e4)throw new Error("Too many combinations when trying to resolve a nested selector with lists, reduce the complexity of your selectors");const n=[];for(let e=0;e=0;s--){let t=n[s];if(t>=e.length){if(t=0,n[s]=0,0===s)return r;n[s-1]+=1}o[s]=e[t]}r.push(o),n[n.length-1]++}}function nodesAreEquallySpecific(n){const r=n.map((t=>e().astSync(t))).map((e=>t(e))),o=r[0];for(let e=1;ee().astSync(t))):[e().astSync(`:is(${t.join(",")})`)];const s=[];for(let t=0;t{"nesting"===e.type&&(n=!0)}));const r=t.nodes[0];let o=!1;r.each((e=>"combinator"===e.type&&(o=!0,!1))),n?o&&r.insertBefore(r.at(0),e.nesting({})):(r.insertBefore(r.at(0),e.combinator({value:" "})),r.insertBefore(r.at(0),e.nesting({}))),l=t.toString()}let c=[],a=0;if(e().astSync(l).walkNesting((()=>{a++})),a>1&&o.length>1)c=combinationsWithSizeN(o,a),i=c.length;else{i=o.length;for(let e=0;e{if("nesting"!==o.type)return;let s=c[t][n];n++,"root"===s.type&&1===s.nodes.length&&(s=s.nodes[0]);const i=e().astSync(`:is(${s.toString()})`),l=isSimpleSelector(s.nodes[0]),a=isCompoundSelector(s.nodes[0]),p=isSimpleSelector(o),u=isCompoundSelector(o);if(l&&p)return void o.replaceWith(s.clone());if((l||a)&&(p||u)){const e=o.parent;return l&&"selector"===s.type?o.replaceWith(s.clone().nodes[0]):o.replaceWith(...s.clone().nodes),void(e&&e.nodes.length>1&&sortCompoundSelectorsInsideComplexSelector(e))}if(l){const e=o.parent;return o.replaceWith(s.clone().nodes[0]),void(e&&sortCompoundSelectorsInsideComplexSelector(e))}if(a){const e=o.parent;return o.replaceWith(...s.clone().nodes),void(e&&sortCompoundSelectorsInsideComplexSelector(e))}if(nestingIsFirstAndOnlyInSelectorWithEitherSpaceOrChildCombinator(o)){const e=o.parent;return o.replaceWith(...s.clone().nodes),void(e&&sortCompoundSelectorsInsideComplexSelector(e))}if(nestingIsNotInsideCompoundSelector(o)){const e=o.parent;return o.replaceWith(...s.clone().nodes),void(e&&sortCompoundSelectorsInsideComplexSelector(e))}const d=o.parent;r.noIsPseudoSelector?o.replaceWith(...s.clone().nodes):o.replaceWith(...i.clone({}).nodes),d&&sortCompoundSelectorsInsideComplexSelector(d)})),s.push(o.toString())}}return s}function isSimpleSelector(e){return"combinator"!==e.type&&!(e.parent&&e.parent.nodes.length>1)}function isCompoundSelector(e,t=null){if(isSimpleSelector(e))return!1;if(!e.parent)return!1;if(!!e.parent.nodes.find((e=>"combinator"===e.type)))return!1;return!(!!e.parent.nodes.find((e=>"nesting"===e.type))&&t&&!isCompoundSelector(t))}function nestingIsFirstAndOnlyInSelectorWithEitherSpaceOrChildCombinator(e){if(!e.parent)return!1;if(0!==e.parent.nodes.indexOf(e))return!1;for(let t=1;t"!==e.parent.nodes[t].value)return!1;return!0}function nestingIsNotInsideCompoundSelector(e){if(isSimpleSelector(e))return!0;if(!e.parent)return!1;for(let t=0;t{if("decl"===n.type)return t===r-1?void(t=r):(n.remove(),e.insertAfter(t,n),void(t=e.index(n)));if("atrule"===n.type&&"mixin"===n.name.toLowerCase()){let o=n.prev();for(;o;){if("rule"===o.type||"atrule"===o.type)return;o=o.prev()}return t===r-1?void(t=r):(n.remove(),e.insertAfter(t,n),void(t=e.index(n)))}if("comment"===n.type){const o=n.next();if(o&&("comment"===o.type||"rule"===o.type||"atrule"===o.type&&"mixin"!==o.name.toLowerCase()))return;return t===r-1?void(t=r):(n.remove(),e.insertAfter(t,n),void(t=e.index(n)))}}))}function transformRuleWithinRule(e,t,n,r){let o=[];try{o=mergeSelectors(t.selectors,e.selectors,r)}catch(r){return void e.warn(n,`Failed to parse selectors : "${t.selector}" / "${e.selector}" with message: "${r instanceof Error?r.message:r}"`)}if(!o.length)return;groupDeclarations(t),shiftNodesBeforeParent(e,t),e.selectors=o;"rule"===e.type&&"rule"===t.type&&e.selector===t.selector&&e.append(...t.nodes),cleanupParent(t)}function isValidRuleWithinRule(e){return e.selectors.every((e=>-1===e.indexOf("|")))}function comma(e){const t=[];let n="",r=!1,o=0,s=!1,i=!1;for(const l of e)i?i=!1:"\\"===l?i=!0:s?l===s&&(s=!1):'"'===l||"'"===l?s=l:"("===l?o+=1:")"===l?o>0&&(o-=1):0===o&&","===l&&(r=!0),r?(""!==n&&t.push(n.trim()),n="",r=!1):n+=l;return t.push(n.trim()),t}function transformNestRuleWithinRule(e,t,n,r,o){let s=[];try{s=mergeSelectors(t.selectors,comma(e.params),o)}catch(r){return void e.warn(n,`Failed to parse selectors : "${t.selector}" / "${e.params}" with message: "${r instanceof Error?r.message:r}"`)}if(!s.length)return;shiftNodesBeforeParent(e,t);const i=t.clone().removeAll().append(e.nodes);i.raws.semicolon=!0,i.selectors=s,e.replaceWith(i),cleanupParent(t),r(i,n,o)}function isValidNestRuleWithinRule(e){return comma(e.params).every((e=>e.split("&").length>=2&&-1===e.indexOf("|")))}var o=["container","document","media","supports","layer","starting-style"];function atruleWithinRule(e,t,n,r,o){if(groupDeclarations(t),shiftNodesBeforeParent(e,t),e.nodes){const s=t.clone().removeAll().append(e.nodes);e.append(s),cleanupParent(t),r(s,n,o)}else cleanupParent(t)}function isAtruleWithinRule(e){return o.includes(e.name)}function transformAtruleWithinAtrule(e,t){var n,r;groupDeclarations(t),shiftNodesBeforeParent(e,t),e.params=(n=t.params,r=e.params,comma(n).map((e=>comma(r).map((t=>`${e} and ${t}`)).join(", "))).join(", ")),cleanupParent(t)}function isAtruleWithinAtrule(e,t){return o.includes(e.name)&&e.name===t.name}function isAtRule(e){return e&&"atrule"===e.type}function isNestRule(e){return e&&isAtRule(e)&&"nest"===e.name}function isRule(e){return e&&"rule"===e.type}function walk(e,t,n){e.each((r=>{const o=r.parent;isNestRule(r)&&!n.silenceAtNestWarning&&e.warn(t,`\`@nest\` was removed from the CSS Nesting specification and will be removed from PostCSS Nesting in the next major version.\nChange \`@nest ${r.params} {}\` to \`${r.params} {}\` to migrate to the latest standard.`),isRule(r)&&isRule(o)&&isValidRuleWithinRule(r)?transformRuleWithinRule(r,o,t,n):isNestRule(r)&&isRule(o)&&isValidNestRuleWithinRule(r)?transformNestRuleWithinRule(r,o,t,walk,n):isAtRule(r)&&isRule(o)&&isAtruleWithinRule(r)?atruleWithinRule(r,o,t,walk,n):isAtRule(r)&&isAtRule(o)&&isAtruleWithinAtrule(r,o)&&transformAtruleWithinAtrule(r,o),"nodes"in r&&r.nodes.length&&walk(r,t,n)}))}const creator=e=>{const t=Object.assign({noIsPseudoSelector:!1,silenceAtNestWarning:!1},e);return{postcssPlugin:"postcss-nesting",Rule(e,{result:n}){walk(e,n,t),e.selector.includes("&")&&ersandToScope(e,n)}}};creator.postcss=!0;export{creator as default}; +import e from"postcss-selector-parser";import{resolveNestedSelector as t}from"@csstools/selector-resolve-nested";function ampersandToScope(t,r){let n,o=t.parent;for(;o;){if("rule"===o.type)return;o=o.parent}try{n=e().astSync(t.selector)}catch(e){return void t.warn(r,`Failed to parse selector : "${t.selector}" with message: "${e instanceof Error?e.message:e}"`)}n&&(n.walkNesting((t=>{t.replaceWith(e.pseudo({value:":scope"}))})),t.selector=n.toString())}function cleanupParent(e){if(!e.nodes.length)return void e.remove();const t=e.nodes.filter((e=>"comment"===e.type));t.length===e.nodes.length&&e.replaceWith(...t)}function groupDeclarations(e){let t=-1;e.each(((r,n)=>{if("decl"===r.type)return t===n-1?void(t=n):(r.remove(),e.insertAfter(t,r),void(t=e.index(r)));if("atrule"===r.type&&"mixin"===r.name.toLowerCase()){let o=r.prev();for(;o;){if("rule"===o.type||"atrule"===o.type)return;o=o.prev()}return t===n-1?void(t=n):(r.remove(),e.insertAfter(t,r),void(t=e.index(r)))}if("comment"===r.type){const o=r.next();if(o&&("comment"===o.type||"rule"===o.type||"atrule"===o.type&&"mixin"!==o.name.toLowerCase()))return;return t===n-1?void(t=n):(r.remove(),e.insertAfter(t,r),void(t=e.index(r)))}}))}const r=e();function mergeSelectors(e,n,o,s){let i;try{i=t(r.astSync(n),r.astSync(o))}catch(t){return e.warn(s,`Failed to parse selectors : "${o}" / "${n}" with message: "${t instanceof Error?t.message:t}"`),!1}return!!i&&i.toString()}function shiftNodesBeforeParent(e,t){const r=t.index(e);if(r){const e=t.cloneBefore().removeAll().append(t.nodes.slice(0,r));e.raws.semicolon=!0,cleanupParent(e)}t.before(e),t.raws.semicolon=!0}function transformRuleWithinRule(e,t,r){const n=mergeSelectors(e,e.selector,t.selector,r);if(!n)return;groupDeclarations(t),shiftNodesBeforeParent(e,t),e.selector=n;"rule"===e.type&&"rule"===t.type&&e.selector===t.selector&&e.append(...t.nodes),cleanupParent(t)}function isValidRuleWithinRule(e){return e.selectors.every((e=>-1===e.indexOf("|")))}var n=["container","document","media","supports","layer","starting-style"];function atruleWithinRule(e,t,r,n){if(groupDeclarations(t),shiftNodesBeforeParent(e,t),e.nodes){const o=t.clone().removeAll().append(e.nodes),s=mergeSelectors(e,"&",t.selector,r);s&&(o.selector=s),e.append(o),cleanupParent(t),n(o,r)}else cleanupParent(t)}function isAtruleWithinRule(e){return n.includes(e.name)}function comma(e){const t=[];let r="",n=!1,o=0,s=!1,i=!1;for(const l of e)i?i=!1:"\\"===l?i=!0:s?l===s&&(s=!1):'"'===l||"'"===l?s=l:"("===l?o+=1:")"===l?o>0&&(o-=1):0===o&&","===l&&(n=!0),n?(""!==r&&t.push(r.trim()),r="",n=!1):r+=l;return t.push(r.trim()),t}function transformAtruleWithinAtrule(e,t){var r,n;groupDeclarations(t),shiftNodesBeforeParent(e,t),e.params=(r=t.params,n=e.params,comma(r).map((e=>comma(n).map((t=>`${e} and ${t}`)).join(", "))).join(", ")),cleanupParent(t)}function isAtruleWithinAtrule(e,t){return n.includes(e.name)&&e.name===t.name}function isAtRule(e){return e&&"atrule"===e.type}function isRule(e){return e&&"rule"===e.type}function walk(e,t){e.each((e=>{const r=e.parent;isRule(e)&&isRule(r)&&isValidRuleWithinRule(e)?transformRuleWithinRule(e,r,t):isAtRule(e)&&isRule(r)&&isAtruleWithinRule(e)?atruleWithinRule(e,r,t,walk):isAtRule(e)&&isAtRule(r)&&isAtruleWithinAtrule(e,r)&&transformAtruleWithinAtrule(e,r),"nodes"in e&&e.nodes.length&&walk(e,t)}))}const creator=e=>{if(Object.assign({noIsPseudoSelector:!1},e).noIsPseudoSelector)throw new Error("The `noIsPseudoSelector` option is no longer supported. Migrate your CSS to use the latest CSS nesting syntax.");return{postcssPlugin:"postcss-nesting",Rule(e,{result:t}){walk(e,t),e.selector.includes("&")&&ersandToScope(e,t)},AtRule:{nest(e){throw e.error(`\`@nest\` was removed from the CSS Nesting specification and will be removed from PostCSS Nesting in the next major version.\nChange \`@nest ${e.params} {}\` to \`${e.params} {}\` to migrate to the latest standard.`)}}}};creator.postcss=!0;export{creator as default}; diff --git a/plugins/postcss-nesting/docs/README.md b/plugins/postcss-nesting/docs/README.md index 06b06eefa..a83e37faf 100644 --- a/plugins/postcss-nesting/docs/README.md +++ b/plugins/postcss-nesting/docs/README.md @@ -39,123 +39,10 @@ you might want to use [PostCSS Nested] instead. Previous iterations of the [CSS Nesting specification] required using `@nest` for certain selectors. `@nest` was removed from the specification completely. -Future versions of this plugin will error if you use `@nest`. We advice everyone to migrate their codebase **now** to nested CSS without `@nest`. We published a [Stylelint Plugin](https://github.com/csstools/postcss-plugins/tree/main/plugins-stylelint/no-at-nest-rule#csstoolsstylelint-no-at-nest-rule) to help you migrate. -example warning: -> `@nest` was removed from the CSS Nesting specification and will be removed from PostCSS Nesting in the next major version. -> Change `@nest foo & {}` to `foo & {}` to migrate to the latest standard. - -You can silence this warning with a new `silenceAtNestWarning` plugin option. - -```js -({ - silenceAtNestWarning: true -}) -``` - -## Options - -### noIsPseudoSelector - -#### Specificity - -Before : - -```css -#alpha, -.beta { - &:hover { - order: 1; - } -} -``` - -After **without** the option : - -```js -() -``` - -```css -:is(#alpha,.beta):hover { - order: 1; -} -``` - -_`.beta:hover` has specificity as if `.beta` where an id selector, matching the specification._ - -[specificity: 1, 1, 0](https://polypane.app/css-specificity-calculator/#selector=%3Ais(%23alpha%2C.beta)%3Ahover) - -After **with** the option : - -```js -({ - noIsPseudoSelector: true -}) -``` - -```css -#alpha:hover, .beta:hover { - order: 1; -} -``` - -_`.beta:hover` has specificity as if `.beta` where a class selector, conflicting with the specification._ - -[specificity: 0, 2, 0](https://polypane.app/css-specificity-calculator/#selector=.beta%3Ahover) - - -#### Complex selectors - -Before : - -```css -.alpha > .beta { - & + & { - order: 2; - } -} -``` - -After **without** the option : - -```js -() -``` - -```css -:is(.alpha > .beta) + :is(.alpha > .beta) { - order: 2; -} -``` - -After **with** the option : - -```js -({ - noIsPseudoSelector: true -}) -``` - -```css -.alpha > .beta + .alpha > .beta { - order: 2; -} -``` - -_this is a different selector than expected as `.beta + .alpha` matches `.beta` followed by `.alpha`._
-_avoid these cases when you disable `:is()`_
-_writing the selector without nesting is advised here_ - -```css -/* without nesting */ -.alpha > .beta + .beta { - order: 2; -} -``` [PostCSS Nested]: https://github.com/postcss/postcss-nested diff --git a/plugins/postcss-nesting/package.json b/plugins/postcss-nesting/package.json index bf20a283d..893577968 100644 --- a/plugins/postcss-nesting/package.json +++ b/plugins/postcss-nesting/package.json @@ -54,7 +54,7 @@ "dist" ], "dependencies": { - "@csstools/selector-specificity": "^3.0.1", + "@csstools/selector-resolve-nested": "^1.0.0", "postcss-selector-parser": "^6.0.13" }, "peerDependencies": { diff --git a/plugins/postcss-nesting/src/index.ts b/plugins/postcss-nesting/src/index.ts index a4a36e4c6..a5aeb09e2 100644 --- a/plugins/postcss-nesting/src/index.ts +++ b/plugins/postcss-nesting/src/index.ts @@ -2,12 +2,12 @@ import type { PluginCreator } from 'postcss'; import ampersandToScope from './lib/ampersand-to-scope.js'; import walk from './lib/walk.js'; +// TODO : keep the old logic and compare the produced selectors, error when they are different + /** postcss-nesting plugin options */ export type pluginOptions = { - /** Avoid the `:is()` pseudo class as much as possible. default: false */ + /** This option was removed. You must migrate your CSS to the latest speciation to continue using this plugin. */ noIsPseudoSelector?: boolean, - /** Silence the `@nest` warning. */ - silenceAtNestWarning?: boolean, }; const creator: PluginCreator = (opts?: pluginOptions) => { @@ -15,21 +15,32 @@ const creator: PluginCreator = (opts?: pluginOptions) => { // Default options { noIsPseudoSelector: false, - silenceAtNestWarning: false, }, // Provided options opts, ); + if (options.noIsPseudoSelector) { + throw new Error('The `noIsPseudoSelector` option is no longer supported. Migrate your CSS to use the latest CSS nesting syntax.'); + } + return { postcssPlugin: 'postcss-nesting', Rule(rule, { result }) { - walk(rule, result, options); + walk(rule, result); if (rule.selector.includes('&')) { ampersandToScope(rule, result); } }, + AtRule: { + nest(rule) { + throw rule.error( + '`@nest` was removed from the CSS Nesting specification and will be removed from PostCSS Nesting in the next major version.\n' + + `Change \`@nest ${rule.params} {}\` to \`${rule.params} {}\` to migrate to the latest standard.`, + ); + }, + }, }; }; diff --git a/plugins/postcss-nesting/src/lib/ampersand-to-scope.ts b/plugins/postcss-nesting/src/lib/ampersand-to-scope.ts index 57685b384..66b2cfef3 100644 --- a/plugins/postcss-nesting/src/lib/ampersand-to-scope.ts +++ b/plugins/postcss-nesting/src/lib/ampersand-to-scope.ts @@ -1,6 +1,5 @@ import type { Container, Node, Result, Rule } from 'postcss'; import parser from 'postcss-selector-parser'; -import { sortCompoundSelectorsInsideComplexSelector } from './merge-selectors/compound-selector-order'; export default function ampersandToScope(rule: Rule, result: Result) { let parent: Container = rule.parent; @@ -27,15 +26,9 @@ export default function ampersandToScope(rule: Rule, result: Result) { } selectorAST.walkNesting((nesting) => { - const parentNode = nesting.parent; - nesting.replaceWith(parser.pseudo({ value: ':scope', })); - - if (parentNode) { - sortCompoundSelectorsInsideComplexSelector(parentNode); - } }); rule.selector = selectorAST.toString(); diff --git a/plugins/postcss-nesting/src/lib/atrule-within-rule.ts b/plugins/postcss-nesting/src/lib/atrule-within-rule.ts index b3a78e1a4..6e0282c41 100644 --- a/plugins/postcss-nesting/src/lib/atrule-within-rule.ts +++ b/plugins/postcss-nesting/src/lib/atrule-within-rule.ts @@ -1,12 +1,12 @@ import cleanupParent from './cleanup-parent.js'; -import { options } from './options.js'; import shiftNodesBeforeParent from './shift-nodes-before-parent.js'; import validAtrules from './valid-atrules.js'; import { walkFunc } from './walk-func.js'; import type { AtRule, Result, Rule } from 'postcss'; import groupDeclarations from './group-declarations.js'; +import mergeSelectors from './merge-selectors.js'; -export default function atruleWithinRule(node: AtRule, parent: Rule, result: Result, walk: walkFunc, opts: options) { +export default function atruleWithinRule(node: AtRule, parent: Rule, result: Result, walk: walkFunc) { // Group all declarations after the first one. groupDeclarations(parent); @@ -17,6 +17,11 @@ export default function atruleWithinRule(node: AtRule, parent: Rule, result: Res if (node.nodes) { const rule = parent.clone().removeAll().append(node.nodes); + const selectors = mergeSelectors(node, '&', parent.selector, result); + if (selectors) { + rule.selector = selectors; + } + // append the new rule to the node node.append(rule); @@ -24,7 +29,7 @@ export default function atruleWithinRule(node: AtRule, parent: Rule, result: Res cleanupParent(parent); // walk the children of the new rule - walk(rule, result, opts); + walk(rule, result); } else { // conditionally cleanup an empty parent rule cleanupParent(parent); diff --git a/plugins/postcss-nesting/src/lib/is-type-of-rule.ts b/plugins/postcss-nesting/src/lib/is-type-of-rule.ts index 7cea7cf62..1336f39eb 100644 --- a/plugins/postcss-nesting/src/lib/is-type-of-rule.ts +++ b/plugins/postcss-nesting/src/lib/is-type-of-rule.ts @@ -4,10 +4,6 @@ export function isAtRule(node?: Node): node is AtRule { return node && node.type === 'atrule'; } -export function isNestRule(node?: Node): node is AtRule { - return node && isAtRule(node) && node.name === 'nest'; -} - export function isRule(node?: Node): node is Rule { return node && node.type === 'rule'; } diff --git a/plugins/postcss-nesting/src/lib/merge-selectors.ts b/plugins/postcss-nesting/src/lib/merge-selectors.ts new file mode 100644 index 000000000..abbf815f0 --- /dev/null +++ b/plugins/postcss-nesting/src/lib/merge-selectors.ts @@ -0,0 +1,27 @@ +import parser from 'postcss-selector-parser'; +import type { Root } from 'postcss-selector-parser'; +import type { Node, Result } from 'postcss'; +import { resolveNestedSelector } from '@csstools/selector-resolve-nested'; + +const selectorParser = parser(); + +export default function mergeSelectors(node: Node, nodeSelector: string, parentSelector: string, result: Result): string|false { + let selectors: Root; + + // update the selectors of the node to be merged with the parent + try { + selectors = resolveNestedSelector( + selectorParser.astSync(nodeSelector), + selectorParser.astSync(parentSelector), + ); + } catch (err) { + node.warn(result, `Failed to parse selectors : "${parentSelector}" / "${nodeSelector}" with message: "${(err instanceof Error) ? err.message : err}"`); + return false; + } + + if (!selectors) { + return false; + } + + return selectors.toString(); +} diff --git a/plugins/postcss-nesting/src/lib/merge-selectors/combinations-of-size-n.ts b/plugins/postcss-nesting/src/lib/merge-selectors/combinations-of-size-n.ts deleted file mode 100644 index 74d7bc2b4..000000000 --- a/plugins/postcss-nesting/src/lib/merge-selectors/combinations-of-size-n.ts +++ /dev/null @@ -1,70 +0,0 @@ -export function combinationsWithSizeN(set: Array, n: number): Array> { - // set is the list of parent selectors - // n is the amount of `&` selectors in the current selector. - // all combinations of values in the set with an array size of n must be generated to match the nesting selector behavior. - // - // for example : - // a current selector like: `& + & {}` - // with parent : `.foo, .bar {}` - // - // the set is `['.foo', '.bar']` and n is 2, the resulting combinations are: - // ['.foo', '.bar'] - // ['.foo', '.foo'] - // ['.bar', '.foo'] - // ['.bar', '.bar'] - // - // outputted like : - // .foo + .bar, - // .foo + .foo, - // .bar + .foo, - // .bar + .bar {} - - - if (n < 2) { - // should never happen and is checked by caller - throw new Error('n must be greater than 1'); - } - - if (set.length < 2) { - // should never happen and is checked by caller - throw new Error('s must be greater than 1'); - } - - if (Math.pow(set.length, n) > 10000) { - // Throwing is best here as a warning would be impossible to handle gracefully on our end. - // This will error mid transform and there is no possible fallback at this point. - // The user should reduce complexity. - throw new Error('Too many combinations when trying to resolve a nested selector with lists, reduce the complexity of your selectors'); - } - - const counters: Array = []; - - for (let i = 0; i < n; i++) { - counters[i] = 0; - } - - const result: Array> = []; - - // eslint-disable-next-line no-constant-condition - while (true) { - const ss : Array = []; - for (let i = n-1; i >=0; i--) { - let currentCounter = counters[i]; - if (currentCounter >= set.length) { - currentCounter = 0; - counters[i] = 0; - - if (i === 0) { - return result; - } else { - counters[i-1] += 1; - } - } - - ss[i] = set[currentCounter]; - } - - result.push(ss); - counters[counters.length -1]++; - } -} diff --git a/plugins/postcss-nesting/src/lib/merge-selectors/compound-selector-order.ts b/plugins/postcss-nesting/src/lib/merge-selectors/compound-selector-order.ts deleted file mode 100644 index 3c9985d47..000000000 --- a/plugins/postcss-nesting/src/lib/merge-selectors/compound-selector-order.ts +++ /dev/null @@ -1,102 +0,0 @@ -import parser from 'postcss-selector-parser'; -import type { Container, Node, Pseudo } from 'postcss-selector-parser'; - -const isPseudo = parser.pseudo({ value: ':is' }); - -export function sortCompoundSelectorsInsideComplexSelector(node: Container) { - if (!node || !node.nodes) { - return; - } - - const compoundSelectors: Array> = []; - let currentCompoundSelector: Array = []; - for (let i = 0; i < node.nodes.length; i++) { - if (node.nodes[i].type === 'combinator') { - // Push the current compound selector - compoundSelectors.push(currentCompoundSelector); - - // Push the combinator - compoundSelectors.push([node.nodes[i]]); - - // Start a new compound selector - currentCompoundSelector = []; - - continue; - } - - if (parser.isPseudoElement(node.nodes[i])) { - // Push the current compound selector - compoundSelectors.push(currentCompoundSelector); - - // Start a new compound selector with the pseudo element as the first element - currentCompoundSelector = [node.nodes[i]]; - - continue; - } - - if (node.nodes[i].type === 'tag' && currentCompoundSelector.find(x => x.type === 'tag')) { - const isPseudoClone = isPseudo.clone({}) as Pseudo; - const child = node.nodes[i]; - child.replaceWith(isPseudoClone); - isPseudoClone.append(parser.selector({ - nodes: [child], - value: undefined, - })); - } - - currentCompoundSelector.push(node.nodes[i]); - } - - compoundSelectors.push(currentCompoundSelector); - - const sortedCompoundSelectors = []; - for (let i = 0; i < compoundSelectors.length; i++) { - const compoundSelector = compoundSelectors[i]; - compoundSelector.sort((a, b) => { - if (a.type === 'selector' && b.type === 'selector' && a.nodes.length && b.nodes.length) { - return selectorTypeOrder(a.nodes[0]) - selectorTypeOrder(b.nodes[0]); - } - - if (a.type === 'selector' && a.nodes.length) { - return selectorTypeOrder(a.nodes[0]) - selectorTypeOrder(b); - } - - if (b.type === 'selector' && b.nodes.length) { - return selectorTypeOrder(a) - selectorTypeOrder(b.nodes[0]); - } - - return selectorTypeOrder(a) - selectorTypeOrder(b); - }); - - for (let j = 0; j < compoundSelector.length; j++) { - sortedCompoundSelectors.push(compoundSelector[j]); - } - } - - for (let i = sortedCompoundSelectors.length - 1; i >= 0; i--) { - sortedCompoundSelectors[i].remove(); - node.prepend(sortedCompoundSelectors[i]); - } -} - -function selectorTypeOrder(selector: Node) { - if (parser.isPseudoElement(selector)) { - return selectorTypeOrderIndex.pseudoElement; - } - - return selectorTypeOrderIndex[selector.type]; -} - -const selectorTypeOrderIndex = { - universal: 0, - tag: 1, - pseudoElement: 2, - id: 3, - class: 4, - attribute: 5, - pseudo: 6, - selector: 7, - string: 8, - root: 9, - comment: 10, -}; diff --git a/plugins/postcss-nesting/src/lib/merge-selectors/merge-selectors.ts b/plugins/postcss-nesting/src/lib/merge-selectors/merge-selectors.ts deleted file mode 100644 index 2e35de5d0..000000000 --- a/plugins/postcss-nesting/src/lib/merge-selectors/merge-selectors.ts +++ /dev/null @@ -1,279 +0,0 @@ -import parser from 'postcss-selector-parser'; -import type { Root, Nesting } from 'postcss-selector-parser'; -import { combinationsWithSizeN } from './combinations-of-size-n'; -import { sortCompoundSelectorsInsideComplexSelector } from './compound-selector-order'; -import { nodesAreEquallySpecific } from './specificity'; -import { options } from '../options'; - -export default function mergeSelectors(fromSelectors: Array, toSelectors: Array, opts: options) { - const fromListHasUniformSpecificity = nodesAreEquallySpecific(fromSelectors); - - let fromSelectorsAST = []; - - if (fromListHasUniformSpecificity || opts.noIsPseudoSelector) { - fromSelectorsAST = fromSelectors.map((selector) => { - return parser().astSync(selector); - }); - } else { - fromSelectorsAST = [parser().astSync(`:is(${fromSelectors.join(',')})`)]; - } - - const result = []; - - for (let x = 0; x < toSelectors.length; x++) { - let toSelector = toSelectors[x]; - - { - const toSelectorAST = parser().astSync(toSelector); - - let isNestContaining = false; - toSelectorAST.walk((maybeNesting) => { - if (maybeNesting.type === 'nesting') { - isNestContaining = true; - } - }); - - const selectorAST = toSelectorAST.nodes[0]; - let startsWithCombinator = false; - selectorAST.each((maybeCombinator) => { - if (maybeCombinator.type === 'combinator') { - startsWithCombinator = true; - return false; - } - - return false; - }); - - if (!isNestContaining) { - selectorAST.insertBefore(selectorAST.at(0), parser.combinator({ value: ' ' })); - selectorAST.insertBefore(selectorAST.at(0), parser.nesting({})); - } else if (startsWithCombinator) { - selectorAST.insertBefore(selectorAST.at(0), parser.nesting({})); - } - - toSelector = toSelectorAST.toString(); - } - - let iterations: number; - let fromSelectorCombinations = []; - - let nestingCounter = 0; - parser().astSync(toSelector).walkNesting(() => { - nestingCounter++; - }); - - if (nestingCounter > 1 && fromSelectorsAST.length > 1) { - fromSelectorCombinations = combinationsWithSizeN(fromSelectorsAST, nestingCounter); - iterations = fromSelectorCombinations.length; - } else { - iterations = fromSelectorsAST.length; - for (let i = 0; i < fromSelectorsAST.length; i++) { - fromSelectorCombinations.push([]); - - for (let j = 0; j < nestingCounter; j++) { - fromSelectorCombinations[i].push(fromSelectorsAST[i]); - } - } - } - - for (let y = 0; y < iterations; y++) { - let counter = 0; - - const toSelectorAST = parser().astSync(toSelector); - toSelectorAST.walk((nesting) => { - if (nesting.type !== 'nesting') { - return; - } - - let fromSelectorAST = fromSelectorCombinations[y][counter]; - counter++; - - // If the from selector is simple we extract the first non root, non selector node - if (fromSelectorAST.type === 'root' && fromSelectorAST.nodes.length === 1) { - fromSelectorAST = fromSelectorAST.nodes[0]; - } - - const fromSelectorWithIsAST = parser().astSync(`:is(${fromSelectorAST.toString()})`); - - const fromIsSimple = isSimpleSelector(fromSelectorAST.nodes[0]); // this function looks at the parent of the node passed as an argument - const fromIsCompound = isCompoundSelector(fromSelectorAST.nodes[0]); // this function looks at the parent of the node passed as an argument - - const toIsSimple = isSimpleSelector(nesting); - const toIsCompound = isCompoundSelector(nesting); - - // Parent and child are simple - if (fromIsSimple && toIsSimple) { - nesting.replaceWith(fromSelectorAST.clone()); - return; - } - - // Parent and child are simple or compound - if ((fromIsSimple || fromIsCompound) && (toIsSimple || toIsCompound)) { - const parent = nesting.parent; - - if (fromIsSimple && fromSelectorAST.type === 'selector') { - // fromSelectorAST has type selector with a single child - nesting.replaceWith(fromSelectorAST.clone().nodes[0]); - } else { - // fromSelectorAST has type selector containing a compound selector - nesting.replaceWith(...(fromSelectorAST.clone().nodes)); - } - - if (parent && parent.nodes.length > 1) { - sortCompoundSelectorsInsideComplexSelector(parent); - } - - return; - } - - if (fromIsSimple) { - const parent = nesting.parent; - nesting.replaceWith(fromSelectorAST.clone().nodes[0]); - - if (parent) { - sortCompoundSelectorsInsideComplexSelector(parent); - } - - return; - } - - if (fromIsCompound) { - const parent = nesting.parent; - nesting.replaceWith(...(fromSelectorAST.clone().nodes)); - - if (parent) { - sortCompoundSelectorsInsideComplexSelector(parent); - } - - return; - } - - if (nestingIsFirstAndOnlyInSelectorWithEitherSpaceOrChildCombinator(nesting)) { - const parent = nesting.parent; - nesting.replaceWith(...(fromSelectorAST.clone().nodes)); - - if (parent) { - sortCompoundSelectorsInsideComplexSelector(parent); - } - - return; - } - - if (nestingIsNotInsideCompoundSelector(nesting)) { - const parent = nesting.parent; - nesting.replaceWith(...(fromSelectorAST.clone().nodes)); - - if (parent) { - sortCompoundSelectorsInsideComplexSelector(parent); - } - - return; - } - - const parent = nesting.parent; - if (opts.noIsPseudoSelector) { - nesting.replaceWith(...(fromSelectorAST.clone().nodes)); - } else { - nesting.replaceWith(...((fromSelectorWithIsAST.clone({}) as Root).nodes)); - } - - if (parent) { - sortCompoundSelectorsInsideComplexSelector(parent); - } - }); - - result.push(toSelectorAST.toString()); - } - } - - return result; -} - -function isSimpleSelector(selector) { - if (selector.type === 'combinator') { - return false; - } - - if (selector.parent && selector.parent.nodes.length > 1) { - return false; - } - - return true; -} - -function isCompoundSelector(selector, toSelector = null) { - if (isSimpleSelector(selector)) { - return false; - } - - if (!selector.parent) { - return false; - } - - const hasCombinators = !!(selector.parent.nodes.find((x) => { - return x.type === 'combinator'; - })); - - if (hasCombinators) { - return false; - } - - const hasExtraNesting = !!(selector.parent.nodes.find((x) => { - return x.type === 'nesting'; - })); - - if (hasExtraNesting && toSelector && !isCompoundSelector(toSelector)) { - return false; - } - - return true; -} - - -function nestingIsFirstAndOnlyInSelectorWithEitherSpaceOrChildCombinator(selector) { - if (!selector.parent) { - return false; - } - - if (selector.parent.nodes.indexOf(selector) !== 0) { - return false; - } - - for (let i = 1; i < selector.parent.nodes.length; i++) { - if (selector.parent.nodes[i].type === 'combinator' && (selector.parent.nodes[i].value !== ' ' && selector.parent.nodes[i].value !== '>')) { - return false; - } - } - - return true; -} - -function nestingIsNotInsideCompoundSelector(selector: Nesting) { - if (isSimpleSelector(selector)) { - return true; - } - - if (!selector.parent) { - return false; - } - - for (let i = 0; i < selector.parent.nodes.length; i++) { - if (selector.parent.nodes[i].type === 'nesting') { - continue; - } - - if (!selector.parent.nodes[i].prev() && !selector.parent.nodes[i].next()) { - continue; - } - - if (selector.parent.nodes[i].prev() && selector.parent.nodes[i].prev().type !== 'combinator') { - return false; - } - - if (selector.parent.nodes[i].next() && selector.parent.nodes[i].next().type !== 'combinator') { - return false; - } - } - - return true; -} diff --git a/plugins/postcss-nesting/src/lib/merge-selectors/specificity.ts b/plugins/postcss-nesting/src/lib/merge-selectors/specificity.ts deleted file mode 100644 index a855f8f96..000000000 --- a/plugins/postcss-nesting/src/lib/merge-selectors/specificity.ts +++ /dev/null @@ -1,26 +0,0 @@ -import parser from 'postcss-selector-parser'; -import { selectorSpecificity } from '@csstools/selector-specificity'; - -export function nodesAreEquallySpecific(nodes: Array) { - // Selector specificity is important when the parent selector is a list. - // These cases should be resolved with `:is()` pseudo. - // Since browser support for `:is()` is not great, we try to avoid it. - // If the selector specificity is equal for all items in the selector list, we don't need `:is`. - - const specificities = nodes.map((node) => { - return parser().astSync(node); - }).map((ast) => { - return selectorSpecificity(ast); - }); - - const first = specificities[0]; - for (let i = 1; i < specificities.length; i++) { - if (first.a === specificities[i].a && first.b === specificities[i].b && first.c === specificities[i].c) { - continue; - } - - return false; - } - - return true; -} diff --git a/plugins/postcss-nesting/src/lib/nest-rule-within-rule.ts b/plugins/postcss-nesting/src/lib/nest-rule-within-rule.ts deleted file mode 100644 index e505fda06..000000000 --- a/plugins/postcss-nesting/src/lib/nest-rule-within-rule.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { comma } from './list.js'; -import shiftNodesBeforeParent from './shift-nodes-before-parent.js'; -import cleanupParent from './cleanup-parent.js'; -import mergeSelectors from './merge-selectors/merge-selectors.js'; -import type { AtRule, Result, Rule } from 'postcss'; -import { walkFunc } from './walk-func.js'; -import { options } from './options.js'; - -export default function transformNestRuleWithinRule(node: AtRule, parent: Rule, result: Result, walk: walkFunc, opts: options) { - let selectors = []; - - try { - selectors = mergeSelectors(parent.selectors, comma(node.params), opts); - } catch (err) { - node.warn(result, `Failed to parse selectors : "${parent.selector}" / "${node.params}" with message: "${(err instanceof Error) ? err.message: err}"`); - return; - } - - if (!selectors.length) { - return; - } - - // move previous siblings and the node to before the parent - shiftNodesBeforeParent(node, parent); - - // clone the parent as a new rule with children appended to it - const rule = parent.clone().removeAll().append(node.nodes); - rule.raws.semicolon = true; /* nested rules end with "}" and do not have this flag set */ - - // update the selectors of the node to be merged with the parent - rule.selectors = selectors; - - // replace the node with the new rule - node.replaceWith(rule); - - // conditionally cleanup an empty parent rule - cleanupParent(parent); - - // walk the children of the new rule - walk(rule, result, opts); -} - -export function isValidNestRuleWithinRule(node: AtRule) { - return comma(node.params).every((selector) => { - return selector.split('&').length >= 2 && - selector.indexOf('|') === -1; - }); -} diff --git a/plugins/postcss-nesting/src/lib/options.ts b/plugins/postcss-nesting/src/lib/options.ts deleted file mode 100644 index cf1f23307..000000000 --- a/plugins/postcss-nesting/src/lib/options.ts +++ /dev/null @@ -1 +0,0 @@ -export type options = { noIsPseudoSelector: boolean, silenceAtNestWarning: boolean } diff --git a/plugins/postcss-nesting/src/lib/rule-within-rule.ts b/plugins/postcss-nesting/src/lib/rule-within-rule.ts index 005effb31..dcadeb375 100644 --- a/plugins/postcss-nesting/src/lib/rule-within-rule.ts +++ b/plugins/postcss-nesting/src/lib/rule-within-rule.ts @@ -1,22 +1,12 @@ -import shiftNodesBeforeParent from './shift-nodes-before-parent.js'; import cleanupParent from './cleanup-parent.js'; -import mergeSelectors from './merge-selectors/merge-selectors.js'; -import type { Result, Rule } from 'postcss'; -import { options } from './options.js'; import groupDeclarations from './group-declarations.js'; +import mergeSelectors from './merge-selectors.js'; +import shiftNodesBeforeParent from './shift-nodes-before-parent.js'; +import type { Result, Rule } from 'postcss'; -export default function transformRuleWithinRule(node: Rule, parent: Rule, result: Result, opts: options) { - let selectors = []; - - // update the selectors of the node to be merged with the parent - try { - selectors = mergeSelectors(parent.selectors, node.selectors, opts); - } catch (err) { - node.warn(result, `Failed to parse selectors : "${parent.selector}" / "${node.selector}" with message: "${(err instanceof Error) ? err.message: err}"`); - return; - } - - if (!selectors.length) { +export default function transformRuleWithinRule(node: Rule, parent: Rule, result: Result) { + const selectors = mergeSelectors(node, node.selector, parent.selector, result); + if (!selectors) { return; } @@ -27,7 +17,7 @@ export default function transformRuleWithinRule(node: Rule, parent: Rule, result shiftNodesBeforeParent(node, parent); // update the selectors of the node to be merged with the parent - node.selectors = selectors; + node.selector = selectors; // merge similar rules back together const areSameRule = (node.type === 'rule' && parent.type === 'rule' && node.selector === parent.selector); diff --git a/plugins/postcss-nesting/src/lib/walk-func.ts b/plugins/postcss-nesting/src/lib/walk-func.ts index 65214ced9..f73a5d18b 100644 --- a/plugins/postcss-nesting/src/lib/walk-func.ts +++ b/plugins/postcss-nesting/src/lib/walk-func.ts @@ -1,3 +1,3 @@ import type { Container, Result } from 'postcss'; -export type walkFunc = (node: Container, result: Result, opts: { noIsPseudoSelector: boolean }) => void; +export type walkFunc = (node: Container, result: Result) => void; diff --git a/plugins/postcss-nesting/src/lib/walk.ts b/plugins/postcss-nesting/src/lib/walk.ts index 30ffad425..174504797 100644 --- a/plugins/postcss-nesting/src/lib/walk.ts +++ b/plugins/postcss-nesting/src/lib/walk.ts @@ -1,41 +1,25 @@ import transformRuleWithinRule, { isValidRuleWithinRule } from './rule-within-rule.js'; -import transformNestRuleWithinRule, { isValidNestRuleWithinRule } from './nest-rule-within-rule.js'; import transformAtruleWithinRule, { isAtruleWithinRule } from './atrule-within-rule.js'; import transformAtruleWithinAtrule, { isAtruleWithinAtrule } from './atrule-within-atrule.js'; import type { Container, Result } from 'postcss'; -import { options } from './options.js'; -import { isAtRule, isNestRule, isRule } from './is-type-of-rule.js'; +import { isAtRule, isRule } from './is-type-of-rule.js'; -export default function walk(node: Container, result: Result, opts: options) { +export default function walk(node: Container, result: Result) { node.each((child) => { const parent = child.parent; - if (isNestRule(child) && !opts.silenceAtNestWarning) { - node.warn( - result, - '`@nest` was removed from the CSS Nesting specification and will be removed from PostCSS Nesting in the next major version.\n' + - `Change \`@nest ${child.params} {}\` to \`${child.params} {}\` to migrate to the latest standard.`, - ); - } - if ( isRule(child) && isRule(parent) && isValidRuleWithinRule(child) ) { - transformRuleWithinRule(child, parent, result, opts); - } else if ( - isNestRule(child) && - isRule(parent) && - isValidNestRuleWithinRule(child) - ) { - transformNestRuleWithinRule(child, parent, result, walk, opts); + transformRuleWithinRule(child, parent, result); } else if ( isAtRule(child) && isRule(parent) && isAtruleWithinRule(child) ) { - transformAtruleWithinRule(child, parent, result, walk, opts); + transformAtruleWithinRule(child, parent, result, walk); } else if ( isAtRule(child) && isAtRule(parent) && @@ -45,7 +29,7 @@ export default function walk(node: Container, result: Result, opts: options) { } if ('nodes' in child && child.nodes.length) { - walk(child, result, opts); + walk(child, result); } }); } diff --git a/plugins/postcss-nesting/test/_tape.mjs b/plugins/postcss-nesting/test/_tape.mjs index e8c7d4e8a..ddabb88b8 100644 --- a/plugins/postcss-nesting/test/_tape.mjs +++ b/plugins/postcss-nesting/test/_tape.mjs @@ -31,72 +31,28 @@ postcssTape(plugin)({ 'basic': { message: 'supports basic usage', }, - 'basic:no-is-pseudo-selector': { - message: 'supports basic usage { noIsPseudoSelector: true }', - options: { - noIsPseudoSelector: true, - }, - }, 'ampersand-everywhere': { message: 'supports & at the root', }, 'complex': { message: 'supports complex entries', }, - 'complex:no-is-pseudo-selector': { - message: 'supports complex entries { noIsPseudoSelector: true }', - options: { - noIsPseudoSelector: true, - }, - }, 'direct': { message: 'supports direct usage', }, - 'direct:no-is-pseudo-selector': { - message: 'supports direct usage { noIsPseudoSelector: true }', - options: { - noIsPseudoSelector: true, - }, - }, 'at-nest': { message: 'supports at-nest usage', - warnings: 64, - }, - 'at-nest:silent': { - message: 'supports at-nest usage { silenceAtNestWarning: true }', - warnings: 4, - options: { - silenceAtNestWarning: true, - }, - }, - 'at-nest:no-is-pseudo-selector': { - message: 'supports at-nest usage { noIsPseudoSelector: true }', - warnings: 64, - options: { - noIsPseudoSelector: true, - }, + exception: /was removed/, }, 'container': { message: 'supports nested @container', }, - 'container:no-is-pseudo-selector': { - message: 'supports nested @container { noIsPseudoSelector: true }', - options: { - noIsPseudoSelector: true, - }, - }, 'decl-order': { message: 'resolves to the correct order', }, 'document': { message: 'supports nested @document', }, - 'document:no-is-pseudo-selector': { - message: 'supports nested @document { noIsPseudoSelector: true }', - options: { - noIsPseudoSelector: true, - }, - }, 'invalid-selector': { message: 'warns on invalid selectors', warnings: 4, @@ -104,12 +60,6 @@ postcssTape(plugin)({ 'media': { message: 'supports nested @media', }, - 'media:no-is-pseudo-selector': { - message: 'supports nested @media { noIsPseudoSelector: true }', - options: { - noIsPseudoSelector: true, - }, - }, 'multiple-replacements': { message: 'supports multiple replacements', }, @@ -119,76 +69,32 @@ postcssTape(plugin)({ 'supports': { message: 'supports nested @supports', }, - 'supports:no-is-pseudo-selector': { - message: 'supports nested @supports { noIsPseudoSelector: true }', - options: { - noIsPseudoSelector: true, - }, - }, 'layer': { message: 'supports nested @layer', }, 'empty': { message: 'removes empty rules', }, - 'empty:no-is-pseudo-selector': { - message: 'removes empty rules { noIsPseudoSelector: true }', - options: { - noIsPseudoSelector: true, - }, - }, 'ignore': { message: 'ignores invalid entries', }, - 'ignore:no-is-pseudo-selector': { - message: 'ignores invalid entries { noIsPseudoSelector: true }', - options: { - noIsPseudoSelector: true, - }, - }, 'mixin-declaration': { message: 'supports other visitors (mixin declaration)', plugins: [mixinPluginDeclaration(), plugin()], }, - 'mixin-declaration:no-is-pseudo-selector': { - message: 'supports other visitors (mixin declaration) { noIsPseudoSelector: true }', - plugins: [mixinPluginDeclaration(), plugin()], - options: { - noIsPseudoSelector: true, - }, - }, 'mixin-rule': { message: 'supports other visitors (mixin rule)', plugins: [mixinPluginRule(), plugin()], }, - 'mixin-rule:no-is-pseudo-selector': { - message: 'supports other visitors (mixin rule) { noIsPseudoSelector: true }', - plugins: [mixinPluginRule(), plugin()], - options: { - noIsPseudoSelector: true, - }, - }, 'spec-examples': { message: 'supports all spec examples', }, - 'spec-examples:no-is-pseudo-selector': { - message: 'supports all spec examples { noIsPseudoSelector: true }', - options: { - noIsPseudoSelector: true, - }, - }, 'relative-selectors': { message: 'supports relative selectors', }, 'requires-is-pseudo': { message: 'examples of selector nesting that require :is to be correct', }, - 'requires-is-pseudo:no-is-pseudo-selector': { - message: 'examples of selector nesting that require :is to be correct { noIsPseudoSelector: true }', - options: { - noIsPseudoSelector: true, - }, - }, 'examples/example': { message: 'basic examples', }, diff --git a/plugins/postcss-nesting/test/ampersand-everywhere.css b/plugins/postcss-nesting/test/ampersand-everywhere.css index 6abff7c0c..03370cd72 100644 --- a/plugins/postcss-nesting/test/ampersand-everywhere.css +++ b/plugins/postcss-nesting/test/ampersand-everywhere.css @@ -27,7 +27,7 @@ } } -&html { +&.html { order: 7; } diff --git a/plugins/postcss-nesting/test/ampersand-everywhere.expect.css b/plugins/postcss-nesting/test/ampersand-everywhere.expect.css index 3d8ed9c2d..f0f95f07f 100644 --- a/plugins/postcss-nesting/test/ampersand-everywhere.expect.css +++ b/plugins/postcss-nesting/test/ampersand-everywhere.expect.css @@ -27,7 +27,7 @@ } } -html:scope { +:scope.html { order: 7; } diff --git a/plugins/postcss-nesting/test/at-nest.expect.css b/plugins/postcss-nesting/test/at-nest.expect.css index a56ab074d..f57d63a5c 100644 --- a/plugins/postcss-nesting/test/at-nest.expect.css +++ b/plugins/postcss-nesting/test/at-nest.expect.css @@ -28,18 +28,20 @@ a b { order: 9; } -a b c { +:is(a b) c { order: 8; } -body a { +a { + + @nest body & { order: 11; -} -html :is(body a) { + + @nest html & { order: 12; -} -body a { + } order: 13; + } } @media screen { a { @@ -51,35 +53,42 @@ a { order: 16; } } -body:is(a) { +a { + + @nest body& { order: 17; -} -html body:is(a) { + } + + @nest html body& { order: 18; + } } -a.foo { +a { + @nest .foo& { order: 19; -} + } -.foo a.bar { + @nest .foo .bar& { order: 20; + } } -.foo:is(a b) { +a b { + @nest .foo& { order: 21; -} + } -.foo .bar:is(a b) { + @nest .foo .bar& { order: 22; + } } -h1.foo, - h2.foo { +h1.foo, h2.foo { color: red; } -li+li { +li + li { background: red; } @@ -91,11 +100,11 @@ a b[a="a&b"] { order: 31; } -.a.c::before, .b.c::before, .a.d::before, .b.d::before { +:is(.c:is(.a,.b),.d:is(.a,.b))::before { order: 41; } -.a:hover::before, .b:focus::before, .a:hover::after, .b:focus::after { +:is(.a:hover,.b:focus)::before, :is(.a:hover,.b:focus)::after { order: 51; } @@ -117,40 +126,48 @@ a b[a="a&b"] { } /* trailing: 5 */ /* nested deeper */ -.comments .comment .comment { +:is(.comments .comment) .comment { order: 65; } -::before.pseudo-element { +.pseudo-element { + @nest ::before& { order: 71; -} + } -::before .pseudo-element { + @nest ::before & { order: 71.1; + } } -:before.pseudo-element { +.pseudo-element { + @nest :before& { order: 72; -} + } -:before .pseudo-element { + @nest :before & { order: 72.1; + } } -.pseudo-element::after { +.pseudo-element { + @nest &::after { order: 73; -} + } -.pseudo-element ::after { + @nest & ::after { order: 73.1; + } } -.pseudo-element:after { +.pseudo-element { + @nest &:after { order: 74; -} + } -.pseudo-element :after { + @nest & :after { order: 74.1; + } } .has-semi-colons-on-the-last-decl { @@ -165,10 +182,10 @@ a b[a="a&b"] { .has-semi-colons-on-the-last-decl { order: 74; /* a comment */ -} -.has-semi-colons-on-the-last-decl .foo { + @nest & .foo { order: 74.1; + } } .mixed-declarations-and-rules--a { @@ -211,87 +228,111 @@ a b[a="a&b"] { /* at-rule.css */ a { order: 1; -} -b a { + + @nest b & { order: 2; -} -c a { + } + + @nest c & { order: 3; -} -d a { + } + + @nest d & { order: 4; -} -e a { + } + + @nest e & { order: 5; + } } a { order: 1; -} -a b { + @nest & b { order: 2; -} + } -a c { + @nest & c { order: 3; -} + } -a d { + @nest & d { order: 4; -} + } -a e { + @nest & e { order: 5; -} + } -a[foo="& ,\'"] { + @nest &[foo="& ,\'"] { order: 6; -} + } -a[a="& ,\'"][b='& . \\a &'] { + @nest &[a="& ,\'"][b='& . \\a &'] { order: 7; -} + } -a:is(\\foo) { + @nest &\\foo { order: 8; + } } -h1.foo { +.foo { + @nest &h1 { color: red; + } } -h1.foo, h2.foo { +.foo { + + @nest &h1, + &h2 { color: red; + } } -.foo.bar { +.foo { + @nest &.bar { color: red; + } } -.foo.bar, .foo.baz { +.foo { + + @nest &.bar, + &.baz { color: red; + } } -h1.foo { +h1 { + @nest .foo& { color: blue; + } } -h1.foo .baz h1 { +h1 { + @nest .foo& .baz & { color: blue; + } } -h1.foo, h1.bar { +h1 { + + @nest .foo&, + .bar& { color: blue; + } } article { color: blue; -} -:where(article) { + @nest :where(&) { color: red; + } } /* direct.css */ @@ -301,58 +342,30 @@ b { order: 5; } -a c, - b c, - a d, - b d { +:is(a,b) c, :is(a,b) d { order: 2; order: 4; } -a c e, - b c e, - a d e, - b d e, - a c f, - b c f, - a d f, - b d f { +:is(:is(a,b) c,:is(a,b) d) e, :is(:is(a,b) c,:is(a,b) d) f { order: 3; } a, b { order: 1; -} -a c, -b c, -a d, -b d { + @nest & c, + & d { order: 2; -} -a c e, -b c e, -a d e, -b d e, -a c f, -b c f, -a d f, -b d f { + @nest & e, + & f { order: 3; -} - -a c, -b c, -a d, -b d { + } order: 4; -} - -a, -b { + } order: 5; } @@ -364,65 +377,37 @@ b { order: 5; } -a c, - b c, - a d, - b d { +:is(a,b) c, :is(a,b) d { order: 2; order: 4; } -a c e, - b c e, - a d e, - b d e, - a c f, - b c f, - a d f, - b d f { +:is(:is(a,b) c,:is(a,b) d) e, :is(:is(a,b) c,:is(a,b) d) f { order: 3; } .a, .b { order: 6; -} -.a .c, -.b .c, -.a .d, -.b .d { + @nest & .c, + & .d { order: 7; -} -.a .c .e, -.b .c .e, -.a .d .e, -.b .d .e, -.a .c .f, -.b .c .f, -.a .d .f, -.b .d .f { + @nest & .e, + & .f { order: 8; -} - -.a .c, -.b .c, -.a .d, -.b .d { + } order: 9; -} - -.a, -.b { + } order: 10; } /* empty.css */ -a b c { +:is(a b) c { order: 1; } @@ -443,23 +428,26 @@ f g { order: 4; } -a b c { +a { + @nest & b { + @nest & c { order: 1; + } + } } d { order: 2; -} -d e { + @nest & e { order: 3; -} - -f g { - order: 4; + } } f { + @nest & g { + order: 4; + } order: 5; } @@ -469,10 +457,7 @@ a, b { order: 1; } -a c, - b c, - a d, - b d { +:is(a,b) c, :is(a,b) d { order: 2; } @@ -498,11 +483,10 @@ b { order: 3; } -f:is(h) { - order: 5; -} - f { + @nest &h { + order: 5; + } @nest &|i { order: 6; @@ -582,33 +566,39 @@ a { } } -@media (min-width: 100px) and (max-width: 200px) { +@media (min-width: 100px) { -a b { +a { + + @nest & b { + @media (max-width: 200px) { order: 4; -} } + } +} + } @media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { a { order: 5; -} -a c { + @nest & c { order: 6; + } } } /* pseudo-element.css */ -.foo::before, ::before:focus { +::before { + + @nest .foo&, + &:focus { order: 1; + } } -.a:hover::before, - .b:focus::before, - .a:hover::after, - .b:focus::after { +:is(.a:hover,.b:focus)::before, :is(.a:hover,.b:focus)::after { order: 2; } @@ -636,8 +626,10 @@ a c { order: 8; } -.something_else>.anything::before { +.anything::before { + @nest .something_else>& { order: 9; + } } /* spec-examples.css */ @@ -649,12 +641,11 @@ table.colortable td { text-align: center; } -table.colortable td.c { +.c:is(table.colortable td) { text-transform: uppercase } -table.colortable td:first-child, - :is(table.colortable td):first-child+td { +:is(table.colortable td):first-child, :is(table.colortable td):first-child + td { border: 1px solid black } @@ -669,7 +660,7 @@ table.colortable th { .foo { color: blue; } -.foo>.bar { +.foo > .bar { color: red; } @@ -699,10 +690,7 @@ table.colortable th { .bar { color: blue; } -.foo+.baz, - .bar+.baz, - .foo.qux, - .bar.qux { +:is(.foo,.bar) + .baz, .qux:is(.foo,.bar) { color: red; } @@ -759,7 +747,7 @@ table.colortable th { */ /* The parent selector can be arbitrarily complicated */ -:is(.error,#404):hover>.baz { +:is(.error,#404):hover > .baz { color: red; } @@ -780,10 +768,10 @@ table.colortable th { figure { margin: 0; } -figure>figcaption { +figure > figcaption { background: hsl(0 0% 0% / 50%); } -figure>figcaption>p { +:is(figure > figcaption) > p { font-size: .9rem; } @@ -822,19 +810,17 @@ __bar.foo { .bar { color: blue; } -.foo+.baz, - .bar+.baz, - .foo .qux, - .bar .qux { +:is(.foo,.bar) + .baz, :is(.foo,.bar) .qux { color: red; } /* Example 4 */ .foo { color: red; -} -.foo>.bar { + + @nest &>.bar { color: blue; + } } /* equivalent to @@ -844,10 +830,10 @@ __bar.foo { .foo { color: red; -} -.parent .foo { + @nest .parent & { color: blue; + } } /* equivalent to @@ -857,10 +843,10 @@ __bar.foo { .foo { color: red; -} -:not(.foo) { + @nest :not(&) { color: blue; + } } /* equivalent to @@ -893,13 +879,15 @@ __bar.foo { /* Example 5 */ .foo { color: blue; -} -.bar .foo { + + @nest .bar & { color: red; -} -.bar .foo.baz { + + &.baz { color: green; } + } +} /* equivalent to .foo { color: blue; } @@ -975,8 +963,7 @@ __bar.foo { @media (min-width: 480px) { - .foo h1, - .foo h2 { + .foo h1, .foo h2 { color: blue; } } diff --git a/plugins/postcss-nesting/test/at-nest.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/at-nest.no-is-pseudo-selector.expect.css deleted file mode 100644 index bd1d54208..000000000 --- a/plugins/postcss-nesting/test/at-nest.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,1032 +0,0 @@ -/* This entire file can be deleted after removing support for "@nest" */ - -/* basic.css */ -a { - order: 1; - - order: 5; - order: 6; - - order: 10; - - order: 14; -} -@media screen, print { -a { - order: 2; - - order: 4; -} - } -@media screen and (min-width: 480px), print and (min-width: 480px) { -a { - order: 3; -} - } -a b { - order: 7; - - order: 9; - } -a b c { - order: 8; - } -body a { - order: 11; -} -html body a { - order: 12; -} -body a { - - order: 13; -} -@media screen { -a { - order: 15; -} - } -@media screen and (min-width: 480px) { -a { - order: 16; -} - } -body:is(a) { - order: 17; -} -html body:is(a) { - order: 18; -} - -a.foo { - order: 19; -} - -.foo a.bar { - order: 20; -} - -a.foo b { - order: 21; -} - -.foo a.bar b { - order: 22; -} - -h1.foo, - h2.foo { - color: red; - } - -li+li { - background: red; - } - -.foo:where(h1) { - background: red; - } - -a b[a="a&b"] { - order: 31; - } - -.a.c::before, .b.c::before, .a.d::before, .b.d::before { - order: 41; - } - -.a:hover::before, .b:focus::before, .a:hover::after, .b:focus::after { - order: 51; - } - -/* leading : root */ -.comments { - /* leading : 1 */ - order: 61; - - /* leading : 4 */ - order: 64; - /* trailing: 2 */ -} -.comments .comment { - order: 62; - } -/* loose comment */ -.comments .comment { - order: 63; - } -/* trailing: 5 */ -/* nested deeper */ -.comments .comment .comment { - order: 65; - } - -::before.pseudo-element { - order: 71; -} - -::before .pseudo-element { - order: 71.1; -} - -:before.pseudo-element { - order: 72; -} - -:before .pseudo-element { - order: 72.1; -} - -.pseudo-element::after { - order: 73; -} - -.pseudo-element ::after { - order: 73.1; -} - -.pseudo-element:after { - order: 74; -} - -.pseudo-element :after { - order: 74.1; -} - -.has-semi-colons-on-the-last-decl { - order: 73; - /* a comment */ -} - -.has-semi-colons-on-the-last-decl .foo { - order: 73.1; - } - -.has-semi-colons-on-the-last-decl { - order: 74; - /* a comment */ -} - -.has-semi-colons-on-the-last-decl .foo { - order: 74.1; -} - -.mixed-declarations-and-rules--a { - - declaration: 1; -} - -.mixed-declarations-and-rules--a { - nested: 1; - } - -.mixed-declarations-and-rules--b { - declaration: 1; - - declaration: 2; - - declaration: 3; -} - -.mixed-declarations-and-rules--b { - nested: 1; - } - -@media screen { - -.mixed-declarations-and-rules--b { - nested: 2; - } - } - -.node-less-at-rule { - declaration: 1; - - declaration: 2; -} - -@layer foo; - - -/* at-rule.css */ -a { - order: 1; -} -b a { - order: 2; -} -c a { - order: 3; -} -d a { - order: 4; -} -e a { - order: 5; -} - -a { - order: 1; -} - -a b { - order: 2; -} - -a c { - order: 3; -} - -a d { - order: 4; -} - -a e { - order: 5; -} - -a[foo="& ,\'"] { - order: 6; -} - -a[a="& ,\'"][b='& . \\a &'] { - order: 7; -} - -a:is(\\foo) { - order: 8; -} - -h1.foo { - color: red; -} - -h1.foo, h2.foo { - color: red; -} - -.foo.bar { - color: red; -} - - -.foo.bar, .foo.baz { - color: red; -} - -h1.foo { - color: blue; -} - -h1.foo .baz h1 { - color: blue; -} - -h1.foo, h1.bar { - color: blue; -} - -article { - color: blue; -} - -:where(article) { - color: red; -} - -/* direct.css */ -a, -b { - order: 1; - - order: 5; -} -a c, - b c, - a d, - b d { - order: 2; - - order: 4; - } -a c e, - b c e, - a d e, - b d e, - a c f, - b c f, - a d f, - b d f { - order: 3; - } - -a, -b { - order: 1; -} - -a c, -b c, -a d, -b d { - order: 2; -} - -a c e, -b c e, -a d e, -b d e, -a c f, -b c f, -a d f, -b d f { - order: 3; -} - -a c, -b c, -a d, -b d { - - order: 4; -} - -a, -b { - - order: 5; -} - -a, -b { - order: 1; - - order: 5; -} - -a c, - b c, - a d, - b d { - order: 2; - - order: 4; - } - -a c e, - b c e, - a d e, - b d e, - a c f, - b c f, - a d f, - b d f { - order: 3; - } - -.a, -.b { - order: 6; -} - -.a .c, -.b .c, -.a .d, -.b .d { - order: 7; -} - -.a .c .e, -.b .c .e, -.a .d .e, -.b .d .e, -.a .c .f, -.b .c .f, -.a .d .f, -.b .d .f { - order: 8; -} - -.a .c, -.b .c, -.a .d, -.b .d { - - order: 9; -} - -.a, -.b { - - order: 10; -} - -/* empty.css */ -a b c { - order: 1; - } - -d { - order: 2; -} - -d e { - order: 3; - } - -f { - - order: 5; -} - -f g { - order: 4; - } - -a b c { - order: 1; -} - -d { - order: 2; -} - -d e { - order: 3; -} - -f g { - order: 4; -} - -f { - - order: 5; -} - -/* ignore.css */ -a, -b { - order: 1; -} -a c, - b c, - a d, - b d { - order: 2; - } - -:scope e { - order: 3; -} - -f:is(g) { - order: 5; - } - -a, -b { - order: 1; - - @nest c, - d { - order: 2; - } -} - -@nest & e { - order: 3; -} - -f:is(h) { - order: 5; -} - -f { - - @nest &|i { - order: 6; - } -} - -/* invalid-selector.css */ -.foo : bar { - &.child { - order: 1; - } -} - -.foo : bar { - @nest &.child { - order: 2; - } -} - -.foo { - &.child : bar { - order: 3; - } -} - -.foo { - @nest &.child : bar { - order: 4; - } -} - -/* media.css */ -a { - order: 1; -} -@media (min-width: 100px) { -a { - order: 2; -} - } -@media (min-width: 100px) and (max-width: 200px) { -a { - order: 3; -} - } -@media (min-width: 100px) and (max-width: 200px) { - - a b { - order: 4; - } - } -@media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { -a { - order: 5; -} - - a c { - order: 6; - } - } - -a { - order: 1; -} - -@media (min-width: 100px) { - -a { - order: 2; -} - } - -@media (min-width: 100px) and (max-width: 200px) { - -a { - order: 3; -} - } - -@media (min-width: 100px) and (max-width: 200px) { - -a b { - order: 4; -} - } - -@media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { - -a { - order: 5; -} - -a c { - order: 6; -} - } - -/* pseudo-element.css */ -.foo::before, ::before:focus { - order: 1; -} - -.a:hover::before, - .b:focus::before, - .a:hover::after, - .b:focus::after { - order: 2; - } - -.a::before { - order: 3; - } - -.a::after { - order: 4; - } - -.a::before { - order: 5; - } - -.a::before:focus { - order: 6; - } - -.a::after { - order: 7; - } - -.a::after:hover { - order: 8; - } - -.something_else>.anything::before { - order: 9; -} - -/* spec-examples.css */ -/* https://www.w3.org/TR/css-nesting-1/ */ - -/* Example 2 */ - -table.colortable td { - text-align: center; - } - -table.colortable td.c { - text-transform: uppercase - } - -table.colortable td:first-child, - table.colortable td:first-child+td { - border: 1px solid black - } - -table.colortable th { - text-align: center; - background: black; - color: white; - } - -/* Example 3 */ -/* & can be used on its own */ -.foo { - color: blue; -} -.foo>.bar { - color: red; - } - -/* equivalent to - .foo { color: blue; } - .foo > .bar { color: red; } -*/ - - -/* or in a compound selector, - refining the parent’s selector */ -.foo { - color: blue; -} -.foo.bar { - color: red; - } - -/* equivalent to - .foo { color: blue; } - .foo.bar { color: red; } -*/ - -/* multiple selectors in the list must all - start with & */ -.foo, -.bar { - color: blue; -} -.foo+.baz, - .bar+.baz, - .foo.qux, - .bar.qux { - color: red; - } - -/* equivalent to - .foo, .bar { color: blue; } - :is(.foo, .bar) + .baz, - :is(.foo, .bar).qux { color: red; } -*/ - -/* & can be used multiple times in a single selector */ -.foo { - color: blue; -} -.foo .bar .foo .baz .foo .qux { - color: red; - } - -/* equivalent to - .foo { color: blue; } - .foo .bar .foo .baz .foo .qux { color: red; } -*/ - -/* Somewhat silly, but can be used all on its own, as well. */ -.foo { - color: blue; -} -.foo { - padding: 2ch; - } - -/* equivalent to - .foo { color: blue; } - .foo { padding: 2ch; } - - // or - - .foo { - color: blue; - padding: 2ch; - } -*/ - -/* Again, silly, but can even be doubled up. */ -.foo { - color: blue; -} -.foo.foo { - padding: 2ch; - } - -/* equivalent to - .foo { color: blue; } - .foo.foo { padding: 2ch; } -*/ - -/* The parent selector can be arbitrarily complicated */ -.error:hover>.baz, #404:hover>.baz { - color: red; - } - -/* equivalent to - :is(.error, #404):hover > .baz { color: red; } -*/ - -/* As can the nested selector */ -.foo:is(.bar,.foo.baz) { - color: red; - } - -/* equivalent to - .foo:is(.bar, .foo.baz) { color: red; } -*/ - -/* Multiple levels of nesting "stack up" the selectors */ -figure { - margin: 0; -} -figure>figcaption { - background: hsl(0 0% 0% / 50%); - } -figure>figcaption>p { - font-size: .9rem; - } - -/* equivalent to - figure { margin: 0; } - figure > figcaption { background: hsl(0 0% 0% / 50%); } - figure > figcaption > p { font-size: .9rem; } -*/ - -/* No concatenation */ -.foo { - color: blue; -} -__bar.foo { - color: red; - } - -/* No & at all */ -.foo { - color: blue; -} -.foo .bar { - color: red; - } - -/* & isn’t the first simple selector */ -.foo { - color: blue; -} -.bar.foo { - color: red; - } - -/* & isn’t the first selector of every one in the list */ -.foo, -.bar { - color: blue; -} -.foo+.baz, - .bar+.baz, - .foo .qux, - .bar .qux { - color: red; - } - -/* Example 4 */ -.foo { - color: red; -} -.foo>.bar { - color: blue; -} - -/* equivalent to - .foo { color: red; } - .foo > .bar { color: blue; } -*/ - -.foo { - color: red; -} - -.parent .foo { - color: blue; -} - -/* equivalent to - .foo { color: red; } - .parent .foo { color: blue; } -*/ - -.foo { - color: red; -} - -:not(.foo) { - color: blue; -} - -/* equivalent to - .foo { color: red; } - :not(.foo) { color: blue; } -*/ - -.foo { - color: red; - - @nest .bar { - color: blue; - } -} - -/* Invalid because there’s no nesting selector */ - -.foo { - color: red; - - @nest & .bar, - .baz { - color: blue; - } -} - -/* Invalid because not all selectors in the list - contain a nesting selector */ - -/* Example 5 */ -.foo { - color: blue; -} -.bar .foo { - color: red; -} -.bar .foo.baz { - color: green; - } - -/* equivalent to - .foo { color: blue; } - .bar .foo { color: red; } - .bar .foo.baz { color: green; } -*/ - -/* Example 6 */ -/* Properties can be directly used */ -.foo { - display: grid; -} -@media (orientation: landscape) { -.foo { - grid-auto-flow: column; -} - } - -/* equivalent to - .foo { display: grid; } - - @media (orientation: landscape) { - & { - grid-auto-flow: column; - } - } -*/ - -/* finally equivalent to - .foo { display: grid; } - - @media (orientation: landscape) { - .foo { - grid-auto-flow: column; - } - } -*/ - -/* Conditionals can be further nested */ -.foo { - display: grid; -} -@media (orientation: landscape) { -.foo { - grid-auto-flow: column; -} - } -@media (orientation: landscape) and (min-inline-size > 1024px) { -.foo { - max-inline-size: 1024px; -} - } - -/* equivalent to - .foo { display: grid; } - - @media (orientation: landscape) { - .foo { - grid-auto-flow: column; - } - } - - @media (orientation: landscape) and (min-inline-size > 1024px) { - .foo { - max-inline-size: 1024px; - } - } -*/ - -.foo { - color: red; -} - -@media (min-width: 480px) { - - .foo h1, - .foo h2 { - color: blue; - } - } - -/* Invalid because not all selectors in the list - contain a nesting selector */ - -.foo { - color: red; - - @nest @media (min-width: 480px) { - & { - color: blue; - } - } -} - -/* Invalid because @nest expects a selector prelude, - instead a conditional group rule was provided */ - -/* Example 7 */ -article { - color: green; - - /* - NOTE : We are more forgiving than the spec - This declaration is preserved - */ - color: red; -} -article { - color: blue; - } - -article { - color: green; - - /* - NOTE : We are more forgiving than the spec - This declaration is preserved - */ - color: red; - - /* valid! */ -} - -article { - color: blue; - } - -article.foo { - color: yellow; - } diff --git a/plugins/postcss-nesting/test/at-nest.silent.expect.css b/plugins/postcss-nesting/test/at-nest.silent.expect.css index a56ab074d..01bc637e0 100644 --- a/plugins/postcss-nesting/test/at-nest.silent.expect.css +++ b/plugins/postcss-nesting/test/at-nest.silent.expect.css @@ -23,23 +23,25 @@ a { order: 3; } } -a b { +:is(a) b { order: 7; order: 9; } -a b c { +:is(:is(a) b) c { order: 8; } -body a { +a { + + @nest body & { order: 11; -} -html :is(body a) { + + @nest html & { order: 12; -} -body a { + } order: 13; + } } @media screen { a { @@ -51,51 +53,62 @@ a { order: 16; } } -body:is(a) { +a { + + @nest body& { order: 17; -} -html body:is(a) { + } + + @nest html body& { order: 18; + } } -a.foo { +a { + @nest .foo& { order: 19; -} + } -.foo a.bar { + @nest .foo .bar& { order: 20; + } } -.foo:is(a b) { +a b { + @nest .foo& { order: 21; -} + } -.foo .bar:is(a b) { + @nest .foo .bar& { order: 22; + } } -h1.foo, - h2.foo { +:is(.foo)h1, + :is(.foo)h2 { color: red; } -li+li { +:is(li)+:is(li) { background: red; } -.foo:where(h1) { +:is(.foo):where(h1) { background: red; } -a b[a="a&b"] { +:is(a) b[a="a&b"] { order: 31; } -.a.c::before, .b.c::before, .a.d::before, .b.d::before { +:is(:is(.a, +.b).c, + :is(.a, +.b).d)::before { order: 41; } -.a:hover::before, .b:focus::before, .a:hover::after, .b:focus::after { +:is(.a:hover, .b:focus)::before, :is(.a:hover, .b:focus)::after { order: 51; } @@ -108,49 +121,57 @@ a b[a="a&b"] { order: 64; /* trailing: 2 */ } -.comments .comment { +:is(.comments) .comment { order: 62; } /* loose comment */ -.comments .comment { +:is(.comments) .comment { order: 63; } /* trailing: 5 */ /* nested deeper */ -.comments .comment .comment { +:is(:is(.comments) .comment) .comment { order: 65; } -::before.pseudo-element { +.pseudo-element { + @nest ::before& { order: 71; -} + } -::before .pseudo-element { + @nest ::before & { order: 71.1; + } } -:before.pseudo-element { +.pseudo-element { + @nest :before& { order: 72; -} + } -:before .pseudo-element { + @nest :before & { order: 72.1; + } } -.pseudo-element::after { +.pseudo-element { + @nest &::after { order: 73; -} + } -.pseudo-element ::after { + @nest & ::after { order: 73.1; + } } -.pseudo-element:after { +.pseudo-element { + @nest &:after { order: 74; -} + } -.pseudo-element :after { + @nest & :after { order: 74.1; + } } .has-semi-colons-on-the-last-decl { @@ -158,17 +179,17 @@ a b[a="a&b"] { /* a comment */ } -.has-semi-colons-on-the-last-decl .foo { +:is(.has-semi-colons-on-the-last-decl) .foo { order: 73.1; } .has-semi-colons-on-the-last-decl { order: 74; /* a comment */ -} -.has-semi-colons-on-the-last-decl .foo { + @nest & .foo { order: 74.1; + } } .mixed-declarations-and-rules--a { @@ -176,7 +197,7 @@ a b[a="a&b"] { declaration: 1; } -.mixed-declarations-and-rules--a { +:is(.mixed-declarations-and-rules--a) { nested: 1; } @@ -188,7 +209,7 @@ a b[a="a&b"] { declaration: 3; } -.mixed-declarations-and-rules--b { +:is(.mixed-declarations-and-rules--b) { nested: 1; } @@ -196,7 +217,7 @@ a b[a="a&b"] { .mixed-declarations-and-rules--b { nested: 2; - } +} } .node-less-at-rule { @@ -211,87 +232,111 @@ a b[a="a&b"] { /* at-rule.css */ a { order: 1; -} -b a { + + @nest b & { order: 2; -} -c a { + } + + @nest c & { order: 3; -} -d a { + } + + @nest d & { order: 4; -} -e a { + } + + @nest e & { order: 5; + } } a { order: 1; -} -a b { + @nest & b { order: 2; -} + } -a c { + @nest & c { order: 3; -} + } -a d { + @nest & d { order: 4; -} + } -a e { + @nest & e { order: 5; -} + } -a[foo="& ,\'"] { + @nest &[foo="& ,\'"] { order: 6; -} + } -a[a="& ,\'"][b='& . \\a &'] { + @nest &[a="& ,\'"][b='& . \\a &'] { order: 7; -} + } -a:is(\\foo) { + @nest &\\foo { order: 8; + } } -h1.foo { +.foo { + @nest &h1 { color: red; + } } -h1.foo, h2.foo { +.foo { + + @nest &h1, + &h2 { color: red; + } } -.foo.bar { +.foo { + @nest &.bar { color: red; + } } -.foo.bar, .foo.baz { +.foo { + + @nest &.bar, + &.baz { color: red; + } } -h1.foo { +h1 { + @nest .foo& { color: blue; + } } -h1.foo .baz h1 { +h1 { + @nest .foo& .baz & { color: blue; + } } -h1.foo, h1.bar { +h1 { + + @nest .foo&, + .bar& { color: blue; + } } article { color: blue; -} -:where(article) { + @nest :where(&) { color: red; + } } /* direct.css */ @@ -301,58 +346,40 @@ b { order: 5; } -a c, - b c, - a d, - b d { +:is(a, +b) c, + :is(a, +b) d { order: 2; order: 4; } -a c e, - b c e, - a d e, - b d e, - a c f, - b c f, - a d f, - b d f { +:is(:is(a, +b) c, + :is(a, +b) d) e, + :is(:is(a, +b) c, + :is(a, +b) d) f { order: 3; } a, b { order: 1; -} -a c, -b c, -a d, -b d { + @nest & c, + & d { order: 2; -} -a c e, -b c e, -a d e, -b d e, -a c f, -b c f, -a d f, -b d f { + @nest & e, + & f { order: 3; -} - -a c, -b c, -a d, -b d { + } order: 4; -} - -a, -b { + } order: 5; } @@ -364,65 +391,47 @@ b { order: 5; } -a c, - b c, - a d, - b d { +:is(a, +b) c, + :is(a, +b) d { order: 2; order: 4; } -a c e, - b c e, - a d e, - b d e, - a c f, - b c f, - a d f, - b d f { +:is(:is(a, +b) c, + :is(a, +b) d) e, + :is(:is(a, +b) c, + :is(a, +b) d) f { order: 3; } .a, .b { order: 6; -} -.a .c, -.b .c, -.a .d, -.b .d { + @nest & .c, + & .d { order: 7; -} -.a .c .e, -.b .c .e, -.a .d .e, -.b .d .e, -.a .c .f, -.b .c .f, -.a .d .f, -.b .d .f { + @nest & .e, + & .f { order: 8; -} - -.a .c, -.b .c, -.a .d, -.b .d { + } order: 9; -} - -.a, -.b { + } order: 10; } /* empty.css */ -a b c { +:is(:is(a) b) c { order: 1; } @@ -430,7 +439,7 @@ d { order: 2; } -d e { +:is(d) e { order: 3; } @@ -439,27 +448,30 @@ f { order: 5; } -f g { +:is(f) g { order: 4; } -a b c { +a { + @nest & b { + @nest & c { order: 1; + } + } } d { order: 2; -} -d e { + @nest & e { order: 3; -} - -f g { - order: 4; + } } f { + @nest & g { + order: 4; + } order: 5; } @@ -469,10 +481,10 @@ a, b { order: 1; } -a c, - b c, - a d, - b d { +:is(a, +b) c, + :is(a, +b) d { order: 2; } @@ -480,7 +492,7 @@ a c, order: 3; } -f:is(g) { +:is(f)g { order: 5; } @@ -498,11 +510,10 @@ b { order: 3; } -f:is(h) { - order: 5; -} - f { + @nest &h { + order: 5; + } @nest &|i { order: 6; @@ -550,7 +561,7 @@ a { } @media (min-width: 100px) and (max-width: 200px) { - a b { + :is(a) b { order: 4; } } @@ -559,7 +570,7 @@ a { order: 5; } - a c { + :is(a) c { order: 6; } } @@ -582,62 +593,73 @@ a { } } -@media (min-width: 100px) and (max-width: 200px) { +@media (min-width: 100px) { -a b { +a { + + @nest & b { + @media (max-width: 200px) { order: 4; -} } + } +} + } @media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { a { order: 5; -} -a c { + @nest & c { order: 6; + } } } /* pseudo-element.css */ -.foo::before, ::before:focus { +::before { + + @nest .foo&, + &:focus { order: 1; + } } -.a:hover::before, - .b:focus::before, - .a:hover::after, - .b:focus::after { +:is(.a:hover, +.b:focus)::before, + :is(.a:hover, +.b:focus)::after { order: 2; } -.a::before { +:is(.a)::before { order: 3; } -.a::after { +:is(.a)::after { order: 4; } -.a::before { +:is(.a)::before { order: 5; } -.a::before:focus { +:is(:is(.a)::before):focus { order: 6; } -.a::after { +:is(.a)::after { order: 7; } -.a::after:hover { +:is(:is(.a)::after):hover { order: 8; } -.something_else>.anything::before { +.anything::before { + @nest .something_else>& { order: 9; + } } /* spec-examples.css */ @@ -645,20 +667,20 @@ a c { /* Example 2 */ -table.colortable td { +:is(table.colortable) td { text-align: center; } -table.colortable td.c { +:is(:is(table.colortable) td).c { text-transform: uppercase } -table.colortable td:first-child, - :is(table.colortable td):first-child+td { +:is(:is(table.colortable) td):first-child, + :is(:is(table.colortable) td):first-child+td { border: 1px solid black } -table.colortable th { +:is(table.colortable) th { text-align: center; background: black; color: white; @@ -669,7 +691,7 @@ table.colortable th { .foo { color: blue; } -.foo>.bar { +:is(.foo)>.bar { color: red; } @@ -684,7 +706,7 @@ table.colortable th { .foo { color: blue; } -.foo.bar { +:is(.foo).bar { color: red; } @@ -699,10 +721,10 @@ table.colortable th { .bar { color: blue; } -.foo+.baz, - .bar+.baz, - .foo.qux, - .bar.qux { +:is(.foo, +.bar)+.baz, + :is(.foo, +.bar).qux { color: red; } @@ -716,7 +738,7 @@ table.colortable th { .foo { color: blue; } -.foo .bar .foo .baz .foo .qux { +:is(.foo) .bar :is(.foo) .baz :is(.foo) .qux { color: red; } @@ -729,7 +751,7 @@ table.colortable th { .foo { color: blue; } -.foo { +:is(.foo) { padding: 2ch; } @@ -749,7 +771,7 @@ table.colortable th { .foo { color: blue; } -.foo.foo { +:is(.foo):is(.foo) { padding: 2ch; } @@ -759,7 +781,8 @@ table.colortable th { */ /* The parent selector can be arbitrarily complicated */ -:is(.error,#404):hover>.baz { +:is(.error, +#404):hover>.baz { color: red; } @@ -768,7 +791,7 @@ table.colortable th { */ /* As can the nested selector */ -.foo:is(.bar,.foo.baz) { +:is(.foo):is(.bar,:is(.foo).baz) { color: red; } @@ -780,10 +803,10 @@ table.colortable th { figure { margin: 0; } -figure>figcaption { +:is(figure)>figcaption { background: hsl(0 0% 0% / 50%); } -figure>figcaption>p { +:is(:is(figure)>figcaption)>p { font-size: .9rem; } @@ -797,7 +820,7 @@ figure>figcaption>p { .foo { color: blue; } -__bar.foo { +:is(.foo)__bar { color: red; } @@ -805,7 +828,7 @@ __bar.foo { .foo { color: blue; } -.foo .bar { +:is(.foo) .bar { color: red; } @@ -813,7 +836,7 @@ __bar.foo { .foo { color: blue; } -.bar.foo { +.bar:is(.foo) { color: red; } @@ -822,19 +845,20 @@ __bar.foo { .bar { color: blue; } -.foo+.baz, - .bar+.baz, - .foo .qux, - .bar .qux { +:is(.foo, +.bar)+.baz, + :is(.foo, +.bar) .qux { color: red; } /* Example 4 */ .foo { color: red; -} -.foo>.bar { + + @nest &>.bar { color: blue; + } } /* equivalent to @@ -844,10 +868,10 @@ __bar.foo { .foo { color: red; -} -.parent .foo { + @nest .parent & { color: blue; + } } /* equivalent to @@ -857,10 +881,10 @@ __bar.foo { .foo { color: red; -} -:not(.foo) { + @nest :not(&) { color: blue; + } } /* equivalent to @@ -893,13 +917,15 @@ __bar.foo { /* Example 5 */ .foo { color: blue; -} -.bar .foo { + + @nest .bar & { color: red; -} -.bar .foo.baz { + + &.baz { color: green; } + } +} /* equivalent to .foo { color: blue; } @@ -975,8 +1001,8 @@ __bar.foo { @media (min-width: 480px) { - .foo h1, - .foo h2 { + :is(.foo) h1, + :is(.foo) h2 { color: blue; } } @@ -1007,7 +1033,7 @@ article { */ color: red; } -article { +:is(article) { color: blue; } @@ -1023,10 +1049,10 @@ article { /* valid! */ } -article { +:is(article) { color: blue; } -article.foo { +:is(article).foo { color: yellow; } diff --git a/plugins/postcss-nesting/test/basic.css b/plugins/postcss-nesting/test/basic.css index 2c44eea38..efdd2b735 100644 --- a/plugins/postcss-nesting/test/basic.css +++ b/plugins/postcss-nesting/test/basic.css @@ -242,3 +242,45 @@ h1 { background-color: transparent; } } + +.foo { /* simple */ + :has(&) { /* simple */ + color: green; + } +} + +.foo .bar { /* complex */ + :has(&) { /* simple */ + color: green; + } +} + +.foo { /* simple */ + :has(& .fooz) { /* complex */ + color: green; + } +} + +.foo .bar { /* complex */ + :has(& .fooz) { /* complex */ + color: green; + } +} + +.foo .bar { /* complex */ + :has(.fooz .bar, &) { /* complex + list */ + color: green; + } +} + +.foo .bar, .baz { /* complex + list */ + :has(.fooz .bar, &) { /* complex + list */ + color: green; + } +} + +::before { + &:hover { + color: red; + } +} diff --git a/plugins/postcss-nesting/test/basic.expect.css b/plugins/postcss-nesting/test/basic.expect.css index 324f548b9..a44b41065 100644 --- a/plugins/postcss-nesting/test/basic.expect.css +++ b/plugins/postcss-nesting/test/basic.expect.css @@ -31,7 +31,7 @@ a b { order: 9; } -a b c { +:is(a b) c { order: 8; } @@ -83,12 +83,11 @@ a.foo { order: 22; } -h1.foo, - h2.foo { +h1.foo,h2.foo { color: red; } -li+li { +li + li { background: red; } @@ -100,11 +99,11 @@ a b[a="a&b"] { order: 31; } -.a.c::before, .b.c::before, .a.d::before, .b.d::before { +:is(.c:is(.a,.b),.d:is(.a,.b))::before { order: 41; } -.a:hover::before, .b:focus::before, .a:hover::after, .b:focus::after { +:is(.a:hover,.b:focus)::before,:is(.a:hover,.b:focus)::after { order: 51; } @@ -126,7 +125,7 @@ a b[a="a&b"] { } /* trailing: 5 */ /* nested deeper */ -.comments .comment .comment { +:is(.comments .comment) .comment { order: 65; } @@ -227,3 +226,43 @@ h1 { background-color: transparent; } } + +/* simple */ + +:has(:is(.foo)) { /* simple */ + color: green; + } + +/* complex */ + +:has(:is(.foo .bar)) { /* simple */ + color: green; + } + +/* simple */ + +:has(:is(.foo) .fooz) { /* complex */ + color: green; + } + +/* complex */ + +:has(:is(.foo .bar) .fooz) { /* complex */ + color: green; + } + +/* complex */ + +:has(.fooz .bar,:is(.foo .bar)) { /* complex + list */ + color: green; + } + +/* complex + list */ + +:has(.fooz .bar,:is(.foo .bar,.baz)) { /* complex + list */ + color: green; + } + +:is(::before):hover { + color: red; + } diff --git a/plugins/postcss-nesting/test/basic.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/basic.no-is-pseudo-selector.expect.css deleted file mode 100644 index 92243f6c1..000000000 --- a/plugins/postcss-nesting/test/basic.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,229 +0,0 @@ -a { - order: 1; - - order: 5; - order: 6; - - order: 10; - - order: 14; -} - -@media screen, print { - -a { - order: 2; - - order: 4; -} - } - -@media screen and (min-width: 480px), print and (min-width: 480px) { - -a { - order: 3; -} - } - -a b { - order: 7; - - order: 9; - } - -a b c { - order: 8; - } - -body a { - order: 11; - - order: 13; - } - -html body a { - order: 12; - } - -@media screen { - -a { - order: 15; -} - } - -@media screen and (min-width: 480px) { - -a { - order: 16; -} - } - -body:is(a) { - order: 17; - } - -html body:is(a) { - order: 18; - } - -a.foo { - order: 19; - } - -.foo a.bar { - order: 20; - } - -a.foo b { - order: 21; - } - -.foo a.bar b { - order: 22; - } - -h1.foo, - h2.foo { - color: red; - } - -li+li { - background: red; - } - -.foo:where(h1) { - background: red; - } - -a b[a="a&b"] { - order: 31; - } - -.a.c::before, .b.c::before, .a.d::before, .b.d::before { - order: 41; - } - -.a:hover::before, .b:focus::before, .a:hover::after, .b:focus::after { - order: 51; - } - -/* leading : root */ -.comments { - /* leading : 1 */ - order: 61; - - /* leading : 4 */ - order: 64; - /* trailing: 2 */ -} -.comments .comment { - order: 62; - } -/* loose comment */ -.comments .comment { - order: 63; - } -/* trailing: 5 */ -/* nested deeper */ -.comments .comment .comment { - order: 65; - } - -::before.pseudo-element { - order: 71; - } - -::before .pseudo-element { - order: 71.1; - } - -:before.pseudo-element { - order: 72; - } - -:before .pseudo-element { - order: 72.1; - } - -.pseudo-element::after { - order: 73; - } - -.pseudo-element ::after { - order: 73.1; - } - -.pseudo-element:after { - order: 74; - } - -.pseudo-element :after { - order: 74.1; - } - -.has-semi-colons-on-the-last-decl { - order: 73; - /* a comment */ -} - -.has-semi-colons-on-the-last-decl .foo { - order: 73.1; - } - -.has-semi-colons-on-the-last-decl { - order: 74; - /* a comment */ -} - -.has-semi-colons-on-the-last-decl .foo { - order: 74.1; - } - -.mixed-declarations-and-rules--a { - - declaration: 1; -} - -.mixed-declarations-and-rules--a { - nested: 1; - } - -.mixed-declarations-and-rules--b { - declaration: 1; - - declaration: 2; - - declaration: 3; -} - -.mixed-declarations-and-rules--b { - nested: 1; - } - -@media screen { - -.mixed-declarations-and-rules--b { - nested: 2; - } - } - -.node-less-at-rule { - declaration: 1; - - declaration: 2; -} - -@layer foo; - -h1 { - transition: background-color 1.5s; - background-color: green; -} - -@starting-style { - -h1 { - background-color: transparent; -} - } diff --git a/plugins/postcss-nesting/test/complex.expect.css b/plugins/postcss-nesting/test/complex.expect.css index 75d7c290e..167fcf3b3 100644 --- a/plugins/postcss-nesting/test/complex.expect.css +++ b/plugins/postcss-nesting/test/complex.expect.css @@ -3,51 +3,37 @@ body > p, body > ul { } -:is(body > p) ~ :is(body > p), :is(body > p) ~ :is(body > ul), :is(body > ul) ~ :is(body > p), :is(body > ul) ~ :is(body > ul) { +:is(body > p,body > ul) ~ :is(body > p,body > ul) { order: 2; } -:is(body > p) ~ :is(body > p):hover, - :is(body > p) ~ :is(body > ul):hover, - :is(body > ul) ~ :is(body > p):hover, - :is(body > ul) ~ :is(body > ul):hover, - :is(body > p) ~ :is(body > p):focus, - :is(body > p) ~ :is(body > ul):focus, - :is(body > ul) ~ :is(body > p):focus, - :is(body > ul) ~ :is(body > ul):focus { +:is(:is(body > p,body > ul) ~ :is(body > p,body > ul)):hover,:is(:is(body > p,body > ul) ~ :is(body > p,body > ul)):focus { order: 3; } -:is(body > p) ~ :is(body > p) *:hover, - :is(body > p) ~ :is(body > ul) *:hover, - :is(body > ul) ~ :is(body > p) *:hover, - :is(body > ul) ~ :is(body > ul) *:hover, - :is(body > p) ~ :is(body > p) *:focus, - :is(body > p) ~ :is(body > ul) *:focus, - :is(body > ul) ~ :is(body > p) *:focus, - :is(body > ul) ~ :is(body > ul) *:focus { +:is(:is(body > p,body > ul) ~ :is(body > p,body > ul)) *:hover,:is(:is(body > p,body > ul) ~ :is(body > p,body > ul)) *:focus { order: 4; } -body > p > *:hover, body > ul > *:hover { +:is(body > p,body > ul) > *:hover { order: 5; } -body > p :is(body > p), body > p :is(body > ul), body > ul :is(body > p), body > ul :is(body > ul) { +:is(body > p,body > ul) :is(body > p,body > ul) { order: 6; } -body > p:is(body > p), body > p:is(body > ul), body > ul:is(body > p), body > ul:is(body > ul) { +:is(body > p,body > ul):is(body > p,body > ul) { order: 7; } -body > p:is(body > p):is(body > p), body > p:is(body > p):is(body > ul), body > p:is(body > ul):is(body > p), body > p:is(body > ul):is(body > ul), body > ul:is(body > p):is(body > p), body > ul:is(body > p):is(body > ul), body > ul:is(body > ul):is(body > p), body > ul:is(body > ul):is(body > ul) { +:is(body > p,body > ul):is(body > p,body > ul):is(body > p,body > ul) { order: 8; } @@ -57,24 +43,22 @@ body > p, body > .foo { } -:is(body > p,body > .foo)~:is(body > p,body > .foo) { +:is(body > p,body > .foo) ~ :is(body > p,body > .foo) { order: 102; } -:is(body > p,body > .foo)~:is(body > p,body > .foo):hover, - :is(body > p,body > .foo)~:is(body > p,body > .foo):focus { +:is(:is(body > p,body > .foo) ~ :is(body > p,body > .foo)):hover,:is(:is(body > p,body > .foo) ~ :is(body > p,body > .foo)):focus { order: 103; } -:is(body > p,body > .foo)~:is(body > p,body > .foo) *:hover, - :is(body > p,body > .foo)~:is(body > p,body > .foo) *:focus { +:is(:is(body > p,body > .foo) ~ :is(body > p,body > .foo)) *:hover,:is(:is(body > p,body > .foo) ~ :is(body > p,body > .foo)) *:focus { order: 104; } -:is(body > p,body > .foo)>*:hover { +:is(body > p,body > .foo) > *:hover { order: 105; } @@ -88,6 +72,6 @@ body > p, body > .foo { order: 107; } -body.foo + body.foo, body.foo + html.baz, html.baz + body.foo, html.baz + html.baz { +:is(body.foo,html.baz) + :is(body.foo,html.baz) { order: 201; } diff --git a/plugins/postcss-nesting/test/complex.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/complex.no-is-pseudo-selector.expect.css deleted file mode 100644 index 0198fec47..000000000 --- a/plugins/postcss-nesting/test/complex.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,105 +0,0 @@ -body > p, body > ul { - order: 1; -} - - -body > p ~ body > p, body > p ~ body > ul, body > ul ~ body > p, body > ul ~ body > ul { - order: 2; - } - - -body > p ~ body > p:hover, - body > p ~ body > ul:hover, - body > ul ~ body > p:hover, - body > ul ~ body > ul:hover, - body > p ~ body > p:focus, - body > p ~ body > ul:focus, - body > ul ~ body > p:focus, - body > ul ~ body > ul:focus { - order: 3; - } - - -body > p ~ body > p *:hover, - body > p ~ body > ul *:hover, - body > ul ~ body > p *:hover, - body > ul ~ body > ul *:hover, - body > p ~ body > p *:focus, - body > p ~ body > ul *:focus, - body > ul ~ body > p *:focus, - body > ul ~ body > ul *:focus { - order: 4; - } - - -body > p > *:hover, body > ul > *:hover { - order: 5; - } - - -body > p body > p, body > p body > ul, body > ul body > p, body > ul body > ul { - order: 6; - } - - -body > p:is(body) > p, body > p:is(body) > ul, body > ul:is(body) > p, body > ul:is(body) > ul { - order: 7; - } - - -body > p:is(body) > p:is(body) > p, body > p:is(body) > p:is(body) > ul, body > p:is(body) > ul:is(body) > p, body > p:is(body) > ul:is(body) > ul, body > ul:is(body) > p:is(body) > p, body > ul:is(body) > p:is(body) > ul, body > ul:is(body) > ul:is(body) > p, body > ul:is(body) > ul:is(body) > ul { - order: 8; - } - - -body > p, body > .foo { - order: 101; -} - - -body > p~body > p, body > p~body > .foo, body > .foo~body > p, body > .foo~body > .foo { - order: 102; - } - - -body > p~body > p:hover, - body > p~body > .foo:hover, - body > .foo~body > p:hover, - body > .foo~body > .foo:hover, - body > p~body > p:focus, - body > p~body > .foo:focus, - body > .foo~body > p:focus, - body > .foo~body > .foo:focus { - order: 103; - } - - -body > p~body > p *:hover, - body > p~body > .foo *:hover, - body > .foo~body > p *:hover, - body > .foo~body > .foo *:hover, - body > p~body > p *:focus, - body > p~body > .foo *:focus, - body > .foo~body > p *:focus, - body > .foo~body > .foo *:focus { - order: 104; - } - - -body > p>*:hover, body > .foo>*:hover { - order: 105; - } - - -body > p:is(body) > p, body > p:is(body) > .foo, body > body.foo > p, body > body.foo > .foo { - order: 106; - } - - -body > p:is(body) > p:is(body) > p, body > p:is(body) > p:is(body) > .foo, body > p:is(body) > body.foo > p, body > p:is(body) > body.foo > .foo, body > body.foo > p:is(body) > p, body > body.foo > p:is(body) > .foo, body > body.foo > body.foo > p, body > body.foo > body.foo > .foo { - order: 107; - } - -body.foo + body.foo, body.foo + html.baz, html.baz + body.foo, html.baz + html.baz { - order: 201; - } diff --git a/plugins/postcss-nesting/test/container.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/container.no-is-pseudo-selector.expect.css deleted file mode 100644 index 02aca6262..000000000 --- a/plugins/postcss-nesting/test/container.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,16 +0,0 @@ -.container { - contain: layout inline-size; -} - -.contained { - background-color: blue; - height: 100px; - width: 100px; -} - -@container (min-width: 640px) { - -.contained { - background-color: red; -} - } diff --git a/plugins/postcss-nesting/test/direct.expect.css b/plugins/postcss-nesting/test/direct.expect.css index 617833d48..3b5c7cbcc 100644 --- a/plugins/postcss-nesting/test/direct.expect.css +++ b/plugins/postcss-nesting/test/direct.expect.css @@ -2,22 +2,22 @@ a, b { order: 1; order: 5; } -a c, b c, a d, b d { +:is(a,b) c,:is(a,b) d { order: 2; order: 4; } -a c e, b c e, a d e, b d e, a c f, b c f, a d f, b d f { +:is(:is(a,b) c,:is(a,b) d) e,:is(:is(a,b) c,:is(a,b) d) f { order: 3; } a, b { order: 1; order: 5; } -a c, b c, a d, b d { +:is(a,b) c,:is(a,b) d { order: 2; order: 4; } -a c e, b c e, a d e, b d e, a c f, b c f, a d f, b d f { +:is(:is(a,b) c,:is(a,b) d) e,:is(:is(a,b) c,:is(a,b) d) f { order: 3; } @@ -28,23 +28,13 @@ b { order: 5; } -a c, - b c, - a d, - b d { +:is(a,b) c,:is(a,b) d { order: 2; order: 4; } -a c e, - b c e, - a d e, - b d e, - a c f, - b c f, - a d f, - b d f { +:is(:is(a,b) c,:is(a,b) d) e,:is(:is(a,b) c,:is(a,b) d) f { order: 3; } @@ -55,22 +45,12 @@ a c e, order: 10; } -.a .c, - .b .c, - .a .d, - .b .d { +:is(.a,.b) .c,:is(.a,.b) .d { order: 7; order: 9; } -.a .c .e, - .b .c .e, - .a .d .e, - .b .d .e, - .a .c .f, - .b .c .f, - .a .d .f, - .b .d .f { +:is(:is(.a,.b) .c,:is(.a,.b) .d) .e,:is(:is(.a,.b) .c,:is(.a,.b) .d) .f { order: 8; } diff --git a/plugins/postcss-nesting/test/direct.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/direct.no-is-pseudo-selector.expect.css deleted file mode 100644 index 617833d48..000000000 --- a/plugins/postcss-nesting/test/direct.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,76 +0,0 @@ -a, b { - order: 1; - order: 5; -} -a c, b c, a d, b d { - order: 2; - order: 4; - } -a c e, b c e, a d e, b d e, a c f, b c f, a d f, b d f { - order: 3; - } -a, b { - order: 1; - order: 5; -} -a c, b c, a d, b d { - order: 2; - order: 4; - } -a c e, b c e, a d e, b d e, a c f, b c f, a d f, b d f { - order: 3; - } - -a, -b { - order: 1; - - order: 5; -} - -a c, - b c, - a d, - b d { - order: 2; - - order: 4; - } - -a c e, - b c e, - a d e, - b d e, - a c f, - b c f, - a d f, - b d f { - order: 3; - } - -.a, -.b { - order: 6; - - order: 10; -} - -.a .c, - .b .c, - .a .d, - .b .d { - order: 7; - - order: 9; - } - -.a .c .e, - .b .c .e, - .a .d .e, - .b .d .e, - .a .c .f, - .b .c .f, - .a .d .f, - .b .d .f { - order: 8; - } diff --git a/plugins/postcss-nesting/test/document.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/document.no-is-pseudo-selector.expect.css deleted file mode 100644 index 2303b3dcf..000000000 --- a/plugins/postcss-nesting/test/document.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,8 +0,0 @@ -a { - order: 1; -} -@document url("https://www.example.com/") { - a { - order: 2; -} - } diff --git a/plugins/postcss-nesting/test/empty.expect.css b/plugins/postcss-nesting/test/empty.expect.css index 9892800a9..360f32f88 100644 --- a/plugins/postcss-nesting/test/empty.expect.css +++ b/plugins/postcss-nesting/test/empty.expect.css @@ -1,5 +1,5 @@ - a b c { + :is(a b) c { order: 1; } d { @@ -14,7 +14,7 @@ f { f g { order: 4; } -a b c { +:is(a b) c { order: 1; } d { diff --git a/plugins/postcss-nesting/test/empty.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/empty.no-is-pseudo-selector.expect.css deleted file mode 100644 index 9892800a9..000000000 --- a/plugins/postcss-nesting/test/empty.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,31 +0,0 @@ - - a b c { - order: 1; - } -d { - order: 2; -} -d e { - order: 3; - } -f { - order: 5; -} -f g { - order: 4; - } -a b c { - order: 1; - } -d { - order: 2; -} -d e { - order: 3; - } -f { - order: 5; -} -f g { - order: 4; - } diff --git a/plugins/postcss-nesting/test/examples/example.expect.css b/plugins/postcss-nesting/test/examples/example.expect.css index c2de30e41..94b8f30cc 100644 --- a/plugins/postcss-nesting/test/examples/example.expect.css +++ b/plugins/postcss-nesting/test/examples/example.expect.css @@ -4,7 +4,7 @@ .foo:hover { color: green; } -.foo > .bar { +.foo > .bar { color: blue; } @media (prefers-color-scheme: dark) { diff --git a/plugins/postcss-nesting/test/ignore.expect.css b/plugins/postcss-nesting/test/ignore.expect.css index 32dcf5863..92c5a47e5 100644 --- a/plugins/postcss-nesting/test/ignore.expect.css +++ b/plugins/postcss-nesting/test/ignore.expect.css @@ -1,7 +1,7 @@ a, b { order: 1; } -a c, b c, a d, b d { +:is(a,b) c,:is(a,b) d { order: 2; } :scope e { @@ -13,7 +13,7 @@ f:is(g) { a, b { order: 1; } -a c, b c, a d, b d { +:is(a,b) c,:is(a,b) d { order: 2; } :scope e { diff --git a/plugins/postcss-nesting/test/ignore.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/ignore.no-is-pseudo-selector.expect.css deleted file mode 100644 index 32dcf5863..000000000 --- a/plugins/postcss-nesting/test/ignore.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,29 +0,0 @@ -a, b { - order: 1; -} -a c, b c, a d, b d { - order: 2; - } -:scope e { - order: 3; -} -f:is(g) { - order: 5; - } -a, b { - order: 1; -} -a c, b c, a d, b d { - order: 2; - } -:scope e { - order: 3; -} -f:is(h) { - order: 5; - } -f { - &|i { - order: 6; - } -} diff --git a/plugins/postcss-nesting/test/media.css b/plugins/postcss-nesting/test/media.css index 79d72086e..42a5f0c4c 100644 --- a/plugins/postcss-nesting/test/media.css +++ b/plugins/postcss-nesting/test/media.css @@ -11,7 +11,7 @@ a { } } } - @media screen, print and speech { + @media screen, print and (width) { @media (max-width: 300px), (min-aspect-ratio: 16/9) { order: 5; & c { @@ -33,7 +33,7 @@ a { } } } - @media screen, print and speech { + @media screen, print and (width) { @media (max-width: 300px), (min-aspect-ratio: 16/9) { order: 5; & c { @@ -42,3 +42,11 @@ a { } } } + +#foo, div { + color: green; + + @media screen and (min-width: 100px) { + color: red; + } +} diff --git a/plugins/postcss-nesting/test/media.expect.css b/plugins/postcss-nesting/test/media.expect.css index 46bbaa778..eec82ac96 100644 --- a/plugins/postcss-nesting/test/media.expect.css +++ b/plugins/postcss-nesting/test/media.expect.css @@ -12,11 +12,11 @@ a { } } @media (min-width: 100px) and (max-width: 200px) { - a b { + :is(a b) { order: 4; } } -@media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { +@media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and (width) and (max-width: 300px), print and (width) and (min-aspect-ratio: 16/9) { a { order: 5; } @@ -38,11 +38,11 @@ a { } } @media (min-width: 100px) and (max-width: 200px) { - a b { + :is(a b) { order: 4; } } -@media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { +@media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and (width) and (max-width: 300px), print and (width) and (min-aspect-ratio: 16/9) { a { order: 5; } @@ -50,3 +50,14 @@ a { order: 6; } } + +#foo, div { + color: green; +} + +@media screen and (min-width: 100px) { + +:is(#foo,div) { + color: red; +} + } diff --git a/plugins/postcss-nesting/test/media.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/media.no-is-pseudo-selector.expect.css deleted file mode 100644 index 46bbaa778..000000000 --- a/plugins/postcss-nesting/test/media.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,52 +0,0 @@ -a { - order: 1; -} -@media (min-width: 100px) { -a { - order: 2; -} - } -@media (min-width: 100px) and (max-width: 200px) { -a { - order: 3; -} - } -@media (min-width: 100px) and (max-width: 200px) { - a b { - order: 4; - } - } -@media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { -a { - order: 5; -} - a c { - order: 6; - } - } -a { - order: 1; -} -@media (min-width: 100px) { -a { - order: 2; -} - } -@media (min-width: 100px) and (max-width: 200px) { -a { - order: 3; -} - } -@media (min-width: 100px) and (max-width: 200px) { - a b { - order: 4; - } - } -@media screen and (max-width: 300px), screen and (min-aspect-ratio: 16/9), print and speech and (max-width: 300px), print and speech and (min-aspect-ratio: 16/9) { -a { - order: 5; -} - a c { - order: 6; - } - } diff --git a/plugins/postcss-nesting/test/mixin-declaration.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/mixin-declaration.no-is-pseudo-selector.expect.css deleted file mode 100644 index 2576e5d1c..000000000 --- a/plugins/postcss-nesting/test/mixin-declaration.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,70 +0,0 @@ -/* prevent regressions : https://github.com/csstools/postcss-nesting/issues/95 */ -body {color: blue; - - background: red; - font-size: 1rem; - - margin: 0; -} -@media (min-width: 64em) { -body { - background: green; -} - } - - -:root { - /* a comment */color: blue; - - background: red; - font-size: 1rem; - - margin: 0; -} - - -@media (min-width: 64em) { - - -:root { - background: green; -} - } - -html { - color: pink;color: blue; - - background: red; - font-size: 1rem; - - margin: 0; -} - -@media (min-width: 64em) { - -html { - background: green; -} - } - -.other { - - background: red; - font-size: 1rem; - - margin: 0; -} - -.other .a-rule { - color: cyan; - } - -.other {color: blue; -} - -@media (min-width: 64em) { - -.other { - background: green; -} - } diff --git a/plugins/postcss-nesting/test/mixin-rule.expect.css b/plugins/postcss-nesting/test/mixin-rule.expect.css index a00c7325e..d591e870a 100644 --- a/plugins/postcss-nesting/test/mixin-rule.expect.css +++ b/plugins/postcss-nesting/test/mixin-rule.expect.css @@ -3,7 +3,7 @@ color: red; } -a .in.deep { color: blue; } +.deep:is(a .in) { color: blue; } /* a comment */ @@ -11,4 +11,4 @@ f g { color: red; } -f .in.deep { color: blue; } +.deep:is(f .in) { color: blue; } diff --git a/plugins/postcss-nesting/test/mixin-rule.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/mixin-rule.no-is-pseudo-selector.expect.css deleted file mode 100644 index a00c7325e..000000000 --- a/plugins/postcss-nesting/test/mixin-rule.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,14 +0,0 @@ - - a b { - color: red; - } - -a .in.deep { color: blue; } - -/* a comment */ - -f g { - color: red; - } - -f .in.deep { color: blue; } diff --git a/plugins/postcss-nesting/test/pseudo-element.expect.css b/plugins/postcss-nesting/test/pseudo-element.expect.css index 50617a3b3..cf4bb5ef5 100644 --- a/plugins/postcss-nesting/test/pseudo-element.expect.css +++ b/plugins/postcss-nesting/test/pseudo-element.expect.css @@ -1,9 +1,9 @@ - .foo::before, ::before:focus { + .foo:is(::before),:is(::before):focus { order: 1; } -.a:hover::before, .b:focus::before, .a:hover::after, .b:focus::after { +:is(.a:hover,.b:focus)::before,:is(.a:hover,.b:focus)::after { order: 2; } @@ -19,7 +19,7 @@ order: 5; } -.a::before:focus { +:is(.a::before):focus { order: 6; } @@ -27,10 +27,10 @@ order: 7; } -.a::after:hover { +:is(.a::after):hover { order: 8; } -.something_else > .anything::before { +.something_else > :is(.anything::before) { order: 9; } diff --git a/plugins/postcss-nesting/test/relative-selectors.expect.css b/plugins/postcss-nesting/test/relative-selectors.expect.css index ba3da1ff2..636ef31ad 100644 --- a/plugins/postcss-nesting/test/relative-selectors.expect.css +++ b/plugins/postcss-nesting/test/relative-selectors.expect.css @@ -4,17 +4,17 @@ } -.foo > .bar { +.foo > .bar { order: 2; } -.foo + .bar { +.foo + .bar { order: 3; } -.foo ~ .bar { +.foo ~ .bar { order: 4; } @@ -24,50 +24,50 @@ } -.foo .bar, .foo .other { +.foo .bar,.foo .other { order: 11; } -.foo >.bar, .foo .other { +.foo > .bar,.foo .other { order: 12; } -.foo +.bar, .foo .other { +.foo + .bar,.foo .other { order: 13; } -.foo ~.bar, .foo .other { +.foo ~ .bar,.foo .other { order: 14; } -.foo ::before, .foo .other { +.foo ::before,.foo .other { order: 15; } -.bar .foo, .foo .other { +.bar .foo,.foo .other { order: 21; } -.foo>.bar .foo, .foo .other { +.foo > .bar .foo,.foo .other { order: 22; } -.foo+.bar .foo, .foo .other { +.foo + .bar .foo,.foo .other { order: 23; } -.foo~.bar .foo, .foo .other { +.foo ~ .bar .foo,.foo .other { order: 24; } -::before .foo, .foo .other { +::before .foo,.foo .other { order: 25; } -:is(.unrelated .foo, .bar) { +:is(.unrelated .foo,.bar) { order: 31; } diff --git a/plugins/postcss-nesting/test/requires-is-pseudo.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/requires-is-pseudo.no-is-pseudo-selector.expect.css deleted file mode 100644 index 52f808cb9..000000000 --- a/plugins/postcss-nesting/test/requires-is-pseudo.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,46 +0,0 @@ -/* - * two tag selectors in a compound selector - * would never match any elements selector, but :is required to have a correct selector - */ -body:is(html) { - order: 1; - } - -/* - * Adjacent element of parent/child selector - * Without :is it is not possible to match the selector - */ -.alpha > .beta + .alpha > .beta { - order: 2; - } - -/* Would be better written without nesting : */ -.alpha > .beta + .beta { - order: 2; -} - -/* - * Selector lists with mixed specificity - * In practice this will rarely be an issue. - * But we have to verify this once nesting is implemented in browsers. - */ -#alpha:hover, .beta:hover { - order: 3; - } - -/* will give unexpected results for
when the rule is followed by : */ -.delta:hover { - /* - * order will be 3 - * as the previous rule will have higher specificity - * - * only starts having effect once there is native support and when shipping untransformed code. - */ - order: 2; -} - -/* Would be better written without nesting : */ -#alpha:hover, -.beta:hover { - order: 3; -} diff --git a/plugins/postcss-nesting/test/spec-examples.expect.css b/plugins/postcss-nesting/test/spec-examples.expect.css index 76a6bff88..6fd00c14f 100644 --- a/plugins/postcss-nesting/test/spec-examples.expect.css +++ b/plugins/postcss-nesting/test/spec-examples.expect.css @@ -6,12 +6,11 @@ table.colortable td { text-align: center; } -table.colortable td.c { +.c:is(table.colortable td) { text-transform: uppercase } -table.colortable td:first-child, - :is(table.colortable td):first-child+td { +:is(table.colortable td):first-child,:is(table.colortable td):first-child + td { border: 1px solid black } @@ -26,7 +25,7 @@ table.colortable th { .foo { color: blue; } -.foo>.bar { +.foo > .bar { color: red; } @@ -56,10 +55,7 @@ table.colortable th { .bar { color: blue; } -.foo+.baz, - .bar+.baz, - .foo.qux, - .bar.qux { +:is(.foo,.bar) + .baz,.qux:is(.foo,.bar) { color: red; } @@ -116,7 +112,7 @@ table.colortable th { */ /* The parent selector can be arbitrarily complicated */ -:is(.error,#404):hover>.baz { +:is(.error,#404):hover > .baz { color: red; } @@ -137,10 +133,10 @@ table.colortable th { figure { margin: 0; } -figure>figcaption { +figure > figcaption { background: hsl(0 0% 0% / 50%); } -figure>figcaption>p { +:is(figure > figcaption) > p { font-size: .9rem; } @@ -179,10 +175,7 @@ __bar.foo { .bar { color: blue; } -.foo+.baz, - .bar+.baz, - .foo .qux, - .bar .qux { +:is(.foo,.bar) + .baz,:is(.foo,.bar) .qux { color: red; } @@ -190,7 +183,7 @@ __bar.foo { .foo { color: red; } -.foo>.bar { +.foo > .bar { color: blue; } @@ -239,8 +232,7 @@ __bar.foo { color: red; } -.foo .bar, - .foo .baz { +.foo .bar,.foo .baz { color: blue; } @@ -254,7 +246,7 @@ __bar.foo { .bar .foo { color: red; } -.bar .foo.baz { +.baz:is(.bar .foo) { color: green; } @@ -332,8 +324,7 @@ __bar.foo { @media (min-width: 480px) { - .foo h1, - .foo h2 { + .foo h1,.foo h2 { color: blue; } } diff --git a/plugins/postcss-nesting/test/spec-examples.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/spec-examples.no-is-pseudo-selector.expect.css deleted file mode 100644 index 0b937ab4a..000000000 --- a/plugins/postcss-nesting/test/spec-examples.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,389 +0,0 @@ -/* https://www.w3.org/TR/css-nesting-1/ */ - -/* Example 2 */ - -table.colortable td { - text-align: center; - } - -table.colortable td.c { - text-transform: uppercase - } - -table.colortable td:first-child, - table.colortable td:first-child+td { - border: 1px solid black - } - -table.colortable th { - text-align: center; - background: black; - color: white; - } - -/* Example 3 */ -/* & can be used on its own */ -.foo { - color: blue; -} -.foo>.bar { - color: red; - } - -/* equivalent to - .foo { color: blue; } - .foo > .bar { color: red; } -*/ - - -/* or in a compound selector, - refining the parent’s selector */ -.foo { - color: blue; -} -.foo.bar { - color: red; - } - -/* equivalent to - .foo { color: blue; } - .foo.bar { color: red; } -*/ - -/* multiple selectors in the list must all - start with & */ -.foo, -.bar { - color: blue; -} -.foo+.baz, - .bar+.baz, - .foo.qux, - .bar.qux { - color: red; - } - -/* equivalent to - .foo, .bar { color: blue; } - :is(.foo, .bar) + .baz, - :is(.foo, .bar).qux { color: red; } -*/ - -/* & can be used multiple times in a single selector */ -.foo { - color: blue; -} -.foo .bar .foo .baz .foo .qux { - color: red; - } - -/* equivalent to - .foo { color: blue; } - .foo .bar .foo .baz .foo .qux { color: red; } -*/ - -/* Somewhat silly, but can be used all on its own, as well. */ -.foo { - color: blue; -} -.foo { - padding: 2ch; - } - -/* equivalent to - .foo { color: blue; } - .foo { padding: 2ch; } - - // or - - .foo { - color: blue; - padding: 2ch; - } -*/ - -/* Again, silly, but can even be doubled up. */ -.foo { - color: blue; -} -.foo.foo { - padding: 2ch; - } - -/* equivalent to - .foo { color: blue; } - .foo.foo { padding: 2ch; } -*/ - -/* The parent selector can be arbitrarily complicated */ -.error:hover>.baz, #404:hover>.baz { - color: red; - } - -/* equivalent to - :is(.error, #404):hover > .baz { color: red; } -*/ - -/* As can the nested selector */ -.foo:is(.bar,.foo.baz) { - color: red; - } - -/* equivalent to - .foo:is(.bar, .foo.baz) { color: red; } -*/ - -/* Multiple levels of nesting "stack up" the selectors */ -figure { - margin: 0; -} -figure>figcaption { - background: hsl(0 0% 0% / 50%); - } -figure>figcaption>p { - font-size: .9rem; - } - -/* equivalent to - figure { margin: 0; } - figure > figcaption { background: hsl(0 0% 0% / 50%); } - figure > figcaption > p { font-size: .9rem; } -*/ - -/* No concatenation */ -.foo { - color: blue; -} -__bar.foo { - color: red; - } - -/* No & at all */ -.foo { - color: blue; -} -.foo .bar { - color: red; - } - -/* & isn’t the first simple selector */ -.foo { - color: blue; -} -.bar.foo { - color: red; - } - -/* & isn’t the first selector of every one in the list */ -.foo, -.bar { - color: blue; -} -.foo+.baz, - .bar+.baz, - .foo .qux, - .bar .qux { - color: red; - } - -/* Example 4 */ -.foo { - color: red; -} -.foo>.bar { - color: blue; - } - -/* equivalent to - .foo { color: red; } - .foo > .bar { color: blue; } -*/ - -.foo { - color: red; -} - -.parent .foo { - color: blue; - } - -/* equivalent to - .foo { color: red; } - .parent .foo { color: blue; } -*/ - -.foo { - color: red; -} - -:not(.foo) { - color: blue; - } - -/* equivalent to - .foo { color: red; } - :not(.foo) { color: blue; } -*/ - -.foo { - color: red; -} - -.foo .bar { - color: blue; - } - -/* Invalid because there’s no nesting selector */ - -.foo { - color: red; -} - -.foo .bar, - .foo .baz { - color: blue; - } - -/* Invalid because not all selectors in the list - contain a nesting selector */ - -/* Example 5 */ -.foo { - color: blue; -} -.bar .foo { - color: red; - } -.bar .foo.baz { - color: green; - } - -/* equivalent to - .foo { color: blue; } - .bar .foo { color: red; } - .bar .foo.baz { color: green; } -*/ - -/* Example 6 */ -/* Properties can be directly used */ -.foo { - display: grid; -} -@media (orientation: landscape) { -.foo { - grid-auto-flow: column; -} - } - -/* equivalent to - .foo { display: grid; } - - @media (orientation: landscape) { - & { - grid-auto-flow: column; - } - } -*/ - -/* finally equivalent to - .foo { display: grid; } - - @media (orientation: landscape) { - .foo { - grid-auto-flow: column; - } - } -*/ - -/* Conditionals can be further nested */ -.foo { - display: grid; -} -@media (orientation: landscape) { -.foo { - grid-auto-flow: column; -} - } -@media (orientation: landscape) and (min-inline-size > 1024px) { -.foo { - max-inline-size: 1024px; -} - } - -/* equivalent to - .foo { display: grid; } - - @media (orientation: landscape) { - .foo { - grid-auto-flow: column; - } - } - - @media (orientation: landscape) and (min-inline-size > 1024px) { - .foo { - max-inline-size: 1024px; - } - } -*/ - -.foo { - color: red; -} - -@media (min-width: 480px) { - - .foo h1, - .foo h2 { - color: blue; - } - } - -/* Invalid because not all selectors in the list - contain a nesting selector */ - -.foo { - color: red; -} - -@media (min-width: 480px) { - .foo { - color: blue; - } - } - -/* Invalid because expects a selector prelude, - instead a conditional group rule was provided */ - -/* Example 7 */ -article { - color: green; - - /* - NOTE : We are more forgiving than the spec - This declaration is preserved - */ - color: red; -} -article { - color: blue; - } - -article { - color: green; - - /* - NOTE : We are more forgiving than the spec - This declaration is preserved - */ - color: red; - - /* valid! */ -} - -article { - color: blue; - } - -article.foo { - color: yellow; - } diff --git a/plugins/postcss-nesting/test/supports.no-is-pseudo-selector.expect.css b/plugins/postcss-nesting/test/supports.no-is-pseudo-selector.expect.css deleted file mode 100644 index 2342752b3..000000000 --- a/plugins/postcss-nesting/test/supports.no-is-pseudo-selector.expect.css +++ /dev/null @@ -1,13 +0,0 @@ -a { - order: 1; -} -@supports (order: 2) { - a { - order: 2; -} - } -@supports (background-image: url('fo and o.png')) { - a { - order: 3; -} - } diff --git a/rollup/configs/externals.mjs b/rollup/configs/externals.mjs index ddef6307b..c6f2ca602 100644 --- a/rollup/configs/externals.mjs +++ b/rollup/configs/externals.mjs @@ -63,6 +63,7 @@ export const externalsForCLI = [ '@csstools/postcss-trigonometric-functions', '@csstools/postcss-unset-value', '@csstools/selector-specificity', + '@csstools/selector-resolve-nested', 'autoprefixer', 'browserslist', 'caniuse-lite', @@ -167,6 +168,7 @@ export const externalsForPlugin = [ '@csstools/postcss-trigonometric-functions', '@csstools/postcss-unset-value', '@csstools/selector-specificity', + '@csstools/selector-resolve-nested', 'autoprefixer', 'browserslist', 'caniuse-lite',