Bug 1560200 - Implement very basic markup view support traversing remote frames via resource api. r=ochameau,rcaliman

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
yulia 2019-08-13 11:54:06 +00:00
Родитель 75ce4fd5c6
Коммит 84b0e082f1
5 изменённых файлов: 102 добавлений и 2 удалений

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

@ -2191,13 +2191,18 @@ MarkupView.prototype = {
/**
* Return a list of the children to display for this container.
*/
_getVisibleChildren: function(container, centered) {
_getVisibleChildren: async function(container, centered) {
let maxChildren = container.maxChildren || this.maxChildren;
if (maxChildren == -1) {
maxChildren = undefined;
}
return this.walker.children(container.node, {
// We have to use node's walker and not a top level walker
// as for fission frames, we are going to have multiple walkers
const inspectorFront = await container.node.targetFront.getFront(
"inspector"
);
return inspectorFront.walker.children(container.node, {
maxNodes: maxChildren,
center: centered,
});

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

@ -6,10 +6,12 @@
const { Cu } = require("chrome");
const Services = require("Services");
const ChromeUtils = require("ChromeUtils");
const InspectorUtils = require("InspectorUtils");
const protocol = require("devtools/shared/protocol");
const { PSEUDO_CLASSES } = require("devtools/shared/css/constants");
const { nodeSpec, nodeListSpec } = require("devtools/shared/specs/node");
const { DebuggerServer } = require("devtools/server/debugger-server");
loader.lazyRequireGetter(
this,
@ -143,6 +145,11 @@ const SUBGRID_ENABLED = Services.prefs.getBoolPref(
"layout.css.grid-template-subgrid-value.enabled"
);
const BROWSER_TOOLBOX_FISSION_ENABLED = Services.prefs.getBoolPref(
"devtools.browsertoolbox.fission",
false
);
const FONT_FAMILY_PREVIEW_TEXT = "The quick brown fox jumps over the lazy dog";
const FONT_FAMILY_PREVIEW_TEXT_SIZE = 20;
@ -263,6 +270,13 @@ const NodeActor = protocol.ActorClassWithSpec(nodeSpec, {
form.isDocumentElement = true;
}
// Flag the remote frame and declare at least one child (the #document element) so
// that they can be expanded.
if (this.isRemoteFrame) {
form.remoteFrame = true;
form.numChildren = 1;
}
return form;
},
@ -295,6 +309,19 @@ const NodeActor = protocol.ActorClassWithSpec(nodeSpec, {
this.rawNode.addEventListener("slotchange", this.slotchangeListener);
},
/**
* Check if the current node is representing a remote frame.
* EXPERIMENTAL: Only works if fission is enabled in the toolbox.
*/
get isRemoteFrame() {
return (
this.numChildren == 0 &&
ChromeUtils.getClassName(this.rawNode) == "XULFrameElement" &&
this.rawNode.getAttribute("remote") == "true" &&
BROWSER_TOOLBOX_FISSION_ENABLED
);
},
// Estimate the number of children that the walker will return without making
// a call to children() if possible.
get numChildren() {
@ -671,6 +698,21 @@ const NodeActor = protocol.ActorClassWithSpec(nodeSpec, {
innerHeight: win.innerHeight,
};
},
/**
* Fetch the target actor's form for the current remote frame.
*
* (to be called only if form.remoteFrame is true)
*/
connectToRemoteFrame() {
if (!this.isRemoteFrame) {
return {
error: "ErrorRemoteFrame",
message: "Tried to call `connectToRemoteFrame` on a local frame",
};
}
return DebuggerServer.connectToFrame(this.conn, this.rawNode);
},
});
/**

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

@ -452,6 +452,25 @@ class WalkerFront extends FrontClassWithSpec(walkerSpec) {
nextSibling: nextSibling,
};
}
async children(node, options) {
if (!node.remoteFrame) {
return super.children(node, options);
}
// First get the target actor form of this remote frame element
const target = await node.connectToRemoteFrame();
// Then get an inspector front, and grab its walker front
const walker = (await target.getFront("inspector")).walker;
// Finally retrieve the NodeFront of the remote frame's document
const documentNode = await walker.getRootNode();
// And return the same kind of response `walker.children` returns
return {
nodes: [documentNode],
hasFirst: true,
hasLast: true,
};
}
}
exports.WalkerFront = WalkerFront;

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

@ -20,6 +20,13 @@ loader.lazyRequireGetter(
"devtools/shared/dom-node-constants"
);
loader.lazyRequireGetter(
this,
"BrowsingContextTargetFront",
"devtools/shared/fronts/targets/browsing-context",
true
);
const HIDDEN_CLASS = "__fx-devtools-hide-shortcut__";
/**
@ -273,6 +280,9 @@ class NodeFront extends FrontClassWithSpec(nodeSpec) {
get numChildren() {
return this._form.numChildren;
}
get remoteFrame() {
return this._form.remoteFrame;
}
get hasEventListeners() {
return this._form.hasEventListeners;
}
@ -497,6 +507,20 @@ class NodeFront extends FrontClassWithSpec(nodeSpec) {
}
return actor.rawNode;
}
async connectToRemoteFrame() {
if (this._remoteFrameTarget) {
return this._remoteFrameTarget;
}
// First get the target actor form of this remote frame element
const form = await super.connectToRemoteFrame();
// Build the related Target object
this._remoteFrameTarget = new BrowsingContextTargetFront(this.conn);
this._remoteFrameTarget.actorID = form.actor;
this._remoteFrameTarget.form(form);
this._remoteFrameTarget.manage(this._remoteFrameTarget);
return this._remoteFrameTarget;
}
}
exports.NodeFront = NodeFront;

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

@ -134,6 +134,16 @@ const nodeSpec = generateActorSpec({
request: {},
response: RetVal("windowDimensions"),
},
connectToRemoteFrame: {
request: {},
// We are passing a target actor form here.
// As we are manually fetching the form JSON via DebuggerServer.connectToFrame,
// we are not instanciating a protocol.js front class and can't use proper type
// here and have automatic marshalling.
//
// Alex: Can we do something to address that??
response: RetVal("json"),
},
},
});