@@ -262,40 +262,55 @@ export class IframeSandbox implements SignalSandbox {
262
262
this . iframe . style . display = 'none'
263
263
this . iframe . src = 'about:blank'
264
264
document . body . appendChild ( this . iframe )
265
- this . iframeReady = new Promise ( ( resolve ) => {
266
- void window . addEventListener ( 'message' , ( e ) => {
265
+ this . iframeReady = this . listenForIframeInit ( )
266
+
267
+ const doc = this . iframe . contentDocument !
268
+ doc . open ( )
269
+ doc . write ( this . getIframeInitialDoc ( processSignalFn ) )
270
+ doc . close ( )
271
+
272
+ const runtimeJs = this . getRuntimeJSForIframe ( processSignalFn )
273
+ const blob = new Blob ( [ runtimeJs ] , { type : 'application/javascript' } )
274
+ const runtimeScript = doc . createElement ( 'script' )
275
+ runtimeScript . src = URL . createObjectURL ( blob )
276
+ doc . head . appendChild ( runtimeScript )
277
+ }
278
+
279
+ private listenForIframeInit ( ) : Promise < void > {
280
+ return new Promise ( ( resolve ) => {
281
+ window . addEventListener ( 'message' , ( e ) => {
267
282
if (
268
283
e . source === this . iframe . contentWindow &&
269
284
e . data === 'iframe_ready'
270
285
) {
271
286
this . iframe . contentWindow ! . postMessage ( {
272
287
type : 'init' ,
273
288
} )
274
- resolve ( )
289
+ resolve ( undefined )
275
290
}
276
291
} )
277
292
} )
293
+ }
278
294
279
- const doc = this . iframe . contentDocument !
280
- doc . open ( )
281
- doc . write (
282
- [
283
- `<!DOCTYPE html>` ,
284
- `<html>` ,
285
- `<head>` ,
286
- processSignalFn
287
- ? ''
288
- : `<script id="edge-fn" src=${ this . edgeFnUrl } ></script>` ,
289
- `</head>` ,
290
- `<body></body>
295
+ private getIframeInitialDoc ( processSignalFn ?: string ) : string {
296
+ return [
297
+ `<!DOCTYPE html>` ,
298
+ `<html>` ,
299
+ `<head>` ,
300
+ // this could probably also be loaded dynamically (in getRuntimeJS etc)
301
+ processSignalFn
302
+ ? ''
303
+ : `<script id="edge-fn" src=${ this . edgeFnUrl } ></script>` ,
304
+ `</head>` ,
305
+ `<body></body>
291
306
</html>` ,
292
- ] . join ( ',' )
293
- )
294
- doc . close ( )
307
+ ] . join ( ',' )
308
+ }
295
309
310
+ private getRuntimeJSForIframe ( processSignalFn ?: string ) {
296
311
// External signal processor script
297
312
// Inject runtime via Blob (CSP-safe)
298
- const runtimeJs = `
313
+ return `
299
314
${ processSignalFn ? `window.processSignal = ${ processSignalFn } ` : '' }
300
315
301
316
const signalsScript = document.getElementById('edge-fn')
@@ -367,16 +382,8 @@ export class IframeSandbox implements SignalSandbox {
367
382
}
368
383
}
369
384
});
370
-
371
-
372
385
`
373
- const blob = new Blob ( [ runtimeJs ] , { type : 'application/javascript' } )
374
- const runtimeScript = doc . createElement ( 'script' )
375
- runtimeScript . src = URL . createObjectURL ( blob )
376
-
377
- doc . head . appendChild ( runtimeScript )
378
386
}
379
-
380
387
private normalizeAnalyticsMethodCallsWithArgResolver = (
381
388
methodCalls : AnalyticsMethodCalls
382
389
) => {
0 commit comments