Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

css-has-pseudo

Package Overview
Dependencies
Maintainers
2
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

css-has-pseudo - npm Package Compare versions

Comparing version 2.0.0 to 3.0.0

CHANGELOG.md

117

browser.js

@@ -0,2 +1,117 @@

(function () {
//# sourceMappingURL=browser.js.map
/* global MutationObserver,requestAnimationFrame */
function cssHasPseudo(document) {
var observedItems = []; // document.createAttribute() doesn't support `:` in the name. innerHTML does
var attributeElement = document.createElement('x'); // walk all stylesheets to collect observed css rules
[].forEach.call(document.styleSheets, walkStyleSheet);
transformObservedItems(); // observe DOM modifications that affect selectors
var mutationObserver = new MutationObserver(function (mutationsList) {
mutationsList.forEach(function (mutation) {
[].forEach.call(mutation.addedNodes || [], function (node) {
// walk stylesheets to collect observed css rules
if (node.nodeType === 1 && node.sheet) {
walkStyleSheet(node.sheet);
}
}); // transform observed css rules
cleanupObservedCssRules();
transformObservedItems();
});
});
mutationObserver.observe(document, {
childList: true,
subtree: true
}); // observe DOM events that affect pseudo-selectors
document.addEventListener('focus', transformObservedItems, true);
document.addEventListener('blur', transformObservedItems, true);
document.addEventListener('input', transformObservedItems); // transform observed css rules
function transformObservedItems() {
requestAnimationFrame(function () {
observedItems.forEach(function (item) {
var nodes = [];
[].forEach.call(document.querySelectorAll(item.scopeSelector), function (element) {
var nthChild = [].indexOf.call(element.parentNode.children, element) + 1;
var relativeSelectors = item.relativeSelectors.map(function (relativeSelector) {
return item.scopeSelector + ':nth-child(' + nthChild + ') ' + relativeSelector;
}).join(); // find any relative :has element from the :scope element
var relativeElement = element.parentNode.querySelector(relativeSelectors);
var shouldElementMatch = item.isNot ? !relativeElement : relativeElement;
if (shouldElementMatch) {
// memorize the node
nodes.push(element); // set an attribute with an irregular attribute name
// document.createAttribute() doesn't support special characters
attributeElement.innerHTML = '<x ' + item.attributeName + '>';
element.setAttributeNode(attributeElement.children[0].attributes[0].cloneNode()); // trigger a style refresh in IE and Edge
document.documentElement.style.zoom = 1;
document.documentElement.style.zoom = null;
}
}); // remove the encoded attribute from all nodes that no longer match them
item.nodes.forEach(function (node) {
if (nodes.indexOf(node) === -1) {
node.removeAttribute(item.attributeName); // trigger a style refresh in IE and Edge
document.documentElement.style.zoom = 1;
document.documentElement.style.zoom = null;
}
}); // update the
item.nodes = nodes;
});
});
} // remove any observed cssrules that no longer apply
function cleanupObservedCssRules() {
[].push.apply(observedItems, observedItems.splice(0).filter(function (item) {
return item.rule.parentStyleSheet && item.rule.parentStyleSheet.ownerNode && document.documentElement.contains(item.rule.parentStyleSheet.ownerNode);
}));
} // walk a stylesheet to collect observed css rules
function walkStyleSheet(styleSheet) {
try {
// walk a css rule to collect observed css rules
[].forEach.call(styleSheet.cssRules || [], function (rule) {
if (rule.selectorText) {
// decode the selector text in all browsers to:
// [1] = :scope, [2] = :not(:has), [3] = :has relative, [4] = :scope relative
var selectors = decodeURIComponent(rule.selectorText.replace(/\\(.)/g, '$1')).match(/^(.*?)\[:(not-)?has\((.+?)\)\](.*?)$/);
if (selectors) {
var attributeName = ':' + (selectors[2] ? 'not-' : '') + 'has(' + // encode a :has() pseudo selector as an attribute name
encodeURIComponent(selectors[3]).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',') + ')';
observedItems.push({
rule: rule,
scopeSelector: selectors[1],
isNot: selectors[2],
relativeSelectors: selectors[3].split(/\s*,\s*/),
attributeName: attributeName,
nodes: []
});
}
} else {
walkStyleSheet(rule);
}
});
} catch (error) {
/* do nothing and continue */
}
}
}
/* global self */
self.cssHasPseudo = cssHasPseudo;
})();
//# sourceMappingURL=browser-global.js.map

101

package.json
{
"name": "css-has-pseudo",
"version": "2.0.0",
"version": "3.0.0",
"description": "Style elements relative to other elements in CSS",
"author": "Jonathan Neal <jonathantneal@hotmail.com>",
"license": "CC0-1.0",
"repository": "csstools/css-has-pseudo",
"homepage": "https://github.com/csstools/css-has-pseudo#readme",
"bugs": "https://github.com/csstools/css-has-pseudo/issues",
"main": "index.js",
"module": "index.mjs",
"bin": {
"css-has-pseudo": "cli.js"
"homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/css-has-pseudo#readme",
"bugs": "https://github.com/csstools/postcss-plugins/issues",
"main": "dist/index.cjs",
"module": "dist/index.mjs",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"default": "./dist/index.mjs"
},
"./browser": {
"default": "./dist/browser.js"
},
"./browser-global": {
"default": "./dist/browser-global.js"
}
},
"files": [
"browser.js",
"cli.js",
"index.js",
"index.js.map",
"index.mjs",
"index.mjs.map",
"postcss.js",
"postcss.js.map",
"postcss.mjs",
"postcss.mjs.map"
"CHANGELOG.md",
"INSTALL.md",
"LICENSE.md",
"README.md",
"dist",
"browser.js"
],
"bin": {
"css-has-pseudo": "dist/cli.mjs"
},
"scripts": {
"build": "npm run build:browser && npm run build:cli && npm run build:node && npm run build:postcss",
"build:browser": "cross-env NODE_ENV=browser rollup --config .rollup.js --silent",
"build:cli": "cross-env NODE_ENV=cli rollup --config .rollup.js --silent",
"build:postcss": "cross-env NODE_ENV=postcss rollup --config .rollup.js --silent",
"build:node": "rollup --config .rollup.js --silent",
"prepublishOnly": "npm test && npm run build",
"pretest:postcss": "npm run build:postcss",
"test": "npm run test:js && npm run test:postcss",
"test:js": "eslint src/{*,**/*}.js --cache --ignore-path .gitignore --quiet",
"test:postcss": "postcss-tape --plugin postcss.js"
"build": "rollup -c ../../rollup/default.js && npm run copy-browser-scripts-to-old-location",
"clean": "node -e \"fs.rmSync('./dist', { recursive: true, force: true });\"",
"copy-browser-scripts-to-old-location": "node -e \"fs.copyFileSync('./dist/browser-global.js', './browser.js')\"",
"lint": "eslint ./src --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern",
"prepublishOnly": "npm run clean && npm run build && npm run test",
"stryker": "stryker run --logLevel error",
"test": "postcss-tape --ci"
},
"engines": {
"node": ">=12"
"node": "^12 || ^14 || >=16"
},
"peerDependencies": {
"postcss": ">=8.3"
},
"dependencies": {
"postcss-selector-parser": "^6"
"postcss-selector-parser": "^6.0.7"
},
"devDependencies": {
"@babel/core": "7.15.5",
"@babel/preset-env": "7.15.6",
"@rollup/plugin-babel": "5.3.0",
"cross-env": "7.0.3",
"eslint": "7.32.0",
"postcss": "8.3.4",
"postcss-tape": "6.0.1",
"pre-commit": "1.2.2",
"rollup": "2.56.3",
"rollup-plugin-terser": "7.0.2"
"postcss": "^8.3.6",
"postcss-tape": "^6.0.1"
},
"eslintConfig": {
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
},
"root": true
"peerDependencies": {
"postcss": "^8.3"
},

@@ -85,3 +69,8 @@ "keywords": [

"selector"
]
],
"repository": {
"type": "git",
"url": "https://github.com/csstools/postcss-plugins.git",
"directory": "plugins/css-has-pseudo"
}
}
# CSS Has Pseudo [<img src="http://jonathantneal.github.io/js-logo.svg" alt="" width="90" height="90" align="right">][CSS Has Pseudo]
[![NPM Version][npm-img]][npm-url]
[![Build Status][cli-img]][cli-url]
[![Support Chat][git-img]][git-url]

@@ -35,3 +34,3 @@

```bash
npx css-has-pseudo SOURCE.css TRANSFORMED.css
npx css-has-pseudo SOURCE.css --output TRANSFORMED.css
```

@@ -43,10 +42,18 @@

<link rel="stylesheet" href="TRANSFORMED.css">
<script src="https://unpkg.com/css-has-pseudo/browser"></script>
<script src="https://unpkg.com/css-has-pseudo/dist/browser-global.js"></script>
<script>cssHasPseudo(document)</script>
```
That’s it. The script is 765 bytes and works in all browsers, including
⚠️ Please use a versioned url, like this : `https://unpkg.com/css-has-pseudo@3.0.0/dist/browser-global.js`
Without the version, you might unexpectedly get a new major version of the library with breaking changes.
⚠️ If you were using an older version via a CDN, please update the entire url.
The old URL will no longer work in a future release.
That’s it. The script is 765 bytes and works in most browser versions, including
Internet Explorer 11. With a [Mutation Observer polyfill], the script will work
down to Internet Explorer 9.
See [README BROWSER](README-BROWSER.md) for more information.
## How it works

@@ -94,4 +101,2 @@

[cli-img]: https://img.shields.io/travis/csstools/css-has-pseudo/master.svg
[cli-url]: https://travis-ci.org/csstools/css-has-pseudo
[git-img]: https://img.shields.io/badge/support-chat-blue.svg

@@ -102,4 +107,4 @@ [git-url]: https://gitter.im/postcss/postcss

[CSS Has Pseudo]: https://github.com/csstools/css-has-pseudo
[CSS Has Pseudo]: https://github.com/csstools/postcss-plugins/tree/main/plugins/css-has-pseudo
[Mutation Observer polyfill]: https://github.com/webmodules/mutation-observer
[Selectors Level 4]: https://drafts.csswg.org/selectors-4/#has-pseudo
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc