22const EventEmitter = require ( 'events' ) . EventEmitter ;
33
44const log = require ( '../../../../lib/logger' ) ( { hostname : 'background' , MODULE : 'tabs/background/ScriptWindow' } ) ;
5+ const { BLANK_HTML } = require ( './urls' ) ;
6+ const WaitForEvent = require ( '../../../../lib/WaitForEvent' ) ;
57
68class ScriptWindow extends EventEmitter {
7- constructor ( browserWindows , browserTabs ) {
9+ constructor ( { browserWindows, browserTabs, browserWebNavigation } ) {
810 super ( ) ;
11+ this . _attached = false ;
912 this . browserWindows = browserWindows ;
1013 this . browserTabs = browserTabs ;
14+ this . browserWebNavigation = browserWebNavigation ;
1115 this . openPromise = null ;
1216 this . firstTabCreation = true ;
1317 this . closed = false ;
18+ this . _navigationCompletedWait = new WaitForEvent ( ) ; // key is the browserTabId
19+ this . _sizeMinusViewport = Object . freeze ( { width : 0 , height : 0 } ) ;
20+ this . handleWebNavigationCompleted = this . handleWebNavigationCompleted . bind ( this ) ;
1421 Object . seal ( this ) ;
1522 }
1623
24+ attach ( ) {
25+ this . browserWebNavigation . onCompleted . addListener ( this . handleWebNavigationCompleted ) ;
26+ this . _attached = true ;
27+ }
28+
29+ detach ( ) {
30+ this . _attached = false ;
31+ this . browserWebNavigation . onCompleted . removeListener ( this . handleWebNavigationCompleted ) ;
32+ }
33+
34+ handleWebNavigationCompleted ( { tabId : browserTabId , frameId, url} ) {
35+ try {
36+ log . debug ( { browserTabId, frameId, url} , 'browser.webNavigation.onCompleted' ) ;
37+
38+ if ( frameId || url === 'about:blank' ) { // frameId === 0 is top; otherwise it is an iframe
39+ return ;
40+ }
41+
42+ this . _navigationCompletedWait . resolve ( browserTabId ) ;
43+ }
44+ catch ( err ) {
45+ log . error ( { err} , 'Error in browser.webNavigation.onCompleted' ) ;
46+ }
47+ }
48+
1749 async open ( ) {
1850 if ( this . closed || this . openPromise ) {
1951 throw Error ( 'Invalid state' ) ;
2052 }
2153
54+ log . debug ( { } , 'Creating new window...' ) ;
55+
2256 this . firstTabCreation = true ;
2357 this . openPromise = this . browserWindows . create ( {
24- // focused: true,
2558 incognito : true ,
2659 state : 'maximized' ,
2760 url : 'about:blank' ,
2861 } ) . then ( window => window . id ) ;
2962
3063 const browserWindowId = await this . openPromise ;
64+ const { tabs : windowTabs } = await this . browserWindows . get ( browserWindowId , { populate : true } ) ;
65+ const firstTabId = windowTabs [ 0 ] . id ;
66+ await this . _gatherBrowserWindowDetails ( browserWindowId , firstTabId ) ;
67+
68+ log . debug ( { browserWindowId, firstTabId, sizeMinusViewport : this . sizeMinusViewport } , 'Created a new window' ) ;
69+
3170 this . emit ( 'windowCreated' , { browserWindowId} ) ;
3271 }
3372
73+ /**
74+ * Navigate to an extension page and gather some statistics about the environment, such as the position of the viewport.
75+ * @param {string } browserWindowId
76+ * @param {string } firstTabId
77+ * @private
78+ */
79+ async _gatherBrowserWindowDetails ( browserWindowId , firstTabId ) {
80+ // navigate to blank.html and wait for the load event
81+ await this . _navigationCompletedWait . wait ( firstTabId , async ( ) => {
82+ await this . browserTabs . update ( firstTabId , { url : BLANK_HTML } ) ;
83+ } ) ;
84+
85+ let sizeMinusViewport = [ 0 , 0 ] ;
86+ try {
87+ [ sizeMinusViewport ] = await this . browserTabs . executeScript ( firstTabId , {
88+ code : '([window.outerWidth - window.innerWidth, window.outerHeight - window.innerHeight])' ,
89+ } ) ;
90+ }
91+ catch ( err ) {
92+ log . debug ( { browserWindowId, firstTabId, err} , 'Unable to determine the window dimension' ) ;
93+ }
94+
95+ this . _sizeMinusViewport = Object . freeze ( {
96+ width : Number ( sizeMinusViewport [ 0 ] ) ,
97+ height : Number ( sizeMinusViewport [ 1 ] ) ,
98+ } ) ;
99+ }
100+
101+ /**
102+ * @return {{width: number, height: number} }
103+ */
104+ get sizeMinusViewport ( ) {
105+ return this . _sizeMinusViewport ;
106+ }
107+
34108 get isOpen ( ) {
35109 return Boolean ( this . openPromise ) ;
36110 }
@@ -47,7 +121,6 @@ class ScriptWindow extends EventEmitter {
47121 const browserWindowId = await this . getBrowserWindowId ( ) ;
48122 return await this . browserWindows . get ( browserWindowId , {
49123 populate : true ,
50- windowTypes : [ 'normal' ] ,
51124 } ) ;
52125 }
53126
@@ -94,6 +167,20 @@ class ScriptWindow extends EventEmitter {
94167 const { id : browserWindowId } = await this . getBrowserWindow ( ) ;
95168 return browserWindowId === browserTab . windowId ;
96169 }
170+
171+ async setWindowSize ( { width, height} ) {
172+ const { id : browserWindowId } = await this . getBrowserWindow ( ) ;
173+ await this . browserWindows . update ( browserWindowId , {
174+ width : Number ( width ) ,
175+ height : Number ( height ) ,
176+ } ) ;
177+
178+ const result = await this . browserWindows . get ( browserWindowId ) ;
179+ return Object . freeze ( {
180+ width : result . width ,
181+ height : result . height ,
182+ } ) ;
183+ }
97184}
98185
99186
0 commit comments