Remove accidentally committed node_modules from root
- Delete node_modules directory that was accidentally committed - Add .gitignore to prevent future commits
This commit is contained in:
-1
@@ -1 +0,0 @@
|
|||||||
../tldts/bin/cli.js
|
|
||||||
-1075
File diff suppressed because it is too large
Load Diff
-21
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2024 asamuzaK (Kazz)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
-316
@@ -1,316 +0,0 @@
|
|||||||
# CSS color
|
|
||||||
|
|
||||||
[](https://github.com/asamuzaK/cssColor/actions/workflows/node.js.yml)
|
|
||||||
[](https://github.com/asamuzaK/cssColor/actions/workflows/github-code-scanning/codeql)
|
|
||||||
[](https://www.npmjs.com/package/@asamuzakjp/css-color)
|
|
||||||
|
|
||||||
Resolve and convert CSS colors.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```console
|
|
||||||
npm i @asamuzakjp/css-color
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
import { convert, resolve, utils } from '@asamuzakjp/css-color';
|
|
||||||
|
|
||||||
const resolvedValue = resolve(
|
|
||||||
'color-mix(in oklab, lch(67.5345 42.5 258.2), color(srgb 0 0.5 0))'
|
|
||||||
);
|
|
||||||
// 'oklab(0.620754 -0.0931934 -0.00374881)'
|
|
||||||
|
|
||||||
const convertedValue = covert.colorToHex('lab(46.2775% -47.5621 48.5837)');
|
|
||||||
// '#008000'
|
|
||||||
|
|
||||||
const result = utils.isColor('green');
|
|
||||||
// true
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
|
|
||||||
|
|
||||||
### resolve(color, opt)
|
|
||||||
|
|
||||||
resolves CSS color
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `color` **[string][133]** color value
|
|
||||||
- system colors are not supported
|
|
||||||
- `opt` **[object][135]?** options (optional, default `{}`)
|
|
||||||
- `opt.currentColor` **[string][133]?**
|
|
||||||
- color to use for `currentcolor` keyword
|
|
||||||
- if omitted, it will be treated as a missing color,
|
|
||||||
i.e. `rgb(none none none / none)`
|
|
||||||
- `opt.customProperty` **[object][135]?**
|
|
||||||
- custom properties
|
|
||||||
- pair of `--` prefixed property name as a key and it's value,
|
|
||||||
e.g.
|
|
||||||
```javascript
|
|
||||||
const opt = {
|
|
||||||
customProperty: {
|
|
||||||
'--some-color': '#008000',
|
|
||||||
'--some-length': '16px'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
- and/or `callback` function to get the value of the custom property,
|
|
||||||
e.g.
|
|
||||||
```javascript
|
|
||||||
const node = document.getElementById('foo');
|
|
||||||
const opt = {
|
|
||||||
customProperty: {
|
|
||||||
callback: node.style.getPropertyValue
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
- `opt.dimension` **[object][135]?**
|
|
||||||
- dimension, e.g. for converting relative length to pixels
|
|
||||||
- pair of unit as a key and number in pixels as it's value,
|
|
||||||
e.g. suppose `1em === 12px`, `1rem === 16px` and `100vw === 1024px`, then
|
|
||||||
```javascript
|
|
||||||
const opt = {
|
|
||||||
dimension: {
|
|
||||||
em: 12,
|
|
||||||
rem: 16,
|
|
||||||
vw: 10.24
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
- and/or `callback` function to get the value as a number in pixels,
|
|
||||||
e.g.
|
|
||||||
```javascript
|
|
||||||
const opt = {
|
|
||||||
dimension: {
|
|
||||||
callback: unit => {
|
|
||||||
switch (unit) {
|
|
||||||
case 'em':
|
|
||||||
return 12;
|
|
||||||
case 'rem':
|
|
||||||
return 16;
|
|
||||||
case 'vw':
|
|
||||||
return 10.24;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
- `opt.format` **[string][133]?**
|
|
||||||
- output format, one of below
|
|
||||||
- `computedValue` (default), [computed value][139] of the color
|
|
||||||
- `specifiedValue`, [specified value][140] of the color
|
|
||||||
- `hex`, hex color notation, i.e. `#rrggbb`
|
|
||||||
- `hexAlpha`, hex color notation with alpha channel, i.e. `#rrggbbaa`
|
|
||||||
|
|
||||||
Returns **[string][133]?** one of `rgba?()`, `#rrggbb(aa)?`, `color-name`, `color(color-space r g b / alpha)`, `color(color-space x y z / alpha)`, `(ok)?lab(l a b / alpha)`, `(ok)?lch(l c h / alpha)`, `'(empty-string)'`, `null`
|
|
||||||
|
|
||||||
- in `computedValue`, values are numbers, however `rgb()` values are integers
|
|
||||||
- in `specifiedValue`, returns `empty string` for unknown and/or invalid color
|
|
||||||
- in `hex`, returns `null` for `transparent`, and also returns `null` if any of `r`, `g`, `b`, `alpha` is not a number
|
|
||||||
- in `hexAlpha`, returns `#00000000` for `transparent`, however returns `null` if any of `r`, `g`, `b`, `alpha` is not a number
|
|
||||||
|
|
||||||
### convert
|
|
||||||
|
|
||||||
Contains various color conversion functions.
|
|
||||||
|
|
||||||
### convert.numberToHex(value)
|
|
||||||
|
|
||||||
convert number to hex string
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `value` **[number][134]** color value
|
|
||||||
|
|
||||||
Returns **[string][133]** hex string: 00..ff
|
|
||||||
|
|
||||||
### convert.colorToHex(value, opt)
|
|
||||||
|
|
||||||
convert color to hex
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `value` **[string][133]** color value
|
|
||||||
- `opt` **[object][135]?** options (optional, default `{}`)
|
|
||||||
- `opt.alpha` **[boolean][136]?** return in #rrggbbaa notation
|
|
||||||
- `opt.customProperty` **[object][135]?**
|
|
||||||
- custom properties, see `resolve()` function above
|
|
||||||
- `opt.dimension` **[object][135]?**
|
|
||||||
- dimension, see `resolve()` function above
|
|
||||||
|
|
||||||
Returns **[string][133]** #rrggbb(aa)?
|
|
||||||
|
|
||||||
### convert.colorToHsl(value, opt)
|
|
||||||
|
|
||||||
convert color to hsl
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `value` **[string][133]** color value
|
|
||||||
- `opt` **[object][135]?** options (optional, default `{}`)
|
|
||||||
- `opt.customProperty` **[object][135]?**
|
|
||||||
- custom properties, see `resolve()` function above
|
|
||||||
- `opt.dimension` **[object][135]?**
|
|
||||||
- dimension, see `resolve()` function above
|
|
||||||
|
|
||||||
Returns **[Array][137]<[number][134]>** \[h, s, l, alpha]
|
|
||||||
|
|
||||||
### convert.colorToHwb(value, opt)
|
|
||||||
|
|
||||||
convert color to hwb
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `value` **[string][133]** color value
|
|
||||||
- `opt` **[object][135]?** options (optional, default `{}`)
|
|
||||||
- `opt.customProperty` **[object][135]?**
|
|
||||||
- custom properties, see `resolve()` function above
|
|
||||||
- `opt.dimension` **[object][135]?**
|
|
||||||
- dimension, see `resolve()` function above
|
|
||||||
|
|
||||||
Returns **[Array][137]<[number][134]>** \[h, w, b, alpha]
|
|
||||||
|
|
||||||
### convert.colorToLab(value, opt)
|
|
||||||
|
|
||||||
convert color to lab
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `value` **[string][133]** color value
|
|
||||||
- `opt` **[object][135]?** options (optional, default `{}`)
|
|
||||||
- `opt.customProperty` **[object][135]?**
|
|
||||||
- custom properties, see `resolve()` function above
|
|
||||||
- `opt.dimension` **[object][135]?**
|
|
||||||
- dimension, see `resolve()` function above
|
|
||||||
|
|
||||||
Returns **[Array][137]<[number][134]>** \[l, a, b, alpha]
|
|
||||||
|
|
||||||
### convert.colorToLch(value, opt)
|
|
||||||
|
|
||||||
convert color to lch
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `value` **[string][133]** color value
|
|
||||||
- `opt` **[object][135]?** options (optional, default `{}`)
|
|
||||||
- `opt.customProperty` **[object][135]?**
|
|
||||||
- custom properties, see `resolve()` function above
|
|
||||||
- `opt.dimension` **[object][135]?**
|
|
||||||
- dimension, see `resolve()` function above
|
|
||||||
|
|
||||||
Returns **[Array][137]<[number][134]>** \[l, c, h, alpha]
|
|
||||||
|
|
||||||
### convert.colorToOklab(value, opt)
|
|
||||||
|
|
||||||
convert color to oklab
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `value` **[string][133]** color value
|
|
||||||
- `opt` **[object][135]?** options (optional, default `{}`)
|
|
||||||
- `opt.customProperty` **[object][135]?**
|
|
||||||
- custom properties, see `resolve()` function above
|
|
||||||
- `opt.dimension` **[object][135]?**
|
|
||||||
- dimension, see `resolve()` function above
|
|
||||||
|
|
||||||
Returns **[Array][137]<[number][134]>** \[l, a, b, alpha]
|
|
||||||
|
|
||||||
### convert.colorToOklch(value, opt)
|
|
||||||
|
|
||||||
convert color to oklch
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `value` **[string][133]** color value
|
|
||||||
- `opt` **[object][135]?** options (optional, default `{}`)
|
|
||||||
- `opt.customProperty` **[object][135]?**
|
|
||||||
- custom properties, see `resolve()` function above
|
|
||||||
- `opt.dimension` **[object][135]?**
|
|
||||||
- dimension, see `resolve()` function above
|
|
||||||
|
|
||||||
Returns **[Array][137]<[number][134]>** \[l, c, h, alpha]
|
|
||||||
|
|
||||||
### convert.colorToRgb(value, opt)
|
|
||||||
|
|
||||||
convert color to rgb
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `value` **[string][133]** color value
|
|
||||||
- `opt` **[object][135]?** options (optional, default `{}`)
|
|
||||||
- `opt.customProperty` **[object][135]?**
|
|
||||||
- custom properties, see `resolve()` function above
|
|
||||||
- `opt.dimension` **[object][135]?**
|
|
||||||
- dimension, see `resolve()` function above
|
|
||||||
|
|
||||||
Returns **[Array][137]<[number][134]>** \[r, g, b, alpha]
|
|
||||||
|
|
||||||
### convert.colorToXyz(value, opt)
|
|
||||||
|
|
||||||
convert color to xyz
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `value` **[string][133]** color value
|
|
||||||
- `opt` **[object][135]?** options (optional, default `{}`)
|
|
||||||
- `opt.customProperty` **[object][135]?**
|
|
||||||
- custom properties, see `resolve()` function above
|
|
||||||
- `opt.dimension` **[object][135]?**
|
|
||||||
- dimension, see `resolve()` function above
|
|
||||||
- `opt.d50` **[boolean][136]?** xyz in d50 white point
|
|
||||||
|
|
||||||
Returns **[Array][137]<[number][134]>** \[x, y, z, alpha]
|
|
||||||
|
|
||||||
### convert.colorToXyzD50(value, opt)
|
|
||||||
|
|
||||||
convert color to xyz-d50
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `value` **[string][133]** color value
|
|
||||||
- `opt` **[object][135]?** options (optional, default `{}`)
|
|
||||||
- `opt.customProperty` **[object][135]?**
|
|
||||||
- custom properties, see `resolve()` function above
|
|
||||||
- `opt.dimension` **[object][135]?**
|
|
||||||
- dimension, see `resolve()` function above
|
|
||||||
|
|
||||||
Returns **[Array][137]<[number][134]>** \[x, y, z, alpha]
|
|
||||||
|
|
||||||
### utils
|
|
||||||
|
|
||||||
Contains utility functions.
|
|
||||||
|
|
||||||
### utils.isColor(color)
|
|
||||||
|
|
||||||
is valid color type
|
|
||||||
|
|
||||||
#### Parameters
|
|
||||||
|
|
||||||
- `color` **[string][133]** color value
|
|
||||||
- system colors are not supported
|
|
||||||
|
|
||||||
Returns **[boolean][136]**
|
|
||||||
|
|
||||||
## Acknowledgments
|
|
||||||
|
|
||||||
The following resources have been of great help in the development of the CSS color.
|
|
||||||
|
|
||||||
- [csstools/postcss-plugins](https://github.com/csstools/postcss-plugins)
|
|
||||||
- [lru-cache](https://github.com/isaacs/node-lru-cache)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Copyright (c) 2024 [asamuzaK (Kazz)](https://github.com/asamuzaK/)
|
|
||||||
|
|
||||||
[133]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
|
|
||||||
[134]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
|
|
||||||
[135]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
|
|
||||||
[136]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
|
|
||||||
[137]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
|
|
||||||
[138]: https://w3c.github.io/csswg-drafts/css-color-4/#color-conversion-code
|
|
||||||
[139]: https://developer.mozilla.org/en-US/docs/Web/CSS/computed_value
|
|
||||||
[140]: https://developer.mozilla.org/en-US/docs/Web/CSS/specified_value
|
|
||||||
[141]: https://www.npmjs.com/package/@csstools/css-calc
|
|
||||||
-220
File diff suppressed because one or more lines are too long
-1
File diff suppressed because one or more lines are too long
-5484
File diff suppressed because it is too large
Load Diff
-1
File diff suppressed because one or more lines are too long
-109
@@ -1,109 +0,0 @@
|
|||||||
/**
|
|
||||||
* typedef
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @typedef Options - options
|
|
||||||
* @property [alpha] - enable alpha
|
|
||||||
* @property [colorSpace] - color space
|
|
||||||
* @property [currentColor] - color for currentcolor
|
|
||||||
* @property [customPropeerty] - custom properties
|
|
||||||
* @property [d50] - white point in d50
|
|
||||||
* @property [dimension] - dimension
|
|
||||||
* @property [format] - output format
|
|
||||||
* @property [key] - key
|
|
||||||
*/
|
|
||||||
interface Options {
|
|
||||||
alpha?: boolean;
|
|
||||||
colorSpace?: string;
|
|
||||||
currentColor?: string;
|
|
||||||
customProperty?: Record<string, string | ((K: string) => string)>;
|
|
||||||
d50?: boolean;
|
|
||||||
delimiter?: string | string[];
|
|
||||||
dimension?: Record<string, number | ((K: string) => number)>;
|
|
||||||
format?: string;
|
|
||||||
nullable?: boolean;
|
|
||||||
preserveComment?: boolean;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @type ColorChannels - color channels
|
|
||||||
*/
|
|
||||||
type ColorChannels = [x: number, y: number, z: number, alpha: number];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare const convert: {
|
|
||||||
colorToHex: (value: string, opt?: Options) => string | null;
|
|
||||||
colorToHsl: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToHwb: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToLab: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToLch: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToOklab: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToOklch: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToRgb: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToXyz: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToXyzD50: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
numberToHex: (value: number) => string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resolve
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resolve CSS color
|
|
||||||
* @param value
|
|
||||||
* - CSS color value
|
|
||||||
* - system colors are not supported
|
|
||||||
* @param [opt] - options
|
|
||||||
* @param [opt.currentColor]
|
|
||||||
* - color to use for `currentcolor` keyword
|
|
||||||
* - if omitted, it will be treated as a missing color
|
|
||||||
* i.e. `rgb(none none none / none)`
|
|
||||||
* @param [opt.customProperty]
|
|
||||||
* - custom properties
|
|
||||||
* - pair of `--` prefixed property name and value,
|
|
||||||
* e.g. `customProperty: { '--some-color': '#0000ff' }`
|
|
||||||
* - and/or `callback` function to get the value of the custom property,
|
|
||||||
* e.g. `customProperty: { callback: someDeclaration.getPropertyValue }`
|
|
||||||
* @param [opt.dimension]
|
|
||||||
* - dimension, convert relative length to pixels
|
|
||||||
* - pair of unit and it's value as a number in pixels,
|
|
||||||
* e.g. `dimension: { em: 12, rem: 16, vw: 10.26 }`
|
|
||||||
* - and/or `callback` function to get the value as a number in pixels,
|
|
||||||
* e.g. `dimension: { callback: convertUnitToPixel }`
|
|
||||||
* @param [opt.format]
|
|
||||||
* - output format, one of below
|
|
||||||
* - `computedValue` (default), [computed value][139] of the color
|
|
||||||
* - `specifiedValue`, [specified value][140] of the color
|
|
||||||
* - `hex`, hex color notation, i.e. `rrggbb`
|
|
||||||
* - `hexAlpha`, hex color notation with alpha channel, i.e. `#rrggbbaa`
|
|
||||||
* @returns
|
|
||||||
* - one of rgba?(), #rrggbb(aa)?, color-name, '(empty-string)',
|
|
||||||
* color(color-space r g b / alpha), color(color-space x y z / alpha),
|
|
||||||
* lab(l a b / alpha), lch(l c h / alpha), oklab(l a b / alpha),
|
|
||||||
* oklch(l c h / alpha), null
|
|
||||||
* - in `computedValue`, values are numbers, however `rgb()` values are
|
|
||||||
* integers
|
|
||||||
* - in `specifiedValue`, returns `empty string` for unknown and/or invalid
|
|
||||||
* color
|
|
||||||
* - in `hex`, returns `null` for `transparent`, and also returns `null` if
|
|
||||||
* any of `r`, `g`, `b`, `alpha` is not a number
|
|
||||||
* - in `hexAlpha`, returns `#00000000` for `transparent`,
|
|
||||||
* however returns `null` if any of `r`, `g`, `b`, `alpha` is not a number
|
|
||||||
*/
|
|
||||||
declare const resolve: (value: string, opt?: Options) => string | null;
|
|
||||||
|
|
||||||
declare const utils: {
|
|
||||||
cssCalc: (value: string, opt?: Options) => string;
|
|
||||||
cssVar: (value: string, opt?: Options) => string;
|
|
||||||
extractDashedIdent: (value: string) => string[];
|
|
||||||
isColor: (value: unknown, opt?: Options) => boolean;
|
|
||||||
isGradient: (value: string, opt?: Options) => boolean;
|
|
||||||
splitValue: (value: string, opt?: Options) => string[];
|
|
||||||
};
|
|
||||||
declare const isColor: (value: unknown, opt?: Options) => boolean;
|
|
||||||
declare const cssCalc: (value: string, opt?: Options) => string;
|
|
||||||
|
|
||||||
export { convert, cssCalc, isColor, resolve, utils };
|
|
||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
/*!
|
|
||||||
* CSS color - Resolve, parse, convert CSS color.
|
|
||||||
* @license MIT
|
|
||||||
* @copyright asamuzaK (Kazz)
|
|
||||||
* @see {@link https://github.com/asamuzaK/cssColor/blob/main/LICENSE}
|
|
||||||
*/
|
|
||||||
export { convert } from './js/convert.js';
|
|
||||||
export { resolve } from './js/resolve.js';
|
|
||||||
export declare const utils: {
|
|
||||||
cssCalc: (value: string, opt?: import('./js/typedef.js').Options) => string;
|
|
||||||
cssVar: (value: string, opt?: import('./js/typedef.js').Options) => string;
|
|
||||||
extractDashedIdent: (value: string) => string[];
|
|
||||||
isColor: (value: unknown, opt?: import('./js/typedef.js').Options) => boolean;
|
|
||||||
isGradient: (value: string, opt?: import('./js/typedef.js').Options) => boolean;
|
|
||||||
splitValue: (value: string, opt?: import('./js/typedef.js').Options) => string[];
|
|
||||||
};
|
|
||||||
export declare const isColor: (value: unknown, opt?: import('./js/typedef.js').Options) => boolean;
|
|
||||||
export declare const cssCalc: (value: string, opt?: import('./js/typedef.js').Options) => string;
|
|
||||||
-30
@@ -1,30 +0,0 @@
|
|||||||
import { cssCalc as cssCalc$1 } from "./js/css-calc.js";
|
|
||||||
import { isGradient } from "./js/css-gradient.js";
|
|
||||||
import { cssVar } from "./js/css-var.js";
|
|
||||||
import { splitValue, isColor as isColor$1, extractDashedIdent } from "./js/util.js";
|
|
||||||
import { convert } from "./js/convert.js";
|
|
||||||
import { resolve } from "./js/resolve.js";
|
|
||||||
/*!
|
|
||||||
* CSS color - Resolve, parse, convert CSS color.
|
|
||||||
* @license MIT
|
|
||||||
* @copyright asamuzaK (Kazz)
|
|
||||||
* @see {@link https://github.com/asamuzaK/cssColor/blob/main/LICENSE}
|
|
||||||
*/
|
|
||||||
const utils = {
|
|
||||||
cssCalc: cssCalc$1,
|
|
||||||
cssVar,
|
|
||||||
extractDashedIdent,
|
|
||||||
isColor: isColor$1,
|
|
||||||
isGradient,
|
|
||||||
splitValue
|
|
||||||
};
|
|
||||||
const isColor = utils.isColor;
|
|
||||||
const cssCalc = utils.cssCalc;
|
|
||||||
export {
|
|
||||||
convert,
|
|
||||||
cssCalc,
|
|
||||||
isColor,
|
|
||||||
resolve,
|
|
||||||
utils
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=index.js.map
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["/*!\n * CSS color - Resolve, parse, convert CSS color.\n * @license MIT\n * @copyright asamuzaK (Kazz)\n * @see {@link https://github.com/asamuzaK/cssColor/blob/main/LICENSE}\n */\n\nimport { cssCalc as csscalc } from './js/css-calc';\nimport { isGradient } from './js/css-gradient';\nimport { cssVar } from './js/css-var';\nimport { extractDashedIdent, isColor as iscolor, splitValue } from './js/util';\n\nexport { convert } from './js/convert';\nexport { resolve } from './js/resolve';\n/* utils */\nexport const utils = {\n cssCalc: csscalc,\n cssVar,\n extractDashedIdent,\n isColor: iscolor,\n isGradient,\n splitValue\n};\n/* TODO: remove later */\n/* alias */\nexport const isColor = utils.isColor;\nexport const cssCalc = utils.cssCalc;\n"],"names":["csscalc","iscolor"],"mappings":";;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAeO,MAAM,QAAQ;AAAA,EACnB,SAASA;AAAAA,EACT;AAAA,EACA;AAAA,EACA,SAASC;AAAAA,EACT;AAAA,EACA;AACF;AAGO,MAAM,UAAU,MAAM;AACtB,MAAM,UAAU,MAAM;"}
|
|
||||||
-44
@@ -1,44 +0,0 @@
|
|||||||
import { LRUCache } from 'lru-cache';
|
|
||||||
import { Options } from './typedef.js';
|
|
||||||
/**
|
|
||||||
* CacheItem
|
|
||||||
*/
|
|
||||||
export declare class CacheItem {
|
|
||||||
#private;
|
|
||||||
/**
|
|
||||||
* constructor
|
|
||||||
*/
|
|
||||||
constructor(item: unknown, isNull?: boolean);
|
|
||||||
get item(): unknown;
|
|
||||||
get isNull(): boolean;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* NullObject
|
|
||||||
*/
|
|
||||||
export declare class NullObject extends CacheItem {
|
|
||||||
/**
|
|
||||||
* constructor
|
|
||||||
*/
|
|
||||||
constructor();
|
|
||||||
}
|
|
||||||
export declare const lruCache: LRUCache<{}, {}, unknown>;
|
|
||||||
/**
|
|
||||||
* set cache
|
|
||||||
* @param key - cache key
|
|
||||||
* @param value - value to cache
|
|
||||||
* @returns void
|
|
||||||
*/
|
|
||||||
export declare const setCache: (key: string, value: unknown) => void;
|
|
||||||
/**
|
|
||||||
* get cache
|
|
||||||
* @param key - cache key
|
|
||||||
* @returns cached item or false otherwise
|
|
||||||
*/
|
|
||||||
export declare const getCache: (key: string) => CacheItem | boolean;
|
|
||||||
/**
|
|
||||||
* create cache key
|
|
||||||
* @param keyData - key data
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns cache key
|
|
||||||
*/
|
|
||||||
export declare const createCacheKey: (keyData: Record<string, string>, opt?: Options) => string;
|
|
||||||
-82
@@ -1,82 +0,0 @@
|
|||||||
var __typeError = (msg) => {
|
|
||||||
throw TypeError(msg);
|
|
||||||
};
|
|
||||||
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
||||||
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
||||||
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
||||||
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
||||||
var _isNull, _item;
|
|
||||||
import { LRUCache } from "lru-cache";
|
|
||||||
import { valueToJsonString } from "./util.js";
|
|
||||||
const MAX_CACHE = 4096;
|
|
||||||
class CacheItem {
|
|
||||||
/**
|
|
||||||
* constructor
|
|
||||||
*/
|
|
||||||
constructor(item, isNull = false) {
|
|
||||||
/* private */
|
|
||||||
__privateAdd(this, _isNull);
|
|
||||||
__privateAdd(this, _item);
|
|
||||||
__privateSet(this, _item, item);
|
|
||||||
__privateSet(this, _isNull, !!isNull);
|
|
||||||
}
|
|
||||||
get item() {
|
|
||||||
return __privateGet(this, _item);
|
|
||||||
}
|
|
||||||
get isNull() {
|
|
||||||
return __privateGet(this, _isNull);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_isNull = new WeakMap();
|
|
||||||
_item = new WeakMap();
|
|
||||||
class NullObject extends CacheItem {
|
|
||||||
/**
|
|
||||||
* constructor
|
|
||||||
*/
|
|
||||||
constructor() {
|
|
||||||
super(Symbol("null"), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const lruCache = new LRUCache({
|
|
||||||
max: MAX_CACHE
|
|
||||||
});
|
|
||||||
const setCache = (key, value) => {
|
|
||||||
if (key) {
|
|
||||||
if (value === null) {
|
|
||||||
lruCache.set(key, new NullObject());
|
|
||||||
} else if (value instanceof CacheItem) {
|
|
||||||
lruCache.set(key, value);
|
|
||||||
} else {
|
|
||||||
lruCache.set(key, new CacheItem(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const getCache = (key) => {
|
|
||||||
if (key && lruCache.has(key)) {
|
|
||||||
const item = lruCache.get(key);
|
|
||||||
if (item instanceof CacheItem) {
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
lruCache.delete(key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
const createCacheKey = (keyData, opt = {}) => {
|
|
||||||
const { customProperty = {}, dimension = {} } = opt;
|
|
||||||
let cacheKey = "";
|
|
||||||
if (keyData && Object.keys(keyData).length && typeof customProperty.callback !== "function" && typeof dimension.callback !== "function") {
|
|
||||||
keyData.opt = valueToJsonString(opt);
|
|
||||||
cacheKey = valueToJsonString(keyData);
|
|
||||||
}
|
|
||||||
return cacheKey;
|
|
||||||
};
|
|
||||||
export {
|
|
||||||
CacheItem,
|
|
||||||
NullObject,
|
|
||||||
createCacheKey,
|
|
||||||
getCache,
|
|
||||||
lruCache,
|
|
||||||
setCache
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=cache.js.map
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"cache.js","sources":["../../../src/js/cache.ts"],"sourcesContent":["/**\n * cache\n */\n\nimport { LRUCache } from 'lru-cache';\nimport { Options } from './typedef';\nimport { valueToJsonString } from './util';\n\n/* numeric constants */\nconst MAX_CACHE = 4096;\n\n/**\n * CacheItem\n */\nexport class CacheItem {\n /* private */\n #isNull: boolean;\n #item: unknown;\n\n /**\n * constructor\n */\n constructor(item: unknown, isNull: boolean = false) {\n this.#item = item;\n this.#isNull = !!isNull;\n }\n\n get item() {\n return this.#item;\n }\n\n get isNull() {\n return this.#isNull;\n }\n}\n\n/**\n * NullObject\n */\nexport class NullObject extends CacheItem {\n /**\n * constructor\n */\n constructor() {\n super(Symbol('null'), true);\n }\n}\n\n/*\n * lru cache\n */\nexport const lruCache = new LRUCache({\n max: MAX_CACHE\n});\n\n/**\n * set cache\n * @param key - cache key\n * @param value - value to cache\n * @returns void\n */\nexport const setCache = (key: string, value: unknown): void => {\n if (key) {\n if (value === null) {\n lruCache.set(key, new NullObject());\n } else if (value instanceof CacheItem) {\n lruCache.set(key, value);\n } else {\n lruCache.set(key, new CacheItem(value));\n }\n }\n};\n\n/**\n * get cache\n * @param key - cache key\n * @returns cached item or false otherwise\n */\nexport const getCache = (key: string): CacheItem | boolean => {\n if (key && lruCache.has(key)) {\n const item = lruCache.get(key);\n if (item instanceof CacheItem) {\n return item;\n }\n // delete unexpected cached item\n lruCache.delete(key);\n return false;\n }\n return false;\n};\n\n/**\n * create cache key\n * @param keyData - key data\n * @param [opt] - options\n * @returns cache key\n */\nexport const createCacheKey = (\n keyData: Record<string, string>,\n opt: Options = {}\n): string => {\n const { customProperty = {}, dimension = {} } = opt;\n let cacheKey = '';\n if (\n keyData &&\n Object.keys(keyData).length &&\n typeof customProperty.callback !== 'function' &&\n typeof dimension.callback !== 'function'\n ) {\n keyData.opt = valueToJsonString(opt);\n cacheKey = valueToJsonString(keyData);\n }\n return cacheKey;\n};\n"],"names":[],"mappings":";;;;;;;;;;AASA,MAAM,YAAY;AAKX,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA,EAQrB,YAAY,MAAe,SAAkB,OAAO;AANpD;AAAA;AACA;AAME,uBAAK,OAAQ;AACR,uBAAA,SAAU,CAAC,CAAC;AAAA,EAAA;AAAA,EAGnB,IAAI,OAAO;AACT,WAAO,mBAAK;AAAA,EAAA;AAAA,EAGd,IAAI,SAAS;AACX,WAAO,mBAAK;AAAA,EAAA;AAEhB;AAlBE;AACA;AAsBK,MAAM,mBAAmB,UAAU;AAAA;AAAA;AAAA;AAAA,EAIxC,cAAc;AACN,UAAA,OAAO,MAAM,GAAG,IAAI;AAAA,EAAA;AAE9B;AAKa,MAAA,WAAW,IAAI,SAAS;AAAA,EACnC,KAAK;AACP,CAAC;AAQY,MAAA,WAAW,CAAC,KAAa,UAAyB;AAC7D,MAAI,KAAK;AACP,QAAI,UAAU,MAAM;AAClB,eAAS,IAAI,KAAK,IAAI,WAAA,CAAY;AAAA,IAAA,WACzB,iBAAiB,WAAW;AAC5B,eAAA,IAAI,KAAK,KAAK;AAAA,IAAA,OAClB;AACL,eAAS,IAAI,KAAK,IAAI,UAAU,KAAK,CAAC;AAAA,IAAA;AAAA,EACxC;AAEJ;AAOa,MAAA,WAAW,CAAC,QAAqC;AAC5D,MAAI,OAAO,SAAS,IAAI,GAAG,GAAG;AACtB,UAAA,OAAO,SAAS,IAAI,GAAG;AAC7B,QAAI,gBAAgB,WAAW;AACtB,aAAA;AAAA,IAAA;AAGT,aAAS,OAAO,GAAG;AACZ,WAAA;AAAA,EAAA;AAEF,SAAA;AACT;AAQO,MAAM,iBAAiB,CAC5B,SACA,MAAe,OACJ;AACX,QAAM,EAAE,iBAAiB,CAAA,GAAI,YAAY,CAAA,EAAO,IAAA;AAChD,MAAI,WAAW;AACf,MACE,WACA,OAAO,KAAK,OAAO,EAAE,UACrB,OAAO,eAAe,aAAa,cACnC,OAAO,UAAU,aAAa,YAC9B;AACQ,YAAA,MAAM,kBAAkB,GAAG;AACnC,eAAW,kBAAkB,OAAO;AAAA,EAAA;AAE/B,SAAA;AACT;"}
|
|
||||||
-537
@@ -1,537 +0,0 @@
|
|||||||
import { NullObject } from './cache.js';
|
|
||||||
import { ColorChannels, Options, SpecifiedColorChannels } from './typedef.js';
|
|
||||||
/**
|
|
||||||
* @type TriColorChannels - color channels without alpha
|
|
||||||
*/
|
|
||||||
type TriColorChannels = [x: number, y: number, z: number];
|
|
||||||
/**
|
|
||||||
* @type ColorMatrix - color matrix
|
|
||||||
*/
|
|
||||||
type ColorMatrix = [
|
|
||||||
r1: TriColorChannels,
|
|
||||||
r2: TriColorChannels,
|
|
||||||
r3: TriColorChannels
|
|
||||||
];
|
|
||||||
/**
|
|
||||||
* named colors
|
|
||||||
*/
|
|
||||||
export declare const NAMED_COLORS: {
|
|
||||||
readonly aliceblue: [240, 248, 255];
|
|
||||||
readonly antiquewhite: [250, 235, 215];
|
|
||||||
readonly aqua: [0, 255, 255];
|
|
||||||
readonly aquamarine: [127, 255, 212];
|
|
||||||
readonly azure: [240, 255, 255];
|
|
||||||
readonly beige: [245, 245, 220];
|
|
||||||
readonly bisque: [255, 228, 196];
|
|
||||||
readonly black: [0, 0, 0];
|
|
||||||
readonly blanchedalmond: [255, 235, 205];
|
|
||||||
readonly blue: [0, 0, 255];
|
|
||||||
readonly blueviolet: [138, 43, 226];
|
|
||||||
readonly brown: [165, 42, 42];
|
|
||||||
readonly burlywood: [222, 184, 135];
|
|
||||||
readonly cadetblue: [95, 158, 160];
|
|
||||||
readonly chartreuse: [127, 255, 0];
|
|
||||||
readonly chocolate: [210, 105, 30];
|
|
||||||
readonly coral: [255, 127, 80];
|
|
||||||
readonly cornflowerblue: [100, 149, 237];
|
|
||||||
readonly cornsilk: [255, 248, 220];
|
|
||||||
readonly crimson: [220, 20, 60];
|
|
||||||
readonly cyan: [0, 255, 255];
|
|
||||||
readonly darkblue: [0, 0, 139];
|
|
||||||
readonly darkcyan: [0, 139, 139];
|
|
||||||
readonly darkgoldenrod: [184, 134, 11];
|
|
||||||
readonly darkgray: [169, 169, 169];
|
|
||||||
readonly darkgreen: [0, 100, 0];
|
|
||||||
readonly darkgrey: [169, 169, 169];
|
|
||||||
readonly darkkhaki: [189, 183, 107];
|
|
||||||
readonly darkmagenta: [139, 0, 139];
|
|
||||||
readonly darkolivegreen: [85, 107, 47];
|
|
||||||
readonly darkorange: [255, 140, 0];
|
|
||||||
readonly darkorchid: [153, 50, 204];
|
|
||||||
readonly darkred: [139, 0, 0];
|
|
||||||
readonly darksalmon: [233, 150, 122];
|
|
||||||
readonly darkseagreen: [143, 188, 143];
|
|
||||||
readonly darkslateblue: [72, 61, 139];
|
|
||||||
readonly darkslategray: [47, 79, 79];
|
|
||||||
readonly darkslategrey: [47, 79, 79];
|
|
||||||
readonly darkturquoise: [0, 206, 209];
|
|
||||||
readonly darkviolet: [148, 0, 211];
|
|
||||||
readonly deeppink: [255, 20, 147];
|
|
||||||
readonly deepskyblue: [0, 191, 255];
|
|
||||||
readonly dimgray: [105, 105, 105];
|
|
||||||
readonly dimgrey: [105, 105, 105];
|
|
||||||
readonly dodgerblue: [30, 144, 255];
|
|
||||||
readonly firebrick: [178, 34, 34];
|
|
||||||
readonly floralwhite: [255, 250, 240];
|
|
||||||
readonly forestgreen: [34, 139, 34];
|
|
||||||
readonly fuchsia: [255, 0, 255];
|
|
||||||
readonly gainsboro: [220, 220, 220];
|
|
||||||
readonly ghostwhite: [248, 248, 255];
|
|
||||||
readonly gold: [255, 215, 0];
|
|
||||||
readonly goldenrod: [218, 165, 32];
|
|
||||||
readonly gray: [128, 128, 128];
|
|
||||||
readonly green: [0, 128, 0];
|
|
||||||
readonly greenyellow: [173, 255, 47];
|
|
||||||
readonly grey: [128, 128, 128];
|
|
||||||
readonly honeydew: [240, 255, 240];
|
|
||||||
readonly hotpink: [255, 105, 180];
|
|
||||||
readonly indianred: [205, 92, 92];
|
|
||||||
readonly indigo: [75, 0, 130];
|
|
||||||
readonly ivory: [255, 255, 240];
|
|
||||||
readonly khaki: [240, 230, 140];
|
|
||||||
readonly lavender: [230, 230, 250];
|
|
||||||
readonly lavenderblush: [255, 240, 245];
|
|
||||||
readonly lawngreen: [124, 252, 0];
|
|
||||||
readonly lemonchiffon: [255, 250, 205];
|
|
||||||
readonly lightblue: [173, 216, 230];
|
|
||||||
readonly lightcoral: [240, 128, 128];
|
|
||||||
readonly lightcyan: [224, 255, 255];
|
|
||||||
readonly lightgoldenrodyellow: [250, 250, 210];
|
|
||||||
readonly lightgray: [211, 211, 211];
|
|
||||||
readonly lightgreen: [144, 238, 144];
|
|
||||||
readonly lightgrey: [211, 211, 211];
|
|
||||||
readonly lightpink: [255, 182, 193];
|
|
||||||
readonly lightsalmon: [255, 160, 122];
|
|
||||||
readonly lightseagreen: [32, 178, 170];
|
|
||||||
readonly lightskyblue: [135, 206, 250];
|
|
||||||
readonly lightslategray: [119, 136, 153];
|
|
||||||
readonly lightslategrey: [119, 136, 153];
|
|
||||||
readonly lightsteelblue: [176, 196, 222];
|
|
||||||
readonly lightyellow: [255, 255, 224];
|
|
||||||
readonly lime: [0, 255, 0];
|
|
||||||
readonly limegreen: [50, 205, 50];
|
|
||||||
readonly linen: [250, 240, 230];
|
|
||||||
readonly magenta: [255, 0, 255];
|
|
||||||
readonly maroon: [128, 0, 0];
|
|
||||||
readonly mediumaquamarine: [102, 205, 170];
|
|
||||||
readonly mediumblue: [0, 0, 205];
|
|
||||||
readonly mediumorchid: [186, 85, 211];
|
|
||||||
readonly mediumpurple: [147, 112, 219];
|
|
||||||
readonly mediumseagreen: [60, 179, 113];
|
|
||||||
readonly mediumslateblue: [123, 104, 238];
|
|
||||||
readonly mediumspringgreen: [0, 250, 154];
|
|
||||||
readonly mediumturquoise: [72, 209, 204];
|
|
||||||
readonly mediumvioletred: [199, 21, 133];
|
|
||||||
readonly midnightblue: [25, 25, 112];
|
|
||||||
readonly mintcream: [245, 255, 250];
|
|
||||||
readonly mistyrose: [255, 228, 225];
|
|
||||||
readonly moccasin: [255, 228, 181];
|
|
||||||
readonly navajowhite: [255, 222, 173];
|
|
||||||
readonly navy: [0, 0, 128];
|
|
||||||
readonly oldlace: [253, 245, 230];
|
|
||||||
readonly olive: [128, 128, 0];
|
|
||||||
readonly olivedrab: [107, 142, 35];
|
|
||||||
readonly orange: [255, 165, 0];
|
|
||||||
readonly orangered: [255, 69, 0];
|
|
||||||
readonly orchid: [218, 112, 214];
|
|
||||||
readonly palegoldenrod: [238, 232, 170];
|
|
||||||
readonly palegreen: [152, 251, 152];
|
|
||||||
readonly paleturquoise: [175, 238, 238];
|
|
||||||
readonly palevioletred: [219, 112, 147];
|
|
||||||
readonly papayawhip: [255, 239, 213];
|
|
||||||
readonly peachpuff: [255, 218, 185];
|
|
||||||
readonly peru: [205, 133, 63];
|
|
||||||
readonly pink: [255, 192, 203];
|
|
||||||
readonly plum: [221, 160, 221];
|
|
||||||
readonly powderblue: [176, 224, 230];
|
|
||||||
readonly purple: [128, 0, 128];
|
|
||||||
readonly rebeccapurple: [102, 51, 153];
|
|
||||||
readonly red: [255, 0, 0];
|
|
||||||
readonly rosybrown: [188, 143, 143];
|
|
||||||
readonly royalblue: [65, 105, 225];
|
|
||||||
readonly saddlebrown: [139, 69, 19];
|
|
||||||
readonly salmon: [250, 128, 114];
|
|
||||||
readonly sandybrown: [244, 164, 96];
|
|
||||||
readonly seagreen: [46, 139, 87];
|
|
||||||
readonly seashell: [255, 245, 238];
|
|
||||||
readonly sienna: [160, 82, 45];
|
|
||||||
readonly silver: [192, 192, 192];
|
|
||||||
readonly skyblue: [135, 206, 235];
|
|
||||||
readonly slateblue: [106, 90, 205];
|
|
||||||
readonly slategray: [112, 128, 144];
|
|
||||||
readonly slategrey: [112, 128, 144];
|
|
||||||
readonly snow: [255, 250, 250];
|
|
||||||
readonly springgreen: [0, 255, 127];
|
|
||||||
readonly steelblue: [70, 130, 180];
|
|
||||||
readonly tan: [210, 180, 140];
|
|
||||||
readonly teal: [0, 128, 128];
|
|
||||||
readonly thistle: [216, 191, 216];
|
|
||||||
readonly tomato: [255, 99, 71];
|
|
||||||
readonly turquoise: [64, 224, 208];
|
|
||||||
readonly violet: [238, 130, 238];
|
|
||||||
readonly wheat: [245, 222, 179];
|
|
||||||
readonly white: [255, 255, 255];
|
|
||||||
readonly whitesmoke: [245, 245, 245];
|
|
||||||
readonly yellow: [255, 255, 0];
|
|
||||||
readonly yellowgreen: [154, 205, 50];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* cache invalid color value
|
|
||||||
* @param key - cache key
|
|
||||||
* @param nullable - is nullable
|
|
||||||
* @returns cached value
|
|
||||||
*/
|
|
||||||
export declare const cacheInvalidColorValue: (cacheKey: string, format: string, nullable?: boolean) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
/**
|
|
||||||
* resolve invalid color value
|
|
||||||
* @param format - output format
|
|
||||||
* @param nullable - is nullable
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
export declare const resolveInvalidColorValue: (format: string, nullable?: boolean) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
/**
|
|
||||||
* validate color components
|
|
||||||
* @param arr - color components
|
|
||||||
* @param [opt] - options
|
|
||||||
* @param [opt.alpha] - alpha channel
|
|
||||||
* @param [opt.minLength] - min length
|
|
||||||
* @param [opt.maxLength] - max length
|
|
||||||
* @param [opt.minRange] - min range
|
|
||||||
* @param [opt.maxRange] - max range
|
|
||||||
* @param [opt.validateRange] - validate range
|
|
||||||
* @returns result - validated color components
|
|
||||||
*/
|
|
||||||
export declare const validateColorComponents: (arr: ColorChannels | TriColorChannels, opt?: {
|
|
||||||
alpha?: boolean;
|
|
||||||
minLength?: number;
|
|
||||||
maxLength?: number;
|
|
||||||
minRange?: number;
|
|
||||||
maxRange?: number;
|
|
||||||
validateRange?: boolean;
|
|
||||||
}) => ColorChannels | TriColorChannels;
|
|
||||||
/**
|
|
||||||
* transform matrix
|
|
||||||
* @param mtx - 3 * 3 matrix
|
|
||||||
* @param vct - vector
|
|
||||||
* @param [skip] - skip validate
|
|
||||||
* @returns TriColorChannels - [p1, p2, p3]
|
|
||||||
*/
|
|
||||||
export declare const transformMatrix: (mtx: ColorMatrix, vct: TriColorChannels, skip?: boolean) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* normalize color components
|
|
||||||
* @param colorA - color components [v1, v2, v3, v4]
|
|
||||||
* @param colorB - color components [v1, v2, v3, v4]
|
|
||||||
* @param [skip] - skip validate
|
|
||||||
* @returns result - [colorA, colorB]
|
|
||||||
*/
|
|
||||||
export declare const normalizeColorComponents: (colorA: [number | string, number | string, number | string, number | string], colorB: [number | string, number | string, number | string, number | string], skip?: boolean) => [ColorChannels, ColorChannels];
|
|
||||||
/**
|
|
||||||
* number to hex string
|
|
||||||
* @param value - numeric value
|
|
||||||
* @returns hex string
|
|
||||||
*/
|
|
||||||
export declare const numberToHexString: (value: number) => string;
|
|
||||||
/**
|
|
||||||
* angle to deg
|
|
||||||
* @param angle
|
|
||||||
* @returns deg: 0..360
|
|
||||||
*/
|
|
||||||
export declare const angleToDeg: (angle: string) => number;
|
|
||||||
/**
|
|
||||||
* parse alpha
|
|
||||||
* @param [alpha] - alpha value
|
|
||||||
* @returns alpha: 0..1
|
|
||||||
*/
|
|
||||||
export declare const parseAlpha: (alpha?: string) => number;
|
|
||||||
/**
|
|
||||||
* parse hex alpha
|
|
||||||
* @param value - alpha value in hex string
|
|
||||||
* @returns alpha: 0..1
|
|
||||||
*/
|
|
||||||
export declare const parseHexAlpha: (value: string) => number;
|
|
||||||
/**
|
|
||||||
* transform rgb to linear rgb
|
|
||||||
* @param rgb - [r, g, b] r|g|b: 0..255
|
|
||||||
* @param [skip] - skip validate
|
|
||||||
* @returns TriColorChannels - [r, g, b] r|g|b: 0..1
|
|
||||||
*/
|
|
||||||
export declare const transformRgbToLinearRgb: (rgb: TriColorChannels, skip?: boolean) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* transform rgb to xyz
|
|
||||||
* @param rgb - [r, g, b] r|g|b: 0..255
|
|
||||||
* @param [skip] - skip validate
|
|
||||||
* @returns TriColorChannels - [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare const transformRgbToXyz: (rgb: TriColorChannels, skip?: boolean) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* transform rgb to xyz-d50
|
|
||||||
* @param rgb - [r, g, b] r|g|b: 0..255 alpha: 0..1
|
|
||||||
* @returns TriColorChannels - [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare const transformRgbToXyzD50: (rgb: TriColorChannels) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* transform linear rgb to rgb
|
|
||||||
* @param rgb - [r, g, b] r|g|b: 0..1
|
|
||||||
* @param [round] - round result
|
|
||||||
* @returns TriColorChannels - [r, g, b] r|g|b: 0..255
|
|
||||||
*/
|
|
||||||
export declare const transformLinearRgbToRgb: (rgb: TriColorChannels, round?: boolean) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* transform xyz to rgb
|
|
||||||
* @param xyz - [x, y, z]
|
|
||||||
* @param [skip] - skip validate
|
|
||||||
* @returns TriColorChannels - [r, g, b] r|g|b: 0..255
|
|
||||||
*/
|
|
||||||
export declare const transformXyzToRgb: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* transform xyz to xyz-d50
|
|
||||||
* @param xyz - [x, y, z]
|
|
||||||
* @returns TriColorChannels - [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare const transformXyzToXyzD50: (xyz: TriColorChannels) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* transform xyz to hsl
|
|
||||||
* @param xyz - [x, y, z]
|
|
||||||
* @param [skip] - skip validate
|
|
||||||
* @returns TriColorChannels - [h, s, l]
|
|
||||||
*/
|
|
||||||
export declare const transformXyzToHsl: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* transform xyz to hwb
|
|
||||||
* @param xyz - [x, y, z]
|
|
||||||
* @param [skip] - skip validate
|
|
||||||
* @returns TriColorChannels - [h, w, b]
|
|
||||||
*/
|
|
||||||
export declare const transformXyzToHwb: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* transform xyz to oklab
|
|
||||||
* @param xyz - [x, y, z]
|
|
||||||
* @param [skip] - skip validate
|
|
||||||
* @returns TriColorChannels - [l, a, b]
|
|
||||||
*/
|
|
||||||
export declare const transformXyzToOklab: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* transform xyz to oklch
|
|
||||||
* @param xyz - [x, y, z]
|
|
||||||
* @param [skip] - skip validate
|
|
||||||
* @returns TriColorChannels - [l, c, h]
|
|
||||||
*/
|
|
||||||
export declare const transformXyzToOklch: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* transform xyz D50 to rgb
|
|
||||||
* @param xyz - [x, y, z]
|
|
||||||
* @param [skip] - skip validate
|
|
||||||
* @returns TriColorChannels - [r, g, b] r|g|b: 0..255
|
|
||||||
*/
|
|
||||||
export declare const transformXyzD50ToRgb: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* transform xyz-d50 to lab
|
|
||||||
* @param xyz - [x, y, z]
|
|
||||||
* @param [skip] - skip validate
|
|
||||||
* @returns TriColorChannels - [l, a, b]
|
|
||||||
*/
|
|
||||||
export declare const transformXyzD50ToLab: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* transform xyz-d50 to lch
|
|
||||||
* @param xyz - [x, y, z]
|
|
||||||
* @param [skip] - skip validate
|
|
||||||
* @returns TriColorChannels - [l, c, h]
|
|
||||||
*/
|
|
||||||
export declare const transformXyzD50ToLch: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
|
|
||||||
/**
|
|
||||||
* convert rgb to hex color
|
|
||||||
* @param rgb - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1
|
|
||||||
* @returns hex color
|
|
||||||
*/
|
|
||||||
export declare const convertRgbToHex: (rgb: ColorChannels) => string;
|
|
||||||
/**
|
|
||||||
* convert linear rgb to hex color
|
|
||||||
* @param rgb - [r, g, b, alpha] r|g|b|alpha: 0..1
|
|
||||||
* @param [skip] - skip validate
|
|
||||||
* @returns hex color
|
|
||||||
*/
|
|
||||||
export declare const convertLinearRgbToHex: (rgb: ColorChannels, skip?: boolean) => string;
|
|
||||||
/**
|
|
||||||
* convert xyz to hex color
|
|
||||||
* @param xyz - [x, y, z, alpha]
|
|
||||||
* @returns hex color
|
|
||||||
*/
|
|
||||||
export declare const convertXyzToHex: (xyz: ColorChannels) => string;
|
|
||||||
/**
|
|
||||||
* convert xyz D50 to hex color
|
|
||||||
* @param xyz - [x, y, z, alpha]
|
|
||||||
* @returns hex color
|
|
||||||
*/
|
|
||||||
export declare const convertXyzD50ToHex: (xyz: ColorChannels) => string;
|
|
||||||
/**
|
|
||||||
* convert hex color to rgb
|
|
||||||
* @param value - hex color value
|
|
||||||
* @returns ColorChannels - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1
|
|
||||||
*/
|
|
||||||
export declare const convertHexToRgb: (value: string) => ColorChannels;
|
|
||||||
/**
|
|
||||||
* convert hex color to linear rgb
|
|
||||||
* @param value - hex color value
|
|
||||||
* @returns ColorChannels - [r, g, b, alpha] r|g|b|alpha: 0..1
|
|
||||||
*/
|
|
||||||
export declare const convertHexToLinearRgb: (value: string) => ColorChannels;
|
|
||||||
/**
|
|
||||||
* convert hex color to xyz
|
|
||||||
* @param value - hex color value
|
|
||||||
* @returns ColorChannels - [x, y, z, alpha]
|
|
||||||
*/
|
|
||||||
export declare const convertHexToXyz: (value: string) => ColorChannels;
|
|
||||||
/**
|
|
||||||
* parse rgb()
|
|
||||||
* @param value - rgb color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject
|
|
||||||
*/
|
|
||||||
export declare const parseRgb: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
/**
|
|
||||||
* parse hsl()
|
|
||||||
* @param value - hsl color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject
|
|
||||||
*/
|
|
||||||
export declare const parseHsl: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
/**
|
|
||||||
* parse hwb()
|
|
||||||
* @param value - hwb color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', NullObject
|
|
||||||
*/
|
|
||||||
export declare const parseHwb: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
/**
|
|
||||||
* parse lab()
|
|
||||||
* @param value - lab color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed color
|
|
||||||
* - [xyz-d50, x, y, z, alpha], ['lab', l, a, b, alpha], '(empty)', NullObject
|
|
||||||
*/
|
|
||||||
export declare const parseLab: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
/**
|
|
||||||
* parse lch()
|
|
||||||
* @param value - lch color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed color
|
|
||||||
* - ['xyz-d50', x, y, z, alpha], ['lch', l, c, h, alpha]
|
|
||||||
* - '(empty)', NullObject
|
|
||||||
*/
|
|
||||||
export declare const parseLch: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
/**
|
|
||||||
* parse oklab()
|
|
||||||
* @param value - oklab color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed color
|
|
||||||
* - ['xyz-d65', x, y, z, alpha], ['oklab', l, a, b, alpha]
|
|
||||||
* - '(empty)', NullObject
|
|
||||||
*/
|
|
||||||
export declare const parseOklab: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
/**
|
|
||||||
* parse oklch()
|
|
||||||
* @param value - oklch color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed color
|
|
||||||
* - ['xyz-d65', x, y, z, alpha], ['oklch', l, c, h, alpha]
|
|
||||||
* - '(empty)', NullObject
|
|
||||||
*/
|
|
||||||
export declare const parseOklch: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
/**
|
|
||||||
* parse color()
|
|
||||||
* @param value - color function value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed color
|
|
||||||
* - ['xyz-(d50|d65)', x, y, z, alpha], [cs, r, g, b, alpha]
|
|
||||||
* - '(empty)', NullObject
|
|
||||||
*/
|
|
||||||
export declare const parseColorFunc: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
/**
|
|
||||||
* parse color value
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed color
|
|
||||||
* - ['xyz-(d50|d65)', x, y, z, alpha], ['rgb', r, g, b, alpha]
|
|
||||||
* - value, '(empty)', NullObject
|
|
||||||
*/
|
|
||||||
export declare const parseColorValue: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
/**
|
|
||||||
* resolve color value
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved color
|
|
||||||
* - [cs, v1, v2, v3, alpha], value, '(empty)', NullObject
|
|
||||||
*/
|
|
||||||
export declare const resolveColorValue: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
/**
|
|
||||||
* resolve color()
|
|
||||||
* @param value - color function value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved color - [cs, v1, v2, v3, alpha], '(empty)', NullObject
|
|
||||||
*/
|
|
||||||
export declare const resolveColorFunc: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
/**
|
|
||||||
* convert color value to linear rgb
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels | NullObject - [r, g, b, alpha] r|g|b|alpha: 0..1
|
|
||||||
*/
|
|
||||||
export declare const convertColorToLinearRgb: (value: string, opt?: {
|
|
||||||
colorSpace?: string;
|
|
||||||
format?: string;
|
|
||||||
}) => ColorChannels | NullObject;
|
|
||||||
/**
|
|
||||||
* convert color value to rgb
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels | NullObject
|
|
||||||
* - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1
|
|
||||||
*/
|
|
||||||
export declare const convertColorToRgb: (value: string, opt?: Options) => ColorChannels | NullObject;
|
|
||||||
/**
|
|
||||||
* convert color value to xyz
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels | NullObject - [x, y, z, alpha]
|
|
||||||
*/
|
|
||||||
export declare const convertColorToXyz: (value: string, opt?: Options) => ColorChannels | NullObject;
|
|
||||||
/**
|
|
||||||
* convert color value to hsl
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels | NullObject - [h, s, l, alpha], hue may be powerless
|
|
||||||
*/
|
|
||||||
export declare const convertColorToHsl: (value: string, opt?: Options) => ColorChannels | [number | string, number, number, number] | NullObject;
|
|
||||||
/**
|
|
||||||
* convert color value to hwb
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels | NullObject - [h, w, b, alpha], hue may be powerless
|
|
||||||
*/
|
|
||||||
export declare const convertColorToHwb: (value: string, opt?: Options) => ColorChannels | [number | string, number, number, number] | NullObject;
|
|
||||||
/**
|
|
||||||
* convert color value to lab
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels | NullObject - [l, a, b, alpha]
|
|
||||||
*/
|
|
||||||
export declare const convertColorToLab: (value: string, opt?: Options) => ColorChannels | NullObject;
|
|
||||||
/**
|
|
||||||
* convert color value to lch
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels | NullObject - [l, c, h, alpha], hue may be powerless
|
|
||||||
*/
|
|
||||||
export declare const convertColorToLch: (value: string, opt?: Options) => ColorChannels | [number, number, number | string, number] | NullObject;
|
|
||||||
/**
|
|
||||||
* convert color value to oklab
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels | NullObject - [l, a, b, alpha]
|
|
||||||
*/
|
|
||||||
export declare const convertColorToOklab: (value: string, opt?: Options) => ColorChannels | NullObject;
|
|
||||||
/**
|
|
||||||
* convert color value to oklch
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels | NullObject - [l, c, h, alpha], hue may be powerless
|
|
||||||
*/
|
|
||||||
export declare const convertColorToOklch: (value: string, opt?: Options) => ColorChannels | [number, number, number | string, number] | NullObject;
|
|
||||||
/**
|
|
||||||
* resolve color-mix()
|
|
||||||
* @param value - color-mix color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved color - [cs, v1, v2, v3, alpha], '(empty)'
|
|
||||||
*/
|
|
||||||
export declare const resolveColorMix: (value: string, opt?: Options) => SpecifiedColorChannels | string | NullObject;
|
|
||||||
export {};
|
|
||||||
-2792
File diff suppressed because it is too large
Load Diff
-1
File diff suppressed because one or more lines are too long
-21
@@ -1,21 +0,0 @@
|
|||||||
/**
|
|
||||||
* common
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* get type
|
|
||||||
* @param o - object to check
|
|
||||||
* @returns type of object
|
|
||||||
*/
|
|
||||||
export declare const getType: (o: unknown) => string;
|
|
||||||
/**
|
|
||||||
* is string
|
|
||||||
* @param o - object to check
|
|
||||||
* @returns result
|
|
||||||
*/
|
|
||||||
export declare const isString: (o: unknown) => o is string;
|
|
||||||
/**
|
|
||||||
* is string or number
|
|
||||||
* @param o - object to check
|
|
||||||
* @returns result
|
|
||||||
*/
|
|
||||||
export declare const isStringOrNumber: (o: unknown) => boolean;
|
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
const isString = (o) => typeof o === "string" || o instanceof String;
|
|
||||||
const isStringOrNumber = (o) => isString(o) || typeof o === "number";
|
|
||||||
export {
|
|
||||||
isString,
|
|
||||||
isStringOrNumber
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=common.js.map
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"common.js","sources":["../../../src/js/common.ts"],"sourcesContent":["/**\n * common\n */\n\n/* numeric constants */\nconst TYPE_FROM = 8;\nconst TYPE_TO = -1;\n\n/**\n * get type\n * @param o - object to check\n * @returns type of object\n */\nexport const getType = (o: unknown): string =>\n Object.prototype.toString.call(o).slice(TYPE_FROM, TYPE_TO);\n\n/**\n * is string\n * @param o - object to check\n * @returns result\n */\nexport const isString = (o: unknown): o is string =>\n typeof o === 'string' || o instanceof String;\n\n/**\n * is string or number\n * @param o - object to check\n * @returns result\n */\nexport const isStringOrNumber = (o: unknown): boolean =>\n isString(o) || typeof o === 'number';\n"],"names":[],"mappings":"AAqBO,MAAM,WAAW,CAAC,MACvB,OAAO,MAAM,YAAY,aAAa;AAOjC,MAAM,mBAAmB,CAAC,MAC/B,SAAS,CAAC,KAAK,OAAO,MAAM;"}
|
|
||||||
-41
File diff suppressed because one or more lines are too long
-97
@@ -1,97 +0,0 @@
|
|||||||
const _DIGIT = "(?:0|[1-9]\\d*)";
|
|
||||||
const _COMPARE = "clamp|max|min";
|
|
||||||
const _EXPO = "exp|hypot|log|pow|sqrt";
|
|
||||||
const _SIGN = "abs|sign";
|
|
||||||
const _STEP = "mod|rem|round";
|
|
||||||
const _TRIG = "a?(?:cos|sin|tan)|atan2";
|
|
||||||
const _MATH = `${_COMPARE}|${_EXPO}|${_SIGN}|${_STEP}|${_TRIG}`;
|
|
||||||
const _CALC = `calc|${_MATH}`;
|
|
||||||
const _VAR = `var|${_CALC}`;
|
|
||||||
const ANGLE = "deg|g?rad|turn";
|
|
||||||
const LENGTH = "[cm]m|[dls]?v(?:[bhiw]|max|min)|in|p[ctx]|q|r?(?:[cl]h|cap|e[mx]|ic)";
|
|
||||||
const NUM = `[+-]?(?:${_DIGIT}(?:\\.\\d*)?|\\.\\d+)(?:e-?${_DIGIT})?`;
|
|
||||||
const NUM_POSITIVE = `\\+?(?:${_DIGIT}(?:\\.\\d*)?|\\.\\d+)(?:e-?${_DIGIT})?`;
|
|
||||||
const NONE = "none";
|
|
||||||
const PCT = `${NUM}%`;
|
|
||||||
const SYN_FN_CALC = `^(?:${_CALC})\\(|(?<=[*\\/\\s\\(])(?:${_CALC})\\(`;
|
|
||||||
const SYN_FN_MATH_START = `^(?:${_MATH})\\($`;
|
|
||||||
const SYN_FN_VAR = "^var\\(|(?<=[*\\/\\s\\(])var\\(";
|
|
||||||
const SYN_FN_VAR_START = `^(?:${_VAR})\\(`;
|
|
||||||
const _ALPHA = `(?:\\s*\\/\\s*(?:${NUM}|${PCT}|${NONE}))?`;
|
|
||||||
const _ALPHA_LV3 = `(?:\\s*,\\s*(?:${NUM}|${PCT}))?`;
|
|
||||||
const _COLOR_FUNC = "(?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?";
|
|
||||||
const _COLOR_KEY = "[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}";
|
|
||||||
const _CS_HUE = "(?:ok)?lch|hsl|hwb";
|
|
||||||
const _CS_HUE_ARC = "(?:de|in)creasing|longer|shorter";
|
|
||||||
const _NUM_ANGLE = `${NUM}(?:${ANGLE})?`;
|
|
||||||
const _NUM_ANGLE_NONE = `(?:${NUM}(?:${ANGLE})?|${NONE})`;
|
|
||||||
const _NUM_PCT_NONE = `(?:${NUM}|${PCT}|${NONE})`;
|
|
||||||
const CS_HUE = `(?:${_CS_HUE})(?:\\s(?:${_CS_HUE_ARC})\\shue)?`;
|
|
||||||
const CS_HUE_CAPT = `(${_CS_HUE})(?:\\s(${_CS_HUE_ARC})\\shue)?`;
|
|
||||||
const CS_LAB = "(?:ok)?lab";
|
|
||||||
const CS_LCH = "(?:ok)?lch";
|
|
||||||
const CS_SRGB = "srgb(?:-linear)?";
|
|
||||||
const CS_RGB = `(?:a98|prophoto)-rgb|display-p3|rec2020|${CS_SRGB}`;
|
|
||||||
const CS_XYZ = "xyz(?:-d(?:50|65))?";
|
|
||||||
const CS_RECT = `${CS_LAB}|${CS_RGB}|${CS_XYZ}`;
|
|
||||||
const CS_MIX = `${CS_HUE}|${CS_RECT}`;
|
|
||||||
const FN_COLOR = "color(";
|
|
||||||
const FN_MIX = "color-mix(";
|
|
||||||
const FN_REL = `(?:${_COLOR_FUNC})\\(\\s*from\\s+`;
|
|
||||||
const FN_REL_CAPT = `(${_COLOR_FUNC})\\(\\s*from\\s+`;
|
|
||||||
const FN_VAR = "var(";
|
|
||||||
const SYN_FN_COLOR = `(?:${CS_RGB}|${CS_XYZ})(?:\\s+${_NUM_PCT_NONE}){3}${_ALPHA}`;
|
|
||||||
const SYN_FN_REL = `^${FN_REL}|(?<=[\\s])${FN_REL}`;
|
|
||||||
const SYN_HSL = `${_NUM_ANGLE_NONE}(?:\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`;
|
|
||||||
const SYN_HSL_LV3 = `${_NUM_ANGLE}(?:\\s*,\\s*${PCT}){2}${_ALPHA_LV3}`;
|
|
||||||
const SYN_LCH = `(?:${_NUM_PCT_NONE}\\s+){2}${_NUM_ANGLE_NONE}${_ALPHA}`;
|
|
||||||
const SYN_MOD = `${_NUM_PCT_NONE}(?:\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`;
|
|
||||||
const SYN_RGB_LV3 = `(?:${NUM}(?:\\s*,\\s*${NUM}){2}|${PCT}(?:\\s*,\\s*${PCT}){2})${_ALPHA_LV3}`;
|
|
||||||
const SYN_COLOR_TYPE = `${_COLOR_KEY}|hsla?\\(\\s*${SYN_HSL_LV3}\\s*\\)|rgba?\\(\\s*${SYN_RGB_LV3}\\s*\\)|(?:hsla?|hwb)\\(\\s*${SYN_HSL}\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*${SYN_MOD}\\s*\\)|(?:ok)?lch\\(\\s*${SYN_LCH}\\s*\\)|color\\(\\s*${SYN_FN_COLOR}\\s*\\)`;
|
|
||||||
const SYN_MIX_PART = `(?:${SYN_COLOR_TYPE})(?:\\s+${PCT})?`;
|
|
||||||
const SYN_MIX = `color-mix\\(\\s*in\\s+(?:${CS_MIX})\\s*,\\s*${SYN_MIX_PART}\\s*,\\s*${SYN_MIX_PART}\\s*\\)`;
|
|
||||||
const SYN_MIX_CAPT = `color-mix\\(\\s*in\\s+(${CS_MIX})\\s*,\\s*(${SYN_MIX_PART})\\s*,\\s*(${SYN_MIX_PART})\\s*\\)`;
|
|
||||||
const VAL_COMP = "computedValue";
|
|
||||||
const VAL_MIX = "mixValue";
|
|
||||||
const VAL_SPEC = "specifiedValue";
|
|
||||||
export {
|
|
||||||
ANGLE,
|
|
||||||
CS_HUE,
|
|
||||||
CS_HUE_CAPT,
|
|
||||||
CS_LAB,
|
|
||||||
CS_LCH,
|
|
||||||
CS_MIX,
|
|
||||||
CS_RECT,
|
|
||||||
CS_RGB,
|
|
||||||
CS_SRGB,
|
|
||||||
CS_XYZ,
|
|
||||||
FN_COLOR,
|
|
||||||
FN_MIX,
|
|
||||||
FN_REL,
|
|
||||||
FN_REL_CAPT,
|
|
||||||
FN_VAR,
|
|
||||||
LENGTH,
|
|
||||||
NONE,
|
|
||||||
NUM,
|
|
||||||
NUM_POSITIVE,
|
|
||||||
PCT,
|
|
||||||
SYN_COLOR_TYPE,
|
|
||||||
SYN_FN_CALC,
|
|
||||||
SYN_FN_COLOR,
|
|
||||||
SYN_FN_MATH_START,
|
|
||||||
SYN_FN_REL,
|
|
||||||
SYN_FN_VAR,
|
|
||||||
SYN_FN_VAR_START,
|
|
||||||
SYN_HSL,
|
|
||||||
SYN_HSL_LV3,
|
|
||||||
SYN_LCH,
|
|
||||||
SYN_MIX,
|
|
||||||
SYN_MIX_CAPT,
|
|
||||||
SYN_MIX_PART,
|
|
||||||
SYN_MOD,
|
|
||||||
SYN_RGB_LV3,
|
|
||||||
VAL_COMP,
|
|
||||||
VAL_MIX,
|
|
||||||
VAL_SPEC
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=constant.js.map
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-99
@@ -1,99 +0,0 @@
|
|||||||
import { NullObject } from './cache.js';
|
|
||||||
import { ColorChannels, Options } from './typedef.js';
|
|
||||||
/**
|
|
||||||
* pre process
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns value
|
|
||||||
*/
|
|
||||||
export declare const preProcess: (value: string, opt?: Options) => string | NullObject;
|
|
||||||
/**
|
|
||||||
* convert number to hex string
|
|
||||||
* @param value - numeric value
|
|
||||||
* @returns hex string: 00..ff
|
|
||||||
*/
|
|
||||||
export declare const numberToHex: (value: number) => string;
|
|
||||||
/**
|
|
||||||
* convert color to hex
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @param [opt.alpha] - enable alpha channel
|
|
||||||
* @returns #rrggbb | #rrggbbaa | null
|
|
||||||
*/
|
|
||||||
export declare const colorToHex: (value: string, opt?: Options) => string | null;
|
|
||||||
/**
|
|
||||||
* convert color to hsl
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [h, s, l, alpha]
|
|
||||||
*/
|
|
||||||
export declare const colorToHsl: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
/**
|
|
||||||
* convert color to hwb
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [h, w, b, alpha]
|
|
||||||
*/
|
|
||||||
export declare const colorToHwb: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
/**
|
|
||||||
* convert color to lab
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [l, a, b, alpha]
|
|
||||||
*/
|
|
||||||
export declare const colorToLab: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
/**
|
|
||||||
* convert color to lch
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [l, c, h, alpha]
|
|
||||||
*/
|
|
||||||
export declare const colorToLch: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
/**
|
|
||||||
* convert color to oklab
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [l, a, b, alpha]
|
|
||||||
*/
|
|
||||||
export declare const colorToOklab: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
/**
|
|
||||||
* convert color to oklch
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [l, c, h, alpha]
|
|
||||||
*/
|
|
||||||
export declare const colorToOklch: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
/**
|
|
||||||
* convert color to rgb
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [r, g, b, alpha]
|
|
||||||
*/
|
|
||||||
export declare const colorToRgb: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
/**
|
|
||||||
* convert color to xyz
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [x, y, z, alpha]
|
|
||||||
*/
|
|
||||||
export declare const colorToXyz: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
/**
|
|
||||||
* convert color to xyz-d50
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [x, y, z, alpha]
|
|
||||||
*/
|
|
||||||
export declare const colorToXyzD50: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
export declare const convert: {
|
|
||||||
colorToHex: (value: string, opt?: Options) => string | null;
|
|
||||||
colorToHsl: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToHwb: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToLab: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToLch: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToOklab: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToOklch: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToRgb: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToXyz: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
colorToXyzD50: (value: string, opt?: Options) => ColorChannels;
|
|
||||||
numberToHex: (value: number) => string;
|
|
||||||
};
|
|
||||||
-361
@@ -1,361 +0,0 @@
|
|||||||
import { NullObject, createCacheKey, getCache, CacheItem, setCache } from "./cache.js";
|
|
||||||
import { numberToHexString, parseColorFunc, parseColorValue, convertColorToRgb, convertColorToOklch, convertColorToOklab, convertColorToLch, convertColorToLab, convertColorToHwb, convertColorToHsl } from "./color.js";
|
|
||||||
import { isString } from "./common.js";
|
|
||||||
import { cssCalc } from "./css-calc.js";
|
|
||||||
import { resolveVar } from "./css-var.js";
|
|
||||||
import { resolveRelativeColor } from "./relative-color.js";
|
|
||||||
import { resolveColor } from "./resolve.js";
|
|
||||||
import { VAL_COMP, SYN_FN_VAR, SYN_FN_REL, SYN_FN_CALC } from "./constant.js";
|
|
||||||
const NAMESPACE = "convert";
|
|
||||||
const REG_FN_CALC = new RegExp(SYN_FN_CALC);
|
|
||||||
const REG_FN_REL = new RegExp(SYN_FN_REL);
|
|
||||||
const REG_FN_VAR = new RegExp(SYN_FN_VAR);
|
|
||||||
const preProcess = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.trim();
|
|
||||||
if (!value) {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "preProcess",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return cachedResult;
|
|
||||||
}
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
if (REG_FN_VAR.test(value)) {
|
|
||||||
const resolvedValue = resolveVar(value, opt);
|
|
||||||
if (isString(resolvedValue)) {
|
|
||||||
value = resolvedValue;
|
|
||||||
} else {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (REG_FN_REL.test(value)) {
|
|
||||||
const resolvedValue = resolveRelativeColor(value, opt);
|
|
||||||
if (isString(resolvedValue)) {
|
|
||||||
value = resolvedValue;
|
|
||||||
} else {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
} else if (REG_FN_CALC.test(value)) {
|
|
||||||
value = cssCalc(value, opt);
|
|
||||||
}
|
|
||||||
if (value.startsWith("color-mix")) {
|
|
||||||
const clonedOpt = structuredClone(opt);
|
|
||||||
clonedOpt.format = VAL_COMP;
|
|
||||||
clonedOpt.nullable = true;
|
|
||||||
const resolvedValue = resolveColor(value, clonedOpt);
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
setCache(cacheKey, value);
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
const numberToHex = (value) => {
|
|
||||||
const hex = numberToHexString(value);
|
|
||||||
return hex;
|
|
||||||
};
|
|
||||||
const colorToHex = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const { alpha = false } = opt;
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "colorToHex",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
let hex;
|
|
||||||
opt.nullable = true;
|
|
||||||
if (alpha) {
|
|
||||||
opt.format = "hexAlpha";
|
|
||||||
hex = resolveColor(value, opt);
|
|
||||||
} else {
|
|
||||||
opt.format = "hex";
|
|
||||||
hex = resolveColor(value, opt);
|
|
||||||
}
|
|
||||||
if (isString(hex)) {
|
|
||||||
setCache(cacheKey, hex);
|
|
||||||
return hex;
|
|
||||||
}
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
const colorToHsl = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "colorToHsl",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
opt.format = "hsl";
|
|
||||||
const hsl = convertColorToHsl(value, opt);
|
|
||||||
setCache(cacheKey, hsl);
|
|
||||||
return hsl;
|
|
||||||
};
|
|
||||||
const colorToHwb = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "colorToHwb",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
opt.format = "hwb";
|
|
||||||
const hwb = convertColorToHwb(value, opt);
|
|
||||||
setCache(cacheKey, hwb);
|
|
||||||
return hwb;
|
|
||||||
};
|
|
||||||
const colorToLab = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "colorToLab",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
const lab = convertColorToLab(value, opt);
|
|
||||||
setCache(cacheKey, lab);
|
|
||||||
return lab;
|
|
||||||
};
|
|
||||||
const colorToLch = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "colorToLch",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
const lch = convertColorToLch(value, opt);
|
|
||||||
setCache(cacheKey, lch);
|
|
||||||
return lch;
|
|
||||||
};
|
|
||||||
const colorToOklab = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "colorToOklab",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
const lab = convertColorToOklab(value, opt);
|
|
||||||
setCache(cacheKey, lab);
|
|
||||||
return lab;
|
|
||||||
};
|
|
||||||
const colorToOklch = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "colorToOklch",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
const lch = convertColorToOklch(value, opt);
|
|
||||||
setCache(cacheKey, lch);
|
|
||||||
return lch;
|
|
||||||
};
|
|
||||||
const colorToRgb = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "colorToRgb",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
const rgb = convertColorToRgb(value, opt);
|
|
||||||
setCache(cacheKey, rgb);
|
|
||||||
return rgb;
|
|
||||||
};
|
|
||||||
const colorToXyz = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "colorToXyz",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
let xyz;
|
|
||||||
if (value.startsWith("color(")) {
|
|
||||||
[, ...xyz] = parseColorFunc(value, opt);
|
|
||||||
} else {
|
|
||||||
[, ...xyz] = parseColorValue(value, opt);
|
|
||||||
}
|
|
||||||
setCache(cacheKey, xyz);
|
|
||||||
return xyz;
|
|
||||||
};
|
|
||||||
const colorToXyzD50 = (value, opt = {}) => {
|
|
||||||
opt.d50 = true;
|
|
||||||
return colorToXyz(value, opt);
|
|
||||||
};
|
|
||||||
const convert = {
|
|
||||||
colorToHex,
|
|
||||||
colorToHsl,
|
|
||||||
colorToHwb,
|
|
||||||
colorToLab,
|
|
||||||
colorToLch,
|
|
||||||
colorToOklab,
|
|
||||||
colorToOklch,
|
|
||||||
colorToRgb,
|
|
||||||
colorToXyz,
|
|
||||||
colorToXyzD50,
|
|
||||||
numberToHex
|
|
||||||
};
|
|
||||||
export {
|
|
||||||
colorToHex,
|
|
||||||
colorToHsl,
|
|
||||||
colorToHwb,
|
|
||||||
colorToLab,
|
|
||||||
colorToLch,
|
|
||||||
colorToOklab,
|
|
||||||
colorToOklch,
|
|
||||||
colorToRgb,
|
|
||||||
colorToXyz,
|
|
||||||
colorToXyzD50,
|
|
||||||
convert,
|
|
||||||
numberToHex,
|
|
||||||
preProcess
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=convert.js.map
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-89
@@ -1,89 +0,0 @@
|
|||||||
import { CSSToken } from '@csstools/css-tokenizer';
|
|
||||||
import { NullObject } from './cache.js';
|
|
||||||
import { Options } from './typedef.js';
|
|
||||||
/**
|
|
||||||
* Calclator
|
|
||||||
*/
|
|
||||||
export declare class Calculator {
|
|
||||||
#private;
|
|
||||||
/**
|
|
||||||
* constructor
|
|
||||||
*/
|
|
||||||
constructor();
|
|
||||||
get hasNum(): boolean;
|
|
||||||
set hasNum(value: boolean);
|
|
||||||
get numSum(): number[];
|
|
||||||
get numMul(): number[];
|
|
||||||
get hasPct(): boolean;
|
|
||||||
set hasPct(value: boolean);
|
|
||||||
get pctSum(): number[];
|
|
||||||
get pctMul(): number[];
|
|
||||||
get hasDim(): boolean;
|
|
||||||
set hasDim(value: boolean);
|
|
||||||
get dimSum(): string[];
|
|
||||||
get dimSub(): string[];
|
|
||||||
get dimMul(): string[];
|
|
||||||
get dimDiv(): string[];
|
|
||||||
get hasEtc(): boolean;
|
|
||||||
set hasEtc(value: boolean);
|
|
||||||
get etcSum(): string[];
|
|
||||||
get etcSub(): string[];
|
|
||||||
get etcMul(): string[];
|
|
||||||
get etcDiv(): string[];
|
|
||||||
/**
|
|
||||||
* clear values
|
|
||||||
* @returns void
|
|
||||||
*/
|
|
||||||
clear(): void;
|
|
||||||
/**
|
|
||||||
* sort values
|
|
||||||
* @param values - values
|
|
||||||
* @returns sorted values
|
|
||||||
*/
|
|
||||||
sort(values?: string[]): string[];
|
|
||||||
/**
|
|
||||||
* multiply values
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
multiply(): string;
|
|
||||||
/**
|
|
||||||
* sum values
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
sum(): string;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* sort calc values
|
|
||||||
* @param values - values to sort
|
|
||||||
* @param [finalize] - finalize values
|
|
||||||
* @returns sorted values
|
|
||||||
*/
|
|
||||||
export declare const sortCalcValues: (values?: (number | string)[], finalize?: boolean) => string;
|
|
||||||
/**
|
|
||||||
* serialize calc
|
|
||||||
* @param value - CSS value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns serialized value
|
|
||||||
*/
|
|
||||||
export declare const serializeCalc: (value: string, opt?: Options) => string;
|
|
||||||
/**
|
|
||||||
* resolve dimension
|
|
||||||
* @param token - CSS token
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
export declare const resolveDimension: (token: CSSToken, opt?: Options) => string | NullObject;
|
|
||||||
/**
|
|
||||||
* parse tokens
|
|
||||||
* @param tokens - CSS tokens
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed tokens
|
|
||||||
*/
|
|
||||||
export declare const parseTokens: (tokens: CSSToken[], opt?: Options) => string[];
|
|
||||||
/**
|
|
||||||
* CSS calc()
|
|
||||||
* @param value - CSS value including calc()
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
export declare const cssCalc: (value: string, opt?: Options) => string;
|
|
||||||
-860
@@ -1,860 +0,0 @@
|
|||||||
var __typeError = (msg) => {
|
|
||||||
throw TypeError(msg);
|
|
||||||
};
|
|
||||||
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
||||||
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
||||||
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
||||||
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
||||||
var _hasNum, _numSum, _numMul, _hasPct, _pctSum, _pctMul, _hasDim, _dimSum, _dimSub, _dimMul, _dimDiv, _hasEtc, _etcSum, _etcSub, _etcMul, _etcDiv;
|
|
||||||
import { calc } from "@csstools/css-calc";
|
|
||||||
import { TokenType, tokenize } from "@csstools/css-tokenizer";
|
|
||||||
import { createCacheKey, getCache, CacheItem, setCache, NullObject } from "./cache.js";
|
|
||||||
import { isString, isStringOrNumber } from "./common.js";
|
|
||||||
import { resolveVar } from "./css-var.js";
|
|
||||||
import { roundToPrecision } from "./util.js";
|
|
||||||
import { VAL_SPEC, SYN_FN_VAR, SYN_FN_CALC, SYN_FN_VAR_START, NUM, ANGLE, LENGTH, SYN_FN_MATH_START } from "./constant.js";
|
|
||||||
const {
|
|
||||||
CloseParen: PAREN_CLOSE,
|
|
||||||
Comment: COMMENT,
|
|
||||||
Dimension: DIM,
|
|
||||||
EOF,
|
|
||||||
Function: FUNC,
|
|
||||||
OpenParen: PAREN_OPEN,
|
|
||||||
Whitespace: W_SPACE
|
|
||||||
} = TokenType;
|
|
||||||
const NAMESPACE = "css-calc";
|
|
||||||
const TRIA = 3;
|
|
||||||
const HEX = 16;
|
|
||||||
const MAX_PCT = 100;
|
|
||||||
const REG_FN_CALC = new RegExp(SYN_FN_CALC);
|
|
||||||
const REG_FN_CALC_NUM = new RegExp(`^calc\\((${NUM})\\)$`);
|
|
||||||
const REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START);
|
|
||||||
const REG_FN_VAR = new RegExp(SYN_FN_VAR);
|
|
||||||
const REG_FN_VAR_START = new RegExp(SYN_FN_VAR_START);
|
|
||||||
const REG_OPERATOR = /\s[*+/-]\s/;
|
|
||||||
const REG_TYPE_DIM = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH})$`);
|
|
||||||
const REG_TYPE_DIM_PCT = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH}|%)$`);
|
|
||||||
const REG_TYPE_PCT = new RegExp(`^(${NUM})%$`);
|
|
||||||
class Calculator {
|
|
||||||
/**
|
|
||||||
* constructor
|
|
||||||
*/
|
|
||||||
constructor() {
|
|
||||||
/* private */
|
|
||||||
// number
|
|
||||||
__privateAdd(this, _hasNum);
|
|
||||||
__privateAdd(this, _numSum);
|
|
||||||
__privateAdd(this, _numMul);
|
|
||||||
// percentage
|
|
||||||
__privateAdd(this, _hasPct);
|
|
||||||
__privateAdd(this, _pctSum);
|
|
||||||
__privateAdd(this, _pctMul);
|
|
||||||
// dimension
|
|
||||||
__privateAdd(this, _hasDim);
|
|
||||||
__privateAdd(this, _dimSum);
|
|
||||||
__privateAdd(this, _dimSub);
|
|
||||||
__privateAdd(this, _dimMul);
|
|
||||||
__privateAdd(this, _dimDiv);
|
|
||||||
// et cetra
|
|
||||||
__privateAdd(this, _hasEtc);
|
|
||||||
__privateAdd(this, _etcSum);
|
|
||||||
__privateAdd(this, _etcSub);
|
|
||||||
__privateAdd(this, _etcMul);
|
|
||||||
__privateAdd(this, _etcDiv);
|
|
||||||
__privateSet(this, _hasNum, false);
|
|
||||||
__privateSet(this, _numSum, []);
|
|
||||||
__privateSet(this, _numMul, []);
|
|
||||||
__privateSet(this, _hasPct, false);
|
|
||||||
__privateSet(this, _pctSum, []);
|
|
||||||
__privateSet(this, _pctMul, []);
|
|
||||||
__privateSet(this, _hasDim, false);
|
|
||||||
__privateSet(this, _dimSum, []);
|
|
||||||
__privateSet(this, _dimSub, []);
|
|
||||||
__privateSet(this, _dimMul, []);
|
|
||||||
__privateSet(this, _dimDiv, []);
|
|
||||||
__privateSet(this, _hasEtc, false);
|
|
||||||
__privateSet(this, _etcSum, []);
|
|
||||||
__privateSet(this, _etcSub, []);
|
|
||||||
__privateSet(this, _etcMul, []);
|
|
||||||
__privateSet(this, _etcDiv, []);
|
|
||||||
}
|
|
||||||
get hasNum() {
|
|
||||||
return __privateGet(this, _hasNum);
|
|
||||||
}
|
|
||||||
set hasNum(value) {
|
|
||||||
__privateSet(this, _hasNum, !!value);
|
|
||||||
}
|
|
||||||
get numSum() {
|
|
||||||
return __privateGet(this, _numSum);
|
|
||||||
}
|
|
||||||
get numMul() {
|
|
||||||
return __privateGet(this, _numMul);
|
|
||||||
}
|
|
||||||
get hasPct() {
|
|
||||||
return __privateGet(this, _hasPct);
|
|
||||||
}
|
|
||||||
set hasPct(value) {
|
|
||||||
__privateSet(this, _hasPct, !!value);
|
|
||||||
}
|
|
||||||
get pctSum() {
|
|
||||||
return __privateGet(this, _pctSum);
|
|
||||||
}
|
|
||||||
get pctMul() {
|
|
||||||
return __privateGet(this, _pctMul);
|
|
||||||
}
|
|
||||||
get hasDim() {
|
|
||||||
return __privateGet(this, _hasDim);
|
|
||||||
}
|
|
||||||
set hasDim(value) {
|
|
||||||
__privateSet(this, _hasDim, !!value);
|
|
||||||
}
|
|
||||||
get dimSum() {
|
|
||||||
return __privateGet(this, _dimSum);
|
|
||||||
}
|
|
||||||
get dimSub() {
|
|
||||||
return __privateGet(this, _dimSub);
|
|
||||||
}
|
|
||||||
get dimMul() {
|
|
||||||
return __privateGet(this, _dimMul);
|
|
||||||
}
|
|
||||||
get dimDiv() {
|
|
||||||
return __privateGet(this, _dimDiv);
|
|
||||||
}
|
|
||||||
get hasEtc() {
|
|
||||||
return __privateGet(this, _hasEtc);
|
|
||||||
}
|
|
||||||
set hasEtc(value) {
|
|
||||||
__privateSet(this, _hasEtc, !!value);
|
|
||||||
}
|
|
||||||
get etcSum() {
|
|
||||||
return __privateGet(this, _etcSum);
|
|
||||||
}
|
|
||||||
get etcSub() {
|
|
||||||
return __privateGet(this, _etcSub);
|
|
||||||
}
|
|
||||||
get etcMul() {
|
|
||||||
return __privateGet(this, _etcMul);
|
|
||||||
}
|
|
||||||
get etcDiv() {
|
|
||||||
return __privateGet(this, _etcDiv);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* clear values
|
|
||||||
* @returns void
|
|
||||||
*/
|
|
||||||
clear() {
|
|
||||||
__privateSet(this, _hasNum, false);
|
|
||||||
__privateSet(this, _numSum, []);
|
|
||||||
__privateSet(this, _numMul, []);
|
|
||||||
__privateSet(this, _hasPct, false);
|
|
||||||
__privateSet(this, _pctSum, []);
|
|
||||||
__privateSet(this, _pctMul, []);
|
|
||||||
__privateSet(this, _hasDim, false);
|
|
||||||
__privateSet(this, _dimSum, []);
|
|
||||||
__privateSet(this, _dimSub, []);
|
|
||||||
__privateSet(this, _dimMul, []);
|
|
||||||
__privateSet(this, _dimDiv, []);
|
|
||||||
__privateSet(this, _hasEtc, false);
|
|
||||||
__privateSet(this, _etcSum, []);
|
|
||||||
__privateSet(this, _etcSub, []);
|
|
||||||
__privateSet(this, _etcMul, []);
|
|
||||||
__privateSet(this, _etcDiv, []);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* sort values
|
|
||||||
* @param values - values
|
|
||||||
* @returns sorted values
|
|
||||||
*/
|
|
||||||
sort(values = []) {
|
|
||||||
const arr = [...values];
|
|
||||||
if (arr.length > 1) {
|
|
||||||
arr.sort((a, b) => {
|
|
||||||
let res;
|
|
||||||
if (REG_TYPE_DIM_PCT.test(a) && REG_TYPE_DIM_PCT.test(b)) {
|
|
||||||
const [, valA, unitA] = a.match(REG_TYPE_DIM_PCT);
|
|
||||||
const [, valB, unitB] = b.match(REG_TYPE_DIM_PCT);
|
|
||||||
if (unitA === unitB) {
|
|
||||||
if (Number(valA) === Number(valB)) {
|
|
||||||
res = 0;
|
|
||||||
} else if (Number(valA) > Number(valB)) {
|
|
||||||
res = 1;
|
|
||||||
} else {
|
|
||||||
res = -1;
|
|
||||||
}
|
|
||||||
} else if (unitA > unitB) {
|
|
||||||
res = 1;
|
|
||||||
} else {
|
|
||||||
res = -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (a === b) {
|
|
||||||
res = 0;
|
|
||||||
} else if (a > b) {
|
|
||||||
res = 1;
|
|
||||||
} else {
|
|
||||||
res = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* multiply values
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
multiply() {
|
|
||||||
const value = [];
|
|
||||||
let num;
|
|
||||||
if (__privateGet(this, _hasNum)) {
|
|
||||||
num = 1;
|
|
||||||
for (const i of __privateGet(this, _numMul)) {
|
|
||||||
num *= i;
|
|
||||||
if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!__privateGet(this, _hasPct) && !__privateGet(this, _hasDim) && !this.hasEtc) {
|
|
||||||
if (Number.isFinite(num)) {
|
|
||||||
num = roundToPrecision(num, HEX);
|
|
||||||
}
|
|
||||||
value.push(num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (__privateGet(this, _hasPct)) {
|
|
||||||
if (typeof num !== "number") {
|
|
||||||
num = 1;
|
|
||||||
}
|
|
||||||
for (const i of __privateGet(this, _pctMul)) {
|
|
||||||
num *= i;
|
|
||||||
if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Number.isFinite(num)) {
|
|
||||||
num = `${roundToPrecision(num, HEX)}%`;
|
|
||||||
}
|
|
||||||
if (!__privateGet(this, _hasDim) && !this.hasEtc) {
|
|
||||||
value.push(num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (__privateGet(this, _hasDim)) {
|
|
||||||
let dim = "";
|
|
||||||
let mul = "";
|
|
||||||
let div = "";
|
|
||||||
if (__privateGet(this, _dimMul).length) {
|
|
||||||
if (__privateGet(this, _dimMul).length === 1) {
|
|
||||||
[mul] = __privateGet(this, _dimMul);
|
|
||||||
} else {
|
|
||||||
mul = `${this.sort(__privateGet(this, _dimMul)).join(" * ")}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (__privateGet(this, _dimDiv).length) {
|
|
||||||
if (__privateGet(this, _dimDiv).length === 1) {
|
|
||||||
[div] = __privateGet(this, _dimDiv);
|
|
||||||
} else {
|
|
||||||
div = `${this.sort(__privateGet(this, _dimDiv)).join(" * ")}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Number.isFinite(num)) {
|
|
||||||
if (mul) {
|
|
||||||
if (div) {
|
|
||||||
if (div.includes("*")) {
|
|
||||||
dim = calc(`calc(${num} * ${mul} / (${div}))`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${num} * ${mul} / ${div})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${num} * ${mul})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (div.includes("*")) {
|
|
||||||
dim = calc(`calc(${num} / (${div}))`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${num} / ${div})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
value.push(dim.replace(/^calc/, ""));
|
|
||||||
} else {
|
|
||||||
if (!value.length && num !== void 0) {
|
|
||||||
value.push(num);
|
|
||||||
}
|
|
||||||
if (mul) {
|
|
||||||
if (div) {
|
|
||||||
if (div.includes("*")) {
|
|
||||||
dim = calc(`calc(${mul} / (${div}))`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${mul} / ${div})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${mul})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (value.length) {
|
|
||||||
value.push("*", dim.replace(/^calc/, ""));
|
|
||||||
} else {
|
|
||||||
value.push(dim.replace(/^calc/, ""));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${div})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
if (value.length) {
|
|
||||||
value.push("/", dim.replace(/^calc/, ""));
|
|
||||||
} else {
|
|
||||||
value.push("1", "/", dim.replace(/^calc/, ""));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (__privateGet(this, _hasEtc)) {
|
|
||||||
if (__privateGet(this, _etcMul).length) {
|
|
||||||
if (!value.length && num !== void 0) {
|
|
||||||
value.push(num);
|
|
||||||
}
|
|
||||||
const mul = this.sort(__privateGet(this, _etcMul)).join(" * ");
|
|
||||||
if (value.length) {
|
|
||||||
value.push(`* ${mul}`);
|
|
||||||
} else {
|
|
||||||
value.push(`${mul}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (__privateGet(this, _etcDiv).length) {
|
|
||||||
const div = this.sort(__privateGet(this, _etcDiv)).join(" * ");
|
|
||||||
if (div.includes("*")) {
|
|
||||||
if (value.length) {
|
|
||||||
value.push(`/ (${div})`);
|
|
||||||
} else {
|
|
||||||
value.push(`1 / (${div})`);
|
|
||||||
}
|
|
||||||
} else if (value.length) {
|
|
||||||
value.push(`/ ${div}`);
|
|
||||||
} else {
|
|
||||||
value.push(`1 / ${div}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (value.length) {
|
|
||||||
return value.join(" ");
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* sum values
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
sum() {
|
|
||||||
const value = [];
|
|
||||||
if (__privateGet(this, _hasNum)) {
|
|
||||||
let num = 0;
|
|
||||||
for (const i of __privateGet(this, _numSum)) {
|
|
||||||
num += i;
|
|
||||||
if (!Number.isFinite(num) || Number.isNaN(num)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
value.push(num);
|
|
||||||
}
|
|
||||||
if (__privateGet(this, _hasPct)) {
|
|
||||||
let num = 0;
|
|
||||||
for (const i of __privateGet(this, _pctSum)) {
|
|
||||||
num += i;
|
|
||||||
if (!Number.isFinite(num)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Number.isFinite(num)) {
|
|
||||||
num = `${num}%`;
|
|
||||||
}
|
|
||||||
if (value.length) {
|
|
||||||
value.push(`+ ${num}`);
|
|
||||||
} else {
|
|
||||||
value.push(num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (__privateGet(this, _hasDim)) {
|
|
||||||
let dim, sum, sub;
|
|
||||||
if (__privateGet(this, _dimSum).length) {
|
|
||||||
sum = this.sort(__privateGet(this, _dimSum)).join(" + ");
|
|
||||||
}
|
|
||||||
if (__privateGet(this, _dimSub).length) {
|
|
||||||
sub = this.sort(__privateGet(this, _dimSub)).join(" + ");
|
|
||||||
}
|
|
||||||
if (sum) {
|
|
||||||
if (sub) {
|
|
||||||
if (sub.includes("-")) {
|
|
||||||
dim = calc(`calc(${sum} - (${sub}))`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${sum} - ${sub})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${sum})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(-1 * (${sub}))`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (value.length) {
|
|
||||||
value.push("+", dim.replace(/^calc/, ""));
|
|
||||||
} else {
|
|
||||||
value.push(dim.replace(/^calc/, ""));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (__privateGet(this, _hasEtc)) {
|
|
||||||
if (__privateGet(this, _etcSum).length) {
|
|
||||||
const sum = this.sort(__privateGet(this, _etcSum)).map((item) => {
|
|
||||||
let res;
|
|
||||||
if (REG_OPERATOR.test(item) && !item.startsWith("(") && !item.endsWith(")")) {
|
|
||||||
res = `(${item})`;
|
|
||||||
} else {
|
|
||||||
res = item;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}).join(" + ");
|
|
||||||
if (value.length) {
|
|
||||||
if (__privateGet(this, _etcSum).length > 1) {
|
|
||||||
value.push(`+ (${sum})`);
|
|
||||||
} else {
|
|
||||||
value.push(`+ ${sum}`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value.push(`${sum}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (__privateGet(this, _etcSub).length) {
|
|
||||||
const sub = this.sort(__privateGet(this, _etcSub)).map((item) => {
|
|
||||||
let res;
|
|
||||||
if (REG_OPERATOR.test(item) && !item.startsWith("(") && !item.endsWith(")")) {
|
|
||||||
res = `(${item})`;
|
|
||||||
} else {
|
|
||||||
res = item;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}).join(" + ");
|
|
||||||
if (value.length) {
|
|
||||||
if (__privateGet(this, _etcSub).length > 1) {
|
|
||||||
value.push(`- (${sub})`);
|
|
||||||
} else {
|
|
||||||
value.push(`- ${sub}`);
|
|
||||||
}
|
|
||||||
} else if (__privateGet(this, _etcSub).length > 1) {
|
|
||||||
value.push(`-1 * (${sub})`);
|
|
||||||
} else {
|
|
||||||
value.push(`-1 * ${sub}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (value.length) {
|
|
||||||
return value.join(" ");
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_hasNum = new WeakMap();
|
|
||||||
_numSum = new WeakMap();
|
|
||||||
_numMul = new WeakMap();
|
|
||||||
_hasPct = new WeakMap();
|
|
||||||
_pctSum = new WeakMap();
|
|
||||||
_pctMul = new WeakMap();
|
|
||||||
_hasDim = new WeakMap();
|
|
||||||
_dimSum = new WeakMap();
|
|
||||||
_dimSub = new WeakMap();
|
|
||||||
_dimMul = new WeakMap();
|
|
||||||
_dimDiv = new WeakMap();
|
|
||||||
_hasEtc = new WeakMap();
|
|
||||||
_etcSum = new WeakMap();
|
|
||||||
_etcSub = new WeakMap();
|
|
||||||
_etcMul = new WeakMap();
|
|
||||||
_etcDiv = new WeakMap();
|
|
||||||
const sortCalcValues = (values = [], finalize = false) => {
|
|
||||||
if (values.length < TRIA) {
|
|
||||||
throw new Error(`Unexpected array length ${values.length}.`);
|
|
||||||
}
|
|
||||||
const start = values.shift();
|
|
||||||
if (!isString(start) || !start.endsWith("(")) {
|
|
||||||
throw new Error(`Unexpected token ${start}.`);
|
|
||||||
}
|
|
||||||
const end = values.pop();
|
|
||||||
if (end !== ")") {
|
|
||||||
throw new Error(`Unexpected token ${end}.`);
|
|
||||||
}
|
|
||||||
if (values.length === 1) {
|
|
||||||
const [value] = values;
|
|
||||||
if (!isStringOrNumber(value)) {
|
|
||||||
throw new Error(`Unexpected token ${value}.`);
|
|
||||||
}
|
|
||||||
return `${start}${value}${end}`;
|
|
||||||
}
|
|
||||||
const sortedValues = [];
|
|
||||||
const cal = new Calculator();
|
|
||||||
let operator = "";
|
|
||||||
const l = values.length;
|
|
||||||
for (let i = 0; i < l; i++) {
|
|
||||||
const value = values[i];
|
|
||||||
if (!isStringOrNumber(value)) {
|
|
||||||
throw new Error(`Unexpected token ${value}.`);
|
|
||||||
}
|
|
||||||
if (value === "*" || value === "/") {
|
|
||||||
operator = value;
|
|
||||||
} else if (value === "+" || value === "-") {
|
|
||||||
const sortedValue = cal.multiply();
|
|
||||||
if (sortedValue) {
|
|
||||||
sortedValues.push(sortedValue, value);
|
|
||||||
}
|
|
||||||
cal.clear();
|
|
||||||
operator = "";
|
|
||||||
} else {
|
|
||||||
const numValue = Number(value);
|
|
||||||
const strValue = `${value}`;
|
|
||||||
switch (operator) {
|
|
||||||
case "/": {
|
|
||||||
if (Number.isFinite(numValue)) {
|
|
||||||
cal.hasNum = true;
|
|
||||||
cal.numMul.push(1 / numValue);
|
|
||||||
} else if (REG_TYPE_PCT.test(strValue)) {
|
|
||||||
const [, val] = strValue.match(REG_TYPE_PCT);
|
|
||||||
cal.hasPct = true;
|
|
||||||
cal.pctMul.push(MAX_PCT * MAX_PCT / Number(val));
|
|
||||||
} else if (REG_TYPE_DIM.test(strValue)) {
|
|
||||||
cal.hasDim = true;
|
|
||||||
cal.dimDiv.push(strValue);
|
|
||||||
} else {
|
|
||||||
cal.hasEtc = true;
|
|
||||||
cal.etcDiv.push(strValue);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "*":
|
|
||||||
default: {
|
|
||||||
if (Number.isFinite(numValue)) {
|
|
||||||
cal.hasNum = true;
|
|
||||||
cal.numMul.push(numValue);
|
|
||||||
} else if (REG_TYPE_PCT.test(strValue)) {
|
|
||||||
const [, val] = strValue.match(REG_TYPE_PCT);
|
|
||||||
cal.hasPct = true;
|
|
||||||
cal.pctMul.push(Number(val));
|
|
||||||
} else if (REG_TYPE_DIM.test(strValue)) {
|
|
||||||
cal.hasDim = true;
|
|
||||||
cal.dimMul.push(strValue);
|
|
||||||
} else {
|
|
||||||
cal.hasEtc = true;
|
|
||||||
cal.etcMul.push(strValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i === l - 1) {
|
|
||||||
const sortedValue = cal.multiply();
|
|
||||||
if (sortedValue) {
|
|
||||||
sortedValues.push(sortedValue);
|
|
||||||
}
|
|
||||||
cal.clear();
|
|
||||||
operator = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let resolvedValue = "";
|
|
||||||
if (finalize && (sortedValues.includes("+") || sortedValues.includes("-"))) {
|
|
||||||
const finalizedValues = [];
|
|
||||||
cal.clear();
|
|
||||||
operator = "";
|
|
||||||
const l2 = sortedValues.length;
|
|
||||||
for (let i = 0; i < l2; i++) {
|
|
||||||
const value = sortedValues[i];
|
|
||||||
if (isStringOrNumber(value)) {
|
|
||||||
if (value === "+" || value === "-") {
|
|
||||||
operator = value;
|
|
||||||
} else {
|
|
||||||
const numValue = Number(value);
|
|
||||||
const strValue = `${value}`;
|
|
||||||
switch (operator) {
|
|
||||||
case "-": {
|
|
||||||
if (Number.isFinite(numValue)) {
|
|
||||||
cal.hasNum = true;
|
|
||||||
cal.numSum.push(-1 * numValue);
|
|
||||||
} else if (REG_TYPE_PCT.test(strValue)) {
|
|
||||||
const [, val] = strValue.match(REG_TYPE_PCT);
|
|
||||||
cal.hasPct = true;
|
|
||||||
cal.pctSum.push(-1 * Number(val));
|
|
||||||
} else if (REG_TYPE_DIM.test(strValue)) {
|
|
||||||
cal.hasDim = true;
|
|
||||||
cal.dimSub.push(strValue);
|
|
||||||
} else {
|
|
||||||
cal.hasEtc = true;
|
|
||||||
cal.etcSub.push(strValue);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "+":
|
|
||||||
default: {
|
|
||||||
if (Number.isFinite(numValue)) {
|
|
||||||
cal.hasNum = true;
|
|
||||||
cal.numSum.push(numValue);
|
|
||||||
} else if (REG_TYPE_PCT.test(strValue)) {
|
|
||||||
const [, val] = strValue.match(REG_TYPE_PCT);
|
|
||||||
cal.hasPct = true;
|
|
||||||
cal.pctSum.push(Number(val));
|
|
||||||
} else if (REG_TYPE_DIM.test(strValue)) {
|
|
||||||
cal.hasDim = true;
|
|
||||||
cal.dimSum.push(strValue);
|
|
||||||
} else {
|
|
||||||
cal.hasEtc = true;
|
|
||||||
cal.etcSum.push(strValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i === l2 - 1) {
|
|
||||||
const sortedValue = cal.sum();
|
|
||||||
if (sortedValue) {
|
|
||||||
finalizedValues.push(sortedValue);
|
|
||||||
}
|
|
||||||
cal.clear();
|
|
||||||
operator = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resolvedValue = finalizedValues.join(" ").replace(/\+\s-/g, "- ");
|
|
||||||
} else {
|
|
||||||
resolvedValue = sortedValues.join(" ").replace(/\+\s-/g, "- ");
|
|
||||||
}
|
|
||||||
if (resolvedValue.startsWith("(") && resolvedValue.endsWith(")") && resolvedValue.lastIndexOf("(") === 0 && resolvedValue.indexOf(")") === resolvedValue.length - 1) {
|
|
||||||
resolvedValue = resolvedValue.replace(/^\(/, "").replace(/\)$/, "");
|
|
||||||
}
|
|
||||||
return `${start}${resolvedValue}${end}`;
|
|
||||||
};
|
|
||||||
const serializeCalc = (value, opt = {}) => {
|
|
||||||
const { format = "" } = opt;
|
|
||||||
if (isString(value)) {
|
|
||||||
if (!REG_FN_VAR_START.test(value) || format !== VAL_SPEC) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
value = value.toLowerCase().trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "serializeCalc",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
const items = tokenize({ css: value }).map((token) => {
|
|
||||||
const [type, value2] = token;
|
|
||||||
let res = "";
|
|
||||||
if (type !== W_SPACE && type !== COMMENT) {
|
|
||||||
res = value2;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}).filter((v) => v);
|
|
||||||
let startIndex = items.findLastIndex((item) => /\($/.test(item));
|
|
||||||
while (startIndex) {
|
|
||||||
const endIndex = items.findIndex((item, index) => {
|
|
||||||
return item === ")" && index > startIndex;
|
|
||||||
});
|
|
||||||
const slicedValues = items.slice(startIndex, endIndex + 1);
|
|
||||||
let serializedValue = sortCalcValues(slicedValues);
|
|
||||||
if (REG_FN_VAR_START.test(serializedValue)) {
|
|
||||||
serializedValue = calc(serializedValue, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
items.splice(startIndex, endIndex - startIndex + 1, serializedValue);
|
|
||||||
startIndex = items.findLastIndex((item) => /\($/.test(item));
|
|
||||||
}
|
|
||||||
const serializedCalc = sortCalcValues(items, true);
|
|
||||||
setCache(cacheKey, serializedCalc);
|
|
||||||
return serializedCalc;
|
|
||||||
};
|
|
||||||
const resolveDimension = (token, opt = {}) => {
|
|
||||||
if (!Array.isArray(token)) {
|
|
||||||
throw new TypeError(`${token} is not an array.`);
|
|
||||||
}
|
|
||||||
const [, , , , detail = {}] = token;
|
|
||||||
const { unit, value } = detail;
|
|
||||||
const { dimension = {} } = opt;
|
|
||||||
if (unit === "px") {
|
|
||||||
return `${value}${unit}`;
|
|
||||||
}
|
|
||||||
const relativeValue = Number(value);
|
|
||||||
if (unit && Number.isFinite(relativeValue)) {
|
|
||||||
let pixelValue;
|
|
||||||
if (Object.hasOwnProperty.call(dimension, unit)) {
|
|
||||||
pixelValue = dimension[unit];
|
|
||||||
} else if (typeof dimension.callback === "function") {
|
|
||||||
pixelValue = dimension.callback(unit);
|
|
||||||
}
|
|
||||||
pixelValue = Number(pixelValue);
|
|
||||||
if (Number.isFinite(pixelValue)) {
|
|
||||||
return `${relativeValue * pixelValue}px`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new NullObject();
|
|
||||||
};
|
|
||||||
const parseTokens = (tokens, opt = {}) => {
|
|
||||||
if (!Array.isArray(tokens)) {
|
|
||||||
throw new TypeError(`${tokens} is not an array.`);
|
|
||||||
}
|
|
||||||
const { format = "" } = opt;
|
|
||||||
const mathFunc = /* @__PURE__ */ new Set();
|
|
||||||
let nest = 0;
|
|
||||||
const res = [];
|
|
||||||
while (tokens.length) {
|
|
||||||
const token = tokens.shift();
|
|
||||||
if (!Array.isArray(token)) {
|
|
||||||
throw new TypeError(`${token} is not an array.`);
|
|
||||||
}
|
|
||||||
const [type = "", value = ""] = token;
|
|
||||||
switch (type) {
|
|
||||||
case DIM: {
|
|
||||||
if (format === VAL_SPEC && !mathFunc.has(nest)) {
|
|
||||||
res.push(value);
|
|
||||||
} else {
|
|
||||||
const resolvedValue = resolveDimension(token, opt);
|
|
||||||
if (isString(resolvedValue)) {
|
|
||||||
res.push(resolvedValue);
|
|
||||||
} else {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FUNC:
|
|
||||||
case PAREN_OPEN: {
|
|
||||||
res.push(value);
|
|
||||||
nest++;
|
|
||||||
if (REG_FN_MATH_START.test(value)) {
|
|
||||||
mathFunc.add(nest);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PAREN_CLOSE: {
|
|
||||||
if (res.length) {
|
|
||||||
const lastValue = res[res.length - 1];
|
|
||||||
if (lastValue === " ") {
|
|
||||||
res.splice(-1, 1, value);
|
|
||||||
} else {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
if (mathFunc.has(nest)) {
|
|
||||||
mathFunc.delete(nest);
|
|
||||||
}
|
|
||||||
nest--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case W_SPACE: {
|
|
||||||
if (res.length) {
|
|
||||||
const lastValue = res[res.length - 1];
|
|
||||||
if (isString(lastValue) && !lastValue.endsWith("(") && lastValue !== " ") {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
if (type !== COMMENT && type !== EOF) {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
const cssCalc = (value, opt = {}) => {
|
|
||||||
const { format = "" } = opt;
|
|
||||||
if (isString(value)) {
|
|
||||||
if (REG_FN_VAR.test(value)) {
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
return value;
|
|
||||||
} else {
|
|
||||||
const resolvedValue2 = resolveVar(value, opt);
|
|
||||||
if (isString(resolvedValue2)) {
|
|
||||||
return resolvedValue2;
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (!REG_FN_CALC.test(value)) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
value = value.toLowerCase().trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "cssCalc",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
const tokens = tokenize({ css: value });
|
|
||||||
const values = parseTokens(tokens, opt);
|
|
||||||
let resolvedValue = calc(values.join(""), {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
if (REG_FN_VAR_START.test(value)) {
|
|
||||||
if (REG_TYPE_DIM_PCT.test(resolvedValue)) {
|
|
||||||
const [, val, unit] = resolvedValue.match(
|
|
||||||
REG_TYPE_DIM_PCT
|
|
||||||
);
|
|
||||||
resolvedValue = `${roundToPrecision(Number(val), HEX)}${unit}`;
|
|
||||||
}
|
|
||||||
if (resolvedValue && !REG_FN_VAR_START.test(resolvedValue) && format === VAL_SPEC) {
|
|
||||||
resolvedValue = `calc(${resolvedValue})`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
if (/\s[-+*/]\s/.test(resolvedValue) && !resolvedValue.includes("NaN")) {
|
|
||||||
resolvedValue = serializeCalc(resolvedValue, opt);
|
|
||||||
} else if (REG_FN_CALC_NUM.test(resolvedValue)) {
|
|
||||||
const [, val] = resolvedValue.match(REG_FN_CALC_NUM);
|
|
||||||
resolvedValue = `calc(${roundToPrecision(Number(val), HEX)})`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
};
|
|
||||||
export {
|
|
||||||
Calculator,
|
|
||||||
cssCalc,
|
|
||||||
parseTokens,
|
|
||||||
resolveDimension,
|
|
||||||
serializeCalc,
|
|
||||||
sortCalcValues
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=css-calc.js.map
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-54
@@ -1,54 +0,0 @@
|
|||||||
import { Options } from './typedef.js';
|
|
||||||
/**
|
|
||||||
* @type ColorStopList - list of color stops
|
|
||||||
*/
|
|
||||||
type ColorStopList = [string, string, ...string[]];
|
|
||||||
/**
|
|
||||||
* @typedef Gradient - parsed CSS gradient
|
|
||||||
* @property value - input value
|
|
||||||
* @property type - gradient type
|
|
||||||
* @property [gradientLine] - gradient line
|
|
||||||
* @property colorStopList - list of color stops
|
|
||||||
*/
|
|
||||||
interface Gradient {
|
|
||||||
value: string;
|
|
||||||
type: string;
|
|
||||||
gradientLine?: string;
|
|
||||||
colorStopList: ColorStopList;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* get gradient type
|
|
||||||
* @param value - gradient value
|
|
||||||
* @returns gradient type
|
|
||||||
*/
|
|
||||||
export declare const getGradientType: (value: string) => string;
|
|
||||||
/**
|
|
||||||
* validate gradient line
|
|
||||||
* @param value - gradient line value
|
|
||||||
* @param type - gradient type
|
|
||||||
* @returns result
|
|
||||||
*/
|
|
||||||
export declare const validateGradientLine: (value: string, type: string) => boolean;
|
|
||||||
/**
|
|
||||||
* validate color stop list
|
|
||||||
* @param list
|
|
||||||
* @param type
|
|
||||||
* @param [opt]
|
|
||||||
* @returns result
|
|
||||||
*/
|
|
||||||
export declare const validateColorStopList: (list: string[], type: string, opt?: Options) => boolean;
|
|
||||||
/**
|
|
||||||
* parse CSS gradient
|
|
||||||
* @param value - gradient value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed result
|
|
||||||
*/
|
|
||||||
export declare const parseGradient: (value: string, opt?: Options) => Gradient | null;
|
|
||||||
/**
|
|
||||||
* is CSS gradient
|
|
||||||
* @param value - CSS value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns result
|
|
||||||
*/
|
|
||||||
export declare const isGradient: (value: string, opt?: Options) => boolean;
|
|
||||||
export {};
|
|
||||||
-195
@@ -1,195 +0,0 @@
|
|||||||
import { createCacheKey, getCache, CacheItem, setCache } from "./cache.js";
|
|
||||||
import { isString } from "./common.js";
|
|
||||||
import { splitValue, isColor } from "./util.js";
|
|
||||||
import { NUM, ANGLE, PCT, LENGTH, CS_RECT, CS_HUE, NUM_POSITIVE } from "./constant.js";
|
|
||||||
const NAMESPACE = "css-gradient";
|
|
||||||
const DIM_ANGLE = `${NUM}(?:${ANGLE})`;
|
|
||||||
const DIM_ANGLE_PCT = `${DIM_ANGLE}|${PCT}`;
|
|
||||||
const DIM_LEN = `${NUM}(?:${LENGTH})|0`;
|
|
||||||
const DIM_LEN_PCT = `${DIM_LEN}|${PCT}`;
|
|
||||||
const DIM_LEN_PCT_POSI = `${NUM_POSITIVE}(?:${LENGTH}|%)|0`;
|
|
||||||
const DIM_LEN_POSI = `${NUM_POSITIVE}(?:${LENGTH})|0`;
|
|
||||||
const CTR = "center";
|
|
||||||
const L_R = "left|right";
|
|
||||||
const T_B = "top|bottom";
|
|
||||||
const S_E = "start|end";
|
|
||||||
const AXIS_X = `${L_R}|x-(?:${S_E})`;
|
|
||||||
const AXIS_Y = `${T_B}|y-(?:${S_E})`;
|
|
||||||
const BLOCK = `block-(?:${S_E})`;
|
|
||||||
const INLINE = `inline-(?:${S_E})`;
|
|
||||||
const POS_1 = `${CTR}|${AXIS_X}|${AXIS_Y}|${BLOCK}|${INLINE}|${DIM_LEN_PCT}`;
|
|
||||||
const POS_2 = [
|
|
||||||
`(?:${CTR}|${AXIS_X})\\s+(?:${CTR}|${AXIS_Y})`,
|
|
||||||
`(?:${CTR}|${AXIS_Y})\\s+(?:${CTR}|${AXIS_X})`,
|
|
||||||
`(?:${CTR}|${AXIS_X}|${DIM_LEN_PCT})\\s+(?:${CTR}|${AXIS_Y}|${DIM_LEN_PCT})`,
|
|
||||||
`(?:${CTR}|${BLOCK})\\s+(?:${CTR}|${INLINE})`,
|
|
||||||
`(?:${CTR}|${INLINE})\\s+(?:${CTR}|${BLOCK})`,
|
|
||||||
`(?:${CTR}|${S_E})\\s+(?:${CTR}|${S_E})`
|
|
||||||
].join("|");
|
|
||||||
const POS_4 = [
|
|
||||||
`(?:${AXIS_X})\\s+(?:${DIM_LEN_PCT})\\s+(?:${AXIS_Y})\\s+(?:${DIM_LEN_PCT})`,
|
|
||||||
`(?:${AXIS_Y})\\s+(?:${DIM_LEN_PCT})\\s+(?:${AXIS_X})\\s+(?:${DIM_LEN_PCT})`,
|
|
||||||
`(?:${BLOCK})\\s+(?:${DIM_LEN_PCT})\\s+(?:${INLINE})\\s+(?:${DIM_LEN_PCT})`,
|
|
||||||
`(?:${INLINE})\\s+(?:${DIM_LEN_PCT})\\s+(?:${BLOCK})\\s+(?:${DIM_LEN_PCT})`,
|
|
||||||
`(?:${S_E})\\s+(?:${DIM_LEN_PCT})\\s+(?:${S_E})\\s+(?:${DIM_LEN_PCT})`
|
|
||||||
].join("|");
|
|
||||||
const RAD_EXTENT = "(?:clos|farth)est-(?:corner|side)";
|
|
||||||
const RAD_SIZE = [
|
|
||||||
`${RAD_EXTENT}(?:\\s+${RAD_EXTENT})?`,
|
|
||||||
`${DIM_LEN_POSI}`,
|
|
||||||
`(?:${DIM_LEN_PCT_POSI})\\s+(?:${DIM_LEN_PCT_POSI})`
|
|
||||||
].join("|");
|
|
||||||
const RAD_SHAPE = "circle|ellipse";
|
|
||||||
const FROM_ANGLE = `from\\s+${DIM_ANGLE}`;
|
|
||||||
const AT_POSITION = `at\\s+(?:${POS_1}|${POS_2}|${POS_4})`;
|
|
||||||
const TO_SIDE_CORNER = `to\\s+(?:(?:${L_R})(?:\\s(?:${T_B}))?|(?:${T_B})(?:\\s(?:${L_R}))?)`;
|
|
||||||
const IN_COLOR_SPACE = `in\\s+(?:${CS_RECT}|${CS_HUE})`;
|
|
||||||
const REG_GRAD = /^(?:repeating-)?(?:conic|linear|radial)-gradient\(/;
|
|
||||||
const REG_GRAD_CAPT = /^((?:repeating-)?(?:conic|linear|radial)-gradient)\(/;
|
|
||||||
const getGradientType = (value) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.trim();
|
|
||||||
if (REG_GRAD.test(value)) {
|
|
||||||
const [, type] = value.match(REG_GRAD_CAPT);
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
};
|
|
||||||
const validateGradientLine = (value, type) => {
|
|
||||||
if (isString(value) && isString(type)) {
|
|
||||||
value = value.trim();
|
|
||||||
type = type.trim();
|
|
||||||
let lineSyntax = "";
|
|
||||||
if (/^(?:repeating-)?linear-gradient$/.test(type)) {
|
|
||||||
lineSyntax = [
|
|
||||||
`(?:${DIM_ANGLE}|${TO_SIDE_CORNER})(?:\\s+${IN_COLOR_SPACE})?`,
|
|
||||||
`${IN_COLOR_SPACE}(?:\\s+(?:${DIM_ANGLE}|${TO_SIDE_CORNER}))?`
|
|
||||||
].join("|");
|
|
||||||
} else if (/^(?:repeating-)?radial-gradient$/.test(type)) {
|
|
||||||
lineSyntax = [
|
|
||||||
`(?:${RAD_SHAPE})(?:\\s+(?:${RAD_SIZE}))?(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`,
|
|
||||||
`(?:${RAD_SIZE})(?:\\s+(?:${RAD_SHAPE}))?(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`,
|
|
||||||
`${AT_POSITION}(?:\\s+${IN_COLOR_SPACE})?`,
|
|
||||||
`${IN_COLOR_SPACE}(?:\\s+${RAD_SHAPE})(?:\\s+(?:${RAD_SIZE}))?(?:\\s+${AT_POSITION})?`,
|
|
||||||
`${IN_COLOR_SPACE}(?:\\s+${RAD_SIZE})(?:\\s+(?:${RAD_SHAPE}))?(?:\\s+${AT_POSITION})?`,
|
|
||||||
`${IN_COLOR_SPACE}(?:\\s+${AT_POSITION})?`
|
|
||||||
].join("|");
|
|
||||||
} else if (/^(?:repeating-)?conic-gradient$/.test(type)) {
|
|
||||||
lineSyntax = [
|
|
||||||
`${FROM_ANGLE}(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`,
|
|
||||||
`${AT_POSITION}(?:\\s+${IN_COLOR_SPACE})?`,
|
|
||||||
`${IN_COLOR_SPACE}(?:\\s+${FROM_ANGLE})?(?:\\s+${AT_POSITION})?`
|
|
||||||
].join("|");
|
|
||||||
}
|
|
||||||
if (lineSyntax) {
|
|
||||||
const reg = new RegExp(`^(?:${lineSyntax})$`);
|
|
||||||
return reg.test(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
const validateColorStopList = (list, type, opt = {}) => {
|
|
||||||
if (Array.isArray(list) && list.length > 1) {
|
|
||||||
const dimension = /^(?:repeating-)?conic-gradient$/.test(type) ? DIM_ANGLE_PCT : DIM_LEN_PCT;
|
|
||||||
const regColorHint = new RegExp(`^(?:${dimension})$`);
|
|
||||||
const regDimension = new RegExp(`(?:\\s+(?:${dimension})){1,2}$`);
|
|
||||||
const arr = [];
|
|
||||||
for (const item of list) {
|
|
||||||
if (isString(item)) {
|
|
||||||
if (regColorHint.test(item)) {
|
|
||||||
arr.push("hint");
|
|
||||||
} else {
|
|
||||||
const color = item.replace(regDimension, "");
|
|
||||||
if (isColor(color, opt)) {
|
|
||||||
arr.push("color");
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const value = arr.join(",");
|
|
||||||
return /^color(?:,(?:hint,)?color)+$/.test(value);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
const parseGradient = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.trim();
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "parseGradient",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
const type = getGradientType(value);
|
|
||||||
const gradValue = value.replace(REG_GRAD, "").replace(/\)$/, "");
|
|
||||||
if (type && gradValue) {
|
|
||||||
const [lineOrColorStop = "", ...colorStops] = splitValue(gradValue, {
|
|
||||||
delimiter: ","
|
|
||||||
});
|
|
||||||
const dimension = /^(?:repeating-)?conic-gradient$/.test(type) ? DIM_ANGLE_PCT : DIM_LEN_PCT;
|
|
||||||
const regDimension = new RegExp(`(?:\\s+(?:${dimension})){1,2}$`);
|
|
||||||
let isColorStop = false;
|
|
||||||
if (regDimension.test(lineOrColorStop)) {
|
|
||||||
const colorStop = lineOrColorStop.replace(regDimension, "");
|
|
||||||
if (isColor(colorStop, opt)) {
|
|
||||||
isColorStop = true;
|
|
||||||
}
|
|
||||||
} else if (isColor(lineOrColorStop, opt)) {
|
|
||||||
isColorStop = true;
|
|
||||||
}
|
|
||||||
if (isColorStop) {
|
|
||||||
colorStops.unshift(lineOrColorStop);
|
|
||||||
const valid = validateColorStopList(colorStops, type, opt);
|
|
||||||
if (valid) {
|
|
||||||
const res = {
|
|
||||||
value,
|
|
||||||
type,
|
|
||||||
colorStopList: colorStops
|
|
||||||
};
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
} else if (colorStops.length > 1) {
|
|
||||||
const gradientLine = lineOrColorStop;
|
|
||||||
const valid = validateGradientLine(gradientLine, type) && validateColorStopList(colorStops, type, opt);
|
|
||||||
if (valid) {
|
|
||||||
const res = {
|
|
||||||
value,
|
|
||||||
type,
|
|
||||||
gradientLine,
|
|
||||||
colorStopList: colorStops
|
|
||||||
};
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
const isGradient = (value, opt = {}) => {
|
|
||||||
const gradient = parseGradient(value, opt);
|
|
||||||
return gradient !== null;
|
|
||||||
};
|
|
||||||
export {
|
|
||||||
getGradientType,
|
|
||||||
isGradient,
|
|
||||||
parseGradient,
|
|
||||||
validateColorStopList,
|
|
||||||
validateGradientLine
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=css-gradient.js.map
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-31
@@ -1,31 +0,0 @@
|
|||||||
import { CSSToken } from '@csstools/css-tokenizer';
|
|
||||||
import { NullObject } from './cache.js';
|
|
||||||
import { Options } from './typedef.js';
|
|
||||||
/**
|
|
||||||
* resolve custom property
|
|
||||||
* @param tokens - CSS tokens
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns result - [tokens, resolvedValue]
|
|
||||||
*/
|
|
||||||
export declare function resolveCustomProperty(tokens: CSSToken[], opt?: Options): [CSSToken[], string];
|
|
||||||
/**
|
|
||||||
* parse tokens
|
|
||||||
* @param tokens - CSS tokens
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed tokens
|
|
||||||
*/
|
|
||||||
export declare function parseTokens(tokens: CSSToken[], opt?: Options): string[] | NullObject;
|
|
||||||
/**
|
|
||||||
* resolve CSS var()
|
|
||||||
* @param value - CSS value including var()
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
export declare function resolveVar(value: string, opt?: Options): string | NullObject;
|
|
||||||
/**
|
|
||||||
* CSS var()
|
|
||||||
* @param value - CSS value including var()
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
export declare const cssVar: (value: string, opt?: Options) => string;
|
|
||||||
-195
@@ -1,195 +0,0 @@
|
|||||||
import { TokenType, tokenize } from "@csstools/css-tokenizer";
|
|
||||||
import { createCacheKey, getCache, CacheItem, setCache, NullObject } from "./cache.js";
|
|
||||||
import { isString } from "./common.js";
|
|
||||||
import { cssCalc } from "./css-calc.js";
|
|
||||||
import { isColor } from "./util.js";
|
|
||||||
import { VAL_SPEC, SYN_FN_VAR, FN_VAR, SYN_FN_CALC } from "./constant.js";
|
|
||||||
const {
|
|
||||||
CloseParen: PAREN_CLOSE,
|
|
||||||
Comment: COMMENT,
|
|
||||||
EOF,
|
|
||||||
Ident: IDENT,
|
|
||||||
Whitespace: W_SPACE
|
|
||||||
} = TokenType;
|
|
||||||
const NAMESPACE = "css-var";
|
|
||||||
const REG_FN_CALC = new RegExp(SYN_FN_CALC);
|
|
||||||
const REG_FN_VAR = new RegExp(SYN_FN_VAR);
|
|
||||||
function resolveCustomProperty(tokens, opt = {}) {
|
|
||||||
if (!Array.isArray(tokens)) {
|
|
||||||
throw new TypeError(`${tokens} is not an array.`);
|
|
||||||
}
|
|
||||||
const { customProperty = {} } = opt;
|
|
||||||
const items = [];
|
|
||||||
while (tokens.length) {
|
|
||||||
const token = tokens.shift();
|
|
||||||
if (!Array.isArray(token)) {
|
|
||||||
throw new TypeError(`${token} is not an array.`);
|
|
||||||
}
|
|
||||||
const [type, value] = token;
|
|
||||||
if (type === PAREN_CLOSE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (value === FN_VAR) {
|
|
||||||
const [restTokens, item] = resolveCustomProperty(tokens, opt);
|
|
||||||
tokens = restTokens;
|
|
||||||
if (item) {
|
|
||||||
items.push(item);
|
|
||||||
}
|
|
||||||
} else if (type === IDENT) {
|
|
||||||
if (value.startsWith("--")) {
|
|
||||||
let item;
|
|
||||||
if (Object.hasOwnProperty.call(customProperty, value)) {
|
|
||||||
item = customProperty[value];
|
|
||||||
} else if (typeof customProperty.callback === "function") {
|
|
||||||
item = customProperty.callback(value);
|
|
||||||
}
|
|
||||||
if (item) {
|
|
||||||
items.push(item);
|
|
||||||
}
|
|
||||||
} else if (value) {
|
|
||||||
items.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let resolveAsColor = false;
|
|
||||||
if (items.length > 1) {
|
|
||||||
const lastValue = items[items.length - 1];
|
|
||||||
resolveAsColor = isColor(lastValue);
|
|
||||||
}
|
|
||||||
let resolvedValue = "";
|
|
||||||
for (let item of items) {
|
|
||||||
item = item.trim();
|
|
||||||
if (REG_FN_VAR.test(item)) {
|
|
||||||
const resolvedItem = resolveVar(item, opt);
|
|
||||||
if (isString(resolvedItem)) {
|
|
||||||
if (resolveAsColor) {
|
|
||||||
if (isColor(resolvedItem)) {
|
|
||||||
resolvedValue = resolvedItem;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resolvedValue = resolvedItem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (REG_FN_CALC.test(item)) {
|
|
||||||
item = cssCalc(item, opt);
|
|
||||||
if (resolveAsColor) {
|
|
||||||
if (isColor(item)) {
|
|
||||||
resolvedValue = item;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resolvedValue = item;
|
|
||||||
}
|
|
||||||
} else if (item && !/^(?:inherit|initial|revert(?:-layer)?|unset)$/.test(item)) {
|
|
||||||
if (resolveAsColor) {
|
|
||||||
if (isColor(item)) {
|
|
||||||
resolvedValue = item;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resolvedValue = item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (resolvedValue) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [tokens, resolvedValue];
|
|
||||||
}
|
|
||||||
function parseTokens(tokens, opt = {}) {
|
|
||||||
const res = [];
|
|
||||||
while (tokens.length) {
|
|
||||||
const token = tokens.shift();
|
|
||||||
const [type = "", value = ""] = token;
|
|
||||||
if (value === FN_VAR) {
|
|
||||||
const [restTokens, resolvedValue] = resolveCustomProperty(tokens, opt);
|
|
||||||
if (!resolvedValue) {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
tokens = restTokens;
|
|
||||||
res.push(resolvedValue);
|
|
||||||
} else {
|
|
||||||
switch (type) {
|
|
||||||
case PAREN_CLOSE: {
|
|
||||||
if (res.length) {
|
|
||||||
const lastValue = res[res.length - 1];
|
|
||||||
if (lastValue === " ") {
|
|
||||||
res.splice(-1, 1, value);
|
|
||||||
} else {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case W_SPACE: {
|
|
||||||
if (res.length) {
|
|
||||||
const lastValue = res[res.length - 1];
|
|
||||||
if (isString(lastValue) && !lastValue.endsWith("(") && lastValue !== " ") {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
if (type !== COMMENT && type !== EOF) {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
function resolveVar(value, opt = {}) {
|
|
||||||
const { format = "" } = opt;
|
|
||||||
if (isString(value)) {
|
|
||||||
if (!REG_FN_VAR.test(value) || format === VAL_SPEC) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
value = value.trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "resolveVar",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return cachedResult;
|
|
||||||
}
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
const tokens = tokenize({ css: value });
|
|
||||||
const values = parseTokens(tokens, opt);
|
|
||||||
if (Array.isArray(values)) {
|
|
||||||
let color = values.join("");
|
|
||||||
if (REG_FN_CALC.test(color)) {
|
|
||||||
color = cssCalc(color, opt);
|
|
||||||
}
|
|
||||||
setCache(cacheKey, color);
|
|
||||||
return color;
|
|
||||||
} else {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const cssVar = (value, opt = {}) => {
|
|
||||||
const resolvedValue = resolveVar(value, opt);
|
|
||||||
if (isString(resolvedValue)) {
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
};
|
|
||||||
export {
|
|
||||||
cssVar,
|
|
||||||
parseTokens,
|
|
||||||
resolveCustomProperty,
|
|
||||||
resolveVar
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=css-var.js.map
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-29
@@ -1,29 +0,0 @@
|
|||||||
import { CSSToken } from '@csstools/css-tokenizer';
|
|
||||||
import { NullObject } from './cache.js';
|
|
||||||
import { ColorChannels, Options, StringColorChannels } from './typedef.js';
|
|
||||||
/**
|
|
||||||
* @type NumberOrStringColorChannels - color channel
|
|
||||||
*/
|
|
||||||
type NumberOrStringColorChannels = ColorChannels & StringColorChannels;
|
|
||||||
/**
|
|
||||||
* resolve relative color channels
|
|
||||||
* @param tokens - CSS tokens
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved color channels
|
|
||||||
*/
|
|
||||||
export declare function resolveColorChannels(tokens: CSSToken[], opt?: Options): NumberOrStringColorChannels | NullObject;
|
|
||||||
/**
|
|
||||||
* extract origin color
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns origin color value
|
|
||||||
*/
|
|
||||||
export declare function extractOriginColor(value: string, opt?: Options): string | NullObject;
|
|
||||||
/**
|
|
||||||
* resolve relative color
|
|
||||||
* @param value - CSS relative color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
export declare function resolveRelativeColor(value: string, opt?: Options): string | NullObject;
|
|
||||||
export {};
|
|
||||||
-487
@@ -1,487 +0,0 @@
|
|||||||
import { SyntaxFlag, color } from "@csstools/css-color-parser";
|
|
||||||
import { parseComponentValue } from "@csstools/css-parser-algorithms";
|
|
||||||
import { TokenType, tokenize } from "@csstools/css-tokenizer";
|
|
||||||
import { createCacheKey, getCache, CacheItem, NullObject, setCache } from "./cache.js";
|
|
||||||
import { convertColorToRgb, NAMED_COLORS } from "./color.js";
|
|
||||||
import { isString, isStringOrNumber } from "./common.js";
|
|
||||||
import { resolveDimension, serializeCalc } from "./css-calc.js";
|
|
||||||
import { resolveColor } from "./resolve.js";
|
|
||||||
import { roundToPrecision } from "./util.js";
|
|
||||||
import { VAL_SPEC, FN_VAR, NONE, SYN_FN_VAR, FN_REL, CS_LAB, CS_LCH, FN_REL_CAPT, SYN_COLOR_TYPE, SYN_MIX, SYN_FN_MATH_START } from "./constant.js";
|
|
||||||
const {
|
|
||||||
CloseParen: PAREN_CLOSE,
|
|
||||||
Comment: COMMENT,
|
|
||||||
Dimension: DIM,
|
|
||||||
EOF,
|
|
||||||
Function: FUNC,
|
|
||||||
Ident: IDENT,
|
|
||||||
Number: NUM,
|
|
||||||
OpenParen: PAREN_OPEN,
|
|
||||||
Percentage: PCT,
|
|
||||||
Whitespace: W_SPACE
|
|
||||||
} = TokenType;
|
|
||||||
const { HasNoneKeywords: KEY_NONE } = SyntaxFlag;
|
|
||||||
const NAMESPACE = "relative-color";
|
|
||||||
const OCT = 8;
|
|
||||||
const DEC = 10;
|
|
||||||
const HEX = 16;
|
|
||||||
const MAX_PCT = 100;
|
|
||||||
const MAX_RGB = 255;
|
|
||||||
const REG_COLOR_CAPT = new RegExp(
|
|
||||||
`^${FN_REL}(${SYN_COLOR_TYPE}|${SYN_MIX})\\s+`
|
|
||||||
);
|
|
||||||
const REG_CS_HSL = /(?:hsla?|hwb)$/;
|
|
||||||
const REG_CS_CIE = new RegExp(`^(?:${CS_LAB}|${CS_LCH})$`);
|
|
||||||
const REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START);
|
|
||||||
const REG_FN_REL = new RegExp(FN_REL);
|
|
||||||
const REG_FN_REL_CAPT = new RegExp(`^${FN_REL_CAPT}`);
|
|
||||||
const REG_FN_REL_START = new RegExp(`^${FN_REL}`);
|
|
||||||
const REG_FN_VAR = new RegExp(SYN_FN_VAR);
|
|
||||||
function resolveColorChannels(tokens, opt = {}) {
|
|
||||||
if (!Array.isArray(tokens)) {
|
|
||||||
throw new TypeError(`${tokens} is not an array.`);
|
|
||||||
}
|
|
||||||
const { colorSpace = "", format = "" } = opt;
|
|
||||||
const colorChannels = /* @__PURE__ */ new Map([
|
|
||||||
["color", ["r", "g", "b", "alpha"]],
|
|
||||||
["hsl", ["h", "s", "l", "alpha"]],
|
|
||||||
["hsla", ["h", "s", "l", "alpha"]],
|
|
||||||
["hwb", ["h", "w", "b", "alpha"]],
|
|
||||||
["lab", ["l", "a", "b", "alpha"]],
|
|
||||||
["lch", ["l", "c", "h", "alpha"]],
|
|
||||||
["oklab", ["l", "a", "b", "alpha"]],
|
|
||||||
["oklch", ["l", "c", "h", "alpha"]],
|
|
||||||
["rgb", ["r", "g", "b", "alpha"]],
|
|
||||||
["rgba", ["r", "g", "b", "alpha"]]
|
|
||||||
]);
|
|
||||||
const colorChannel = colorChannels.get(colorSpace);
|
|
||||||
if (!colorChannel) {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
const mathFunc = /* @__PURE__ */ new Set();
|
|
||||||
const channels = [[], [], [], []];
|
|
||||||
let i = 0;
|
|
||||||
let nest = 0;
|
|
||||||
let func = false;
|
|
||||||
while (tokens.length) {
|
|
||||||
const token = tokens.shift();
|
|
||||||
if (!Array.isArray(token)) {
|
|
||||||
throw new TypeError(`${token} is not an array.`);
|
|
||||||
}
|
|
||||||
const [type, value, , , detail] = token;
|
|
||||||
const channel = channels[i];
|
|
||||||
if (Array.isArray(channel)) {
|
|
||||||
switch (type) {
|
|
||||||
case DIM: {
|
|
||||||
const resolvedValue = resolveDimension(token, opt);
|
|
||||||
if (isString(resolvedValue)) {
|
|
||||||
channel.push(resolvedValue);
|
|
||||||
} else {
|
|
||||||
channel.push(value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FUNC: {
|
|
||||||
channel.push(value);
|
|
||||||
func = true;
|
|
||||||
nest++;
|
|
||||||
if (REG_FN_MATH_START.test(value)) {
|
|
||||||
mathFunc.add(nest);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IDENT: {
|
|
||||||
if (!colorChannel.includes(value)) {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
channel.push(value);
|
|
||||||
if (!func) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NUM: {
|
|
||||||
channel.push(Number(detail == null ? void 0 : detail.value));
|
|
||||||
if (!func) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PAREN_OPEN: {
|
|
||||||
channel.push(value);
|
|
||||||
nest++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PAREN_CLOSE: {
|
|
||||||
if (func) {
|
|
||||||
const lastValue = channel[channel.length - 1];
|
|
||||||
if (lastValue === " ") {
|
|
||||||
channel.splice(-1, 1, value);
|
|
||||||
} else {
|
|
||||||
channel.push(value);
|
|
||||||
}
|
|
||||||
if (mathFunc.has(nest)) {
|
|
||||||
mathFunc.delete(nest);
|
|
||||||
}
|
|
||||||
nest--;
|
|
||||||
if (nest === 0) {
|
|
||||||
func = false;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PCT: {
|
|
||||||
channel.push(Number(detail == null ? void 0 : detail.value) / MAX_PCT);
|
|
||||||
if (!func) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case W_SPACE: {
|
|
||||||
if (channel.length && func) {
|
|
||||||
const lastValue = channel[channel.length - 1];
|
|
||||||
if (typeof lastValue === "number") {
|
|
||||||
channel.push(value);
|
|
||||||
} else if (isString(lastValue) && !lastValue.endsWith("(") && lastValue !== " ") {
|
|
||||||
channel.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
if (type !== COMMENT && type !== EOF && func) {
|
|
||||||
channel.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const channelValues = [];
|
|
||||||
for (const channel of channels) {
|
|
||||||
if (channel.length === 1) {
|
|
||||||
const [resolvedValue] = channel;
|
|
||||||
if (isStringOrNumber(resolvedValue)) {
|
|
||||||
channelValues.push(resolvedValue);
|
|
||||||
}
|
|
||||||
} else if (channel.length) {
|
|
||||||
const resolvedValue = serializeCalc(channel.join(""), {
|
|
||||||
format
|
|
||||||
});
|
|
||||||
channelValues.push(resolvedValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return channelValues;
|
|
||||||
}
|
|
||||||
function extractOriginColor(value, opt = {}) {
|
|
||||||
const { currentColor = "", format = "" } = opt;
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.toLowerCase().trim();
|
|
||||||
if (!value) {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
if (!REG_FN_REL_START.test(value)) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "extractOriginColor",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return cachedResult;
|
|
||||||
}
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
if (/currentcolor/.test(value)) {
|
|
||||||
if (currentColor) {
|
|
||||||
value = value.replace(/currentcolor/g, currentColor);
|
|
||||||
} else {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let colorSpace = "";
|
|
||||||
if (REG_FN_REL_CAPT.test(value)) {
|
|
||||||
[, colorSpace] = value.match(REG_FN_REL_CAPT);
|
|
||||||
}
|
|
||||||
opt.colorSpace = colorSpace;
|
|
||||||
if (REG_COLOR_CAPT.test(value)) {
|
|
||||||
const [, originColor] = value.match(REG_COLOR_CAPT);
|
|
||||||
const [, restValue] = value.split(originColor);
|
|
||||||
if (/^[a-z]+$/.test(originColor)) {
|
|
||||||
if (!/^transparent$/.test(originColor) && !Object.prototype.hasOwnProperty.call(NAMED_COLORS, originColor)) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
} else if (format === VAL_SPEC) {
|
|
||||||
const resolvedOriginColor = resolveColor(originColor, opt);
|
|
||||||
if (isString(resolvedOriginColor)) {
|
|
||||||
value = value.replace(originColor, resolvedOriginColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
const tokens = tokenize({ css: restValue });
|
|
||||||
const channelValues = resolveColorChannels(tokens, opt);
|
|
||||||
if (channelValues instanceof NullObject) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return channelValues;
|
|
||||||
}
|
|
||||||
const [v1, v2, v3, v4] = channelValues;
|
|
||||||
let channelValue = "";
|
|
||||||
if (isStringOrNumber(v4)) {
|
|
||||||
channelValue = ` ${v1} ${v2} ${v3} / ${v4})`;
|
|
||||||
} else {
|
|
||||||
channelValue = ` ${channelValues.join(" ")})`;
|
|
||||||
}
|
|
||||||
if (restValue !== channelValue) {
|
|
||||||
value = value.replace(restValue, channelValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const [, restValue] = value.split(REG_FN_REL_START);
|
|
||||||
const tokens = tokenize({ css: restValue });
|
|
||||||
const originColor = [];
|
|
||||||
let nest = 0;
|
|
||||||
while (tokens.length) {
|
|
||||||
const [type, tokenValue] = tokens.shift();
|
|
||||||
switch (type) {
|
|
||||||
case FUNC:
|
|
||||||
case PAREN_OPEN: {
|
|
||||||
originColor.push(tokenValue);
|
|
||||||
nest++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PAREN_CLOSE: {
|
|
||||||
const lastValue = originColor[originColor.length - 1];
|
|
||||||
if (lastValue === " ") {
|
|
||||||
originColor.splice(-1, 1, tokenValue);
|
|
||||||
} else if (isString(lastValue)) {
|
|
||||||
originColor.push(tokenValue);
|
|
||||||
}
|
|
||||||
nest--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case W_SPACE: {
|
|
||||||
const lastValue = originColor[originColor.length - 1];
|
|
||||||
if (isString(lastValue) && !lastValue.endsWith("(") && lastValue !== " ") {
|
|
||||||
originColor.push(tokenValue);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
if (type !== COMMENT && type !== EOF) {
|
|
||||||
originColor.push(tokenValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (nest === 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const resolvedOriginColor = resolveRelativeColor(
|
|
||||||
originColor.join("").trim(),
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
if (resolvedOriginColor instanceof NullObject) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return resolvedOriginColor;
|
|
||||||
}
|
|
||||||
const channelValues = resolveColorChannels(tokens, opt);
|
|
||||||
if (channelValues instanceof NullObject) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return channelValues;
|
|
||||||
}
|
|
||||||
const [v1, v2, v3, v4] = channelValues;
|
|
||||||
let channelValue = "";
|
|
||||||
if (isStringOrNumber(v4)) {
|
|
||||||
channelValue = ` ${v1} ${v2} ${v3} / ${v4})`;
|
|
||||||
} else {
|
|
||||||
channelValue = ` ${channelValues.join(" ")})`;
|
|
||||||
}
|
|
||||||
value = value.replace(restValue, `${resolvedOriginColor}${channelValue}`);
|
|
||||||
}
|
|
||||||
setCache(cacheKey, value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
function resolveRelativeColor(value, opt = {}) {
|
|
||||||
const { format = "" } = opt;
|
|
||||||
if (isString(value)) {
|
|
||||||
if (REG_FN_VAR.test(value)) {
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
return value;
|
|
||||||
} else {
|
|
||||||
throw new SyntaxError(`Unexpected token ${FN_VAR} found.`);
|
|
||||||
}
|
|
||||||
} else if (!REG_FN_REL.test(value)) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
value = value.toLowerCase().trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "resolveRelativeColor",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return cachedResult;
|
|
||||||
}
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
const originColor = extractOriginColor(value, opt);
|
|
||||||
if (originColor instanceof NullObject) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return originColor;
|
|
||||||
}
|
|
||||||
value = originColor;
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
if (value.startsWith("rgba(")) {
|
|
||||||
value = value.replace(/^rgba\(/, "rgb(");
|
|
||||||
} else if (value.startsWith("hsla(")) {
|
|
||||||
value = value.replace(/^hsla\(/, "hsl(");
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
const tokens = tokenize({ css: value });
|
|
||||||
const components = parseComponentValue(tokens);
|
|
||||||
const parsedComponents = color(components);
|
|
||||||
if (!parsedComponents) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
const {
|
|
||||||
alpha: alphaComponent,
|
|
||||||
channels: channelsComponent,
|
|
||||||
colorNotation,
|
|
||||||
syntaxFlags
|
|
||||||
} = parsedComponents;
|
|
||||||
let alpha;
|
|
||||||
if (Number.isNaN(Number(alphaComponent))) {
|
|
||||||
if (syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE)) {
|
|
||||||
alpha = NONE;
|
|
||||||
} else {
|
|
||||||
alpha = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
alpha = roundToPrecision(Number(alphaComponent), OCT);
|
|
||||||
}
|
|
||||||
let v1;
|
|
||||||
let v2;
|
|
||||||
let v3;
|
|
||||||
[v1, v2, v3] = channelsComponent;
|
|
||||||
let resolvedValue;
|
|
||||||
if (REG_CS_CIE.test(colorNotation)) {
|
|
||||||
const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE);
|
|
||||||
if (Number.isNaN(v1)) {
|
|
||||||
if (hasNone) {
|
|
||||||
v1 = NONE;
|
|
||||||
} else {
|
|
||||||
v1 = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v1 = roundToPrecision(v1, HEX);
|
|
||||||
}
|
|
||||||
if (Number.isNaN(v2)) {
|
|
||||||
if (hasNone) {
|
|
||||||
v2 = NONE;
|
|
||||||
} else {
|
|
||||||
v2 = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v2 = roundToPrecision(v2, HEX);
|
|
||||||
}
|
|
||||||
if (Number.isNaN(v3)) {
|
|
||||||
if (hasNone) {
|
|
||||||
v3 = NONE;
|
|
||||||
} else {
|
|
||||||
v3 = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v3 = roundToPrecision(v3, HEX);
|
|
||||||
}
|
|
||||||
if (alpha === 1) {
|
|
||||||
resolvedValue = `${colorNotation}(${v1} ${v2} ${v3})`;
|
|
||||||
} else {
|
|
||||||
resolvedValue = `${colorNotation}(${v1} ${v2} ${v3} / ${alpha})`;
|
|
||||||
}
|
|
||||||
} else if (REG_CS_HSL.test(colorNotation)) {
|
|
||||||
if (Number.isNaN(v1)) {
|
|
||||||
v1 = 0;
|
|
||||||
}
|
|
||||||
if (Number.isNaN(v2)) {
|
|
||||||
v2 = 0;
|
|
||||||
}
|
|
||||||
if (Number.isNaN(v3)) {
|
|
||||||
v3 = 0;
|
|
||||||
}
|
|
||||||
let [r, g, b] = convertColorToRgb(
|
|
||||||
`${colorNotation}(${v1} ${v2} ${v3} / ${alpha})`
|
|
||||||
);
|
|
||||||
r = roundToPrecision(r / MAX_RGB, DEC);
|
|
||||||
g = roundToPrecision(g / MAX_RGB, DEC);
|
|
||||||
b = roundToPrecision(b / MAX_RGB, DEC);
|
|
||||||
if (alpha === 1) {
|
|
||||||
resolvedValue = `color(srgb ${r} ${g} ${b})`;
|
|
||||||
} else {
|
|
||||||
resolvedValue = `color(srgb ${r} ${g} ${b} / ${alpha})`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const cs = colorNotation === "rgb" ? "srgb" : colorNotation;
|
|
||||||
const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE);
|
|
||||||
if (Number.isNaN(v1)) {
|
|
||||||
if (hasNone) {
|
|
||||||
v1 = NONE;
|
|
||||||
} else {
|
|
||||||
v1 = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v1 = roundToPrecision(v1, DEC);
|
|
||||||
}
|
|
||||||
if (Number.isNaN(v2)) {
|
|
||||||
if (hasNone) {
|
|
||||||
v2 = NONE;
|
|
||||||
} else {
|
|
||||||
v2 = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v2 = roundToPrecision(v2, DEC);
|
|
||||||
}
|
|
||||||
if (Number.isNaN(v3)) {
|
|
||||||
if (hasNone) {
|
|
||||||
v3 = NONE;
|
|
||||||
} else {
|
|
||||||
v3 = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v3 = roundToPrecision(v3, DEC);
|
|
||||||
}
|
|
||||||
if (alpha === 1) {
|
|
||||||
resolvedValue = `color(${cs} ${v1} ${v2} ${v3})`;
|
|
||||||
} else {
|
|
||||||
resolvedValue = `color(${cs} ${v1} ${v2} ${v3} / ${alpha})`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
export {
|
|
||||||
extractOriginColor,
|
|
||||||
resolveColorChannels,
|
|
||||||
resolveRelativeColor
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=relative-color.js.map
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-52
@@ -1,52 +0,0 @@
|
|||||||
import { NullObject } from './cache.js';
|
|
||||||
import { Options } from './typedef.js';
|
|
||||||
/**
|
|
||||||
* resolve color
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved color
|
|
||||||
*/
|
|
||||||
export declare const resolveColor: (value: string, opt?: Options) => string | NullObject;
|
|
||||||
/**
|
|
||||||
* resolve CSS color
|
|
||||||
* @param value
|
|
||||||
* - CSS color value
|
|
||||||
* - system colors are not supported
|
|
||||||
* @param [opt] - options
|
|
||||||
* @param [opt.currentColor]
|
|
||||||
* - color to use for `currentcolor` keyword
|
|
||||||
* - if omitted, it will be treated as a missing color
|
|
||||||
* i.e. `rgb(none none none / none)`
|
|
||||||
* @param [opt.customProperty]
|
|
||||||
* - custom properties
|
|
||||||
* - pair of `--` prefixed property name and value,
|
|
||||||
* e.g. `customProperty: { '--some-color': '#0000ff' }`
|
|
||||||
* - and/or `callback` function to get the value of the custom property,
|
|
||||||
* e.g. `customProperty: { callback: someDeclaration.getPropertyValue }`
|
|
||||||
* @param [opt.dimension]
|
|
||||||
* - dimension, convert relative length to pixels
|
|
||||||
* - pair of unit and it's value as a number in pixels,
|
|
||||||
* e.g. `dimension: { em: 12, rem: 16, vw: 10.26 }`
|
|
||||||
* - and/or `callback` function to get the value as a number in pixels,
|
|
||||||
* e.g. `dimension: { callback: convertUnitToPixel }`
|
|
||||||
* @param [opt.format]
|
|
||||||
* - output format, one of below
|
|
||||||
* - `computedValue` (default), [computed value][139] of the color
|
|
||||||
* - `specifiedValue`, [specified value][140] of the color
|
|
||||||
* - `hex`, hex color notation, i.e. `rrggbb`
|
|
||||||
* - `hexAlpha`, hex color notation with alpha channel, i.e. `#rrggbbaa`
|
|
||||||
* @returns
|
|
||||||
* - one of rgba?(), #rrggbb(aa)?, color-name, '(empty-string)',
|
|
||||||
* color(color-space r g b / alpha), color(color-space x y z / alpha),
|
|
||||||
* lab(l a b / alpha), lch(l c h / alpha), oklab(l a b / alpha),
|
|
||||||
* oklch(l c h / alpha), null
|
|
||||||
* - in `computedValue`, values are numbers, however `rgb()` values are
|
|
||||||
* integers
|
|
||||||
* - in `specifiedValue`, returns `empty string` for unknown and/or invalid
|
|
||||||
* color
|
|
||||||
* - in `hex`, returns `null` for `transparent`, and also returns `null` if
|
|
||||||
* any of `r`, `g`, `b`, `alpha` is not a number
|
|
||||||
* - in `hexAlpha`, returns `#00000000` for `transparent`,
|
|
||||||
* however returns `null` if any of `r`, `g`, `b`, `alpha` is not a number
|
|
||||||
*/
|
|
||||||
export declare const resolve: (value: string, opt?: Options) => string | null;
|
|
||||||
-288
@@ -1,288 +0,0 @@
|
|||||||
import { NullObject, createCacheKey, getCache, CacheItem, setCache } from "./cache.js";
|
|
||||||
import { resolveColorMix, resolveColorFunc, resolveColorValue, convertRgbToHex } from "./color.js";
|
|
||||||
import { isString } from "./common.js";
|
|
||||||
import { cssCalc } from "./css-calc.js";
|
|
||||||
import { resolveVar } from "./css-var.js";
|
|
||||||
import { resolveRelativeColor } from "./relative-color.js";
|
|
||||||
import { VAL_COMP, VAL_SPEC, FN_MIX, FN_COLOR, SYN_FN_VAR, SYN_FN_REL, SYN_FN_CALC } from "./constant.js";
|
|
||||||
const NAMESPACE = "resolve";
|
|
||||||
const RGB_TRANSPARENT = "rgba(0, 0, 0, 0)";
|
|
||||||
const REG_FN_CALC = new RegExp(SYN_FN_CALC);
|
|
||||||
const REG_FN_REL = new RegExp(SYN_FN_REL);
|
|
||||||
const REG_FN_VAR = new RegExp(SYN_FN_VAR);
|
|
||||||
const resolveColor = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const { currentColor = "", format = VAL_COMP, nullable = false } = opt;
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "resolve",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return cachedResult;
|
|
||||||
}
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
if (REG_FN_VAR.test(value)) {
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
setCache(cacheKey, value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
const resolvedValue = resolveVar(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
switch (format) {
|
|
||||||
case "hex":
|
|
||||||
case "hexAlpha": {
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
if (nullable) {
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
const res2 = RGB_TRANSPARENT;
|
|
||||||
setCache(cacheKey, res2);
|
|
||||||
return res2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value = resolvedValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (opt.format !== format) {
|
|
||||||
opt.format = format;
|
|
||||||
}
|
|
||||||
value = value.toLowerCase();
|
|
||||||
if (REG_FN_REL.test(value)) {
|
|
||||||
const resolvedValue = resolveRelativeColor(value, opt);
|
|
||||||
if (format === VAL_COMP) {
|
|
||||||
let res2;
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
if (nullable) {
|
|
||||||
res2 = resolvedValue;
|
|
||||||
} else {
|
|
||||||
res2 = RGB_TRANSPARENT;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res2 = resolvedValue;
|
|
||||||
}
|
|
||||||
setCache(cacheKey, res2);
|
|
||||||
return res2;
|
|
||||||
}
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
let res2 = "";
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
res2 = "";
|
|
||||||
} else {
|
|
||||||
res2 = resolvedValue;
|
|
||||||
}
|
|
||||||
setCache(cacheKey, res2);
|
|
||||||
return res2;
|
|
||||||
}
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
value = "";
|
|
||||||
} else {
|
|
||||||
value = resolvedValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (REG_FN_CALC.test(value)) {
|
|
||||||
value = cssCalc(value, opt);
|
|
||||||
}
|
|
||||||
let cs = "";
|
|
||||||
let r = NaN;
|
|
||||||
let g = NaN;
|
|
||||||
let b = NaN;
|
|
||||||
let alpha = NaN;
|
|
||||||
if (value === "transparent") {
|
|
||||||
switch (format) {
|
|
||||||
case VAL_SPEC: {
|
|
||||||
setCache(cacheKey, value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
case "hex": {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
case "hexAlpha": {
|
|
||||||
const res2 = "#00000000";
|
|
||||||
setCache(cacheKey, res2);
|
|
||||||
return res2;
|
|
||||||
}
|
|
||||||
case VAL_COMP:
|
|
||||||
default: {
|
|
||||||
const res2 = RGB_TRANSPARENT;
|
|
||||||
setCache(cacheKey, res2);
|
|
||||||
return res2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (value === "currentcolor") {
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
setCache(cacheKey, value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
if (currentColor) {
|
|
||||||
let resolvedValue;
|
|
||||||
if (currentColor.startsWith(FN_MIX)) {
|
|
||||||
resolvedValue = resolveColorMix(currentColor, opt);
|
|
||||||
} else if (currentColor.startsWith(FN_COLOR)) {
|
|
||||||
resolvedValue = resolveColorFunc(currentColor, opt);
|
|
||||||
} else {
|
|
||||||
resolvedValue = resolveColorValue(currentColor, opt);
|
|
||||||
}
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
[cs, r, g, b, alpha] = resolvedValue;
|
|
||||||
} else if (format === VAL_COMP) {
|
|
||||||
const res2 = RGB_TRANSPARENT;
|
|
||||||
setCache(cacheKey, res2);
|
|
||||||
return res2;
|
|
||||||
}
|
|
||||||
} else if (format === VAL_SPEC) {
|
|
||||||
if (value.startsWith(FN_MIX)) {
|
|
||||||
const res2 = resolveColorMix(value, opt);
|
|
||||||
setCache(cacheKey, res2);
|
|
||||||
return res2;
|
|
||||||
} else if (value.startsWith(FN_COLOR)) {
|
|
||||||
const [scs, rr, gg, bb, aa] = resolveColorFunc(
|
|
||||||
value,
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
let res2 = "";
|
|
||||||
if (aa === 1) {
|
|
||||||
res2 = `color(${scs} ${rr} ${gg} ${bb})`;
|
|
||||||
} else {
|
|
||||||
res2 = `color(${scs} ${rr} ${gg} ${bb} / ${aa})`;
|
|
||||||
}
|
|
||||||
setCache(cacheKey, res2);
|
|
||||||
return res2;
|
|
||||||
} else {
|
|
||||||
const rgb = resolveColorValue(value, opt);
|
|
||||||
if (isString(rgb)) {
|
|
||||||
setCache(cacheKey, rgb);
|
|
||||||
return rgb;
|
|
||||||
}
|
|
||||||
const [scs, rr, gg, bb, aa] = rgb;
|
|
||||||
let res2 = "";
|
|
||||||
if (scs === "rgb") {
|
|
||||||
if (aa === 1) {
|
|
||||||
res2 = `${scs}(${rr}, ${gg}, ${bb})`;
|
|
||||||
} else {
|
|
||||||
res2 = `${scs}a(${rr}, ${gg}, ${bb}, ${aa})`;
|
|
||||||
}
|
|
||||||
} else if (aa === 1) {
|
|
||||||
res2 = `${scs}(${rr} ${gg} ${bb})`;
|
|
||||||
} else {
|
|
||||||
res2 = `${scs}(${rr} ${gg} ${bb} / ${aa})`;
|
|
||||||
}
|
|
||||||
setCache(cacheKey, res2);
|
|
||||||
return res2;
|
|
||||||
}
|
|
||||||
} else if (value.startsWith(FN_MIX)) {
|
|
||||||
if (/currentcolor/.test(value)) {
|
|
||||||
if (currentColor) {
|
|
||||||
value = value.replace(/currentcolor/g, currentColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (/transparent/.test(value)) {
|
|
||||||
value = value.replace(/transparent/g, RGB_TRANSPARENT);
|
|
||||||
}
|
|
||||||
const resolvedValue = resolveColorMix(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
[cs, r, g, b, alpha] = resolvedValue;
|
|
||||||
} else if (value.startsWith(FN_COLOR)) {
|
|
||||||
const resolvedValue = resolveColorFunc(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
[cs, r, g, b, alpha] = resolvedValue;
|
|
||||||
} else if (value) {
|
|
||||||
const resolvedValue = resolveColorValue(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
[cs, r, g, b, alpha] = resolvedValue;
|
|
||||||
}
|
|
||||||
let res = "";
|
|
||||||
switch (format) {
|
|
||||||
case "hex": {
|
|
||||||
if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b) || Number.isNaN(alpha) || alpha === 0) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
res = convertRgbToHex([r, g, b, 1]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "hexAlpha": {
|
|
||||||
if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b) || Number.isNaN(alpha)) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
res = convertRgbToHex([r, g, b, alpha]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VAL_COMP:
|
|
||||||
default: {
|
|
||||||
switch (cs) {
|
|
||||||
case "rgb": {
|
|
||||||
if (alpha === 1) {
|
|
||||||
res = `${cs}(${r}, ${g}, ${b})`;
|
|
||||||
} else {
|
|
||||||
res = `${cs}a(${r}, ${g}, ${b}, ${alpha})`;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "lab":
|
|
||||||
case "lch":
|
|
||||||
case "oklab":
|
|
||||||
case "oklch": {
|
|
||||||
if (alpha === 1) {
|
|
||||||
res = `${cs}(${r} ${g} ${b})`;
|
|
||||||
} else {
|
|
||||||
res = `${cs}(${r} ${g} ${b} / ${alpha})`;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// color()
|
|
||||||
default: {
|
|
||||||
if (alpha === 1) {
|
|
||||||
res = `color(${cs} ${r} ${g} ${b})`;
|
|
||||||
} else {
|
|
||||||
res = `color(${cs} ${r} ${g} ${b} / ${alpha})`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
const resolve = (value, opt = {}) => {
|
|
||||||
opt.nullable = false;
|
|
||||||
const resolvedValue = resolveColor(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return resolvedValue;
|
|
||||||
};
|
|
||||||
export {
|
|
||||||
resolve,
|
|
||||||
resolveColor
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=resolve.js.map
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-79
@@ -1,79 +0,0 @@
|
|||||||
/**
|
|
||||||
* typedef
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @typedef Options - options
|
|
||||||
* @property [alpha] - enable alpha
|
|
||||||
* @property [colorSpace] - color space
|
|
||||||
* @property [currentColor] - color for currentcolor
|
|
||||||
* @property [customPropeerty] - custom properties
|
|
||||||
* @property [d50] - white point in d50
|
|
||||||
* @property [dimension] - dimension
|
|
||||||
* @property [format] - output format
|
|
||||||
* @property [key] - key
|
|
||||||
*/
|
|
||||||
export interface Options {
|
|
||||||
alpha?: boolean;
|
|
||||||
colorSpace?: string;
|
|
||||||
currentColor?: string;
|
|
||||||
customProperty?: Record<string, string | ((K: string) => string)>;
|
|
||||||
d50?: boolean;
|
|
||||||
delimiter?: string | string[];
|
|
||||||
dimension?: Record<string, number | ((K: string) => number)>;
|
|
||||||
format?: string;
|
|
||||||
nullable?: boolean;
|
|
||||||
preserveComment?: boolean;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @type ColorChannels - color channels
|
|
||||||
*/
|
|
||||||
export type ColorChannels = [x: number, y: number, z: number, alpha: number];
|
|
||||||
/**
|
|
||||||
* @type StringColorChannels - color channels
|
|
||||||
*/
|
|
||||||
export type StringColorChannels = [
|
|
||||||
x: string,
|
|
||||||
y: string,
|
|
||||||
z: string,
|
|
||||||
alpha: string | undefined
|
|
||||||
];
|
|
||||||
/**
|
|
||||||
* @type StringColorSpacedChannels - specified value
|
|
||||||
*/
|
|
||||||
export type StringColorSpacedChannels = [
|
|
||||||
cs: string,
|
|
||||||
x: string,
|
|
||||||
y: string,
|
|
||||||
z: string,
|
|
||||||
alpha: string | undefined
|
|
||||||
];
|
|
||||||
/**
|
|
||||||
* @type ComputedColorChannels - computed value
|
|
||||||
*/
|
|
||||||
export type ComputedColorChannels = [
|
|
||||||
cs: string,
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
alpha: number
|
|
||||||
];
|
|
||||||
/**
|
|
||||||
* @type SpecifiedColorChannels - specified value
|
|
||||||
*/
|
|
||||||
export type SpecifiedColorChannels = [
|
|
||||||
cs: string,
|
|
||||||
x: number | string,
|
|
||||||
y: number | string,
|
|
||||||
z: number | string,
|
|
||||||
alpha: number | string
|
|
||||||
];
|
|
||||||
/**
|
|
||||||
* @type MatchedRegExp - matched regexp array
|
|
||||||
*/
|
|
||||||
export type MatchedRegExp = [
|
|
||||||
match: string,
|
|
||||||
gr1: string,
|
|
||||||
gr2: string,
|
|
||||||
gr3: string,
|
|
||||||
gr4: string
|
|
||||||
];
|
|
||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
import { Options } from './typedef.js';
|
|
||||||
/**
|
|
||||||
* split value
|
|
||||||
* NOTE: comments are stripped, it can be preserved if, in the options param,
|
|
||||||
* `delimiter` is either ',' or '/' and with `preserveComment` set to `true`
|
|
||||||
* @param value - CSS value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns array of values
|
|
||||||
*/
|
|
||||||
export declare const splitValue: (value: string, opt?: Options) => string[];
|
|
||||||
/**
|
|
||||||
* extract dashed-ident tokens
|
|
||||||
* @param value - CSS value
|
|
||||||
* @returns array of dashed-ident tokens
|
|
||||||
*/
|
|
||||||
export declare const extractDashedIdent: (value: string) => string[];
|
|
||||||
/**
|
|
||||||
* is color
|
|
||||||
* @param value - CSS value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns result
|
|
||||||
*/
|
|
||||||
export declare const isColor: (value: unknown, opt?: Options) => boolean;
|
|
||||||
/**
|
|
||||||
* value to JSON string
|
|
||||||
* @param value - CSS value
|
|
||||||
* @param [func] - stringify function
|
|
||||||
* @returns stringified value in JSON notation
|
|
||||||
*/
|
|
||||||
export declare const valueToJsonString: (value: unknown, func?: boolean) => string;
|
|
||||||
/**
|
|
||||||
* round to specified precision
|
|
||||||
* @param value - numeric value
|
|
||||||
* @param bit - minimum bits
|
|
||||||
* @returns rounded value
|
|
||||||
*/
|
|
||||||
export declare const roundToPrecision: (value: number, bit?: number) => number;
|
|
||||||
/**
|
|
||||||
* interpolate hue
|
|
||||||
* @param hueA - hue value
|
|
||||||
* @param hueB - hue value
|
|
||||||
* @param arc - shorter | longer | increasing | decreasing
|
|
||||||
* @returns result - [hueA, hueB]
|
|
||||||
*/
|
|
||||||
export declare const interpolateHue: (hueA: number, hueB: number, arc?: string) => [number, number];
|
|
||||||
-279
@@ -1,279 +0,0 @@
|
|||||||
import { TokenType, tokenize } from "@csstools/css-tokenizer";
|
|
||||||
import { createCacheKey, getCache, CacheItem, setCache } from "./cache.js";
|
|
||||||
import { isString } from "./common.js";
|
|
||||||
import { resolveColor } from "./resolve.js";
|
|
||||||
import { NAMED_COLORS } from "./color.js";
|
|
||||||
import { VAL_SPEC, SYN_COLOR_TYPE, SYN_MIX } from "./constant.js";
|
|
||||||
const {
|
|
||||||
CloseParen: PAREN_CLOSE,
|
|
||||||
Comma: COMMA,
|
|
||||||
Comment: COMMENT,
|
|
||||||
Delim: DELIM,
|
|
||||||
EOF,
|
|
||||||
Function: FUNC,
|
|
||||||
Ident: IDENT,
|
|
||||||
OpenParen: PAREN_OPEN,
|
|
||||||
Whitespace: W_SPACE
|
|
||||||
} = TokenType;
|
|
||||||
const NAMESPACE = "util";
|
|
||||||
const DEC = 10;
|
|
||||||
const HEX = 16;
|
|
||||||
const DEG = 360;
|
|
||||||
const DEG_HALF = 180;
|
|
||||||
const REG_COLOR = new RegExp(`^(?:${SYN_COLOR_TYPE})$`);
|
|
||||||
const REG_FN_COLOR = /^(?:(?:ok)?l(?:ab|ch)|color(?:-mix)?|hsla?|hwb|rgba?|var)\(/;
|
|
||||||
const REG_MIX = new RegExp(SYN_MIX);
|
|
||||||
const splitValue = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const { delimiter = " ", preserveComment = false } = opt;
|
|
||||||
const cacheKey = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "splitValue",
|
|
||||||
value
|
|
||||||
},
|
|
||||||
{
|
|
||||||
delimiter,
|
|
||||||
preserveComment
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
let regDelimiter;
|
|
||||||
if (delimiter === ",") {
|
|
||||||
regDelimiter = /^,$/;
|
|
||||||
} else if (delimiter === "/") {
|
|
||||||
regDelimiter = /^\/$/;
|
|
||||||
} else {
|
|
||||||
regDelimiter = /^\s+$/;
|
|
||||||
}
|
|
||||||
const tokens = tokenize({ css: value });
|
|
||||||
let nest = 0;
|
|
||||||
let str = "";
|
|
||||||
const res = [];
|
|
||||||
while (tokens.length) {
|
|
||||||
const [type, value2] = tokens.shift();
|
|
||||||
switch (type) {
|
|
||||||
case COMMA: {
|
|
||||||
if (regDelimiter.test(value2)) {
|
|
||||||
if (nest === 0) {
|
|
||||||
res.push(str.trim());
|
|
||||||
str = "";
|
|
||||||
} else {
|
|
||||||
str += value2;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
str += value2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DELIM: {
|
|
||||||
if (regDelimiter.test(value2)) {
|
|
||||||
if (nest === 0) {
|
|
||||||
res.push(str.trim());
|
|
||||||
str = "";
|
|
||||||
} else {
|
|
||||||
str += value2;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
str += value2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COMMENT: {
|
|
||||||
if (preserveComment && (delimiter === "," || delimiter === "/")) {
|
|
||||||
str += value2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FUNC:
|
|
||||||
case PAREN_OPEN: {
|
|
||||||
str += value2;
|
|
||||||
nest++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PAREN_CLOSE: {
|
|
||||||
str += value2;
|
|
||||||
nest--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case W_SPACE: {
|
|
||||||
if (regDelimiter.test(value2)) {
|
|
||||||
if (nest === 0) {
|
|
||||||
if (str) {
|
|
||||||
res.push(str.trim());
|
|
||||||
str = "";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
str += " ";
|
|
||||||
}
|
|
||||||
} else if (!str.endsWith(" ")) {
|
|
||||||
str += " ";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
if (type === EOF) {
|
|
||||||
res.push(str.trim());
|
|
||||||
str = "";
|
|
||||||
} else {
|
|
||||||
str += value2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
const extractDashedIdent = (value) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey = createCacheKey({
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: "extractDashedIdent",
|
|
||||||
value
|
|
||||||
});
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item;
|
|
||||||
}
|
|
||||||
const tokens = tokenize({ css: value });
|
|
||||||
const items = /* @__PURE__ */ new Set();
|
|
||||||
while (tokens.length) {
|
|
||||||
const [type, value2] = tokens.shift();
|
|
||||||
if (type === IDENT && value2.startsWith("--")) {
|
|
||||||
items.add(value2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const res = [...items];
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
const isColor = (value, opt = {}) => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.toLowerCase().trim();
|
|
||||||
if (value && isString(value)) {
|
|
||||||
if (/^[a-z]+$/.test(value)) {
|
|
||||||
if (/^(?:currentcolor|transparent)$/.test(value) || Object.prototype.hasOwnProperty.call(NAMED_COLORS, value)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (REG_COLOR.test(value) || REG_MIX.test(value)) {
|
|
||||||
return true;
|
|
||||||
} else if (REG_FN_COLOR.test(value)) {
|
|
||||||
opt.nullable = true;
|
|
||||||
if (!opt.format) {
|
|
||||||
opt.format = VAL_SPEC;
|
|
||||||
}
|
|
||||||
const resolvedValue = resolveColor(value, opt);
|
|
||||||
if (resolvedValue) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
const valueToJsonString = (value, func = false) => {
|
|
||||||
if (typeof value === "undefined") {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
const res = JSON.stringify(value, (_key, val) => {
|
|
||||||
let replacedValue;
|
|
||||||
if (typeof val === "undefined") {
|
|
||||||
replacedValue = null;
|
|
||||||
} else if (typeof val === "function") {
|
|
||||||
if (func) {
|
|
||||||
replacedValue = val.toString().replace(/\s/g, "").substring(0, HEX);
|
|
||||||
} else {
|
|
||||||
replacedValue = val.name;
|
|
||||||
}
|
|
||||||
} else if (val instanceof Map || val instanceof Set) {
|
|
||||||
replacedValue = [...val];
|
|
||||||
} else if (typeof val === "bigint") {
|
|
||||||
replacedValue = val.toString();
|
|
||||||
} else {
|
|
||||||
replacedValue = val;
|
|
||||||
}
|
|
||||||
return replacedValue;
|
|
||||||
});
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
const roundToPrecision = (value, bit = 0) => {
|
|
||||||
if (!Number.isFinite(value)) {
|
|
||||||
throw new TypeError(`${value} is not a finite number.`);
|
|
||||||
}
|
|
||||||
if (!Number.isFinite(bit)) {
|
|
||||||
throw new TypeError(`${bit} is not a finite number.`);
|
|
||||||
} else if (bit < 0 || bit > HEX) {
|
|
||||||
throw new RangeError(`${bit} is not between 0 and ${HEX}.`);
|
|
||||||
}
|
|
||||||
if (bit === 0) {
|
|
||||||
return Math.round(value);
|
|
||||||
}
|
|
||||||
let val;
|
|
||||||
if (bit === HEX) {
|
|
||||||
val = value.toPrecision(6);
|
|
||||||
} else if (bit < DEC) {
|
|
||||||
val = value.toPrecision(4);
|
|
||||||
} else {
|
|
||||||
val = value.toPrecision(5);
|
|
||||||
}
|
|
||||||
return parseFloat(val);
|
|
||||||
};
|
|
||||||
const interpolateHue = (hueA, hueB, arc = "shorter") => {
|
|
||||||
if (!Number.isFinite(hueA)) {
|
|
||||||
throw new TypeError(`${hueA} is not a finite number.`);
|
|
||||||
}
|
|
||||||
if (!Number.isFinite(hueB)) {
|
|
||||||
throw new TypeError(`${hueB} is not a finite number.`);
|
|
||||||
}
|
|
||||||
switch (arc) {
|
|
||||||
case "decreasing": {
|
|
||||||
if (hueB > hueA) {
|
|
||||||
hueA += DEG;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "increasing": {
|
|
||||||
if (hueB < hueA) {
|
|
||||||
hueB += DEG;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "longer": {
|
|
||||||
if (hueB > hueA && hueB < hueA + DEG_HALF) {
|
|
||||||
hueA += DEG;
|
|
||||||
} else if (hueB > hueA + DEG_HALF * -1 && hueB <= hueA) {
|
|
||||||
hueB += DEG;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "shorter":
|
|
||||||
default: {
|
|
||||||
if (hueB > hueA + DEG_HALF) {
|
|
||||||
hueA += DEG;
|
|
||||||
} else if (hueB < hueA + DEG_HALF * -1) {
|
|
||||||
hueB += DEG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [hueA, hueB];
|
|
||||||
};
|
|
||||||
export {
|
|
||||||
extractDashedIdent,
|
|
||||||
interpolateHue,
|
|
||||||
isColor,
|
|
||||||
roundToPrecision,
|
|
||||||
splitValue,
|
|
||||||
valueToJsonString
|
|
||||||
};
|
|
||||||
//# sourceMappingURL=util.js.map
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-81
@@ -1,81 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@asamuzakjp/css-color",
|
|
||||||
"description": "CSS color - Resolve and convert CSS colors.",
|
|
||||||
"author": "asamuzaK",
|
|
||||||
"license": "MIT",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/asamuzaK/cssColor.git"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/asamuzaK/cssColor#readme",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/asamuzaK/cssColor/issues"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist",
|
|
||||||
"src"
|
|
||||||
],
|
|
||||||
"type": "module",
|
|
||||||
"types": "dist/esm/index.d.ts",
|
|
||||||
"module": "dist/esm/index.js",
|
|
||||||
"main": "dist/cjs/index.cjs",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"import": {
|
|
||||||
"types": "./dist/esm/index.d.ts",
|
|
||||||
"default": "./dist/esm/index.js"
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"types": "./dist/cjs/index.d.cts",
|
|
||||||
"default": "./dist/cjs/index.cjs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"./package.json": "./package.json"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@csstools/css-calc": "^2.1.3",
|
|
||||||
"@csstools/css-color-parser": "^3.0.9",
|
|
||||||
"@csstools/css-parser-algorithms": "^3.0.4",
|
|
||||||
"@csstools/css-tokenizer": "^3.0.3",
|
|
||||||
"lru-cache": "^10.4.3"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@tanstack/vite-config": "^0.2.0",
|
|
||||||
"@vitest/coverage-istanbul": "^3.1.4",
|
|
||||||
"esbuild": "^0.25.4",
|
|
||||||
"eslint": "^9.27.0",
|
|
||||||
"eslint-plugin-regexp": "^2.7.0",
|
|
||||||
"globals": "^16.1.0",
|
|
||||||
"knip": "^5.56.0",
|
|
||||||
"neostandard": "^0.12.1",
|
|
||||||
"prettier": "^3.5.3",
|
|
||||||
"publint": "^0.3.12",
|
|
||||||
"rimraf": "^6.0.1",
|
|
||||||
"tsup": "^8.5.0",
|
|
||||||
"typescript": "^5.8.3",
|
|
||||||
"vite": "^6.3.5",
|
|
||||||
"vitest": "^3.1.4"
|
|
||||||
},
|
|
||||||
"packageManager": "pnpm@10.11.0",
|
|
||||||
"pnpm": {
|
|
||||||
"onlyBuiltDependencies": [
|
|
||||||
"esbuild",
|
|
||||||
"unrs-resolver"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"build": "pnpm run clean && pnpm run test && pnpm run knip && pnpm run build:prod && pnpm run build:cjs && pnpm run build:browser && pnpm run publint",
|
|
||||||
"build:browser": "vite build -c ./vite.browser.config.ts",
|
|
||||||
"build:prod": "vite build",
|
|
||||||
"build:cjs": "tsup ./src/index.ts --format=cjs --platform=node --outDir=./dist/cjs/ --sourcemap --dts",
|
|
||||||
"clean": "rimraf ./coverage ./dist",
|
|
||||||
"knip": "knip",
|
|
||||||
"prettier": "prettier . --ignore-unknown --write",
|
|
||||||
"publint": "publint --strict",
|
|
||||||
"test": "pnpm run prettier && pnpm run --stream \"/^test:.*/\"",
|
|
||||||
"test:eslint": "eslint ./src ./test --fix",
|
|
||||||
"test:types": "tsc",
|
|
||||||
"test:unit": "vitest"
|
|
||||||
},
|
|
||||||
"version": "3.2.0"
|
|
||||||
}
|
|
||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
/*!
|
|
||||||
* CSS color - Resolve, parse, convert CSS color.
|
|
||||||
* @license MIT
|
|
||||||
* @copyright asamuzaK (Kazz)
|
|
||||||
* @see {@link https://github.com/asamuzaK/cssColor/blob/main/LICENSE}
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { cssCalc as csscalc } from './js/css-calc';
|
|
||||||
import { isGradient } from './js/css-gradient';
|
|
||||||
import { cssVar } from './js/css-var';
|
|
||||||
import { extractDashedIdent, isColor as iscolor, splitValue } from './js/util';
|
|
||||||
|
|
||||||
export { convert } from './js/convert';
|
|
||||||
export { resolve } from './js/resolve';
|
|
||||||
/* utils */
|
|
||||||
export const utils = {
|
|
||||||
cssCalc: csscalc,
|
|
||||||
cssVar,
|
|
||||||
extractDashedIdent,
|
|
||||||
isColor: iscolor,
|
|
||||||
isGradient,
|
|
||||||
splitValue
|
|
||||||
};
|
|
||||||
/* TODO: remove later */
|
|
||||||
/* alias */
|
|
||||||
export const isColor = utils.isColor;
|
|
||||||
export const cssCalc = utils.cssCalc;
|
|
||||||
-114
@@ -1,114 +0,0 @@
|
|||||||
/**
|
|
||||||
* cache
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { LRUCache } from 'lru-cache';
|
|
||||||
import { Options } from './typedef';
|
|
||||||
import { valueToJsonString } from './util';
|
|
||||||
|
|
||||||
/* numeric constants */
|
|
||||||
const MAX_CACHE = 4096;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CacheItem
|
|
||||||
*/
|
|
||||||
export class CacheItem {
|
|
||||||
/* private */
|
|
||||||
#isNull: boolean;
|
|
||||||
#item: unknown;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* constructor
|
|
||||||
*/
|
|
||||||
constructor(item: unknown, isNull: boolean = false) {
|
|
||||||
this.#item = item;
|
|
||||||
this.#isNull = !!isNull;
|
|
||||||
}
|
|
||||||
|
|
||||||
get item() {
|
|
||||||
return this.#item;
|
|
||||||
}
|
|
||||||
|
|
||||||
get isNull() {
|
|
||||||
return this.#isNull;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NullObject
|
|
||||||
*/
|
|
||||||
export class NullObject extends CacheItem {
|
|
||||||
/**
|
|
||||||
* constructor
|
|
||||||
*/
|
|
||||||
constructor() {
|
|
||||||
super(Symbol('null'), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* lru cache
|
|
||||||
*/
|
|
||||||
export const lruCache = new LRUCache({
|
|
||||||
max: MAX_CACHE
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set cache
|
|
||||||
* @param key - cache key
|
|
||||||
* @param value - value to cache
|
|
||||||
* @returns void
|
|
||||||
*/
|
|
||||||
export const setCache = (key: string, value: unknown): void => {
|
|
||||||
if (key) {
|
|
||||||
if (value === null) {
|
|
||||||
lruCache.set(key, new NullObject());
|
|
||||||
} else if (value instanceof CacheItem) {
|
|
||||||
lruCache.set(key, value);
|
|
||||||
} else {
|
|
||||||
lruCache.set(key, new CacheItem(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get cache
|
|
||||||
* @param key - cache key
|
|
||||||
* @returns cached item or false otherwise
|
|
||||||
*/
|
|
||||||
export const getCache = (key: string): CacheItem | boolean => {
|
|
||||||
if (key && lruCache.has(key)) {
|
|
||||||
const item = lruCache.get(key);
|
|
||||||
if (item instanceof CacheItem) {
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
// delete unexpected cached item
|
|
||||||
lruCache.delete(key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* create cache key
|
|
||||||
* @param keyData - key data
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns cache key
|
|
||||||
*/
|
|
||||||
export const createCacheKey = (
|
|
||||||
keyData: Record<string, string>,
|
|
||||||
opt: Options = {}
|
|
||||||
): string => {
|
|
||||||
const { customProperty = {}, dimension = {} } = opt;
|
|
||||||
let cacheKey = '';
|
|
||||||
if (
|
|
||||||
keyData &&
|
|
||||||
Object.keys(keyData).length &&
|
|
||||||
typeof customProperty.callback !== 'function' &&
|
|
||||||
typeof dimension.callback !== 'function'
|
|
||||||
) {
|
|
||||||
keyData.opt = valueToJsonString(opt);
|
|
||||||
cacheKey = valueToJsonString(keyData);
|
|
||||||
}
|
|
||||||
return cacheKey;
|
|
||||||
};
|
|
||||||
-3459
File diff suppressed because it is too large
Load Diff
-31
@@ -1,31 +0,0 @@
|
|||||||
/**
|
|
||||||
* common
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* numeric constants */
|
|
||||||
const TYPE_FROM = 8;
|
|
||||||
const TYPE_TO = -1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get type
|
|
||||||
* @param o - object to check
|
|
||||||
* @returns type of object
|
|
||||||
*/
|
|
||||||
export const getType = (o: unknown): string =>
|
|
||||||
Object.prototype.toString.call(o).slice(TYPE_FROM, TYPE_TO);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* is string
|
|
||||||
* @param o - object to check
|
|
||||||
* @returns result
|
|
||||||
*/
|
|
||||||
export const isString = (o: unknown): o is string =>
|
|
||||||
typeof o === 'string' || o instanceof String;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* is string or number
|
|
||||||
* @param o - object to check
|
|
||||||
* @returns result
|
|
||||||
*/
|
|
||||||
export const isStringOrNumber = (o: unknown): boolean =>
|
|
||||||
isString(o) || typeof o === 'number';
|
|
||||||
-66
@@ -1,66 +0,0 @@
|
|||||||
/**
|
|
||||||
* constant
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* values and units */
|
|
||||||
const _DIGIT = '(?:0|[1-9]\\d*)';
|
|
||||||
const _COMPARE = 'clamp|max|min';
|
|
||||||
const _EXPO = 'exp|hypot|log|pow|sqrt';
|
|
||||||
const _SIGN = 'abs|sign';
|
|
||||||
const _STEP = 'mod|rem|round';
|
|
||||||
const _TRIG = 'a?(?:cos|sin|tan)|atan2';
|
|
||||||
const _MATH = `${_COMPARE}|${_EXPO}|${_SIGN}|${_STEP}|${_TRIG}`;
|
|
||||||
const _CALC = `calc|${_MATH}`;
|
|
||||||
const _VAR = `var|${_CALC}`;
|
|
||||||
export const ANGLE = 'deg|g?rad|turn';
|
|
||||||
export const LENGTH =
|
|
||||||
'[cm]m|[dls]?v(?:[bhiw]|max|min)|in|p[ctx]|q|r?(?:[cl]h|cap|e[mx]|ic)';
|
|
||||||
export const NUM = `[+-]?(?:${_DIGIT}(?:\\.\\d*)?|\\.\\d+)(?:e-?${_DIGIT})?`;
|
|
||||||
export const NUM_POSITIVE = `\\+?(?:${_DIGIT}(?:\\.\\d*)?|\\.\\d+)(?:e-?${_DIGIT})?`;
|
|
||||||
export const NONE = 'none';
|
|
||||||
export const PCT = `${NUM}%`;
|
|
||||||
export const SYN_FN_CALC = `^(?:${_CALC})\\(|(?<=[*\\/\\s\\(])(?:${_CALC})\\(`;
|
|
||||||
export const SYN_FN_MATH_START = `^(?:${_MATH})\\($`;
|
|
||||||
export const SYN_FN_VAR = '^var\\(|(?<=[*\\/\\s\\(])var\\(';
|
|
||||||
export const SYN_FN_VAR_START = `^(?:${_VAR})\\(`;
|
|
||||||
|
|
||||||
/* colors */
|
|
||||||
const _ALPHA = `(?:\\s*\\/\\s*(?:${NUM}|${PCT}|${NONE}))?`;
|
|
||||||
const _ALPHA_LV3 = `(?:\\s*,\\s*(?:${NUM}|${PCT}))?`;
|
|
||||||
const _COLOR_FUNC = '(?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?';
|
|
||||||
const _COLOR_KEY = '[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}';
|
|
||||||
const _CS_HUE = '(?:ok)?lch|hsl|hwb';
|
|
||||||
const _CS_HUE_ARC = '(?:de|in)creasing|longer|shorter';
|
|
||||||
const _NUM_ANGLE = `${NUM}(?:${ANGLE})?`;
|
|
||||||
const _NUM_ANGLE_NONE = `(?:${NUM}(?:${ANGLE})?|${NONE})`;
|
|
||||||
const _NUM_PCT_NONE = `(?:${NUM}|${PCT}|${NONE})`;
|
|
||||||
export const CS_HUE = `(?:${_CS_HUE})(?:\\s(?:${_CS_HUE_ARC})\\shue)?`;
|
|
||||||
export const CS_HUE_CAPT = `(${_CS_HUE})(?:\\s(${_CS_HUE_ARC})\\shue)?`;
|
|
||||||
export const CS_LAB = '(?:ok)?lab';
|
|
||||||
export const CS_LCH = '(?:ok)?lch';
|
|
||||||
export const CS_SRGB = 'srgb(?:-linear)?';
|
|
||||||
export const CS_RGB = `(?:a98|prophoto)-rgb|display-p3|rec2020|${CS_SRGB}`;
|
|
||||||
export const CS_XYZ = 'xyz(?:-d(?:50|65))?';
|
|
||||||
export const CS_RECT = `${CS_LAB}|${CS_RGB}|${CS_XYZ}`;
|
|
||||||
export const CS_MIX = `${CS_HUE}|${CS_RECT}`;
|
|
||||||
export const FN_COLOR = 'color(';
|
|
||||||
export const FN_MIX = 'color-mix(';
|
|
||||||
export const FN_REL = `(?:${_COLOR_FUNC})\\(\\s*from\\s+`;
|
|
||||||
export const FN_REL_CAPT = `(${_COLOR_FUNC})\\(\\s*from\\s+`;
|
|
||||||
export const FN_VAR = 'var(';
|
|
||||||
export const SYN_FN_COLOR = `(?:${CS_RGB}|${CS_XYZ})(?:\\s+${_NUM_PCT_NONE}){3}${_ALPHA}`;
|
|
||||||
export const SYN_FN_REL = `^${FN_REL}|(?<=[\\s])${FN_REL}`;
|
|
||||||
export const SYN_HSL = `${_NUM_ANGLE_NONE}(?:\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`;
|
|
||||||
export const SYN_HSL_LV3 = `${_NUM_ANGLE}(?:\\s*,\\s*${PCT}){2}${_ALPHA_LV3}`;
|
|
||||||
export const SYN_LCH = `(?:${_NUM_PCT_NONE}\\s+){2}${_NUM_ANGLE_NONE}${_ALPHA}`;
|
|
||||||
export const SYN_MOD = `${_NUM_PCT_NONE}(?:\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`;
|
|
||||||
export const SYN_RGB_LV3 = `(?:${NUM}(?:\\s*,\\s*${NUM}){2}|${PCT}(?:\\s*,\\s*${PCT}){2})${_ALPHA_LV3}`;
|
|
||||||
export const SYN_COLOR_TYPE = `${_COLOR_KEY}|hsla?\\(\\s*${SYN_HSL_LV3}\\s*\\)|rgba?\\(\\s*${SYN_RGB_LV3}\\s*\\)|(?:hsla?|hwb)\\(\\s*${SYN_HSL}\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*${SYN_MOD}\\s*\\)|(?:ok)?lch\\(\\s*${SYN_LCH}\\s*\\)|color\\(\\s*${SYN_FN_COLOR}\\s*\\)`;
|
|
||||||
export const SYN_MIX_PART = `(?:${SYN_COLOR_TYPE})(?:\\s+${PCT})?`;
|
|
||||||
export const SYN_MIX = `color-mix\\(\\s*in\\s+(?:${CS_MIX})\\s*,\\s*${SYN_MIX_PART}\\s*,\\s*${SYN_MIX_PART}\\s*\\)`;
|
|
||||||
export const SYN_MIX_CAPT = `color-mix\\(\\s*in\\s+(${CS_MIX})\\s*,\\s*(${SYN_MIX_PART})\\s*,\\s*(${SYN_MIX_PART})\\s*\\)`;
|
|
||||||
|
|
||||||
/* formats */
|
|
||||||
export const VAL_COMP = 'computedValue';
|
|
||||||
export const VAL_MIX = 'mixValue';
|
|
||||||
export const VAL_SPEC = 'specifiedValue';
|
|
||||||
-469
@@ -1,469 +0,0 @@
|
|||||||
/**
|
|
||||||
* convert
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {
|
|
||||||
CacheItem,
|
|
||||||
NullObject,
|
|
||||||
createCacheKey,
|
|
||||||
getCache,
|
|
||||||
setCache
|
|
||||||
} from './cache';
|
|
||||||
import {
|
|
||||||
convertColorToHsl,
|
|
||||||
convertColorToHwb,
|
|
||||||
convertColorToLab,
|
|
||||||
convertColorToLch,
|
|
||||||
convertColorToOklab,
|
|
||||||
convertColorToOklch,
|
|
||||||
convertColorToRgb,
|
|
||||||
numberToHexString,
|
|
||||||
parseColorFunc,
|
|
||||||
parseColorValue
|
|
||||||
} from './color';
|
|
||||||
import { isString } from './common';
|
|
||||||
import { cssCalc } from './css-calc';
|
|
||||||
import { resolveVar } from './css-var';
|
|
||||||
import { resolveRelativeColor } from './relative-color';
|
|
||||||
import { resolveColor } from './resolve';
|
|
||||||
import { ColorChannels, ComputedColorChannels, Options } from './typedef';
|
|
||||||
|
|
||||||
/* constants */
|
|
||||||
import { SYN_FN_CALC, SYN_FN_REL, SYN_FN_VAR, VAL_COMP } from './constant';
|
|
||||||
const NAMESPACE = 'convert';
|
|
||||||
|
|
||||||
/* regexp */
|
|
||||||
const REG_FN_CALC = new RegExp(SYN_FN_CALC);
|
|
||||||
const REG_FN_REL = new RegExp(SYN_FN_REL);
|
|
||||||
const REG_FN_VAR = new RegExp(SYN_FN_VAR);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* pre process
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns value
|
|
||||||
*/
|
|
||||||
export const preProcess = (
|
|
||||||
value: string,
|
|
||||||
opt: Options = {}
|
|
||||||
): string | NullObject => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.trim();
|
|
||||||
if (!value) {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'preProcess',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return cachedResult as NullObject;
|
|
||||||
}
|
|
||||||
return cachedResult.item as string;
|
|
||||||
}
|
|
||||||
if (REG_FN_VAR.test(value)) {
|
|
||||||
const resolvedValue = resolveVar(value, opt);
|
|
||||||
if (isString(resolvedValue)) {
|
|
||||||
value = resolvedValue;
|
|
||||||
} else {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (REG_FN_REL.test(value)) {
|
|
||||||
const resolvedValue = resolveRelativeColor(value, opt);
|
|
||||||
if (isString(resolvedValue)) {
|
|
||||||
value = resolvedValue;
|
|
||||||
} else {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
} else if (REG_FN_CALC.test(value)) {
|
|
||||||
value = cssCalc(value, opt);
|
|
||||||
}
|
|
||||||
if (value.startsWith('color-mix')) {
|
|
||||||
const clonedOpt = structuredClone(opt);
|
|
||||||
clonedOpt.format = VAL_COMP;
|
|
||||||
clonedOpt.nullable = true;
|
|
||||||
const resolvedValue = resolveColor(value, clonedOpt);
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
setCache(cacheKey, value);
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert number to hex string
|
|
||||||
* @param value - numeric value
|
|
||||||
* @returns hex string: 00..ff
|
|
||||||
*/
|
|
||||||
export const numberToHex = (value: number): string => {
|
|
||||||
const hex = numberToHexString(value);
|
|
||||||
return hex;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert color to hex
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @param [opt.alpha] - enable alpha channel
|
|
||||||
* @returns #rrggbb | #rrggbbaa | null
|
|
||||||
*/
|
|
||||||
export const colorToHex = (value: string, opt: Options = {}): string | null => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const { alpha = false } = opt;
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'colorToHex',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return cachedResult.item as string;
|
|
||||||
}
|
|
||||||
let hex;
|
|
||||||
opt.nullable = true;
|
|
||||||
if (alpha) {
|
|
||||||
opt.format = 'hexAlpha';
|
|
||||||
hex = resolveColor(value, opt);
|
|
||||||
} else {
|
|
||||||
opt.format = 'hex';
|
|
||||||
hex = resolveColor(value, opt);
|
|
||||||
}
|
|
||||||
if (isString(hex)) {
|
|
||||||
setCache(cacheKey, hex);
|
|
||||||
return hex;
|
|
||||||
}
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert color to hsl
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [h, s, l, alpha]
|
|
||||||
*/
|
|
||||||
export const colorToHsl = (value: string, opt: Options = {}): ColorChannels => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'colorToHsl',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item as ColorChannels;
|
|
||||||
}
|
|
||||||
opt.format = 'hsl';
|
|
||||||
const hsl = convertColorToHsl(value, opt) as ColorChannels;
|
|
||||||
setCache(cacheKey, hsl);
|
|
||||||
return hsl;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert color to hwb
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [h, w, b, alpha]
|
|
||||||
*/
|
|
||||||
export const colorToHwb = (value: string, opt: Options = {}): ColorChannels => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'colorToHwb',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item as ColorChannels;
|
|
||||||
}
|
|
||||||
opt.format = 'hwb';
|
|
||||||
const hwb = convertColorToHwb(value, opt) as ColorChannels;
|
|
||||||
setCache(cacheKey, hwb);
|
|
||||||
return hwb;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert color to lab
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [l, a, b, alpha]
|
|
||||||
*/
|
|
||||||
export const colorToLab = (value: string, opt: Options = {}): ColorChannels => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'colorToLab',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item as ColorChannels;
|
|
||||||
}
|
|
||||||
const lab = convertColorToLab(value, opt) as ColorChannels;
|
|
||||||
setCache(cacheKey, lab);
|
|
||||||
return lab;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert color to lch
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [l, c, h, alpha]
|
|
||||||
*/
|
|
||||||
export const colorToLch = (value: string, opt: Options = {}): ColorChannels => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'colorToLch',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item as ColorChannels;
|
|
||||||
}
|
|
||||||
const lch = convertColorToLch(value, opt) as ColorChannels;
|
|
||||||
setCache(cacheKey, lch);
|
|
||||||
return lch;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert color to oklab
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [l, a, b, alpha]
|
|
||||||
*/
|
|
||||||
export const colorToOklab = (
|
|
||||||
value: string,
|
|
||||||
opt: Options = {}
|
|
||||||
): ColorChannels => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'colorToOklab',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item as ColorChannels;
|
|
||||||
}
|
|
||||||
const lab = convertColorToOklab(value, opt) as ColorChannels;
|
|
||||||
setCache(cacheKey, lab);
|
|
||||||
return lab;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert color to oklch
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [l, c, h, alpha]
|
|
||||||
*/
|
|
||||||
export const colorToOklch = (
|
|
||||||
value: string,
|
|
||||||
opt: Options = {}
|
|
||||||
): ColorChannels => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'colorToOklch',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item as ColorChannels;
|
|
||||||
}
|
|
||||||
const lch = convertColorToOklch(value, opt) as ColorChannels;
|
|
||||||
setCache(cacheKey, lch);
|
|
||||||
return lch;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert color to rgb
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [r, g, b, alpha]
|
|
||||||
*/
|
|
||||||
export const colorToRgb = (value: string, opt: Options = {}): ColorChannels => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'colorToRgb',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item as ColorChannels;
|
|
||||||
}
|
|
||||||
const rgb = convertColorToRgb(value, opt) as ColorChannels;
|
|
||||||
setCache(cacheKey, rgb);
|
|
||||||
return rgb;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert color to xyz
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [x, y, z, alpha]
|
|
||||||
*/
|
|
||||||
export const colorToXyz = (value: string, opt: Options = {}): ColorChannels => {
|
|
||||||
if (isString(value)) {
|
|
||||||
const resolvedValue = preProcess(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return [0, 0, 0, 0];
|
|
||||||
}
|
|
||||||
value = resolvedValue.toLowerCase();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'colorToXyz',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item as ColorChannels;
|
|
||||||
}
|
|
||||||
let xyz;
|
|
||||||
if (value.startsWith('color(')) {
|
|
||||||
[, ...xyz] = parseColorFunc(value, opt) as ComputedColorChannels;
|
|
||||||
} else {
|
|
||||||
[, ...xyz] = parseColorValue(value, opt) as ComputedColorChannels;
|
|
||||||
}
|
|
||||||
setCache(cacheKey, xyz);
|
|
||||||
return xyz as ColorChannels;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert color to xyz-d50
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns ColorChannels - [x, y, z, alpha]
|
|
||||||
*/
|
|
||||||
export const colorToXyzD50 = (
|
|
||||||
value: string,
|
|
||||||
opt: Options = {}
|
|
||||||
): ColorChannels => {
|
|
||||||
opt.d50 = true;
|
|
||||||
return colorToXyz(value, opt);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* convert */
|
|
||||||
export const convert = {
|
|
||||||
colorToHex,
|
|
||||||
colorToHsl,
|
|
||||||
colorToHwb,
|
|
||||||
colorToLab,
|
|
||||||
colorToLch,
|
|
||||||
colorToOklab,
|
|
||||||
colorToOklch,
|
|
||||||
colorToRgb,
|
|
||||||
colorToXyz,
|
|
||||||
colorToXyzD50,
|
|
||||||
numberToHex
|
|
||||||
};
|
|
||||||
-965
@@ -1,965 +0,0 @@
|
|||||||
/**
|
|
||||||
* css-calc
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { calc } from '@csstools/css-calc';
|
|
||||||
import { CSSToken, TokenType, tokenize } from '@csstools/css-tokenizer';
|
|
||||||
import {
|
|
||||||
CacheItem,
|
|
||||||
NullObject,
|
|
||||||
createCacheKey,
|
|
||||||
getCache,
|
|
||||||
setCache
|
|
||||||
} from './cache';
|
|
||||||
import { isString, isStringOrNumber } from './common';
|
|
||||||
import { resolveVar } from './css-var';
|
|
||||||
import { roundToPrecision } from './util';
|
|
||||||
import { MatchedRegExp, Options } from './typedef';
|
|
||||||
|
|
||||||
/* constants */
|
|
||||||
import {
|
|
||||||
ANGLE,
|
|
||||||
LENGTH,
|
|
||||||
NUM,
|
|
||||||
SYN_FN_CALC,
|
|
||||||
SYN_FN_MATH_START,
|
|
||||||
SYN_FN_VAR,
|
|
||||||
SYN_FN_VAR_START,
|
|
||||||
VAL_SPEC
|
|
||||||
} from './constant';
|
|
||||||
const {
|
|
||||||
CloseParen: PAREN_CLOSE,
|
|
||||||
Comment: COMMENT,
|
|
||||||
Dimension: DIM,
|
|
||||||
EOF,
|
|
||||||
Function: FUNC,
|
|
||||||
OpenParen: PAREN_OPEN,
|
|
||||||
Whitespace: W_SPACE
|
|
||||||
} = TokenType;
|
|
||||||
const NAMESPACE = 'css-calc';
|
|
||||||
|
|
||||||
/* numeric constants */
|
|
||||||
const TRIA = 3;
|
|
||||||
const HEX = 16;
|
|
||||||
const MAX_PCT = 100;
|
|
||||||
|
|
||||||
/* regexp */
|
|
||||||
const REG_FN_CALC = new RegExp(SYN_FN_CALC);
|
|
||||||
const REG_FN_CALC_NUM = new RegExp(`^calc\\((${NUM})\\)$`);
|
|
||||||
const REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START);
|
|
||||||
const REG_FN_VAR = new RegExp(SYN_FN_VAR);
|
|
||||||
const REG_FN_VAR_START = new RegExp(SYN_FN_VAR_START);
|
|
||||||
const REG_OPERATOR = /\s[*+/-]\s/;
|
|
||||||
const REG_TYPE_DIM = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH})$`);
|
|
||||||
const REG_TYPE_DIM_PCT = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH}|%)$`);
|
|
||||||
const REG_TYPE_PCT = new RegExp(`^(${NUM})%$`);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calclator
|
|
||||||
*/
|
|
||||||
export class Calculator {
|
|
||||||
/* private */
|
|
||||||
// number
|
|
||||||
#hasNum: boolean;
|
|
||||||
#numSum: number[];
|
|
||||||
#numMul: number[];
|
|
||||||
// percentage
|
|
||||||
#hasPct: boolean;
|
|
||||||
#pctSum: number[];
|
|
||||||
#pctMul: number[];
|
|
||||||
// dimension
|
|
||||||
#hasDim: boolean;
|
|
||||||
#dimSum: string[];
|
|
||||||
#dimSub: string[];
|
|
||||||
#dimMul: string[];
|
|
||||||
#dimDiv: string[];
|
|
||||||
// et cetra
|
|
||||||
#hasEtc: boolean;
|
|
||||||
#etcSum: string[];
|
|
||||||
#etcSub: string[];
|
|
||||||
#etcMul: string[];
|
|
||||||
#etcDiv: string[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* constructor
|
|
||||||
*/
|
|
||||||
constructor() {
|
|
||||||
// number
|
|
||||||
this.#hasNum = false;
|
|
||||||
this.#numSum = [];
|
|
||||||
this.#numMul = [];
|
|
||||||
// percentage
|
|
||||||
this.#hasPct = false;
|
|
||||||
this.#pctSum = [];
|
|
||||||
this.#pctMul = [];
|
|
||||||
// dimension
|
|
||||||
this.#hasDim = false;
|
|
||||||
this.#dimSum = [];
|
|
||||||
this.#dimSub = [];
|
|
||||||
this.#dimMul = [];
|
|
||||||
this.#dimDiv = [];
|
|
||||||
// et cetra
|
|
||||||
this.#hasEtc = false;
|
|
||||||
this.#etcSum = [];
|
|
||||||
this.#etcSub = [];
|
|
||||||
this.#etcMul = [];
|
|
||||||
this.#etcDiv = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
get hasNum() {
|
|
||||||
return this.#hasNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
set hasNum(value: boolean) {
|
|
||||||
this.#hasNum = !!value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get numSum() {
|
|
||||||
return this.#numSum;
|
|
||||||
}
|
|
||||||
|
|
||||||
get numMul() {
|
|
||||||
return this.#numMul;
|
|
||||||
}
|
|
||||||
|
|
||||||
get hasPct() {
|
|
||||||
return this.#hasPct;
|
|
||||||
}
|
|
||||||
|
|
||||||
set hasPct(value: boolean) {
|
|
||||||
this.#hasPct = !!value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get pctSum() {
|
|
||||||
return this.#pctSum;
|
|
||||||
}
|
|
||||||
|
|
||||||
get pctMul() {
|
|
||||||
return this.#pctMul;
|
|
||||||
}
|
|
||||||
|
|
||||||
get hasDim() {
|
|
||||||
return this.#hasDim;
|
|
||||||
}
|
|
||||||
|
|
||||||
set hasDim(value: boolean) {
|
|
||||||
this.#hasDim = !!value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get dimSum() {
|
|
||||||
return this.#dimSum;
|
|
||||||
}
|
|
||||||
|
|
||||||
get dimSub() {
|
|
||||||
return this.#dimSub;
|
|
||||||
}
|
|
||||||
|
|
||||||
get dimMul() {
|
|
||||||
return this.#dimMul;
|
|
||||||
}
|
|
||||||
|
|
||||||
get dimDiv() {
|
|
||||||
return this.#dimDiv;
|
|
||||||
}
|
|
||||||
|
|
||||||
get hasEtc() {
|
|
||||||
return this.#hasEtc;
|
|
||||||
}
|
|
||||||
|
|
||||||
set hasEtc(value: boolean) {
|
|
||||||
this.#hasEtc = !!value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get etcSum() {
|
|
||||||
return this.#etcSum;
|
|
||||||
}
|
|
||||||
|
|
||||||
get etcSub() {
|
|
||||||
return this.#etcSub;
|
|
||||||
}
|
|
||||||
|
|
||||||
get etcMul() {
|
|
||||||
return this.#etcMul;
|
|
||||||
}
|
|
||||||
|
|
||||||
get etcDiv() {
|
|
||||||
return this.#etcDiv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* clear values
|
|
||||||
* @returns void
|
|
||||||
*/
|
|
||||||
clear() {
|
|
||||||
// number
|
|
||||||
this.#hasNum = false;
|
|
||||||
this.#numSum = [];
|
|
||||||
this.#numMul = [];
|
|
||||||
// percentage
|
|
||||||
this.#hasPct = false;
|
|
||||||
this.#pctSum = [];
|
|
||||||
this.#pctMul = [];
|
|
||||||
// dimension
|
|
||||||
this.#hasDim = false;
|
|
||||||
this.#dimSum = [];
|
|
||||||
this.#dimSub = [];
|
|
||||||
this.#dimMul = [];
|
|
||||||
this.#dimDiv = [];
|
|
||||||
// et cetra
|
|
||||||
this.#hasEtc = false;
|
|
||||||
this.#etcSum = [];
|
|
||||||
this.#etcSub = [];
|
|
||||||
this.#etcMul = [];
|
|
||||||
this.#etcDiv = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sort values
|
|
||||||
* @param values - values
|
|
||||||
* @returns sorted values
|
|
||||||
*/
|
|
||||||
sort(values: string[] = []): string[] {
|
|
||||||
const arr = [...values];
|
|
||||||
if (arr.length > 1) {
|
|
||||||
arr.sort((a, b) => {
|
|
||||||
let res;
|
|
||||||
if (REG_TYPE_DIM_PCT.test(a) && REG_TYPE_DIM_PCT.test(b)) {
|
|
||||||
const [, valA, unitA] = a.match(REG_TYPE_DIM_PCT) as MatchedRegExp;
|
|
||||||
const [, valB, unitB] = b.match(REG_TYPE_DIM_PCT) as MatchedRegExp;
|
|
||||||
if (unitA === unitB) {
|
|
||||||
if (Number(valA) === Number(valB)) {
|
|
||||||
res = 0;
|
|
||||||
} else if (Number(valA) > Number(valB)) {
|
|
||||||
res = 1;
|
|
||||||
} else {
|
|
||||||
res = -1;
|
|
||||||
}
|
|
||||||
} else if (unitA > unitB) {
|
|
||||||
res = 1;
|
|
||||||
} else {
|
|
||||||
res = -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (a === b) {
|
|
||||||
res = 0;
|
|
||||||
} else if (a > b) {
|
|
||||||
res = 1;
|
|
||||||
} else {
|
|
||||||
res = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* multiply values
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
multiply(): string {
|
|
||||||
const value = [];
|
|
||||||
let num;
|
|
||||||
if (this.#hasNum) {
|
|
||||||
num = 1;
|
|
||||||
for (const i of this.#numMul) {
|
|
||||||
num *= i;
|
|
||||||
if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!this.#hasPct && !this.#hasDim && !this.hasEtc) {
|
|
||||||
if (Number.isFinite(num)) {
|
|
||||||
num = roundToPrecision(num, HEX);
|
|
||||||
}
|
|
||||||
value.push(num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.#hasPct) {
|
|
||||||
if (typeof num !== 'number') {
|
|
||||||
num = 1;
|
|
||||||
}
|
|
||||||
for (const i of this.#pctMul) {
|
|
||||||
num *= i;
|
|
||||||
if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Number.isFinite(num)) {
|
|
||||||
num = `${roundToPrecision(num, HEX)}%`;
|
|
||||||
}
|
|
||||||
if (!this.#hasDim && !this.hasEtc) {
|
|
||||||
value.push(num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.#hasDim) {
|
|
||||||
let dim = '';
|
|
||||||
let mul = '';
|
|
||||||
let div = '';
|
|
||||||
if (this.#dimMul.length) {
|
|
||||||
if (this.#dimMul.length === 1) {
|
|
||||||
[mul] = this.#dimMul as [string];
|
|
||||||
} else {
|
|
||||||
mul = `${this.sort(this.#dimMul).join(' * ')}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.#dimDiv.length) {
|
|
||||||
if (this.#dimDiv.length === 1) {
|
|
||||||
[div] = this.#dimDiv as [string];
|
|
||||||
} else {
|
|
||||||
div = `${this.sort(this.#dimDiv).join(' * ')}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Number.isFinite(num)) {
|
|
||||||
if (mul) {
|
|
||||||
if (div) {
|
|
||||||
if (div.includes('*')) {
|
|
||||||
dim = calc(`calc(${num} * ${mul} / (${div}))`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${num} * ${mul} / ${div})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${num} * ${mul})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (div.includes('*')) {
|
|
||||||
dim = calc(`calc(${num} / (${div}))`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${num} / ${div})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
value.push(dim.replace(/^calc/, ''));
|
|
||||||
} else {
|
|
||||||
if (!value.length && num !== undefined) {
|
|
||||||
value.push(num);
|
|
||||||
}
|
|
||||||
if (mul) {
|
|
||||||
if (div) {
|
|
||||||
if (div.includes('*')) {
|
|
||||||
dim = calc(`calc(${mul} / (${div}))`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${mul} / ${div})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${mul})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (value.length) {
|
|
||||||
value.push('*', dim.replace(/^calc/, ''));
|
|
||||||
} else {
|
|
||||||
value.push(dim.replace(/^calc/, ''));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${div})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
if (value.length) {
|
|
||||||
value.push('/', dim.replace(/^calc/, ''));
|
|
||||||
} else {
|
|
||||||
value.push('1', '/', dim.replace(/^calc/, ''));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.#hasEtc) {
|
|
||||||
if (this.#etcMul.length) {
|
|
||||||
if (!value.length && num !== undefined) {
|
|
||||||
value.push(num);
|
|
||||||
}
|
|
||||||
const mul = this.sort(this.#etcMul).join(' * ');
|
|
||||||
if (value.length) {
|
|
||||||
value.push(`* ${mul}`);
|
|
||||||
} else {
|
|
||||||
value.push(`${mul}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.#etcDiv.length) {
|
|
||||||
const div = this.sort(this.#etcDiv).join(' * ');
|
|
||||||
if (div.includes('*')) {
|
|
||||||
if (value.length) {
|
|
||||||
value.push(`/ (${div})`);
|
|
||||||
} else {
|
|
||||||
value.push(`1 / (${div})`);
|
|
||||||
}
|
|
||||||
} else if (value.length) {
|
|
||||||
value.push(`/ ${div}`);
|
|
||||||
} else {
|
|
||||||
value.push(`1 / ${div}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (value.length) {
|
|
||||||
return value.join(' ');
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sum values
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
sum(): string {
|
|
||||||
const value = [];
|
|
||||||
if (this.#hasNum) {
|
|
||||||
let num = 0;
|
|
||||||
for (const i of this.#numSum) {
|
|
||||||
num += i;
|
|
||||||
if (!Number.isFinite(num) || Number.isNaN(num)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
value.push(num);
|
|
||||||
}
|
|
||||||
if (this.#hasPct) {
|
|
||||||
let num: number | string = 0;
|
|
||||||
for (const i of this.#pctSum) {
|
|
||||||
num += i;
|
|
||||||
if (!Number.isFinite(num)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Number.isFinite(num)) {
|
|
||||||
num = `${num}%`;
|
|
||||||
}
|
|
||||||
if (value.length) {
|
|
||||||
value.push(`+ ${num}`);
|
|
||||||
} else {
|
|
||||||
value.push(num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.#hasDim) {
|
|
||||||
let dim, sum, sub;
|
|
||||||
if (this.#dimSum.length) {
|
|
||||||
sum = this.sort(this.#dimSum).join(' + ');
|
|
||||||
}
|
|
||||||
if (this.#dimSub.length) {
|
|
||||||
sub = this.sort(this.#dimSub).join(' + ');
|
|
||||||
}
|
|
||||||
if (sum) {
|
|
||||||
if (sub) {
|
|
||||||
if (sub.includes('-')) {
|
|
||||||
dim = calc(`calc(${sum} - (${sub}))`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${sum} - ${sub})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(${sum})`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dim = calc(`calc(-1 * (${sub}))`, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (value.length) {
|
|
||||||
value.push('+', dim.replace(/^calc/, ''));
|
|
||||||
} else {
|
|
||||||
value.push(dim.replace(/^calc/, ''));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.#hasEtc) {
|
|
||||||
if (this.#etcSum.length) {
|
|
||||||
const sum = this.sort(this.#etcSum)
|
|
||||||
.map(item => {
|
|
||||||
let res;
|
|
||||||
if (
|
|
||||||
REG_OPERATOR.test(item) &&
|
|
||||||
!item.startsWith('(') &&
|
|
||||||
!item.endsWith(')')
|
|
||||||
) {
|
|
||||||
res = `(${item})`;
|
|
||||||
} else {
|
|
||||||
res = item;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
})
|
|
||||||
.join(' + ');
|
|
||||||
if (value.length) {
|
|
||||||
if (this.#etcSum.length > 1) {
|
|
||||||
value.push(`+ (${sum})`);
|
|
||||||
} else {
|
|
||||||
value.push(`+ ${sum}`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value.push(`${sum}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.#etcSub.length) {
|
|
||||||
const sub = this.sort(this.#etcSub)
|
|
||||||
.map(item => {
|
|
||||||
let res;
|
|
||||||
if (
|
|
||||||
REG_OPERATOR.test(item) &&
|
|
||||||
!item.startsWith('(') &&
|
|
||||||
!item.endsWith(')')
|
|
||||||
) {
|
|
||||||
res = `(${item})`;
|
|
||||||
} else {
|
|
||||||
res = item;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
})
|
|
||||||
.join(' + ');
|
|
||||||
if (value.length) {
|
|
||||||
if (this.#etcSub.length > 1) {
|
|
||||||
value.push(`- (${sub})`);
|
|
||||||
} else {
|
|
||||||
value.push(`- ${sub}`);
|
|
||||||
}
|
|
||||||
} else if (this.#etcSub.length > 1) {
|
|
||||||
value.push(`-1 * (${sub})`);
|
|
||||||
} else {
|
|
||||||
value.push(`-1 * ${sub}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (value.length) {
|
|
||||||
return value.join(' ');
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sort calc values
|
|
||||||
* @param values - values to sort
|
|
||||||
* @param [finalize] - finalize values
|
|
||||||
* @returns sorted values
|
|
||||||
*/
|
|
||||||
export const sortCalcValues = (
|
|
||||||
values: (number | string)[] = [],
|
|
||||||
finalize: boolean = false
|
|
||||||
): string => {
|
|
||||||
if (values.length < TRIA) {
|
|
||||||
throw new Error(`Unexpected array length ${values.length}.`);
|
|
||||||
}
|
|
||||||
const start = values.shift();
|
|
||||||
if (!isString(start) || !start.endsWith('(')) {
|
|
||||||
throw new Error(`Unexpected token ${start}.`);
|
|
||||||
}
|
|
||||||
const end = values.pop();
|
|
||||||
if (end !== ')') {
|
|
||||||
throw new Error(`Unexpected token ${end}.`);
|
|
||||||
}
|
|
||||||
if (values.length === 1) {
|
|
||||||
const [value] = values;
|
|
||||||
if (!isStringOrNumber(value)) {
|
|
||||||
throw new Error(`Unexpected token ${value}.`);
|
|
||||||
}
|
|
||||||
return `${start}${value}${end}`;
|
|
||||||
}
|
|
||||||
const sortedValues = [];
|
|
||||||
const cal = new Calculator();
|
|
||||||
let operator: string = '';
|
|
||||||
const l = values.length;
|
|
||||||
for (let i = 0; i < l; i++) {
|
|
||||||
const value = values[i];
|
|
||||||
if (!isStringOrNumber(value)) {
|
|
||||||
throw new Error(`Unexpected token ${value}.`);
|
|
||||||
}
|
|
||||||
if (value === '*' || value === '/') {
|
|
||||||
operator = value;
|
|
||||||
} else if (value === '+' || value === '-') {
|
|
||||||
const sortedValue = cal.multiply();
|
|
||||||
if (sortedValue) {
|
|
||||||
sortedValues.push(sortedValue, value);
|
|
||||||
}
|
|
||||||
cal.clear();
|
|
||||||
operator = '';
|
|
||||||
} else {
|
|
||||||
const numValue = Number(value);
|
|
||||||
const strValue = `${value}`;
|
|
||||||
switch (operator) {
|
|
||||||
case '/': {
|
|
||||||
if (Number.isFinite(numValue)) {
|
|
||||||
cal.hasNum = true;
|
|
||||||
cal.numMul.push(1 / numValue);
|
|
||||||
} else if (REG_TYPE_PCT.test(strValue)) {
|
|
||||||
const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp;
|
|
||||||
cal.hasPct = true;
|
|
||||||
cal.pctMul.push((MAX_PCT * MAX_PCT) / Number(val));
|
|
||||||
} else if (REG_TYPE_DIM.test(strValue)) {
|
|
||||||
cal.hasDim = true;
|
|
||||||
cal.dimDiv.push(strValue);
|
|
||||||
} else {
|
|
||||||
cal.hasEtc = true;
|
|
||||||
cal.etcDiv.push(strValue);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '*':
|
|
||||||
default: {
|
|
||||||
if (Number.isFinite(numValue)) {
|
|
||||||
cal.hasNum = true;
|
|
||||||
cal.numMul.push(numValue);
|
|
||||||
} else if (REG_TYPE_PCT.test(strValue)) {
|
|
||||||
const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp;
|
|
||||||
cal.hasPct = true;
|
|
||||||
cal.pctMul.push(Number(val));
|
|
||||||
} else if (REG_TYPE_DIM.test(strValue)) {
|
|
||||||
cal.hasDim = true;
|
|
||||||
cal.dimMul.push(strValue);
|
|
||||||
} else {
|
|
||||||
cal.hasEtc = true;
|
|
||||||
cal.etcMul.push(strValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i === l - 1) {
|
|
||||||
const sortedValue = cal.multiply();
|
|
||||||
if (sortedValue) {
|
|
||||||
sortedValues.push(sortedValue);
|
|
||||||
}
|
|
||||||
cal.clear();
|
|
||||||
operator = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let resolvedValue = '';
|
|
||||||
if (finalize && (sortedValues.includes('+') || sortedValues.includes('-'))) {
|
|
||||||
const finalizedValues = [];
|
|
||||||
cal.clear();
|
|
||||||
operator = '';
|
|
||||||
const l = sortedValues.length;
|
|
||||||
for (let i = 0; i < l; i++) {
|
|
||||||
const value = sortedValues[i];
|
|
||||||
if (isStringOrNumber(value)) {
|
|
||||||
if (value === '+' || value === '-') {
|
|
||||||
operator = value;
|
|
||||||
} else {
|
|
||||||
const numValue = Number(value);
|
|
||||||
const strValue = `${value}`;
|
|
||||||
switch (operator) {
|
|
||||||
case '-': {
|
|
||||||
if (Number.isFinite(numValue)) {
|
|
||||||
cal.hasNum = true;
|
|
||||||
cal.numSum.push(-1 * numValue);
|
|
||||||
} else if (REG_TYPE_PCT.test(strValue)) {
|
|
||||||
const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp;
|
|
||||||
cal.hasPct = true;
|
|
||||||
cal.pctSum.push(-1 * Number(val));
|
|
||||||
} else if (REG_TYPE_DIM.test(strValue)) {
|
|
||||||
cal.hasDim = true;
|
|
||||||
cal.dimSub.push(strValue);
|
|
||||||
} else {
|
|
||||||
cal.hasEtc = true;
|
|
||||||
cal.etcSub.push(strValue);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '+':
|
|
||||||
default: {
|
|
||||||
if (Number.isFinite(numValue)) {
|
|
||||||
cal.hasNum = true;
|
|
||||||
cal.numSum.push(numValue);
|
|
||||||
} else if (REG_TYPE_PCT.test(strValue)) {
|
|
||||||
const [, val] = strValue.match(REG_TYPE_PCT) as MatchedRegExp;
|
|
||||||
cal.hasPct = true;
|
|
||||||
cal.pctSum.push(Number(val));
|
|
||||||
} else if (REG_TYPE_DIM.test(strValue)) {
|
|
||||||
cal.hasDim = true;
|
|
||||||
cal.dimSum.push(strValue);
|
|
||||||
} else {
|
|
||||||
cal.hasEtc = true;
|
|
||||||
cal.etcSum.push(strValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i === l - 1) {
|
|
||||||
const sortedValue = cal.sum();
|
|
||||||
if (sortedValue) {
|
|
||||||
finalizedValues.push(sortedValue);
|
|
||||||
}
|
|
||||||
cal.clear();
|
|
||||||
operator = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resolvedValue = finalizedValues.join(' ').replace(/\+\s-/g, '- ');
|
|
||||||
} else {
|
|
||||||
resolvedValue = sortedValues.join(' ').replace(/\+\s-/g, '- ');
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
resolvedValue.startsWith('(') &&
|
|
||||||
resolvedValue.endsWith(')') &&
|
|
||||||
resolvedValue.lastIndexOf('(') === 0 &&
|
|
||||||
resolvedValue.indexOf(')') === resolvedValue.length - 1
|
|
||||||
) {
|
|
||||||
resolvedValue = resolvedValue.replace(/^\(/, '').replace(/\)$/, '');
|
|
||||||
}
|
|
||||||
return `${start}${resolvedValue}${end}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* serialize calc
|
|
||||||
* @param value - CSS value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns serialized value
|
|
||||||
*/
|
|
||||||
export const serializeCalc = (value: string, opt: Options = {}): string => {
|
|
||||||
const { format = '' } = opt;
|
|
||||||
if (isString(value)) {
|
|
||||||
if (!REG_FN_VAR_START.test(value) || format !== VAL_SPEC) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
value = value.toLowerCase().trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'serializeCalc',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item as string;
|
|
||||||
}
|
|
||||||
const items: string[] = tokenize({ css: value })
|
|
||||||
.map((token: CSSToken): string => {
|
|
||||||
const [type, value] = token as [TokenType, string];
|
|
||||||
let res = '';
|
|
||||||
if (type !== W_SPACE && type !== COMMENT) {
|
|
||||||
res = value;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
})
|
|
||||||
.filter(v => v);
|
|
||||||
let startIndex = items.findLastIndex((item: string) => /\($/.test(item));
|
|
||||||
while (startIndex) {
|
|
||||||
const endIndex = items.findIndex((item: unknown, index: number) => {
|
|
||||||
return item === ')' && index > startIndex;
|
|
||||||
});
|
|
||||||
const slicedValues: string[] = items.slice(startIndex, endIndex + 1);
|
|
||||||
let serializedValue: string = sortCalcValues(slicedValues);
|
|
||||||
if (REG_FN_VAR_START.test(serializedValue)) {
|
|
||||||
serializedValue = calc(serializedValue, {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
items.splice(startIndex, endIndex - startIndex + 1, serializedValue);
|
|
||||||
startIndex = items.findLastIndex((item: string) => /\($/.test(item));
|
|
||||||
}
|
|
||||||
const serializedCalc = sortCalcValues(items, true);
|
|
||||||
setCache(cacheKey, serializedCalc);
|
|
||||||
return serializedCalc;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resolve dimension
|
|
||||||
* @param token - CSS token
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
export const resolveDimension = (
|
|
||||||
token: CSSToken,
|
|
||||||
opt: Options = {}
|
|
||||||
): string | NullObject => {
|
|
||||||
if (!Array.isArray(token)) {
|
|
||||||
throw new TypeError(`${token} is not an array.`);
|
|
||||||
}
|
|
||||||
const [, , , , detail = {}] = token;
|
|
||||||
const { unit, value } = detail as {
|
|
||||||
unit: string;
|
|
||||||
value: number;
|
|
||||||
};
|
|
||||||
const { dimension = {} } = opt;
|
|
||||||
if (unit === 'px') {
|
|
||||||
return `${value}${unit}`;
|
|
||||||
}
|
|
||||||
const relativeValue = Number(value);
|
|
||||||
if (unit && Number.isFinite(relativeValue)) {
|
|
||||||
let pixelValue;
|
|
||||||
if (Object.hasOwnProperty.call(dimension, unit)) {
|
|
||||||
pixelValue = dimension[unit];
|
|
||||||
} else if (typeof dimension.callback === 'function') {
|
|
||||||
pixelValue = dimension.callback(unit);
|
|
||||||
}
|
|
||||||
pixelValue = Number(pixelValue);
|
|
||||||
if (Number.isFinite(pixelValue)) {
|
|
||||||
return `${relativeValue * pixelValue}px`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new NullObject();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* parse tokens
|
|
||||||
* @param tokens - CSS tokens
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed tokens
|
|
||||||
*/
|
|
||||||
export const parseTokens = (
|
|
||||||
tokens: CSSToken[],
|
|
||||||
opt: Options = {}
|
|
||||||
): string[] => {
|
|
||||||
if (!Array.isArray(tokens)) {
|
|
||||||
throw new TypeError(`${tokens} is not an array.`);
|
|
||||||
}
|
|
||||||
const { format = '' } = opt;
|
|
||||||
const mathFunc = new Set();
|
|
||||||
let nest = 0;
|
|
||||||
const res: string[] = [];
|
|
||||||
while (tokens.length) {
|
|
||||||
const token = tokens.shift();
|
|
||||||
if (!Array.isArray(token)) {
|
|
||||||
throw new TypeError(`${token} is not an array.`);
|
|
||||||
}
|
|
||||||
const [type = '', value = ''] = token as [TokenType, string];
|
|
||||||
switch (type) {
|
|
||||||
case DIM: {
|
|
||||||
if (format === VAL_SPEC && !mathFunc.has(nest)) {
|
|
||||||
res.push(value);
|
|
||||||
} else {
|
|
||||||
const resolvedValue = resolveDimension(token, opt);
|
|
||||||
if (isString(resolvedValue)) {
|
|
||||||
res.push(resolvedValue);
|
|
||||||
} else {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FUNC:
|
|
||||||
case PAREN_OPEN: {
|
|
||||||
res.push(value);
|
|
||||||
nest++;
|
|
||||||
if (REG_FN_MATH_START.test(value)) {
|
|
||||||
mathFunc.add(nest);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PAREN_CLOSE: {
|
|
||||||
if (res.length) {
|
|
||||||
const lastValue = res[res.length - 1];
|
|
||||||
if (lastValue === ' ') {
|
|
||||||
res.splice(-1, 1, value);
|
|
||||||
} else {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
if (mathFunc.has(nest)) {
|
|
||||||
mathFunc.delete(nest);
|
|
||||||
}
|
|
||||||
nest--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case W_SPACE: {
|
|
||||||
if (res.length) {
|
|
||||||
const lastValue = res[res.length - 1];
|
|
||||||
if (
|
|
||||||
isString(lastValue) &&
|
|
||||||
!lastValue.endsWith('(') &&
|
|
||||||
lastValue !== ' '
|
|
||||||
) {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
if (type !== COMMENT && type !== EOF) {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CSS calc()
|
|
||||||
* @param value - CSS value including calc()
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
export const cssCalc = (value: string, opt: Options = {}): string => {
|
|
||||||
const { format = '' } = opt;
|
|
||||||
if (isString(value)) {
|
|
||||||
if (REG_FN_VAR.test(value)) {
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
return value;
|
|
||||||
} else {
|
|
||||||
const resolvedValue = resolveVar(value, opt);
|
|
||||||
if (isString(resolvedValue)) {
|
|
||||||
return resolvedValue;
|
|
||||||
} else {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (!REG_FN_CALC.test(value)) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
value = value.toLowerCase().trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'cssCalc',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item as string;
|
|
||||||
}
|
|
||||||
const tokens = tokenize({ css: value });
|
|
||||||
const values = parseTokens(tokens, opt);
|
|
||||||
let resolvedValue: string = calc(values.join(''), {
|
|
||||||
toCanonicalUnits: true
|
|
||||||
});
|
|
||||||
if (REG_FN_VAR_START.test(value)) {
|
|
||||||
if (REG_TYPE_DIM_PCT.test(resolvedValue)) {
|
|
||||||
const [, val, unit] = resolvedValue.match(
|
|
||||||
REG_TYPE_DIM_PCT
|
|
||||||
) as MatchedRegExp;
|
|
||||||
resolvedValue = `${roundToPrecision(Number(val), HEX)}${unit}`;
|
|
||||||
}
|
|
||||||
// wrap with `calc()`
|
|
||||||
if (
|
|
||||||
resolvedValue &&
|
|
||||||
!REG_FN_VAR_START.test(resolvedValue) &&
|
|
||||||
format === VAL_SPEC
|
|
||||||
) {
|
|
||||||
resolvedValue = `calc(${resolvedValue})`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
if (/\s[-+*/]\s/.test(resolvedValue) && !resolvedValue.includes('NaN')) {
|
|
||||||
resolvedValue = serializeCalc(resolvedValue, opt);
|
|
||||||
} else if (REG_FN_CALC_NUM.test(resolvedValue)) {
|
|
||||||
const [, val] = resolvedValue.match(REG_FN_CALC_NUM) as MatchedRegExp;
|
|
||||||
resolvedValue = `calc(${roundToPrecision(Number(val), HEX)})`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
};
|
|
||||||
-289
@@ -1,289 +0,0 @@
|
|||||||
/**
|
|
||||||
* css-gradient
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { CacheItem, createCacheKey, getCache, setCache } from './cache';
|
|
||||||
import { isString } from './common';
|
|
||||||
import { MatchedRegExp, Options } from './typedef';
|
|
||||||
import { isColor, splitValue } from './util';
|
|
||||||
|
|
||||||
/* constants */
|
|
||||||
import {
|
|
||||||
ANGLE,
|
|
||||||
CS_HUE,
|
|
||||||
CS_RECT,
|
|
||||||
LENGTH,
|
|
||||||
NUM,
|
|
||||||
NUM_POSITIVE,
|
|
||||||
PCT
|
|
||||||
} from './constant';
|
|
||||||
const NAMESPACE = 'css-gradient';
|
|
||||||
const DIM_ANGLE = `${NUM}(?:${ANGLE})`;
|
|
||||||
const DIM_ANGLE_PCT = `${DIM_ANGLE}|${PCT}`;
|
|
||||||
const DIM_LEN = `${NUM}(?:${LENGTH})|0`;
|
|
||||||
const DIM_LEN_PCT = `${DIM_LEN}|${PCT}`;
|
|
||||||
const DIM_LEN_PCT_POSI = `${NUM_POSITIVE}(?:${LENGTH}|%)|0`;
|
|
||||||
const DIM_LEN_POSI = `${NUM_POSITIVE}(?:${LENGTH})|0`;
|
|
||||||
const CTR = 'center';
|
|
||||||
const L_R = 'left|right';
|
|
||||||
const T_B = 'top|bottom';
|
|
||||||
const S_E = 'start|end';
|
|
||||||
const AXIS_X = `${L_R}|x-(?:${S_E})`;
|
|
||||||
const AXIS_Y = `${T_B}|y-(?:${S_E})`;
|
|
||||||
const BLOCK = `block-(?:${S_E})`;
|
|
||||||
const INLINE = `inline-(?:${S_E})`;
|
|
||||||
const POS_1 = `${CTR}|${AXIS_X}|${AXIS_Y}|${BLOCK}|${INLINE}|${DIM_LEN_PCT}`;
|
|
||||||
const POS_2 = [
|
|
||||||
`(?:${CTR}|${AXIS_X})\\s+(?:${CTR}|${AXIS_Y})`,
|
|
||||||
`(?:${CTR}|${AXIS_Y})\\s+(?:${CTR}|${AXIS_X})`,
|
|
||||||
`(?:${CTR}|${AXIS_X}|${DIM_LEN_PCT})\\s+(?:${CTR}|${AXIS_Y}|${DIM_LEN_PCT})`,
|
|
||||||
`(?:${CTR}|${BLOCK})\\s+(?:${CTR}|${INLINE})`,
|
|
||||||
`(?:${CTR}|${INLINE})\\s+(?:${CTR}|${BLOCK})`,
|
|
||||||
`(?:${CTR}|${S_E})\\s+(?:${CTR}|${S_E})`
|
|
||||||
].join('|');
|
|
||||||
const POS_4 = [
|
|
||||||
`(?:${AXIS_X})\\s+(?:${DIM_LEN_PCT})\\s+(?:${AXIS_Y})\\s+(?:${DIM_LEN_PCT})`,
|
|
||||||
`(?:${AXIS_Y})\\s+(?:${DIM_LEN_PCT})\\s+(?:${AXIS_X})\\s+(?:${DIM_LEN_PCT})`,
|
|
||||||
`(?:${BLOCK})\\s+(?:${DIM_LEN_PCT})\\s+(?:${INLINE})\\s+(?:${DIM_LEN_PCT})`,
|
|
||||||
`(?:${INLINE})\\s+(?:${DIM_LEN_PCT})\\s+(?:${BLOCK})\\s+(?:${DIM_LEN_PCT})`,
|
|
||||||
`(?:${S_E})\\s+(?:${DIM_LEN_PCT})\\s+(?:${S_E})\\s+(?:${DIM_LEN_PCT})`
|
|
||||||
].join('|');
|
|
||||||
const RAD_EXTENT = '(?:clos|farth)est-(?:corner|side)';
|
|
||||||
const RAD_SIZE = [
|
|
||||||
`${RAD_EXTENT}(?:\\s+${RAD_EXTENT})?`,
|
|
||||||
`${DIM_LEN_POSI}`,
|
|
||||||
`(?:${DIM_LEN_PCT_POSI})\\s+(?:${DIM_LEN_PCT_POSI})`
|
|
||||||
].join('|');
|
|
||||||
const RAD_SHAPE = 'circle|ellipse';
|
|
||||||
const FROM_ANGLE = `from\\s+${DIM_ANGLE}`;
|
|
||||||
const AT_POSITION = `at\\s+(?:${POS_1}|${POS_2}|${POS_4})`;
|
|
||||||
const TO_SIDE_CORNER = `to\\s+(?:(?:${L_R})(?:\\s(?:${T_B}))?|(?:${T_B})(?:\\s(?:${L_R}))?)`;
|
|
||||||
const IN_COLOR_SPACE = `in\\s+(?:${CS_RECT}|${CS_HUE})`;
|
|
||||||
|
|
||||||
/* type definitions */
|
|
||||||
/**
|
|
||||||
* @type ColorStopList - list of color stops
|
|
||||||
*/
|
|
||||||
type ColorStopList = [string, string, ...string[]];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef Gradient - parsed CSS gradient
|
|
||||||
* @property value - input value
|
|
||||||
* @property type - gradient type
|
|
||||||
* @property [gradientLine] - gradient line
|
|
||||||
* @property colorStopList - list of color stops
|
|
||||||
*/
|
|
||||||
interface Gradient {
|
|
||||||
value: string;
|
|
||||||
type: string;
|
|
||||||
gradientLine?: string;
|
|
||||||
colorStopList: ColorStopList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* regexp */
|
|
||||||
const REG_GRAD = /^(?:repeating-)?(?:conic|linear|radial)-gradient\(/;
|
|
||||||
const REG_GRAD_CAPT = /^((?:repeating-)?(?:conic|linear|radial)-gradient)\(/;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get gradient type
|
|
||||||
* @param value - gradient value
|
|
||||||
* @returns gradient type
|
|
||||||
*/
|
|
||||||
export const getGradientType = (value: string): string => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.trim();
|
|
||||||
if (REG_GRAD.test(value)) {
|
|
||||||
const [, type] = value.match(REG_GRAD_CAPT) as MatchedRegExp;
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* validate gradient line
|
|
||||||
* @param value - gradient line value
|
|
||||||
* @param type - gradient type
|
|
||||||
* @returns result
|
|
||||||
*/
|
|
||||||
export const validateGradientLine = (value: string, type: string): boolean => {
|
|
||||||
if (isString(value) && isString(type)) {
|
|
||||||
value = value.trim();
|
|
||||||
type = type.trim();
|
|
||||||
let lineSyntax = '';
|
|
||||||
if (/^(?:repeating-)?linear-gradient$/.test(type)) {
|
|
||||||
/*
|
|
||||||
* <linear-gradient-line> = [
|
|
||||||
* [ <angle> | to <side-or-corner> ] ||
|
|
||||||
* <color-interpolation-method>
|
|
||||||
* ]
|
|
||||||
*/
|
|
||||||
lineSyntax = [
|
|
||||||
`(?:${DIM_ANGLE}|${TO_SIDE_CORNER})(?:\\s+${IN_COLOR_SPACE})?`,
|
|
||||||
`${IN_COLOR_SPACE}(?:\\s+(?:${DIM_ANGLE}|${TO_SIDE_CORNER}))?`
|
|
||||||
].join('|');
|
|
||||||
} else if (/^(?:repeating-)?radial-gradient$/.test(type)) {
|
|
||||||
/*
|
|
||||||
* <radial-gradient-line> = [
|
|
||||||
* [ [ <radial-shape> || <radial-size> ]? [ at <position> ]? ] ||
|
|
||||||
* <color-interpolation-method>]?
|
|
||||||
*/
|
|
||||||
lineSyntax = [
|
|
||||||
`(?:${RAD_SHAPE})(?:\\s+(?:${RAD_SIZE}))?(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`,
|
|
||||||
`(?:${RAD_SIZE})(?:\\s+(?:${RAD_SHAPE}))?(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`,
|
|
||||||
`${AT_POSITION}(?:\\s+${IN_COLOR_SPACE})?`,
|
|
||||||
`${IN_COLOR_SPACE}(?:\\s+${RAD_SHAPE})(?:\\s+(?:${RAD_SIZE}))?(?:\\s+${AT_POSITION})?`,
|
|
||||||
`${IN_COLOR_SPACE}(?:\\s+${RAD_SIZE})(?:\\s+(?:${RAD_SHAPE}))?(?:\\s+${AT_POSITION})?`,
|
|
||||||
`${IN_COLOR_SPACE}(?:\\s+${AT_POSITION})?`
|
|
||||||
].join('|');
|
|
||||||
} else if (/^(?:repeating-)?conic-gradient$/.test(type)) {
|
|
||||||
/*
|
|
||||||
* <conic-gradient-line> = [
|
|
||||||
* [ [ from <angle> ]? [ at <position> ]? ] ||
|
|
||||||
* <color-interpolation-method>
|
|
||||||
* ]
|
|
||||||
*/
|
|
||||||
lineSyntax = [
|
|
||||||
`${FROM_ANGLE}(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`,
|
|
||||||
`${AT_POSITION}(?:\\s+${IN_COLOR_SPACE})?`,
|
|
||||||
`${IN_COLOR_SPACE}(?:\\s+${FROM_ANGLE})?(?:\\s+${AT_POSITION})?`
|
|
||||||
].join('|');
|
|
||||||
}
|
|
||||||
if (lineSyntax) {
|
|
||||||
const reg = new RegExp(`^(?:${lineSyntax})$`);
|
|
||||||
return reg.test(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* validate color stop list
|
|
||||||
* @param list
|
|
||||||
* @param type
|
|
||||||
* @param [opt]
|
|
||||||
* @returns result
|
|
||||||
*/
|
|
||||||
export const validateColorStopList = (
|
|
||||||
list: string[],
|
|
||||||
type: string,
|
|
||||||
opt: Options = {}
|
|
||||||
): boolean => {
|
|
||||||
if (Array.isArray(list) && list.length > 1) {
|
|
||||||
const dimension = /^(?:repeating-)?conic-gradient$/.test(type)
|
|
||||||
? DIM_ANGLE_PCT
|
|
||||||
: DIM_LEN_PCT;
|
|
||||||
const regColorHint = new RegExp(`^(?:${dimension})$`);
|
|
||||||
const regDimension = new RegExp(`(?:\\s+(?:${dimension})){1,2}$`);
|
|
||||||
const arr = [];
|
|
||||||
for (const item of list) {
|
|
||||||
if (isString(item)) {
|
|
||||||
if (regColorHint.test(item)) {
|
|
||||||
arr.push('hint');
|
|
||||||
} else {
|
|
||||||
const color = item.replace(regDimension, '');
|
|
||||||
if (isColor(color, opt)) {
|
|
||||||
arr.push('color');
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const value = arr.join(',');
|
|
||||||
return /^color(?:,(?:hint,)?color)+$/.test(value);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* parse CSS gradient
|
|
||||||
* @param value - gradient value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed result
|
|
||||||
*/
|
|
||||||
export const parseGradient = (
|
|
||||||
value: string,
|
|
||||||
opt: Options = {}
|
|
||||||
): Gradient | null => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.trim();
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'parseGradient',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return cachedResult.item as Gradient;
|
|
||||||
}
|
|
||||||
const type = getGradientType(value);
|
|
||||||
const gradValue = value.replace(REG_GRAD, '').replace(/\)$/, '');
|
|
||||||
if (type && gradValue) {
|
|
||||||
const [lineOrColorStop = '', ...colorStops] = splitValue(gradValue, {
|
|
||||||
delimiter: ','
|
|
||||||
});
|
|
||||||
const dimension = /^(?:repeating-)?conic-gradient$/.test(type)
|
|
||||||
? DIM_ANGLE_PCT
|
|
||||||
: DIM_LEN_PCT;
|
|
||||||
const regDimension = new RegExp(`(?:\\s+(?:${dimension})){1,2}$`);
|
|
||||||
let isColorStop = false;
|
|
||||||
if (regDimension.test(lineOrColorStop)) {
|
|
||||||
const colorStop = lineOrColorStop.replace(regDimension, '');
|
|
||||||
if (isColor(colorStop, opt)) {
|
|
||||||
isColorStop = true;
|
|
||||||
}
|
|
||||||
} else if (isColor(lineOrColorStop, opt)) {
|
|
||||||
isColorStop = true;
|
|
||||||
}
|
|
||||||
if (isColorStop) {
|
|
||||||
colorStops.unshift(lineOrColorStop);
|
|
||||||
const valid = validateColorStopList(colorStops, type, opt);
|
|
||||||
if (valid) {
|
|
||||||
const res: Gradient = {
|
|
||||||
value,
|
|
||||||
type,
|
|
||||||
colorStopList: colorStops as ColorStopList
|
|
||||||
};
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
} else if (colorStops.length > 1) {
|
|
||||||
const gradientLine = lineOrColorStop;
|
|
||||||
const valid =
|
|
||||||
validateGradientLine(gradientLine, type) &&
|
|
||||||
validateColorStopList(colorStops, type, opt);
|
|
||||||
if (valid) {
|
|
||||||
const res: Gradient = {
|
|
||||||
value,
|
|
||||||
type,
|
|
||||||
gradientLine,
|
|
||||||
colorStopList: colorStops as ColorStopList
|
|
||||||
};
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* is CSS gradient
|
|
||||||
* @param value - CSS value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns result
|
|
||||||
*/
|
|
||||||
export const isGradient = (value: string, opt: Options = {}): boolean => {
|
|
||||||
const gradient = parseGradient(value, opt);
|
|
||||||
return gradient !== null;
|
|
||||||
};
|
|
||||||
-250
@@ -1,250 +0,0 @@
|
|||||||
/**
|
|
||||||
* css-var
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { CSSToken, TokenType, tokenize } from '@csstools/css-tokenizer';
|
|
||||||
import {
|
|
||||||
CacheItem,
|
|
||||||
NullObject,
|
|
||||||
createCacheKey,
|
|
||||||
getCache,
|
|
||||||
setCache
|
|
||||||
} from './cache';
|
|
||||||
import { isString } from './common';
|
|
||||||
import { cssCalc } from './css-calc';
|
|
||||||
import { isColor } from './util';
|
|
||||||
import { Options } from './typedef';
|
|
||||||
|
|
||||||
/* constants */
|
|
||||||
import { FN_VAR, SYN_FN_CALC, SYN_FN_VAR, VAL_SPEC } from './constant';
|
|
||||||
const {
|
|
||||||
CloseParen: PAREN_CLOSE,
|
|
||||||
Comment: COMMENT,
|
|
||||||
EOF,
|
|
||||||
Ident: IDENT,
|
|
||||||
Whitespace: W_SPACE
|
|
||||||
} = TokenType;
|
|
||||||
const NAMESPACE = 'css-var';
|
|
||||||
|
|
||||||
/* regexp */
|
|
||||||
const REG_FN_CALC = new RegExp(SYN_FN_CALC);
|
|
||||||
const REG_FN_VAR = new RegExp(SYN_FN_VAR);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resolve custom property
|
|
||||||
* @param tokens - CSS tokens
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns result - [tokens, resolvedValue]
|
|
||||||
*/
|
|
||||||
export function resolveCustomProperty(
|
|
||||||
tokens: CSSToken[],
|
|
||||||
opt: Options = {}
|
|
||||||
): [CSSToken[], string] {
|
|
||||||
if (!Array.isArray(tokens)) {
|
|
||||||
throw new TypeError(`${tokens} is not an array.`);
|
|
||||||
}
|
|
||||||
const { customProperty = {} } = opt;
|
|
||||||
const items: string[] = [];
|
|
||||||
while (tokens.length) {
|
|
||||||
const token = tokens.shift();
|
|
||||||
if (!Array.isArray(token)) {
|
|
||||||
throw new TypeError(`${token} is not an array.`);
|
|
||||||
}
|
|
||||||
const [type, value] = token as [TokenType, string];
|
|
||||||
// end of var()
|
|
||||||
if (type === PAREN_CLOSE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// nested var()
|
|
||||||
if (value === FN_VAR) {
|
|
||||||
const [restTokens, item] = resolveCustomProperty(tokens, opt);
|
|
||||||
tokens = restTokens;
|
|
||||||
if (item) {
|
|
||||||
items.push(item);
|
|
||||||
}
|
|
||||||
} else if (type === IDENT) {
|
|
||||||
if (value.startsWith('--')) {
|
|
||||||
let item;
|
|
||||||
if (Object.hasOwnProperty.call(customProperty, value)) {
|
|
||||||
item = customProperty[value] as string;
|
|
||||||
} else if (typeof customProperty.callback === 'function') {
|
|
||||||
item = customProperty.callback(value);
|
|
||||||
}
|
|
||||||
if (item) {
|
|
||||||
items.push(item);
|
|
||||||
}
|
|
||||||
} else if (value) {
|
|
||||||
items.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let resolveAsColor = false;
|
|
||||||
if (items.length > 1) {
|
|
||||||
const lastValue = items[items.length - 1];
|
|
||||||
resolveAsColor = isColor(lastValue);
|
|
||||||
}
|
|
||||||
let resolvedValue = '';
|
|
||||||
for (let item of items) {
|
|
||||||
item = item.trim();
|
|
||||||
if (REG_FN_VAR.test(item)) {
|
|
||||||
// recurse resolveVar()
|
|
||||||
const resolvedItem = resolveVar(item, opt);
|
|
||||||
if (isString(resolvedItem)) {
|
|
||||||
if (resolveAsColor) {
|
|
||||||
if (isColor(resolvedItem)) {
|
|
||||||
resolvedValue = resolvedItem;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resolvedValue = resolvedItem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (REG_FN_CALC.test(item)) {
|
|
||||||
item = cssCalc(item, opt);
|
|
||||||
if (resolveAsColor) {
|
|
||||||
if (isColor(item)) {
|
|
||||||
resolvedValue = item;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resolvedValue = item;
|
|
||||||
}
|
|
||||||
} else if (
|
|
||||||
item &&
|
|
||||||
!/^(?:inherit|initial|revert(?:-layer)?|unset)$/.test(item)
|
|
||||||
) {
|
|
||||||
if (resolveAsColor) {
|
|
||||||
if (isColor(item)) {
|
|
||||||
resolvedValue = item;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
resolvedValue = item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (resolvedValue) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [tokens, resolvedValue];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* parse tokens
|
|
||||||
* @param tokens - CSS tokens
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns parsed tokens
|
|
||||||
*/
|
|
||||||
export function parseTokens(
|
|
||||||
tokens: CSSToken[],
|
|
||||||
opt: Options = {}
|
|
||||||
): string[] | NullObject {
|
|
||||||
const res: string[] = [];
|
|
||||||
while (tokens.length) {
|
|
||||||
const token = tokens.shift();
|
|
||||||
const [type = '', value = ''] = token as [TokenType, string];
|
|
||||||
if (value === FN_VAR) {
|
|
||||||
const [restTokens, resolvedValue] = resolveCustomProperty(tokens, opt);
|
|
||||||
if (!resolvedValue) {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
tokens = restTokens;
|
|
||||||
res.push(resolvedValue);
|
|
||||||
} else {
|
|
||||||
switch (type) {
|
|
||||||
case PAREN_CLOSE: {
|
|
||||||
if (res.length) {
|
|
||||||
const lastValue = res[res.length - 1];
|
|
||||||
if (lastValue === ' ') {
|
|
||||||
res.splice(-1, 1, value);
|
|
||||||
} else {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case W_SPACE: {
|
|
||||||
if (res.length) {
|
|
||||||
const lastValue = res[res.length - 1];
|
|
||||||
if (
|
|
||||||
isString(lastValue) &&
|
|
||||||
!lastValue.endsWith('(') &&
|
|
||||||
lastValue !== ' '
|
|
||||||
) {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
if (type !== COMMENT && type !== EOF) {
|
|
||||||
res.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resolve CSS var()
|
|
||||||
* @param value - CSS value including var()
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
export function resolveVar(
|
|
||||||
value: string,
|
|
||||||
opt: Options = {}
|
|
||||||
): string | NullObject {
|
|
||||||
const { format = '' } = opt;
|
|
||||||
if (isString(value)) {
|
|
||||||
if (!REG_FN_VAR.test(value) || format === VAL_SPEC) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
value = value.trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'resolveVar',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return cachedResult as NullObject;
|
|
||||||
}
|
|
||||||
return cachedResult.item as string;
|
|
||||||
}
|
|
||||||
const tokens = tokenize({ css: value });
|
|
||||||
const values = parseTokens(tokens, opt);
|
|
||||||
if (Array.isArray(values)) {
|
|
||||||
let color = values.join('');
|
|
||||||
if (REG_FN_CALC.test(color)) {
|
|
||||||
color = cssCalc(color, opt);
|
|
||||||
}
|
|
||||||
setCache(cacheKey, color);
|
|
||||||
return color;
|
|
||||||
} else {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CSS var()
|
|
||||||
* @param value - CSS value including var()
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
export const cssVar = (value: string, opt: Options = {}): string => {
|
|
||||||
const resolvedValue = resolveVar(value, opt);
|
|
||||||
if (isString(resolvedValue)) {
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
-580
@@ -1,580 +0,0 @@
|
|||||||
/**
|
|
||||||
* relative-color
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { SyntaxFlag, color as colorParser } from '@csstools/css-color-parser';
|
|
||||||
import {
|
|
||||||
ComponentValue,
|
|
||||||
parseComponentValue
|
|
||||||
} from '@csstools/css-parser-algorithms';
|
|
||||||
import { CSSToken, TokenType, tokenize } from '@csstools/css-tokenizer';
|
|
||||||
import {
|
|
||||||
CacheItem,
|
|
||||||
NullObject,
|
|
||||||
createCacheKey,
|
|
||||||
getCache,
|
|
||||||
setCache
|
|
||||||
} from './cache';
|
|
||||||
import { NAMED_COLORS, convertColorToRgb } from './color';
|
|
||||||
import { isString, isStringOrNumber } from './common';
|
|
||||||
import { resolveDimension, serializeCalc } from './css-calc';
|
|
||||||
import { resolveColor } from './resolve';
|
|
||||||
import { roundToPrecision } from './util';
|
|
||||||
import {
|
|
||||||
ColorChannels,
|
|
||||||
MatchedRegExp,
|
|
||||||
Options,
|
|
||||||
StringColorChannels
|
|
||||||
} from './typedef';
|
|
||||||
|
|
||||||
/* constants */
|
|
||||||
import {
|
|
||||||
CS_LAB,
|
|
||||||
CS_LCH,
|
|
||||||
FN_REL,
|
|
||||||
FN_REL_CAPT,
|
|
||||||
FN_VAR,
|
|
||||||
NONE,
|
|
||||||
SYN_COLOR_TYPE,
|
|
||||||
SYN_FN_MATH_START,
|
|
||||||
SYN_FN_VAR,
|
|
||||||
SYN_MIX,
|
|
||||||
VAL_SPEC
|
|
||||||
} from './constant';
|
|
||||||
const {
|
|
||||||
CloseParen: PAREN_CLOSE,
|
|
||||||
Comment: COMMENT,
|
|
||||||
Dimension: DIM,
|
|
||||||
EOF,
|
|
||||||
Function: FUNC,
|
|
||||||
Ident: IDENT,
|
|
||||||
Number: NUM,
|
|
||||||
OpenParen: PAREN_OPEN,
|
|
||||||
Percentage: PCT,
|
|
||||||
Whitespace: W_SPACE
|
|
||||||
} = TokenType;
|
|
||||||
const { HasNoneKeywords: KEY_NONE } = SyntaxFlag;
|
|
||||||
const NAMESPACE = 'relative-color';
|
|
||||||
|
|
||||||
/* numeric constants */
|
|
||||||
const OCT = 8;
|
|
||||||
const DEC = 10;
|
|
||||||
const HEX = 16;
|
|
||||||
const MAX_PCT = 100;
|
|
||||||
const MAX_RGB = 255;
|
|
||||||
|
|
||||||
/* type definitions */
|
|
||||||
/**
|
|
||||||
* @type NumberOrStringColorChannels - color channel
|
|
||||||
*/
|
|
||||||
type NumberOrStringColorChannels = ColorChannels & StringColorChannels;
|
|
||||||
|
|
||||||
/* regexp */
|
|
||||||
const REG_COLOR_CAPT = new RegExp(
|
|
||||||
`^${FN_REL}(${SYN_COLOR_TYPE}|${SYN_MIX})\\s+`
|
|
||||||
);
|
|
||||||
const REG_CS_HSL = /(?:hsla?|hwb)$/;
|
|
||||||
const REG_CS_CIE = new RegExp(`^(?:${CS_LAB}|${CS_LCH})$`);
|
|
||||||
const REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START);
|
|
||||||
const REG_FN_REL = new RegExp(FN_REL);
|
|
||||||
const REG_FN_REL_CAPT = new RegExp(`^${FN_REL_CAPT}`);
|
|
||||||
const REG_FN_REL_START = new RegExp(`^${FN_REL}`);
|
|
||||||
const REG_FN_VAR = new RegExp(SYN_FN_VAR);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resolve relative color channels
|
|
||||||
* @param tokens - CSS tokens
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved color channels
|
|
||||||
*/
|
|
||||||
export function resolveColorChannels(
|
|
||||||
tokens: CSSToken[],
|
|
||||||
opt: Options = {}
|
|
||||||
): NumberOrStringColorChannels | NullObject {
|
|
||||||
if (!Array.isArray(tokens)) {
|
|
||||||
throw new TypeError(`${tokens} is not an array.`);
|
|
||||||
}
|
|
||||||
const { colorSpace = '', format = '' } = opt;
|
|
||||||
const colorChannels = new Map([
|
|
||||||
['color', ['r', 'g', 'b', 'alpha']],
|
|
||||||
['hsl', ['h', 's', 'l', 'alpha']],
|
|
||||||
['hsla', ['h', 's', 'l', 'alpha']],
|
|
||||||
['hwb', ['h', 'w', 'b', 'alpha']],
|
|
||||||
['lab', ['l', 'a', 'b', 'alpha']],
|
|
||||||
['lch', ['l', 'c', 'h', 'alpha']],
|
|
||||||
['oklab', ['l', 'a', 'b', 'alpha']],
|
|
||||||
['oklch', ['l', 'c', 'h', 'alpha']],
|
|
||||||
['rgb', ['r', 'g', 'b', 'alpha']],
|
|
||||||
['rgba', ['r', 'g', 'b', 'alpha']]
|
|
||||||
]);
|
|
||||||
const colorChannel = colorChannels.get(colorSpace);
|
|
||||||
// invalid color channel
|
|
||||||
if (!colorChannel) {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
const mathFunc = new Set();
|
|
||||||
const channels: [
|
|
||||||
(number | string)[],
|
|
||||||
(number | string)[],
|
|
||||||
(number | string)[],
|
|
||||||
(number | string)[]
|
|
||||||
] = [[], [], [], []];
|
|
||||||
let i = 0;
|
|
||||||
let nest = 0;
|
|
||||||
let func = false;
|
|
||||||
while (tokens.length) {
|
|
||||||
const token = tokens.shift();
|
|
||||||
if (!Array.isArray(token)) {
|
|
||||||
throw new TypeError(`${token} is not an array.`);
|
|
||||||
}
|
|
||||||
const [type, value, , , detail] = token as [
|
|
||||||
TokenType,
|
|
||||||
string,
|
|
||||||
number,
|
|
||||||
number,
|
|
||||||
{ value: string | number } | undefined
|
|
||||||
];
|
|
||||||
const channel = channels[i];
|
|
||||||
if (Array.isArray(channel)) {
|
|
||||||
switch (type) {
|
|
||||||
case DIM: {
|
|
||||||
const resolvedValue = resolveDimension(token, opt);
|
|
||||||
if (isString(resolvedValue)) {
|
|
||||||
channel.push(resolvedValue);
|
|
||||||
} else {
|
|
||||||
channel.push(value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FUNC: {
|
|
||||||
channel.push(value);
|
|
||||||
func = true;
|
|
||||||
nest++;
|
|
||||||
if (REG_FN_MATH_START.test(value)) {
|
|
||||||
mathFunc.add(nest);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IDENT: {
|
|
||||||
// invalid channel key
|
|
||||||
if (!colorChannel.includes(value)) {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
channel.push(value);
|
|
||||||
if (!func) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NUM: {
|
|
||||||
channel.push(Number(detail?.value));
|
|
||||||
if (!func) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PAREN_OPEN: {
|
|
||||||
channel.push(value);
|
|
||||||
nest++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PAREN_CLOSE: {
|
|
||||||
if (func) {
|
|
||||||
const lastValue = channel[channel.length - 1];
|
|
||||||
if (lastValue === ' ') {
|
|
||||||
channel.splice(-1, 1, value);
|
|
||||||
} else {
|
|
||||||
channel.push(value);
|
|
||||||
}
|
|
||||||
if (mathFunc.has(nest)) {
|
|
||||||
mathFunc.delete(nest);
|
|
||||||
}
|
|
||||||
nest--;
|
|
||||||
if (nest === 0) {
|
|
||||||
func = false;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PCT: {
|
|
||||||
channel.push(Number(detail?.value) / MAX_PCT);
|
|
||||||
if (!func) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case W_SPACE: {
|
|
||||||
if (channel.length && func) {
|
|
||||||
const lastValue = channel[channel.length - 1];
|
|
||||||
if (typeof lastValue === 'number') {
|
|
||||||
channel.push(value);
|
|
||||||
} else if (
|
|
||||||
isString(lastValue) &&
|
|
||||||
!lastValue.endsWith('(') &&
|
|
||||||
lastValue !== ' '
|
|
||||||
) {
|
|
||||||
channel.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
if (type !== COMMENT && type !== EOF && func) {
|
|
||||||
channel.push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const channelValues = [];
|
|
||||||
for (const channel of channels) {
|
|
||||||
if (channel.length === 1) {
|
|
||||||
const [resolvedValue] = channel;
|
|
||||||
if (isStringOrNumber(resolvedValue)) {
|
|
||||||
channelValues.push(resolvedValue);
|
|
||||||
}
|
|
||||||
} else if (channel.length) {
|
|
||||||
const resolvedValue = serializeCalc(channel.join(''), {
|
|
||||||
format
|
|
||||||
});
|
|
||||||
channelValues.push(resolvedValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return channelValues as NumberOrStringColorChannels;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* extract origin color
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns origin color value
|
|
||||||
*/
|
|
||||||
export function extractOriginColor(
|
|
||||||
value: string,
|
|
||||||
opt: Options = {}
|
|
||||||
): string | NullObject {
|
|
||||||
const { currentColor = '', format = '' } = opt;
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.toLowerCase().trim();
|
|
||||||
if (!value) {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
if (!REG_FN_REL_START.test(value)) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'extractOriginColor',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return cachedResult as NullObject;
|
|
||||||
}
|
|
||||||
return cachedResult.item as string;
|
|
||||||
}
|
|
||||||
if (/currentcolor/.test(value)) {
|
|
||||||
if (currentColor) {
|
|
||||||
value = value.replace(/currentcolor/g, currentColor);
|
|
||||||
} else {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let colorSpace = '';
|
|
||||||
if (REG_FN_REL_CAPT.test(value)) {
|
|
||||||
[, colorSpace] = value.match(REG_FN_REL_CAPT) as MatchedRegExp;
|
|
||||||
}
|
|
||||||
opt.colorSpace = colorSpace;
|
|
||||||
if (REG_COLOR_CAPT.test(value)) {
|
|
||||||
const [, originColor] = value.match(REG_COLOR_CAPT) as MatchedRegExp;
|
|
||||||
const [, restValue] = value.split(originColor) as MatchedRegExp;
|
|
||||||
if (/^[a-z]+$/.test(originColor)) {
|
|
||||||
if (
|
|
||||||
!/^transparent$/.test(originColor) &&
|
|
||||||
!Object.prototype.hasOwnProperty.call(NAMED_COLORS, originColor)
|
|
||||||
) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
} else if (format === VAL_SPEC) {
|
|
||||||
const resolvedOriginColor = resolveColor(originColor, opt);
|
|
||||||
if (isString(resolvedOriginColor)) {
|
|
||||||
value = value.replace(originColor, resolvedOriginColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
const tokens = tokenize({ css: restValue });
|
|
||||||
const channelValues = resolveColorChannels(tokens, opt);
|
|
||||||
if (channelValues instanceof NullObject) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return channelValues;
|
|
||||||
}
|
|
||||||
const [v1, v2, v3, v4] = channelValues;
|
|
||||||
let channelValue = '';
|
|
||||||
if (isStringOrNumber(v4)) {
|
|
||||||
channelValue = ` ${v1} ${v2} ${v3} / ${v4})`;
|
|
||||||
} else {
|
|
||||||
channelValue = ` ${channelValues.join(' ')})`;
|
|
||||||
}
|
|
||||||
if (restValue !== channelValue) {
|
|
||||||
value = value.replace(restValue, channelValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// nested relative color
|
|
||||||
} else {
|
|
||||||
const [, restValue] = value.split(REG_FN_REL_START) as MatchedRegExp;
|
|
||||||
const tokens = tokenize({ css: restValue });
|
|
||||||
const originColor: string[] = [];
|
|
||||||
let nest = 0;
|
|
||||||
while (tokens.length) {
|
|
||||||
const [type, tokenValue] = tokens.shift() as [TokenType, string];
|
|
||||||
switch (type) {
|
|
||||||
case FUNC:
|
|
||||||
case PAREN_OPEN: {
|
|
||||||
originColor.push(tokenValue);
|
|
||||||
nest++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PAREN_CLOSE: {
|
|
||||||
const lastValue = originColor[originColor.length - 1];
|
|
||||||
if (lastValue === ' ') {
|
|
||||||
originColor.splice(-1, 1, tokenValue);
|
|
||||||
} else if (isString(lastValue)) {
|
|
||||||
originColor.push(tokenValue);
|
|
||||||
}
|
|
||||||
nest--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case W_SPACE: {
|
|
||||||
const lastValue = originColor[originColor.length - 1];
|
|
||||||
if (
|
|
||||||
isString(lastValue) &&
|
|
||||||
!lastValue.endsWith('(') &&
|
|
||||||
lastValue !== ' '
|
|
||||||
) {
|
|
||||||
originColor.push(tokenValue);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
if (type !== COMMENT && type !== EOF) {
|
|
||||||
originColor.push(tokenValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (nest === 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const resolvedOriginColor = resolveRelativeColor(
|
|
||||||
originColor.join('').trim(),
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
if (resolvedOriginColor instanceof NullObject) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return resolvedOriginColor;
|
|
||||||
}
|
|
||||||
const channelValues = resolveColorChannels(tokens, opt);
|
|
||||||
if (channelValues instanceof NullObject) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return channelValues;
|
|
||||||
}
|
|
||||||
const [v1, v2, v3, v4] = channelValues;
|
|
||||||
let channelValue = '';
|
|
||||||
if (isStringOrNumber(v4)) {
|
|
||||||
channelValue = ` ${v1} ${v2} ${v3} / ${v4})`;
|
|
||||||
} else {
|
|
||||||
channelValue = ` ${channelValues.join(' ')})`;
|
|
||||||
}
|
|
||||||
value = value.replace(restValue, `${resolvedOriginColor}${channelValue}`);
|
|
||||||
}
|
|
||||||
setCache(cacheKey, value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resolve relative color
|
|
||||||
* @param value - CSS relative color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved value
|
|
||||||
*/
|
|
||||||
export function resolveRelativeColor(
|
|
||||||
value: string,
|
|
||||||
opt: Options = {}
|
|
||||||
): string | NullObject {
|
|
||||||
const { format = '' } = opt;
|
|
||||||
if (isString(value)) {
|
|
||||||
if (REG_FN_VAR.test(value)) {
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
return value;
|
|
||||||
// var() must be resolved before resolveRelativeColor()
|
|
||||||
} else {
|
|
||||||
throw new SyntaxError(`Unexpected token ${FN_VAR} found.`);
|
|
||||||
}
|
|
||||||
} else if (!REG_FN_REL.test(value)) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
value = value.toLowerCase().trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'resolveRelativeColor',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return cachedResult as NullObject;
|
|
||||||
}
|
|
||||||
return cachedResult.item as string;
|
|
||||||
}
|
|
||||||
const originColor = extractOriginColor(value, opt);
|
|
||||||
if (originColor instanceof NullObject) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return originColor;
|
|
||||||
}
|
|
||||||
value = originColor;
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
if (value.startsWith('rgba(')) {
|
|
||||||
value = value.replace(/^rgba\(/, 'rgb(');
|
|
||||||
} else if (value.startsWith('hsla(')) {
|
|
||||||
value = value.replace(/^hsla\(/, 'hsl(');
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
const tokens = tokenize({ css: value });
|
|
||||||
const components = parseComponentValue(tokens) as ComponentValue;
|
|
||||||
const parsedComponents = colorParser(components);
|
|
||||||
if (!parsedComponents) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
const {
|
|
||||||
alpha: alphaComponent,
|
|
||||||
channels: channelsComponent,
|
|
||||||
colorNotation,
|
|
||||||
syntaxFlags
|
|
||||||
} = parsedComponents;
|
|
||||||
let alpha: number | string;
|
|
||||||
if (Number.isNaN(Number(alphaComponent))) {
|
|
||||||
if (syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE)) {
|
|
||||||
alpha = NONE;
|
|
||||||
} else {
|
|
||||||
alpha = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
alpha = roundToPrecision(Number(alphaComponent), OCT);
|
|
||||||
}
|
|
||||||
let v1: number | string;
|
|
||||||
let v2: number | string;
|
|
||||||
let v3: number | string;
|
|
||||||
[v1, v2, v3] = channelsComponent;
|
|
||||||
let resolvedValue;
|
|
||||||
if (REG_CS_CIE.test(colorNotation)) {
|
|
||||||
const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE);
|
|
||||||
if (Number.isNaN(v1)) {
|
|
||||||
if (hasNone) {
|
|
||||||
v1 = NONE;
|
|
||||||
} else {
|
|
||||||
v1 = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v1 = roundToPrecision(v1, HEX);
|
|
||||||
}
|
|
||||||
if (Number.isNaN(v2)) {
|
|
||||||
if (hasNone) {
|
|
||||||
v2 = NONE;
|
|
||||||
} else {
|
|
||||||
v2 = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v2 = roundToPrecision(v2, HEX);
|
|
||||||
}
|
|
||||||
if (Number.isNaN(v3)) {
|
|
||||||
if (hasNone) {
|
|
||||||
v3 = NONE;
|
|
||||||
} else {
|
|
||||||
v3 = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v3 = roundToPrecision(v3, HEX);
|
|
||||||
}
|
|
||||||
if (alpha === 1) {
|
|
||||||
resolvedValue = `${colorNotation}(${v1} ${v2} ${v3})`;
|
|
||||||
} else {
|
|
||||||
resolvedValue = `${colorNotation}(${v1} ${v2} ${v3} / ${alpha})`;
|
|
||||||
}
|
|
||||||
} else if (REG_CS_HSL.test(colorNotation)) {
|
|
||||||
if (Number.isNaN(v1)) {
|
|
||||||
v1 = 0;
|
|
||||||
}
|
|
||||||
if (Number.isNaN(v2)) {
|
|
||||||
v2 = 0;
|
|
||||||
}
|
|
||||||
if (Number.isNaN(v3)) {
|
|
||||||
v3 = 0;
|
|
||||||
}
|
|
||||||
let [r, g, b] = convertColorToRgb(
|
|
||||||
`${colorNotation}(${v1} ${v2} ${v3} / ${alpha})`
|
|
||||||
) as ColorChannels;
|
|
||||||
r = roundToPrecision(r / MAX_RGB, DEC);
|
|
||||||
g = roundToPrecision(g / MAX_RGB, DEC);
|
|
||||||
b = roundToPrecision(b / MAX_RGB, DEC);
|
|
||||||
if (alpha === 1) {
|
|
||||||
resolvedValue = `color(srgb ${r} ${g} ${b})`;
|
|
||||||
} else {
|
|
||||||
resolvedValue = `color(srgb ${r} ${g} ${b} / ${alpha})`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const cs = colorNotation === 'rgb' ? 'srgb' : colorNotation;
|
|
||||||
const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE);
|
|
||||||
if (Number.isNaN(v1)) {
|
|
||||||
if (hasNone) {
|
|
||||||
v1 = NONE;
|
|
||||||
} else {
|
|
||||||
v1 = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v1 = roundToPrecision(v1, DEC);
|
|
||||||
}
|
|
||||||
if (Number.isNaN(v2)) {
|
|
||||||
if (hasNone) {
|
|
||||||
v2 = NONE;
|
|
||||||
} else {
|
|
||||||
v2 = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v2 = roundToPrecision(v2, DEC);
|
|
||||||
}
|
|
||||||
if (Number.isNaN(v3)) {
|
|
||||||
if (hasNone) {
|
|
||||||
v3 = NONE;
|
|
||||||
} else {
|
|
||||||
v3 = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v3 = roundToPrecision(v3, DEC);
|
|
||||||
}
|
|
||||||
if (alpha === 1) {
|
|
||||||
resolvedValue = `color(${cs} ${v1} ${v2} ${v3})`;
|
|
||||||
} else {
|
|
||||||
resolvedValue = `color(${cs} ${v1} ${v2} ${v3} / ${alpha})`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
-379
@@ -1,379 +0,0 @@
|
|||||||
/**
|
|
||||||
* resolve
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {
|
|
||||||
CacheItem,
|
|
||||||
NullObject,
|
|
||||||
createCacheKey,
|
|
||||||
getCache,
|
|
||||||
setCache
|
|
||||||
} from './cache';
|
|
||||||
import {
|
|
||||||
convertRgbToHex,
|
|
||||||
resolveColorFunc,
|
|
||||||
resolveColorMix,
|
|
||||||
resolveColorValue
|
|
||||||
} from './color';
|
|
||||||
import { isString } from './common';
|
|
||||||
import { cssCalc } from './css-calc';
|
|
||||||
import { resolveVar } from './css-var';
|
|
||||||
import { resolveRelativeColor } from './relative-color';
|
|
||||||
import {
|
|
||||||
ComputedColorChannels,
|
|
||||||
Options,
|
|
||||||
SpecifiedColorChannels
|
|
||||||
} from './typedef';
|
|
||||||
|
|
||||||
/* constants */
|
|
||||||
import {
|
|
||||||
FN_COLOR,
|
|
||||||
FN_MIX,
|
|
||||||
SYN_FN_CALC,
|
|
||||||
SYN_FN_REL,
|
|
||||||
SYN_FN_VAR,
|
|
||||||
VAL_COMP,
|
|
||||||
VAL_SPEC
|
|
||||||
} from './constant';
|
|
||||||
const NAMESPACE = 'resolve';
|
|
||||||
const RGB_TRANSPARENT = 'rgba(0, 0, 0, 0)';
|
|
||||||
|
|
||||||
/* regexp */
|
|
||||||
const REG_FN_CALC = new RegExp(SYN_FN_CALC);
|
|
||||||
const REG_FN_REL = new RegExp(SYN_FN_REL);
|
|
||||||
const REG_FN_VAR = new RegExp(SYN_FN_VAR);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resolve color
|
|
||||||
* @param value - CSS color value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns resolved color
|
|
||||||
*/
|
|
||||||
export const resolveColor = (
|
|
||||||
value: string,
|
|
||||||
opt: Options = {}
|
|
||||||
): string | NullObject => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const { currentColor = '', format = VAL_COMP, nullable = false } = opt;
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'resolve',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
opt
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
if (cachedResult.isNull) {
|
|
||||||
return cachedResult as NullObject;
|
|
||||||
}
|
|
||||||
return cachedResult.item as string;
|
|
||||||
}
|
|
||||||
if (REG_FN_VAR.test(value)) {
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
setCache(cacheKey, value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
const resolvedValue = resolveVar(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
switch (format) {
|
|
||||||
case 'hex':
|
|
||||||
case 'hexAlpha': {
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
if (nullable) {
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
const res = RGB_TRANSPARENT;
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value = resolvedValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (opt.format !== format) {
|
|
||||||
opt.format = format;
|
|
||||||
}
|
|
||||||
value = value.toLowerCase();
|
|
||||||
if (REG_FN_REL.test(value)) {
|
|
||||||
const resolvedValue = resolveRelativeColor(value, opt);
|
|
||||||
if (format === VAL_COMP) {
|
|
||||||
let res;
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
if (nullable) {
|
|
||||||
res = resolvedValue;
|
|
||||||
} else {
|
|
||||||
res = RGB_TRANSPARENT;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res = resolvedValue;
|
|
||||||
}
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
let res = '';
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
res = '';
|
|
||||||
} else {
|
|
||||||
res = resolvedValue;
|
|
||||||
}
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
value = '';
|
|
||||||
} else {
|
|
||||||
value = resolvedValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (REG_FN_CALC.test(value)) {
|
|
||||||
value = cssCalc(value, opt);
|
|
||||||
}
|
|
||||||
let cs = '';
|
|
||||||
let r = NaN;
|
|
||||||
let g = NaN;
|
|
||||||
let b = NaN;
|
|
||||||
let alpha = NaN;
|
|
||||||
if (value === 'transparent') {
|
|
||||||
switch (format) {
|
|
||||||
case VAL_SPEC: {
|
|
||||||
setCache(cacheKey, value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
case 'hex': {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
case 'hexAlpha': {
|
|
||||||
const res = '#00000000';
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
case VAL_COMP:
|
|
||||||
default: {
|
|
||||||
const res = RGB_TRANSPARENT;
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (value === 'currentcolor') {
|
|
||||||
if (format === VAL_SPEC) {
|
|
||||||
setCache(cacheKey, value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
if (currentColor) {
|
|
||||||
let resolvedValue;
|
|
||||||
if (currentColor.startsWith(FN_MIX)) {
|
|
||||||
resolvedValue = resolveColorMix(currentColor, opt);
|
|
||||||
} else if (currentColor.startsWith(FN_COLOR)) {
|
|
||||||
resolvedValue = resolveColorFunc(currentColor, opt);
|
|
||||||
} else {
|
|
||||||
resolvedValue = resolveColorValue(currentColor, opt);
|
|
||||||
}
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
[cs, r, g, b, alpha] = resolvedValue as ComputedColorChannels;
|
|
||||||
} else if (format === VAL_COMP) {
|
|
||||||
const res = RGB_TRANSPARENT;
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
} else if (format === VAL_SPEC) {
|
|
||||||
if (value.startsWith(FN_MIX)) {
|
|
||||||
const res = resolveColorMix(value, opt) as string;
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
} else if (value.startsWith(FN_COLOR)) {
|
|
||||||
const [scs, rr, gg, bb, aa] = resolveColorFunc(
|
|
||||||
value,
|
|
||||||
opt
|
|
||||||
) as SpecifiedColorChannels;
|
|
||||||
let res = '';
|
|
||||||
if (aa === 1) {
|
|
||||||
res = `color(${scs} ${rr} ${gg} ${bb})`;
|
|
||||||
} else {
|
|
||||||
res = `color(${scs} ${rr} ${gg} ${bb} / ${aa})`;
|
|
||||||
}
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
} else {
|
|
||||||
const rgb = resolveColorValue(value, opt);
|
|
||||||
if (isString(rgb)) {
|
|
||||||
setCache(cacheKey, rgb);
|
|
||||||
return rgb;
|
|
||||||
}
|
|
||||||
const [scs, rr, gg, bb, aa] = rgb as SpecifiedColorChannels;
|
|
||||||
let res = '';
|
|
||||||
if (scs === 'rgb') {
|
|
||||||
if (aa === 1) {
|
|
||||||
res = `${scs}(${rr}, ${gg}, ${bb})`;
|
|
||||||
} else {
|
|
||||||
res = `${scs}a(${rr}, ${gg}, ${bb}, ${aa})`;
|
|
||||||
}
|
|
||||||
} else if (aa === 1) {
|
|
||||||
res = `${scs}(${rr} ${gg} ${bb})`;
|
|
||||||
} else {
|
|
||||||
res = `${scs}(${rr} ${gg} ${bb} / ${aa})`;
|
|
||||||
}
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
} else if (value.startsWith(FN_MIX)) {
|
|
||||||
if (/currentcolor/.test(value)) {
|
|
||||||
if (currentColor) {
|
|
||||||
value = value.replace(/currentcolor/g, currentColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (/transparent/.test(value)) {
|
|
||||||
value = value.replace(/transparent/g, RGB_TRANSPARENT);
|
|
||||||
}
|
|
||||||
const resolvedValue = resolveColorMix(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
[cs, r, g, b, alpha] = resolvedValue as ComputedColorChannels;
|
|
||||||
} else if (value.startsWith(FN_COLOR)) {
|
|
||||||
const resolvedValue = resolveColorFunc(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
[cs, r, g, b, alpha] = resolvedValue as ComputedColorChannels;
|
|
||||||
} else if (value) {
|
|
||||||
const resolvedValue = resolveColorValue(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
setCache(cacheKey, resolvedValue);
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
[cs, r, g, b, alpha] = resolvedValue as ComputedColorChannels;
|
|
||||||
}
|
|
||||||
let res = '';
|
|
||||||
switch (format) {
|
|
||||||
case 'hex': {
|
|
||||||
if (
|
|
||||||
Number.isNaN(r) ||
|
|
||||||
Number.isNaN(g) ||
|
|
||||||
Number.isNaN(b) ||
|
|
||||||
Number.isNaN(alpha) ||
|
|
||||||
alpha === 0
|
|
||||||
) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
res = convertRgbToHex([r, g, b, 1]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'hexAlpha': {
|
|
||||||
if (
|
|
||||||
Number.isNaN(r) ||
|
|
||||||
Number.isNaN(g) ||
|
|
||||||
Number.isNaN(b) ||
|
|
||||||
Number.isNaN(alpha)
|
|
||||||
) {
|
|
||||||
setCache(cacheKey, null);
|
|
||||||
return new NullObject();
|
|
||||||
}
|
|
||||||
res = convertRgbToHex([r, g, b, alpha]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VAL_COMP:
|
|
||||||
default: {
|
|
||||||
switch (cs) {
|
|
||||||
case 'rgb': {
|
|
||||||
if (alpha === 1) {
|
|
||||||
res = `${cs}(${r}, ${g}, ${b})`;
|
|
||||||
} else {
|
|
||||||
res = `${cs}a(${r}, ${g}, ${b}, ${alpha})`;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'lab':
|
|
||||||
case 'lch':
|
|
||||||
case 'oklab':
|
|
||||||
case 'oklch': {
|
|
||||||
if (alpha === 1) {
|
|
||||||
res = `${cs}(${r} ${g} ${b})`;
|
|
||||||
} else {
|
|
||||||
res = `${cs}(${r} ${g} ${b} / ${alpha})`;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// color()
|
|
||||||
default: {
|
|
||||||
if (alpha === 1) {
|
|
||||||
res = `color(${cs} ${r} ${g} ${b})`;
|
|
||||||
} else {
|
|
||||||
res = `color(${cs} ${r} ${g} ${b} / ${alpha})`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resolve CSS color
|
|
||||||
* @param value
|
|
||||||
* - CSS color value
|
|
||||||
* - system colors are not supported
|
|
||||||
* @param [opt] - options
|
|
||||||
* @param [opt.currentColor]
|
|
||||||
* - color to use for `currentcolor` keyword
|
|
||||||
* - if omitted, it will be treated as a missing color
|
|
||||||
* i.e. `rgb(none none none / none)`
|
|
||||||
* @param [opt.customProperty]
|
|
||||||
* - custom properties
|
|
||||||
* - pair of `--` prefixed property name and value,
|
|
||||||
* e.g. `customProperty: { '--some-color': '#0000ff' }`
|
|
||||||
* - and/or `callback` function to get the value of the custom property,
|
|
||||||
* e.g. `customProperty: { callback: someDeclaration.getPropertyValue }`
|
|
||||||
* @param [opt.dimension]
|
|
||||||
* - dimension, convert relative length to pixels
|
|
||||||
* - pair of unit and it's value as a number in pixels,
|
|
||||||
* e.g. `dimension: { em: 12, rem: 16, vw: 10.26 }`
|
|
||||||
* - and/or `callback` function to get the value as a number in pixels,
|
|
||||||
* e.g. `dimension: { callback: convertUnitToPixel }`
|
|
||||||
* @param [opt.format]
|
|
||||||
* - output format, one of below
|
|
||||||
* - `computedValue` (default), [computed value][139] of the color
|
|
||||||
* - `specifiedValue`, [specified value][140] of the color
|
|
||||||
* - `hex`, hex color notation, i.e. `rrggbb`
|
|
||||||
* - `hexAlpha`, hex color notation with alpha channel, i.e. `#rrggbbaa`
|
|
||||||
* @returns
|
|
||||||
* - one of rgba?(), #rrggbb(aa)?, color-name, '(empty-string)',
|
|
||||||
* color(color-space r g b / alpha), color(color-space x y z / alpha),
|
|
||||||
* lab(l a b / alpha), lch(l c h / alpha), oklab(l a b / alpha),
|
|
||||||
* oklch(l c h / alpha), null
|
|
||||||
* - in `computedValue`, values are numbers, however `rgb()` values are
|
|
||||||
* integers
|
|
||||||
* - in `specifiedValue`, returns `empty string` for unknown and/or invalid
|
|
||||||
* color
|
|
||||||
* - in `hex`, returns `null` for `transparent`, and also returns `null` if
|
|
||||||
* any of `r`, `g`, `b`, `alpha` is not a number
|
|
||||||
* - in `hexAlpha`, returns `#00000000` for `transparent`,
|
|
||||||
* however returns `null` if any of `r`, `g`, `b`, `alpha` is not a number
|
|
||||||
*/
|
|
||||||
export const resolve = (value: string, opt: Options = {}): string | null => {
|
|
||||||
opt.nullable = false;
|
|
||||||
const resolvedValue = resolveColor(value, opt);
|
|
||||||
if (resolvedValue instanceof NullObject) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return resolvedValue as string;
|
|
||||||
};
|
|
||||||
-87
@@ -1,87 +0,0 @@
|
|||||||
/**
|
|
||||||
* typedef
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* type definitions */
|
|
||||||
/**
|
|
||||||
* @typedef Options - options
|
|
||||||
* @property [alpha] - enable alpha
|
|
||||||
* @property [colorSpace] - color space
|
|
||||||
* @property [currentColor] - color for currentcolor
|
|
||||||
* @property [customPropeerty] - custom properties
|
|
||||||
* @property [d50] - white point in d50
|
|
||||||
* @property [dimension] - dimension
|
|
||||||
* @property [format] - output format
|
|
||||||
* @property [key] - key
|
|
||||||
*/
|
|
||||||
export interface Options {
|
|
||||||
alpha?: boolean;
|
|
||||||
colorSpace?: string;
|
|
||||||
currentColor?: string;
|
|
||||||
customProperty?: Record<string, string | ((K: string) => string)>;
|
|
||||||
d50?: boolean;
|
|
||||||
delimiter?: string | string[];
|
|
||||||
dimension?: Record<string, number | ((K: string) => number)>;
|
|
||||||
format?: string;
|
|
||||||
nullable?: boolean;
|
|
||||||
preserveComment?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type ColorChannels - color channels
|
|
||||||
*/
|
|
||||||
export type ColorChannels = [x: number, y: number, z: number, alpha: number];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type StringColorChannels - color channels
|
|
||||||
*/
|
|
||||||
export type StringColorChannels = [
|
|
||||||
x: string,
|
|
||||||
y: string,
|
|
||||||
z: string,
|
|
||||||
alpha: string | undefined
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type StringColorSpacedChannels - specified value
|
|
||||||
*/
|
|
||||||
export type StringColorSpacedChannels = [
|
|
||||||
cs: string,
|
|
||||||
x: string,
|
|
||||||
y: string,
|
|
||||||
z: string,
|
|
||||||
alpha: string | undefined
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type ComputedColorChannels - computed value
|
|
||||||
*/
|
|
||||||
export type ComputedColorChannels = [
|
|
||||||
cs: string,
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
alpha: number
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type SpecifiedColorChannels - specified value
|
|
||||||
*/
|
|
||||||
export type SpecifiedColorChannels = [
|
|
||||||
cs: string,
|
|
||||||
x: number | string,
|
|
||||||
y: number | string,
|
|
||||||
z: number | string,
|
|
||||||
alpha: number | string
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type MatchedRegExp - matched regexp array
|
|
||||||
*/
|
|
||||||
export type MatchedRegExp = [
|
|
||||||
match: string,
|
|
||||||
gr1: string,
|
|
||||||
gr2: string,
|
|
||||||
gr3: string,
|
|
||||||
gr4: string
|
|
||||||
];
|
|
||||||
-336
@@ -1,336 +0,0 @@
|
|||||||
/**
|
|
||||||
* util
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { TokenType, tokenize } from '@csstools/css-tokenizer';
|
|
||||||
import { CacheItem, createCacheKey, getCache, setCache } from './cache';
|
|
||||||
import { isString } from './common';
|
|
||||||
import { resolveColor } from './resolve';
|
|
||||||
import { Options } from './typedef';
|
|
||||||
|
|
||||||
/* constants */
|
|
||||||
import { NAMED_COLORS } from './color';
|
|
||||||
import { SYN_COLOR_TYPE, SYN_MIX, VAL_SPEC } from './constant';
|
|
||||||
const {
|
|
||||||
CloseParen: PAREN_CLOSE,
|
|
||||||
Comma: COMMA,
|
|
||||||
Comment: COMMENT,
|
|
||||||
Delim: DELIM,
|
|
||||||
EOF,
|
|
||||||
Function: FUNC,
|
|
||||||
Ident: IDENT,
|
|
||||||
OpenParen: PAREN_OPEN,
|
|
||||||
Whitespace: W_SPACE
|
|
||||||
} = TokenType;
|
|
||||||
const NAMESPACE = 'util';
|
|
||||||
|
|
||||||
/* numeric constants */
|
|
||||||
const DEC = 10;
|
|
||||||
const HEX = 16;
|
|
||||||
const DEG = 360;
|
|
||||||
const DEG_HALF = 180;
|
|
||||||
|
|
||||||
/* regexp */
|
|
||||||
const REG_COLOR = new RegExp(`^(?:${SYN_COLOR_TYPE})$`);
|
|
||||||
const REG_FN_COLOR =
|
|
||||||
/^(?:(?:ok)?l(?:ab|ch)|color(?:-mix)?|hsla?|hwb|rgba?|var)\(/;
|
|
||||||
const REG_MIX = new RegExp(SYN_MIX);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* split value
|
|
||||||
* NOTE: comments are stripped, it can be preserved if, in the options param,
|
|
||||||
* `delimiter` is either ',' or '/' and with `preserveComment` set to `true`
|
|
||||||
* @param value - CSS value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns array of values
|
|
||||||
*/
|
|
||||||
export const splitValue = (value: string, opt: Options = {}): string[] => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const { delimiter = ' ', preserveComment = false } = opt;
|
|
||||||
const cacheKey: string = createCacheKey(
|
|
||||||
{
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'splitValue',
|
|
||||||
value
|
|
||||||
},
|
|
||||||
{
|
|
||||||
delimiter,
|
|
||||||
preserveComment
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item as string[];
|
|
||||||
}
|
|
||||||
let regDelimiter;
|
|
||||||
if (delimiter === ',') {
|
|
||||||
regDelimiter = /^,$/;
|
|
||||||
} else if (delimiter === '/') {
|
|
||||||
regDelimiter = /^\/$/;
|
|
||||||
} else {
|
|
||||||
regDelimiter = /^\s+$/;
|
|
||||||
}
|
|
||||||
const tokens = tokenize({ css: value });
|
|
||||||
let nest = 0;
|
|
||||||
let str = '';
|
|
||||||
const res: string[] = [];
|
|
||||||
while (tokens.length) {
|
|
||||||
const [type, value] = tokens.shift() as [TokenType, string];
|
|
||||||
switch (type) {
|
|
||||||
case COMMA: {
|
|
||||||
if (regDelimiter.test(value)) {
|
|
||||||
if (nest === 0) {
|
|
||||||
res.push(str.trim());
|
|
||||||
str = '';
|
|
||||||
} else {
|
|
||||||
str += value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
str += value;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DELIM: {
|
|
||||||
if (regDelimiter.test(value)) {
|
|
||||||
if (nest === 0) {
|
|
||||||
res.push(str.trim());
|
|
||||||
str = '';
|
|
||||||
} else {
|
|
||||||
str += value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
str += value;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case COMMENT: {
|
|
||||||
if (preserveComment && (delimiter === ',' || delimiter === '/')) {
|
|
||||||
str += value;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FUNC:
|
|
||||||
case PAREN_OPEN: {
|
|
||||||
str += value;
|
|
||||||
nest++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PAREN_CLOSE: {
|
|
||||||
str += value;
|
|
||||||
nest--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case W_SPACE: {
|
|
||||||
if (regDelimiter.test(value)) {
|
|
||||||
if (nest === 0) {
|
|
||||||
if (str) {
|
|
||||||
res.push(str.trim());
|
|
||||||
str = '';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
str += ' ';
|
|
||||||
}
|
|
||||||
} else if (!str.endsWith(' ')) {
|
|
||||||
str += ' ';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
if (type === EOF) {
|
|
||||||
res.push(str.trim());
|
|
||||||
str = '';
|
|
||||||
} else {
|
|
||||||
str += value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* extract dashed-ident tokens
|
|
||||||
* @param value - CSS value
|
|
||||||
* @returns array of dashed-ident tokens
|
|
||||||
*/
|
|
||||||
export const extractDashedIdent = (value: string): string[] => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.trim();
|
|
||||||
} else {
|
|
||||||
throw new TypeError(`${value} is not a string.`);
|
|
||||||
}
|
|
||||||
const cacheKey: string = createCacheKey({
|
|
||||||
namespace: NAMESPACE,
|
|
||||||
name: 'extractDashedIdent',
|
|
||||||
value
|
|
||||||
});
|
|
||||||
const cachedResult = getCache(cacheKey);
|
|
||||||
if (cachedResult instanceof CacheItem) {
|
|
||||||
return cachedResult.item as string[];
|
|
||||||
}
|
|
||||||
const tokens = tokenize({ css: value });
|
|
||||||
const items = new Set();
|
|
||||||
while (tokens.length) {
|
|
||||||
const [type, value] = tokens.shift() as [TokenType, string];
|
|
||||||
if (type === IDENT && value.startsWith('--')) {
|
|
||||||
items.add(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const res = [...items] as string[];
|
|
||||||
setCache(cacheKey, res);
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* is color
|
|
||||||
* @param value - CSS value
|
|
||||||
* @param [opt] - options
|
|
||||||
* @returns result
|
|
||||||
*/
|
|
||||||
export const isColor = (value: unknown, opt: Options = {}): boolean => {
|
|
||||||
if (isString(value)) {
|
|
||||||
value = value.toLowerCase().trim();
|
|
||||||
if (value && isString(value)) {
|
|
||||||
if (/^[a-z]+$/.test(value)) {
|
|
||||||
if (
|
|
||||||
/^(?:currentcolor|transparent)$/.test(value) ||
|
|
||||||
Object.prototype.hasOwnProperty.call(NAMED_COLORS, value)
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (REG_COLOR.test(value) || REG_MIX.test(value)) {
|
|
||||||
return true;
|
|
||||||
} else if (REG_FN_COLOR.test(value)) {
|
|
||||||
opt.nullable = true;
|
|
||||||
if (!opt.format) {
|
|
||||||
opt.format = VAL_SPEC;
|
|
||||||
}
|
|
||||||
const resolvedValue = resolveColor(value, opt);
|
|
||||||
if (resolvedValue) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* value to JSON string
|
|
||||||
* @param value - CSS value
|
|
||||||
* @param [func] - stringify function
|
|
||||||
* @returns stringified value in JSON notation
|
|
||||||
*/
|
|
||||||
export const valueToJsonString = (
|
|
||||||
value: unknown,
|
|
||||||
func: boolean = false
|
|
||||||
): string => {
|
|
||||||
if (typeof value === 'undefined') {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
const res = JSON.stringify(value, (_key, val) => {
|
|
||||||
let replacedValue;
|
|
||||||
if (typeof val === 'undefined') {
|
|
||||||
replacedValue = null;
|
|
||||||
} else if (typeof val === 'function') {
|
|
||||||
if (func) {
|
|
||||||
replacedValue = val.toString().replace(/\s/g, '').substring(0, HEX);
|
|
||||||
} else {
|
|
||||||
replacedValue = val.name;
|
|
||||||
}
|
|
||||||
} else if (val instanceof Map || val instanceof Set) {
|
|
||||||
replacedValue = [...val];
|
|
||||||
} else if (typeof val === 'bigint') {
|
|
||||||
replacedValue = val.toString();
|
|
||||||
} else {
|
|
||||||
replacedValue = val;
|
|
||||||
}
|
|
||||||
return replacedValue;
|
|
||||||
});
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* round to specified precision
|
|
||||||
* @param value - numeric value
|
|
||||||
* @param bit - minimum bits
|
|
||||||
* @returns rounded value
|
|
||||||
*/
|
|
||||||
export const roundToPrecision = (value: number, bit: number = 0): number => {
|
|
||||||
if (!Number.isFinite(value)) {
|
|
||||||
throw new TypeError(`${value} is not a finite number.`);
|
|
||||||
}
|
|
||||||
if (!Number.isFinite(bit)) {
|
|
||||||
throw new TypeError(`${bit} is not a finite number.`);
|
|
||||||
} else if (bit < 0 || bit > HEX) {
|
|
||||||
throw new RangeError(`${bit} is not between 0 and ${HEX}.`);
|
|
||||||
}
|
|
||||||
if (bit === 0) {
|
|
||||||
return Math.round(value);
|
|
||||||
}
|
|
||||||
let val;
|
|
||||||
if (bit === HEX) {
|
|
||||||
val = value.toPrecision(6);
|
|
||||||
} else if (bit < DEC) {
|
|
||||||
val = value.toPrecision(4);
|
|
||||||
} else {
|
|
||||||
val = value.toPrecision(5);
|
|
||||||
}
|
|
||||||
return parseFloat(val);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* interpolate hue
|
|
||||||
* @param hueA - hue value
|
|
||||||
* @param hueB - hue value
|
|
||||||
* @param arc - shorter | longer | increasing | decreasing
|
|
||||||
* @returns result - [hueA, hueB]
|
|
||||||
*/
|
|
||||||
export const interpolateHue = (
|
|
||||||
hueA: number,
|
|
||||||
hueB: number,
|
|
||||||
arc: string = 'shorter'
|
|
||||||
): [number, number] => {
|
|
||||||
if (!Number.isFinite(hueA)) {
|
|
||||||
throw new TypeError(`${hueA} is not a finite number.`);
|
|
||||||
}
|
|
||||||
if (!Number.isFinite(hueB)) {
|
|
||||||
throw new TypeError(`${hueB} is not a finite number.`);
|
|
||||||
}
|
|
||||||
switch (arc) {
|
|
||||||
case 'decreasing': {
|
|
||||||
if (hueB > hueA) {
|
|
||||||
hueA += DEG;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'increasing': {
|
|
||||||
if (hueB < hueA) {
|
|
||||||
hueB += DEG;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'longer': {
|
|
||||||
if (hueB > hueA && hueB < hueA + DEG_HALF) {
|
|
||||||
hueA += DEG;
|
|
||||||
} else if (hueB > hueA + DEG_HALF * -1 && hueB <= hueA) {
|
|
||||||
hueB += DEG;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'shorter':
|
|
||||||
default: {
|
|
||||||
if (hueB > hueA + DEG_HALF) {
|
|
||||||
hueA += DEG;
|
|
||||||
} else if (hueB < hueA + DEG_HALF * -1) {
|
|
||||||
hueB += DEG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [hueA, hueB];
|
|
||||||
};
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2014-present Sebastian McKenzie and other contributors
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
# @babel/code-frame
|
|
||||||
|
|
||||||
> Generate errors that contain a code frame that point to source locations.
|
|
||||||
|
|
||||||
See our website [@babel/code-frame](https://babeljs.io/docs/babel-code-frame) for more information.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
Using npm:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm install --save-dev @babel/code-frame
|
|
||||||
```
|
|
||||||
|
|
||||||
or using yarn:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
yarn add @babel/code-frame --dev
|
|
||||||
```
|
|
||||||
-217
@@ -1,217 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', { value: true });
|
|
||||||
|
|
||||||
var picocolors = require('picocolors');
|
|
||||||
var jsTokens = require('js-tokens');
|
|
||||||
var helperValidatorIdentifier = require('@babel/helper-validator-identifier');
|
|
||||||
|
|
||||||
function isColorSupported() {
|
|
||||||
return (typeof process === "object" && (process.env.FORCE_COLOR === "0" || process.env.FORCE_COLOR === "false") ? false : picocolors.isColorSupported
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const compose = (f, g) => v => f(g(v));
|
|
||||||
function buildDefs(colors) {
|
|
||||||
return {
|
|
||||||
keyword: colors.cyan,
|
|
||||||
capitalized: colors.yellow,
|
|
||||||
jsxIdentifier: colors.yellow,
|
|
||||||
punctuator: colors.yellow,
|
|
||||||
number: colors.magenta,
|
|
||||||
string: colors.green,
|
|
||||||
regex: colors.magenta,
|
|
||||||
comment: colors.gray,
|
|
||||||
invalid: compose(compose(colors.white, colors.bgRed), colors.bold),
|
|
||||||
gutter: colors.gray,
|
|
||||||
marker: compose(colors.red, colors.bold),
|
|
||||||
message: compose(colors.red, colors.bold),
|
|
||||||
reset: colors.reset
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const defsOn = buildDefs(picocolors.createColors(true));
|
|
||||||
const defsOff = buildDefs(picocolors.createColors(false));
|
|
||||||
function getDefs(enabled) {
|
|
||||||
return enabled ? defsOn : defsOff;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sometimesKeywords = new Set(["as", "async", "from", "get", "of", "set"]);
|
|
||||||
const NEWLINE$1 = /\r\n|[\n\r\u2028\u2029]/;
|
|
||||||
const BRACKET = /^[()[\]{}]$/;
|
|
||||||
let tokenize;
|
|
||||||
const JSX_TAG = /^[a-z][\w-]*$/i;
|
|
||||||
const getTokenType = function (token, offset, text) {
|
|
||||||
if (token.type === "name") {
|
|
||||||
const tokenValue = token.value;
|
|
||||||
if (helperValidatorIdentifier.isKeyword(tokenValue) || helperValidatorIdentifier.isStrictReservedWord(tokenValue, true) || sometimesKeywords.has(tokenValue)) {
|
|
||||||
return "keyword";
|
|
||||||
}
|
|
||||||
if (JSX_TAG.test(tokenValue) && (text[offset - 1] === "<" || text.slice(offset - 2, offset) === "</")) {
|
|
||||||
return "jsxIdentifier";
|
|
||||||
}
|
|
||||||
const firstChar = String.fromCodePoint(tokenValue.codePointAt(0));
|
|
||||||
if (firstChar !== firstChar.toLowerCase()) {
|
|
||||||
return "capitalized";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (token.type === "punctuator" && BRACKET.test(token.value)) {
|
|
||||||
return "bracket";
|
|
||||||
}
|
|
||||||
if (token.type === "invalid" && (token.value === "@" || token.value === "#")) {
|
|
||||||
return "punctuator";
|
|
||||||
}
|
|
||||||
return token.type;
|
|
||||||
};
|
|
||||||
tokenize = function* (text) {
|
|
||||||
let match;
|
|
||||||
while (match = jsTokens.default.exec(text)) {
|
|
||||||
const token = jsTokens.matchToToken(match);
|
|
||||||
yield {
|
|
||||||
type: getTokenType(token, match.index, text),
|
|
||||||
value: token.value
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
function highlight(text) {
|
|
||||||
if (text === "") return "";
|
|
||||||
const defs = getDefs(true);
|
|
||||||
let highlighted = "";
|
|
||||||
for (const {
|
|
||||||
type,
|
|
||||||
value
|
|
||||||
} of tokenize(text)) {
|
|
||||||
if (type in defs) {
|
|
||||||
highlighted += value.split(NEWLINE$1).map(str => defs[type](str)).join("\n");
|
|
||||||
} else {
|
|
||||||
highlighted += value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return highlighted;
|
|
||||||
}
|
|
||||||
|
|
||||||
let deprecationWarningShown = false;
|
|
||||||
const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
|
|
||||||
function getMarkerLines(loc, source, opts, startLineBaseZero) {
|
|
||||||
const startLoc = Object.assign({
|
|
||||||
column: 0,
|
|
||||||
line: -1
|
|
||||||
}, loc.start);
|
|
||||||
const endLoc = Object.assign({}, startLoc, loc.end);
|
|
||||||
const {
|
|
||||||
linesAbove = 2,
|
|
||||||
linesBelow = 3
|
|
||||||
} = opts || {};
|
|
||||||
const startLine = startLoc.line - startLineBaseZero;
|
|
||||||
const startColumn = startLoc.column;
|
|
||||||
const endLine = endLoc.line - startLineBaseZero;
|
|
||||||
const endColumn = endLoc.column;
|
|
||||||
let start = Math.max(startLine - (linesAbove + 1), 0);
|
|
||||||
let end = Math.min(source.length, endLine + linesBelow);
|
|
||||||
if (startLine === -1) {
|
|
||||||
start = 0;
|
|
||||||
}
|
|
||||||
if (endLine === -1) {
|
|
||||||
end = source.length;
|
|
||||||
}
|
|
||||||
const lineDiff = endLine - startLine;
|
|
||||||
const markerLines = {};
|
|
||||||
if (lineDiff) {
|
|
||||||
for (let i = 0; i <= lineDiff; i++) {
|
|
||||||
const lineNumber = i + startLine;
|
|
||||||
if (!startColumn) {
|
|
||||||
markerLines[lineNumber] = true;
|
|
||||||
} else if (i === 0) {
|
|
||||||
const sourceLength = source[lineNumber - 1].length;
|
|
||||||
markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1];
|
|
||||||
} else if (i === lineDiff) {
|
|
||||||
markerLines[lineNumber] = [0, endColumn];
|
|
||||||
} else {
|
|
||||||
const sourceLength = source[lineNumber - i].length;
|
|
||||||
markerLines[lineNumber] = [0, sourceLength];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (startColumn === endColumn) {
|
|
||||||
if (startColumn) {
|
|
||||||
markerLines[startLine] = [startColumn, 0];
|
|
||||||
} else {
|
|
||||||
markerLines[startLine] = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
markerLines[startLine] = [startColumn, endColumn - startColumn];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
markerLines
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function codeFrameColumns(rawLines, loc, opts = {}) {
|
|
||||||
const shouldHighlight = opts.forceColor || isColorSupported() && opts.highlightCode;
|
|
||||||
const startLineBaseZero = (opts.startLine || 1) - 1;
|
|
||||||
const defs = getDefs(shouldHighlight);
|
|
||||||
const lines = rawLines.split(NEWLINE);
|
|
||||||
const {
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
markerLines
|
|
||||||
} = getMarkerLines(loc, lines, opts, startLineBaseZero);
|
|
||||||
const hasColumns = loc.start && typeof loc.start.column === "number";
|
|
||||||
const numberMaxWidth = String(end + startLineBaseZero).length;
|
|
||||||
const highlightedLines = shouldHighlight ? highlight(rawLines) : rawLines;
|
|
||||||
let frame = highlightedLines.split(NEWLINE, end).slice(start, end).map((line, index) => {
|
|
||||||
const number = start + 1 + index;
|
|
||||||
const paddedNumber = ` ${number + startLineBaseZero}`.slice(-numberMaxWidth);
|
|
||||||
const gutter = ` ${paddedNumber} |`;
|
|
||||||
const hasMarker = markerLines[number];
|
|
||||||
const lastMarkerLine = !markerLines[number + 1];
|
|
||||||
if (hasMarker) {
|
|
||||||
let markerLine = "";
|
|
||||||
if (Array.isArray(hasMarker)) {
|
|
||||||
const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " ");
|
|
||||||
const numberOfMarkers = hasMarker[1] || 1;
|
|
||||||
markerLine = ["\n ", defs.gutter(gutter.replace(/\d/g, " ")), " ", markerSpacing, defs.marker("^").repeat(numberOfMarkers)].join("");
|
|
||||||
if (lastMarkerLine && opts.message) {
|
|
||||||
markerLine += " " + defs.message(opts.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [defs.marker(">"), defs.gutter(gutter), line.length > 0 ? ` ${line}` : "", markerLine].join("");
|
|
||||||
} else {
|
|
||||||
return ` ${defs.gutter(gutter)}${line.length > 0 ? ` ${line}` : ""}`;
|
|
||||||
}
|
|
||||||
}).join("\n");
|
|
||||||
if (opts.message && !hasColumns) {
|
|
||||||
frame = `${" ".repeat(numberMaxWidth + 1)}${opts.message}\n${frame}`;
|
|
||||||
}
|
|
||||||
if (shouldHighlight) {
|
|
||||||
return defs.reset(frame);
|
|
||||||
} else {
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function index (rawLines, lineNumber, colNumber, opts = {}) {
|
|
||||||
if (!deprecationWarningShown) {
|
|
||||||
deprecationWarningShown = true;
|
|
||||||
const message = "Passing lineNumber and colNumber is deprecated to @babel/code-frame. Please use `codeFrameColumns`.";
|
|
||||||
if (process.emitWarning) {
|
|
||||||
process.emitWarning(message, "DeprecationWarning");
|
|
||||||
} else {
|
|
||||||
const deprecationError = new Error(message);
|
|
||||||
deprecationError.name = "DeprecationWarning";
|
|
||||||
console.warn(new Error(message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
colNumber = Math.max(colNumber, 0);
|
|
||||||
const location = {
|
|
||||||
start: {
|
|
||||||
column: colNumber,
|
|
||||||
line: lineNumber
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return codeFrameColumns(rawLines, location, opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.codeFrameColumns = codeFrameColumns;
|
|
||||||
exports.default = index;
|
|
||||||
exports.highlight = highlight;
|
|
||||||
//# sourceMappingURL=index.js.map
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-32
@@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@babel/code-frame",
|
|
||||||
"version": "7.29.0",
|
|
||||||
"description": "Generate errors that contain a code frame that point to source locations.",
|
|
||||||
"author": "The Babel Team (https://babel.dev/team)",
|
|
||||||
"homepage": "https://babel.dev/docs/en/next/babel-code-frame",
|
|
||||||
"bugs": "https://github.com/babel/babel/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen",
|
|
||||||
"license": "MIT",
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/babel/babel.git",
|
|
||||||
"directory": "packages/babel-code-frame"
|
|
||||||
},
|
|
||||||
"main": "./lib/index.js",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/helper-validator-identifier": "^7.28.5",
|
|
||||||
"js-tokens": "^4.0.0",
|
|
||||||
"picocolors": "^1.1.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"charcodes": "^0.2.0",
|
|
||||||
"import-meta-resolve": "^4.1.0",
|
|
||||||
"strip-ansi": "^4.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
},
|
|
||||||
"type": "commonjs"
|
|
||||||
}
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2014-present Sebastian McKenzie and other contributors
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
# @babel/helper-validator-identifier
|
|
||||||
|
|
||||||
> Validate identifier/keywords name
|
|
||||||
|
|
||||||
See our website [@babel/helper-validator-identifier](https://babeljs.io/docs/babel-helper-validator-identifier) for more information.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
Using npm:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm install --save @babel/helper-validator-identifier
|
|
||||||
```
|
|
||||||
|
|
||||||
or using yarn:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
yarn add @babel/helper-validator-identifier
|
|
||||||
```
|
|
||||||
-70
@@ -1,70 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", {
|
|
||||||
value: true
|
|
||||||
});
|
|
||||||
exports.isIdentifierChar = isIdentifierChar;
|
|
||||||
exports.isIdentifierName = isIdentifierName;
|
|
||||||
exports.isIdentifierStart = isIdentifierStart;
|
|
||||||
let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088f\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5c\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdc-\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c8a\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7dc\ua7f1-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
|
|
||||||
let nonASCIIidentifierChars = "\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0897-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1add\u1ae0-\u1aeb\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65";
|
|
||||||
const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
|
|
||||||
const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
|
|
||||||
nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
|
|
||||||
const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 7, 25, 39, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 39, 27, 10, 22, 251, 41, 7, 1, 17, 5, 57, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 31, 9, 2, 0, 3, 0, 2, 37, 2, 0, 26, 0, 2, 0, 45, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 200, 32, 32, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 24, 43, 261, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 26, 3994, 6, 582, 6842, 29, 1763, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 433, 44, 212, 63, 33, 24, 3, 24, 45, 74, 6, 0, 67, 12, 65, 1, 2, 0, 15, 4, 10, 7381, 42, 31, 98, 114, 8702, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 229, 29, 3, 0, 208, 30, 2, 2, 2, 1, 2, 6, 3, 4, 10, 1, 225, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4381, 3, 5773, 3, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 8489];
|
|
||||||
const astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 7, 9, 32, 4, 318, 1, 78, 5, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 68, 8, 2, 0, 3, 0, 2, 3, 2, 4, 2, 0, 15, 1, 83, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 7, 19, 58, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 199, 7, 137, 9, 54, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 55, 9, 266, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 10, 5350, 0, 7, 14, 11465, 27, 2343, 9, 87, 9, 39, 4, 60, 6, 26, 9, 535, 9, 470, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4178, 9, 519, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 245, 1, 2, 9, 233, 0, 3, 0, 8, 1, 6, 0, 475, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];
|
|
||||||
function isInAstralSet(code, set) {
|
|
||||||
let pos = 0x10000;
|
|
||||||
for (let i = 0, length = set.length; i < length; i += 2) {
|
|
||||||
pos += set[i];
|
|
||||||
if (pos > code) return false;
|
|
||||||
pos += set[i + 1];
|
|
||||||
if (pos >= code) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
function isIdentifierStart(code) {
|
|
||||||
if (code < 65) return code === 36;
|
|
||||||
if (code <= 90) return true;
|
|
||||||
if (code < 97) return code === 95;
|
|
||||||
if (code <= 122) return true;
|
|
||||||
if (code <= 0xffff) {
|
|
||||||
return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
|
|
||||||
}
|
|
||||||
return isInAstralSet(code, astralIdentifierStartCodes);
|
|
||||||
}
|
|
||||||
function isIdentifierChar(code) {
|
|
||||||
if (code < 48) return code === 36;
|
|
||||||
if (code < 58) return true;
|
|
||||||
if (code < 65) return false;
|
|
||||||
if (code <= 90) return true;
|
|
||||||
if (code < 97) return code === 95;
|
|
||||||
if (code <= 122) return true;
|
|
||||||
if (code <= 0xffff) {
|
|
||||||
return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
|
|
||||||
}
|
|
||||||
return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
|
|
||||||
}
|
|
||||||
function isIdentifierName(name) {
|
|
||||||
let isFirst = true;
|
|
||||||
for (let i = 0; i < name.length; i++) {
|
|
||||||
let cp = name.charCodeAt(i);
|
|
||||||
if ((cp & 0xfc00) === 0xd800 && i + 1 < name.length) {
|
|
||||||
const trail = name.charCodeAt(++i);
|
|
||||||
if ((trail & 0xfc00) === 0xdc00) {
|
|
||||||
cp = 0x10000 + ((cp & 0x3ff) << 10) + (trail & 0x3ff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isFirst) {
|
|
||||||
isFirst = false;
|
|
||||||
if (!isIdentifierStart(cp)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!isIdentifierChar(cp)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return !isFirst;
|
|
||||||
}
|
|
||||||
|
|
||||||
//# sourceMappingURL=identifier.js.map
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-57
@@ -1,57 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", {
|
|
||||||
value: true
|
|
||||||
});
|
|
||||||
Object.defineProperty(exports, "isIdentifierChar", {
|
|
||||||
enumerable: true,
|
|
||||||
get: function () {
|
|
||||||
return _identifier.isIdentifierChar;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(exports, "isIdentifierName", {
|
|
||||||
enumerable: true,
|
|
||||||
get: function () {
|
|
||||||
return _identifier.isIdentifierName;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(exports, "isIdentifierStart", {
|
|
||||||
enumerable: true,
|
|
||||||
get: function () {
|
|
||||||
return _identifier.isIdentifierStart;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(exports, "isKeyword", {
|
|
||||||
enumerable: true,
|
|
||||||
get: function () {
|
|
||||||
return _keyword.isKeyword;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(exports, "isReservedWord", {
|
|
||||||
enumerable: true,
|
|
||||||
get: function () {
|
|
||||||
return _keyword.isReservedWord;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(exports, "isStrictBindOnlyReservedWord", {
|
|
||||||
enumerable: true,
|
|
||||||
get: function () {
|
|
||||||
return _keyword.isStrictBindOnlyReservedWord;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(exports, "isStrictBindReservedWord", {
|
|
||||||
enumerable: true,
|
|
||||||
get: function () {
|
|
||||||
return _keyword.isStrictBindReservedWord;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object.defineProperty(exports, "isStrictReservedWord", {
|
|
||||||
enumerable: true,
|
|
||||||
get: function () {
|
|
||||||
return _keyword.isStrictReservedWord;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var _identifier = require("./identifier.js");
|
|
||||||
var _keyword = require("./keyword.js");
|
|
||||||
|
|
||||||
//# sourceMappingURL=index.js.map
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
{"version":3,"names":["_identifier","require","_keyword"],"sources":["../src/index.ts"],"sourcesContent":["export {\n isIdentifierName,\n isIdentifierChar,\n isIdentifierStart,\n} from \"./identifier.ts\";\nexport {\n isReservedWord,\n isStrictBindOnlyReservedWord,\n isStrictBindReservedWord,\n isStrictReservedWord,\n isKeyword,\n} from \"./keyword.ts\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,WAAA,GAAAC,OAAA;AAKA,IAAAC,QAAA,GAAAD,OAAA","ignoreList":[]}
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", {
|
|
||||||
value: true
|
|
||||||
});
|
|
||||||
exports.isKeyword = isKeyword;
|
|
||||||
exports.isReservedWord = isReservedWord;
|
|
||||||
exports.isStrictBindOnlyReservedWord = isStrictBindOnlyReservedWord;
|
|
||||||
exports.isStrictBindReservedWord = isStrictBindReservedWord;
|
|
||||||
exports.isStrictReservedWord = isStrictReservedWord;
|
|
||||||
const reservedWords = {
|
|
||||||
keyword: ["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"],
|
|
||||||
strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"],
|
|
||||||
strictBind: ["eval", "arguments"]
|
|
||||||
};
|
|
||||||
const keywords = new Set(reservedWords.keyword);
|
|
||||||
const reservedWordsStrictSet = new Set(reservedWords.strict);
|
|
||||||
const reservedWordsStrictBindSet = new Set(reservedWords.strictBind);
|
|
||||||
function isReservedWord(word, inModule) {
|
|
||||||
return inModule && word === "await" || word === "enum";
|
|
||||||
}
|
|
||||||
function isStrictReservedWord(word, inModule) {
|
|
||||||
return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word);
|
|
||||||
}
|
|
||||||
function isStrictBindOnlyReservedWord(word) {
|
|
||||||
return reservedWordsStrictBindSet.has(word);
|
|
||||||
}
|
|
||||||
function isStrictBindReservedWord(word, inModule) {
|
|
||||||
return isStrictReservedWord(word, inModule) || isStrictBindOnlyReservedWord(word);
|
|
||||||
}
|
|
||||||
function isKeyword(word) {
|
|
||||||
return keywords.has(word);
|
|
||||||
}
|
|
||||||
|
|
||||||
//# sourceMappingURL=keyword.js.map
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
{"version":3,"names":["reservedWords","keyword","strict","strictBind","keywords","Set","reservedWordsStrictSet","reservedWordsStrictBindSet","isReservedWord","word","inModule","isStrictReservedWord","has","isStrictBindOnlyReservedWord","isStrictBindReservedWord","isKeyword"],"sources":["../src/keyword.ts"],"sourcesContent":["const reservedWords = {\n keyword: [\n \"break\",\n \"case\",\n \"catch\",\n \"continue\",\n \"debugger\",\n \"default\",\n \"do\",\n \"else\",\n \"finally\",\n \"for\",\n \"function\",\n \"if\",\n \"return\",\n \"switch\",\n \"throw\",\n \"try\",\n \"var\",\n \"const\",\n \"while\",\n \"with\",\n \"new\",\n \"this\",\n \"super\",\n \"class\",\n \"extends\",\n \"export\",\n \"import\",\n \"null\",\n \"true\",\n \"false\",\n \"in\",\n \"instanceof\",\n \"typeof\",\n \"void\",\n \"delete\",\n ],\n strict: [\n \"implements\",\n \"interface\",\n \"let\",\n \"package\",\n \"private\",\n \"protected\",\n \"public\",\n \"static\",\n \"yield\",\n ],\n strictBind: [\"eval\", \"arguments\"],\n};\nconst keywords = new Set(reservedWords.keyword);\nconst reservedWordsStrictSet = new Set(reservedWords.strict);\nconst reservedWordsStrictBindSet = new Set(reservedWords.strictBind);\n\n/**\n * Checks if word is a reserved word in non-strict mode\n */\nexport function isReservedWord(word: string, inModule: boolean): boolean {\n return (inModule && word === \"await\") || word === \"enum\";\n}\n\n/**\n * Checks if word is a reserved word in non-binding strict mode\n *\n * Includes non-strict reserved words\n */\nexport function isStrictReservedWord(word: string, inModule: boolean): boolean {\n return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word);\n}\n\n/**\n * Checks if word is a reserved word in binding strict mode, but it is allowed as\n * a normal identifier.\n */\nexport function isStrictBindOnlyReservedWord(word: string): boolean {\n return reservedWordsStrictBindSet.has(word);\n}\n\n/**\n * Checks if word is a reserved word in binding strict mode\n *\n * Includes non-strict reserved words and non-binding strict reserved words\n */\nexport function isStrictBindReservedWord(\n word: string,\n inModule: boolean,\n): boolean {\n return (\n isStrictReservedWord(word, inModule) || isStrictBindOnlyReservedWord(word)\n );\n}\n\nexport function isKeyword(word: string): boolean {\n return keywords.has(word);\n}\n"],"mappings":";;;;;;;;;;AAAA,MAAMA,aAAa,GAAG;EACpBC,OAAO,EAAE,CACP,OAAO,EACP,MAAM,EACN,OAAO,EACP,UAAU,EACV,UAAU,EACV,SAAS,EACT,IAAI,EACJ,MAAM,EACN,SAAS,EACT,KAAK,EACL,UAAU,EACV,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,EACL,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,MAAM,EACN,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,QAAQ,CACT;EACDC,MAAM,EAAE,CACN,YAAY,EACZ,WAAW,EACX,KAAK,EACL,SAAS,EACT,SAAS,EACT,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,OAAO,CACR;EACDC,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW;AAClC,CAAC;AACD,MAAMC,QAAQ,GAAG,IAAIC,GAAG,CAACL,aAAa,CAACC,OAAO,CAAC;AAC/C,MAAMK,sBAAsB,GAAG,IAAID,GAAG,CAACL,aAAa,CAACE,MAAM,CAAC;AAC5D,MAAMK,0BAA0B,GAAG,IAAIF,GAAG,CAACL,aAAa,CAACG,UAAU,CAAC;AAK7D,SAASK,cAAcA,CAACC,IAAY,EAAEC,QAAiB,EAAW;EACvE,OAAQA,QAAQ,IAAID,IAAI,KAAK,OAAO,IAAKA,IAAI,KAAK,MAAM;AAC1D;AAOO,SAASE,oBAAoBA,CAACF,IAAY,EAAEC,QAAiB,EAAW;EAC7E,OAAOF,cAAc,CAACC,IAAI,EAAEC,QAAQ,CAAC,IAAIJ,sBAAsB,CAACM,GAAG,CAACH,IAAI,CAAC;AAC3E;AAMO,SAASI,4BAA4BA,CAACJ,IAAY,EAAW;EAClE,OAAOF,0BAA0B,CAACK,GAAG,CAACH,IAAI,CAAC;AAC7C;AAOO,SAASK,wBAAwBA,CACtCL,IAAY,EACZC,QAAiB,EACR;EACT,OACEC,oBAAoB,CAACF,IAAI,EAAEC,QAAQ,CAAC,IAAIG,4BAA4B,CAACJ,IAAI,CAAC;AAE9E;AAEO,SAASM,SAASA,CAACN,IAAY,EAAW;EAC/C,OAAOL,QAAQ,CAACQ,GAAG,CAACH,IAAI,CAAC;AAC3B","ignoreList":[]}
|
|
||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@babel/helper-validator-identifier",
|
|
||||||
"version": "7.28.5",
|
|
||||||
"description": "Validate identifier/keywords name",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/babel/babel.git",
|
|
||||||
"directory": "packages/babel-helper-validator-identifier"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"main": "./lib/index.js",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"types": "./lib/index.d.ts",
|
|
||||||
"default": "./lib/index.js"
|
|
||||||
},
|
|
||||||
"./package.json": "./package.json"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@unicode/unicode-17.0.0": "^1.6.10",
|
|
||||||
"charcodes": "^0.2.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
},
|
|
||||||
"author": "The Babel Team (https://babel.dev/team)",
|
|
||||||
"type": "commonjs"
|
|
||||||
}
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
# Changes to Color Helpers
|
|
||||||
|
|
||||||
### 5.1.0
|
|
||||||
|
|
||||||
_August 22, 2025_
|
|
||||||
|
|
||||||
- Add `lin_P3_to_XYZ_D50`
|
|
||||||
- Add `XYZ_D50_to_lin_P3`
|
|
||||||
|
|
||||||
[Full CHANGELOG](https://github.com/csstools/postcss-plugins/tree/main/packages/color-helpers/CHANGELOG.md)
|
|
||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
MIT No Attribution (MIT-0)
|
|
||||||
|
|
||||||
Copyright © CSSTools Contributors
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the “Software”), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
-32
@@ -1,32 +0,0 @@
|
|||||||
# Color Helpers <img src="https://cssdb.org/images/css.svg" alt="for CSS" width="90" height="90" align="right">
|
|
||||||
|
|
||||||
[<img alt="npm version" src="https://img.shields.io/npm/v/@csstools/color-helpers.svg" height="20">][npm-url]
|
|
||||||
[<img alt="Build Status" src="https://github.com/csstools/postcss-plugins/actions/workflows/test.yml/badge.svg?branch=main" height="20">][cli-url]
|
|
||||||
[<img alt="Discord" src="https://shields.io/badge/Discord-5865F2?logo=discord&logoColor=white">][discord]
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Add [Color Helpers] to your project:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @csstools/color-helpers --save-dev
|
|
||||||
```
|
|
||||||
|
|
||||||
This package exists to join all the different color functions scattered among the Colors 4 and Colors 5 plugins we maintain such as:
|
|
||||||
|
|
||||||
* [PostCSS Color Function]
|
|
||||||
* [PostCSS Lab Function]
|
|
||||||
* [PostCSS OKLab Function]
|
|
||||||
|
|
||||||
## Copyright
|
|
||||||
|
|
||||||
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).
|
|
||||||
|
|
||||||
[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
|
|
||||||
[discord]: https://discord.gg/bUadyRwkJS
|
|
||||||
[npm-url]: https://www.npmjs.com/package/@csstools/color-helpers
|
|
||||||
|
|
||||||
[Color Helpers]: https://github.com/csstools/postcss-plugins/tree/main/packages/color-helpers
|
|
||||||
[PostCSS Color Function]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-color-function
|
|
||||||
[PostCSS Lab Function]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-lab-functionw
|
|
||||||
[PostCSS OKLab Function]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-oklab-function
|
|
||||||
-263
@@ -1,263 +0,0 @@
|
|||||||
"use strict";function multiplyMatrices(t,_){return[t[0]*_[0]+t[1]*_[1]+t[2]*_[2],t[3]*_[0]+t[4]*_[1]+t[5]*_[2],t[6]*_[0]+t[7]*_[1]+t[8]*_[2]]}const t=[.955473421488075,-.02309845494876471,.06325924320057072,-.0283697093338637,1.0099953980813041,.021041441191917323,.012314014864481998,-.020507649298898964,1.330365926242124];
|
|
||||||
/**
|
|
||||||
* Bradford chromatic adaptation from D50 to D65
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function D50_to_D65(_){return multiplyMatrices(t,_)}const _=[1.0479297925449969,.022946870601609652,-.05019226628920524,.02962780877005599,.9904344267538799,-.017073799063418826,-.009243040646204504,.015055191490298152,.7518742814281371];
|
|
||||||
/**
|
|
||||||
* Bradford chromatic adaptation from D65 to D50
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
|
|
||||||
*/function D65_to_D50(t){return multiplyMatrices(_,t)}
|
|
||||||
/**
|
|
||||||
* @param {number} hue - Hue as degrees 0..360
|
|
||||||
* @param {number} sat - Saturation as percentage 0..100
|
|
||||||
* @param {number} light - Lightness as percentage 0..100
|
|
||||||
* @return {number[]} Array of sRGB components; in-gamut colors in range [0..1]
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/hslToRgb.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/hslToRgb.js
|
|
||||||
*/function HSL_to_sRGB(t){let _=t[0]%360;const n=t[1]/100,o=t[2]/100;return _<0&&(_+=360),[HSL_to_sRGB_channel(0,_,n,o),HSL_to_sRGB_channel(8,_,n,o),HSL_to_sRGB_channel(4,_,n,o)]}function HSL_to_sRGB_channel(t,_,n,o){const e=(t+_/30)%12;return o-n*Math.min(o,1-o)*Math.max(-1,Math.min(e-3,9-e,1))}
|
|
||||||
/**
|
|
||||||
* @param {number} hue - Hue as degrees 0..360
|
|
||||||
* @param {number} white - Whiteness as percentage 0..100
|
|
||||||
* @param {number} black - Blackness as percentage 0..100
|
|
||||||
* @return {number[]} Array of RGB components 0..1
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/hwbToRgb.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/hwbToRgb.js
|
|
||||||
*/function HWB_to_sRGB(t){const _=t[0],n=t[1]/100,o=t[2]/100;if(n+o>=1){const t=n/(n+o);return[t,t,t]}const e=HSL_to_sRGB([_,100,50]),r=1-n-o;return[e[0]*r+n,e[1]*r+n,e[2]*r+n]}
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function LCH_to_Lab(t){const _=t[2]*Math.PI/180;return[t[0],t[1]*Math.cos(_),t[1]*Math.sin(_)]}
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function Lab_to_LCH(t){const _=180*Math.atan2(t[2],t[1])/Math.PI;return[t[0],Math.sqrt(Math.pow(t[1],2)+Math.pow(t[2],2)),_>=0?_:_+360]}const n=[.3457/.3585,1,.2958/.3585];
|
|
||||||
/**
|
|
||||||
* Convert Lab to D50-adapted XYZ
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
||||||
*/function Lab_to_XYZ(t){const _=24389/27,o=216/24389,e=(t[0]+16)/116,r=t[1]/500+e,a=e-t[2]/200;return[(Math.pow(r,3)>o?Math.pow(r,3):(116*r-16)/_)*n[0],(t[0]>8?Math.pow((t[0]+16)/116,3):t[0]/_)*n[1],(Math.pow(a,3)>o?Math.pow(a,3):(116*a-16)/_)*n[2]]}
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js
|
|
||||||
*/function OKLCH_to_OKLab(t){const _=t[2]*Math.PI/180;return[t[0],t[1]*Math.cos(_),t[1]*Math.sin(_)]}
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js
|
|
||||||
*/function OKLab_to_OKLCH(t){const _=180*Math.atan2(t[2],t[1])/Math.PI;return[t[0],Math.sqrt(t[1]**2+t[2]**2),_>=0?_:_+360]}const o=[1.2268798758459243,-.5578149944602171,.2813910456659647,-.0405757452148008,1.112286803280317,-.0717110580655164,-.0763729366746601,-.4214933324022432,1.5869240198367816],e=[1,.3963377773761749,.2158037573099136,1,-.1055613458156586,-.0638541728258133,1,-.0894841775298119,-1.2914855480194092];
|
|
||||||
/**
|
|
||||||
* Given OKLab, convert to XYZ relative to D65
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js
|
|
||||||
*/
|
|
||||||
function OKLab_to_XYZ(t){const _=multiplyMatrices(e,t);return multiplyMatrices(o,[_[0]**3,_[1]**3,_[2]**3])}
|
|
||||||
/**
|
|
||||||
* Assuming XYZ is relative to D50, convert to CIE Lab
|
|
||||||
* from CIE standard, which now defines these as a rational fraction
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function XYZ_to_Lab(t){const _=compute_f(t[0]/n[0]),o=compute_f(t[1]/n[1]);return[116*o-16,500*(_-o),200*(o-compute_f(t[2]/n[2]))]}const r=216/24389,a=24389/27;function compute_f(t){return t>r?Math.cbrt(t):(a*t+16)/116}const i=[.819022437996703,.3619062600528904,-.1288737815209879,.0329836539323885,.9292868615863434,.0361446663506424,.0481771893596242,.2642395317527308,.6335478284694309],l=[.210454268309314,.7936177747023054,-.0040720430116193,1.9779985324311684,-2.42859224204858,.450593709617411,.0259040424655478,.7827717124575296,-.8086757549230774];
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*
|
|
||||||
* XYZ <-> LMS matrices recalculated for consistent reference white
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/issues/6642#issuecomment-943521484
|
|
||||||
*/
|
|
||||||
function XYZ_to_OKLab(t){const _=multiplyMatrices(i,t);return multiplyMatrices(l,[Math.cbrt(_[0]),Math.cbrt(_[1]),Math.cbrt(_[2])])}const s=[30757411/17917100,-6372589/17917100,-4539589/17917100,-.666684351832489,1.616481236634939,467509/29648200,792561/44930125,-1921689/44930125,.942103121235474];
|
|
||||||
/**
|
|
||||||
* Convert XYZ to linear-light rec2020
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/const c=[446124/178915,-333277/357830,-72051/178915,-14852/17905,63121/35810,423/17905,11844/330415,-50337/660830,316169/330415];
|
|
||||||
/**
|
|
||||||
* Convert XYZ to linear-light P3
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function XYZ_to_lin_P3(t){return multiplyMatrices(c,t)}const u=[1.3457868816471583,-.25557208737979464,-.05110186497554526,-.5446307051249019,1.5082477428451468,.02052744743642139,0,0,1.2119675456389452];
|
|
||||||
/**
|
|
||||||
* Convert D50 XYZ to linear-light prophoto-rgb
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
||||||
*/const h=[1829569/896150,-506331/896150,-308931/896150,-851781/878810,1648619/878810,36519/878810,16779/1248040,-147721/1248040,1266979/1248040];
|
|
||||||
/**
|
|
||||||
* Convert XYZ to linear-light a98-rgb
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/const m=[12831/3959,-329/214,-1974/3959,-851781/878810,1648619/878810,36519/878810,705/12673,-2585/12673,705/667];
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function XYZ_to_lin_sRGB(t){return multiplyMatrices(m,t)}
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light rec2020 RGB in the range 0.0-1.0
|
|
||||||
* to gamma corrected form ITU-R BT.2020-2 p.4
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/const p=1.09929682680944,D=.018053968510807;function gam_2020_channel(t){const _=t<0?-1:1,n=Math.abs(t);return n>D?_*(p*Math.pow(n,.45)-(p-1)):4.5*t}
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light sRGB values in the range 0.0-1.0 to gamma corrected form
|
|
||||||
* Extended transfer function:
|
|
||||||
* For negative values, linear portion extends on reflection
|
|
||||||
* of axis, then uses reflected pow below that
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://en.wikipedia.org/wiki/SRGB
|
|
||||||
*/function gam_sRGB(t){return[gam_sRGB_channel(t[0]),gam_sRGB_channel(t[1]),gam_sRGB_channel(t[2])]}function gam_sRGB_channel(t){const _=t<0?-1:1,n=Math.abs(t);return n>.0031308?_*(1.055*Math.pow(n,1/2.4)-.055):12.92*t}
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light display-p3 RGB in the range 0.0-1.0
|
|
||||||
* to gamma corrected form
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function gam_P3(t){return gam_sRGB(t)}
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light prophoto-rgb in the range 0.0-1.0
|
|
||||||
* to gamma corrected form.
|
|
||||||
* Transfer curve is gamma 1.8 with a small linear portion.
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/const X=1/512;function gam_ProPhoto_channel(t){const _=t<0?-1:1,n=Math.abs(t);return n>=X?_*Math.pow(n,1/1.8):16*t}
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light a98-rgb in the range 0.0-1.0
|
|
||||||
* to gamma corrected form. Negative values are also now accepted
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function gam_a98rgb_channel(t){const _=t<0?-1:1,n=Math.abs(t);return _*Math.pow(n,256/563)}
|
|
||||||
/**
|
|
||||||
* Convert an array of rec2020 RGB values in the range 0.0 - 1.0
|
|
||||||
* to linear light (un-companded) form.
|
|
||||||
* ITU-R BT.2020-2 p.4
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/const Y=1.09929682680944,Z=.018053968510807;function lin_2020_channel(t){const _=t<0?-1:1,n=Math.abs(t);return n<4.5*Z?t/4.5:_*Math.pow((n+Y-1)/Y,1/.45)}const b=[63426534/99577255,20160776/139408157,47086771/278816314,26158966/99577255,.677998071518871,8267143/139408157,0,19567812/697040785,1.0609850577107909];
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light rec2020 values to CIE XYZ
|
|
||||||
* using D65 (no chromatic adaptation)
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Convert an array of of sRGB values where in-gamut values are in the range
|
|
||||||
* [0 - 1] to linear light (un-companded) form.
|
|
||||||
* Extended transfer function:
|
|
||||||
* For negative values, linear portion is extended on reflection of axis,
|
|
||||||
* then reflected power function is used.
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://en.wikipedia.org/wiki/SRGB
|
|
||||||
*/
|
|
||||||
function lin_sRGB(t){return[lin_sRGB_channel(t[0]),lin_sRGB_channel(t[1]),lin_sRGB_channel(t[2])]}function lin_sRGB_channel(t){const _=t<0?-1:1,n=Math.abs(t);return n<=.04045?t/12.92:_*Math.pow((n+.055)/1.055,2.4)}
|
|
||||||
/**
|
|
||||||
* Convert an array of display-p3 RGB values in the range 0.0 - 1.0
|
|
||||||
* to linear light (un-companded) form.
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function lin_P3(t){return lin_sRGB(t)}const g=[608311/1250200,189793/714400,198249/1000160,35783/156275,247089/357200,198249/2500400,0,32229/714400,5220557/5000800];
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light display-p3 values to CIE XYZ
|
|
||||||
* using D65 (no chromatic adaptation)
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
||||||
*/function lin_P3_to_XYZ(t){return multiplyMatrices(g,t)}
|
|
||||||
/**
|
|
||||||
* Convert an array of prophoto-rgb values where in-gamut Colors are in the
|
|
||||||
* range [0.0 - 1.0] to linear light (un-companded) form. Transfer curve is
|
|
||||||
* gamma 1.8 with a small linear portion. Extended transfer function
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/const f=16/512;function lin_ProPhoto_channel(t){const _=t<0?-1:1,n=Math.abs(t);return n<=f?t/16:_*Math.pow(n,1.8)}const L=[.7977666449006423,.13518129740053308,.0313477341283922,.2880748288194013,.711835234241873,8993693872564e-17,0,0,.8251046025104602];
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light prophoto-rgb values to CIE D50 XYZ.
|
|
||||||
* Matrix cannot be expressed in rational form, but is calculated to 64 bit accuracy.
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see see https://github.com/w3c/csswg-drafts/issues/7675
|
|
||||||
*/function lin_a98rgb_channel(t){const _=t<0?-1:1,n=Math.abs(t);return _*Math.pow(n,563/256)}const M=[573536/994567,263643/1420810,187206/994567,591459/1989134,6239551/9945670,374412/4972835,53769/1989134,351524/4972835,4929758/4972835];
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light a98-rgb values to CIE XYZ
|
|
||||||
* http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
||||||
* has greater numerical precision than section 4.3.5.3 of
|
|
||||||
* https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf
|
|
||||||
* but the values below were calculated from first principles
|
|
||||||
* from the chromaticity coordinates of R G B W
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
||||||
* @see https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/matrixmaker.html
|
|
||||||
*/const d=[506752/1228815,87881/245763,12673/70218,87098/409605,175762/245763,12673/175545,7918/409605,87881/737289,1001167/1053270];
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light sRGB values to CIE XYZ
|
|
||||||
* using sRGB's own white, D65 (no chromatic adaptation)
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function lin_sRGB_to_XYZ(t){return multiplyMatrices(d,t)}
|
|
||||||
/**
|
|
||||||
* Convert an array of gamma-corrected sRGB values in the 0.0 to 1.0 range to HSL.
|
|
||||||
*
|
|
||||||
* @param {Color} RGB [r, g, b]
|
|
||||||
* - Red component 0..1
|
|
||||||
* - Green component 0..1
|
|
||||||
* - Blue component 0..1
|
|
||||||
* @return {number[]} Array of HSL values: Hue as degrees 0..360, Saturation and Lightness as percentages 0..100
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/utilities.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/better-rgbToHsl.js
|
|
||||||
*/function sRGB_to_HSL(t){const _=t[0],n=t[1],o=t[2],e=Math.max(_,n,o),r=Math.min(_,n,o),a=(r+e)/2,i=e-r;let l=Number.NaN,s=0;if(0!==Math.round(1e5*i)){const t=Math.round(1e5*a);switch(s=0===t||1e5===t?0:(e-a)/Math.min(a,1-a),e){case _:l=(n-o)/i+(n<o?6:0);break;case n:l=(o-_)/i+2;break;case o:l=(_-n)/i+4}l*=60}return s<0&&(l+=180,s=Math.abs(s)),l>=360&&(l-=360),[l,100*s,100*a]}function sRGB_to_Hue(t){const _=t[0],n=t[1],o=t[2],e=Math.max(_,n,o),r=Math.min(_,n,o);let a=Number.NaN;const i=e-r;if(0!==i){switch(e){case _:a=(n-o)/i+(n<o?6:0);break;case n:a=(o-_)/i+2;break;case o:a=(_-n)/i+4}a*=60}return a>=360&&(a-=360),a}function inGamut(t){return t[0]>=-1e-4&&t[0]<=1.0001&&t[1]>=-1e-4&&t[1]<=1.0001&&t[2]>=-1e-4&&t[2]<=1.0001}function clip(t){return[t[0]<0?0:t[0]>1?1:t[0],t[1]<0?0:t[1]>1?1:t[1],t[2]<0?0:t[2]>1?1:t[2]]}
|
|
||||||
/**
|
|
||||||
* @description Calculate deltaE OK which is the simple root sum of squares
|
|
||||||
* @param {number[]} reference - Array of OKLab values: L as 0..1, a and b as -1..1
|
|
||||||
* @param {number[]} sample - Array of OKLab values: L as 0..1, a and b as -1..1
|
|
||||||
* @return {number} How different a color sample is from reference
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/deltaEOK.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/deltaEOK.js
|
|
||||||
*/function deltaEOK(t,_){const[n,o,e]=t,[r,a,i]=_,l=n-r,s=o-a,c=e-i;return Math.sqrt(l**2+s**2+c**2)}const B=.02,G=1e-4;function rayTraceBox(t,_){let n=1/0,o=-1/0;const e=[0,0,0];for(let r=0;r<3;r++){const a=t[r],i=_[r]-a;e[r]=i;const l=0,s=1;if(i){const t=1/i,_=(l-a)*t,e=(s-a)*t;o=Math.max(Math.min(_,e),o),n=Math.min(Math.max(_,e),n)}else if(a<l||a>s)return!1}return!(o>n||n<0)&&(o<0&&(o=n),!!isFinite(o)&&[t[0]+e[0]*o,t[1]+e[1]*o,t[2]+e[2]*o])}function luminance(t){const[_,n,o]=t.map(t=>t<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4));return.2126*_+.7152*n+.0722*o}exports.HSL_to_XYZ_D50=function HSL_to_XYZ_D50(t){let _=t;return _=HSL_to_sRGB(_),_=lin_sRGB(_),_=lin_sRGB_to_XYZ(_),_=D65_to_D50(_),_},exports.HWB_to_XYZ_D50=function HWB_to_XYZ_D50(t){let _=t;return _=HWB_to_sRGB(_),_=lin_sRGB(_),_=lin_sRGB_to_XYZ(_),_=D65_to_D50(_),_},exports.LCH_to_XYZ_D50=function LCH_to_XYZ_D50(t){let _=t;return _=LCH_to_Lab(_),_=Lab_to_XYZ(_),_},exports.Lab_to_XYZ_D50=function Lab_to_XYZ_D50(t){let _=t;return _=Lab_to_XYZ(_),_},exports.OKLCH_to_OKLab=OKLCH_to_OKLab,exports.OKLCH_to_XYZ_D50=function OKLCH_to_XYZ_D50(t){let _=t;return _=OKLCH_to_OKLab(_),_=OKLab_to_XYZ(_),_=D65_to_D50(_),_},exports.OKLab_to_OKLCH=OKLab_to_OKLCH,exports.OKLab_to_XYZ=OKLab_to_XYZ,exports.OKLab_to_XYZ_D50=function OKLab_to_XYZ_D50(t){let _=t;return _=OKLab_to_XYZ(_),_=D65_to_D50(_),_},exports.P3_to_XYZ_D50=function P3_to_XYZ_D50(t){let _=t;return _=lin_P3(_),_=lin_P3_to_XYZ(_),_=D65_to_D50(_),_},exports.ProPhoto_RGB_to_XYZ_D50=function ProPhoto_RGB_to_XYZ_D50(t){let _=t;var n;return _=[lin_ProPhoto_channel((n=_)[0]),lin_ProPhoto_channel(n[1]),lin_ProPhoto_channel(n[2])],_=multiplyMatrices(L,_),_},exports.XYZ_D50_to_HSL=function XYZ_D50_to_HSL(t){let _=t;return _=D50_to_D65(_),_=XYZ_to_lin_sRGB(_),_=gam_sRGB(_),_=sRGB_to_HSL(_),_},exports.XYZ_D50_to_HWB=function XYZ_D50_to_HWB(t){let _=t;_=D50_to_D65(_),_=XYZ_to_lin_sRGB(_);const n=gam_sRGB(_),o=Math.min(n[0],n[1],n[2]),e=1-Math.max(n[0],n[1],n[2]);return[sRGB_to_Hue(n),100*o,100*e]},exports.XYZ_D50_to_LCH=function XYZ_D50_to_LCH(t){let _=t;return _=XYZ_to_Lab(_),_=Lab_to_LCH(_),_},exports.XYZ_D50_to_Lab=function XYZ_D50_to_Lab(t){let _=t;return _=XYZ_to_Lab(_),_},exports.XYZ_D50_to_OKLCH=function XYZ_D50_to_OKLCH(t){let _=t;return _=D50_to_D65(_),_=XYZ_to_OKLab(_),_=OKLab_to_OKLCH(_),_},exports.XYZ_D50_to_OKLab=function XYZ_D50_to_OKLab(t){let _=t;return _=D50_to_D65(_),_=XYZ_to_OKLab(_),_},exports.XYZ_D50_to_P3=function XYZ_D50_to_P3(t){let _=t;return _=D50_to_D65(_),_=XYZ_to_lin_P3(_),_=gam_P3(_),_},exports.XYZ_D50_to_ProPhoto=function XYZ_D50_to_ProPhoto(t){let _=t;var n;return _=multiplyMatrices(u,_),_=[gam_ProPhoto_channel((n=_)[0]),gam_ProPhoto_channel(n[1]),gam_ProPhoto_channel(n[2])],_},exports.XYZ_D50_to_XYZ_D50=function XYZ_D50_to_XYZ_D50(t){return t},exports.XYZ_D50_to_XYZ_D65=function XYZ_D50_to_XYZ_D65(t){let _=t;return _=D50_to_D65(_),_},exports.XYZ_D50_to_a98_RGB=function XYZ_D50_to_a98_RGB(t){let _=t;var n;return _=D50_to_D65(_),_=multiplyMatrices(h,_),_=[gam_a98rgb_channel((n=_)[0]),gam_a98rgb_channel(n[1]),gam_a98rgb_channel(n[2])],_},exports.XYZ_D50_to_lin_P3=function XYZ_D50_to_lin_P3(t){let _=t;return _=D50_to_D65(_),_=XYZ_to_lin_P3(_),_},exports.XYZ_D50_to_lin_sRGB=function XYZ_D50_to_lin_sRGB(t){let _=t;return _=D50_to_D65(_),_=XYZ_to_lin_sRGB(_),_},exports.XYZ_D50_to_rec_2020=function XYZ_D50_to_rec_2020(t){let _=t;var n;return _=D50_to_D65(_),_=multiplyMatrices(s,_),_=[gam_2020_channel((n=_)[0]),gam_2020_channel(n[1]),gam_2020_channel(n[2])],_},exports.XYZ_D50_to_sRGB=function XYZ_D50_to_sRGB(t){let _=t;return _=D50_to_D65(_),_=XYZ_to_lin_sRGB(_),_=gam_sRGB(_),_},exports.XYZ_D65_to_XYZ_D50=function XYZ_D65_to_XYZ_D50(t){let _=t;return _=D65_to_D50(_),_},exports.XYZ_to_OKLab=XYZ_to_OKLab,exports.XYZ_to_lin_P3=XYZ_to_lin_P3,exports.XYZ_to_lin_sRGB=XYZ_to_lin_sRGB,exports.a98_RGB_to_XYZ_D50=function a98_RGB_to_XYZ_D50(t){let _=t;
|
|
||||||
/**
|
|
||||||
* Convert an array of a98-rgb values in the range 0.0 - 1.0
|
|
||||||
* to linear light (un-companded) form. Negative values are also now accepted
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/
|
|
||||||
var n;return _=[lin_a98rgb_channel((n=_)[0]),lin_a98rgb_channel(n[1]),lin_a98rgb_channel(n[2])],_=multiplyMatrices(M,_),_=D65_to_D50(_),_},exports.clip=clip,exports.contrast_ratio_wcag_2_1=function contrast_ratio_wcag_2_1(t,_){const n=luminance(t),o=luminance(_);return(Math.max(n,o)+.05)/(Math.min(n,o)+.05)},exports.gam_P3=gam_P3,exports.gam_sRGB=gam_sRGB,exports.inGamut=inGamut,exports.lin_P3=lin_P3,exports.lin_P3_to_XYZ=lin_P3_to_XYZ,exports.lin_P3_to_XYZ_D50=function lin_P3_to_XYZ_D50(t){let _=t;return _=lin_P3_to_XYZ(_),_=D65_to_D50(_),_},exports.lin_sRGB=lin_sRGB,exports.lin_sRGB_to_XYZ=lin_sRGB_to_XYZ,exports.lin_sRGB_to_XYZ_D50=function lin_sRGB_to_XYZ_D50(t){let _=t;return _=lin_sRGB_to_XYZ(_),_=D65_to_D50(_),_},exports.mapGamut=function mapGamut(t,_,n){const o=t;let e=clip(_(o)),r=deltaEOK(OKLCH_to_OKLab(n(e)),OKLCH_to_OKLab(o));if(r<B)return e;let a=0,i=o[1],l=!0;for(;i-a>G;){const t=(a+i)/2;if(o[1]=t,l&&inGamut(_(o)))a=t;else if(e=clip(_(o)),r=deltaEOK(OKLCH_to_OKLab(n(e)),OKLCH_to_OKLab(o)),r<B){if(B-r<G)return e;l=!1,a=t}else i=t}return clip(_([...o]))}
|
|
||||||
/**
|
|
||||||
* @license MIT https://github.com/facelessuser/coloraide/blob/main/LICENSE.md
|
|
||||||
*/,exports.mapGamutRayTrace=function mapGamutRayTrace(t,_,n){const o=t[0],e=t[2];let r=_(t);const a=_([o,0,e]);for(let t=0;t<4;t++){if(t>0){const t=n(r);t[0]=o,t[2]=e,r=_(t)}const i=rayTraceBox(a,r);if(!i)break;r=i}return clip(r)},exports.namedColors={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},exports.rec_2020_to_XYZ_D50=function rec_2020_to_XYZ_D50(t){let _=t;var n;return _=[lin_2020_channel((n=_)[0]),lin_2020_channel(n[1]),lin_2020_channel(n[2])],_=multiplyMatrices(b,_),_=D65_to_D50(_),_},exports.sRGB_to_XYZ_D50=function sRGB_to_XYZ_D50(t){let _=t;return _=lin_sRGB(_),_=lin_sRGB_to_XYZ(_),_=D65_to_D50(_),_};
|
|
||||||
-429
@@ -1,429 +0,0 @@
|
|||||||
/**
|
|
||||||
* @param {Color} color [r, g, b]
|
|
||||||
* - Red as number 0..1;
|
|
||||||
* - Green as number 0..1;
|
|
||||||
* - Blue as number 0..1;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function a98_RGB_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
export declare function clip(color: Color): Color;
|
|
||||||
|
|
||||||
export declare type Color = [number, number, number];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WCAG 2.1 contrast ratio
|
|
||||||
*/
|
|
||||||
export declare function contrast_ratio_wcag_2_1(color1: Color, color2: Color): number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light display-p3 RGB in the range 0.0-1.0
|
|
||||||
* to gamma corrected form
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/
|
|
||||||
export declare function gam_P3(RGB: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light sRGB values in the range 0.0-1.0 to gamma corrected form
|
|
||||||
* Extended transfer function:
|
|
||||||
* For negative values, linear portion extends on reflection
|
|
||||||
* of axis, then uses reflected pow below that
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://en.wikipedia.org/wiki/SRGB
|
|
||||||
*/
|
|
||||||
export declare function gam_sRGB(RGB: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [h, s, l]
|
|
||||||
* - Hue as degrees 0..360;
|
|
||||||
* - Saturation as number 0..100;
|
|
||||||
* - Lightness as number 0..100;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function HSL_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [h, w, b]
|
|
||||||
* - Hue as degrees 0..360;
|
|
||||||
* - Whiteness as number 0..100;
|
|
||||||
* - Blackness as number 0..100;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function HWB_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
export declare function inGamut(x: Color): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [l, a, b]
|
|
||||||
* - Lightness as number 0..100;
|
|
||||||
* - a as number -160..160;
|
|
||||||
* - b as number -160..160;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function Lab_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [l, c, h]
|
|
||||||
* - Lightness as number 0..100;
|
|
||||||
* - Chroma as number 0..230;
|
|
||||||
* - Hue as degrees 0..360;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function LCH_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert an array of display-p3 RGB values in the range 0.0 - 1.0
|
|
||||||
* to linear light (un-companded) form.
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/
|
|
||||||
export declare function lin_P3(RGB: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light display-p3 values to CIE XYZ
|
|
||||||
* using D65 (no chromatic adaptation)
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
||||||
*/
|
|
||||||
export declare function lin_P3_to_XYZ(rgb: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [r, g, b]
|
|
||||||
* - Red as number 0..1;
|
|
||||||
* - Green as number 0..1;
|
|
||||||
* - Blue as number 0..1;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function lin_P3_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert an array of of sRGB values where in-gamut values are in the range
|
|
||||||
* [0 - 1] to linear light (un-companded) form.
|
|
||||||
* Extended transfer function:
|
|
||||||
* For negative values, linear portion is extended on reflection of axis,
|
|
||||||
* then reflected power function is used.
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://en.wikipedia.org/wiki/SRGB
|
|
||||||
*/
|
|
||||||
export declare function lin_sRGB(RGB: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light sRGB values to CIE XYZ
|
|
||||||
* using sRGB's own white, D65 (no chromatic adaptation)
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/
|
|
||||||
export declare function lin_sRGB_to_XYZ(rgb: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [r, g, b]
|
|
||||||
* - Red as number 0..1;
|
|
||||||
* - Green as number 0..1;
|
|
||||||
* - Blue as number 0..1;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function lin_sRGB_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
export declare function mapGamut(startOKLCH: Color, toDestination: (x: Color) => Color, fromDestination: (x: Color) => Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license MIT https://github.com/facelessuser/coloraide/blob/main/LICENSE.md
|
|
||||||
*/
|
|
||||||
export declare function mapGamutRayTrace(startOKLCH: Color, toLinear: (x: Color) => Color, fromLinear: (x: Color) => Color): Color;
|
|
||||||
|
|
||||||
export declare const namedColors: Record<string, Color>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js
|
|
||||||
*/
|
|
||||||
export declare function OKLab_to_OKLCH(OKLab: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given OKLab, convert to XYZ relative to D65
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js
|
|
||||||
*/
|
|
||||||
export declare function OKLab_to_XYZ(OKLab: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [l, a, b]
|
|
||||||
* - Lightness as number 0..1;
|
|
||||||
* - a as number 0..0.5;
|
|
||||||
* - b as number 0..0.5;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function OKLab_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js
|
|
||||||
*/
|
|
||||||
export declare function OKLCH_to_OKLab(OKLCH: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [l, c, h]
|
|
||||||
* - Lightness as number 0..1;
|
|
||||||
* - Chroma as number 0..0.5;
|
|
||||||
* - Hue as degrees 0..360;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function OKLCH_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [r, g, b]
|
|
||||||
* - Red as number 0..1;
|
|
||||||
* - Green as number 0..1;
|
|
||||||
* - Blue as number 0..1;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function P3_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [r, g, b]
|
|
||||||
* - Red as number 0..1;
|
|
||||||
* - Green as number 0..1;
|
|
||||||
* - Blue as number 0..1;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function ProPhoto_RGB_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [r, g, b]
|
|
||||||
* - Red as number 0..1;
|
|
||||||
* - Green as number 0..1;
|
|
||||||
* - Blue as number 0..1;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function rec_2020_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [r, g, b]
|
|
||||||
* - Red as number 0..1;
|
|
||||||
* - Green as number 0..1;
|
|
||||||
* - Blue as number 0..1;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function sRGB_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} a98 sRGB [r, g, b]
|
|
||||||
* - Red as number 0..1;
|
|
||||||
* - Green as number 0..1;
|
|
||||||
* - Blue as number 0..1;
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_a98_RGB(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} HSL [r, g, b]
|
|
||||||
* - Hue as degrees 0..360;
|
|
||||||
* - Saturation as number 0..100;
|
|
||||||
* - Lightness as number 0..100;
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_HSL(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} HWB [r, g, b]
|
|
||||||
* - Hue as degrees 0..360;
|
|
||||||
* - Whiteness as number 0..100;
|
|
||||||
* - Blackness as number 0..100;
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_HWB(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} Lab [r, g, b]
|
|
||||||
* - Lightness as number 0..100;
|
|
||||||
* - a as number -160..160;
|
|
||||||
* - b as number -160..160;
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_Lab(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} LCH [r, g, b]
|
|
||||||
* - Lightness as number 0..100;
|
|
||||||
* - Chroma as number 0..230;
|
|
||||||
* - Hue as degrees 0..360;
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_LCH(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} P3 [r, g, b]
|
|
||||||
* - R as number 0..1;
|
|
||||||
* - G as number 0..1;
|
|
||||||
* - B as number 0..1;
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_lin_P3(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} linear sRGB [r, g, b]
|
|
||||||
* - Red as number 0..1;
|
|
||||||
* - Green as number 0..1;
|
|
||||||
* - Blue as number 0..1;
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_lin_sRGB(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} OKLab [r, g, b]
|
|
||||||
* - Lightness as number 0..1;
|
|
||||||
* - a as number 0..0.5;
|
|
||||||
* - b as number 0..0.5;
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_OKLab(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} OKLCH [r, g, b]
|
|
||||||
* - Lightness as number 0..1;
|
|
||||||
* - Chroma as number 0..0.5;
|
|
||||||
* - Hue as degrees 0..360;
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_OKLCH(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} P3 [r, g, b]
|
|
||||||
* - R as number 0..1;
|
|
||||||
* - G as number 0..1;
|
|
||||||
* - B as number 0..1;
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_P3(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} ProPhoto [r, g, b]
|
|
||||||
* - Red as number 0..1;
|
|
||||||
* - Green as number 0..1;
|
|
||||||
* - Blue as number 0..1;
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_ProPhoto(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} rec 2020 [r, g, b]
|
|
||||||
* - Red as number 0..1;
|
|
||||||
* - Green as number 0..1;
|
|
||||||
* - Blue as number 0..1;
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_rec_2020(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} sRGB [r, g, b]
|
|
||||||
* - Red as number 0..1;
|
|
||||||
* - Green as number 0..1;
|
|
||||||
* - Blue as number 0..1;
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_sRGB(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} D65 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D50_to_XYZ_D65(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Color} color [x, y, z]
|
|
||||||
* - X as number 0..1;
|
|
||||||
* - Y as number 0..1;
|
|
||||||
* - Z as number 0..1;
|
|
||||||
* @return {Color} D50 XYZ [x, y, z]
|
|
||||||
*/
|
|
||||||
export declare function XYZ_D65_to_XYZ_D50(x: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert XYZ to linear-light P3
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/
|
|
||||||
export declare function XYZ_to_lin_P3(XYZ: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/
|
|
||||||
export declare function XYZ_to_lin_sRGB(XYZ: Color): Color;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*
|
|
||||||
* XYZ <-> LMS matrices recalculated for consistent reference white
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/issues/6642#issuecomment-943521484
|
|
||||||
*/
|
|
||||||
export declare function XYZ_to_OKLab(XYZ: Color): Color;
|
|
||||||
|
|
||||||
export { }
|
|
||||||
-263
@@ -1,263 +0,0 @@
|
|||||||
function multiplyMatrices(t,n){return[t[0]*n[0]+t[1]*n[1]+t[2]*n[2],t[3]*n[0]+t[4]*n[1]+t[5]*n[2],t[6]*n[0]+t[7]*n[1]+t[8]*n[2]]}const t=[.955473421488075,-.02309845494876471,.06325924320057072,-.0283697093338637,1.0099953980813041,.021041441191917323,.012314014864481998,-.020507649298898964,1.330365926242124];
|
|
||||||
/**
|
|
||||||
* Bradford chromatic adaptation from D50 to D65
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function D50_to_D65(n){return multiplyMatrices(t,n)}const n=[1.0479297925449969,.022946870601609652,-.05019226628920524,.02962780877005599,.9904344267538799,-.017073799063418826,-.009243040646204504,.015055191490298152,.7518742814281371];
|
|
||||||
/**
|
|
||||||
* Bradford chromatic adaptation from D65 to D50
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
|
|
||||||
*/function D65_to_D50(t){return multiplyMatrices(n,t)}
|
|
||||||
/**
|
|
||||||
* @param {number} hue - Hue as degrees 0..360
|
|
||||||
* @param {number} sat - Saturation as percentage 0..100
|
|
||||||
* @param {number} light - Lightness as percentage 0..100
|
|
||||||
* @return {number[]} Array of sRGB components; in-gamut colors in range [0..1]
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/hslToRgb.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/hslToRgb.js
|
|
||||||
*/function HSL_to_sRGB(t){let n=t[0]%360;const _=t[1]/100,o=t[2]/100;return n<0&&(n+=360),[HSL_to_sRGB_channel(0,n,_,o),HSL_to_sRGB_channel(8,n,_,o),HSL_to_sRGB_channel(4,n,_,o)]}function HSL_to_sRGB_channel(t,n,_,o){const e=(t+n/30)%12;return o-_*Math.min(o,1-o)*Math.max(-1,Math.min(e-3,9-e,1))}
|
|
||||||
/**
|
|
||||||
* @param {number} hue - Hue as degrees 0..360
|
|
||||||
* @param {number} white - Whiteness as percentage 0..100
|
|
||||||
* @param {number} black - Blackness as percentage 0..100
|
|
||||||
* @return {number[]} Array of RGB components 0..1
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/hwbToRgb.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/hwbToRgb.js
|
|
||||||
*/function HWB_to_sRGB(t){const n=t[0],_=t[1]/100,o=t[2]/100;if(_+o>=1){const t=_/(_+o);return[t,t,t]}const e=HSL_to_sRGB([n,100,50]),a=1-_-o;return[e[0]*a+_,e[1]*a+_,e[2]*a+_]}
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function LCH_to_Lab(t){const n=t[2]*Math.PI/180;return[t[0],t[1]*Math.cos(n),t[1]*Math.sin(n)]}
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function Lab_to_LCH(t){const n=180*Math.atan2(t[2],t[1])/Math.PI;return[t[0],Math.sqrt(Math.pow(t[1],2)+Math.pow(t[2],2)),n>=0?n:n+360]}const _=[.3457/.3585,1,.2958/.3585];
|
|
||||||
/**
|
|
||||||
* Convert Lab to D50-adapted XYZ
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
||||||
*/function Lab_to_XYZ(t){const n=24389/27,o=216/24389,e=(t[0]+16)/116,a=t[1]/500+e,r=e-t[2]/200;return[(Math.pow(a,3)>o?Math.pow(a,3):(116*a-16)/n)*_[0],(t[0]>8?Math.pow((t[0]+16)/116,3):t[0]/n)*_[1],(Math.pow(r,3)>o?Math.pow(r,3):(116*r-16)/n)*_[2]]}
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js
|
|
||||||
*/function OKLCH_to_OKLab(t){const n=t[2]*Math.PI/180;return[t[0],t[1]*Math.cos(n),t[1]*Math.sin(n)]}
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js
|
|
||||||
*/function OKLab_to_OKLCH(t){const n=180*Math.atan2(t[2],t[1])/Math.PI;return[t[0],Math.sqrt(t[1]**2+t[2]**2),n>=0?n:n+360]}const o=[1.2268798758459243,-.5578149944602171,.2813910456659647,-.0405757452148008,1.112286803280317,-.0717110580655164,-.0763729366746601,-.4214933324022432,1.5869240198367816],e=[1,.3963377773761749,.2158037573099136,1,-.1055613458156586,-.0638541728258133,1,-.0894841775298119,-1.2914855480194092];
|
|
||||||
/**
|
|
||||||
* Given OKLab, convert to XYZ relative to D65
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js
|
|
||||||
*/
|
|
||||||
function OKLab_to_XYZ(t){const n=multiplyMatrices(e,t);return multiplyMatrices(o,[n[0]**3,n[1]**3,n[2]**3])}
|
|
||||||
/**
|
|
||||||
* Assuming XYZ is relative to D50, convert to CIE Lab
|
|
||||||
* from CIE standard, which now defines these as a rational fraction
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function XYZ_to_Lab(t){const n=compute_f(t[0]/_[0]),o=compute_f(t[1]/_[1]);return[116*o-16,500*(n-o),200*(o-compute_f(t[2]/_[2]))]}const a=216/24389,r=24389/27;function compute_f(t){return t>a?Math.cbrt(t):(r*t+16)/116}const l=[.819022437996703,.3619062600528904,-.1288737815209879,.0329836539323885,.9292868615863434,.0361446663506424,.0481771893596242,.2642395317527308,.6335478284694309],i=[.210454268309314,.7936177747023054,-.0040720430116193,1.9779985324311684,-2.42859224204858,.450593709617411,.0259040424655478,.7827717124575296,-.8086757549230774];
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*
|
|
||||||
* XYZ <-> LMS matrices recalculated for consistent reference white
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/issues/6642#issuecomment-943521484
|
|
||||||
*/
|
|
||||||
function XYZ_to_OKLab(t){const n=multiplyMatrices(l,t);return multiplyMatrices(i,[Math.cbrt(n[0]),Math.cbrt(n[1]),Math.cbrt(n[2])])}const c=[30757411/17917100,-6372589/17917100,-4539589/17917100,-.666684351832489,1.616481236634939,467509/29648200,792561/44930125,-1921689/44930125,.942103121235474];
|
|
||||||
/**
|
|
||||||
* Convert XYZ to linear-light rec2020
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/const u=[446124/178915,-333277/357830,-72051/178915,-14852/17905,63121/35810,423/17905,11844/330415,-50337/660830,316169/330415];
|
|
||||||
/**
|
|
||||||
* Convert XYZ to linear-light P3
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function XYZ_to_lin_P3(t){return multiplyMatrices(u,t)}const s=[1.3457868816471583,-.25557208737979464,-.05110186497554526,-.5446307051249019,1.5082477428451468,.02052744743642139,0,0,1.2119675456389452];
|
|
||||||
/**
|
|
||||||
* Convert D50 XYZ to linear-light prophoto-rgb
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
||||||
*/const h=[1829569/896150,-506331/896150,-308931/896150,-851781/878810,1648619/878810,36519/878810,16779/1248040,-147721/1248040,1266979/1248040];
|
|
||||||
/**
|
|
||||||
* Convert XYZ to linear-light a98-rgb
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/const m=[12831/3959,-329/214,-1974/3959,-851781/878810,1648619/878810,36519/878810,705/12673,-2585/12673,705/667];
|
|
||||||
/**
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function XYZ_to_lin_sRGB(t){return multiplyMatrices(m,t)}
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light rec2020 RGB in the range 0.0-1.0
|
|
||||||
* to gamma corrected form ITU-R BT.2020-2 p.4
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/const D=1.09929682680944,b=.018053968510807;function gam_2020_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _>b?n*(D*Math.pow(_,.45)-(D-1)):4.5*t}
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light sRGB values in the range 0.0-1.0 to gamma corrected form
|
|
||||||
* Extended transfer function:
|
|
||||||
* For negative values, linear portion extends on reflection
|
|
||||||
* of axis, then uses reflected pow below that
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://en.wikipedia.org/wiki/SRGB
|
|
||||||
*/function gam_sRGB(t){return[gam_sRGB_channel(t[0]),gam_sRGB_channel(t[1]),gam_sRGB_channel(t[2])]}function gam_sRGB_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _>.0031308?n*(1.055*Math.pow(_,1/2.4)-.055):12.92*t}
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light display-p3 RGB in the range 0.0-1.0
|
|
||||||
* to gamma corrected form
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function gam_P3(t){return gam_sRGB(t)}
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light prophoto-rgb in the range 0.0-1.0
|
|
||||||
* to gamma corrected form.
|
|
||||||
* Transfer curve is gamma 1.8 with a small linear portion.
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/const g=1/512;function gam_ProPhoto_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _>=g?n*Math.pow(_,1/1.8):16*t}
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light a98-rgb in the range 0.0-1.0
|
|
||||||
* to gamma corrected form. Negative values are also now accepted
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function gam_a98rgb_channel(t){const n=t<0?-1:1,_=Math.abs(t);return n*Math.pow(_,256/563)}
|
|
||||||
/**
|
|
||||||
* Convert an array of rec2020 RGB values in the range 0.0 - 1.0
|
|
||||||
* to linear light (un-companded) form.
|
|
||||||
* ITU-R BT.2020-2 p.4
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/const X=1.09929682680944,Y=.018053968510807;function lin_2020_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _<4.5*Y?t/4.5:n*Math.pow((_+X-1)/X,1/.45)}const Z=[63426534/99577255,20160776/139408157,47086771/278816314,26158966/99577255,.677998071518871,8267143/139408157,0,19567812/697040785,1.0609850577107909];
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light rec2020 values to CIE XYZ
|
|
||||||
* using D65 (no chromatic adaptation)
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Convert an array of of sRGB values where in-gamut values are in the range
|
|
||||||
* [0 - 1] to linear light (un-companded) form.
|
|
||||||
* Extended transfer function:
|
|
||||||
* For negative values, linear portion is extended on reflection of axis,
|
|
||||||
* then reflected power function is used.
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://en.wikipedia.org/wiki/SRGB
|
|
||||||
*/
|
|
||||||
function lin_sRGB(t){return[lin_sRGB_channel(t[0]),lin_sRGB_channel(t[1]),lin_sRGB_channel(t[2])]}function lin_sRGB_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _<=.04045?t/12.92:n*Math.pow((_+.055)/1.055,2.4)}
|
|
||||||
/**
|
|
||||||
* Convert an array of display-p3 RGB values in the range 0.0 - 1.0
|
|
||||||
* to linear light (un-companded) form.
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function lin_P3(t){return lin_sRGB(t)}const f=[608311/1250200,189793/714400,198249/1000160,35783/156275,247089/357200,198249/2500400,0,32229/714400,5220557/5000800];
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light display-p3 values to CIE XYZ
|
|
||||||
* using D65 (no chromatic adaptation)
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
||||||
*/function lin_P3_to_XYZ(t){return multiplyMatrices(f,t)}
|
|
||||||
/**
|
|
||||||
* Convert an array of prophoto-rgb values where in-gamut Colors are in the
|
|
||||||
* range [0.0 - 1.0] to linear light (un-companded) form. Transfer curve is
|
|
||||||
* gamma 1.8 with a small linear portion. Extended transfer function
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/const M=16/512;function lin_ProPhoto_channel(t){const n=t<0?-1:1,_=Math.abs(t);return _<=M?t/16:n*Math.pow(_,1.8)}const p=[.7977666449006423,.13518129740053308,.0313477341283922,.2880748288194013,.711835234241873,8993693872564e-17,0,0,.8251046025104602];
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light prophoto-rgb values to CIE D50 XYZ.
|
|
||||||
* Matrix cannot be expressed in rational form, but is calculated to 64 bit accuracy.
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see see https://github.com/w3c/csswg-drafts/issues/7675
|
|
||||||
*/function lin_a98rgb_channel(t){const n=t<0?-1:1,_=Math.abs(t);return n*Math.pow(_,563/256)}const d=[573536/994567,263643/1420810,187206/994567,591459/1989134,6239551/9945670,374412/4972835,53769/1989134,351524/4972835,4929758/4972835];
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light a98-rgb values to CIE XYZ
|
|
||||||
* http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
||||||
* has greater numerical precision than section 4.3.5.3 of
|
|
||||||
* https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf
|
|
||||||
* but the values below were calculated from first principles
|
|
||||||
* from the chromaticity coordinates of R G B W
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
|
|
||||||
* @see https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/matrixmaker.html
|
|
||||||
*/const L=[506752/1228815,87881/245763,12673/70218,87098/409605,175762/245763,12673/175545,7918/409605,87881/737289,1001167/1053270];
|
|
||||||
/**
|
|
||||||
* Convert an array of linear-light sRGB values to CIE XYZ
|
|
||||||
* using sRGB's own white, D65 (no chromatic adaptation)
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/function lin_sRGB_to_XYZ(t){return multiplyMatrices(L,t)}
|
|
||||||
/**
|
|
||||||
* Convert an array of gamma-corrected sRGB values in the 0.0 to 1.0 range to HSL.
|
|
||||||
*
|
|
||||||
* @param {Color} RGB [r, g, b]
|
|
||||||
* - Red component 0..1
|
|
||||||
* - Green component 0..1
|
|
||||||
* - Blue component 0..1
|
|
||||||
* @return {number[]} Array of HSL values: Hue as degrees 0..360, Saturation and Lightness as percentages 0..100
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/utilities.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/better-rgbToHsl.js
|
|
||||||
*/function sRGB_to_HSL(t){const n=t[0],_=t[1],o=t[2],e=Math.max(n,_,o),a=Math.min(n,_,o),r=(a+e)/2,l=e-a;let i=Number.NaN,c=0;if(0!==Math.round(1e5*l)){const t=Math.round(1e5*r);switch(c=0===t||1e5===t?0:(e-r)/Math.min(r,1-r),e){case n:i=(_-o)/l+(_<o?6:0);break;case _:i=(o-n)/l+2;break;case o:i=(n-_)/l+4}i*=60}return c<0&&(i+=180,c=Math.abs(c)),i>=360&&(i-=360),[i,100*c,100*r]}function sRGB_to_Hue(t){const n=t[0],_=t[1],o=t[2],e=Math.max(n,_,o),a=Math.min(n,_,o);let r=Number.NaN;const l=e-a;if(0!==l){switch(e){case n:r=(_-o)/l+(_<o?6:0);break;case _:r=(o-n)/l+2;break;case o:r=(n-_)/l+4}r*=60}return r>=360&&(r-=360),r}function sRGB_to_XYZ_D50(t){let n=t;return n=lin_sRGB(n),n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_sRGB(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n),n=gam_sRGB(n),n}function HSL_to_XYZ_D50(t){let n=t;return n=HSL_to_sRGB(n),n=lin_sRGB(n),n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_HSL(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n),n=gam_sRGB(n),n=sRGB_to_HSL(n),n}function HWB_to_XYZ_D50(t){let n=t;return n=HWB_to_sRGB(n),n=lin_sRGB(n),n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_HWB(t){let n=t;n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n);const _=gam_sRGB(n),o=Math.min(_[0],_[1],_[2]),e=1-Math.max(_[0],_[1],_[2]);return[sRGB_to_Hue(_),100*o,100*e]}function Lab_to_XYZ_D50(t){let n=t;return n=Lab_to_XYZ(n),n}function XYZ_D50_to_Lab(t){let n=t;return n=XYZ_to_Lab(n),n}function LCH_to_XYZ_D50(t){let n=t;return n=LCH_to_Lab(n),n=Lab_to_XYZ(n),n}function XYZ_D50_to_LCH(t){let n=t;return n=XYZ_to_Lab(n),n=Lab_to_LCH(n),n}function OKLab_to_XYZ_D50(t){let n=t;return n=OKLab_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_OKLab(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_OKLab(n),n}function OKLCH_to_XYZ_D50(t){let n=t;return n=OKLCH_to_OKLab(n),n=OKLab_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_OKLCH(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_OKLab(n),n=OKLab_to_OKLCH(n),n}function lin_sRGB_to_XYZ_D50(t){let n=t;return n=lin_sRGB_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_lin_sRGB(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_sRGB(n),n}function a98_RGB_to_XYZ_D50(t){let n=t;
|
|
||||||
/**
|
|
||||||
* Convert an array of a98-rgb values in the range 0.0 - 1.0
|
|
||||||
* to linear light (un-companded) form. Negative values are also now accepted
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/conversions.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
*/
|
|
||||||
var _;return n=[lin_a98rgb_channel((_=n)[0]),lin_a98rgb_channel(_[1]),lin_a98rgb_channel(_[2])],n=multiplyMatrices(d,n),n=D65_to_D50(n),n}function XYZ_D50_to_a98_RGB(t){let n=t;var _;return n=D50_to_D65(n),n=multiplyMatrices(h,n),n=[gam_a98rgb_channel((_=n)[0]),gam_a98rgb_channel(_[1]),gam_a98rgb_channel(_[2])],n}function P3_to_XYZ_D50(t){let n=t;return n=lin_P3(n),n=lin_P3_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_P3(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_P3(n),n=gam_P3(n),n}function lin_P3_to_XYZ_D50(t){let n=t;return n=lin_P3_to_XYZ(n),n=D65_to_D50(n),n}function XYZ_D50_to_lin_P3(t){let n=t;return n=D50_to_D65(n),n=XYZ_to_lin_P3(n),n}function rec_2020_to_XYZ_D50(t){let n=t;var _;return n=[lin_2020_channel((_=n)[0]),lin_2020_channel(_[1]),lin_2020_channel(_[2])],n=multiplyMatrices(Z,n),n=D65_to_D50(n),n}function XYZ_D50_to_rec_2020(t){let n=t;var _;return n=D50_to_D65(n),n=multiplyMatrices(c,n),n=[gam_2020_channel((_=n)[0]),gam_2020_channel(_[1]),gam_2020_channel(_[2])],n}function ProPhoto_RGB_to_XYZ_D50(t){let n=t;var _;return n=[lin_ProPhoto_channel((_=n)[0]),lin_ProPhoto_channel(_[1]),lin_ProPhoto_channel(_[2])],n=multiplyMatrices(p,n),n}function XYZ_D50_to_ProPhoto(t){let n=t;var _;return n=multiplyMatrices(s,n),n=[gam_ProPhoto_channel((_=n)[0]),gam_ProPhoto_channel(_[1]),gam_ProPhoto_channel(_[2])],n}function XYZ_D65_to_XYZ_D50(t){let n=t;return n=D65_to_D50(n),n}function XYZ_D50_to_XYZ_D65(t){let n=t;return n=D50_to_D65(n),n}function XYZ_D50_to_XYZ_D50(t){return t}function inGamut(t){return t[0]>=-1e-4&&t[0]<=1.0001&&t[1]>=-1e-4&&t[1]<=1.0001&&t[2]>=-1e-4&&t[2]<=1.0001}function clip(t){return[t[0]<0?0:t[0]>1?1:t[0],t[1]<0?0:t[1]>1?1:t[1],t[2]<0?0:t[2]>1?1:t[2]]}
|
|
||||||
/**
|
|
||||||
* @description Calculate deltaE OK which is the simple root sum of squares
|
|
||||||
* @param {number[]} reference - Array of OKLab values: L as 0..1, a and b as -1..1
|
|
||||||
* @param {number[]} sample - Array of OKLab values: L as 0..1, a and b as -1..1
|
|
||||||
* @return {number} How different a color sample is from reference
|
|
||||||
*
|
|
||||||
* @license W3C https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
|
|
||||||
* @copyright This software or document includes material copied from or derived from https://github.com/w3c/csswg-drafts/blob/main/css-color-4/deltaEOK.js. Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang).
|
|
||||||
* @see https://github.com/w3c/csswg-drafts/blob/main/css-color-4/deltaEOK.js
|
|
||||||
*/function deltaEOK(t,n){const[_,o,e]=t,[a,r,l]=n,i=_-a,c=o-r,u=e-l;return Math.sqrt(i**2+c**2+u**2)}const B=.02,G=1e-4;function mapGamut(t,n,_){const o=t;let e=clip(n(o)),a=deltaEOK(OKLCH_to_OKLab(_(e)),OKLCH_to_OKLab(o));if(a<B)return e;let r=0,l=o[1],i=!0;for(;l-r>G;){const t=(r+l)/2;if(o[1]=t,i&&inGamut(n(o)))r=t;else if(e=clip(n(o)),a=deltaEOK(OKLCH_to_OKLab(_(e)),OKLCH_to_OKLab(o)),a<B){if(B-a<G)return e;i=!1,r=t}else l=t}return clip(n([...o]))}
|
|
||||||
/**
|
|
||||||
* @license MIT https://github.com/facelessuser/coloraide/blob/main/LICENSE.md
|
|
||||||
*/function mapGamutRayTrace(t,n,_){const o=t[0],e=t[2];let a=n(t);const r=n([o,0,e]);for(let t=0;t<4;t++){if(t>0){const t=_(a);t[0]=o,t[2]=e,a=n(t)}const l=rayTraceBox(r,a);if(!l)break;a=l}return clip(a)}function rayTraceBox(t,n){let _=1/0,o=-1/0;const e=[0,0,0];for(let a=0;a<3;a++){const r=t[a],l=n[a]-r;e[a]=l;const i=0,c=1;if(l){const t=1/l,n=(i-r)*t,e=(c-r)*t;o=Math.max(Math.min(n,e),o),_=Math.min(Math.max(n,e),_)}else if(r<i||r>c)return!1}return!(o>_||_<0)&&(o<0&&(o=_),!!isFinite(o)&&[t[0]+e[0]*o,t[1]+e[1]*o,t[2]+e[2]*o])}const R={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]};function luminance(t){const[n,_,o]=t.map(t=>t<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4));return.2126*n+.7152*_+.0722*o}function contrast_ratio_wcag_2_1(t,n){const _=luminance(t),o=luminance(n);return(Math.max(_,o)+.05)/(Math.min(_,o)+.05)}export{HSL_to_XYZ_D50,HWB_to_XYZ_D50,LCH_to_XYZ_D50,Lab_to_XYZ_D50,OKLCH_to_OKLab,OKLCH_to_XYZ_D50,OKLab_to_OKLCH,OKLab_to_XYZ,OKLab_to_XYZ_D50,P3_to_XYZ_D50,ProPhoto_RGB_to_XYZ_D50,XYZ_D50_to_HSL,XYZ_D50_to_HWB,XYZ_D50_to_LCH,XYZ_D50_to_Lab,XYZ_D50_to_OKLCH,XYZ_D50_to_OKLab,XYZ_D50_to_P3,XYZ_D50_to_ProPhoto,XYZ_D50_to_XYZ_D50,XYZ_D50_to_XYZ_D65,XYZ_D50_to_a98_RGB,XYZ_D50_to_lin_P3,XYZ_D50_to_lin_sRGB,XYZ_D50_to_rec_2020,XYZ_D50_to_sRGB,XYZ_D65_to_XYZ_D50,XYZ_to_OKLab,XYZ_to_lin_P3,XYZ_to_lin_sRGB,a98_RGB_to_XYZ_D50,clip,contrast_ratio_wcag_2_1,gam_P3,gam_sRGB,inGamut,lin_P3,lin_P3_to_XYZ,lin_P3_to_XYZ_D50,lin_sRGB,lin_sRGB_to_XYZ,lin_sRGB_to_XYZ_D50,mapGamut,mapGamutRayTrace,R as namedColors,rec_2020_to_XYZ_D50,sRGB_to_XYZ_D50};
|
|
||||||
-62
@@ -1,62 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@csstools/color-helpers",
|
|
||||||
"description": "Color helpers to ease transformation between formats, gamut, etc",
|
|
||||||
"version": "5.1.0",
|
|
||||||
"contributors": [
|
|
||||||
{
|
|
||||||
"name": "Antonio Laguna",
|
|
||||||
"email": "antonio@laguna.es",
|
|
||||||
"url": "https://antonio.laguna.es"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Romain Menke",
|
|
||||||
"email": "romainmenke@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT-0",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/csstools"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/csstools"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"type": "module",
|
|
||||||
"main": "dist/index.cjs",
|
|
||||||
"module": "dist/index.mjs",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"import": {
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"default": "./dist/index.mjs"
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"default": "./dist/index.cjs"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"CHANGELOG.md",
|
|
||||||
"LICENSE.md",
|
|
||||||
"README.md",
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"scripts": {},
|
|
||||||
"homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/color-helpers#readme",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/csstools/postcss-plugins.git",
|
|
||||||
"directory": "packages/color-helpers"
|
|
||||||
},
|
|
||||||
"bugs": "https://github.com/csstools/postcss-plugins/issues",
|
|
||||||
"keywords": [
|
|
||||||
"colors",
|
|
||||||
"css"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
-10
@@ -1,10 +0,0 @@
|
|||||||
# Changes to CSS Calc
|
|
||||||
|
|
||||||
### 2.1.4
|
|
||||||
|
|
||||||
_May 27, 2025_
|
|
||||||
|
|
||||||
- Updated [`@csstools/css-tokenizer`](https://github.com/csstools/postcss-plugins/tree/main/packages/css-tokenizer) to [`3.0.4`](https://github.com/csstools/postcss-plugins/tree/main/packages/css-tokenizer/CHANGELOG.md#304) (patch)
|
|
||||||
- Updated [`@csstools/css-parser-algorithms`](https://github.com/csstools/postcss-plugins/tree/main/packages/css-parser-algorithms) to [`3.0.5`](https://github.com/csstools/postcss-plugins/tree/main/packages/css-parser-algorithms/CHANGELOG.md#305) (patch)
|
|
||||||
|
|
||||||
[Full CHANGELOG](https://github.com/csstools/postcss-plugins/tree/main/packages/css-calc/CHANGELOG.md)
|
|
||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright 2022 Romain Menke, Antonio Laguna <antonio@laguna.es>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
-132
@@ -1,132 +0,0 @@
|
|||||||
# CSS Calc <img src="https://cssdb.org/images/css.svg" alt="for CSS" width="90" height="90" align="right">
|
|
||||||
|
|
||||||
[<img alt="npm version" src="https://img.shields.io/npm/v/@csstools/css-calc.svg" height="20">][npm-url]
|
|
||||||
[<img alt="Build Status" src="https://github.com/csstools/postcss-plugins/actions/workflows/test.yml/badge.svg?branch=main" height="20">][cli-url]
|
|
||||||
[<img alt="Discord" src="https://shields.io/badge/Discord-5865F2?logo=discord&logoColor=white">][discord]
|
|
||||||
|
|
||||||
Implemented from : https://drafts.csswg.org/css-values-4/ on 2023-02-17
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Add [CSS calc] to your project:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @csstools/css-calc @csstools/css-parser-algorithms @csstools/css-tokenizer --save-dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### With string values :
|
|
||||||
|
|
||||||
```mjs
|
|
||||||
import { calc } from '@csstools/css-calc';
|
|
||||||
|
|
||||||
// '20'
|
|
||||||
console.log(calc('calc(10 * 2)'));
|
|
||||||
```
|
|
||||||
|
|
||||||
### With component values :
|
|
||||||
|
|
||||||
```mjs
|
|
||||||
import { stringify, tokenizer } from '@csstools/css-tokenizer';
|
|
||||||
import { parseCommaSeparatedListOfComponentValues } from '@csstools/css-parser-algorithms';
|
|
||||||
import { calcFromComponentValues } from '@csstools/css-calc';
|
|
||||||
|
|
||||||
const t = tokenizer({
|
|
||||||
css: 'calc(10 * 2)',
|
|
||||||
});
|
|
||||||
|
|
||||||
const tokens = [];
|
|
||||||
|
|
||||||
{
|
|
||||||
while (!t.endOfFile()) {
|
|
||||||
tokens.push(t.nextToken());
|
|
||||||
}
|
|
||||||
|
|
||||||
tokens.push(t.nextToken()); // EOF-token
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = parseCommaSeparatedListOfComponentValues(tokens, {});
|
|
||||||
|
|
||||||
// filter or mutate the component values
|
|
||||||
|
|
||||||
const calcResult = calcFromComponentValues(result, { precision: 5, toCanonicalUnits: true });
|
|
||||||
|
|
||||||
// filter or mutate the component values even further
|
|
||||||
|
|
||||||
const calcResultStr = calcResult.map((componentValues) => {
|
|
||||||
return componentValues.map((x) => stringify(...x.tokens())).join('');
|
|
||||||
}).join(',');
|
|
||||||
|
|
||||||
// '20'
|
|
||||||
console.log(calcResultStr);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Options
|
|
||||||
|
|
||||||
#### `precision` :
|
|
||||||
|
|
||||||
The default precision is fairly high.
|
|
||||||
It aims to be high enough to make rounding unnoticeable in the browser.
|
|
||||||
|
|
||||||
You can set it to a lower number to suit your needs.
|
|
||||||
|
|
||||||
```mjs
|
|
||||||
import { calc } from '@csstools/css-calc';
|
|
||||||
|
|
||||||
// '0.3'
|
|
||||||
console.log(calc('calc(1 / 3)', { precision: 1 }));
|
|
||||||
// '0.33'
|
|
||||||
console.log(calc('calc(1 / 3)', { precision: 2 }));
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `globals` :
|
|
||||||
|
|
||||||
Pass global values as a map of key value pairs.
|
|
||||||
|
|
||||||
> Example : Relative color syntax (`lch(from pink calc(l / 2) c h)`) exposes color channel information as ident tokens.
|
|
||||||
> By passing globals for `l`, `c` and `h` it is possible to solve nested `calc()`'s.
|
|
||||||
|
|
||||||
```mjs
|
|
||||||
import { calc } from '@csstools/css-calc';
|
|
||||||
|
|
||||||
const globals = new Map([
|
|
||||||
['a', '10px'],
|
|
||||||
['b', '2rem'],
|
|
||||||
]);
|
|
||||||
|
|
||||||
// '20px'
|
|
||||||
console.log(calc('calc(a * 2)', { globals: globals }));
|
|
||||||
// '6rem'
|
|
||||||
console.log(calc('calc(b * 3)', { globals: globals }));
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `toCanonicalUnits` :
|
|
||||||
|
|
||||||
By default this package will try to preserve units.
|
|
||||||
The heuristic to do this is very simplistic.
|
|
||||||
We take the first unit we encounter and try to convert other dimensions to that unit.
|
|
||||||
|
|
||||||
This better matches what users expect from a CSS dev tool.
|
|
||||||
|
|
||||||
If you want to have outputs that are closes to CSS serialized values you can pass `toCanonicalUnits: true`.
|
|
||||||
|
|
||||||
```mjs
|
|
||||||
import { calc } from '@csstools/css-calc';
|
|
||||||
|
|
||||||
// '20hz'
|
|
||||||
console.log(calc('calc(0.01khz + 10hz)', { toCanonicalUnits: true }));
|
|
||||||
|
|
||||||
// '20hz'
|
|
||||||
console.log(calc('calc(10hz + 0.01khz)', { toCanonicalUnits: true }));
|
|
||||||
|
|
||||||
// '0.02khz' !!!
|
|
||||||
console.log(calc('calc(0.01khz + 10hz)', { toCanonicalUnits: false }));
|
|
||||||
|
|
||||||
// '20hz'
|
|
||||||
console.log(calc('calc(10hz + 0.01khz)', { toCanonicalUnits: false }));
|
|
||||||
```
|
|
||||||
|
|
||||||
[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
|
|
||||||
[discord]: https://discord.gg/bUadyRwkJS
|
|
||||||
[npm-url]: https://www.npmjs.com/package/@csstools/css-calc
|
|
||||||
|
|
||||||
[CSS calc]: https://github.com/csstools/postcss-plugins/tree/main/packages/css-calc
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-71
@@ -1,71 +0,0 @@
|
|||||||
import type { ComponentValue } from '@csstools/css-parser-algorithms';
|
|
||||||
import type { TokenDimension } from '@csstools/css-tokenizer';
|
|
||||||
import type { TokenNumber } from '@csstools/css-tokenizer';
|
|
||||||
import type { TokenPercentage } from '@csstools/css-tokenizer';
|
|
||||||
|
|
||||||
export declare function calc(css: string, options?: conversionOptions): string;
|
|
||||||
|
|
||||||
export declare function calcFromComponentValues(componentValuesList: Array<Array<ComponentValue>>, options?: conversionOptions): Array<Array<ComponentValue>>;
|
|
||||||
|
|
||||||
export declare type conversionOptions = {
|
|
||||||
/**
|
|
||||||
* Pass global values as a map of key value pairs.
|
|
||||||
*/
|
|
||||||
globals?: GlobalsWithStrings;
|
|
||||||
/**
|
|
||||||
* The default precision is fairly high.
|
|
||||||
* It aims to be high enough to make rounding unnoticeable in the browser.
|
|
||||||
* You can set it to a lower number to suite your needs.
|
|
||||||
*/
|
|
||||||
precision?: number;
|
|
||||||
/**
|
|
||||||
* By default this package will try to preserve units.
|
|
||||||
* The heuristic to do this is very simplistic.
|
|
||||||
* We take the first unit we encounter and try to convert other dimensions to that unit.
|
|
||||||
*
|
|
||||||
* This better matches what users expect from a CSS dev tool.
|
|
||||||
*
|
|
||||||
* If you want to have outputs that are closes to CSS serialized values you can set `true`.
|
|
||||||
*/
|
|
||||||
toCanonicalUnits?: boolean;
|
|
||||||
/**
|
|
||||||
* Convert NaN, Infinity, ... into standard representable values.
|
|
||||||
*/
|
|
||||||
censorIntoStandardRepresentableValues?: boolean;
|
|
||||||
/**
|
|
||||||
* Some percentages resolve against other values and might be negative or positive depending on context.
|
|
||||||
* Raw percentages are more likely to be safe to simplify outside of a browser context
|
|
||||||
*
|
|
||||||
* @see https://drafts.csswg.org/css-values-4/#calc-simplification
|
|
||||||
*/
|
|
||||||
rawPercentages?: boolean;
|
|
||||||
/**
|
|
||||||
* The values used to generate random value cache keys.
|
|
||||||
*/
|
|
||||||
randomCaching?: {
|
|
||||||
/**
|
|
||||||
* The name of the property the random function is used in.
|
|
||||||
*/
|
|
||||||
propertyName: string;
|
|
||||||
/**
|
|
||||||
* N is the index of the random function among other random functions in the same property value.
|
|
||||||
*/
|
|
||||||
propertyN: number;
|
|
||||||
/**
|
|
||||||
* An element ID identifying the element the style is being applied to.
|
|
||||||
* When omitted any `random()` call will not be computed.
|
|
||||||
*/
|
|
||||||
elementID: string;
|
|
||||||
/**
|
|
||||||
* A document ID identifying the Document the styles are from.
|
|
||||||
* When omitted any `random()` call will not be computed.
|
|
||||||
*/
|
|
||||||
documentID: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export declare type GlobalsWithStrings = Map<string, TokenDimension | TokenNumber | TokenPercentage | string>;
|
|
||||||
|
|
||||||
export declare const mathFunctionNames: Set<string>;
|
|
||||||
|
|
||||||
export { }
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-66
@@ -1,66 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@csstools/css-calc",
|
|
||||||
"description": "Solve CSS math expressions",
|
|
||||||
"version": "2.1.4",
|
|
||||||
"contributors": [
|
|
||||||
{
|
|
||||||
"name": "Antonio Laguna",
|
|
||||||
"email": "antonio@laguna.es",
|
|
||||||
"url": "https://antonio.laguna.es"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Romain Menke",
|
|
||||||
"email": "romainmenke@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/csstools"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/csstools"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"type": "module",
|
|
||||||
"main": "dist/index.cjs",
|
|
||||||
"module": "dist/index.mjs",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"import": {
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"default": "./dist/index.mjs"
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"default": "./dist/index.cjs"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"CHANGELOG.md",
|
|
||||||
"LICENSE.md",
|
|
||||||
"README.md",
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"peerDependencies": {
|
|
||||||
"@csstools/css-parser-algorithms": "^3.0.5",
|
|
||||||
"@csstools/css-tokenizer": "^3.0.4"
|
|
||||||
},
|
|
||||||
"scripts": {},
|
|
||||||
"homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/css-calc#readme",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/csstools/postcss-plugins.git",
|
|
||||||
"directory": "packages/css-calc"
|
|
||||||
},
|
|
||||||
"bugs": "https://github.com/csstools/postcss-plugins/issues",
|
|
||||||
"keywords": [
|
|
||||||
"calc",
|
|
||||||
"css"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
# Changes to CSS Color Parser
|
|
||||||
|
|
||||||
### 3.1.0
|
|
||||||
|
|
||||||
_August 22, 2025_
|
|
||||||
|
|
||||||
- Add support for `display-p3-linear` in `color(display-p3-linear 0.3081 0.014 0.0567)`
|
|
||||||
- Add support for `display-p3-linear` in `color-mix(in display-p3-linear, red, blue)`
|
|
||||||
- Add support for omitting the color space in `color-mix(red, blue)`
|
|
||||||
- Add support for `alpha(from red / 0.5)`
|
|
||||||
- Updated [`@csstools/color-helpers`](https://github.com/csstools/postcss-plugins/tree/main/packages/color-helpers) to [`5.1.0`](https://github.com/csstools/postcss-plugins/tree/main/packages/color-helpers/CHANGELOG.md#510) (minor)
|
|
||||||
|
|
||||||
[Full CHANGELOG](https://github.com/csstools/postcss-plugins/tree/main/packages/css-color-parser/CHANGELOG.md)
|
|
||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright 2022 Romain Menke, Antonio Laguna <antonio@laguna.es>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
-37
@@ -1,37 +0,0 @@
|
|||||||
# CSS Color Parser <img src="https://cssdb.org/images/css.svg" alt="for CSS" width="90" height="90" align="right">
|
|
||||||
|
|
||||||
[<img alt="npm version" src="https://img.shields.io/npm/v/@csstools/css-color-parser.svg" height="20">][npm-url]
|
|
||||||
[<img alt="Build Status" src="https://github.com/csstools/postcss-plugins/actions/workflows/test.yml/badge.svg?branch=main" height="20">][cli-url]
|
|
||||||
[<img alt="Discord" src="https://shields.io/badge/Discord-5865F2?logo=discord&logoColor=white">][discord]
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Add [CSS Color Parser] to your project:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @csstools/css-color-parser @csstools/css-parser-algorithms @csstools/css-tokenizer --save-dev
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { color } from '@csstools/css-color-parser';
|
|
||||||
import { isFunctionNode, parseComponentValue } from '@csstools/css-parser-algorithms';
|
|
||||||
import { serializeRGB } from '@csstools/css-color-parser';
|
|
||||||
import { tokenize } from '@csstools/css-tokenizer';
|
|
||||||
|
|
||||||
// color() expects a parsed component value.
|
|
||||||
const hwbComponentValue = parseComponentValue(tokenize({ css: 'hwb(10deg 10% 20%)' }));
|
|
||||||
const colorData = color(hwbComponentValue);
|
|
||||||
if (colorData) {
|
|
||||||
console.log(colorData);
|
|
||||||
|
|
||||||
// serializeRGB() returns a component value.
|
|
||||||
const rgbComponentValue = serializeRGB(colorData);
|
|
||||||
console.log(rgbComponentValue.toString());
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
|
|
||||||
[discord]: https://discord.gg/bUadyRwkJS
|
|
||||||
[npm-url]: https://www.npmjs.com/package/@csstools/css-color-parser
|
|
||||||
|
|
||||||
[CSS Color Parser]: https://github.com/csstools/postcss-plugins/tree/main/packages/css-color-parser
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-168
@@ -1,168 +0,0 @@
|
|||||||
import type { Color } from '@csstools/color-helpers';
|
|
||||||
import type { ComponentValue } from '@csstools/css-parser-algorithms';
|
|
||||||
import { FunctionNode } from '@csstools/css-parser-algorithms';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a color function to a `ColorData` object.
|
|
||||||
*
|
|
||||||
* @param {ComponentValue} colorNode - The color function to be converted.
|
|
||||||
* @returns {ColorData|false} The color function as a `ColorData` object or `false` if it could not be converted.
|
|
||||||
*/
|
|
||||||
export declare function color(colorNode: ComponentValue): ColorData | false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A color data object.
|
|
||||||
* It contains as much information as possible about the color and the original parsed syntax.
|
|
||||||
*/
|
|
||||||
export declare interface ColorData {
|
|
||||||
/**
|
|
||||||
* The color notation of the color data.
|
|
||||||
*
|
|
||||||
* We use "color notation" and not "color space" because these represent the original notation and not the actual color space.
|
|
||||||
* The actual color space is however always implied by the color notation.
|
|
||||||
*/
|
|
||||||
colorNotation: ColorNotation;
|
|
||||||
/**
|
|
||||||
* The color channels.
|
|
||||||
* This is always an array of three numbers
|
|
||||||
* but the channels can only be interpreted by looking at the color notation.
|
|
||||||
*/
|
|
||||||
channels: Color;
|
|
||||||
/**
|
|
||||||
* The alpha channel.
|
|
||||||
* This is either a number between `0` and `1` or a `ComponentValue` object.
|
|
||||||
*
|
|
||||||
* Since most computations are not dependent on the alpha channel,
|
|
||||||
* we allow things like `var(--some-alpha)` as an alpha channel value for most inputs.
|
|
||||||
*/
|
|
||||||
alpha: number | ComponentValue;
|
|
||||||
/**
|
|
||||||
* Information about the original syntax.
|
|
||||||
*/
|
|
||||||
syntaxFlags: Set<SyntaxFlag>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a color data object fits the `display-p3` gamut.
|
|
||||||
*
|
|
||||||
* @param {ColorData} x - The color data to be checked.
|
|
||||||
* @returns {boolean} Whether the color data fits the `display-p3` gamut.
|
|
||||||
*/
|
|
||||||
export declare function colorDataFitsDisplayP3_Gamut(x: ColorData): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a color data object fits the `sRGB` gamut.
|
|
||||||
*
|
|
||||||
* @param {ColorData} x - The color data to be checked.
|
|
||||||
* @returns {boolean} Whether the color data fits the `sRGB` gamut.
|
|
||||||
*/
|
|
||||||
export declare function colorDataFitsRGB_Gamut(x: ColorData): boolean;
|
|
||||||
|
|
||||||
export declare enum ColorNotation {
|
|
||||||
/** Adobe 1999, expressed through `color(a98-rgb 0 0 0)` */
|
|
||||||
A98_RGB = "a98-rgb",
|
|
||||||
/** Display P3, expressed through `color(display-p3 0 0 0)` */
|
|
||||||
Display_P3 = "display-p3",
|
|
||||||
/** Display P3, expressed through `color(display-p3-linear 0 0 0)` */
|
|
||||||
Linear_Display_P3 = "display-p3-linear",
|
|
||||||
/** Hex, expressed through `#000` */
|
|
||||||
HEX = "hex",
|
|
||||||
/** HSL, expressed through `hsl(0 0% 0%)` */
|
|
||||||
HSL = "hsl",
|
|
||||||
/** HWB, expressed through `hwb(0 0% 0%)` */
|
|
||||||
HWB = "hwb",
|
|
||||||
/** LCH, expressed through `lch(0 0% 0deg)` */
|
|
||||||
LCH = "lch",
|
|
||||||
/** Lab, expressed through `lab(0 0 0)` */
|
|
||||||
Lab = "lab",
|
|
||||||
/** Linear sRGB, expressed through `color(linear-srgb 0 0 0)` */
|
|
||||||
Linear_sRGB = "srgb-linear",
|
|
||||||
/** Oklch, expressed through `oklch(0 0% 0deg)` */
|
|
||||||
OKLCH = "oklch",
|
|
||||||
/** Oklab, expressed through `oklab(0 0 0)` */
|
|
||||||
OKLab = "oklab",
|
|
||||||
/** ProPhoto RGB, expressed through `color(prophoto-rgb 0 0 0)` */
|
|
||||||
ProPhoto_RGB = "prophoto-rgb",
|
|
||||||
/** RGB, expressed through `rgb(0 0 0)` */
|
|
||||||
RGB = "rgb",
|
|
||||||
/** sRGB, expressed through `color(srgb 0 0 0)` */
|
|
||||||
sRGB = "srgb",
|
|
||||||
/** Rec. 2020, expressed through `color(rec2020 0 0 0)` */
|
|
||||||
Rec2020 = "rec2020",
|
|
||||||
/** XYZ, expressed through `color(xyz-d50 0 0 0)` */
|
|
||||||
XYZ_D50 = "xyz-d50",
|
|
||||||
/** XYZ, expressed through `color(xyz-d65 0 0 0)` */
|
|
||||||
XYZ_D65 = "xyz-d65"
|
|
||||||
}
|
|
||||||
|
|
||||||
export declare function serializeHSL(color: ColorData, gamutMapping?: boolean): FunctionNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert color data to component values in the OKLCH color space.
|
|
||||||
* The return value can be converted to a string by calling `toString()` on it.
|
|
||||||
*
|
|
||||||
* @param {ColorData} color - The color data to be serialized.
|
|
||||||
* @returns {FunctionNode} The serialized color data as a FunctionNode object.
|
|
||||||
*/
|
|
||||||
export declare function serializeOKLCH(color: ColorData): FunctionNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert color data to component values in the display-p3 color space.
|
|
||||||
* The return value can be converted to a string by calling `toString()` on it.
|
|
||||||
*
|
|
||||||
* @param {ColorData} color - The color data to be serialized.
|
|
||||||
* @param {boolean} gamutMapping - Whether to perform gamut mapping, defaults to `true`.
|
|
||||||
* @returns {FunctionNode} The serialized color data as a FunctionNode object.
|
|
||||||
*/
|
|
||||||
export declare function serializeP3(color: ColorData, gamutMapping?: boolean): FunctionNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert color data to component values in the srgb color space.
|
|
||||||
* The return value can be converted to a string by calling `toString()` on it.
|
|
||||||
*
|
|
||||||
* @param {ColorData} color - The color data to be serialized.
|
|
||||||
* @param {boolean} gamutMapping - Whether to perform gamut mapping, defaults to `true`.
|
|
||||||
* @returns {FunctionNode} The serialized color data as a FunctionNode object.
|
|
||||||
*/
|
|
||||||
export declare function serializeRGB(color: ColorData, gamutMapping?: boolean): FunctionNode;
|
|
||||||
|
|
||||||
export declare enum SyntaxFlag {
|
|
||||||
/** Is a color keyword, e.g. `transparent`, `currentColor`, ... */
|
|
||||||
ColorKeyword = "color-keyword",
|
|
||||||
/** Has an explicit alpha channel */
|
|
||||||
HasAlpha = "has-alpha",
|
|
||||||
/** Has a channel with a dimension value, e.g. `50deg` */
|
|
||||||
HasDimensionValues = "has-dimension-values",
|
|
||||||
/** Has a channel with the `none` keyword */
|
|
||||||
HasNoneKeywords = "has-none-keywords",
|
|
||||||
/** Has a channel with a number value */
|
|
||||||
HasNumberValues = "has-number-values",
|
|
||||||
/** Has an alpha channel with a percentage value */
|
|
||||||
HasPercentageAlpha = "has-percentage-alpha",
|
|
||||||
/** Has a channel with a percentage value */
|
|
||||||
HasPercentageValues = "has-percentage-values",
|
|
||||||
/** Has an alpha channel with a `var()` function value */
|
|
||||||
HasVariableAlpha = "has-variable-alpha",
|
|
||||||
/** Is Hex notation */
|
|
||||||
Hex = "hex",
|
|
||||||
/** Is legacy HSL, e.g. `hsl(50deg, 0%, 0%)` */
|
|
||||||
LegacyHSL = "legacy-hsl",
|
|
||||||
/** Is legacy RGB, e.g. `rgb(0, 0, 0)` */
|
|
||||||
LegacyRGB = "legacy-rgb",
|
|
||||||
/** Is a named color, e.g. `red`, `blue` */
|
|
||||||
NamedColor = "named-color",
|
|
||||||
/** Is a relative color syntax, e.g. `rgb(from purple r g b)` */
|
|
||||||
RelativeColorSyntax = "relative-color-syntax",
|
|
||||||
/** Is a mixed color, e.g. `color-mix(in oklch, red, blue)` */
|
|
||||||
ColorMix = "color-mix",
|
|
||||||
/** Is a variadic mixed color, e.g. `color-mix(in oklch, red)` `color-mix(in oklch, red, blue, green)` */
|
|
||||||
ColorMixVariadic = "color-mix-variadic",
|
|
||||||
/** Is a contrasting color, e.g. `contrast-color()` */
|
|
||||||
ContrastColor = "contrast-color",
|
|
||||||
/** Is a relative alpha syntax `alpha(from red / 0.5)` */
|
|
||||||
RelativeAlphaSyntax = "relative-alpha-syntax",
|
|
||||||
/** Is an experimental color syntax */
|
|
||||||
Experimental = "experimental"
|
|
||||||
}
|
|
||||||
|
|
||||||
export { }
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-71
@@ -1,71 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@csstools/css-color-parser",
|
|
||||||
"description": "Parse CSS color values",
|
|
||||||
"version": "3.1.0",
|
|
||||||
"contributors": [
|
|
||||||
{
|
|
||||||
"name": "Antonio Laguna",
|
|
||||||
"email": "antonio@laguna.es",
|
|
||||||
"url": "https://antonio.laguna.es"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Romain Menke",
|
|
||||||
"email": "romainmenke@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/csstools"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/csstools"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"type": "module",
|
|
||||||
"main": "dist/index.cjs",
|
|
||||||
"module": "dist/index.mjs",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"import": {
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"default": "./dist/index.mjs"
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"default": "./dist/index.cjs"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"CHANGELOG.md",
|
|
||||||
"LICENSE.md",
|
|
||||||
"README.md",
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"dependencies": {
|
|
||||||
"@csstools/color-helpers": "^5.1.0",
|
|
||||||
"@csstools/css-calc": "^2.1.4"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@csstools/css-parser-algorithms": "^3.0.5",
|
|
||||||
"@csstools/css-tokenizer": "^3.0.4"
|
|
||||||
},
|
|
||||||
"scripts": {},
|
|
||||||
"homepage": "https://github.com/csstools/postcss-plugins/tree/main/packages/css-color-parser#readme",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/csstools/postcss-plugins.git",
|
|
||||||
"directory": "packages/css-color-parser"
|
|
||||||
},
|
|
||||||
"bugs": "https://github.com/csstools/postcss-plugins/issues",
|
|
||||||
"keywords": [
|
|
||||||
"color",
|
|
||||||
"css",
|
|
||||||
"parser"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
# Changes to CSS Parser Algorithms
|
|
||||||
|
|
||||||
### 3.0.5
|
|
||||||
|
|
||||||
_May 27, 2025_
|
|
||||||
|
|
||||||
- Updated [`@csstools/css-tokenizer`](https://github.com/csstools/postcss-plugins/tree/main/packages/css-tokenizer) to [`3.0.4`](https://github.com/csstools/postcss-plugins/tree/main/packages/css-tokenizer/CHANGELOG.md#304) (patch)
|
|
||||||
|
|
||||||
[Full CHANGELOG](https://github.com/csstools/postcss-plugins/tree/main/packages/css-parser-algorithms/CHANGELOG.md)
|
|
||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright 2022 Romain Menke, Antonio Laguna <antonio@laguna.es>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
-119
@@ -1,119 +0,0 @@
|
|||||||
# CSS Parser Algorithms <img src="https://cssdb.org/images/css.svg" alt="for CSS" width="90" height="90" align="right">
|
|
||||||
|
|
||||||
[<img alt="npm version" src="https://img.shields.io/npm/v/@csstools/css-parser-algorithms.svg" height="20">][npm-url]
|
|
||||||
[<img alt="Build Status" src="https://github.com/csstools/postcss-plugins/actions/workflows/test.yml/badge.svg?branch=main" height="20">][cli-url]
|
|
||||||
[<img alt="Discord" src="https://shields.io/badge/Discord-5865F2?logo=discord&logoColor=white">][discord]
|
|
||||||
|
|
||||||
Implemented from : https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
[Read the API docs](./docs/css-parser-algorithms.md)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Add [CSS Parser Algorithms] to your project:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @csstools/css-parser-algorithms @csstools/css-tokenizer --save-dev
|
|
||||||
```
|
|
||||||
|
|
||||||
[CSS Parser Algorithms] only accepts tokenized CSS.
|
|
||||||
It must be used together with `@csstools/css-tokenizer`.
|
|
||||||
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { tokenizer, TokenType } from '@csstools/css-tokenizer';
|
|
||||||
import { parseComponentValue } from '@csstools/css-parser-algorithms';
|
|
||||||
|
|
||||||
const myCSS = `@media only screen and (min-width: 768rem) {
|
|
||||||
.foo {
|
|
||||||
content: 'Some content!' !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const t = tokenizer({
|
|
||||||
css: myCSS,
|
|
||||||
});
|
|
||||||
|
|
||||||
const tokens = [];
|
|
||||||
|
|
||||||
{
|
|
||||||
while (!t.endOfFile()) {
|
|
||||||
tokens.push(t.nextToken());
|
|
||||||
}
|
|
||||||
|
|
||||||
tokens.push(t.nextToken()); // EOF-token
|
|
||||||
}
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
onParseError: ((err) => {
|
|
||||||
throw err;
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = parseComponentValue(tokens, options);
|
|
||||||
|
|
||||||
console.log(result);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Available functions
|
|
||||||
|
|
||||||
- [`parseComponentValue`](https://www.w3.org/TR/css-syntax-3/#parse-component-value)
|
|
||||||
- [`parseListOfComponentValues`](https://www.w3.org/TR/css-syntax-3/#parse-list-of-component-values)
|
|
||||||
- [`parseCommaSeparatedListOfComponentValues`](https://www.w3.org/TR/css-syntax-3/#parse-comma-separated-list-of-component-values)
|
|
||||||
|
|
||||||
### Utilities
|
|
||||||
|
|
||||||
#### `gatherNodeAncestry`
|
|
||||||
|
|
||||||
The AST does not expose the entire ancestry of each node.
|
|
||||||
The walker methods do provide access to the current parent, but also not the entire ancestry.
|
|
||||||
|
|
||||||
To gather the entire ancestry for a a given sub tree of the AST you can use `gatherNodeAncestry`.
|
|
||||||
The result is a `Map` with the child nodes as keys and the parents as values.
|
|
||||||
This allows you to lookup any ancestor of any node.
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { parseComponentValue } from '@csstools/css-parser-algorithms';
|
|
||||||
|
|
||||||
const result = parseComponentValue(tokens, options);
|
|
||||||
const ancestry = gatherNodeAncestry(result);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Options
|
|
||||||
|
|
||||||
```ts
|
|
||||||
{
|
|
||||||
onParseError?: (error: ParseError) => void
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `onParseError`
|
|
||||||
|
|
||||||
The parser algorithms are forgiving and won't stop when a parse error is encountered.
|
|
||||||
Parse errors also aren't tokens.
|
|
||||||
|
|
||||||
To receive parsing error information you can set a callback.
|
|
||||||
|
|
||||||
Parser errors will try to inform you about the point in the parsing logic the error happened.
|
|
||||||
This tells you the kind of error.
|
|
||||||
|
|
||||||
## Goals and non-goals
|
|
||||||
|
|
||||||
Things this package aims to be:
|
|
||||||
- specification compliant CSS parser
|
|
||||||
- a reliable low level package to be used in CSS sub-grammars
|
|
||||||
|
|
||||||
What it is not:
|
|
||||||
- opinionated
|
|
||||||
- fast
|
|
||||||
- small
|
|
||||||
- a replacement for PostCSS (PostCSS is fast and also an ecosystem)
|
|
||||||
|
|
||||||
[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
|
|
||||||
[discord]: https://discord.gg/bUadyRwkJS
|
|
||||||
[npm-url]: https://www.npmjs.com/package/@csstools/css-parser-algorithms
|
|
||||||
|
|
||||||
[CSS Parser Algorithms]: https://github.com/csstools/postcss-plugins/tree/main/packages/css-parser-algorithms
|
|
||||||
-1
File diff suppressed because one or more lines are too long
-604
@@ -1,604 +0,0 @@
|
|||||||
/**
|
|
||||||
* Parse CSS following the {@link https://drafts.csswg.org/css-syntax/#parsing | CSS Syntax Level 3 specification}.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* The tokenizing and parsing tools provided by CSS Tools are designed to be low level and generic with strong ties to their respective specifications.
|
|
||||||
*
|
|
||||||
* Any analysis or mutation of CSS source code should be done with the least powerful tool that can accomplish the task.
|
|
||||||
* For many applications it is sufficient to work with tokens.
|
|
||||||
* For others you might need to use {@link https://github.com/csstools/postcss-plugins/tree/main/packages/css-parser-algorithms | @csstools/css-parser-algorithms} or a more specific parser.
|
|
||||||
*
|
|
||||||
* The implementation of the AST nodes is kept lightweight and simple.
|
|
||||||
* Do not expect magic methods, instead assume that arrays and class instances behave like any other JavaScript.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* Parse a string of CSS into a component value:
|
|
||||||
* ```js
|
|
||||||
* import { tokenize } from '@csstools/css-tokenizer';
|
|
||||||
* import { parseComponentValue } from '@csstools/css-parser-algorithms';
|
|
||||||
*
|
|
||||||
* const myCSS = `calc(1px * 2)`;
|
|
||||||
*
|
|
||||||
* const componentValue = parseComponentValue(tokenize({
|
|
||||||
* css: myCSS,
|
|
||||||
* }));
|
|
||||||
*
|
|
||||||
* console.log(componentValue);
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* Use the right algorithm for the job.
|
|
||||||
*
|
|
||||||
* Algorithms that can parse larger structures (comma-separated lists, ...) can also parse smaller structures.
|
|
||||||
* However, the opposite is not true.
|
|
||||||
*
|
|
||||||
* If your context allows a list of component values, use {@link parseListOfComponentValues}:
|
|
||||||
* ```js
|
|
||||||
* import { tokenize } from '@csstools/css-tokenizer';
|
|
||||||
* import { parseListOfComponentValues } from '@csstools/css-parser-algorithms';
|
|
||||||
*
|
|
||||||
* parseListOfComponentValues(tokenize({ css: `10x 20px` }));
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* If your context allows a comma-separated list of component values, use {@link parseCommaSeparatedListOfComponentValues}:
|
|
||||||
* ```js
|
|
||||||
* import { tokenize } from '@csstools/css-tokenizer';
|
|
||||||
* import { parseCommaSeparatedListOfComponentValues } from '@csstools/css-parser-algorithms';
|
|
||||||
*
|
|
||||||
* parseCommaSeparatedListOfComponentValues(tokenize({ css: `20deg, 50%, 30%` }));
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* Use the stateful walkers to keep track of the context of a given component value.
|
|
||||||
*
|
|
||||||
* ```js
|
|
||||||
* import { tokenize } from '@csstools/css-tokenizer';
|
|
||||||
* import { parseComponentValue, isSimpleBlockNode } from '@csstools/css-parser-algorithms';
|
|
||||||
*
|
|
||||||
* const myCSS = `calc(1px * (5 / 2))`;
|
|
||||||
*
|
|
||||||
* const componentValue = parseComponentValue(tokenize({ css: myCSS }));
|
|
||||||
*
|
|
||||||
* let state = { inSimpleBlock: false };
|
|
||||||
* componentValue.walk((entry) => {
|
|
||||||
* if (isSimpleBlockNode(entry)) {
|
|
||||||
* entry.state.inSimpleBlock = true;
|
|
||||||
* return;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* if (entry.state.inSimpleBlock) {
|
|
||||||
* console.log(entry.node.toString()); // `5`, ...
|
|
||||||
* }
|
|
||||||
* }, state);
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @packageDocumentation
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type { CSSToken } from '@csstools/css-tokenizer';
|
|
||||||
import { ParseError } from '@csstools/css-tokenizer';
|
|
||||||
import type { TokenFunction } from '@csstools/css-tokenizer';
|
|
||||||
|
|
||||||
export declare class CommentNode {
|
|
||||||
/**
|
|
||||||
* The node type, always `ComponentValueType.Comment`
|
|
||||||
*/
|
|
||||||
type: ComponentValueType;
|
|
||||||
/**
|
|
||||||
* The comment token.
|
|
||||||
*/
|
|
||||||
value: CSSToken;
|
|
||||||
constructor(value: CSSToken);
|
|
||||||
/**
|
|
||||||
* Retrieve the tokens for the current comment.
|
|
||||||
* This is the inverse of parsing from a list of tokens.
|
|
||||||
*/
|
|
||||||
tokens(): Array<CSSToken>;
|
|
||||||
/**
|
|
||||||
* Convert the current comment to a string.
|
|
||||||
* This is not a true serialization.
|
|
||||||
* It is purely a concatenation of the string representation of the tokens.
|
|
||||||
*/
|
|
||||||
toString(): string;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* A debug helper to convert the current object to a JSON representation.
|
|
||||||
* This is useful in asserts and to store large ASTs in files.
|
|
||||||
*/
|
|
||||||
toJSON(): Record<string, unknown>;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
isCommentNode(): this is CommentNode;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
static isCommentNode(x: unknown): x is CommentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export declare type ComponentValue = FunctionNode | SimpleBlockNode | WhitespaceNode | CommentNode | TokenNode;
|
|
||||||
|
|
||||||
export declare enum ComponentValueType {
|
|
||||||
Function = "function",
|
|
||||||
SimpleBlock = "simple-block",
|
|
||||||
Whitespace = "whitespace",
|
|
||||||
Comment = "comment",
|
|
||||||
Token = "token"
|
|
||||||
}
|
|
||||||
|
|
||||||
export declare type ContainerNode = FunctionNode | SimpleBlockNode;
|
|
||||||
|
|
||||||
export declare abstract class ContainerNodeBaseClass {
|
|
||||||
/**
|
|
||||||
* The contents of the `Function` or `Simple Block`.
|
|
||||||
* This is a list of component values.
|
|
||||||
*/
|
|
||||||
value: Array<ComponentValue>;
|
|
||||||
/**
|
|
||||||
* Retrieve the index of the given item in the current node.
|
|
||||||
* For most node types this will be trivially implemented as `this.value.indexOf(item)`.
|
|
||||||
*/
|
|
||||||
indexOf(item: ComponentValue): number | string;
|
|
||||||
/**
|
|
||||||
* Retrieve the item at the given index in the current node.
|
|
||||||
* For most node types this will be trivially implemented as `this.value[index]`.
|
|
||||||
*/
|
|
||||||
at(index: number | string): ComponentValue | undefined;
|
|
||||||
/**
|
|
||||||
* Iterates over each item in the `value` array of the current node.
|
|
||||||
*
|
|
||||||
* @param cb - The callback function to execute for each item.
|
|
||||||
* The function receives an object containing the current node (`node`), its parent (`parent`),
|
|
||||||
* and an optional `state` object.
|
|
||||||
* A second parameter is the index of the current node.
|
|
||||||
* The function can return `false` to stop the iteration.
|
|
||||||
*
|
|
||||||
* @param state - An optional state object that can be used to pass additional information to the callback function.
|
|
||||||
* The state object is cloned for each iteration. This means that changes to the state object are not reflected in the next iteration.
|
|
||||||
*
|
|
||||||
* @returns `false` if the iteration was halted, `undefined` otherwise.
|
|
||||||
*/
|
|
||||||
forEach<T extends Record<string, unknown>, U extends ContainerNode>(this: U, cb: (entry: {
|
|
||||||
node: ComponentValue;
|
|
||||||
parent: ContainerNode;
|
|
||||||
state?: T;
|
|
||||||
}, index: number | string) => boolean | void, state?: T): false | undefined;
|
|
||||||
/**
|
|
||||||
* Walks the current node and all its children.
|
|
||||||
*
|
|
||||||
* @param cb - The callback function to execute for each item.
|
|
||||||
* The function receives an object containing the current node (`node`), its parent (`parent`),
|
|
||||||
* and an optional `state` object.
|
|
||||||
* A second parameter is the index of the current node.
|
|
||||||
* The function can return `false` to stop the iteration.
|
|
||||||
*
|
|
||||||
* @param state - An optional state object that can be used to pass additional information to the callback function.
|
|
||||||
* The state object is cloned for each iteration. This means that changes to the state object are not reflected in the next iteration.
|
|
||||||
* However changes are passed down to child node iterations.
|
|
||||||
*
|
|
||||||
* @returns `false` if the iteration was halted, `undefined` otherwise.
|
|
||||||
*/
|
|
||||||
walk<T extends Record<string, unknown>, U extends ContainerNode>(this: U, cb: (entry: {
|
|
||||||
node: ComponentValue;
|
|
||||||
parent: ContainerNode;
|
|
||||||
state?: T;
|
|
||||||
}, index: number | string) => boolean | void, state?: T): false | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterates over each item in a list of component values.
|
|
||||||
*
|
|
||||||
* @param cb - The callback function to execute for each item.
|
|
||||||
* The function receives an object containing the current node (`node`), its parent (`parent`),
|
|
||||||
* and an optional `state` object.
|
|
||||||
* A second parameter is the index of the current node.
|
|
||||||
* The function can return `false` to stop the iteration.
|
|
||||||
*
|
|
||||||
* @param state - An optional state object that can be used to pass additional information to the callback function.
|
|
||||||
* The state object is cloned for each iteration. This means that changes to the state object are not reflected in the next iteration.
|
|
||||||
*
|
|
||||||
* @returns `false` if the iteration was halted, `undefined` otherwise.
|
|
||||||
*/
|
|
||||||
export declare function forEach<T extends Record<string, unknown>>(componentValues: Array<ComponentValue>, cb: (entry: {
|
|
||||||
node: ComponentValue;
|
|
||||||
parent: ContainerNode | {
|
|
||||||
value: Array<ComponentValue>;
|
|
||||||
};
|
|
||||||
state?: T;
|
|
||||||
}, index: number | string) => boolean | void, state?: T): false | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function node.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```js
|
|
||||||
* const node = parseComponentValue(tokenize('calc(1 + 1)'));
|
|
||||||
*
|
|
||||||
* isFunctionNode(node); // true
|
|
||||||
* node.getName(); // 'calc'
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export declare class FunctionNode extends ContainerNodeBaseClass {
|
|
||||||
/**
|
|
||||||
* The node type, always `ComponentValueType.Function`
|
|
||||||
*/
|
|
||||||
type: ComponentValueType;
|
|
||||||
/**
|
|
||||||
* The token for the name of the function.
|
|
||||||
*/
|
|
||||||
name: TokenFunction;
|
|
||||||
/**
|
|
||||||
* The token for the closing parenthesis of the function.
|
|
||||||
* If the function is unclosed, this will be an EOF token.
|
|
||||||
*/
|
|
||||||
endToken: CSSToken;
|
|
||||||
constructor(name: TokenFunction, endToken: CSSToken, value: Array<ComponentValue>);
|
|
||||||
/**
|
|
||||||
* Retrieve the name of the current function.
|
|
||||||
* This is the parsed and unescaped name of the function.
|
|
||||||
*/
|
|
||||||
getName(): string;
|
|
||||||
/**
|
|
||||||
* Normalize the current function:
|
|
||||||
* 1. if the "endToken" is EOF, replace with a ")-token"
|
|
||||||
*/
|
|
||||||
normalize(): void;
|
|
||||||
/**
|
|
||||||
* Retrieve the tokens for the current function.
|
|
||||||
* This is the inverse of parsing from a list of tokens.
|
|
||||||
*/
|
|
||||||
tokens(): Array<CSSToken>;
|
|
||||||
/**
|
|
||||||
* Convert the current function to a string.
|
|
||||||
* This is not a true serialization.
|
|
||||||
* It is purely a concatenation of the string representation of the tokens.
|
|
||||||
*/
|
|
||||||
toString(): string;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* A debug helper to convert the current object to a JSON representation.
|
|
||||||
* This is useful in asserts and to store large ASTs in files.
|
|
||||||
*/
|
|
||||||
toJSON(): unknown;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
isFunctionNode(): this is FunctionNode;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
static isFunctionNode(x: unknown): x is FunctionNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AST nodes do not have a `parent` property or method.
|
|
||||||
* This makes it harder to traverse the AST upwards.
|
|
||||||
* This function builds a `Map<Child, Parent>` that can be used to lookup ancestors of a node.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* There is no magic behind this or the map it returns.
|
|
||||||
* Mutating the AST will not update the map.
|
|
||||||
*
|
|
||||||
* Types are erased and any content of the map has type `unknown`.
|
|
||||||
* If someone knows a clever way to type this, please let us know.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```js
|
|
||||||
* const ancestry = gatherNodeAncestry(mediaQuery);
|
|
||||||
* mediaQuery.walk((entry) => {
|
|
||||||
* const node = entry.node; // directly exposed
|
|
||||||
* const parent = entry.parent; // directly exposed
|
|
||||||
* const grandParent: unknown = ancestry.get(parent); // lookup
|
|
||||||
*
|
|
||||||
* console.log('node', node);
|
|
||||||
* console.log('parent', parent);
|
|
||||||
* console.log('grandParent', grandParent);
|
|
||||||
* });
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export declare function gatherNodeAncestry(node: {
|
|
||||||
walk(cb: (entry: {
|
|
||||||
node: unknown;
|
|
||||||
parent: unknown;
|
|
||||||
}, index: number | string) => boolean | void): false | undefined;
|
|
||||||
}): Map<unknown, unknown>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the current object is a `CommentNode`.
|
|
||||||
* This is a type guard.
|
|
||||||
*/
|
|
||||||
export declare function isCommentNode(x: unknown): x is CommentNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the current object is a `FunctionNode`.
|
|
||||||
* This is a type guard.
|
|
||||||
*/
|
|
||||||
export declare function isFunctionNode(x: unknown): x is FunctionNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the current object is a `SimpleBlockNode`.
|
|
||||||
* This is a type guard.
|
|
||||||
*/
|
|
||||||
export declare function isSimpleBlockNode(x: unknown): x is SimpleBlockNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the current object is a `TokenNode`.
|
|
||||||
* This is a type guard.
|
|
||||||
*/
|
|
||||||
export declare function isTokenNode(x: unknown): x is TokenNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the current object is a `WhitespaceNode`.
|
|
||||||
* This is a type guard.
|
|
||||||
*/
|
|
||||||
export declare function isWhitespaceNode(x: unknown): x is WhitespaceNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the current object is a `WhiteSpaceNode` or a `CommentNode`.
|
|
||||||
* This is a type guard.
|
|
||||||
*/
|
|
||||||
export declare function isWhiteSpaceOrCommentNode(x: unknown): x is WhitespaceNode | CommentNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a comma-separated list of component values.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```js
|
|
||||||
* import { tokenize } from '@csstools/css-tokenizer';
|
|
||||||
* import { parseCommaSeparatedListOfComponentValues } from '@csstools/css-parser-algorithms';
|
|
||||||
*
|
|
||||||
* parseCommaSeparatedListOfComponentValues(tokenize({ css: `20deg, 50%, 30%` }));
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export declare function parseCommaSeparatedListOfComponentValues(tokens: Array<CSSToken>, options?: {
|
|
||||||
onParseError?: (error: ParseError) => void;
|
|
||||||
}): Array<Array<ComponentValue>>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a single component value.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```js
|
|
||||||
* import { tokenize } from '@csstools/css-tokenizer';
|
|
||||||
* import { parseCommaSeparatedListOfComponentValues } from '@csstools/css-parser-algorithms';
|
|
||||||
*
|
|
||||||
* parseCommaSeparatedListOfComponentValues(tokenize({ css: `10px` }));
|
|
||||||
* parseCommaSeparatedListOfComponentValues(tokenize({ css: `calc((10px + 1x) * 4)` }));
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export declare function parseComponentValue(tokens: Array<CSSToken>, options?: {
|
|
||||||
onParseError?: (error: ParseError) => void;
|
|
||||||
}): ComponentValue | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a list of component values.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```js
|
|
||||||
* import { tokenize } from '@csstools/css-tokenizer';
|
|
||||||
* import { parseListOfComponentValues } from '@csstools/css-parser-algorithms';
|
|
||||||
*
|
|
||||||
* parseListOfComponentValues(tokenize({ css: `20deg 30%` }));
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export declare function parseListOfComponentValues(tokens: Array<CSSToken>, options?: {
|
|
||||||
onParseError?: (error: ParseError) => void;
|
|
||||||
}): Array<ComponentValue>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replace specific component values in a list of component values.
|
|
||||||
* A helper for the most common and simplistic cases when mutating an AST.
|
|
||||||
*/
|
|
||||||
export declare function replaceComponentValues(componentValuesList: Array<Array<ComponentValue>>, replaceWith: (componentValue: ComponentValue) => Array<ComponentValue> | ComponentValue | void): Array<Array<ComponentValue>>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple block node.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```js
|
|
||||||
* const node = parseComponentValue(tokenize('[foo=bar]'));
|
|
||||||
*
|
|
||||||
* isSimpleBlockNode(node); // true
|
|
||||||
* node.startToken; // [TokenType.OpenSquare, '[', 0, 0, undefined]
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export declare class SimpleBlockNode extends ContainerNodeBaseClass {
|
|
||||||
/**
|
|
||||||
* The node type, always `ComponentValueType.SimpleBlock`
|
|
||||||
*/
|
|
||||||
type: ComponentValueType;
|
|
||||||
/**
|
|
||||||
* The token for the opening token of the block.
|
|
||||||
*/
|
|
||||||
startToken: CSSToken;
|
|
||||||
/**
|
|
||||||
* The token for the closing token of the block.
|
|
||||||
* If the block is closed it will be the mirror variant of the `startToken`.
|
|
||||||
* If the block is unclosed, this will be an EOF token.
|
|
||||||
*/
|
|
||||||
endToken: CSSToken;
|
|
||||||
constructor(startToken: CSSToken, endToken: CSSToken, value: Array<ComponentValue>);
|
|
||||||
/**
|
|
||||||
* Normalize the current simple block
|
|
||||||
* 1. if the "endToken" is EOF, replace with the mirror token of the "startToken"
|
|
||||||
*/
|
|
||||||
normalize(): void;
|
|
||||||
/**
|
|
||||||
* Retrieve the tokens for the current simple block.
|
|
||||||
* This is the inverse of parsing from a list of tokens.
|
|
||||||
*/
|
|
||||||
tokens(): Array<CSSToken>;
|
|
||||||
/**
|
|
||||||
* Convert the current simple block to a string.
|
|
||||||
* This is not a true serialization.
|
|
||||||
* It is purely a concatenation of the string representation of the tokens.
|
|
||||||
*/
|
|
||||||
toString(): string;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* A debug helper to convert the current object to a JSON representation.
|
|
||||||
* This is useful in asserts and to store large ASTs in files.
|
|
||||||
*/
|
|
||||||
toJSON(): unknown;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
isSimpleBlockNode(): this is SimpleBlockNode;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
static isSimpleBlockNode(x: unknown): x is SimpleBlockNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the start and end index of a node in the CSS source string.
|
|
||||||
*/
|
|
||||||
export declare function sourceIndices(x: {
|
|
||||||
tokens(): Array<CSSToken>;
|
|
||||||
} | Array<{
|
|
||||||
tokens(): Array<CSSToken>;
|
|
||||||
}>): [number, number];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Concatenate the string representation of a collection of component values.
|
|
||||||
* This is not a proper serializer that will handle escaping and whitespace.
|
|
||||||
* It only produces valid CSS for token lists that are also valid.
|
|
||||||
*/
|
|
||||||
export declare function stringify(componentValueLists: Array<Array<ComponentValue>>): string;
|
|
||||||
|
|
||||||
export declare class TokenNode {
|
|
||||||
/**
|
|
||||||
* The node type, always `ComponentValueType.Token`
|
|
||||||
*/
|
|
||||||
type: ComponentValueType;
|
|
||||||
/**
|
|
||||||
* The token.
|
|
||||||
*/
|
|
||||||
value: CSSToken;
|
|
||||||
constructor(value: CSSToken);
|
|
||||||
/**
|
|
||||||
* This is the inverse of parsing from a list of tokens.
|
|
||||||
*/
|
|
||||||
tokens(): [CSSToken];
|
|
||||||
/**
|
|
||||||
* Convert the current token to a string.
|
|
||||||
* This is not a true serialization.
|
|
||||||
* It is purely the string representation of token.
|
|
||||||
*/
|
|
||||||
toString(): string;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* A debug helper to convert the current object to a JSON representation.
|
|
||||||
* This is useful in asserts and to store large ASTs in files.
|
|
||||||
*/
|
|
||||||
toJSON(): Record<string, unknown>;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
isTokenNode(): this is TokenNode;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
static isTokenNode(x: unknown): x is TokenNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Walks each item in a list of component values all of their children.
|
|
||||||
*
|
|
||||||
* @param cb - The callback function to execute for each item.
|
|
||||||
* The function receives an object containing the current node (`node`), its parent (`parent`),
|
|
||||||
* and an optional `state` object.
|
|
||||||
* A second parameter is the index of the current node.
|
|
||||||
* The function can return `false` to stop the iteration.
|
|
||||||
*
|
|
||||||
* @param state - An optional state object that can be used to pass additional information to the callback function.
|
|
||||||
* The state object is cloned for each iteration. This means that changes to the state object are not reflected in the next iteration.
|
|
||||||
* However changes are passed down to child node iterations.
|
|
||||||
*
|
|
||||||
* @returns `false` if the iteration was halted, `undefined` otherwise.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```js
|
|
||||||
* import { tokenize } from '@csstools/css-tokenizer';
|
|
||||||
* import { parseListOfComponentValues, isSimpleBlockNode } from '@csstools/css-parser-algorithms';
|
|
||||||
*
|
|
||||||
* const myCSS = `calc(1px * (5 / 2)) 10px`;
|
|
||||||
*
|
|
||||||
* const componentValues = parseListOfComponentValues(tokenize({ css: myCSS }));
|
|
||||||
*
|
|
||||||
* let state = { inSimpleBlock: false };
|
|
||||||
* walk(componentValues, (entry) => {
|
|
||||||
* if (isSimpleBlockNode(entry)) {
|
|
||||||
* entry.state.inSimpleBlock = true;
|
|
||||||
* return;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* if (entry.state.inSimpleBlock) {
|
|
||||||
* console.log(entry.node.toString()); // `5`, ...
|
|
||||||
* }
|
|
||||||
* }, state);
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export declare function walk<T extends Record<string, unknown>>(componentValues: Array<ComponentValue>, cb: (entry: {
|
|
||||||
node: ComponentValue;
|
|
||||||
parent: ContainerNode | {
|
|
||||||
value: Array<ComponentValue>;
|
|
||||||
};
|
|
||||||
state?: T;
|
|
||||||
}, index: number | string) => boolean | void, state?: T): false | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a function that finds the next element that should be visited when walking an AST.
|
|
||||||
* Rules :
|
|
||||||
* 1. the previous iteration is used as a reference, so any checks are relative to the start of the current iteration.
|
|
||||||
* 2. the next element always appears after the current index.
|
|
||||||
* 3. the next element always exists in the list.
|
|
||||||
* 4. replacing an element does not cause the replaced element to be visited.
|
|
||||||
* 5. removing an element does not cause elements to be skipped.
|
|
||||||
* 6. an element added later in the list will be visited.
|
|
||||||
*/
|
|
||||||
export declare function walkerIndexGenerator<T>(initialList: Array<T>): (list: Array<T>, child: T, index: number) => number;
|
|
||||||
|
|
||||||
export declare class WhitespaceNode {
|
|
||||||
/**
|
|
||||||
* The node type, always `ComponentValueType.WhiteSpace`
|
|
||||||
*/
|
|
||||||
type: ComponentValueType;
|
|
||||||
/**
|
|
||||||
* The list of consecutive whitespace tokens.
|
|
||||||
*/
|
|
||||||
value: Array<CSSToken>;
|
|
||||||
constructor(value: Array<CSSToken>);
|
|
||||||
/**
|
|
||||||
* Retrieve the tokens for the current whitespace.
|
|
||||||
* This is the inverse of parsing from a list of tokens.
|
|
||||||
*/
|
|
||||||
tokens(): Array<CSSToken>;
|
|
||||||
/**
|
|
||||||
* Convert the current whitespace to a string.
|
|
||||||
* This is not a true serialization.
|
|
||||||
* It is purely a concatenation of the string representation of the tokens.
|
|
||||||
*/
|
|
||||||
toString(): string;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* A debug helper to convert the current object to a JSON representation.
|
|
||||||
* This is useful in asserts and to store large ASTs in files.
|
|
||||||
*/
|
|
||||||
toJSON(): Record<string, unknown>;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
isWhitespaceNode(): this is WhitespaceNode;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
static isWhitespaceNode(x: unknown): x is WhitespaceNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export { }
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user