Bug 1586201 - Add a function to get a nodeFront from a ContentDomReference. r=pbro,jdescottes.

A function is added on the walker actor that creates a NodeFront
from a ContentDomReference, e.g. an object containing a browsingContextId
and a unique DOM element identifier.
A trait is added on the walker actor since the ContentDomReference API was
only added in Firefox 69.
We then add a function on the toolbox that can return a NodeFront from a
element grip.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nicolas Chevobbe 2019-10-18 09:07:05 +00:00
parent ac6ad6abfb
commit 43250917b0
3 changed files with 97 additions and 1 deletions

View File

@ -171,6 +171,16 @@ loader.lazyRequireGetter(
true
);
// ContentDOMReference requires ChromeUtils, which isn't available in worker context.
if (!isWorker) {
loader.lazyRequireGetter(
this,
"ContentDOMReference",
"resource://gre/modules/ContentDOMReference.jsm",
true
);
}
loader.lazyServiceGetter(
this,
"eventListenerService",
@ -372,7 +382,10 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
return {
actor: this.actorID,
root: this.rootNode.form(),
traits: {},
traits: {
// Firefox 71: getNodeActorFromContentDomReference is available.
retrieveNodeFromContentDomReference: true,
},
};
},
@ -2653,6 +2666,24 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
return this.attachElement(win.frameElement);
},
/**
* Given a contentDomReference return the NodeActor for the corresponding frameElement.
*/
getNodeActorFromContentDomReference: function(contentDomReference) {
let rawNode = ContentDOMReference.resolve(contentDomReference);
if (!rawNode || !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);
},
/**
* Given a StyleSheetActor (identified by its ID), commonly used in the
* style-editor, get its ownerNode and return the corresponding walker's

View File

@ -182,6 +182,21 @@ class WalkerFront extends FrontClassWithSpec(walkerSpec) {
});
}
getNodeActorFromContentDomReference(contentDomReference) {
if (!this.traits.retrieveNodeFromContentDomReference) {
console.error(
"The server is too old to retrieve a node from a contentDomReference"
);
return Promise.resolve(null);
}
return super
.getNodeActorFromContentDomReference(contentDomReference)
.then(response => {
return response ? response.node : null;
});
}
getStyleSheetOwnerNode(styleSheetActorID) {
return super.getStyleSheetOwnerNode(styleSheetActorID).then(response => {
return response ? response.node : null;
@ -640,6 +655,48 @@ class InspectorFront extends FrontClassWithSpec(inspectorSpec) {
const remoteInspectors = await this.getChildInspectors();
return [this, ...remoteInspectors];
}
/**
* Given a node grip, return a NodeFront on the right context.
*
* @param {Object} grip: The node grip.
* @returns {Promise<NodeFront|null>} A promise that resolves with a NodeFront or null
* if the NodeFront couldn't be created/retrieved.
*/
async getNodeFrontFromNodeGrip(grip) {
const gripHasContentDomReference = "contentDomReference" in grip;
if (!gripHasContentDomReference) {
// Backward compatibility ( < Firefox 71):
// If the grip does not have a contentDomReference, we can't know in which browsing
// context id the node lives. We fall back on gripToNodeFront that might retrieve
// the expected nodeFront.
return this.walker.gripToNodeFront(grip);
}
const { contentDomReference } = grip;
const { browsingContextId } = contentDomReference;
// If the grip lives in the same browsing context id than the current one, we can
// directly use the current walker.
// TODO: When Bug 1578745 lands, we might want to force using `this.walker` as well
// when the new pref is set to false.
if (this.targetFront.browsingContextID === browsingContextId) {
return this.walker.getNodeActorFromContentDomReference(
contentDomReference
);
}
// If the contentDomReference has a different browsing context than the current one,
// we are either in Fission or in the Omniscient Browser Toolbox, so we need to
// retrieve the walker of the BrowsingContextTarget.
const descriptor = await this.targetFront.client.mainRoot.getBrowsingContextDescriptor(
browsingContextId
);
const target = await descriptor.getTarget();
const { walker } = await target.getFront("inspector");
return walker.getNodeActorFromContentDomReference(contentDomReference);
}
}
exports.InspectorFront = InspectorFront;

View File

@ -306,6 +306,14 @@ const walkerSpec = generateActorSpec({
nodeFront: RetVal("nullable:disconnectedNode"),
},
},
getNodeActorFromContentDomReference: {
request: {
contentDomReference: Arg(0, "json"),
},
response: {
nodeFront: RetVal("nullable:disconnectedNode"),
},
},
getStyleSheetOwnerNode: {
request: {
styleSheetActorID: Arg(0, "string"),