css-has-pseudo 3.0.2 → 4.0.0

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,44 @@
1
1
  # Changes to CSS Has Pseudo
2
2
 
3
+ ### 4.0.0 (July 8, 2022)
4
+
5
+ [Read the full changelog](https://github.com/csstools/postcss-plugins/wiki/PostCSS-Preset-Env-8)
6
+
7
+ - Breaking: removed old CDN urls
8
+ - Added: 'hover' options for browser polyfill
9
+ - Added: 'observedAttributes' options for browser polyfill
10
+ - Added: 'forcePolyfill' options for browser polyfill
11
+ - Added: Rules within `@supports selector(:has(something))` won't be transformed.
12
+ - Fix: Use base36 encoding to support all possible selectors.
13
+ - Fix: case insensitive matching.
14
+
15
+ #### How to migrate :
16
+
17
+ ##### Re-build your CSS with the new version of the library.
18
+
19
+ ##### If you use a CDN url, please update it.
20
+
21
+ ```diff
22
+ - <script src="https://unpkg.com/css-has-pseudo/browser"></script>
23
+ + <script src="https://unpkg.com/css-has-pseudo/dist/browser-global.js"></script>
24
+ ```
25
+
26
+ ```diff
27
+ - <script src="https://unpkg.com/css-has-pseudo/browser.min"></script>
28
+ + <script src="https://unpkg.com/css-has-pseudo/dist/browser-global.js"></script>
29
+ ```
30
+
31
+ ### 3.0.4 (February 5, 2022)
32
+
33
+ - Rebuild of browser polyfills
34
+
35
+ ### 3.0.3 (January 12, 2022)
36
+
37
+ - Fix compatibility with PostCSS `v8.2.x` [#147](https://github.com/csstools/postcss-plugins/issues/147)
38
+
39
+ This version is not officially supported but some tool providers pinned PostCSS to `v8.2.x`,
40
+ making it impossible for end users to have a working setup.
41
+
3
42
  ### 3.0.2 (January 2, 2022)
4
43
 
5
44
  - Removed Sourcemaps from package tarball.
package/README.md CHANGED
@@ -1,106 +1,308 @@
1
- # CSS Has Pseudo [<img src="http://jonathantneal.github.io/js-logo.svg" alt="" width="90" height="90" align="right">][CSS Has Pseudo]
1
+ # PostCSS Has Pseudo [<img src="https://postcss.github.io/postcss/logo.svg" alt="PostCSS Logo" width="90" height="90" align="right">][postcss]
2
2
 
3
- [![NPM Version][npm-img]][npm-url]
4
- [![Support Chat][git-img]][git-url]
3
+ [<img alt="npm version" src="https://img.shields.io/npm/v/css-has-pseudo.svg" height="20">][npm-url] [<img alt="CSS Standard Status" src="https://cssdb.org/images/badges/has-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]
5
4
 
6
- [CSS Has Pseudo] lets you style elements relative to other elements in CSS,
7
- following the [Selectors Level 4] specification.
5
+ [PostCSS Has Pseudo] lets you style elements relative to other elements in CSS, following the [Selectors Level 4] specification.
8
6
 
9
- [!['Can I use' table](https://caniuse.bitsofco.de/image/css-has.png)](https://caniuse.com/#feat=css-has)
10
-
11
- ```css
12
- a:has(> img) {
13
- /* style links that contain an image */
7
+ ```pcss
8
+ .title:has(+ p) {
9
+ margin-bottom: 1.5rem;
14
10
  }
15
11
 
16
- h1:has(+ p) {
17
- /* style level 1 headings that are followed by a paragraph */
18
- }
12
+ /* becomes */
19
13
 
20
- section:not(:has(h1, h2, h3, h4, h5, h6)) {
21
- /* style sections that don’t contain any heading elements */
14
+ [csstools-has-1a-38-2x-38-30-2t-1m-2w-2p-37-14-17-w-34-15]:not(does-not-exist) {
15
+ margin-bottom: 1.5rem;
22
16
  }
23
-
24
- body:has(:focus) {
25
- /* style the body if it contains a focused element */
17
+ .title:has(+ p) {
18
+ margin-bottom: 1.5rem;
26
19
  }
27
20
  ```
28
21
 
29
22
  ## Usage
30
23
 
31
- From the command line, transform CSS files that use `:has` selectors:
24
+ Add [PostCSS Has Pseudo] to your project:
32
25
 
33
26
  ```bash
34
- npx css-has-pseudo SOURCE.css --output TRANSFORMED.css
27
+ npm install postcss css-has-pseudo --save-dev
35
28
  ```
36
29
 
37
- Next, use your transformed CSS with this script:
30
+ Use it as a [PostCSS] plugin:
38
31
 
39
- ```html
40
- <link rel="stylesheet" href="TRANSFORMED.css">
41
- <script src="https://unpkg.com/css-has-pseudo/dist/browser-global.js"></script>
42
- <script>cssHasPseudo(document)</script>
32
+ ```js
33
+ const postcss = require('postcss');
34
+ const postcssHasPseudo = require('css-has-pseudo');
35
+
36
+ postcss([
37
+ postcssHasPseudo(/* pluginOptions */)
38
+ ]).process(YOUR_CSS /*, processOptions */);
43
39
  ```
44
40
 
45
- ⚠️ Please use a versioned url, like this : `https://unpkg.com/css-has-pseudo@3.0.0/dist/browser-global.js`
46
- Without the version, you might unexpectedly get a new major version of the library with breaking changes.
41
+ [PostCSS Has Pseudo] runs in all Node environments, with special
42
+ instructions for:
47
43
 
48
- ⚠️ If you were using an older version via a CDN, please update the entire url.
49
- The old URL will no longer work in a future release.
44
+ | [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) |
45
+ | --- | --- | --- | --- | --- | --- |
50
46
 
51
- That’s it. The script is 765 bytes and works in most browser versions, including
52
- Internet Explorer 11. With a [Mutation Observer polyfill], the script will work
53
- down to Internet Explorer 9.
47
+ ## Options
54
48
 
55
- See [README BROWSER](README-BROWSER.md) for more information.
49
+ ### preserve
56
50
 
57
- ## How it works
51
+ The `preserve` option determines whether the original notation
52
+ is preserved. By default the original rules are preserved.
58
53
 
59
- The [PostCSS plugin](README-POSTCSS.md) clones rules containing `:has`,
60
- replacing them with an alternative `[:has]` selector.
54
+ ```js
55
+ postcssHasPseudo({ preserve: false })
56
+ ```
61
57
 
62
- ```css
63
- body:has(:focus) {
64
- background-color: yellow;
58
+ ```pcss
59
+ .title:has(+ p) {
60
+ margin-bottom: 1.5rem;
65
61
  }
66
62
 
67
- section:not(:has(h1, h2, h3, h4, h5, h6)) {
68
- background-color: gray;
63
+ /* becomes */
64
+
65
+ [csstools-has-1a-38-2x-38-30-2t-1m-2w-2p-37-14-17-w-34-15]:not(does-not-exist) {
66
+ margin-bottom: 1.5rem;
69
67
  }
68
+ ```
70
69
 
71
- /* becomes */
70
+ ### specificityMatchingName
71
+
72
+ The `specificityMatchingName` option allows you to change to selector that is used to adjust specificity.
73
+ The default value is `does-not-exist`.
74
+ If this is an actual class, id or tag name in your code, you will need to set a different option here.
75
+
76
+ See how `:not` is used to modify [specificity](#specificity).
77
+
78
+ ```js
79
+ postcssHasPseudo({ specificityMatchingName: 'something-random' })
80
+ ```
72
81
 
73
- body[\:has\(\:focus\)] {
74
- background-color: yellow;
82
+ [specificity 1, 2, 0](https://polypane.app/css-specificity-calculator/#selector=.x%3Ahas(%3E%20%23a%3Ahover))
83
+
84
+ Before :
85
+
86
+ ```css
87
+ .x:has(> #a:hover) {
88
+ order: 11;
75
89
  }
90
+ ```
76
91
 
77
- body:has(:focus) {
78
- background-color: yellow;
92
+ After :
93
+
94
+ [specificity 1, 2, 0](https://polypane.app/css-specificity-calculator/#selector=%5Bcsstools-has-1a-3c-1m-2w-2p-37-14-1q-w-z-2p-1m-2w-33-3a-2t-36-15%5D%3Anot(%23does-not-exist)%3Anot(.does-not-exist))
95
+
96
+ ```css
97
+ [csstools-has-1a-3c-1m-2w-2p-37-14-1q-w-z-2p-1m-2w-33-3a-2t-36-15]:not(#does-not-exist):not(.does-not-exist) {
98
+ order: 11;
79
99
  }
100
+ ```
101
+
102
+ ## ⚠️ Known shortcomings
103
+
104
+ ### Specificity
105
+
106
+ `:has` transforms will result in at least one attribute selector with specificity `0, 1, 0`.<br>
107
+ If your selector only has tags we won't be able to match the original specificity.
108
+
109
+ Before :
110
+
111
+ [specificity 0, 0, 2](https://polypane.app/css-specificity-calculator/#selector=figure%3Ahas(%3E%20img))
112
+
113
+ ```css
114
+ figure:has(> img)
115
+ ```
116
+
117
+ After :
118
+
119
+ [specificity 0, 1, 2](https://polypane.app/css-specificity-calculator/#selector=%5Bcsstools-has-2u-2x-2v-39-36-2t-1m-2w-2p-37-14-1q-w-2x-31-2v-15%5D%3Anot(does-not-exist)%3Anot(does-not-exist))
120
+
121
+ ```css
122
+ [csstools-has-2u-2x-2v-39-36-2t-1m-2w-2p-37-14-1q-w-2x-31-2v-15]:not(does-not-exist):not(does-not-exist)
123
+ ```
124
+
125
+ ### Plugin order
126
+
127
+ As selectors are encoded, this plugin (or `postcss-preset-env`) must be run after any other plugin that transforms selectors.
128
+
129
+ If other plugins are used, you need to place these in your config before `postcss-preset-env` or `css-has-pseudo`.
130
+
131
+ Please let us know if you have issues with plugins that transform selectors.
132
+ Then we can investigate and maybe fix these.
133
+
134
+ ## Browser
135
+
136
+ ```js
137
+ // initialize prefersColorScheme (applies the current OS color scheme, if available)
138
+ import cssHasPseudo from 'css-has-pseudo/browser';
139
+ cssHasPseudo(document);
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/css-has-pseudo@3.0.4/dist/browser-global.js"></script>
147
+ <script>cssHasPseudo(document)</script>
148
+ ```
149
+
150
+ ⚠️ Please use a versioned url, like this : `https://unpkg.com/css-has-pseudo@3.0.4/dist/browser-global.js`
151
+ Without the version, you might unexpectedly get a new major version of the library with breaking changes.
80
152
 
81
- section[\:not-has\(h1\,\%20h2\,\%20h3\,\%20h4\,\%20h5\,\%20h6\)] {
82
- background-color: gray;
153
+ [PostCSS Has Pseudo] works in all major browsers, including
154
+ Internet Explorer 11. With a [Mutation Observer polyfill](https://github.com/webmodules/mutation-observer), the script will work
155
+ down to Internet Explorer 9.
156
+
157
+ ### Browser Usage
158
+
159
+ #### hover
160
+
161
+ The `hover` option determines if `:hover` pseudo-class should be tracked.
162
+ This is disabled by default because it is an expensive operation.
163
+
164
+ ```js
165
+ cssHasPseudo(document, { hover: true });
166
+ ```
167
+
168
+ #### observedAttributes
169
+
170
+ The `observedAttributes` option determines which html attributes are observed.
171
+ If you do any client side modification of non-standard attributes and use these in combination with `:has()` you should add these here.
172
+
173
+ ```js
174
+ cssHasPseudo(document, { observedAttributes: ['something-not-standard'] });
175
+ ```
176
+
177
+ #### forcePolyfill
178
+
179
+ The `forcePolyfill` option determines if the polyfill is used even when the browser has native support.
180
+ This is needed when you set `preserve: false` in the PostCSS plugin config.
181
+
182
+ ```js
183
+ cssHasPseudo(document, { forcePolyfill: true });
184
+ ```
185
+
186
+ #### debug
187
+
188
+ The `debug` option determines if errors are emitted to the console in browser.
189
+ By default the polyfill will not emit errors or warnings.
190
+
191
+ ```js
192
+ cssHasPseudo(document, { debug: true });
193
+ ```
194
+
195
+
196
+ ### Browser Dependencies
197
+
198
+ Web API's:
199
+
200
+ - [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)
201
+ - [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame)
202
+ - [querySelectorAll](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) with support for post CSS 2.1 selectors and `:scope` selectors.
203
+
204
+ ECMA Script:
205
+
206
+ - `Array.prototype.filter`
207
+ - `Array.prototype.forEach`
208
+ - `Array.prototype.indexOf`
209
+ - `Array.prototype.join`
210
+ - `Array.prototype.map`
211
+ - `Array.prototype.splice`
212
+ - `RegExp.prototype.exec`
213
+ - `String.prototype.match`
214
+ - `String.prototype.replace`
215
+ - `String.prototype.split`
216
+
217
+ ## CORS
218
+
219
+ ⚠️ Applies to you if you load CSS from a different domain than the page.
220
+
221
+ In this case the CSS is treated as untrusted and will not be made available to the JavaScript polyfill.
222
+ The polyfill will not work without applying the correct configuration for CORS.
223
+
224
+ Example :
225
+
226
+ | page | css | CORS applies |
227
+ | --- | --- | --- |
228
+ | https://example.com/ | https://example.com/style.css | no |
229
+ | https://example.com/ | https://other.com/style.css | yes |
230
+
231
+
232
+ **You might see one of these error messages :**
233
+
234
+ Chrome :
235
+
236
+ > DOMException: Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules
237
+
238
+ Safari :
239
+
240
+ > SecurityError: Not allowed to access cross-origin stylesheet
241
+
242
+ Firefox :
243
+
244
+ > DOMException: CSSStyleSheet.cssRules getter: Not allowed to access cross-origin stylesheet
245
+
246
+ To resolve CORS errors you need to take two steps :
247
+
248
+ - add an HTTP header `Access-Control-Allow-Origin: <your-value>` when serving your CSS file.
249
+ - add `crossorigin="anonymous"` to the `<link rel="stylesheet">` tag for your CSS file.
250
+
251
+ In a node server setting the HTTP header might look like this :
252
+
253
+ ```js
254
+ // http://localhost:8080 is the domain of your page!
255
+ res.setHeader('Access-Control-Allow-Origin', 'https://example.com');
256
+ ```
257
+
258
+ You can also configure a wildcard but please be aware that this might be a security risk.
259
+ It is better to only set the header for the domain you want to allow and only on the responses you want to allow.
260
+
261
+ HTML might look like this :
262
+
263
+ ```html
264
+ <link rel="stylesheet" href="https://example.com/styles.css" crossorigin="anonymous">
265
+ ```
266
+
267
+
268
+ ## How it works
269
+
270
+ The [PostCSS Has Pseudo] clones rules containing `:has()`,
271
+ replacing them with an alternative `[csstools-has-]` selector.
272
+
273
+ ```pcss
274
+ .title:has(+ p) {
275
+ margin-bottom: 1.5rem;
83
276
  }
84
277
 
85
- section:not(:has(h1, h2, h3, h4, h5, h6)) {
86
- background-color: gray;
278
+ /* becomes */
279
+
280
+ [csstools-has-1a-38-2x-38-30-2t-1m-2w-2p-37-14-17-w-34-15]:not(does-not-exist) {
281
+ margin-bottom: 1.5rem;
282
+ }
283
+ .title:has(+ p) {
284
+ margin-bottom: 1.5rem;
87
285
  }
88
286
  ```
89
287
 
90
- Next, the [JavaScript library](README-BROWSER.md) adds a `[:has]` attribute to
288
+ Next, the [browser script](#browser) adds a `[:has]` attribute to
91
289
  elements otherwise matching `:has` natively.
92
290
 
93
291
  ```html
94
- <body :has(:focus)>
95
- <input value="This element is focused">
96
- </body>
292
+ <div class="title" [csstools-has-1a-38-2x-38-30-2t-1m-2w-2p-37-14-17-w-34-15]>
293
+ <h1>A title block</h1>
294
+ <p>With an extra paragraph</p>
295
+ </div>
97
296
  ```
98
297
 
99
- [git-img]: https://img.shields.io/badge/support-chat-blue.svg
100
- [git-url]: https://gitter.im/postcss/postcss
101
- [npm-img]: https://img.shields.io/npm/v/css-has-pseudo.svg
298
+ [cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
299
+ [css-url]: https://cssdb.org/#has-pseudo-class
300
+ [discord]: https://discord.gg/bUadyRwkJS
102
301
  [npm-url]: https://www.npmjs.com/package/css-has-pseudo
103
302
 
104
- [CSS Has Pseudo]: https://github.com/csstools/postcss-plugins/tree/main/plugins/css-has-pseudo
105
- [Mutation Observer polyfill]: https://github.com/webmodules/mutation-observer
106
- [Selectors Level 4]: https://drafts.csswg.org/selectors-4/#has-pseudo
303
+ [Gulp PostCSS]: https://github.com/postcss/gulp-postcss
304
+ [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss
305
+ [PostCSS]: https://github.com/postcss/postcss
306
+ [PostCSS Loader]: https://github.com/postcss/postcss-loader
307
+ [PostCSS Has Pseudo]: https://github.com/csstools/postcss-plugins/tree/main/plugins/css-has-pseudo
308
+ [Selectors Level 4]: https://www.w3.org/TR/selectors-4/#has-pseudo
@@ -1,117 +1,2 @@
1
- (function () {
2
-
3
- /* global MutationObserver,requestAnimationFrame */
4
- function cssHasPseudo(document) {
5
- var observedItems = []; // document.createAttribute() doesn't support `:` in the name. innerHTML does
6
-
7
- var attributeElement = document.createElement('x'); // walk all stylesheets to collect observed css rules
8
-
9
- [].forEach.call(document.styleSheets, walkStyleSheet);
10
- transformObservedItems(); // observe DOM modifications that affect selectors
11
-
12
- var mutationObserver = new MutationObserver(function (mutationsList) {
13
- mutationsList.forEach(function (mutation) {
14
- [].forEach.call(mutation.addedNodes || [], function (node) {
15
- // walk stylesheets to collect observed css rules
16
- if (node.nodeType === 1 && node.sheet) {
17
- walkStyleSheet(node.sheet);
18
- }
19
- }); // transform observed css rules
20
-
21
- cleanupObservedCssRules();
22
- transformObservedItems();
23
- });
24
- });
25
- mutationObserver.observe(document, {
26
- childList: true,
27
- subtree: true
28
- }); // observe DOM events that affect pseudo-selectors
29
-
30
- document.addEventListener('focus', transformObservedItems, true);
31
- document.addEventListener('blur', transformObservedItems, true);
32
- document.addEventListener('input', transformObservedItems); // transform observed css rules
33
-
34
- function transformObservedItems() {
35
- requestAnimationFrame(function () {
36
- observedItems.forEach(function (item) {
37
- var nodes = [];
38
- [].forEach.call(document.querySelectorAll(item.scopeSelector), function (element) {
39
- var nthChild = [].indexOf.call(element.parentNode.children, element) + 1;
40
- var relativeSelectors = item.relativeSelectors.map(function (relativeSelector) {
41
- return item.scopeSelector + ':nth-child(' + nthChild + ') ' + relativeSelector;
42
- }).join(); // find any relative :has element from the :scope element
43
-
44
- var relativeElement = element.parentNode.querySelector(relativeSelectors);
45
- var shouldElementMatch = item.isNot ? !relativeElement : relativeElement;
46
-
47
- if (shouldElementMatch) {
48
- // memorize the node
49
- nodes.push(element); // set an attribute with an irregular attribute name
50
- // document.createAttribute() doesn't support special characters
51
-
52
- attributeElement.innerHTML = '<x ' + item.attributeName + '>';
53
- element.setAttributeNode(attributeElement.children[0].attributes[0].cloneNode()); // trigger a style refresh in IE and Edge
54
-
55
- document.documentElement.style.zoom = 1;
56
- document.documentElement.style.zoom = null;
57
- }
58
- }); // remove the encoded attribute from all nodes that no longer match them
59
-
60
- item.nodes.forEach(function (node) {
61
- if (nodes.indexOf(node) === -1) {
62
- node.removeAttribute(item.attributeName); // trigger a style refresh in IE and Edge
63
-
64
- document.documentElement.style.zoom = 1;
65
- document.documentElement.style.zoom = null;
66
- }
67
- }); // update the
68
-
69
- item.nodes = nodes;
70
- });
71
- });
72
- } // remove any observed cssrules that no longer apply
73
-
74
-
75
- function cleanupObservedCssRules() {
76
- [].push.apply(observedItems, observedItems.splice(0).filter(function (item) {
77
- return item.rule.parentStyleSheet && item.rule.parentStyleSheet.ownerNode && document.documentElement.contains(item.rule.parentStyleSheet.ownerNode);
78
- }));
79
- } // walk a stylesheet to collect observed css rules
80
-
81
-
82
- function walkStyleSheet(styleSheet) {
83
- try {
84
- // walk a css rule to collect observed css rules
85
- [].forEach.call(styleSheet.cssRules || [], function (rule) {
86
- if (rule.selectorText) {
87
- // decode the selector text in all browsers to:
88
- // [1] = :scope, [2] = :not(:has), [3] = :has relative, [4] = :scope relative
89
- var selectors = decodeURIComponent(rule.selectorText.replace(/\\(.)/g, '$1')).match(/^(.*?)\[:(not-)?has\((.+?)\)\](.*?)$/);
90
-
91
- if (selectors) {
92
- var attributeName = ':' + (selectors[2] ? 'not-' : '') + 'has(' + // encode a :has() pseudo selector as an attribute name
93
- encodeURIComponent(selectors[3]).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',') + ')';
94
- observedItems.push({
95
- rule: rule,
96
- scopeSelector: selectors[1],
97
- isNot: selectors[2],
98
- relativeSelectors: selectors[3].split(/\s*,\s*/),
99
- attributeName: attributeName,
100
- nodes: []
101
- });
102
- }
103
- } else {
104
- walkStyleSheet(rule);
105
- }
106
- });
107
- } catch (error) {
108
- /* do nothing and continue */
109
- }
110
- }
111
- }
112
-
113
- /* global self */
114
- self.cssHasPseudo = cssHasPseudo;
115
-
116
- })();
1
+ !function(){function e(e){if("csstools-has-"!==e.slice(0,13))return"";for(var t=(e=e.slice(13)).split("-"),r="",n=0;n<t.length;n++)r+=String.fromCharCode(parseInt(t[n],36));return r}function t(e){if(""===e)return"";for(var t,r="",n=0;n<e.length;n++)t=e.charCodeAt(n).toString(36),r+=0===n?t:"-"+t;return"csstools-has-"+r}!function(e){try{if(e.document.querySelector(":has(*, :does-not-exist, > *)"),e.document.querySelector(":has(:has(any))"),!e.document.querySelector(":has(:scope *)"))return}catch(e){}var t=d(e.Element.prototype.querySelector);e.Element.prototype.querySelector=function(e){return t.apply(this,arguments)};var r=d(e.Element.prototype.querySelectorAll);if(e.Element.prototype.querySelectorAll=function(e){return r.apply(this,arguments)},e.Element.prototype.matches){var n=d(e.Element.prototype.matches);e.Element.prototype.matches=function(e){return n.apply(this,arguments)}}if(e.Element.prototype.closest){var o=d(e.Element.prototype.closest);e.Element.prototype.closest=function(e){return o.apply(this,arguments)}}if("Document"in e&&"prototype"in e.Document){var i=d(e.Document.prototype.querySelector);e.Document.prototype.querySelector=function(e){return i.apply(this,arguments)};var s=d(e.Document.prototype.querySelectorAll);if(e.Document.prototype.querySelectorAll=function(e){return s.apply(this,arguments)},e.Document.prototype.matches){var c=d(e.Document.prototype.matches);e.Document.prototype.matches=function(e){return c.apply(this,arguments)}}if(e.Document.prototype.closest){var a=d(e.Document.prototype.closest);e.Document.prototype.closest=function(e){return a.apply(this,arguments)}}}function u(e){for(var t="",r=0,n=0,o=!1,i=!1,s=!1,c=!1,a=0;a<e.length;a++){var u=e[a];if(o)t+=u,o=!1;else switch(":has("!==t.toLowerCase()||c||(c=!0,r=a,t=""),u){case":":if(i){t+=u;continue}c||(t=""),t+=u;continue;case"(":c&&n++,t+=u;continue;case")":if(c){if(0===n)return{innerQuery:t,start:r,end:a-1};n--}t+=u;continue;case"\\":t+=u,o=!0;continue;case'"':case"'":if(i&&u===s){t+=u,i=!1;continue}t+=u,i=!0,s=u;continue;default:t+=u;continue}}return!1}function l(e,t){for(var r=[],n="",o=!1,i=!1,s=!1,c=0;c<e.length;c++){var a=e[c];if(o)n+=a,o=!1;else switch(":scope"!==n.toLowerCase()||/^[\w|\\]/.test(a||"")||(r.push(n.slice(0,n.length-6)),r.push("["+t+"]"),n=""),a){case":":if(i){n+=a;continue}r.push(n),n="",n+=a;continue;case"\\":n+=a,o=!0;continue;case'"':case"'":if(i&&a===s){n+=a,i=!1;continue}n+=a,i=!0,s=a;continue;default:n+=a;continue}}return 0===r.length?e:r.join("")+n}function f(e){for(var t,r,n=[],o="",i=!1,s=!1,c=!1,a=!1,u=0,l=0;l<e.length;l++){var f=e[l];if(i)o+=f,i=!1;else switch(f){case",":if(s){o+=f;continue}if(u>0){o+=f;continue}n.push(o),o="";continue;case"\\":o+=f,i=!0;continue;case'"':case"'":if(s&&f===c){o+=f,s=!1;continue}o+=f,s=!0,c=f;continue;case"(":case")":case"[":case"]":if(s){o+=f;continue}if(t=f,"("===(r=a)&&")"===t||"["===r&&"]"===t){o+=f,0===--u&&(a=!1);continue}if(f===a){o+=f,u++;continue}o+=f,u++,a=f;continue;default:o+=f;continue}}return n.push(o),n}function p(e,t,r){var n=u(e);if(!n)return e;if(t)return!1;var o=n.innerQuery,i="q-has"+(Math.floor(9e6*Math.random())+1e6),s="["+i+"]",c=e;if(n.innerQuery.toLowerCase().indexOf(":has(")>-1){for(var a=f(n.innerQuery),l=[],h=0;h<a.length;h++){var d=a[h];p(d,!0,(function(){}))?l.push(d):l.push(":not(*)")}var m=c.substring(0,n.start-5),y=c.substring(n.end+2);return m+l.join(", ")+y}m=c.substring(0,n.start-5),y=c.substring(n.end+2);if(c=m+s+y,r(o,i),c.toLowerCase().indexOf(":has(")>-1){var v=p(c,!1,r);if(v)return v}return c}function h(e,t){if("setAttribute"in e&&"querySelector"in e&&t(e),e.hasChildNodes())for(var r=e.childNodes,n=0;n<r.length;++n)h(r[n],t)}function d(t){return function(r){if(-1===r.toLowerCase().indexOf(":has(")||!u(r))return t.apply(this,arguments);var n;if("getRootNode"in this)n=this.getRootNode();else for(var o=this;o;)n=o,o=o.parentNode;var i=this;i===e.document&&(i=e.document.documentElement);var s="q-has-scope"+(Math.floor(9e6*Math.random())+1e6);i.setAttribute(s,"");try{r=l(r,s);var c=[s],a=p(r,!1,(function(e,t){c.push(t);for(var r=f(e),o=0;o<r.length;o++){var i=r[o].trim(),s=i;s=">"===i[0]||"+"===i[0]||"~"===i[0]?i.slice(1).trim():":scope "+i;try{h(n,(function(e){if(e.querySelector(s))switch(i[0]){case"~":case"+":for(var r=e.childNodes,n=0;n<r.length;n++){var o=r[n];if("setAttribute"in o){var c="q-has-id"+(Math.floor(9e6*Math.random())+1e6);o.setAttribute(c,""),e.querySelector(":scope ["+c+"] "+i)&&o.setAttribute(t,""),o.removeAttribute(c)}}break;case">":c="q-has-id"+(Math.floor(9e6*Math.random())+1e6);e.setAttribute(c,""),e.querySelector(":scope["+c+"] "+i)&&e.setAttribute(t,""),e.removeAttribute(c);break;default:e.setAttribute(t,"")}}))}catch(e){}}}));arguments[0]=a;var d=t.apply(this,arguments);if(i.removeAttribute(s),c.length>0){for(var m=[],y=0;y<c.length;y++)m.push("["+c[y]+"]");for(var v=e.document.querySelectorAll(m.join(",")),b=0;b<v.length;b++)for(var g=v[b],E=0;E<c.length;E++)g.removeAttribute(c[E])}return d}catch(t){if(i.removeAttribute(s),c.length>0){for(m=[],y=0;y<c.length;y++)m.push("["+c[y]+"]");for(v=e.document.querySelectorAll(m.join(",")),b=0;b<v.length;b++)for(g=v[b],E=0;E<c.length;E++)g.removeAttribute(c[E])}throw t}}}}(self),self.cssHasPseudo=function(r,n){n||(n={}),(n={hover:!!n.hover||!1,debug:!!n.debug||!1,observedAttributes:n.observedAttributes||[],forcePolyfill:!!n.forcePolyfill||!1}).mustPolyfill=n.forcePolyfill||!function(e){try{if(e.querySelector(":has(*, :does-not-exist, > *)"),e.querySelector(":has(:has(any))"),e.querySelector(":has(:scope *)"))return!1;if(!("CSS"in self)||!("supports"in self.CSS)||!self.CSS.supports(":has(any)"))return!1}catch(e){return!1}return!0}(r),Array.isArray(n.observedAttributes)||(n.observedAttributes=[]),n.observedAttributes=n.observedAttributes.filter((function(e){return"string"==typeof e})),n.observedAttributes=n.observedAttributes.concat(["accept","accept-charset","accesskey","action","align","allow","alt","async","autocapitalize","autocomplete","autofocus","autoplay","buffered","capture","challenge","charset","checked","cite","class","code","codebase","cols","colspan","content","contenteditable","contextmenu","controls","coords","crossorigin","csp","data","datetime","decoding","default","defer","dir","dirname","disabled","download","draggable","enctype","enterkeyhint","for","form","formaction","formenctype","formmethod","formnovalidate","formtarget","headers","hidden","high","href","hreflang","http-equiv","icon","id","importance","integrity","intrinsicsize","inputmode","ismap","itemprop","keytype","kind","label","lang","language","list","loop","low","manifest","max","maxlength","minlength","media","method","min","multiple","muted","name","novalidate","open","optimum","pattern","ping","placeholder","poster","preload","radiogroup","readonly","referrerpolicy","rel","required","reversed","rows","rowspan","sandbox","scope","scoped","selected","shape","size","sizes","slot","span","spellcheck","src","srcdoc","srclang","srcset","start","step","summary","tabindex","target","title","translate","type","usemap","value","width","wrap"]);var o=[],i=r.createElement("x");if([].forEach.call(r.styleSheets,u),n.mustPolyfill){if(a(),"MutationObserver"in self)new MutationObserver((function(e){e.forEach((function(e){[].forEach.call(e.addedNodes||[],(function(e){1===e.nodeType&&e.sheet&&u(e.sheet)})),[].push.apply(o,o.splice(0).filter((function(e){return e.rule.parentStyleSheet&&e.rule.parentStyleSheet.ownerNode&&r.documentElement.contains(e.rule.parentStyleSheet.ownerNode)}))),a()}))})).observe(r,{childList:!0,subtree:!0,attributes:!0,attributeFilter:n.observedAttributes});if(r.addEventListener("focus",a,!0),r.addEventListener("blur",a,!0),r.addEventListener("input",a),r.addEventListener("change",a,!0),n.hover&&("onpointerenter"in r?(r.addEventListener("pointerenter",a,!0),r.addEventListener("pointerleave",a,!0)):(r.addEventListener("mouseover",a,!0),r.addEventListener("mouseout",a,!0))),"defineProperty"in Object&&"getOwnPropertyDescriptor"in Object&&"hasOwnProperty"in Object)try{var s=function(e,t){if(e.hasOwnProperty(t)){var r=Object.getOwnPropertyDescriptor(e,t);r&&r.configurable&&"set"in r&&Object.defineProperty(e,t,{configurable:r.configurable,enumerable:r.enumerable,get:function(){return r.get.apply(this,arguments)},set:function(){r.set.apply(this,arguments);try{a()}catch(e){}}})}};"HTMLElement"in self&&HTMLElement.prototype&&s(HTMLElement.prototype,"disabled"),["checked","selected","readOnly","required"].forEach((function(e){["HTMLButtonElement","HTMLFieldSetElement","HTMLInputElement","HTMLMeterElement","HTMLOptGroupElement","HTMLOptionElement","HTMLOutputElement","HTMLProgressElement","HTMLSelectElement","HTMLTextAreaElement"].forEach((function(t){t in self&&self[t].prototype&&s(self[t].prototype,e)}))}))}catch(e){n.debug&&console.error(e)}var c=!1}function a(){c&&cancelAnimationFrame(c),c=requestAnimationFrame((function(){o.forEach((function(e){var t=[],o=[];try{o=r.querySelectorAll(e.selector)}catch(e){return void(n.debug&&console.error(e))}[].forEach.call(o,(function(n){t.push(n),i.innerHTML="<x "+e.attributeName+">",n.setAttributeNode(i.children[0].attributes[0].cloneNode()),r.documentElement.style.zoom=1,r.documentElement.style.zoom=null})),e.nodes.forEach((function(n){-1===t.indexOf(n)&&(n.removeAttribute(e.attributeName),r.documentElement.style.zoom=1,r.documentElement.style.zoom=null)})),e.nodes=t}))}))}function u(r){try{[].forEach.call(r.cssRules||[],(function(r){if(r.selectorText){r.selectorText=r.selectorText.replace(/\.js-has-pseudo\s/g,"");try{var i=function(t){for(var r,n,o=[],i=0,s=!1,c=!1,a=0;a<t.length;a++){var u=t[a];switch(u){case"[":if(s){r+=u;continue}0===i?r="":r+=u,i++;continue;case"]":if(s){r+=u;continue}if(0==--i){var l=e(r);c&&o.push(l)}else r+=u;continue;case"\\":r+=t[a],r+=t[a+1],a++;continue;case'"':case"'":if(s&&u===n){s=!1;continue}if(s){r+=u;continue}s=!0,n=u;continue;default:""===r&&1===i&&"csstools-has-"===t.slice(a,a+13)&&(c=!0),r+=u;continue}}for(var f=[],p=0;p<o.length;p++)-1===f.indexOf(o[p])&&f.push(o[p]);return f}(r.selectorText.toString());if(0===i.length)return;if(!n.mustPolyfill)return void r.deleteRule();for(var s=0;s<i.length;s++){var c=i[s];o.push({rule:r,selector:c,attributeName:t(c),nodes:[]})}}catch(e){n.debug&&console.error(e)}}else u(r)}))}catch(e){n.debug&&console.error(e)}}}}();
117
2
  //# sourceMappingURL=browser-global.js.map