diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2023-10-14 15:05:55 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2023-10-14 15:05:55 +0800 |
| commit | c06f7ee0a40255214c477e13d9b956a7e07c2900 (patch) | |
| tree | f5982a568ef8fab865d0142e71c7494fea3e4c1b /node_modules/postcss-minify-selectors | |
| parent | 3fd9400d4dccc25aa29b5702216732e0b7542073 (diff) | |
postcss,(plugins): nanocss, postcss-preset-env
Diffstat (limited to 'node_modules/postcss-minify-selectors')
7 files changed, 402 insertions, 0 deletions
diff --git a/node_modules/postcss-minify-selectors/LICENSE-MIT b/node_modules/postcss-minify-selectors/LICENSE-MIT new file mode 100644 index 00000000..fd0e863a --- /dev/null +++ b/node_modules/postcss-minify-selectors/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) Ben Briggs <beneb.info@gmail.com> (http://beneb.info) + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/postcss-minify-selectors/README.md b/node_modules/postcss-minify-selectors/README.md new file mode 100644 index 00000000..46c87f0b --- /dev/null +++ b/node_modules/postcss-minify-selectors/README.md @@ -0,0 +1,42 @@ +# [postcss][postcss]-minify-selectors + +> Minify selectors with PostCSS. + +## Install + +With [npm](https://www.npmjs.com/package/postcss-minify-selectors) do: + +``` +npm install postcss-minify-selectors --save +``` + +## Example + +### Input + +```css +h1 + p, h2, h3, h2{color:blue} +``` + +### Output + +```css +h1+p,h2,h3{color:blue} +``` + +For more examples see the [tests](test.js). + +## Usage + +See the [PostCSS documentation](https://github.com/postcss/postcss#usage) for +examples for your environment. + +## Contributors + +See [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md). + +## License + +MIT © [Ben Briggs](http://beneb.info) + +[postcss]: https://github.com/postcss/postcss diff --git a/node_modules/postcss-minify-selectors/package.json b/node_modules/postcss-minify-selectors/package.json new file mode 100644 index 00000000..395ec43e --- /dev/null +++ b/node_modules/postcss-minify-selectors/package.json @@ -0,0 +1,43 @@ +{ + "name": "postcss-minify-selectors", + "version": "6.0.0", + "description": "Minify selectors with PostCSS.", + "main": "src/index.js", + "types": "types/index.d.ts", + "files": [ + "src", + "LICENSE-MIT", + "types" + ], + "keywords": [ + "css", + "minify", + "optimise", + "postcss", + "postcss-plugin", + "selectors" + ], + "license": "MIT", + "homepage": "https://github.com/cssnano/cssnano", + "author": { + "name": "Ben Briggs", + "email": "beneb.info@gmail.com", + "url": "http://beneb.info" + }, + "repository": "cssnano/cssnano", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "bugs": { + "url": "https://github.com/cssnano/cssnano/issues" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "devDependencies": { + "postcss": "^8.2.15" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } +}
\ No newline at end of file diff --git a/node_modules/postcss-minify-selectors/src/index.js b/node_modules/postcss-minify-selectors/src/index.js new file mode 100644 index 00000000..9276ff2b --- /dev/null +++ b/node_modules/postcss-minify-selectors/src/index.js @@ -0,0 +1,260 @@ +'use strict'; +const parser = require('postcss-selector-parser'); +const canUnquote = require('./lib/canUnquote.js'); + +const pseudoElements = new Set([ + '::before', + '::after', + '::first-letter', + '::first-line', +]); + +/** + * @param {parser.Attribute} selector + * @return {void} + */ +function attribute(selector) { + if (selector.value) { + if (selector.raws.value) { + // Join selectors that are split over new lines + selector.raws.value = selector.raws.value.replace(/\\\n/g, '').trim(); + } + if (canUnquote(selector.value)) { + selector.quoteMark = null; + } + + if (selector.operator) { + selector.operator = /** @type {parser.AttributeOperator} */ ( + selector.operator.trim() + ); + } + } + + selector.rawSpaceBefore = ''; + selector.rawSpaceAfter = ''; + selector.spaces.attribute = { before: '', after: '' }; + selector.spaces.operator = { before: '', after: '' }; + selector.spaces.value = { + before: '', + after: selector.insensitive ? ' ' : '', + }; + + if (selector.raws.spaces) { + selector.raws.spaces.attribute = { + before: '', + after: '', + }; + + selector.raws.spaces.operator = { + before: '', + after: '', + }; + + selector.raws.spaces.value = { + before: '', + after: selector.insensitive ? ' ' : '', + }; + + if (selector.insensitive) { + selector.raws.spaces.insensitive = { + before: '', + after: '', + }; + } + } + + selector.attribute = selector.attribute.trim(); +} + +/** + * @param {parser.Combinator} selector + * @return {void} + */ +function combinator(selector) { + const value = selector.value.trim(); + selector.spaces.before = ''; + selector.spaces.after = ''; + selector.rawSpaceBefore = ''; + selector.rawSpaceAfter = ''; + selector.value = value.length ? value : ' '; +} + +const pseudoReplacements = new Map([ + [':nth-child', ':first-child'], + [':nth-of-type', ':first-of-type'], + [':nth-last-child', ':last-child'], + [':nth-last-of-type', ':last-of-type'], +]); + +/** + * @param {parser.Pseudo} selector + * @return {void} + */ +function pseudo(selector) { + const value = selector.value.toLowerCase(); + + if (selector.nodes.length === 1 && pseudoReplacements.has(value)) { + const first = selector.at(0); + const one = first.at(0); + + if (first.length === 1) { + if (one.value === '1') { + selector.replaceWith( + parser.pseudo({ + value: /** @type {string} */ (pseudoReplacements.get(value)), + }) + ); + } + + if (one.value && one.value.toLowerCase() === 'even') { + one.value = '2n'; + } + } + + if (first.length === 3) { + const two = first.at(1); + const three = first.at(2); + + if ( + one.value && + one.value.toLowerCase() === '2n' && + two.value === '+' && + three.value === '1' + ) { + one.value = 'odd'; + + two.remove(); + three.remove(); + } + } + + return; + } + + selector.walk((child) => { + if (child.type === 'selector' && child.parent) { + const uniques = new Set(); + child.parent.each((sibling) => { + const siblingStr = String(sibling); + + if (!uniques.has(siblingStr)) { + uniques.add(siblingStr); + } else { + sibling.remove(); + } + }); + } + }); + + if (pseudoElements.has(value)) { + selector.value = selector.value.slice(1); + } +} + +const tagReplacements = new Map([ + ['from', '0%'], + ['100%', 'to'], +]); + +/** + * @param {parser.Tag} selector + * @return {void} + */ +function tag(selector) { + const value = selector.value.toLowerCase(); + + if (tagReplacements.has(value)) { + selector.value = /** @type {string} */ (tagReplacements.get(value)); + } +} + +/** + * @param {parser.Universal} selector + * @return {void} + */ +function universal(selector) { + const next = selector.next(); + + if (next && next.type !== 'combinator') { + selector.remove(); + } +} + +const reducers = new Map( + /** @type {[string, ((selector: parser.Node) => void)][]}*/ ([ + ['attribute', attribute], + ['combinator', combinator], + ['pseudo', pseudo], + ['tag', tag], + ['universal', universal], + ]) +); + +/** + * @type {import('postcss').PluginCreator<void>} + * @return {import('postcss').Plugin} + */ +function pluginCreator() { + return { + postcssPlugin: 'postcss-minify-selectors', + + OnceExit(css) { + const cache = new Map(); + const processor = parser((selectors) => { + const uniqueSelectors = new Set(); + + selectors.walk((sel) => { + // Trim whitespace around the value + sel.spaces.before = sel.spaces.after = ''; + const reducer = reducers.get(sel.type); + if (reducer !== undefined) { + reducer(sel); + return; + } + + const toString = String(sel); + + if ( + sel.type === 'selector' && + sel.parent && + sel.parent.type !== 'pseudo' + ) { + if (!uniqueSelectors.has(toString)) { + uniqueSelectors.add(toString); + } else { + sel.remove(); + } + } + }); + selectors.nodes.sort(); + }); + + css.walkRules((rule) => { + const selector = + rule.raws.selector && rule.raws.selector.value === rule.selector + ? rule.raws.selector.raw + : rule.selector; + + // If the selector ends with a ':' it is likely a part of a custom mixin, + // so just pass through. + if (selector[selector.length - 1] === ':') { + return; + } + + if (cache.has(selector)) { + rule.selector = cache.get(selector); + + return; + } + + const optimizedSelector = processor.processSync(selector); + + rule.selector = optimizedSelector; + cache.set(selector, optimizedSelector); + }); + }, + }; +} + +pluginCreator.postcss = true; +module.exports = pluginCreator; diff --git a/node_modules/postcss-minify-selectors/src/lib/canUnquote.js b/node_modules/postcss-minify-selectors/src/lib/canUnquote.js new file mode 100644 index 00000000..aeefa171 --- /dev/null +++ b/node_modules/postcss-minify-selectors/src/lib/canUnquote.js @@ -0,0 +1,24 @@ +'use strict'; +/** + * Can unquote attribute detection from mothereff.in + * Copyright Mathias Bynens <https://mathiasbynens.be/> + * https://github.com/mathiasbynens/mothereff.in + */ +const escapes = /\\([0-9A-Fa-f]{1,6})[ \t\n\f\r]?/g; +const range = + // eslint-disable-next-line no-control-regex + /[\u0000-\u002c\u002e\u002f\u003A-\u0040\u005B-\u005E\u0060\u007B-\u009f]/; + +/** + * @param {string} value + * @return {boolean} + */ +module.exports = function canUnquote(value) { + if (value === '-' || value === '') { + return false; + } + + value = value.replace(escapes, 'a').replace(/\\./g, 'a'); + + return !(range.test(value) || /^(?:-?\d|--)/.test(value)); +}; diff --git a/node_modules/postcss-minify-selectors/types/index.d.ts b/node_modules/postcss-minify-selectors/types/index.d.ts new file mode 100644 index 00000000..d2beadb6 --- /dev/null +++ b/node_modules/postcss-minify-selectors/types/index.d.ts @@ -0,0 +1,9 @@ +export = pluginCreator; +/** + * @type {import('postcss').PluginCreator<void>} + * @return {import('postcss').Plugin} + */ +declare function pluginCreator(): import('postcss').Plugin; +declare namespace pluginCreator { + const postcss: true; +} diff --git a/node_modules/postcss-minify-selectors/types/lib/canUnquote.d.ts b/node_modules/postcss-minify-selectors/types/lib/canUnquote.d.ts new file mode 100644 index 00000000..3fd1c4e4 --- /dev/null +++ b/node_modules/postcss-minify-selectors/types/lib/canUnquote.d.ts @@ -0,0 +1,2 @@ +declare function _exports(value: string): boolean; +export = _exports; |
