diff --git a/plugins/css-has-pseudo/.editorconfig b/plugins/css-has-pseudo/.editorconfig
deleted file mode 100644
index e06d7982b..000000000
--- a/plugins/css-has-pseudo/.editorconfig
+++ /dev/null
@@ -1,15 +0,0 @@
-root = true
-
-[*]
-charset = utf-8
-end_of_line = lf
-indent_style = tab
-insert_final_newline = true
-trim_trailing_whitespace = true
-
-[*.md]
-trim_trailing_whitespace = false
-
-[*.{json,md,yml}]
-indent_size = 2
-indent_style = space
diff --git a/plugins/css-has-pseudo/.gitignore b/plugins/css-has-pseudo/.gitignore
index b3a3c6d85..17847a362 100644
--- a/plugins/css-has-pseudo/.gitignore
+++ b/plugins/css-has-pseudo/.gitignore
@@ -1,13 +1,10 @@
node_modules
-/browser.*
-/cli.*
-/index.*
-/postcss.*
+dist
package-lock.json
yarn.lock
*.log*
*.result.css
-.*
+*.result.css.map
!.editorconfig
!.gitignore
!.rollup.js
diff --git a/plugins/css-has-pseudo/.rollup.js b/plugins/css-has-pseudo/.rollup.js
deleted file mode 100644
index 7a350f728..000000000
--- a/plugins/css-has-pseudo/.rollup.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import babel from '@rollup/plugin-babel';
-import { terser } from 'rollup-plugin-terser';
-
-const isCLI = String(process.env.NODE_ENV).includes('cli');
-const isPostCSS = String(process.env.NODE_ENV).includes('postcss');
-const isBrowser = String(process.env.NODE_ENV).includes('browser');
-
-const input = `src/${isCLI ? 'cli' : isPostCSS ? 'postcss' : 'browser'}.js`;
-
-const output = isCLI
- ? { file: 'cli.js', format: 'cjs', sourcemap: true, strict: false }
-: isPostCSS
- ? [
- { file: 'postcss.js', format: 'cjs', exports: 'default', sourcemap: true },
- { file: 'postcss.mjs', format: 'esm', sourcemap: true }
-] : isBrowser
- ? { file: 'browser.js', format: 'cjs', exports: 'default', sourcemap: true, strict: false }
-: [
- { file: 'index.js', format: 'cjs', exports: 'default', sourcemap: true },
- { file: 'index.mjs', format: 'esm', sourcemap: true }
-];
-
-const targets = isCLI || isPostCSS || !isBrowser ? { node: 10 } : 'last 2 versions, not dead';
-const plugins = [
- babel({
- babelHelpers: 'bundled',
- presets: [
- ['@babel/env', { targets }]
- ]
- })
-].concat(isBrowser
- ? [
- trimContentForBrowser(),
- terser({
- mangle: {
- properties: {
- reserved: ['addEventListener', 'addedNodes', 'attributes', 'childList', 'children', 'cloneNode', 'contains', 'createElement', 'cssRules', 'documentElement', 'innerHTML', 'nodeType', 'observe', 'ownerNode', 'parentNode', 'parentStyleSheet', 'querySelector', 'querySelectorAll', 'removeAttribute', 'selectorText', 'setAttributeNode', 'setNamedItem', 'sheet', 'style', 'styleSheets', 'subtree', 'zoom']
- }
- }
- })
- ]
-: isCLI
- ? [
- trimContentForBrowser(),
- addHashBang()
- ]
-: []);
-
-export default { input, output, plugins };
-
-function addHashBang () {
- return {
- name: 'add-hash-bang',
- renderChunk (code) {
- const updatedCode = `#!/usr/bin/env node\n\n${code}`;
-
- return updatedCode;
- }
- };
-}
-
-function trimContentForBrowser () {
- return {
- name: 'trim-content-for-browser',
- renderChunk (code) {
- const updatedCode = code
- .replace(/'use strict';\n*/, '')
- .replace(/\n*module\.exports = cssHasPseudo;/, '');
-
- return updatedCode;
- }
- };
-}
diff --git a/plugins/css-has-pseudo/.travis.yml b/plugins/css-has-pseudo/.travis.yml
deleted file mode 100644
index b17d4a447..000000000
--- a/plugins/css-has-pseudo/.travis.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-# https://docs.travis-ci.com/user/travis-lint
-
-language: node_js
-
-node_js:
- - 12
- - 14
-
-install:
- - npm install --ignore-scripts
diff --git a/plugins/css-has-pseudo/CONTRIBUTING.md b/plugins/css-has-pseudo/CONTRIBUTING.md
deleted file mode 100644
index 517c47dcb..000000000
--- a/plugins/css-has-pseudo/CONTRIBUTING.md
+++ /dev/null
@@ -1,65 +0,0 @@
-# Contributing to CSS Has Pseudo
-
-You want to help? You rock! Now, take a moment to be sure your contributions
-make sense to everyone else.
-
-## Reporting Issues
-
-Found a problem? Want a new feature?
-
-- See if your issue or idea has [already been reported].
-- Provide a [reduced test case] or a [live example].
-
-Remember, a bug is a _demonstrable problem_ caused by _our_ code.
-
-## Submitting Pull Requests
-
-Pull requests are the greatest contributions, so be sure they are focused in
-scope and avoid unrelated commits.
-
-1. To begin; [fork this project], clone your fork, and add our upstream.
- ```bash
- # Clone your fork of the repo into the current directory
- git clone git@github.com:YOUR_USER/css-has-pseudo.git
-
- # Navigate to the newly cloned directory
- cd css-has-pseudo
-
- # Assign the original repo to a remote called "upstream"
- git remote add upstream git@github.com:csstools/css-has-pseudo.git
-
- # Install the tools necessary for testing
- npm install
- ```
-
-2. Create a branch for your feature or fix:
- ```bash
- # Move into a new branch for your feature
- git checkout -b feature/thing
- ```
- ```bash
- # Move into a new branch for your fix
- git checkout -b fix/something
- ```
-
-3. If your code follows our practices, then push your feature branch:
- ```bash
- # Test current code
- npm test
- ```
- ```bash
- # Push the branch for your new feature
- git push origin feature/thing
- ```
- ```bash
- # Or, push the branch for your update
- git push origin update/something
- ```
-
-That’s it! Now [open a pull request] with a clear title and description.
-
-[already been reported]: issues
-[fork this project]: fork
-[live example]: https://codepen.io/pen
-[open a pull request]: https://help.github.com/articles/using-pull-requests/
-[reduced test case]: https://css-tricks.com/reduced-test-cases/
diff --git a/plugins/css-has-pseudo/INSTALL-POSTCSS.md b/plugins/css-has-pseudo/INSTALL-POSTCSS.md
index 92f3b641b..4a8609faf 100644
--- a/plugins/css-has-pseudo/INSTALL-POSTCSS.md
+++ b/plugins/css-has-pseudo/INSTALL-POSTCSS.md
@@ -13,19 +13,11 @@ Add [CSS Has Pseudo] to your project:
npm install css-has-pseudo --save-dev
```
-Use [CSS Has Pseudo] to process your CSS:
-
-```js
-const postcssHasPseudo = require('css-has-pseudo/postcss');
-
-postcssHasPseudo.process(YOUR_CSS /*, processOptions, pluginOptions */);
-```
-
-Or use it as a [PostCSS] plugin:
+Use it as a [PostCSS] plugin:
```js
const postcss = require('postcss');
-const postcssHasPseudo = require('css-has-pseudo/postcss');
+const postcssHasPseudo = require('css-has-pseudo');
postcss([
postcssHasPseudo(/* pluginOptions */)
@@ -43,7 +35,7 @@ npm install postcss-cli --save-dev
Use [CSS Has Pseudo] in your `postcss.config.js` configuration file:
```js
-const postcssHasPseudo = require('css-has-pseudo/postcss');
+const postcssHasPseudo = require('css-has-pseudo');
module.exports = {
plugins: [
@@ -63,7 +55,7 @@ npm install postcss-loader --save-dev
Use [CSS Has Pseudo] in your Webpack configuration:
```js
-const postcssHasPseudo = require('css-has-pseudo/postcss');
+const postcssHasPseudo = require('css-has-pseudo');
module.exports = {
module: {
@@ -100,7 +92,7 @@ file:
```js
const reactAppRewirePostcss = require('react-app-rewire-postcss');
-const postcssHasPseudo = require('css-has-pseudo/postcss');
+const postcssHasPseudo = require('css-has-pseudo');
module.exports = config => reactAppRewirePostcss(config, {
plugins: () => [
@@ -121,7 +113,7 @@ Use [CSS Has Pseudo] in your Gulpfile:
```js
const postcss = require('gulp-postcss');
-const postcssHasPseudo = require('css-has-pseudo/postcss');
+const postcssHasPseudo = require('css-has-pseudo');
gulp.task('css', () => gulp.src('./src/*.css').pipe(
postcss([
@@ -143,7 +135,7 @@ npm install grunt-postcss --save-dev
Use [CSS Has Pseudo] in your Gruntfile:
```js
-const postcssHasPseudo = require('css-has-pseudo/postcss');
+const postcssHasPseudo = require('css-has-pseudo');
grunt.loadNpmTasks('grunt-postcss');
@@ -161,7 +153,7 @@ grunt.initConfig({
});
```
-[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
[Gulp PostCSS]: https://github.com/postcss/gulp-postcss
[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss
[PostCSS]: https://github.com/postcss/postcss
diff --git a/plugins/css-has-pseudo/README-BROWSER.md b/plugins/css-has-pseudo/README-BROWSER.md
index 706fab7dd..302cffbe1 100644
--- a/plugins/css-has-pseudo/README-BROWSER.md
+++ b/plugins/css-has-pseudo/README-BROWSER.md
@@ -1,7 +1,6 @@
# CSS Has Pseudo for Browsers [
][CSS Has Pseudo]
[![NPM Version][npm-img]][npm-url]
-[![Build Status][cli-img]][cli-url]
[![Support Chat][git-img]][git-url]
[CSS Has Pseudo] lets you style elements relative to other elements in CSS,
@@ -28,17 +27,42 @@ npm install css-has-pseudo
Then include and initialize it on your document:
```js
-const cssHasPseudo = require('css-has-pseudo');
+const cssHasPseudo = require('css-has-pseudo/browser');
cssHasPseudo(document);
```
-[cli-img]: https://img.shields.io/travis/csstools/css-has-pseudo/master.svg
-[cli-url]: https://travis-ci.org/csstools/css-has-pseudo
+```html
+
+
+
+```
+
+## Dependencies
+
+Web API's:
+
+- [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)
+- [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame)
+- [querySelectorAll](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) with support for post CSS 2.1 selectors
+
+ECMA Script:
+
+- `Array.prototype.filter`
+- `Array.prototype.forEach`
+- `Array.prototype.indexOf`
+- `Array.prototype.join`
+- `Array.prototype.map`
+- `Array.prototype.splice`
+- `RegExp.prototype.exec`
+- `String.prototype.match`
+- `String.prototype.replace`
+- `String.prototype.split`
+
[git-img]: https://img.shields.io/badge/support-chat-blue.svg
[git-url]: https://gitter.im/postcss/postcss
[npm-img]: https://img.shields.io/npm/v/css-has-pseudo.svg
[npm-url]: https://www.npmjs.com/package/css-has-pseudo
-[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
[Selectors Level 4]: https://drafts.csswg.org/selectors-4/#has
diff --git a/plugins/css-has-pseudo/README-POSTCSS.md b/plugins/css-has-pseudo/README-POSTCSS.md
index de85c7656..989ea6f31 100644
--- a/plugins/css-has-pseudo/README-POSTCSS.md
+++ b/plugins/css-has-pseudo/README-POSTCSS.md
@@ -1,7 +1,6 @@
# CSS Has Pseudo for PostCSS [
][CSS Has Pseudo]
[![NPM Version][npm-img]][npm-url]
-[![Build Status][cli-img]][cli-url]
[![Support Chat][git-img]][git-url]
[CSS Has Pseudo] lets you style elements relative to other elements in CSS,
@@ -38,7 +37,7 @@ npm install css-has-pseudo --save-dev
Use [CSS Has Pseudo] to process your CSS:
```js
-const postcssHasPseudo = require('css-has-pseudo/postcss');
+const postcssHasPseudo = require('css-has-pseudo');
postcssHasPseudo.process(YOUR_CSS /*, processOptions, pluginOptions */);
```
@@ -47,7 +46,7 @@ Or use it as a [PostCSS] plugin:
```js
const postcss = require('postcss');
-const postcssHasPseudo = require('css-has-pseudo/postcss');
+const postcssHasPseudo = require('css-has-pseudo');
postcss([
postcssHasPseudo(/* pluginOptions */)
@@ -83,12 +82,10 @@ body[\:has\(\:focus\)] {
}
```
-[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
[git-url]: https://gitter.im/postcss/postcss
[npm-img]: https://img.shields.io/npm/v/css-has-pseudo.svg
[npm-url]: https://www.npmjs.com/package/css-has-pseudo
-[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
[Selectors Level 4]: https://drafts.csswg.org/selectors-4/#has-pseudo
diff --git a/plugins/css-has-pseudo/README.md b/plugins/css-has-pseudo/README.md
index 549f7198d..089b238b2 100644
--- a/plugins/css-has-pseudo/README.md
+++ b/plugins/css-has-pseudo/README.md
@@ -1,7 +1,6 @@
# CSS Has Pseudo [
][CSS Has Pseudo]
[![NPM Version][npm-img]][npm-url]
-[![Build Status][cli-img]][cli-url]
[![Support Chat][git-img]][git-url]
[CSS Has Pseudo] lets you style elements relative to other elements in CSS,
@@ -32,21 +31,23 @@ body:has(:focus) {
From the command line, transform CSS files that use `:has` selectors:
```bash
-npx css-has-pseudo SOURCE.css TRANSFORMED.css
+npx css-has-pseudo SOURCE.css --output TRANSFORMED.css
```
Next, use your transformed CSS with this script:
```html
-
+
```
-That’s it. The script is 765 bytes and works in all browsers, including
+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
The [PostCSS plugin](README-POSTCSS.md) clones rules containing `:has`,
@@ -89,13 +90,11 @@ elements otherwise matching `:has` natively.
```
-[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
[git-url]: https://gitter.im/postcss/postcss
[npm-img]: https://img.shields.io/npm/v/css-has-pseudo.svg
[npm-url]: https://www.npmjs.com/package/css-has-pseudo
-[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
diff --git a/plugins/css-has-pseudo/package.json b/plugins/css-has-pseudo/package.json
index 3cfb40183..871d927de 100644
--- a/plugins/css-has-pseudo/package.json
+++ b/plugins/css-has-pseudo/package.json
@@ -4,71 +4,47 @@
"description": "Style elements relative to other elements in CSS",
"author": "Jonathan Neal ",
"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": {
+ "./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"
],
+ "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"
+ "prepublishOnly": "npm run build && npm run test",
+ "lint": "eslint src/**/*.js",
+ "test": "postcss-tape",
+ "build": "rollup -c ../../rollup/default-with-browser.js",
+ "stryker": "stryker run --logLevel error"
},
"engines": {
- "node": ">=12"
- },
- "peerDependencies": {
- "postcss": ">=8.3"
+ "node": "^12 || ^14 || >=16"
},
"dependencies": {
- "postcss-selector-parser": "^6"
+ "postcss-selector-parser": "6.0.6"
},
"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"
},
"keywords": [
"postcss",
@@ -82,5 +58,10 @@
"descendant",
"pseudo",
"selector"
- ]
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/csstools/postcss-plugins.git",
+ "directory": "plugins/css-has-pseudo"
+ }
}
diff --git a/plugins/css-has-pseudo/src/browser-global.js b/plugins/css-has-pseudo/src/browser-global.js
new file mode 100644
index 000000000..4c547e114
--- /dev/null
+++ b/plugins/css-has-pseudo/src/browser-global.js
@@ -0,0 +1,3 @@
+/* global self */
+import * as cssHasPseudo from './browser';
+self.cssHasPseudo = cssHasPseudo;
diff --git a/plugins/css-has-pseudo/src/browser.js b/plugins/css-has-pseudo/src/browser.js
index 31e19216e..7fe3f28c8 100644
--- a/plugins/css-has-pseudo/src/browser.js
+++ b/plugins/css-has-pseudo/src/browser.js
@@ -1,4 +1,5 @@
-export default function cssHasPseudo (document) {
+/* global MutationObserver,requestAnimationFrame */
+export default function cssHasPseudo(document) {
const observedItems = [];
// document.createAttribute() doesn't support `:` in the name. innerHTML does
@@ -43,7 +44,7 @@ export default function cssHasPseudo (document) {
element => {
const nthChild = [].indexOf.call(element.parentNode.children, element) + 1;
const relativeSelectors = item.relativeSelectors.map(
- relativeSelector => item.scopeSelector + ':nth-child(' + nthChild + ') ' + relativeSelector
+ relativeSelector => item.scopeSelector + ':nth-child(' + nthChild + ') ' + relativeSelector,
).join();
// find any relative :has element from the :scope element
@@ -64,7 +65,7 @@ export default function cssHasPseudo (document) {
// 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
@@ -79,7 +80,7 @@ export default function cssHasPseudo (document) {
// update the
item.nodes = nodes;
- }
+ },
);
});
}
@@ -91,8 +92,8 @@ export default function cssHasPseudo (document) {
observedItems.splice(0).filter(
item => item.rule.parentStyleSheet &&
item.rule.parentStyleSheet.ownerNode &&
- document.documentElement.contains(item.rule.parentStyleSheet.ownerNode)
- )
+ document.documentElement.contains(item.rule.parentStyleSheet.ownerNode),
+ ),
);
}
@@ -118,7 +119,7 @@ export default function cssHasPseudo (document) {
isNot: selectors[2],
relativeSelectors: selectors[3].split(/\s*,\s*/),
attributeName,
- nodes: []
+ nodes: [],
});
}
} else {
diff --git a/plugins/css-has-pseudo/src/cli.js b/plugins/css-has-pseudo/src/cli.js
index 7fbe108b7..db0162d30 100644
--- a/plugins/css-has-pseudo/src/cli.js
+++ b/plugins/css-has-pseudo/src/cli.js
@@ -1,134 +1,15 @@
-/* eslint no-console: 0 */
-
-import fs from 'fs';
-import plugin from './postcss';
-
-// get process and plugin options from the command line
-const fileRegExp = /^[\w/.]+$/;
-const argRegExp = /^--(\w+)=("|')?(.+)\2$/;
-const relaxedJsonPropRegExp = /(['"])?([a-z0-9A-Z_]+)(['"])?:/g;
-const relaxedJsonValueRegExp = /("[a-z0-9A-Z_]+":\s*)(?!true|false|null|\d+)'?([A-z0-9]+)'?([,}])/g;
-const argo = process.argv.slice(2).reduce(
- (object, arg) => {
- const argMatch = arg.match(argRegExp);
- const fileMatch = arg.match(fileRegExp);
-
- if (argMatch) {
- object[argMatch[1]] = argMatch[3];
- } else if (fileMatch) {
- if (object.from === '') {
- object.from = arg;
- } else if (object.to === '') {
- object.to = arg;
- }
- }
-
- return object;
- },
- { from: '', to: '', opts: 'null' }
+import plugin from './index';
+import { cli, helpTextLogger } from '@csstools/base-cli';
+
+cli(
+ plugin,
+ ['preserve'],
+ helpTextLogger(
+ 'css-has-pseudo',
+ 'PostCSS Has Pseudo',
+ 'Transforms CSS with :has {}',
+ {
+ preserve: true,
+ },
+ ),
);
-
-// get css from command line arguments or stdin
-(argo.from === '' ? getStdin() : readFile(argo.from))
-.then(css => {
- if (argo.from === '' && !css) {
- console.log([
- 'CSS Has Pseudo\n',
- ' Transforms CSS with :has {}\n',
- 'Usage:\n',
- ' css-has-pseudo source.css transformed.css',
- ' css-has-pseudo --from=source.css --to=transformed.css --opts={}',
- ' echo "body:has(:focus) {}" | css-has-pseudo\n'
- ].join('\n'));
-
- process.exit(0);
- }
-
- const pluginOpts = JSON.parse(
- argo.opts
- .replace(relaxedJsonPropRegExp, '"$2": ')
- .replace(relaxedJsonValueRegExp, '$1"$2"$3')
- );
- const processOptions = Object.assign({ from: argo.from, to: argo.to || argo.from }, argo.map ? { map: JSON.parse(argo.map) } : {});
-
- const result = plugin.process(css, processOptions, pluginOpts);
-
- if (argo.to === '') {
- return result.css;
- } else {
- return writeFile(argo.to, result.css).then(
- () => `CSS was written to "${argo.to}"`
- )
- }
-}).catch(
- error => {
- if (Object(error).name === 'CssSyntaxError') {
- throw new Error(`PostCSS had trouble reading the file (${error.reason} on line ${error.line}, column ${error.column}).`);
- }
-
- if (Object(error).errno === -2) {
- throw new Error(`Sorry, "${error.path}" could not be read.`);
- }
-
- throw error;
- }
-).then(
- result => {
- console.log(result);
-
- process.exit(0);
- },
- error => {
- console.error(Object(error).message || 'Something bad happened and we don’t even know what it was.');
-
- process.exit(1);
- }
-);
-
-function readFile (pathname) {
- return new Promise((resolve, reject) => {
- fs.readFile(pathname, 'utf8', (error, data) => {
- if (error) {
- reject(error);
- } else {
- resolve(data);
- }
- });
- });
-}
-
-function writeFile (pathname, data) {
- return new Promise((resolve, reject) => {
- fs.writeFile(pathname, data, (error, content) => {
- if (error) {
- reject(error);
- } else {
- resolve(content);
- }
- });
- });
-}
-
-function getStdin () {
- return new Promise(resolve => {
- let data = '';
-
- if (process.stdin.isTTY) {
- resolve(data);
- } else {
- process.stdin.setEncoding('utf8');
-
- process.stdin.on('readable', () => {
- let chunk;
-
- while ((chunk = process.stdin.read())) {
- data += chunk;
- }
- });
-
- process.stdin.on('end', () => {
- resolve(data);
- });
- }
- });
-}
diff --git a/plugins/css-has-pseudo/src/postcss.js b/plugins/css-has-pseudo/src/index.js
similarity index 55%
rename from plugins/css-has-pseudo/src/postcss.js
rename to plugins/css-has-pseudo/src/index.js
index 334f954a2..886bdad63 100644
--- a/plugins/css-has-pseudo/src/postcss.js
+++ b/plugins/css-has-pseudo/src/index.js
@@ -1,53 +1,56 @@
-import parser from 'postcss-selector-parser'
+import parser from 'postcss-selector-parser';
const creator = (/** @type {{ preserve: true | false }} */ opts) => {
- opts = typeof opts === 'object' && opts || defaultOptions
+ opts = typeof opts === 'object' && opts || defaultOptions;
/** Whether the original rule should be preserved. */
- const shouldPreserve = Boolean('preserve' in opts ? opts.preserve : true)
+ const shouldPreserve = Boolean('preserve' in opts ? opts.preserve : true);
return {
postcssPlugin: 'css-has-pseudo',
Rule: rule => {
if (rule.selector.includes(':has(')) {
- const fallbackSelector = getFallbackSelector(rule.selector)
+ const fallbackSelector = getFallbackSelector(rule.selector);
- if (shouldPreserve) rule.cloneBefore({ selector: fallbackSelector })
- else rule.assign({ selector: fallbackSelector })
+ if (shouldPreserve) {
+ rule.cloneBefore({ selector: fallbackSelector });
+ } else {
+ rule.assign({ selector: fallbackSelector });
+ }
}
},
- }
-}
+ };
+};
-creator.postcss = true
+creator.postcss = true;
const getFallbackSelector = (/** @type {string} */ selectorText) => parser(selectors => {
selectors.walkPseudos(selector => {
if (selector.value === ':has' && selector.nodes) {
- const isNotHas = isParentInNotPseudo(selector)
+ const isNotHas = isParentInNotPseudo(selector);
- selector.value = isNotHas ? ':not-has' : ':has'
+ selector.value = isNotHas ? ':not-has' : ':has';
const attribute = parser.attribute({
- attribute: getEscapedCss(String(selector))
- })
+ attribute: getEscapedCss(String(selector)),
+ });
if (isNotHas) {
- selector.parent.parent.replaceWith(attribute)
+ selector.parent.parent.replaceWith(attribute);
} else {
- selector.replaceWith(attribute)
+ selector.replaceWith(attribute);
}
}
- })
-}).processSync(selectorText)
+ });
+}).processSync(selectorText);
/** Default options. */
-const defaultOptions = { preserve: true }
+const defaultOptions = { preserve: true };
/** Returns the string as an escaped CSS identifier. */
-const getEscapedCss = (/** @type {string} */ value) => encodeURIComponent(value).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',').replace(/[():%[\],]/g, '\\$&')
+const getEscapedCss = (/** @type {string} */ value) => encodeURIComponent(value).replace(/%3A/g, ':').replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%2C/g, ',').replace(/[():%[\],]/g, '\\$&');
/** Returns whether the selector is within a `:not` pseudo-class. */
-const isParentInNotPseudo = (selector) => selector.parent?.parent?.type === 'pseudo' && selector.parent.parent.value === ':not'
+const isParentInNotPseudo = (selector) => selector.parent?.parent?.type === 'pseudo' && selector.parent.parent.value === ':not';
-export default creator
+export default creator;
diff --git a/rollup/default-with-browser.js b/rollup/default-with-browser.js
new file mode 100644
index 000000000..4c983e09c
--- /dev/null
+++ b/rollup/default-with-browser.js
@@ -0,0 +1,142 @@
+import babel from '@rollup/plugin-babel';
+import commonjs from '@rollup/plugin-commonjs';
+import path from 'path';
+import { nodeResolve } from '@rollup/plugin-node-resolve';
+import { terser } from 'rollup-plugin-terser';
+
+export default [
+ {
+ input: 'src/index.js',
+ output: [
+ { file: 'dist/index.cjs', format: 'cjs', sourcemap: true, exports: 'auto' },
+ { file: 'dist/index.mjs', format: 'esm', sourcemap: true, exports: 'auto' },
+ ],
+ external: [
+ 'postcss-values-parser',
+ 'postcss-selector-parser',
+ ],
+ plugins: [
+ babel({
+ babelHelpers: 'bundled',
+ exclude: 'node_modules/**',
+ presets: [
+ ['@babel/preset-env', {
+ corejs: 3,
+ loose: true,
+ modules: false,
+ targets: { node: 12 },
+ useBuiltIns: 'usage',
+ }],
+ ],
+ }),
+ terser(),
+ ],
+ },
+ {
+ input: 'src/browser.js',
+ output: [
+ { file: 'dist/browser.cjs', format: 'cjs', sourcemap: true, exports: 'auto', strict: false },
+ ],
+ plugins: [
+ babel({
+ babelHelpers: 'bundled',
+ exclude: 'node_modules/**',
+ presets: [
+ ['@babel/preset-env', {
+ loose: true,
+ modules: false,
+ targets: {
+ browsers: [
+ 'IE >= 8',
+ 'Opera >= 12',
+ 'Safari >= 5.1',
+ 'Chrome >= 15',
+ 'Edge >= 12',
+ 'Firefox >= 4',
+ ],
+ },
+ useBuiltIns: false,
+ }],
+ ],
+ }),
+ ],
+ },
+ {
+ input: 'src/browser-global.js',
+ output: [
+ { file: 'dist/browser-global.js', format: 'iife', sourcemap: true, exports: 'auto', strict: false },
+ ],
+ plugins: [
+ babel({
+ babelHelpers: 'bundled',
+ exclude: 'node_modules/**',
+ presets: [
+ ['@babel/preset-env', {
+ loose: true,
+ modules: false,
+ targets: {
+ browsers: [
+ 'IE >= 8',
+ 'Opera >= 12',
+ 'Safari >= 5.1',
+ 'Chrome >= 15',
+ 'Edge >= 12',
+ 'Firefox >= 4',
+ ],
+ },
+ useBuiltIns: false,
+ }],
+ ],
+ }),
+ ],
+ },
+ {
+ input: 'src/cli.js',
+ output: [
+ { file: 'dist/cli.mjs', format: 'esm', sourcemap: false },
+ ],
+ onwarn: (warning) => {
+ // Silence circular dependency warning for postcss-values-parsers package
+ if (
+ warning.code === 'CIRCULAR_DEPENDENCY' &&
+ warning.importer.indexOf('node_modules/postcss-values-parser/lib') > -1
+ ) {
+ return;
+ }
+
+ console.warn(`(!) ${warning.message}`);
+ },
+ plugins: [
+ commonjs(),
+ nodeResolve({
+ rootDir: path.join(process.cwd(), '..', '..'),
+ }),
+ babel({
+ babelHelpers: 'bundled',
+ exclude: 'node_modules/**',
+ presets: [
+ ['@babel/preset-env', {
+ corejs: 3,
+ loose: true,
+ modules: false,
+ targets: { node: 12 },
+ useBuiltIns: 'usage',
+ }],
+ ],
+ }),
+ terser(),
+ addHashBang(),
+ ],
+ },
+];
+
+function addHashBang () {
+ return {
+ name: 'add-hash-bang',
+ renderChunk (code) {
+ const updatedCode = `#!/usr/bin/env node\n\n${code}`;
+
+ return updatedCode;
+ },
+ };
+}
diff --git a/rollup/default.js b/rollup/default.js
index 0c816deda..38071c1c1 100644
--- a/rollup/default.js
+++ b/rollup/default.js
@@ -11,17 +11,10 @@ export default [
{ file: 'dist/index.cjs', format: 'cjs', sourcemap: true, exports: 'auto' },
{ file: 'dist/index.mjs', format: 'esm', sourcemap: true, exports: 'auto' },
],
- onwarn: (warning) => {
- // Silence circular dependency warning for postcss-values-parsers package
- if (
- warning.code === 'CIRCULAR_DEPENDENCY' &&
- warning.importer.indexOf('node_modules/postcss-values-parser/lib') > -1
- ) {
- return;
- }
-
- console.warn(`(!) ${warning.message}`);
- },
+ external: [
+ 'postcss-values-parser',
+ 'postcss-selector-parser',
+ ],
plugins: [
babel({
babelHelpers: 'bundled',
diff --git a/rollup/default.ts.js b/rollup/default.ts.js
index ea69e1736..7d0df0606 100644
--- a/rollup/default.ts.js
+++ b/rollup/default.ts.js
@@ -14,6 +14,7 @@ export default [
],
external: [
'postcss-values-parser',
+ 'postcss-selector-parser',
],
plugins: [
typescript({ tsconfig: './tsconfig.json' }),