css-has-pseudo 1.0.0 → 2.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/README.md CHANGED
@@ -7,6 +7,8 @@
7
7
  [CSS Has Pseudo] lets you style elements relative to other elements in CSS,
8
8
  following the [Selectors Level 4] specification.
9
9
 
10
+ [!['Can I use' table](https://caniuse.bitsofco.de/image/css-has.png)](https://caniuse.com/#feat=css-has)
11
+
10
12
  ```css
11
13
  a:has(> img) {
12
14
  /* style links that contain an image */
package/browser.js CHANGED
@@ -1,2 +1,2 @@
1
- function cssHasPseudo(n){var t=[],e=n.createElement("x");function o(){requestAnimationFrame(function(){t.forEach(function(t){var o=[];[].forEach.call(n.querySelectorAll(t.t),function(u){var i=[].indexOf.call(u.parentNode.children,u)+1,c=t.o.map(function(n){return t.t+":nth-child("+i+") "+n}).join(),r=u.parentNode.querySelector(c);(t.u?!r:r)&&(o.push(u),e.innerHTML="<x "+t.attributeName+">",u.setAttributeNode(e.children[0].attributes[0].cloneNode()),n.documentElement.style.zoom=1,n.documentElement.style.zoom=null)}),t.i.forEach(function(e){-1===o.indexOf(e)&&(e.removeAttribute(t.attributeName),n.documentElement.style.zoom=1,n.documentElement.style.zoom=null)}),t.i=o})})}function u(n){try{[].forEach.call(n.cssRules||[],function(n){if(n.selectorText){var e=decodeURIComponent(n.selectorText.replace(/\\(.)/g,"$1")).match(/^(.*?)\[:(not-)?has\((.+?)\)\](.*?)$/);if(e){var o=":"+(e[2]?"not-":"")+"has("+encodeURIComponent(e[3]).replace(/%3A/g,":").replace(/%5B/g,"[").replace(/%5D/g,"]").replace(/%2C/g,",")+")";t.push({s:n,t:e[1],u:e[2],o:e[3].split(/\s*,\s*/),attributeName:o,i:[]})}}else u(n)})}catch(n){}}[].forEach.call(n.styleSheets,u),o(),new MutationObserver(function(e){e.forEach(function(e){[].forEach.call(e.addedNodes||[],function(n){1===n.nodeType&&n.sheet&&u(n.sheet)}),[].push.apply(t,t.splice(0).filter(function(t){return t.s.parentStyleSheet&&t.s.parentStyleSheet.ownerNode&&n.documentElement.contains(t.s.parentStyleSheet.ownerNode)})),o()})}).observe(n,{childList:!0,subtree:!0}),n.addEventListener("focus",o,!0),n.addEventListener("blur",o,!0),n.addEventListener("input",o)}
1
+
2
2
  //# sourceMappingURL=browser.js.map
package/cli.js CHANGED
@@ -1,49 +1,75 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
4
-
5
- var fs = _interopDefault(require('fs'));
6
- var parser = _interopDefault(require('postcss-selector-parser'));
7
- var postcss = _interopDefault(require('postcss'));
8
-
9
- const selectorRegExp = /:has/;
10
- var plugin = postcss.plugin('css-has-pseudo', opts => {
11
- const preserve = Boolean('preserve' in Object(opts) ? opts.preserve : true);
12
- return root => {
13
- root.walkRules(selectorRegExp, rule => {
14
- const modifiedSelector = parser(selectors => {
15
- selectors.walkPseudos(selector => {
16
- if (selector.value === ':has' && selector.nodes) {
17
- const isNotHas = checkIfParentIsNot(selector);
18
- selector.value = isNotHas ? ':not-has' : ':has';
19
- const attribute = parser.attribute({
20
- attribute: encodeURIComponent(String(selector)).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',').replace(/[():%[\],]/g, '\\$&')
21
- });
22
-
23
- if (isNotHas) {
24
- selector.parent.parent.replaceWith(attribute);
25
- } else {
26
- selector.replaceWith(attribute);
27
- }
28
- }
3
+ var fs = require('fs');
4
+ var parser = require('postcss-selector-parser');
5
+
6
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
7
+
8
+ var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
9
+ var parser__default = /*#__PURE__*/_interopDefaultLegacy(parser);
10
+
11
+ const creator = (
12
+ /** @type {{ preserve: true | false }} */
13
+ opts) => {
14
+ opts = typeof opts === 'object' && opts || defaultOptions;
15
+ /** Whether the original rule should be preserved. */
16
+
17
+ const shouldPreserve = Boolean('preserve' in opts ? opts.preserve : true);
18
+ return {
19
+ postcssPlugin: 'css-has-pseudo',
20
+ Rule: rule => {
21
+ if (rule.selector.includes(':has(')) {
22
+ const fallbackSelector = getFallbackSelector(rule.selector);
23
+ if (shouldPreserve) rule.cloneBefore({
24
+ selector: fallbackSelector
25
+ });else rule.assign({
26
+ selector: fallbackSelector
29
27
  });
30
- }).processSync(rule.selector);
31
- const clone = rule.clone({
32
- selector: modifiedSelector
28
+ }
29
+ }
30
+ };
31
+ };
32
+
33
+ creator.postcss = true;
34
+
35
+ const getFallbackSelector = (
36
+ /** @type {string} */
37
+ selectorText) => parser__default['default'](selectors => {
38
+ selectors.walkPseudos(selector => {
39
+ if (selector.value === ':has' && selector.nodes) {
40
+ const isNotHas = isParentInNotPseudo(selector);
41
+ selector.value = isNotHas ? ':not-has' : ':has';
42
+ const attribute = parser__default['default'].attribute({
43
+ attribute: getEscapedCss(String(selector))
33
44
  });
34
45
 
35
- if (preserve) {
36
- rule.before(clone);
46
+ if (isNotHas) {
47
+ selector.parent.parent.replaceWith(attribute);
37
48
  } else {
38
- rule.replaceWith(clone);
49
+ selector.replaceWith(attribute);
39
50
  }
40
- });
41
- };
42
- });
51
+ }
52
+ });
53
+ }).processSync(selectorText);
54
+ /** Default options. */
43
55
 
44
- function checkIfParentIsNot(selector) {
45
- return Object(Object(selector.parent).parent).type === 'pseudo' && selector.parent.parent.value === ':not';
46
- }
56
+
57
+ const defaultOptions = {
58
+ preserve: true
59
+ };
60
+ /** Returns the string as an escaped CSS identifier. */
61
+
62
+ const getEscapedCss = (
63
+ /** @type {string} */
64
+ value) => encodeURIComponent(value).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',').replace(/[():%[\],]/g, '\\$&');
65
+ /** Returns whether the selector is within a `:not` pseudo-class. */
66
+
67
+
68
+ const isParentInNotPseudo = selector => {
69
+ var _selector$parent, _selector$parent$pare;
70
+
71
+ return ((_selector$parent = selector.parent) === null || _selector$parent === void 0 ? void 0 : (_selector$parent$pare = _selector$parent.parent) === null || _selector$parent$pare === void 0 ? void 0 : _selector$parent$pare.type) === 'pseudo' && selector.parent.parent.value === ':not';
72
+ };
47
73
 
48
74
  /* eslint no-console: 0 */
49
75
 
@@ -85,7 +111,7 @@ const argo = process.argv.slice(2).reduce((object, arg) => {
85
111
  }, argo.map ? {
86
112
  map: JSON.parse(argo.map)
87
113
  } : {});
88
- const result = plugin.process(css, processOptions, pluginOpts);
114
+ const result = creator.process(css, processOptions, pluginOpts);
89
115
 
90
116
  if (argo.to === '<stdout>') {
91
117
  return result.css;
@@ -112,7 +138,7 @@ const argo = process.argv.slice(2).reduce((object, arg) => {
112
138
 
113
139
  function readFile(pathname) {
114
140
  return new Promise((resolve, reject) => {
115
- fs.readFile(pathname, 'utf8', (error, data) => {
141
+ fs__default['default'].readFile(pathname, 'utf8', (error, data) => {
116
142
  if (error) {
117
143
  reject(error);
118
144
  } else {
@@ -124,7 +150,7 @@ function readFile(pathname) {
124
150
 
125
151
  function writeFile(pathname, data) {
126
152
  return new Promise((resolve, reject) => {
127
- fs.writeFile(pathname, data, (error, content) => {
153
+ fs__default['default'].writeFile(pathname, data, (error, content) => {
128
154
  if (error) {
129
155
  reject(error);
130
156
  } else {
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["src/browser.js"],"sourcesContent":["export default function cssHasPseudo (document) {\n\tconst observedItems = [];\n\n\t// document.createAttribute() doesn't support `:` in the name. innerHTML does\n\tconst attributeElement = document.createElement('x');\n\n\t// walk all stylesheets to collect observed css rules\n\t[].forEach.call(document.styleSheets, walkStyleSheet);\n\ttransformObservedItems();\n\n\t// observe DOM modifications that affect selectors\n\tconst mutationObserver = new MutationObserver(mutationsList => {\n\t\tmutationsList.forEach(mutation => {\n\t\t\t[].forEach.call(mutation.addedNodes || [], node => {\n\t\t\t\t// walk stylesheets to collect observed css rules\n\t\t\t\tif (node.nodeType === 1 && node.sheet) {\n\t\t\t\t\twalkStyleSheet(node.sheet);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// transform observed css rules\n\t\t\tcleanupObservedCssRules();\n\t\t\ttransformObservedItems();\n\t\t});\n\t});\n\n\tmutationObserver.observe(document, { childList: true, subtree: true });\n\n\t// observe DOM events that affect pseudo-selectors\n\tdocument.addEventListener('focus', transformObservedItems, true);\n\tdocument.addEventListener('blur', transformObservedItems, true);\n\tdocument.addEventListener('input', transformObservedItems);\n\n\t// transform observed css rules\n\tfunction transformObservedItems () {\n\t\trequestAnimationFrame(() => {\n\t\t\tobservedItems.forEach(\n\t\t\t\titem => {\n\t\t\t\t\tconst nodes = [];\n\n\t\t\t\t\t[].forEach.call(\n\t\t\t\t\t\tdocument.querySelectorAll(item.scopeSelector),\n\t\t\t\t\t\telement => {\n\t\t\t\t\t\t\tconst nthChild = [].indexOf.call(element.parentNode.children, element) + 1;\n\t\t\t\t\t\t\tconst relativeSelectors = item.relativeSelectors.map(\n\t\t\t\t\t\t\t\trelativeSelector => item.scopeSelector + ':nth-child(' + nthChild + ') ' + relativeSelector\n\t\t\t\t\t\t\t).join();\n\n\t\t\t\t\t\t\t// find any relative :has element from the :scope element\n\t\t\t\t\t\t\tconst relativeElement = element.parentNode.querySelector(relativeSelectors);\n\n\t\t\t\t\t\t\tconst shouldElementMatch = item.isNot ? !relativeElement : relativeElement;\n\n\t\t\t\t\t\t\tif (shouldElementMatch) {\n\t\t\t\t\t\t\t\t// memorize the node\n\t\t\t\t\t\t\t\tnodes.push(element);\n\n\t\t\t\t\t\t\t\t// set an attribute with an irregular attribute name\n\t\t\t\t\t\t\t\t// document.createAttribute() doesn't support special characters\n\t\t\t\t\t\t\t\tattributeElement.innerHTML = '<x ' + item.attributeName + '>';\n\n\t\t\t\t\t\t\t\telement.setAttributeNode(attributeElement.children[0].attributes[0].cloneNode());\n\n\t\t\t\t\t\t\t\t// trigger a style refresh in IE and Edge\n\t\t\t\t\t\t\t\tdocument.documentElement.style.zoom = 1; document.documentElement.style.zoom = null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\n\t\t\t\t\t// remove the encoded attribute from all nodes that no longer match them\n\t\t\t\t\titem.nodes.forEach(node => {\n\t\t\t\t\t\tif (nodes.indexOf(node) === -1) {\n\t\t\t\t\t\t\tnode.removeAttribute(item.attributeName);\n\n\t\t\t\t\t\t\t// trigger a style refresh in IE and Edge\n\t\t\t\t\t\t\tdocument.documentElement.style.zoom = 1; document.documentElement.style.zoom = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\t// update the\n\t\t\t\t\titem.nodes = nodes;\n\t\t\t\t}\n\t\t\t);\n\t\t});\n\t}\n\n\t// remove any observed cssrules that no longer apply\n\tfunction cleanupObservedCssRules () {\n\t\t[].push.apply(\n\t\t\tobservedItems,\n\t\t\tobservedItems.splice(0).filter(\n\t\t\t\titem => item.rule.parentStyleSheet &&\n\t\t\t\t\titem.rule.parentStyleSheet.ownerNode &&\n\t\t\t\t\tdocument.documentElement.contains(item.rule.parentStyleSheet.ownerNode)\n\t\t\t)\n\t\t);\n\t}\n\n\t// walk a stylesheet to collect observed css rules\n\tfunction walkStyleSheet (styleSheet) {\n\t\ttry {\n\t\t\t// walk a css rule to collect observed css rules\n\t\t\t[].forEach.call(styleSheet.cssRules || [], rule => {\n\t\t\t\tif (rule.selectorText) {\n\t\t\t\t\t// decode the selector text in all browsers to:\n\t\t\t\t\t// [1] = :scope, [2] = :not(:has), [3] = :has relative, [4] = :scope relative\n\t\t\t\t\tconst selectors = decodeURIComponent(rule.selectorText.replace(/\\\\(.)/g, '$1')).match(/^(.*?)\\[:(not-)?has\\((.+?)\\)\\](.*?)$/);\n\n\t\t\t\t\tif (selectors) {\n\t\t\t\t\t\tconst attributeName = ':' + (selectors[2] ? 'not-' : '') + 'has(' +\n\t\t\t\t\t\t\t// encode a :has() pseudo selector as an attribute name\n\t\t\t\t\t\t\tencodeURIComponent(selectors[3]).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',') +\n\t\t\t\t\t\t')';\n\n\t\t\t\t\t\tobservedItems.push({\n\t\t\t\t\t\t\trule,\n\t\t\t\t\t\t\tscopeSelector: selectors[1],\n\t\t\t\t\t\t\tisNot: selectors[2],\n\t\t\t\t\t\t\trelativeSelectors: selectors[3].split(/\\s*,\\s*/),\n\t\t\t\t\t\t\tattributeName,\n\t\t\t\t\t\t\tnodes: []\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\twalkStyleSheet(rule);\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (error) {\n\t\t\t/* do nothing and continue */\n\t\t}\n\t}\n}\n"],"names":["cssHasPseudo","document","observedItems","attributeElement","createElement","forEach","call","styleSheets","walkStyleSheet","transformObservedItems","mutationObserver","MutationObserver","mutationsList","mutation","addedNodes","node","nodeType","sheet","cleanupObservedCssRules","observe","childList","subtree","addEventListener","requestAnimationFrame","item","nodes","querySelectorAll","scopeSelector","element","nthChild","indexOf","parentNode","children","relativeSelectors","map","relativeSelector","join","relativeElement","querySelector","shouldElementMatch","isNot","push","innerHTML","attributeName","setAttributeNode","attributes","cloneNode","documentElement","style","zoom","removeAttribute","apply","splice","filter","rule","parentStyleSheet","ownerNode","contains","styleSheet","cssRules","selectorText","selectors","decodeURIComponent","replace","match","encodeURIComponent","split","error"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["src/browser.js"],"sourcesContent":["export default function cssHasPseudo (document) {\n\tconst observedItems = [];\n\n\t// document.createAttribute() doesn't support `:` in the name. innerHTML does\n\tconst attributeElement = document.createElement('x');\n\n\t// walk all stylesheets to collect observed css rules\n\t[].forEach.call(document.styleSheets, walkStyleSheet);\n\ttransformObservedItems();\n\n\t// observe DOM modifications that affect selectors\n\tconst mutationObserver = new MutationObserver(mutationsList => {\n\t\tmutationsList.forEach(mutation => {\n\t\t\t[].forEach.call(mutation.addedNodes || [], node => {\n\t\t\t\t// walk stylesheets to collect observed css rules\n\t\t\t\tif (node.nodeType === 1 && node.sheet) {\n\t\t\t\t\twalkStyleSheet(node.sheet);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// transform observed css rules\n\t\t\tcleanupObservedCssRules();\n\t\t\ttransformObservedItems();\n\t\t});\n\t});\n\n\tmutationObserver.observe(document, { childList: true, subtree: true });\n\n\t// observe DOM events that affect pseudo-selectors\n\tdocument.addEventListener('focus', transformObservedItems, true);\n\tdocument.addEventListener('blur', transformObservedItems, true);\n\tdocument.addEventListener('input', transformObservedItems);\n\n\t// transform observed css rules\n\tfunction transformObservedItems () {\n\t\trequestAnimationFrame(() => {\n\t\t\tobservedItems.forEach(\n\t\t\t\titem => {\n\t\t\t\t\tconst nodes = [];\n\n\t\t\t\t\t[].forEach.call(\n\t\t\t\t\t\tdocument.querySelectorAll(item.scopeSelector),\n\t\t\t\t\t\telement => {\n\t\t\t\t\t\t\tconst nthChild = [].indexOf.call(element.parentNode.children, element) + 1;\n\t\t\t\t\t\t\tconst relativeSelectors = item.relativeSelectors.map(\n\t\t\t\t\t\t\t\trelativeSelector => item.scopeSelector + ':nth-child(' + nthChild + ') ' + relativeSelector\n\t\t\t\t\t\t\t).join();\n\n\t\t\t\t\t\t\t// find any relative :has element from the :scope element\n\t\t\t\t\t\t\tconst relativeElement = element.parentNode.querySelector(relativeSelectors);\n\n\t\t\t\t\t\t\tconst shouldElementMatch = item.isNot ? !relativeElement : relativeElement;\n\n\t\t\t\t\t\t\tif (shouldElementMatch) {\n\t\t\t\t\t\t\t\t// memorize the node\n\t\t\t\t\t\t\t\tnodes.push(element);\n\n\t\t\t\t\t\t\t\t// set an attribute with an irregular attribute name\n\t\t\t\t\t\t\t\t// document.createAttribute() doesn't support special characters\n\t\t\t\t\t\t\t\tattributeElement.innerHTML = '<x ' + item.attributeName + '>';\n\n\t\t\t\t\t\t\t\telement.setAttributeNode(attributeElement.children[0].attributes[0].cloneNode());\n\n\t\t\t\t\t\t\t\t// trigger a style refresh in IE and Edge\n\t\t\t\t\t\t\t\tdocument.documentElement.style.zoom = 1; document.documentElement.style.zoom = null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\n\t\t\t\t\t// remove the encoded attribute from all nodes that no longer match them\n\t\t\t\t\titem.nodes.forEach(node => {\n\t\t\t\t\t\tif (nodes.indexOf(node) === -1) {\n\t\t\t\t\t\t\tnode.removeAttribute(item.attributeName);\n\n\t\t\t\t\t\t\t// trigger a style refresh in IE and Edge\n\t\t\t\t\t\t\tdocument.documentElement.style.zoom = 1; document.documentElement.style.zoom = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\t// update the\n\t\t\t\t\titem.nodes = nodes;\n\t\t\t\t}\n\t\t\t);\n\t\t});\n\t}\n\n\t// remove any observed cssrules that no longer apply\n\tfunction cleanupObservedCssRules () {\n\t\t[].push.apply(\n\t\t\tobservedItems,\n\t\t\tobservedItems.splice(0).filter(\n\t\t\t\titem => item.rule.parentStyleSheet &&\n\t\t\t\t\titem.rule.parentStyleSheet.ownerNode &&\n\t\t\t\t\tdocument.documentElement.contains(item.rule.parentStyleSheet.ownerNode)\n\t\t\t)\n\t\t);\n\t}\n\n\t// walk a stylesheet to collect observed css rules\n\tfunction walkStyleSheet (styleSheet) {\n\t\ttry {\n\t\t\t// walk a css rule to collect observed css rules\n\t\t\t[].forEach.call(styleSheet.cssRules || [], rule => {\n\t\t\t\tif (rule.selectorText) {\n\t\t\t\t\t// decode the selector text in all browsers to:\n\t\t\t\t\t// [1] = :scope, [2] = :not(:has), [3] = :has relative, [4] = :scope relative\n\t\t\t\t\tconst selectors = decodeURIComponent(rule.selectorText.replace(/\\\\(.)/g, '$1')).match(/^(.*?)\\[:(not-)?has\\((.+?)\\)\\](.*?)$/);\n\n\t\t\t\t\tif (selectors) {\n\t\t\t\t\t\tconst attributeName = ':' + (selectors[2] ? 'not-' : '') + 'has(' +\n\t\t\t\t\t\t\t// encode a :has() pseudo selector as an attribute name\n\t\t\t\t\t\t\tencodeURIComponent(selectors[3]).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',') +\n\t\t\t\t\t\t')';\n\n\t\t\t\t\t\tobservedItems.push({\n\t\t\t\t\t\t\trule,\n\t\t\t\t\t\t\tscopeSelector: selectors[1],\n\t\t\t\t\t\t\tisNot: selectors[2],\n\t\t\t\t\t\t\trelativeSelectors: selectors[3].split(/\\s*,\\s*/),\n\t\t\t\t\t\t\tattributeName,\n\t\t\t\t\t\t\tnodes: []\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\twalkStyleSheet(rule);\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (error) {\n\t\t\t/* do nothing and continue */\n\t\t}\n\t}\n}\n"],"names":["cssHasPseudo","document","observedItems","attributeElement","createElement","forEach","call","styleSheets","walkStyleSheet","transformObservedItems","mutationObserver","MutationObserver","mutationsList","mutation","addedNodes","node","nodeType","sheet","cleanupObservedCssRules","observe","childList","subtree","addEventListener","requestAnimationFrame","item","nodes","querySelectorAll","scopeSelector","element","nthChild","indexOf","parentNode","children","relativeSelectors","map","relativeSelector","join","relativeElement","querySelector","shouldElementMatch","isNot","push","innerHTML","attributeName","setAttributeNode","attributes","cloneNode","documentElement","style","zoom","removeAttribute","apply","splice","filter","rule","parentStyleSheet","ownerNode","contains","styleSheet","cssRules","selectorText","selectors","decodeURIComponent","replace","match","encodeURIComponent","split","error"],"mappings":"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"}
package/index.mjs CHANGED
@@ -103,5 +103,5 @@ function cssHasPseudo(document) {
103
103
  }
104
104
  }
105
105
 
106
- export default cssHasPseudo;
106
+ export { cssHasPseudo as default };
107
107
  //# sourceMappingURL=index.mjs.map
package/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["src/browser.js"],"sourcesContent":["export default function cssHasPseudo (document) {\n\tconst observedItems = [];\n\n\t// document.createAttribute() doesn't support `:` in the name. innerHTML does\n\tconst attributeElement = document.createElement('x');\n\n\t// walk all stylesheets to collect observed css rules\n\t[].forEach.call(document.styleSheets, walkStyleSheet);\n\ttransformObservedItems();\n\n\t// observe DOM modifications that affect selectors\n\tconst mutationObserver = new MutationObserver(mutationsList => {\n\t\tmutationsList.forEach(mutation => {\n\t\t\t[].forEach.call(mutation.addedNodes || [], node => {\n\t\t\t\t// walk stylesheets to collect observed css rules\n\t\t\t\tif (node.nodeType === 1 && node.sheet) {\n\t\t\t\t\twalkStyleSheet(node.sheet);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// transform observed css rules\n\t\t\tcleanupObservedCssRules();\n\t\t\ttransformObservedItems();\n\t\t});\n\t});\n\n\tmutationObserver.observe(document, { childList: true, subtree: true });\n\n\t// observe DOM events that affect pseudo-selectors\n\tdocument.addEventListener('focus', transformObservedItems, true);\n\tdocument.addEventListener('blur', transformObservedItems, true);\n\tdocument.addEventListener('input', transformObservedItems);\n\n\t// transform observed css rules\n\tfunction transformObservedItems () {\n\t\trequestAnimationFrame(() => {\n\t\t\tobservedItems.forEach(\n\t\t\t\titem => {\n\t\t\t\t\tconst nodes = [];\n\n\t\t\t\t\t[].forEach.call(\n\t\t\t\t\t\tdocument.querySelectorAll(item.scopeSelector),\n\t\t\t\t\t\telement => {\n\t\t\t\t\t\t\tconst nthChild = [].indexOf.call(element.parentNode.children, element) + 1;\n\t\t\t\t\t\t\tconst relativeSelectors = item.relativeSelectors.map(\n\t\t\t\t\t\t\t\trelativeSelector => item.scopeSelector + ':nth-child(' + nthChild + ') ' + relativeSelector\n\t\t\t\t\t\t\t).join();\n\n\t\t\t\t\t\t\t// find any relative :has element from the :scope element\n\t\t\t\t\t\t\tconst relativeElement = element.parentNode.querySelector(relativeSelectors);\n\n\t\t\t\t\t\t\tconst shouldElementMatch = item.isNot ? !relativeElement : relativeElement;\n\n\t\t\t\t\t\t\tif (shouldElementMatch) {\n\t\t\t\t\t\t\t\t// memorize the node\n\t\t\t\t\t\t\t\tnodes.push(element);\n\n\t\t\t\t\t\t\t\t// set an attribute with an irregular attribute name\n\t\t\t\t\t\t\t\t// document.createAttribute() doesn't support special characters\n\t\t\t\t\t\t\t\tattributeElement.innerHTML = '<x ' + item.attributeName + '>';\n\n\t\t\t\t\t\t\t\telement.setAttributeNode(attributeElement.children[0].attributes[0].cloneNode());\n\n\t\t\t\t\t\t\t\t// trigger a style refresh in IE and Edge\n\t\t\t\t\t\t\t\tdocument.documentElement.style.zoom = 1; document.documentElement.style.zoom = null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\n\t\t\t\t\t// remove the encoded attribute from all nodes that no longer match them\n\t\t\t\t\titem.nodes.forEach(node => {\n\t\t\t\t\t\tif (nodes.indexOf(node) === -1) {\n\t\t\t\t\t\t\tnode.removeAttribute(item.attributeName);\n\n\t\t\t\t\t\t\t// trigger a style refresh in IE and Edge\n\t\t\t\t\t\t\tdocument.documentElement.style.zoom = 1; document.documentElement.style.zoom = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\t// update the\n\t\t\t\t\titem.nodes = nodes;\n\t\t\t\t}\n\t\t\t);\n\t\t});\n\t}\n\n\t// remove any observed cssrules that no longer apply\n\tfunction cleanupObservedCssRules () {\n\t\t[].push.apply(\n\t\t\tobservedItems,\n\t\t\tobservedItems.splice(0).filter(\n\t\t\t\titem => item.rule.parentStyleSheet &&\n\t\t\t\t\titem.rule.parentStyleSheet.ownerNode &&\n\t\t\t\t\tdocument.documentElement.contains(item.rule.parentStyleSheet.ownerNode)\n\t\t\t)\n\t\t);\n\t}\n\n\t// walk a stylesheet to collect observed css rules\n\tfunction walkStyleSheet (styleSheet) {\n\t\ttry {\n\t\t\t// walk a css rule to collect observed css rules\n\t\t\t[].forEach.call(styleSheet.cssRules || [], rule => {\n\t\t\t\tif (rule.selectorText) {\n\t\t\t\t\t// decode the selector text in all browsers to:\n\t\t\t\t\t// [1] = :scope, [2] = :not(:has), [3] = :has relative, [4] = :scope relative\n\t\t\t\t\tconst selectors = decodeURIComponent(rule.selectorText.replace(/\\\\(.)/g, '$1')).match(/^(.*?)\\[:(not-)?has\\((.+?)\\)\\](.*?)$/);\n\n\t\t\t\t\tif (selectors) {\n\t\t\t\t\t\tconst attributeName = ':' + (selectors[2] ? 'not-' : '') + 'has(' +\n\t\t\t\t\t\t\t// encode a :has() pseudo selector as an attribute name\n\t\t\t\t\t\t\tencodeURIComponent(selectors[3]).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',') +\n\t\t\t\t\t\t')';\n\n\t\t\t\t\t\tobservedItems.push({\n\t\t\t\t\t\t\trule,\n\t\t\t\t\t\t\tscopeSelector: selectors[1],\n\t\t\t\t\t\t\tisNot: selectors[2],\n\t\t\t\t\t\t\trelativeSelectors: selectors[3].split(/\\s*,\\s*/),\n\t\t\t\t\t\t\tattributeName,\n\t\t\t\t\t\t\tnodes: []\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\twalkStyleSheet(rule);\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (error) {\n\t\t\t/* do nothing and continue */\n\t\t}\n\t}\n}\n"],"names":["cssHasPseudo","document","observedItems","attributeElement","createElement","forEach","call","styleSheets","walkStyleSheet","transformObservedItems","mutationObserver","MutationObserver","mutationsList","mutation","addedNodes","node","nodeType","sheet","cleanupObservedCssRules","observe","childList","subtree","addEventListener","requestAnimationFrame","item","nodes","querySelectorAll","scopeSelector","element","nthChild","indexOf","parentNode","children","relativeSelectors","map","relativeSelector","join","relativeElement","querySelector","shouldElementMatch","isNot","push","innerHTML","attributeName","setAttributeNode","attributes","cloneNode","documentElement","style","zoom","removeAttribute","apply","splice","filter","rule","parentStyleSheet","ownerNode","contains","styleSheet","cssRules","selectorText","selectors","decodeURIComponent","replace","match","encodeURIComponent","split","error"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["src/browser.js"],"sourcesContent":["export default function cssHasPseudo (document) {\n\tconst observedItems = [];\n\n\t// document.createAttribute() doesn't support `:` in the name. innerHTML does\n\tconst attributeElement = document.createElement('x');\n\n\t// walk all stylesheets to collect observed css rules\n\t[].forEach.call(document.styleSheets, walkStyleSheet);\n\ttransformObservedItems();\n\n\t// observe DOM modifications that affect selectors\n\tconst mutationObserver = new MutationObserver(mutationsList => {\n\t\tmutationsList.forEach(mutation => {\n\t\t\t[].forEach.call(mutation.addedNodes || [], node => {\n\t\t\t\t// walk stylesheets to collect observed css rules\n\t\t\t\tif (node.nodeType === 1 && node.sheet) {\n\t\t\t\t\twalkStyleSheet(node.sheet);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// transform observed css rules\n\t\t\tcleanupObservedCssRules();\n\t\t\ttransformObservedItems();\n\t\t});\n\t});\n\n\tmutationObserver.observe(document, { childList: true, subtree: true });\n\n\t// observe DOM events that affect pseudo-selectors\n\tdocument.addEventListener('focus', transformObservedItems, true);\n\tdocument.addEventListener('blur', transformObservedItems, true);\n\tdocument.addEventListener('input', transformObservedItems);\n\n\t// transform observed css rules\n\tfunction transformObservedItems () {\n\t\trequestAnimationFrame(() => {\n\t\t\tobservedItems.forEach(\n\t\t\t\titem => {\n\t\t\t\t\tconst nodes = [];\n\n\t\t\t\t\t[].forEach.call(\n\t\t\t\t\t\tdocument.querySelectorAll(item.scopeSelector),\n\t\t\t\t\t\telement => {\n\t\t\t\t\t\t\tconst nthChild = [].indexOf.call(element.parentNode.children, element) + 1;\n\t\t\t\t\t\t\tconst relativeSelectors = item.relativeSelectors.map(\n\t\t\t\t\t\t\t\trelativeSelector => item.scopeSelector + ':nth-child(' + nthChild + ') ' + relativeSelector\n\t\t\t\t\t\t\t).join();\n\n\t\t\t\t\t\t\t// find any relative :has element from the :scope element\n\t\t\t\t\t\t\tconst relativeElement = element.parentNode.querySelector(relativeSelectors);\n\n\t\t\t\t\t\t\tconst shouldElementMatch = item.isNot ? !relativeElement : relativeElement;\n\n\t\t\t\t\t\t\tif (shouldElementMatch) {\n\t\t\t\t\t\t\t\t// memorize the node\n\t\t\t\t\t\t\t\tnodes.push(element);\n\n\t\t\t\t\t\t\t\t// set an attribute with an irregular attribute name\n\t\t\t\t\t\t\t\t// document.createAttribute() doesn't support special characters\n\t\t\t\t\t\t\t\tattributeElement.innerHTML = '<x ' + item.attributeName + '>';\n\n\t\t\t\t\t\t\t\telement.setAttributeNode(attributeElement.children[0].attributes[0].cloneNode());\n\n\t\t\t\t\t\t\t\t// trigger a style refresh in IE and Edge\n\t\t\t\t\t\t\t\tdocument.documentElement.style.zoom = 1; document.documentElement.style.zoom = null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\n\t\t\t\t\t// remove the encoded attribute from all nodes that no longer match them\n\t\t\t\t\titem.nodes.forEach(node => {\n\t\t\t\t\t\tif (nodes.indexOf(node) === -1) {\n\t\t\t\t\t\t\tnode.removeAttribute(item.attributeName);\n\n\t\t\t\t\t\t\t// trigger a style refresh in IE and Edge\n\t\t\t\t\t\t\tdocument.documentElement.style.zoom = 1; document.documentElement.style.zoom = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\t// update the\n\t\t\t\t\titem.nodes = nodes;\n\t\t\t\t}\n\t\t\t);\n\t\t});\n\t}\n\n\t// remove any observed cssrules that no longer apply\n\tfunction cleanupObservedCssRules () {\n\t\t[].push.apply(\n\t\t\tobservedItems,\n\t\t\tobservedItems.splice(0).filter(\n\t\t\t\titem => item.rule.parentStyleSheet &&\n\t\t\t\t\titem.rule.parentStyleSheet.ownerNode &&\n\t\t\t\t\tdocument.documentElement.contains(item.rule.parentStyleSheet.ownerNode)\n\t\t\t)\n\t\t);\n\t}\n\n\t// walk a stylesheet to collect observed css rules\n\tfunction walkStyleSheet (styleSheet) {\n\t\ttry {\n\t\t\t// walk a css rule to collect observed css rules\n\t\t\t[].forEach.call(styleSheet.cssRules || [], rule => {\n\t\t\t\tif (rule.selectorText) {\n\t\t\t\t\t// decode the selector text in all browsers to:\n\t\t\t\t\t// [1] = :scope, [2] = :not(:has), [3] = :has relative, [4] = :scope relative\n\t\t\t\t\tconst selectors = decodeURIComponent(rule.selectorText.replace(/\\\\(.)/g, '$1')).match(/^(.*?)\\[:(not-)?has\\((.+?)\\)\\](.*?)$/);\n\n\t\t\t\t\tif (selectors) {\n\t\t\t\t\t\tconst attributeName = ':' + (selectors[2] ? 'not-' : '') + 'has(' +\n\t\t\t\t\t\t\t// encode a :has() pseudo selector as an attribute name\n\t\t\t\t\t\t\tencodeURIComponent(selectors[3]).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',') +\n\t\t\t\t\t\t')';\n\n\t\t\t\t\t\tobservedItems.push({\n\t\t\t\t\t\t\trule,\n\t\t\t\t\t\t\tscopeSelector: selectors[1],\n\t\t\t\t\t\t\tisNot: selectors[2],\n\t\t\t\t\t\t\trelativeSelectors: selectors[3].split(/\\s*,\\s*/),\n\t\t\t\t\t\t\tattributeName,\n\t\t\t\t\t\t\tnodes: []\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\twalkStyleSheet(rule);\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (error) {\n\t\t\t/* do nothing and continue */\n\t\t}\n\t}\n}\n"],"names":["cssHasPseudo","document","observedItems","attributeElement","createElement","forEach","call","styleSheets","walkStyleSheet","transformObservedItems","mutationObserver","MutationObserver","mutationsList","mutation","addedNodes","node","nodeType","sheet","cleanupObservedCssRules","observe","childList","subtree","addEventListener","requestAnimationFrame","item","nodes","querySelectorAll","scopeSelector","element","nthChild","indexOf","parentNode","children","relativeSelectors","map","relativeSelector","join","relativeElement","querySelector","shouldElementMatch","isNot","push","innerHTML","attributeName","setAttributeNode","attributes","cloneNode","documentElement","style","zoom","removeAttribute","apply","splice","filter","rule","parentStyleSheet","ownerNode","contains","styleSheet","cssRules","selectorText","selectors","decodeURIComponent","replace","match","encodeURIComponent","split","error"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "css-has-pseudo",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "Style elements relative to other elements in CSS",
5
5
  "author": "Jonathan Neal <jonathantneal@hotmail.com>",
6
6
  "license": "CC0-1.0",
@@ -37,23 +37,25 @@
37
37
  "test:postcss": "postcss-tape --plugin postcss.js"
38
38
  },
39
39
  "engines": {
40
- "node": ">=8.0.0"
40
+ "node": ">=12"
41
+ },
42
+ "peerDependencies": {
43
+ "postcss": ">=8.3"
41
44
  },
42
45
  "dependencies": {
43
- "postcss": "^7.0.17",
44
- "postcss-selector-parser": "^6.0.2"
46
+ "postcss-selector-parser": "^6"
45
47
  },
46
48
  "devDependencies": {
47
- "@babel/core": "^7.4.5",
48
- "@babel/preset-env": "^7.4.5",
49
- "babel-eslint": "^10.0.1",
50
- "cross-env": "^5.2.0",
51
- "eslint": "^5.16.0",
52
- "postcss-tape": "^5.0.0",
53
- "pre-commit": "^1.2.2",
54
- "rollup": "^1.14.6",
55
- "rollup-plugin-babel": "^4.3.2",
56
- "rollup-plugin-terser": "^5.0.0"
49
+ "@babel/core": "7.15.5",
50
+ "@babel/preset-env": "7.15.6",
51
+ "@rollup/plugin-babel": "5.3.0",
52
+ "cross-env": "7.0.3",
53
+ "eslint": "7.32.0",
54
+ "postcss": "8.3.4",
55
+ "postcss-tape": "6.0.1",
56
+ "pre-commit": "1.2.2",
57
+ "rollup": "2.56.3",
58
+ "rollup-plugin-terser": "7.0.2"
57
59
  },
58
60
  "eslintConfig": {
59
61
  "env": {
@@ -62,10 +64,8 @@
62
64
  "node": true
63
65
  },
64
66
  "extends": "eslint:recommended",
65
- "parser": "babel-eslint",
66
67
  "parserOptions": {
67
- "ecmaVersion": 2018,
68
- "impliedStrict": true,
68
+ "ecmaVersion": 2020,
69
69
  "sourceType": "module"
70
70
  },
71
71
  "root": true
package/postcss.js CHANGED
@@ -1,48 +1,73 @@
1
1
  'use strict';
2
2
 
3
- function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
4
-
5
- var parser = _interopDefault(require('postcss-selector-parser'));
6
- var postcss$1 = _interopDefault(require('postcss'));
7
-
8
- const selectorRegExp = /:has/;
9
- var postcss = postcss$1.plugin('css-has-pseudo', opts => {
10
- const preserve = Boolean('preserve' in Object(opts) ? opts.preserve : true);
11
- return root => {
12
- root.walkRules(selectorRegExp, rule => {
13
- const modifiedSelector = parser(selectors => {
14
- selectors.walkPseudos(selector => {
15
- if (selector.value === ':has' && selector.nodes) {
16
- const isNotHas = checkIfParentIsNot(selector);
17
- selector.value = isNotHas ? ':not-has' : ':has';
18
- const attribute = parser.attribute({
19
- attribute: encodeURIComponent(String(selector)).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',').replace(/[():%[\],]/g, '\\$&')
20
- });
21
-
22
- if (isNotHas) {
23
- selector.parent.parent.replaceWith(attribute);
24
- } else {
25
- selector.replaceWith(attribute);
26
- }
27
- }
3
+ var parser = require('postcss-selector-parser');
4
+
5
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
6
+
7
+ var parser__default = /*#__PURE__*/_interopDefaultLegacy(parser);
8
+
9
+ const creator = (
10
+ /** @type {{ preserve: true | false }} */
11
+ opts) => {
12
+ opts = typeof opts === 'object' && opts || defaultOptions;
13
+ /** Whether the original rule should be preserved. */
14
+
15
+ const shouldPreserve = Boolean('preserve' in opts ? opts.preserve : true);
16
+ return {
17
+ postcssPlugin: 'css-has-pseudo',
18
+ Rule: rule => {
19
+ if (rule.selector.includes(':has(')) {
20
+ const fallbackSelector = getFallbackSelector(rule.selector);
21
+ if (shouldPreserve) rule.cloneBefore({
22
+ selector: fallbackSelector
23
+ });else rule.assign({
24
+ selector: fallbackSelector
28
25
  });
29
- }).processSync(rule.selector);
30
- const clone = rule.clone({
31
- selector: modifiedSelector
26
+ }
27
+ }
28
+ };
29
+ };
30
+
31
+ creator.postcss = true;
32
+
33
+ const getFallbackSelector = (
34
+ /** @type {string} */
35
+ selectorText) => parser__default['default'](selectors => {
36
+ selectors.walkPseudos(selector => {
37
+ if (selector.value === ':has' && selector.nodes) {
38
+ const isNotHas = isParentInNotPseudo(selector);
39
+ selector.value = isNotHas ? ':not-has' : ':has';
40
+ const attribute = parser__default['default'].attribute({
41
+ attribute: getEscapedCss(String(selector))
32
42
  });
33
43
 
34
- if (preserve) {
35
- rule.before(clone);
44
+ if (isNotHas) {
45
+ selector.parent.parent.replaceWith(attribute);
36
46
  } else {
37
- rule.replaceWith(clone);
47
+ selector.replaceWith(attribute);
38
48
  }
39
- });
40
- };
41
- });
49
+ }
50
+ });
51
+ }).processSync(selectorText);
52
+ /** Default options. */
53
+
54
+
55
+ const defaultOptions = {
56
+ preserve: true
57
+ };
58
+ /** Returns the string as an escaped CSS identifier. */
59
+
60
+ const getEscapedCss = (
61
+ /** @type {string} */
62
+ value) => encodeURIComponent(value).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',').replace(/[():%[\],]/g, '\\$&');
63
+ /** Returns whether the selector is within a `:not` pseudo-class. */
64
+
65
+
66
+ const isParentInNotPseudo = selector => {
67
+ var _selector$parent, _selector$parent$pare;
42
68
 
43
- function checkIfParentIsNot(selector) {
44
- return Object(Object(selector.parent).parent).type === 'pseudo' && selector.parent.parent.value === ':not';
45
- }
69
+ return ((_selector$parent = selector.parent) === null || _selector$parent === void 0 ? void 0 : (_selector$parent$pare = _selector$parent.parent) === null || _selector$parent$pare === void 0 ? void 0 : _selector$parent$pare.type) === 'pseudo' && selector.parent.parent.value === ':not';
70
+ };
46
71
 
47
- module.exports = postcss;
72
+ module.exports = creator;
48
73
  //# sourceMappingURL=postcss.js.map
package/postcss.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"postcss.js","sources":["src/postcss.js"],"sourcesContent":["import parser from 'postcss-selector-parser';\nimport postcss from 'postcss';\n\nconst selectorRegExp = /:has/;\n\nexport default postcss.plugin('css-has-pseudo', opts => {\n\tconst preserve = Boolean('preserve' in Object(opts) ? opts.preserve : true);\n\n\treturn root => {\n\t\troot.walkRules(selectorRegExp, rule => {\n\t\t\tconst modifiedSelector = parser(selectors => {\n\t\t\t\tselectors.walkPseudos(selector => {\n\t\t\t\t\tif (selector.value === ':has' && selector.nodes) {\n\t\t\t\t\t\tconst isNotHas = checkIfParentIsNot(selector);\n\t\t\t\t\t\tselector.value = isNotHas ? ':not-has' : ':has';\n\n\t\t\t\t\t\tconst attribute = parser.attribute({\n\t\t\t\t\t\t\tattribute: encodeURIComponent(String(selector))\n\t\t\t\t\t\t\t.replace(/%3A/g, ':')\n\t\t\t\t\t\t\t.replace(/%5B/g, '[')\n\t\t\t\t\t\t\t.replace(/%5D/g, ']')\n\t\t\t\t\t\t\t.replace(/%2C/g, ',')\n\t\t\t\t\t\t\t.replace(/[():%[\\],]/g, '\\\\$&')\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (isNotHas) {\n\t\t\t\t\t\t\tselector.parent.parent.replaceWith(attribute);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tselector.replaceWith(attribute);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}).processSync(rule.selector);\n\n\t\t\tconst clone = rule.clone({ selector: modifiedSelector });\n\n\t\t\tif (preserve) {\n\t\t\t\trule.before(clone);\n\t\t\t} else {\n\t\t\t\trule.replaceWith(clone);\n\t\t\t}\n\t\t});\n\t};\n});\n\nfunction checkIfParentIsNot (selector) {\n\treturn Object(Object(selector.parent).parent).type === 'pseudo' && selector.parent.parent.value === ':not';\n}\n"],"names":["selectorRegExp","postcss","plugin","opts","preserve","Boolean","Object","root","walkRules","rule","modifiedSelector","parser","selectors","walkPseudos","selector","value","nodes","isNotHas","checkIfParentIsNot","attribute","encodeURIComponent","String","replace","parent","replaceWith","processSync","clone","before","type"],"mappings":";;;;;;;AAGA,MAAMA,cAAc,GAAG,MAAvB;AAEA,cAAeC,SAAO,CAACC,MAAR,CAAe,gBAAf,EAAiCC,IAAI,IAAI;QACjDC,QAAQ,GAAGC,OAAO,CAAC,cAAcC,MAAM,CAACH,IAAD,CAApB,GAA6BA,IAAI,CAACC,QAAlC,GAA6C,IAA9C,CAAxB;SAEOG,IAAI,IAAI;IACdA,IAAI,CAACC,SAAL,CAAeR,cAAf,EAA+BS,IAAI,IAAI;YAChCC,gBAAgB,GAAGC,MAAM,CAACC,SAAS,IAAI;QAC5CA,SAAS,CAACC,WAAV,CAAsBC,QAAQ,IAAI;cAC7BA,QAAQ,CAACC,KAAT,KAAmB,MAAnB,IAA6BD,QAAQ,CAACE,KAA1C,EAAiD;kBAC1CC,QAAQ,GAAGC,kBAAkB,CAACJ,QAAD,CAAnC;YACAA,QAAQ,CAACC,KAAT,GAAiBE,QAAQ,GAAG,UAAH,GAAgB,MAAzC;kBAEME,SAAS,GAAGR,MAAM,CAACQ,SAAP,CAAiB;cAClCA,SAAS,EAAEC,kBAAkB,CAACC,MAAM,CAACP,QAAD,CAAP,CAAlB,CACVQ,OADU,CACF,MADE,EACM,GADN,EAEVA,OAFU,CAEF,MAFE,EAEM,GAFN,EAGVA,OAHU,CAGF,MAHE,EAGM,GAHN,EAIVA,OAJU,CAIF,MAJE,EAIM,GAJN,EAKVA,OALU,CAKF,aALE,EAKa,MALb;aADM,CAAlB;;gBASIL,QAAJ,EAAc;cACbH,QAAQ,CAACS,MAAT,CAAgBA,MAAhB,CAAuBC,WAAvB,CAAmCL,SAAnC;aADD,MAEO;cACNL,QAAQ,CAACU,WAAT,CAAqBL,SAArB;;;SAjBH;OAD8B,CAAN,CAsBtBM,WAtBsB,CAsBVhB,IAAI,CAACK,QAtBK,CAAzB;YAwBMY,KAAK,GAAGjB,IAAI,CAACiB,KAAL,CAAW;QAAEZ,QAAQ,EAAEJ;OAAvB,CAAd;;UAEIN,QAAJ,EAAc;QACbK,IAAI,CAACkB,MAAL,CAAYD,KAAZ;OADD,MAEO;QACNjB,IAAI,CAACe,WAAL,CAAiBE,KAAjB;;KA9BF;GADD;CAHc,CAAf;;AAwCA,SAASR,kBAAT,CAA6BJ,QAA7B,EAAuC;SAC/BR,MAAM,CAACA,MAAM,CAACQ,QAAQ,CAACS,MAAV,CAAN,CAAwBA,MAAzB,CAAN,CAAuCK,IAAvC,KAAgD,QAAhD,IAA4Dd,QAAQ,CAACS,MAAT,CAAgBA,MAAhB,CAAuBR,KAAvB,KAAiC,MAApG;;;;;"}
1
+ {"version":3,"file":"postcss.js","sources":["src/postcss.js"],"sourcesContent":["import parser from 'postcss-selector-parser'\n\nconst creator = (/** @type {{ preserve: true | false }} */ opts) => {\n\topts = typeof opts === 'object' && opts || defaultOptions\n\n\t/** Whether the original rule should be preserved. */\n\tconst shouldPreserve = Boolean('preserve' in opts ? opts.preserve : true)\n\n\treturn {\n\t\tpostcssPlugin: 'css-has-pseudo',\n\t\tRule: rule => {\n\t\t\tif (rule.selector.includes(':has(')) {\n\t\t\t\tconst fallbackSelector = getFallbackSelector(rule.selector)\n\n\t\t\t\tif (shouldPreserve) rule.cloneBefore({ selector: fallbackSelector })\n\t\t\t\telse rule.assign({ selector: fallbackSelector })\n\t\t\t}\n\t\t},\n\t}\n}\n\ncreator.postcss = true\n\nconst getFallbackSelector = (/** @type {string} */ selectorText) => parser(selectors => {\n\tselectors.walkPseudos(selector => {\n\t\tif (selector.value === ':has' && selector.nodes) {\n\t\t\tconst isNotHas = isParentInNotPseudo(selector)\n\n\t\t\tselector.value = isNotHas ? ':not-has' : ':has'\n\n\t\t\tconst attribute = parser.attribute({\n\t\t\t\tattribute: getEscapedCss(String(selector))\n\t\t\t})\n\n\t\t\tif (isNotHas) {\n\t\t\t\tselector.parent.parent.replaceWith(attribute)\n\t\t\t} else {\n\t\t\t\tselector.replaceWith(attribute)\n\t\t\t}\n\t\t}\n\t})\n}).processSync(selectorText)\n\n/** Default options. */\nconst defaultOptions = { preserve: true }\n\n/** Returns the string as an escaped CSS identifier. */\nconst getEscapedCss = (/** @type {string} */ value) => encodeURIComponent(value).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',').replace(/[():%[\\],]/g, '\\\\$&')\n\n/** Returns whether the selector is within a `:not` pseudo-class. */\nconst isParentInNotPseudo = (selector) => selector.parent?.parent?.type === 'pseudo' && selector.parent.parent.value === ':not'\n\nexport default creator\n"],"names":["creator","opts","defaultOptions","shouldPreserve","Boolean","preserve","postcssPlugin","Rule","rule","selector","includes","fallbackSelector","getFallbackSelector","cloneBefore","assign","postcss","selectorText","parser","selectors","walkPseudos","value","nodes","isNotHas","isParentInNotPseudo","attribute","getEscapedCss","String","parent","replaceWith","processSync","encodeURIComponent","replace","type"],"mappings":";;;;;;;;MAEMA,OAAO,GAAG;AAAC;AAA0CC,IAA3C,KAAoD;AACnEA,EAAAA,IAAI,GAAG,OAAOA,IAAP,KAAgB,QAAhB,IAA4BA,IAA5B,IAAoCC,cAA3C;AAEA;;AACA,QAAMC,cAAc,GAAGC,OAAO,CAAC,cAAcH,IAAd,GAAqBA,IAAI,CAACI,QAA1B,GAAqC,IAAtC,CAA9B;AAEA,SAAO;AACNC,IAAAA,aAAa,EAAE,gBADT;AAENC,IAAAA,IAAI,EAAEC,IAAI,IAAI;AACb,UAAIA,IAAI,CAACC,QAAL,CAAcC,QAAd,CAAuB,OAAvB,CAAJ,EAAqC;AACpC,cAAMC,gBAAgB,GAAGC,mBAAmB,CAACJ,IAAI,CAACC,QAAN,CAA5C;AAEA,YAAIN,cAAJ,EAAoBK,IAAI,CAACK,WAAL,CAAiB;AAAEJ,UAAAA,QAAQ,EAAEE;AAAZ,SAAjB,EAApB,KACKH,IAAI,CAACM,MAAL,CAAY;AAAEL,UAAAA,QAAQ,EAAEE;AAAZ,SAAZ;AACL;AACD;AATK,GAAP;AAWA;;AAEDX,OAAO,CAACe,OAAR,GAAkB,IAAlB;;AAEA,MAAMH,mBAAmB,GAAG;AAAC;AAAsBI,YAAvB,KAAwCC,0BAAM,CAACC,SAAS,IAAI;AACvFA,EAAAA,SAAS,CAACC,WAAV,CAAsBV,QAAQ,IAAI;AACjC,QAAIA,QAAQ,CAACW,KAAT,KAAmB,MAAnB,IAA6BX,QAAQ,CAACY,KAA1C,EAAiD;AAChD,YAAMC,QAAQ,GAAGC,mBAAmB,CAACd,QAAD,CAApC;AAEAA,MAAAA,QAAQ,CAACW,KAAT,GAAiBE,QAAQ,GAAG,UAAH,GAAgB,MAAzC;AAEA,YAAME,SAAS,GAAGP,0BAAM,CAACO,SAAP,CAAiB;AAClCA,QAAAA,SAAS,EAAEC,aAAa,CAACC,MAAM,CAACjB,QAAD,CAAP;AADU,OAAjB,CAAlB;;AAIA,UAAIa,QAAJ,EAAc;AACbb,QAAAA,QAAQ,CAACkB,MAAT,CAAgBA,MAAhB,CAAuBC,WAAvB,CAAmCJ,SAAnC;AACA,OAFD,MAEO;AACNf,QAAAA,QAAQ,CAACmB,WAAT,CAAqBJ,SAArB;AACA;AACD;AACD,GAhBD;AAiBA,CAlByE,CAAN,CAkBjEK,WAlBiE,CAkBrDb,YAlBqD,CAApE;AAoBA;;;AACA,MAAMd,cAAc,GAAG;AAAEG,EAAAA,QAAQ,EAAE;AAAZ,CAAvB;AAEA;;AACA,MAAMoB,aAAa,GAAG;AAAC;AAAsBL,KAAvB,KAAiCU,kBAAkB,CAACV,KAAD,CAAlB,CAA0BW,OAA1B,CAAkC,MAAlC,EAA0C,GAA1C,EAA+CA,OAA/C,CAAuD,MAAvD,EAA+D,GAA/D,EAAoEA,OAApE,CAA4E,MAA5E,EAAoF,GAApF,EAAyFA,OAAzF,CAAiG,MAAjG,EAAyG,GAAzG,EAA8GA,OAA9G,CAAsH,aAAtH,EAAqI,MAArI,CAAvD;AAEA;;;AACA,MAAMR,mBAAmB,GAAId,QAAD;AAAA;;AAAA,SAAc,qBAAAA,QAAQ,CAACkB,MAAT,+FAAiBA,MAAjB,gFAAyBK,IAAzB,MAAkC,QAAlC,IAA8CvB,QAAQ,CAACkB,MAAT,CAAgBA,MAAhB,CAAuBP,KAAvB,KAAiC,MAA7F;AAAA,CAA5B;;;;"}
package/postcss.mjs CHANGED
@@ -1,44 +1,67 @@
1
1
  import parser from 'postcss-selector-parser';
2
- import postcss$1 from 'postcss';
3
-
4
- const selectorRegExp = /:has/;
5
- var postcss = postcss$1.plugin('css-has-pseudo', opts => {
6
- const preserve = Boolean('preserve' in Object(opts) ? opts.preserve : true);
7
- return root => {
8
- root.walkRules(selectorRegExp, rule => {
9
- const modifiedSelector = parser(selectors => {
10
- selectors.walkPseudos(selector => {
11
- if (selector.value === ':has' && selector.nodes) {
12
- const isNotHas = checkIfParentIsNot(selector);
13
- selector.value = isNotHas ? ':not-has' : ':has';
14
- const attribute = parser.attribute({
15
- attribute: encodeURIComponent(String(selector)).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',').replace(/[():%[\],]/g, '\\$&')
16
- });
17
-
18
- if (isNotHas) {
19
- selector.parent.parent.replaceWith(attribute);
20
- } else {
21
- selector.replaceWith(attribute);
22
- }
23
- }
2
+
3
+ const creator = (
4
+ /** @type {{ preserve: true | false }} */
5
+ opts) => {
6
+ opts = typeof opts === 'object' && opts || defaultOptions;
7
+ /** Whether the original rule should be preserved. */
8
+
9
+ const shouldPreserve = Boolean('preserve' in opts ? opts.preserve : true);
10
+ return {
11
+ postcssPlugin: 'css-has-pseudo',
12
+ Rule: rule => {
13
+ if (rule.selector.includes(':has(')) {
14
+ const fallbackSelector = getFallbackSelector(rule.selector);
15
+ if (shouldPreserve) rule.cloneBefore({
16
+ selector: fallbackSelector
17
+ });else rule.assign({
18
+ selector: fallbackSelector
24
19
  });
25
- }).processSync(rule.selector);
26
- const clone = rule.clone({
27
- selector: modifiedSelector
20
+ }
21
+ }
22
+ };
23
+ };
24
+
25
+ creator.postcss = true;
26
+
27
+ const getFallbackSelector = (
28
+ /** @type {string} */
29
+ selectorText) => parser(selectors => {
30
+ selectors.walkPseudos(selector => {
31
+ if (selector.value === ':has' && selector.nodes) {
32
+ const isNotHas = isParentInNotPseudo(selector);
33
+ selector.value = isNotHas ? ':not-has' : ':has';
34
+ const attribute = parser.attribute({
35
+ attribute: getEscapedCss(String(selector))
28
36
  });
29
37
 
30
- if (preserve) {
31
- rule.before(clone);
38
+ if (isNotHas) {
39
+ selector.parent.parent.replaceWith(attribute);
32
40
  } else {
33
- rule.replaceWith(clone);
41
+ selector.replaceWith(attribute);
34
42
  }
35
- });
36
- };
37
- });
43
+ }
44
+ });
45
+ }).processSync(selectorText);
46
+ /** Default options. */
47
+
48
+
49
+ const defaultOptions = {
50
+ preserve: true
51
+ };
52
+ /** Returns the string as an escaped CSS identifier. */
53
+
54
+ const getEscapedCss = (
55
+ /** @type {string} */
56
+ value) => encodeURIComponent(value).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',').replace(/[():%[\],]/g, '\\$&');
57
+ /** Returns whether the selector is within a `:not` pseudo-class. */
58
+
59
+
60
+ const isParentInNotPseudo = selector => {
61
+ var _selector$parent, _selector$parent$pare;
38
62
 
39
- function checkIfParentIsNot(selector) {
40
- return Object(Object(selector.parent).parent).type === 'pseudo' && selector.parent.parent.value === ':not';
41
- }
63
+ return ((_selector$parent = selector.parent) === null || _selector$parent === void 0 ? void 0 : (_selector$parent$pare = _selector$parent.parent) === null || _selector$parent$pare === void 0 ? void 0 : _selector$parent$pare.type) === 'pseudo' && selector.parent.parent.value === ':not';
64
+ };
42
65
 
43
- export default postcss;
66
+ export { creator as default };
44
67
  //# sourceMappingURL=postcss.mjs.map
package/postcss.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"postcss.mjs","sources":["src/postcss.js"],"sourcesContent":["import parser from 'postcss-selector-parser';\nimport postcss from 'postcss';\n\nconst selectorRegExp = /:has/;\n\nexport default postcss.plugin('css-has-pseudo', opts => {\n\tconst preserve = Boolean('preserve' in Object(opts) ? opts.preserve : true);\n\n\treturn root => {\n\t\troot.walkRules(selectorRegExp, rule => {\n\t\t\tconst modifiedSelector = parser(selectors => {\n\t\t\t\tselectors.walkPseudos(selector => {\n\t\t\t\t\tif (selector.value === ':has' && selector.nodes) {\n\t\t\t\t\t\tconst isNotHas = checkIfParentIsNot(selector);\n\t\t\t\t\t\tselector.value = isNotHas ? ':not-has' : ':has';\n\n\t\t\t\t\t\tconst attribute = parser.attribute({\n\t\t\t\t\t\t\tattribute: encodeURIComponent(String(selector))\n\t\t\t\t\t\t\t.replace(/%3A/g, ':')\n\t\t\t\t\t\t\t.replace(/%5B/g, '[')\n\t\t\t\t\t\t\t.replace(/%5D/g, ']')\n\t\t\t\t\t\t\t.replace(/%2C/g, ',')\n\t\t\t\t\t\t\t.replace(/[():%[\\],]/g, '\\\\$&')\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (isNotHas) {\n\t\t\t\t\t\t\tselector.parent.parent.replaceWith(attribute);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tselector.replaceWith(attribute);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}).processSync(rule.selector);\n\n\t\t\tconst clone = rule.clone({ selector: modifiedSelector });\n\n\t\t\tif (preserve) {\n\t\t\t\trule.before(clone);\n\t\t\t} else {\n\t\t\t\trule.replaceWith(clone);\n\t\t\t}\n\t\t});\n\t};\n});\n\nfunction checkIfParentIsNot (selector) {\n\treturn Object(Object(selector.parent).parent).type === 'pseudo' && selector.parent.parent.value === ':not';\n}\n"],"names":["selectorRegExp","postcss","plugin","opts","preserve","Boolean","Object","root","walkRules","rule","modifiedSelector","parser","selectors","walkPseudos","selector","value","nodes","isNotHas","checkIfParentIsNot","attribute","encodeURIComponent","String","replace","parent","replaceWith","processSync","clone","before","type"],"mappings":";;;AAGA,MAAMA,cAAc,GAAG,MAAvB;AAEA,cAAeC,SAAO,CAACC,MAAR,CAAe,gBAAf,EAAiCC,IAAI,IAAI;QACjDC,QAAQ,GAAGC,OAAO,CAAC,cAAcC,MAAM,CAACH,IAAD,CAApB,GAA6BA,IAAI,CAACC,QAAlC,GAA6C,IAA9C,CAAxB;SAEOG,IAAI,IAAI;IACdA,IAAI,CAACC,SAAL,CAAeR,cAAf,EAA+BS,IAAI,IAAI;YAChCC,gBAAgB,GAAGC,MAAM,CAACC,SAAS,IAAI;QAC5CA,SAAS,CAACC,WAAV,CAAsBC,QAAQ,IAAI;cAC7BA,QAAQ,CAACC,KAAT,KAAmB,MAAnB,IAA6BD,QAAQ,CAACE,KAA1C,EAAiD;kBAC1CC,QAAQ,GAAGC,kBAAkB,CAACJ,QAAD,CAAnC;YACAA,QAAQ,CAACC,KAAT,GAAiBE,QAAQ,GAAG,UAAH,GAAgB,MAAzC;kBAEME,SAAS,GAAGR,MAAM,CAACQ,SAAP,CAAiB;cAClCA,SAAS,EAAEC,kBAAkB,CAACC,MAAM,CAACP,QAAD,CAAP,CAAlB,CACVQ,OADU,CACF,MADE,EACM,GADN,EAEVA,OAFU,CAEF,MAFE,EAEM,GAFN,EAGVA,OAHU,CAGF,MAHE,EAGM,GAHN,EAIVA,OAJU,CAIF,MAJE,EAIM,GAJN,EAKVA,OALU,CAKF,aALE,EAKa,MALb;aADM,CAAlB;;gBASIL,QAAJ,EAAc;cACbH,QAAQ,CAACS,MAAT,CAAgBA,MAAhB,CAAuBC,WAAvB,CAAmCL,SAAnC;aADD,MAEO;cACNL,QAAQ,CAACU,WAAT,CAAqBL,SAArB;;;SAjBH;OAD8B,CAAN,CAsBtBM,WAtBsB,CAsBVhB,IAAI,CAACK,QAtBK,CAAzB;YAwBMY,KAAK,GAAGjB,IAAI,CAACiB,KAAL,CAAW;QAAEZ,QAAQ,EAAEJ;OAAvB,CAAd;;UAEIN,QAAJ,EAAc;QACbK,IAAI,CAACkB,MAAL,CAAYD,KAAZ;OADD,MAEO;QACNjB,IAAI,CAACe,WAAL,CAAiBE,KAAjB;;KA9BF;GADD;CAHc,CAAf;;AAwCA,SAASR,kBAAT,CAA6BJ,QAA7B,EAAuC;SAC/BR,MAAM,CAACA,MAAM,CAACQ,QAAQ,CAACS,MAAV,CAAN,CAAwBA,MAAzB,CAAN,CAAuCK,IAAvC,KAAgD,QAAhD,IAA4Dd,QAAQ,CAACS,MAAT,CAAgBA,MAAhB,CAAuBR,KAAvB,KAAiC,MAApG;;;;;"}
1
+ {"version":3,"file":"postcss.mjs","sources":["src/postcss.js"],"sourcesContent":["import parser from 'postcss-selector-parser'\n\nconst creator = (/** @type {{ preserve: true | false }} */ opts) => {\n\topts = typeof opts === 'object' && opts || defaultOptions\n\n\t/** Whether the original rule should be preserved. */\n\tconst shouldPreserve = Boolean('preserve' in opts ? opts.preserve : true)\n\n\treturn {\n\t\tpostcssPlugin: 'css-has-pseudo',\n\t\tRule: rule => {\n\t\t\tif (rule.selector.includes(':has(')) {\n\t\t\t\tconst fallbackSelector = getFallbackSelector(rule.selector)\n\n\t\t\t\tif (shouldPreserve) rule.cloneBefore({ selector: fallbackSelector })\n\t\t\t\telse rule.assign({ selector: fallbackSelector })\n\t\t\t}\n\t\t},\n\t}\n}\n\ncreator.postcss = true\n\nconst getFallbackSelector = (/** @type {string} */ selectorText) => parser(selectors => {\n\tselectors.walkPseudos(selector => {\n\t\tif (selector.value === ':has' && selector.nodes) {\n\t\t\tconst isNotHas = isParentInNotPseudo(selector)\n\n\t\t\tselector.value = isNotHas ? ':not-has' : ':has'\n\n\t\t\tconst attribute = parser.attribute({\n\t\t\t\tattribute: getEscapedCss(String(selector))\n\t\t\t})\n\n\t\t\tif (isNotHas) {\n\t\t\t\tselector.parent.parent.replaceWith(attribute)\n\t\t\t} else {\n\t\t\t\tselector.replaceWith(attribute)\n\t\t\t}\n\t\t}\n\t})\n}).processSync(selectorText)\n\n/** Default options. */\nconst defaultOptions = { preserve: true }\n\n/** Returns the string as an escaped CSS identifier. */\nconst getEscapedCss = (/** @type {string} */ value) => encodeURIComponent(value).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',').replace(/[():%[\\],]/g, '\\\\$&')\n\n/** Returns whether the selector is within a `:not` pseudo-class. */\nconst isParentInNotPseudo = (selector) => selector.parent?.parent?.type === 'pseudo' && selector.parent.parent.value === ':not'\n\nexport default creator\n"],"names":["creator","opts","defaultOptions","shouldPreserve","Boolean","preserve","postcssPlugin","Rule","rule","selector","includes","fallbackSelector","getFallbackSelector","cloneBefore","assign","postcss","selectorText","parser","selectors","walkPseudos","value","nodes","isNotHas","isParentInNotPseudo","attribute","getEscapedCss","String","parent","replaceWith","processSync","encodeURIComponent","replace","type"],"mappings":";;MAEMA,OAAO,GAAG;AAAC;AAA0CC,IAA3C,KAAoD;AACnEA,EAAAA,IAAI,GAAG,OAAOA,IAAP,KAAgB,QAAhB,IAA4BA,IAA5B,IAAoCC,cAA3C;AAEA;;AACA,QAAMC,cAAc,GAAGC,OAAO,CAAC,cAAcH,IAAd,GAAqBA,IAAI,CAACI,QAA1B,GAAqC,IAAtC,CAA9B;AAEA,SAAO;AACNC,IAAAA,aAAa,EAAE,gBADT;AAENC,IAAAA,IAAI,EAAEC,IAAI,IAAI;AACb,UAAIA,IAAI,CAACC,QAAL,CAAcC,QAAd,CAAuB,OAAvB,CAAJ,EAAqC;AACpC,cAAMC,gBAAgB,GAAGC,mBAAmB,CAACJ,IAAI,CAACC,QAAN,CAA5C;AAEA,YAAIN,cAAJ,EAAoBK,IAAI,CAACK,WAAL,CAAiB;AAAEJ,UAAAA,QAAQ,EAAEE;AAAZ,SAAjB,EAApB,KACKH,IAAI,CAACM,MAAL,CAAY;AAAEL,UAAAA,QAAQ,EAAEE;AAAZ,SAAZ;AACL;AACD;AATK,GAAP;AAWA;;AAEDX,OAAO,CAACe,OAAR,GAAkB,IAAlB;;AAEA,MAAMH,mBAAmB,GAAG;AAAC;AAAsBI,YAAvB,KAAwCC,MAAM,CAACC,SAAS,IAAI;AACvFA,EAAAA,SAAS,CAACC,WAAV,CAAsBV,QAAQ,IAAI;AACjC,QAAIA,QAAQ,CAACW,KAAT,KAAmB,MAAnB,IAA6BX,QAAQ,CAACY,KAA1C,EAAiD;AAChD,YAAMC,QAAQ,GAAGC,mBAAmB,CAACd,QAAD,CAApC;AAEAA,MAAAA,QAAQ,CAACW,KAAT,GAAiBE,QAAQ,GAAG,UAAH,GAAgB,MAAzC;AAEA,YAAME,SAAS,GAAGP,MAAM,CAACO,SAAP,CAAiB;AAClCA,QAAAA,SAAS,EAAEC,aAAa,CAACC,MAAM,CAACjB,QAAD,CAAP;AADU,OAAjB,CAAlB;;AAIA,UAAIa,QAAJ,EAAc;AACbb,QAAAA,QAAQ,CAACkB,MAAT,CAAgBA,MAAhB,CAAuBC,WAAvB,CAAmCJ,SAAnC;AACA,OAFD,MAEO;AACNf,QAAAA,QAAQ,CAACmB,WAAT,CAAqBJ,SAArB;AACA;AACD;AACD,GAhBD;AAiBA,CAlByE,CAAN,CAkBjEK,WAlBiE,CAkBrDb,YAlBqD,CAApE;AAoBA;;;AACA,MAAMd,cAAc,GAAG;AAAEG,EAAAA,QAAQ,EAAE;AAAZ,CAAvB;AAEA;;AACA,MAAMoB,aAAa,GAAG;AAAC;AAAsBL,KAAvB,KAAiCU,kBAAkB,CAACV,KAAD,CAAlB,CAA0BW,OAA1B,CAAkC,MAAlC,EAA0C,GAA1C,EAA+CA,OAA/C,CAAuD,MAAvD,EAA+D,GAA/D,EAAoEA,OAApE,CAA4E,MAA5E,EAAoF,GAApF,EAAyFA,OAAzF,CAAiG,MAAjG,EAAyG,GAAzG,EAA8GA,OAA9G,CAAsH,aAAtH,EAAqI,MAArI,CAAvD;AAEA;;;AACA,MAAMR,mBAAmB,GAAId,QAAD;AAAA;;AAAA,SAAc,qBAAAA,QAAQ,CAACkB,MAAT,+FAAiBA,MAAjB,gFAAyBK,IAAzB,MAAkC,QAAlC,IAA8CvB,QAAQ,CAACkB,MAAT,CAAgBA,MAAhB,CAAuBP,KAAvB,KAAiC,MAA7F;AAAA,CAA5B;;;;"}
package/CHANGELOG.md DELETED
@@ -1,49 +0,0 @@
1
- # Changes to CSS Has Pseudo
2
-
3
- ### 1.0.0 (June 10, 2019)
4
-
5
- - Updated: `postcss-selector-parser` to 6.0.2 (major)
6
- - Updated: `postcss` to 7.0.16 (patch)
7
- - Updated: Node 8+ compatibility (major)
8
-
9
- ### 0.10.0 (December 11, 2018)
10
-
11
- - Fixed an issue where inaccessible rules would crash the library
12
-
13
- ### 0.9.0 (November 26, 2018)
14
-
15
- - Improved CLI usage
16
-
17
- ### 0.8.0 (November 26, 2018)
18
-
19
- - Fixed an issue where attribute names were not being properly encoded
20
-
21
- ### 0.7.0 (November 25, 2018)
22
-
23
- - Replaced `setImmediate` with `requestAnimationFrame` for future compatibility
24
-
25
- ### 0.6.0 (November 25, 2018)
26
-
27
- - Fixed an issue where nested rules were not supported
28
-
29
- ### 0.5.0 (November 21, 2018)
30
-
31
- - Further optimize script; from 775 bytes to 757 bytes
32
-
33
- ### 0.4.0 (November 21, 2018)
34
-
35
- - Fixed an issue with the browser script not picking up added nodes
36
-
37
- ### 0.3.0 (November 21, 2018)
38
-
39
- - Fixed the misnamed function name for the browser-ready script
40
-
41
- ### 0.2.0 (November 21, 2018)
42
-
43
- - Improved browser compatibility with updated parsers, encoders, and decoders
44
- - Improved performance by walking the DOM less
45
- - Reduced script size by 9%; from 855 bytes to 775 bytes
46
-
47
- ### 0.1.0 (November 20, 2018)
48
-
49
- - Initial version