diff --git a/package-lock.json b/package-lock.json index 1a4a9509c..e32328135 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7092,6 +7092,9 @@ "dependencies": { "postcss-selector-parser": "^6.0.10" }, + "devDependencies": { + "puppeteer": "^15.1.1" + }, "engines": { "node": "^12 || ^14 || >=16" }, @@ -11380,7 +11383,8 @@ "postcss-focus-visible": { "version": "file:plugins/postcss-focus-visible", "requires": { - "postcss-selector-parser": "^6.0.10" + "postcss-selector-parser": "^6.0.10", + "puppeteer": "^15.1.1" } }, "postcss-focus-within": { 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 67c580e48..04a386918 100644 --- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css @@ -248,11 +248,7 @@ word-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } 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 67c580e48..04a386918 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 @@ -248,11 +248,7 @@ word-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } 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 8662f17da..a5705715b 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css @@ -168,11 +168,7 @@ overflow-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } 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 aa72d3538..e2e988048 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 @@ -167,11 +167,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te overflow-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } 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 13a393a42..1bacd82cf 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 @@ -160,11 +160,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te overflow-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } 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 beeba4b2b..f952bd095 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 @@ -160,11 +160,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te overflow-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } diff --git a/plugin-packs/postcss-preset-env/test/basic.expect.css b/plugin-packs/postcss-preset-env/test/basic.expect.css index 55763624e..e11ceebf5 100644 --- a/plugin-packs/postcss-preset-env/test/basic.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.expect.css @@ -271,11 +271,7 @@ word-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } 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 34b0a3fa7..ffefaebfe 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css @@ -164,11 +164,7 @@ overflow-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } 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 37806912a..750ac0a92 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css @@ -152,11 +152,7 @@ overflow-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } 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 3c2fbd479..04aa57af0 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css @@ -278,12 +278,7 @@ word-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - -ms-flex-order: 26; - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { -ms-flex-order: 26; order: 26; } 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 12dca7cf3..ffb44f222 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 @@ -269,11 +269,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te word-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } 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 57e75c092..b49914b31 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 @@ -255,11 +255,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te word-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } diff --git a/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css b/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css index 4e01ebd91..a1f0d0dd7 100644 --- a/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css @@ -495,7 +495,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te word-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { -webkit-box-ordinal-group: 27; -webkit-order: 26; -moz-box-ordinal-group: 27; 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 725600ff5..34fb267d8 100644 --- a/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css @@ -137,11 +137,7 @@ overflow-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } 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 a58b488f0..819fa1807 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 @@ -169,11 +169,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te overflow-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } 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 26f9a3fee..6c3310c42 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 @@ -157,11 +157,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te overflow-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } 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 57e734eae..2b9efb7d1 100644 --- a/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css @@ -276,11 +276,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te word-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible { - order: 26; -} - -.test-focus-visible-pseudo-class:focus-visible { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible { order: 26; } 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 ba171663b..eb3e1fa8a 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 @@ -2,7 +2,7 @@ order: 1; } -.focus-visible { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 2; } 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 f72e02255..557e9e2a1 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 @@ -2,7 +2,7 @@ order: 1; } -.focus-visible { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 2; } 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 88a4963f9..a51a04d89 100644 --- a/plugin-packs/postcss-preset-env/test/layers-basic.expect.css +++ b/plugin-packs/postcss-preset-env/test/layers-basic.expect.css @@ -445,15 +445,7 @@ h1.test-custom-selectors:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):n word-wrap: break-word; } -.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-focus-visible-pseudo-class:focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#), .js-focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) .test-focus-visible-pseudo-class.focus-visible { -webkit-box-ordinal-group: 27; -webkit-order: 26; -moz-box-ordinal-group: 27; diff --git a/plugin-packs/postcss-preset-env/test/layers-basic.preserve.true.expect.css b/plugin-packs/postcss-preset-env/test/layers-basic.preserve.true.expect.css index 47a28fae3..d007c24b5 100644 --- a/plugin-packs/postcss-preset-env/test/layers-basic.preserve.true.expect.css +++ b/plugin-packs/postcss-preset-env/test/layers-basic.preserve.true.expect.css @@ -506,7 +506,7 @@ h1.test-custom-selectors:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):n word-wrap: break-word; } -.test-focus-visible-pseudo-class.focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { +.test-focus-visible-pseudo-class.focus-visible.js-focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#), .js-focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) .test-focus-visible-pseudo-class.focus-visible { -webkit-box-ordinal-group: 27; -webkit-order: 26; -moz-box-ordinal-group: 27; diff --git a/plugins/css-blank-pseudo/src/index.ts b/plugins/css-blank-pseudo/src/index.ts index 62b01afda..4a870374a 100644 --- a/plugins/css-blank-pseudo/src/index.ts +++ b/plugins/css-blank-pseudo/src/index.ts @@ -2,7 +2,7 @@ import type { PluginCreator } from 'postcss'; import parser from 'postcss-selector-parser'; import isValidReplacement from './is-valid-replacement.mjs'; -type pluginOptions = { color?: string, preserve?: boolean }; +type pluginOptions = { preserve?: boolean, replaceWith?: string }; const creator: PluginCreator = (opts?: pluginOptions) => { const options = Object.assign( diff --git a/plugins/postcss-focus-visible/.gitignore b/plugins/postcss-focus-visible/.gitignore index 17847a362..7172b04f1 100644 --- a/plugins/postcss-focus-visible/.gitignore +++ b/plugins/postcss-focus-visible/.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-visible/.tape.mjs b/plugins/postcss-focus-visible/.tape.mjs index 4b1596d6d..fcacb0d33 100644 --- a/plugins/postcss-focus-visible/.tape.mjs +++ b/plugins/postcss-focus-visible/.tape.mjs @@ -8,7 +8,7 @@ postcssTape(plugin)({ 'basic:replacewith': { message: 'supports { replaceWith: "[focus-visible]" } usage', options: { - replaceWith: '[focus-visible]' + replaceWith: '[data-focus-visible-added]' } }, 'basic:preserve': { @@ -24,4 +24,22 @@ postcssTape(plugin)({ preserve: false } }, + 'browser': { + message: 'css for browser tests', + }, + 'examples/example': { + message: 'minimal example', + }, + 'examples/example:preserve-false': { + message: 'minimal example', + options: { + preserve: false + } + }, + 'examples/example:replacewith': { + message: 'minimal example', + options: { + replaceWith: '[focus-visible]' + } + }, }); diff --git a/plugins/postcss-focus-visible/CHANGELOG.md b/plugins/postcss-focus-visible/CHANGELOG.md index 534c3c904..5b54bba01 100644 --- a/plugins/postcss-focus-visible/CHANGELOG.md +++ b/plugins/postcss-focus-visible/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Focus Visible +### Unreleased (major) + +- Breaking: Changed generated classes so it prepends `.js-focus-visible` to the +generated class so CSS is applied when the polyfill is known to be running. + ### 6.0.4 (February 5, 2022) - Improved `es module` and `commonjs` compatibility diff --git a/plugins/postcss-focus-visible/README.md b/plugins/postcss-focus-visible/README.md index 22022bcf9..6f1f2c3e5 100644 --- a/plugins/postcss-focus-visible/README.md +++ b/plugins/postcss-focus-visible/README.md @@ -1,63 +1,50 @@ # PostCSS Focus Visible [PostCSS Logo][postcss] -[npm version][npm-url] -[CSS Standard Status][css-url] -[Build Status][cli-url] -[Discord][discord] +[npm version][npm-url] [CSS Standard Status][css-url] [Build Status][cli-url] [Discord][discord] -[PostCSS Focus Visible] lets you use the `:focus-visible` pseudo-class in -CSS, following the [Selectors Level 4 specification]. +[PostCSS Focus Visible] lets you use the `:focus-visible` pseudo-class in CSS, +following the [Selectors Level 4 specification]. -It is the companion to the [focus-visible polyfill]. +It is the companion to the [focus-visible polyfill]. Note that this plugin +alone **is not** sufficient to polyfill for `:focus-visible` and that you need +the browser's polyfill as well. [!['Can I use' table](https://caniuse.bitsofco.de/image/css-focus-visible.png)](https://caniuse.com/#feat=css-focus-visible) ```css + +```pcss :focus:not(:focus-visible) { - outline: none; + outline: none; } /* becomes */ -:focus:not(.focus-visible) { - outline: none; -} - -:focus:not(:focus-visible) { - outline: none; +:focus:not(.focus-visible).js-focus-visible, .js-focus-visible :focus:not(.focus-visible) { + outline: none; } ``` [PostCSS Focus Visible] duplicates rules using the `:focus-visible` pseudo-class with a `.focus-visible` class selector, the same selector used by the -[focus-visible polyfill]. This replacement selector can be changed using the -`replaceWith` option. Also, the preservation of the original `:focus-visible` -rule can be disabled using the `preserve` option. +[focus-visible polyfill]. ## Usage Add [PostCSS Focus Visible] to your project: ```bash -npm install postcss-focus-visible --save-dev -``` - -Use [PostCSS Focus Visible] to process your CSS: - -```js -const postcssFocusVisible = require('postcss-focus-visible'); - -postcssFocusVisible.process(YOUR_CSS /*, processOptions, pluginOptions */); +npm install postcss postcss-focus-visible --save-dev ``` -Or use it as a [PostCSS] plugin: +Use it as a [PostCSS] plugin: ```js const postcss = require('postcss'); const postcssFocusVisible = require('postcss-focus-visible'); postcss([ - postcssFocusVisible(/* pluginOptions */) + postcssFocusVisible(/* pluginOptions */) ]).process(YOUR_CSS /*, processOptions */); ``` @@ -71,22 +58,27 @@ 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 not preserved. ```js -focusVisible({ preserve: false }); +postcssFocusVisible({ preserve: true }) ``` -```css +```pcss :focus:not(:focus-visible) { - outline: none; + outline: none; } /* becomes */ -:focus:not(.focus-visible) { - outline: none; +.foo { + color: blue; + color: red; +} + +.baz { + color: green; } ``` @@ -96,34 +88,39 @@ The `replaceWith` option defines the selector to replace `:focus-visible`. By default, the replacement selector is `.focus-visible`. ```js -focusVisible({ replaceWith: '[focus-visible]' }); +postcssFocusVisible({ replaceWith: '[data-focus-visible-added]' }) ``` -```css +```pcss :focus:not(:focus-visible) { - outline: none; + outline: none; } /* becomes */ -:focus:not([focus-visible]) { - outline: none; +.foo { + color: blue; + color: red; } -:focus:not(:focus-visible) { - outline: none; +.baz { + color: green; } ``` +Note that if you want to keep using [focus-visible polyfill], the only +acceptable value would be `[data-focus-visible-added]`, +given that the polyfill does not support arbitrary values. + [cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test [css-url]: https://cssdb.org/#focus-visible-pseudo-class [discord]: https://discord.gg/bUadyRwkJS [npm-url]: https://www.npmjs.com/package/postcss-focus-visible -[focus-visible polyfill]: https://github.com/WICG/focus-visible [Gulp PostCSS]: https://github.com/postcss/gulp-postcss [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss [PostCSS]: https://github.com/postcss/postcss -[PostCSS Focus Visible]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-visible [PostCSS Loader]: https://github.com/postcss/postcss-loader +[PostCSS Focus Visible]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-visible [Selectors Level 4 specification]: https://www.w3.org/TR/selectors-4/#the-focus-visible-pseudo +[focus-visible polyfill]: https://github.com/WICG/focus-visible diff --git a/plugins/postcss-focus-visible/docs/README.md b/plugins/postcss-focus-visible/docs/README.md new file mode 100644 index 000000000..def195d90 --- /dev/null +++ b/plugins/postcss-focus-visible/docs/README.md @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + +
+ +[] lets you use the `:focus-visible` pseudo-class in CSS, +following the [Selectors Level 4 specification]. + +It is the companion to the [focus-visible polyfill]. Note that this plugin +alone **is not** sufficient to polyfill for `:focus-visible` and that you need +the browser's polyfill as well. + +[!['Can I use' table](https://caniuse.bitsofco.de/image/css-focus-visible.png)](https://caniuse.com/#feat=css-focus-visible) + +```css + +```pcss + + +/* becomes */ + + +``` + +[PostCSS Focus Visible] duplicates rules using the `:focus-visible` pseudo-class +with a `.focus-visible` class selector, the same selector used by the +[focus-visible polyfill]. + + + + + +## Options + +### preserve + +The `preserve` option determines whether the original notation +is preserved. By default, it is not preserved. + +```js +({ preserve: true }) +``` + +```pcss + + +/* becomes */ + + +``` + +### replaceWith + +The `replaceWith` option defines the selector to replace `:focus-visible`. By +default, the replacement selector is `.focus-visible`. + +```js +({ replaceWith: '[data-focus-visible-added]' }) +``` + +```pcss + + +/* becomes */ + + +``` + +Note that if you want to keep using [focus-visible polyfill], the only +acceptable value would be `[data-focus-visible-added]`, +given that the polyfill does not support arbitrary values. + + +[Selectors Level 4 specification]: +[focus-visible polyfill]: https://github.com/WICG/focus-visible diff --git a/plugins/postcss-focus-visible/package.json b/plugins/postcss-focus-visible/package.json index 8c12e8a2a..43325819d 100644 --- a/plugins/postcss-focus-visible/package.json +++ b/plugins/postcss-focus-visible/package.json @@ -2,7 +2,17 @@ "name": "postcss-focus-visible", "description": "Use the :focus-visible pseudo-selector in CSS", "version": "6.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" + } + ], "license": "CC0-1.0", "funding": { "type": "opencollective", @@ -33,15 +43,19 @@ "peerDependencies": { "postcss": "^8.2" }, + "devDependencies": { + "puppeteer": "^15.1.1" + }, "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" }, @@ -80,8 +94,10 @@ "trackpad" ], "csstools": { + "cssdbId": "focus-visible-pseudo-class", "exportName": "postcssFocusVisible", - "humanReadableName": "PostCSS Focus Visible" + "humanReadableName": "PostCSS Focus Visible", + "specUrl": "https://www.w3.org/TR/selectors-4/#the-focus-visible-pseudo" }, "volta": { "extends": "../../package.json" diff --git a/plugins/postcss-focus-visible/src/index.ts b/plugins/postcss-focus-visible/src/index.ts index 492ccfd4f..6b7151141 100644 --- a/plugins/postcss-focus-visible/src/index.ts +++ b/plugins/postcss-focus-visible/src/index.ts @@ -1,57 +1,109 @@ - import parser from 'postcss-selector-parser'; import type { PluginCreator } from 'postcss'; -const creator: PluginCreator<{ preserve?: boolean, replaceWith?: string }> = (opts?: { preserve?: boolean, replaceWith?: string }) => { - opts = Object(opts); - const preserve = Boolean('preserve' in opts ? opts.preserve : true); - const replaceWith = String(opts.replaceWith || '.focus-visible'); - const replacementAST = parser().astSync(replaceWith); +type pluginOptions = { preserve?: boolean, replaceWith?: string }; + +const POLYFILL_READY_CLASSNAME = 'js-focus-visible'; +const PSEUDO = ':focus-visible'; + +const creator: PluginCreator = (opts?: pluginOptions) => { + const options = Object.assign( + // Default options + { + preserve: false, + replaceWith: '.focus-visible', + }, + // Provided options + opts, + ); + + const replacementAST = parser().astSync(options.replaceWith); return { postcssPlugin: 'postcss-focus-visible', Rule(rule, { result }) { - if (!rule.selector.includes(':focus-visible')) { + if (!rule.selector.includes(PSEUDO)) { return; } - let modifiedSelector; + const selectors = rule.selectors.flatMap((selector) => { + if (!selector.includes(PSEUDO)) { + return [selector]; + } - try { - const modifiedSelectorAST = parser((selectors) => { - selectors.walkPseudos((pseudo) => { - if (pseudo.value !== ':focus-visible') { - 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 !== 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-visible + // becomes: + // html.js-focus-visible > .foo:focus-visible, + // .js-focus-visible html > .foo:focus-visible + { + 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 (modifiedSelector === rule.selector) { + 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 (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(); } }, }; @@ -60,3 +112,4 @@ const creator: PluginCreator<{ preserve?: boolean, replaceWith?: string }> = (op creator.postcss = true; export default creator; + diff --git a/plugins/postcss-focus-visible/test/_browser.html b/plugins/postcss-focus-visible/test/_browser.html new file mode 100644 index 000000000..66b359cc4 --- /dev/null +++ b/plugins/postcss-focus-visible/test/_browser.html @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + diff --git a/plugins/postcss-focus-visible/test/_browser.mjs b/plugins/postcss-focus-visible/test/_browser.mjs new file mode 100644 index 000000000..dd294a04d --- /dev/null +++ b/plugins/postcss-focus-visible/test/_browser.mjs @@ -0,0 +1,97 @@ +/* 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; + 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'); + + // None of the elements should have styles + await page.evaluate(async () => window.checkElement('default', 'a', false)); + await page.evaluate(async () => window.checkElement('default', 'b', false)); + await page.evaluate(async () => window.checkElement('default', 'c', false)); + + await page.keyboard.press('Tab'); + await page.evaluate(async () => window.checkElement('default', 'a', true)); + await page.evaluate(async () => window.checkElement('default', 'b', false)); + await page.evaluate(async () => window.checkElement('default', 'c', false)); + + await page.keyboard.press('Tab'); + await page.evaluate(async () => window.checkElement('default', 'a', false)); + await page.evaluate(async () => window.checkElement('default', 'b', true)); + await page.evaluate(async () => window.checkElement('default', 'c', false)); + + await page.keyboard.press('Tab'); + await page.evaluate(async () => window.checkElement('default', 'a', false)); + await page.evaluate(async () => window.checkElement('default', 'b', false)); + await page.evaluate(async () => window.checkElement('default', 'c', true)); + } + + // Clicking + { + await page.goto('http://localhost:8080'); + + // None of the elements should have styles + await page.evaluate(async () => window.checkElement('click', 'a', false)); + await page.evaluate(async () => window.checkElement('click', 'b', false)); + await page.evaluate(async () => window.checkElement('click', 'c', false)); + + await page.click('#a'); + await page.evaluate(async () => window.checkElement('click', 'a', true)); + + await page.click('#b'); + await page.evaluate(async () => window.checkElement('click', 'b', true)); + + // Clicking on a non-input element should not trigger focus-visible if not with keyboard + await page.click('#c'); + await page.evaluate(async () => window.checkElement('click', 'c', false)); + } + + await browser.close(); + + await server.close(); + } else { + console.log('visit : http://localhost:8080'); + } +})(); diff --git a/plugins/postcss-focus-visible/test/basic.css b/plugins/postcss-focus-visible/test/basic.css index 6b5c0b5f6..a2ac10d1a 100644 --- a/plugins/postcss-focus-visible/test/basic.css +++ b/plugins/postcss-focus-visible/test/basic.css @@ -6,6 +6,7 @@ :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, @@ -36,3 +37,43 @@ test :matches(test :focus-visible :focus-visible test) test { .escaped\:times\:two:focus-visible { order: 5; } + +html :focus-visible { + order: 6; +} + +html:focus-visible { + order: 6.1; +} + +:not(:focus-visible) { + order: 7; +} + +html :not(:focus-visible) { + order: 8; +} + +:focus-visible::before { + order: 10.0; +} + +:focus-visible .foo { + order: 10.1; +} + +:focus-visible > .foo { + order: 10.2; +} + +::before:focus-visible { + order: 10.3; +} + +.foo :focus-visible { + order: 10.4; +} + +.foo > :focus-visible { + order: 10.5; +} diff --git a/plugins/postcss-focus-visible/test/basic.expect.css b/plugins/postcss-focus-visible/test/basic.expect.css index 1635ac6ae..3fed12a64 100644 --- a/plugins/postcss-focus-visible/test/basic.expect.css +++ b/plugins/postcss-focus-visible/test/basic.expect.css @@ -1,41 +1,37 @@ -.focus-visible { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 1; } -:focus-visible { - order: 1; -} - -.focus-visible,.focus-visible test, -test .focus-visible, -test test.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; -} - -:focus-visible, -:focus-visible test, -test :focus-visible, -test test: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 { +.focus-visible.js-focus-visible, +.js-focus-visible .focus-visible, +.focus-visible.js-focus-visible test, +.js-focus-visible .focus-visible test, +test.js-focus-visible .focus-visible, +.js-focus-visible test .focus-visible, +test.js-focus-visible test.focus-visible, +.js-focus-visible test test.focus-visible, +html[dir="rtl"].js-focus-visible .focus-visible, +.js-focus-visible html[dir="rtl"] .focus-visible, +test.js-focus-visible .focus-visible test, +.js-focus-visible test .focus-visible test, +test.js-focus-visible test.focus-visible test, +.js-focus-visible test test.focus-visible test, +test.js-focus-visible .focus-visible .focus-visible test, +.js-focus-visible test .focus-visible .focus-visible test, +test.js-focus-visible :matches(.focus-visible) test, +.js-focus-visible test :matches(.focus-visible) test, +test.js-focus-visible :matches(.focus-visible test) test, +.js-focus-visible test :matches(.focus-visible test) test, +test.js-focus-visible :matches(test .focus-visible) test, +.js-focus-visible test :matches(test .focus-visible) test, +test.js-focus-visible :matches(test test.focus-visible) test, +.js-focus-visible test :matches(test test.focus-visible) test, +test.js-focus-visible :matches(test .focus-visible test) test, +.js-focus-visible test :matches(test .focus-visible test) test, +test.js-focus-visible :matches(test test.focus-visible test) test, +.js-focus-visible test :matches(test test.focus-visible test) test, +test.js-focus-visible :matches(test .focus-visible .focus-visible test) test, +.js-focus-visible test :matches(test .focus-visible .focus-visible test) test { order: 2; } @@ -52,14 +48,49 @@ test :matches(test :focus-visible :focus-visible test) test { .escaped\:focus-visible, .escaped\:times\:two\:focus-visible, -.escaped\:focus-visible.focus-visible, -.escaped\:times\:two.focus-visible { +.escaped\:focus-visible.focus-visible.js-focus-visible, +.js-focus-visible .escaped\:focus-visible.focus-visible, +.escaped\:times\:two.focus-visible.js-focus-visible, +.js-focus-visible .escaped\:times\:two.focus-visible { 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.js-focus-visible, .js-focus-visible html.focus-visible { + order: 6.1; +} + +:not(.focus-visible).js-focus-visible, .js-focus-visible :not(.focus-visible) { + order: 7; +} + +html.js-focus-visible :not(.focus-visible), .js-focus-visible html :not(.focus-visible) { + order: 8; +} + +.focus-visible.js-focus-visible::before, .js-focus-visible .focus-visible::before { + order: 10.0; +} + +.focus-visible.js-focus-visible .foo, .js-focus-visible .focus-visible .foo { + order: 10.1; +} + +.focus-visible.js-focus-visible > .foo, .js-focus-visible .focus-visible > .foo { + order: 10.2; +} + +.js-focus-visible::before.focus-visible, .js-focus-visible ::before.focus-visible { + order: 10.3; +} + +.foo.js-focus-visible .focus-visible, .js-focus-visible .foo .focus-visible { + order: 10.4; +} + +.foo.js-focus-visible > .focus-visible, .js-focus-visible .foo > .focus-visible { + order: 10.5; } diff --git a/plugins/postcss-focus-visible/test/basic.preserve.expect.css b/plugins/postcss-focus-visible/test/basic.preserve.expect.css index 56f3d0a59..3fed12a64 100644 --- a/plugins/postcss-focus-visible/test/basic.preserve.expect.css +++ b/plugins/postcss-focus-visible/test/basic.preserve.expect.css @@ -1,20 +1,37 @@ -.focus-visible { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 1; } -.focus-visible,.focus-visible test, -test .focus-visible, -test test.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 { +.focus-visible.js-focus-visible, +.js-focus-visible .focus-visible, +.focus-visible.js-focus-visible test, +.js-focus-visible .focus-visible test, +test.js-focus-visible .focus-visible, +.js-focus-visible test .focus-visible, +test.js-focus-visible test.focus-visible, +.js-focus-visible test test.focus-visible, +html[dir="rtl"].js-focus-visible .focus-visible, +.js-focus-visible html[dir="rtl"] .focus-visible, +test.js-focus-visible .focus-visible test, +.js-focus-visible test .focus-visible test, +test.js-focus-visible test.focus-visible test, +.js-focus-visible test test.focus-visible test, +test.js-focus-visible .focus-visible .focus-visible test, +.js-focus-visible test .focus-visible .focus-visible test, +test.js-focus-visible :matches(.focus-visible) test, +.js-focus-visible test :matches(.focus-visible) test, +test.js-focus-visible :matches(.focus-visible test) test, +.js-focus-visible test :matches(.focus-visible test) test, +test.js-focus-visible :matches(test .focus-visible) test, +.js-focus-visible test :matches(test .focus-visible) test, +test.js-focus-visible :matches(test test.focus-visible) test, +.js-focus-visible test :matches(test test.focus-visible) test, +test.js-focus-visible :matches(test .focus-visible test) test, +.js-focus-visible test :matches(test .focus-visible test) test, +test.js-focus-visible :matches(test test.focus-visible test) test, +.js-focus-visible test :matches(test test.focus-visible test) test, +test.js-focus-visible :matches(test .focus-visible .focus-visible test) test, +.js-focus-visible test :matches(test .focus-visible .focus-visible test) test { order: 2; } @@ -31,7 +48,49 @@ test :matches(test .focus-visible .focus-visible test) test { .escaped\:focus-visible, .escaped\:times\:two\:focus-visible, -.escaped\:focus-visible.focus-visible, -.escaped\:times\:two.focus-visible { +.escaped\:focus-visible.focus-visible.js-focus-visible, +.js-focus-visible .escaped\:focus-visible.focus-visible, +.escaped\:times\:two.focus-visible.js-focus-visible, +.js-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.js-focus-visible, .js-focus-visible html.focus-visible { + order: 6.1; +} + +:not(.focus-visible).js-focus-visible, .js-focus-visible :not(.focus-visible) { + order: 7; +} + +html.js-focus-visible :not(.focus-visible), .js-focus-visible html :not(.focus-visible) { + order: 8; +} + +.focus-visible.js-focus-visible::before, .js-focus-visible .focus-visible::before { + order: 10.0; +} + +.focus-visible.js-focus-visible .foo, .js-focus-visible .focus-visible .foo { + order: 10.1; +} + +.focus-visible.js-focus-visible > .foo, .js-focus-visible .focus-visible > .foo { + order: 10.2; +} + +.js-focus-visible::before.focus-visible, .js-focus-visible ::before.focus-visible { + order: 10.3; +} + +.foo.js-focus-visible .focus-visible, .js-focus-visible .foo .focus-visible { + order: 10.4; +} + +.foo.js-focus-visible > .focus-visible, .js-focus-visible .foo > .focus-visible { + order: 10.5; +} diff --git a/plugins/postcss-focus-visible/test/basic.replacewith.expect.css b/plugins/postcss-focus-visible/test/basic.replacewith.expect.css index 1b9240bf7..a5162561f 100644 --- a/plugins/postcss-focus-visible/test/basic.replacewith.expect.css +++ b/plugins/postcss-focus-visible/test/basic.replacewith.expect.css @@ -1,41 +1,37 @@ -[focus-visible] { +[data-focus-visible-added].js-focus-visible, .js-focus-visible [data-focus-visible-added] { order: 1; } -:focus-visible { - order: 1; -} - -[focus-visible],[focus-visible] test, -test [focus-visible], -test test[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; -} - -:focus-visible, -:focus-visible test, -test :focus-visible, -test test: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 { +[data-focus-visible-added].js-focus-visible, +.js-focus-visible [data-focus-visible-added], +[data-focus-visible-added].js-focus-visible test, +.js-focus-visible [data-focus-visible-added] test, +test.js-focus-visible [data-focus-visible-added], +.js-focus-visible test [data-focus-visible-added], +test.js-focus-visible test[data-focus-visible-added], +.js-focus-visible test test[data-focus-visible-added], +html[dir="rtl"].js-focus-visible [data-focus-visible-added], +.js-focus-visible html[dir="rtl"] [data-focus-visible-added], +test.js-focus-visible [data-focus-visible-added] test, +.js-focus-visible test [data-focus-visible-added] test, +test.js-focus-visible test[data-focus-visible-added] test, +.js-focus-visible test test[data-focus-visible-added] test, +test.js-focus-visible [data-focus-visible-added] [data-focus-visible-added] test, +.js-focus-visible test [data-focus-visible-added] [data-focus-visible-added] test, +test.js-focus-visible :matches([data-focus-visible-added]) test, +.js-focus-visible test :matches([data-focus-visible-added]) test, +test.js-focus-visible :matches([data-focus-visible-added] test) test, +.js-focus-visible test :matches([data-focus-visible-added] test) test, +test.js-focus-visible :matches(test [data-focus-visible-added]) test, +.js-focus-visible test :matches(test [data-focus-visible-added]) test, +test.js-focus-visible :matches(test test[data-focus-visible-added]) test, +.js-focus-visible test :matches(test test[data-focus-visible-added]) test, +test.js-focus-visible :matches(test [data-focus-visible-added] test) test, +.js-focus-visible test :matches(test [data-focus-visible-added] test) test, +test.js-focus-visible :matches(test test[data-focus-visible-added] test) test, +.js-focus-visible test :matches(test test[data-focus-visible-added] test) test, +test.js-focus-visible :matches(test [data-focus-visible-added] [data-focus-visible-added] test) test, +.js-focus-visible test :matches(test [data-focus-visible-added] [data-focus-visible-added] test) test { order: 2; } @@ -52,14 +48,49 @@ test :matches(test :focus-visible :focus-visible test) test { .escaped\:focus-visible, .escaped\:times\:two\:focus-visible, -.escaped\:focus-visible[focus-visible], -.escaped\:times\:two[focus-visible] { +.escaped\:focus-visible[data-focus-visible-added].js-focus-visible, +.js-focus-visible .escaped\:focus-visible[data-focus-visible-added], +.escaped\:times\:two[data-focus-visible-added].js-focus-visible, +.js-focus-visible .escaped\:times\:two[data-focus-visible-added] { 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[data-focus-visible-added].js-focus-visible, .js-focus-visible html[data-focus-visible-added] { + order: 6.1; +} + +:not([data-focus-visible-added]).js-focus-visible, .js-focus-visible :not([data-focus-visible-added]) { + order: 7; +} + +html.js-focus-visible :not([data-focus-visible-added]), .js-focus-visible html :not([data-focus-visible-added]) { + order: 8; +} + +[data-focus-visible-added].js-focus-visible::before, .js-focus-visible [data-focus-visible-added]::before { + order: 10.0; +} + +[data-focus-visible-added].js-focus-visible .foo, .js-focus-visible [data-focus-visible-added] .foo { + order: 10.1; +} + +[data-focus-visible-added].js-focus-visible > .foo, .js-focus-visible [data-focus-visible-added] > .foo { + order: 10.2; +} + +.js-focus-visible::before[data-focus-visible-added], .js-focus-visible ::before[data-focus-visible-added] { + order: 10.3; +} + +.foo.js-focus-visible [data-focus-visible-added], .js-focus-visible .foo [data-focus-visible-added] { + order: 10.4; +} + +.foo.js-focus-visible > [data-focus-visible-added], .js-focus-visible .foo > [data-focus-visible-added] { + order: 10.5; } diff --git a/plugins/postcss-focus-visible/test/browser.css b/plugins/postcss-focus-visible/test/browser.css new file mode 100644 index 000000000..12122d422 --- /dev/null +++ b/plugins/postcss-focus-visible/test/browser.css @@ -0,0 +1,9 @@ +input, +select, +textarea { + background-color: rgb(255, 192, 203); +} + +:focus-visible { + background-color: rgb(128, 0, 128); +} diff --git a/plugins/postcss-focus-visible/test/browser.expect.css b/plugins/postcss-focus-visible/test/browser.expect.css new file mode 100644 index 000000000..cf0e52c08 --- /dev/null +++ b/plugins/postcss-focus-visible/test/browser.expect.css @@ -0,0 +1,9 @@ +input, +select, +textarea { + background-color: rgb(255, 192, 203); +} + +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible { + background-color: rgb(128, 0, 128); +} diff --git a/plugins/postcss-focus-visible/test/examples/example.css b/plugins/postcss-focus-visible/test/examples/example.css new file mode 100644 index 000000000..b83264afe --- /dev/null +++ b/plugins/postcss-focus-visible/test/examples/example.css @@ -0,0 +1,3 @@ +:focus:not(:focus-visible) { + outline: none; +} diff --git a/plugins/postcss-focus-visible/test/examples/example.expect.css b/plugins/postcss-focus-visible/test/examples/example.expect.css new file mode 100644 index 000000000..d2288c25d --- /dev/null +++ b/plugins/postcss-focus-visible/test/examples/example.expect.css @@ -0,0 +1,3 @@ +:focus:not(.focus-visible).js-focus-visible, .js-focus-visible :focus:not(.focus-visible) { + outline: none; +} diff --git a/plugins/postcss-focus-visible/test/examples/example.preserve-false.expect.css b/plugins/postcss-focus-visible/test/examples/example.preserve-false.expect.css new file mode 100644 index 000000000..d2288c25d --- /dev/null +++ b/plugins/postcss-focus-visible/test/examples/example.preserve-false.expect.css @@ -0,0 +1,3 @@ +:focus:not(.focus-visible).js-focus-visible, .js-focus-visible :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 new file mode 100644 index 000000000..8b020470a --- /dev/null +++ b/plugins/postcss-focus-visible/test/examples/example.preserve-true.expect.css @@ -0,0 +1,8 @@ +.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 new file mode 100644 index 000000000..9e6327e76 --- /dev/null +++ b/plugins/postcss-focus-visible/test/examples/example.replacewith.expect.css @@ -0,0 +1,3 @@ +:focus:not([focus-visible]).js-focus-visible, .js-focus-visible :focus:not([focus-visible]) { + outline: none; +} diff --git a/plugins/postcss-focus-visible/test/generated-selector-cases.expect.css b/plugins/postcss-focus-visible/test/generated-selector-cases.expect.css index d8ed51a13..d122f1b4c 100644 --- a/plugins/postcss-focus-visible/test/generated-selector-cases.expect.css +++ b/plugins/postcss-focus-visible/test/generated-selector-cases.expect.css @@ -1,84 +1,84 @@ -.focus-visible.focus-visible { +.focus-visible.focus-visible.js-focus-visible, .js-focus-visible .focus-visible.focus-visible { order: 0; } -.focus-visible.focus-visible { +.focus-visible.focus-visible.js-focus-visible, .js-focus-visible .focus-visible.focus-visible { order: 1; } -.focus-visible .focus-visible { +.focus-visible.js-focus-visible .focus-visible, .js-focus-visible .focus-visible .focus-visible { order: 2; } -.focus-visible .focus-visible { +.focus-visible.js-focus-visible .focus-visible, .js-focus-visible .focus-visible .focus-visible { order: 3; } -.focus-visible .focus-visible { +.focus-visible.js-focus-visible .focus-visible, .js-focus-visible .focus-visible .focus-visible { order: 4; } -.focus-visible .focus-visible { +.focus-visible.js-focus-visible .focus-visible, .js-focus-visible .focus-visible .focus-visible { order: 5; } -.focus-visible+.focus-visible { +.focus-visible.js-focus-visible+.focus-visible, .js-focus-visible .focus-visible+.focus-visible { order: 6; } -.focus-visible+.focus-visible { +.focus-visible.js-focus-visible+.focus-visible, .js-focus-visible .focus-visible+.focus-visible { order: 7; } -.focus-visible + .focus-visible { +.focus-visible.js-focus-visible + .focus-visible, .js-focus-visible .focus-visible + .focus-visible { order: 8; } -.focus-visible + .focus-visible { +.focus-visible.js-focus-visible + .focus-visible, .js-focus-visible .focus-visible + .focus-visible { order: 9; } -.focus-visible~.focus-visible { +.focus-visible.js-focus-visible~.focus-visible, .js-focus-visible .focus-visible~.focus-visible { order: 10; } -.focus-visible~.focus-visible { +.focus-visible.js-focus-visible~.focus-visible, .js-focus-visible .focus-visible~.focus-visible { order: 11; } -.focus-visible ~ .focus-visible { +.focus-visible.js-focus-visible ~ .focus-visible, .js-focus-visible .focus-visible ~ .focus-visible { order: 12; } -.focus-visible ~ .focus-visible { +.focus-visible.js-focus-visible ~ .focus-visible, .js-focus-visible .focus-visible ~ .focus-visible { order: 13; } -.focus-visible>.focus-visible { +.focus-visible.js-focus-visible>.focus-visible, .js-focus-visible .focus-visible>.focus-visible { order: 14; } -.focus-visible>.focus-visible { +.focus-visible.js-focus-visible>.focus-visible, .js-focus-visible .focus-visible>.focus-visible { order: 15; } -.focus-visible > .focus-visible { +.focus-visible.js-focus-visible > .focus-visible, .js-focus-visible .focus-visible > .focus-visible { order: 16; } -.focus-visible > .focus-visible { +.focus-visible.js-focus-visible > .focus-visible, .js-focus-visible .focus-visible > .focus-visible { order: 17; } -.focus-visible,.focus-visible { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 18; } -.focus-visible,.focus-visible { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 19; } -button.focus-visible { +button.focus-visible.js-focus-visible, .js-focus-visible button.focus-visible { order: 20; } @@ -86,319 +86,319 @@ button.focus-visible { order: 21; } -button .focus-visible { +button.js-focus-visible .focus-visible, .js-focus-visible button .focus-visible { order: 22; } -.focus-visible button { +.focus-visible.js-focus-visible button, .js-focus-visible .focus-visible button { order: 23; } -button .focus-visible { +button.js-focus-visible .focus-visible, .js-focus-visible button .focus-visible { order: 24; } -.focus-visible button { +.focus-visible.js-focus-visible button, .js-focus-visible .focus-visible button { order: 25; } -button+.focus-visible { +button.js-focus-visible+.focus-visible, .js-focus-visible button+.focus-visible { order: 26; } -.focus-visible+button { +.focus-visible.js-focus-visible+button, .js-focus-visible .focus-visible+button { order: 27; } -button + .focus-visible { +button.js-focus-visible + .focus-visible, .js-focus-visible button + .focus-visible { order: 28; } -.focus-visible + button { +.focus-visible.js-focus-visible + button, .js-focus-visible .focus-visible + button { order: 29; } -button~.focus-visible { +button.js-focus-visible~.focus-visible, .js-focus-visible button~.focus-visible { order: 30; } -.focus-visible~button { +.focus-visible.js-focus-visible~button, .js-focus-visible .focus-visible~button { order: 31; } -button ~ .focus-visible { +button.js-focus-visible ~ .focus-visible, .js-focus-visible button ~ .focus-visible { order: 32; } -.focus-visible ~ button { +.focus-visible.js-focus-visible ~ button, .js-focus-visible .focus-visible ~ button { order: 33; } -button>.focus-visible { +button.js-focus-visible>.focus-visible, .js-focus-visible button>.focus-visible { order: 34; } -.focus-visible>button { +.focus-visible.js-focus-visible>button, .js-focus-visible .focus-visible>button { order: 35; } -button > .focus-visible { +button.js-focus-visible > .focus-visible, .js-focus-visible button > .focus-visible { order: 36; } -.focus-visible > button { +.focus-visible.js-focus-visible > button, .js-focus-visible .focus-visible > button { order: 37; } -button,.focus-visible { +button, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 38; } -.focus-visible, button { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, button { order: 39; } -.🧑🏾‍🎤.focus-visible { +.🧑🏾‍🎤.focus-visible.js-focus-visible, .js-focus-visible .🧑🏾‍🎤.focus-visible { order: 40; } -.focus-visible.🧑🏾‍🎤 { +.focus-visible.🧑🏾‍🎤.js-focus-visible, .js-focus-visible .focus-visible.🧑🏾‍🎤 { order: 41; } -.🧑🏾‍🎤 .focus-visible { +.🧑🏾‍🎤.js-focus-visible .focus-visible, .js-focus-visible .🧑🏾‍🎤 .focus-visible { order: 42; } -.focus-visible .🧑🏾‍🎤 { +.focus-visible.js-focus-visible .🧑🏾‍🎤, .js-focus-visible .focus-visible .🧑🏾‍🎤 { order: 43; } -.🧑🏾‍🎤 .focus-visible { +.🧑🏾‍🎤.js-focus-visible .focus-visible, .js-focus-visible .🧑🏾‍🎤 .focus-visible { order: 44; } -.focus-visible .🧑🏾‍🎤 { +.focus-visible.js-focus-visible .🧑🏾‍🎤, .js-focus-visible .focus-visible .🧑🏾‍🎤 { order: 45; } -.🧑🏾‍🎤+.focus-visible { +.🧑🏾‍🎤.js-focus-visible+.focus-visible, .js-focus-visible .🧑🏾‍🎤+.focus-visible { order: 46; } -.focus-visible+.🧑🏾‍🎤 { +.focus-visible.js-focus-visible+.🧑🏾‍🎤, .js-focus-visible .focus-visible+.🧑🏾‍🎤 { order: 47; } -.🧑🏾‍🎤 + .focus-visible { +.🧑🏾‍🎤.js-focus-visible + .focus-visible, .js-focus-visible .🧑🏾‍🎤 + .focus-visible { order: 48; } -.focus-visible + .🧑🏾‍🎤 { +.focus-visible.js-focus-visible + .🧑🏾‍🎤, .js-focus-visible .focus-visible + .🧑🏾‍🎤 { order: 49; } -.🧑🏾‍🎤~.focus-visible { +.🧑🏾‍🎤.js-focus-visible~.focus-visible, .js-focus-visible .🧑🏾‍🎤~.focus-visible { order: 50; } -.focus-visible~.🧑🏾‍🎤 { +.focus-visible.js-focus-visible~.🧑🏾‍🎤, .js-focus-visible .focus-visible~.🧑🏾‍🎤 { order: 51; } -.🧑🏾‍🎤 ~ .focus-visible { +.🧑🏾‍🎤.js-focus-visible ~ .focus-visible, .js-focus-visible .🧑🏾‍🎤 ~ .focus-visible { order: 52; } -.focus-visible ~ .🧑🏾‍🎤 { +.focus-visible.js-focus-visible ~ .🧑🏾‍🎤, .js-focus-visible .focus-visible ~ .🧑🏾‍🎤 { order: 53; } -.🧑🏾‍🎤>.focus-visible { +.🧑🏾‍🎤.js-focus-visible>.focus-visible, .js-focus-visible .🧑🏾‍🎤>.focus-visible { order: 54; } -.focus-visible>.🧑🏾‍🎤 { +.focus-visible.js-focus-visible>.🧑🏾‍🎤, .js-focus-visible .focus-visible>.🧑🏾‍🎤 { order: 55; } -.🧑🏾‍🎤 > .focus-visible { +.🧑🏾‍🎤.js-focus-visible > .focus-visible, .js-focus-visible .🧑🏾‍🎤 > .focus-visible { order: 56; } -.focus-visible > .🧑🏾‍🎤 { +.focus-visible.js-focus-visible > .🧑🏾‍🎤, .js-focus-visible .focus-visible > .🧑🏾‍🎤 { order: 57; } -.🧑🏾‍🎤,.focus-visible { +.🧑🏾‍🎤, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 58; } -.focus-visible, .🧑🏾‍🎤 { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, .🧑🏾‍🎤 { order: 59; } -.foo.focus-visible { +.foo.focus-visible.js-focus-visible, .js-focus-visible .foo.focus-visible { order: 60; } -.focus-visible.foo { +.focus-visible.foo.js-focus-visible, .js-focus-visible .focus-visible.foo { order: 61; } -.foo .focus-visible { +.foo.js-focus-visible .focus-visible, .js-focus-visible .foo .focus-visible { order: 62; } -.focus-visible .foo { +.focus-visible.js-focus-visible .foo, .js-focus-visible .focus-visible .foo { order: 63; } -.foo .focus-visible { +.foo.js-focus-visible .focus-visible, .js-focus-visible .foo .focus-visible { order: 64; } -.focus-visible .foo { +.focus-visible.js-focus-visible .foo, .js-focus-visible .focus-visible .foo { order: 65; } -.foo+.focus-visible { +.foo.js-focus-visible+.focus-visible, .js-focus-visible .foo+.focus-visible { order: 66; } -.focus-visible+.foo { +.focus-visible.js-focus-visible+.foo, .js-focus-visible .focus-visible+.foo { order: 67; } -.foo + .focus-visible { +.foo.js-focus-visible + .focus-visible, .js-focus-visible .foo + .focus-visible { order: 68; } -.focus-visible + .foo { +.focus-visible.js-focus-visible + .foo, .js-focus-visible .focus-visible + .foo { order: 69; } -.foo~.focus-visible { +.foo.js-focus-visible~.focus-visible, .js-focus-visible .foo~.focus-visible { order: 70; } -.focus-visible~.foo { +.focus-visible.js-focus-visible~.foo, .js-focus-visible .focus-visible~.foo { order: 71; } -.foo ~ .focus-visible { +.foo.js-focus-visible ~ .focus-visible, .js-focus-visible .foo ~ .focus-visible { order: 72; } -.focus-visible ~ .foo { +.focus-visible.js-focus-visible ~ .foo, .js-focus-visible .focus-visible ~ .foo { order: 73; } -.foo>.focus-visible { +.foo.js-focus-visible>.focus-visible, .js-focus-visible .foo>.focus-visible { order: 74; } -.focus-visible>.foo { +.focus-visible.js-focus-visible>.foo, .js-focus-visible .focus-visible>.foo { order: 75; } -.foo > .focus-visible { +.foo.js-focus-visible > .focus-visible, .js-focus-visible .foo > .focus-visible { order: 76; } -.focus-visible > .foo { +.focus-visible.js-focus-visible > .foo, .js-focus-visible .focus-visible > .foo { order: 77; } -.foo,.focus-visible { +.foo, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 78; } -.focus-visible, .foo { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, .foo { order: 79; } -#foo.focus-visible { +#foo.focus-visible.js-focus-visible, .js-focus-visible #foo.focus-visible { order: 80; } -.focus-visible#foo { +.focus-visible#foo.js-focus-visible, .js-focus-visible .focus-visible#foo { order: 81; } -#foo .focus-visible { +#foo.js-focus-visible .focus-visible, .js-focus-visible #foo .focus-visible { order: 82; } -.focus-visible #foo { +.focus-visible.js-focus-visible #foo, .js-focus-visible .focus-visible #foo { order: 83; } -#foo .focus-visible { +#foo.js-focus-visible .focus-visible, .js-focus-visible #foo .focus-visible { order: 84; } -.focus-visible #foo { +.focus-visible.js-focus-visible #foo, .js-focus-visible .focus-visible #foo { order: 85; } -#foo+.focus-visible { +#foo.js-focus-visible+.focus-visible, .js-focus-visible #foo+.focus-visible { order: 86; } -.focus-visible+#foo { +.focus-visible.js-focus-visible+#foo, .js-focus-visible .focus-visible+#foo { order: 87; } -#foo + .focus-visible { +#foo.js-focus-visible + .focus-visible, .js-focus-visible #foo + .focus-visible { order: 88; } -.focus-visible + #foo { +.focus-visible.js-focus-visible + #foo, .js-focus-visible .focus-visible + #foo { order: 89; } -#foo~.focus-visible { +#foo.js-focus-visible~.focus-visible, .js-focus-visible #foo~.focus-visible { order: 90; } -.focus-visible~#foo { +.focus-visible.js-focus-visible~#foo, .js-focus-visible .focus-visible~#foo { order: 91; } -#foo ~ .focus-visible { +#foo.js-focus-visible ~ .focus-visible, .js-focus-visible #foo ~ .focus-visible { order: 92; } -.focus-visible ~ #foo { +.focus-visible.js-focus-visible ~ #foo, .js-focus-visible .focus-visible ~ #foo { order: 93; } -#foo>.focus-visible { +#foo.js-focus-visible>.focus-visible, .js-focus-visible #foo>.focus-visible { order: 94; } -.focus-visible>#foo { +.focus-visible.js-focus-visible>#foo, .js-focus-visible .focus-visible>#foo { order: 95; } -#foo > .focus-visible { +#foo.js-focus-visible > .focus-visible, .js-focus-visible #foo > .focus-visible { order: 96; } -.focus-visible > #foo { +.focus-visible.js-focus-visible > #foo, .js-focus-visible .focus-visible > #foo { order: 97; } -#foo,.focus-visible { +#foo, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 98; } -.focus-visible, #foo { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, #foo { order: 99; } -__foo.focus-visible { +__foo.focus-visible.js-focus-visible, .js-focus-visible __foo.focus-visible { order: 100; } @@ -406,475 +406,475 @@ __foo.focus-visible { order: 101; } -__foo .focus-visible { +__foo.js-focus-visible .focus-visible, .js-focus-visible __foo .focus-visible { order: 102; } -.focus-visible __foo { +.focus-visible.js-focus-visible __foo, .js-focus-visible .focus-visible __foo { order: 103; } -__foo .focus-visible { +__foo.js-focus-visible .focus-visible, .js-focus-visible __foo .focus-visible { order: 104; } -.focus-visible __foo { +.focus-visible.js-focus-visible __foo, .js-focus-visible .focus-visible __foo { order: 105; } -__foo+.focus-visible { +__foo.js-focus-visible+.focus-visible, .js-focus-visible __foo+.focus-visible { order: 106; } -.focus-visible+__foo { +.focus-visible.js-focus-visible+__foo, .js-focus-visible .focus-visible+__foo { order: 107; } -__foo + .focus-visible { +__foo.js-focus-visible + .focus-visible, .js-focus-visible __foo + .focus-visible { order: 108; } -.focus-visible + __foo { +.focus-visible.js-focus-visible + __foo, .js-focus-visible .focus-visible + __foo { order: 109; } -__foo~.focus-visible { +__foo.js-focus-visible~.focus-visible, .js-focus-visible __foo~.focus-visible { order: 110; } -.focus-visible~__foo { +.focus-visible.js-focus-visible~__foo, .js-focus-visible .focus-visible~__foo { order: 111; } -__foo ~ .focus-visible { +__foo.js-focus-visible ~ .focus-visible, .js-focus-visible __foo ~ .focus-visible { order: 112; } -.focus-visible ~ __foo { +.focus-visible.js-focus-visible ~ __foo, .js-focus-visible .focus-visible ~ __foo { order: 113; } -__foo>.focus-visible { +__foo.js-focus-visible>.focus-visible, .js-focus-visible __foo>.focus-visible { order: 114; } -.focus-visible>__foo { +.focus-visible.js-focus-visible>__foo, .js-focus-visible .focus-visible>__foo { order: 115; } -__foo > .focus-visible { +__foo.js-focus-visible > .focus-visible, .js-focus-visible __foo > .focus-visible { order: 116; } -.focus-visible > __foo { +.focus-visible.js-focus-visible > __foo, .js-focus-visible .focus-visible > __foo { order: 117; } -__foo,.focus-visible { +__foo, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 118; } -.focus-visible, __foo { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, __foo { order: 119; } -:--foo.focus-visible { +:--foo.focus-visible.js-focus-visible, .js-focus-visible :--foo.focus-visible { order: 120; } -.focus-visible:--foo { +.focus-visible:--foo.js-focus-visible, .js-focus-visible .focus-visible:--foo { order: 121; } -:--foo .focus-visible { +:--foo.js-focus-visible .focus-visible, .js-focus-visible :--foo .focus-visible { order: 122; } -.focus-visible :--foo { +.focus-visible.js-focus-visible :--foo, .js-focus-visible .focus-visible :--foo { order: 123; } -:--foo .focus-visible { +:--foo.js-focus-visible .focus-visible, .js-focus-visible :--foo .focus-visible { order: 124; } -.focus-visible :--foo { +.focus-visible.js-focus-visible :--foo, .js-focus-visible .focus-visible :--foo { order: 125; } -:--foo+.focus-visible { +:--foo.js-focus-visible+.focus-visible, .js-focus-visible :--foo+.focus-visible { order: 126; } -.focus-visible+:--foo { +.focus-visible.js-focus-visible+:--foo, .js-focus-visible .focus-visible+:--foo { order: 127; } -:--foo + .focus-visible { +:--foo.js-focus-visible + .focus-visible, .js-focus-visible :--foo + .focus-visible { order: 128; } -.focus-visible + :--foo { +.focus-visible.js-focus-visible + :--foo, .js-focus-visible .focus-visible + :--foo { order: 129; } -:--foo~.focus-visible { +:--foo.js-focus-visible~.focus-visible, .js-focus-visible :--foo~.focus-visible { order: 130; } -.focus-visible~:--foo { +.focus-visible.js-focus-visible~:--foo, .js-focus-visible .focus-visible~:--foo { order: 131; } -:--foo ~ .focus-visible { +:--foo.js-focus-visible ~ .focus-visible, .js-focus-visible :--foo ~ .focus-visible { order: 132; } -.focus-visible ~ :--foo { +.focus-visible.js-focus-visible ~ :--foo, .js-focus-visible .focus-visible ~ :--foo { order: 133; } -:--foo>.focus-visible { +:--foo.js-focus-visible>.focus-visible, .js-focus-visible :--foo>.focus-visible { order: 134; } -.focus-visible>:--foo { +.focus-visible.js-focus-visible>:--foo, .js-focus-visible .focus-visible>:--foo { order: 135; } -:--foo > .focus-visible { +:--foo.js-focus-visible > .focus-visible, .js-focus-visible :--foo > .focus-visible { order: 136; } -.focus-visible > :--foo { +.focus-visible.js-focus-visible > :--foo, .js-focus-visible .focus-visible > :--foo { order: 137; } -:--foo,.focus-visible { +:--foo, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 138; } -.focus-visible, :--foo { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, :--foo { order: 139; } -[foo="baz"].focus-visible { +[foo="baz"].focus-visible.js-focus-visible, .js-focus-visible [foo="baz"].focus-visible { order: 140; } -.focus-visible[foo="baz"] { +.focus-visible[foo="baz"].js-focus-visible, .js-focus-visible .focus-visible[foo="baz"] { order: 141; } -[foo="baz"] .focus-visible { +[foo="baz"].js-focus-visible .focus-visible, .js-focus-visible [foo="baz"] .focus-visible { order: 142; } -.focus-visible [foo="baz"] { +.focus-visible.js-focus-visible [foo="baz"], .js-focus-visible .focus-visible [foo="baz"] { order: 143; } -[foo="baz"] .focus-visible { +[foo="baz"].js-focus-visible .focus-visible, .js-focus-visible [foo="baz"] .focus-visible { order: 144; } -.focus-visible [foo="baz"] { +.focus-visible.js-focus-visible [foo="baz"], .js-focus-visible .focus-visible [foo="baz"] { order: 145; } -[foo="baz"]+.focus-visible { +[foo="baz"].js-focus-visible+.focus-visible, .js-focus-visible [foo="baz"]+.focus-visible { order: 146; } -.focus-visible+[foo="baz"] { +.focus-visible.js-focus-visible+[foo="baz"], .js-focus-visible .focus-visible+[foo="baz"] { order: 147; } -[foo="baz"] + .focus-visible { +[foo="baz"].js-focus-visible + .focus-visible, .js-focus-visible [foo="baz"] + .focus-visible { order: 148; } -.focus-visible + [foo="baz"] { +.focus-visible.js-focus-visible + [foo="baz"], .js-focus-visible .focus-visible + [foo="baz"] { order: 149; } -[foo="baz"]~.focus-visible { +[foo="baz"].js-focus-visible~.focus-visible, .js-focus-visible [foo="baz"]~.focus-visible { order: 150; } -.focus-visible~[foo="baz"] { +.focus-visible.js-focus-visible~[foo="baz"], .js-focus-visible .focus-visible~[foo="baz"] { order: 151; } -[foo="baz"] ~ .focus-visible { +[foo="baz"].js-focus-visible ~ .focus-visible, .js-focus-visible [foo="baz"] ~ .focus-visible { order: 152; } -.focus-visible ~ [foo="baz"] { +.focus-visible.js-focus-visible ~ [foo="baz"], .js-focus-visible .focus-visible ~ [foo="baz"] { order: 153; } -[foo="baz"]>.focus-visible { +[foo="baz"].js-focus-visible>.focus-visible, .js-focus-visible [foo="baz"]>.focus-visible { order: 154; } -.focus-visible>[foo="baz"] { +.focus-visible.js-focus-visible>[foo="baz"], .js-focus-visible .focus-visible>[foo="baz"] { order: 155; } -[foo="baz"] > .focus-visible { +[foo="baz"].js-focus-visible > .focus-visible, .js-focus-visible [foo="baz"] > .focus-visible { order: 156; } -.focus-visible > [foo="baz"] { +.focus-visible.js-focus-visible > [foo="baz"], .js-focus-visible .focus-visible > [foo="baz"] { order: 157; } -[foo="baz"],.focus-visible { +[foo="baz"], .focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 158; } -.focus-visible, [foo="baz"] { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, [foo="baz"] { order: 159; } -*.focus-visible { +*.focus-visible.js-focus-visible, .js-focus-visible *.focus-visible { order: 160; } -.focus-visible* { +.focus-visible*.js-focus-visible, .js-focus-visible .focus-visible* { order: 161; } -* .focus-visible { +*.js-focus-visible .focus-visible, .js-focus-visible * .focus-visible { order: 162; } -.focus-visible * { +.focus-visible.js-focus-visible *, .js-focus-visible .focus-visible * { order: 163; } -* .focus-visible { +*.js-focus-visible .focus-visible, .js-focus-visible * .focus-visible { order: 164; } -.focus-visible * { +.focus-visible.js-focus-visible *, .js-focus-visible .focus-visible * { order: 165; } -*+.focus-visible { +*.js-focus-visible+.focus-visible, .js-focus-visible *+.focus-visible { order: 166; } -.focus-visible+* { +.focus-visible.js-focus-visible+*, .js-focus-visible .focus-visible+* { order: 167; } -* + .focus-visible { +*.js-focus-visible + .focus-visible, .js-focus-visible * + .focus-visible { order: 168; } -.focus-visible + * { +.focus-visible.js-focus-visible + *, .js-focus-visible .focus-visible + * { order: 169; } -*~.focus-visible { +*.js-focus-visible~.focus-visible, .js-focus-visible *~.focus-visible { order: 170; } -.focus-visible~* { +.focus-visible.js-focus-visible~*, .js-focus-visible .focus-visible~* { order: 171; } -* ~ .focus-visible { +*.js-focus-visible ~ .focus-visible, .js-focus-visible * ~ .focus-visible { order: 172; } -.focus-visible ~ * { +.focus-visible.js-focus-visible ~ *, .js-focus-visible .focus-visible ~ * { order: 173; } -*>.focus-visible { +*.js-focus-visible>.focus-visible, .js-focus-visible *>.focus-visible { order: 174; } -.focus-visible>* { +.focus-visible.js-focus-visible>*, .js-focus-visible .focus-visible>* { order: 175; } -* > .focus-visible { +*.js-focus-visible > .focus-visible, .js-focus-visible * > .focus-visible { order: 176; } -.focus-visible > * { +.focus-visible.js-focus-visible > *, .js-focus-visible .focus-visible > * { order: 177; } -*,.focus-visible { +*, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 178; } -.focus-visible, * { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, * { order: 179; } -:hover.focus-visible { +:hover.focus-visible.js-focus-visible, .js-focus-visible :hover.focus-visible { order: 180; } -.focus-visible:hover { +.focus-visible:hover.js-focus-visible, .js-focus-visible .focus-visible:hover { order: 181; } -:hover .focus-visible { +:hover.js-focus-visible .focus-visible, .js-focus-visible :hover .focus-visible { order: 182; } -.focus-visible :hover { +.focus-visible.js-focus-visible :hover, .js-focus-visible .focus-visible :hover { order: 183; } -:hover .focus-visible { +:hover.js-focus-visible .focus-visible, .js-focus-visible :hover .focus-visible { order: 184; } -.focus-visible :hover { +.focus-visible.js-focus-visible :hover, .js-focus-visible .focus-visible :hover { order: 185; } -:hover+.focus-visible { +:hover.js-focus-visible+.focus-visible, .js-focus-visible :hover+.focus-visible { order: 186; } -.focus-visible+:hover { +.focus-visible.js-focus-visible+:hover, .js-focus-visible .focus-visible+:hover { order: 187; } -:hover + .focus-visible { +:hover.js-focus-visible + .focus-visible, .js-focus-visible :hover + .focus-visible { order: 188; } -.focus-visible + :hover { +.focus-visible.js-focus-visible + :hover, .js-focus-visible .focus-visible + :hover { order: 189; } -:hover~.focus-visible { +:hover.js-focus-visible~.focus-visible, .js-focus-visible :hover~.focus-visible { order: 190; } -.focus-visible~:hover { +.focus-visible.js-focus-visible~:hover, .js-focus-visible .focus-visible~:hover { order: 191; } -:hover ~ .focus-visible { +:hover.js-focus-visible ~ .focus-visible, .js-focus-visible :hover ~ .focus-visible { order: 192; } -.focus-visible ~ :hover { +.focus-visible.js-focus-visible ~ :hover, .js-focus-visible .focus-visible ~ :hover { order: 193; } -:hover>.focus-visible { +:hover.js-focus-visible>.focus-visible, .js-focus-visible :hover>.focus-visible { order: 194; } -.focus-visible>:hover { +.focus-visible.js-focus-visible>:hover, .js-focus-visible .focus-visible>:hover { order: 195; } -:hover > .focus-visible { +:hover.js-focus-visible > .focus-visible, .js-focus-visible :hover > .focus-visible { order: 196; } -.focus-visible > :hover { +.focus-visible.js-focus-visible > :hover, .js-focus-visible .focus-visible > :hover { order: 197; } -:hover,.focus-visible { +:hover, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 198; } -.focus-visible, :hover { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, :hover { order: 199; } -::before.focus-visible { +.js-focus-visible::before.focus-visible, .js-focus-visible ::before.focus-visible { order: 200; } -.focus-visible::before { +.focus-visible.js-focus-visible::before, .js-focus-visible .focus-visible::before { order: 201; } -::before .focus-visible { +.js-focus-visible::before .focus-visible, .js-focus-visible ::before .focus-visible { order: 202; } -.focus-visible ::before { +.focus-visible.js-focus-visible ::before, .js-focus-visible .focus-visible ::before { order: 203; } -::before .focus-visible { +.js-focus-visible::before .focus-visible, .js-focus-visible ::before .focus-visible { order: 204; } -.focus-visible ::before { +.focus-visible.js-focus-visible ::before, .js-focus-visible .focus-visible ::before { order: 205; } -::before+.focus-visible { +.js-focus-visible::before+.focus-visible, .js-focus-visible ::before+.focus-visible { order: 206; } -.focus-visible+::before { +.focus-visible.js-focus-visible+::before, .js-focus-visible .focus-visible+::before { order: 207; } -::before + .focus-visible { +.js-focus-visible::before + .focus-visible, .js-focus-visible ::before + .focus-visible { order: 208; } -.focus-visible + ::before { +.focus-visible.js-focus-visible + ::before, .js-focus-visible .focus-visible + ::before { order: 209; } -::before~.focus-visible { +.js-focus-visible::before~.focus-visible, .js-focus-visible ::before~.focus-visible { order: 210; } -.focus-visible~::before { +.focus-visible.js-focus-visible~::before, .js-focus-visible .focus-visible~::before { order: 211; } -::before ~ .focus-visible { +.js-focus-visible::before ~ .focus-visible, .js-focus-visible ::before ~ .focus-visible { order: 212; } -.focus-visible ~ ::before { +.focus-visible.js-focus-visible ~ ::before, .js-focus-visible .focus-visible ~ ::before { order: 213; } -::before>.focus-visible { +.js-focus-visible::before>.focus-visible, .js-focus-visible ::before>.focus-visible { order: 214; } -.focus-visible>::before { +.focus-visible.js-focus-visible>::before, .js-focus-visible .focus-visible>::before { order: 215; } -::before > .focus-visible { +.js-focus-visible::before > .focus-visible, .js-focus-visible ::before > .focus-visible { order: 216; } -.focus-visible > ::before { +.focus-visible.js-focus-visible > ::before, .js-focus-visible .focus-visible > ::before { order: 217; } -::before,.focus-visible { +::before, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible { order: 218; } -.focus-visible, ::before { +.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, ::before { order: 219; } @@ -886,7 +886,7 @@ foo[baz=":focus-visible"] { order: 221; } -:not(.focus-visible) { +:not(.focus-visible).js-focus-visible, .js-focus-visible :not(.focus-visible) { order: 222; } @@ -894,11 +894,11 @@ foo[baz=":focus-visible"] { order: 223; } -:--.focus-visible { +:--.focus-visible.js-focus-visible, .js-focus-visible :--.focus-visible { order: 224; } -__.focus-visible { +__.focus-visible.js-focus-visible, .js-focus-visible __.focus-visible { order: 225; }