From b70446e2ab22784446e321176e61c2834d0567e7 Mon Sep 17 00:00:00 2001 From: Antonio Laguna Date: Sat, 2 Jul 2022 12:45:35 +0200 Subject: [PATCH 1/8] Starting focus-within plugin --- package-lock.json | 34 ++++-- plugins/postcss-focus-within/.gitignore | 8 +- plugins/postcss-focus-within/.tape.mjs | 24 ++++ plugins/postcss-focus-within/INSTALL.md | 34 +++--- plugins/postcss-focus-within/README.md | 103 ++++++------------ plugins/postcss-focus-within/docs/README.md | 60 ++++++++++ plugins/postcss-focus-within/package.json | 38 ++++++- .../src/browser-global.js | 3 + plugins/postcss-focus-within/src/browser.js | 75 +++++++++++++ plugins/postcss-focus-within/src/index.ts | 19 +++- .../src/is-valid-replacement.mjs | 24 ++++ plugins/postcss-focus-within/test/browser.css | 0 .../test/browser.expect.css | 0 .../test/examples/example.css | 3 + .../test/examples/example.expect.css | 7 ++ .../examples/example.preserve-true.expect.css | 8 ++ 16 files changed, 328 insertions(+), 112 deletions(-) create mode 100644 plugins/postcss-focus-within/docs/README.md create mode 100644 plugins/postcss-focus-within/src/browser-global.js create mode 100644 plugins/postcss-focus-within/src/browser.js create mode 100644 plugins/postcss-focus-within/src/is-valid-replacement.mjs create mode 100644 plugins/postcss-focus-within/test/browser.css create mode 100644 plugins/postcss-focus-within/test/browser.expect.css create mode 100644 plugins/postcss-focus-within/test/examples/example.css create mode 100644 plugins/postcss-focus-within/test/examples/example.expect.css create mode 100644 plugins/postcss-focus-within/test/examples/example.preserve-true.expect.css diff --git a/package-lock.json b/package-lock.json index 1a4a9509c..b0dd5aaac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1806,6 +1806,10 @@ "resolved": "plugins/postcss-design-tokens", "link": true }, + "node_modules/@csstools/postcss-focus-within": { + "resolved": "plugins/postcss-focus-within", + "link": true + }, "node_modules/@csstools/postcss-font-format-keywords": { "resolved": "plugins/postcss-font-format-keywords", "link": true @@ -5377,8 +5381,18 @@ "link": true }, "node_modules/postcss-focus-within": { - "resolved": "plugins/postcss-focus-within", - "link": true + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } }, "node_modules/postcss-font-variant": { "version": "5.0.0", @@ -7104,11 +7118,9 @@ } }, "plugins/postcss-focus-within": { - "version": "5.0.4", + "name": "@csstools/postcss-focus-within", + "version": "1.0.0", "license": "CC0-1.0", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, "engines": { "node": "^12 || ^14 || >=16" }, @@ -8714,6 +8726,10 @@ "style-dictionary-design-tokens-example": "^1.0.0" } }, + "@csstools/postcss-focus-within": { + "version": "file:plugins/postcss-focus-within", + "requires": {} + }, "@csstools/postcss-font-format-keywords": { "version": "file:plugins/postcss-font-format-keywords", "requires": { @@ -11384,9 +11400,11 @@ } }, "postcss-focus-within": { - "version": "file:plugins/postcss-focus-within", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", "requires": { - "postcss-selector-parser": "^6.0.10" + "postcss-selector-parser": "^6.0.9" } }, "postcss-font-variant": { 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..079384881 100644 --- a/plugins/postcss-focus-within/.tape.mjs +++ b/plugins/postcss-focus-within/.tape.mjs @@ -24,4 +24,28 @@ postcssTape(plugin)({ preserve: false } }, + 'examples/example': { + message: 'minimal example', + }, + 'examples/example:preserve-false': { + message: 'minimal example', + options: { + preserve: false + } + }, + 'examples/example:replacewith': { + message: 'minimal example', + options: { + replaceWith: '.css-blank' + } + }, + 'browser': { + message: 'css for browser tests', + }, + 'browser:replacewith': { + message: 'css for browser tests', + options: { + replaceWith: '.css-blank' + } + }, }); diff --git a/plugins/postcss-focus-within/INSTALL.md b/plugins/postcss-focus-within/INSTALL.md index c8528ac02..e325a41dd 100644 --- a/plugins/postcss-focus-within/INSTALL.md +++ b/plugins/postcss-focus-within/INSTALL.md @@ -10,17 +10,17 @@ Add [PostCSS Focus Within] to your project: ```bash -npm install postcss postcss-focus-within --save-dev +npm install postcss @csstools/postcss-focus-within --save-dev ``` Use it as a [PostCSS] plugin: ```js const postcss = require('postcss'); -const postcssFocusWithin = require('postcss-focus-within'); +const postcssBasePlugin = require('@csstools/postcss-focus-within'); postcss([ - postcssFocusWithin(/* pluginOptions */) + postcssBasePlugin(/* pluginOptions */) ]).process(YOUR_CSS /*, processOptions */); ``` @@ -29,17 +29,17 @@ postcss([ Add [PostCSS CLI] to your project: ```bash -npm install postcss-cli postcss-focus-within --save-dev +npm install postcss-cli @csstools/postcss-focus-within --save-dev ``` Use [PostCSS Focus Within] in your `postcss.config.js` configuration file: ```js -const postcssFocusWithin = require('postcss-focus-within'); +const postcssBasePlugin = require('@csstools/postcss-focus-within'); module.exports = { plugins: [ - postcssFocusWithin(/* pluginOptions */) + postcssBasePlugin(/* pluginOptions */) ] } ``` @@ -51,7 +51,7 @@ _Webpack version 5_ Add [PostCSS Loader] to your project: ```bash -npm install postcss-loader postcss-focus-within --save-dev +npm install postcss-loader @csstools/postcss-focus-within --save-dev ``` Use [PostCSS Focus Within] in your Webpack configuration: @@ -74,7 +74,7 @@ module.exports = { postcssOptions: { plugins: [ [ - "postcss-focus-within", + "@csstools/postcss-focus-within", { // Options }, @@ -95,7 +95,7 @@ module.exports = { Add [React App Rewired] and [React App Rewire PostCSS] to your project: ```bash -npm install react-app-rewired react-app-rewire-postcss postcss-focus-within --save-dev +npm install react-app-rewired react-app-rewire-postcss @csstools/postcss-focus-within --save-dev ``` Use [React App Rewire PostCSS] and [PostCSS Focus Within] in your @@ -103,11 +103,11 @@ Use [React App Rewire PostCSS] and [PostCSS Focus Within] in your ```js const reactAppRewirePostcss = require('react-app-rewire-postcss'); -const postcssFocusWithin = require('postcss-focus-within'); +const postcssBasePlugin = require('@csstools/postcss-focus-within'); module.exports = config => reactAppRewirePostcss(config, { plugins: () => [ - postcssFocusWithin(/* pluginOptions */) + postcssBasePlugin(/* pluginOptions */) ] }); ``` @@ -117,18 +117,18 @@ module.exports = config => reactAppRewirePostcss(config, { Add [Gulp PostCSS] to your project: ```bash -npm install gulp-postcss postcss-focus-within --save-dev +npm install gulp-postcss @csstools/postcss-focus-within --save-dev ``` Use [PostCSS Focus Within] in your Gulpfile: ```js const postcss = require('gulp-postcss'); -const postcssFocusWithin = require('postcss-focus-within'); +const postcssBasePlugin = require('@csstools/postcss-focus-within'); gulp.task('css', function () { var plugins = [ - postcssFocusWithin(/* pluginOptions */) + postcssBasePlugin(/* pluginOptions */) ]; return gulp.src('./src/*.css') @@ -142,13 +142,13 @@ gulp.task('css', function () { Add [Grunt PostCSS] to your project: ```bash -npm install grunt-postcss postcss-focus-within --save-dev +npm install grunt-postcss @csstools/postcss-focus-within --save-dev ``` Use [PostCSS Focus Within] in your Gruntfile: ```js -const postcssFocusWithin = require('postcss-focus-within'); +const postcssBasePlugin = require('@csstools/postcss-focus-within'); grunt.loadNpmTasks('grunt-postcss'); @@ -156,7 +156,7 @@ grunt.initConfig({ postcss: { options: { processors: [ - postcssFocusWithin(/* pluginOptions */) + postcssBasePlugin(/* pluginOptions */) ] }, dist: { diff --git a/plugins/postcss-focus-within/README.md b/plugins/postcss-focus-within/README.md index 8fe6d8619..2f4e93e72 100644 --- a/plugins/postcss-focus-within/README.md +++ b/plugins/postcss-focus-within/README.md @@ -1,63 +1,45 @@ # PostCSS Focus Within [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 Within] lets you use the `:focus-within` pseudo-class in CSS, -following the [Selectors Level 4 specification]. +[PostCSS Focus Within] lets you easily create new plugins following some [CSS Specification]. -It is the companion to the [focus-within polyfill]. - -[!['Can I use' table](https://caniuse.bitsofco.de/image/css-focus-within.png)](https://caniuse.com/#feat=css-focus-within) +```pcss +.foo { + color: red; +} -```css -.my-form-field:focus-within label { - background-color: yellow; +.baz { + color: green; } /* becomes */ -.my-form-field[focus-within] label { - background-color: yellow; +.foo { + color: blue; } -.my-form-field:focus-within label { - background-color: yellow; +.baz { + color: green; } ``` -[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 -`replaceWith` option. Also, the preservation of the original `:focus-within` -rule can be disabled using the `preserve` option. - ## Usage Add [PostCSS Focus Within] to your project: ```bash -npm install postcss postcss-focus-within --save-dev +npm install postcss @csstools/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'); +const postcssBasePlugin = require('@csstools/postcss-focus-within'); postcss([ - postcssFocusWithin(/* pluginOptions */) + postcssBasePlugin(/* pluginOptions */) ]).process(YOUR_CSS /*, processOptions */); ``` @@ -71,59 +53,42 @@ 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 -focusWithin({ preserve: false }); +postcssBasePlugin({ preserve: true }) ``` -```css -.my-form-field:focus-within label { - background-color: yellow; -} - -/* becomes */ - -.my-form-field[focus-within] label { - background-color: yellow; +```pcss +.foo { + color: red; } -``` - -### replaceWith - -The `replaceWith` option defines the selector to replace `:focus-within`. By -default, the replacement selector is `[focus-within]`. - -```js -focusWithin({ replaceWith: '.focus-within' }); -``` -```css -.my-form-field:focus-within label { - background-color: yellow; +.baz { + color: green; } /* becomes */ -.my-form-field.focus-within label { - background-color: yellow; +.foo { + color: blue; + color: red; } -.my-form-field:focus-within label { - background-color: yellow; +.baz { + color: green; } ``` -[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 +[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test +[css-url]: https://cssdb.org/#TODO [discord]: https://discord.gg/bUadyRwkJS -[npm-url]: https://www.npmjs.com/package/postcss-focus-within +[npm-url]: https://www.npmjs.com/package/@csstools/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 -[Selectors Level 4 specification]: https://www.w3.org/TR/selectors-4/#the-focus-within-pseudo +[PostCSS Focus Within]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-within +[CSS Specification]: #TODO diff --git a/plugins/postcss-focus-within/docs/README.md b/plugins/postcss-focus-within/docs/README.md new file mode 100644 index 000000000..df6c74f1a --- /dev/null +++ b/plugins/postcss-focus-within/docs/README.md @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + +
+ +[] 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 not preserved. + +```js +({ preserve: true }) +``` + +```pcss + + +/* becomes */ + + +``` + + +[Selectors Level 4 specification]: diff --git a/plugins/postcss-focus-within/package.json b/plugins/postcss-focus-within/package.json index f2c97d87e..ef0cc4e34 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,22 +58,22 @@ "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", + "stryker": "stryker run --logLevel error", "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" }, - "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-within#readme", "repository": { "type": "git", "url": "https://github.com/csstools/postcss-plugins.git", "directory": "plugins/postcss-focus-within" }, - "bugs": "https://github.com/csstools/postcss-plugins/issues", "keywords": [ "a11y", "accessibility", @@ -67,10 +89,14 @@ "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" - } + }, + "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-within#readme", + "bugs": "https://github.com/csstools/postcss-plugins/issues" } 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..523e74144 --- /dev/null +++ b/plugins/postcss-focus-within/src/browser.js @@ -0,0 +1,75 @@ +/* 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 = Object.assign( + // Default options + { + force: false, + replaceWith: '[focus-within]', + }, + // Provided options + opts, + ); + + 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..e4d0b4db9 100644 --- a/plugins/postcss-focus-within/src/index.ts +++ b/plugins/postcss-focus-within/src/index.ts @@ -1,10 +1,19 @@ import parser from 'postcss-selector-parser'; import type { PluginCreator } from 'postcss'; -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 creator: PluginCreator = (opts?: pluginOptions) => { + const options = Object.assign( + // Default options + { + preserve: false, + replaceWith: '[focus-within]', + }, + // Provided options + opts, + ); + const replacementAST = parser().astSync(options.replaceWith); return { postcssPlugin: 'postcss-focus-within', @@ -46,7 +55,7 @@ const creator: PluginCreator<{ preserve?: boolean, replaceWith?: string }> = (op const clone = rule.clone({ selector: modifiedSelector }); - if (preserve) { + if (options.preserve) { rule.before(clone); } else { rule.replaceWith(clone); 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.css b/plugins/postcss-focus-within/test/browser.css new file mode 100644 index 000000000..e69de29bb 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..e69de29bb 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..9d738d5ac --- /dev/null +++ b/plugins/postcss-focus-within/test/examples/example.expect.css @@ -0,0 +1,7 @@ +.foo { + color: blue; +} + +.baz { + color: green; +} diff --git a/plugins/postcss-focus-within/test/examples/example.preserve-true.expect.css b/plugins/postcss-focus-within/test/examples/example.preserve-true.expect.css new file mode 100644 index 000000000..8b020470a --- /dev/null +++ b/plugins/postcss-focus-within/test/examples/example.preserve-true.expect.css @@ -0,0 +1,8 @@ +.foo { + color: blue; + color: red; +} + +.baz { + color: green; +} From 7bca8ef89fa26a3499483b4a6609261f7e53c92c Mon Sep 17 00:00:00 2001 From: Antonio Laguna Date: Sat, 2 Jul 2022 21:28:23 +0200 Subject: [PATCH 2/8] Finishing focus within --- plugins/postcss-focus-visible/README.md | 22 +- plugins/postcss-focus-visible/docs/README.md | 6 +- plugins/postcss-focus-visible/src/index.ts | 8 +- plugins/postcss-focus-visible/test/basic.css | 4 + .../test/basic.expect.css | 4 + .../test/basic.preserve.expect.css | 4 + .../test/basic.replacewith.expect.css | 4 + .../examples/example.preserve-true.expect.css | 8 - plugins/postcss-focus-within/.tape.mjs | 24 +- plugins/postcss-focus-within/INSTALL.md | 34 +- plugins/postcss-focus-within/README.md | 120 +++-- plugins/postcss-focus-within/docs/README.md | 68 ++- plugins/postcss-focus-within/src/index.ts | 117 +++-- .../postcss-focus-within/test/_browser.html | 43 ++ .../postcss-focus-within/test/_browser.mjs | 160 +++++++ .../test/_browser_replace.html | 43 ++ plugins/postcss-focus-within/test/basic.css | 4 + .../test/basic.expect.css | 77 ++- .../test/basic.preserve.expect.css | 53 ++- .../test/basic.replacewith.expect.css | 77 ++- plugins/postcss-focus-within/test/browser.css | 11 + .../test/browser.expect.css | 11 + .../test/browser.replacewith.expect.css | 11 + .../test/examples/example.expect.css | 8 +- .../example.preserve-false.expect.css | 3 + .../examples/example.preserve-true.expect.css | 8 - .../examples/example.replacewith.expect.css | 3 + .../test/generated-selector-cases.expect.css | 442 +++++++++--------- 28 files changed, 913 insertions(+), 464 deletions(-) delete mode 100644 plugins/postcss-focus-visible/test/examples/example.preserve-true.expect.css create mode 100644 plugins/postcss-focus-within/test/_browser.html create mode 100644 plugins/postcss-focus-within/test/_browser.mjs create mode 100644 plugins/postcss-focus-within/test/_browser_replace.html create mode 100644 plugins/postcss-focus-within/test/browser.replacewith.expect.css create mode 100644 plugins/postcss-focus-within/test/examples/example.preserve-false.expect.css delete mode 100644 plugins/postcss-focus-within/test/examples/example.preserve-true.expect.css create mode 100644 plugins/postcss-focus-within/test/examples/example.replacewith.expect.css diff --git a/plugins/postcss-focus-visible/README.md b/plugins/postcss-focus-visible/README.md index 6f1f2c3e5..4a70c1210 100644 --- a/plugins/postcss-focus-visible/README.md +++ b/plugins/postcss-focus-visible/README.md @@ -59,10 +59,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 +72,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 +93,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..e3d0a30b3 100644 --- a/plugins/postcss-focus-visible/test/basic.expect.css +++ b/plugins/postcss-focus-visible/test/basic.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.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..8923428ad 100644 --- a/plugins/postcss-focus-visible/test/basic.replacewith.expect.css +++ b/plugins/postcss-focus-visible/test/basic.replacewith.expect.css @@ -94,3 +94,7 @@ html.js-focus-visible :not([data-focus-visible-added]), .js-focus-visible html : .foo.js-focus-visible > [data-focus-visible-added], .js-focus-visible .foo > [data-focus-visible-added] { order: 10.5; } + +[data-focus-visible-added].js-focus-visible, .js-focus-visible [data-focus-visible-added] { + order: 11; +} 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-within/.tape.mjs b/plugins/postcss-focus-within/.tape.mjs index 079384881..3f9f2e1de 100644 --- a/plugins/postcss-focus-within/.tape.mjs +++ b/plugins/postcss-focus-within/.tape.mjs @@ -3,41 +3,35 @@ 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, - options: { - preserve: false - } }, 'examples/example': { message: 'minimal example', }, 'examples/example:preserve-false': { message: 'minimal example', - options: { - preserve: false - } }, 'examples/example:replacewith': { message: 'minimal example', options: { - replaceWith: '.css-blank' - } + replaceWith: '.focus-within', + }, }, 'browser': { message: 'css for browser tests', @@ -45,7 +39,7 @@ postcssTape(plugin)({ 'browser:replacewith': { message: 'css for browser tests', options: { - replaceWith: '.css-blank' - } + replaceWith: '.focus-within', + }, }, }); diff --git a/plugins/postcss-focus-within/INSTALL.md b/plugins/postcss-focus-within/INSTALL.md index e325a41dd..c8528ac02 100644 --- a/plugins/postcss-focus-within/INSTALL.md +++ b/plugins/postcss-focus-within/INSTALL.md @@ -10,17 +10,17 @@ Add [PostCSS Focus Within] to your project: ```bash -npm install postcss @csstools/postcss-focus-within --save-dev +npm install postcss postcss-focus-within --save-dev ``` Use it as a [PostCSS] plugin: ```js const postcss = require('postcss'); -const postcssBasePlugin = require('@csstools/postcss-focus-within'); +const postcssFocusWithin = require('postcss-focus-within'); postcss([ - postcssBasePlugin(/* pluginOptions */) + postcssFocusWithin(/* pluginOptions */) ]).process(YOUR_CSS /*, processOptions */); ``` @@ -29,17 +29,17 @@ postcss([ Add [PostCSS CLI] to your project: ```bash -npm install postcss-cli @csstools/postcss-focus-within --save-dev +npm install postcss-cli postcss-focus-within --save-dev ``` Use [PostCSS Focus Within] in your `postcss.config.js` configuration file: ```js -const postcssBasePlugin = require('@csstools/postcss-focus-within'); +const postcssFocusWithin = require('postcss-focus-within'); module.exports = { plugins: [ - postcssBasePlugin(/* pluginOptions */) + postcssFocusWithin(/* pluginOptions */) ] } ``` @@ -51,7 +51,7 @@ _Webpack version 5_ Add [PostCSS Loader] to your project: ```bash -npm install postcss-loader @csstools/postcss-focus-within --save-dev +npm install postcss-loader postcss-focus-within --save-dev ``` Use [PostCSS Focus Within] in your Webpack configuration: @@ -74,7 +74,7 @@ module.exports = { postcssOptions: { plugins: [ [ - "@csstools/postcss-focus-within", + "postcss-focus-within", { // Options }, @@ -95,7 +95,7 @@ module.exports = { Add [React App Rewired] and [React App Rewire PostCSS] to your project: ```bash -npm install react-app-rewired react-app-rewire-postcss @csstools/postcss-focus-within --save-dev +npm install react-app-rewired react-app-rewire-postcss postcss-focus-within --save-dev ``` Use [React App Rewire PostCSS] and [PostCSS Focus Within] in your @@ -103,11 +103,11 @@ Use [React App Rewire PostCSS] and [PostCSS Focus Within] in your ```js const reactAppRewirePostcss = require('react-app-rewire-postcss'); -const postcssBasePlugin = require('@csstools/postcss-focus-within'); +const postcssFocusWithin = require('postcss-focus-within'); module.exports = config => reactAppRewirePostcss(config, { plugins: () => [ - postcssBasePlugin(/* pluginOptions */) + postcssFocusWithin(/* pluginOptions */) ] }); ``` @@ -117,18 +117,18 @@ module.exports = config => reactAppRewirePostcss(config, { Add [Gulp PostCSS] to your project: ```bash -npm install gulp-postcss @csstools/postcss-focus-within --save-dev +npm install gulp-postcss postcss-focus-within --save-dev ``` Use [PostCSS Focus Within] in your Gulpfile: ```js const postcss = require('gulp-postcss'); -const postcssBasePlugin = require('@csstools/postcss-focus-within'); +const postcssFocusWithin = require('postcss-focus-within'); gulp.task('css', function () { var plugins = [ - postcssBasePlugin(/* pluginOptions */) + postcssFocusWithin(/* pluginOptions */) ]; return gulp.src('./src/*.css') @@ -142,13 +142,13 @@ gulp.task('css', function () { Add [Grunt PostCSS] to your project: ```bash -npm install grunt-postcss @csstools/postcss-focus-within --save-dev +npm install grunt-postcss postcss-focus-within --save-dev ``` Use [PostCSS Focus Within] in your Gruntfile: ```js -const postcssBasePlugin = require('@csstools/postcss-focus-within'); +const postcssFocusWithin = require('postcss-focus-within'); grunt.loadNpmTasks('grunt-postcss'); @@ -156,7 +156,7 @@ grunt.initConfig({ postcss: { options: { processors: [ - postcssBasePlugin(/* pluginOptions */) + postcssFocusWithin(/* pluginOptions */) ] }, dist: { diff --git a/plugins/postcss-focus-within/README.md b/plugins/postcss-focus-within/README.md index 2f4e93e72..6d57e8bb1 100644 --- a/plugins/postcss-focus-within/README.md +++ b/plugins/postcss-focus-within/README.md @@ -1,45 +1,44 @@ # PostCSS Focus Within [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 Within] lets you easily create new plugins following some [CSS Specification]. +[PostCSS Focus Within] lets you use the `:focus-within` pseudo-class in CSS, +following the [Selectors Level 4 specification]. ```pcss -.foo { - color: red; -} - -.baz { - color: green; +.my-form-field:focus-within label { + background-color: yellow; } /* becomes */ -.foo { - color: blue; -} - -.baz { - color: green; +.my-form-field[focus-within].js-focus-within label, .js-focus-within .my-form-field[focus-within] label { + 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 +`replaceWith` option. Also, the preservation of the original `:focus-within` +rule can be disabled using the `preserve` option. + ## Usage Add [PostCSS Focus Within] to your project: ```bash -npm install postcss @csstools/postcss-focus-within --save-dev +npm install postcss postcss-focus-within --save-dev ``` Use it as a [PostCSS] plugin: ```js const postcss = require('postcss'); -const postcssBasePlugin = require('@csstools/postcss-focus-within'); +const postcssFocusWithin = require('postcss-focus-within'); postcss([ - postcssBasePlugin(/* pluginOptions */) + postcssFocusWithin(/* pluginOptions */) ]).process(YOUR_CSS /*, processOptions */); ``` @@ -54,41 +53,98 @@ 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 -postcssBasePlugin({ preserve: true }) +postcssFocusWithin({ preserve: false }) ``` ```pcss -.foo { - color: red; +.my-form-field:focus-within label { + background-color: yellow; } -.baz { - color: green; +/* becomes */ + +.my-form-field[focus-within].js-focus-within label, .js-focus-within .my-form-field[focus-within] label { + background-color: yellow; } +``` -/* becomes */ +### replaceWith + +The `replaceWith` option defines the selector to replace `:focus-within`. By +default, the replacement selector is `[focus-within]`. -.foo { - color: blue; - color: red; +```js +postcssFocusWithin({ replaceWith: '.focus-within' }); +``` + +```pcss +.my-form-field:focus-within label { + background-color: yellow; } -.baz { - color: green; +/* becomes */ + +.my-form-field.focus-within.js-focus-within label, .js-focus-within .my-form-field.focus-within label { + 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/#TODO +[css-url]: https://cssdb.org/#focus-within-pseudo-class [discord]: https://discord.gg/bUadyRwkJS -[npm-url]: https://www.npmjs.com/package/@csstools/postcss-focus-within +[npm-url]: https://www.npmjs.com/package/postcss-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 Loader]: https://github.com/postcss/postcss-loader [PostCSS Focus Within]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-within -[CSS Specification]: #TODO +[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 index df6c74f1a..cd8d22648 100644 --- a/plugins/postcss-focus-within/docs/README.md +++ b/plugins/postcss-focus-within/docs/README.md @@ -42,10 +42,10 @@ rule can be disabled using the `preserve` option. ### 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 @@ -53,8 +53,70 @@ is preserved. By default, it is not preserved. /* 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/src/index.ts b/plugins/postcss-focus-within/src/index.ts index e4d0b4db9..dd2bd03c4 100644 --- a/plugins/postcss-focus-within/src/index.ts +++ b/plugins/postcss-focus-within/src/index.ts @@ -1,64 +1,121 @@ import parser from 'postcss-selector-parser'; import type { PluginCreator } from 'postcss'; +import isValidReplacement from './is-valid-replacement.mjs'; 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: false, + 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 (options.preserve) { - rule.before(clone); - } else { - rule.replaceWith(clone); + if (!options.preserve) { + rule.remove(); } }, }; 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..034a0d288 100644 --- a/plugins/postcss-focus-within/test/basic.expect.css +++ b/plugins/postcss-focus-within/test/basic.expect.css @@ -1,41 +1,35 @@ -[focus-within] { +[focus-within].js-focus-within, .js-focus-within [focus-within] { order: 1; } -: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 { - order: 2; -} - -: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,14 +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; } -.escaped\:focus-within, -.escaped\:times\:two\:focus-within, -.escaped\:focus-within: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.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..9d430a232 100644 --- a/plugins/postcss-focus-within/test/basic.replacewith.expect.css +++ b/plugins/postcss-focus-within/test/basic.replacewith.expect.css @@ -1,41 +1,35 @@ -.focus-within { +.focus-within.js-focus-within, .js-focus-within .focus-within { order: 1; } -: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 { - order: 2; -} - -: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,14 +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; } -.escaped\:focus-within, -.escaped\:times\:two\:focus-within, -.escaped\:focus-within: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/browser.css b/plugins/postcss-focus-within/test/browser.css index e69de29bb..1860c200a 100644 --- a/plugins/postcss-focus-within/test/browser.css +++ 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 index e69de29bb..16174b186 100644 --- a/plugins/postcss-focus-within/test/browser.expect.css +++ b/plugins/postcss-focus-within/test/browser.expect.css @@ -0,0 +1,11 @@ +div { + padding: 2em; +} + +div[focus-within].js-focus-within, .js-focus-within 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); +} 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..4b3410061 --- /dev/null +++ b/plugins/postcss-focus-within/test/browser.replacewith.expect.css @@ -0,0 +1,11 @@ +div { + padding: 2em; +} + +div.focus-within.js-focus-within, .js-focus-within 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); +} diff --git a/plugins/postcss-focus-within/test/examples/example.expect.css b/plugins/postcss-focus-within/test/examples/example.expect.css index 9d738d5ac..1188030bd 100644 --- a/plugins/postcss-focus-within/test/examples/example.expect.css +++ b/plugins/postcss-focus-within/test/examples/example.expect.css @@ -1,7 +1,3 @@ -.foo { - color: blue; -} - -.baz { - color: green; +.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.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.preserve-true.expect.css b/plugins/postcss-focus-within/test/examples/example.preserve-true.expect.css deleted file mode 100644 index 8b020470a..000000000 --- a/plugins/postcss-focus-within/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-within/test/examples/example.replacewith.expect.css b/plugins/postcss-focus-within/test/examples/example.replacewith.expect.css new file mode 100644 index 000000000..5908cfe31 --- /dev/null +++ b/plugins/postcss-focus-within/test/examples/example.replacewith.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/generated-selector-cases.expect.css b/plugins/postcss-focus-within/test/generated-selector-cases.expect.css index 25299452c..0b1c1eae0 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,84 @@ -[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].js-focus-within, .js-focus-within [focus-within][focus-within] { order: 1; } -[focus-within] [focus-within] { +[focus-within].js-focus-within [focus-within], .js-focus-within [focus-within] [focus-within] { order: 2; } -[focus-within] [focus-within] { +[focus-within].js-focus-within [focus-within], .js-focus-within [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] { +[focus-within].js-focus-within [focus-within], .js-focus-within [focus-within] [focus-within] { order: 5; } -[focus-within]+[focus-within] { +[focus-within].js-focus-within+[focus-within], .js-focus-within [focus-within]+[focus-within] { order: 6; } -[focus-within]+[focus-within] { +[focus-within].js-focus-within+[focus-within], .js-focus-within [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] { +[focus-within].js-focus-within + [focus-within], .js-focus-within [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] { +[focus-within].js-focus-within~[focus-within], .js-focus-within [focus-within]~[focus-within] { order: 11; } -[focus-within] ~ [focus-within] { +[focus-within].js-focus-within ~ [focus-within], .js-focus-within [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].js-focus-within>[focus-within], .js-focus-within [focus-within]>[focus-within] { order: 14; } -[focus-within]>[focus-within] { +[focus-within].js-focus-within>[focus-within], .js-focus-within [focus-within]>[focus-within] { order: 15; } -[focus-within] > [focus-within] { +[focus-within].js-focus-within > [focus-within], .js-focus-within [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].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].js-focus-within, .js-focus-within [focus-within], [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 19; } -button[focus-within] { +button[focus-within].js-focus-within, .js-focus-within button[focus-within] { order: 20; } @@ -86,319 +86,319 @@ button[focus-within] { order: 21; } -button [focus-within] { +button.js-focus-within [focus-within], .js-focus-within button [focus-within] { order: 22; } -[focus-within] button { +[focus-within].js-focus-within button, .js-focus-within [focus-within] button { order: 23; } -button [focus-within] { +button.js-focus-within [focus-within], .js-focus-within 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] { +button.js-focus-within+[focus-within], .js-focus-within 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] { +button.js-focus-within + [focus-within], .js-focus-within button + [focus-within] { order: 28; } -[focus-within] + button { +[focus-within].js-focus-within + button, .js-focus-within [focus-within] + button { order: 29; } -button~[focus-within] { +button.js-focus-within~[focus-within], .js-focus-within 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] { +button.js-focus-within ~ [focus-within], .js-focus-within button ~ [focus-within] { order: 32; } -[focus-within] ~ button { +[focus-within].js-focus-within ~ button, .js-focus-within [focus-within] ~ button { order: 33; } -button>[focus-within] { +button.js-focus-within>[focus-within], .js-focus-within button>[focus-within] { order: 34; } -[focus-within]>button { +[focus-within].js-focus-within>button, .js-focus-within [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 { +[focus-within].js-focus-within > button, .js-focus-within [focus-within] > button { order: 37; } -button,[focus-within] { +button, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 38; } -[focus-within], button { +[focus-within].js-focus-within, .js-focus-within [focus-within], button { order: 39; } -.🧑🏾‍🎤[focus-within] { +.🧑🏾‍🎤[focus-within].js-focus-within, .js-focus-within .🧑🏾‍🎤[focus-within] { order: 40; } -[focus-within].🧑🏾‍🎤 { +[focus-within].🧑🏾‍🎤.js-focus-within, .js-focus-within [focus-within].🧑🏾‍🎤 { order: 41; } -.🧑🏾‍🎤 [focus-within] { +.🧑🏾‍🎤.js-focus-within [focus-within], .js-focus-within .🧑🏾‍🎤 [focus-within] { order: 42; } -[focus-within] .🧑🏾‍🎤 { +[focus-within].js-focus-within .🧑🏾‍🎤, .js-focus-within [focus-within] .🧑🏾‍🎤 { order: 43; } -.🧑🏾‍🎤 [focus-within] { +.🧑🏾‍🎤.js-focus-within [focus-within], .js-focus-within .🧑🏾‍🎤 [focus-within] { order: 44; } -[focus-within] .🧑🏾‍🎤 { +[focus-within].js-focus-within .🧑🏾‍🎤, .js-focus-within [focus-within] .🧑🏾‍🎤 { order: 45; } -.🧑🏾‍🎤+[focus-within] { +.🧑🏾‍🎤.js-focus-within+[focus-within], .js-focus-within .🧑🏾‍🎤+[focus-within] { order: 46; } -[focus-within]+.🧑🏾‍🎤 { +[focus-within].js-focus-within+.🧑🏾‍🎤, .js-focus-within [focus-within]+.🧑🏾‍🎤 { order: 47; } -.🧑🏾‍🎤 + [focus-within] { +.🧑🏾‍🎤.js-focus-within + [focus-within], .js-focus-within .🧑🏾‍🎤 + [focus-within] { order: 48; } -[focus-within] + .🧑🏾‍🎤 { +[focus-within].js-focus-within + .🧑🏾‍🎤, .js-focus-within [focus-within] + .🧑🏾‍🎤 { order: 49; } -.🧑🏾‍🎤~[focus-within] { +.🧑🏾‍🎤.js-focus-within~[focus-within], .js-focus-within .🧑🏾‍🎤~[focus-within] { order: 50; } -[focus-within]~.🧑🏾‍🎤 { +[focus-within].js-focus-within~.🧑🏾‍🎤, .js-focus-within [focus-within]~.🧑🏾‍🎤 { order: 51; } -.🧑🏾‍🎤 ~ [focus-within] { +.🧑🏾‍🎤.js-focus-within ~ [focus-within], .js-focus-within .🧑🏾‍🎤 ~ [focus-within] { order: 52; } -[focus-within] ~ .🧑🏾‍🎤 { +[focus-within].js-focus-within ~ .🧑🏾‍🎤, .js-focus-within [focus-within] ~ .🧑🏾‍🎤 { order: 53; } -.🧑🏾‍🎤>[focus-within] { +.🧑🏾‍🎤.js-focus-within>[focus-within], .js-focus-within .🧑🏾‍🎤>[focus-within] { order: 54; } -[focus-within]>.🧑🏾‍🎤 { +[focus-within].js-focus-within>.🧑🏾‍🎤, .js-focus-within [focus-within]>.🧑🏾‍🎤 { order: 55; } -.🧑🏾‍🎤 > [focus-within] { +.🧑🏾‍🎤.js-focus-within > [focus-within], .js-focus-within .🧑🏾‍🎤 > [focus-within] { order: 56; } -[focus-within] > .🧑🏾‍🎤 { +[focus-within].js-focus-within > .🧑🏾‍🎤, .js-focus-within [focus-within] > .🧑🏾‍🎤 { order: 57; } -.🧑🏾‍🎤,[focus-within] { +.🧑🏾‍🎤, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 58; } -[focus-within], .🧑🏾‍🎤 { +[focus-within].js-focus-within, .js-focus-within [focus-within], .🧑🏾‍🎤 { order: 59; } -.foo[focus-within] { +.foo[focus-within].js-focus-within, .js-focus-within .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] { +.foo.js-focus-within [focus-within], .js-focus-within .foo [focus-within] { order: 62; } -[focus-within] .foo { +[focus-within].js-focus-within .foo, .js-focus-within [focus-within] .foo { order: 63; } -.foo [focus-within] { +.foo.js-focus-within [focus-within], .js-focus-within .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] { +.foo.js-focus-within+[focus-within], .js-focus-within .foo+[focus-within] { order: 66; } -[focus-within]+.foo { +[focus-within].js-focus-within+.foo, .js-focus-within [focus-within]+.foo { order: 67; } -.foo + [focus-within] { +.foo.js-focus-within + [focus-within], .js-focus-within .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] { +.foo.js-focus-within~[focus-within], .js-focus-within .foo~[focus-within] { order: 70; } -[focus-within]~.foo { +[focus-within].js-focus-within~.foo, .js-focus-within [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 { +[focus-within].js-focus-within ~ .foo, .js-focus-within [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 { +[focus-within].js-focus-within>.foo, .js-focus-within [focus-within]>.foo { order: 75; } -.foo > [focus-within] { +.foo.js-focus-within > [focus-within], .js-focus-within .foo > [focus-within] { order: 76; } -[focus-within] > .foo { +[focus-within].js-focus-within > .foo, .js-focus-within [focus-within] > .foo { order: 77; } -.foo,[focus-within] { +.foo, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 78; } -[focus-within], .foo { +[focus-within].js-focus-within, .js-focus-within [focus-within], .foo { order: 79; } -#foo[focus-within] { +#foo[focus-within].js-focus-within, .js-focus-within #foo[focus-within] { order: 80; } -[focus-within]#foo { +[focus-within]#foo.js-focus-within, .js-focus-within [focus-within]#foo { order: 81; } -#foo [focus-within] { +#foo.js-focus-within [focus-within], .js-focus-within #foo [focus-within] { order: 82; } -[focus-within] #foo { +[focus-within].js-focus-within #foo, .js-focus-within [focus-within] #foo { order: 83; } -#foo [focus-within] { +#foo.js-focus-within [focus-within], .js-focus-within #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] { +#foo.js-focus-within+[focus-within], .js-focus-within #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] { +#foo.js-focus-within + [focus-within], .js-focus-within #foo + [focus-within] { order: 88; } -[focus-within] + #foo { +[focus-within].js-focus-within + #foo, .js-focus-within [focus-within] + #foo { order: 89; } -#foo~[focus-within] { +#foo.js-focus-within~[focus-within], .js-focus-within #foo~[focus-within] { order: 90; } -[focus-within]~#foo { +[focus-within].js-focus-within~#foo, .js-focus-within [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 { +[focus-within].js-focus-within ~ #foo, .js-focus-within [focus-within] ~ #foo { order: 93; } -#foo>[focus-within] { +#foo.js-focus-within>[focus-within], .js-focus-within #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] { +#foo.js-focus-within > [focus-within], .js-focus-within #foo > [focus-within] { order: 96; } -[focus-within] > #foo { +[focus-within].js-focus-within > #foo, .js-focus-within [focus-within] > #foo { order: 97; } -#foo,[focus-within] { +#foo, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 98; } -[focus-within], #foo { +[focus-within].js-focus-within, .js-focus-within [focus-within], #foo { order: 99; } -__foo[focus-within] { +__foo[focus-within].js-focus-within, .js-focus-within __foo[focus-within] { order: 100; } @@ -406,475 +406,475 @@ __foo[focus-within] { order: 101; } -__foo [focus-within] { +__foo.js-focus-within [focus-within], .js-focus-within __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] { +__foo.js-focus-within [focus-within], .js-focus-within __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] { +__foo.js-focus-within+[focus-within], .js-focus-within __foo+[focus-within] { order: 106; } -[focus-within]+__foo { +[focus-within].js-focus-within+__foo, .js-focus-within [focus-within]+__foo { order: 107; } -__foo + [focus-within] { +__foo.js-focus-within + [focus-within], .js-focus-within __foo + [focus-within] { order: 108; } -[focus-within] + __foo { +[focus-within].js-focus-within + __foo, .js-focus-within [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 { +[focus-within].js-focus-within~__foo, .js-focus-within [focus-within]~__foo { order: 111; } -__foo ~ [focus-within] { +__foo.js-focus-within ~ [focus-within], .js-focus-within __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] { +__foo.js-focus-within>[focus-within], .js-focus-within __foo>[focus-within] { order: 114; } -[focus-within]>__foo { +[focus-within].js-focus-within>__foo, .js-focus-within [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 { +[focus-within].js-focus-within > __foo, .js-focus-within [focus-within] > __foo { order: 117; } -__foo,[focus-within] { +__foo, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 118; } -[focus-within], __foo { +[focus-within].js-focus-within, .js-focus-within [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 { +[focus-within]:--foo.js-focus-within, .js-focus-within [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 { +[focus-within].js-focus-within :--foo, .js-focus-within [focus-within] :--foo { order: 123; } -:--foo [focus-within] { +:--foo.js-focus-within [focus-within], .js-focus-within :--foo [focus-within] { order: 124; } -[focus-within] :--foo { +[focus-within].js-focus-within :--foo, .js-focus-within [focus-within] :--foo { order: 125; } -:--foo+[focus-within] { +:--foo.js-focus-within+[focus-within], .js-focus-within :--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] { +:--foo.js-focus-within + [focus-within], .js-focus-within :--foo + [focus-within] { order: 128; } -[focus-within] + :--foo { +[focus-within].js-focus-within + :--foo, .js-focus-within [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 { +[focus-within].js-focus-within~:--foo, .js-focus-within [focus-within]~:--foo { order: 131; } -:--foo ~ [focus-within] { +:--foo.js-focus-within ~ [focus-within], .js-focus-within :--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] { +:--foo.js-focus-within>[focus-within], .js-focus-within :--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] { +:--foo.js-focus-within > [focus-within], .js-focus-within :--foo > [focus-within] { order: 136; } -[focus-within] > :--foo { +[focus-within].js-focus-within > :--foo, .js-focus-within [focus-within] > :--foo { order: 137; } -:--foo,[focus-within] { +:--foo, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 138; } -[focus-within], :--foo { +[focus-within].js-focus-within, .js-focus-within [focus-within], :--foo { order: 139; } -[foo="baz"][focus-within] { +[foo="baz"][focus-within].js-focus-within, .js-focus-within [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; } -[foo="baz"] [focus-within] { +[foo="baz"].js-focus-within [focus-within], .js-focus-within [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] { +[foo="baz"].js-focus-within [focus-within], .js-focus-within [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; } -[foo="baz"]+[focus-within] { +[foo="baz"].js-focus-within+[focus-within], .js-focus-within [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] { +[foo="baz"].js-focus-within + [focus-within], .js-focus-within [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; } -[foo="baz"]~[focus-within] { +[foo="baz"].js-focus-within~[focus-within], .js-focus-within [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] { +[foo="baz"].js-focus-within ~ [focus-within], .js-focus-within [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; } -[foo="baz"]>[focus-within] { +[foo="baz"].js-focus-within>[focus-within], .js-focus-within [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] { +[foo="baz"].js-focus-within > [focus-within], .js-focus-within [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; } -[foo="baz"],[focus-within] { +[foo="baz"], [focus-within].js-focus-within, .js-focus-within [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].js-focus-within, .js-focus-within *[focus-within] { order: 160; } -[focus-within]* { +[focus-within]*.js-focus-within, .js-focus-within [focus-within]* { order: 161; } -* [focus-within] { +*.js-focus-within [focus-within], .js-focus-within * [focus-within] { order: 162; } -[focus-within] * { +[focus-within].js-focus-within *, .js-focus-within [focus-within] * { order: 163; } -* [focus-within] { +*.js-focus-within [focus-within], .js-focus-within * [focus-within] { order: 164; } -[focus-within] * { +[focus-within].js-focus-within *, .js-focus-within [focus-within] * { order: 165; } -*+[focus-within] { +*.js-focus-within+[focus-within], .js-focus-within *+[focus-within] { order: 166; } -[focus-within]+* { +[focus-within].js-focus-within+*, .js-focus-within [focus-within]+* { order: 167; } -* + [focus-within] { +*.js-focus-within + [focus-within], .js-focus-within * + [focus-within] { order: 168; } -[focus-within] + * { +[focus-within].js-focus-within + *, .js-focus-within [focus-within] + * { order: 169; } -*~[focus-within] { +*.js-focus-within~[focus-within], .js-focus-within *~[focus-within] { order: 170; } -[focus-within]~* { +[focus-within].js-focus-within~*, .js-focus-within [focus-within]~* { order: 171; } -* ~ [focus-within] { +*.js-focus-within ~ [focus-within], .js-focus-within * ~ [focus-within] { order: 172; } -[focus-within] ~ * { +[focus-within].js-focus-within ~ *, .js-focus-within [focus-within] ~ * { order: 173; } -*>[focus-within] { +*.js-focus-within>[focus-within], .js-focus-within *>[focus-within] { order: 174; } -[focus-within]>* { +[focus-within].js-focus-within>*, .js-focus-within [focus-within]>* { order: 175; } -* > [focus-within] { +*.js-focus-within > [focus-within], .js-focus-within * > [focus-within] { order: 176; } -[focus-within] > * { +[focus-within].js-focus-within > *, .js-focus-within [focus-within] > * { order: 177; } -*,[focus-within] { +*, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 178; } -[focus-within], * { +[focus-within].js-focus-within, .js-focus-within [focus-within], * { order: 179; } -:hover[focus-within] { +:hover[focus-within].js-focus-within, .js-focus-within :hover[focus-within] { order: 180; } -[focus-within]:hover { +[focus-within]:hover.js-focus-within, .js-focus-within [focus-within]:hover { order: 181; } -:hover [focus-within] { +:hover.js-focus-within [focus-within], .js-focus-within :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] { +:hover.js-focus-within [focus-within], .js-focus-within :hover [focus-within] { order: 184; } -[focus-within] :hover { +[focus-within].js-focus-within :hover, .js-focus-within [focus-within] :hover { order: 185; } -:hover+[focus-within] { +:hover.js-focus-within+[focus-within], .js-focus-within :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] { +:hover.js-focus-within + [focus-within], .js-focus-within :hover + [focus-within] { order: 188; } -[focus-within] + :hover { +[focus-within].js-focus-within + :hover, .js-focus-within [focus-within] + :hover { order: 189; } -:hover~[focus-within] { +:hover.js-focus-within~[focus-within], .js-focus-within :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] { +:hover.js-focus-within ~ [focus-within], .js-focus-within :hover ~ [focus-within] { order: 192; } -[focus-within] ~ :hover { +[focus-within].js-focus-within ~ :hover, .js-focus-within [focus-within] ~ :hover { order: 193; } -:hover>[focus-within] { +:hover.js-focus-within>[focus-within], .js-focus-within :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] { +:hover.js-focus-within > [focus-within], .js-focus-within :hover > [focus-within] { order: 196; } -[focus-within] > :hover { +[focus-within].js-focus-within > :hover, .js-focus-within [focus-within] > :hover { order: 197; } -:hover,[focus-within] { +:hover, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 198; } -[focus-within], :hover { +[focus-within].js-focus-within, .js-focus-within [focus-within], :hover { order: 199; } -::before[focus-within] { +.js-focus-within::before[focus-within], .js-focus-within ::before[focus-within] { order: 200; } -[focus-within]::before { +[focus-within].js-focus-within::before, .js-focus-within [focus-within]::before { order: 201; } -::before [focus-within] { +.js-focus-within::before [focus-within], .js-focus-within ::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] { +.js-focus-within::before [focus-within], .js-focus-within ::before [focus-within] { order: 204; } -[focus-within] ::before { +[focus-within].js-focus-within ::before, .js-focus-within [focus-within] ::before { order: 205; } -::before+[focus-within] { +.js-focus-within::before+[focus-within], .js-focus-within ::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] { +.js-focus-within::before + [focus-within], .js-focus-within ::before + [focus-within] { order: 208; } -[focus-within] + ::before { +[focus-within].js-focus-within + ::before, .js-focus-within [focus-within] + ::before { order: 209; } -::before~[focus-within] { +.js-focus-within::before~[focus-within], .js-focus-within ::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] { +.js-focus-within::before ~ [focus-within], .js-focus-within ::before ~ [focus-within] { order: 212; } -[focus-within] ~ ::before { +[focus-within].js-focus-within ~ ::before, .js-focus-within [focus-within] ~ ::before { order: 213; } -::before>[focus-within] { +.js-focus-within::before>[focus-within], .js-focus-within ::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] { +.js-focus-within::before > [focus-within], .js-focus-within ::before > [focus-within] { order: 216; } -[focus-within] > ::before { +[focus-within].js-focus-within > ::before, .js-focus-within [focus-within] > ::before { order: 217; } -::before,[focus-within] { +::before, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 218; } -[focus-within], ::before { +[focus-within].js-focus-within, .js-focus-within [focus-within], ::before { order: 219; } @@ -886,7 +886,7 @@ foo[baz=":focus-within"] { order: 221; } -:not([focus-within]) { +:not([focus-within]).js-focus-within, .js-focus-within :not([focus-within]) { order: 222; } @@ -894,11 +894,11 @@ foo[baz=":focus-within"] { order: 223; } -:--[focus-within] { +:--[focus-within].js-focus-within, .js-focus-within :--[focus-within] { order: 224; } -__[focus-within] { +__[focus-within].js-focus-within, .js-focus-within __[focus-within] { order: 225; } From b73ffad0f8fa1e9f3ff3310b3e4d587acfadcd9c Mon Sep 17 00:00:00 2001 From: Antonio Laguna Date: Sat, 2 Jul 2022 22:16:58 +0200 Subject: [PATCH 3/8] Updating tests --- package-lock.json | 34 +++++-------------- .../test/basic.autoprefixer.expect.css | 4 +++ .../test/basic.autoprefixer.false.expect.css | 4 +++ .../test/basic.ch38.expect.css | 4 +++ .../test/basic.ch88-ff78-saf10.expect.css | 4 +++ .../test/basic.ch88-ff78.expect.css | 4 +++ .../basic.ch88-ff78.no-is-pseudo.expect.css | 4 +++ .../postcss-preset-env/test/basic.expect.css | 4 +++ .../test/basic.ff49.expect.css | 4 +++ .../test/basic.ff66.expect.css | 4 +++ .../test/basic.ie10.expect.css | 5 +++ .../test/basic.nesting.false.expect.css | 4 +++ .../test/basic.op_mini.expect.css | 4 +++ .../test/basic.safari15.expect.css | 4 +++ .../test/basic.stage0-ff49.expect.css | 4 +++ .../test/basic.stage0-ff66.expect.css | 4 +++ .../test/basic.stage0.expect.css | 4 +++ .../client-side-polyfills.stage-1.expect.css | 2 +- .../client-side-polyfills.stage-2.expect.css | 2 +- ...-client-side-polyfills.disabled.expect.css | 2 +- .../test/layers-basic.expect.css | 8 +++++ plugins/postcss-focus-within/package.json | 7 ++-- 22 files changed, 87 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index d4af5f33a..9acb1eb8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1806,10 +1806,6 @@ "resolved": "plugins/postcss-design-tokens", "link": true }, - "node_modules/@csstools/postcss-focus-within": { - "resolved": "plugins/postcss-focus-within", - "link": true - }, "node_modules/@csstools/postcss-font-format-keywords": { "resolved": "plugins/postcss-font-format-keywords", "link": true @@ -5381,18 +5377,8 @@ "link": true }, "node_modules/postcss-focus-within": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", - "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } + "resolved": "plugins/postcss-focus-within", + "link": true }, "node_modules/postcss-font-variant": { "version": "5.0.0", @@ -7121,9 +7107,11 @@ } }, "plugins/postcss-focus-within": { - "name": "@csstools/postcss-focus-within", - "version": "1.0.0", + "version": "5.0.4", "license": "CC0-1.0", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, "engines": { "node": "^12 || ^14 || >=16" }, @@ -8732,10 +8720,6 @@ "style-dictionary-design-tokens-example": "^1.0.0" } }, - "@csstools/postcss-focus-within": { - "version": "file:plugins/postcss-focus-within", - "requires": {} - }, "@csstools/postcss-font-format-keywords": { "version": "file:plugins/postcss-font-format-keywords", "requires": { @@ -11407,11 +11391,9 @@ } }, "postcss-focus-within": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", - "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", + "version": "file:plugins/postcss-focus-within", "requires": { - "postcss-selector-parser": "^6.0.9" + "postcss-selector-parser": "^6.0.10" } }, "postcss-font-variant": { 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/postcss-focus-within/package.json b/plugins/postcss-focus-within/package.json index ef0cc4e34..64224f596 100644 --- a/plugins/postcss-focus-within/package.json +++ b/plugins/postcss-focus-within/package.json @@ -63,17 +63,18 @@ "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", - "stryker": "stryker run --logLevel error", "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" }, + "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-within#readme", "repository": { "type": "git", "url": "https://github.com/csstools/postcss-plugins.git", "directory": "plugins/postcss-focus-within" }, + "bugs": "https://github.com/csstools/postcss-plugins/issues", "keywords": [ "a11y", "accessibility", @@ -96,7 +97,5 @@ }, "volta": { "extends": "../../package.json" - }, - "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-within#readme", - "bugs": "https://github.com/csstools/postcss-plugins/issues" + } } From 9196298835022d299f39173ec907ac2b654b3649 Mon Sep 17 00:00:00 2001 From: Antonio Laguna Date: Sat, 2 Jul 2022 22:27:25 +0200 Subject: [PATCH 4/8] Fixed tests after swapping preserve --- .../test/basic.expect.css | 73 +++++++++++++++++++ .../test/basic.replacewith.expect.css | 73 +++++++++++++++++++ .../test/browser.expect.css | 4 + .../test/examples/example.expect.css | 3 + .../examples/example.replacewith.expect.css | 3 + 5 files changed, 156 insertions(+) diff --git a/plugins/postcss-focus-visible/test/basic.expect.css b/plugins/postcss-focus-visible/test/basic.expect.css index e3d0a30b3..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,46 +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.replacewith.expect.css b/plugins/postcss-focus-visible/test/basic.replacewith.expect.css index 8923428ad..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,46 +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.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; +} From 4f13a1e567ae70c83f39c99000fe8e858b8d4874 Mon Sep 17 00:00:00 2001 From: Antonio Laguna Date: Sat, 2 Jul 2022 22:30:48 +0200 Subject: [PATCH 5/8] Adding CHANGELOG --- plugins/postcss-focus-within/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) 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 From 00ea745bc2ae1f264919bb2db5e557e8828d3727 Mon Sep 17 00:00:00 2001 From: Antonio Laguna Date: Sat, 2 Jul 2022 22:46:24 +0200 Subject: [PATCH 6/8] Updating tests --- plugins/postcss-focus-within/.tape.mjs | 3 + .../test/basic.expect.css | 32 + .../test/basic.replacewith.expect.css | 32 + .../test/browser.expect.css | 8 + .../test/browser.replacewith.expect.css | 8 + .../test/examples/example.expect.css | 3 + .../examples/example.replacewith.expect.css | 3 + .../test/generated-selector-cases.expect.css | 886 +++++++++++++++++- 8 files changed, 974 insertions(+), 1 deletion(-) diff --git a/plugins/postcss-focus-within/.tape.mjs b/plugins/postcss-focus-within/.tape.mjs index 3f9f2e1de..91561fece 100644 --- a/plugins/postcss-focus-within/.tape.mjs +++ b/plugins/postcss-focus-within/.tape.mjs @@ -26,6 +26,9 @@ postcssTape(plugin)({ }, 'examples/example:preserve-false': { message: 'minimal example', + options: { + preserve: false, + }, }, 'examples/example:replacewith': { message: 'minimal example', diff --git a/plugins/postcss-focus-within/test/basic.expect.css b/plugins/postcss-focus-within/test/basic.expect.css index 034a0d288..e85b1630c 100644 --- a/plugins/postcss-focus-within/test/basic.expect.css +++ b/plugins/postcss-focus-within/test/basic.expect.css @@ -2,6 +2,10 @@ order: 1; } +:focus-within { + order: 1; +} + [focus-within].js-focus-within, .js-focus-within [focus-within], [focus-within].js-focus-within test, @@ -33,6 +37,23 @@ test.js-focus-within :matches(test [focus-within] [focus-within] test) test, order: 2; } +: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 { + order: 2; +} + :ignore-focus-within, :focus-within-ignore, :ignorefocus-within, @@ -53,6 +74,17 @@ test.js-focus-within :matches(test [focus-within] [focus-within] test) test, order: 5; } +.escaped\:focus-within, +.escaped\:times\:two\:focus-within, +.escaped\:focus-within:focus-within, +.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.replacewith.expect.css b/plugins/postcss-focus-within/test/basic.replacewith.expect.css index 9d430a232..5a7666a11 100644 --- a/plugins/postcss-focus-within/test/basic.replacewith.expect.css +++ b/plugins/postcss-focus-within/test/basic.replacewith.expect.css @@ -2,6 +2,10 @@ order: 1; } +:focus-within { + order: 1; +} + .focus-within.js-focus-within, .js-focus-within .focus-within, .focus-within.js-focus-within test, @@ -33,6 +37,23 @@ test.js-focus-within :matches(test .focus-within .focus-within test) test, order: 2; } +: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 { + order: 2; +} + :ignore-focus-within, :focus-within-ignore, :ignorefocus-within, @@ -53,6 +74,17 @@ test.js-focus-within :matches(test .focus-within .focus-within test) test, order: 5; } +.escaped\:focus-within, +.escaped\:times\:two\:focus-within, +.escaped\:focus-within:focus-within, +.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.expect.css b/plugins/postcss-focus-within/test/browser.expect.css index 16174b186..0d9156ca7 100644 --- a/plugins/postcss-focus-within/test/browser.expect.css +++ b/plugins/postcss-focus-within/test/browser.expect.css @@ -6,6 +6,14 @@ 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 index 4b3410061..5e2ad9944 100644 --- a/plugins/postcss-focus-within/test/browser.replacewith.expect.css +++ b/plugins/postcss-focus-within/test/browser.replacewith.expect.css @@ -6,6 +6,14 @@ 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.expect.css b/plugins/postcss-focus-within/test/examples/example.expect.css index 1188030bd..fe6084d56 100644 --- a/plugins/postcss-focus-within/test/examples/example.expect.css +++ b/plugins/postcss-focus-within/test/examples/example.expect.css @@ -1,3 +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.replacewith.expect.css b/plugins/postcss-focus-within/test/examples/example.replacewith.expect.css index 5908cfe31..cab94c735 100644 --- a/plugins/postcss-focus-within/test/examples/example.replacewith.expect.css +++ b/plugins/postcss-focus-within/test/examples/example.replacewith.expect.css @@ -1,3 +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 0b1c1eae0..b3fb1623e 100644 --- a/plugins/postcss-focus-within/test/generated-selector-cases.expect.css +++ b/plugins/postcss-focus-within/test/generated-selector-cases.expect.css @@ -2,86 +2,170 @@ order: 0; } +: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 { + order: 1; +} + [focus-within].js-focus-within [focus-within], .js-focus-within [focus-within] [focus-within] { order: 2; } +: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].js-focus-within [focus-within], .js-focus-within [focus-within] [focus-within] { order: 4; } +:focus-within :focus-within { + order: 4; +} + [focus-within].js-focus-within [focus-within], .js-focus-within [focus-within] [focus-within] { order: 5; } +: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 { + 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].js-focus-within + [focus-within], .js-focus-within [focus-within] + [focus-within] { order: 8; } +:focus-within + :focus-within { + order: 8; +} + [focus-within].js-focus-within + [focus-within], .js-focus-within [focus-within] + [focus-within] { order: 9; } +:focus-within + :focus-within { + order: 9; +} + [focus-within].js-focus-within~[focus-within], .js-focus-within [focus-within]~[focus-within] { order: 10; } +:focus-within~:focus-within { + order: 10; +} + [focus-within].js-focus-within~[focus-within], .js-focus-within [focus-within]~[focus-within] { order: 11; } +: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].js-focus-within ~ [focus-within], .js-focus-within [focus-within] ~ [focus-within] { order: 13; } +: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 { + order: 14; +} + [focus-within].js-focus-within>[focus-within], .js-focus-within [focus-within]>[focus-within] { order: 15; } +: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].js-focus-within > [focus-within], .js-focus-within [focus-within] > [focus-within] { order: 17; } +: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 { + order: 18; +} + [focus-within].js-focus-within, .js-focus-within [focus-within], [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 19; } +: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; +} + :focus-withinbutton { order: 21; } @@ -90,318 +174,634 @@ button.js-focus-within [focus-within], .js-focus-within button [focus-within] { order: 22; } +button :focus-within { + order: 22; +} + [focus-within].js-focus-within button, .js-focus-within [focus-within] button { order: 23; } +:focus-within button { + order: 23; +} + button.js-focus-within [focus-within], .js-focus-within button [focus-within] { order: 24; } +button :focus-within { + order: 24; +} + [focus-within].js-focus-within button, .js-focus-within [focus-within] button { order: 25; } +: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].js-focus-within+button, .js-focus-within [focus-within]+button { order: 27; } +:focus-within+button { + order: 27; +} + button.js-focus-within + [focus-within], .js-focus-within button + [focus-within] { order: 28; } +button + :focus-within { + order: 28; +} + [focus-within].js-focus-within + button, .js-focus-within [focus-within] + button { order: 29; } +: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].js-focus-within~button, .js-focus-within [focus-within]~button { order: 31; } +: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].js-focus-within ~ button, .js-focus-within [focus-within] ~ button { order: 33; } +:focus-within ~ button { + order: 33; +} + button.js-focus-within>[focus-within], .js-focus-within button>[focus-within] { order: 34; } +button>:focus-within { + order: 34; +} + [focus-within].js-focus-within>button, .js-focus-within [focus-within]>button { order: 35; } +:focus-within>button { + order: 35; +} + button.js-focus-within > [focus-within], .js-focus-within button > [focus-within] { order: 36; } +button > :focus-within { + order: 36; +} + [focus-within].js-focus-within > button, .js-focus-within [focus-within] > button { order: 37; } +: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].js-focus-within, .js-focus-within [focus-within], button { order: 39; } +:focus-within, button { + order: 39; +} + .🧑🏾‍🎤[focus-within].js-focus-within, .js-focus-within .🧑🏾‍🎤[focus-within] { order: 40; } +.🧑🏾‍🎤:focus-within { + order: 40; +} + [focus-within].🧑🏾‍🎤.js-focus-within, .js-focus-within [focus-within].🧑🏾‍🎤 { order: 41; } +:focus-within.🧑🏾‍🎤 { + order: 41; +} + .🧑🏾‍🎤.js-focus-within [focus-within], .js-focus-within .🧑🏾‍🎤 [focus-within] { order: 42; } +.🧑🏾‍🎤 :focus-within { + order: 42; +} + [focus-within].js-focus-within .🧑🏾‍🎤, .js-focus-within [focus-within] .🧑🏾‍🎤 { order: 43; } +:focus-within .🧑🏾‍🎤 { + order: 43; +} + .🧑🏾‍🎤.js-focus-within [focus-within], .js-focus-within .🧑🏾‍🎤 [focus-within] { order: 44; } +.🧑🏾‍🎤 :focus-within { + order: 44; +} + [focus-within].js-focus-within .🧑🏾‍🎤, .js-focus-within [focus-within] .🧑🏾‍🎤 { order: 45; } +:focus-within .🧑🏾‍🎤 { + order: 45; +} + .🧑🏾‍🎤.js-focus-within+[focus-within], .js-focus-within .🧑🏾‍🎤+[focus-within] { order: 46; } +.🧑🏾‍🎤+:focus-within { + order: 46; +} + [focus-within].js-focus-within+.🧑🏾‍🎤, .js-focus-within [focus-within]+.🧑🏾‍🎤 { order: 47; } +:focus-within+.🧑🏾‍🎤 { + order: 47; +} + .🧑🏾‍🎤.js-focus-within + [focus-within], .js-focus-within .🧑🏾‍🎤 + [focus-within] { order: 48; } +.🧑🏾‍🎤 + :focus-within { + order: 48; +} + [focus-within].js-focus-within + .🧑🏾‍🎤, .js-focus-within [focus-within] + .🧑🏾‍🎤 { order: 49; } +:focus-within + .🧑🏾‍🎤 { + order: 49; +} + .🧑🏾‍🎤.js-focus-within~[focus-within], .js-focus-within .🧑🏾‍🎤~[focus-within] { order: 50; } +.🧑🏾‍🎤~:focus-within { + order: 50; +} + [focus-within].js-focus-within~.🧑🏾‍🎤, .js-focus-within [focus-within]~.🧑🏾‍🎤 { order: 51; } +:focus-within~.🧑🏾‍🎤 { + order: 51; +} + .🧑🏾‍🎤.js-focus-within ~ [focus-within], .js-focus-within .🧑🏾‍🎤 ~ [focus-within] { order: 52; } +.🧑🏾‍🎤 ~ :focus-within { + order: 52; +} + [focus-within].js-focus-within ~ .🧑🏾‍🎤, .js-focus-within [focus-within] ~ .🧑🏾‍🎤 { order: 53; } +:focus-within ~ .🧑🏾‍🎤 { + order: 53; +} + .🧑🏾‍🎤.js-focus-within>[focus-within], .js-focus-within .🧑🏾‍🎤>[focus-within] { order: 54; } +.🧑🏾‍🎤>:focus-within { + order: 54; +} + [focus-within].js-focus-within>.🧑🏾‍🎤, .js-focus-within [focus-within]>.🧑🏾‍🎤 { order: 55; } +:focus-within>.🧑🏾‍🎤 { + order: 55; +} + .🧑🏾‍🎤.js-focus-within > [focus-within], .js-focus-within .🧑🏾‍🎤 > [focus-within] { order: 56; } +.🧑🏾‍🎤 > :focus-within { + order: 56; +} + [focus-within].js-focus-within > .🧑🏾‍🎤, .js-focus-within [focus-within] > .🧑🏾‍🎤 { order: 57; } +:focus-within > .🧑🏾‍🎤 { + order: 57; +} + .🧑🏾‍🎤, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 58; } +.🧑🏾‍🎤, :focus-within { + order: 58; +} + [focus-within].js-focus-within, .js-focus-within [focus-within], .🧑🏾‍🎤 { order: 59; } +: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.js-focus-within, .js-focus-within [focus-within].foo { order: 61; } +:focus-within.foo { + order: 61; +} + .foo.js-focus-within [focus-within], .js-focus-within .foo [focus-within] { order: 62; } +.foo :focus-within { + order: 62; +} + [focus-within].js-focus-within .foo, .js-focus-within [focus-within] .foo { order: 63; } +: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].js-focus-within .foo, .js-focus-within [focus-within] .foo { order: 65; } +: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].js-focus-within+.foo, .js-focus-within [focus-within]+.foo { order: 67; } +:focus-within+.foo { + order: 67; +} + .foo.js-focus-within + [focus-within], .js-focus-within .foo + [focus-within] { order: 68; } +.foo + :focus-within { + order: 68; +} + [focus-within].js-focus-within + .foo, .js-focus-within [focus-within] + .foo { order: 69; } +: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].js-focus-within~.foo, .js-focus-within [focus-within]~.foo { order: 71; } +:focus-within~.foo { + order: 71; +} + .foo.js-focus-within ~ [focus-within], .js-focus-within .foo ~ [focus-within] { order: 72; } +.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.js-focus-within>[focus-within], .js-focus-within .foo>[focus-within] { order: 74; } +.foo>:focus-within { + order: 74; +} + [focus-within].js-focus-within>.foo, .js-focus-within [focus-within]>.foo { order: 75; } +:focus-within>.foo { + order: 75; +} + .foo.js-focus-within > [focus-within], .js-focus-within .foo > [focus-within] { order: 76; } +.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].js-focus-within, .js-focus-within [focus-within] { order: 78; } +.foo, :focus-within { + order: 78; +} + [focus-within].js-focus-within, .js-focus-within [focus-within], .foo { order: 79; } +:focus-within, .foo { + order: 79; +} + #foo[focus-within].js-focus-within, .js-focus-within #foo[focus-within] { order: 80; } +#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.js-focus-within [focus-within], .js-focus-within #foo [focus-within] { order: 82; } +#foo :focus-within { + order: 82; +} + [focus-within].js-focus-within #foo, .js-focus-within [focus-within] #foo { order: 83; } +:focus-within #foo { + order: 83; +} + #foo.js-focus-within [focus-within], .js-focus-within #foo [focus-within] { order: 84; } +#foo :focus-within { + order: 84; +} + [focus-within].js-focus-within #foo, .js-focus-within [focus-within] #foo { order: 85; } +: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].js-focus-within+#foo, .js-focus-within [focus-within]+#foo { order: 87; } +:focus-within+#foo { + order: 87; +} + #foo.js-focus-within + [focus-within], .js-focus-within #foo + [focus-within] { order: 88; } +#foo + :focus-within { + order: 88; +} + [focus-within].js-focus-within + #foo, .js-focus-within [focus-within] + #foo { order: 89; } +: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].js-focus-within~#foo, .js-focus-within [focus-within]~#foo { order: 91; } +:focus-within~#foo { + order: 91; +} + #foo.js-focus-within ~ [focus-within], .js-focus-within #foo ~ [focus-within] { order: 92; } +#foo ~ :focus-within { + order: 92; +} + [focus-within].js-focus-within ~ #foo, .js-focus-within [focus-within] ~ #foo { order: 93; } +: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].js-focus-within>#foo, .js-focus-within [focus-within]>#foo { order: 95; } +: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].js-focus-within > #foo, .js-focus-within [focus-within] > #foo { order: 97; } +:focus-within > #foo { + order: 97; +} + #foo, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 98; } +#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].js-focus-within, .js-focus-within __foo[focus-within] { order: 100; } +__foo:focus-within { + order: 100; +} + :focus-within__foo { order: 101; } @@ -410,143 +810,287 @@ __foo.js-focus-within [focus-within], .js-focus-within __foo [focus-within] { order: 102; } +__foo :focus-within { + order: 102; +} + [focus-within].js-focus-within __foo, .js-focus-within [focus-within] __foo { order: 103; } +: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].js-focus-within __foo, .js-focus-within [focus-within] __foo { order: 105; } +:focus-within __foo { + order: 105; +} + __foo.js-focus-within+[focus-within], .js-focus-within __foo+[focus-within] { order: 106; } +__foo+:focus-within { + order: 106; +} + [focus-within].js-focus-within+__foo, .js-focus-within [focus-within]+__foo { order: 107; } +: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].js-focus-within + __foo, .js-focus-within [focus-within] + __foo { order: 109; } +:focus-within + __foo { + order: 109; +} + __foo.js-focus-within~[focus-within], .js-focus-within __foo~[focus-within] { order: 110; } +__foo~:focus-within { + order: 110; +} + [focus-within].js-focus-within~__foo, .js-focus-within [focus-within]~__foo { order: 111; } +: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].js-focus-within ~ __foo, .js-focus-within [focus-within] ~ __foo { order: 113; } +: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].js-focus-within>__foo, .js-focus-within [focus-within]>__foo { order: 115; } +:focus-within>__foo { + order: 115; +} + __foo.js-focus-within > [focus-within], .js-focus-within __foo > [focus-within] { order: 116; } +__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].js-focus-within, .js-focus-within [focus-within] { order: 118; } +__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].js-focus-within, .js-focus-within :--foo[focus-within] { order: 120; } +:--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.js-focus-within [focus-within], .js-focus-within :--foo [focus-within] { order: 122; } +:--foo :focus-within { + order: 122; +} + [focus-within].js-focus-within :--foo, .js-focus-within [focus-within] :--foo { order: 123; } +:focus-within :--foo { + order: 123; +} + :--foo.js-focus-within [focus-within], .js-focus-within :--foo [focus-within] { order: 124; } +:--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.js-focus-within+[focus-within], .js-focus-within :--foo+[focus-within] { order: 126; } +:--foo+:focus-within { + order: 126; +} + [focus-within].js-focus-within+:--foo, .js-focus-within [focus-within]+:--foo { order: 127; } +:focus-within+:--foo { + order: 127; +} + :--foo.js-focus-within + [focus-within], .js-focus-within :--foo + [focus-within] { order: 128; } +:--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.js-focus-within~[focus-within], .js-focus-within :--foo~[focus-within] { order: 130; } +:--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.js-focus-within ~ [focus-within], .js-focus-within :--foo ~ [focus-within] { order: 132; } +:--foo ~ :focus-within { + order: 132; +} + [focus-within].js-focus-within ~ :--foo, .js-focus-within [focus-within] ~ :--foo { order: 133; } +: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].js-focus-within>:--foo, .js-focus-within [focus-within]>:--foo { order: 135; } +:focus-within>:--foo { + order: 135; +} + :--foo.js-focus-within > [focus-within], .js-focus-within :--foo > [focus-within] { order: 136; } -[focus-within].js-focus-within > :--foo, .js-focus-within [focus-within] > :--foo { +:--foo > :focus-within { + order: 136; +} + +[focus-within].js-focus-within > :--foo, .js-focus-within [focus-within] > :--foo { + order: 137; +} + +:focus-within > :--foo { order: 137; } @@ -554,330 +1098,658 @@ __foo, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 138; } +:--foo, :focus-within { + order: 138; +} + [focus-within].js-focus-within, .js-focus-within [focus-within], :--foo { order: 139; } +: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"].js-focus-within, .js-focus-within [focus-within][foo="baz"] { order: 141; } +:focus-within[foo="baz"] { + order: 141; +} + [foo="baz"].js-focus-within [focus-within], .js-focus-within [foo="baz"] [focus-within] { order: 142; } +[foo="baz"] :focus-within { + order: 142; +} + [focus-within].js-focus-within [foo="baz"], .js-focus-within [focus-within] [foo="baz"] { order: 143; } +: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].js-focus-within [foo="baz"], .js-focus-within [focus-within] [foo="baz"] { order: 145; } +:focus-within [foo="baz"] { + order: 145; +} + [foo="baz"].js-focus-within+[focus-within], .js-focus-within [foo="baz"]+[focus-within] { order: 146; } +[foo="baz"]+:focus-within { + order: 146; +} + [focus-within].js-focus-within+[foo="baz"], .js-focus-within [focus-within]+[foo="baz"] { order: 147; } +: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].js-focus-within + [foo="baz"], .js-focus-within [focus-within] + [foo="baz"] { order: 149; } +:focus-within + [foo="baz"] { + order: 149; +} + [foo="baz"].js-focus-within~[focus-within], .js-focus-within [foo="baz"]~[focus-within] { order: 150; } +[foo="baz"]~:focus-within { + order: 150; +} + [focus-within].js-focus-within~[foo="baz"], .js-focus-within [focus-within]~[foo="baz"] { order: 151; } +: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].js-focus-within ~ [foo="baz"], .js-focus-within [focus-within] ~ [foo="baz"] { order: 153; } +:focus-within ~ [foo="baz"] { + order: 153; +} + [foo="baz"].js-focus-within>[focus-within], .js-focus-within [foo="baz"]>[focus-within] { order: 154; } +[foo="baz"]>:focus-within { + order: 154; +} + [focus-within].js-focus-within>[foo="baz"], .js-focus-within [focus-within]>[foo="baz"] { order: 155; } +: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].js-focus-within > [foo="baz"], .js-focus-within [focus-within] > [foo="baz"] { order: 157; } +:focus-within > [foo="baz"] { + order: 157; +} + [foo="baz"], [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 158; } +[foo="baz"], :focus-within { + order: 158; +} + [focus-within].js-focus-within, .js-focus-within [focus-within], [foo="baz"] { order: 159; } +:focus-within, [foo="baz"] { + order: 159; +} + *[focus-within].js-focus-within, .js-focus-within *[focus-within] { order: 160; } +*:focus-within { + order: 160; +} + [focus-within]*.js-focus-within, .js-focus-within [focus-within]* { order: 161; } +:focus-within* { + order: 161; +} + *.js-focus-within [focus-within], .js-focus-within * [focus-within] { order: 162; } +* :focus-within { + order: 162; +} + [focus-within].js-focus-within *, .js-focus-within [focus-within] * { order: 163; } +:focus-within * { + order: 163; +} + *.js-focus-within [focus-within], .js-focus-within * [focus-within] { order: 164; } +* :focus-within { + order: 164; +} + [focus-within].js-focus-within *, .js-focus-within [focus-within] * { order: 165; } +:focus-within * { + order: 165; +} + *.js-focus-within+[focus-within], .js-focus-within *+[focus-within] { order: 166; } +*+:focus-within { + order: 166; +} + [focus-within].js-focus-within+*, .js-focus-within [focus-within]+* { order: 167; } +:focus-within+* { + order: 167; +} + *.js-focus-within + [focus-within], .js-focus-within * + [focus-within] { order: 168; } +* + :focus-within { + order: 168; +} + [focus-within].js-focus-within + *, .js-focus-within [focus-within] + * { order: 169; } +:focus-within + * { + order: 169; +} + *.js-focus-within~[focus-within], .js-focus-within *~[focus-within] { order: 170; } +*~:focus-within { + order: 170; +} + [focus-within].js-focus-within~*, .js-focus-within [focus-within]~* { order: 171; } +:focus-within~* { + order: 171; +} + *.js-focus-within ~ [focus-within], .js-focus-within * ~ [focus-within] { order: 172; } +* ~ :focus-within { + order: 172; +} + [focus-within].js-focus-within ~ *, .js-focus-within [focus-within] ~ * { order: 173; } +:focus-within ~ * { + order: 173; +} + *.js-focus-within>[focus-within], .js-focus-within *>[focus-within] { order: 174; } +*>:focus-within { + order: 174; +} + [focus-within].js-focus-within>*, .js-focus-within [focus-within]>* { order: 175; } +:focus-within>* { + order: 175; +} + *.js-focus-within > [focus-within], .js-focus-within * > [focus-within] { order: 176; } +* > :focus-within { + order: 176; +} + [focus-within].js-focus-within > *, .js-focus-within [focus-within] > * { order: 177; } +:focus-within > * { + order: 177; +} + *, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 178; } +*, :focus-within { + order: 178; +} + [focus-within].js-focus-within, .js-focus-within [focus-within], * { order: 179; } +: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.js-focus-within, .js-focus-within [focus-within]:hover { order: 181; } +:focus-within:hover { + order: 181; +} + :hover.js-focus-within [focus-within], .js-focus-within :hover [focus-within] { order: 182; } +:hover :focus-within { + order: 182; +} + [focus-within].js-focus-within :hover, .js-focus-within [focus-within] :hover { order: 183; } +: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].js-focus-within :hover, .js-focus-within [focus-within] :hover { order: 185; } +:focus-within :hover { + order: 185; +} + :hover.js-focus-within+[focus-within], .js-focus-within :hover+[focus-within] { order: 186; } +:hover+:focus-within { + order: 186; +} + [focus-within].js-focus-within+:hover, .js-focus-within [focus-within]+:hover { order: 187; } +: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].js-focus-within + :hover, .js-focus-within [focus-within] + :hover { order: 189; } +:focus-within + :hover { + order: 189; +} + :hover.js-focus-within~[focus-within], .js-focus-within :hover~[focus-within] { order: 190; } +:hover~:focus-within { + order: 190; +} + [focus-within].js-focus-within~:hover, .js-focus-within [focus-within]~:hover { order: 191; } +: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].js-focus-within ~ :hover, .js-focus-within [focus-within] ~ :hover { order: 193; } +:focus-within ~ :hover { + order: 193; +} + :hover.js-focus-within>[focus-within], .js-focus-within :hover>[focus-within] { order: 194; } +:hover>:focus-within { + order: 194; +} + [focus-within].js-focus-within>:hover, .js-focus-within [focus-within]>:hover { order: 195; } +: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].js-focus-within > :hover, .js-focus-within [focus-within] > :hover { order: 197; } +:focus-within > :hover { + order: 197; +} + :hover, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 198; } +:hover, :focus-within { + order: 198; +} + [focus-within].js-focus-within, .js-focus-within [focus-within], :hover { order: 199; } +: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].js-focus-within::before, .js-focus-within [focus-within]::before { order: 201; } +:focus-within::before { + order: 201; +} + .js-focus-within::before [focus-within], .js-focus-within ::before [focus-within] { order: 202; } +::before :focus-within { + order: 202; +} + [focus-within].js-focus-within ::before, .js-focus-within [focus-within] ::before { order: 203; } +: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].js-focus-within ::before, .js-focus-within [focus-within] ::before { order: 205; } +:focus-within ::before { + order: 205; +} + .js-focus-within::before+[focus-within], .js-focus-within ::before+[focus-within] { order: 206; } +::before+:focus-within { + order: 206; +} + [focus-within].js-focus-within+::before, .js-focus-within [focus-within]+::before { order: 207; } +: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].js-focus-within + ::before, .js-focus-within [focus-within] + ::before { order: 209; } +:focus-within + ::before { + order: 209; +} + .js-focus-within::before~[focus-within], .js-focus-within ::before~[focus-within] { order: 210; } +::before~:focus-within { + order: 210; +} + [focus-within].js-focus-within~::before, .js-focus-within [focus-within]~::before { order: 211; } +: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].js-focus-within ~ ::before, .js-focus-within [focus-within] ~ ::before { order: 213; } +:focus-within ~ ::before { + order: 213; +} + .js-focus-within::before>[focus-within], .js-focus-within ::before>[focus-within] { order: 214; } +::before>:focus-within { + order: 214; +} + [focus-within].js-focus-within>::before, .js-focus-within [focus-within]>::before { order: 215; } +: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].js-focus-within > ::before, .js-focus-within [focus-within] > ::before { order: 217; } +:focus-within > ::before { + order: 217; +} + ::before, [focus-within].js-focus-within, .js-focus-within [focus-within] { order: 218; } +::before, :focus-within { + order: 218; +} + [focus-within].js-focus-within, .js-focus-within [focus-within], ::before { order: 219; } +:focus-within, ::before { + order: 219; +} + foo[:focus-within] { order: 220; } @@ -890,6 +1762,10 @@ foo[baz=":focus-within"] { order: 222; } +:not(:focus-within) { + order: 222; +} + ::focus-within { order: 223; } @@ -898,8 +1774,16 @@ foo[baz=":focus-within"] { order: 224; } +:--:focus-within { + order: 224; +} + __[focus-within].js-focus-within, .js-focus-within __[focus-within] { order: 225; } +__:focus-within { + order: 225; +} + /* :focus-within */ From dda9f901f4b585166bdd4a0799d7e9ebe4695541 Mon Sep 17 00:00:00 2001 From: Antonio Laguna Date: Sun, 3 Jul 2022 11:46:42 +0200 Subject: [PATCH 7/8] Generating docs --- plugins/postcss-focus-visible/README.md | 3 +++ plugins/postcss-focus-within/README.md | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/plugins/postcss-focus-visible/README.md b/plugins/postcss-focus-visible/README.md index 4a70c1210..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 diff --git a/plugins/postcss-focus-within/README.md b/plugins/postcss-focus-within/README.md index 6d57e8bb1..a38a13ed6 100644 --- a/plugins/postcss-focus-within/README.md +++ b/plugins/postcss-focus-within/README.md @@ -15,6 +15,9 @@ following the [Selectors Level 4 specification]. .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; +} ``` [PostCSS Focus Within] duplicates rules using the `:focus-within` pseudo-class @@ -90,6 +93,9 @@ postcssFocusWithin({ replaceWith: '.focus-within' }); .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; +} ``` Note that changing this option implies that it needs to be passed to the From a0d7a6f263607d155d3ae12799dfec3ed2690d32 Mon Sep 17 00:00:00 2001 From: Antonio Laguna Date: Sun, 3 Jul 2022 11:58:26 +0200 Subject: [PATCH 8/8] Better options for older browsers --- plugins/css-blank-pseudo/src/browser.js | 21 ++++++++++++--------- plugins/postcss-focus-within/src/browser.js | 21 ++++++++++++--------- 2 files changed, 24 insertions(+), 18 deletions(-) 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-within/src/browser.js b/plugins/postcss-focus-within/src/browser.js index 523e74144..6a225a7bd 100644 --- a/plugins/postcss-focus-within/src/browser.js +++ b/plugins/postcss-focus-within/src/browser.js @@ -37,15 +37,18 @@ function generateHandler(replaceWith) { export default function focusWithin(opts) { // configuration - const options = Object.assign( - // Default options - { - force: false, - replaceWith: '[focus-within]', - }, - // Provided options - opts, - ); + 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.`);