8889841cPK@[4 README.mdnuW+A# [postcss][postcss]-discard-duplicates > Discard duplicate rules in your CSS files with PostCSS. ## Install With [npm](https://npmjs.org/package/postcss-discard-duplicates) do: ``` npm install postcss-discard-duplicates --save ``` ## Example This module will remove all duplicate rules from your stylesheets. It works on at rules, normal rules and declarations. Note that this module does not have any responsibility for normalising declarations, selectors or whitespace, so that it considers these two rules to be different: ```css h1, h2 { color: blue; } h2, h1 { color: blue; } ``` It has to assume that your rules have already been transformed by another processor, otherwise it would be responsible for too many things. ### Input ```css h1 { margin: 0 auto; margin: 0 auto } h1 { margin: 0 auto } ``` ### Output ```css h1 { margin: 0 auto } ``` ## 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 PK@[. src/index.jsnuW+A'use strict'; /** * @param {string | undefined} value * @return {string | undefined} */ function trimValue(value) { return value ? value.trim() : value; } /** * @param {{nodes: import('postcss').Node[]}} node * @return {boolean} */ function empty(node) { return !node.nodes.filter((child) => child.type !== 'comment').length; } /** * @param {import('postcss').AnyNode} nodeA * @param {import('postcss').AnyNode} nodeB * @return {boolean} */ function equals(nodeA, nodeB) { const a = /** @type {any} */ (nodeA); const b = /** @type {any} */ (nodeB); if (a.type !== b.type) { return false; } if (a.important !== b.important) { return false; } if ((a.raws && !b.raws) || (!a.raws && b.raws)) { return false; } switch (a.type) { case 'rule': if (a.selector !== b.selector) { return false; } break; case 'atrule': if (a.name !== b.name || a.params !== b.params) { return false; } if (a.raws && trimValue(a.raws.before) !== trimValue(b.raws.before)) { return false; } if ( a.raws && trimValue(a.raws.afterName) !== trimValue(b.raws.afterName) ) { return false; } break; case 'decl': if (a.prop !== b.prop || a.value !== b.value) { return false; } if (a.raws && trimValue(a.raws.before) !== trimValue(b.raws.before)) { return false; } break; } if (a.nodes) { if (a.nodes.length !== b.nodes.length) { return false; } for (let i = 0; i < a.nodes.length; i++) { if (!equals(a.nodes[i], b.nodes[i])) { return false; } } } return true; } /** * @param {import('postcss').Rule} last * @param {import('postcss').AnyNode[]} nodes * @return {void} */ function dedupeRule(last, nodes) { let index = nodes.indexOf(last) - 1; while (index >= 0) { const node = nodes[index--]; if (node && node.type === 'rule' && node.selector === last.selector) { last.each((child) => { if (child.type === 'decl') { dedupeNode(child, node.nodes); } }); if (empty(node)) { node.remove(); } } } } /** * @param {import('postcss').AtRule | import('postcss').Declaration} last * @param {import('postcss').AnyNode[]} nodes * @return {void} */ function dedupeNode(last, nodes) { let index = nodes.includes(last) ? nodes.indexOf(last) - 1 : nodes.length - 1; while (index >= 0) { const node = nodes[index--]; if (node && equals(node, last)) { node.remove(); } } } /** * @param {import('postcss').AnyNode} root * @return {void} */ function dedupe(root) { const { nodes } = /** @type {import('postcss').Container} */ ( root ); if (!nodes) { return; } let index = nodes.length - 1; while (index >= 0) { let last = nodes[index--]; if (!last || !last.parent) { continue; } dedupe(last); if (last.type === 'rule') { dedupeRule(last, nodes); } else if (last.type === 'atrule' || last.type === 'decl') { dedupeNode(last, nodes); } } } /** * @type {import('postcss').PluginCreator} * @return {import('postcss').Plugin} */ function pluginCreator() { return { postcssPlugin: 'postcss-discard-duplicates', OnceExit(css) { dedupe(css); }, }; } pluginCreator.postcss = true; module.exports = pluginCreator; PK@[m;Ӭtypes/index.d.tsnuW+Aexport = pluginCreator; /** * @type {import('postcss').PluginCreator} * @return {import('postcss').Plugin} */ declare function pluginCreator(): import('postcss').Plugin; declare namespace pluginCreator { const postcss: true; } PK@[͍DD LICENSE-MITnuW+ACopyright (c) Ben Briggs (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. PK@[( ?? package.jsonnuW+A{ "name": "postcss-discard-duplicates", "version": "5.1.0", "description": "Discard duplicate rules in your CSS files with PostCSS.", "main": "src/index.js", "types": "types/index.d.ts", "files": [ "src", "LICENSE-MIT", "types" ], "keywords": [ "css", "dedupe", "optimise", "postcss", "postcss-plugin" ], "license": "MIT", "homepage": "https://github.com/cssnano/cssnano", "author": { "name": "Ben Briggs", "email": "beneb.info@gmail.com", "url": "http://beneb.info" }, "repository": "cssnano/cssnano", "bugs": { "url": "https://github.com/cssnano/cssnano/issues" }, "engines": { "node": "^10 || ^12 || >=14.0" }, "devDependencies": { "postcss": "^8.2.15" }, "peerDependencies": { "postcss": "^8.2.15" }, "readme": "# [postcss][postcss]-discard-duplicates\n\n> Discard duplicate rules in your CSS files with PostCSS.\n\n## Install\n\nWith [npm](https://npmjs.org/package/postcss-discard-duplicates) do:\n\n```\nnpm install postcss-discard-duplicates --save\n```\n\n## Example\n\nThis module will remove all duplicate rules from your stylesheets. It works on\nat rules, normal rules and declarations. Note that this module does not have any\nresponsibility for normalising declarations, selectors or whitespace, so that it\nconsiders these two rules to be different:\n\n```css\nh1, h2 {\n color: blue;\n}\n\nh2, h1 {\n color: blue;\n}\n```\n\nIt has to assume that your rules have already been transformed by another\nprocessor, otherwise it would be responsible for too many things.\n\n### Input\n\n```css\nh1 {\n margin: 0 auto;\n margin: 0 auto\n}\n\nh1 {\n margin: 0 auto\n}\n```\n\n### Output\n\n```css\nh1 {\n margin: 0 auto\n}\n```\n\n## Usage\n\nSee the [PostCSS documentation](https://github.com/postcss/postcss#usage) for\nexamples for your environment.\n\n\n## Contributors\n\nSee [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md).\n\n\n## License\n\nMIT © [Ben Briggs](http://beneb.info)\n\n\n[postcss]: https://github.com/postcss/postcss\n" }PK@[4 README.mdnuW+APK@[. src/index.jsnuW+APK@[m;Ӭtypes/index.d.tsnuW+APK@[͍DD LICENSE-MITnuW+APK@[( ?? |package.jsonnuW+APK|