Bug 1574401 - allow reparenting r=rcaliman,ochameau

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
yulia 2019-10-02 09:49:12 +00:00
parent cd1a3bfb7b
commit 39e4903e66
4 changed files with 63 additions and 7 deletions

View File

@ -67,17 +67,30 @@ const FrameDescriptorActor = ActorClassWithSpec(frameDescriptorSpec, {
return form;
},
getParentID() {
if (this._browsingContext.parent) {
return this._browsingContext.parent.id;
}
// if we are at the top level document for this frame, but
// we need to access the browser element, then we will not
// be able to get the parent id from the browsing context.
// instead, we can get it from the embedderWindowGlobal.
if (this._browsingContext.embedderWindowGlobal) {
return this._browsingContext.embedderWindowGlobal.browsingContext.id;
}
return null;
},
form() {
const url = this._browsingContext.currentWindowGlobal
? this._browsingContext.currentWindowGlobal.documentURI.displaySpec
: null;
const parentID = this.getParentID();
return {
actor: this.actorID,
id: this.id,
url,
parentID: this._browsingContext.parent
? this._browsingContext.parent.id
: null,
parentID,
};
},

View File

@ -2773,6 +2773,22 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
return acc && acc.indexInParent > -1;
},
getEmbedderElement(browsingContextID) {
const browsingContext = BrowsingContext.get(browsingContextID);
let rawNode = browsingContext.embedderElement;
if (!this._isInDOMTree(rawNode)) {
return null;
}
// This is a special case for the document object whereby it is considered
// as document.documentElement (the <html> node)
if (rawNode.defaultView && rawNode === rawNode.defaultView.document) {
rawNode = rawNode.documentElement;
}
return this.attachElement(rawNode);
},
});
exports.WalkerActor = WalkerActor;

View File

@ -453,10 +453,9 @@ class WalkerFront extends FrontClassWithSpec(walkerSpec) {
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;
const remoteTarget = await node.connectToRemoteFrame();
const walker = (await remoteTarget.getFront("inspector")).walker;
// Finally retrieve the NodeFront of the remote frame's document
const documentNode = await walker.getRootNode();
@ -470,6 +469,24 @@ class WalkerFront extends FrontClassWithSpec(walkerSpec) {
hasLast: true,
};
}
async reparentRemoteFrame() {
// Get the parent target, which most likely runs in another process
const descriptorFront = this.targetFront.descriptorFront;
const parentTarget = await descriptorFront.getParentTarget();
// Get the NodeFront for the embedder element
// i.e. the <iframe> element which is hosting the document that
const parentWalker = (await parentTarget.getFront("inspector")).walker;
// As this <iframe> most likely runs in another process, we have to get it through the parent
// target's WalkerFront.
const parentNode = (await parentWalker.getEmbedderElement(
descriptorFront.id
)).node;
// Finally, set this embedder element's node front as the
const documentNode = await this.getRootNode();
documentNode.reparent(parentNode);
}
}
exports.WalkerFront = WalkerFront;
@ -597,7 +614,9 @@ class InspectorFront extends FrontClassWithSpec(inspectorSpec) {
for (const descriptor of frames) {
const remoteTarget = await descriptor.getTarget();
if (remoteTarget) {
// get inspector
const remoteInspectorFront = await remoteTarget.getFront("inspector");
await remoteInspectorFront.walker.reparentRemoteFrame();
childInspectors.push(remoteInspectorFront);
}
}

View File

@ -362,6 +362,14 @@ const walkerSpec = generateActorSpec({
},
response: {},
},
getEmbedderElement: {
request: {
browsingContextID: Arg(0, "string"),
},
response: {
nodeFront: RetVal("disconnectedNode"),
},
},
},
});