| 
									
										
										
										
											2020-06-02 16:51:13 -07: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/. */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  | const {Helper, EventWatcher} = ChromeUtils.import('chrome://juggler/content/Helper.js'); | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  | const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  | const {NetUtil} = ChromeUtils.import('resource://gre/modules/NetUtil.jsm'); | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  | const {NetworkObserver, PageNetwork} = ChromeUtils.import('chrome://juggler/content/NetworkObserver.js'); | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  | const {PageTarget} = ChromeUtils.import('chrome://juggler/content/TargetRegistry.js'); | 
					
						
							| 
									
										
										
										
											2022-07-06 15:02:48 -07:00
										 |  |  | const {setTimeout} = ChromeUtils.import('resource://gre/modules/Timer.jsm'); | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | const Cc = Components.classes; | 
					
						
							|  |  |  | const Ci = Components.interfaces; | 
					
						
							|  |  |  | const Cu = Components.utils; | 
					
						
							|  |  |  | const XUL_NS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'; | 
					
						
							|  |  |  | const helper = new Helper(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-01 11:29:33 -05:00
										 |  |  | function hashConsoleMessage(params) { | 
					
						
							|  |  |  |   return params.location.lineNumber + ':' + params.location.columnNumber + ':' + params.location.url; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  | class WorkerHandler { | 
					
						
							|  |  |  |   constructor(session, contentChannel, workerId) { | 
					
						
							|  |  |  |     this._session = session; | 
					
						
							| 
									
										
										
										
											2020-10-02 04:13:42 -07:00
										 |  |  |     this._contentWorker = contentChannel.connect(workerId); | 
					
						
							| 
									
										
										
										
											2021-04-01 11:29:33 -05:00
										 |  |  |     this._workerConsoleMessages = new Set(); | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     this._workerId = workerId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const emitWrappedProtocolEvent = eventName => { | 
					
						
							|  |  |  |       return params => { | 
					
						
							|  |  |  |         this._session.emitEvent('Page.dispatchMessageFromWorker', { | 
					
						
							|  |  |  |           workerId, | 
					
						
							|  |  |  |           message: JSON.stringify({method: eventName, params}), | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this._eventListeners = [ | 
					
						
							| 
									
										
										
										
											2020-10-02 04:13:42 -07:00
										 |  |  |       contentChannel.register(workerId, { | 
					
						
							| 
									
										
										
										
											2021-04-01 11:29:33 -05:00
										 |  |  |         runtimeConsole: (params) => { | 
					
						
							|  |  |  |           this._workerConsoleMessages.add(hashConsoleMessage(params)); | 
					
						
							|  |  |  |           emitWrappedProtocolEvent('Runtime.console')(params); | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |         runtimeExecutionContextCreated: emitWrappedProtocolEvent('Runtime.executionContextCreated'), | 
					
						
							|  |  |  |         runtimeExecutionContextDestroyed: emitWrappedProtocolEvent('Runtime.executionContextDestroyed'), | 
					
						
							|  |  |  |       }), | 
					
						
							|  |  |  |     ]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async sendMessage(message) { | 
					
						
							|  |  |  |     const [domain, method] = message.method.split('.'); | 
					
						
							|  |  |  |     if (domain !== 'Runtime') | 
					
						
							|  |  |  |       throw new Error('ERROR: can only dispatch to Runtime domain inside worker'); | 
					
						
							|  |  |  |     const result = await this._contentWorker.send(method, message.params); | 
					
						
							|  |  |  |     this._session.emitEvent('Page.dispatchMessageFromWorker', { | 
					
						
							|  |  |  |       workerId: this._workerId, | 
					
						
							|  |  |  |       message: JSON.stringify({result, id: message.id}), | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   dispose() { | 
					
						
							|  |  |  |     this._contentWorker.dispose(); | 
					
						
							|  |  |  |     helper.removeListeners(this._eventListeners); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PageHandler { | 
					
						
							|  |  |  |   constructor(target, session, contentChannel) { | 
					
						
							|  |  |  |     this._session = session; | 
					
						
							|  |  |  |     this._contentChannel = contentChannel; | 
					
						
							| 
									
										
										
										
											2020-10-02 04:13:42 -07:00
										 |  |  |     this._contentPage = contentChannel.connect('page'); | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     this._workers = new Map(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |     this._pageTarget = target; | 
					
						
							| 
									
										
										
										
											2021-08-10 14:43:21 -07:00
										 |  |  |     this._pageNetwork = PageNetwork.forPageTarget(target); | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     const emitProtocolEvent = eventName => { | 
					
						
							|  |  |  |       return (...args) => this._session.emitEvent(eventName, ...args); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |     this._isDragging = false; | 
					
						
							|  |  |  |     this._lastMousePosition = { x: 0, y: 0 }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |     this._reportedFrameIds = new Set(); | 
					
						
							|  |  |  |     this._networkEventsForUnreportedFrameIds = new Map(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-02 16:21:34 -08:00
										 |  |  |     // `Page.ready` protocol event is emitted whenever page has completed initialization, e.g.
 | 
					
						
							|  |  |  |     // finished all the transient navigations to the `about:blank`.
 | 
					
						
							|  |  |  |     //
 | 
					
						
							|  |  |  |     // We'd like to avoid reporting meaningful events before the `Page.ready` since they are likely
 | 
					
						
							|  |  |  |     // to be ignored by the protocol clients.
 | 
					
						
							|  |  |  |     this._isPageReady = false; | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 19:11:42 -07:00
										 |  |  |     if (this._pageTarget.videoRecordingInfo()) | 
					
						
							|  |  |  |       this._onVideoRecordingStarted(); | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |     this._pageEventSink = {}; | 
					
						
							|  |  |  |     helper.decorateAsEventEmitter(this._pageEventSink); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     this._eventListeners = [ | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  |       helper.on(this._pageTarget, PageTarget.Events.DialogOpened, this._onDialogOpened.bind(this)), | 
					
						
							|  |  |  |       helper.on(this._pageTarget, PageTarget.Events.DialogClosed, this._onDialogClosed.bind(this)), | 
					
						
							|  |  |  |       helper.on(this._pageTarget, PageTarget.Events.Crashed, () => { | 
					
						
							|  |  |  |         this._session.emitEvent('Page.crashed', {}); | 
					
						
							|  |  |  |       }), | 
					
						
							| 
									
										
										
										
											2021-05-06 19:11:42 -07:00
										 |  |  |       helper.on(this._pageTarget, PageTarget.Events.ScreencastStarted, this._onVideoRecordingStarted.bind(this)), | 
					
						
							|  |  |  |       helper.on(this._pageTarget, PageTarget.Events.ScreencastFrame, this._onScreencastFrame.bind(this)), | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  |       helper.on(this._pageNetwork, PageNetwork.Events.Request, this._handleNetworkEvent.bind(this, 'Network.requestWillBeSent')), | 
					
						
							|  |  |  |       helper.on(this._pageNetwork, PageNetwork.Events.Response, this._handleNetworkEvent.bind(this, 'Network.responseReceived')), | 
					
						
							|  |  |  |       helper.on(this._pageNetwork, PageNetwork.Events.RequestFinished, this._handleNetworkEvent.bind(this, 'Network.requestFinished')), | 
					
						
							|  |  |  |       helper.on(this._pageNetwork, PageNetwork.Events.RequestFailed, this._handleNetworkEvent.bind(this, 'Network.requestFailed')), | 
					
						
							| 
									
										
										
										
											2020-10-02 04:13:42 -07:00
										 |  |  |       contentChannel.register('page', { | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |         pageBindingCalled: emitProtocolEvent('Page.bindingCalled'), | 
					
						
							|  |  |  |         pageDispatchMessageFromWorker: emitProtocolEvent('Page.dispatchMessageFromWorker'), | 
					
						
							|  |  |  |         pageEventFired: emitProtocolEvent('Page.eventFired'), | 
					
						
							|  |  |  |         pageFileChooserOpened: emitProtocolEvent('Page.fileChooserOpened'), | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |         pageFrameAttached: this._onFrameAttached.bind(this), | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |         pageFrameDetached: emitProtocolEvent('Page.frameDetached'), | 
					
						
							|  |  |  |         pageLinkClicked: emitProtocolEvent('Page.linkClicked'), | 
					
						
							|  |  |  |         pageWillOpenNewWindowAsynchronously: emitProtocolEvent('Page.willOpenNewWindowAsynchronously'), | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |         pageNavigationAborted: emitProtocolEvent('Page.navigationAborted'), | 
					
						
							|  |  |  |         pageNavigationCommitted: emitProtocolEvent('Page.navigationCommitted'), | 
					
						
							|  |  |  |         pageNavigationStarted: emitProtocolEvent('Page.navigationStarted'), | 
					
						
							| 
									
										
										
										
											2020-11-13 14:56:27 -08:00
										 |  |  |         pageReady: this._onPageReady.bind(this), | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |         pageInputEvent: (event) => this._pageEventSink.emit(event.type, event), | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |         pageSameDocumentNavigation: emitProtocolEvent('Page.sameDocumentNavigation'), | 
					
						
							|  |  |  |         pageUncaughtError: emitProtocolEvent('Page.uncaughtError'), | 
					
						
							|  |  |  |         pageWorkerCreated: this._onWorkerCreated.bind(this), | 
					
						
							|  |  |  |         pageWorkerDestroyed: this._onWorkerDestroyed.bind(this), | 
					
						
							| 
									
										
										
										
											2021-04-01 11:29:33 -05:00
										 |  |  |         runtimeConsole: params => { | 
					
						
							|  |  |  |           const consoleMessageHash = hashConsoleMessage(params); | 
					
						
							| 
									
										
										
										
											2022-07-29 16:56:17 -07:00
										 |  |  |           for (const worker of this._workers.values()) { | 
					
						
							| 
									
										
										
										
											2021-04-01 11:29:33 -05:00
										 |  |  |             if (worker._workerConsoleMessages.has(consoleMessageHash)) { | 
					
						
							|  |  |  |               worker._workerConsoleMessages.delete(consoleMessageHash); | 
					
						
							|  |  |  |               return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2023-01-23 11:29:48 -08:00
										 |  |  |           this._session.emitEvent('Runtime.console', params); | 
					
						
							| 
									
										
										
										
											2021-04-01 11:29:33 -05:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |         runtimeExecutionContextCreated: emitProtocolEvent('Runtime.executionContextCreated'), | 
					
						
							|  |  |  |         runtimeExecutionContextDestroyed: emitProtocolEvent('Runtime.executionContextDestroyed'), | 
					
						
							| 
									
										
										
										
											2023-01-23 11:29:48 -08:00
										 |  |  |         runtimeExecutionContextsCleared: emitProtocolEvent('Runtime.executionContextsCleared'), | 
					
						
							| 
									
										
										
										
											2020-10-29 16:33:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         webSocketCreated: emitProtocolEvent('Page.webSocketCreated'), | 
					
						
							|  |  |  |         webSocketOpened: emitProtocolEvent('Page.webSocketOpened'), | 
					
						
							|  |  |  |         webSocketClosed: emitProtocolEvent('Page.webSocketClosed'), | 
					
						
							|  |  |  |         webSocketFrameReceived: emitProtocolEvent('Page.webSocketFrameReceived'), | 
					
						
							|  |  |  |         webSocketFrameSent: emitProtocolEvent('Page.webSocketFrameSent'), | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |       }), | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     ]; | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async dispose() { | 
					
						
							|  |  |  |     this._contentPage.dispose(); | 
					
						
							|  |  |  |     helper.removeListeners(this._eventListeners); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 19:11:42 -07:00
										 |  |  |   _onVideoRecordingStarted() { | 
					
						
							|  |  |  |     const info = this._pageTarget.videoRecordingInfo(); | 
					
						
							|  |  |  |     this._session.emitEvent('Page.videoRecordingStarted', { screencastId: info.sessionId, file: info.file }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-07 18:05:26 -07:00
										 |  |  |   _onScreencastFrame(params) { | 
					
						
							|  |  |  |     this._session.emitEvent('Page.screencastFrame', params); | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-02 16:21:34 -08:00
										 |  |  |   _onPageReady(event) { | 
					
						
							|  |  |  |     this._isPageReady = true; | 
					
						
							|  |  |  |     this._session.emitEvent('Page.ready'); | 
					
						
							|  |  |  |     for (const dialog of this._pageTarget.dialogs()) | 
					
						
							|  |  |  |       this._onDialogOpened(dialog); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  |   _onDialogOpened(dialog) { | 
					
						
							| 
									
										
										
										
											2020-11-02 16:21:34 -08:00
										 |  |  |     if (!this._isPageReady) | 
					
						
							|  |  |  |       return; | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  |     this._session.emitEvent('Page.dialogOpened', { | 
					
						
							|  |  |  |       dialogId: dialog.id(), | 
					
						
							|  |  |  |       type: dialog.type(), | 
					
						
							|  |  |  |       message: dialog.message(), | 
					
						
							|  |  |  |       defaultValue: dialog.defaultValue(), | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   _onDialogClosed(dialog) { | 
					
						
							| 
									
										
										
										
											2020-11-02 16:21:34 -08:00
										 |  |  |     if (!this._isPageReady) | 
					
						
							|  |  |  |       return; | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  |     this._session.emitEvent('Page.dialogClosed', { dialogId: dialog.id(), }); | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   _onWorkerCreated({workerId, frameId, url}) { | 
					
						
							|  |  |  |     const worker = new WorkerHandler(this._session, this._contentChannel, workerId); | 
					
						
							|  |  |  |     this._workers.set(workerId, worker); | 
					
						
							|  |  |  |     this._session.emitEvent('Page.workerCreated', {workerId, frameId, url}); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   _onWorkerDestroyed({workerId}) { | 
					
						
							|  |  |  |     const worker = this._workers.get(workerId); | 
					
						
							|  |  |  |     if (!worker) | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     this._workers.delete(workerId); | 
					
						
							|  |  |  |     worker.dispose(); | 
					
						
							|  |  |  |     this._session.emitEvent('Page.workerDestroyed', {workerId}); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   _handleNetworkEvent(protocolEventName, eventDetails, frameId) { | 
					
						
							|  |  |  |     if (!this._reportedFrameIds.has(frameId)) { | 
					
						
							|  |  |  |       let events = this._networkEventsForUnreportedFrameIds.get(frameId); | 
					
						
							|  |  |  |       if (!events) { | 
					
						
							|  |  |  |         events = []; | 
					
						
							|  |  |  |         this._networkEventsForUnreportedFrameIds.set(frameId, events); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       events.push({eventName: protocolEventName, eventDetails}); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       this._session.emitEvent(protocolEventName, eventDetails); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   _onFrameAttached({frameId, parentFrameId}) { | 
					
						
							|  |  |  |     this._session.emitEvent('Page.frameAttached', {frameId, parentFrameId}); | 
					
						
							|  |  |  |     this._reportedFrameIds.add(frameId); | 
					
						
							|  |  |  |     const events = this._networkEventsForUnreportedFrameIds.get(frameId) || []; | 
					
						
							|  |  |  |     this._networkEventsForUnreportedFrameIds.delete(frameId); | 
					
						
							|  |  |  |     for (const {eventName, eventDetails} of events) | 
					
						
							|  |  |  |       this._session.emitEvent(eventName, eventDetails); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async ['Page.close']({runBeforeUnload}) { | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     // Postpone target close to deliver response in session.
 | 
					
						
							|  |  |  |     Services.tm.dispatchToMainThread(() => { | 
					
						
							|  |  |  |       this._pageTarget.close(runBeforeUnload); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   async ['Page.setViewportSize']({viewportSize}) { | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     await this._pageTarget.setViewportSize(viewportSize === null ? undefined : viewportSize); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   async ['Runtime.evaluate'](options) { | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  |     return await this._contentPage.send('evaluate', options); | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async ['Runtime.callFunction'](options) { | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  |     return await this._contentPage.send('callFunction', options); | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async ['Runtime.getObjectProperties'](options) { | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  |     return await this._contentPage.send('getObjectProperties', options); | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async ['Runtime.disposeObject'](options) { | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  |     return await this._contentPage.send('disposeObject', options); | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async ['Network.getResponseBody']({requestId}) { | 
					
						
							|  |  |  |     return this._pageNetwork.getResponseBody(requestId); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async ['Network.setExtraHTTPHeaders']({headers}) { | 
					
						
							|  |  |  |     this._pageNetwork.setExtraHTTPHeaders(headers); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async ['Network.setRequestInterception']({enabled}) { | 
					
						
							|  |  |  |     if (enabled) | 
					
						
							|  |  |  |       this._pageNetwork.enableRequestInterception(); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       this._pageNetwork.disableRequestInterception(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 12:29:36 -07:00
										 |  |  |   async ['Network.resumeInterceptedRequest']({requestId, url, method, headers, postData}) { | 
					
						
							|  |  |  |     this._pageNetwork.resumeInterceptedRequest(requestId, url, method, headers, postData); | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async ['Network.abortInterceptedRequest']({requestId, errorCode}) { | 
					
						
							|  |  |  |     this._pageNetwork.abortInterceptedRequest(requestId, errorCode); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async ['Network.fulfillInterceptedRequest']({requestId, status, statusText, headers, base64body}) { | 
					
						
							|  |  |  |     this._pageNetwork.fulfillInterceptedRequest(requestId, status, statusText, headers, base64body); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async ['Accessibility.getFullAXTree'](params) { | 
					
						
							|  |  |  |     return await this._contentPage.send('getFullAXTree', params); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async ['Page.setFileInputFiles'](options) { | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     return await this._contentPage.send('setFileInputFiles', options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-08 16:00:15 -07:00
										 |  |  |   async ['Page.setEmulatedMedia']({colorScheme, type, reducedMotion, forcedColors}) { | 
					
						
							| 
									
										
										
										
											2021-03-02 18:52:19 -08:00
										 |  |  |     this._pageTarget.setColorScheme(colorScheme || null); | 
					
						
							| 
									
										
										
										
											2021-05-18 21:23:12 +02:00
										 |  |  |     this._pageTarget.setReducedMotion(reducedMotion || null); | 
					
						
							| 
									
										
										
										
											2021-06-08 16:00:15 -07:00
										 |  |  |     this._pageTarget.setForcedColors(forcedColors || null); | 
					
						
							| 
									
										
										
										
											2021-03-02 18:52:19 -08:00
										 |  |  |     this._pageTarget.setEmulatedMedia(type); | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   async ['Page.bringToFront'](options) { | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |     await this._pageTarget.activateAndRun(() => {}); | 
					
						
							| 
									
										
										
										
											2020-07-20 16:47:27 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   async ['Page.setCacheDisabled'](options) { | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     return await this._contentPage.send('setCacheDisabled', options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-23 11:29:48 -08:00
										 |  |  |   async ['Page.addBinding']({ worldName, name, script }) { | 
					
						
							|  |  |  |     return await this._pageTarget.addBinding(worldName, name, script); | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   async ['Page.adoptNode'](options) { | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     return await this._contentPage.send('adoptNode', options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 15:02:48 -07:00
										 |  |  |   async ['Page.screenshot']({ mimeType, clip, omitDeviceScaleFactor }) { | 
					
						
							|  |  |  |     const rect = new DOMRect(clip.x, clip.y, clip.width, clip.height); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const browsingContext = this._pageTarget.linkedBrowser().browsingContext; | 
					
						
							|  |  |  |     // `win.devicePixelRatio` returns a non-overriden value to priveleged code.
 | 
					
						
							|  |  |  |     // See https://bugzilla.mozilla.org/show_bug.cgi?id=1761032
 | 
					
						
							|  |  |  |     // See https://phabricator.services.mozilla.com/D141323
 | 
					
						
							|  |  |  |     const devicePixelRatio = browsingContext.overrideDPPX || this._pageTarget._window.devicePixelRatio; | 
					
						
							|  |  |  |     const scale = omitDeviceScaleFactor ? 1 : devicePixelRatio; | 
					
						
							|  |  |  |     const canvasWidth = rect.width * scale; | 
					
						
							|  |  |  |     const canvasHeight = rect.height * scale; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const MAX_CANVAS_DIMENSIONS = 32767; | 
					
						
							|  |  |  |     const MAX_CANVAS_AREA = 472907776; | 
					
						
							|  |  |  |     if (canvasWidth > MAX_CANVAS_DIMENSIONS || canvasHeight > MAX_CANVAS_DIMENSIONS) | 
					
						
							|  |  |  |       throw new Error('Cannot take screenshot larger than ' + MAX_CANVAS_DIMENSIONS); | 
					
						
							|  |  |  |     if (canvasWidth * canvasHeight > MAX_CANVAS_AREA) | 
					
						
							|  |  |  |       throw new Error('Cannot take screenshot with more than ' + MAX_CANVAS_AREA + ' pixels'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let snapshot; | 
					
						
							|  |  |  |     while (!snapshot) { | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         //TODO(fission): browsingContext will change in case of cross-group navigation.
 | 
					
						
							|  |  |  |         snapshot = await browsingContext.currentWindowGlobal.drawSnapshot( | 
					
						
							|  |  |  |           rect, | 
					
						
							|  |  |  |           scale, | 
					
						
							|  |  |  |           "rgb(255,255,255)" | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       } catch (e) { | 
					
						
							|  |  |  |         // The currentWindowGlobal.drawSnapshot might throw
 | 
					
						
							|  |  |  |         // NS_ERROR_LOSS_OF_SIGNIFICANT_DATA if called during navigation.
 | 
					
						
							|  |  |  |         // wait a little and re-try.
 | 
					
						
							|  |  |  |         await new Promise(x => setTimeout(x, 50)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const win = browsingContext.topChromeWindow.ownerGlobal; | 
					
						
							|  |  |  |     const canvas = win.document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas'); | 
					
						
							|  |  |  |     canvas.width = canvasWidth; | 
					
						
							|  |  |  |     canvas.height = canvasHeight; | 
					
						
							|  |  |  |     let ctx = canvas.getContext('2d'); | 
					
						
							|  |  |  |     ctx.drawImage(snapshot, 0, 0); | 
					
						
							|  |  |  |     snapshot.close(); | 
					
						
							|  |  |  |     const dataURL = canvas.toDataURL(mimeType); | 
					
						
							|  |  |  |     return { data: dataURL.substring(dataURL.indexOf(',') + 1) }; | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   async ['Page.getContentQuads'](options) { | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     return await this._contentPage.send('getContentQuads', options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |   async ['Page.navigate']({frameId, url, referer}) { | 
					
						
							|  |  |  |     const browsingContext = this._pageTarget.frameIdToBrowsingContext(frameId); | 
					
						
							|  |  |  |     let sameDocumentNavigation = false; | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       const uri = NetUtil.newURI(url); | 
					
						
							|  |  |  |       // This is the same check that verifes browser-side if this is the same-document navigation.
 | 
					
						
							|  |  |  |       // See CanonicalBrowsingContext::SupportsLoadingInParent.
 | 
					
						
							|  |  |  |       sameDocumentNavigation = browsingContext.currentURI && uri.hasRef && uri.equalsExceptRef(browsingContext.currentURI); | 
					
						
							|  |  |  |     } catch (e) { | 
					
						
							|  |  |  |       throw new Error(`Invalid url: "${url}"`); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     let referrerURI = null; | 
					
						
							|  |  |  |     let referrerInfo = null; | 
					
						
							|  |  |  |     if (referer) { | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         referrerURI = NetUtil.newURI(referer); | 
					
						
							|  |  |  |         const ReferrerInfo = Components.Constructor( | 
					
						
							|  |  |  |           '@mozilla.org/referrer-info;1', | 
					
						
							|  |  |  |           'nsIReferrerInfo', | 
					
						
							|  |  |  |           'init' | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |         referrerInfo = new ReferrerInfo(Ci.nsIHttpChannel.REFERRER_POLICY_UNSET, true, referrerURI); | 
					
						
							|  |  |  |       } catch (e) { | 
					
						
							|  |  |  |         throw new Error(`Invalid referer: "${referer}"`); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let navigationId; | 
					
						
							|  |  |  |     const unsubscribe = helper.addObserver((browsingContext, topic, loadIdentifier) => { | 
					
						
							|  |  |  |       navigationId = helper.toProtocolNavigationId(loadIdentifier); | 
					
						
							|  |  |  |     }, 'juggler-navigation-started-browser'); | 
					
						
							|  |  |  |     browsingContext.loadURI(url, { | 
					
						
							|  |  |  |       triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), | 
					
						
							|  |  |  |       loadFlags: Ci.nsIWebNavigation.LOAD_FLAGS_IS_LINK, | 
					
						
							|  |  |  |       referrerInfo, | 
					
						
							|  |  |  |       // postData: null,
 | 
					
						
							|  |  |  |       // headers: null,
 | 
					
						
							|  |  |  |       // Fake user activation.
 | 
					
						
							|  |  |  |       hasValidUserGestureActivation: true, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     unsubscribe(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       navigationId: sameDocumentNavigation ? null : navigationId, | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-23 11:29:48 -08:00
										 |  |  |   async ['Page.goBack']({}) { | 
					
						
							|  |  |  |     const browsingContext = this._pageTarget.linkedBrowser().browsingContext; | 
					
						
							|  |  |  |     if (!browsingContext.embedderElement?.canGoBack) | 
					
						
							|  |  |  |       return { success: false }; | 
					
						
							|  |  |  |     browsingContext.goBack(); | 
					
						
							|  |  |  |     return { success: true }; | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-23 11:29:48 -08:00
										 |  |  |   async ['Page.goForward']({}) { | 
					
						
							|  |  |  |     const browsingContext = this._pageTarget.linkedBrowser().browsingContext; | 
					
						
							|  |  |  |     if (!browsingContext.embedderElement?.canGoForward) | 
					
						
							|  |  |  |       return { success: false }; | 
					
						
							|  |  |  |     browsingContext.goForward(); | 
					
						
							|  |  |  |     return { success: true }; | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 21:28:08 +00:00
										 |  |  |   async ['Page.reload']() { | 
					
						
							|  |  |  |     await this._pageTarget.activateAndRun(() => { | 
					
						
							|  |  |  |       const doc = this._pageTarget._tab.linkedBrowser.ownerDocument; | 
					
						
							|  |  |  |       doc.getElementById('Browser:Reload').doCommand(); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   async ['Page.describeNode'](options) { | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     return await this._contentPage.send('describeNode', options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   async ['Page.scrollIntoViewIfNeeded'](options) { | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     return await this._contentPage.send('scrollIntoViewIfNeeded', options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-14 20:32:12 -08:00
										 |  |  |   async ['Page.setInitScripts']({ scripts }) { | 
					
						
							|  |  |  |     return await this._pageTarget.setInitScripts(scripts); | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |   async ['Page.dispatchKeyEvent']({type, keyCode, code, key, repeat, location, text}) { | 
					
						
							|  |  |  |     // key events don't fire if we are dragging.
 | 
					
						
							|  |  |  |     if (this._isDragging) { | 
					
						
							|  |  |  |       if (type === 'keydown' && key === 'Escape') { | 
					
						
							|  |  |  |         await this._contentPage.send('dispatchDragEvent', { | 
					
						
							|  |  |  |           type: 'dragover', | 
					
						
							|  |  |  |           x: this._lastMousePosition.x, | 
					
						
							|  |  |  |           y: this._lastMousePosition.y, | 
					
						
							|  |  |  |           modifiers: 0 | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         await this._contentPage.send('dispatchDragEvent', {type: 'dragend'}); | 
					
						
							|  |  |  |         this._isDragging = false; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return await this._contentPage.send('dispatchKeyEvent', {type, keyCode, code, key, repeat, location, text}); | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   async ['Page.dispatchTouchEvent'](options) { | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     return await this._contentPage.send('dispatchTouchEvent', options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-13 12:24:11 -07:00
										 |  |  |   async ['Page.dispatchTapEvent'](options) { | 
					
						
							|  |  |  |     return await this._contentPage.send('dispatchTapEvent', options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |   async ['Page.dispatchMouseEvent']({type, x, y, button, clickCount, modifiers, buttons}) { | 
					
						
							| 
									
										
										
										
											2023-04-24 21:28:08 +00:00
										 |  |  |     this._pageTarget.ensureContextMenuClosed(); | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 21:28:08 +00:00
										 |  |  |     const boundingBox = this._pageTarget._linkedBrowser.getBoundingClientRect(); | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |     const win = this._pageTarget._window; | 
					
						
							|  |  |  |     const sendEvents = async (types) => { | 
					
						
							| 
									
										
										
										
											2023-04-24 21:28:08 +00:00
										 |  |  |       for (const type of types) { | 
					
						
							|  |  |  |         // This dispatches to the renderer synchronously.
 | 
					
						
							|  |  |  |         win.windowUtils.sendMouseEvent( | 
					
						
							|  |  |  |           type, | 
					
						
							|  |  |  |           x + boundingBox.left, | 
					
						
							|  |  |  |           y + boundingBox.top, | 
					
						
							|  |  |  |           button, | 
					
						
							|  |  |  |           clickCount, | 
					
						
							|  |  |  |           modifiers, | 
					
						
							|  |  |  |           false /* aIgnoreRootScrollFrame */, | 
					
						
							|  |  |  |           undefined /* pressure */, | 
					
						
							|  |  |  |           undefined /* inputSource */, | 
					
						
							|  |  |  |           true /* isDOMEventSynthesized */, | 
					
						
							|  |  |  |           undefined /* isWidgetEventSynthesized */, | 
					
						
							|  |  |  |           buttons); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 21:28:08 +00:00
										 |  |  |     // We must switch to proper tab in the tabbed browser so that
 | 
					
						
							|  |  |  |     // 1. Event is dispatched to a proper renderer.
 | 
					
						
							|  |  |  |     // 2. We receive an ack from the renderer for the dispatched event.
 | 
					
						
							|  |  |  |     await this._pageTarget.activateAndRun(async () => { | 
					
						
							|  |  |  |       if (type === 'mousedown') { | 
					
						
							|  |  |  |         if (this._isDragging) | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const eventNames = button === 2 ? ['mousedown', 'contextmenu'] : ['mousedown']; | 
					
						
							|  |  |  |         const watcher = new EventWatcher(this._pageEventSink, eventNames); | 
					
						
							|  |  |  |         await sendEvents(eventNames); | 
					
						
							|  |  |  |         await watcher.ensureEventsAndDispose(eventNames); | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 21:28:08 +00:00
										 |  |  |       if (type === 'mousemove') { | 
					
						
							|  |  |  |         this._lastMousePosition = { x, y }; | 
					
						
							|  |  |  |         if (this._isDragging) { | 
					
						
							|  |  |  |           const watcher = new EventWatcher(this._pageEventSink, ['dragover']); | 
					
						
							|  |  |  |           await this._contentPage.send('dispatchDragEvent', {type:'dragover', x, y, modifiers}); | 
					
						
							|  |  |  |           await watcher.ensureEventsAndDispose(['dragover']); | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const watcher = new EventWatcher(this._pageEventSink, ['dragstart', 'mousemove', 'juggler-drag-finalized']); | 
					
						
							|  |  |  |         await sendEvents(['mousemove']); | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 21:28:08 +00:00
										 |  |  |         // The order of events after 'mousemove' is sent:
 | 
					
						
							|  |  |  |         // 1. [dragstart] - might or might NOT be emitted
 | 
					
						
							|  |  |  |         // 2. [mousemove] - always emitted
 | 
					
						
							|  |  |  |         // 3. [juggler-drag-finalized] - only emitted if dragstart was emitted.
 | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 21:28:08 +00:00
										 |  |  |         await watcher.ensureEvent('mousemove'); | 
					
						
							|  |  |  |         if (watcher.hasEvent('dragstart')) { | 
					
						
							|  |  |  |           const eventObject = await watcher.ensureEvent('juggler-drag-finalized'); | 
					
						
							|  |  |  |           this._isDragging = eventObject.dragSessionStarted; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         watcher.dispose(); | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 21:28:08 +00:00
										 |  |  |       if (type === 'mouseup') { | 
					
						
							|  |  |  |         if (this._isDragging) { | 
					
						
							| 
									
										
										
										
											2023-05-18 00:50:43 +00:00
										 |  |  |           const watcher = new EventWatcher(this._pageEventSink, ['dragover']); | 
					
						
							| 
									
										
										
										
											2023-04-24 21:28:08 +00:00
										 |  |  |           await this._contentPage.send('dispatchDragEvent', {type: 'dragover', x, y, modifiers}); | 
					
						
							|  |  |  |           await this._contentPage.send('dispatchDragEvent', {type: 'drop', x, y, modifiers}); | 
					
						
							|  |  |  |           await this._contentPage.send('dispatchDragEvent', {type: 'dragend', x, y, modifiers}); | 
					
						
							| 
									
										
										
										
											2023-05-18 00:50:43 +00:00
										 |  |  |           // NOTE:
 | 
					
						
							|  |  |  |           // - 'drop' event might not be dispatched at all, depending on dropAction.
 | 
					
						
							|  |  |  |           // - 'dragend' event might not be dispatched at all, if the source element was removed
 | 
					
						
							|  |  |  |           //   during drag. However, it'll be dispatched synchronously in the renderer.
 | 
					
						
							|  |  |  |           await watcher.ensureEventsAndDispose(['dragover']); | 
					
						
							| 
									
										
										
										
											2023-04-24 21:28:08 +00:00
										 |  |  |           this._isDragging = false; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           const watcher = new EventWatcher(this._pageEventSink, ['mouseup']); | 
					
						
							|  |  |  |           await sendEvents(['mouseup']); | 
					
						
							|  |  |  |           await watcher.ensureEventsAndDispose(['mouseup']); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2023-04-24 21:28:08 +00:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 08:20:01 -07:00
										 |  |  |   async ['Page.dispatchWheelEvent']({x, y, button, deltaX, deltaY, deltaZ, modifiers }) { | 
					
						
							| 
									
										
										
										
											2023-04-24 21:28:08 +00:00
										 |  |  |     this._pageTarget.ensureContextMenuClosed(); | 
					
						
							| 
									
										
										
										
											2022-07-05 08:20:01 -07:00
										 |  |  |     const boundingBox = this._pageTarget._linkedBrowser.getBoundingClientRect(); | 
					
						
							|  |  |  |     x += boundingBox.left; | 
					
						
							|  |  |  |     y += boundingBox.top; | 
					
						
							|  |  |  |     const deltaMode = 0; // WheelEvent.DOM_DELTA_PIXEL
 | 
					
						
							|  |  |  |     const lineOrPageDeltaX = deltaX > 0 ? Math.floor(deltaX) : Math.ceil(deltaX); | 
					
						
							|  |  |  |     const lineOrPageDeltaY = deltaY > 0 ? Math.floor(deltaY) : Math.ceil(deltaY); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-21 01:23:12 +00:00
										 |  |  |     await this._pageTarget.activateAndRun(() => { | 
					
						
							|  |  |  |       const win = this._pageTarget._window; | 
					
						
							|  |  |  |       win.windowUtils.sendWheelEvent( | 
					
						
							|  |  |  |         x, | 
					
						
							|  |  |  |         y, | 
					
						
							|  |  |  |         deltaX, | 
					
						
							|  |  |  |         deltaY, | 
					
						
							|  |  |  |         deltaZ, | 
					
						
							|  |  |  |         deltaMode, | 
					
						
							|  |  |  |         modifiers, | 
					
						
							|  |  |  |         lineOrPageDeltaX, | 
					
						
							|  |  |  |         lineOrPageDeltaY, | 
					
						
							|  |  |  |         0 /* options */); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-08-25 11:27:12 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   async ['Page.insertText'](options) { | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     return await this._contentPage.send('insertText', options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   async ['Page.crash'](options) { | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     return await this._contentPage.send('crash', options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   async ['Page.handleDialog']({dialogId, accept, promptText}) { | 
					
						
							| 
									
										
										
										
											2020-10-06 01:53:25 -07:00
										 |  |  |     const dialog = this._pageTarget.dialog(dialogId); | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     if (!dialog) | 
					
						
							|  |  |  |       throw new Error('Failed to find dialog with id = ' + dialogId); | 
					
						
							|  |  |  |     if (accept) | 
					
						
							|  |  |  |       dialog.accept(promptText); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       dialog.dismiss(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-23 11:29:48 -08:00
										 |  |  |   async ['Page.setInterceptFileChooserDialog']({ enabled }) { | 
					
						
							|  |  |  |     return await this._pageTarget.setInterceptFileChooserDialog(enabled); | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 19:11:42 -07:00
										 |  |  |   async ['Page.startScreencast'](options) { | 
					
						
							|  |  |  |     return await this._pageTarget.startScreencast(options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async ['Page.screencastFrameAck'](options) { | 
					
						
							|  |  |  |     await this._pageTarget.screencastFrameAck(options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async ['Page.stopScreencast'](options) { | 
					
						
							|  |  |  |     await this._pageTarget.stopScreencast(options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-06 00:15:24 -07:00
										 |  |  |   async ['Page.sendMessageToWorker']({workerId, message}) { | 
					
						
							| 
									
										
										
										
											2020-06-02 16:51:13 -07:00
										 |  |  |     const worker = this._workers.get(workerId); | 
					
						
							|  |  |  |     if (!worker) | 
					
						
							|  |  |  |       throw new Error('ERROR: cannot find worker with id ' + workerId); | 
					
						
							|  |  |  |     return await worker.sendMessage(JSON.parse(message)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var EXPORTED_SYMBOLS = ['PageHandler']; | 
					
						
							|  |  |  | this.PageHandler = PageHandler; |