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' }),