postcss-focus-within 5.0.4 → 6.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changes to PostCSS Focus Within
2
2
 
3
+ ### 6.1.1 (August 23, 2022)
4
+
5
+ - Fix: assign global browser polyfill to `window`, `self` or a blank object.
6
+
7
+ ### 6.1.0 (July 30, 2022)
8
+
9
+ - Added: `disablePolyfillReadyClass` plugin option to prevent `.js-focus-within` from being added.
10
+
11
+ ### 6.0.0 (July 8, 2022)
12
+
13
+ - Breaking: Changed generated classes so it prepends `.js-focus-within` to the
14
+ generated class so CSS is applied when the polyfill is known to be running.
15
+ - Added: Now bundling browser polyfill.
16
+
3
17
  ### 5.0.4 (February 5, 2022)
4
18
 
5
19
  - Improved `es module` and `commonjs` compatibility
package/README.md CHANGED
@@ -1,36 +1,28 @@
1
1
  # PostCSS Focus Within [<img src="https://postcss.github.io/postcss/logo.svg" alt="PostCSS Logo" width="90" height="90" align="right">][postcss]
2
2
 
3
- [<img alt="npm version" src="https://img.shields.io/npm/v/postcss-focus-within.svg" height="20">][npm-url]
4
- [<img alt="CSS Standard Status" src="https://cssdb.org/images/badges/focus-within-pseudo-class.svg" height="20">][css-url]
5
- [<img alt="Build Status" src="https://github.com/csstools/postcss-plugins/tree/main/postcss-focus-within/workflows/test/badge.svg" height="20">][cli-url]
6
- [<img alt="Discord" src="https://shields.io/badge/Discord-5865F2?logo=discord&logoColor=white">][discord]
3
+ [<img alt="npm version" src="https://img.shields.io/npm/v/postcss-focus-within.svg" height="20">][npm-url] [<img alt="CSS Standard Status" src="https://cssdb.org/images/badges/focus-within-pseudo-class.svg" height="20">][css-url] [<img alt="Build Status" src="https://github.com/csstools/postcss-plugins/workflows/test/badge.svg" height="20">][cli-url] [<img alt="Discord" src="https://shields.io/badge/Discord-5865F2?logo=discord&logoColor=white">][discord]
7
4
 
8
- [PostCSS Focus Within] lets you use the `:focus-within` pseudo-class in CSS,
5
+ [PostCSS Focus Within] lets you use the `:focus-within` pseudo-class in CSS,
9
6
  following the [Selectors Level 4 specification].
10
7
 
11
- It is the companion to the [focus-within polyfill].
12
-
13
- [!['Can I use' table](https://caniuse.bitsofco.de/image/css-focus-within.png)](https://caniuse.com/#feat=css-focus-within)
14
-
15
- ```css
8
+ ```pcss
16
9
  .my-form-field:focus-within label {
17
- background-color: yellow;
10
+ background-color: yellow;
18
11
  }
19
12
 
20
13
  /* becomes */
21
14
 
22
- .my-form-field[focus-within] label {
23
- background-color: yellow;
15
+ .my-form-field[focus-within].js-focus-within label, .js-focus-within .my-form-field[focus-within] label {
16
+ background-color: yellow;
24
17
  }
25
-
26
18
  .my-form-field:focus-within label {
27
- background-color: yellow;
19
+ background-color: yellow;
28
20
  }
29
21
  ```
30
22
 
31
23
  [PostCSS Focus Within] duplicates rules using the `:focus-within` pseudo-class
32
24
  with a `[focus-within]` attribute selector, the same selector used by the
33
- [focus-within polyfill]. This replacement selector can be changed using the
25
+ focus-within polyfill. This replacement selector can be changed using the
34
26
  `replaceWith` option. Also, the preservation of the original `:focus-within`
35
27
  rule can be disabled using the `preserve` option.
36
28
 
@@ -42,22 +34,14 @@ Add [PostCSS Focus Within] to your project:
42
34
  npm install postcss postcss-focus-within --save-dev
43
35
  ```
44
36
 
45
- Use [PostCSS Focus Within] to process your CSS:
46
-
47
- ```js
48
- const postcssFocusWithin = require('postcss-focus-within');
49
-
50
- postcssFocusWithin.process(YOUR_CSS /*, processOptions, pluginOptions */);
51
- ```
52
-
53
- Or use it as a [PostCSS] plugin:
37
+ Use it as a [PostCSS] plugin:
54
38
 
55
39
  ```js
56
40
  const postcss = require('postcss');
57
41
  const postcssFocusWithin = require('postcss-focus-within');
58
42
 
59
43
  postcss([
60
- postcssFocusWithin(/* pluginOptions */)
44
+ postcssFocusWithin(/* pluginOptions */)
61
45
  ]).process(YOUR_CSS /*, processOptions */);
62
46
  ```
63
47
 
@@ -71,22 +55,22 @@ instructions for:
71
55
 
72
56
  ### preserve
73
57
 
74
- The `preserve` option defines whether the original selector should remain. By
75
- default, the original selector is preserved.
58
+ The `preserve` option determines whether the original notation
59
+ is preserved. By default, it is preserved.
76
60
 
77
61
  ```js
78
- focusWithin({ preserve: false });
62
+ postcssFocusWithin({ preserve: false })
79
63
  ```
80
64
 
81
- ```css
65
+ ```pcss
82
66
  .my-form-field:focus-within label {
83
- background-color: yellow;
67
+ background-color: yellow;
84
68
  }
85
69
 
86
70
  /* becomes */
87
71
 
88
- .my-form-field[focus-within] label {
89
- background-color: yellow;
72
+ .my-form-field[focus-within].js-focus-within label, .js-focus-within .my-form-field[focus-within] label {
73
+ background-color: yellow;
90
74
  }
91
75
  ```
92
76
 
@@ -94,36 +78,109 @@ focusWithin({ preserve: false });
94
78
 
95
79
  The `replaceWith` option defines the selector to replace `:focus-within`. By
96
80
  default, the replacement selector is `[focus-within]`.
81
+ Please note that using a class, leverages `classList` under the hood which
82
+ might not be supported on some old browsers such as IE9, so you may need
83
+ to polyfill `classList` in those cases.
97
84
 
98
85
  ```js
99
- focusWithin({ replaceWith: '.focus-within' });
86
+ postcssFocusWithin({ replaceWith: '.focus-within' });
100
87
  ```
101
88
 
102
- ```css
89
+ ```pcss
103
90
  .my-form-field:focus-within label {
104
- background-color: yellow;
91
+ background-color: yellow;
105
92
  }
106
93
 
107
94
  /* becomes */
108
95
 
109
- .my-form-field.focus-within label {
110
- background-color: yellow;
96
+ .my-form-field.focus-within.js-focus-within label, .js-focus-within .my-form-field.focus-within label {
97
+ background-color: yellow;
111
98
  }
99
+ .my-form-field:focus-within label {
100
+ background-color: yellow;
101
+ }
102
+ ```
103
+
104
+ Note that changing this option implies that it needs to be passed to the
105
+ browser polyfill as well.
106
+
107
+ ### disablePolyfillReadyClass
108
+
109
+ The `disablePolyfillReadyClass` option determines if selectors are prefixed with an indicator class.
110
+ This class is only set on your document if the polyfill loads and is needed.
111
+
112
+ By default this option is `false`.
113
+ Set this to `true` to prevent the class from being added.
114
+
115
+ ```js
116
+ postcssFocusWithin({ disablePolyfillReadyClass: true })
117
+ ```
118
+
119
+ ```pcss
120
+ .my-form-field:focus-within label {
121
+ background-color: yellow;
122
+ }
123
+
124
+ /* becomes */
112
125
 
126
+ .my-form-field[focus-within] label, .my-form-field[focus-within] label {
127
+ background-color: yellow;
128
+ }
113
129
  .my-form-field:focus-within label {
114
- background-color: yellow;
130
+ background-color: yellow;
115
131
  }
116
132
  ```
117
133
 
134
+ ## Browser
135
+
136
+ ```js
137
+ import focusWithinInit from 'postcss-focus-within/browser';
138
+
139
+ focusWithinInit();
140
+ ```
141
+
142
+ or
143
+
144
+ ```html
145
+ <!-- When using a CDN url you will have to manually update the version number -->
146
+ <script src="https://unpkg.com/postcss-focus-within@6.1.1/dist/browser-global.js"></script>
147
+ <script>focusWithinInit()</script>
148
+ ```
149
+
150
+ [PostCSS Focus Within] works in all major browsers, including Safari 6+ and
151
+ Internet Explorer 9+ without any additional polyfills.
152
+
153
+ ### Browser Usage
154
+
155
+ #### force
156
+
157
+ The `force` option determines whether the library runs even if the browser
158
+ supports the selector or not. By default, it won't run if the browser does
159
+ support the selector.
160
+
161
+ ```js
162
+ focusWithinInit({ force: true });
163
+ ```
164
+
165
+ #### replaceWith
166
+
167
+ Similar to the option for the PostCSS Plugin, `replaceWith` determines the
168
+ attribute or class to apply to an element when it's considered to be `:focus-within`.
169
+
170
+ ```js
171
+ focusWithinInit({ replaceWith: '.focus-within });
172
+ ```
173
+
174
+ This option should be used if it was changed at PostCSS configuration level.
175
+
176
+ [cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
118
177
  [css-url]: https://cssdb.org/#focus-within-pseudo-class
119
- [cli-url]: https://github.com/csstools/postcss-plugins/tree/main/postcss-focus-within/actions/workflows/test.yml?query=workflow/test
120
178
  [discord]: https://discord.gg/bUadyRwkJS
121
179
  [npm-url]: https://www.npmjs.com/package/postcss-focus-within
122
180
 
123
- [focus-within polyfill]: https://github.com/jsxtools/focus-within
124
181
  [Gulp PostCSS]: https://github.com/postcss/gulp-postcss
125
182
  [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss
126
183
  [PostCSS]: https://github.com/postcss/postcss
127
- [PostCSS Focus Within]: https://github.com/csstools/postcss-plugins/tree/main/postcss-focus-within
128
184
  [PostCSS Loader]: https://github.com/postcss/postcss-loader
185
+ [PostCSS Focus Within]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-within
129
186
  [Selectors Level 4 specification]: https://www.w3.org/TR/selectors-4/#the-focus-within-pseudo
@@ -0,0 +1,2 @@
1
+ !function(){var e=[" ",">","~",":","+","@","#","(",")"];function t(t){var n={force:!1,replaceWith:"[focus-within]"};if(void 0!==t&&"force"in t&&(n.force=t.force),void 0!==t&&"replaceWith"in t&&(n.replaceWith=t.replaceWith),!function(t){for(var n=!0,c=0,o=e.length;c<o&&n;c++)t.indexOf(e[c])>-1&&(n=!1);return n}(n.replaceWith))throw new Error(n.replaceWith+" is not a valid replacement since it can't be applied to single elements.");try{if(document.querySelector(":focus-within"),!n.force)return}catch(e){}var c,o,i,r,u,a=(c=n.replaceWith,u=[],"."===c[0]?(o=c.slice(1),i=function(e){return e.classList.remove(o)},r=function(e){return e.classList.add(o)}):(o=c.slice(1,-1),i=function(e){return e.removeAttribute(o,"")},r=function(e){return e.setAttribute(o,"")}),function(){u.forEach((function(e){return i(e)})),u.length=0;var e=document.activeElement;if(!/^(#document|HTML|BODY)$/.test(Object(e).nodeName))for(;e&&1===e.nodeType;)r(e),u.push(e),e=e.parentNode}),d=function(){document.documentElement.className.indexOf("js-focus-within")>-1||(document.documentElement.className=document.documentElement.className+" js-focus-within",document.addEventListener("focus",a,!0),document.addEventListener("blur",a,!0))};"complete"===document.readyState?d():document.addEventListener("DOMContentLoaded",d)}("object"==typeof window&&window||"object"==typeof self&&self||{}).focusWithinInit=t}();
2
+ //# sourceMappingURL=browser-global.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-global.js","sources":["../src/is-valid-replacement.mjs","../src/browser.js","../src/browser-global.js"],"sourcesContent":["const INVALID_SELECTOR_CHAR = [\n\t' ', // Can't use child selector\n\t'>', // Can't use direct child selector\n\t'~', // Can't use sibling selector\n\t':', // Can't use pseudo selector\n\t'+', // Can't use adjacent selector\n\t'@', // Can't use at\n\t'#', // Can't use id selector\n\t'(', // Can't use parenthesis\n\t')', // Can't use parenthesis\n];\n\nexport default function isValidReplacement(selector) {\n\tlet isValid = true;\n\n\t// Purposely archaic so it's interoperable in old browsers\n\tfor (let i = 0, length = INVALID_SELECTOR_CHAR.length; i < length && isValid; i++) {\n\t\tif (selector.indexOf(INVALID_SELECTOR_CHAR[i]) > -1) {\n\t\t\tisValid = false;\n\t\t}\n\t}\n\n\treturn isValid;\n}\n","/* global document */\nimport isValidReplacement from './is-valid-replacement.mjs';\nfunction generateHandler(replaceWith) {\n\tlet selector;\n\tlet remove;\n\tlet add;\n\tconst lastElements = [];\n\n\tif (replaceWith[0] === '.') {\n\t\tselector = replaceWith.slice(1);\n\t\tremove = (el) => el.classList.remove(selector);\n\t\tadd = (el) => el.classList.add(selector);\n\t} else {\n\t\t// A bit naive\n\t\tselector = replaceWith.slice(1, -1);\n\t\tremove = (el) => el.removeAttribute(selector, '');\n\t\tadd = (el) => el.setAttribute(selector, '');\n\t}\n\n\treturn function handleFocusChange() {\n\t\tlastElements.forEach(lastElement => remove(lastElement));\n\t\tlastElements.length = 0;\n\n\t\tlet activeElement = document.activeElement;\n\n\t\t// only add focus if it has not been added and is not the document element\n\t\tif (!/^(#document|HTML|BODY)$/.test(Object(activeElement).nodeName)) {\n\t\t\twhile (activeElement && activeElement.nodeType === 1) {\n\t\t\t\tadd(activeElement);\n\t\t\t\tlastElements.push(activeElement);\n\n\t\t\t\tactiveElement = activeElement.parentNode;\n\t\t\t}\n\t\t}\n\t};\n}\n\nexport default function focusWithin(opts) {\n\t// configuration\n\tconst options = {\n\t\tforce: false,\n\t\treplaceWith: '[focus-within]',\n\t};\n\n\tif (typeof opts !== 'undefined' && 'force' in opts) {\n\t\toptions.force = opts.force;\n\t}\n\n\tif (typeof opts !== 'undefined' && 'replaceWith' in opts) {\n\t\toptions.replaceWith = opts.replaceWith;\n\t}\n\n\tif (!isValidReplacement(options.replaceWith)) {\n\t\tthrow new Error(`${options.replaceWith} is not a valid replacement since it can't be applied to single elements.`);\n\t}\n\n\ttry {\n\t\tdocument.querySelector(':focus-within');\n\n\t\tif (!options.force) {\n\t\t\treturn;\n\t\t}\n\t} catch (ignoredError) { /* do nothing and continue */ }\n\n\tconst handleFocusChange = generateHandler(options.replaceWith);\n\n\tconst initialize = function initializeEventListeners() {\n\t\tif (document.documentElement.className.indexOf('js-focus-within') > -1) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocument.documentElement.className = document.documentElement.className + ' js-focus-within';\n\t\tdocument.addEventListener('focus', handleFocusChange, true);\n\t\tdocument.addEventListener('blur', handleFocusChange, true);\n\t};\n\n\tif (document.readyState === 'complete') {\n\t\tinitialize();\n\t} else {\n\t\tdocument.addEventListener('DOMContentLoaded', initialize);\n\t}\n}\n","/* global self,window */\nimport { default as focusWithinInit } from './browser';\n\n(function (global) {\n\tglobal.focusWithinInit = focusWithinInit;\n}('object' === typeof window && window || 'object' === typeof self && self || {}));\n"],"names":["INVALID_SELECTOR_CHAR","focusWithin","opts","options","force","replaceWith","selector","isValid","i","length","indexOf","isValidReplacement","Error","document","querySelector","ignoredError","remove","add","lastElements","handleFocusChange","slice","el","classList","removeAttribute","setAttribute","forEach","lastElement","activeElement","test","Object","nodeName","nodeType","push","parentNode","initialize","documentElement","className","addEventListener","readyState","window","self","focusWithinInit"],"mappings":"YAAA,IAAMA,EAAwB,CAC7B,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,KC4Bc,SAASC,EAAYC,GAEnC,IAAMC,EAAU,CACfC,OAAO,EACPC,YAAa,kBAWd,QARoB,IAATH,GAAwB,UAAWA,IAC7CC,EAAQC,MAAQF,EAAKE,YAGF,IAATF,GAAwB,gBAAiBA,IACnDC,EAAQE,YAAcH,EAAKG,cDrCd,SAA4BC,GAI1C,IAHA,IAAIC,GAAU,EAGLC,EAAI,EAAGC,EAAST,EAAsBS,OAAQD,EAAIC,GAAUF,EAASC,IACzEF,EAASI,QAAQV,EAAsBQ,KAAO,IACjDD,GAAU,GAIZ,OAAOA,CACP,CC6BKI,CAAmBR,EAAQE,aAC/B,MAAM,IAAIO,MAAST,EAAQE,YAA3B,6EAGD,IAGC,GAFAQ,SAASC,cAAc,kBAElBX,EAAQC,MACZ,MAEsD,CAAtD,MAAOW,GAA+C,CAExD,IA9DwBV,EACpBC,EACAU,EACAC,EACEC,EA0DAC,GA9DkBd,EA8DkBF,EAAQE,YA1D5Ca,EAAe,GAEE,MAAnBb,EAAY,IACfC,EAAWD,EAAYe,MAAM,GAC7BJ,EAAS,SAACK,GAAD,OAAQA,EAAGC,UAAUN,OAAOV,IACrCW,EAAM,SAACI,GAAD,OAAQA,EAAGC,UAAUL,IAAIX,MAG/BA,EAAWD,EAAYe,MAAM,GAAI,GACjCJ,EAAS,SAACK,GAAD,OAAQA,EAAGE,gBAAgBjB,EAAU,KAC9CW,EAAM,SAACI,GAAD,OAAQA,EAAGG,aAAalB,EAAU,MAGlC,WACNY,EAAaO,SAAQ,SAAAC,GAAW,OAAIV,EAAOU,MAC3CR,EAAaT,OAAS,EAEtB,IAAIkB,EAAgBd,SAASc,cAG7B,IAAK,0BAA0BC,KAAKC,OAAOF,GAAeG,UACzD,KAAOH,GAA4C,IAA3BA,EAAcI,UACrCd,EAAIU,GACJT,EAAac,KAAKL,GAElBA,EAAgBA,EAAcM,aAmC3BC,EAAa,WACdrB,SAASsB,gBAAgBC,UAAU1B,QAAQ,oBAAsB,IAIrEG,SAASsB,gBAAgBC,UAAYvB,SAASsB,gBAAgBC,UAAY,mBAC1EvB,SAASwB,iBAAiB,QAASlB,GAAmB,GACtDN,SAASwB,iBAAiB,OAAQlB,GAAmB,KAG1B,aAAxBN,SAASyB,WACZJ,IAEArB,SAASwB,iBAAiB,mBAAoBH,EAE/C,EC5EC,iBAAoBK,QAAUA,QAAU,iBAAoBC,MAAQA,MAAQ,IADtEC,gBAAkBA"}
@@ -0,0 +1,2 @@
1
+ var e=[" ",">","~",":","+","@","#","(",")"];module.exports=function(t){var n={force:!1,replaceWith:"[focus-within]"};if(void 0!==t&&"force"in t&&(n.force=t.force),void 0!==t&&"replaceWith"in t&&(n.replaceWith=t.replaceWith),!function(t){for(var n=!0,c=0,r=e.length;c<r&&n;c++)t.indexOf(e[c])>-1&&(n=!1);return n}(n.replaceWith))throw new Error(n.replaceWith+" is not a valid replacement since it can't be applied to single elements.");try{if(document.querySelector(":focus-within"),!n.force)return}catch(e){}var c,r,o,i,u,a=(c=n.replaceWith,u=[],"."===c[0]?(r=c.slice(1),o=function(e){return e.classList.remove(r)},i=function(e){return e.classList.add(r)}):(r=c.slice(1,-1),o=function(e){return e.removeAttribute(r,"")},i=function(e){return e.setAttribute(r,"")}),function(){u.forEach((function(e){return o(e)})),u.length=0;var e=document.activeElement;if(!/^(#document|HTML|BODY)$/.test(Object(e).nodeName))for(;e&&1===e.nodeType;)i(e),u.push(e),e=e.parentNode}),d=function(){document.documentElement.className.indexOf("js-focus-within")>-1||(document.documentElement.className=document.documentElement.className+" js-focus-within",document.addEventListener("focus",a,!0),document.addEventListener("blur",a,!0))};"complete"===document.readyState?d():document.addEventListener("DOMContentLoaded",d)};
2
+ //# sourceMappingURL=browser.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.cjs","sources":["../src/is-valid-replacement.mjs","../src/browser.js"],"sourcesContent":["const INVALID_SELECTOR_CHAR = [\n\t' ', // Can't use child selector\n\t'>', // Can't use direct child selector\n\t'~', // Can't use sibling selector\n\t':', // Can't use pseudo selector\n\t'+', // Can't use adjacent selector\n\t'@', // Can't use at\n\t'#', // Can't use id selector\n\t'(', // Can't use parenthesis\n\t')', // Can't use parenthesis\n];\n\nexport default function isValidReplacement(selector) {\n\tlet isValid = true;\n\n\t// Purposely archaic so it's interoperable in old browsers\n\tfor (let i = 0, length = INVALID_SELECTOR_CHAR.length; i < length && isValid; i++) {\n\t\tif (selector.indexOf(INVALID_SELECTOR_CHAR[i]) > -1) {\n\t\t\tisValid = false;\n\t\t}\n\t}\n\n\treturn isValid;\n}\n","/* global document */\nimport isValidReplacement from './is-valid-replacement.mjs';\nfunction generateHandler(replaceWith) {\n\tlet selector;\n\tlet remove;\n\tlet add;\n\tconst lastElements = [];\n\n\tif (replaceWith[0] === '.') {\n\t\tselector = replaceWith.slice(1);\n\t\tremove = (el) => el.classList.remove(selector);\n\t\tadd = (el) => el.classList.add(selector);\n\t} else {\n\t\t// A bit naive\n\t\tselector = replaceWith.slice(1, -1);\n\t\tremove = (el) => el.removeAttribute(selector, '');\n\t\tadd = (el) => el.setAttribute(selector, '');\n\t}\n\n\treturn function handleFocusChange() {\n\t\tlastElements.forEach(lastElement => remove(lastElement));\n\t\tlastElements.length = 0;\n\n\t\tlet activeElement = document.activeElement;\n\n\t\t// only add focus if it has not been added and is not the document element\n\t\tif (!/^(#document|HTML|BODY)$/.test(Object(activeElement).nodeName)) {\n\t\t\twhile (activeElement && activeElement.nodeType === 1) {\n\t\t\t\tadd(activeElement);\n\t\t\t\tlastElements.push(activeElement);\n\n\t\t\t\tactiveElement = activeElement.parentNode;\n\t\t\t}\n\t\t}\n\t};\n}\n\nexport default function focusWithin(opts) {\n\t// configuration\n\tconst options = {\n\t\tforce: false,\n\t\treplaceWith: '[focus-within]',\n\t};\n\n\tif (typeof opts !== 'undefined' && 'force' in opts) {\n\t\toptions.force = opts.force;\n\t}\n\n\tif (typeof opts !== 'undefined' && 'replaceWith' in opts) {\n\t\toptions.replaceWith = opts.replaceWith;\n\t}\n\n\tif (!isValidReplacement(options.replaceWith)) {\n\t\tthrow new Error(`${options.replaceWith} is not a valid replacement since it can't be applied to single elements.`);\n\t}\n\n\ttry {\n\t\tdocument.querySelector(':focus-within');\n\n\t\tif (!options.force) {\n\t\t\treturn;\n\t\t}\n\t} catch (ignoredError) { /* do nothing and continue */ }\n\n\tconst handleFocusChange = generateHandler(options.replaceWith);\n\n\tconst initialize = function initializeEventListeners() {\n\t\tif (document.documentElement.className.indexOf('js-focus-within') > -1) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocument.documentElement.className = document.documentElement.className + ' js-focus-within';\n\t\tdocument.addEventListener('focus', handleFocusChange, true);\n\t\tdocument.addEventListener('blur', handleFocusChange, true);\n\t};\n\n\tif (document.readyState === 'complete') {\n\t\tinitialize();\n\t} else {\n\t\tdocument.addEventListener('DOMContentLoaded', initialize);\n\t}\n}\n"],"names":["INVALID_SELECTOR_CHAR","opts","options","force","replaceWith","selector","isValid","i","length","indexOf","isValidReplacement","Error","document","querySelector","ignoredError","remove","add","lastElements","handleFocusChange","slice","el","classList","removeAttribute","setAttribute","forEach","lastElement","activeElement","test","Object","nodeName","nodeType","push","parentNode","initialize","documentElement","className","addEventListener","readyState"],"mappings":"AAAA,IAAMA,EAAwB,CAC7B,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,oBC4Bc,SAAqBC,GAEnC,IAAMC,EAAU,CACfC,OAAO,EACPC,YAAa,kBAWd,QARoB,IAATH,GAAwB,UAAWA,IAC7CC,EAAQC,MAAQF,EAAKE,YAGF,IAATF,GAAwB,gBAAiBA,IACnDC,EAAQE,YAAcH,EAAKG,cDrCd,SAA4BC,GAI1C,IAHA,IAAIC,GAAU,EAGLC,EAAI,EAAGC,EAASR,EAAsBQ,OAAQD,EAAIC,GAAUF,EAASC,IACzEF,EAASI,QAAQT,EAAsBO,KAAO,IACjDD,GAAU,GAIZ,OAAOA,CACP,CC6BKI,CAAmBR,EAAQE,aAC/B,MAAM,IAAIO,MAAST,EAAQE,YAA3B,6EAGD,IAGC,GAFAQ,SAASC,cAAc,kBAElBX,EAAQC,MACZ,MAEsD,CAAtD,MAAOW,GAA+C,CAExD,IA9DwBV,EACpBC,EACAU,EACAC,EACEC,EA0DAC,GA9DkBd,EA8DkBF,EAAQE,YA1D5Ca,EAAe,GAEE,MAAnBb,EAAY,IACfC,EAAWD,EAAYe,MAAM,GAC7BJ,EAAS,SAACK,GAAD,OAAQA,EAAGC,UAAUN,OAAOV,IACrCW,EAAM,SAACI,GAAD,OAAQA,EAAGC,UAAUL,IAAIX,MAG/BA,EAAWD,EAAYe,MAAM,GAAI,GACjCJ,EAAS,SAACK,GAAD,OAAQA,EAAGE,gBAAgBjB,EAAU,KAC9CW,EAAM,SAACI,GAAD,OAAQA,EAAGG,aAAalB,EAAU,MAGlC,WACNY,EAAaO,SAAQ,SAAAC,GAAW,OAAIV,EAAOU,MAC3CR,EAAaT,OAAS,EAEtB,IAAIkB,EAAgBd,SAASc,cAG7B,IAAK,0BAA0BC,KAAKC,OAAOF,GAAeG,UACzD,KAAOH,GAA4C,IAA3BA,EAAcI,UACrCd,EAAIU,GACJT,EAAac,KAAKL,GAElBA,EAAgBA,EAAcM,aAmC3BC,EAAa,WACdrB,SAASsB,gBAAgBC,UAAU1B,QAAQ,oBAAsB,IAIrEG,SAASsB,gBAAgBC,UAAYvB,SAASsB,gBAAgBC,UAAY,mBAC1EvB,SAASwB,iBAAiB,QAASlB,GAAmB,GACtDN,SAASwB,iBAAiB,OAAQlB,GAAmB,KAG1B,aAAxBN,SAASyB,WACZJ,IAEArB,SAASwB,iBAAiB,mBAAoBH,EAE/C"}
@@ -0,0 +1,2 @@
1
+ var e=[" ",">","~",":","+","@","#","(",")"];function t(t){var n={force:!1,replaceWith:"[focus-within]"};if(void 0!==t&&"force"in t&&(n.force=t.force),void 0!==t&&"replaceWith"in t&&(n.replaceWith=t.replaceWith),!function(t){for(var n=!0,c=0,r=e.length;c<r&&n;c++)t.indexOf(e[c])>-1&&(n=!1);return n}(n.replaceWith))throw new Error(n.replaceWith+" is not a valid replacement since it can't be applied to single elements.");try{if(document.querySelector(":focus-within"),!n.force)return}catch(e){}var c,r,o,i,u,a=(c=n.replaceWith,u=[],"."===c[0]?(r=c.slice(1),o=function(e){return e.classList.remove(r)},i=function(e){return e.classList.add(r)}):(r=c.slice(1,-1),o=function(e){return e.removeAttribute(r,"")},i=function(e){return e.setAttribute(r,"")}),function(){u.forEach((function(e){return o(e)})),u.length=0;var e=document.activeElement;if(!/^(#document|HTML|BODY)$/.test(Object(e).nodeName))for(;e&&1===e.nodeType;)i(e),u.push(e),e=e.parentNode}),d=function(){document.documentElement.className.indexOf("js-focus-within")>-1||(document.documentElement.className=document.documentElement.className+" js-focus-within",document.addEventListener("focus",a,!0),document.addEventListener("blur",a,!0))};"complete"===document.readyState?d():document.addEventListener("DOMContentLoaded",d)}export{t as default};
2
+ //# sourceMappingURL=browser.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.mjs","sources":["../src/is-valid-replacement.mjs","../src/browser.js"],"sourcesContent":["const INVALID_SELECTOR_CHAR = [\n\t' ', // Can't use child selector\n\t'>', // Can't use direct child selector\n\t'~', // Can't use sibling selector\n\t':', // Can't use pseudo selector\n\t'+', // Can't use adjacent selector\n\t'@', // Can't use at\n\t'#', // Can't use id selector\n\t'(', // Can't use parenthesis\n\t')', // Can't use parenthesis\n];\n\nexport default function isValidReplacement(selector) {\n\tlet isValid = true;\n\n\t// Purposely archaic so it's interoperable in old browsers\n\tfor (let i = 0, length = INVALID_SELECTOR_CHAR.length; i < length && isValid; i++) {\n\t\tif (selector.indexOf(INVALID_SELECTOR_CHAR[i]) > -1) {\n\t\t\tisValid = false;\n\t\t}\n\t}\n\n\treturn isValid;\n}\n","/* global document */\nimport isValidReplacement from './is-valid-replacement.mjs';\nfunction generateHandler(replaceWith) {\n\tlet selector;\n\tlet remove;\n\tlet add;\n\tconst lastElements = [];\n\n\tif (replaceWith[0] === '.') {\n\t\tselector = replaceWith.slice(1);\n\t\tremove = (el) => el.classList.remove(selector);\n\t\tadd = (el) => el.classList.add(selector);\n\t} else {\n\t\t// A bit naive\n\t\tselector = replaceWith.slice(1, -1);\n\t\tremove = (el) => el.removeAttribute(selector, '');\n\t\tadd = (el) => el.setAttribute(selector, '');\n\t}\n\n\treturn function handleFocusChange() {\n\t\tlastElements.forEach(lastElement => remove(lastElement));\n\t\tlastElements.length = 0;\n\n\t\tlet activeElement = document.activeElement;\n\n\t\t// only add focus if it has not been added and is not the document element\n\t\tif (!/^(#document|HTML|BODY)$/.test(Object(activeElement).nodeName)) {\n\t\t\twhile (activeElement && activeElement.nodeType === 1) {\n\t\t\t\tadd(activeElement);\n\t\t\t\tlastElements.push(activeElement);\n\n\t\t\t\tactiveElement = activeElement.parentNode;\n\t\t\t}\n\t\t}\n\t};\n}\n\nexport default function focusWithin(opts) {\n\t// configuration\n\tconst options = {\n\t\tforce: false,\n\t\treplaceWith: '[focus-within]',\n\t};\n\n\tif (typeof opts !== 'undefined' && 'force' in opts) {\n\t\toptions.force = opts.force;\n\t}\n\n\tif (typeof opts !== 'undefined' && 'replaceWith' in opts) {\n\t\toptions.replaceWith = opts.replaceWith;\n\t}\n\n\tif (!isValidReplacement(options.replaceWith)) {\n\t\tthrow new Error(`${options.replaceWith} is not a valid replacement since it can't be applied to single elements.`);\n\t}\n\n\ttry {\n\t\tdocument.querySelector(':focus-within');\n\n\t\tif (!options.force) {\n\t\t\treturn;\n\t\t}\n\t} catch (ignoredError) { /* do nothing and continue */ }\n\n\tconst handleFocusChange = generateHandler(options.replaceWith);\n\n\tconst initialize = function initializeEventListeners() {\n\t\tif (document.documentElement.className.indexOf('js-focus-within') > -1) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocument.documentElement.className = document.documentElement.className + ' js-focus-within';\n\t\tdocument.addEventListener('focus', handleFocusChange, true);\n\t\tdocument.addEventListener('blur', handleFocusChange, true);\n\t};\n\n\tif (document.readyState === 'complete') {\n\t\tinitialize();\n\t} else {\n\t\tdocument.addEventListener('DOMContentLoaded', initialize);\n\t}\n}\n"],"names":["INVALID_SELECTOR_CHAR","focusWithin","opts","options","force","replaceWith","selector","isValid","i","length","indexOf","isValidReplacement","Error","document","querySelector","ignoredError","remove","add","lastElements","handleFocusChange","slice","el","classList","removeAttribute","setAttribute","forEach","lastElement","activeElement","test","Object","nodeName","nodeType","push","parentNode","initialize","documentElement","className","addEventListener","readyState"],"mappings":"AAAA,IAAMA,EAAwB,CAC7B,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,KC4Bc,SAASC,EAAYC,GAEnC,IAAMC,EAAU,CACfC,OAAO,EACPC,YAAa,kBAWd,QARoB,IAATH,GAAwB,UAAWA,IAC7CC,EAAQC,MAAQF,EAAKE,YAGF,IAATF,GAAwB,gBAAiBA,IACnDC,EAAQE,YAAcH,EAAKG,cDrCd,SAA4BC,GAI1C,IAHA,IAAIC,GAAU,EAGLC,EAAI,EAAGC,EAAST,EAAsBS,OAAQD,EAAIC,GAAUF,EAASC,IACzEF,EAASI,QAAQV,EAAsBQ,KAAO,IACjDD,GAAU,GAIZ,OAAOA,CACP,CC6BKI,CAAmBR,EAAQE,aAC/B,MAAM,IAAIO,MAAST,EAAQE,YAA3B,6EAGD,IAGC,GAFAQ,SAASC,cAAc,kBAElBX,EAAQC,MACZ,MAEsD,CAAtD,MAAOW,GAA+C,CAExD,IA9DwBV,EACpBC,EACAU,EACAC,EACEC,EA0DAC,GA9DkBd,EA8DkBF,EAAQE,YA1D5Ca,EAAe,GAEE,MAAnBb,EAAY,IACfC,EAAWD,EAAYe,MAAM,GAC7BJ,EAAS,SAACK,GAAD,OAAQA,EAAGC,UAAUN,OAAOV,IACrCW,EAAM,SAACI,GAAD,OAAQA,EAAGC,UAAUL,IAAIX,MAG/BA,EAAWD,EAAYe,MAAM,GAAI,GACjCJ,EAAS,SAACK,GAAD,OAAQA,EAAGE,gBAAgBjB,EAAU,KAC9CW,EAAM,SAACI,GAAD,OAAQA,EAAGG,aAAalB,EAAU,MAGlC,WACNY,EAAaO,SAAQ,SAAAC,GAAW,OAAIV,EAAOU,MAC3CR,EAAaT,OAAS,EAEtB,IAAIkB,EAAgBd,SAASc,cAG7B,IAAK,0BAA0BC,KAAKC,OAAOF,GAAeG,UACzD,KAAOH,GAA4C,IAA3BA,EAAcI,UACrCd,EAAIU,GACJT,EAAac,KAAKL,GAElBA,EAAgBA,EAAcM,aAmC3BC,EAAa,WACdrB,SAASsB,gBAAgBC,UAAU1B,QAAQ,oBAAsB,IAIrEG,SAASsB,gBAAgBC,UAAYvB,SAASsB,gBAAgBC,UAAY,mBAC1EvB,SAASwB,iBAAiB,QAASlB,GAAmB,GACtDN,SAASwB,iBAAiB,OAAQlB,GAAmB,KAG1B,aAAxBN,SAASyB,WACZJ,IAEArB,SAASwB,iBAAiB,mBAAoBH,EAE/C"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var t=e(require("postcss-selector-parser"));const s=e=>{const s=String(Object(e).replaceWith||"[focus-within]"),r=Boolean(!("preserve"in Object(e))||e.preserve),o=t.default().astSync(s);return{postcssPlugin:"postcss-focus-within",Rule:(e,{result:s})=>{if(!e.selector.includes(":focus-within"))return;let c;try{const s=t.default((e=>{e.walkPseudos((e=>{":focus-within"===e.value&&(e.nodes&&e.nodes.length||e.replaceWith(o.clone({})))}))})).processSync(e.selector);c=String(s)}catch(t){return void e.warn(s,`Failed to parse selector : ${e.selector}`)}if(void 0===c)return;if(c===e.selector)return;const n=e.clone({selector:c});r?e.before(n):e.replaceWith(n)}}};s.postcss=!0,module.exports=s;
1
+ "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=e(require("postcss-selector-parser"));const t=[" ",">","~",":","+","@","#","(",")"];const n=":focus-within",l=e=>{const l=Object.assign({preserve:!0,replaceWith:"[focus-within]",disablePolyfillReadyClass:!1},e),o=s.default().astSync(l.replaceWith);return function(e){let s=!0;for(let n=0,l=t.length;n<l&&s;n++)e.indexOf(t[n])>-1&&(s=!1);return s}(l.replaceWith)?{postcssPlugin:"postcss-focus-within",Rule(e,{result:t}){if(!e.selector.toLowerCase().includes(n))return;const r=e.selectors.flatMap((r=>{if(!r.toLowerCase().includes(n))return[r];let a;try{a=s.default().astSync(r)}catch(s){return e.warn(t,`Failed to parse selector : ${r}`),r}if(void 0===a)return[r];let i=!1;if(a.walkPseudos((e=>{e.value.toLowerCase()===n&&(e.nodes&&e.nodes.length||(i=!0,e.replaceWith(o.clone({}))))})),!i)return[r];const c=a.clone();if(!l.disablePolyfillReadyClass){var u,d,f,p,h;if(null!=(u=a.nodes)&&null!=(d=u[0])&&null!=(f=d.nodes)&&f.length)for(let e=0;e<a.nodes[0].nodes.length;e++){const t=a.nodes[0].nodes[e];if("combinator"===t.type||s.default.isPseudoElement(t)){a.nodes[0].insertBefore(t,s.default.className({value:"js-focus-within"}));break}if(e===a.nodes[0].nodes.length-1){a.nodes[0].append(s.default.className({value:"js-focus-within"}));break}}null!=(p=a.nodes)&&null!=(h=p[0])&&h.nodes&&(c.nodes[0].prepend(s.default.combinator({value:" "})),c.nodes[0].prepend(s.default.className({value:"js-focus-within"})))}return[a.toString(),c.toString()]}));r.join(",")!==e.selectors.join(",")&&(e.cloneBefore({selectors:r}),l.preserve||e.remove())}}:{postcssPlugin:"postcss-focus-within",Once:(e,{result:s})=>{e.warn(s,`${l.replaceWith} is not a valid replacement since it can't be applied to single elements.`)}}};l.postcss=!0,module.exports=l;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import type { PluginCreator } from 'postcss';
2
- declare const creator: PluginCreator<{
2
+ declare type pluginOptions = {
3
3
  preserve?: boolean;
4
4
  replaceWith?: string;
5
- }>;
5
+ disablePolyfillReadyClass?: boolean;
6
+ };
7
+ declare const creator: PluginCreator<pluginOptions>;
6
8
  export default creator;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import e from"postcss-selector-parser";const s=s=>{const t=String(Object(s).replaceWith||"[focus-within]"),r=Boolean(!("preserve"in Object(s))||s.preserve),o=e().astSync(t);return{postcssPlugin:"postcss-focus-within",Rule:(s,{result:t})=>{if(!s.selector.includes(":focus-within"))return;let c;try{const t=e((e=>{e.walkPseudos((e=>{":focus-within"===e.value&&(e.nodes&&e.nodes.length||e.replaceWith(o.clone({})))}))})).processSync(s.selector);c=String(t)}catch(e){return void s.warn(t,`Failed to parse selector : ${s.selector}`)}if(void 0===c)return;if(c===s.selector)return;const n=s.clone({selector:c});r?s.before(n):s.replaceWith(n)}}};s.postcss=!0;export{s as default};
1
+ import e from"postcss-selector-parser";const s=[" ",">","~",":","+","@","#","(",")"];const n=":focus-within",t=t=>{const o=Object.assign({preserve:!0,replaceWith:"[focus-within]",disablePolyfillReadyClass:!1},t),l=e().astSync(o.replaceWith);return function(e){let n=!0;for(let t=0,o=s.length;t<o&&n;t++)e.indexOf(s[t])>-1&&(n=!1);return n}(o.replaceWith)?{postcssPlugin:"postcss-focus-within",Rule(s,{result:t}){if(!s.selector.toLowerCase().includes(n))return;const r=s.selectors.flatMap((r=>{if(!r.toLowerCase().includes(n))return[r];let i;try{i=e().astSync(r)}catch(e){return s.warn(t,`Failed to parse selector : ${r}`),r}if(void 0===i)return[r];let a=!1;if(i.walkPseudos((e=>{e.value.toLowerCase()===n&&(e.nodes&&e.nodes.length||(a=!0,e.replaceWith(l.clone({}))))})),!a)return[r];const c=i.clone();if(!o.disablePolyfillReadyClass){var u,d,p,f,h;if(null!=(u=i.nodes)&&null!=(d=u[0])&&null!=(p=d.nodes)&&p.length)for(let s=0;s<i.nodes[0].nodes.length;s++){const n=i.nodes[0].nodes[s];if("combinator"===n.type||e.isPseudoElement(n)){i.nodes[0].insertBefore(n,e.className({value:"js-focus-within"}));break}if(s===i.nodes[0].nodes.length-1){i.nodes[0].append(e.className({value:"js-focus-within"}));break}}null!=(f=i.nodes)&&null!=(h=f[0])&&h.nodes&&(c.nodes[0].prepend(e.combinator({value:" "})),c.nodes[0].prepend(e.className({value:"js-focus-within"})))}return[i.toString(),c.toString()]}));r.join(",")!==s.selectors.join(",")&&(s.cloneBefore({selectors:r}),o.preserve||s.remove())}}:{postcssPlugin:"postcss-focus-within",Once:(e,{result:s})=>{e.warn(s,`${o.replaceWith} is not a valid replacement since it can't be applied to single elements.`)}}};t.postcss=!0;export{t as default};
package/package.json CHANGED
@@ -1,69 +1,101 @@
1
1
  {
2
- "name": "postcss-focus-within",
3
- "version": "5.0.4",
4
- "description": "Use the :focus-within pseudo-selector in CSS",
5
- "author": "Jonathan Neal <jonathantneal@hotmail.com>",
6
- "license": "CC0-1.0",
7
- "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-within#readme",
8
- "bugs": "https://github.com/csstools/postcss-plugins/issues",
9
- "main": "dist/index.cjs",
10
- "module": "dist/index.mjs",
11
- "types": "dist/index.d.ts",
12
- "exports": {
13
- ".": {
14
- "import": "./dist/index.mjs",
15
- "require": "./dist/index.cjs",
16
- "default": "./dist/index.mjs"
17
- }
18
- },
19
- "files": [
20
- "CHANGELOG.md",
21
- "LICENSE.md",
22
- "README.md",
23
- "dist"
24
- ],
25
- "scripts": {
26
- "build": "rollup -c ../../rollup/default.js",
27
- "clean": "node -e \"fs.rmSync('./dist', { recursive: true, force: true });\"",
28
- "lint": "eslint ./src --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern",
29
- "prepublishOnly": "npm run clean && npm run build && npm run test",
30
- "stryker": "stryker run --logLevel error",
31
- "test": "postcss-tape --ci && npm run test:exports",
32
- "test:exports": "node ./test/_import.mjs && node ./test/_require.cjs"
33
- },
34
- "engines": {
35
- "node": "^12 || ^14 || >=16"
36
- },
37
- "dependencies": {
38
- "postcss-selector-parser": "^6.0.9"
39
- },
40
- "devDependencies": {
41
- "postcss": "^8.3.6",
42
- "postcss-tape": "^6.0.1"
43
- },
44
- "peerDependencies": {
45
- "postcss": "^8.4"
46
- },
47
- "keywords": [
48
- "postcss",
49
- "css",
50
- "postcss-plugin",
51
- "focus",
52
- "within",
53
- "polyfill",
54
- "pseudos",
55
- "selectors",
56
- "accessibility",
57
- "a11y",
58
- "descendants",
59
- "ancestors"
60
- ],
61
- "repository": {
62
- "type": "git",
63
- "url": "https://github.com/csstools/postcss-plugins.git",
64
- "directory": "plugins/postcss-focus-within"
65
- },
66
- "volta": {
67
- "extends": "../../package.json"
68
- }
2
+ "name": "postcss-focus-within",
3
+ "description": "Use the :focus-within pseudo-selector in CSS",
4
+ "version": "6.1.1",
5
+ "contributors": [
6
+ {
7
+ "name": "Antonio Laguna",
8
+ "email": "antonio@laguna.es",
9
+ "url": "https://antonio.laguna.es"
10
+ },
11
+ {
12
+ "name": "Romain Menke",
13
+ "email": "romainmenke@gmail.com"
14
+ },
15
+ {
16
+ "name": "Jonathan Neal",
17
+ "email": "jonathantneal@hotmail.com"
18
+ }
19
+ ],
20
+ "license": "CC0-1.0",
21
+ "funding": {
22
+ "type": "opencollective",
23
+ "url": "https://opencollective.com/csstools"
24
+ },
25
+ "engines": {
26
+ "node": "^12 || ^14 || >=16"
27
+ },
28
+ "main": "dist/index.cjs",
29
+ "module": "dist/index.mjs",
30
+ "types": "dist/index.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "import": "./dist/index.mjs",
34
+ "require": "./dist/index.cjs",
35
+ "default": "./dist/index.mjs"
36
+ },
37
+ "./browser": {
38
+ "import": "./dist/browser.mjs",
39
+ "require": "./dist/browser.cjs",
40
+ "default": "./dist/browser.mjs"
41
+ },
42
+ "./browser-global": {
43
+ "default": "./dist/browser-global.js"
44
+ }
45
+ },
46
+ "files": [
47
+ "CHANGELOG.md",
48
+ "LICENSE.md",
49
+ "README.md",
50
+ "dist"
51
+ ],
52
+ "dependencies": {
53
+ "postcss-selector-parser": "^6.0.10"
54
+ },
55
+ "peerDependencies": {
56
+ "postcss": "^8.2"
57
+ },
58
+ "scripts": {
59
+ "build": "rollup -c ../../rollup/default.js",
60
+ "clean": "node -e \"fs.rmSync('./dist', { recursive: true, force: true });\"",
61
+ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs",
62
+ "lint": "npm run lint:eslint && npm run lint:package-json",
63
+ "lint:eslint": "eslint ./src --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern",
64
+ "lint:package-json": "node ../../.github/bin/format-package-json.mjs",
65
+ "prepublishOnly": "npm run clean && npm run build && npm run test",
66
+ "test": "node .tape.mjs && npm run test:exports",
67
+ "test:browser": "node ./test/_browser.mjs",
68
+ "test:exports": "node ./test/_import.mjs && node ./test/_require.cjs",
69
+ "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs"
70
+ },
71
+ "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-within#readme",
72
+ "repository": {
73
+ "type": "git",
74
+ "url": "https://github.com/csstools/postcss-plugins.git",
75
+ "directory": "plugins/postcss-focus-within"
76
+ },
77
+ "bugs": "https://github.com/csstools/postcss-plugins/issues",
78
+ "keywords": [
79
+ "a11y",
80
+ "accessibility",
81
+ "ancestors",
82
+ "css",
83
+ "descendants",
84
+ "focus",
85
+ "polyfill",
86
+ "postcss",
87
+ "postcss-plugin",
88
+ "pseudos",
89
+ "selectors",
90
+ "within"
91
+ ],
92
+ "csstools": {
93
+ "cssdbId": "focus-within-pseudo-class",
94
+ "exportName": "postcssFocusWithin",
95
+ "humanReadableName": "PostCSS Focus Within",
96
+ "specUrl": "https://www.w3.org/TR/selectors-4/#the-focus-within-pseudo"
97
+ },
98
+ "volta": {
99
+ "extends": "../../package.json"
100
+ }
69
101
  }