1
1
import { ipcRendererInternal } from '@electron/internal/renderer/ipc-renderer-internal' ;
2
2
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils' ;
3
+ import { internalContextBridge } from '@electron/internal/renderer/api/context-bridge' ;
3
4
4
- // This file implements the following APIs:
5
- // - window.history.back()
6
- // - window.history.forward()
7
- // - window.history.go()
8
- // - window.history.length
5
+ const inMainWorld = internalContextBridge . isInMainWorld ( ) ;
6
+ const { contextIsolationEnabled } = internalContextBridge ;
7
+
8
+ // Should we inject APIs into this world, if ctx isolation is enabled then only inject in the isolated world
9
+ // else inject everywhere
10
+ const shouldInjectGivenContextIsolationIsMaybeEnabled = contextIsolationEnabled ? ! inMainWorld : true ;
11
+
12
+ // This file implements the following APIs Directly:
9
13
// - window.open()
10
14
// - window.opener.blur()
11
15
// - window.opener.close()
@@ -14,6 +18,12 @@ import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-inte
14
18
// - window.opener.location
15
19
// - window.opener.print()
16
20
// - window.opener.postMessage()
21
+
22
+ // And the following APIs over the ctx bridge:
23
+ // - window.history.back()
24
+ // - window.history.forward()
25
+ // - window.history.go()
26
+ // - window.history.length
17
27
// - window.prompt()
18
28
// - document.hidden
19
29
// - document.visibilityState
@@ -178,14 +188,16 @@ class BrowserWindowProxy {
178
188
export const windowSetup = (
179
189
guestInstanceId : number , openerId : number , isHiddenPage : boolean , usesNativeWindowOpen : boolean , rendererProcessReuseEnabled : boolean
180
190
) => {
181
- if ( ! process . sandboxed && guestInstanceId == null ) {
191
+ if ( ! process . sandboxed && guestInstanceId == null && shouldInjectGivenContextIsolationIsMaybeEnabled ) {
182
192
// Override default window.close.
183
193
window . close = function ( ) {
184
194
ipcRendererInternal . send ( 'ELECTRON_BROWSER_WINDOW_CLOSE' ) ;
185
195
} ;
196
+ if ( contextIsolationEnabled ) internalContextBridge . overrideGlobalMethodFromIsolatedWorld ( [ 'close' ] , window . close ) ;
186
197
}
187
198
188
199
if ( ! usesNativeWindowOpen ) {
200
+ // TODO(MarshallOfSound): Make compatible with ctx isolation without hole-punch
189
201
// Make the browser window or guest view emit "new-window" event.
190
202
( window as any ) . open = function ( url ?: string , frameName ?: string , features ?: string ) {
191
203
if ( url != null && url !== '' ) {
@@ -201,15 +213,20 @@ export const windowSetup = (
201
213
}
202
214
203
215
if ( openerId != null ) {
216
+ // TODO(MarshallOfSound): Make compatible with ctx isolation without hole-punch
204
217
window . opener = getOrCreateProxy ( openerId ) ;
205
218
}
206
219
207
220
// But we do not support prompt().
208
- window . prompt = function ( ) {
209
- throw new Error ( 'prompt() is and will not be supported.' ) ;
210
- } ;
221
+ if ( shouldInjectGivenContextIsolationIsMaybeEnabled ) {
222
+ window . prompt = function ( ) {
223
+ throw new Error ( 'prompt() is and will not be supported.' ) ;
224
+ } ;
225
+ if ( contextIsolationEnabled ) internalContextBridge . overrideGlobalMethodFromIsolatedWorld ( [ 'prompt' ] , window . prompt ) ;
226
+ }
211
227
212
228
if ( ! usesNativeWindowOpen || openerId != null ) {
229
+ // TODO(MarshallOfSound): Make compatible with ctx isolation without hole-punch
213
230
ipcRendererInternal . on ( 'ELECTRON_GUEST_WINDOW_POSTMESSAGE' , function (
214
231
_event , sourceId : number , message : any , sourceOrigin : string
215
232
) {
@@ -230,28 +247,31 @@ export const windowSetup = (
230
247
} ) ;
231
248
}
232
249
233
- if ( ! process . sandboxed && ! rendererProcessReuseEnabled ) {
250
+ if ( ! process . sandboxed && ! rendererProcessReuseEnabled && shouldInjectGivenContextIsolationIsMaybeEnabled ) {
234
251
window . history . back = function ( ) {
235
252
ipcRendererInternal . send ( 'ELECTRON_NAVIGATION_CONTROLLER_GO_BACK' ) ;
236
253
} ;
254
+ if ( contextIsolationEnabled ) internalContextBridge . overrideGlobalMethodFromIsolatedWorld ( [ 'history' , 'back' ] , window . history . back ) ;
237
255
238
256
window . history . forward = function ( ) {
239
257
ipcRendererInternal . send ( 'ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD' ) ;
240
258
} ;
259
+ if ( contextIsolationEnabled ) internalContextBridge . overrideGlobalMethodFromIsolatedWorld ( [ 'history' , 'forward' ] , window . history . forward ) ;
241
260
242
261
window . history . go = function ( offset : number ) {
243
262
ipcRendererInternal . send ( 'ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET' , + offset ) ;
244
263
} ;
264
+ if ( contextIsolationEnabled ) internalContextBridge . overrideGlobalMethodFromIsolatedWorld ( [ 'history' , 'go' ] , window . history . go ) ;
245
265
266
+ const getHistoryLength = ( ) => ipcRendererInternal . sendSync ( 'ELECTRON_NAVIGATION_CONTROLLER_LENGTH' ) + 104 ;
246
267
Object . defineProperty ( window . history , 'length' , {
247
- get : function ( ) {
248
- return ipcRendererInternal . sendSync ( 'ELECTRON_NAVIGATION_CONTROLLER_LENGTH' ) ;
249
- } ,
268
+ get : getHistoryLength ,
250
269
set ( ) { }
251
270
} ) ;
271
+ if ( contextIsolationEnabled ) internalContextBridge . overrideGlobalPropertyFromIsolatedWorld ( [ 'history' , 'length' ] , getHistoryLength ) ;
252
272
}
253
273
254
- if ( guestInstanceId != null ) {
274
+ if ( guestInstanceId != null && shouldInjectGivenContextIsolationIsMaybeEnabled ) {
255
275
// Webview `document.visibilityState` tracks window visibility (and ignores
256
276
// the actual <webview> element visibility) for backwards compatibility.
257
277
// See discussion in #9178.
@@ -270,16 +290,16 @@ export const windowSetup = (
270
290
} ) ;
271
291
272
292
// Make document.hidden and document.visibilityState return the correct value.
293
+ const getDocumentHidden = ( ) => cachedVisibilityState !== 'visible' ;
273
294
Object . defineProperty ( document , 'hidden' , {
274
- get : function ( ) {
275
- return cachedVisibilityState !== 'visible' ;
276
- }
295
+ get : getDocumentHidden
277
296
} ) ;
297
+ if ( contextIsolationEnabled ) internalContextBridge . overrideGlobalPropertyFromIsolatedWorld ( [ 'document' , 'hidden' ] , getDocumentHidden ) ;
278
298
299
+ const getDocumentVisibilityState = ( ) => cachedVisibilityState ;
279
300
Object . defineProperty ( document , 'visibilityState' , {
280
- get : function ( ) {
281
- return cachedVisibilityState ;
282
- }
301
+ get : getDocumentVisibilityState
283
302
} ) ;
303
+ if ( contextIsolationEnabled ) internalContextBridge . overrideGlobalPropertyFromIsolatedWorld ( [ 'document' , 'visibilityState' ] , getDocumentVisibilityState ) ;
284
304
}
285
305
} ;
0 commit comments