Skip to content

Commit b5ef875

Browse files
authored
Bug fix
1 parent 66d65d3 commit b5ef875

File tree

1 file changed

+50
-27
lines changed

1 file changed

+50
-27
lines changed

static/app_script.js

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const swPath = "/lab/service-worker.js";
22
let newWorker = null;
3+
let iframeBodyObserver = null;
34

45
document.addEventListener("DOMContentLoaded", () => {
56
initializeAppUI();
@@ -136,8 +137,13 @@ function listenForControllerChange() {
136137
window.location.reload();
137138
});
138139
}
140+
139141
function updateThemeColorFromIframe() {
140142
const iframe = document.getElementById("appFrame");
143+
if (!iframe) {
144+
console.error("Iframe not found.");
145+
return;
146+
}
141147

142148
try {
143149
// Access the content document of the iframe
@@ -154,76 +160,91 @@ function updateThemeColorFromIframe() {
154160
// Find or create the meta theme-color tag in the main document
155161
let themeMetaTag = document.querySelector('meta[name="theme-color"]');
156162
if (!themeMetaTag) {
157-
// Create it if it doesn't exist
158163
themeMetaTag = document.createElement("meta");
159164
themeMetaTag.name = "theme-color";
160165
document.head.appendChild(themeMetaTag);
161166
console.log("Created new meta theme-color tag.");
162167
}
163-
164-
// Set the content attribute to the iframe's body background color
165-
themeMetaTag.content = backgroundColor;
168+
themeMetaTag.content = backgroundColor.trim();
166169
console.log(`Updated theme color to: ${backgroundColor}`);
167170
} else {
168171
console.warn("Could not retrieve background-color from iframe body.");
169172
}
170173
} catch (e) {
171-
// This catch block will usually handle the Cross-Origin security error
172174
console.error(
173-
"Error accessing iframe content. Check for Cross-Origin policy restrictions (CORS).",
175+
"Error accessing iframe content. Check for Same-Origin restrictions.",
174176
e
175177
);
176178
}
177179
}
178180

179181
function monitorIframeBackgroundColor() {
180182
const iframe = document.getElementById("appFrame");
181-
182183
if (!iframe) {
183184
console.error("Iframe not found.");
184185
return;
185186
}
186187

187-
// --- 1. Initial Load and Setup ---
188-
iframe.onload = function () {
189-
// Run the update once the content is loaded
188+
// --- Prevent re-initialization if this gets called again ---
189+
if (iframe.dataset.themeSyncInit === "1") {
190+
return;
191+
}
192+
iframe.dataset.themeSyncInit = "1";
193+
194+
const onLoad = function () {
195+
// Update immediately on each navigation
190196
updateThemeColorFromIframe();
191197

192198
try {
199+
// Clean up a previous observer (from a previous document)
200+
if (iframeBodyObserver) {
201+
iframeBodyObserver.disconnect();
202+
iframeBodyObserver = null;
203+
}
204+
193205
const iframeBody = iframe.contentWindow.document.body;
194206

195-
// --- 2. Create the MutationObserver ---
196-
const observer = new MutationObserver(function (mutationsList, observer) {
197-
// Check if any change was an attribute change on the body
207+
// Watch for inline style changes on the body
208+
iframeBodyObserver = new MutationObserver((mutationsList) => {
198209
for (const mutation of mutationsList) {
199210
if (
200211
mutation.type === "attributes" &&
201212
mutation.attributeName === "style"
202213
) {
203-
// The style attribute changed, re-run the update function
204-
// Wait for the next animation frame to ensure computed styles are ready.
205214
requestAnimationFrame(updateThemeColorFromIframe);
206215
}
207216
}
208217
});
209218

210-
// --- 3. Configuration and Start Observing ---
211-
const config = {
212-
attributes: true, // Watch for attribute changes
213-
attributeFilter: ["style"], // Only care about the 'style' attribute
214-
subtree: false, // Don't watch children, just the body itself
215-
};
219+
iframeBodyObserver.observe(iframeBody, {
220+
attributes: true,
221+
attributeFilter: ["style"],
222+
subtree: false,
223+
});
216224

217-
// Start observing the iframe's body element
218-
observer.observe(iframeBody, config);
219225
console.log("MutationObserver started on iframe body.");
220226
} catch (e) {
221227
console.error(
222-
"Cannot set up MutationObserver due to Same-Origin Policy. The iframe content is likely cross-origin.",
228+
"Cannot set up MutationObserver due to Same-Origin Policy.",
223229
e
224230
);
225231
}
226232
};
233+
234+
// add this as listener to iframe
235+
iframe.addEventListener("load", onLoad);
236+
237+
// If the iframe is already loaded when this runs, run once now
238+
try {
239+
if (
240+
iframe.contentDocument &&
241+
iframe.contentDocument.readyState === "complete"
242+
) {
243+
onLoad();
244+
}
245+
} catch (e) {
246+
// Ignore if no iframe content
247+
}
227248
}
228249

229250
function initializeAppUI() {
@@ -233,7 +254,9 @@ function initializeAppUI() {
233254
const header = document.querySelector("body header");
234255
const links = document.querySelectorAll("#app-links li a");
235256

236-
// Function to collapse the hamburger menu/sidebar
257+
// Initialize theme sync once at startup
258+
monitorIframeBackgroundColor();
259+
237260
const collapseSidebar = () => {
238261
sidebar.classList.add("collapsed");
239262
sidebar.classList.remove("overlay");
@@ -243,8 +266,6 @@ function initializeAppUI() {
243266
header.style.display = "none";
244267
sidebar.style.paddingTop = "6.75em";
245268
}
246-
247-
monitorIframeBackgroundColor();
248269
};
249270

250271
iframe.addEventListener("load", collapseSidebar);
@@ -257,10 +278,12 @@ function initializeAppUI() {
257278

258279
// The link is already active and loaded
259280
if (iframe.getAttribute("src") === href) {
281+
console.log(`Already loaded ${href} in iframe`);
260282
return;
261283
}
262284

263285
iframe.setAttribute("src", href);
286+
console.log(`Loading ${href} in iframe`);
264287

265288
links.forEach((l) => l.parentElement.classList.remove("active"));
266289
link.parentElement.classList.add("active");

0 commit comments

Comments
 (0)