Skip to content

Commit

Permalink
css-color-parser : allow color channels to be normalized individually (
Browse files Browse the repository at this point in the history
  • Loading branch information
romainmenke authored Aug 29, 2023
1 parent 1b74068 commit 2247887
Show file tree
Hide file tree
Showing 26 changed files with 701 additions and 743 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import type { ColorData } from '../color-data';
import { CSSToken, TokenNumber } from '@csstools/css-tokenizer';
export declare function normalize_Color_ChannelValues(tokens: Array<CSSToken>, colorData: ColorData): Array<TokenNumber> | false;
import { CSSToken } from '@csstools/css-tokenizer';
export declare function normalize_Color_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false;
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { ColorData } from '../color-data';
import type { TokenNumber } from '@csstools/css-tokenizer';
import { CSSToken } from '@csstools/css-tokenizer';
export declare function normalize_legacy_HSL_ChannelValues(tokens: Array<CSSToken>, colorData: ColorData): Array<TokenNumber> | false;
export declare function normalize_modern_HSL_ChannelValues(tokens: Array<CSSToken>, colorData: ColorData): Array<TokenNumber> | false;
export declare function normalize_legacy_HSL_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false;
export declare function normalize_modern_HSL_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false;
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { ColorData } from '../color-data';
import type { TokenNumber } from '@csstools/css-tokenizer';
import { CSSToken } from '@csstools/css-tokenizer';
export declare function normalize_HWB_ChannelValues(tokens: Array<CSSToken>, colorData: ColorData): Array<TokenNumber> | false;
export declare function normalize_HWB_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false;
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { ColorData } from '../color-data';
import type { TokenNumber } from '@csstools/css-tokenizer';
import { CSSToken } from '@csstools/css-tokenizer';
export declare function normalize_Lab_ChannelValues(tokens: Array<CSSToken>, colorData: ColorData): Array<TokenNumber> | false;
export declare function normalize_Lab_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false;
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { ColorData } from '../color-data';
import type { TokenNumber } from '@csstools/css-tokenizer';
import { CSSToken } from '@csstools/css-tokenizer';
export declare function normalize_LCH_ChannelValues(tokens: Array<CSSToken>, colorData: ColorData): Array<TokenNumber> | false;
export declare function normalize_LCH_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false;
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { ColorData } from '../color-data';
import type { TokenNumber } from '@csstools/css-tokenizer';
import { CSSToken } from '@csstools/css-tokenizer';
export type normalizeChannelValuesFn = (tokens: Array<CSSToken>, colorData: ColorData) => Array<TokenNumber> | false;
export type normalizeChannelValuesFn = (token: CSSToken, index: number, colorData: ColorData) => CSSToken | false;
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { ColorData } from '../color-data';
import type { TokenNumber } from '@csstools/css-tokenizer';
import { CSSToken } from '@csstools/css-tokenizer';
export declare function normalize_OKLab_ChannelValues(tokens: Array<CSSToken>, colorData: ColorData): Array<TokenNumber> | false;
export declare function normalize_OKLab_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false;
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { ColorData } from '../color-data';
import type { TokenNumber } from '@csstools/css-tokenizer';
import { CSSToken } from '@csstools/css-tokenizer';
export declare function normalize_OKLCH_ChannelValues(tokens: Array<CSSToken>, colorData: ColorData): Array<TokenNumber> | false;
export declare function normalize_OKLCH_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false;
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { ColorData } from '../color-data';
import type { TokenNumber } from '@csstools/css-tokenizer';
import { CSSToken } from '@csstools/css-tokenizer';
export declare function normalize_legacy_sRGB_ChannelValues(tokens: Array<CSSToken>, colorData: ColorData): Array<TokenNumber> | false;
export declare function normalize_modern_sRGB_ChannelValues(tokens: Array<CSSToken>, colorData: ColorData): Array<TokenNumber> | false;
export declare function normalize_legacy_sRGB_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false;
export declare function normalize_modern_sRGB_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false;
2 changes: 1 addition & 1 deletion packages/css-color-parser/dist/index.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/css-color-parser/dist/index.mjs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,79 +1,68 @@
import type { ColorData } from '../color-data';
import { CSSToken, NumberType, TokenNumber, TokenType } from '@csstools/css-tokenizer';
import { CSSToken, NumberType, TokenType } from '@csstools/css-tokenizer';
import { SyntaxFlag } from '../color-data';
import { normalize } from './normalize';
import { toLowerCaseAZ } from '../util/to-lower-case-a-z';

export function normalize_Color_ChannelValues(tokens: Array<CSSToken>, colorData: ColorData): Array<TokenNumber> | false {
const result: Array<TokenNumber> = [];
export function normalize_Color_ChannelValues(token: CSSToken, index: number, colorData: ColorData): CSSToken | false {
if (token[0] === TokenType.Ident && toLowerCaseAZ(token[4].value) === 'none') {
colorData.syntaxFlags.add(SyntaxFlag.HasNoneKeywords);

for (let index = 0; index < tokens.length; index++) {
const token = tokens[index];

if (token[0] === TokenType.Ident && toLowerCaseAZ(token[4].value) === 'none') {
colorData.syntaxFlags.add(SyntaxFlag.HasNoneKeywords);
return [
TokenType.Number,
'none',
token[2],
token[3],
{
value: NaN,
type: NumberType.Number,
},
];
}

result.push([
TokenType.Number,
'none',
token[2],
token[3],
{
value: NaN,
type: NumberType.Number,
},
]);
continue;
if (token[0] === TokenType.Percentage) {
if (index !== 3) {
colorData.syntaxFlags.add(SyntaxFlag.HasPercentageValues);
}

if (token[0] === TokenType.Percentage) {
if (index !== 3) {
colorData.syntaxFlags.add(SyntaxFlag.HasPercentageValues);
}

let value = normalize(token[4].value, 100, -Infinity, Infinity);
if (index === 3) {
value = normalize(token[4].value, 100, 0, 1);
}

result.push([
TokenType.Number,
value.toString(),
token[2],
token[3],
{
value: value,
type: NumberType.Number,
},
]);
continue;
let value = normalize(token[4].value, 100, -Infinity, Infinity);
if (index === 3) {
value = normalize(token[4].value, 100, 0, 1);
}

if (token[0] === TokenType.Number) {
if (index !== 3) {
colorData.syntaxFlags.add(SyntaxFlag.HasNumberValues);
}
return [
TokenType.Number,
value.toString(),
token[2],
token[3],
{
value: value,
type: NumberType.Number,
},
];
}

let value = normalize(token[4].value, 1, -Infinity, Infinity);
if (index === 3) {
value = normalize(token[4].value, 1, 0, 1);
}
if (token[0] === TokenType.Number) {
if (index !== 3) {
colorData.syntaxFlags.add(SyntaxFlag.HasNumberValues);
}

result.push([
TokenType.Number,
value.toString(),
token[2],
token[3],
{
value: value,
type: NumberType.Number,
},
]);
continue;
let value = normalize(token[4].value, 1, -Infinity, Infinity);
if (index === 3) {
value = normalize(token[4].value, 1, 0, 1);
}

return false;
return [
TokenType.Number,
value.toString(),
token[2],
token[3],
{
value: value,
type: NumberType.Number,
},
];
}

return result;
return false;
}
52 changes: 36 additions & 16 deletions packages/css-color-parser/src/functions/color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ColorData, SyntaxFlag, colorDataTo, noneToZeroInRelativeColorDataChanne
import type { ColorParser } from '../color-parser';
import { ColorNotation } from '../color-notation';
import { ComponentValue, FunctionNode, TokenNode, isCommentNode, isFunctionNode, isTokenNode, isWhitespaceNode } from '@csstools/css-parser-algorithms';
import { CSSToken, TokenDimension, TokenNumber, TokenPercentage, TokenType } from '@csstools/css-tokenizer';
import { TokenDimension, TokenNumber, TokenPercentage, TokenType } from '@csstools/css-tokenizer';
import { normalize_Color_ChannelValues } from './color-normalize-channel-values';
import { toLowerCaseAZ } from '../util/to-lower-case-a-z';
import { calcFromComponentValues, mathFunctionNames } from '@csstools/css-calc';
Expand Down Expand Up @@ -187,38 +187,58 @@ export function color(colorFunctionNode: FunctionNode, colorParser: ColorParser)
return false;
}

const channelValues: Array<CSSToken> = [
channel1[0].value,
channel2[0].value,
channel3[0].value,
const channelValue1 = normalize_Color_ChannelValues(channel1[0].value, 0, colorData);
if (!channelValue1 || channelValue1[0] !== TokenType.Number) {
return false;
}

const channelValue2 = normalize_Color_ChannelValues(channel2[0].value, 1, colorData);
if (!channelValue2 || channelValue2[0] !== TokenType.Number) {
return false;
}

const channelValue3 = normalize_Color_ChannelValues(channel3[0].value, 2, colorData);
if (!channelValue3 || channelValue3[0] !== TokenType.Number) {
return false;
}

const channelValues: Array<TokenNumber> = [
channelValue1,
channelValue2,
channelValue3,
];

if (channelAlpha.length === 1) {
colorData.syntaxFlags.add(SyntaxFlag.HasAlpha);

if (isTokenNode(channelAlpha[0])) {
channelValues.push(channelAlpha[0].value);
const channelValueAlpha = normalize_Color_ChannelValues(channelAlpha[0].value, 3, colorData);
if (!channelValueAlpha || channelValueAlpha[0] !== TokenType.Number) {
return false;
}

channelValues.push(channelValueAlpha);
} else {
colorData.alpha = channelAlpha[0];
}
} else if (relativeColorChannels && relativeColorChannels.has('alpha')) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
channelValues.push(relativeColorChannels.get('alpha')!);
}
const channelValueAlpha = normalize_Color_ChannelValues(relativeColorChannels.get('alpha')!, 3, colorData);
if (!channelValueAlpha || channelValueAlpha[0] !== TokenType.Number) {
return false;
}

const normalizedChannelValues = normalize_Color_ChannelValues(channelValues, colorData);
if (normalizedChannelValues === false) {
return false;
channelValues.push(channelValueAlpha);
}

colorData.channels = [
normalizedChannelValues[0][4].value,
normalizedChannelValues[1][4].value,
normalizedChannelValues[2][4].value,
channelValues[0][4].value,
channelValues[1][4].value,
channelValues[2][4].value,
];

if (normalizedChannelValues.length === 4) {
colorData.alpha = normalizedChannelValues[3][4].value;
if (channelValues.length === 4) {
colorData.alpha = channelValues[3][4].value;
}

return colorData;
Expand Down
Loading

0 comments on commit 2247887

Please sign in to comment.