From 66c47d30ec92f74a3ece4140808eb784ec060926 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Fri, 19 Mar 2021 16:38:51 +0100 Subject: [PATCH 1/2] update tests for recursive @apply --- tests/10-apply.test.css | 87 ++++++++++++++++++++++++++++++++++++++++ tests/10-apply.test.html | 9 +++++ tests/10-apply.test.js | 34 ++++++++++++++++ 3 files changed, 130 insertions(+) diff --git a/tests/10-apply.test.css b/tests/10-apply.test.css index ceca6f3..ddf73cf 100644 --- a/tests/10-apply.test.css +++ b/tests/10-apply.test.css @@ -178,3 +178,90 @@ font-weight: 400; } } +.use-base-only-a { + font-weight: 700; +} +.use-dependant-only-b { + font-weight: 700; + font-weight: 400; +} +.btn { + border-radius: 0.25rem; + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-weight: 700; +} +.btn-blue { + border-radius: 0.25rem; + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-weight: 700; + --tw-bg-opacity: 1; + background-color: rgba(59, 130, 246, var(--tw-bg-opacity)); + --tw-text-opacity: 1; + color: rgba(255, 255, 255, var(--tw-text-opacity)); +} +.btn-blue:hover { + --tw-bg-opacity: 1; + background-color: rgba(29, 78, 216, var(--tw-bg-opacity)); +} +.recursive-apply-a { + font-weight: 900; +} +@media (min-width: 640px) { + .recursive-apply-a { + font-weight: 100; + } +} +.recursive-apply-b { + font-weight: 900; +} +@media (min-width: 640px) { + .recursive-apply-b { + font-weight: 100; + } +} +.recursive-apply-b { + font-weight: 600; +} +@media (min-width: 768px) { + .recursive-apply-b { + font-weight: 200; + } +} +.recursive-apply-c { + font-weight: 900; +} +@media (min-width: 640px) { + .recursive-apply-c { + font-weight: 100; + } +} +.recursive-apply-c { + font-weight: 600; +} +@media (min-width: 768px) { + .recursive-apply-c { + font-weight: 200; + } +} +.recursive-apply-c { + font-weight: 700; +} +@media (min-width: 1024px) { + .recursive-apply-c { + font-weight: 300; + } +} +.use-with-other-properties-base { + color: green; + font-weight: 700; +} +.use-with-other-properties-component { + color: green; + font-weight: 700; +} diff --git a/tests/10-apply.test.html b/tests/10-apply.test.html index 7f9c472..d355412 100644 --- a/tests/10-apply.test.html +++ b/tests/10-apply.test.html @@ -23,5 +23,14 @@
+
+
+
+
+
+
+
+
+
diff --git a/tests/10-apply.test.js b/tests/10-apply.test.js index 173f190..732ed03 100644 --- a/tests/10-apply.test.js +++ b/tests/10-apply.test.js @@ -65,6 +65,40 @@ test('@apply', () => { @apply font-bold hover:font-normal; } } + .use-base-only-a { + @apply font-bold; + } + .use-base-only-b { + @apply use-base-only-a font-normal; + } + .use-dependant-only-a { + @apply font-bold; + } + .use-dependant-only-b { + @apply use-dependant-only-a font-normal; + } + .btn { + @apply font-bold py-2 px-4 rounded; + } + .btn-blue { + @apply btn bg-blue-500 hover:bg-blue-700 text-white; + } + .recursive-apply-a { + @apply font-black sm:font-thin; + } + .recursive-apply-b { + @apply recursive-apply-a font-semibold md:font-extralight; + } + .recursive-apply-c { + @apply recursive-apply-b font-bold lg:font-light; + } + .use-with-other-properties-base { + color: green; + @apply font-bold; + } + .use-with-other-properties-component { + @apply use-with-other-properties-base; + } } @layer utilities { From 5644eb483cd621b03d11d54bd4fd06f10f1ec3d0 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Fri, 19 Mar 2021 16:39:56 +0100 Subject: [PATCH 2/2] implement naive recursive @apply Currently what it will do is re-run the apply code. If it turns out that there are @apply rules left, then it will re-apply those. If there are no @apply rules left, this means that we are "done". One big downside is that we are (at the time of this commit) running the apply code for the test at least 4 times. The good part is that we are doing it on the exact same tree so we don't need to re-parse it. This is the first implementation which can be improved! --- src/lib/expandApplyAtRules.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/lib/expandApplyAtRules.js b/src/lib/expandApplyAtRules.js index c3bad3e..d0a46fe 100644 --- a/src/lib/expandApplyAtRules.js +++ b/src/lib/expandApplyAtRules.js @@ -9,7 +9,10 @@ function buildApplyCache(applyCandidates, context) { } if (context.classCache.has(candidate)) { - context.applyClassCache.set(candidate, context.classCache.get(candidate)) + context.applyClassCache.set( + candidate, + context.classCache.get(candidate).map(([meta, rule]) => [meta, rule.clone()]) + ) continue } @@ -38,7 +41,7 @@ function extractApplyCandidates(params) { } function expandApplyAtRules(context) { - return (root) => { + return function processApply(root) { let applyCandidates = new Set() // Collect all @apply rules and candidates @@ -79,12 +82,16 @@ function expandApplyAtRules(context) { */ // TODO: Should we use postcss-selector-parser for this instead? function replaceSelector(selector, utilitySelectors, candidate) { + let needle = `.${escapeClassName(candidate)}` + let utilitySelectorsList = utilitySelectors.split(/\s*,\s*/g) + return selector .split(/\s*,\s*/g) .map((s) => { let replaced = [] - for (let utilitySelector of utilitySelectors.split(/\s*,\s*/g)) { - let replacedSelector = utilitySelector.replace(`.${escapeClassName(candidate)}`, s) + + for (let utilitySelector of utilitySelectorsList) { + let replacedSelector = utilitySelector.replace(needle, s) if (replacedSelector === utilitySelector) { continue } @@ -136,6 +143,9 @@ function expandApplyAtRules(context) { apply.parent.remove() } } + + // Do it again, in case we have other `@apply` rules + processApply(root) } } }