-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcv-preview-color.ts
More file actions
58 lines (49 loc) · 1.54 KB
/
cv-preview-color.ts
File metadata and controls
58 lines (49 loc) · 1.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const findPreviewRule = (rules: CSSRuleList, selector: string): CSSStyleRule | null => {
for (const rule of Array.from(rules)) {
if (rule instanceof CSSStyleRule && rule.selectorText === selector) {
return rule;
}
if (rule instanceof CSSGroupingRule) {
const nested = findPreviewRule(rule.cssRules, selector);
if (nested) {
return nested;
}
}
}
return null;
};
export const isValidHexColor = (value: string): boolean => {
return /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value);
};
export const createPreviewColorApplicator = (
selector: string,
fallbackColor: string
): ((requestedColor: string) => void) => {
let cachedPreviewRule: CSSStyleRule | null = null;
const getPreviewRule = (): CSSStyleRule | null => {
if (cachedPreviewRule instanceof CSSStyleRule) {
return cachedPreviewRule;
}
for (const styleSheet of Array.from(document.styleSheets)) {
try {
const foundRule = findPreviewRule(styleSheet.cssRules, selector);
if (foundRule instanceof CSSStyleRule) {
cachedPreviewRule = foundRule;
return cachedPreviewRule;
}
} catch {
// Ignore non-readable cross-origin stylesheets.
}
}
return null;
};
return (requestedColor: string): void => {
const safeColor = isValidHexColor(requestedColor) ? requestedColor : fallbackColor;
const previewRule = getPreviewRule();
if (!(previewRule instanceof CSSStyleRule)) {
console.warn('No se pudo aplicar el color del preview: regla CSS no disponible.');
return;
}
previewRule.style.setProperty('--cv-primary', safeColor);
};
};