Skip to content

Commit b4d591e

Browse files
Create themecollector.js
1 parent a42bf0a commit b4d591e

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

themecollector.js

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/**
2+
* Theme Collector 1.1.1
3+
* Released under the MIT License
4+
* Released on: January 17, 2025
5+
*/
6+
function getColorThemes() {
7+
const STORAGE_KEYS = {
8+
THEMES: "colorThemes_data",
9+
PUBLISH_DATE: "colorThemes_publishDate",
10+
};
11+
function getPublishDate() {
12+
const htmlComment = document.documentElement.previousSibling;
13+
return htmlComment?.nodeType === Node.COMMENT_NODE
14+
? new Date(
15+
htmlComment.textContent.match(/Last Published: (.+?) GMT/)[1]
16+
).getTime()
17+
: null;
18+
}
19+
20+
function loadFromStorage() {
21+
try {
22+
const storedPublishDate = localStorage.getItem(STORAGE_KEYS.PUBLISH_DATE),
23+
currentPublishDate = getPublishDate();
24+
if (
25+
!currentPublishDate ||
26+
!storedPublishDate ||
27+
storedPublishDate !== currentPublishDate.toString()
28+
)
29+
return null;
30+
return JSON.parse(localStorage.getItem(STORAGE_KEYS.THEMES));
31+
} catch (error) {
32+
console.warn("Failed to load from localStorage:", error);
33+
return null;
34+
}
35+
}
36+
37+
function saveToStorage(themes) {
38+
try {
39+
const publishDate = getPublishDate();
40+
if (publishDate) {
41+
localStorage.setItem(STORAGE_KEYS.PUBLISH_DATE, publishDate.toString());
42+
localStorage.setItem(STORAGE_KEYS.THEMES, JSON.stringify(themes));
43+
}
44+
} catch (error) {
45+
console.warn("Failed to save to localStorage:", error);
46+
}
47+
}
48+
49+
window.colorThemes = {
50+
themes: {},
51+
getTheme(themeName = "", brandName = "") {
52+
if (!themeName)
53+
return this.getTheme(Object.keys(this.themes)[0], brandName);
54+
const theme = this.themes[themeName];
55+
if (!theme) return {};
56+
if (!theme.brands || Object.keys(theme.brands).length === 0) return theme;
57+
if (!brandName) return theme.brands[Object.keys(theme.brands)[0]];
58+
return theme.brands[brandName] || {};
59+
},
60+
};
61+
62+
const cachedThemes = loadFromStorage();
63+
if (cachedThemes) {
64+
window.colorThemes.themes = cachedThemes;
65+
document.dispatchEvent(new CustomEvent("colorThemesReady"));
66+
return;
67+
}
68+
69+
const firstLink = document.querySelectorAll('link[rel="stylesheet"]')[1];
70+
if (!firstLink?.href) return null;
71+
72+
const themeVariables = new Set(),
73+
themeClasses = new Set(),
74+
brandClasses = new Set();
75+
76+
fetch(firstLink.href)
77+
.then((response) => {
78+
if (!response.ok)
79+
throw new Error(`Failed to fetch stylesheet: ${response.statusText}`);
80+
return response.text();
81+
})
82+
.then((cssText) => {
83+
(cssText.match(/--_theme[\w-]+:\s*[^;]+/g) || []).forEach((variable) =>
84+
themeVariables.add(variable.split(":")[0].trim())
85+
);
86+
(cssText.match(/\.u-(theme|brand)-[\w-]+/g) || []).forEach(
87+
(className) => {
88+
if (className.startsWith(".u-theme-")) themeClasses.add(className);
89+
if (className.startsWith(".u-brand-")) brandClasses.add(className);
90+
}
91+
);
92+
93+
const themeVariablesArray = Array.from(themeVariables);
94+
function checkClass(themeClass, brandClass = null) {
95+
let documentClasses = document.documentElement.getAttribute("class");
96+
document.documentElement.setAttribute("class", "");
97+
document.documentElement.classList.add(themeClass, brandClass);
98+
const styleObject = {};
99+
themeVariablesArray.forEach(
100+
(variable) =>
101+
(styleObject[variable] = getComputedStyle(
102+
document.documentElement
103+
).getPropertyValue(variable))
104+
);
105+
document.documentElement.setAttribute("class", documentClasses);
106+
return styleObject;
107+
}
108+
109+
themeClasses.forEach((themeClassWithDot) => {
110+
const themeName = themeClassWithDot
111+
.replace(".", "")
112+
.replace("u-theme-", "");
113+
window.colorThemes.themes[themeName] = { brands: {} };
114+
brandClasses.forEach((brandClassWithDot) => {
115+
const brandName = brandClassWithDot
116+
.replace(".", "")
117+
.replace("u-brand-", "");
118+
window.colorThemes.themes[themeName].brands[brandName] = checkClass(
119+
themeClassWithDot.replace(".", ""),
120+
brandClassWithDot.replace(".", "")
121+
);
122+
});
123+
if (!brandClasses.size)
124+
window.colorThemes.themes[themeName] = checkClass(
125+
themeClassWithDot.replace(".", "")
126+
);
127+
});
128+
129+
saveToStorage(window.colorThemes.themes);
130+
document.dispatchEvent(new CustomEvent("colorThemesReady"));
131+
})
132+
.catch((error) => console.error("Error:", error.message));
133+
}
134+
window.addEventListener("DOMContentLoaded", (event) => {
135+
getColorThemes();
136+
});

0 commit comments

Comments
 (0)