New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

postcss-discard-unused

Package Overview
Dependencies
Maintainers
8
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

postcss-discard-unused - npm Package Compare versions

Comparing version 4.0.1 to 5.0.0-rc.0

47

CHANGELOG.md

@@ -1,50 +0,31 @@

# 4.0.0-rc.0
# Change Log
* Breaking: Drops support for Node 0.12, we now require at least Node 4.
* Breaking: Update PostCSS to 6.0.0.
* Resolves an issue with the module not properly detecting namespaces
within attribute selectors.
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# 2.2.3
# 5.0.0-rc.0 (2021-02-19)
* Font lookup is now case-insensitive, preventing unwanted removal of fonts
that are used (thanks to @thomas-mcdonald).
# 2.2.2
### chore
* Removed a dependency on `flatten`.
* Performance tweaks; now performs a single AST pass instead of four.
* minimum require version of node is 10.13 ([#871](https://github.com/cssnano/cssnano/issues/871)) ([28bda24](https://github.com/cssnano/cssnano/commit/28bda243e32ce3ba89b3c358a5f78727b3732f11))
# 2.2.1
* Now compiled with Babel 6.
### Features
# 2.2.0
* migarete to PostCSS 8 ([#975](https://github.com/cssnano/cssnano/issues/975)) ([40b82dc](https://github.com/cssnano/cssnano/commit/40b82dca7f53ac02cd4fe62846dec79b898ccb49))
* Added a new option to remove `@namespace` rules (thanks to @plesiecki).
# 2.1.0
### BREAKING CHANGES
* Added options to customise what the module discards (thanks to @TrySound).
* minimum supported `postcss` version is `8.2.1`
* minimum require version of node is 10.13
# 2.0.0
* Upgraded to PostCSS 5.
# 1.0.3
## 4.1.1 (2018-09-24)
* Improved performance by reducing the amount of AST iterations.
* Converted the codebase to ES6.
# 1.0.2
### Bug Fixes
* Fixes an integration issue where the module would crash on `undefined`
`rule.nodes`.
# 1.0.1
* Fixes an issue where multiple animations were not being recognized.
# 1.0.0
* Initial release.
* **postcss-merge-longhand:** not mangle border output ([#555](https://github.com/cssnano/cssnano/issues/555)) ([9a70605](https://github.com/cssnano/cssnano/commit/9a706050b621e7795a9bf74eb7110b5c81804ffe)), closes [#553](https://github.com/cssnano/cssnano/issues/553) [#554](https://github.com/cssnano/cssnano/issues/554)

@@ -1,21 +0,12 @@

'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true
});
exports.default = void 0;
var _uniqs = require('uniqs');
var _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser"));
var _uniqs2 = _interopRequireDefault(_uniqs);
var _postcss = require('postcss');
var _postcssSelectorParser = require('postcss-selector-parser');
var _postcssSelectorParser2 = _interopRequireDefault(_postcssSelectorParser);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const { comma, space } = _postcss.list;
const atrule = 'atrule';

@@ -25,113 +16,195 @@ const decl = 'decl';

function addValues(cache, { value }) {
return comma(value).reduce((memo, val) => [...memo, ...space(val)], cache);
function uniqs(items) {
return items.filter(function (item, i) {
return i === items.indexOf(item);
});
}
function filterAtRule({ atRules, values }) {
values = (0, _uniqs2.default)(values);
atRules.forEach(node => {
const hasAtRule = values.some(value => value === node.params);
if (!hasAtRule) {
node.remove();
}
});
function addValues(cache, {
value
}, comma, space) {
return comma(value).reduce((memo, val) => [...memo, ...space(val)], cache);
}
function filterNamespace({ atRules, rules }) {
rules = (0, _uniqs2.default)(rules);
atRules.forEach(atRule => {
const { 0: param, length: len } = atRule.params.split(' ').filter(Boolean);
if (len === 1) {
return;
}
const hasRule = rules.some(r => r === param || r === '*');
if (!hasRule) {
atRule.remove();
}
});
function filterAtRule({
atRules,
values
}) {
values = uniqs(values);
atRules.forEach(node => {
const hasAtRule = values.some(value => value === node.params);
if (!hasAtRule) {
node.remove();
}
});
}
function hasFont(fontFamily, cache) {
return comma(fontFamily).some(font => cache.some(c => ~c.indexOf(font)));
function filterNamespace({
atRules,
rules
}) {
rules = uniqs(rules);
atRules.forEach(atRule => {
const {
0: param,
length: len
} = atRule.params.split(' ').filter(Boolean);
if (len === 1) {
return;
}
const hasRule = rules.some(r => r === param || r === '*');
if (!hasRule) {
atRule.remove();
}
});
}
// fonts have slightly different logic
function filterFont({ atRules, values }) {
values = (0, _uniqs2.default)(values);
atRules.forEach(r => {
const families = r.nodes.filter(({ prop }) => prop === 'font-family');
// Discard the @font-face if it has no font-family
if (!families.length) {
return r.remove();
}
families.forEach(family => {
if (!hasFont(family.value.toLowerCase(), values)) {
r.remove();
}
});
function hasFont(fontFamily, cache, comma) {
return comma(fontFamily).some(font => cache.some(c => ~c.indexOf(font)));
} // fonts have slightly different logic
function filterFont({
atRules,
values
}, comma) {
values = uniqs(values);
atRules.forEach(r => {
const families = r.nodes.filter(({
prop
}) => prop === 'font-family'); // Discard the @font-face if it has no font-family
if (!families.length) {
return r.remove();
}
families.forEach(family => {
if (!hasFont(family.value.toLowerCase(), values, comma)) {
r.remove();
}
});
});
}
exports.default = (0, _postcss.plugin)('postcss-discard-unused', opts => {
const { fontFace, counterStyle, keyframes, namespace } = Object.assign({}, {
fontFace: true,
counterStyle: true,
keyframes: true,
namespace: true
}, opts);
return css => {
const counterStyleCache = { atRules: [], values: [] };
const keyframesCache = { atRules: [], values: [] };
const namespaceCache = { atRules: [], rules: [] };
const fontCache = { atRules: [], values: [] };
css.walk(node => {
const { type, prop, selector, name } = node;
function pluginCreator(opts) {
const {
fontFace,
counterStyle,
keyframes,
namespace
} = Object.assign({}, {
fontFace: true,
counterStyle: true,
keyframes: true,
namespace: true
}, opts);
return {
postcssPlugin: 'postcss-discard-unused',
prepare() {
const counterStyleCache = {
atRules: [],
values: []
};
const keyframesCache = {
atRules: [],
values: []
};
const namespaceCache = {
atRules: [],
rules: []
};
const fontCache = {
atRules: [],
values: []
};
return {
OnceExit(css, {
list
}) {
const {
comma,
space
} = list;
css.walk(node => {
const {
type,
prop,
selector,
name
} = node;
if (type === rule && namespace && ~selector.indexOf('|')) {
if (~selector.indexOf('[')) {
// Attribute selector, so we should parse further.
(0, _postcssSelectorParser2.default)(ast => {
ast.walkAttributes(({ namespace: ns }) => {
namespaceCache.rules = namespaceCache.rules.concat(ns);
});
}).process(selector);
} else {
// Use a simple split function for the namespace
namespaceCache.rules = namespaceCache.rules.concat(selector.split('|')[0]);
}
return;
if (~selector.indexOf('[')) {
// Attribute selector, so we should parse further.
(0, _postcssSelectorParser.default)(ast => {
ast.walkAttributes(({
namespace: ns
}) => {
namespaceCache.rules = namespaceCache.rules.concat(ns);
});
}).process(selector);
} else {
// Use a simple split function for the namespace
namespaceCache.rules = namespaceCache.rules.concat(selector.split('|')[0]);
}
return;
}
if (type === decl) {
if (counterStyle && /list-style|system/.test(prop)) {
counterStyleCache.values = addValues(counterStyleCache.values, node);
}
if (fontFace && node.parent.type === rule && /font(|-family)/.test(prop)) {
fontCache.values = fontCache.values.concat(comma(node.value.toLowerCase()));
}
if (keyframes && /animation/.test(prop)) {
keyframesCache.values = addValues(keyframesCache.values, node);
}
return;
if (counterStyle && /list-style|system/.test(prop)) {
counterStyleCache.values = addValues(counterStyleCache.values, node, comma, space);
}
if (fontFace && node.parent.type === rule && /font(|-family)/.test(prop)) {
fontCache.values = fontCache.values.concat(comma(node.value.toLowerCase()));
}
if (keyframes && /animation/.test(prop)) {
keyframesCache.values = addValues(keyframesCache.values, node, comma, space);
}
return;
}
if (type === atrule) {
if (counterStyle && /counter-style/.test(name)) {
counterStyleCache.atRules.push(node);
}
if (fontFace && name === 'font-face' && node.nodes) {
fontCache.atRules.push(node);
}
if (keyframes && /keyframes/.test(name)) {
keyframesCache.atRules.push(node);
}
if (namespace && name === 'namespace') {
namespaceCache.atRules.push(node);
}
return;
if (counterStyle && /counter-style/.test(name)) {
counterStyleCache.atRules.push(node);
}
if (fontFace && name === 'font-face' && node.nodes) {
fontCache.atRules.push(node);
}
if (keyframes && /keyframes/.test(name)) {
keyframesCache.atRules.push(node);
}
if (namespace && name === 'namespace') {
namespaceCache.atRules.push(node);
}
return;
}
});
counterStyle && filterAtRule(counterStyleCache);
fontFace && filterFont(fontCache);
keyframes && filterAtRule(keyframesCache);
namespace && filterNamespace(namespaceCache);
};
});
module.exports = exports['default'];
});
counterStyle && filterAtRule(counterStyleCache);
fontFace && filterFont(fontCache, comma);
keyframes && filterAtRule(keyframesCache);
namespace && filterNamespace(namespaceCache);
}
};
}
};
}
pluginCreator.postcss = true;
var _default = pluginCreator;
exports.default = _default;
module.exports = exports.default;
{
"name": "postcss-discard-unused",
"version": "4.0.1",
"version": "5.0.0-rc.0",
"description": "Discard unused counter styles, keyframes and fonts.",

@@ -12,3 +12,5 @@ "main": "dist/index.js",

"scripts": {
"prepublish": "cross-env BABEL_ENV=publish babel src --out-dir dist --ignore /__tests__/"
"prebuild": "del-cli dist",
"build": "cross-env BABEL_ENV=publish babel src --config-file ../../babel.config.js --out-dir dist --ignore \"**/__tests__/\"",
"prepublish": "yarn build"
},

@@ -24,6 +26,2 @@ "keywords": [

"license": "MIT",
"devDependencies": {
"babel-cli": "^6.0.0",
"cross-env": "^5.0.0"
},
"homepage": "https://github.com/cssnano/cssnano",

@@ -37,5 +35,3 @@ "author": {

"dependencies": {
"postcss": "^7.0.0",
"postcss-selector-parser": "^3.0.0",
"uniqs": "^2.0.0"
"postcss-selector-parser": "^6.0.4"
},

@@ -46,4 +42,11 @@ "bugs": {

"engines": {
"node": ">=6.9.0"
}
"node": "^10 || ^12 || >=14.0"
},
"devDependencies": {
"postcss": "^8.2.1"
},
"peerDependencies": {
"postcss": "^8.2.1"
},
"gitHead": "8c16e67a4d24a13ac7e09a36d4faf504196efd0f"
}
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