95 lines
3.1 KiB
JavaScript
95 lines
3.1 KiB
JavaScript
document.addEventListener('DOMContentLoaded', function () {
|
|
const injectedSvgs = [];
|
|
|
|
function parseColorMap(cssText, prop) {
|
|
const map = {};
|
|
const regex = new RegExp('\\[' + prop + '="([^"]+)"\\]\\s*{\\s*' + prop + ':\\s*([^;]+);', 'g');
|
|
let m;
|
|
while ((m = regex.exec(cssText)) !== null) {
|
|
map[m[1]] = m[2].trim();
|
|
}
|
|
return map;
|
|
}
|
|
|
|
function applyThemeToSvg(entry, isDark) {
|
|
const { svgEl, fillMap, strokeMap } = entry;
|
|
|
|
Object.keys(fillMap).forEach(function (lightColor) {
|
|
svgEl.querySelectorAll('[fill="' + lightColor + '"]').forEach(function (el) {
|
|
el.setAttribute('fill', isDark ? fillMap[lightColor] : lightColor);
|
|
});
|
|
});
|
|
|
|
Object.keys(strokeMap).forEach(function (lightColor) {
|
|
svgEl.querySelectorAll('[stroke="' + lightColor + '"]').forEach(function (el) {
|
|
el.setAttribute('stroke', isDark ? strokeMap[lightColor] : lightColor);
|
|
});
|
|
});
|
|
}
|
|
|
|
function getIsDark() {
|
|
const attr = document.documentElement.getAttribute('data-theme');
|
|
if (attr) return attr === 'dark';
|
|
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
}
|
|
|
|
function applyThemeToAll() {
|
|
const isDark = getIsDark();
|
|
injectedSvgs.forEach(function (entry) {
|
|
applyThemeToSvg(entry, isDark);
|
|
});
|
|
}
|
|
|
|
const svgImages = document.querySelectorAll('.entry-content img[src$=".svg"]');
|
|
|
|
svgImages.forEach(function (img, index) {
|
|
const figureNumber = index + 1;
|
|
const originalSrc = img.src;
|
|
const originalAlt = img.alt;
|
|
const captionEl = img.nextElementSibling;
|
|
const captionText = (captionEl && captionEl.tagName === 'EM') ? captionEl.textContent : '';
|
|
|
|
fetch(img.src)
|
|
.then(function (response) { return response.text(); })
|
|
.then(function (svgText) {
|
|
const parser = new DOMParser();
|
|
const svgDoc = parser.parseFromString(svgText, 'image/svg+xml');
|
|
const svgEl = svgDoc.querySelector('svg');
|
|
|
|
if (!svgEl) return;
|
|
|
|
if (img.alt) {
|
|
svgEl.setAttribute('role', 'img');
|
|
svgEl.setAttribute('aria-label', img.alt);
|
|
}
|
|
|
|
svgEl.classList.add('injected-svg');
|
|
|
|
// Dark-Farbzuordnung aus dem internen <style>-Block auslesen, dann Block entfernen
|
|
const styleEl = svgEl.querySelector('style');
|
|
let fillMap = {};
|
|
let strokeMap = {};
|
|
if (styleEl) {
|
|
fillMap = parseColorMap(styleEl.textContent, 'fill');
|
|
strokeMap = parseColorMap(styleEl.textContent, 'stroke');
|
|
styleEl.remove();
|
|
}
|
|
|
|
img.replaceWith(svgEl);
|
|
|
|
const entry = { svgEl: svgEl, fillMap: fillMap, strokeMap: strokeMap };
|
|
injectedSvgs.push(entry);
|
|
applyThemeToSvg(entry, getIsDark());
|
|
|
|
document.dispatchEvent(new CustomEvent('svg-injected', {
|
|
detail: { svgEl: svgEl, originalSrc: originalSrc, originalAlt: originalAlt, figureNumber: figureNumber, captionText: captionText }
|
|
}));
|
|
})
|
|
.catch(function (err) {
|
|
console.error('SVG injection failed for', img.src, err);
|
|
});
|
|
});
|
|
|
|
document.addEventListener('themechange', applyThemeToAll);
|
|
});
|