postcss-color-functional-notation 4.0.1 → 4.2.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,65 @@
1
+ # Changes to PostCSS Color Functional Notation
2
+
3
+ ### 4.2.1 (January 2, 2022)
4
+
5
+ - Removed Sourcemaps from package tarball.
6
+ - Moved CLI to CLI Package. See [announcement](https://github.com/csstools/postcss-plugins/discussions/121).
7
+
8
+ ### 4.2.0 (December 27, 2021)
9
+
10
+ - Added: support for Alpha value as the fourth argument in comma separated values notation.
11
+
12
+ ### 4.1.0 (December 15, 2021)
13
+
14
+ - Added: support for Alpha value as a CSS variable in `rgb()` and `rgba()`.
15
+
16
+ ### 4.0.2 (December 13, 2021)
17
+
18
+ - Changed: now uses `postcss-value-parser` for parsing.
19
+ - Updated: documentation
20
+ - Added: support for CSS variables with `preserve: true` option.
21
+
22
+ ### 4.0.1 (November 18, 2021)
23
+
24
+ - Added: Safeguards against postcss-values-parser potentially throwing an error.
25
+ - Updated: postcss-value-parser to 6.0.1 (patch)
26
+
27
+ ### 4.0.0 (September 17, 2021)
28
+
29
+ - Updated: Support for PostCS 8+ (major).
30
+ - Updated: Support for Node 12+ (major).
31
+
32
+ ### 3.0.2 (April 25, 2020)
33
+
34
+ - Updated: Publish
35
+
36
+ ### 3.0.1 (April 25, 2020)
37
+
38
+ - Updated: Using `walkType` to evade walker bug in `postcss-values-parser`
39
+
40
+ ### 3.0.0 (April 25, 2020)
41
+
42
+ - Updated: Support for Node 10+
43
+ - Updated: `postcss` to 7.0.27 (patch)
44
+ - Updated: `postcss-values-parser` to 3.2.0 (minor)
45
+
46
+ ### 2.0.1 (September 18, 2018)
47
+
48
+ - Updated: PostCSS Values Parser 2 (patch for this project)
49
+
50
+ ### 2.0.0 (September 17, 2018)
51
+
52
+ - Updated: Support for PostCSS v7+
53
+ - Updated: Support for Node 6+
54
+
55
+ ### 1.0.2 (July 13, 2018)
56
+
57
+ - Fixed: Poorly detected hsl() and rgb() now resolve correctly
58
+
59
+ ### 1.0.1 (May 11, 2018)
60
+
61
+ - Fixed: A non-percentage 0 works alongside other percentages
62
+
63
+ ### 1.0.0 (May 7, 2018)
64
+
65
+ - Initial version
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [<img alt="NPM Version" src="https://img.shields.io/npm/v/postcss-color-functional-notation.svg" height="20">][npm-url]
4
4
  [<img alt="CSS Standard Status" src="https://cssdb.org/badge/lab-function.svg" height="20">][css-url]
5
- [<img alt="Build Status" src="https://github.com/csstools/postcss-color-functional-notation/workflows/test/badge.svg" height="20">][cli-url]
5
+ [<img alt="Build Status" src="https://github.com/csstools/postcss-plugins/workflows/test/badge.svg" height="20">][cli-url]
6
6
  [<img alt="Support Chat" src="https://img.shields.io/badge/support-chat-blue.svg" height="20">][git-url]
7
7
 
8
8
  [PostCSS Color Functional Notation] lets you use space and slash separated
@@ -83,7 +83,7 @@ postcssImageSetFunction({ preserve: true })
83
83
  }
84
84
  ```
85
85
 
86
- [cli-url]: https://github.com/csstools/postcss-color-functional-notation/actions/workflows/test.yml?query=workflow/test
86
+ [cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
87
87
  [css-url]: https://cssdb.org/#color-functional-notation
88
88
  [git-url]: https://gitter.im/postcss/postcss
89
89
  [npm-url]: https://www.npmjs.com/package/postcss-color-functional-notation
@@ -93,4 +93,4 @@ postcssImageSetFunction({ preserve: true })
93
93
  [Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss
94
94
  [PostCSS]: https://github.com/postcss/postcss
95
95
  [PostCSS Loader]: https://github.com/postcss/postcss-loader
96
- [PostCSS Color Functional Notation]: https://github.com/csstools/postcss-color-functional-notation
96
+ [PostCSS Color Functional Notation]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-color-functional-notation
@@ -0,0 +1,2 @@
1
+ import type { Node } from 'postcss';
2
+ export declare function hasSupportsAtRuleAncestor(node: Node): boolean;
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=e(require("postcss-value-parser"));function n(e){const n=e.value;let i=e.nodes;"rgb"!==n&&"hsl"!==n||(i=function(e){let r=0;for(let n=0;n<e.length;n++){const t=e[n];if("div"===t.type&&","===t.value){if(r<2&&(t.value=" ",t.type="space"),2===r&&(t.value="/"),r>2)return;r++}}return e}(i));const s=i.slice().filter((e=>"comment"!==e.type&&"space"!==e.type));let f=null;if("hsl"===n||"hsla"===n?f=function(e){if(!function(e){if(!e||"word"!==e.type)return!1;if(!o(e))return!1;const n=r.default.unit(e.value);if(!n)return!1;return!!n.number&&("deg"===n.unit||"grad"===n.unit||"rad"===n.unit||"turn"===n.unit||""===n.unit)}(e[0]))return null;if(!t(e[1]))return null;if(!t(e[2]))return null;const n={h:r.default.unit(e[0].value),hNode:e[0],s:r.default.unit(e[1].value),sNode:e[1],l:r.default.unit(e[2].value),lNode:e[2]};if(function(e){switch(e.unit){case"deg":return void(e.unit="");case"rad":return e.unit="",void(e.number=Math.round(180*parseFloat(e.number)/Math.PI).toString());case"grad":return e.unit="",void(e.number=Math.round(.9*parseFloat(e.number)).toString());case"turn":e.unit="",e.number=Math.round(360*parseFloat(e.number)).toString()}}(n.h),""!==n.h.unit)return null;n.hNode.value=n.h.number,l(e[3])&&(n.slash=e[3]);(t(e[4])||u(e[4])||a(e[4]))&&(n.alpha=e[4]);return n}(s):"rgb"!==n&&"rgba"!==n||(f=function(e){if(!t(e[0]))return null;if(!t(e[1]))return null;if(!t(e[2]))return null;const n={r:r.default.unit(e[0].value),rNode:e[0],g:r.default.unit(e[1].value),gNode:e[1],b:r.default.unit(e[2].value),bNode:e[2]};"%"===n.r.unit&&(n.r.number=String(Math.floor(Number(n.r.number)/100*255)),n.rNode.value=n.r.number);"%"===n.g.unit&&(n.g.number=String(Math.floor(Number(n.g.number)/100*255)),n.gNode.value=n.g.number);"%"===n.b.unit&&(n.b.number=String(Math.floor(Number(n.b.number)/100*255)),n.bNode.value=n.b.number);l(e[3])&&(n.slash=e[3]);(t(e[4])||u(e[4])||a(e[4]))&&(n.alpha=e[4]);return n}(s)),!f)return;if(s.length>3&&(!f.slash||!f.alpha))return;!function(e,n,t){"hsl"===e.value||"hsla"===e.value?e.value="hsl":"rgb"!==e.value&&"rgba"!==e.value||(e.value="rgb");if(!n||!t)return;"hsl"===e.value?e.value="hsla":e.value="rgba";if(n.value=",",n.before="",!function(e){if(!e||"word"!==e.type)return!1;if(!o(e))return!1;const n=r.default.unit(e.value);if(!n)return!1;return!!n.number}(t))return;const u=r.default.unit(t.value);if(!u)return;"%"===u.unit&&(u.number=String(parseFloat(u.number)/100),t.value=String(u.number))}(e,f.slash,f.alpha);const[c,d]=function(e){if(function(e){if(void 0!==e.r)return!0;return!1}(e))return[e.rNode,e.gNode,e.bNode];return[e.hNode,e.sNode,e.lNode]}(f);e.nodes.splice(e.nodes.indexOf(c)+1,0,{sourceIndex:0,sourceEndIndex:1,value:",",type:"div",before:"",after:""}),e.nodes.splice(e.nodes.indexOf(d)+1,0,{sourceIndex:0,sourceEndIndex:1,value:",",type:"div",before:"",after:""})}function t(e){if(!e||"word"!==e.type)return!1;if(!o(e))return!1;const n=r.default.unit(e.value);return!!n&&("%"===n.unit||""===n.unit)}function u(e){return e&&"function"===e.type&&"calc"===e.value}function a(e){return e&&"function"===e.type&&"var"===e.value}function l(e){return e&&"div"===e.type&&"/"===e.value}function o(e){if(!e||!e.value)return!1;try{return!1!==r.default.unit(e.value)}catch(e){return!1}}const i=e=>{const t="preserve"in Object(e)&&Boolean(e.preserve);return{postcssPlugin:"postcss-color-functional-notation",Declaration:(e,{result:u,postcss:a})=>{if(t&&function(e){let r=e.parent;for(;r;)if("atrule"===r.type){if("supports"===r.name&&-1!==r.params.indexOf("(color: rgb(0 0 0 / 0.5)) and (color: hsl(0 0% 0% / 0.5))"))return!0;r=r.parent}else r=r.parent;return!1}(e))return;const l=e.value;if(!/(^|[^\w-])(hsla?|rgba?)\(/i.test(l))return;let o;try{o=r.default(l)}catch(r){e.warn(u,`Failed to parse value '${l}' as a hsl or rgb function. Leaving the original value intact.`)}if(void 0===o)return;o.walk((e=>{e.type&&"function"===e.type&&("hsl"!==e.value&&"hsla"!==e.value&&"rgb"!==e.value&&"rgba"!==e.value||n(e))}));const i=String(o);if(i!==l)if(t&&e.variable){const r=e.parent,n="(color: rgb(0 0 0 / 0.5)) and (color: hsl(0 0% 0% / 0.5))",t=a.atRule({name:"supports",params:n,source:e.source}),u=r.clone();u.removeAll(),u.append(e.clone()),t.append(u);let l=r,o=r.next();for(;l&&o&&"atrule"===o.type&&"supports"===o.name&&o.params===n;)l=o,o=o.next();l.after(t),e.value=i}else t?e.cloneBefore({value:i}):e.value=i}}};i.postcss=!0,module.exports=i;
@@ -0,0 +1,6 @@
1
+ import type { PluginCreator } from 'postcss';
2
+ /** Transform lab() and lch() functions in CSS. */
3
+ declare const postcssPlugin: PluginCreator<{
4
+ preserve: boolean;
5
+ }>;
6
+ export default postcssPlugin;
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ import e from"postcss-value-parser";function r(r){const o=r.value;let i=r.nodes;"rgb"!==o&&"hsl"!==o||(i=function(e){let r=0;for(let n=0;n<e.length;n++){const t=e[n];if("div"===t.type&&","===t.value){if(r<2&&(t.value=" ",t.type="space"),2===r&&(t.value="/"),r>2)return;r++}}return e}(i));const s=i.slice().filter((e=>"comment"!==e.type&&"space"!==e.type));let c=null;if("hsl"===o||"hsla"===o?c=function(r){if(!function(r){if(!r||"word"!==r.type)return!1;if(!l(r))return!1;const n=e.unit(r.value);if(!n)return!1;return!!n.number&&("deg"===n.unit||"grad"===n.unit||"rad"===n.unit||"turn"===n.unit||""===n.unit)}(r[0]))return null;if(!n(r[1]))return null;if(!n(r[2]))return null;const o={h:e.unit(r[0].value),hNode:r[0],s:e.unit(r[1].value),sNode:r[1],l:e.unit(r[2].value),lNode:r[2]};if(function(e){switch(e.unit){case"deg":return void(e.unit="");case"rad":return e.unit="",void(e.number=Math.round(180*parseFloat(e.number)/Math.PI).toString());case"grad":return e.unit="",void(e.number=Math.round(.9*parseFloat(e.number)).toString());case"turn":e.unit="",e.number=Math.round(360*parseFloat(e.number)).toString()}}(o.h),""!==o.h.unit)return null;o.hNode.value=o.h.number,a(r[3])&&(o.slash=r[3]);(n(r[4])||t(r[4])||u(r[4]))&&(o.alpha=r[4]);return o}(s):"rgb"!==o&&"rgba"!==o||(c=function(r){if(!n(r[0]))return null;if(!n(r[1]))return null;if(!n(r[2]))return null;const l={r:e.unit(r[0].value),rNode:r[0],g:e.unit(r[1].value),gNode:r[1],b:e.unit(r[2].value),bNode:r[2]};"%"===l.r.unit&&(l.r.number=String(Math.floor(Number(l.r.number)/100*255)),l.rNode.value=l.r.number);"%"===l.g.unit&&(l.g.number=String(Math.floor(Number(l.g.number)/100*255)),l.gNode.value=l.g.number);"%"===l.b.unit&&(l.b.number=String(Math.floor(Number(l.b.number)/100*255)),l.bNode.value=l.b.number);a(r[3])&&(l.slash=r[3]);(n(r[4])||t(r[4])||u(r[4]))&&(l.alpha=r[4]);return l}(s)),!c)return;if(s.length>3&&(!c.slash||!c.alpha))return;!function(r,n,t){"hsl"===r.value||"hsla"===r.value?r.value="hsl":"rgb"!==r.value&&"rgba"!==r.value||(r.value="rgb");if(!n||!t)return;"hsl"===r.value?r.value="hsla":r.value="rgba";if(n.value=",",n.before="",!function(r){if(!r||"word"!==r.type)return!1;if(!l(r))return!1;const n=e.unit(r.value);if(!n)return!1;return!!n.number}(t))return;const u=e.unit(t.value);if(!u)return;"%"===u.unit&&(u.number=String(parseFloat(u.number)/100),t.value=String(u.number))}(r,c.slash,c.alpha);const[f,v]=function(e){if(function(e){if(void 0!==e.r)return!0;return!1}(e))return[e.rNode,e.gNode,e.bNode];return[e.hNode,e.sNode,e.lNode]}(c);r.nodes.splice(r.nodes.indexOf(f)+1,0,{sourceIndex:0,sourceEndIndex:1,value:",",type:"div",before:"",after:""}),r.nodes.splice(r.nodes.indexOf(v)+1,0,{sourceIndex:0,sourceEndIndex:1,value:",",type:"div",before:"",after:""})}function n(r){if(!r||"word"!==r.type)return!1;if(!l(r))return!1;const n=e.unit(r.value);return!!n&&("%"===n.unit||""===n.unit)}function t(e){return e&&"function"===e.type&&"calc"===e.value}function u(e){return e&&"function"===e.type&&"var"===e.value}function a(e){return e&&"div"===e.type&&"/"===e.value}function l(r){if(!r||!r.value)return!1;try{return!1!==e.unit(r.value)}catch(e){return!1}}const o=n=>{const t="preserve"in Object(n)&&Boolean(n.preserve);return{postcssPlugin:"postcss-color-functional-notation",Declaration:(n,{result:u,postcss:a})=>{if(t&&function(e){let r=e.parent;for(;r;)if("atrule"===r.type){if("supports"===r.name&&-1!==r.params.indexOf("(color: rgb(0 0 0 / 0.5)) and (color: hsl(0 0% 0% / 0.5))"))return!0;r=r.parent}else r=r.parent;return!1}(n))return;const l=n.value;if(!/(^|[^\w-])(hsla?|rgba?)\(/i.test(l))return;let o;try{o=e(l)}catch(e){n.warn(u,`Failed to parse value '${l}' as a hsl or rgb function. Leaving the original value intact.`)}if(void 0===o)return;o.walk((e=>{e.type&&"function"===e.type&&("hsl"!==e.value&&"hsla"!==e.value&&"rgb"!==e.value&&"rgba"!==e.value||r(e))}));const i=String(o);if(i!==l)if(t&&n.variable){const e=n.parent,r="(color: rgb(0 0 0 / 0.5)) and (color: hsl(0 0% 0% / 0.5))",t=a.atRule({name:"supports",params:r,source:n.source}),u=e.clone();u.removeAll(),u.append(n.clone()),t.append(u);let l=e,o=e.next();for(;l&&o&&"atrule"===o.type&&"supports"===o.name&&o.params===r;)l=o,o=o.next();l.after(t),n.value=i}else t?n.cloneBefore({value:i}):n.value=i}}};o.postcss=!0;export{o as default};
@@ -0,0 +1,3 @@
1
+ import type { FunctionNode } from 'postcss-value-parser';
2
+ declare function onCSSFunction(node: FunctionNode): void;
3
+ export default onCSSFunction;
package/package.json CHANGED
@@ -1,82 +1,41 @@
1
1
  {
2
2
  "name": "postcss-color-functional-notation",
3
- "version": "4.0.1",
3
+ "version": "4.2.1",
4
4
  "description": "Use space and slash separated color notation in CSS",
5
5
  "author": "Jonathan Neal <jonathantneal@hotmail.com>",
6
6
  "license": "CC0-1.0",
7
- "repository": "csstools/postcss-color-functional-notation",
8
- "homepage": "https://github.com/csstools/postcss-color-functional-notation#readme",
9
- "bugs": "https://github.com/csstools/postcss-color-functional-notation/issues",
10
- "main": "dist/index.cjs.js",
11
- "module": "dist/index.esm.mjs",
7
+ "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-color-functional-notation#readme",
8
+ "bugs": "https://github.com/csstools/postcss-plugins/issues",
9
+ "main": "dist/index.cjs",
10
+ "module": "dist/index.mjs",
11
+ "types": "./dist/index.d.ts",
12
12
  "files": [
13
+ "CHANGELOG.md",
14
+ "LICENSE.md",
15
+ "README.md",
13
16
  "dist"
14
17
  ],
15
18
  "scripts": {
16
- "build": "npx rollup -c .rollup.js",
17
- "build:watch": "npx rollup -c .rollup.js --watch",
18
- "lint": "npx eslint --cache src",
19
- "lint:fix": "npx eslint --cache --fix",
20
- "pretest": "npm install && npm run build",
21
- "test": "npm run lint && npm run tape",
22
- "tape": "npx postcss-tape",
23
- "prepublishOnly": "npm test"
19
+ "build": "rollup -c ../../rollup/default.js",
20
+ "clean": "node -e \"fs.rmSync('./dist', { recursive: true, force: true });\"",
21
+ "lint": "eslint ./src --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern",
22
+ "prepublishOnly": "npm run clean && npm run build && npm run test",
23
+ "stryker": "stryker run --logLevel error",
24
+ "test": "postcss-tape --ci && npm run test:exports",
25
+ "test:exports": "node ./test/_import.mjs && node ./test/_require.cjs"
24
26
  },
25
27
  "engines": {
26
- "node": ">=12"
28
+ "node": "^12 || ^14 || >=16"
27
29
  },
28
30
  "dependencies": {
29
- "postcss-values-parser": "6.0.1"
30
- },
31
- "peerDependencies": {
32
- "postcss": "^8.3"
31
+ "postcss-value-parser": "^4.2.0"
33
32
  },
34
33
  "devDependencies": {
35
- "@babel/core": "^7.16.0",
36
- "@babel/preset-env": "^7.16.4",
37
- "eslint": "^8.2.0",
38
- "postcss": "^8.3.11",
39
- "postcss-tape": "^6.0.1",
40
- "pre-commit": "^1.2.2",
41
- "rollup": "^2.60.0",
42
- "rollup-plugin-babel": "^4.4.0"
43
- },
44
- "babel": {
45
- "presets": [
46
- [
47
- "@babel/env",
48
- {
49
- "targets": "maintained node versions"
50
- }
51
- ]
52
- ]
53
- },
54
- "eslintConfig": {
55
- "env": {
56
- "es6": true,
57
- "node": true
58
- },
59
- "extends": "eslint:recommended",
60
- "parserOptions": {
61
- "sourceType": "module"
62
- }
34
+ "postcss": "^8.3.6",
35
+ "postcss-tape": "^6.0.1"
63
36
  },
64
- "rollup": {
65
- "input": "src/index.js",
66
- "plugins": [
67
- "rollup-plugin-babel"
68
- ],
69
- "output": [
70
- {
71
- "exports": "default",
72
- "file": "dist/index.cjs.js",
73
- "format": "cjs"
74
- },
75
- {
76
- "file": "dist/index.esm.js",
77
- "format": "esm"
78
- }
79
- ]
37
+ "peerDependencies": {
38
+ "postcss": "^8.3"
80
39
  },
81
40
  "keywords": [
82
41
  "postcss",
@@ -95,5 +54,13 @@
95
54
  "syntax",
96
55
  "space",
97
56
  "comma"
98
- ]
57
+ ],
58
+ "repository": {
59
+ "type": "git",
60
+ "url": "https://github.com/csstools/postcss-plugins.git",
61
+ "directory": "plugins/postcss-color-functional-notation"
62
+ },
63
+ "volta": {
64
+ "extends": "../../package.json"
65
+ }
99
66
  }
package/dist/index.cjs.js DELETED
@@ -1,228 +0,0 @@
1
- 'use strict';
2
-
3
- var postcssValuesParser = require('postcss-values-parser');
4
-
5
- /** @type {(decl: CSSFunction) => void} Transform a space and slash separated color function. */
6
-
7
- const onCSSFunction = node => {
8
- /** @type {{ name: string, nodes: CSSNode[] }} */
9
- const {
10
- name,
11
- nodes
12
- } = node;
13
-
14
- if (isColorFunctionName(name)) {
15
- const isHsl = isHslColorFunctionName(name) && isHslFunctionContents(nodes);
16
- const isRgbWithNumbers = isRgbColorFunctionName(name) && isRgbNumberFunctionContents(nodes);
17
- const isRgbWithPercents = isRgbColorFunctionName(name) && isRgbPercentFunctionContents(nodes);
18
-
19
- if (isHsl || isRgbWithNumbers || isRgbWithPercents) {
20
- // rename the Color function to `hsl` or `rgb`
21
- Object.assign(node, {
22
- name: isHsl ? 'hsl' : 'rgb'
23
- });
24
- /** @type {CSSPunctuation} Slash punctuation before the Alpha channel. */
25
-
26
- const slashNode = nodes[3];
27
- /** @type {CSSNumber} Alpha channel. */
28
-
29
- const alphaNode = nodes[4];
30
-
31
- if (alphaNode) {
32
- if (isPercentage(alphaNode) && !isCalc(alphaNode)) {
33
- // transform the Alpha channel from a Percentage to (0-1) Number
34
- Object.assign(alphaNode, {
35
- value: String(alphaNode.value / 100),
36
- unit: ''
37
- });
38
- } // if the color is fully opaque (i.e. the Alpha channel is `1`)
39
-
40
-
41
- if (alphaNode.value === '1') {
42
- // remove the Slash and Alpha channel
43
- slashNode.remove();
44
- alphaNode.remove();
45
- } else {
46
- // otherwise, rename the Color function to `hsla` or `rgba`
47
- Object.assign(node, {
48
- name: isHsl ? 'hsla' : 'rgba'
49
- });
50
- }
51
- } // replace a remaining Slash with a Comma
52
-
53
-
54
- if (slashNode && isSlash(slashNode)) {
55
- slashNode.replaceWith(commaNode.clone());
56
- }
57
- /** Extracted Color channels. */
58
-
59
-
60
- let [channelNode1, channelNode2, channelNode3] = nodes;
61
-
62
- if (isRgbWithPercents) {
63
- Object.assign(channelNode1, {
64
- value: to255ColorValue(channelNode1.value),
65
- unit: ''
66
- });
67
- Object.assign(channelNode2, {
68
- value: to255ColorValue(channelNode2.value),
69
- unit: ''
70
- });
71
- Object.assign(channelNode3, {
72
- value: to255ColorValue(channelNode3.value),
73
- unit: ''
74
- });
75
- }
76
-
77
- channelNode2.after(commaNode.clone());
78
- channelNode1.after(commaNode.clone());
79
- }
80
- }
81
- };
82
- const commaNode = postcssValuesParser.parse(',').first;
83
- /** Return a value transformed from a scale of 0-100 to a scale of 0-255 */
84
-
85
- function to255ColorValue(value) {
86
- return String(Math.floor(value * 255 / 100));
87
- }
88
- /** @type {(value: RegExp) => (value: string) => boolean} Return a function that checks whether the expression exists in a value. */
89
-
90
-
91
- const createRegExpTest$1 = Function.bind.bind(RegExp.prototype.test);
92
- /** Return whether the function name is `hsl()`, `hsla()`, `rgb()`, or `rgba()`. */
93
-
94
- const isColorFunctionName = createRegExpTest$1(/^(hsl|rgb)a?$/i);
95
- /** Return whether the function name is `hsl()` or `hsla()`. */
96
-
97
- const isHslColorFunctionName = createRegExpTest$1(/^hsla?$/i);
98
- /** Return whether the function name is `rgb()` or `rgba()`. */
99
-
100
- const isRgbColorFunctionName = createRegExpTest$1(/^rgba?$/i);
101
- /** Return whether the function name is `calc`. */
102
-
103
- const isCalcFunctionName = createRegExpTest$1(/^calc$/i);
104
- /** Return whether the unit is alpha-like. */
105
-
106
- const isAlphaLikeUnit = createRegExpTest$1(/^%?$/i);
107
- /** Return whether the unit is hue-like. */
108
-
109
- const isHueLikeUnit = createRegExpTest$1(/^(deg|grad|rad|turn)?$/i);
110
- /** @type {(node: CSSNumber) => boolean} Return whether the node is an Alpha-like unit. */
111
-
112
- const isAlphaValue = node => isCalc(node) || node.type === 'numeric' && isAlphaLikeUnit(node.unit);
113
- /** @type {(node: CSSFunction) => boolean} Return whether the node is a calc() function. */
114
-
115
-
116
- const isCalc = node => node.type === 'func' && isCalcFunctionName(node.name);
117
- /** @type {(node: CSSNumber) => boolean} Return whether the node is a Hue-like unit. */
118
-
119
-
120
- const isHue = node => isCalc(node) || node.type === 'numeric' && isHueLikeUnit(node.unit);
121
- /** @type {(node: CSSNumber) => boolean} Return whether the node is a Number unit. */
122
-
123
-
124
- const isNumber = node => isCalc(node) || node.type === 'numeric' && node.unit === '';
125
- /** @type {(node: CSSNumber) => boolean} Return whether the node is a Percentage unit. */
126
-
127
-
128
- const isPercentage = node => isCalc(node) || node.type === 'numeric' && (node.unit === '%' || node.unit === '' && node.value === '0');
129
- /** @type {(node: CSSOperator) => boolean} Return whether the node is a Slash delimiter. */
130
-
131
-
132
- const isSlash = node => node.type === 'operator' && node.value === '/';
133
- /** @type {(nodes: Node[]) => boolean} Return whether a set of nodes is an hsl() function. */
134
-
135
-
136
- const isHslFunctionContents = nodes => nodes.every((node, index) => typeof hslFunctionContents[index] === 'function' && hslFunctionContents[index](node));
137
- /** Set of nodes in a lab() function. */
138
-
139
-
140
- const hslFunctionContents = [isHue, isPercentage, isPercentage, isSlash, isAlphaValue];
141
- /** @type {(nodes: Node[]) => boolean} Return whether a set of nodes is an rgb() function with numbers. */
142
-
143
- const isRgbNumberFunctionContents = nodes => nodes.every((node, index) => typeof rgbNumberFunctionContents[index] === 'function' && rgbNumberFunctionContents[index](node));
144
- /** Set of nodes in a rgb() function with numbers. */
145
-
146
-
147
- const rgbNumberFunctionContents = [isNumber, isNumber, isNumber, isSlash, isAlphaValue];
148
- /** @type {(nodes: Node[]) => boolean} Return whether a set of nodes is an rgb() function with percentages. */
149
-
150
- const isRgbPercentFunctionContents = nodes => nodes.every((node, index) => typeof rgbPercentFunctionContents[index] === 'function' && rgbPercentFunctionContents[index](node));
151
- /** Set of nodes in a rgb() function with percentages. */
152
-
153
-
154
- const rgbPercentFunctionContents = [isPercentage, isPercentage, isPercentage, isSlash, isAlphaValue];
155
- /** @typedef {import('postcss-values-parser').Func} CSSFunction */
156
-
157
- /** @typedef {import('postcss-values-parser').Node} CSSNode */
158
-
159
- /** @typedef {import('postcss-values-parser').Numeric} CSSNumber */
160
-
161
- /** @typedef {import('postcss-values-parser').Operator} CSSOperator */
162
-
163
- /** @typedef {import('postcss-values-parser').Punctuation} CSSPunctuation */
164
-
165
- var options = {
166
- /** Whether to preserve the original functional color declaration. */
167
- preserve: false
168
- };
169
-
170
- /** @type {(decl: CSSDeclaration) => void} Transform space and slash separated color functions in CSS Declarations. */
171
-
172
- const onCSSDeclaration = (decl, {
173
- result
174
- }) => {
175
- const {
176
- value: originalValue
177
- } = decl;
178
-
179
- if (hasAnyColorFunction(originalValue)) {
180
- let valueAST;
181
-
182
- try {
183
- valueAST = postcssValuesParser.parse(originalValue, {
184
- ignoreUnknownWords: true
185
- });
186
- } catch (error) {
187
- decl.warn(result, `Failed to parse value '${originalValue}' as a color function. Leaving the original value intact.`);
188
- }
189
-
190
- if (typeof valueAST === 'undefined') {
191
- return;
192
- }
193
-
194
- valueAST.walkType('func', onCSSFunction);
195
- const modifiedValue = String(valueAST);
196
-
197
- if (modifiedValue !== originalValue) {
198
- if (options.preserve) decl.cloneBefore({
199
- value: modifiedValue
200
- });else decl.value = modifiedValue;
201
- }
202
- }
203
- };
204
- /** @type {(value: RegExp) => (value: string) => boolean} Return a function that checks whether the expression exists in a value. */
205
-
206
- const createRegExpTest = Function.bind.bind(RegExp.prototype.test);
207
- /** Return whether the value has an `hsl()`, `hsla()`, `rgb()`, or `rgba()` function. */
208
-
209
- const hasAnyColorFunction = createRegExpTest(/(^|[^\w-])(hsla?|rgba?)\(/i);
210
- /** @typedef {import('postcss').Declaration} CSSDeclaration */
211
-
212
- /** Transform space and slash separated color functions in CSS. */
213
-
214
- function postcssColorFunctionalNotation(opts) {
215
- options.preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : false;
216
- return {
217
- postcssPlugin: 'postcss-color-functional-notation',
218
- Declaration: onCSSDeclaration
219
- };
220
- }
221
- postcssColorFunctionalNotation.postcss = true;
222
- /** @typedef {import('postcss').Root} CSSRoot */
223
-
224
- /** @typedef {(root: CSSRoot) => void} PostCSSTransformCallback */
225
-
226
- /** @typedef {(opts: options) => PostCSSTransformCallback} PostCSSPluginInitializer */
227
-
228
- module.exports = postcssColorFunctionalNotation;
package/dist/index.esm.js DELETED
@@ -1,226 +0,0 @@
1
- import { parse } from 'postcss-values-parser';
2
-
3
- /** @type {(decl: CSSFunction) => void} Transform a space and slash separated color function. */
4
-
5
- const onCSSFunction = node => {
6
- /** @type {{ name: string, nodes: CSSNode[] }} */
7
- const {
8
- name,
9
- nodes
10
- } = node;
11
-
12
- if (isColorFunctionName(name)) {
13
- const isHsl = isHslColorFunctionName(name) && isHslFunctionContents(nodes);
14
- const isRgbWithNumbers = isRgbColorFunctionName(name) && isRgbNumberFunctionContents(nodes);
15
- const isRgbWithPercents = isRgbColorFunctionName(name) && isRgbPercentFunctionContents(nodes);
16
-
17
- if (isHsl || isRgbWithNumbers || isRgbWithPercents) {
18
- // rename the Color function to `hsl` or `rgb`
19
- Object.assign(node, {
20
- name: isHsl ? 'hsl' : 'rgb'
21
- });
22
- /** @type {CSSPunctuation} Slash punctuation before the Alpha channel. */
23
-
24
- const slashNode = nodes[3];
25
- /** @type {CSSNumber} Alpha channel. */
26
-
27
- const alphaNode = nodes[4];
28
-
29
- if (alphaNode) {
30
- if (isPercentage(alphaNode) && !isCalc(alphaNode)) {
31
- // transform the Alpha channel from a Percentage to (0-1) Number
32
- Object.assign(alphaNode, {
33
- value: String(alphaNode.value / 100),
34
- unit: ''
35
- });
36
- } // if the color is fully opaque (i.e. the Alpha channel is `1`)
37
-
38
-
39
- if (alphaNode.value === '1') {
40
- // remove the Slash and Alpha channel
41
- slashNode.remove();
42
- alphaNode.remove();
43
- } else {
44
- // otherwise, rename the Color function to `hsla` or `rgba`
45
- Object.assign(node, {
46
- name: isHsl ? 'hsla' : 'rgba'
47
- });
48
- }
49
- } // replace a remaining Slash with a Comma
50
-
51
-
52
- if (slashNode && isSlash(slashNode)) {
53
- slashNode.replaceWith(commaNode.clone());
54
- }
55
- /** Extracted Color channels. */
56
-
57
-
58
- let [channelNode1, channelNode2, channelNode3] = nodes;
59
-
60
- if (isRgbWithPercents) {
61
- Object.assign(channelNode1, {
62
- value: to255ColorValue(channelNode1.value),
63
- unit: ''
64
- });
65
- Object.assign(channelNode2, {
66
- value: to255ColorValue(channelNode2.value),
67
- unit: ''
68
- });
69
- Object.assign(channelNode3, {
70
- value: to255ColorValue(channelNode3.value),
71
- unit: ''
72
- });
73
- }
74
-
75
- channelNode2.after(commaNode.clone());
76
- channelNode1.after(commaNode.clone());
77
- }
78
- }
79
- };
80
- const commaNode = parse(',').first;
81
- /** Return a value transformed from a scale of 0-100 to a scale of 0-255 */
82
-
83
- function to255ColorValue(value) {
84
- return String(Math.floor(value * 255 / 100));
85
- }
86
- /** @type {(value: RegExp) => (value: string) => boolean} Return a function that checks whether the expression exists in a value. */
87
-
88
-
89
- const createRegExpTest$1 = Function.bind.bind(RegExp.prototype.test);
90
- /** Return whether the function name is `hsl()`, `hsla()`, `rgb()`, or `rgba()`. */
91
-
92
- const isColorFunctionName = createRegExpTest$1(/^(hsl|rgb)a?$/i);
93
- /** Return whether the function name is `hsl()` or `hsla()`. */
94
-
95
- const isHslColorFunctionName = createRegExpTest$1(/^hsla?$/i);
96
- /** Return whether the function name is `rgb()` or `rgba()`. */
97
-
98
- const isRgbColorFunctionName = createRegExpTest$1(/^rgba?$/i);
99
- /** Return whether the function name is `calc`. */
100
-
101
- const isCalcFunctionName = createRegExpTest$1(/^calc$/i);
102
- /** Return whether the unit is alpha-like. */
103
-
104
- const isAlphaLikeUnit = createRegExpTest$1(/^%?$/i);
105
- /** Return whether the unit is hue-like. */
106
-
107
- const isHueLikeUnit = createRegExpTest$1(/^(deg|grad|rad|turn)?$/i);
108
- /** @type {(node: CSSNumber) => boolean} Return whether the node is an Alpha-like unit. */
109
-
110
- const isAlphaValue = node => isCalc(node) || node.type === 'numeric' && isAlphaLikeUnit(node.unit);
111
- /** @type {(node: CSSFunction) => boolean} Return whether the node is a calc() function. */
112
-
113
-
114
- const isCalc = node => node.type === 'func' && isCalcFunctionName(node.name);
115
- /** @type {(node: CSSNumber) => boolean} Return whether the node is a Hue-like unit. */
116
-
117
-
118
- const isHue = node => isCalc(node) || node.type === 'numeric' && isHueLikeUnit(node.unit);
119
- /** @type {(node: CSSNumber) => boolean} Return whether the node is a Number unit. */
120
-
121
-
122
- const isNumber = node => isCalc(node) || node.type === 'numeric' && node.unit === '';
123
- /** @type {(node: CSSNumber) => boolean} Return whether the node is a Percentage unit. */
124
-
125
-
126
- const isPercentage = node => isCalc(node) || node.type === 'numeric' && (node.unit === '%' || node.unit === '' && node.value === '0');
127
- /** @type {(node: CSSOperator) => boolean} Return whether the node is a Slash delimiter. */
128
-
129
-
130
- const isSlash = node => node.type === 'operator' && node.value === '/';
131
- /** @type {(nodes: Node[]) => boolean} Return whether a set of nodes is an hsl() function. */
132
-
133
-
134
- const isHslFunctionContents = nodes => nodes.every((node, index) => typeof hslFunctionContents[index] === 'function' && hslFunctionContents[index](node));
135
- /** Set of nodes in a lab() function. */
136
-
137
-
138
- const hslFunctionContents = [isHue, isPercentage, isPercentage, isSlash, isAlphaValue];
139
- /** @type {(nodes: Node[]) => boolean} Return whether a set of nodes is an rgb() function with numbers. */
140
-
141
- const isRgbNumberFunctionContents = nodes => nodes.every((node, index) => typeof rgbNumberFunctionContents[index] === 'function' && rgbNumberFunctionContents[index](node));
142
- /** Set of nodes in a rgb() function with numbers. */
143
-
144
-
145
- const rgbNumberFunctionContents = [isNumber, isNumber, isNumber, isSlash, isAlphaValue];
146
- /** @type {(nodes: Node[]) => boolean} Return whether a set of nodes is an rgb() function with percentages. */
147
-
148
- const isRgbPercentFunctionContents = nodes => nodes.every((node, index) => typeof rgbPercentFunctionContents[index] === 'function' && rgbPercentFunctionContents[index](node));
149
- /** Set of nodes in a rgb() function with percentages. */
150
-
151
-
152
- const rgbPercentFunctionContents = [isPercentage, isPercentage, isPercentage, isSlash, isAlphaValue];
153
- /** @typedef {import('postcss-values-parser').Func} CSSFunction */
154
-
155
- /** @typedef {import('postcss-values-parser').Node} CSSNode */
156
-
157
- /** @typedef {import('postcss-values-parser').Numeric} CSSNumber */
158
-
159
- /** @typedef {import('postcss-values-parser').Operator} CSSOperator */
160
-
161
- /** @typedef {import('postcss-values-parser').Punctuation} CSSPunctuation */
162
-
163
- var options = {
164
- /** Whether to preserve the original functional color declaration. */
165
- preserve: false
166
- };
167
-
168
- /** @type {(decl: CSSDeclaration) => void} Transform space and slash separated color functions in CSS Declarations. */
169
-
170
- const onCSSDeclaration = (decl, {
171
- result
172
- }) => {
173
- const {
174
- value: originalValue
175
- } = decl;
176
-
177
- if (hasAnyColorFunction(originalValue)) {
178
- let valueAST;
179
-
180
- try {
181
- valueAST = parse(originalValue, {
182
- ignoreUnknownWords: true
183
- });
184
- } catch (error) {
185
- decl.warn(result, `Failed to parse value '${originalValue}' as a color function. Leaving the original value intact.`);
186
- }
187
-
188
- if (typeof valueAST === 'undefined') {
189
- return;
190
- }
191
-
192
- valueAST.walkType('func', onCSSFunction);
193
- const modifiedValue = String(valueAST);
194
-
195
- if (modifiedValue !== originalValue) {
196
- if (options.preserve) decl.cloneBefore({
197
- value: modifiedValue
198
- });else decl.value = modifiedValue;
199
- }
200
- }
201
- };
202
- /** @type {(value: RegExp) => (value: string) => boolean} Return a function that checks whether the expression exists in a value. */
203
-
204
- const createRegExpTest = Function.bind.bind(RegExp.prototype.test);
205
- /** Return whether the value has an `hsl()`, `hsla()`, `rgb()`, or `rgba()` function. */
206
-
207
- const hasAnyColorFunction = createRegExpTest(/(^|[^\w-])(hsla?|rgba?)\(/i);
208
- /** @typedef {import('postcss').Declaration} CSSDeclaration */
209
-
210
- /** Transform space and slash separated color functions in CSS. */
211
-
212
- function postcssColorFunctionalNotation(opts) {
213
- options.preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : false;
214
- return {
215
- postcssPlugin: 'postcss-color-functional-notation',
216
- Declaration: onCSSDeclaration
217
- };
218
- }
219
- postcssColorFunctionalNotation.postcss = true;
220
- /** @typedef {import('postcss').Root} CSSRoot */
221
-
222
- /** @typedef {(root: CSSRoot) => void} PostCSSTransformCallback */
223
-
224
- /** @typedef {(opts: options) => PostCSSTransformCallback} PostCSSPluginInitializer */
225
-
226
- export { postcssColorFunctionalNotation as default };