parent
c517542f39
commit
2520dedb41
|
|
@ -1824,10 +1824,10 @@ index 0000000000000000000000000000000000000000..2508cce41565023b7fee9c7b85afe8ec
|
|||
+
|
||||
diff --git a/testing/juggler/content/PageAgent.js b/testing/juggler/content/PageAgent.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a76984ed4860
|
||||
index 0000000000000000000000000000000000000000..37ab5f56739cfd16200a4ada9f4cf83436688eba
|
||||
--- /dev/null
|
||||
+++ b/testing/juggler/content/PageAgent.js
|
||||
@@ -0,0 +1,721 @@
|
||||
@@ -0,0 +1,843 @@
|
||||
+"use strict";
|
||||
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
+const Ci = Components.interfaces;
|
||||
|
|
@ -1839,11 +1839,28 @@ index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a769
|
|||
+
|
||||
+const helper = new Helper();
|
||||
+
|
||||
+const registeredWorkerListeners = new Map();
|
||||
+const workerListener = {
|
||||
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIWorkerDebuggerListener]),
|
||||
+ onMessage: (wrapped) => {
|
||||
+ const message = JSON.parse(wrapped);
|
||||
+ const listener = registeredWorkerListeners.get(message.workerId);
|
||||
+ if (listener)
|
||||
+ listener(message);
|
||||
+ },
|
||||
+ onClose: () => {
|
||||
+ },
|
||||
+ onError: (filename, lineno, message) => {
|
||||
+ dump(`Error in worker: ${message} @${filename}:${lineno}\n`);
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+class FrameData {
|
||||
+ constructor(agent, frame) {
|
||||
+ this._agent = agent;
|
||||
+ this._frame = frame;
|
||||
+ this._isolatedWorlds = new Map();
|
||||
+ this._workers = new Map();
|
||||
+ this.reset();
|
||||
+ }
|
||||
+
|
||||
|
|
@ -1913,6 +1930,59 @@ index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a769
|
|||
+ }
|
||||
+ throw new Error('Cannot find object with id = ' + objectId);
|
||||
+ }
|
||||
+
|
||||
+ workerCreated(workerDebugger) {
|
||||
+ const workerId = helper.generateId();
|
||||
+ this._workers.set(workerId, workerDebugger);
|
||||
+ this._agent._session.emitEvent('Page.workerCreated', {
|
||||
+ workerId,
|
||||
+ frameId: this._frame.id(),
|
||||
+ url: workerDebugger.url,
|
||||
+ });
|
||||
+ // Note: this does not interoperate with firefox devtools.
|
||||
+ if (!workerDebugger.isInitialized) {
|
||||
+ workerDebugger.initialize('chrome://juggler/content/content/WorkerMain.js');
|
||||
+ workerDebugger.addListener(workerListener);
|
||||
+ }
|
||||
+ registeredWorkerListeners.set(workerId, message => {
|
||||
+ if (message.command === 'dispatch') {
|
||||
+ this._agent._session.emitEvent('Page.dispatchMessageFromWorker', {
|
||||
+ workerId,
|
||||
+ message: message.message,
|
||||
+ });
|
||||
+ }
|
||||
+ if (message.command === 'console')
|
||||
+ this._agent._runtime.filterConsoleMessage(message.hash);
|
||||
+ });
|
||||
+ workerDebugger.postMessage(JSON.stringify({command: 'connect', workerId}));
|
||||
+ }
|
||||
+
|
||||
+ workerDestroyed(wd) {
|
||||
+ for (const [workerId, workerDebugger] of this._workers) {
|
||||
+ if (workerDebugger === wd) {
|
||||
+ this._agent._session.emitEvent('Page.workerDestroyed', {
|
||||
+ workerId,
|
||||
+ });
|
||||
+ this._workers.delete(workerId);
|
||||
+ registeredWorkerListeners.delete(workerId);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ sendMessageToWorker(workerId, message) {
|
||||
+ const workerDebugger = this._workers.get(workerId);
|
||||
+ if (!workerDebugger)
|
||||
+ throw new Error('Cannot find worker with id "' + workerId + '"');
|
||||
+ workerDebugger.postMessage(JSON.stringify({command: 'dispatch', workerId, message}));
|
||||
+ }
|
||||
+
|
||||
+ dispose() {
|
||||
+ for (const [workerId, workerDebugger] of this._workers) {
|
||||
+ workerDebugger.postMessage(JSON.stringify({command: 'disconnect', workerId}));
|
||||
+ registeredWorkerListeners.delete(workerId);
|
||||
+ }
|
||||
+ this._workers.clear();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+class PageAgent {
|
||||
|
|
@ -1934,6 +2004,24 @@ index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a769
|
|||
+ this._docShell = docShell;
|
||||
+ this._initialDPPX = docShell.contentViewer.overrideDPPX;
|
||||
+ this._customScrollbars = null;
|
||||
+
|
||||
+ this._wdm = Cc["@mozilla.org/dom/workers/workerdebuggermanager;1"].createInstance(Ci.nsIWorkerDebuggerManager);
|
||||
+ this._wdmListener = {
|
||||
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIWorkerDebuggerManagerListener]),
|
||||
+ onRegister: this._onWorkerCreated.bind(this),
|
||||
+ onUnregister: this._onWorkerDestroyed.bind(this),
|
||||
+ };
|
||||
+
|
||||
+ this._runtime.setOnErrorFromWorker((domWindow, message, stack) => {
|
||||
+ const frame = this._frameTree.frameForDocShell(domWindow.docShell);
|
||||
+ if (!frame)
|
||||
+ return;
|
||||
+ this._session.emitEvent('Page.uncaughtError', {
|
||||
+ frameId: frame.id(),
|
||||
+ message,
|
||||
+ stack,
|
||||
+ });
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ async awaitViewportDimensions({width, height}) {
|
||||
|
|
@ -2042,12 +2130,43 @@ index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a769
|
|||
+ helper.on(this._frameTree, 'navigationaborted', this._onNavigationAborted.bind(this)),
|
||||
+ helper.on(this._frameTree, 'samedocumentnavigation', this._onSameDocumentNavigation.bind(this)),
|
||||
+ ];
|
||||
+
|
||||
+ this._wdm.addListener(this._wdmListener);
|
||||
+ for (const workerDebugger of this._wdm.getWorkerDebuggerEnumerator())
|
||||
+ this._onWorkerCreated(workerDebugger);
|
||||
+ }
|
||||
+
|
||||
+ setInterceptFileChooserDialog({enabled}) {
|
||||
+ this._docShell.fileInputInterceptionEnabled = !!enabled;
|
||||
+ }
|
||||
+
|
||||
+ _frameForWorker(workerDebugger) {
|
||||
+ if (workerDebugger.type !== Ci.nsIWorkerDebugger.TYPE_DEDICATED)
|
||||
+ return null;
|
||||
+ const docShell = workerDebugger.window.docShell;
|
||||
+ const frame = this._frameTree.frameForDocShell(docShell);
|
||||
+ return frame ? this._frameData.get(frame) : null;
|
||||
+ }
|
||||
+
|
||||
+ _onWorkerCreated(workerDebugger) {
|
||||
+ const frameData = this._frameForWorker(workerDebugger);
|
||||
+ if (frameData)
|
||||
+ frameData.workerCreated(workerDebugger);
|
||||
+ }
|
||||
+
|
||||
+ _onWorkerDestroyed(workerDebugger) {
|
||||
+ const frameData = this._frameForWorker(workerDebugger);
|
||||
+ if (frameData)
|
||||
+ frameData.workerDestroyed(workerDebugger);
|
||||
+ }
|
||||
+
|
||||
+ sendMessageToWorker({frameId, workerId, message}) {
|
||||
+ const frame = this._frameTree.frame(frameId);
|
||||
+ if (!frame)
|
||||
+ throw new Error('Failed to find frame with id = ' + frameId);
|
||||
+ this._frameData.get(frame).sendMessageToWorker(workerId, message);
|
||||
+ }
|
||||
+
|
||||
+ _filePickerShown(inputElement) {
|
||||
+ if (inputElement.ownerGlobal.docShell !== this._docShell)
|
||||
+ return;
|
||||
|
|
@ -2166,7 +2285,10 @@ index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a769
|
|||
+ }
|
||||
+
|
||||
+ dispose() {
|
||||
+ for (const frameData of this._frameData.values())
|
||||
+ frameData.dispose();
|
||||
+ helper.removeListeners(this._eventListeners);
|
||||
+ this._wdm.removeListener(this._wdmListener);
|
||||
+ }
|
||||
+
|
||||
+ async navigate({frameId, url, referer}) {
|
||||
|
|
@ -2551,20 +2673,24 @@ index 0000000000000000000000000000000000000000..03c4c9717148169110f7e7d19306a769
|
|||
+
|
||||
diff --git a/testing/juggler/content/RuntimeAgent.js b/testing/juggler/content/RuntimeAgent.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac357fb9b60
|
||||
index 0000000000000000000000000000000000000000..5765d5c3b1de7b9383a80435b37b034d6951d981
|
||||
--- /dev/null
|
||||
+++ b/testing/juggler/content/RuntimeAgent.js
|
||||
@@ -0,0 +1,478 @@
|
||||
@@ -0,0 +1,545 @@
|
||||
+"use strict";
|
||||
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||
+const {addDebuggerToGlobal} = ChromeUtils.import("resource://gre/modules/jsdebugger.jsm", {});
|
||||
+// Note: this file should be loadabale with eval() into worker environment.
|
||||
+// Avoid Components.*, ChromeUtils and global const variables.
|
||||
+
|
||||
+const Ci = Components.interfaces;
|
||||
+const Cr = Components.results;
|
||||
+const Cu = Components.utils;
|
||||
+addDebuggerToGlobal(Cu.getGlobalForObject(this));
|
||||
+const helper = new Helper();
|
||||
+if (!this.Debugger) {
|
||||
+ // Worker has a Debugger defined already.
|
||||
+ const {addDebuggerToGlobal} = ChromeUtils.import("resource://gre/modules/jsdebugger.jsm", {});
|
||||
+ addDebuggerToGlobal(Components.utils.getGlobalForObject(this));
|
||||
+}
|
||||
+
|
||||
+let lastId = 0;
|
||||
+function generateId() {
|
||||
+ return 'id-' + (++lastId);
|
||||
+}
|
||||
+
|
||||
+const consoleLevelToProtocolType = {
|
||||
+ 'dir': 'dir',
|
||||
|
|
@ -2603,13 +2729,39 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
|||
+]);
|
||||
+
|
||||
+class RuntimeAgent {
|
||||
+ constructor(session) {
|
||||
+ constructor(session, onWorkerConsoleMessage) {
|
||||
+ this._debugger = new Debugger();
|
||||
+ this._pendingPromises = new Map();
|
||||
+ this._session = session;
|
||||
+ this._executionContexts = new Map();
|
||||
+ this._windowToExecutionContext = new Map();
|
||||
+ this._consoleServiceListener = {
|
||||
+ this._eventListeners = [];
|
||||
+ this._enabled = false;
|
||||
+ this._filteredConsoleMessageHashes = new Set();
|
||||
+ this._onErrorFromWorker = null;
|
||||
+ this._onWorkerConsoleMessage = onWorkerConsoleMessage;
|
||||
+ }
|
||||
+
|
||||
+ enable() {
|
||||
+ if (this._enabled)
|
||||
+ return;
|
||||
+ this._enabled = true;
|
||||
+ for (const executionContext of this._executionContexts.values())
|
||||
+ this._notifyExecutionContextCreated(executionContext);
|
||||
+
|
||||
+ const isWorker = !!this._onWorkerConsoleMessage;
|
||||
+ if (isWorker) {
|
||||
+ this._registerConsoleEventHandler();
|
||||
+ } else {
|
||||
+ const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
+ this._registerConsoleServiceListener(Services);
|
||||
+ this._registerConsoleObserver(Services);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ _registerConsoleServiceListener(Services) {
|
||||
+ const Ci = Components.interfaces;
|
||||
+ const consoleServiceListener = {
|
||||
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIConsoleListener]),
|
||||
+
|
||||
+ observe: message => {
|
||||
|
|
@ -2618,6 +2770,11 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
|||
+ return;
|
||||
+ }
|
||||
+ 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);
|
||||
+ return;
|
||||
+ }
|
||||
+ const executionContext = this._windowToExecutionContext.get(errorWindow);
|
||||
+ if (!executionContext)
|
||||
+ return;
|
||||
|
|
@ -2641,47 +2798,67 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
|||
+ });
|
||||
+ },
|
||||
+ };
|
||||
+
|
||||
+ this._eventListeners = [];
|
||||
+ this._enabled = false;
|
||||
+ Services.console.registerListener(consoleServiceListener);
|
||||
+ this._eventListeners.push(() => Services.console.unregisterListener(consoleServiceListener));
|
||||
+ }
|
||||
+
|
||||
+ _consoleAPICalled({wrappedJSObject}, topic, data) {
|
||||
+ const type = consoleLevelToProtocolType[wrappedJSObject.level];
|
||||
+ _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;
|
||||
+ });
|
||||
+ if (!executionContext)
|
||||
+ return;
|
||||
+ this._onConsoleMessage(executionContext, wrappedJSObject);
|
||||
+ };
|
||||
+ Services.obs.addObserver(consoleObserver, "console-api-log-event");
|
||||
+ this._eventListeners.push(() => Services.obs.removeObserver(consoleObserver, "console-api-log-event"));
|
||||
+ }
|
||||
+
|
||||
+ _registerConsoleEventHandler() {
|
||||
+ setConsoleEventHandler(message => {
|
||||
+ this._onWorkerConsoleMessage(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 executionContext = Array.from(this._executionContexts.values()).find(context => {
|
||||
+ const domWindow = context._domWindow;
|
||||
+ return domWindow && domWindow.windowUtils.currentInnerWindowID === wrappedJSObject.innerID;
|
||||
+ });
|
||||
+ if (!executionContext)
|
||||
+ return;
|
||||
+ const args = wrappedJSObject.arguments.map(arg => executionContext.rawValueToRemoteObject(arg));
|
||||
+ const args = message.arguments.map(arg => executionContext.rawValueToRemoteObject(arg));
|
||||
+ this._session.emitEvent('Runtime.console', {
|
||||
+ args,
|
||||
+ type,
|
||||
+ executionContextId: executionContext.id(),
|
||||
+ location: {
|
||||
+ lineNumber: wrappedJSObject.lineNumber - 1,
|
||||
+ columnNumber: wrappedJSObject.columnNumber - 1,
|
||||
+ url: wrappedJSObject.filename,
|
||||
+ lineNumber: message.lineNumber - 1,
|
||||
+ columnNumber: message.columnNumber - 1,
|
||||
+ url: message.filename,
|
||||
+ },
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ enable() {
|
||||
+ if (this._enabled)
|
||||
+ return;
|
||||
+ this._enabled = true;
|
||||
+ for (const executionContext of this._executionContexts.values())
|
||||
+ this._notifyExecutionContextCreated(executionContext);
|
||||
+ Services.console.registerListener(this._consoleServiceListener);
|
||||
+ this._eventListeners = [
|
||||
+ () => Services.console.unregisterListener(this._consoleServiceListener),
|
||||
+ helper.addObserver(this._consoleAPICalled.bind(this), "console-api-log-event"),
|
||||
+ ];
|
||||
+ }
|
||||
+
|
||||
+ _notifyExecutionContextCreated(executionContext) {
|
||||
+ if (!this._enabled)
|
||||
+ return;
|
||||
|
|
@ -2700,7 +2877,9 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
|||
+ }
|
||||
+
|
||||
+ dispose() {
|
||||
+ helper.removeListeners(this._eventListeners);
|
||||
+ for (const tearDown of this._eventListeners)
|
||||
+ tearDown.call(null);
|
||||
+ this._eventListeners = [];
|
||||
+ }
|
||||
+
|
||||
+ async _awaitPromise(executionContext, obj, exceptionDetails = {}) {
|
||||
|
|
@ -2742,9 +2921,11 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
|||
+ }
|
||||
+
|
||||
+ createExecutionContext(domWindow, contextGlobal, auxData) {
|
||||
+ const context = new ExecutionContext(this, domWindow, this._debugger.addDebuggee(contextGlobal), auxData);
|
||||
+ // Note: domWindow is null for workers.
|
||||
+ const context = new ExecutionContext(this, domWindow, contextGlobal, this._debugger.addDebuggee(contextGlobal), auxData);
|
||||
+ this._executionContexts.set(context._id, context);
|
||||
+ this._windowToExecutionContext.set(domWindow, context);
|
||||
+ if (domWindow)
|
||||
+ this._windowToExecutionContext.set(domWindow, context);
|
||||
+ this._notifyExecutionContextCreated(context);
|
||||
+ return context;
|
||||
+ }
|
||||
|
|
@ -2765,9 +2946,10 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
|||
+ }
|
||||
+ if (!this._pendingPromises.size)
|
||||
+ this._debugger.onPromiseSettled = undefined;
|
||||
+ this._debugger.removeDebuggee(destroyedContext._domWindow);
|
||||
+ this._debugger.removeDebuggee(destroyedContext._contextGlobal);
|
||||
+ this._executionContexts.delete(destroyedContext._id);
|
||||
+ this._windowToExecutionContext.delete(destroyedContext._domWindow);
|
||||
+ if (destroyedContext._domWindow)
|
||||
+ this._windowToExecutionContext.delete(destroyedContext._domWindow);
|
||||
+ this._notifyExecutionContextDestroyed(destroyedContext);
|
||||
+ }
|
||||
+
|
||||
|
|
@ -2813,12 +2995,13 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
|||
+}
|
||||
+
|
||||
+class ExecutionContext {
|
||||
+ constructor(runtime, domWindow, global, auxData) {
|
||||
+ constructor(runtime, domWindow, contextGlobal, global, auxData) {
|
||||
+ this._runtime = runtime;
|
||||
+ this._domWindow = domWindow;
|
||||
+ this._contextGlobal = contextGlobal;
|
||||
+ this._global = global;
|
||||
+ this._remoteObjects = new Map();
|
||||
+ this._id = helper.generateId();
|
||||
+ this._id = generateId();
|
||||
+ this._auxData = auxData;
|
||||
+ this._jsonStringifyObject = this._global.executeInGlobal(`((stringify, dateProto, object) => {
|
||||
+ const oldToJson = dateProto.toJSON;
|
||||
|
|
@ -2839,9 +3022,9 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
|||
+ }
|
||||
+
|
||||
+ async evaluateScript(script, exceptionDetails = {}) {
|
||||
+ const userInputHelper = this._domWindow.windowUtils.setHandlingUserInput(true);
|
||||
+ const userInputHelper = this._domWindow ? this._domWindow.windowUtils.setHandlingUserInput(true) : null;
|
||||
+ let {success, obj} = this._getResult(this._global.executeInGlobal(script), exceptionDetails);
|
||||
+ userInputHelper.destruct();
|
||||
+ userInputHelper && userInputHelper.destruct();
|
||||
+ if (!success)
|
||||
+ return null;
|
||||
+ if (obj && obj.isPromise) {
|
||||
|
|
@ -2873,9 +3056,9 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
|||
+ default: return this._toDebugger(arg.value);
|
||||
+ }
|
||||
+ });
|
||||
+ const userInputHelper = this._domWindow.windowUtils.setHandlingUserInput(true);
|
||||
+ const userInputHelper = this._domWindow ? this._domWindow.windowUtils.setHandlingUserInput(true) : null;
|
||||
+ let {success, obj} = this._getResult(funEvaluation.obj.apply(null, args), exceptionDetails);
|
||||
+ userInputHelper.destruct();
|
||||
+ userInputHelper && userInputHelper.destruct();
|
||||
+ if (!success)
|
||||
+ return null;
|
||||
+ if (obj && obj.isPromise) {
|
||||
|
|
@ -2898,9 +3081,15 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
|||
+ return this._createRemoteObject(debuggerObj);
|
||||
+ }
|
||||
+
|
||||
+ _instanceOf(debuggerObj, rawObj, className) {
|
||||
+ if (this._domWindow)
|
||||
+ return rawObj instanceof this._domWindow[className];
|
||||
+ return this._global.executeInGlobalWithBindings('o instanceof this[className]', {o: debuggerObj, className: this._global.makeDebuggeeValue(className)}).return;
|
||||
+ }
|
||||
+
|
||||
+ _createRemoteObject(debuggerObj) {
|
||||
+ if (debuggerObj instanceof Debugger.Object) {
|
||||
+ const objectId = helper.generateId();
|
||||
+ const objectId = generateId();
|
||||
+ this._remoteObjects.set(objectId, debuggerObj);
|
||||
+ const rawObj = debuggerObj.unsafeDereference();
|
||||
+ const type = typeof rawObj;
|
||||
|
|
@ -2911,35 +3100,35 @@ index 0000000000000000000000000000000000000000..262011d8fda346078a6cfcb7aae5dac3
|
|||
+ subtype = 'array';
|
||||
+ else if (Object.is(rawObj, null))
|
||||
+ subtype = 'null';
|
||||
+ else if (rawObj instanceof this._domWindow.Node)
|
||||
+ else if (this._instanceOf(debuggerObj, rawObj, 'Node'))
|
||||
+ subtype = 'node';
|
||||
+ else if (rawObj instanceof this._domWindow.RegExp)
|
||||
+ else if (this._instanceOf(debuggerObj, rawObj, 'RegExp'))
|
||||
+ subtype = 'regexp';
|
||||
+ else if (rawObj instanceof this._domWindow.Date)
|
||||
+ else if (this._instanceOf(debuggerObj, rawObj, 'Date'))
|
||||
+ subtype = 'date';
|
||||
+ else if (rawObj instanceof this._domWindow.Map)
|
||||
+ else if (this._instanceOf(debuggerObj, rawObj, 'Map'))
|
||||
+ subtype = 'map';
|
||||
+ else if (rawObj instanceof this._domWindow.Set)
|
||||
+ else if (this._instanceOf(debuggerObj, rawObj, 'Set'))
|
||||
+ subtype = 'set';
|
||||
+ else if (rawObj instanceof this._domWindow.WeakMap)
|
||||
+ else if (this._instanceOf(debuggerObj, rawObj, 'WeakMap'))
|
||||
+ subtype = 'weakmap';
|
||||
+ else if (rawObj instanceof this._domWindow.WeakSet)
|
||||
+ else if (this._instanceOf(debuggerObj, rawObj, 'WeakSet'))
|
||||
+ subtype = 'weakset';
|
||||
+ else if (rawObj instanceof this._domWindow.Error)
|
||||
+ else if (this._instanceOf(debuggerObj, rawObj, 'Error'))
|
||||
+ subtype = 'error';
|
||||
+ else if (rawObj instanceof this._domWindow.Promise)
|
||||
+ else if (this._instanceOf(debuggerObj, rawObj, 'Promise'))
|
||||
+ subtype = 'promise';
|
||||
+ else if ((rawObj instanceof this._domWindow.Int8Array) || (rawObj instanceof this._domWindow.Uint8Array) ||
|
||||
+ (rawObj instanceof this._domWindow.Uint8ClampedArray) || (rawObj instanceof this._domWindow.Int16Array) ||
|
||||
+ (rawObj instanceof this._domWindow.Uint16Array) || (rawObj instanceof this._domWindow.Int32Array) ||
|
||||
+ (rawObj instanceof this._domWindow.Uint32Array) || (rawObj instanceof this._domWindow.Float32Array) ||
|
||||
+ (rawObj instanceof this._domWindow.Float64Array)) {
|
||||
+ else if ((this._instanceOf(debuggerObj, rawObj, 'Int8Array')) || (this._instanceOf(debuggerObj, rawObj, 'Uint8Array')) ||
|
||||
+ (this._instanceOf(debuggerObj, rawObj, 'Uint8ClampedArray')) || (this._instanceOf(debuggerObj, rawObj, 'Int16Array')) ||
|
||||
+ (this._instanceOf(debuggerObj, rawObj, 'Uint16Array')) || (this._instanceOf(debuggerObj, rawObj, 'Int32Array')) ||
|
||||
+ (this._instanceOf(debuggerObj, rawObj, 'Uint32Array')) || (this._instanceOf(debuggerObj, rawObj, 'Float32Array')) ||
|
||||
+ (this._instanceOf(debuggerObj, rawObj, 'Float64Array'))) {
|
||||
+ subtype = 'typedarray';
|
||||
+ }
|
||||
+ return {objectId, type, subtype};
|
||||
+ }
|
||||
+ if (typeof debuggerObj === 'symbol') {
|
||||
+ const objectId = helper.generateId();
|
||||
+ const objectId = generateId();
|
||||
+ this._remoteObjects.set(objectId, debuggerObj);
|
||||
+ return {objectId, type: 'symbol'};
|
||||
+ }
|
||||
|
|
@ -3124,6 +3313,79 @@ index 0000000000000000000000000000000000000000..caee4df323d0a526ed7e38947c41c643
|
|||
+var EXPORTED_SYMBOLS = ['ScrollbarManager'];
|
||||
+this.ScrollbarManager = ScrollbarManager;
|
||||
+
|
||||
diff --git a/testing/juggler/content/WorkerMain.js b/testing/juggler/content/WorkerMain.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..73cdce649608f068e59e1ff7808883c4482bff7e
|
||||
--- /dev/null
|
||||
+++ b/testing/juggler/content/WorkerMain.js
|
||||
@@ -0,0 +1,67 @@
|
||||
+"use strict";
|
||||
+loadSubScript('chrome://juggler/content/content/RuntimeAgent.js');
|
||||
+
|
||||
+class WorkerSession {
|
||||
+ constructor(workerId) {
|
||||
+ this._workerId = workerId;
|
||||
+ this._agents = {
|
||||
+ Runtime: new RuntimeAgent(this, hash => this._send({command: 'console', hash})),
|
||||
+ };
|
||||
+ this._agents.Runtime.enable();
|
||||
+ this._agents.Runtime.createExecutionContext(null /* domWindow */, global, {});
|
||||
+ }
|
||||
+
|
||||
+ _send(command) {
|
||||
+ postMessage(JSON.stringify({...command, workerId: this._workerId}));
|
||||
+ }
|
||||
+
|
||||
+ _dispatchProtocolMessage(protocolMessage) {
|
||||
+ this._send({command: 'dispatch', message: JSON.stringify(protocolMessage)});
|
||||
+ }
|
||||
+
|
||||
+ emitEvent(eventName, params) {
|
||||
+ this._dispatchProtocolMessage({method: eventName, params});
|
||||
+ }
|
||||
+
|
||||
+ async _onMessage(message) {
|
||||
+ const object = JSON.parse(message);
|
||||
+ const id = object.id;
|
||||
+ try {
|
||||
+ const [domainName, methodName] = object.method.split('.');
|
||||
+ const agent = this._agents[domainName];
|
||||
+ if (!agent)
|
||||
+ throw new Error(`unknown domain: ${domainName}`);
|
||||
+ const handler = agent[methodName];
|
||||
+ if (!handler)
|
||||
+ throw new Error(`unknown method: ${domainName}.${methodName}`);
|
||||
+ const result = await handler.call(agent, object.params);
|
||||
+ this._dispatchProtocolMessage({id, result});
|
||||
+ } catch (e) {
|
||||
+ this._dispatchProtocolMessage({id, error: e.message + '\n' + e.stack});
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ dispose() {
|
||||
+ for (const agent of Object.values(this._agents))
|
||||
+ agent.dispose();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+const workerSessions = new Map();
|
||||
+
|
||||
+this.addEventListener('message', event => {
|
||||
+ const data = JSON.parse(event.data);
|
||||
+ if (data.command === 'connect') {
|
||||
+ const session = new WorkerSession(data.workerId);
|
||||
+ workerSessions.set(data.workerId, session);
|
||||
+ }
|
||||
+ if (data.command === 'disconnect') {
|
||||
+ const session = workerSessions.get(data.workerId);
|
||||
+ session.dispose();
|
||||
+ workerSessions.delete(data.workerId);
|
||||
+ }
|
||||
+ if (data.command === 'dispatch') {
|
||||
+ const session = workerSessions.get(data.workerId);
|
||||
+ session._onMessage(data.message);
|
||||
+ }
|
||||
+});
|
||||
diff --git a/testing/juggler/content/floating-scrollbars.css b/testing/juggler/content/floating-scrollbars.css
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7709bdd34c65062fc63684ef17fc792d3991d965
|
||||
|
|
@ -3243,10 +3505,10 @@ index 0000000000000000000000000000000000000000..8585092e04e7e763a0c115c28363e505
|
|||
+
|
||||
diff --git a/testing/juggler/jar.mn b/testing/juggler/jar.mn
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..27f5a15fd7f14385bb1f080d5965d90e60423d1a
|
||||
index 0000000000000000000000000000000000000000..76377927a8c9af3cac3b028ff754491966d03ba3
|
||||
--- /dev/null
|
||||
+++ b/testing/juggler/jar.mn
|
||||
@@ -0,0 +1,29 @@
|
||||
@@ -0,0 +1,30 @@
|
||||
+# 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/.
|
||||
|
|
@ -3272,6 +3534,7 @@ index 0000000000000000000000000000000000000000..27f5a15fd7f14385bb1f080d5965d90e
|
|||
+ content/content/NetworkMonitor.js (content/NetworkMonitor.js)
|
||||
+ content/content/PageAgent.js (content/PageAgent.js)
|
||||
+ content/content/RuntimeAgent.js (content/RuntimeAgent.js)
|
||||
+ content/content/WorkerMain.js (content/WorkerMain.js)
|
||||
+ content/content/ScrollbarManager.js (content/ScrollbarManager.js)
|
||||
+ content/content/floating-scrollbars.css (content/floating-scrollbars.css)
|
||||
+ content/content/hidden-scrollbars.css (content/hidden-scrollbars.css)
|
||||
|
|
@ -3392,10 +3655,10 @@ index 0000000000000000000000000000000000000000..708059a95b3a01f3d9c7b7ef4714ee6f
|
|||
+this.BrowserHandler = BrowserHandler;
|
||||
diff --git a/testing/juggler/protocol/Dispatcher.js b/testing/juggler/protocol/Dispatcher.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7b3a6fa4fe7a2b50a78ed446fbf5537504994798
|
||||
index 0000000000000000000000000000000000000000..956988738079272be8d3998dcbbaa91abc415fcc
|
||||
--- /dev/null
|
||||
+++ b/testing/juggler/protocol/Dispatcher.js
|
||||
@@ -0,0 +1,255 @@
|
||||
@@ -0,0 +1,254 @@
|
||||
+const {TargetRegistry} = ChromeUtils.import("chrome://juggler/content/TargetRegistry.js");
|
||||
+const {protocol, checkScheme} = ChromeUtils.import("chrome://juggler/content/protocol/Protocol.js");
|
||||
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||
|
|
@ -3630,7 +3893,6 @@ index 0000000000000000000000000000000000000000..7b3a6fa4fe7a2b50a78ed446fbf55375
|
|||
+
|
||||
+ _onMessage({data}) {
|
||||
+ if (data.id) {
|
||||
+ let id = data.id;
|
||||
+ const {resolve, reject} = this._pendingMessages.get(data.id);
|
||||
+ this._pendingMessages.delete(data.id);
|
||||
+ if (data.error)
|
||||
|
|
@ -3813,10 +4075,10 @@ index 0000000000000000000000000000000000000000..f5e7e919594b3778fd3046bf69d34878
|
|||
+this.NetworkHandler = NetworkHandler;
|
||||
diff --git a/testing/juggler/protocol/PageHandler.js b/testing/juggler/protocol/PageHandler.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bf59b2afa8692d02fd0ce664eec2e9827a8209d2
|
||||
index 0000000000000000000000000000000000000000..23a32be2200e90e2e05d31aec85874a829cb1bbe
|
||||
--- /dev/null
|
||||
+++ b/testing/juggler/protocol/PageHandler.js
|
||||
@@ -0,0 +1,281 @@
|
||||
@@ -0,0 +1,285 @@
|
||||
+"use strict";
|
||||
+
|
||||
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||
|
|
@ -4039,6 +4301,10 @@ index 0000000000000000000000000000000000000000..bf59b2afa8692d02fd0ce664eec2e982
|
|||
+ async handleFileChooser(options) {
|
||||
+ return await this._contentSession.send('Page.handleFileChooser', options);
|
||||
+ }
|
||||
+
|
||||
+ async sendMessageToWorker(options) {
|
||||
+ return await this._contentSession.send('Page.sendMessageToWorker', options);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+class Dialog {
|
||||
|
|
@ -4249,10 +4515,10 @@ index 0000000000000000000000000000000000000000..78b6601b91d0b7fcda61114e6846aa07
|
|||
+this.EXPORTED_SYMBOLS = ['t', 'checkScheme'];
|
||||
diff --git a/testing/juggler/protocol/Protocol.js b/testing/juggler/protocol/Protocol.js
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..75b5276d085bd4217389cd05099895ebec2438b6
|
||||
index 0000000000000000000000000000000000000000..1eecb6120f101cb7506fcf8d40c177089e62671b
|
||||
--- /dev/null
|
||||
+++ b/testing/juggler/protocol/Protocol.js
|
||||
@@ -0,0 +1,712 @@
|
||||
@@ -0,0 +1,731 @@
|
||||
+const {t, checkScheme} = ChromeUtils.import('chrome://juggler/content/protocol/PrimitiveTypes.js');
|
||||
+
|
||||
+// Protocol-specific types.
|
||||
|
|
@ -4738,6 +5004,18 @@ index 0000000000000000000000000000000000000000..75b5276d085bd4217389cd05099895eb
|
|||
+ executionContextId: t.String,
|
||||
+ element: runtimeTypes.RemoteObject
|
||||
+ },
|
||||
+ 'workerCreated': {
|
||||
+ workerId: t.String,
|
||||
+ frameId: t.String,
|
||||
+ url: t.String,
|
||||
+ },
|
||||
+ 'workerDestroyed': {
|
||||
+ workerId: t.String,
|
||||
+ },
|
||||
+ 'dispatchMessageFromWorker': {
|
||||
+ workerId: t.String,
|
||||
+ message: t.String,
|
||||
+ },
|
||||
+ },
|
||||
+
|
||||
+ methods: {
|
||||
|
|
@ -4940,6 +5218,13 @@ index 0000000000000000000000000000000000000000..75b5276d085bd4217389cd05099895eb
|
|||
+ enabled: t.Boolean,
|
||||
+ },
|
||||
+ },
|
||||
+ 'sendMessageToWorker': {
|
||||
+ params: {
|
||||
+ frameId: t.String,
|
||||
+ workerId: t.String,
|
||||
+ message: t.String,
|
||||
+ },
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
|
|
|
|||
Loading…
Reference in a new issue