@thejaredwilcurt/csslop 0.0.46 → 0.0.47
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 +5 -5
- package/src/declarations/border.js +1 -1
- package/src/rules/stringify.js +57 -8
- package/src/value/math-expression.js +67 -14
- package/src/value/math.js +63 -3
- package/src/value/minify.js +38 -0
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@thejaredwilcurt/csslop",
|
|
3
3
|
"main": "index.js",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.47",
|
|
6
6
|
"description": "Experimental CSS minification",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"prestart": "node ./scripts/pre/start.js",
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
"eslint-config-tjw-import-x": "^1.0.1",
|
|
36
36
|
"eslint-config-tjw-jsdoc": "^2.0.1",
|
|
37
37
|
"eslint-plugin-import-x": "^4.17.0",
|
|
38
|
-
"eslint-plugin-jsdoc": "^65.4.
|
|
38
|
+
"eslint-plugin-jsdoc": "^65.4.2",
|
|
39
39
|
"fflate": "^0.8.3",
|
|
40
40
|
"globals": "^17.13.0",
|
|
41
41
|
"pretty-ms": "^10.0.0",
|
|
42
42
|
"real-world-css-libraries": "^1.0.8",
|
|
43
|
-
"vite": "^8.3.
|
|
43
|
+
"vite": "^8.3.5"
|
|
44
44
|
},
|
|
45
45
|
"author": "The Jared Wilcurt",
|
|
46
46
|
"homepage": "https://github.com/TheJaredWilcurt/csslop#readme",
|
|
@@ -57,11 +57,11 @@
|
|
|
57
57
|
"devEngines": {
|
|
58
58
|
"runtime": {
|
|
59
59
|
"name": "node",
|
|
60
|
-
"version": "26.12.
|
|
60
|
+
"version": "26.12.1"
|
|
61
61
|
},
|
|
62
62
|
"packageManager": {
|
|
63
63
|
"name": "npm",
|
|
64
|
-
"version": "12.2.
|
|
64
|
+
"version": "12.2.1"
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
}
|
|
@@ -182,7 +182,7 @@ function collapseBorderTrioWithPerEdgeOverrides (declarations, context) {
|
|
|
182
182
|
const borderValue = buildBorderShorthandValue(
|
|
183
183
|
widthComponents.length === 1 ? width : '',
|
|
184
184
|
styleComponents.length === 1 ? style : '',
|
|
185
|
-
colorComponents[0]
|
|
185
|
+
colorComponents.length === 1 ? colorComponents[0] : ''
|
|
186
186
|
) + importantSuffix;
|
|
187
187
|
const overrides = BORDER_TRIO_PROPERTIES.flatMap((property, index) => {
|
|
188
188
|
if (componentsByProperty[index].length === 1) {
|
package/src/rules/stringify.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { processDeclarations } from '../declarations/process.js';
|
|
6
6
|
import {
|
|
7
|
+
findMatchingParenthesis,
|
|
7
8
|
skipParenthesizedGroup,
|
|
8
9
|
skipQuotedString,
|
|
9
10
|
splitTopLevelCommaList,
|
|
@@ -74,7 +75,20 @@ const LAYER_STATEMENT_PATTERN = /^@layer [^{}();'"]*;$/;
|
|
|
74
75
|
*/
|
|
75
76
|
function removeRedundantLayerStatementSemicolon (ruleStrings) {
|
|
76
77
|
const lastIndex = ruleStrings.length - 1;
|
|
77
|
-
if (lastIndex < 0
|
|
78
|
+
if (lastIndex < 0) {
|
|
79
|
+
return ruleStrings;
|
|
80
|
+
}
|
|
81
|
+
const lastRule = ruleStrings[lastIndex];
|
|
82
|
+
const isTrailingLayerStatement = LAYER_STATEMENT_PATTERN.test(lastRule);
|
|
83
|
+
const isTrailingImportStatement = (
|
|
84
|
+
lastRule.endsWith(';') &&
|
|
85
|
+
(
|
|
86
|
+
lastRule.startsWith('@import ') ||
|
|
87
|
+
lastRule.startsWith('@import"') ||
|
|
88
|
+
lastRule.startsWith('@import\'')
|
|
89
|
+
)
|
|
90
|
+
);
|
|
91
|
+
if (!isTrailingLayerStatement && !isTrailingImportStatement) {
|
|
78
92
|
return ruleStrings;
|
|
79
93
|
}
|
|
80
94
|
const result = [...ruleStrings];
|
|
@@ -82,6 +96,47 @@ function removeRedundantLayerStatementSemicolon (ruleStrings) {
|
|
|
82
96
|
return result;
|
|
83
97
|
}
|
|
84
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Normalizes every `supports()` condition in an import prelude while leaving
|
|
101
|
+
* nested functions and quoted strings to the condition parser.
|
|
102
|
+
*
|
|
103
|
+
* @param {string} importStatement The import prelude being minified.
|
|
104
|
+
* @return {string} The import prelude with normalized conditions.
|
|
105
|
+
*/
|
|
106
|
+
function normalizeImportSupports (importStatement) {
|
|
107
|
+
let result = '';
|
|
108
|
+
let index = 0;
|
|
109
|
+
const normalizedStatement = importStatement.toLowerCase();
|
|
110
|
+
while (index < importStatement.length) {
|
|
111
|
+
let supportsIndex = -1;
|
|
112
|
+
let scanIndex = index;
|
|
113
|
+
while (scanIndex < importStatement.length) {
|
|
114
|
+
if (importStatement[scanIndex] === '"' || importStatement[scanIndex] === '\'') {
|
|
115
|
+
scanIndex = skipQuotedString(importStatement, scanIndex);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (normalizedStatement.startsWith('supports(', scanIndex)) {
|
|
119
|
+
supportsIndex = scanIndex;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
scanIndex++;
|
|
123
|
+
}
|
|
124
|
+
if (supportsIndex === -1) {
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
const openIndex = supportsIndex + 'supports'.length;
|
|
128
|
+
const closeIndex = findMatchingParenthesis(importStatement, openIndex);
|
|
129
|
+
if (closeIndex === -1) {
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
const condition = importStatement.slice(openIndex + 1, closeIndex);
|
|
133
|
+
result += importStatement.slice(index, openIndex + 1);
|
|
134
|
+
result += normalizeSupports(condition) + ')';
|
|
135
|
+
index = closeIndex + 1;
|
|
136
|
+
}
|
|
137
|
+
return result + importStatement.slice(index);
|
|
138
|
+
}
|
|
139
|
+
|
|
85
140
|
/**
|
|
86
141
|
* Recursively stringifies child rules into a concatenated minified CSS string.
|
|
87
142
|
*
|
|
@@ -550,13 +605,7 @@ function stringifyRule (rule, context) {
|
|
|
550
605
|
importStatement = importStatement.replace(/^(".*?"|'.*?') /, '$1');
|
|
551
606
|
// Remove space between closing paren and next at-rule condition keyword
|
|
552
607
|
importStatement = importStatement.replace(/\) ([a-zA-Z])/g, ')$1');
|
|
553
|
-
|
|
554
|
-
importStatement = importStatement.replace(
|
|
555
|
-
/supports\(([^()]*)\)/g,
|
|
556
|
-
(fullMatch, content) => {
|
|
557
|
-
return 'supports(' + content.replace(/\s*:\s*/g, ':') + ')';
|
|
558
|
-
}
|
|
559
|
-
);
|
|
608
|
+
importStatement = normalizeImportSupports(importStatement);
|
|
560
609
|
const startsWithQuote = importStatement.startsWith('"') || importStatement.startsWith('\'');
|
|
561
610
|
let importSeparator;
|
|
562
611
|
if (startsWithQuote) {
|
|
@@ -66,17 +66,29 @@ const MAXIMUM_NESTING_DEPTH = 32;
|
|
|
66
66
|
* length is held as the pixels it measures, since every length stating the
|
|
67
67
|
* same measurement then totals under the same unit.
|
|
68
68
|
*
|
|
69
|
-
* @param {number}
|
|
70
|
-
* @param {string}
|
|
71
|
-
* @
|
|
69
|
+
* @param {number} number The number the quantity is written from.
|
|
70
|
+
* @param {string} unit The unit the quantity is written with, or the empty string when it is a plain number.
|
|
71
|
+
* @param {boolean} preserveWrittenQuantity Whether to retain the original spelling for a standalone quantity.
|
|
72
|
+
* @return {Map} The unit totals the quantity states.
|
|
72
73
|
*/
|
|
73
|
-
function createUnitTotals (number, unit) {
|
|
74
|
+
function createUnitTotals (number, unit, preserveWrittenQuantity = false) {
|
|
74
75
|
const lowercasedUnit = unit.toLowerCase();
|
|
75
76
|
const pixels = convertAbsoluteLengthToPx(number, lowercasedUnit);
|
|
77
|
+
let totals;
|
|
76
78
|
if (pixels === null) {
|
|
77
|
-
|
|
79
|
+
totals = new Map([[lowercasedUnit, number]]);
|
|
80
|
+
} else {
|
|
81
|
+
totals = new Map([['px', pixels]]);
|
|
82
|
+
}
|
|
83
|
+
if (preserveWrittenQuantity) {
|
|
84
|
+
totals.writtenQuantity = {
|
|
85
|
+
number,
|
|
86
|
+
unit: lowercasedUnit,
|
|
87
|
+
canonicalUnit: pixels === null ? lowercasedUnit : 'px',
|
|
88
|
+
canonicalNumber: pixels === null ? number : pixels
|
|
89
|
+
};
|
|
78
90
|
}
|
|
79
|
-
return
|
|
91
|
+
return totals;
|
|
80
92
|
}
|
|
81
93
|
|
|
82
94
|
/**
|
|
@@ -162,6 +174,16 @@ function multiplyUnitTotals (left, right) {
|
|
|
162
174
|
if (isPlainNumber(left)) {
|
|
163
175
|
return scaleUnitTotals(right, left.get(UNITLESS));
|
|
164
176
|
}
|
|
177
|
+
const leftQuantity = readSingleQuantity(left);
|
|
178
|
+
const rightQuantity = readSingleQuantity(right);
|
|
179
|
+
if (leftQuantity && rightQuantity) {
|
|
180
|
+
if (leftQuantity.unit.startsWith('reciprocal:') && leftQuantity.unit.slice('reciprocal:'.length) === rightQuantity.unit) {
|
|
181
|
+
return createUnitTotals(leftQuantity.number * rightQuantity.number, UNITLESS);
|
|
182
|
+
}
|
|
183
|
+
if (rightQuantity.unit.startsWith('reciprocal:') && rightQuantity.unit.slice('reciprocal:'.length) === leftQuantity.unit) {
|
|
184
|
+
return createUnitTotals(leftQuantity.number * rightQuantity.number, UNITLESS);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
165
187
|
return null;
|
|
166
188
|
}
|
|
167
189
|
|
|
@@ -175,14 +197,28 @@ function multiplyUnitTotals (left, right) {
|
|
|
175
197
|
* @return {Map|null} The totals of the quotient, or null when the division cannot be worked out.
|
|
176
198
|
*/
|
|
177
199
|
function divideUnitTotals (left, right) {
|
|
178
|
-
if (
|
|
179
|
-
|
|
200
|
+
if (isPlainNumber(right)) {
|
|
201
|
+
const divisor = right.get(UNITLESS);
|
|
202
|
+
if (divisor === 0) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
return scaleUnitTotals(left, 1 / divisor);
|
|
180
206
|
}
|
|
181
|
-
const
|
|
182
|
-
|
|
207
|
+
const dividendQuantity = readSingleQuantity(left);
|
|
208
|
+
const divisorQuantity = readSingleQuantity(right);
|
|
209
|
+
if (!dividendQuantity || !divisorQuantity || divisorQuantity.number === 0) {
|
|
183
210
|
return null;
|
|
184
211
|
}
|
|
185
|
-
|
|
212
|
+
if (dividendQuantity.unit === divisorQuantity.unit) {
|
|
213
|
+
return createUnitTotals(dividendQuantity.number / divisorQuantity.number, UNITLESS);
|
|
214
|
+
}
|
|
215
|
+
if (dividendQuantity.unit === UNITLESS) {
|
|
216
|
+
return createUnitTotals(
|
|
217
|
+
dividendQuantity.number / divisorQuantity.number,
|
|
218
|
+
'reciprocal:' + divisorQuantity.unit
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
return null;
|
|
186
222
|
}
|
|
187
223
|
|
|
188
224
|
/**
|
|
@@ -478,7 +514,7 @@ function parseOperand (reader) {
|
|
|
478
514
|
}
|
|
479
515
|
if (token.type === 'number') {
|
|
480
516
|
reader.index++;
|
|
481
|
-
return createUnitTotals(token.number, token.unit);
|
|
517
|
+
return createUnitTotals(token.number, token.unit, true);
|
|
482
518
|
}
|
|
483
519
|
if (token.type === 'identifier') {
|
|
484
520
|
reader.index++;
|
|
@@ -661,7 +697,8 @@ function evaluateMinimum (argumentList) {
|
|
|
661
697
|
if (!comparable) {
|
|
662
698
|
return null;
|
|
663
699
|
}
|
|
664
|
-
|
|
700
|
+
const winningIndex = comparable.numbers.indexOf(Math.min(...comparable.numbers));
|
|
701
|
+
return argumentList[winningIndex].value;
|
|
665
702
|
}
|
|
666
703
|
|
|
667
704
|
/**
|
|
@@ -675,7 +712,8 @@ function evaluateMaximum (argumentList) {
|
|
|
675
712
|
if (!comparable) {
|
|
676
713
|
return null;
|
|
677
714
|
}
|
|
678
|
-
|
|
715
|
+
const winningIndex = comparable.numbers.indexOf(Math.max(...comparable.numbers));
|
|
716
|
+
return argumentList[winningIndex].value;
|
|
679
717
|
}
|
|
680
718
|
|
|
681
719
|
/**
|
|
@@ -1043,7 +1081,22 @@ function writeTermNumber (total) {
|
|
|
1043
1081
|
* @return {string|null} The value the calculation resolved to, or null when it cannot be written faithfully.
|
|
1044
1082
|
*/
|
|
1045
1083
|
function formatUnitTotals (totals) {
|
|
1084
|
+
const writtenQuantity = totals.writtenQuantity;
|
|
1085
|
+
if (
|
|
1086
|
+
writtenQuantity &&
|
|
1087
|
+
totals.size === 1 &&
|
|
1088
|
+
totals.has(writtenQuantity.canonicalUnit) &&
|
|
1089
|
+
totals.get(writtenQuantity.canonicalUnit) === writtenQuantity.canonicalNumber
|
|
1090
|
+
) {
|
|
1091
|
+
return formatResolvedNumber(writtenQuantity.number) + writtenQuantity.unit;
|
|
1092
|
+
}
|
|
1046
1093
|
const mergedTotals = mergeUnitsOfSameKind(totals);
|
|
1094
|
+
const hasUnrepresentableReciprocalUnit = [...mergedTotals.keys()].some((unit) => {
|
|
1095
|
+
return unit.startsWith('reciprocal:');
|
|
1096
|
+
});
|
|
1097
|
+
if (hasUnrepresentableReciprocalUnit) {
|
|
1098
|
+
return null;
|
|
1099
|
+
}
|
|
1047
1100
|
const outputTerms = collectOutputTerms(mergedTotals);
|
|
1048
1101
|
if (dropsPercentageBasis(mergedTotals, outputTerms)) {
|
|
1049
1102
|
return null;
|
package/src/value/math.js
CHANGED
|
@@ -453,6 +453,30 @@ const NON_NEGATIVE_PROPERTIES = new Set([
|
|
|
453
453
|
'width'
|
|
454
454
|
]);
|
|
455
455
|
|
|
456
|
+
/**
|
|
457
|
+
* Properties whose computed math values must be integers.
|
|
458
|
+
*
|
|
459
|
+
* @type {Set<string>}
|
|
460
|
+
*/
|
|
461
|
+
const INTEGER_VALUE_PROPERTIES = new Set([
|
|
462
|
+
'column-count',
|
|
463
|
+
'order',
|
|
464
|
+
'orphans',
|
|
465
|
+
'widows',
|
|
466
|
+
'z-index'
|
|
467
|
+
]);
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* The inclusive bounds that CSS applies to numeric property values after
|
|
471
|
+
* resolving a math expression.
|
|
472
|
+
*
|
|
473
|
+
* @type {Map<string, {minimum?: number, maximum?: number}>}
|
|
474
|
+
*/
|
|
475
|
+
const NUMERIC_PROPERTY_RANGES = new Map([
|
|
476
|
+
['column-count', { minimum: 1 }],
|
|
477
|
+
['opacity', { minimum: 0, maximum: 1 }]
|
|
478
|
+
]);
|
|
479
|
+
|
|
456
480
|
/**
|
|
457
481
|
* Matches a value written as a single negative number, with or without the
|
|
458
482
|
* unit or percent sign that follows its digits.
|
|
@@ -461,6 +485,14 @@ const NON_NEGATIVE_PROPERTIES = new Set([
|
|
|
461
485
|
*/
|
|
462
486
|
const NEGATIVE_NUMBER_VALUE = /^-(?:\d+|\d*\.\d+)(?:[a-z]+|%)?$/i;
|
|
463
487
|
|
|
488
|
+
/**
|
|
489
|
+
* Matches a resolved unitless number whose value can be rounded or clamped by
|
|
490
|
+
* a property's numeric range.
|
|
491
|
+
*
|
|
492
|
+
* @type {RegExp}
|
|
493
|
+
*/
|
|
494
|
+
const UNIT_LESS_NUMBER_VALUE = /^[+-]?(?:\d+|\d*\.\d+)$/;
|
|
495
|
+
|
|
464
496
|
/**
|
|
465
497
|
* Clamps what a math function resolved to into the range its property
|
|
466
498
|
* accepts. A negative length written out directly makes the declaration
|
|
@@ -475,11 +507,39 @@ const NEGATIVE_NUMBER_VALUE = /^-(?:\d+|\d*\.\d+)(?:[a-z]+|%)?$/i;
|
|
|
475
507
|
* @return {string} The resolved value, held inside the property's range.
|
|
476
508
|
*/
|
|
477
509
|
function clampResolvedValueToPropertyRange (resolvedValue, property) {
|
|
478
|
-
const
|
|
479
|
-
|
|
510
|
+
const normalizedProperty = String(property).toLowerCase();
|
|
511
|
+
const acceptsNegativeValues = !NON_NEGATIVE_PROPERTIES.has(normalizedProperty);
|
|
512
|
+
const hasPropertyRange = NUMERIC_PROPERTY_RANGES.has(normalizedProperty);
|
|
513
|
+
const range = NUMERIC_PROPERTY_RANGES.get(normalizedProperty) || {};
|
|
514
|
+
const isNegativeNonNegativeValue = !acceptsNegativeValues && NEGATIVE_NUMBER_VALUE.test(resolvedValue);
|
|
515
|
+
if (isNegativeNonNegativeValue) {
|
|
516
|
+
const isUnitlessNumber = UNIT_LESS_NUMBER_VALUE.test(resolvedValue);
|
|
517
|
+
if (!isUnitlessNumber) {
|
|
518
|
+
return formatResolvedNumber(range.minimum === undefined ? 0 : range.minimum);
|
|
519
|
+
}
|
|
520
|
+
if (!hasPropertyRange && !INTEGER_VALUE_PROPERTIES.has(normalizedProperty)) {
|
|
521
|
+
return '0';
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
if (!hasPropertyRange && !INTEGER_VALUE_PROPERTIES.has(normalizedProperty)) {
|
|
480
525
|
return resolvedValue;
|
|
481
526
|
}
|
|
482
|
-
|
|
527
|
+
if (!UNIT_LESS_NUMBER_VALUE.test(resolvedValue)) {
|
|
528
|
+
return resolvedValue;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
const shouldRoundToInteger = INTEGER_VALUE_PROPERTIES.has(normalizedProperty);
|
|
532
|
+
let numericValue = Number(resolvedValue);
|
|
533
|
+
if (shouldRoundToInteger) {
|
|
534
|
+
numericValue = Math.round(numericValue);
|
|
535
|
+
}
|
|
536
|
+
if (range.minimum !== undefined) {
|
|
537
|
+
numericValue = Math.max(range.minimum, numericValue);
|
|
538
|
+
}
|
|
539
|
+
if (range.maximum !== undefined) {
|
|
540
|
+
numericValue = Math.min(range.maximum, numericValue);
|
|
541
|
+
}
|
|
542
|
+
return formatResolvedNumber(numericValue);
|
|
483
543
|
}
|
|
484
544
|
|
|
485
545
|
/**
|
package/src/value/minify.js
CHANGED
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
import {
|
|
39
39
|
collapseShorthandParts,
|
|
40
40
|
convertAbsoluteLengthToPx,
|
|
41
|
+
formatCompactNumber,
|
|
41
42
|
formatResolvedNumber,
|
|
42
43
|
hasSubstitutedParts,
|
|
43
44
|
normalizeScaleComponent,
|
|
@@ -623,6 +624,40 @@ function isCssDigit (character) {
|
|
|
623
624
|
return character >= '0' && character <= '9';
|
|
624
625
|
}
|
|
625
626
|
|
|
627
|
+
/**
|
|
628
|
+
* Converts OKLCH lightness and chroma percentages when doing so is shorter,
|
|
629
|
+
* including the separator each spelling needs before the hue.
|
|
630
|
+
*
|
|
631
|
+
* @param {string} value The normalized arguments of an `oklch()` function.
|
|
632
|
+
* @return {string} The arguments with shorter percentage spellings.
|
|
633
|
+
*/
|
|
634
|
+
function minifyOklchPercentages (value) {
|
|
635
|
+
const slashIndex = value.indexOf('/');
|
|
636
|
+
const componentsText = slashIndex === -1 ? value : value.slice(0, slashIndex);
|
|
637
|
+
const alphaText = slashIndex === -1 ? '' : value.slice(slashIndex + 1);
|
|
638
|
+
const components = componentsText.trim().split(' ');
|
|
639
|
+
if (components.length !== 3) {
|
|
640
|
+
return value;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
let [lightness, chroma, hue] = components;
|
|
644
|
+
if (lightness.endsWith('%')) {
|
|
645
|
+
lightness = formatCompactNumber(Number.parseFloat(lightness) / 100);
|
|
646
|
+
}
|
|
647
|
+
if (chroma.endsWith('%')) {
|
|
648
|
+
const convertedChroma = formatCompactNumber(
|
|
649
|
+
Number.parseFloat(chroma) / 100 * OKLCH_CHROMA_PERCENT_REFERENCE
|
|
650
|
+
);
|
|
651
|
+
const convertedWithHueSeparator = convertedChroma.length + 1;
|
|
652
|
+
if (chroma.length < convertedWithHueSeparator) {
|
|
653
|
+
return [lightness, chroma + hue].join(' ') + (slashIndex === -1 ? '' : '/' + alphaText);
|
|
654
|
+
}
|
|
655
|
+
chroma = convertedChroma;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
return [lightness, chroma, hue].join(' ') + (slashIndex === -1 ? '' : '/' + alphaText);
|
|
659
|
+
}
|
|
660
|
+
|
|
626
661
|
/**
|
|
627
662
|
* Converts `oklch()` colors that fall inside the sRGB gamut to their hex
|
|
628
663
|
* equivalent when that is shorter. Out-of-gamut colors have no sRGB
|
|
@@ -747,6 +782,9 @@ function convertColorsToHex (val) {
|
|
|
747
782
|
return integer;
|
|
748
783
|
});
|
|
749
784
|
minified = compactNegativeColorChannelSpacing(func, minified);
|
|
785
|
+
if (func.toLowerCase() === 'oklch') {
|
|
786
|
+
minified = minifyOklchPercentages(minified);
|
|
787
|
+
}
|
|
750
788
|
return func + '(' + minified.trim() + ')';
|
|
751
789
|
});
|
|
752
790
|
|