1
1
const swPath = "/lab/service-worker.js" ;
2
2
let newWorker = null ;
3
+ let iframeBodyObserver = null ;
3
4
4
5
document . addEventListener ( "DOMContentLoaded" , ( ) => {
5
6
initializeAppUI ( ) ;
@@ -136,8 +137,13 @@ function listenForControllerChange() {
136
137
window . location . reload ( ) ;
137
138
} ) ;
138
139
}
140
+
139
141
function updateThemeColorFromIframe ( ) {
140
142
const iframe = document . getElementById ( "appFrame" ) ;
143
+ if ( ! iframe ) {
144
+ console . error ( "Iframe not found." ) ;
145
+ return ;
146
+ }
141
147
142
148
try {
143
149
// Access the content document of the iframe
@@ -154,76 +160,91 @@ function updateThemeColorFromIframe() {
154
160
// Find or create the meta theme-color tag in the main document
155
161
let themeMetaTag = document . querySelector ( 'meta[name="theme-color"]' ) ;
156
162
if ( ! themeMetaTag ) {
157
- // Create it if it doesn't exist
158
163
themeMetaTag = document . createElement ( "meta" ) ;
159
164
themeMetaTag . name = "theme-color" ;
160
165
document . head . appendChild ( themeMetaTag ) ;
161
166
console . log ( "Created new meta theme-color tag." ) ;
162
167
}
163
-
164
- // Set the content attribute to the iframe's body background color
165
- themeMetaTag . content = backgroundColor ;
168
+ themeMetaTag . content = backgroundColor . trim ( ) ;
166
169
console . log ( `Updated theme color to: ${ backgroundColor } ` ) ;
167
170
} else {
168
171
console . warn ( "Could not retrieve background-color from iframe body." ) ;
169
172
}
170
173
} catch ( e ) {
171
- // This catch block will usually handle the Cross-Origin security error
172
174
console . error (
173
- "Error accessing iframe content. Check for Cross -Origin policy restrictions (CORS) ." ,
175
+ "Error accessing iframe content. Check for Same -Origin restrictions." ,
174
176
e
175
177
) ;
176
178
}
177
179
}
178
180
179
181
function monitorIframeBackgroundColor ( ) {
180
182
const iframe = document . getElementById ( "appFrame" ) ;
181
-
182
183
if ( ! iframe ) {
183
184
console . error ( "Iframe not found." ) ;
184
185
return ;
185
186
}
186
187
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
190
196
updateThemeColorFromIframe ( ) ;
191
197
192
198
try {
199
+ // Clean up a previous observer (from a previous document)
200
+ if ( iframeBodyObserver ) {
201
+ iframeBodyObserver . disconnect ( ) ;
202
+ iframeBodyObserver = null ;
203
+ }
204
+
193
205
const iframeBody = iframe . contentWindow . document . body ;
194
206
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 ) => {
198
209
for ( const mutation of mutationsList ) {
199
210
if (
200
211
mutation . type === "attributes" &&
201
212
mutation . attributeName === "style"
202
213
) {
203
- // The style attribute changed, re-run the update function
204
- // Wait for the next animation frame to ensure computed styles are ready.
205
214
requestAnimationFrame ( updateThemeColorFromIframe ) ;
206
215
}
207
216
}
208
217
} ) ;
209
218
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
+ } ) ;
216
224
217
- // Start observing the iframe's body element
218
- observer . observe ( iframeBody , config ) ;
219
225
console . log ( "MutationObserver started on iframe body." ) ;
220
226
} catch ( e ) {
221
227
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." ,
223
229
e
224
230
) ;
225
231
}
226
232
} ;
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
+ }
227
248
}
228
249
229
250
function initializeAppUI ( ) {
@@ -233,7 +254,9 @@ function initializeAppUI() {
233
254
const header = document . querySelector ( "body header" ) ;
234
255
const links = document . querySelectorAll ( "#app-links li a" ) ;
235
256
236
- // Function to collapse the hamburger menu/sidebar
257
+ // Initialize theme sync once at startup
258
+ monitorIframeBackgroundColor ( ) ;
259
+
237
260
const collapseSidebar = ( ) => {
238
261
sidebar . classList . add ( "collapsed" ) ;
239
262
sidebar . classList . remove ( "overlay" ) ;
@@ -243,8 +266,6 @@ function initializeAppUI() {
243
266
header . style . display = "none" ;
244
267
sidebar . style . paddingTop = "6.75em" ;
245
268
}
246
-
247
- monitorIframeBackgroundColor ( ) ;
248
269
} ;
249
270
250
271
iframe . addEventListener ( "load" , collapseSidebar ) ;
@@ -257,10 +278,12 @@ function initializeAppUI() {
257
278
258
279
// The link is already active and loaded
259
280
if ( iframe . getAttribute ( "src" ) === href ) {
281
+ console . log ( `Already loaded ${ href } in iframe` ) ;
260
282
return ;
261
283
}
262
284
263
285
iframe . setAttribute ( "src" , href ) ;
286
+ console . log ( `Loading ${ href } in iframe` ) ;
264
287
265
288
links . forEach ( ( l ) => l . parentElement . classList . remove ( "active" ) ) ;
266
289
link . parentElement . classList . add ( "active" ) ;
0 commit comments