| 
									
										
										
										
											2021-04-10 00:13:19 -05:00
										 |  |  | /* This Source Code Form is subject to the terms of the Mozilla Public | 
					
						
							|  |  |  |  * License, v. 2.0. If a copy of the MPL was not distributed with this | 
					
						
							|  |  |  |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); | 
					
						
							|  |  |  | const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js'); | 
					
						
							|  |  |  | const {FrameTree} = ChromeUtils.import('chrome://juggler/content/content/FrameTree.js'); | 
					
						
							|  |  |  | const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js'); | 
					
						
							|  |  |  | const {PageAgent} = ChromeUtils.import('chrome://juggler/content/content/PageAgent.js'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let frameTree; | 
					
						
							|  |  |  | const helper = new Helper(); | 
					
						
							|  |  |  | const messageManager = this; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let pageAgent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let failedToOverrideTimezone = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const applySetting = { | 
					
						
							|  |  |  |   geolocation: (geolocation) => { | 
					
						
							|  |  |  |     if (geolocation) { | 
					
						
							|  |  |  |       docShell.setGeolocationOverride({ | 
					
						
							|  |  |  |         coords: { | 
					
						
							|  |  |  |           latitude: geolocation.latitude, | 
					
						
							|  |  |  |           longitude: geolocation.longitude, | 
					
						
							|  |  |  |           accuracy: geolocation.accuracy, | 
					
						
							|  |  |  |           altitude: NaN, | 
					
						
							|  |  |  |           altitudeAccuracy: NaN, | 
					
						
							|  |  |  |           heading: NaN, | 
					
						
							|  |  |  |           speed: NaN, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         address: null, | 
					
						
							|  |  |  |         timestamp: Date.now() | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       docShell.setGeolocationOverride(null); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   onlineOverride: (onlineOverride) => { | 
					
						
							|  |  |  |     if (!onlineOverride) { | 
					
						
							|  |  |  |       docShell.onlineOverride = Ci.nsIDocShell.ONLINE_OVERRIDE_NONE; | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     docShell.onlineOverride = onlineOverride === 'online' ? | 
					
						
							|  |  |  |         Ci.nsIDocShell.ONLINE_OVERRIDE_ONLINE : Ci.nsIDocShell.ONLINE_OVERRIDE_OFFLINE; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bypassCSP: (bypassCSP) => { | 
					
						
							|  |  |  |     docShell.bypassCSPEnabled = bypassCSP; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   timezoneId: (timezoneId) => { | 
					
						
							|  |  |  |     failedToOverrideTimezone = !docShell.overrideTimezone(timezoneId); | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   locale: (locale) => { | 
					
						
							|  |  |  |     docShell.languageOverride = locale; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-14 08:06:34 -07:00
										 |  |  |   scrollbarsHidden: (hidden) => { | 
					
						
							|  |  |  |     frameTree.setScrollbarsHidden(hidden); | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-10 00:13:19 -05:00
										 |  |  |   colorScheme: (colorScheme) => { | 
					
						
							|  |  |  |     frameTree.setColorScheme(colorScheme); | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2021-05-18 21:23:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   reducedMotion: (reducedMotion) => { | 
					
						
							|  |  |  |     frameTree.setReducedMotion(reducedMotion); | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2021-06-08 16:00:15 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   forcedColors: (forcedColors) => { | 
					
						
							|  |  |  |     frameTree.setForcedColors(forcedColors); | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2021-04-10 00:13:19 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const channel = SimpleChannel.createForMessageManager('content::page', messageManager); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function initialize() { | 
					
						
							|  |  |  |   const response = sendSyncMessage('juggler:content-ready')[0]; | 
					
						
							|  |  |  |   // If we didn't get a response, then we don't want to do anything
 | 
					
						
							|  |  |  |   // as a part of this frame script.
 | 
					
						
							|  |  |  |   if (!response) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   const { | 
					
						
							| 
									
										
										
										
											2022-02-14 20:32:12 -08:00
										 |  |  |     initScripts = [], | 
					
						
							| 
									
										
										
										
											2021-04-10 00:13:19 -05:00
										 |  |  |     bindings = [], | 
					
						
							|  |  |  |     settings = {} | 
					
						
							|  |  |  |   } = response || {}; | 
					
						
							|  |  |  |   // Enforce focused state for all top level documents.
 | 
					
						
							|  |  |  |   docShell.overrideHasFocus = true; | 
					
						
							|  |  |  |   docShell.forceActiveState = true; | 
					
						
							|  |  |  |   frameTree = new FrameTree(docShell); | 
					
						
							|  |  |  |   for (const [name, value] of Object.entries(settings)) { | 
					
						
							|  |  |  |     if (value !== undefined) | 
					
						
							|  |  |  |       applySetting[name](value); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-05-11 16:34:10 +00:00
										 |  |  |   for (const { worldName, name, script } of bindings) | 
					
						
							|  |  |  |     frameTree.addBinding(worldName, name, script); | 
					
						
							| 
									
										
										
										
											2022-02-14 20:32:12 -08:00
										 |  |  |   frameTree.setInitScripts(initScripts); | 
					
						
							| 
									
										
										
										
											2021-04-10 00:13:19 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   pageAgent = new PageAgent(messageManager, channel, frameTree); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   channel.register('', { | 
					
						
							| 
									
										
										
										
											2022-02-14 20:32:12 -08:00
										 |  |  |     setInitScripts(scripts) { | 
					
						
							|  |  |  |       frameTree.setInitScripts(scripts); | 
					
						
							| 
									
										
										
										
											2021-04-10 00:13:19 -05:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-11 16:34:10 +00:00
										 |  |  |     addBinding({worldName, name, script}) { | 
					
						
							|  |  |  |       frameTree.addBinding(worldName, name, script); | 
					
						
							| 
									
										
										
										
											2021-04-10 00:13:19 -05:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     applyContextSetting({name, value}) { | 
					
						
							|  |  |  |       applySetting[name](value); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ensurePermissions() { | 
					
						
							|  |  |  |       // noop, just a rountrip.
 | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     hasFailedToOverrideTimezone() { | 
					
						
							|  |  |  |       return failedToOverrideTimezone; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async awaitViewportDimensions({width, height, deviceSizeIsPageSize}) { | 
					
						
							|  |  |  |       docShell.deviceSizeIsPageSize = deviceSizeIsPageSize; | 
					
						
							|  |  |  |       const win = docShell.domWindow; | 
					
						
							|  |  |  |       if (win.innerWidth === width && win.innerHeight === height) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       await new Promise(resolve => { | 
					
						
							|  |  |  |         const listener = helper.addEventListener(win, 'resize', () => { | 
					
						
							|  |  |  |           if (win.innerWidth === width && win.innerHeight === height) { | 
					
						
							|  |  |  |             helper.removeListeners([listener]); | 
					
						
							|  |  |  |             resolve(); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dispose() { | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const gListeners = [ | 
					
						
							|  |  |  |     helper.addEventListener(messageManager, 'unload', msg => { | 
					
						
							|  |  |  |       helper.removeListeners(gListeners); | 
					
						
							|  |  |  |       pageAgent.dispose(); | 
					
						
							|  |  |  |       frameTree.dispose(); | 
					
						
							|  |  |  |       channel.dispose(); | 
					
						
							|  |  |  |     }), | 
					
						
							|  |  |  |   ]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | initialize(); |