Skip to content

Commit cc3b9b7

Browse files
authored
only produce valid fallback values (#1187)
1 parent 7bd9253 commit cc3b9b7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+334
-618
lines changed

packages/css-color-parser/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes to CSS Color Parser
22

3+
### Unreleased (minor)
4+
5+
- Add a `serializeHSL` function.
6+
37
### 1.4.0
48

59
_October 9, 2023_

packages/css-color-parser/dist/index.cjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

packages/css-color-parser/dist/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ export { SyntaxFlag } from './color-data';
66
export { colorDataTo, colorDataFitsRGB_Gamut, colorDataFitsDisplayP3_Gamut } from './color-data';
77
export { serializeP3 } from './serialize/p3';
88
export { serializeRGB } from './serialize/rgb';
9+
export { serializeHSL } from './serialize/hsl';
910
export { serializeOKLCH } from './serialize/oklch';
1011
export declare function color(colorNode: ComponentValue): ColorData | false;

packages/css-color-parser/dist/index.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { ColorData } from '../color-data';
2+
import { FunctionNode } from '@csstools/css-parser-algorithms';
3+
export declare function serializeHSL(color: ColorData, gamutMapping?: boolean): FunctionNode;

packages/css-color-parser/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export { SyntaxFlag } from './color-data';
2222
export { colorDataTo, colorDataFitsRGB_Gamut, colorDataFitsDisplayP3_Gamut } from './color-data';
2323
export { serializeP3 } from './serialize/p3';
2424
export { serializeRGB } from './serialize/rgb';
25+
export { serializeHSL } from './serialize/hsl';
2526
export { serializeOKLCH } from './serialize/oklch';
2627

2728
export function color(colorNode: ComponentValue): ColorData | false {
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { ColorData, convertPowerlessComponentsToZeroValuesForDisplay } from '../color-data';
2+
import type { TokenCloseParen, TokenComma, TokenWhitespace } from '@csstools/css-tokenizer';
3+
import { FunctionNode, TokenNode, WhitespaceNode } from '@csstools/css-parser-algorithms';
4+
import { NumberType, TokenType } from '@csstools/css-tokenizer';
5+
import { xyz } from '@csstools/color-helpers';
6+
import { colorData_to_XYZ_D50 } from '../color-data';
7+
import { toPrecision } from './to-precision';
8+
import { XYZ_D50_to_sRGB_Gamut } from '../gamut-mapping/srgb';
9+
10+
export function serializeHSL(color: ColorData, gamutMapping = true): FunctionNode {
11+
color.channels = convertPowerlessComponentsToZeroValuesForDisplay(color.channels, color.colorNotation);
12+
let hsl = color.channels.map((x) => Number.isNaN(x) ? 0 : x);
13+
14+
if (gamutMapping) {
15+
hsl = xyz.XYZ_D50_to_HSL(xyz.sRGB_to_XYZ_D50(
16+
XYZ_D50_to_sRGB_Gamut(colorData_to_XYZ_D50(color).channels),
17+
));
18+
} else {
19+
hsl = xyz.XYZ_D50_to_HSL(colorData_to_XYZ_D50(color).channels);
20+
}
21+
22+
// Needs to be done twice because `xyz.XYZ_D50_to_HSL` can return `NaN` values.
23+
hsl = hsl.map((x) => Number.isNaN(x) ? 0 : x);
24+
25+
const h = Math.min(360, Math.max(0, Math.round(toPrecision(hsl[0]))));
26+
const s = Math.min(100, Math.max(0, Math.round(toPrecision(hsl[1]))));
27+
const l = Math.min(100, Math.max(0, Math.round(toPrecision(hsl[2]))));
28+
29+
const close: TokenCloseParen = [TokenType.CloseParen, ')', -1, -1, undefined];
30+
const space: TokenWhitespace = [TokenType.Whitespace, ' ', -1, -1, undefined];
31+
const comma: TokenComma = [TokenType.Comma, ',', -1, -1, undefined];
32+
33+
const channels = [
34+
new TokenNode([TokenType.Number, h.toString(), -1, -1, { value: hsl[0], type: NumberType.Integer }]),
35+
new TokenNode(comma),
36+
new WhitespaceNode([space]),
37+
new TokenNode([TokenType.Percentage, s.toString() + '%', -1, -1, { value: hsl[1] }]),
38+
new TokenNode(comma),
39+
new WhitespaceNode([space]),
40+
new TokenNode([TokenType.Percentage, l.toString() + '%', -1, -1, { value: hsl[2] }]),
41+
];
42+
43+
if (typeof color.alpha === 'number') {
44+
const a = Math.min(1, Math.max(0, toPrecision(Number.isNaN(color.alpha) ? 0 : color.alpha)));
45+
if (toPrecision(a, 4) === 1) {
46+
return new FunctionNode(
47+
[TokenType.Function, 'hsl(', -1, -1, { value: 'hsl' }],
48+
close,
49+
channels,
50+
);
51+
}
52+
53+
return new FunctionNode(
54+
[TokenType.Function, 'hsla(', -1, -1, { value: 'hsla' }],
55+
close,
56+
[
57+
...channels,
58+
new TokenNode(comma),
59+
new WhitespaceNode([space]),
60+
new TokenNode([TokenType.Number, toPrecision(a, 4).toString(), -1, -1, { value: color.alpha, type: NumberType.Number }]),
61+
],
62+
);
63+
}
64+
65+
return new FunctionNode(
66+
[TokenType.Function, 'hsla(', -1, -1, { value: 'hsla' }],
67+
close,
68+
[
69+
...channels,
70+
new TokenNode(comma),
71+
new WhitespaceNode([space]),
72+
color.alpha,
73+
],
74+
);
75+
}

packages/css-color-parser/test/basic/basic.mjs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { color } from '@csstools/css-color-parser';
22
import assert from 'assert';
33
import { parse } from '../util/parse.mjs';
4-
import { serialize_sRGB_data } from '../util/serialize.mjs';
4+
import { serialize_HSL_data, serialize_sRGB_data } from '../util/serialize.mjs';
55

66
[
77
'rgb( )',
@@ -159,3 +159,18 @@ assert.deepStrictEqual(
159159
serialize_sRGB_data(color(parse('color-mix(in srgb, red min(10%, 20%), blue)'))),
160160
'rgb(26, 0, 230)',
161161
);
162+
163+
assert.deepStrictEqual(
164+
serialize_HSL_data(color(parse('hsl(50deg 50 65% / 0.5)'))),
165+
'hsla(50, 50%, 65%, 0.5)',
166+
);
167+
168+
assert.deepStrictEqual(
169+
serialize_HSL_data(color(parse('hsla(50deg, 50%, 65%, 45%)'))),
170+
'hsla(50, 50%, 65%, 0.45)',
171+
);
172+
173+
assert.deepStrictEqual(
174+
serialize_HSL_data(color(parse('hsl(0 0% 100%)'))),
175+
'hsl(0, 0%, 100%)',
176+
);

packages/css-color-parser/test/util/serialize.mjs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { serializeRGB, serializeP3, serializeOKLCH } from '@csstools/css-color-parser';
1+
import { serializeRGB, serializeP3, serializeOKLCH, serializeHSL } from '@csstools/css-color-parser';
22

33
export function serialize_sRGB_data(x) {
44
if (!x) {
@@ -8,6 +8,14 @@ export function serialize_sRGB_data(x) {
88
return serializeRGB(x).toString();
99
}
1010

11+
export function serialize_HSL_data(x) {
12+
if (!x) {
13+
return '';
14+
}
15+
16+
return serializeHSL(x).toString();
17+
}
18+
1119
export function serialize_P3_data(x) {
1220
if (!x) {
1321
return '';

plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@
103103
}
104104

105105
.test-color-functional-notation {
106-
color: rgba(178, 34, 34, 0.5);
106+
color: rgba(179, 34, 34, 0.5);
107107
order: 16;
108108
}
109109

plugin-packs/postcss-preset-env/test/basic.autoprefixer.false.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@
103103
}
104104

105105
.test-color-functional-notation {
106-
color: rgba(178, 34, 34, 0.5);
106+
color: rgba(179, 34, 34, 0.5);
107107
order: 16;
108108
}
109109

plugin-packs/postcss-preset-env/test/basic.ch38.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
}
9797

9898
.test-color-functional-notation {
99-
color: rgba(178, 34, 34, 0.5);
99+
color: rgba(179, 34, 34, 0.5);
100100
order: 16;
101101
}
102102

plugin-packs/postcss-preset-env/test/basic.ch88-ff78-saf10.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe
101101
}
102102

103103
.test-color-functional-notation {
104-
color: rgba(178, 34, 34, 0.5);
104+
color: rgba(179, 34, 34, 0.5);
105105
order: 16;
106106
}
107107

plugin-packs/postcss-preset-env/test/basic.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
}
105105

106106
.test-color-functional-notation {
107-
color: rgba(178, 34, 34, 0.5);
107+
color: rgba(179, 34, 34, 0.5);
108108
order: 16;
109109
}
110110

plugin-packs/postcss-preset-env/test/basic.ff49.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
}
103103

104104
.test-color-functional-notation {
105-
color: rgba(178, 34, 34, 0.5);
105+
color: rgba(179, 34, 34, 0.5);
106106
order: 16;
107107
}
108108

plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe
102102
}
103103

104104
.test-color-functional-notation {
105-
color: rgba(178, 34, 34, 0.5);
105+
color: rgba(179, 34, 34, 0.5);
106106
order: 16;
107107
}
108108

plugin-packs/postcss-preset-env/test/basic.ie10.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@
121121
}
122122

123123
.test-color-functional-notation {
124-
color: rgba(178, 34, 34, 0.5);
124+
color: rgba(179, 34, 34, 0.5);
125125
-ms-flex-order: 16;
126126
order: 16;
127127
}

plugin-packs/postcss-preset-env/test/basic.nesting.false.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe
102102
}
103103

104104
.test-color-functional-notation {
105-
color: rgba(178, 34, 34, 0.5);
105+
color: rgba(179, 34, 34, 0.5);
106106
order: 16;
107107
}
108108

plugin-packs/postcss-preset-env/test/basic.op_mini.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe
101101
}
102102

103103
.test-color-functional-notation {
104-
color: rgba(178, 34, 34, 0.5);
104+
color: rgba(179, 34, 34, 0.5);
105105
order: 16;
106106
}
107107

plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe
151151
}
152152

153153
.test-color-functional-notation {
154-
color: rgba(178, 34, 34, 0.5);
154+
color: rgba(179, 34, 34, 0.5);
155155
-webkit-box-ordinal-group: 17;
156156
-webkit-order: 16;
157157
-moz-box-ordinal-group: 17;

plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe
212212
}
213213

214214
.test-color-functional-notation {
215-
color: rgba(178, 34, 34, 0.5);
215+
color: rgba(179, 34, 34, 0.5);
216216
color: rgb(70% 13.5% 13.5% / 50%);
217217
-webkit-box-ordinal-group: 17;
218218
-webkit-order: 16;

plugin-packs/postcss-preset-env/test/basic.stage0-ff49.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe
100100
}
101101

102102
.test-color-functional-notation {
103-
color: rgba(178, 34, 34, 0.5);
103+
color: rgba(179, 34, 34, 0.5);
104104
order: 16;
105105
}
106106

plugin-packs/postcss-preset-env/test/basic.stage0.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe
102102
}
103103

104104
.test-color-functional-notation {
105-
color: rgba(178, 34, 34, 0.5);
105+
color: rgba(179, 34, 34, 0.5);
106106
order: 16;
107107
}
108108

plugin-packs/postcss-preset-env/test/basic.vendors-1.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@
108108
}
109109

110110
.test-color-functional-notation {
111-
color: rgba(178, 34, 34, 0.5);
111+
color: rgba(179, 34, 34, 0.5);
112112
order: 16;
113113
}
114114

plugin-packs/postcss-preset-env/test/basic.vendors-2.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@
108108
}
109109

110110
.test-color-functional-notation {
111-
color: rgba(178, 34, 34, 0.5);
111+
color: rgba(179, 34, 34, 0.5);
112112
order: 16;
113113
}
114114

plugin-packs/postcss-preset-env/test/basic.vendors-3.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@
108108
}
109109

110110
.test-color-functional-notation {
111-
color: rgba(178, 34, 34, 0.5);
111+
color: rgba(179, 34, 34, 0.5);
112112
order: 16;
113113
}
114114

plugin-packs/postcss-preset-env/test/layers-basic.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ h1.test-custom-selectors:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):n
162162
}
163163

164164
.test-color-functional-notation:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) {
165-
color: rgba(178, 34, 34, 0.5);
165+
color: rgba(179, 34, 34, 0.5);
166166
-webkit-box-ordinal-group: 17;
167167
-webkit-order: 16;
168168
-moz-box-ordinal-group: 17;

plugin-packs/postcss-preset-env/test/layers-basic.preserve.true.expect.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ h1.test-custom-selectors:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):n
215215
}
216216

217217
.test-color-functional-notation:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) {
218-
color: rgba(178, 34, 34, 0.5);
218+
color: rgba(179, 34, 34, 0.5);
219219
color: rgb(70% 13.5% 13.5% / 50%);
220220
-webkit-box-ordinal-group: 17;
221221
-webkit-order: 16;

plugins/postcss-color-functional-notation/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes to PostCSS Color Functional Notation
22

3+
### Unreleased (patch)
4+
5+
- Ensure that fallback values are always valid legacy syntax.
6+
37
### 6.0.2
48

59
_October 9, 2023_
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
import type { Node } from 'postcss';
2+
export declare const rgb_hsl_functionRegex: RegExp;
23
export declare function hasSupportsAtRuleAncestor(node: Node): boolean;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"use strict";var e=require("@csstools/postcss-progressive-custom-properties"),r=require("postcss-value-parser");function onCSSFunction(e){const r=e.value.toLowerCase();if(!needsConversion("rgb"===r||"rgba"===r,e.nodes))return;const n=convertOldSyntaxToNewSyntaxBeforeTransform(e.nodes).slice().filter((e=>"comment"!==e.type&&"space"!==e.type));let t=null;if("hsl"===r||"hsla"===r?t=hslFunctionContents(n):"rgb"!==r&&"rgba"!==r||(t=rgbFunctionContents(n)),!t)return;if(n.length>3&&(!t.slash||!t.alpha))return;transformAlpha(e,t.slash,t.alpha);const[o,u]=channelNodes(t);e.nodes.splice(e.nodes.indexOf(o)+1,0,{sourceIndex:0,sourceEndIndex:1,value:",",type:"div",before:"",after:""}),e.nodes.splice(e.nodes.indexOf(u)+1,0,{sourceIndex:0,sourceEndIndex:1,value:",",type:"div",before:"",after:""})}function isNumericNode(e){if(!e||"word"!==e.type)return!1;if(!canParseAsUnit(e))return!1;const n=r.unit(e.value);return!!n&&!!n.number}function isNumericNodeHueLike(e){if(!e||"word"!==e.type)return!1;if(!canParseAsUnit(e))return!1;const n=r.unit(e.value);if(!n)return!1;const t=n.unit.toLowerCase();return!!n.number&&("deg"===t||"grad"===t||"rad"===t||"turn"===t||""===n.unit)}function isNumericNodePercentageOrNumber(e){if(!e||"word"!==e.type)return!1;if(!canParseAsUnit(e))return!1;const n=r.unit(e.value);return!!n&&("%"===n.unit||""===n.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 isSlashNode(e){return e&&"div"===e.type&&"/"===e.value}function hslFunctionContents(e){if(!isNumericNodeHueLike(e[0]))return null;if(!isNumericNodePercentageOrNumber(e[1]))return null;if(!isNumericNodePercentageOrNumber(e[2]))return null;const n={h:r.unit(e[0].value),hNode:e[0],s:r.unit(e[1].value),sNode:e[1],l:r.unit(e[2].value),lNode:e[2]};return normalizeHueNode(n.h),""!==n.h.unit?null:(n.hNode.value=n.h.number,isSlashNode(e[3])&&(n.slash=e[3]),(isNumericNodePercentageOrNumber(e[4])||isCalcNode(e[4])||isVarNode(e[4]))&&(n.alpha=e[4]),n)}function rgbFunctionContents(e){if(!isNumericNodePercentageOrNumber(e[0]))return null;if(!isNumericNodePercentageOrNumber(e[1]))return null;if(!isNumericNodePercentageOrNumber(e[2]))return null;const n={r:r.unit(e[0].value),rNode:e[0],g:r.unit(e[1].value),gNode:e[1],b:r.unit(e[2].value),bNode:e[2]};return"%"===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),isSlashNode(e[3])&&(n.slash=e[3]),(isNumericNodePercentageOrNumber(e[4])||isCalcNode(e[4])||isVarNode(e[4]))&&(n.alpha=e[4]),n}function isRgb(e){return void 0!==e.r}function channelNodes(e){return isRgb(e)?[e.rNode,e.gNode,e.bNode]:[e.hNode,e.sNode,e.lNode]}function transformAlpha(e,n,t){if("hsl"===e.value.toLowerCase()||"hsla"===e.value.toLowerCase()?e.value="hsl":"rgb"!==e.value.toLowerCase()&&"rgba"!==e.value.toLowerCase()||(e.value="rgb"),!n||!t)return;if("hsl"===e.value.toLowerCase()?e.value="hsla":e.value="rgba",n.value=",",n.before="",!isNumericNode(t))return;const o=r.unit(t.value);o&&"%"===o.unit&&(o.number=String(parseFloat(o.number)/100),t.value=String(o.number))}function normalizeHueNode(e){switch(e.unit.toLowerCase()){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":return e.unit="",void(e.number=Math.round(360*parseFloat(e.number)).toString())}}function canParseAsUnit(e){if(!e||!e.value)return!1;try{return!1!==r.unit(e.value)}catch(e){return!1}}function convertOldSyntaxToNewSyntaxBeforeTransform(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}function needsConversion(e,r){let n=!1,t=!1,o=!1;const u=r.slice().filter((e=>"comment"!==e.type&&"space"!==e.type));for(let s=0;s<u.length;s++){const a=u[s];if("word"===a.type&&"from"===a.value.toLowerCase())return!1;"div"!==a.type||","!==a.value?e&&"word"===a.type&&a.value.endsWith("%")?o=!0:s===r.length-1&&"word"===a.type&&a.value.endsWith("%")&&(t=!0):n=!0}return!(!n||!t&&!o)||!n}const n=/(\(color: rgb(a?)\(0 0 0 \/ 0)|(\(color: hsl(a?)\(0 0% 0% \/ 0)/i;function hasSupportsAtRuleAncestor(e){let r=e.parent;for(;r;)if("atrule"===r.type){if("supports"===r.name&&n.test(r.params))return!0;r=r.parent}else r=r.parent;return!1}function hasFallback(e){const r=e.parent;if(!r)return!1;const n=e.prop.toLowerCase(),t=r.index(e);for(let e=0;e<t;e++){const t=r.nodes[e];if("decl"===t.type&&t.prop.toLowerCase()===n)return!0}return!1}const t=/(?:rgb|hsl)a?\(/i,basePlugin=e=>({postcssPlugin:"postcss-color-function",Declaration:(n,{result:o})=>{const u=n.value;if(!t.test(u))return;if(hasFallback(n))return;if(hasSupportsAtRuleAncestor(n))return;let s;try{s=r(u)}catch(e){n.warn(o,`Failed to parse value '${u}' as a hsl or rgb function. Leaving the original value intact.`)}if(void 0===s)return;s.walk((e=>{if(!e.type||"function"!==e.type)return;const r=e.value.toLowerCase();"hsl"!==r&&"hsla"!==r&&"rgb"!==r&&"rgba"!==r||onCSSFunction(e)}));const a=String(s);a!==u&&(n.cloneBefore({value:a}),null!=e&&e.preserve||n.remove())}});basePlugin.postcss=!0;const postcssPlugin=r=>{const n=Object.assign({preserve:!1,enableProgressiveCustomProperties:!0},r);return n.enableProgressiveCustomProperties&&n.preserve?{postcssPlugin:"postcss-color-function",plugins:[e(),basePlugin(n)]}:basePlugin(n)};postcssPlugin.postcss=!0,module.exports=postcssPlugin;
1+
"use strict";var s=require("@csstools/postcss-progressive-custom-properties"),e=require("@csstools/css-tokenizer"),t=require("@csstools/css-color-parser"),r=require("@csstools/css-parser-algorithms");function hasFallback(s){const e=s.parent;if(!e)return!1;const t=s.prop.toLowerCase(),r=e.index(s);for(let s=0;s<r;s++){const r=e.nodes[s];if("decl"===r.type&&r.prop.toLowerCase()===t)return!0}return!1}const o=/(?:rgb|hsl)a?\(/i;function hasSupportsAtRuleAncestor(s){let e=s.parent;for(;e;)if("atrule"===e.type){if("supports"===e.name.toLowerCase()&&o.test(e.params))return!0;e=e.parent}else e=e.parent;return!1}const a=/^(?:rgb|hsl)a?$/i,basePlugin=s=>({postcssPlugin:"postcss-color-functional-notation",Declaration:n=>{const l=n.value;if(!o.test(l))return;if(hasFallback(n))return;if(hasSupportsAtRuleAncestor(n))return;const i=r.replaceComponentValues(r.parseCommaSeparatedListOfComponentValues(e.tokenize({css:l})),(s=>{if(r.isFunctionNode(s)&&a.test(s.getName())){const e=t.color(s);if(!e)return;if(e.syntaxFlags.has(t.SyntaxFlag.HasNoneKeywords))return;if(e.syntaxFlags.has(t.SyntaxFlag.RelativeColorSyntax))return;if((e.syntaxFlags.has(t.SyntaxFlag.LegacyRGB)||e.syntaxFlags.has(t.SyntaxFlag.LegacyHSL))&&!e.syntaxFlags.has(t.SyntaxFlag.HasPercentageAlpha))return;return"hsl"===e.colorNotation?t.serializeHSL(e):t.serializeRGB(e)}})),c=r.stringify(i);c!==l&&(n.cloneBefore({value:c}),null!=s&&s.preserve||n.remove())}});basePlugin.postcss=!0;const postcssPlugin=e=>{const t=Object.assign({preserve:!1,enableProgressiveCustomProperties:!0},e);return t.enableProgressiveCustomProperties&&t.preserve?{postcssPlugin:"postcss-color-functional-notation",plugins:[s(),basePlugin(t)]}:basePlugin(t)};postcssPlugin.postcss=!0,module.exports=postcssPlugin;

0 commit comments

Comments
 (0)