feat: persist theme across dev targets via ?theme= query param
Each target reads the theme from ?theme=dark|light on load and applies it to data-theme before first paint. A MutationObserver syncs theme changes back to the URL via replaceState, and a click handler appends ?theme= to cross-port navigation links automatically. The outer iframe shell (dev/index.html) uses postMessage to track theme changes from iframes and passes the param when switching tabs. For hiccup, the server also reads ?theme= and sets data-theme on the <html> element server-side to prevent any flash of wrong theme.
This commit is contained in:
@@ -7,6 +7,41 @@
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; }
|
||||
</style>
|
||||
<script>
|
||||
(function() {
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
var theme = params.get('theme');
|
||||
if (theme === 'dark' || theme === 'light') {
|
||||
document.documentElement.dataset.theme = theme;
|
||||
}
|
||||
new MutationObserver(function(mutations) {
|
||||
for (var i = 0; i < mutations.length; i++) {
|
||||
if (mutations[i].attributeName === 'data-theme') {
|
||||
var t = document.documentElement.dataset.theme;
|
||||
var url = new URL(window.location);
|
||||
if (t) url.searchParams.set('theme', t);
|
||||
else url.searchParams.delete('theme');
|
||||
history.replaceState(null, '', url);
|
||||
if (window.parent !== window) {
|
||||
window.parent.postMessage({ type: 'theme-change', theme: t || '' }, '*');
|
||||
}
|
||||
}
|
||||
}
|
||||
}).observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
|
||||
document.addEventListener('click', function(e) {
|
||||
var a = e.target.closest('a[href]');
|
||||
if (!a) return;
|
||||
try {
|
||||
var url = new URL(a.href);
|
||||
if (url.hostname === location.hostname && url.port !== location.port) {
|
||||
var t = document.documentElement.dataset.theme;
|
||||
if (t) url.searchParams.set('theme', t);
|
||||
a.href = url.toString();
|
||||
}
|
||||
} catch (ex) {}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
Reference in New Issue
Block a user