@@ -190,11 +190,12 @@ class TargetRegistry {
190
190
} ,
191
191
} ) ;
192
192
193
- const onTabOpenListener = ( window , event ) => {
193
+ const onTabOpenListener = ( appWindow , window , event ) => {
194
194
const tab = event . target ;
195
195
const userContextId = tab . userContextId ;
196
196
const browserContext = this . _userContextIdToBrowserContext . get ( userContextId ) ;
197
- if ( browserContext && browserContext . defaultViewportSize )
197
+ const hasExplicitSize = ( appWindow . chromeFlags & Ci . nsIWebBrowserChrome . JUGGLER_WINDOW_EXPLICIT_SIZE ) !== 0 ;
198
+ if ( ! hasExplicitSize && browserContext && browserContext . defaultViewportSize )
198
199
setViewportSizeForBrowser ( browserContext . defaultViewportSize , tab . linkedBrowser , window ) ;
199
200
} ;
200
201
@@ -206,36 +207,46 @@ class TargetRegistry {
206
207
target . dispose ( ) ;
207
208
} ;
208
209
209
- Services . wm . addListener ( {
210
- onOpenWindow : async window => {
211
- const domWindow = window . QueryInterface ( Ci . nsIInterfaceRequestor ) . getInterface ( Ci . nsIDOMWindowInternal || Ci . nsIDOMWindow ) ;
212
- if ( ! ( domWindow instanceof Ci . nsIDOMChromeWindow ) )
213
- return ;
214
- if ( domWindow . document . readyState !== 'uninitialized' )
215
- throw new Error ( 'DOMWindow should not be loaded yet' ) ;
216
- await new Promise ( fulfill => {
217
- domWindow . addEventListener ( 'DOMContentLoaded' , function listener ( ) {
218
- domWindow . removeEventListener ( 'DOMContentLoaded' , listener ) ;
219
- fulfill ( ) ;
220
- } ) ;
221
- } ) ;
222
- if ( ! domWindow . gBrowser )
223
- return ;
224
- domWindow . gBrowser . tabContainer . addEventListener ( 'TabOpen' , event => onTabOpenListener ( domWindow , event ) ) ;
225
- domWindow . gBrowser . tabContainer . addEventListener ( 'TabClose' , onTabCloseListener ) ;
226
- } ,
227
- onCloseWindow : window => {
228
- const domWindow = window . QueryInterface ( Ci . nsIInterfaceRequestor ) . getInterface ( Ci . nsIDOMWindowInternal || Ci . nsIDOMWindow ) ;
229
- if ( ! ( domWindow instanceof Ci . nsIDOMChromeWindow ) )
230
- return ;
231
- if ( ! domWindow . gBrowser )
232
- return ;
233
- domWindow . gBrowser . tabContainer . removeEventListener ( 'TabOpen' , onTabOpenListener ) ;
234
- domWindow . gBrowser . tabContainer . removeEventListener ( 'TabClose' , onTabCloseListener ) ;
235
- for ( const tab of domWindow . gBrowser . tabs )
236
- onTabCloseListener ( { target : tab } ) ;
237
- } ,
238
- } ) ;
210
+ const domWindowTabListeners = new Map ( ) ;
211
+
212
+ const onOpenWindow = async ( appWindow ) => {
213
+ if ( ! ( appWindow instanceof Ci . nsIAppWindow ) )
214
+ return ;
215
+ const domWindow = appWindow . QueryInterface ( Ci . nsIInterfaceRequestor ) . getInterface ( Ci . nsIDOMWindowInternal || Ci . nsIDOMWindow ) ;
216
+ if ( ! ( domWindow instanceof Ci . nsIDOMChromeWindow ) )
217
+ return ;
218
+ if ( domWindow . document . readyState !== 'uninitialized' )
219
+ throw new Error ( 'DOMWindow should not be loaded yet' ) ;
220
+ await helper . awaitEvent ( domWindow , 'DOMContentLoaded' ) ;
221
+
222
+ if ( ! domWindow . gBrowser )
223
+ return ;
224
+ const tabContainer = domWindow . gBrowser . tabContainer ;
225
+ domWindowTabListeners . set ( domWindow , [
226
+ helper . addEventListener ( tabContainer , 'TabOpen' , event => onTabOpenListener ( appWindow , domWindow , event ) ) ,
227
+ helper . addEventListener ( tabContainer , 'TabClose' , onTabCloseListener ) ,
228
+ ] ) ;
229
+ for ( const tab of domWindow . gBrowser . tabs )
230
+ onTabOpenListener ( appWindow , domWindow , { target : tab } ) ;
231
+ } ;
232
+
233
+ const onCloseWindow = window => {
234
+ const domWindow = window . QueryInterface ( Ci . nsIInterfaceRequestor ) . getInterface ( Ci . nsIDOMWindowInternal || Ci . nsIDOMWindow ) ;
235
+ if ( ! ( domWindow instanceof Ci . nsIDOMChromeWindow ) )
236
+ return ;
237
+ if ( ! domWindow . gBrowser )
238
+ return ;
239
+
240
+ const listeners = domWindowTabListeners . get ( domWindow ) || [ ] ;
241
+ domWindowTabListeners . delete ( domWindow ) ;
242
+ helper . removeListeners ( listeners ) ;
243
+ for ( const tab of domWindow . gBrowser . tabs )
244
+ onTabCloseListener ( { target : tab } ) ;
245
+ } ;
246
+
247
+ Services . wm . addListener ( { onOpenWindow, onCloseWindow } ) ;
248
+ for ( const win of Services . wm . getEnumerator ( null ) )
249
+ onOpenWindow ( win ) ;
239
250
240
251
const extHelperAppSvc = Cc [ "@mozilla.org/uriloader/external-helper-app-service;1" ] . getService ( Ci . nsIExternalHelperAppService ) ;
241
252
extHelperAppSvc . setDownloadInterceptor ( new DownloadInterceptor ( this ) ) ;
@@ -308,7 +319,7 @@ class TargetRegistry {
308
319
const window = Services . ww . openWindow ( null , AppConstants . BROWSER_CHROME_URL , '_blank' , features , args ) ;
309
320
await waitForWindowReady ( window ) ;
310
321
if ( window . gBrowser . browsers . length !== 1 )
311
- throw new Error ( `Unexpcted number of tabs in the new window: ${ window . gBrowser . browsers . length } ` ) ;
322
+ throw new Error ( `Unexpected number of tabs in the new window: ${ window . gBrowser . browsers . length } ` ) ;
312
323
const browser = window . gBrowser . browsers [ 0 ] ;
313
324
const target = this . _browserToTarget . get ( browser ) || await new Promise ( fulfill => {
314
325
const listener = helper . on ( this , TargetRegistry . Events . TargetCreated , ( { target} ) => {
@@ -318,8 +329,6 @@ class TargetRegistry {
318
329
}
319
330
} ) ;
320
331
} ) ;
321
- if ( browserContext && browserContext . defaultViewportSize )
322
- setViewportSizeForBrowser ( browserContext . defaultViewportSize , browser , window ) ;
323
332
browser . focus ( ) ;
324
333
if ( browserContext . settings . timezoneId ) {
325
334
if ( await target . hasFailedToOverrideTimezone ( ) )
@@ -373,7 +382,6 @@ class PageTarget {
373
382
374
383
this . _disposed = false ;
375
384
browserContext . pages . add ( this ) ;
376
- browserContext . _firstPageCallback ( ) ;
377
385
this . _registry . _browserToTarget . set ( this . _linkedBrowser , this ) ;
378
386
this . _registry . _browserBrowsingContextToTarget . set ( this . _linkedBrowser . browsingContext , this ) ;
379
387
}
@@ -501,7 +509,6 @@ class BrowserContext {
501
509
this . bindings = [ ] ;
502
510
this . settings = { } ;
503
511
this . pages = new Set ( ) ;
504
- this . _firstPagePromise = new Promise ( f => this . _firstPageCallback = f ) ;
505
512
}
506
513
507
514
async destroy ( ) {
@@ -545,11 +552,6 @@ class BrowserContext {
545
552
546
553
async setDefaultViewport ( viewport ) {
547
554
this . defaultViewportSize = viewport ? viewport . viewportSize : undefined ;
548
- if ( ! this . userContextId ) {
549
- // First page in the default context comes before onTabOpenListener
550
- // so we don't set default viewport. Wait for it here and ensure the viewport.
551
- await this . _firstPagePromise ;
552
- }
553
555
const promises = Array . from ( this . pages ) . map ( async page => {
554
556
// Resize to new default, unless the page has a custom viewport.
555
557
if ( ! page . _viewportSize )
@@ -707,14 +709,8 @@ async function waitForWindowReady(window) {
707
709
} , "browser-delayed-startup-finished" ) ;
708
710
} ) ) ;
709
711
}
710
- if ( window . document . readyState !== 'complete' ) {
711
- await new Promise ( fulfill => {
712
- window . addEventListener ( 'load' , function listener ( ) {
713
- window . removeEventListener ( 'load' , listener ) ;
714
- fulfill ( ) ;
715
- } ) ;
716
- } ) ;
717
- }
712
+ if ( window . document . readyState !== 'complete' )
713
+ await helper . awaitEvent ( window , 'load' ) ;
718
714
}
719
715
720
716
function setViewportSizeForBrowser ( viewportSize , browser , window ) {
0 commit comments