Bug 1588730 - Ensure calling form() before calling notifying onFront listeners. r=jdescottes

You can listen for fronts creation via `parentFront.onFront(typeName, callback)`.
For now, we were calling `callback` before we pass the `form` to Front.
This leads to empty attributes as the Front doesn't have access to any data.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Alexandre Poirot 2019-10-15 15:56:18 +00:00
parent dc833aabf2
commit f5ed7d3556
3 changed files with 29 additions and 8 deletions

View File

@ -24,6 +24,7 @@ const ChildActor = protocol.ActorClassWithSpec(childSpec, {
return {
actor: this.actorID,
childID: this.childID,
foo: "bar",
};
},
});
@ -69,6 +70,7 @@ const RootActor = protocol.ActorClassWithSpec(rootSpec, {
class ChildFront extends protocol.FrontClassWithSpec(childSpec) {
form(form) {
this.childID = form.childID;
this.foo = form.foo;
}
}
protocol.registerFront(ChildFront);
@ -94,6 +96,11 @@ add_task(async function run_test() {
const fronts = [];
rootFront.onFront("childActor", front => {
equal(
front.foo,
"bar",
"Front's form is set before onFront listeners are called"
);
fronts.push(front);
});

View File

@ -76,7 +76,7 @@ class Front extends Pool {
this._beforeListeners = null;
}
async manage(front) {
async manage(front, form, ctx) {
if (!front.actorID) {
throw new Error(
"Can't manage front without an actor ID.\n" +
@ -91,6 +91,15 @@ class Front extends Pool {
await front.initialize();
}
// Ensure calling form() *before* notifying about this front being just created.
// We exprect the front to be fully initialized, especially via its form attributes.
// But do that *after* calling manage() so that the front is already registered
// in Pools and can be fetched by its ID, in case a child actor, created in form()
// tries to get a reference to its parent via the actor ID.
if (form) {
front.form(form, ctx);
}
// Call listeners registered via `onFront` method
this._frontListeners.emit(front.typeName, front);
}

View File

@ -316,6 +316,15 @@ types.addActorType = function(name) {
const actorID = typeof v === "string" ? v : v.actor;
// `ctx.conn` is a DebuggerClient
let front = ctx.conn.getFrontByID(actorID);
// When the type `${name}#actorid` is used, `v` is a string refering to the
// actor ID. We cannot read form information in this case and the actorID was
// already set when creating the front, so no need to do anything.
let form = null;
if (detail != "actorid") {
form = identityWrite(v);
}
if (!front) {
// If front isn't instantiated yet, create one.
// Try lazy loading front if not already loaded.
@ -333,14 +342,10 @@ types.addActorType = function(name) {
const Class = type.frontClass;
front = new Class(ctx.conn, targetFront, parentFront);
front.actorID = actorID;
parentFront.manage(front);
}
// When the type `${name}#actorid` is used, `v` is a string refering to the
// actor ID. We only set the actorID just before and so do not need anything else.
if (detail != "actorid") {
v = identityWrite(v);
front.form(v, ctx);
parentFront.manage(front, form, ctx);
} else if (form) {
front.form(form, ctx);
}
return front;