@@ -4,6 +4,7 @@ const Cr = Components.results;
4
4
const Cu = Components . utils ;
5
5
6
6
const { Helper} = ChromeUtils . import ( 'chrome://juggler/content/Helper.js' ) ;
7
+ const { SimpleChannel} = ChromeUtils . import ( 'chrome://juggler/content/SimpleChannel.js' ) ;
7
8
const { EventEmitter} = ChromeUtils . import ( 'resource://gre/modules/EventEmitter.jsm' ) ;
8
9
9
10
const helper = new Helper ( ) ;
@@ -17,6 +18,7 @@ class FrameTree {
17
18
this . _browsingContextGroup . __jugglerFrameTrees = new Set ( ) ;
18
19
this . _browsingContextGroup . __jugglerFrameTrees . add ( this ) ;
19
20
21
+ this . _workers = new Map ( ) ;
20
22
this . _docShellToFrame = new Map ( ) ;
21
23
this . _frameIdToFrame = new Map ( ) ;
22
24
this . _pageReady = ! waitForInitialNavigation ;
@@ -30,6 +32,17 @@ class FrameTree {
30
32
] ) ;
31
33
this . _scriptsToEvaluateOnNewDocument = [ ] ;
32
34
35
+ this . _wdm = Cc [ "@mozilla.org/dom/workers/workerdebuggermanager;1" ] . createInstance ( Ci . nsIWorkerDebuggerManager ) ;
36
+ this . _wdmListener = {
37
+ QueryInterface : ChromeUtils . generateQI ( [ Ci . nsIWorkerDebuggerManagerListener ] ) ,
38
+ onRegister : this . _onWorkerCreated . bind ( this ) ,
39
+ onUnregister : this . _onWorkerDestroyed . bind ( this ) ,
40
+ } ;
41
+ this . _wdm . addListener ( this . _wdmListener ) ;
42
+ for ( const workerDebugger of this . _wdm . getWorkerDebuggerEnumerator ( ) )
43
+ this . _onWorkerCreated ( workerDebugger ) ;
44
+
45
+
33
46
const flags = Ci . nsIWebProgress . NOTIFY_STATE_DOCUMENT |
34
47
Ci . nsIWebProgress . NOTIFY_FRAME_LOCATION ;
35
48
this . _eventListeners = [
@@ -39,6 +52,41 @@ class FrameTree {
39
52
] ;
40
53
}
41
54
55
+ workers ( ) {
56
+ return [ ...this . _workers . values ( ) ] ;
57
+ }
58
+
59
+ _frameForWorker ( workerDebugger ) {
60
+ if ( workerDebugger . type !== Ci . nsIWorkerDebugger . TYPE_DEDICATED )
61
+ return null ;
62
+ const docShell = workerDebugger . window . docShell ;
63
+ return this . _docShellToFrame . get ( docShell ) || null ;
64
+ }
65
+
66
+ _onWorkerCreated ( workerDebugger ) {
67
+ // Note: we do not interoperate with firefox devtools.
68
+ if ( workerDebugger . isInitialized )
69
+ return ;
70
+ const frame = this . _frameForWorker ( workerDebugger ) ;
71
+ if ( ! frame )
72
+ return ;
73
+ const worker = new Worker ( frame , workerDebugger ) ;
74
+ this . _workers . set ( workerDebugger , worker ) ;
75
+ this . emit ( FrameTree . Events . WorkerCreated , worker ) ;
76
+ }
77
+
78
+ _onWorkerDestroyed ( workerDebugger ) {
79
+ const frame = this . _frameForWorker ( workerDebugger ) ;
80
+ if ( ! frame )
81
+ return ;
82
+ const worker = this . _workers . get ( workerDebugger ) ;
83
+ if ( ! worker )
84
+ return ;
85
+ worker . dispose ( ) ;
86
+ this . _workers . delete ( workerDebugger ) ;
87
+ this . emit ( FrameTree . Events . WorkerDestroyed , worker ) ;
88
+ }
89
+
42
90
allFramesInBrowsingContextGroup ( group ) {
43
91
const frames = [ ] ;
44
92
for ( const frameTree of ( group . __jugglerFrameTrees || [ ] ) )
@@ -84,6 +132,7 @@ class FrameTree {
84
132
85
133
dispose ( ) {
86
134
this . _browsingContextGroup . __jugglerFrameTrees . delete ( this ) ;
135
+ this . _wdm . removeListener ( this . _wdmListener ) ;
87
136
helper . removeListeners ( this . _eventListeners ) ;
88
137
}
89
138
@@ -192,6 +241,8 @@ class FrameTree {
192
241
FrameTree . Events = {
193
242
FrameAttached : 'frameattached' ,
194
243
FrameDetached : 'framedetached' ,
244
+ WorkerCreated : 'workercreated' ,
245
+ WorkerDestroyed : 'workerdestroyed' ,
195
246
NavigationStarted : 'navigationstarted' ,
196
247
NavigationCommitted : 'navigationcommitted' ,
197
248
NavigationAborted : 'navigationaborted' ,
@@ -268,6 +319,53 @@ class Frame {
268
319
url ( ) {
269
320
return this . _url ;
270
321
}
322
+
323
+ }
324
+
325
+ class Worker {
326
+ constructor ( frame , workerDebugger ) {
327
+ this . _frame = frame ;
328
+ this . _workerId = helper . generateId ( ) ;
329
+ this . _workerDebugger = workerDebugger ;
330
+
331
+ workerDebugger . initialize ( 'chrome://juggler/content/content/WorkerMain.js' ) ;
332
+
333
+ this . _channel = new SimpleChannel ( `content::worker[${ this . _workerId } ]` ) ;
334
+ this . _channel . transport = {
335
+ sendMessage : obj => workerDebugger . postMessage ( JSON . stringify ( obj ) ) ,
336
+ dispose : ( ) => { } ,
337
+ } ;
338
+ this . _workerDebuggerListener = {
339
+ QueryInterface : ChromeUtils . generateQI ( [ Ci . nsIWorkerDebuggerListener ] ) ,
340
+ onMessage : msg => void this . _channel . _onMessage ( JSON . parse ( msg ) ) ,
341
+ onClose : ( ) => void this . _channel . dispose ( ) ,
342
+ onError : ( filename , lineno , message ) => {
343
+ dump ( `Error in worker: ${ message } @${ filename } :${ lineno } \n` ) ;
344
+ } ,
345
+ } ;
346
+ workerDebugger . addListener ( this . _workerDebuggerListener ) ;
347
+ }
348
+
349
+ channel ( ) {
350
+ return this . _channel ;
351
+ }
352
+
353
+ frame ( ) {
354
+ return this . _frame ;
355
+ }
356
+
357
+ id ( ) {
358
+ return this . _workerId ;
359
+ }
360
+
361
+ url ( ) {
362
+ return this . _workerDebugger . url ;
363
+ }
364
+
365
+ dispose ( ) {
366
+ this . _channel . dispose ( ) ;
367
+ this . _workerDebugger . removeListener ( this . _workerDebuggerListener ) ;
368
+ }
271
369
}
272
370
273
371
var EXPORTED_SYMBOLS = [ 'FrameTree' ] ;
0 commit comments