Skip to content

Commit 19c9722

Browse files
author
Bart Veneman
committed
WIP: analyze color spaces
1 parent b470cad commit 19c9722

File tree

4 files changed

+250
-7
lines changed

4 files changed

+250
-7
lines changed

src/index.js

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import walk from 'css-tree/walker'
33
import { calculateForAST } from '@bramus/specificity/core'
44
import { isSupportsBrowserhack, isMediaBrowserhack } from './atrules/atrules.js'
55
import { getCombinators, getComplexity, isAccessibility, isPrefixed, hasPseudoClass } from './selectors/utils.js'
6-
import { colorFunctions, colorKeywords, namedColors, systemColors } from './values/colors.js'
6+
import { colorFunctions, colorKeywords, colorSpace, namedColors, systemColors } from './values/colors.js'
77
import { destructure, isSystemFont } from './values/destructure-font-shorthand.js'
88
import { isValueKeyword, keywords, isValueReset } from './values/values.js'
99
import { analyzeAnimation } from './values/animations.js'
@@ -197,6 +197,7 @@ export function analyze(css, options = {}) {
197197
let durations = new Collection(useLocations)
198198
let colors = new ContextCollection(useLocations)
199199
let colorFormats = new Collection(useLocations)
200+
let colorSpaces = new Collection(useLocations)
200201
let units = new ContextCollection(useLocations)
201202
let gradients = new Collection(useLocations)
202203
let valueKeywords = new Collection(useLocations)
@@ -643,6 +644,7 @@ export function analyze(css, options = {}) {
643644
}
644645
colors.push('#' + valueNode.value, property, loc)
645646
colorFormats.p(`hex` + hexLength, loc)
647+
colorSpaces.p('srgb', loc)
646648

647649
return this.skip
648650
}
@@ -664,6 +666,7 @@ export function analyze(css, options = {}) {
664666
let stringified = stringifyNode(valueNode)
665667
colors.push(stringified, property, loc)
666668
colorFormats.p(nodeName.toLowerCase(), loc)
669+
colorSpaces.p('srgb', loc)
667670
return
668671
}
669672

@@ -672,6 +675,7 @@ export function analyze(css, options = {}) {
672675
let stringified = stringifyNode(valueNode)
673676
colors.push(stringified, property, loc)
674677
colorFormats.p('named', loc)
678+
colorSpaces.p('srgb', loc)
675679
return
676680
}
677681

@@ -680,6 +684,7 @@ export function analyze(css, options = {}) {
680684
let stringified = stringifyNode(valueNode)
681685
colors.push(stringified, property, loc)
682686
colorFormats.p('system', loc)
687+
colorSpaces.p('srgb', loc)
683688
return
684689
}
685690
return this.skip
@@ -692,8 +697,41 @@ export function analyze(css, options = {}) {
692697

693698
// rgb(a), hsl(a), color(), hwb(), lch(), lab(), oklab(), oklch()
694699
if (colorFunctions.has(nodeName)) {
695-
colors.push(stringifyNode(valueNode), property, valueNode.loc)
696-
colorFormats.p(nodeName.toLowerCase(), valueNode.loc)
700+
let loc = valueNode.loc
701+
colors.push(stringifyNode(valueNode), property, loc)
702+
colorFormats.p(nodeName.toLowerCase(), loc)
703+
704+
if (new KeywordSet(['rgb', 'rgba', 'hsl', 'hsla', 'hwb']).has(nodeName)) {
705+
colorSpaces.p('srgb', loc)
706+
} else if (nodeName.toLowerCase() === 'oklch') {
707+
colorSpaces.p('oklch', loc)
708+
} else if (new KeywordSet(['lab', 'lch']).has(nodeName)) {
709+
colorSpaces.p('lab', loc)
710+
} else if (nodeName.toLowerCase() === 'oklab') {
711+
colorSpaces.p('oklab', loc)
712+
} else if (nodeName.toLowerCase() === 'color') {
713+
// Determine color space from the color value
714+
// color(space ...) -> space
715+
// color(from X Y ...) -> Y
716+
let space_or_from = valueNode.children.first
717+
if (space_or_from.type === 'Identifier') {
718+
if (space_or_from.name.toLowerCase() === 'from') {
719+
// Take the next identifier as the color space
720+
let next = space_or_from.next
721+
if (next?.type === 'Identifier') {
722+
let space = colorSpace(next.name)
723+
if (space) {
724+
colorSpaces.p(space, loc)
725+
}
726+
}
727+
} else {
728+
let space = colorSpace(space_or_from.name)
729+
if (space) {
730+
colorSpaces.p(space, loc)
731+
}
732+
}
733+
}
734+
}
697735
return
698736
}
699737

@@ -1012,6 +1050,7 @@ export function analyze(css, options = {}) {
10121050
colors.count(),
10131051
{
10141052
formats: colorFormats.c(),
1053+
spaces: colorSpaces.c(),
10151054
},
10161055
),
10171056
gradients: gradients.c(),

src/keyword-set.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,9 @@ export class KeywordSet {
1313
has(item) {
1414
return this.set.has(item.toLowerCase())
1515
}
16+
17+
/** @returns {Iterator<string>} */
18+
[Symbol.iterator]() {
19+
return this.set[Symbol.iterator]()
20+
}
1621
}

src/values/colors.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,35 @@ export const colorKeywords = new KeywordSet([
197197
'transparent',
198198
'currentcolor',
199199
])
200+
201+
const rgbSpaces = new KeywordSet([
202+
'srgb',
203+
'srgb-linear',
204+
'xyz',
205+
'xyz-d50',
206+
'xyz-d65',
207+
])
208+
209+
const colorSpaces = new KeywordSet([
210+
'display-p3',
211+
'a98-rgb',
212+
'rec2020',
213+
'prophoto-rgb',
214+
...rgbSpaces,
215+
])
216+
217+
/** @param {string} space */
218+
export function colorSpace(space) {
219+
if (rgbSpaces.has(space)) {
220+
return 'rgb'
221+
}
222+
if (cielabSpaces.has(space)) {
223+
return 'cielab'
224+
}
225+
if (xyzSpaces.has(space)) {
226+
return 'xyz'
227+
}
228+
if (colorSpaces.has(space)) {
229+
return space
230+
}
231+
}

0 commit comments

Comments
 (0)