зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1084525 - Part 5: Add onNewPromise event handler to PromisesActor r=fitzgen
This commit is contained in:
Родитель
d721f8d0e5
Коммит
22dde4881e
|
@ -24,6 +24,15 @@ types.addType("ObjectActor", {
|
|||
let PromisesActor = protocol.ActorClass({
|
||||
typeName: "promises",
|
||||
|
||||
events: {
|
||||
// Event emitted for new promises allocated in debuggee and bufferred by
|
||||
// sending the list of promise objects in a batch.
|
||||
"new-promises": {
|
||||
type: "new-promises",
|
||||
data: Arg(0, "array:ObjectActor"),
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param conn DebuggerServerConnection.
|
||||
* @param parent TabActor|RootActor
|
||||
|
@ -37,8 +46,10 @@ let PromisesActor = protocol.ActorClass({
|
|||
this._dbg = null;
|
||||
this._gripDepth = 0;
|
||||
this._navigationLifetimePool = null;
|
||||
this._newPromises = null;
|
||||
|
||||
this.objectGrip = this.objectGrip.bind(this);
|
||||
this._makePromiseEventHandler = this._makePromiseEventHandler.bind(this);
|
||||
this._onWindowReady = this._onWindowReady.bind(this);
|
||||
},
|
||||
|
||||
|
@ -66,6 +77,8 @@ let PromisesActor = protocol.ActorClass({
|
|||
this._navigationLifetimePool = this._createActorPool();
|
||||
this.conn.addActorPool(this._navigationLifetimePool);
|
||||
|
||||
this._newPromises = [];
|
||||
|
||||
events.on(this.parent, "window-ready", this._onWindowReady);
|
||||
|
||||
this.state = "attached";
|
||||
|
@ -81,6 +94,7 @@ let PromisesActor = protocol.ActorClass({
|
|||
this.dbg.removeAllDebuggees();
|
||||
this.dbg.enabled = false;
|
||||
this._dbg = null;
|
||||
this._newPromises = null;
|
||||
|
||||
if (this._navigationLifetimePool) {
|
||||
this.conn.removeActorPool(this._navigationLifetimePool);
|
||||
|
@ -110,7 +124,11 @@ let PromisesActor = protocol.ActorClass({
|
|||
* An ObjectActor object that wraps the given Promise object
|
||||
*/
|
||||
_createObjectActorForPromise: function(promise) {
|
||||
let object = new ObjectActor(promise, {
|
||||
if (this._navigationLifetimePool.objectActors.has(promise)) {
|
||||
return this._navigationLifetimePool.objectActors.get(promise);
|
||||
}
|
||||
|
||||
let actor = new ObjectActor(promise, {
|
||||
getGripDepth: () => this._gripDepth,
|
||||
incrementGripDepth: () => this._gripDepth++,
|
||||
decrementGripDepth: () => this._gripDepth--,
|
||||
|
@ -121,8 +139,11 @@ let PromisesActor = protocol.ActorClass({
|
|||
createEnvironmentActor: () => DevToolsUtils.reportException(
|
||||
"PromisesActor", Error("createEnvironmentActor not yet implemented"))
|
||||
});
|
||||
this._navigationLifetimePool.addActor(object);
|
||||
return object;
|
||||
|
||||
this._navigationLifetimePool.addActor(actor);
|
||||
this._navigationLifetimePool.objectActors.set(promise, actor);
|
||||
|
||||
return actor;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -134,15 +155,7 @@ let PromisesActor = protocol.ActorClass({
|
|||
* The grip for the given Promise object
|
||||
*/
|
||||
objectGrip: function(value) {
|
||||
let pool = this._navigationLifetimePool;
|
||||
|
||||
if (pool.objectActors.has(value)) {
|
||||
return pool.objectActors.get(value).grip();
|
||||
}
|
||||
|
||||
let actor = this._createObjectActorForPromise(value);
|
||||
pool.objectActors.set(value, actor);
|
||||
return actor.grip();
|
||||
return this._createObjectActorForPromise(value).grip();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -150,6 +163,8 @@ let PromisesActor = protocol.ActorClass({
|
|||
*/
|
||||
listPromises: method(function() {
|
||||
let promises = this.dbg.findObjects({ class: "Promise" });
|
||||
this.dbg.onNewPromise = this._makePromiseEventHandler(this._newPromises,
|
||||
"new-promises");
|
||||
return promises.map(p => this._createObjectActorForPromise(p));
|
||||
}, {
|
||||
request: {
|
||||
|
@ -159,6 +174,31 @@ let PromisesActor = protocol.ActorClass({
|
|||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Creates an event handler for onNewPromise that will add the new
|
||||
* Promise ObjectActor to the array and schedule it to be emitted as a
|
||||
* batch for the provided event.
|
||||
*
|
||||
* @param array array
|
||||
* The list of Promise ObjectActors to emit
|
||||
* @param string eventName
|
||||
* The event name
|
||||
*/
|
||||
_makePromiseEventHandler: function(array, eventName) {
|
||||
return promise => {
|
||||
let actor = this._createObjectActorForPromise(promise)
|
||||
let needsScheduling = array.length == 0;
|
||||
|
||||
array.push(actor);
|
||||
|
||||
if (needsScheduling) {
|
||||
DevToolsUtils.executeSoon(() => {
|
||||
events.emit(this, eventName, array.splice(0, array.length));
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onWindowReady: expectState("attached", function({ isTopLevel }) {
|
||||
if (!isTopLevel) {
|
||||
return;
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that we can get the list of all new Promise objects from the
|
||||
* PromisesActor onNewPromise event handler.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { PromisesFront } = devtools.require("devtools/server/actors/promises");
|
||||
|
||||
let events = devtools.require("sdk/event/core");
|
||||
|
||||
add_task(function*() {
|
||||
let client = yield startTestDebuggerServer("promises-actor-test");
|
||||
let chromeActors = yield getChromeActors(client);
|
||||
|
||||
ok(Promise.toString().contains("native code"), "Expect native DOM Promise");
|
||||
|
||||
yield testNewPromisesEvent(client, chromeActors,
|
||||
v => new Promise(resolve => resolve(v)));
|
||||
|
||||
let response = yield listTabs(client);
|
||||
let targetTab = findTab(response.tabs, "promises-actor-test");
|
||||
ok(targetTab, "Found our target tab.");
|
||||
|
||||
yield testNewPromisesEvent(client, targetTab, v => {
|
||||
const debuggee = DebuggerServer.getTestGlobal("promises-actor-test");
|
||||
return debuggee.Promise.resolve(v);
|
||||
});
|
||||
|
||||
yield close(client);
|
||||
});
|
||||
|
||||
function* testNewPromisesEvent(client, form, makePromise) {
|
||||
let front = PromisesFront(client, form);
|
||||
let resolution = "MyLittleSecret" + Math.random();
|
||||
let found = false;
|
||||
|
||||
yield front.attach();
|
||||
yield front.listPromises();
|
||||
|
||||
let onNewPromise = new Promise(resolve => {
|
||||
events.on(front, "new-promises", promises => {
|
||||
for (let p of promises) {
|
||||
equal(p.type, "object", "Expect type to be Object");
|
||||
equal(p.class, "Promise", "Expect class to be Promise");
|
||||
|
||||
if (p.promiseState.state === "fulfilled" &&
|
||||
p.promiseState.value === resolution) {
|
||||
found = true;
|
||||
resolve();
|
||||
} else {
|
||||
dump("Found non-target promise\n");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let promise = makePromise(resolution);
|
||||
|
||||
yield onNewPromise;
|
||||
ok(found, "Found our new promise");
|
||||
yield front.detach();
|
||||
// Appease eslint
|
||||
void promise;
|
||||
}
|
|
@ -83,6 +83,7 @@ support-files =
|
|||
[test_promises_actor_attach.js]
|
||||
[test_promises_actor_exist.js]
|
||||
[test_promises_actor_list_promises.js]
|
||||
[test_promises_actor_onnewpromise.js]
|
||||
[test_protocol_abort.js]
|
||||
[test_protocol_async.js]
|
||||
[test_protocol_children.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче