postcss-colormin 5.2.3 → 5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -8
- package/src/index.js +159 -0
- package/src/minifyColor.js +28 -0
- package/types/index.d.ts +10 -0
- package/types/minifyColor.d.ts +2 -0
- package/dist/index.js +0 -144
- package/dist/minifyColor.js +0 -38
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "postcss-colormin",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "Minify colors in your CSS files with PostCSS.",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"types": "types/index.d.ts",
|
|
6
7
|
"files": [
|
|
7
|
-
"
|
|
8
|
-
"LICENSE-MIT"
|
|
8
|
+
"src",
|
|
9
|
+
"LICENSE-MIT",
|
|
10
|
+
"types"
|
|
9
11
|
],
|
|
10
12
|
"keywords": [
|
|
11
13
|
"color",
|
|
@@ -37,14 +39,11 @@
|
|
|
37
39
|
"node": "^10 || ^12 || >=14.0"
|
|
38
40
|
},
|
|
39
41
|
"devDependencies": {
|
|
42
|
+
"@types/caniuse-api": "^3.0.2",
|
|
40
43
|
"postcss": "^8.2.15"
|
|
41
44
|
},
|
|
42
45
|
"peerDependencies": {
|
|
43
46
|
"postcss": "^8.2.15"
|
|
44
47
|
},
|
|
45
|
-
"scripts": {
|
|
46
|
-
"prebuild": "rimraf dist",
|
|
47
|
-
"build": "babel src --config-file ../../babel.config.json --out-dir dist --ignore \"**/__tests__/\""
|
|
48
|
-
},
|
|
49
48
|
"readme": "# [postcss][postcss]-colormin\n\n> Minify colors in your CSS files with PostCSS.\n\n## Install\n\nWith [npm](https://npmjs.org/package/postcss-colormin) do:\n\n```\nnpm install postcss-colormin --save\n```\n\n\n## Example\n\n```js\nvar postcss = require('postcss')\nvar colormin = require('postcss-colormin');\n\nvar css = 'h1 {color: rgba(255, 0, 0, 1)}';\nconsole.log(postcss(colormin()).process(css).css);\n\n// => 'h1 {color:red}'\n```\n\nFor more examples see the [tests](src/__tests__/index.js).\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"
|
|
50
49
|
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const browserslist = require('browserslist');
|
|
3
|
+
const { isSupported } = require('caniuse-api');
|
|
4
|
+
const valueParser = require('postcss-value-parser');
|
|
5
|
+
const minifyColor = require('./minifyColor');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {{nodes: valueParser.Node[]}} parent
|
|
9
|
+
* @param {(node: valueParser.Node, index: number, parent: {nodes: valueParser.Node[]}) => false | undefined} callback
|
|
10
|
+
* @return {void}
|
|
11
|
+
*/
|
|
12
|
+
function walk(parent, callback) {
|
|
13
|
+
parent.nodes.forEach((node, index) => {
|
|
14
|
+
const bubble = callback(node, index, parent);
|
|
15
|
+
|
|
16
|
+
if (node.type === 'function' && bubble !== false) {
|
|
17
|
+
walk(node, callback);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* IE 8 & 9 do not properly handle clicks on elements
|
|
24
|
+
* with a `transparent` `background-color`.
|
|
25
|
+
*
|
|
26
|
+
* https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer
|
|
27
|
+
*/
|
|
28
|
+
const browsersWithTransparentBug = new Set(['ie 8', 'ie 9']);
|
|
29
|
+
const mathFunctions = new Set(['calc', 'min', 'max', 'clamp']);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @param {valueParser.Node} node
|
|
33
|
+
* @return {boolean}
|
|
34
|
+
*/
|
|
35
|
+
function isMathFunctionNode(node) {
|
|
36
|
+
if (node.type !== 'function') {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return mathFunctions.has(node.value.toLowerCase());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {string} value
|
|
44
|
+
* @param {Record<string, boolean>} options
|
|
45
|
+
* @return {string}
|
|
46
|
+
*/
|
|
47
|
+
function transform(value, options) {
|
|
48
|
+
const parsed = valueParser(value);
|
|
49
|
+
|
|
50
|
+
walk(parsed, (node, index, parent) => {
|
|
51
|
+
if (node.type === 'function') {
|
|
52
|
+
if (/^(rgb|hsl)a?$/i.test(node.value)) {
|
|
53
|
+
const { value: originalValue } = node;
|
|
54
|
+
|
|
55
|
+
node.value = minifyColor(valueParser.stringify(node), options);
|
|
56
|
+
/** @type {string} */ (node.type) = 'word';
|
|
57
|
+
|
|
58
|
+
const next = parent.nodes[index + 1];
|
|
59
|
+
|
|
60
|
+
if (
|
|
61
|
+
node.value !== originalValue &&
|
|
62
|
+
next &&
|
|
63
|
+
(next.type === 'word' || next.type === 'function')
|
|
64
|
+
) {
|
|
65
|
+
parent.nodes.splice(
|
|
66
|
+
index + 1,
|
|
67
|
+
0,
|
|
68
|
+
/** @type {valueParser.SpaceNode} */ ({
|
|
69
|
+
type: 'space',
|
|
70
|
+
value: ' ',
|
|
71
|
+
})
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
} else if (isMathFunctionNode(node)) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
} else if (node.type === 'word') {
|
|
78
|
+
node.value = minifyColor(node.value, options);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return parsed.toString();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @param {Record<string, boolean>} options
|
|
87
|
+
* @param {string[]} browsers
|
|
88
|
+
* @return {Record<string, boolean>}
|
|
89
|
+
*/
|
|
90
|
+
function addPluginDefaults(options, browsers) {
|
|
91
|
+
const defaults = {
|
|
92
|
+
// Does the browser support 4 & 8 character hex notation
|
|
93
|
+
transparent:
|
|
94
|
+
browsers.some((b) => browsersWithTransparentBug.has(b)) === false,
|
|
95
|
+
// Does the browser support "transparent" value properly
|
|
96
|
+
alphaHex: isSupported('css-rrggbbaa', browsers),
|
|
97
|
+
name: true,
|
|
98
|
+
};
|
|
99
|
+
return { ...defaults, ...options };
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* @type {import('postcss').PluginCreator<Record<string, boolean>>}
|
|
103
|
+
* @param {Record<string, boolean>} config
|
|
104
|
+
* @return {import('postcss').Plugin}
|
|
105
|
+
*/
|
|
106
|
+
function pluginCreator(config = {}) {
|
|
107
|
+
return {
|
|
108
|
+
postcssPlugin: 'postcss-colormin',
|
|
109
|
+
|
|
110
|
+
prepare(result) {
|
|
111
|
+
/** @type {typeof result.opts & browserslist.Options} */
|
|
112
|
+
const resultOptions = result.opts || {};
|
|
113
|
+
const browsers = browserslist(null, {
|
|
114
|
+
stats: resultOptions.stats,
|
|
115
|
+
path: __dirname,
|
|
116
|
+
env: resultOptions.env,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const cache = new Map();
|
|
120
|
+
const options = addPluginDefaults(config, browsers);
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
OnceExit(css) {
|
|
124
|
+
css.walkDecls((decl) => {
|
|
125
|
+
if (
|
|
126
|
+
/^(composes|font|filter|-webkit-tap-highlight-color)/i.test(
|
|
127
|
+
decl.prop
|
|
128
|
+
)
|
|
129
|
+
) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const value = decl.value;
|
|
134
|
+
|
|
135
|
+
if (!value) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const cacheKey = JSON.stringify({ value, options, browsers });
|
|
140
|
+
|
|
141
|
+
if (cache.has(cacheKey)) {
|
|
142
|
+
decl.value = cache.get(cacheKey);
|
|
143
|
+
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const newValue = transform(value, options);
|
|
148
|
+
|
|
149
|
+
decl.value = newValue;
|
|
150
|
+
cache.set(cacheKey, newValue);
|
|
151
|
+
});
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
pluginCreator.postcss = true;
|
|
159
|
+
module.exports = pluginCreator;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const { colord, extend } = require('colord');
|
|
3
|
+
const namesPlugin = require('colord/plugins/names');
|
|
4
|
+
const minifierPlugin = require('colord/plugins/minify');
|
|
5
|
+
|
|
6
|
+
extend(/** @type {any[]} */ ([namesPlugin, minifierPlugin]));
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Performs color value minification
|
|
10
|
+
*
|
|
11
|
+
* @param {string} input - CSS value
|
|
12
|
+
* @param {Record<string, boolean>} options object with colord.minify() options
|
|
13
|
+
* @return {string}
|
|
14
|
+
*/
|
|
15
|
+
module.exports = function minifyColor(input, options = {}) {
|
|
16
|
+
const instance = colord(input);
|
|
17
|
+
|
|
18
|
+
if (instance.isValid()) {
|
|
19
|
+
// Try to shorten the string if it is a valid CSS color value
|
|
20
|
+
const minified = instance.minify(options);
|
|
21
|
+
|
|
22
|
+
// Fall back to the original input if it's smaller or has equal length
|
|
23
|
+
return minified.length < input.length ? minified : input.toLowerCase();
|
|
24
|
+
} else {
|
|
25
|
+
// Possibly malformed, so pass through
|
|
26
|
+
return input;
|
|
27
|
+
}
|
|
28
|
+
};
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export = pluginCreator;
|
|
2
|
+
/**
|
|
3
|
+
* @type {import('postcss').PluginCreator<Record<string, boolean>>}
|
|
4
|
+
* @param {Record<string, boolean>} config
|
|
5
|
+
* @return {import('postcss').Plugin}
|
|
6
|
+
*/
|
|
7
|
+
declare function pluginCreator(config?: Record<string, boolean>): import('postcss').Plugin;
|
|
8
|
+
declare namespace pluginCreator {
|
|
9
|
+
const postcss: true;
|
|
10
|
+
}
|
package/dist/index.js
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
|
|
8
|
-
var _browserslist = _interopRequireDefault(require("browserslist"));
|
|
9
|
-
|
|
10
|
-
var _caniuseApi = require("caniuse-api");
|
|
11
|
-
|
|
12
|
-
var _postcssValueParser = _interopRequireWildcard(require("postcss-value-parser"));
|
|
13
|
-
|
|
14
|
-
var _minifyColor = _interopRequireDefault(require("./minifyColor"));
|
|
15
|
-
|
|
16
|
-
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
17
|
-
|
|
18
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
19
|
-
|
|
20
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
|
-
|
|
22
|
-
function walk(parent, callback) {
|
|
23
|
-
parent.nodes.forEach((node, index) => {
|
|
24
|
-
const bubble = callback(node, index, parent);
|
|
25
|
-
|
|
26
|
-
if (node.nodes && bubble !== false) {
|
|
27
|
-
walk(node, callback);
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
/*
|
|
32
|
-
* IE 8 & 9 do not properly handle clicks on elements
|
|
33
|
-
* with a `transparent` `background-color`.
|
|
34
|
-
*
|
|
35
|
-
* https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer
|
|
36
|
-
*/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
function hasTransparentBug(browser) {
|
|
40
|
-
return ~['ie 8', 'ie 9'].indexOf(browser);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function isMathFunctionNode(node) {
|
|
44
|
-
if (node.type !== 'function') {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return ['calc', 'min', 'max', 'clamp'].includes(node.value.toLowerCase());
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function transform(value, options) {
|
|
52
|
-
const parsed = (0, _postcssValueParser.default)(value);
|
|
53
|
-
walk(parsed, (node, index, parent) => {
|
|
54
|
-
if (node.type === 'function') {
|
|
55
|
-
if (/^(rgb|hsl)a?$/i.test(node.value)) {
|
|
56
|
-
const {
|
|
57
|
-
value: originalValue
|
|
58
|
-
} = node;
|
|
59
|
-
node.value = (0, _minifyColor.default)((0, _postcssValueParser.stringify)(node), options);
|
|
60
|
-
node.type = 'word';
|
|
61
|
-
const next = parent.nodes[index + 1];
|
|
62
|
-
|
|
63
|
-
if (node.value !== originalValue && next && (next.type === 'word' || next.type === 'function')) {
|
|
64
|
-
parent.nodes.splice(index + 1, 0, {
|
|
65
|
-
type: 'space',
|
|
66
|
-
value: ' '
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
} else if (isMathFunctionNode(node)) {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
} else if (node.type === 'word') {
|
|
73
|
-
node.value = (0, _minifyColor.default)(node.value, options);
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
return parsed.toString();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function addPluginDefaults(options, browsers) {
|
|
80
|
-
const defaults = {
|
|
81
|
-
transparent: browsers.some(hasTransparentBug) === false,
|
|
82
|
-
// Does the browser support 4 & 8 character hex notation
|
|
83
|
-
alphaHex: (0, _caniuseApi.isSupported)('css-rrggbbaa', browsers),
|
|
84
|
-
// Does the browser support "transparent" value properly
|
|
85
|
-
name: true
|
|
86
|
-
};
|
|
87
|
-
return { ...defaults,
|
|
88
|
-
...options
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function pluginCreator(config = {}) {
|
|
93
|
-
return {
|
|
94
|
-
postcssPlugin: 'postcss-colormin',
|
|
95
|
-
|
|
96
|
-
prepare(result) {
|
|
97
|
-
const resultOptions = result.opts || {};
|
|
98
|
-
const browsers = (0, _browserslist.default)(null, {
|
|
99
|
-
stats: resultOptions.stats,
|
|
100
|
-
path: __dirname,
|
|
101
|
-
env: resultOptions.env
|
|
102
|
-
});
|
|
103
|
-
const cache = new Map();
|
|
104
|
-
const options = addPluginDefaults(config, browsers);
|
|
105
|
-
return {
|
|
106
|
-
OnceExit(css) {
|
|
107
|
-
css.walkDecls(decl => {
|
|
108
|
-
if (/^(composes|font|filter|-webkit-tap-highlight-color)/i.test(decl.prop)) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const value = decl.value;
|
|
113
|
-
|
|
114
|
-
if (!value) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const cacheKey = JSON.stringify({
|
|
119
|
-
value,
|
|
120
|
-
options,
|
|
121
|
-
browsers
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
if (cache.has(cacheKey)) {
|
|
125
|
-
decl.value = cache.get(cacheKey);
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const newValue = transform(value, options);
|
|
130
|
-
decl.value = newValue;
|
|
131
|
-
cache.set(cacheKey, newValue);
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
pluginCreator.postcss = true;
|
|
142
|
-
var _default = pluginCreator;
|
|
143
|
-
exports.default = _default;
|
|
144
|
-
module.exports = exports.default;
|
package/dist/minifyColor.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = minifyColor;
|
|
7
|
-
|
|
8
|
-
var _colord = require("colord");
|
|
9
|
-
|
|
10
|
-
var _names = _interopRequireDefault(require("colord/plugins/names"));
|
|
11
|
-
|
|
12
|
-
var _minify = _interopRequireDefault(require("colord/plugins/minify"));
|
|
13
|
-
|
|
14
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
-
|
|
16
|
-
(0, _colord.extend)([_names.default, _minify.default]);
|
|
17
|
-
/**
|
|
18
|
-
* Performs color value minification
|
|
19
|
-
*
|
|
20
|
-
* @param {string} input - CSS value
|
|
21
|
-
* @param {boolean} options - object with colord.minify() options
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
function minifyColor(input, options = {}) {
|
|
25
|
-
const instance = (0, _colord.colord)(input);
|
|
26
|
-
|
|
27
|
-
if (instance.isValid()) {
|
|
28
|
-
// Try to shorten the string if it is a valid CSS color value
|
|
29
|
-
const minified = instance.minify(options); // Fall back to the original input if it's smaller or has equal length
|
|
30
|
-
|
|
31
|
-
return minified.length < input.length ? minified : input.toLowerCase();
|
|
32
|
-
} else {
|
|
33
|
-
// Possibly malformed, so pass through
|
|
34
|
-
return input;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
module.exports = exports.default;
|