From 8923476caf686dbd0663ce9338effc42688a344b Mon Sep 17 00:00:00 2001 From: Gabriel Luong Date: Fri, 26 Jul 2019 21:40:12 +0000 Subject: [PATCH] Bug 1539764 - Add a targetFront attribute to the Front class to retrieve the target front. r=ochameau Differential Revision: https://phabricator.services.mozilla.com/D39130 --HG-- extra : moz-landing-system : lando --- .../framework/test/browser_target_get-front.js | 30 +++++++++++++++++++++- devtools/shared/fronts/targets/target-mixin.js | 5 ++-- devtools/shared/protocol/Front.js | 4 +++ devtools/shared/protocol/types.js | 14 +++++++--- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/devtools/client/framework/test/browser_target_get-front.js b/devtools/client/framework/test/browser_target_get-front.js index a749e7d8ca0a..925d99c3d7da 100644 --- a/devtools/client/framework/test/browser_target_get-front.js +++ b/devtools/client/framework/test/browser_target_get-front.js @@ -3,8 +3,8 @@ add_task(async function() { gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser); - const tab = await addTab("about:blank"); + const tab = await addTab("about:blank"); const target = await TargetFactory.forTab(tab); await target.attach(); @@ -12,6 +12,14 @@ add_task(async function() { const target2 = await TargetFactory.forTab(tab2); await target2.attach(); + info("Test the targetFront attribute for the root"); + const { client } = target; + is( + client.mainRoot.targetFront, + null, + "got null from the targetFront attribute for the root" + ); + info("Test getting a front twice"); const getAccessibilityFront = await target.getFront("accessibility"); const getAccessibilityFront2 = await target.getFront("accessibility"); @@ -20,6 +28,16 @@ add_task(async function() { getAccessibilityFront2, "got the same front when calling getFront twice" ); + is( + getAccessibilityFront.targetFront, + target, + "got the correct targetFront attribute from the front" + ); + is( + getAccessibilityFront2.targetFront, + target, + "got the correct targetFront attribute from the front" + ); info("Test getting a front on different targets"); const target1Front = await target.getFront("accessibility"); @@ -29,6 +47,16 @@ add_task(async function() { true, "got different fronts when calling getFront on different targets" ); + is( + target1Front.targetFront !== target2Front.targetFront, + true, + "got different targetFront from different fronts from different targets" + ); + is( + target2Front.targetFront, + target2, + "got the correct targetFront attribute from the front" + ); info("Test async front retrieval"); // use two fronts that are initialized one after the other. diff --git a/devtools/shared/fronts/targets/target-mixin.js b/devtools/shared/fronts/targets/target-mixin.js index 07475692667c..4eedea7f0a83 100644 --- a/devtools/shared/fronts/targets/target-mixin.js +++ b/devtools/shared/fronts/targets/target-mixin.js @@ -202,7 +202,8 @@ function TargetMixin(parentClass) { this._inspector = await getFront( this.client, "inspector", - this.targetForm + this.targetForm, + this ); this.emit("inspector", this._inspector); return this._inspector; @@ -229,7 +230,7 @@ function TargetMixin(parentClass) { ) { return front; } - front = getFront(this.client, typeName, this.targetForm); + front = getFront(this.client, typeName, this.targetForm, this); this.fronts.set(typeName, front); // replace the placeholder with the instance of the front once it has loaded front = await front; diff --git a/devtools/shared/protocol/Front.js b/devtools/shared/protocol/Front.js index 839a5543fc4a..d63cd9d25a6d 100644 --- a/devtools/shared/protocol/Front.js +++ b/devtools/shared/protocol/Front.js @@ -40,6 +40,9 @@ class Front extends Pool { constructor(conn = null) { super(conn); this.actorID = null; + // The targetFront attribute represents the debuggable context. Only target-scoped + // fronts and their children fronts will have the targetFront attribute set. + this.targetFront = null; this._requests = []; // Front listener functions registered via `onFront` get notified @@ -71,6 +74,7 @@ class Front extends Pool { super.destroy(); this.clearEvents(); this.actorID = null; + this.targetFront = null; this._frontListeners = null; this._beforeListeners = null; } diff --git a/devtools/shared/protocol/types.js b/devtools/shared/protocol/types.js index 191e5f241722..9334e69f4047 100644 --- a/devtools/shared/protocol/types.js +++ b/devtools/shared/protocol/types.js @@ -317,7 +317,6 @@ types.addActorType = function(name) { let front = ctx.conn.getActor(actorID); if (!front) { // If front isn't instantiated yet, create one. - // Try lazy loading front if not already loaded. // The front module will synchronously call `FrontClassWithSpec` and // augment `type` with the `frontClass` attribute. @@ -330,7 +329,11 @@ types.addActorType = function(name) { const Class = type.frontClass; front = new Class(ctx.conn); front.actorID = actorID; - ctx.marshallPool().manage(front); + const parentFront = ctx.marshallPool(); + // If this is a child of a target-scoped front, propagate the target front to the + // child front that it manages. + front.targetFront = parentFront.targetFront; + parentFront.manage(front); } // When the type `${name}#actorid` is used, `v` is a string refering to the @@ -490,8 +493,11 @@ exports.registerFront = function(cls) { * @param json form * If we want to instantiate a global actor's front, this is the root front's form, * otherwise we are instantiating a target-scoped front from the target front's form. + * @param [Target|null] target + * If we are instantiating a target-scoped front, this is a reference to the front's + * Target instance, otherwise this is null. */ -function getFront(client, typeName, form) { +function getFront(client, typeName, form, target = null) { const type = types.getType(typeName); if (!type) { throw new Error(`No spec for front type '${typeName}'.`); @@ -503,6 +509,8 @@ function getFront(client, typeName, form) { // a capital letter for all constructors. const Class = type.frontClass; const instance = new Class(client); + // Set the targetFront for target-scoped fronts. + instance.targetFront = target; const { formAttributeName } = instance; if (!formAttributeName) { throw new Error(`Can't find the form attribute name for ${typeName}`); -- 2.11.4.GIT