@@ -23,6 +23,7 @@ class FrameTree {
23
23
this . _browsingContextGroup . __jugglerFrameTrees = new Set ( ) ;
24
24
this . _browsingContextGroup . __jugglerFrameTrees . add ( this ) ;
25
25
this . _scriptsToEvaluateOnNewDocument = new Map ( ) ;
26
+ this . _isolatedWorlds = new Map ( ) ;
26
27
27
28
this . _webSocketEventService = Cc [
28
29
"@mozilla.org/websocketevent/service;1"
@@ -72,6 +73,25 @@ class FrameTree {
72
73
return this . _runtime ;
73
74
}
74
75
76
+ addScriptToEvaluateOnNewDocument ( script , worldName ) {
77
+ const scriptId = helper . generateId ( ) ;
78
+ if ( worldName ) {
79
+ this . _isolatedWorlds . set ( scriptId , { script, worldName} ) ;
80
+ for ( const frame of this . frames ( ) )
81
+ frame . createIsolatedWorld ( worldName ) ;
82
+ } else {
83
+ this . _scriptsToEvaluateOnNewDocument . set ( scriptId , script ) ;
84
+ }
85
+ return { scriptId} ;
86
+ }
87
+
88
+ removeScriptToEvaluateOnNewDocument ( scriptId ) {
89
+ if ( this . _isolatedWorlds . has ( scriptId ) )
90
+ this . _isolatedWorlds . delete ( scriptId ) ;
91
+ else
92
+ this . _scriptsToEvaluateOnNewDocument . delete ( scriptId ) ;
93
+ }
94
+
75
95
_frameForWorker ( workerDebugger ) {
76
96
if ( workerDebugger . type !== Ci . nsIWorkerDebugger . TYPE_DEDICATED )
77
97
return null ;
@@ -86,7 +106,6 @@ class FrameTree {
86
106
if ( ! frame )
87
107
return ;
88
108
frame . _onGlobalObjectCleared ( ) ;
89
- this . emit ( FrameTree . Events . GlobalObjectCreated , { frame, window } ) ;
90
109
}
91
110
92
111
_onWorkerCreated ( workerDebugger ) {
@@ -129,16 +148,6 @@ class FrameTree {
129
148
return true ;
130
149
}
131
150
132
- addScriptToEvaluateOnNewDocument ( script ) {
133
- const scriptId = helper . generateId ( ) ;
134
- this . _scriptsToEvaluateOnNewDocument . set ( scriptId , script ) ;
135
- return scriptId ;
136
- }
137
-
138
- removeScriptToEvaluateOnNewDocument ( scriptId ) {
139
- this . _scriptsToEvaluateOnNewDocument . delete ( scriptId ) ;
140
- }
141
-
142
151
addBinding ( name , script ) {
143
152
this . _bindings . set ( name , script ) ;
144
153
for ( const frame of this . frames ( ) )
@@ -291,7 +300,6 @@ FrameTree.Events = {
291
300
BindingCalled : 'bindingcalled' ,
292
301
FrameAttached : 'frameattached' ,
293
302
FrameDetached : 'framedetached' ,
294
- GlobalObjectCreated : 'globalobjectcreated' ,
295
303
WorkerCreated : 'workercreated' ,
296
304
WorkerDestroyed : 'workerdestroyed' ,
297
305
WebSocketCreated : 'websocketcreated' ,
@@ -330,6 +338,9 @@ class Frame {
330
338
this . _textInputProcessor = null ;
331
339
this . _executionContext = null ;
332
340
341
+ this . _isolatedWorlds = new Map ( ) ;
342
+ this . _initialNavigationDone = false ;
343
+
333
344
this . _webSocketListenerInnerWindowId = 0 ;
334
345
// WebSocketListener calls frameReceived event before webSocketOpened.
335
346
// To avoid this, serialize event reporting.
@@ -415,7 +426,36 @@ class Frame {
415
426
} ;
416
427
}
417
428
429
+ createIsolatedWorld ( name ) {
430
+ const principal = [ this . domWindow ( ) ] ; // extended principal
431
+ const sandbox = Cu . Sandbox ( principal , {
432
+ sandboxPrototype : this . domWindow ( ) ,
433
+ wantComponents : false ,
434
+ wantExportHelpers : false ,
435
+ wantXrays : true ,
436
+ } ) ;
437
+ const world = this . _runtime . createExecutionContext ( this . domWindow ( ) , sandbox , {
438
+ frameId : this . id ( ) ,
439
+ name,
440
+ } ) ;
441
+ this . _isolatedWorlds . set ( world . id ( ) , world ) ;
442
+ return world ;
443
+ }
444
+
445
+ unsafeObject ( objectId ) {
446
+ const contexts = [ this . executionContext ( ) , ...this . _isolatedWorlds . values ( ) ] ;
447
+ for ( const context of contexts ) {
448
+ const result = context . unsafeObject ( objectId ) ;
449
+ if ( result )
450
+ return result . object ;
451
+ }
452
+ throw new Error ( 'Cannot find object with id = ' + objectId ) ;
453
+ }
454
+
418
455
dispose ( ) {
456
+ for ( const world of this . _isolatedWorlds . values ( ) )
457
+ this . _runtime . destroyExecutionContext ( world ) ;
458
+ this . _isolatedWorlds . clear ( ) ;
419
459
if ( this . _executionContext )
420
460
this . _runtime . destroyExecutionContext ( this . _executionContext ) ;
421
461
this . _executionContext = null ;
@@ -458,6 +498,19 @@ class Frame {
458
498
dump ( `ERROR: ${ e . message } \n${ e . stack } \n` ) ;
459
499
}
460
500
}
501
+
502
+ for ( const world of this . _isolatedWorlds . values ( ) )
503
+ this . _runtime . destroyExecutionContext ( world ) ;
504
+ this . _isolatedWorlds . clear ( ) ;
505
+ for ( const { script, worldName} of this . _frameTree . _isolatedWorlds . values ( ) ) {
506
+ const context = worldName ? this . createIsolatedWorld ( worldName ) : this . executionContext ( ) ;
507
+ try {
508
+ let result = context . evaluateScript ( script ) ;
509
+ if ( result && result . objectId )
510
+ context . disposeObject ( result . objectId ) ;
511
+ } catch ( e ) {
512
+ }
513
+ }
461
514
}
462
515
463
516
executionContext ( ) {
0 commit comments