Bug 1497393 Part 7 - Server side changes for inspector support while replaying, r=pbro.

Differential Revision: https://phabricator.services.mozilla.com/D22863

--HG--
extra : rebase_source : 1069a8534dd79e1d2cf309c9d3f3c27079077087
extra : histedit_source : 1a750a022d46da836181f913d012081ea608da7f
This commit is contained in:
Brian Hackett 2019-03-09 16:45:50 -10:00
Родитель c27709d468
Коммит f4af857cef
8 изменённых файлов: 77 добавлений и 20 удалений

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

@ -19,6 +19,8 @@ const {
getCSSStyleRules,
} = require("devtools/shared/inspector/css-logic");
const InspectorUtils = require("InspectorUtils");
const Debugger = require("Debugger");
const ReplayInspector = require("devtools/server/actors/replay/inspector");
// Set up a dummy environment so that EventUtils works. We need to be careful to
// pass a window object into each EventUtils method we call rather than having
@ -299,6 +301,11 @@ var TestActor = exports.TestActor = protocol.ActorClassWithSpec(testSpec, {
},
get content() {
// When replaying, the content window is in the replaying process. We can't
// use isReplaying here because this actor is loaded into its own sandbox.
if (Debugger.recordReplayProcessKind() == "Middleman") {
return ReplayInspector.window;
}
return this.targetActor.window;
},
@ -475,6 +482,20 @@ var TestActor = exports.TestActor = protocol.ActorClassWithSpec(testSpec, {
return regions;
},
/**
* Get the window which mouse events on node should be delivered to.
*/
windowForMouseEvent: function(node) {
// When replaying, the node is a proxy for an element in the replaying
// process. Use the window which the server is running against, which is
// able to receive events. We can't use isReplaying here because this actor
// is loaded into its own sandbox.
if (Debugger.recordReplayProcessKind() == "Middleman") {
return this.targetActor.window;
}
return node.ownerDocument.defaultView;
},
/**
* Synthesize a mouse event on an element, after ensuring that it is visible
* in the viewport. This handler doesn't send a message back. Consumers
@ -491,9 +512,9 @@ var TestActor = exports.TestActor = protocol.ActorClassWithSpec(testSpec, {
const node = this._querySelector(selector);
node.scrollIntoView();
if (center) {
EventUtils.synthesizeMouseAtCenter(node, options, node.ownerDocument.defaultView);
EventUtils.synthesizeMouseAtCenter(node, options, this.windowForMouseEvent(node));
} else {
EventUtils.synthesizeMouse(node, x, y, options, node.ownerDocument.defaultView);
EventUtils.synthesizeMouse(node, x, y, options, this.windowForMouseEvent(node));
}
},

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

@ -10,6 +10,7 @@ const ChromeUtils = require("ChromeUtils");
const EventEmitter = require("devtools/shared/event-emitter");
const protocol = require("devtools/shared/protocol");
const Services = require("Services");
const ReplayInspector = require("devtools/server/actors/replay/inspector");
const { highlighterSpec, customHighlighterSpec } = require("devtools/shared/specs/highlighters");
loader.lazyRequireGetter(this, "isWindowIncluded", "devtools/shared/layout/utils", true);
@ -377,7 +378,9 @@ exports.HighlighterActor = protocol.ActorClassWithSpec(highlighterSpec, {
// originalTarget allows access to the "real" element before any retargeting
// is applied, such as in the case of XBL anonymous elements. See also
// https://developer.mozilla.org/docs/XBL/XBL_1.0_Reference/Anonymous_Content#Event_Flow_and_Targeting
const node = event.originalTarget || event.target;
const node = isReplaying
? ReplayInspector.findEventTarget(event)
: (event.originalTarget || event.target);
return this._walker.attachElement(node);
},

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

@ -6,6 +6,7 @@
const { Cu } = require("chrome");
const EventEmitter = require("devtools/shared/event-emitter");
const ReplayInspector = require("devtools/server/actors/replay/inspector");
const { isNodeValid } = require("./utils/markup");
const { getAdjustedQuads, getWindowDimensions } = require("devtools/shared/layout/utils");
@ -81,7 +82,9 @@ AutoRefreshHighlighter.prototype = {
_ignoreZoom: false,
/**
* Window corresponding to the current highlighterEnv
* Window corresponding to the current highlighterEnv. When replaying, this
* will be the window against which the server is running, which is different
* from the window containing the target content.
*/
get win() {
if (!this.highlighterEnv) {
@ -90,6 +93,11 @@ AutoRefreshHighlighter.prototype = {
return this.highlighterEnv.window;
},
/* Window containing the target content. */
get contentWindow() {
return isReplaying ? ReplayInspector.window : this.win;
},
/**
* Show the highlighter on a given node
* @param {DOMNode} node
@ -178,7 +186,7 @@ AutoRefreshHighlighter.prototype = {
for (const region of BOX_MODEL_REGIONS) {
this.currentQuads[region] = getAdjustedQuads(
this.win,
this.contentWindow,
this.currentNode, region, {ignoreZoom: this._ignoreZoom});
}
},
@ -276,7 +284,7 @@ AutoRefreshHighlighter.prototype = {
},
_startRefreshLoop: function() {
const win = this.currentNode.ownerGlobal;
const win = isReplaying ? this.win : this.currentNode.ownerGlobal;
this.rafID = win.requestAnimationFrame(this._startRefreshLoop.bind(this));
this.rafWin = win;
this.update();

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

@ -6,6 +6,8 @@
const {Cc, Ci, Cu} = require("chrome");
const ReplayInspector = require("devtools/server/actors/replay/inspector");
loader.lazyRequireGetter(this, "isShadowRoot", "devtools/shared/layout/utils", true);
loader.lazyRequireGetter(this, "nodeFilterConstants", "devtools/shared/dom-node-filter-constants");
loader.lazyRequireGetter(this, "standardTreeWalkerFilter", "devtools/server/actors/inspector/utils", true);
@ -48,8 +50,12 @@ function DocumentWalker(node, rootWin,
throw new Error("Got an invalid root window in DocumentWalker");
}
if (isReplaying) {
this.walker = ReplayInspector.newDeepTreeWalker();
} else {
this.walker = Cc["@mozilla.org/inspector/deep-tree-walker;1"]
.createInstance(Ci.inIDeepTreeWalker);
}
this.walker.showAnonymousContent = showAnonymousContent;
this.walker.showSubDocuments = true;
this.walker.showDocumentsAsNodes = true;

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

@ -16,6 +16,7 @@ const {
isNativeAnonymous,
} = require("devtools/shared/layout/utils");
const Debugger = require("Debugger");
const ReplayInspector = require("devtools/server/actors/replay/inspector");
// eslint-disable-next-line
const JQUERY_LIVE_REGEX = /return typeof \w+.*.event\.triggered[\s\S]*\.event\.(dispatch|handle).*arguments/;
@ -252,17 +253,18 @@ class MainEventCollector {
* An array of unfiltered event listeners or an empty array
*/
getDOMListeners(node) {
const els = isReplaying ? ReplayInspector.els : Services.els;
if (typeof node.nodeName !== "undefined" && node.nodeName.toLowerCase() === "html") {
const winListeners =
Services.els.getListenerInfoFor(node.ownerGlobal) || [];
els.getListenerInfoFor(node.ownerGlobal) || [];
const docElementListeners =
Services.els.getListenerInfoFor(node) || [];
els.getListenerInfoFor(node) || [];
const docListeners =
Services.els.getListenerInfoFor(node.parentNode) || [];
els.getListenerInfoFor(node.parentNode) || [];
return [...winListeners, ...docElementListeners, ...docListeners];
}
return Services.els.getListenerInfoFor(node) || [];
return els.getListenerInfoFor(node) || [];
}
getJQuery(node) {
@ -870,13 +872,19 @@ class EventCollector {
try {
const { capturing, handler } = listener;
let listenerDO;
if (isReplaying) {
listenerDO = ReplayInspector.getDebuggerObject(handler);
} else {
const global = Cu.getGlobalForObject(handler);
// It is important that we recreate the globalDO for each handler because
// their global object can vary e.g. resource:// URLs on a video control. If
// we don't do this then all chrome listeners simply display "native code."
globalDO = dbg.addDebuggee(global);
let listenerDO = globalDO.makeDebuggeeValue(handler);
listenerDO = globalDO.makeDebuggeeValue(handler);
}
const { normalizeListener } = listener;

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

@ -54,6 +54,7 @@ const Services = require("Services");
const protocol = require("devtools/shared/protocol");
const {LongStringActor} = require("devtools/server/actors/string");
const defer = require("devtools/shared/defer");
const ReplayInspector = require("devtools/server/actors/replay/inspector");
const {inspectorSpec} = require("devtools/shared/specs/inspector");
@ -95,7 +96,7 @@ exports.InspectorActor = protocol.ActorClassWithSpec(inspectorSpec, {
},
get window() {
return this.targetActor.window;
return isReplaying ? ReplayInspector.window : this.targetActor.window;
},
getWalker: function(options = {}) {

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

@ -11,6 +11,7 @@ const protocol = require("devtools/shared/protocol");
const {walkerSpec} = require("devtools/shared/specs/inspector");
const {LongStringActor} = require("devtools/server/actors/string");
const InspectorUtils = require("InspectorUtils");
const ReplayInspector = require("devtools/server/actors/replay/inspector");
loader.lazyRequireGetter(this, "getFrameElement", "devtools/shared/layout/utils", true);
loader.lazyRequireGetter(this, "isAfterPseudoElement", "devtools/shared/layout/utils", true);
@ -134,7 +135,7 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
initialize: function(conn, targetActor, options) {
protocol.Actor.prototype.initialize.call(this, conn);
this.targetActor = targetActor;
this.rootWin = targetActor.window;
this.rootWin = isReplaying ? ReplayInspector.window : targetActor.window;
this.rootDoc = this.rootWin.document;
this._refMap = new Map();
this._pendingMutations = [];

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

@ -18,6 +18,8 @@ loader.lazyRequireGetter(this, "setIgnoreLayoutChanges", "devtools/server/actors
exports.setIgnoreLayoutChanges = (...args) =>
this.setIgnoreLayoutChanges(...args);
const ReplayInspector = require("devtools/server/actors/replay/inspector");
/**
* Returns the `DOMWindowUtils` for the window given.
*
@ -780,6 +782,13 @@ exports.getViewportDimensions = getViewportDimensions;
* @return {DOMWindow}
*/
function getWindowFor(node) {
// Check if we are replaying, as the tests below don't work when inspecting
// nodes in another process.
if (isReplaying) {
// Multiple windows are not supported yet when replaying, so return the
// global window.
return ReplayInspector.window;
}
if (Node.isInstance(node)) {
if (node.nodeType === node.DOCUMENT_NODE) {
return node.defaultView;