Bug 1657389 - Rename target actor mock 'window' property to 'workerGlobal'. r=ochameau.

Not having the window property anymore, we have to change the `window` getter
in WebConsoleActor to retrieve `workerGlobal`. And since the getter name wasn't
reflecting what it was holding (it can be a window, a worker global or a sandbox),
we rename it to `global` (and `evalWindow` to `evalGlobal`).

We remove the `globalDebugObject` getter on the thread actor that wasn't used
anywhere in the code.

Differential Revision: https://phabricator.services.mozilla.com/D86035
This commit is contained in:
Nicolas Chevobbe 2020-08-06 14:05:07 +00:00
Родитель 5b26ec0846
Коммит 7ee8cd576d
7 изменённых файлов: 85 добавлений и 118 удалений

Просмотреть файл

@ -75,8 +75,6 @@ const proto = {
* Increment the actor's grip depth
* - decrementGripDepth
* Decrement the actor's grip depth
* - globalDebugObject
* The Debuggee Global Object as given by the ThreadActor
*/
initialize(
obj,

Просмотреть файл

@ -64,11 +64,10 @@ class ConsoleMessageWatcher {
this.listener = listener;
listener.init();
// See `window` definition. It isn't always a DOM Window.
// It can happen that the targetActor does not have a window reference (e.g. in worker
// thread, targetActor exposes a workerGlobal property)
const winStartTime =
targetActor.window && targetActor.window.performance
? targetActor.window.performance.timing.navigationStart
: 0;
targetActor.window?.performance?.timing?.navigationStart || 0;
const cachedMessages = listener.getCachedMessages(!targetActor.isRootActor);
const messages = [];

Просмотреть файл

@ -244,13 +244,6 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
return this._dbg;
},
get globalDebugObject() {
if (!this._parent.window) {
return null;
}
return this.dbg.makeGlobalObjectReference(this._parent.window);
},
get state() {
return this._state;
},
@ -506,13 +499,18 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
return highlighter;
},
_canShowOverlay() {
// Accept only browsing context target, which expose a `window` attribute,
// but ignore privileged document (top level window, special about:* pages, …)
return this._parent.window && !this._parent.window.isChromeWindow;
},
async showOverlay() {
if (
this._options.shouldShowOverlay &&
this.isPaused() &&
this._canShowOverlay() &&
this._parent.on &&
this._parent.window.document &&
!this._parent.window.isChromeWindow &&
this.pauseOverlay
) {
const reason = this._priorPause.why.type;
@ -521,13 +519,8 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
}
},
hideOverlay(msg) {
if (
this._parent.window.document &&
this._parent.on &&
!this._parent.window.isChromeWindow &&
this._pauseOverlay
) {
hideOverlay() {
if (this._canShowOverlay() && this._pauseOverlay) {
this.pauseOverlay.hide();
}
},

Просмотреть файл

@ -4,7 +4,7 @@
"use strict";
/* global XPCNativeWrapper evalWithDebugger */
/* global XPCNativeWrapper */
const { ActorClassWithSpec, Actor } = require("devtools/shared/protocol");
const { webconsoleSpec } = require("devtools/shared/specs/webconsole");
@ -244,18 +244,16 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
traits: null,
/**
* The window or sandbox we work with.
* Note that even if it is named `window` it refers to the current
* global we are debugging, which can be a Sandbox for addons
* or browser content toolbox.
* The global we work with (this can be a Window, a Worker global or even a Sandbox
* for processes and addons).
*
* @type nsIDOMWindow or Sandbox
* @type nsIDOMWindow, WorkerGlobalScope or Sandbox
*/
get window() {
get global() {
if (this.parentActor.isRootActor) {
return this._getWindowForBrowserConsole();
}
return this.parentActor.window;
return this.parentActor.window || this.parentActor.workerGlobal;
},
/**
@ -325,14 +323,14 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
*/
_lastChromeWindow: null,
// The evalWindow is used at the scope for JS evaluation.
_evalWindow: null,
get evalWindow() {
return this._evalWindow || this.window;
// The evalGlobal is used at the scope for JS evaluation.
_evalGlobal: null,
get evalGlobal() {
return this._evalGlobal || this.global;
},
set evalWindow(window) {
this._evalWindow = window;
set evalGlobal(global) {
this._evalGlobal = global;
if (!this._progressListenerActive) {
EventEmitter.on(this.parentActor, "will-navigate", this._onWillNavigate);
@ -343,7 +341,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
/**
* Flag used to track if we are listening for events from the progress
* listener of the target actor. We use the progress listener to clear
* this.evalWindow on page navigation.
* this.evalGlobal on page navigation.
*
* @private
* @type boolean
@ -431,7 +429,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
this._webConsoleCommandsCache = null;
this._lastConsoleInputEvaluation = null;
this._evalWindow = null;
this._evalGlobal = null;
this.dbg = null;
this.conn = null;
},
@ -480,7 +478,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
* The value you want to get a debuggee value for.
* @param boolean useObjectGlobal
* If |true| the object global is determined and added as a debuggee,
* otherwise |this.window| is used when makeDebuggeeValue() is invoked.
* otherwise |this.global| is used when makeDebuggeeValue() is invoked.
* @return object
* Debuggee value for |value|.
*/
@ -495,7 +493,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
// or 'Object in compartment marked as invisible to Debugger'
}
}
const dbgGlobal = this.dbg.makeGlobalObjectReference(this.window);
const dbgGlobal = this.dbg.makeGlobalObjectReference(this.global);
return dbgGlobal.makeDebuggeeValue(value);
},
@ -621,7 +619,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
// eslint-disable-next-line complexity
startListeners: async function(listeners) {
const startedListeners = [];
const window = !this.parentActor.isRootActor ? this.window : null;
const global = !this.parentActor.isRootActor ? this.global : null;
for (const event of listeners) {
switch (event) {
@ -632,7 +630,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
}
if (!this.consoleServiceListener) {
this.consoleServiceListener = new ConsoleServiceListener(
window,
global,
this.onConsoleServiceMessage
);
this.consoleServiceListener.init();
@ -644,7 +642,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
// Create the consoleAPIListener
// (and apply the filtering options defined in the parent actor).
this.consoleAPIListener = new ConsoleAPIListener(
window,
global,
this.onConsoleAPICall,
this.parentActor.consoleAPIListenerOptions
);
@ -703,7 +701,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
// service workers requests)
new NetworkMonitorActor(
this.conn,
{ window },
{ window: global },
this.actorID,
mmMockParent
);
@ -718,7 +716,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
// requests, as well with the NetworkMonitorActor running in the parent
// process. It will communicate via message manager for this one.
this.stackTraceCollector = new StackTraceCollector(
{ window },
{ window: global },
this.netmonitors
);
this.stackTraceCollector.init();
@ -730,10 +728,10 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
if (isWorker) {
break;
}
if (this.window instanceof Ci.nsIDOMWindow) {
if (this.global instanceof Ci.nsIDOMWindow) {
if (!this.consoleFileActivityListener) {
this.consoleFileActivityListener = new ConsoleFileActivityListener(
this.window,
this.global,
this
);
}
@ -748,7 +746,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
}
if (!this.consoleReflowListener) {
this.consoleReflowListener = new ConsoleReflowListener(
this.window,
this.global,
this
);
}
@ -788,7 +786,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
return {
startedListeners: startedListeners,
nativeConsoleAPI: this.hasNativeConsoleAPI(this.window),
nativeConsoleAPI: this.hasNativeConsoleAPI(this.global),
traits: this.traits,
};
},
@ -919,11 +917,10 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
break;
}
// See `window` definition. It isn't always a DOM Window.
const winStartTime =
this.window && this.window.performance
? this.window.performance.timing.navigationStart
: 0;
// this.global might not be a window (can be a worker global or a Sandbox),
// and in such case performance isn't defined
const winStartTime = this.global?.performance?.timing
?.navigationStart;
const cache = this.consoleAPIListener.getCachedMessages(
!this.parentActor.isRootActor
@ -1031,7 +1028,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
});
return;
} catch (e) {
const message = `Encountered error while waiting for Helper Result: ${e}`;
const message = `Encountered error while waiting for Helper Result: ${e}\n${e.stack}`;
DevToolsUtils.reportException("evaluateJSAsync", Error(message));
}
});
@ -1355,7 +1352,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
);
}
} else {
dbgObject = this.dbg.addDebuggee(this.evalWindow);
dbgObject = this.dbg.addDebuggee(this.evalGlobal);
}
const result = JSPropertyProvider({
@ -1444,7 +1441,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
*/
clearMessagesCache: function() {
const windowId = !this.parentActor.isRootActor
? WebConsoleUtils.getInnerWindowId(this.window)
? WebConsoleUtils.getInnerWindowId(this.global)
: null;
const ConsoleAPIStorage = Cc[
"@mozilla.org/consoleAPI-storage;1"
@ -1531,8 +1528,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
*/
_getWebConsoleCommands: function(debuggerGlobal) {
const helpers = {
window: this.evalWindow,
chromeWindow: this.chromeWindow.bind(this),
window: this.evalGlobal,
makeDebuggeeValue: debuggerGlobal.makeDebuggeeValue.bind(debuggerGlobal),
createValueGrip: this.createValueGrip.bind(this),
preprocessDebuggerObject: this.preprocessDebuggerObject.bind(this),
@ -1542,7 +1538,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
};
addWebConsoleCommands(helpers);
const evalWindow = this.evalWindow;
const evalGlobal = this.evalGlobal;
function maybeExport(obj, name) {
if (typeof obj[name] != "function") {
return;
@ -1554,7 +1550,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
// helpers like cd(), where we users sometimes want to pass a cross-origin
// window. To circumvent this restriction, we use exportFunction along
// with a special option designed for this purpose. See bug 1051224.
obj[name] = Cu.exportFunction(obj[name], evalWindow, {
obj[name] = Cu.exportFunction(obj[name], evalGlobal, {
allowCrossOriginArguments: true,
});
}
@ -1780,7 +1776,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
const { url, method, headers, body, cause } = request;
// Set the loadingNode and loadGroup to the target document - otherwise the
// request won't show up in the opened netmonitor.
const doc = this.window.document;
const doc = this.global.document;
const channel = NetUtil.newChannel({
uri: NetUtil.newURI(url),
@ -1988,7 +1984,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
* The original message received from console-api-log-event.
* @param boolean aUseObjectGlobal
* If |true| the object global is determined and added as a debuggee,
* otherwise |this.window| is used when makeDebuggeeValue() is invoked.
* otherwise |this.global| is used when makeDebuggeeValue() is invoked.
* @return object
* The object that can be sent to the remote client.
*/
@ -2109,24 +2105,6 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
return ownProperties;
},
/**
* Find the XUL window that owns the content window.
*
* @return Window
* The XUL window that owns the content window.
*/
chromeWindow: function() {
let window = null;
try {
window = this.window.docShell.chromeEventHandler.ownerGlobal;
} catch (ex) {
// The above can fail because chromeEventHandler is not available for all
// kinds of |this.window|.
}
return window;
},
/**
* Notification observer for the "last-pb-context-exited" topic.
*
@ -2149,7 +2127,7 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
*/
_onWillNavigate: function({ window, isTopLevel }) {
if (isTopLevel) {
this._evalWindow = null;
this._evalGlobal = null;
EventEmitter.off(this.parentActor, "will-navigate", this._onWillNavigate);
this._progressListenerActive = false;
}
@ -2167,8 +2145,8 @@ const WebConsoleActor = ActorClassWithSpec(webconsoleSpec, {
// (pass a copy of the array as it will shift from it)
this.stopListeners(listeners.slice());
// This method is called after this.window is changed,
// so we register new listener on this new window
// This method is called after this.global is changed,
// so we register new listener on this new global
this.startListeners(listeners);
// Also reset the cached top level chrome window being targeted

Просмотреть файл

@ -112,8 +112,7 @@ function isObject(value) {
* An object that holds the following properties:
* - dbg: the debugger where the string was evaluated.
* - frame: (optional) the frame where the string was evaluated.
* - window: the Debugger.Object for the global where the string was
* evaluated.
* - global: the Debugger.Object for the global where the string was evaluated in.
* - result: the result of the evaluation.
* - helperResult: any result coming from a Web Console commands
* function.
@ -128,11 +127,11 @@ exports.evalWithDebugger = function(string, options = {}, webConsole) {
const evalString = getEvalInput(string);
const { frame, dbg } = getFrameDbg(options, webConsole);
const { dbgWindow, bindSelf } = getDbgWindow(options, dbg, webConsole);
const helpers = getHelpers(dbgWindow, options, webConsole);
const { dbgGlobal, bindSelf } = getDbgGlobal(options, dbg, webConsole);
const helpers = getHelpers(dbgGlobal, options, webConsole);
let { bindings, helperCache } = bindCommands(
isCommand(string),
dbgWindow,
dbgGlobal,
bindSelf,
frame,
helpers
@ -156,7 +155,7 @@ exports.evalWithDebugger = function(string, options = {}, webConsole) {
evalOptions.lineNumber = options.lineNumber;
}
updateConsoleInputEvaluation(dbg, dbgWindow, webConsole);
updateConsoleInputEvaluation(dbg, webConsole);
let noSideEffectDebugger = null;
if (options.eager) {
@ -171,7 +170,7 @@ exports.evalWithDebugger = function(string, options = {}, webConsole) {
evalOptions,
bindings,
frame,
dbgWindow,
dbgGlobal,
noSideEffectDebugger
);
} finally {
@ -187,7 +186,7 @@ exports.evalWithDebugger = function(string, options = {}, webConsole) {
// since they may now be stuck in an "initializing" state due to the
// error. Already-initialized bindings will be ignored.
if (!frame && result && "throw" in result) {
parseErrorOutput(dbgWindow, string);
parseErrorOutput(dbgGlobal, string);
}
const { helperResult } = helpers;
@ -203,7 +202,7 @@ exports.evalWithDebugger = function(string, options = {}, webConsole) {
helperResult,
dbg,
frame,
window: dbgWindow,
dbgGlobal,
};
};
@ -213,14 +212,14 @@ function getEvalResult(
evalOptions,
bindings,
frame,
dbgWindow,
dbgGlobal,
noSideEffectDebugger
) {
if (noSideEffectDebugger) {
// Bug 1637883 demonstrated an issue where dbgWindow was somehow in the
// Bug 1637883 demonstrated an issue where dbgGlobal was somehow in the
// same compartment as the Debugger, meaning it could not be debugged
// and thus cannot handle eager evaluation. In that case we skip execution.
if (!noSideEffectDebugger.hasDebuggee(dbgWindow.unsafeDereference())) {
if (!noSideEffectDebugger.hasDebuggee(dbgGlobal.unsafeDereference())) {
return null;
}
@ -228,7 +227,7 @@ function getEvalResult(
// in the context of that debugger in order for the side-effect tracking
// to apply.
frame = frame ? noSideEffectDebugger.adoptFrame(frame) : null;
dbgWindow = noSideEffectDebugger.adoptDebuggeeValue(dbgWindow);
dbgGlobal = noSideEffectDebugger.adoptDebuggeeValue(dbgGlobal);
if (bindings) {
bindings = Object.keys(bindings).reduce((acc, key) => {
acc[key] = noSideEffectDebugger.adoptDebuggeeValue(bindings[key]);
@ -241,7 +240,7 @@ function getEvalResult(
if (frame) {
result = frame.evalWithBindings(string, bindings, evalOptions);
} else {
result = dbgWindow.executeInGlobalWithBindings(
result = dbgGlobal.executeInGlobalWithBindings(
string,
bindings,
evalOptions
@ -258,7 +257,7 @@ function getEvalResult(
return result;
}
function parseErrorOutput(dbgWindow, string) {
function parseErrorOutput(dbgGlobal, string) {
// Reflect is not usable in workers, so return early to avoid logging an error
// to the console when loading it.
if (isWorker) {
@ -320,7 +319,7 @@ function parseErrorOutput(dbgWindow, string) {
}
for (const name of identifiers) {
dbgWindow.forceLexicalInitializationByName(name);
dbgGlobal.forceLexicalInitializationByName(name);
}
}
}
@ -454,7 +453,7 @@ function nativeHasNoSideEffects(fn) {
return natives && natives.some(n => fn.isSameNative(n));
}
function updateConsoleInputEvaluation(dbg, dbgWindow, webConsole) {
function updateConsoleInputEvaluation(dbg, webConsole) {
// Adopt webConsole._lastConsoleInputEvaluation value in the new debugger,
// to prevent "Debugger.Object belongs to a different Debugger" exceptions
// related to the $_ bindings if the debugger object is changed from the
@ -513,8 +512,8 @@ function getFrameDbg(options, webConsole) {
);
}
function getDbgWindow(options, dbg, webConsole) {
let evalWindow = webConsole.evalWindow;
function getDbgGlobal(options, dbg, webConsole) {
let evalGlobal = webConsole.evalGlobal;
if (options.innerWindowID) {
const window = Services.wm.getCurrentInnerWindowWithId(
@ -522,16 +521,16 @@ function getDbgWindow(options, dbg, webConsole) {
);
if (window) {
evalWindow = window;
evalGlobal = window;
}
}
const dbgWindow = dbg.makeGlobalObjectReference(evalWindow);
const dbgGlobal = dbg.makeGlobalObjectReference(evalGlobal);
// If we have an object to bind to |_self|, create a Debugger.Object
// referring to that object, belonging to dbg.
if (!options.selectedObjectActor) {
return { bindSelf: null, dbgWindow };
return { bindSelf: null, dbgGlobal };
}
// For objects related to console messages, they will be registered under the Target Actor
@ -542,25 +541,25 @@ function getDbgWindow(options, dbg, webConsole) {
webConsole.parentActor.getActorByID(options.selectedObjectActor);
if (!actor) {
return { bindSelf: null, dbgWindow };
return { bindSelf: null, dbgGlobal };
}
const jsVal = actor instanceof LongStringActor ? actor.str : actor.rawValue();
if (!isObject(jsVal)) {
return { bindSelf: jsVal, dbgWindow };
return { bindSelf: jsVal, dbgGlobal };
}
// If we use the makeDebuggeeValue method of jsVal's own global, then
// we'll get a D.O that sees jsVal as viewed from its own compartment -
// that is, without wrappers. The evalWithBindings call will then wrap
// jsVal appropriately for the evaluation compartment.
const bindSelf = dbgWindow.makeDebuggeeValue(jsVal);
return { bindSelf, dbgWindow };
const bindSelf = dbgGlobal.makeDebuggeeValue(jsVal);
return { bindSelf, dbgGlobal };
}
function getHelpers(dbgWindow, options, webConsole) {
// Get the Web Console commands for the given debugger window.
const helpers = webConsole._getWebConsoleCommands(dbgWindow);
function getHelpers(dbgGlobal, options, webConsole) {
// Get the Web Console commands for the given debugger global.
const helpers = webConsole._getWebConsoleCommands(dbgGlobal);
if (options.selectedNodeActor) {
const actor = webConsole.conn.getActor(options.selectedNodeActor);
if (actor) {
@ -582,7 +581,7 @@ function cleanupBindings(bindings, helperCache) {
}
}
function bindCommands(isCmd, dbgWindow, bindSelf, frame, helpers) {
function bindCommands(isCmd, dbgGlobal, bindSelf, frame, helpers) {
const bindings = helpers.sandbox;
if (bindSelf) {
bindings._self = bindSelf;
@ -605,7 +604,7 @@ function bindCommands(isCmd, dbgWindow, bindSelf, frame, helpers) {
}
} else {
helpersToDisable = availableHelpers.filter(
name => !!dbgWindow.getOwnPropertyDescriptor(name)
name => !!dbgGlobal.getOwnPropertyDescriptor(name)
);
}
// if we do not have the command key as a prefix, screenshot is disabled by default

Просмотреть файл

@ -552,7 +552,7 @@ WebConsoleCommands._registerOriginal("cd", function(owner, window) {
Services.console.logMessage(scriptError);
if (!window) {
owner.consoleActor.evalWindow = null;
owner.consoleActor.evalGlobal = null;
owner.helperResult = { type: "cd" };
return;
}
@ -571,7 +571,7 @@ WebConsoleCommands._registerOriginal("cd", function(owner, window) {
return;
}
owner.consoleActor.evalWindow = window;
owner.consoleActor.evalGlobal = window;
owner.helperResult = { type: "cd" };
});

Просмотреть файл

@ -83,7 +83,7 @@ this.addEventListener("message", function(event) {
actorID: packet.id,
// threadActor is needed from the webconsole for grip previewing
threadActor,
window: global,
workerGlobal: global,
onThreadAttached() {
postMessage(JSON.stringify({ type: "attached" }));