@csstools/postcss-color-function 2.1.0 → 2.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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changes to PostCSS Color Function
2
2
 
3
+ ### 2.2.1 (April 10, 2023)
4
+
5
+ - Updated `@csstools/css-tokenizer` to `2.1.1` (patch)
6
+ - Updated `@csstools/css-parser-algorithms` to `2.1.1` (patch)
7
+ - Updated `@csstools/css-color-parser` to `1.1.2` (patch)
8
+
9
+ ### 2.2.0 (March 25, 2023)
10
+
11
+ - Add `@csstools/css-color-parser` dependency for all color value transformations.
12
+ - Add support for `calc` expressions in color components.
13
+ - Remove support for missing channel values (`color(display-p3 1)`). This was never documented and was removed from the specification.
14
+
3
15
  ### 2.1.0 (February 6, 2023)
4
16
 
5
17
  - Add: `@csstools/color-helpers` dependency for all color value transformations.
package/README.md CHANGED
@@ -17,11 +17,11 @@ CSS, following the [CSS Color] specification.
17
17
  /* becomes */
18
18
 
19
19
  .color {
20
- color: rgb(179,35,35);
20
+ color: rgb(179, 35, 35);
21
21
  }
22
22
 
23
23
  :root {
24
- --a-color: rgb(164,49,43);
24
+ --a-color: rgb(164, 49, 43);
25
25
  }
26
26
  ```
27
27
 
@@ -78,12 +78,12 @@ postcssColorFunction({ preserve: true })
78
78
  /* becomes */
79
79
 
80
80
  .color {
81
- color: rgb(179,35,35);
81
+ color: rgb(179, 35, 35);
82
82
  color: color(display-p3 0.64331 0.19245 0.16771);
83
83
  }
84
84
 
85
85
  :root {
86
- --a-color: rgb(164,49,43);
86
+ --a-color: rgb(164, 49, 43);
87
87
  }
88
88
 
89
89
  @supports (color: color(srgb 0 0 0)) {
@@ -116,12 +116,12 @@ postcssColorFunction({ enableProgressiveCustomProperties: false })
116
116
  /* becomes */
117
117
 
118
118
  .color {
119
- color: rgb(179,35,35);
119
+ color: rgb(179, 35, 35);
120
120
  color: color(display-p3 0.64331 0.19245 0.16771);
121
121
  }
122
122
 
123
123
  :root {
124
- --a-color: rgb(164,49,43);
124
+ --a-color: rgb(164, 49, 43);
125
125
  --a-color: color(srgb 0.64331 0.19245 0.16771);
126
126
  }
127
127
  ```
@@ -144,20 +144,6 @@ _Custom properties do not fallback to the previous declaration_
144
144
  }
145
145
  ```
146
146
 
147
- ## Out of gamut colors
148
-
149
- Depending on the browser implementation out of gamut colors may be clipped, resulting in a different color.<br>
150
- Fallback values generated by [PostCSS Color Function] are always mapped to a close alternative in sRGB.
151
-
152
- When setting `preserve` to `true` the original values will be used by some browsers and these may be clipped.<br>
153
- Certain browsers will have an incorrect color if this occurs.
154
-
155
- If the plugin detects out of gamut colors it will emit a warning :
156
-
157
- > "color(srgb-linear -0.01656 0.23079 0.25298)" is out of gamut for "srgb-linear". When "preserve: true" is set this will lead to unexpected results in some browsers.
158
-
159
- To resolve this warning pick a larger color space when declaring the original value.
160
-
161
147
  ## Copyright : color conversions
162
148
 
163
149
  This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/tree/main/css-color-4. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("@csstools/postcss-progressive-custom-properties"),r=require("postcss-value-parser"),o=require("@csstools/color-helpers");function hasFallback(e){const r=e.parent;if(!r)return!1;const o=e.prop.toLowerCase(),n=r.index(e);for(let e=0;e<n;e++){const n=r.nodes[e];if("decl"===n.type&&n.prop.toLowerCase()===o)return!0}return!1}function hasSupportsAtRuleAncestor(e){let r=e.parent;for(;r;)if("atrule"===r.type){if("supports"===r.name&&-1!==r.params.indexOf("color("))return!0;r=r.parent}else r=r.parent;return!1}function onCSSFunctionSRgb(e,n,t,s){const a=r.stringify(e),u=e.value,c=e.nodes.slice().filter((e=>"comment"!==e.type&&"space"!==e.type));let i,l=null;if("color"===u.toLowerCase()&&(l=colorFunctionContents(c)),!l)return;switch(e.value="rgb",transformAlpha(e,l.slash,l.alpha),l.colorSpace){case"srgb":i=o.conversions.sRGB_to_sRGB;break;case"srgb-linear":i=o.conversions.sRGB_linear_to_sRGB;break;case"a98-rgb":i=o.conversions.a98_RGB_to_sRGB;break;case"prophoto-rgb":i=o.conversions.proPhoto_RGB_to_sRGB;break;case"display-p3":i=o.conversions.p3_to_sRGB;break;case"rec2020":i=o.conversions.rec_2020_to_sRGB;break;case"xyz-d50":i=o.conversions.cie_XYZ_50_to_sRGB;break;case"xyz-d65":case"xyz":i=o.conversions.cie_XYZ_65_to_sRGB;break;default:return}const p=(d=l,d.parameters.map((e=>e.value))).map((e=>parseFloat(e.number)));var d;const v=i(p);!o.utils.inGamut(p)&&s&&n.warn(t,`"${a}" is out of gamut for "${l.colorSpace}". Given "preserve: true" is set, this will lead to unexpected results in some browsers.`),e.nodes=[{sourceIndex:0,sourceEndIndex:1,value:String(Math.round(255*v[0])),type:"word"},{sourceIndex:0,sourceEndIndex:1,value:",",type:"div",before:"",after:""},{sourceIndex:0,sourceEndIndex:1,value:String(Math.round(255*v[1])),type:"word"},{sourceIndex:0,sourceEndIndex:1,value:",",type:"div",before:"",after:""},{sourceIndex:0,sourceEndIndex:1,value:String(Math.round(255*v[2])),type:"word"}],l.alpha&&(e.nodes.push({sourceIndex:0,sourceEndIndex:1,value:",",type:"div",before:"",after:""}),e.nodes.push(l.alpha))}function isColorSpaceNode(e){if(!e||"word"!==e.type)return!1;switch(e.value.toLowerCase()){case"srgb":case"srgb-linear":case"display-p3":case"a98-rgb":case"prophoto-rgb":case"rec2020":case"xyz-d50":case"xyz-d65":case"xyz":return!0;default:return!1}}function isNumericNode(e){if(!e||"word"!==e.type)return!1;if(!canParseAsUnit(e))return!1;const o=r.unit(e.value);return!!o&&!!o.number}function isNumericNodePercentageOrNumber(e){if(!e||"word"!==e.type)return!1;if(!canParseAsUnit(e))return!1;const o=r.unit(e.value);return!!o&&("%"===o.unit||""===o.unit)}function isCalcNode(e){return e&&"function"===e.type&&"calc"===e.value.toLowerCase()}function isVarNode(e){return e&&"function"===e.type&&"var"===e.value.toLowerCase()}function colorFunctionContents(e){if(!isColorSpaceNode(e[0]))return null;const o={colorSpace:e[0].value.toLowerCase(),colorSpaceNode:e[0],parameters:[]};for(let t=1;t<e.length;t++)if((n=e[t])&&"div"===n.type&&"/"===n.value)o.slash=e[t];else{if(o.slash&&(isNumericNodePercentageOrNumber(e[t])||isCalcNode(e[t])||isVarNode(e[t]))){o.alpha=e[t];break}if(!isNumericNodePercentageOrNumber(e[t]))return null;{const n=r.unit(e[t].value);"%"===n.unit&&(n.number=String(parseFloat(n.number)/100),n.unit="",e[t].value=String(n.number)),o.parameters.push({value:n,node:e[t]})}}var n;return 0===o.parameters.length||(o.parameters.length<3&&(o.parameters=[...o.parameters,{node:{sourceIndex:0,sourceEndIndex:1,value:"0",type:"word"},value:{number:"0",unit:""}},{node:{sourceIndex:0,sourceEndIndex:1,value:"0",type:"word"},value:{number:"0",unit:""}}]),o.parameters.length>3&&(o.parameters=o.parameters.slice(0,3))),o}function transformAlpha(e,o,n){if(!o||!n)return;if(e.value="rgba",o.value=",",o.before="",!isNumericNode(n))return;const t=r.unit(n.value);t&&"%"===t.unit&&(t.number=String(parseFloat(t.number)/100),n.value=String(t.number))}function canParseAsUnit(e){if(!e||!e.value)return!1;try{return!1!==r.unit(e.value)}catch(e){return!1}}function modifiedValues(e,o,n,t){let s;try{s=r(e)}catch(r){o.warn(n,`Failed to parse value '${e}' as a color function. Leaving the original value intact.`)}if(void 0===s)return;s.walk((e=>{e.type&&"function"===e.type&&"color"===e.value.toLowerCase()&&onCSSFunctionSRgb(e,o,n,t)}));const a=String(s);return a!==e?a:void 0}const basePlugin=e=>{const r="preserve"in Object(e)&&Boolean(e.preserve);return{postcssPlugin:"postcss-color-function",Declaration:(e,{result:o})=>{const n=e.value;if(!n.toLowerCase().includes("color("))return;if(hasFallback(e))return;if(hasSupportsAtRuleAncestor(e))return;const t=modifiedValues(n,e,o,r);void 0!==t&&(e.cloneBefore({value:t}),r||e.remove())}}};basePlugin.postcss=!0;const postcssPlugin=r=>{const o=Object.assign({preserve:!1,enableProgressiveCustomProperties:!0},r);return o.enableProgressiveCustomProperties&&o.preserve?{postcssPlugin:"postcss-color-function",plugins:[e(),basePlugin(o)]}:basePlugin(o)};postcssPlugin.postcss=!0,module.exports=postcssPlugin;
1
+ "use strict";var e=require("@csstools/postcss-progressive-custom-properties"),s=require("@csstools/css-tokenizer"),r=require("@csstools/css-color-parser"),o=require("@csstools/css-parser-algorithms");function hasFallback(e){const s=e.parent;if(!s)return!1;const r=e.prop.toLowerCase(),o=s.index(e);for(let e=0;e<o;e++){const o=s.nodes[e];if("decl"===o.type&&o.prop.toLowerCase()===r)return!0}return!1}function hasSupportsAtRuleAncestor(e){let s=e.parent;for(;s;)if("atrule"===s.type){if("supports"===s.name&&-1!==s.params.indexOf("color("))return!0;s=s.parent}else s=s.parent;return!1}const t=/(color)\(/i,n=/^(color)$/i,basePlugin=e=>({postcssPlugin:"postcss-color-function",Declaration:c=>{const a=c.value;if(!t.test(a.toLowerCase()))return;if(hasFallback(c))return;if(hasSupportsAtRuleAncestor(c))return;const i=s.tokenize({css:a}),l=o.replaceComponentValues(o.parseCommaSeparatedListOfComponentValues(i),(e=>{if(o.isFunctionNode(e)&&n.test(e.getName())){const s=r.color(e);if(!s)return;if(s.syntaxFlags.has(r.SyntaxFlag.HasNoneKeywords))return;return r.serializeRGB(s)}})),p=o.stringify(l);p!==a&&(c.cloneBefore({value:p}),null!=e&&e.preserve||c.remove())}});basePlugin.postcss=!0;const postcssPlugin=s=>{const r=Object.assign({preserve:!1,enableProgressiveCustomProperties:!0},s);return r.enableProgressiveCustomProperties&&r.preserve?{postcssPlugin:"postcss-color-function",plugins:[e(),basePlugin(r)]}:basePlugin(r)};postcssPlugin.postcss=!0,module.exports=postcssPlugin;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import e from"@csstools/postcss-progressive-custom-properties";import r from"postcss-value-parser";import{conversions as t,utils as o}from"@csstools/color-helpers";function hasFallback(e){const r=e.parent;if(!r)return!1;const t=e.prop.toLowerCase(),o=r.index(e);for(let e=0;e<o;e++){const o=r.nodes[e];if("decl"===o.type&&o.prop.toLowerCase()===t)return!0}return!1}function hasSupportsAtRuleAncestor(e){let r=e.parent;for(;r;)if("atrule"===r.type){if("supports"===r.name&&-1!==r.params.indexOf("color("))return!0;r=r.parent}else r=r.parent;return!1}function onCSSFunctionSRgb(e,n,s,a){const u=r.stringify(e),c=e.value,i=e.nodes.slice().filter((e=>"comment"!==e.type&&"space"!==e.type));let l,p=null;if("color"===c.toLowerCase()&&(p=colorFunctionContents(i)),!p)return;switch(e.value="rgb",transformAlpha(e,p.slash,p.alpha),p.colorSpace){case"srgb":l=t.sRGB_to_sRGB;break;case"srgb-linear":l=t.sRGB_linear_to_sRGB;break;case"a98-rgb":l=t.a98_RGB_to_sRGB;break;case"prophoto-rgb":l=t.proPhoto_RGB_to_sRGB;break;case"display-p3":l=t.p3_to_sRGB;break;case"rec2020":l=t.rec_2020_to_sRGB;break;case"xyz-d50":l=t.cie_XYZ_50_to_sRGB;break;case"xyz-d65":case"xyz":l=t.cie_XYZ_65_to_sRGB;break;default:return}const d=(f=p,f.parameters.map((e=>e.value))).map((e=>parseFloat(e.number)));var f;const v=l(d);!o.inGamut(d)&&a&&n.warn(s,`"${u}" is out of gamut for "${p.colorSpace}". Given "preserve: true" is set, this will lead to unexpected results in some browsers.`),e.nodes=[{sourceIndex:0,sourceEndIndex:1,value:String(Math.round(255*v[0])),type:"word"},{sourceIndex:0,sourceEndIndex:1,value:",",type:"div",before:"",after:""},{sourceIndex:0,sourceEndIndex:1,value:String(Math.round(255*v[1])),type:"word"},{sourceIndex:0,sourceEndIndex:1,value:",",type:"div",before:"",after:""},{sourceIndex:0,sourceEndIndex:1,value:String(Math.round(255*v[2])),type:"word"}],p.alpha&&(e.nodes.push({sourceIndex:0,sourceEndIndex:1,value:",",type:"div",before:"",after:""}),e.nodes.push(p.alpha))}function isColorSpaceNode(e){if(!e||"word"!==e.type)return!1;switch(e.value.toLowerCase()){case"srgb":case"srgb-linear":case"display-p3":case"a98-rgb":case"prophoto-rgb":case"rec2020":case"xyz-d50":case"xyz-d65":case"xyz":return!0;default:return!1}}function isNumericNode(e){if(!e||"word"!==e.type)return!1;if(!canParseAsUnit(e))return!1;const t=r.unit(e.value);return!!t&&!!t.number}function isNumericNodePercentageOrNumber(e){if(!e||"word"!==e.type)return!1;if(!canParseAsUnit(e))return!1;const t=r.unit(e.value);return!!t&&("%"===t.unit||""===t.unit)}function isCalcNode(e){return e&&"function"===e.type&&"calc"===e.value.toLowerCase()}function isVarNode(e){return e&&"function"===e.type&&"var"===e.value.toLowerCase()}function colorFunctionContents(e){if(!isColorSpaceNode(e[0]))return null;const t={colorSpace:e[0].value.toLowerCase(),colorSpaceNode:e[0],parameters:[]};for(let n=1;n<e.length;n++)if((o=e[n])&&"div"===o.type&&"/"===o.value)t.slash=e[n];else{if(t.slash&&(isNumericNodePercentageOrNumber(e[n])||isCalcNode(e[n])||isVarNode(e[n]))){t.alpha=e[n];break}if(!isNumericNodePercentageOrNumber(e[n]))return null;{const o=r.unit(e[n].value);"%"===o.unit&&(o.number=String(parseFloat(o.number)/100),o.unit="",e[n].value=String(o.number)),t.parameters.push({value:o,node:e[n]})}}var o;return 0===t.parameters.length||(t.parameters.length<3&&(t.parameters=[...t.parameters,{node:{sourceIndex:0,sourceEndIndex:1,value:"0",type:"word"},value:{number:"0",unit:""}},{node:{sourceIndex:0,sourceEndIndex:1,value:"0",type:"word"},value:{number:"0",unit:""}}]),t.parameters.length>3&&(t.parameters=t.parameters.slice(0,3))),t}function transformAlpha(e,t,o){if(!t||!o)return;if(e.value="rgba",t.value=",",t.before="",!isNumericNode(o))return;const n=r.unit(o.value);n&&"%"===n.unit&&(n.number=String(parseFloat(n.number)/100),o.value=String(n.number))}function canParseAsUnit(e){if(!e||!e.value)return!1;try{return!1!==r.unit(e.value)}catch(e){return!1}}function modifiedValues(e,t,o,n){let s;try{s=r(e)}catch(r){t.warn(o,`Failed to parse value '${e}' as a color function. Leaving the original value intact.`)}if(void 0===s)return;s.walk((e=>{e.type&&"function"===e.type&&"color"===e.value.toLowerCase()&&onCSSFunctionSRgb(e,t,o,n)}));const a=String(s);return a!==e?a:void 0}const basePlugin=e=>{const r="preserve"in Object(e)&&Boolean(e.preserve);return{postcssPlugin:"postcss-color-function",Declaration:(e,{result:t})=>{const o=e.value;if(!o.toLowerCase().includes("color("))return;if(hasFallback(e))return;if(hasSupportsAtRuleAncestor(e))return;const n=modifiedValues(o,e,t,r);void 0!==n&&(e.cloneBefore({value:n}),r||e.remove())}}};basePlugin.postcss=!0;const postcssPlugin=r=>{const t=Object.assign({preserve:!1,enableProgressiveCustomProperties:!0},r);return t.enableProgressiveCustomProperties&&t.preserve?{postcssPlugin:"postcss-color-function",plugins:[e(),basePlugin(t)]}:basePlugin(t)};postcssPlugin.postcss=!0;export{postcssPlugin as default};
1
+ import s from"@csstools/postcss-progressive-custom-properties";import{tokenize as r}from"@csstools/css-tokenizer";import{color as e,SyntaxFlag as o,serializeRGB as t}from"@csstools/css-color-parser";import{replaceComponentValues as n,parseCommaSeparatedListOfComponentValues as c,isFunctionNode as p,stringify as a}from"@csstools/css-parser-algorithms";function hasFallback(s){const r=s.parent;if(!r)return!1;const e=s.prop.toLowerCase(),o=r.index(s);for(let s=0;s<o;s++){const o=r.nodes[s];if("decl"===o.type&&o.prop.toLowerCase()===e)return!0}return!1}function hasSupportsAtRuleAncestor(s){let r=s.parent;for(;r;)if("atrule"===r.type){if("supports"===r.name&&-1!==r.params.indexOf("color("))return!0;r=r.parent}else r=r.parent;return!1}const i=/(color)\(/i,l=/^(color)$/i,basePlugin=s=>({postcssPlugin:"postcss-color-function",Declaration:u=>{const f=u.value;if(!i.test(f.toLowerCase()))return;if(hasFallback(u))return;if(hasSupportsAtRuleAncestor(u))return;const m=r({css:f}),g=n(c(m),(s=>{if(p(s)&&l.test(s.getName())){const r=e(s);if(!r)return;if(r.syntaxFlags.has(o.HasNoneKeywords))return;return t(r)}})),v=a(g);v!==f&&(u.cloneBefore({value:v}),null!=s&&s.preserve||u.remove())}});basePlugin.postcss=!0;const postcssPlugin=r=>{const e=Object.assign({preserve:!1,enableProgressiveCustomProperties:!0},r);return e.enableProgressiveCustomProperties&&e.preserve?{postcssPlugin:"postcss-color-function",plugins:[s(),basePlugin(e)]}:basePlugin(e)};postcssPlugin.postcss=!0;export{postcssPlugin as default};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@csstools/postcss-color-function",
3
3
  "description": "Use the color() function in CSS",
4
- "version": "2.1.0",
4
+ "version": "2.2.1",
5
5
  "author": "Jonathan Neal <jonathantneal@hotmail.com>",
6
6
  "license": "CC0-1.0",
7
7
  "funding": {
@@ -29,27 +29,24 @@
29
29
  "dist"
30
30
  ],
31
31
  "dependencies": {
32
- "@csstools/color-helpers": "^1.0.0",
33
- "@csstools/postcss-progressive-custom-properties": "^2.0.0",
34
- "postcss-value-parser": "^4.2.0"
32
+ "@csstools/css-color-parser": "^1.1.2",
33
+ "@csstools/css-parser-algorithms": "^2.1.1",
34
+ "@csstools/css-tokenizer": "^2.1.1",
35
+ "@csstools/postcss-progressive-custom-properties": "^2.0.0"
35
36
  },
36
37
  "peerDependencies": {
37
38
  "postcss": "^8.4"
38
39
  },
39
40
  "devDependencies": {
41
+ "@csstools/postcss-tape": "*",
40
42
  "postcss-lab-function": "^5.0.0"
41
43
  },
42
44
  "scripts": {
43
- "prebuild": "npm run clean",
44
45
  "build": "rollup -c ../../rollup/default.mjs",
45
- "clean": "node -e \"fs.rmSync('./dist', { recursive: true, force: true }); fs.mkdirSync('./dist');\"",
46
46
  "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs",
47
- "lint": "npm run lint:eslint && npm run lint:package-json",
48
- "lint:eslint": "eslint ./src --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern",
49
- "lint:package-json": "node ../../.github/bin/format-package-json.mjs",
50
- "prepublishOnly": "npm run clean && npm run build && npm run test",
51
- "test": "node .tape.mjs && npm run test:exports",
52
- "test:exports": "node ./test/_import.mjs && node ./test/_require.cjs",
47
+ "lint": "node ../../.github/bin/format-package-json.mjs",
48
+ "prepublishOnly": "npm run build && npm run test",
49
+ "test": "node .tape.mjs && node ./test/_import.mjs && node ./test/_require.cjs",
53
50
  "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs"
54
51
  },
55
52
  "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-color-function#readme",
@@ -1,2 +0,0 @@
1
- import type { Declaration, Result } from 'postcss';
2
- export declare function modifiedValues(originalValue: string, decl: Declaration, result: Result, preserve: boolean): string | undefined;
@@ -1,3 +0,0 @@
1
- import type { Declaration, Result } from 'postcss';
2
- import type { FunctionNode } from 'postcss-value-parser';
3
- export declare function onCSSFunctionSRgb(node: FunctionNode, decl: Declaration, result: Result, preserve: boolean): void;