1
- type CSSFeature = 'relativeColorSyntax' | 'colorMix' ;
1
+ type CSSFeature = 'relativeColorSyntax' | 'colorMix' | 'modernColorSupport' ;
2
2
3
- const CSS_FEATURE_TESTS : Record < CSSFeature , string > = {
3
+ type CompositeOperation = 'or' | 'and' ;
4
+
5
+ type CompositeFeatureDefinition = {
6
+ operation : CompositeOperation ;
7
+ features : CSSFeature [ ] ;
8
+ } ;
9
+
10
+ const CSS_FEATURE_TESTS : Record < string , string > = {
4
11
relativeColorSyntax : 'hsl(from white h s l)' ,
5
12
colorMix : 'color-mix(in srgb, white, black)' ,
6
13
} as const ;
7
14
15
+ const COMPOSITE_FEATURES : Record < string , CompositeFeatureDefinition > = {
16
+ modernColorSupport : {
17
+ operation : 'or' ,
18
+ features : [ 'relativeColorSyntax' , 'colorMix' ] ,
19
+ } ,
20
+ } as const ;
21
+
8
22
const supportCache = new Map < CSSFeature , boolean > ( ) ;
9
- // Cache for composite checks
10
- let modernColorSupportCache : boolean | undefined ;
11
23
12
24
/**
13
25
* CSS feature detection
@@ -32,11 +44,14 @@ const testCSSFeature = (feature: CSSFeature, property: string = 'color'): boolea
32
44
let isSupported = false ;
33
45
34
46
try {
35
- const testValue = CSS_FEATURE_TESTS [ feature ] ;
36
-
37
- const testProperty = getPropertyForFeature ( feature , property ) ;
38
-
39
- isSupported = CSS . supports ( testProperty , testValue ) ;
47
+ // Check if this is a composite feature
48
+ if ( feature in COMPOSITE_FEATURES ) {
49
+ isSupported = evaluateCompositeFeature ( feature ) ;
50
+ } else {
51
+ const testValue = CSS_FEATURE_TESTS [ feature ] ;
52
+ const testProperty = getPropertyForFeature ( feature , property ) ;
53
+ isSupported = CSS . supports ( testProperty , testValue ) ;
54
+ }
40
55
} catch {
41
56
isSupported = false ;
42
57
}
@@ -46,6 +61,27 @@ const testCSSFeature = (feature: CSSFeature, property: string = 'color'): boolea
46
61
return isSupported ;
47
62
} ;
48
63
64
+ /**
65
+ * Evaluate a composite feature based on its definition
66
+ */
67
+ const evaluateCompositeFeature = ( feature : string ) : boolean => {
68
+ const definition = COMPOSITE_FEATURES [ feature ] ;
69
+ if ( ! definition ) {
70
+ return false ;
71
+ }
72
+
73
+ const results = definition . features . map ( f => testCSSFeature ( f ) ) ;
74
+
75
+ switch ( definition . operation ) {
76
+ case 'or' :
77
+ return results . some ( Boolean ) ;
78
+ case 'and' :
79
+ return results . every ( Boolean ) ;
80
+ default :
81
+ return false ;
82
+ }
83
+ } ;
84
+
49
85
/**
50
86
* Get the appropriate CSS property for testing a feature
51
87
*/
@@ -70,19 +106,11 @@ export const cssSupports = {
70
106
* Check if the browser supports modern color syntax (color-mix or relative color syntax)
71
107
* @returns true if the browser supports modern color syntax
72
108
*/
73
- hasModernColorSupport : ( ) => {
74
- if ( modernColorSupportCache !== undefined ) {
75
- return modernColorSupportCache ;
76
- }
77
-
78
- modernColorSupportCache = testCSSFeature ( 'relativeColorSyntax' ) || testCSSFeature ( 'colorMix' ) ;
79
- return modernColorSupportCache ;
80
- } ,
109
+ hasModernColorSupport : ( ) => testCSSFeature ( 'modernColorSupport' ) ,
81
110
} as const ;
82
111
83
112
export const clearCSSSupportsCache = ( ) : void => {
84
113
supportCache . clear ( ) ;
85
- modernColorSupportCache = undefined ;
86
114
} ;
87
115
88
116
export const getCachedSupports = ( ) : Record < string , boolean > => {
0 commit comments