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 f2d0f311e..6a8ea282f 100644
--- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css
@@ -252,6 +252,10 @@
order: 26;
}
+.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);
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 f2d0f311e..6a8ea282f 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
@@ -252,6 +252,10 @@
order: 26;
}
+.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);
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 1529b3338..d5e80bf15 100644
--- a/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css
@@ -172,6 +172,10 @@
order: 26;
}
+.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);
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 e2e988048..0df0a119f 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
@@ -171,6 +171,10 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
order: 26;
}
+.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);
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 1bacd82cf..c1ba4a360 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
@@ -164,6 +164,10 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
order: 26;
}
+.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);
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
index f952bd095..f4fbf57c8 100644
--- 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
@@ -164,6 +164,10 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
order: 26;
}
+.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);
diff --git a/plugin-packs/postcss-preset-env/test/basic.expect.css b/plugin-packs/postcss-preset-env/test/basic.expect.css
index 27d1e48a8..3a2b5e9b6 100644
--- a/plugin-packs/postcss-preset-env/test/basic.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.expect.css
@@ -275,6 +275,10 @@
order: 26;
}
+.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);
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 ffefaebfe..fd1f48df0 100644
--- a/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css
@@ -168,6 +168,10 @@
order: 26;
}
+.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);
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 750ac0a92..6f93d7f18 100644
--- a/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css
@@ -156,6 +156,10 @@
order: 26;
}
+.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);
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 ced1a2c08..62bcc0c68 100644
--- a/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css
@@ -283,6 +283,11 @@
order: 26;
}
+.test-focus-visible-pseudo-class:focus-visible {
+ -ms-flex-order: 26;
+ 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);
diff --git a/plugin-packs/postcss-preset-env/test/basic.nesting.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.nesting.false.expect.css
index b83301214..6e1f87b3a 100644
--- a/plugin-packs/postcss-preset-env/test/basic.nesting.false.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.nesting.false.expect.css
@@ -273,6 +273,10 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
order: 26;
}
+.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);
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 b6e11ed52..1e56d5067 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
@@ -259,6 +259,10 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
order: 26;
}
+.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);
diff --git a/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css b/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css
index 34fb267d8..a214545b5 100644
--- a/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css
@@ -141,6 +141,10 @@
order: 26;
}
+.test-focus-visible-pseudo-class:focus-visible {
+ order: 26;
+}
+
.test-double-position-gradients {
background-image: conic-gradient(yellowgreen 40%, gold 0deg 75%, #f06 0deg);
}
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 819fa1807..d646ebd31 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
@@ -173,6 +173,10 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
order: 26;
}
+.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);
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 6c3310c42..de89ffbc6 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
@@ -161,6 +161,10 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
order: 26;
}
+.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);
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 26000e9bd..a9bd25c7a 100644
--- a/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css
@@ -280,6 +280,10 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
order: 26;
}
+.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);
diff --git a/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-1.expect.css b/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-1.expect.css
index eb3e1fa8a..2cdadb7a2 100644
--- a/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-1.expect.css
+++ b/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-1.expect.css
@@ -6,7 +6,7 @@
order: 2;
}
-[focus-within] {
+[focus-within].js-focus-within, .js-focus-within [focus-within] {
order: 3;
}
diff --git a/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-2.expect.css b/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-2.expect.css
index 557e9e2a1..b0b16a92d 100644
--- a/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-2.expect.css
+++ b/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-2.expect.css
@@ -6,7 +6,7 @@
order: 2;
}
-[focus-within] {
+[focus-within].js-focus-within, .js-focus-within [focus-within] {
order: 3;
}
diff --git a/plugin-packs/postcss-preset-env/test/disable-client-side-polyfills.disabled.expect.css b/plugin-packs/postcss-preset-env/test/disable-client-side-polyfills.disabled.expect.css
index 1e7ff7369..cd2b2b435 100644
--- a/plugin-packs/postcss-preset-env/test/disable-client-side-polyfills.disabled.expect.css
+++ b/plugin-packs/postcss-preset-env/test/disable-client-side-polyfills.disabled.expect.css
@@ -26,7 +26,7 @@ a:has(> img) {
}
}
-.my-form-field[focus-within] label {
+.my-form-field[focus-within].js-focus-within label, .js-focus-within .my-form-field[focus-within] label {
order: 4;
}
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 dfbe31fde..9ac9a6736 100644
--- a/plugin-packs/postcss-preset-env/test/layers-basic.expect.css
+++ b/plugin-packs/postcss-preset-env/test/layers-basic.expect.css
@@ -453,6 +453,14 @@ h1.test-custom-selectors:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):n
order: 26;
}
+.test-focus-visible-pseudo-class:focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) {
+ -webkit-box-ordinal-group: 27;
+ -webkit-order: 26;
+ -moz-box-ordinal-group: 27;
+ -ms-flex-order: 26;
+ order: 26;
+}
+
.test-double-position-gradients:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) {
background-image: conic-gradient(yellowgreen 40%, gold 0deg,gold 75%, #f06 0deg);
background-image: conic-gradient(yellowgreen 40%, gold 0deg 75%, #f06 0deg);
diff --git a/plugins/css-blank-pseudo/src/browser.js b/plugins/css-blank-pseudo/src/browser.js
index 5706d8713..691ce89b7 100644
--- a/plugins/css-blank-pseudo/src/browser.js
+++ b/plugins/css-blank-pseudo/src/browser.js
@@ -84,15 +84,18 @@ function observeValueOfHTMLElement(HTMLElement, handler) {
export default function cssBlankPseudoInit(opts) {
// configuration
- const options = Object.assign(
- // Default options
- {
- force: false,
- replaceWith: '[blank]',
- },
- // Provided options
- opts,
- );
+ const options = {
+ force: false,
+ replaceWith: '[blank]',
+ };
+
+ if (typeof opts !== 'undefined' && 'force' in opts) {
+ options.force = opts.force;
+ }
+
+ if (typeof opts !== 'undefined' && 'replaceWith' in opts) {
+ options.replaceWith = opts.replaceWith;
+ }
if (!isValidReplacement(options.replaceWith)) {
throw new Error(`${options.replaceWith} is not a valid replacement since it can't be applied to single elements.`);
diff --git a/plugins/postcss-focus-visible/README.md b/plugins/postcss-focus-visible/README.md
index 6f1f2c3e5..b218c1458 100644
--- a/plugins/postcss-focus-visible/README.md
+++ b/plugins/postcss-focus-visible/README.md
@@ -23,6 +23,9 @@ the browser's polyfill as well.
:focus:not(.focus-visible).js-focus-visible, .js-focus-visible :focus:not(.focus-visible) {
outline: none;
}
+:focus:not(:focus-visible) {
+ outline: none;
+}
```
[PostCSS Focus Visible] duplicates rules using the `:focus-visible` pseudo-class
@@ -59,10 +62,10 @@ instructions for:
### preserve
The `preserve` option determines whether the original notation
-is preserved. By default, it is not preserved.
+is preserved. By default, it is preserved.
```js
-postcssFocusVisible({ preserve: true })
+postcssFocusVisible({ preserve: false })
```
```pcss
@@ -72,13 +75,8 @@ postcssFocusVisible({ preserve: true })
/* becomes */
-.foo {
- color: blue;
- color: red;
-}
-
-.baz {
- color: green;
+:focus:not(.focus-visible).js-focus-visible, .js-focus-visible :focus:not(.focus-visible) {
+ outline: none;
}
```
@@ -98,14 +96,7 @@ postcssFocusVisible({ replaceWith: '[data-focus-visible-added]' })
/* becomes */
-.foo {
- color: blue;
- color: red;
-}
-
-.baz {
- color: green;
-}
+
```
Note that if you want to keep using [focus-visible polyfill], the only
diff --git a/plugins/postcss-focus-visible/docs/README.md b/plugins/postcss-focus-visible/docs/README.md
index def195d90..9b8f4e205 100644
--- a/plugins/postcss-focus-visible/docs/README.md
+++ b/plugins/postcss-focus-visible/docs/README.md
@@ -48,10 +48,10 @@ with a `.focus-visible` class selector, the same selector used by the
### preserve
The `preserve` option determines whether the original notation
-is preserved. By default, it is not preserved.
+is preserved. By default, it is preserved.
```js
-({ preserve: true })
+({ preserve: false })
```
```pcss
@@ -59,7 +59,7 @@ is preserved. By default, it is not preserved.
/* becomes */
-
+
```
### replaceWith
diff --git a/plugins/postcss-focus-visible/src/index.ts b/plugins/postcss-focus-visible/src/index.ts
index 6b7151141..7589d55cc 100644
--- a/plugins/postcss-focus-visible/src/index.ts
+++ b/plugins/postcss-focus-visible/src/index.ts
@@ -10,7 +10,7 @@ const creator: PluginCreator = (opts?: pluginOptions) => {
const options = Object.assign(
// Default options
{
- preserve: false,
+ preserve: true,
replaceWith: '.focus-visible',
},
// Provided options
@@ -22,12 +22,12 @@ const creator: PluginCreator = (opts?: pluginOptions) => {
return {
postcssPlugin: 'postcss-focus-visible',
Rule(rule, { result }) {
- if (!rule.selector.includes(PSEUDO)) {
+ if (!rule.selector.toLowerCase().includes(PSEUDO)) {
return;
}
const selectors = rule.selectors.flatMap((selector) => {
- if (!selector.includes(PSEUDO)) {
+ if (!selector.toLowerCase().includes(PSEUDO)) {
return [selector];
}
@@ -46,7 +46,7 @@ const creator: PluginCreator = (opts?: pluginOptions) => {
let containsPseudo = false;
selectorAST.walkPseudos((pseudo) => {
- if (pseudo.value !== PSEUDO) {
+ if (pseudo.value.toLowerCase() !== PSEUDO) {
return;
}
diff --git a/plugins/postcss-focus-visible/test/basic.css b/plugins/postcss-focus-visible/test/basic.css
index a2ac10d1a..fa0cf5461 100644
--- a/plugins/postcss-focus-visible/test/basic.css
+++ b/plugins/postcss-focus-visible/test/basic.css
@@ -77,3 +77,7 @@ html :not(:focus-visible) {
.foo > :focus-visible {
order: 10.5;
}
+
+:FocuS-VisiblE {
+ order: 11;
+}
diff --git a/plugins/postcss-focus-visible/test/basic.expect.css b/plugins/postcss-focus-visible/test/basic.expect.css
index 3fed12a64..0beb9479d 100644
--- a/plugins/postcss-focus-visible/test/basic.expect.css
+++ b/plugins/postcss-focus-visible/test/basic.expect.css
@@ -2,6 +2,10 @@
order: 1;
}
+:focus-visible {
+ order: 1;
+}
+
.focus-visible.js-focus-visible,
.js-focus-visible .focus-visible,
.focus-visible.js-focus-visible test,
@@ -35,6 +39,24 @@ test.js-focus-visible :matches(test .focus-visible .focus-visible test) test,
order: 2;
}
+:focus-visible,
+:focus-visible test,
+test :focus-visible,
+test test:focus-visible,
+html[dir="rtl"] :focus-visible,
+test :focus-visible test,
+test test:focus-visible test,
+test :focus-visible :focus-visible test,
+test :matches(:focus-visible) test,
+test :matches(:focus-visible test) test,
+test :matches(test :focus-visible) test,
+test :matches(test test:focus-visible) test,
+test :matches(test :focus-visible test) test,
+test :matches(test test:focus-visible test) test,
+test :matches(test :focus-visible :focus-visible test) test {
+ order: 2;
+}
+
:ignore-focus-visible,
:focus-visible-ignore,
:ignorefocus-visible,
@@ -55,42 +77,97 @@ test.js-focus-visible :matches(test .focus-visible .focus-visible test) test,
order: 5;
}
+.escaped\:focus-visible,
+.escaped\:times\:two\:focus-visible,
+.escaped\:focus-visible:focus-visible,
+.escaped\:times\:two:focus-visible {
+ order: 5;
+}
+
html.js-focus-visible .focus-visible, .js-focus-visible html .focus-visible {
order: 6;
}
+html :focus-visible {
+ order: 6;
+}
+
html.focus-visible.js-focus-visible, .js-focus-visible html.focus-visible {
order: 6.1;
}
+html:focus-visible {
+ order: 6.1;
+}
+
:not(.focus-visible).js-focus-visible, .js-focus-visible :not(.focus-visible) {
order: 7;
}
+:not(:focus-visible) {
+ order: 7;
+}
+
html.js-focus-visible :not(.focus-visible), .js-focus-visible html :not(.focus-visible) {
order: 8;
}
+html :not(:focus-visible) {
+ order: 8;
+}
+
.focus-visible.js-focus-visible::before, .js-focus-visible .focus-visible::before {
order: 10.0;
}
+:focus-visible::before {
+ order: 10.0;
+}
+
.focus-visible.js-focus-visible .foo, .js-focus-visible .focus-visible .foo {
order: 10.1;
}
+:focus-visible .foo {
+ order: 10.1;
+}
+
.focus-visible.js-focus-visible > .foo, .js-focus-visible .focus-visible > .foo {
order: 10.2;
}
+:focus-visible > .foo {
+ order: 10.2;
+}
+
.js-focus-visible::before.focus-visible, .js-focus-visible ::before.focus-visible {
order: 10.3;
}
+::before:focus-visible {
+ order: 10.3;
+}
+
.foo.js-focus-visible .focus-visible, .js-focus-visible .foo .focus-visible {
order: 10.4;
}
+.foo :focus-visible {
+ order: 10.4;
+}
+
.foo.js-focus-visible > .focus-visible, .js-focus-visible .foo > .focus-visible {
order: 10.5;
}
+
+.foo > :focus-visible {
+ order: 10.5;
+}
+
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
+ order: 11;
+}
+
+:FocuS-VisiblE {
+ order: 11;
+}
diff --git a/plugins/postcss-focus-visible/test/basic.preserve.expect.css b/plugins/postcss-focus-visible/test/basic.preserve.expect.css
index 3fed12a64..e3d0a30b3 100644
--- a/plugins/postcss-focus-visible/test/basic.preserve.expect.css
+++ b/plugins/postcss-focus-visible/test/basic.preserve.expect.css
@@ -94,3 +94,7 @@ html.js-focus-visible :not(.focus-visible), .js-focus-visible html :not(.focus-v
.foo.js-focus-visible > .focus-visible, .js-focus-visible .foo > .focus-visible {
order: 10.5;
}
+
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
+ order: 11;
+}
diff --git a/plugins/postcss-focus-visible/test/basic.replacewith.expect.css b/plugins/postcss-focus-visible/test/basic.replacewith.expect.css
index a5162561f..5964e5c41 100644
--- a/plugins/postcss-focus-visible/test/basic.replacewith.expect.css
+++ b/plugins/postcss-focus-visible/test/basic.replacewith.expect.css
@@ -2,6 +2,10 @@
order: 1;
}
+:focus-visible {
+ order: 1;
+}
+
[data-focus-visible-added].js-focus-visible,
.js-focus-visible [data-focus-visible-added],
[data-focus-visible-added].js-focus-visible test,
@@ -35,6 +39,24 @@ test.js-focus-visible :matches(test [data-focus-visible-added] [data-focus-visib
order: 2;
}
+:focus-visible,
+:focus-visible test,
+test :focus-visible,
+test test:focus-visible,
+html[dir="rtl"] :focus-visible,
+test :focus-visible test,
+test test:focus-visible test,
+test :focus-visible :focus-visible test,
+test :matches(:focus-visible) test,
+test :matches(:focus-visible test) test,
+test :matches(test :focus-visible) test,
+test :matches(test test:focus-visible) test,
+test :matches(test :focus-visible test) test,
+test :matches(test test:focus-visible test) test,
+test :matches(test :focus-visible :focus-visible test) test {
+ order: 2;
+}
+
:ignore-focus-visible,
:focus-visible-ignore,
:ignorefocus-visible,
@@ -55,42 +77,97 @@ test.js-focus-visible :matches(test [data-focus-visible-added] [data-focus-visib
order: 5;
}
+.escaped\:focus-visible,
+.escaped\:times\:two\:focus-visible,
+.escaped\:focus-visible:focus-visible,
+.escaped\:times\:two:focus-visible {
+ order: 5;
+}
+
html.js-focus-visible [data-focus-visible-added], .js-focus-visible html [data-focus-visible-added] {
order: 6;
}
+html :focus-visible {
+ order: 6;
+}
+
html[data-focus-visible-added].js-focus-visible, .js-focus-visible html[data-focus-visible-added] {
order: 6.1;
}
+html:focus-visible {
+ order: 6.1;
+}
+
:not([data-focus-visible-added]).js-focus-visible, .js-focus-visible :not([data-focus-visible-added]) {
order: 7;
}
+:not(:focus-visible) {
+ order: 7;
+}
+
html.js-focus-visible :not([data-focus-visible-added]), .js-focus-visible html :not([data-focus-visible-added]) {
order: 8;
}
+html :not(:focus-visible) {
+ order: 8;
+}
+
[data-focus-visible-added].js-focus-visible::before, .js-focus-visible [data-focus-visible-added]::before {
order: 10.0;
}
+:focus-visible::before {
+ order: 10.0;
+}
+
[data-focus-visible-added].js-focus-visible .foo, .js-focus-visible [data-focus-visible-added] .foo {
order: 10.1;
}
+:focus-visible .foo {
+ order: 10.1;
+}
+
[data-focus-visible-added].js-focus-visible > .foo, .js-focus-visible [data-focus-visible-added] > .foo {
order: 10.2;
}
+:focus-visible > .foo {
+ order: 10.2;
+}
+
.js-focus-visible::before[data-focus-visible-added], .js-focus-visible ::before[data-focus-visible-added] {
order: 10.3;
}
+::before:focus-visible {
+ order: 10.3;
+}
+
.foo.js-focus-visible [data-focus-visible-added], .js-focus-visible .foo [data-focus-visible-added] {
order: 10.4;
}
+.foo :focus-visible {
+ order: 10.4;
+}
+
.foo.js-focus-visible > [data-focus-visible-added], .js-focus-visible .foo > [data-focus-visible-added] {
order: 10.5;
}
+
+.foo > :focus-visible {
+ order: 10.5;
+}
+
+[data-focus-visible-added].js-focus-visible, .js-focus-visible [data-focus-visible-added] {
+ order: 11;
+}
+
+:FocuS-VisiblE {
+ order: 11;
+}
diff --git a/plugins/postcss-focus-visible/test/browser.expect.css b/plugins/postcss-focus-visible/test/browser.expect.css
index cf0e52c08..767265c01 100644
--- a/plugins/postcss-focus-visible/test/browser.expect.css
+++ b/plugins/postcss-focus-visible/test/browser.expect.css
@@ -7,3 +7,7 @@ textarea {
.focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
background-color: rgb(128, 0, 128);
}
+
+:focus-visible {
+ background-color: rgb(128, 0, 128);
+}
diff --git a/plugins/postcss-focus-visible/test/examples/example.expect.css b/plugins/postcss-focus-visible/test/examples/example.expect.css
index d2288c25d..18a648288 100644
--- a/plugins/postcss-focus-visible/test/examples/example.expect.css
+++ b/plugins/postcss-focus-visible/test/examples/example.expect.css
@@ -1,3 +1,6 @@
:focus:not(.focus-visible).js-focus-visible, .js-focus-visible :focus:not(.focus-visible) {
outline: none;
}
+:focus:not(:focus-visible) {
+ outline: none;
+}
diff --git a/plugins/postcss-focus-visible/test/examples/example.preserve-true.expect.css b/plugins/postcss-focus-visible/test/examples/example.preserve-true.expect.css
deleted file mode 100644
index 8b020470a..000000000
--- a/plugins/postcss-focus-visible/test/examples/example.preserve-true.expect.css
+++ /dev/null
@@ -1,8 +0,0 @@
-.foo {
- color: blue;
- color: red;
-}
-
-.baz {
- color: green;
-}
diff --git a/plugins/postcss-focus-visible/test/examples/example.replacewith.expect.css b/plugins/postcss-focus-visible/test/examples/example.replacewith.expect.css
index 9e6327e76..ef000b459 100644
--- a/plugins/postcss-focus-visible/test/examples/example.replacewith.expect.css
+++ b/plugins/postcss-focus-visible/test/examples/example.replacewith.expect.css
@@ -1,3 +1,6 @@
:focus:not([focus-visible]).js-focus-visible, .js-focus-visible :focus:not([focus-visible]) {
outline: none;
}
+:focus:not(:focus-visible) {
+ outline: none;
+}
diff --git a/plugins/postcss-focus-within/.gitignore b/plugins/postcss-focus-within/.gitignore
index 17847a362..7172b04f1 100644
--- a/plugins/postcss-focus-within/.gitignore
+++ b/plugins/postcss-focus-within/.gitignore
@@ -1,12 +1,6 @@
node_modules
-dist
package-lock.json
yarn.lock
-*.log*
*.result.css
*.result.css.map
-!.editorconfig
-!.gitignore
-!.rollup.js
-!.tape.js
-!.travis.yml
+dist/*
diff --git a/plugins/postcss-focus-within/.tape.mjs b/plugins/postcss-focus-within/.tape.mjs
index 35acb5355..91561fece 100644
--- a/plugins/postcss-focus-within/.tape.mjs
+++ b/plugins/postcss-focus-within/.tape.mjs
@@ -3,25 +3,46 @@ import plugin from 'postcss-focus-within';
postcssTape(plugin)({
'basic': {
- message: 'supports basic usage'
+ message: 'supports basic usage',
},
'basic:replacewith': {
message: 'supports { replaceWith: ".focus-within" } usage',
options: {
- replaceWith: '.focus-within'
- }
+ replaceWith: '.focus-within',
+ },
},
'basic:preserve': {
message: 'supports { preserve: false } usage',
options: {
- preserve: false
- }
+ preserve: false,
+ },
},
'generated-selector-cases': {
message: 'correctly handles generated cases',
warnings: 1,
+ },
+ 'examples/example': {
+ message: 'minimal example',
+ },
+ 'examples/example:preserve-false': {
+ message: 'minimal example',
+ options: {
+ preserve: false,
+ },
+ },
+ 'examples/example:replacewith': {
+ message: 'minimal example',
+ options: {
+ replaceWith: '.focus-within',
+ },
+ },
+ 'browser': {
+ message: 'css for browser tests',
+ },
+ 'browser:replacewith': {
+ message: 'css for browser tests',
options: {
- preserve: false
- }
+ replaceWith: '.focus-within',
+ },
},
});
diff --git a/plugins/postcss-focus-within/CHANGELOG.md b/plugins/postcss-focus-within/CHANGELOG.md
index 5f4507b5d..7c40529c9 100644
--- a/plugins/postcss-focus-within/CHANGELOG.md
+++ b/plugins/postcss-focus-within/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changes to PostCSS Focus Within
+### Unreleased (major)
+
+- Breaking: Changed generated classes so it prepends `.js-focus-within` to the
+generated class so CSS is applied when the polyfill is known to be running.
+- Added: Now bundling browser polyfill.
+
### 5.0.4 (February 5, 2022)
- Improved `es module` and `commonjs` compatibility
diff --git a/plugins/postcss-focus-within/README.md b/plugins/postcss-focus-within/README.md
index 8fe6d8619..a38a13ed6 100644
--- a/plugins/postcss-focus-within/README.md
+++ b/plugins/postcss-focus-within/README.md
@@ -1,36 +1,28 @@
# PostCSS Focus Within [
][postcss]
-[
][npm-url]
-[
][css-url]
-[
][cli-url]
-[
][discord]
+[
][npm-url] [
][css-url] [
][cli-url] [
][discord]
-[PostCSS Focus Within] lets you use the `:focus-within` pseudo-class in CSS,
+[PostCSS Focus Within] lets you use the `:focus-within` pseudo-class in CSS,
following the [Selectors Level 4 specification].
-It is the companion to the [focus-within polyfill].
-
-[](https://caniuse.com/#feat=css-focus-within)
-
-```css
+```pcss
.my-form-field:focus-within label {
- background-color: yellow;
+ background-color: yellow;
}
/* becomes */
-.my-form-field[focus-within] label {
- background-color: yellow;
+.my-form-field[focus-within].js-focus-within label, .js-focus-within .my-form-field[focus-within] label {
+ background-color: yellow;
}
-
.my-form-field:focus-within label {
- background-color: yellow;
+ background-color: yellow;
}
```
[PostCSS Focus Within] duplicates rules using the `:focus-within` pseudo-class
with a `[focus-within]` attribute selector, the same selector used by the
-[focus-within polyfill]. This replacement selector can be changed using the
+focus-within polyfill. This replacement selector can be changed using the
`replaceWith` option. Also, the preservation of the original `:focus-within`
rule can be disabled using the `preserve` option.
@@ -42,22 +34,14 @@ Add [PostCSS Focus Within] to your project:
npm install postcss postcss-focus-within --save-dev
```
-Use [PostCSS Focus Within] to process your CSS:
-
-```js
-const postcssFocusWithin = require('postcss-focus-within');
-
-postcssFocusWithin.process(YOUR_CSS /*, processOptions, pluginOptions */);
-```
-
-Or use it as a [PostCSS] plugin:
+Use it as a [PostCSS] plugin:
```js
const postcss = require('postcss');
const postcssFocusWithin = require('postcss-focus-within');
postcss([
- postcssFocusWithin(/* pluginOptions */)
+ postcssFocusWithin(/* pluginOptions */)
]).process(YOUR_CSS /*, processOptions */);
```
@@ -71,22 +55,22 @@ instructions for:
### preserve
-The `preserve` option defines whether the original selector should remain. By
-default, the original selector is preserved.
+The `preserve` option determines whether the original notation
+is preserved. By default, it is preserved.
```js
-focusWithin({ preserve: false });
+postcssFocusWithin({ preserve: false })
```
-```css
+```pcss
.my-form-field:focus-within label {
- background-color: yellow;
+ background-color: yellow;
}
/* becomes */
-.my-form-field[focus-within] label {
- background-color: yellow;
+.my-form-field[focus-within].js-focus-within label, .js-focus-within .my-form-field[focus-within] label {
+ background-color: yellow;
}
```
@@ -96,34 +80,77 @@ The `replaceWith` option defines the selector to replace `:focus-within`. By
default, the replacement selector is `[focus-within]`.
```js
-focusWithin({ replaceWith: '.focus-within' });
+postcssFocusWithin({ replaceWith: '.focus-within' });
```
-```css
+```pcss
.my-form-field:focus-within label {
- background-color: yellow;
+ background-color: yellow;
}
/* becomes */
-.my-form-field.focus-within label {
- background-color: yellow;
+.my-form-field.focus-within.js-focus-within label, .js-focus-within .my-form-field.focus-within label {
+ background-color: yellow;
}
-
.my-form-field:focus-within label {
- background-color: yellow;
+ background-color: yellow;
}
```
+Note that changing this option implies that it needs to be passed to the
+browser polyfill as well.
+
+## Browser
+
+```js
+import focusWithinInit from 'postcss-focus-within/browser';
+
+focusWithinInit();
+```
+
+or
+
+```html
+
+
+
+```
+
+[PostCSS Focus Within] works in all major browsers, including Safari 6+ and
+Internet Explorer 9+ without any additional polyfills.
+
+### Browser Usage
+
+#### force
+
+The `force` option determines whether the library runs even if the browser
+supports the selector or not. By default, it won't run if the browser does
+support the selector.
+
+```js
+focusWithinInit({ force: true });
+```
+
+#### replaceWith
+
+Similar to the option for the PostCSS Plugin, `replaceWith` determines the
+attribute or class to apply to an element when it's considered to be `:focus-within`.
+
+```js
+focusWithinInit({ replaceWith: '.focus-within });
+```
+
+This option should be used if it was changed at PostCSS configuration level.
+
+[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
[css-url]: https://cssdb.org/#focus-within-pseudo-class
-[cli-url]: https://github.com/csstools/postcss-plugins/tree/main/postcss-focus-within/actions/workflows/test.yml?query=workflow/test
[discord]: https://discord.gg/bUadyRwkJS
[npm-url]: https://www.npmjs.com/package/postcss-focus-within
-[focus-within polyfill]: https://github.com/jsxtools/focus-within
[Gulp PostCSS]: https://github.com/postcss/gulp-postcss
[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss
[PostCSS]: https://github.com/postcss/postcss
-[PostCSS Focus Within]: https://github.com/csstools/postcss-plugins/tree/main/postcss-focus-within
[PostCSS Loader]: https://github.com/postcss/postcss-loader
+[PostCSS Focus Within]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-within
[Selectors Level 4 specification]: https://www.w3.org/TR/selectors-4/#the-focus-within-pseudo
diff --git a/plugins/postcss-focus-within/docs/README.md b/plugins/postcss-focus-within/docs/README.md
new file mode 100644
index 000000000..cd8d22648
--- /dev/null
+++ b/plugins/postcss-focus-within/docs/README.md
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+[] lets you use the `:focus-within` pseudo-class in CSS,
+following the [Selectors Level 4 specification].
+
+```pcss
+
+
+/* becomes */
+
+
+```
+
+[] duplicates rules using the `:focus-within` pseudo-class
+with a `[focus-within]` attribute selector, the same selector used by the
+focus-within polyfill. This replacement selector can be changed using the
+`replaceWith` option. Also, the preservation of the original `:focus-within`
+rule can be disabled using the `preserve` option.
+
+
+
+
+
+## Options
+
+### preserve
+
+The `preserve` option determines whether the original notation
+is preserved. By default, it is preserved.
+
+```js
+({ preserve: false })
+```
+
+```pcss
+
+
+/* becomes */
+
+
+```
+
+### replaceWith
+
+The `replaceWith` option defines the selector to replace `:focus-within`. By
+default, the replacement selector is `[focus-within]`.
+
+```js
+({ replaceWith: '.focus-within' });
+```
+
+```pcss
+
+
+/* becomes */
+
+
+```
+
+Note that changing this option implies that it needs to be passed to the
+browser polyfill as well.
+
+## Browser
+
+```js
+import focusWithinInit from 'postcss-focus-within/browser';
+
+focusWithinInit();
+```
+
+or
+
+```html
+
+
+
+```
+
+[] works in all major browsers, including Safari 6+ and
+Internet Explorer 9+ without any additional polyfills.
+
+### Browser Usage
+
+#### force
+
+The `force` option determines whether the library runs even if the browser
+supports the selector or not. By default, it won't run if the browser does
+support the selector.
+
+```js
+focusWithinInit({ force: true });
+```
+
+#### replaceWith
+
+Similar to the option for the PostCSS Plugin, `replaceWith` determines the
+attribute or class to apply to an element when it's considered to be `:focus-within`.
+
+```js
+focusWithinInit({ replaceWith: '.focus-within });
+```
+
+This option should be used if it was changed at PostCSS configuration level.
+
+
+[Selectors Level 4 specification]:
diff --git a/plugins/postcss-focus-within/package.json b/plugins/postcss-focus-within/package.json
index f2c97d87e..64224f596 100644
--- a/plugins/postcss-focus-within/package.json
+++ b/plugins/postcss-focus-within/package.json
@@ -2,7 +2,21 @@
"name": "postcss-focus-within",
"description": "Use the :focus-within pseudo-selector in CSS",
"version": "5.0.4",
- "author": "Jonathan Neal ",
+ "contributors": [
+ {
+ "name": "Antonio Laguna",
+ "email": "antonio@laguna.es",
+ "url": "https://antonio.laguna.es"
+ },
+ {
+ "name": "Romain Menke",
+ "email": "romainmenke@gmail.com"
+ },
+ {
+ "name": "Jonathan Neal",
+ "email": "jonathantneal@hotmail.com"
+ }
+ ],
"license": "CC0-1.0",
"funding": {
"type": "opencollective",
@@ -19,6 +33,14 @@
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"default": "./dist/index.mjs"
+ },
+ "./browser": {
+ "import": "./dist/browser.mjs",
+ "require": "./dist/browser.cjs",
+ "default": "./dist/browser.mjs"
+ },
+ "./browser-global": {
+ "default": "./dist/browser-global.js"
}
},
"files": [
@@ -36,12 +58,13 @@
"scripts": {
"build": "rollup -c ../../rollup/default.js",
"clean": "node -e \"fs.rmSync('./dist', { recursive: true, force: true });\"",
- "docs": "node ../../.github/bin/generate-docs/install.mjs",
+ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs",
"lint": "npm run lint:eslint && npm run lint:package-json",
"lint:eslint": "eslint ./src --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern",
"lint:package-json": "node ../../.github/bin/format-package-json.mjs",
"prepublishOnly": "npm run clean && npm run build && npm run test",
"test": "node .tape.mjs && npm run test:exports",
+ "test:browser": "node ./test/_browser.mjs",
"test:exports": "node ./test/_import.mjs && node ./test/_require.cjs",
"test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs"
},
@@ -67,8 +90,10 @@
"within"
],
"csstools": {
+ "cssdbId": "focus-within-pseudo-class",
"exportName": "postcssFocusWithin",
- "humanReadableName": "PostCSS Focus Within"
+ "humanReadableName": "PostCSS Focus Within",
+ "specUrl": "https://www.w3.org/TR/selectors-4/#the-focus-within-pseudo"
},
"volta": {
"extends": "../../package.json"
diff --git a/plugins/postcss-focus-within/src/browser-global.js b/plugins/postcss-focus-within/src/browser-global.js
new file mode 100644
index 000000000..7c6d41bd7
--- /dev/null
+++ b/plugins/postcss-focus-within/src/browser-global.js
@@ -0,0 +1,3 @@
+/* global self */
+import { default as focusWithinInit } from './browser';
+self.focusWithinInit = focusWithinInit;
diff --git a/plugins/postcss-focus-within/src/browser.js b/plugins/postcss-focus-within/src/browser.js
new file mode 100644
index 000000000..6a225a7bd
--- /dev/null
+++ b/plugins/postcss-focus-within/src/browser.js
@@ -0,0 +1,78 @@
+/* global document */
+import isValidReplacement from './is-valid-replacement.mjs';
+function generateHandler(replaceWith) {
+ let selector;
+ let remove;
+ let add;
+ const lastElements = [];
+
+ if (replaceWith[0] === '.') {
+ selector = replaceWith.slice(1);
+ remove = (el) => el.classList.remove(selector);
+ add = (el) => el.classList.add(selector);
+ } else {
+ // A bit naive
+ selector = replaceWith.slice(1, -1);
+ remove = (el) => el.removeAttribute(selector, '');
+ add = (el) => el.setAttribute(selector, '');
+ }
+
+ return function handleFocusChange() {
+ lastElements.forEach(lastElement => remove(lastElement));
+ lastElements.length = 0;
+
+ let activeElement = document.activeElement;
+
+ // only add focus if it has not been added and is not the document element
+ if (!/^(#document|HTML|BODY)$/.test(Object(activeElement).nodeName)) {
+ while (activeElement && activeElement.nodeType === 1) {
+ add(activeElement);
+ lastElements.push(activeElement);
+
+ activeElement = activeElement.parentNode;
+ }
+ }
+ };
+}
+
+export default function focusWithin(opts) {
+ // configuration
+ const options = {
+ force: false,
+ replaceWith: '[focus-within]',
+ };
+
+ if (typeof opts !== 'undefined' && 'force' in opts) {
+ options.force = opts.force;
+ }
+
+ if (typeof opts !== 'undefined' && 'replaceWith' in opts) {
+ options.replaceWith = opts.replaceWith;
+ }
+
+ if (!isValidReplacement(options.replaceWith)) {
+ throw new Error(`${options.replaceWith} is not a valid replacement since it can't be applied to single elements.`);
+ }
+
+ try {
+ document.querySelector(':focus-within');
+
+ if (!options.force) {
+ return;
+ }
+ } catch (ignoredError) { /* do nothing and continue */ }
+
+ const handleFocusChange = generateHandler(options.replaceWith);
+
+ const initialize = function initializeEventListeners() {
+ document.documentElement.classList.add('js-focus-within');
+ document.addEventListener('focus', handleFocusChange, true);
+ document.addEventListener('blur', handleFocusChange, true);
+ };
+
+ if (document.readyState === 'complete') {
+ initialize();
+ } else {
+ document.addEventListener('DOMContentLoaded', initialize);
+ }
+}
diff --git a/plugins/postcss-focus-within/src/index.ts b/plugins/postcss-focus-within/src/index.ts
index d523eac34..dd2bd03c4 100644
--- a/plugins/postcss-focus-within/src/index.ts
+++ b/plugins/postcss-focus-within/src/index.ts
@@ -1,55 +1,121 @@
import parser from 'postcss-selector-parser';
import type { PluginCreator } from 'postcss';
+import isValidReplacement from './is-valid-replacement.mjs';
-const creator: PluginCreator<{ preserve?: boolean, replaceWith?: string }> = (opts?: { preserve?: boolean, replaceWith?: string }) => {
- const replaceWith = String(Object(opts).replaceWith || '[focus-within]');
- const preserve = Boolean('preserve' in Object(opts) ? opts.preserve : true);
- const replacementAST = parser().astSync(replaceWith);
+type pluginOptions = { preserve?: boolean, replaceWith?: string };
+
+const POLYFILL_READY_CLASSNAME = 'js-focus-within';
+const PSEUDO = ':focus-within';
+
+const creator: PluginCreator = (opts?: pluginOptions) => {
+ const options = Object.assign(
+ // Default options
+ {
+ preserve: true,
+ replaceWith: '[focus-within]',
+ },
+ // Provided options
+ opts,
+ );
+
+ const replacementAST = parser().astSync(options.replaceWith);
+ if (!isValidReplacement(options.replaceWith)) {
+ return {
+ postcssPlugin: 'postcss-focus-within',
+ Once: (root, { result }) => {
+ root.warn(
+ result,
+ `${options.replaceWith} is not a valid replacement since it can't be applied to single elements.`,
+ );
+ },
+ };
+ }
return {
postcssPlugin: 'postcss-focus-within',
- Rule: (rule, { result })=> {
- if (!rule.selector.includes(':focus-within')) {
+ Rule(rule, { result }) {
+ if (!rule.selector.toLowerCase().includes(PSEUDO)) {
return;
}
- let modifiedSelector;
+ const selectors = rule.selectors.flatMap((selector) => {
+ if (!selector.toLowerCase().includes(PSEUDO)) {
+ return [selector];
+ }
- try {
- const modifiedSelectorAST = parser((selectors) => {
- selectors.walkPseudos((pseudo) => {
- if (pseudo.value !== ':focus-within') {
- return;
- }
+ let selectorAST;
- if (pseudo.nodes && pseudo.nodes.length) {
- return;
- }
+ try {
+ selectorAST = parser().astSync(selector);
+ } catch (_) {
+ rule.warn(result, `Failed to parse selector : ${selector}`);
+ return selector;
+ }
- pseudo.replaceWith(replacementAST.clone({}));
- });
- }).processSync(rule.selector);
+ if (typeof selectorAST === 'undefined') {
+ return [selector];
+ }
- modifiedSelector = String(modifiedSelectorAST);
- } catch (_) {
- rule.warn(result, `Failed to parse selector : ${rule.selector}`);
- return;
- }
+ let containsPseudo = false;
+ selectorAST.walkPseudos((pseudo) => {
+ if (pseudo.value.toLowerCase() !== PSEUDO) {
+ return;
+ }
- if (typeof modifiedSelector === 'undefined') {
- return;
- }
+ if (pseudo.nodes && pseudo.nodes.length) {
+ return;
+ }
+
+ containsPseudo = true;
+ pseudo.replaceWith(replacementAST.clone({}));
+ });
+
+ if (!containsPseudo) {
+ return [selector];
+ }
+
+ const selectorASTClone = selectorAST.clone();
+
+ // html > .foo:focus-within
+ // becomes:
+ // html.js-focus-within > .foo:focus-within,
+ // .js-focus-within html > .foo:focus-within
+ {
+ if (selectorAST.nodes?.[0]?.nodes?.length) {
+ for (let i = 0; i < selectorAST.nodes[0].nodes.length; i++) {
+ const node = selectorAST.nodes[0].nodes[i];
+ if (node.type === 'combinator' || parser.isPseudoElement(node)) {
+ // Insert the class before the first combinator or pseudo element.
+ selectorAST.nodes[0].insertBefore(node, parser.className({ value: POLYFILL_READY_CLASSNAME }));
+ break;
+ }
+
+ if (i === selectorAST.nodes[0].nodes.length - 1) {
+ // Append the class to the end of the selector if not combinator or pseudo element was found.
+ selectorAST.nodes[0].append(parser.className({ value: POLYFILL_READY_CLASSNAME }));
+ break;
+ }
+ }
+ }
+
+ if (selectorAST.nodes?.[0]?.nodes) {
+ // Prepend a space combinator and the class to the beginning of the selector.
+ selectorASTClone.nodes[0].prepend(parser.combinator({ value: ' ' }));
+ selectorASTClone.nodes[0].prepend(parser.className({ value: POLYFILL_READY_CLASSNAME }));
+ }
+ }
+
+ return [selectorAST.toString(), selectorASTClone.toString()];
+ });
- if (modifiedSelector === rule.selector) {
+ if (selectors.join(',') === rule.selectors.join(',')) {
return;
}
- const clone = rule.clone({ selector: modifiedSelector });
+ rule.cloneBefore({ selectors: selectors });
- if (preserve) {
- rule.before(clone);
- } else {
- rule.replaceWith(clone);
+ if (!options.preserve) {
+ rule.remove();
}
},
};
diff --git a/plugins/postcss-focus-within/src/is-valid-replacement.mjs b/plugins/postcss-focus-within/src/is-valid-replacement.mjs
new file mode 100644
index 000000000..ebcf65a12
--- /dev/null
+++ b/plugins/postcss-focus-within/src/is-valid-replacement.mjs
@@ -0,0 +1,24 @@
+const INVALID_SELECTOR_CHAR = [
+ ' ', // Can't use child selector
+ '>', // Can't use direct child selector
+ '~', // Can't use sibling selector
+ ':', // Can't use pseudo selector
+ '+', // Can't use adjacent selector
+ '@', // Can't use at
+ '#', // Can't use id selector
+ '(', // Can't use parenthesis
+ ')', // Can't use parenthesis
+];
+
+export default function isValidReplacement(selector) {
+ let isValid = true;
+
+ // Purposely archaic so it's interoperable in old browsers
+ for (let i = 0, length = INVALID_SELECTOR_CHAR.length; i < length && isValid; i++) {
+ if (selector.indexOf(INVALID_SELECTOR_CHAR[i]) > -1) {
+ isValid = false;
+ }
+ }
+
+ return isValid;
+}
diff --git a/plugins/postcss-focus-within/test/_browser.html b/plugins/postcss-focus-within/test/_browser.html
new file mode 100644
index 000000000..c18455734
--- /dev/null
+++ b/plugins/postcss-focus-within/test/_browser.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/postcss-focus-within/test/_browser.mjs b/plugins/postcss-focus-within/test/_browser.mjs
new file mode 100644
index 000000000..3a2c9c5cb
--- /dev/null
+++ b/plugins/postcss-focus-within/test/_browser.mjs
@@ -0,0 +1,160 @@
+/* global window */
+import puppeteer from 'puppeteer';
+import http from 'http';
+import { promises as fsp } from 'fs';
+
+(async () => {
+ const requestListener = async function (req, res) {
+
+ const parsedUrl = new URL(req.url, 'http://localhost:8080');
+ const pathname = parsedUrl.pathname;
+
+ switch (pathname) {
+ case '':
+ case '/':
+ res.setHeader('Content-type', 'text/html');
+ res.writeHead(200);
+ res.end(await fsp.readFile('test/_browser.html', 'utf8'));
+ break;
+ case '/test/browser.expect.css':
+ res.setHeader('Content-type', 'text/css');
+ res.writeHead(200);
+ res.end(await fsp.readFile('test/browser.expect.css', 'utf8'));
+ break;
+ case '/dist/browser-global.js':
+ res.setHeader('Content-type', 'text/javascript');
+ res.writeHead(200);
+ res.end(await fsp.readFile('dist/browser-global.js', 'utf8'));
+ break;
+ case '/replace-with':
+ res.setHeader('Content-type', 'text/html');
+ res.writeHead(200);
+ res.end(await fsp.readFile('test/_browser_replace.html', 'utf8'));
+ break;
+ case '/test/browser.replacewith.expect.css':
+ res.setHeader('Content-type', 'text/css');
+ res.writeHead(200);
+ res.end(await fsp.readFile('test/browser.replacewith.expect.css', 'utf8'));
+ break;
+ default:
+ res.setHeader('Content-type', 'text/plain' );
+ res.writeHead(404);
+ res.end('Not found');
+ break;
+ }
+ };
+
+ // Use different servers for HTML/CSS/JS to trigger CORS
+ const server = http.createServer(requestListener);
+ server.listen(8080);
+
+ if (!process.env.DEBUG) {
+ const browser = await puppeteer.launch({
+ headless: true,
+ });
+
+ const page = await browser.newPage();
+ page.on('pageerror', (msg) => {
+ throw msg;
+ });
+
+ // Default
+ {
+ await page.goto('http://localhost:8080');
+
+ await page.evaluate(async () => window._focusWithinInit({ force: true }));
+
+ // None of the elements should have styles
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child-input', false));
+
+ await page.click('#a-grand-parent-input');
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent-input', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child-input', false));
+
+ await page.click('#a-parent-input');
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent-input', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-child', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child-input', false));
+
+ await page.click('#a-child-input');
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-child-input', true));
+
+ await page.keyboard.press('Tab');
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child-input', false));
+ }
+
+ // Replace with
+ {
+ await page.goto('http://localhost:8080/replace-with');
+
+ await page.evaluate(async () => window._focusWithinInit({ force: true, replaceWith: '.focus-within' }));
+
+ // None of the elements should have styles
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child-input', false));
+
+ await page.click('#a-grand-parent-input');
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent-input', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child-input', false));
+
+ await page.click('#a-parent-input');
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent-input', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-child', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child-input', false));
+
+ await page.click('#a-child-input');
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child', true));
+ await page.evaluate(async () => window.checkElement('default', 'a-child-input', true));
+
+ await page.keyboard.press('Tab');
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-grand-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-parent-input', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child', false));
+ await page.evaluate(async () => window.checkElement('default', 'a-child-input', false));
+ }
+
+ await browser.close();
+ await server.close();
+ } else {
+ console.log('visit : http://localhost:8080');
+ }
+})();
diff --git a/plugins/postcss-focus-within/test/_browser_replace.html b/plugins/postcss-focus-within/test/_browser_replace.html
new file mode 100644
index 000000000..5cc5b1eaf
--- /dev/null
+++ b/plugins/postcss-focus-within/test/_browser_replace.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/postcss-focus-within/test/basic.css b/plugins/postcss-focus-within/test/basic.css
index f41cae99d..003162925 100644
--- a/plugins/postcss-focus-within/test/basic.css
+++ b/plugins/postcss-focus-within/test/basic.css
@@ -36,3 +36,7 @@ test :matches(test :focus-within :focus-within test) test {
.escaped\:times\:two:focus-within {
order: 5;
}
+
+:FocuS-WithiN {
+ order: 6;
+}
diff --git a/plugins/postcss-focus-within/test/basic.expect.css b/plugins/postcss-focus-within/test/basic.expect.css
index 36e0cb295..e85b1630c 100644
--- a/plugins/postcss-focus-within/test/basic.expect.css
+++ b/plugins/postcss-focus-within/test/basic.expect.css
@@ -1,4 +1,4 @@
-[focus-within] {
+[focus-within].js-focus-within, .js-focus-within [focus-within] {
order: 1;
}
@@ -6,19 +6,34 @@
order: 1;
}
-[focus-within],[focus-within] test,
-test [focus-within],
-test test[focus-within],
-test [focus-within] test,
-test test[focus-within] test,
-test [focus-within] [focus-within] test,
-test :matches([focus-within]) test,
-test :matches([focus-within] test) test,
-test :matches(test [focus-within]) test,
-test :matches(test test[focus-within]) test,
-test :matches(test [focus-within] test) test,
-test :matches(test test[focus-within] test) test,
-test :matches(test [focus-within] [focus-within] test) test {
+[focus-within].js-focus-within,
+.js-focus-within [focus-within],
+[focus-within].js-focus-within test,
+.js-focus-within [focus-within] test,
+test.js-focus-within [focus-within],
+.js-focus-within test [focus-within],
+test.js-focus-within test[focus-within],
+.js-focus-within test test[focus-within],
+test.js-focus-within [focus-within] test,
+.js-focus-within test [focus-within] test,
+test.js-focus-within test[focus-within] test,
+.js-focus-within test test[focus-within] test,
+test.js-focus-within [focus-within] [focus-within] test,
+.js-focus-within test [focus-within] [focus-within] test,
+test.js-focus-within :matches([focus-within]) test,
+.js-focus-within test :matches([focus-within]) test,
+test.js-focus-within :matches([focus-within] test) test,
+.js-focus-within test :matches([focus-within] test) test,
+test.js-focus-within :matches(test [focus-within]) test,
+.js-focus-within test :matches(test [focus-within]) test,
+test.js-focus-within :matches(test test[focus-within]) test,
+.js-focus-within test :matches(test test[focus-within]) test,
+test.js-focus-within :matches(test [focus-within] test) test,
+.js-focus-within test :matches(test [focus-within] test) test,
+test.js-focus-within :matches(test test[focus-within] test) test,
+.js-focus-within test :matches(test test[focus-within] test) test,
+test.js-focus-within :matches(test [focus-within] [focus-within] test) test,
+.js-focus-within test :matches(test [focus-within] [focus-within] test) test {
order: 2;
}
@@ -52,8 +67,10 @@ test :matches(test :focus-within :focus-within test) test {
.escaped\:focus-within,
.escaped\:times\:two\:focus-within,
-.escaped\:focus-within[focus-within],
-.escaped\:times\:two[focus-within] {
+.escaped\:focus-within[focus-within].js-focus-within,
+.js-focus-within .escaped\:focus-within[focus-within],
+.escaped\:times\:two[focus-within].js-focus-within,
+.js-focus-within .escaped\:times\:two[focus-within] {
order: 5;
}
@@ -63,3 +80,11 @@ test :matches(test :focus-within :focus-within test) test {
.escaped\:times\:two:focus-within {
order: 5;
}
+
+[focus-within].js-focus-within, .js-focus-within [focus-within] {
+ order: 6;
+}
+
+:FocuS-WithiN {
+ order: 6;
+}
diff --git a/plugins/postcss-focus-within/test/basic.preserve.expect.css b/plugins/postcss-focus-within/test/basic.preserve.expect.css
index 1fba9c4a0..034a0d288 100644
--- a/plugins/postcss-focus-within/test/basic.preserve.expect.css
+++ b/plugins/postcss-focus-within/test/basic.preserve.expect.css
@@ -1,20 +1,35 @@
-[focus-within] {
+[focus-within].js-focus-within, .js-focus-within [focus-within] {
order: 1;
}
-[focus-within],[focus-within] test,
-test [focus-within],
-test test[focus-within],
-test [focus-within] test,
-test test[focus-within] test,
-test [focus-within] [focus-within] test,
-test :matches([focus-within]) test,
-test :matches([focus-within] test) test,
-test :matches(test [focus-within]) test,
-test :matches(test test[focus-within]) test,
-test :matches(test [focus-within] test) test,
-test :matches(test test[focus-within] test) test,
-test :matches(test [focus-within] [focus-within] test) test {
+[focus-within].js-focus-within,
+.js-focus-within [focus-within],
+[focus-within].js-focus-within test,
+.js-focus-within [focus-within] test,
+test.js-focus-within [focus-within],
+.js-focus-within test [focus-within],
+test.js-focus-within test[focus-within],
+.js-focus-within test test[focus-within],
+test.js-focus-within [focus-within] test,
+.js-focus-within test [focus-within] test,
+test.js-focus-within test[focus-within] test,
+.js-focus-within test test[focus-within] test,
+test.js-focus-within [focus-within] [focus-within] test,
+.js-focus-within test [focus-within] [focus-within] test,
+test.js-focus-within :matches([focus-within]) test,
+.js-focus-within test :matches([focus-within]) test,
+test.js-focus-within :matches([focus-within] test) test,
+.js-focus-within test :matches([focus-within] test) test,
+test.js-focus-within :matches(test [focus-within]) test,
+.js-focus-within test :matches(test [focus-within]) test,
+test.js-focus-within :matches(test test[focus-within]) test,
+.js-focus-within test :matches(test test[focus-within]) test,
+test.js-focus-within :matches(test [focus-within] test) test,
+.js-focus-within test :matches(test [focus-within] test) test,
+test.js-focus-within :matches(test test[focus-within] test) test,
+.js-focus-within test :matches(test test[focus-within] test) test,
+test.js-focus-within :matches(test [focus-within] [focus-within] test) test,
+.js-focus-within test :matches(test [focus-within] [focus-within] test) test {
order: 2;
}
@@ -31,7 +46,13 @@ test :matches(test [focus-within] [focus-within] test) test {
.escaped\:focus-within,
.escaped\:times\:two\:focus-within,
-.escaped\:focus-within[focus-within],
-.escaped\:times\:two[focus-within] {
+.escaped\:focus-within[focus-within].js-focus-within,
+.js-focus-within .escaped\:focus-within[focus-within],
+.escaped\:times\:two[focus-within].js-focus-within,
+.js-focus-within .escaped\:times\:two[focus-within] {
order: 5;
}
+
+[focus-within].js-focus-within, .js-focus-within [focus-within] {
+ order: 6;
+}
diff --git a/plugins/postcss-focus-within/test/basic.replacewith.expect.css b/plugins/postcss-focus-within/test/basic.replacewith.expect.css
index f2856487d..5a7666a11 100644
--- a/plugins/postcss-focus-within/test/basic.replacewith.expect.css
+++ b/plugins/postcss-focus-within/test/basic.replacewith.expect.css
@@ -1,4 +1,4 @@
-.focus-within {
+.focus-within.js-focus-within, .js-focus-within .focus-within {
order: 1;
}
@@ -6,19 +6,34 @@
order: 1;
}
-.focus-within,.focus-within test,
-test .focus-within,
-test test.focus-within,
-test .focus-within test,
-test test.focus-within test,
-test .focus-within .focus-within test,
-test :matches(.focus-within) test,
-test :matches(.focus-within test) test,
-test :matches(test .focus-within) test,
-test :matches(test test.focus-within) test,
-test :matches(test .focus-within test) test,
-test :matches(test test.focus-within test) test,
-test :matches(test .focus-within .focus-within test) test {
+.focus-within.js-focus-within,
+.js-focus-within .focus-within,
+.focus-within.js-focus-within test,
+.js-focus-within .focus-within test,
+test.js-focus-within .focus-within,
+.js-focus-within test .focus-within,
+test.js-focus-within test.focus-within,
+.js-focus-within test test.focus-within,
+test.js-focus-within .focus-within test,
+.js-focus-within test .focus-within test,
+test.js-focus-within test.focus-within test,
+.js-focus-within test test.focus-within test,
+test.js-focus-within .focus-within .focus-within test,
+.js-focus-within test .focus-within .focus-within test,
+test.js-focus-within :matches(.focus-within) test,
+.js-focus-within test :matches(.focus-within) test,
+test.js-focus-within :matches(.focus-within test) test,
+.js-focus-within test :matches(.focus-within test) test,
+test.js-focus-within :matches(test .focus-within) test,
+.js-focus-within test :matches(test .focus-within) test,
+test.js-focus-within :matches(test test.focus-within) test,
+.js-focus-within test :matches(test test.focus-within) test,
+test.js-focus-within :matches(test .focus-within test) test,
+.js-focus-within test :matches(test .focus-within test) test,
+test.js-focus-within :matches(test test.focus-within test) test,
+.js-focus-within test :matches(test test.focus-within test) test,
+test.js-focus-within :matches(test .focus-within .focus-within test) test,
+.js-focus-within test :matches(test .focus-within .focus-within test) test {
order: 2;
}
@@ -52,8 +67,10 @@ test :matches(test :focus-within :focus-within test) test {
.escaped\:focus-within,
.escaped\:times\:two\:focus-within,
-.escaped\:focus-within.focus-within,
-.escaped\:times\:two.focus-within {
+.escaped\:focus-within.focus-within.js-focus-within,
+.js-focus-within .escaped\:focus-within.focus-within,
+.escaped\:times\:two.focus-within.js-focus-within,
+.js-focus-within .escaped\:times\:two.focus-within {
order: 5;
}
@@ -63,3 +80,11 @@ test :matches(test :focus-within :focus-within test) test {
.escaped\:times\:two:focus-within {
order: 5;
}
+
+.focus-within.js-focus-within, .js-focus-within .focus-within {
+ order: 6;
+}
+
+:FocuS-WithiN {
+ order: 6;
+}
diff --git a/plugins/postcss-focus-within/test/browser.css b/plugins/postcss-focus-within/test/browser.css
new file mode 100644
index 000000000..1860c200a
--- /dev/null
+++ b/plugins/postcss-focus-within/test/browser.css
@@ -0,0 +1,11 @@
+div {
+ padding: 2em;
+}
+
+div:focus-within {
+ background-color: rgb(128, 0, 128);
+}
+
+input:focus-within {
+ background-color: rgb(0, 128, 0);
+}
diff --git a/plugins/postcss-focus-within/test/browser.expect.css b/plugins/postcss-focus-within/test/browser.expect.css
new file mode 100644
index 000000000..0d9156ca7
--- /dev/null
+++ b/plugins/postcss-focus-within/test/browser.expect.css
@@ -0,0 +1,19 @@
+div {
+ padding: 2em;
+}
+
+div[focus-within].js-focus-within, .js-focus-within div[focus-within] {
+ background-color: rgb(128, 0, 128);
+}
+
+div:focus-within {
+ background-color: rgb(128, 0, 128);
+}
+
+input[focus-within].js-focus-within, .js-focus-within input[focus-within] {
+ background-color: rgb(0, 128, 0);
+}
+
+input:focus-within {
+ background-color: rgb(0, 128, 0);
+}
diff --git a/plugins/postcss-focus-within/test/browser.replacewith.expect.css b/plugins/postcss-focus-within/test/browser.replacewith.expect.css
new file mode 100644
index 000000000..5e2ad9944
--- /dev/null
+++ b/plugins/postcss-focus-within/test/browser.replacewith.expect.css
@@ -0,0 +1,19 @@
+div {
+ padding: 2em;
+}
+
+div.focus-within.js-focus-within, .js-focus-within div.focus-within {
+ background-color: rgb(128, 0, 128);
+}
+
+div:focus-within {
+ background-color: rgb(128, 0, 128);
+}
+
+input.focus-within.js-focus-within, .js-focus-within input.focus-within {
+ background-color: rgb(0, 128, 0);
+}
+
+input:focus-within {
+ background-color: rgb(0, 128, 0);
+}
diff --git a/plugins/postcss-focus-within/test/examples/example.css b/plugins/postcss-focus-within/test/examples/example.css
new file mode 100644
index 000000000..c3c728c3b
--- /dev/null
+++ b/plugins/postcss-focus-within/test/examples/example.css
@@ -0,0 +1,3 @@
+.my-form-field:focus-within label {
+ background-color: yellow;
+}
diff --git a/plugins/postcss-focus-within/test/examples/example.expect.css b/plugins/postcss-focus-within/test/examples/example.expect.css
new file mode 100644
index 000000000..fe6084d56
--- /dev/null
+++ b/plugins/postcss-focus-within/test/examples/example.expect.css
@@ -0,0 +1,6 @@
+.my-form-field[focus-within].js-focus-within label, .js-focus-within .my-form-field[focus-within] label {
+ background-color: yellow;
+}
+.my-form-field:focus-within label {
+ background-color: yellow;
+}
diff --git a/plugins/postcss-focus-within/test/examples/example.preserve-false.expect.css b/plugins/postcss-focus-within/test/examples/example.preserve-false.expect.css
new file mode 100644
index 000000000..1188030bd
--- /dev/null
+++ b/plugins/postcss-focus-within/test/examples/example.preserve-false.expect.css
@@ -0,0 +1,3 @@
+.my-form-field[focus-within].js-focus-within label, .js-focus-within .my-form-field[focus-within] label {
+ background-color: yellow;
+}
diff --git a/plugins/postcss-focus-within/test/examples/example.replacewith.expect.css b/plugins/postcss-focus-within/test/examples/example.replacewith.expect.css
new file mode 100644
index 000000000..cab94c735
--- /dev/null
+++ b/plugins/postcss-focus-within/test/examples/example.replacewith.expect.css
@@ -0,0 +1,6 @@
+.my-form-field.focus-within.js-focus-within label, .js-focus-within .my-form-field.focus-within label {
+ background-color: yellow;
+}
+.my-form-field:focus-within label {
+ background-color: yellow;
+}
diff --git a/plugins/postcss-focus-within/test/generated-selector-cases.expect.css b/plugins/postcss-focus-within/test/generated-selector-cases.expect.css
index 25299452c..b3fb1623e 100644
--- a/plugins/postcss-focus-within/test/generated-selector-cases.expect.css
+++ b/plugins/postcss-focus-within/test/generated-selector-cases.expect.css
@@ -1,84 +1,168 @@
-[focus-within][focus-within] {
+[focus-within][focus-within].js-focus-within, .js-focus-within [focus-within][focus-within] {
order: 0;
}
-[focus-within][focus-within] {
+:focus-within:focus-within {
+ order: 0;
+}
+
+[focus-within][focus-within].js-focus-within, .js-focus-within [focus-within][focus-within] {
order: 1;
}
-[focus-within] [focus-within] {
+:focus-within:focus-within {
+ order: 1;
+}
+
+[focus-within].js-focus-within [focus-within], .js-focus-within [focus-within] [focus-within] {
order: 2;
}
-[focus-within] [focus-within] {
+:focus-within :focus-within {
+ order: 2;
+}
+
+[focus-within].js-focus-within [focus-within], .js-focus-within [focus-within] [focus-within] {
+ order: 3;
+}
+
+:focus-within :focus-within {
order: 3;
}
-[focus-within] [focus-within] {
+[focus-within].js-focus-within [focus-within], .js-focus-within [focus-within] [focus-within] {
+ order: 4;
+}
+
+:focus-within :focus-within {
order: 4;
}
-[focus-within] [focus-within] {
+[focus-within].js-focus-within [focus-within], .js-focus-within [focus-within] [focus-within] {
order: 5;
}
-[focus-within]+[focus-within] {
+:focus-within :focus-within {
+ order: 5;
+}
+
+[focus-within].js-focus-within+[focus-within], .js-focus-within [focus-within]+[focus-within] {
order: 6;
}
-[focus-within]+[focus-within] {
+:focus-within+:focus-within {
+ order: 6;
+}
+
+[focus-within].js-focus-within+[focus-within], .js-focus-within [focus-within]+[focus-within] {
+ order: 7;
+}
+
+:focus-within+:focus-within {
order: 7;
}
-[focus-within] + [focus-within] {
+[focus-within].js-focus-within + [focus-within], .js-focus-within [focus-within] + [focus-within] {
+ order: 8;
+}
+
+:focus-within + :focus-within {
order: 8;
}
-[focus-within] + [focus-within] {
+[focus-within].js-focus-within + [focus-within], .js-focus-within [focus-within] + [focus-within] {
+ order: 9;
+}
+
+:focus-within + :focus-within {
order: 9;
}
-[focus-within]~[focus-within] {
+[focus-within].js-focus-within~[focus-within], .js-focus-within [focus-within]~[focus-within] {
+ order: 10;
+}
+
+:focus-within~:focus-within {
order: 10;
}
-[focus-within]~[focus-within] {
+[focus-within].js-focus-within~[focus-within], .js-focus-within [focus-within]~[focus-within] {
order: 11;
}
-[focus-within] ~ [focus-within] {
+:focus-within~:focus-within {
+ order: 11;
+}
+
+[focus-within].js-focus-within ~ [focus-within], .js-focus-within [focus-within] ~ [focus-within] {
+ order: 12;
+}
+
+:focus-within ~ :focus-within {
order: 12;
}
-[focus-within] ~ [focus-within] {
+[focus-within].js-focus-within ~ [focus-within], .js-focus-within [focus-within] ~ [focus-within] {
order: 13;
}
-[focus-within]>[focus-within] {
+:focus-within ~ :focus-within {
+ order: 13;
+}
+
+[focus-within].js-focus-within>[focus-within], .js-focus-within [focus-within]>[focus-within] {
order: 14;
}
-[focus-within]>[focus-within] {
+:focus-within>:focus-within {
+ order: 14;
+}
+
+[focus-within].js-focus-within>[focus-within], .js-focus-within [focus-within]>[focus-within] {
order: 15;
}
-[focus-within] > [focus-within] {
+:focus-within>:focus-within {
+ order: 15;
+}
+
+[focus-within].js-focus-within > [focus-within], .js-focus-within [focus-within] > [focus-within] {
+ order: 16;
+}
+
+:focus-within > :focus-within {
order: 16;
}
-[focus-within] > [focus-within] {
+[focus-within].js-focus-within > [focus-within], .js-focus-within [focus-within] > [focus-within] {
order: 17;
}
-[focus-within],[focus-within] {
+:focus-within > :focus-within {
+ order: 17;
+}
+
+[focus-within].js-focus-within, .js-focus-within [focus-within], [focus-within].js-focus-within, .js-focus-within [focus-within] {
order: 18;
}
-[focus-within],[focus-within] {
+:focus-within, :focus-within {
+ order: 18;
+}
+
+[focus-within].js-focus-within, .js-focus-within [focus-within], [focus-within].js-focus-within, .js-focus-within [focus-within] {
order: 19;
}
-button[focus-within] {
+:focus-within, :focus-within {
+ order: 19;
+}
+
+button[focus-within].js-focus-within, .js-focus-within button[focus-within] {
+ order: 20;
+}
+
+button:focus-within {
order: 20;
}
@@ -86,319 +170,635 @@ button[focus-within] {
order: 21;
}
-button [focus-within] {
+button.js-focus-within [focus-within], .js-focus-within button [focus-within] {
+ order: 22;
+}
+
+button :focus-within {
order: 22;
}
-[focus-within] button {
+[focus-within].js-focus-within button, .js-focus-within [focus-within] button {
+ order: 23;
+}
+
+:focus-within button {
order: 23;
}
-button [focus-within] {
+button.js-focus-within [focus-within], .js-focus-within button [focus-within] {
+ order: 24;
+}
+
+button :focus-within {
order: 24;
}
-[focus-within] button {
+[focus-within].js-focus-within button, .js-focus-within [focus-within] button {
order: 25;
}
-button+[focus-within] {
+:focus-within button {
+ order: 25;
+}
+
+button.js-focus-within+[focus-within], .js-focus-within button+[focus-within] {
+ order: 26;
+}
+
+button+:focus-within {
order: 26;
}
-[focus-within]+button {
+[focus-within].js-focus-within+button, .js-focus-within [focus-within]+button {
order: 27;
}
-button + [focus-within] {
+:focus-within+button {
+ order: 27;
+}
+
+button.js-focus-within + [focus-within], .js-focus-within button + [focus-within] {
order: 28;
}
-[focus-within] + button {
+button + :focus-within {
+ order: 28;
+}
+
+[focus-within].js-focus-within + button, .js-focus-within [focus-within] + button {
order: 29;
}
-button~[focus-within] {
+:focus-within + button {
+ order: 29;
+}
+
+button.js-focus-within~[focus-within], .js-focus-within button~[focus-within] {
+ order: 30;
+}
+
+button~:focus-within {
order: 30;
}
-[focus-within]~button {
+[focus-within].js-focus-within~button, .js-focus-within [focus-within]~button {
order: 31;
}
-button ~ [focus-within] {
+:focus-within~button {
+ order: 31;
+}
+
+button.js-focus-within ~ [focus-within], .js-focus-within button ~ [focus-within] {
+ order: 32;
+}
+
+button ~ :focus-within {
order: 32;
}
-[focus-within] ~ button {
+[focus-within].js-focus-within ~ button, .js-focus-within [focus-within] ~ button {
+ order: 33;
+}
+
+:focus-within ~ button {
order: 33;
}
-button>[focus-within] {
+button.js-focus-within>[focus-within], .js-focus-within button>[focus-within] {
+ order: 34;
+}
+
+button>:focus-within {
order: 34;
}
-[focus-within]>button {
+[focus-within].js-focus-within>button, .js-focus-within [focus-within]>button {
+ order: 35;
+}
+
+:focus-within>button {
order: 35;
}
-button > [focus-within] {
+button.js-focus-within > [focus-within], .js-focus-within button > [focus-within] {
order: 36;
}
-[focus-within] > button {
+button > :focus-within {
+ order: 36;
+}
+
+[focus-within].js-focus-within > button, .js-focus-within [focus-within] > button {
order: 37;
}
-button,[focus-within] {
+:focus-within > button {
+ order: 37;
+}
+
+button, [focus-within].js-focus-within, .js-focus-within [focus-within] {
+ order: 38;
+}
+
+button, :focus-within {
order: 38;
}
-[focus-within], button {
+[focus-within].js-focus-within, .js-focus-within [focus-within], button {
+ order: 39;
+}
+
+:focus-within, button {
order: 39;
}
-.🧑🏾🎤[focus-within] {
+.🧑🏾🎤[focus-within].js-focus-within, .js-focus-within .🧑🏾🎤[focus-within] {
+ order: 40;
+}
+
+.🧑🏾🎤:focus-within {
order: 40;
}
-[focus-within].🧑🏾🎤 {
+[focus-within].🧑🏾🎤.js-focus-within, .js-focus-within [focus-within].🧑🏾🎤 {
+ order: 41;
+}
+
+:focus-within.🧑🏾🎤 {
order: 41;
}
-.🧑🏾🎤 [focus-within] {
+.🧑🏾🎤.js-focus-within [focus-within], .js-focus-within .🧑🏾🎤 [focus-within] {
order: 42;
}
-[focus-within] .🧑🏾🎤 {
+.🧑🏾🎤 :focus-within {
+ order: 42;
+}
+
+[focus-within].js-focus-within .🧑🏾🎤, .js-focus-within [focus-within] .🧑🏾🎤 {
+ order: 43;
+}
+
+:focus-within .🧑🏾🎤 {
order: 43;
}
-.🧑🏾🎤 [focus-within] {
+.🧑🏾🎤.js-focus-within [focus-within], .js-focus-within .🧑🏾🎤 [focus-within] {
order: 44;
}
-[focus-within] .🧑🏾🎤 {
+.🧑🏾🎤 :focus-within {
+ order: 44;
+}
+
+[focus-within].js-focus-within .🧑🏾🎤, .js-focus-within [focus-within] .🧑🏾🎤 {
order: 45;
}
-.🧑🏾🎤+[focus-within] {
+:focus-within .🧑🏾🎤 {
+ order: 45;
+}
+
+.🧑🏾🎤.js-focus-within+[focus-within], .js-focus-within .🧑🏾🎤+[focus-within] {
order: 46;
}
-[focus-within]+.🧑🏾🎤 {
+.🧑🏾🎤+:focus-within {
+ order: 46;
+}
+
+[focus-within].js-focus-within+.🧑🏾🎤, .js-focus-within [focus-within]+.🧑🏾🎤 {
+ order: 47;
+}
+
+:focus-within+.🧑🏾🎤 {
order: 47;
}
-.🧑🏾🎤 + [focus-within] {
+.🧑🏾🎤.js-focus-within + [focus-within], .js-focus-within .🧑🏾🎤 + [focus-within] {
+ order: 48;
+}
+
+.🧑🏾🎤 + :focus-within {
order: 48;
}
-[focus-within] + .🧑🏾🎤 {
+[focus-within].js-focus-within + .🧑🏾🎤, .js-focus-within [focus-within] + .🧑🏾🎤 {
order: 49;
}
-.🧑🏾🎤~[focus-within] {
+:focus-within + .🧑🏾🎤 {
+ order: 49;
+}
+
+.🧑🏾🎤.js-focus-within~[focus-within], .js-focus-within .🧑🏾🎤~[focus-within] {
order: 50;
}
-[focus-within]~.🧑🏾🎤 {
+.🧑🏾🎤~:focus-within {
+ order: 50;
+}
+
+[focus-within].js-focus-within~.🧑🏾🎤, .js-focus-within [focus-within]~.🧑🏾🎤 {
+ order: 51;
+}
+
+:focus-within~.🧑🏾🎤 {
order: 51;
}
-.🧑🏾🎤 ~ [focus-within] {
+.🧑🏾🎤.js-focus-within ~ [focus-within], .js-focus-within .🧑🏾🎤 ~ [focus-within] {
order: 52;
}
-[focus-within] ~ .🧑🏾🎤 {
+.🧑🏾🎤 ~ :focus-within {
+ order: 52;
+}
+
+[focus-within].js-focus-within ~ .🧑🏾🎤, .js-focus-within [focus-within] ~ .🧑🏾🎤 {
+ order: 53;
+}
+
+:focus-within ~ .🧑🏾🎤 {
order: 53;
}
-.🧑🏾🎤>[focus-within] {
+.🧑🏾🎤.js-focus-within>[focus-within], .js-focus-within .🧑🏾🎤>[focus-within] {
+ order: 54;
+}
+
+.🧑🏾🎤>:focus-within {
order: 54;
}
-[focus-within]>.🧑🏾🎤 {
+[focus-within].js-focus-within>.🧑🏾🎤, .js-focus-within [focus-within]>.🧑🏾🎤 {
order: 55;
}
-.🧑🏾🎤 > [focus-within] {
+:focus-within>.🧑🏾🎤 {
+ order: 55;
+}
+
+.🧑🏾🎤.js-focus-within > [focus-within], .js-focus-within .🧑🏾🎤 > [focus-within] {
+ order: 56;
+}
+
+.🧑🏾🎤 > :focus-within {
order: 56;
}
-[focus-within] > .🧑🏾🎤 {
+[focus-within].js-focus-within > .🧑🏾🎤, .js-focus-within [focus-within] > .🧑🏾🎤 {
order: 57;
}
-.🧑🏾🎤,[focus-within] {
+:focus-within > .🧑🏾🎤 {
+ order: 57;
+}
+
+.🧑🏾🎤, [focus-within].js-focus-within, .js-focus-within [focus-within] {
order: 58;
}
-[focus-within], .🧑🏾🎤 {
+.🧑🏾🎤, :focus-within {
+ order: 58;
+}
+
+[focus-within].js-focus-within, .js-focus-within [focus-within], .🧑🏾🎤 {
order: 59;
}
-.foo[focus-within] {
+:focus-within, .🧑🏾🎤 {
+ order: 59;
+}
+
+.foo[focus-within].js-focus-within, .js-focus-within .foo[focus-within] {
+ order: 60;
+}
+
+.foo:focus-within {
order: 60;
}
-[focus-within].foo {
+[focus-within].foo.js-focus-within, .js-focus-within [focus-within].foo {
order: 61;
}
-.foo [focus-within] {
+:focus-within.foo {
+ order: 61;
+}
+
+.foo.js-focus-within [focus-within], .js-focus-within .foo [focus-within] {
order: 62;
}
-[focus-within] .foo {
+.foo :focus-within {
+ order: 62;
+}
+
+[focus-within].js-focus-within .foo, .js-focus-within [focus-within] .foo {
order: 63;
}
-.foo [focus-within] {
+:focus-within .foo {
+ order: 63;
+}
+
+.foo.js-focus-within [focus-within], .js-focus-within .foo [focus-within] {
+ order: 64;
+}
+
+.foo :focus-within {
order: 64;
}
-[focus-within] .foo {
+[focus-within].js-focus-within .foo, .js-focus-within [focus-within] .foo {
order: 65;
}
-.foo+[focus-within] {
+:focus-within .foo {
+ order: 65;
+}
+
+.foo.js-focus-within+[focus-within], .js-focus-within .foo+[focus-within] {
+ order: 66;
+}
+
+.foo+:focus-within {
order: 66;
}
-[focus-within]+.foo {
+[focus-within].js-focus-within+.foo, .js-focus-within [focus-within]+.foo {
+ order: 67;
+}
+
+:focus-within+.foo {
order: 67;
}
-.foo + [focus-within] {
+.foo.js-focus-within + [focus-within], .js-focus-within .foo + [focus-within] {
+ order: 68;
+}
+
+.foo + :focus-within {
order: 68;
}
-[focus-within] + .foo {
+[focus-within].js-focus-within + .foo, .js-focus-within [focus-within] + .foo {
order: 69;
}
-.foo~[focus-within] {
+:focus-within + .foo {
+ order: 69;
+}
+
+.foo.js-focus-within~[focus-within], .js-focus-within .foo~[focus-within] {
+ order: 70;
+}
+
+.foo~:focus-within {
order: 70;
}
-[focus-within]~.foo {
+[focus-within].js-focus-within~.foo, .js-focus-within [focus-within]~.foo {
+ order: 71;
+}
+
+:focus-within~.foo {
order: 71;
}
-.foo ~ [focus-within] {
+.foo.js-focus-within ~ [focus-within], .js-focus-within .foo ~ [focus-within] {
order: 72;
}
-[focus-within] ~ .foo {
+.foo ~ :focus-within {
+ order: 72;
+}
+
+[focus-within].js-focus-within ~ .foo, .js-focus-within [focus-within] ~ .foo {
+ order: 73;
+}
+
+:focus-within ~ .foo {
order: 73;
}
-.foo>[focus-within] {
+.foo.js-focus-within>[focus-within], .js-focus-within .foo>[focus-within] {
order: 74;
}
-[focus-within]>.foo {
+.foo>:focus-within {
+ order: 74;
+}
+
+[focus-within].js-focus-within>.foo, .js-focus-within [focus-within]>.foo {
order: 75;
}
-.foo > [focus-within] {
+:focus-within>.foo {
+ order: 75;
+}
+
+.foo.js-focus-within > [focus-within], .js-focus-within .foo > [focus-within] {
order: 76;
}
-[focus-within] > .foo {
+.foo > :focus-within {
+ order: 76;
+}
+
+[focus-within].js-focus-within > .foo, .js-focus-within [focus-within] > .foo {
+ order: 77;
+}
+
+:focus-within > .foo {
order: 77;
}
-.foo,[focus-within] {
+.foo, [focus-within].js-focus-within, .js-focus-within [focus-within] {
+ order: 78;
+}
+
+.foo, :focus-within {
order: 78;
}
-[focus-within], .foo {
+[focus-within].js-focus-within, .js-focus-within [focus-within], .foo {
order: 79;
}
-#foo[focus-within] {
+:focus-within, .foo {
+ order: 79;
+}
+
+#foo[focus-within].js-focus-within, .js-focus-within #foo[focus-within] {
order: 80;
}
-[focus-within]#foo {
+#foo:focus-within {
+ order: 80;
+}
+
+[focus-within]#foo.js-focus-within, .js-focus-within [focus-within]#foo {
+ order: 81;
+}
+
+:focus-within#foo {
order: 81;
}
-#foo [focus-within] {
+#foo.js-focus-within [focus-within], .js-focus-within #foo [focus-within] {
+ order: 82;
+}
+
+#foo :focus-within {
order: 82;
}
-[focus-within] #foo {
+[focus-within].js-focus-within #foo, .js-focus-within [focus-within] #foo {
+ order: 83;
+}
+
+:focus-within #foo {
order: 83;
}
-#foo [focus-within] {
+#foo.js-focus-within [focus-within], .js-focus-within #foo [focus-within] {
+ order: 84;
+}
+
+#foo :focus-within {
order: 84;
}
-[focus-within] #foo {
+[focus-within].js-focus-within #foo, .js-focus-within [focus-within] #foo {
order: 85;
}
-#foo+[focus-within] {
+:focus-within #foo {
+ order: 85;
+}
+
+#foo.js-focus-within+[focus-within], .js-focus-within #foo+[focus-within] {
+ order: 86;
+}
+
+#foo+:focus-within {
order: 86;
}
-[focus-within]+#foo {
+[focus-within].js-focus-within+#foo, .js-focus-within [focus-within]+#foo {
order: 87;
}
-#foo + [focus-within] {
+:focus-within+#foo {
+ order: 87;
+}
+
+#foo.js-focus-within + [focus-within], .js-focus-within #foo + [focus-within] {
order: 88;
}
-[focus-within] + #foo {
+#foo + :focus-within {
+ order: 88;
+}
+
+[focus-within].js-focus-within + #foo, .js-focus-within [focus-within] + #foo {
order: 89;
}
-#foo~[focus-within] {
+:focus-within + #foo {
+ order: 89;
+}
+
+#foo.js-focus-within~[focus-within], .js-focus-within #foo~[focus-within] {
+ order: 90;
+}
+
+#foo~:focus-within {
order: 90;
}
-[focus-within]~#foo {
+[focus-within].js-focus-within~#foo, .js-focus-within [focus-within]~#foo {
+ order: 91;
+}
+
+:focus-within~#foo {
order: 91;
}
-#foo ~ [focus-within] {
+#foo.js-focus-within ~ [focus-within], .js-focus-within #foo ~ [focus-within] {
order: 92;
}
-[focus-within] ~ #foo {
+#foo ~ :focus-within {
+ order: 92;
+}
+
+[focus-within].js-focus-within ~ #foo, .js-focus-within [focus-within] ~ #foo {
order: 93;
}
-#foo>[focus-within] {
+:focus-within ~ #foo {
+ order: 93;
+}
+
+#foo.js-focus-within>[focus-within], .js-focus-within #foo>[focus-within] {
+ order: 94;
+}
+
+#foo>:focus-within {
order: 94;
}
-[focus-within]>#foo {
+[focus-within].js-focus-within>#foo, .js-focus-within [focus-within]>#foo {
order: 95;
}
-#foo > [focus-within] {
+:focus-within>#foo {
+ order: 95;
+}
+
+#foo.js-focus-within > [focus-within], .js-focus-within #foo > [focus-within] {
+ order: 96;
+}
+
+#foo > :focus-within {
order: 96;
}
-[focus-within] > #foo {
+[focus-within].js-focus-within > #foo, .js-focus-within [focus-within] > #foo {
+ order: 97;
+}
+
+:focus-within > #foo {
order: 97;
}
-#foo,[focus-within] {
+#foo, [focus-within].js-focus-within, .js-focus-within [focus-within] {
order: 98;
}
-[focus-within], #foo {
+#foo, :focus-within {
+ order: 98;
+}
+
+[focus-within].js-focus-within, .js-focus-within [focus-within], #foo {
+ order: 99;
+}
+
+:focus-within, #foo {
order: 99;
}
-__foo[focus-within] {
+__foo[focus-within].js-focus-within, .js-focus-within __foo[focus-within] {
+ order: 100;
+}
+
+__foo:focus-within {
order: 100;
}
@@ -406,475 +806,947 @@ __foo[focus-within] {
order: 101;
}
-__foo [focus-within] {
+__foo.js-focus-within [focus-within], .js-focus-within __foo [focus-within] {
+ order: 102;
+}
+
+__foo :focus-within {
order: 102;
}
-[focus-within] __foo {
+[focus-within].js-focus-within __foo, .js-focus-within [focus-within] __foo {
order: 103;
}
-__foo [focus-within] {
+:focus-within __foo {
+ order: 103;
+}
+
+__foo.js-focus-within [focus-within], .js-focus-within __foo [focus-within] {
+ order: 104;
+}
+
+__foo :focus-within {
order: 104;
}
-[focus-within] __foo {
+[focus-within].js-focus-within __foo, .js-focus-within [focus-within] __foo {
order: 105;
}
-__foo+[focus-within] {
+:focus-within __foo {
+ order: 105;
+}
+
+__foo.js-focus-within+[focus-within], .js-focus-within __foo+[focus-within] {
order: 106;
}
-[focus-within]+__foo {
+__foo+:focus-within {
+ order: 106;
+}
+
+[focus-within].js-focus-within+__foo, .js-focus-within [focus-within]+__foo {
order: 107;
}
-__foo + [focus-within] {
+:focus-within+__foo {
+ order: 107;
+}
+
+__foo.js-focus-within + [focus-within], .js-focus-within __foo + [focus-within] {
+ order: 108;
+}
+
+__foo + :focus-within {
order: 108;
}
-[focus-within] + __foo {
+[focus-within].js-focus-within + __foo, .js-focus-within [focus-within] + __foo {
+ order: 109;
+}
+
+:focus-within + __foo {
order: 109;
}
-__foo~[focus-within] {
+__foo.js-focus-within~[focus-within], .js-focus-within __foo~[focus-within] {
order: 110;
}
-[focus-within]~__foo {
+__foo~:focus-within {
+ order: 110;
+}
+
+[focus-within].js-focus-within~__foo, .js-focus-within [focus-within]~__foo {
order: 111;
}
-__foo ~ [focus-within] {
+:focus-within~__foo {
+ order: 111;
+}
+
+__foo.js-focus-within ~ [focus-within], .js-focus-within __foo ~ [focus-within] {
+ order: 112;
+}
+
+__foo ~ :focus-within {
order: 112;
}
-[focus-within] ~ __foo {
+[focus-within].js-focus-within ~ __foo, .js-focus-within [focus-within] ~ __foo {
order: 113;
}
-__foo>[focus-within] {
+:focus-within ~ __foo {
+ order: 113;
+}
+
+__foo.js-focus-within>[focus-within], .js-focus-within __foo>[focus-within] {
+ order: 114;
+}
+
+__foo>:focus-within {
order: 114;
}
-[focus-within]>__foo {
+[focus-within].js-focus-within>__foo, .js-focus-within [focus-within]>__foo {
+ order: 115;
+}
+
+:focus-within>__foo {
order: 115;
}
-__foo > [focus-within] {
+__foo.js-focus-within > [focus-within], .js-focus-within __foo > [focus-within] {
order: 116;
}
-[focus-within] > __foo {
+__foo > :focus-within {
+ order: 116;
+}
+
+[focus-within].js-focus-within > __foo, .js-focus-within [focus-within] > __foo {
+ order: 117;
+}
+
+:focus-within > __foo {
order: 117;
}
-__foo,[focus-within] {
+__foo, [focus-within].js-focus-within, .js-focus-within [focus-within] {
order: 118;
}
-[focus-within], __foo {
+__foo, :focus-within {
+ order: 118;
+}
+
+[focus-within].js-focus-within, .js-focus-within [focus-within], __foo {
+ order: 119;
+}
+
+:focus-within, __foo {
order: 119;
}
-:--foo[focus-within] {
+:--foo[focus-within].js-focus-within, .js-focus-within :--foo[focus-within] {
order: 120;
}
-[focus-within]:--foo {
+:--foo:focus-within {
+ order: 120;
+}
+
+[focus-within]:--foo.js-focus-within, .js-focus-within [focus-within]:--foo {
+ order: 121;
+}
+
+:focus-within:--foo {
order: 121;
}
-:--foo [focus-within] {
+:--foo.js-focus-within [focus-within], .js-focus-within :--foo [focus-within] {
order: 122;
}
-[focus-within] :--foo {
+:--foo :focus-within {
+ order: 122;
+}
+
+[focus-within].js-focus-within :--foo, .js-focus-within [focus-within] :--foo {
order: 123;
}
-:--foo [focus-within] {
+:focus-within :--foo {
+ order: 123;
+}
+
+:--foo.js-focus-within [focus-within], .js-focus-within :--foo [focus-within] {
order: 124;
}
-[focus-within] :--foo {
+:--foo :focus-within {
+ order: 124;
+}
+
+[focus-within].js-focus-within :--foo, .js-focus-within [focus-within] :--foo {
+ order: 125;
+}
+
+:focus-within :--foo {
order: 125;
}
-:--foo+[focus-within] {
+:--foo.js-focus-within+[focus-within], .js-focus-within :--foo+[focus-within] {
+ order: 126;
+}
+
+:--foo+:focus-within {
order: 126;
}
-[focus-within]+:--foo {
+[focus-within].js-focus-within+:--foo, .js-focus-within [focus-within]+:--foo {
order: 127;
}
-:--foo + [focus-within] {
+:focus-within+:--foo {
+ order: 127;
+}
+
+:--foo.js-focus-within + [focus-within], .js-focus-within :--foo + [focus-within] {
order: 128;
}
-[focus-within] + :--foo {
+:--foo + :focus-within {
+ order: 128;
+}
+
+[focus-within].js-focus-within + :--foo, .js-focus-within [focus-within] + :--foo {
+ order: 129;
+}
+
+:focus-within + :--foo {
order: 129;
}
-:--foo~[focus-within] {
+:--foo.js-focus-within~[focus-within], .js-focus-within :--foo~[focus-within] {
order: 130;
}
-[focus-within]~:--foo {
+:--foo~:focus-within {
+ order: 130;
+}
+
+[focus-within].js-focus-within~:--foo, .js-focus-within [focus-within]~:--foo {
+ order: 131;
+}
+
+:focus-within~:--foo {
order: 131;
}
-:--foo ~ [focus-within] {
+:--foo.js-focus-within ~ [focus-within], .js-focus-within :--foo ~ [focus-within] {
+ order: 132;
+}
+
+:--foo ~ :focus-within {
order: 132;
}
-[focus-within] ~ :--foo {
+[focus-within].js-focus-within ~ :--foo, .js-focus-within [focus-within] ~ :--foo {
order: 133;
}
-:--foo>[focus-within] {
+:focus-within ~ :--foo {
+ order: 133;
+}
+
+:--foo.js-focus-within>[focus-within], .js-focus-within :--foo>[focus-within] {
+ order: 134;
+}
+
+:--foo>:focus-within {
order: 134;
}
-[focus-within]>:--foo {
+[focus-within].js-focus-within>:--foo, .js-focus-within [focus-within]>:--foo {
order: 135;
}
-:--foo > [focus-within] {
- order: 136;
+:focus-within>:--foo {
+ order: 135;
+}
+
+:--foo.js-focus-within > [focus-within], .js-focus-within :--foo > [focus-within] {
+ order: 136;
+}
+
+:--foo > :focus-within {
+ order: 136;
+}
+
+[focus-within].js-focus-within > :--foo, .js-focus-within [focus-within] > :--foo {
+ order: 137;
+}
+
+:focus-within > :--foo {
+ order: 137;
}
-[focus-within] > :--foo {
- order: 137;
+:--foo, [focus-within].js-focus-within, .js-focus-within [focus-within] {
+ order: 138;
}
-:--foo,[focus-within] {
+:--foo, :focus-within {
order: 138;
}
-[focus-within], :--foo {
+[focus-within].js-focus-within, .js-focus-within [focus-within], :--foo {
order: 139;
}
-[foo="baz"][focus-within] {
+:focus-within, :--foo {
+ order: 139;
+}
+
+[foo="baz"][focus-within].js-focus-within, .js-focus-within [foo="baz"][focus-within] {
+ order: 140;
+}
+
+[foo="baz"]:focus-within {
order: 140;
}
-[focus-within][foo="baz"] {
+[focus-within][foo="baz"].js-focus-within, .js-focus-within [focus-within][foo="baz"] {
+ order: 141;
+}
+
+:focus-within[foo="baz"] {
order: 141;
}
-[foo="baz"] [focus-within] {
+[foo="baz"].js-focus-within [focus-within], .js-focus-within [foo="baz"] [focus-within] {
+ order: 142;
+}
+
+[foo="baz"] :focus-within {
order: 142;
}
-[focus-within] [foo="baz"] {
+[focus-within].js-focus-within [foo="baz"], .js-focus-within [focus-within] [foo="baz"] {
order: 143;
}
-[foo="baz"] [focus-within] {
+:focus-within [foo="baz"] {
+ order: 143;
+}
+
+[foo="baz"].js-focus-within [focus-within], .js-focus-within [foo="baz"] [focus-within] {
+ order: 144;
+}
+
+[foo="baz"] :focus-within {
order: 144;
}
-[focus-within] [foo="baz"] {
+[focus-within].js-focus-within [foo="baz"], .js-focus-within [focus-within] [foo="baz"] {
+ order: 145;
+}
+
+:focus-within [foo="baz"] {
order: 145;
}
-[foo="baz"]+[focus-within] {
+[foo="baz"].js-focus-within+[focus-within], .js-focus-within [foo="baz"]+[focus-within] {
+ order: 146;
+}
+
+[foo="baz"]+:focus-within {
order: 146;
}
-[focus-within]+[foo="baz"] {
+[focus-within].js-focus-within+[foo="baz"], .js-focus-within [focus-within]+[foo="baz"] {
order: 147;
}
-[foo="baz"] + [focus-within] {
+:focus-within+[foo="baz"] {
+ order: 147;
+}
+
+[foo="baz"].js-focus-within + [focus-within], .js-focus-within [foo="baz"] + [focus-within] {
+ order: 148;
+}
+
+[foo="baz"] + :focus-within {
order: 148;
}
-[focus-within] + [foo="baz"] {
+[focus-within].js-focus-within + [foo="baz"], .js-focus-within [focus-within] + [foo="baz"] {
+ order: 149;
+}
+
+:focus-within + [foo="baz"] {
order: 149;
}
-[foo="baz"]~[focus-within] {
+[foo="baz"].js-focus-within~[focus-within], .js-focus-within [foo="baz"]~[focus-within] {
+ order: 150;
+}
+
+[foo="baz"]~:focus-within {
order: 150;
}
-[focus-within]~[foo="baz"] {
+[focus-within].js-focus-within~[foo="baz"], .js-focus-within [focus-within]~[foo="baz"] {
order: 151;
}
-[foo="baz"] ~ [focus-within] {
+:focus-within~[foo="baz"] {
+ order: 151;
+}
+
+[foo="baz"].js-focus-within ~ [focus-within], .js-focus-within [foo="baz"] ~ [focus-within] {
+ order: 152;
+}
+
+[foo="baz"] ~ :focus-within {
order: 152;
}
-[focus-within] ~ [foo="baz"] {
+[focus-within].js-focus-within ~ [foo="baz"], .js-focus-within [focus-within] ~ [foo="baz"] {
+ order: 153;
+}
+
+:focus-within ~ [foo="baz"] {
order: 153;
}
-[foo="baz"]>[focus-within] {
+[foo="baz"].js-focus-within>[focus-within], .js-focus-within [foo="baz"]>[focus-within] {
+ order: 154;
+}
+
+[foo="baz"]>:focus-within {
order: 154;
}
-[focus-within]>[foo="baz"] {
+[focus-within].js-focus-within>[foo="baz"], .js-focus-within [focus-within]>[foo="baz"] {
order: 155;
}
-[foo="baz"] > [focus-within] {
+:focus-within>[foo="baz"] {
+ order: 155;
+}
+
+[foo="baz"].js-focus-within > [focus-within], .js-focus-within [foo="baz"] > [focus-within] {
+ order: 156;
+}
+
+[foo="baz"] > :focus-within {
order: 156;
}
-[focus-within] > [foo="baz"] {
+[focus-within].js-focus-within > [foo="baz"], .js-focus-within [focus-within] > [foo="baz"] {
+ order: 157;
+}
+
+:focus-within > [foo="baz"] {
order: 157;
}
-[foo="baz"],[focus-within] {
+[foo="baz"], [focus-within].js-focus-within, .js-focus-within [focus-within] {
+ order: 158;
+}
+
+[foo="baz"], :focus-within {
order: 158;
}
-[focus-within], [foo="baz"] {
+[focus-within].js-focus-within, .js-focus-within [focus-within], [foo="baz"] {
order: 159;
}
-*[focus-within] {
+:focus-within, [foo="baz"] {
+ order: 159;
+}
+
+*[focus-within].js-focus-within, .js-focus-within *[focus-within] {
+ order: 160;
+}
+
+*:focus-within {
order: 160;
}
-[focus-within]* {
+[focus-within]*.js-focus-within, .js-focus-within [focus-within]* {
+ order: 161;
+}
+
+:focus-within* {
order: 161;
}
-* [focus-within] {
+*.js-focus-within [focus-within], .js-focus-within * [focus-within] {
+ order: 162;
+}
+
+* :focus-within {
order: 162;
}
-[focus-within] * {
+[focus-within].js-focus-within *, .js-focus-within [focus-within] * {
order: 163;
}
-* [focus-within] {
+:focus-within * {
+ order: 163;
+}
+
+*.js-focus-within [focus-within], .js-focus-within * [focus-within] {
+ order: 164;
+}
+
+* :focus-within {
order: 164;
}
-[focus-within] * {
+[focus-within].js-focus-within *, .js-focus-within [focus-within] * {
+ order: 165;
+}
+
+:focus-within * {
order: 165;
}
-*+[focus-within] {
+*.js-focus-within+[focus-within], .js-focus-within *+[focus-within] {
+ order: 166;
+}
+
+*+:focus-within {
order: 166;
}
-[focus-within]+* {
+[focus-within].js-focus-within+*, .js-focus-within [focus-within]+* {
order: 167;
}
-* + [focus-within] {
+:focus-within+* {
+ order: 167;
+}
+
+*.js-focus-within + [focus-within], .js-focus-within * + [focus-within] {
+ order: 168;
+}
+
+* + :focus-within {
order: 168;
}
-[focus-within] + * {
+[focus-within].js-focus-within + *, .js-focus-within [focus-within] + * {
+ order: 169;
+}
+
+:focus-within + * {
order: 169;
}
-*~[focus-within] {
+*.js-focus-within~[focus-within], .js-focus-within *~[focus-within] {
+ order: 170;
+}
+
+*~:focus-within {
order: 170;
}
-[focus-within]~* {
+[focus-within].js-focus-within~*, .js-focus-within [focus-within]~* {
order: 171;
}
-* ~ [focus-within] {
+:focus-within~* {
+ order: 171;
+}
+
+*.js-focus-within ~ [focus-within], .js-focus-within * ~ [focus-within] {
+ order: 172;
+}
+
+* ~ :focus-within {
order: 172;
}
-[focus-within] ~ * {
+[focus-within].js-focus-within ~ *, .js-focus-within [focus-within] ~ * {
+ order: 173;
+}
+
+:focus-within ~ * {
order: 173;
}
-*>[focus-within] {
+*.js-focus-within>[focus-within], .js-focus-within *>[focus-within] {
+ order: 174;
+}
+
+*>:focus-within {
order: 174;
}
-[focus-within]>* {
+[focus-within].js-focus-within>*, .js-focus-within [focus-within]>* {
order: 175;
}
-* > [focus-within] {
+:focus-within>* {
+ order: 175;
+}
+
+*.js-focus-within > [focus-within], .js-focus-within * > [focus-within] {
+ order: 176;
+}
+
+* > :focus-within {
order: 176;
}
-[focus-within] > * {
+[focus-within].js-focus-within > *, .js-focus-within [focus-within] > * {
+ order: 177;
+}
+
+:focus-within > * {
order: 177;
}
-*,[focus-within] {
+*, [focus-within].js-focus-within, .js-focus-within [focus-within] {
+ order: 178;
+}
+
+*, :focus-within {
order: 178;
}
-[focus-within], * {
+[focus-within].js-focus-within, .js-focus-within [focus-within], * {
order: 179;
}
-:hover[focus-within] {
+:focus-within, * {
+ order: 179;
+}
+
+:hover[focus-within].js-focus-within, .js-focus-within :hover[focus-within] {
+ order: 180;
+}
+
+:hover:focus-within {
order: 180;
}
-[focus-within]:hover {
+[focus-within]:hover.js-focus-within, .js-focus-within [focus-within]:hover {
+ order: 181;
+}
+
+:focus-within:hover {
order: 181;
}
-:hover [focus-within] {
+:hover.js-focus-within [focus-within], .js-focus-within :hover [focus-within] {
+ order: 182;
+}
+
+:hover :focus-within {
order: 182;
}
-[focus-within] :hover {
+[focus-within].js-focus-within :hover, .js-focus-within [focus-within] :hover {
order: 183;
}
-:hover [focus-within] {
+:focus-within :hover {
+ order: 183;
+}
+
+:hover.js-focus-within [focus-within], .js-focus-within :hover [focus-within] {
+ order: 184;
+}
+
+:hover :focus-within {
order: 184;
}
-[focus-within] :hover {
+[focus-within].js-focus-within :hover, .js-focus-within [focus-within] :hover {
+ order: 185;
+}
+
+:focus-within :hover {
order: 185;
}
-:hover+[focus-within] {
+:hover.js-focus-within+[focus-within], .js-focus-within :hover+[focus-within] {
+ order: 186;
+}
+
+:hover+:focus-within {
order: 186;
}
-[focus-within]+:hover {
+[focus-within].js-focus-within+:hover, .js-focus-within [focus-within]+:hover {
order: 187;
}
-:hover + [focus-within] {
+:focus-within+:hover {
+ order: 187;
+}
+
+:hover.js-focus-within + [focus-within], .js-focus-within :hover + [focus-within] {
+ order: 188;
+}
+
+:hover + :focus-within {
order: 188;
}
-[focus-within] + :hover {
+[focus-within].js-focus-within + :hover, .js-focus-within [focus-within] + :hover {
+ order: 189;
+}
+
+:focus-within + :hover {
order: 189;
}
-:hover~[focus-within] {
+:hover.js-focus-within~[focus-within], .js-focus-within :hover~[focus-within] {
+ order: 190;
+}
+
+:hover~:focus-within {
order: 190;
}
-[focus-within]~:hover {
+[focus-within].js-focus-within~:hover, .js-focus-within [focus-within]~:hover {
order: 191;
}
-:hover ~ [focus-within] {
+:focus-within~:hover {
+ order: 191;
+}
+
+:hover.js-focus-within ~ [focus-within], .js-focus-within :hover ~ [focus-within] {
+ order: 192;
+}
+
+:hover ~ :focus-within {
order: 192;
}
-[focus-within] ~ :hover {
+[focus-within].js-focus-within ~ :hover, .js-focus-within [focus-within] ~ :hover {
+ order: 193;
+}
+
+:focus-within ~ :hover {
order: 193;
}
-:hover>[focus-within] {
+:hover.js-focus-within>[focus-within], .js-focus-within :hover>[focus-within] {
+ order: 194;
+}
+
+:hover>:focus-within {
order: 194;
}
-[focus-within]>:hover {
+[focus-within].js-focus-within>:hover, .js-focus-within [focus-within]>:hover {
order: 195;
}
-:hover > [focus-within] {
+:focus-within>:hover {
+ order: 195;
+}
+
+:hover.js-focus-within > [focus-within], .js-focus-within :hover > [focus-within] {
+ order: 196;
+}
+
+:hover > :focus-within {
order: 196;
}
-[focus-within] > :hover {
+[focus-within].js-focus-within > :hover, .js-focus-within [focus-within] > :hover {
+ order: 197;
+}
+
+:focus-within > :hover {
order: 197;
}
-:hover,[focus-within] {
+:hover, [focus-within].js-focus-within, .js-focus-within [focus-within] {
+ order: 198;
+}
+
+:hover, :focus-within {
order: 198;
}
-[focus-within], :hover {
+[focus-within].js-focus-within, .js-focus-within [focus-within], :hover {
order: 199;
}
-::before[focus-within] {
+:focus-within, :hover {
+ order: 199;
+}
+
+.js-focus-within::before[focus-within], .js-focus-within ::before[focus-within] {
+ order: 200;
+}
+
+::before:focus-within {
order: 200;
}
-[focus-within]::before {
+[focus-within].js-focus-within::before, .js-focus-within [focus-within]::before {
+ order: 201;
+}
+
+:focus-within::before {
order: 201;
}
-::before [focus-within] {
+.js-focus-within::before [focus-within], .js-focus-within ::before [focus-within] {
+ order: 202;
+}
+
+::before :focus-within {
order: 202;
}
-[focus-within] ::before {
+[focus-within].js-focus-within ::before, .js-focus-within [focus-within] ::before {
order: 203;
}
-::before [focus-within] {
+:focus-within ::before {
+ order: 203;
+}
+
+.js-focus-within::before [focus-within], .js-focus-within ::before [focus-within] {
+ order: 204;
+}
+
+::before :focus-within {
order: 204;
}
-[focus-within] ::before {
+[focus-within].js-focus-within ::before, .js-focus-within [focus-within] ::before {
+ order: 205;
+}
+
+:focus-within ::before {
order: 205;
}
-::before+[focus-within] {
+.js-focus-within::before+[focus-within], .js-focus-within ::before+[focus-within] {
+ order: 206;
+}
+
+::before+:focus-within {
order: 206;
}
-[focus-within]+::before {
+[focus-within].js-focus-within+::before, .js-focus-within [focus-within]+::before {
order: 207;
}
-::before + [focus-within] {
+:focus-within+::before {
+ order: 207;
+}
+
+.js-focus-within::before + [focus-within], .js-focus-within ::before + [focus-within] {
+ order: 208;
+}
+
+::before + :focus-within {
order: 208;
}
-[focus-within] + ::before {
+[focus-within].js-focus-within + ::before, .js-focus-within [focus-within] + ::before {
+ order: 209;
+}
+
+:focus-within + ::before {
order: 209;
}
-::before~[focus-within] {
+.js-focus-within::before~[focus-within], .js-focus-within ::before~[focus-within] {
+ order: 210;
+}
+
+::before~:focus-within {
order: 210;
}
-[focus-within]~::before {
+[focus-within].js-focus-within~::before, .js-focus-within [focus-within]~::before {
order: 211;
}
-::before ~ [focus-within] {
+:focus-within~::before {
+ order: 211;
+}
+
+.js-focus-within::before ~ [focus-within], .js-focus-within ::before ~ [focus-within] {
+ order: 212;
+}
+
+::before ~ :focus-within {
order: 212;
}
-[focus-within] ~ ::before {
+[focus-within].js-focus-within ~ ::before, .js-focus-within [focus-within] ~ ::before {
+ order: 213;
+}
+
+:focus-within ~ ::before {
order: 213;
}
-::before>[focus-within] {
+.js-focus-within::before>[focus-within], .js-focus-within ::before>[focus-within] {
+ order: 214;
+}
+
+::before>:focus-within {
order: 214;
}
-[focus-within]>::before {
+[focus-within].js-focus-within>::before, .js-focus-within [focus-within]>::before {
order: 215;
}
-::before > [focus-within] {
+:focus-within>::before {
+ order: 215;
+}
+
+.js-focus-within::before > [focus-within], .js-focus-within ::before > [focus-within] {
+ order: 216;
+}
+
+::before > :focus-within {
order: 216;
}
-[focus-within] > ::before {
+[focus-within].js-focus-within > ::before, .js-focus-within [focus-within] > ::before {
+ order: 217;
+}
+
+:focus-within > ::before {
order: 217;
}
-::before,[focus-within] {
+::before, [focus-within].js-focus-within, .js-focus-within [focus-within] {
+ order: 218;
+}
+
+::before, :focus-within {
order: 218;
}
-[focus-within], ::before {
+[focus-within].js-focus-within, .js-focus-within [focus-within], ::before {
+ order: 219;
+}
+
+:focus-within, ::before {
order: 219;
}
@@ -886,7 +1758,11 @@ foo[baz=":focus-within"] {
order: 221;
}
-:not([focus-within]) {
+:not([focus-within]).js-focus-within, .js-focus-within :not([focus-within]) {
+ order: 222;
+}
+
+:not(:focus-within) {
order: 222;
}
@@ -894,11 +1770,19 @@ foo[baz=":focus-within"] {
order: 223;
}
-:--[focus-within] {
+:--[focus-within].js-focus-within, .js-focus-within :--[focus-within] {
+ order: 224;
+}
+
+:--:focus-within {
order: 224;
}
-__[focus-within] {
+__[focus-within].js-focus-within, .js-focus-within __[focus-within] {
+ order: 225;
+}
+
+__:focus-within {
order: 225;
}