browser(firefox): make Runtime a global object shared between sessions (#1458)
Review URL: 88261ea669
Key points:
- `Runtime` is now shared between protocol sessions
- `RuntimeAgent` does not exist any more and is merged into `PageAgent` for Page
- `RuntimeAgent` is re-implemented in a worker
This commit is contained in:
parent
c0c9b7f137
commit
c28c5a6455
|
|
@ -1 +1 @@
|
|||
1051
|
||||
1052
|
||||
|
|
|
|||
|
|
@ -2364,10 +2364,10 @@ index 0000000000000000000000000000000000000000..268fbc361d8053182bb6c27f626e853d
|
|||
+
|
||||
diff --git a/juggler/content/FrameTree.js b/juggler/content/FrameTree.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc45b0de67
|
||||
index 0000000000000000000000000000000000000000..5f2b6b5de4faa91e32c14e53064b9484648ef9eb
|
||||
--- /dev/null
|
||||
+++ b/juggler/content/FrameTree.js
|
||||
@@ -0,0 +1,411 @@
|
||||
@@ -0,0 +1,452 @@
|
||||
+"use strict";
|
||||
+const Ci = Components.interfaces;
|
||||
+const Cr = Components.results;
|
||||
|
|
@ -2376,6 +2376,7 @@ index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc
|
|||
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||
+const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');
|
||||
+const {EventEmitter} = ChromeUtils.import('resource://gre/modules/EventEmitter.jsm');
|
||||
+const {Runtime} = ChromeUtils.import('chrome://juggler/content/content/Runtime.js');
|
||||
+
|
||||
+const helper = new Helper();
|
||||
+
|
||||
|
|
@ -2387,8 +2388,10 @@ index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc
|
|||
+ if (!this._browsingContextGroup.__jugglerFrameTrees)
|
||||
+ this._browsingContextGroup.__jugglerFrameTrees = new Set();
|
||||
+ this._browsingContextGroup.__jugglerFrameTrees.add(this);
|
||||
+ this._scriptsToEvaluateOnNewDocument = new Map();
|
||||
+
|
||||
+ this._bindings = new Map();
|
||||
+ this._runtime = new Runtime(false /* isWorker */);
|
||||
+ this._workers = new Map();
|
||||
+ this._docShellToFrame = new Map();
|
||||
+ this._frameIdToFrame = new Map();
|
||||
|
|
@ -2401,7 +2404,6 @@ index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc
|
|||
+ Ci.nsIWebProgressListener2,
|
||||
+ Ci.nsISupportsWeakReference,
|
||||
+ ]);
|
||||
+ this._scriptsToEvaluateOnNewDocument = [];
|
||||
+
|
||||
+ this._wdm = Cc["@mozilla.org/dom/workers/workerdebuggermanager;1"].createInstance(Ci.nsIWorkerDebuggerManager);
|
||||
+ this._wdmListener = {
|
||||
|
|
@ -2413,13 +2415,12 @@ index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc
|
|||
+ for (const workerDebugger of this._wdm.getWorkerDebuggerEnumerator())
|
||||
+ this._onWorkerCreated(workerDebugger);
|
||||
+
|
||||
+
|
||||
+ const flags = Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT |
|
||||
+ Ci.nsIWebProgress.NOTIFY_FRAME_LOCATION;
|
||||
+ this._eventListeners = [
|
||||
+ helper.addObserver(this._onDOMWindowCreated.bind(this), 'content-document-global-created'),
|
||||
+ helper.addObserver(subject => this._onDocShellCreated(subject.QueryInterface(Ci.nsIDocShell)), 'webnavigation-create'),
|
||||
+ helper.addObserver(subject => this._onDocShellDestroyed(subject.QueryInterface(Ci.nsIDocShell)), 'webnavigation-destroy'),
|
||||
+ helper.addObserver(window => this._onDOMWindowCreated(window), 'content-document-global-created'),
|
||||
+ helper.addProgressListener(webProgress, this, flags),
|
||||
+ ];
|
||||
+ }
|
||||
|
|
@ -2428,6 +2429,10 @@ index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc
|
|||
+ return [...this._workers.values()];
|
||||
+ }
|
||||
+
|
||||
+ runtime() {
|
||||
+ return this._runtime;
|
||||
+ }
|
||||
+
|
||||
+ _frameForWorker(workerDebugger) {
|
||||
+ if (workerDebugger.type !== Ci.nsIWorkerDebugger.TYPE_DEDICATED)
|
||||
+ return null;
|
||||
|
|
@ -2435,6 +2440,14 @@ index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc
|
|||
+ return this._docShellToFrame.get(docShell) || null;
|
||||
+ }
|
||||
+
|
||||
+ _onDOMWindowCreated(window) {
|
||||
+ const frame = this._docShellToFrame.get(window.docShell) || null;
|
||||
+ if (!frame)
|
||||
+ return;
|
||||
+ frame._onGlobalObjectCleared();
|
||||
+ this.emit(FrameTree.Events.GlobalObjectCreated, { frame, window });
|
||||
+ }
|
||||
+
|
||||
+ _onWorkerCreated(workerDebugger) {
|
||||
+ // Note: we do not interoperate with firefox devtools.
|
||||
+ if (workerDebugger.isInitialized)
|
||||
|
|
@ -2476,30 +2489,19 @@ index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc
|
|||
+ }
|
||||
+
|
||||
+ addScriptToEvaluateOnNewDocument(script) {
|
||||
+ this._scriptsToEvaluateOnNewDocument.push(script);
|
||||
+ const scriptId = helper.generateId();
|
||||
+ this._scriptsToEvaluateOnNewDocument.set(scriptId, script);
|
||||
+ return scriptId;
|
||||
+ }
|
||||
+
|
||||
+ scriptsToEvaluateOnNewDocument() {
|
||||
+ return this._scriptsToEvaluateOnNewDocument;
|
||||
+ removeScriptToEvaluateOnNewDocument(scriptId) {
|
||||
+ this._scriptsToEvaluateOnNewDocument.delete(scriptId);
|
||||
+ }
|
||||
+
|
||||
+ addBinding(name, script) {
|
||||
+ this._bindings.set(name, script);
|
||||
+ for (const frame of this.frames())
|
||||
+ this._addBindingToFrame(frame, name, script);
|
||||
+ }
|
||||
+
|
||||
+ _addBindingToFrame(frame, name, script) {
|
||||
+ Cu.exportFunction((...args) => {
|
||||
+ this.emit(FrameTree.Events.BindingCalled, {
|
||||
+ frame,
|
||||
+ name,
|
||||
+ payload: args[0]
|
||||
+ });
|
||||
+ }, frame.domWindow(), {
|
||||
+ defineAs: name,
|
||||
+ });
|
||||
+ frame.domWindow().eval(script);
|
||||
+ frame._addBinding(name, script);
|
||||
+ }
|
||||
+
|
||||
+ frameForDocShell(docShell) {
|
||||
|
|
@ -2529,6 +2531,7 @@ index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc
|
|||
+ dispose() {
|
||||
+ this._browsingContextGroup.__jugglerFrameTrees.delete(this);
|
||||
+ this._wdm.removeListener(this._wdmListener);
|
||||
+ this._runtime.dispose();
|
||||
+ helper.removeListeners(this._eventListeners);
|
||||
+ }
|
||||
+
|
||||
|
|
@ -2606,12 +2609,14 @@ index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc
|
|||
+
|
||||
+ _createFrame(docShell) {
|
||||
+ const parentFrame = this._docShellToFrame.get(docShell.parent) || null;
|
||||
+ const frame = new Frame(this, docShell, parentFrame);
|
||||
+ const frame = new Frame(this, this._runtime, docShell, parentFrame);
|
||||
+ this._docShellToFrame.set(docShell, frame);
|
||||
+ this._frameIdToFrame.set(frame.id(), frame);
|
||||
+ for (const [name, script] of this._bindings)
|
||||
+ this._addBindingToFrame(frame, name, script);
|
||||
+ this.emit(FrameTree.Events.FrameAttached, frame);
|
||||
+ // Create execution context **after** reporting frame.
|
||||
+ // This is our protocol contract.
|
||||
+ if (frame.domWindow())
|
||||
+ frame._onGlobalObjectCleared();
|
||||
+ return frame;
|
||||
+ }
|
||||
+
|
||||
|
|
@ -2621,16 +2626,6 @@ index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc
|
|||
+ this._detachFrame(frame);
|
||||
+ }
|
||||
+
|
||||
+ _onDOMWindowCreated(window) {
|
||||
+ const docShell = window.docShell;
|
||||
+ const frame = this.frameForDocShell(docShell);
|
||||
+ if (!frame)
|
||||
+ return;
|
||||
+ for (const [name, script] of this._bindings)
|
||||
+ this._addBindingToFrame(frame, name, script);
|
||||
+ this.emit(FrameTree.Events.GlobalObjectCreated, { frame, window });
|
||||
+ }
|
||||
+
|
||||
+ _detachFrame(frame) {
|
||||
+ // Detach all children first
|
||||
+ for (const subframe of frame._children)
|
||||
|
|
@ -2640,6 +2635,7 @@ index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc
|
|||
+ if (frame._parentFrame)
|
||||
+ frame._parentFrame._children.delete(frame);
|
||||
+ frame._parentFrame = null;
|
||||
+ frame.dispose();
|
||||
+ this.emit(FrameTree.Events.FrameDetached, frame);
|
||||
+ }
|
||||
+}
|
||||
|
|
@ -2659,8 +2655,9 @@ index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc
|
|||
+};
|
||||
+
|
||||
+class Frame {
|
||||
+ constructor(frameTree, docShell, parentFrame) {
|
||||
+ constructor(frameTree, runtime, docShell, parentFrame) {
|
||||
+ this._frameTree = frameTree;
|
||||
+ this._runtime = runtime;
|
||||
+ this._docShell = docShell;
|
||||
+ this._children = new Set();
|
||||
+ this._frameId = helper.generateId();
|
||||
|
|
@ -2678,6 +2675,50 @@ index 0000000000000000000000000000000000000000..679b5851c427064c636bd1f7793358cc
|
|||
+ this._pendingNavigationURL = null;
|
||||
+
|
||||
+ this._textInputProcessor = null;
|
||||
+ this._executionContext = null;
|
||||
+ }
|
||||
+
|
||||
+ dispose() {
|
||||
+ if (this._executionContext)
|
||||
+ this._runtime.destroyExecutionContext(this._executionContext);
|
||||
+ this._executionContext = null;
|
||||
+ }
|
||||
+
|
||||
+ _addBinding(name, script) {
|
||||
+ Cu.exportFunction((...args) => {
|
||||
+ this._frameTree.emit(FrameTree.Events.BindingCalled, {
|
||||
+ frame: this,
|
||||
+ name,
|
||||
+ payload: args[0]
|
||||
+ });
|
||||
+ }, this.domWindow(), {
|
||||
+ defineAs: name,
|
||||
+ });
|
||||
+ this.domWindow().eval(script);
|
||||
+ }
|
||||
+
|
||||
+ _onGlobalObjectCleared() {
|
||||
+ if (this._executionContext)
|
||||
+ this._runtime.destroyExecutionContext(this._executionContext);
|
||||
+ this._executionContext = this._runtime.createExecutionContext(this.domWindow(), this.domWindow(), {
|
||||
+ frameId: this._frameId,
|
||||
+ name: '',
|
||||
+ });
|
||||
+ for (const [name, script] of this._frameTree._bindings)
|
||||
+ this._addBinding(name, script);
|
||||
+ for (const script of this._frameTree._scriptsToEvaluateOnNewDocument.values()) {
|
||||
+ try {
|
||||
+ const result = this._executionContext.evaluateScript(script);
|
||||
+ if (result && result.objectId)
|
||||
+ this._executionContext.disposeObject(result.objectId);
|
||||
+ } catch (e) {
|
||||
+ dump(`ERROR: ${e.message}\n${e.stack}\n`);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ executionContext() {
|
||||
+ return this._executionContext;
|
||||
+ }
|
||||
+
|
||||
+ textInputProcessor() {
|
||||
|
|
@ -2849,10 +2890,10 @@ index 0000000000000000000000000000000000000000..be70ea364f9534bb3b344f64970366c3
|
|||
+
|
||||
diff --git a/juggler/content/PageAgent.js b/juggler/content/PageAgent.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..6a001d9f51c819edd3981e090172ac87d6f85840
|
||||
index 0000000000000000000000000000000000000000..8b4202213ad6f663a8e161748ebd23c4c5deddec
|
||||
--- /dev/null
|
||||
+++ b/juggler/content/PageAgent.js
|
||||
@@ -0,0 +1,921 @@
|
||||
@@ -0,0 +1,935 @@
|
||||
+"use strict";
|
||||
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
+const Ci = Components.interfaces;
|
||||
|
|
@ -2878,7 +2919,6 @@ index 0000000000000000000000000000000000000000..6a001d9f51c819edd3981e090172ac87
|
|||
+ runtimeConsole: emit('runtimeConsole'),
|
||||
+ runtimeExecutionContextCreated: emit('runtimeExecutionContextCreated'),
|
||||
+ runtimeExecutionContextDestroyed: emit('runtimeExecutionContextDestroyed'),
|
||||
+ workerConsoleMessage: (hash) => pageAgent._runtime.filterConsoleMessage(hash),
|
||||
+ }),
|
||||
+ browserChannel.register(sessionId + worker.id(), {
|
||||
+ evaluate: (options) => this._workerRuntime.send('evaluate', options),
|
||||
|
|
@ -2899,37 +2939,21 @@ index 0000000000000000000000000000000000000000..6a001d9f51c819edd3981e090172ac87
|
|||
+}
|
||||
+
|
||||
+class FrameData {
|
||||
+ constructor(agent, frame) {
|
||||
+ constructor(agent, runtime, frame) {
|
||||
+ this._agent = agent;
|
||||
+ this._runtime = runtime;
|
||||
+ this._frame = frame;
|
||||
+ this._isolatedWorlds = new Map();
|
||||
+ this.reset();
|
||||
+ }
|
||||
+
|
||||
+ reset() {
|
||||
+ if (this.mainContext)
|
||||
+ this._agent._runtime.destroyExecutionContext(this.mainContext);
|
||||
+ for (const world of this._isolatedWorlds.values())
|
||||
+ this._agent._runtime.destroyExecutionContext(world);
|
||||
+ this._runtime.destroyExecutionContext(world);
|
||||
+ this._isolatedWorlds.clear();
|
||||
+
|
||||
+ this.mainContext = this._agent._runtime.createExecutionContext(this._frame.domWindow(), this._frame.domWindow(), {
|
||||
+ frameId: this._frame.id(),
|
||||
+ name: '',
|
||||
+ });
|
||||
+
|
||||
+ for (const script of this._agent._frameTree.scriptsToEvaluateOnNewDocument()) {
|
||||
+ // TODO: this should actually be handled in FrameTree, but first we have to move
|
||||
+ // execution contexts there.
|
||||
+ try {
|
||||
+ let result = this.mainContext.evaluateScript(script);
|
||||
+ if (result && result.objectId)
|
||||
+ this.mainContext.disposeObject(result.objectId);
|
||||
+ } catch (e) {
|
||||
+ }
|
||||
+ }
|
||||
+ for (const {script, worldName} of this._agent._scriptsToEvaluateOnNewDocument.values()) {
|
||||
+ const context = worldName ? this.createIsolatedWorld(worldName) : this.mainContext;
|
||||
+ for (const {script, worldName} of this._agent._isolatedWorlds.values()) {
|
||||
+ const context = worldName ? this.createIsolatedWorld(worldName) : this._frame.executionContext();
|
||||
+ try {
|
||||
+ let result = context.evaluateScript(script);
|
||||
+ if (result && result.objectId)
|
||||
|
|
@ -2947,7 +2971,7 @@ index 0000000000000000000000000000000000000000..6a001d9f51c819edd3981e090172ac87
|
|||
+ wantExportHelpers: false,
|
||||
+ wantXrays: true,
|
||||
+ });
|
||||
+ const world = this._agent._runtime.createExecutionContext(this._frame.domWindow(), sandbox, {
|
||||
+ const world = this._runtime.createExecutionContext(this._frame.domWindow(), sandbox, {
|
||||
+ frameId: this._frame.id(),
|
||||
+ name,
|
||||
+ });
|
||||
|
|
@ -2956,35 +2980,37 @@ index 0000000000000000000000000000000000000000..6a001d9f51c819edd3981e090172ac87
|
|||
+ }
|
||||
+
|
||||
+ unsafeObject(objectId) {
|
||||
+ if (this.mainContext) {
|
||||
+ const result = this.mainContext.unsafeObject(objectId);
|
||||
+ if (result)
|
||||
+ return result.object;
|
||||
+ }
|
||||
+ for (const world of this._isolatedWorlds.values()) {
|
||||
+ const result = world.unsafeObject(objectId);
|
||||
+ const contexts = [this._frame.executionContext(), ...this._isolatedWorlds.values()];
|
||||
+ for (const context of contexts) {
|
||||
+ const result = context.unsafeObject(objectId);
|
||||
+ if (result)
|
||||
+ return result.object;
|
||||
+ }
|
||||
+ throw new Error('Cannot find object with id = ' + objectId);
|
||||
+ }
|
||||
+
|
||||
+ dispose() {}
|
||||
+ dispose() {
|
||||
+ for (const world of this._isolatedWorlds.values())
|
||||
+ this._runtime.destroyExecutionContext(world);
|
||||
+ this._isolatedWorlds.clear();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+class PageAgent {
|
||||
+ constructor(messageManager, browserChannel, sessionId, runtimeAgent, frameTree, networkMonitor) {
|
||||
+ constructor(messageManager, browserChannel, sessionId, frameTree, networkMonitor) {
|
||||
+ this._messageManager = messageManager;
|
||||
+ this._browserChannel = browserChannel;
|
||||
+ this._sessionId = sessionId;
|
||||
+ this._browserPage = browserChannel.connect(sessionId + 'page');
|
||||
+ this._runtime = runtimeAgent;
|
||||
+ this._browserRuntime = browserChannel.connect(sessionId + 'runtime');
|
||||
+ this._frameTree = frameTree;
|
||||
+ this._runtime = frameTree.runtime();
|
||||
+ this._networkMonitor = networkMonitor;
|
||||
+
|
||||
+ this._frameData = new Map();
|
||||
+ this._workerData = new Map();
|
||||
+ this._scriptsToEvaluateOnNewDocument = new Map();
|
||||
+ this._isolatedWorlds = new Map();
|
||||
+
|
||||
+ this._eventListeners = [
|
||||
+ browserChannel.register(sessionId + 'page', {
|
||||
|
|
@ -3014,6 +3040,12 @@ index 0000000000000000000000000000000000000000..6a001d9f51c819edd3981e090172ac87
|
|||
+ setFileInputFiles: this._setFileInputFiles.bind(this),
|
||||
+ setInterceptFileChooserDialog: this._setInterceptFileChooserDialog.bind(this),
|
||||
+ }),
|
||||
+ browserChannel.register(sessionId + 'runtime', {
|
||||
+ evaluate: this._runtime.evaluate.bind(this._runtime),
|
||||
+ callFunction: this._runtime.callFunction.bind(this._runtime),
|
||||
+ getObjectProperties: this._runtime.getObjectProperties.bind(this._runtime),
|
||||
+ disposeObject: this._runtime.disposeObject.bind(this._runtime),
|
||||
+ }),
|
||||
+ ];
|
||||
+ this._enabled = false;
|
||||
+
|
||||
|
|
@ -3021,17 +3053,6 @@ index 0000000000000000000000000000000000000000..6a001d9f51c819edd3981e090172ac87
|
|||
+ this._docShell = docShell;
|
||||
+ this._initialDPPX = docShell.contentViewer.overrideDPPX;
|
||||
+ this._customScrollbars = null;
|
||||
+
|
||||
+ this._runtime.setOnErrorFromWorker((domWindow, message, stack) => {
|
||||
+ const frame = this._frameTree.frameForDocShell(domWindow.docShell);
|
||||
+ if (!frame)
|
||||
+ return;
|
||||
+ this._browserPage.emit('pageUncaughtError', {
|
||||
+ frameId: frame.id(),
|
||||
+ message,
|
||||
+ stack,
|
||||
+ });
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ async _awaitViewportDimensions({width, height}) {
|
||||
|
|
@ -3067,17 +3088,24 @@ index 0000000000000000000000000000000000000000..6a001d9f51c819edd3981e090172ac87
|
|||
+ }
|
||||
+
|
||||
+ _addScriptToEvaluateOnNewDocument({script, worldName}) {
|
||||
+ if (worldName)
|
||||
+ return this._createIsolatedWorld({script, worldName});
|
||||
+ return {scriptId: this._frameTree.addScriptToEvaluateOnNewDocument(script)};
|
||||
+ }
|
||||
+
|
||||
+ _createIsolatedWorld({script, worldName}) {
|
||||
+ const scriptId = helper.generateId();
|
||||
+ this._scriptsToEvaluateOnNewDocument.set(scriptId, {script, worldName});
|
||||
+ if (worldName) {
|
||||
+ for (const frameData of this._frameData.values())
|
||||
+ frameData.createIsolatedWorld(worldName);
|
||||
+ }
|
||||
+ this._isolatedWorlds.set(scriptId, {script, worldName});
|
||||
+ for (const frameData of this._frameData.values())
|
||||
+ frameData.createIsolatedWorld(worldName);
|
||||
+ return {scriptId};
|
||||
+ }
|
||||
+
|
||||
+ _removeScriptToEvaluateOnNewDocument({scriptId}) {
|
||||
+ this._scriptsToEvaluateOnNewDocument.delete(scriptId);
|
||||
+ if (this._isolatedWorlds.has(scriptId))
|
||||
+ this._isolatedWorlds.delete(scriptId);
|
||||
+ else
|
||||
+ this._frameTree.removeScriptToEvaluateOnNewDocument(scriptId);
|
||||
+ }
|
||||
+
|
||||
+ _setCacheDisabled({cacheDisabled}) {
|
||||
|
|
@ -3126,12 +3154,40 @@ index 0000000000000000000000000000000000000000..6a001d9f51c819edd3981e090172ac87
|
|||
+ helper.on(this._frameTree, 'workercreated', this._onWorkerCreated.bind(this)),
|
||||
+ helper.on(this._frameTree, 'workerdestroyed', this._onWorkerDestroyed.bind(this)),
|
||||
+ helper.addObserver(this._onWindowOpen.bind(this), 'webNavigation-createdNavigationTarget-from-js'),
|
||||
+ this._runtime.events.onErrorFromWorker((domWindow, message, stack) => {
|
||||
+ const frame = this._frameTree.frameForDocShell(domWindow.docShell);
|
||||
+ if (!frame)
|
||||
+ return;
|
||||
+ this._browserPage.emit('pageUncaughtError', {
|
||||
+ frameId: frame.id(),
|
||||
+ message,
|
||||
+ stack,
|
||||
+ });
|
||||
+ }),
|
||||
+ this._runtime.events.onConsoleMessage(msg => this._browserRuntime.emit('runtimeConsole', msg)),
|
||||
+ this._runtime.events.onExecutionContextCreated(this._onExecutionContextCreated.bind(this)),
|
||||
+ this._runtime.events.onExecutionContextDestroyed(this._onExecutionContextDestroyed.bind(this)),
|
||||
+ ]);
|
||||
+ for (const context of this._runtime.executionContexts())
|
||||
+ this._onExecutionContextCreated(context);
|
||||
+
|
||||
+ if (this._frameTree.isPageReady())
|
||||
+ this._browserPage.emit('pageReady', {});
|
||||
+ }
|
||||
+
|
||||
+ _onExecutionContextCreated(executionContext) {
|
||||
+ this._browserRuntime.emit('runtimeExecutionContextCreated', {
|
||||
+ executionContextId: executionContext.id(),
|
||||
+ auxData: executionContext.auxData(),
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ _onExecutionContextDestroyed(executionContext) {
|
||||
+ this._browserRuntime.emit('runtimeExecutionContextDestroyed', {
|
||||
+ executionContextId: executionContext.id(),
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ _onWorkerCreated(worker) {
|
||||
+ const workerData = new WorkerData(this, this._browserChannel, this._sessionId, worker);
|
||||
+ this._workerData.set(worker.id(), workerData);
|
||||
|
|
@ -3186,8 +3242,8 @@ index 0000000000000000000000000000000000000000..6a001d9f51c819edd3981e090172ac87
|
|||
+ return;
|
||||
+ const frameData = this._findFrameForNode(inputElement);
|
||||
+ this._browserPage.emit('pageFileChooserOpened', {
|
||||
+ executionContextId: frameData.mainContext.id(),
|
||||
+ element: frameData.mainContext.rawValueToRemoteObject(inputElement)
|
||||
+ executionContextId: frameData._frame.executionContext().id(),
|
||||
+ element: frameData._frame.executionContext().rawValueToRemoteObject(inputElement)
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
|
|
@ -3284,7 +3340,7 @@ index 0000000000000000000000000000000000000000..6a001d9f51c819edd3981e090172ac87
|
|||
+ frameId: frame.id(),
|
||||
+ parentFrameId: frame.parentFrame() ? frame.parentFrame().id() : undefined,
|
||||
+ });
|
||||
+ this._frameData.set(frame, new FrameData(this, frame));
|
||||
+ this._frameData.set(frame, new FrameData(this, this._runtime, frame));
|
||||
+ }
|
||||
+
|
||||
+ _onFrameDetached(frame) {
|
||||
|
|
@ -3295,9 +3351,8 @@ index 0000000000000000000000000000000000000000..6a001d9f51c819edd3981e090172ac87
|
|||
+ }
|
||||
+
|
||||
+ _onBindingCalled({frame, name, payload}) {
|
||||
+ const frameData = this._frameData.get(frame);
|
||||
+ this._browserPage.emit('pageBindingCalled', {
|
||||
+ executionContextId: frameData.mainContext.id(),
|
||||
+ executionContextId: frame.executionContext().id(),
|
||||
+ name,
|
||||
+ payload
|
||||
+ });
|
||||
|
|
@ -3774,12 +3829,12 @@ index 0000000000000000000000000000000000000000..6a001d9f51c819edd3981e090172ac87
|
|||
+var EXPORTED_SYMBOLS = ['PageAgent'];
|
||||
+this.PageAgent = PageAgent;
|
||||
+
|
||||
diff --git a/juggler/content/RuntimeAgent.js b/juggler/content/RuntimeAgent.js
|
||||
diff --git a/juggler/content/Runtime.js b/juggler/content/Runtime.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b10cc8d29bbfff1d3490ee795710bd7c0f803262
|
||||
index 0000000000000000000000000000000000000000..bd5345b1fab48d798b7e628eed67787a4ba952bb
|
||||
--- /dev/null
|
||||
+++ b/juggler/content/RuntimeAgent.js
|
||||
@@ -0,0 +1,559 @@
|
||||
+++ b/juggler/content/Runtime.js
|
||||
@@ -0,0 +1,534 @@
|
||||
+"use strict";
|
||||
+// Note: this file should be loadabale with eval() into worker environment.
|
||||
+// Avoid Components.*, ChromeUtils and global const variables.
|
||||
|
|
@ -3831,41 +3886,72 @@ index 0000000000000000000000000000000000000000..b10cc8d29bbfff1d3490ee795710bd7c
|
|||
+ 'xbl javascript',
|
||||
+]);
|
||||
+
|
||||
+class RuntimeAgent {
|
||||
+ constructor(channel, sessionId, isWorker = false) {
|
||||
+class Runtime {
|
||||
+ constructor(isWorker = false) {
|
||||
+ this._debugger = new Debugger();
|
||||
+ this._pendingPromises = new Map();
|
||||
+ this._executionContexts = new Map();
|
||||
+ this._windowToExecutionContext = new Map();
|
||||
+ this._session = channel.connect(sessionId + 'runtime');
|
||||
+ this._eventListeners = [
|
||||
+ channel.register(sessionId + 'runtime', {
|
||||
+ evaluate: this._evaluate.bind(this),
|
||||
+ callFunction: this._callFunction.bind(this),
|
||||
+ getObjectProperties: this._getObjectProperties.bind(this),
|
||||
+ disposeObject: this._disposeObject.bind(this),
|
||||
+ }),
|
||||
+ ];
|
||||
+ this._enabled = false;
|
||||
+ this._filteredConsoleMessageHashes = new Set();
|
||||
+ this._onErrorFromWorker = null;
|
||||
+ this._isWorker = isWorker;
|
||||
+ }
|
||||
+
|
||||
+ enable() {
|
||||
+ if (this._enabled)
|
||||
+ return;
|
||||
+ this._enabled = true;
|
||||
+ for (const executionContext of this._executionContexts.values())
|
||||
+ this._notifyExecutionContextCreated(executionContext);
|
||||
+
|
||||
+ if (this._isWorker) {
|
||||
+ this._registerConsoleEventHandler();
|
||||
+ this._eventListeners = [];
|
||||
+ if (isWorker) {
|
||||
+ this._registerWorkerConsoleHandler();
|
||||
+ } else {
|
||||
+ const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
+ this._registerConsoleServiceListener(Services);
|
||||
+ this._registerConsoleObserver(Services);
|
||||
+ }
|
||||
+ // We can't use event listener here to be compatible with Worker Global Context.
|
||||
+ // Use plain callbacks instead.
|
||||
+ this.events = {
|
||||
+ onConsoleMessage: createEvent(),
|
||||
+ onErrorFromWorker: createEvent(),
|
||||
+ onExecutionContextCreated: createEvent(),
|
||||
+ onExecutionContextDestroyed: createEvent(),
|
||||
+ };
|
||||
+ }
|
||||
+
|
||||
+ executionContexts() {
|
||||
+ return [...this._executionContexts.values()];
|
||||
+ }
|
||||
+
|
||||
+ async evaluate({executionContextId, expression, returnByValue}) {
|
||||
+ const executionContext = this.findExecutionContext(executionContextId);
|
||||
+ if (!executionContext)
|
||||
+ throw new Error('Failed to find execution context with id = ' + executionContextId);
|
||||
+ const exceptionDetails = {};
|
||||
+ let result = await executionContext.evaluateScript(expression, exceptionDetails);
|
||||
+ if (!result)
|
||||
+ return {exceptionDetails};
|
||||
+ if (returnByValue)
|
||||
+ result = executionContext.ensureSerializedToValue(result);
|
||||
+ return {result};
|
||||
+ }
|
||||
+
|
||||
+ async callFunction({executionContextId, functionDeclaration, args, returnByValue}) {
|
||||
+ const executionContext = this.findExecutionContext(executionContextId);
|
||||
+ if (!executionContext)
|
||||
+ throw new Error('Failed to find execution context with id = ' + executionContextId);
|
||||
+ const exceptionDetails = {};
|
||||
+ let result = await executionContext.evaluateFunction(functionDeclaration, args, exceptionDetails);
|
||||
+ if (!result)
|
||||
+ return {exceptionDetails};
|
||||
+ if (returnByValue)
|
||||
+ result = executionContext.ensureSerializedToValue(result);
|
||||
+ return {result};
|
||||
+ }
|
||||
+
|
||||
+ async getObjectProperties({executionContextId, objectId}) {
|
||||
+ const executionContext = this.findExecutionContext(executionContextId);
|
||||
+ if (!executionContext)
|
||||
+ throw new Error('Failed to find execution context with id = ' + executionContextId);
|
||||
+ return {properties: executionContext.getObjectProperties(objectId)};
|
||||
+ }
|
||||
+
|
||||
+ async disposeObject({executionContextId, objectId}) {
|
||||
+ const executionContext = this.findExecutionContext(executionContextId);
|
||||
+ if (!executionContext)
|
||||
+ throw new Error('Failed to find execution context with id = ' + executionContextId);
|
||||
+ return executionContext.disposeObject(objectId);
|
||||
+ }
|
||||
+
|
||||
+ _registerConsoleServiceListener(Services) {
|
||||
|
|
@ -3880,8 +3966,7 @@ index 0000000000000000000000000000000000000000..b10cc8d29bbfff1d3490ee795710bd7c
|
|||
+ }
|
||||
+ const errorWindow = Services.wm.getOuterWindowWithId(message.outerWindowID);
|
||||
+ if (message.category === 'Web Worker' && (message.flags & Ci.nsIScriptError.exceptionFlag)) {
|
||||
+ if (this._onErrorFromWorker)
|
||||
+ this._onErrorFromWorker(errorWindow, message.message, '' + message.stack);
|
||||
+ emitEvent(this.events.onErrorFromWorker, errorWindow, message.message, '' + message.stack);
|
||||
+ return;
|
||||
+ }
|
||||
+ const executionContext = this._windowToExecutionContext.get(errorWindow);
|
||||
|
|
@ -3893,7 +3978,7 @@ index 0000000000000000000000000000000000000000..b10cc8d29bbfff1d3490ee795710bd7c
|
|||
+ [Ci.nsIConsoleMessage.warn]: 'warn',
|
||||
+ [Ci.nsIConsoleMessage.error]: 'error',
|
||||
+ };
|
||||
+ this._session.emit('runtimeConsole', {
|
||||
+ emitEvent(this.events.onConsoleMessage, {
|
||||
+ args: [{
|
||||
+ value: message.message,
|
||||
+ }],
|
||||
|
|
@ -3913,11 +3998,6 @@ index 0000000000000000000000000000000000000000..b10cc8d29bbfff1d3490ee795710bd7c
|
|||
+
|
||||
+ _registerConsoleObserver(Services) {
|
||||
+ const consoleObserver = ({wrappedJSObject}, topic, data) => {
|
||||
+ const hash = this._consoleMessageHash(wrappedJSObject);
|
||||
+ if (this._filteredConsoleMessageHashes.has(hash)) {
|
||||
+ this._filteredConsoleMessageHashes.delete(hash);
|
||||
+ return;
|
||||
+ }
|
||||
+ const executionContext = Array.from(this._executionContexts.values()).find(context => {
|
||||
+ const domWindow = context._domWindow;
|
||||
+ return domWindow && domWindow.windowUtils.currentInnerWindowID === wrappedJSObject.innerID;
|
||||
|
|
@ -3930,33 +4010,20 @@ index 0000000000000000000000000000000000000000..b10cc8d29bbfff1d3490ee795710bd7c
|
|||
+ this._eventListeners.push(() => Services.obs.removeObserver(consoleObserver, "console-api-log-event"));
|
||||
+ }
|
||||
+
|
||||
+ _registerConsoleEventHandler() {
|
||||
+ _registerWorkerConsoleHandler() {
|
||||
+ setConsoleEventHandler(message => {
|
||||
+ this._session.emit('workerConsoleMessage', this._consoleMessageHash(message));
|
||||
+ const executionContext = Array.from(this._executionContexts.values())[0];
|
||||
+ this._onConsoleMessage(executionContext, message);
|
||||
+ });
|
||||
+ this._eventListeners.push(() => setConsoleEventHandler(null));
|
||||
+ }
|
||||
+
|
||||
+ filterConsoleMessage(messageHash) {
|
||||
+ this._filteredConsoleMessageHashes.add(messageHash);
|
||||
+ }
|
||||
+
|
||||
+ setOnErrorFromWorker(onErrorFromWorker) {
|
||||
+ this._onErrorFromWorker = onErrorFromWorker;
|
||||
+ }
|
||||
+
|
||||
+ _consoleMessageHash(message) {
|
||||
+ return `${message.timeStamp}/${message.filename}/${message.lineNumber}/${message.columnNumber}/${message.sourceId}/${message.level}`;
|
||||
+ }
|
||||
+
|
||||
+ _onConsoleMessage(executionContext, message) {
|
||||
+ const type = consoleLevelToProtocolType[message.level];
|
||||
+ if (!type)
|
||||
+ return;
|
||||
+ const args = message.arguments.map(arg => executionContext.rawValueToRemoteObject(arg));
|
||||
+ this._session.emit('runtimeConsole', {
|
||||
+ emitEvent(this.events.onConsoleMessage, {
|
||||
+ args,
|
||||
+ type,
|
||||
+ executionContextId: executionContext.id(),
|
||||
|
|
@ -3968,25 +4035,7 @@ index 0000000000000000000000000000000000000000..b10cc8d29bbfff1d3490ee795710bd7c
|
|||
+ });
|
||||
+ }
|
||||
+
|
||||
+ _notifyExecutionContextCreated(executionContext) {
|
||||
+ if (!this._enabled)
|
||||
+ return;
|
||||
+ this._session.emit('runtimeExecutionContextCreated', {
|
||||
+ executionContextId: executionContext._id,
|
||||
+ auxData: executionContext._auxData,
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ _notifyExecutionContextDestroyed(executionContext) {
|
||||
+ if (!this._enabled)
|
||||
+ return;
|
||||
+ this._session.emit('runtimeExecutionContextDestroyed', {
|
||||
+ executionContextId: executionContext._id,
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ dispose() {
|
||||
+ this._session.dispose();
|
||||
+ for (const tearDown of this._eventListeners)
|
||||
+ tearDown.call(null);
|
||||
+ this._eventListeners = [];
|
||||
|
|
@ -4036,7 +4085,7 @@ index 0000000000000000000000000000000000000000..b10cc8d29bbfff1d3490ee795710bd7c
|
|||
+ this._executionContexts.set(context._id, context);
|
||||
+ if (domWindow)
|
||||
+ this._windowToExecutionContext.set(domWindow, context);
|
||||
+ this._notifyExecutionContextCreated(context);
|
||||
+ emitEvent(this.events.onExecutionContextCreated, context);
|
||||
+ return context;
|
||||
+ }
|
||||
+
|
||||
|
|
@ -4060,47 +4109,7 @@ index 0000000000000000000000000000000000000000..b10cc8d29bbfff1d3490ee795710bd7c
|
|||
+ this._executionContexts.delete(destroyedContext._id);
|
||||
+ if (destroyedContext._domWindow)
|
||||
+ this._windowToExecutionContext.delete(destroyedContext._domWindow);
|
||||
+ this._notifyExecutionContextDestroyed(destroyedContext);
|
||||
+ }
|
||||
+
|
||||
+ async _evaluate({executionContextId, expression, returnByValue}) {
|
||||
+ const executionContext = this._executionContexts.get(executionContextId);
|
||||
+ if (!executionContext)
|
||||
+ throw new Error('Failed to find execution context with id = ' + executionContextId);
|
||||
+ const exceptionDetails = {};
|
||||
+ let result = await executionContext.evaluateScript(expression, exceptionDetails);
|
||||
+ if (!result)
|
||||
+ return {exceptionDetails};
|
||||
+ if (returnByValue)
|
||||
+ result = executionContext.ensureSerializedToValue(result);
|
||||
+ return {result};
|
||||
+ }
|
||||
+
|
||||
+ async _callFunction({executionContextId, functionDeclaration, args, returnByValue}) {
|
||||
+ const executionContext = this._executionContexts.get(executionContextId);
|
||||
+ if (!executionContext)
|
||||
+ throw new Error('Failed to find execution context with id = ' + executionContextId);
|
||||
+ const exceptionDetails = {};
|
||||
+ let result = await executionContext.evaluateFunction(functionDeclaration, args, exceptionDetails);
|
||||
+ if (!result)
|
||||
+ return {exceptionDetails};
|
||||
+ if (returnByValue)
|
||||
+ result = executionContext.ensureSerializedToValue(result);
|
||||
+ return {result};
|
||||
+ }
|
||||
+
|
||||
+ async _getObjectProperties({executionContextId, objectId}) {
|
||||
+ const executionContext = this._executionContexts.get(executionContextId);
|
||||
+ if (!executionContext)
|
||||
+ throw new Error('Failed to find execution context with id = ' + executionContextId);
|
||||
+ return {properties: executionContext.getObjectProperties(objectId)};
|
||||
+ }
|
||||
+
|
||||
+ async _disposeObject({executionContextId, objectId}) {
|
||||
+ const executionContext = this._executionContexts.get(executionContextId);
|
||||
+ if (!executionContext)
|
||||
+ throw new Error('Failed to find execution context with id = ' + executionContextId);
|
||||
+ return executionContext.disposeObject(objectId);
|
||||
+ emitEvent(this.events.onExecutionContextDestroyed, destroyedContext);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
|
|
@ -4337,8 +4346,29 @@ index 0000000000000000000000000000000000000000..b10cc8d29bbfff1d3490ee795710bd7c
|
|||
+ }
|
||||
+}
|
||||
+
|
||||
+var EXPORTED_SYMBOLS = ['RuntimeAgent'];
|
||||
+this.RuntimeAgent = RuntimeAgent;
|
||||
+const listenersSymbol = Symbol('listeners');
|
||||
+
|
||||
+function createEvent() {
|
||||
+ const listeners = new Set();
|
||||
+ const subscribeFunction = listener => {
|
||||
+ listeners.add(listener);
|
||||
+ return () => listeners.delete(listener);
|
||||
+ }
|
||||
+ subscribeFunction[listenersSymbol] = listeners;
|
||||
+ return subscribeFunction;
|
||||
+}
|
||||
+
|
||||
+function emitEvent(event, ...args) {
|
||||
+ let listeners = event[listenersSymbol];
|
||||
+ if (!listeners || !listeners.size)
|
||||
+ return;
|
||||
+ listeners = new Set(listeners);
|
||||
+ for (const listener of listeners)
|
||||
+ listener.call(null, ...args);
|
||||
+}
|
||||
+
|
||||
+var EXPORTED_SYMBOLS = ['Runtime'];
|
||||
+this.Runtime = Runtime;
|
||||
diff --git a/juggler/content/ScrollbarManager.js b/juggler/content/ScrollbarManager.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..caee4df323d0a526ed7e38947c41c6430983568d
|
||||
|
|
@ -4432,12 +4462,12 @@ index 0000000000000000000000000000000000000000..caee4df323d0a526ed7e38947c41c643
|
|||
+
|
||||
diff --git a/juggler/content/WorkerMain.js b/juggler/content/WorkerMain.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b1a33558c60289c24f7f58e253a0a617ce35e469
|
||||
index 0000000000000000000000000000000000000000..a6ed6200364b871ee21ee2cdfd2c9246c9bf0055
|
||||
--- /dev/null
|
||||
+++ b/juggler/content/WorkerMain.js
|
||||
@@ -0,0 +1,29 @@
|
||||
@@ -0,0 +1,69 @@
|
||||
+"use strict";
|
||||
+loadSubScript('chrome://juggler/content/content/RuntimeAgent.js');
|
||||
+loadSubScript('chrome://juggler/content/content/Runtime.js');
|
||||
+loadSubScript('chrome://juggler/content/SimpleChannel.js');
|
||||
+
|
||||
+const runtimeAgents = new Map();
|
||||
|
|
@ -4450,12 +4480,52 @@ index 0000000000000000000000000000000000000000..b1a33558c60289c24f7f58e253a0a617
|
|||
+ dispose: () => this.removeEventListener('message', eventListener),
|
||||
+};
|
||||
+
|
||||
+const runtime = new Runtime(true /* isWorker */);
|
||||
+runtime.createExecutionContext(null /* domWindow */, global, {});
|
||||
+
|
||||
+class RuntimeAgent {
|
||||
+ constructor(runtime, channel, sessionId) {
|
||||
+ this._runtime = runtime;
|
||||
+ this._browserRuntime = channel.connect(sessionId + 'runtime');
|
||||
+ this._eventListeners = [
|
||||
+ channel.register(sessionId + 'runtime', {
|
||||
+ evaluate: this._runtime.evaluate.bind(this._runtime),
|
||||
+ callFunction: this._runtime.callFunction.bind(this._runtime),
|
||||
+ getObjectProperties: this._runtime.getObjectProperties.bind(this._runtime),
|
||||
+ disposeObject: this._runtime.disposeObject.bind(this._runtime),
|
||||
+ }),
|
||||
+ this._runtime.events.onConsoleMessage(msg => this._browserRuntime.emit('runtimeConsole', msg)),
|
||||
+ this._runtime.events.onExecutionContextCreated(this._onExecutionContextCreated.bind(this)),
|
||||
+ this._runtime.events.onExecutionContextDestroyed(this._onExecutionContextDestroyed.bind(this)),
|
||||
+ ];
|
||||
+ for (const context of this._runtime.executionContexts())
|
||||
+ this._onExecutionContextCreated(context);
|
||||
+ }
|
||||
+
|
||||
+ _onExecutionContextCreated(executionContext) {
|
||||
+ this._browserRuntime.emit('runtimeExecutionContextCreated', {
|
||||
+ executionContextId: executionContext.id(),
|
||||
+ auxData: executionContext.auxData(),
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ _onExecutionContextDestroyed(executionContext) {
|
||||
+ this._browserRuntime.emit('runtimeExecutionContextDestroyed', {
|
||||
+ executionContextId: executionContext.id(),
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ dispose() {
|
||||
+ for (const disposer of this._eventListeners)
|
||||
+ disposer();
|
||||
+ this._eventListeners = [];
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+channel.register('', {
|
||||
+ attach: ({sessionId}) => {
|
||||
+ const runtimeAgent = new RuntimeAgent(channel, sessionId, true /* isWorker */);
|
||||
+ const runtimeAgent = new RuntimeAgent(runtime, channel, sessionId);
|
||||
+ runtimeAgents.set(sessionId, runtimeAgent);
|
||||
+ runtimeAgent.createExecutionContext(null /* domWindow */, global, {});
|
||||
+ runtimeAgent.enable();
|
||||
+ },
|
||||
+
|
||||
+ detach: ({sessionId}) => {
|
||||
|
|
@ -4539,17 +4609,16 @@ index 0000000000000000000000000000000000000000..3a386425d3796d0a6786dea193b3402d
|
|||
+
|
||||
diff --git a/juggler/content/main.js b/juggler/content/main.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9bb5c2bff8eb3e350203b56a3445e9b200747f8b
|
||||
index 0000000000000000000000000000000000000000..97d45c054ab9c8d805eb26fdc4b42dc503bc930b
|
||||
--- /dev/null
|
||||
+++ b/juggler/content/main.js
|
||||
@@ -0,0 +1,178 @@
|
||||
@@ -0,0 +1,174 @@
|
||||
+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 {NetworkMonitor} = ChromeUtils.import('chrome://juggler/content/content/NetworkMonitor.js');
|
||||
+const {ScrollbarManager} = ChromeUtils.import('chrome://juggler/content/content/ScrollbarManager.js');
|
||||
+const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');
|
||||
+const {RuntimeAgent} = ChromeUtils.import('chrome://juggler/content/content/RuntimeAgent.js');
|
||||
+const {PageAgent} = ChromeUtils.import('chrome://juggler/content/content/PageAgent.js');
|
||||
+
|
||||
+const ALL_PERMISSIONS = [
|
||||
|
|
@ -4568,11 +4637,8 @@ index 0000000000000000000000000000000000000000..9bb5c2bff8eb3e350203b56a3445e9b2
|
|||
+const sessions = new Map();
|
||||
+
|
||||
+function createContentSession(channel, sessionId) {
|
||||
+ const runtimeAgent = new RuntimeAgent(channel, sessionId);
|
||||
+ const pageAgent = new PageAgent(messageManager, channel, sessionId, runtimeAgent, frameTree, networkMonitor);
|
||||
+ sessions.set(sessionId, [runtimeAgent, pageAgent]);
|
||||
+
|
||||
+ runtimeAgent.enable();
|
||||
+ const pageAgent = new PageAgent(messageManager, channel, sessionId, frameTree, networkMonitor);
|
||||
+ sessions.set(sessionId, [pageAgent]);
|
||||
+ pageAgent.enable();
|
||||
+}
|
||||
+
|
||||
|
|
@ -4723,7 +4789,7 @@ index 0000000000000000000000000000000000000000..9bb5c2bff8eb3e350203b56a3445e9b2
|
|||
+initialize();
|
||||
diff --git a/juggler/jar.mn b/juggler/jar.mn
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e8a057109be8b328aefc3af26715c00689ecd6d8
|
||||
index 0000000000000000000000000000000000000000..164060acebeaf784d0c38cf161f408e5d141a44e
|
||||
--- /dev/null
|
||||
+++ b/juggler/jar.mn
|
||||
@@ -0,0 +1,29 @@
|
||||
|
|
@ -4750,7 +4816,7 @@ index 0000000000000000000000000000000000000000..e8a057109be8b328aefc3af26715c006
|
|||
+ content/content/FrameTree.js (content/FrameTree.js)
|
||||
+ content/content/NetworkMonitor.js (content/NetworkMonitor.js)
|
||||
+ content/content/PageAgent.js (content/PageAgent.js)
|
||||
+ content/content/RuntimeAgent.js (content/RuntimeAgent.js)
|
||||
+ content/content/Runtime.js (content/Runtime.js)
|
||||
+ content/content/WorkerMain.js (content/WorkerMain.js)
|
||||
+ content/content/ScrollbarManager.js (content/ScrollbarManager.js)
|
||||
+ content/content/floating-scrollbars.css (content/floating-scrollbars.css)
|
||||
|
|
|
|||
Loading…
Reference in a new issue