Bug 1328553 - Part 1: Add a method to NetmonitorController that waits for requests to finish r?jryans
MozReview-Commit-ID: IP18VjUaYCk
--- a/devtools/client/netmonitor/netmonitor-controller.js
+++ b/devtools/client/netmonitor/netmonitor-controller.js
@@ -313,17 +313,65 @@ var NetMonitorController = {
(this.tabClient.traits.reconfigure || !this._target.isApp);
},
/**
* Open a given source in Debugger
*/
viewSourceInDebugger(sourceURL, sourceLine) {
return this._toolbox.viewSourceInDebugger(sourceURL, sourceLine);
- }
+ },
+
+ /**
+ * Start monitoring all incoming update events about network requests and wait until
+ * a complete info about all requests is received. (We wait for the timings info
+ * explicitly, because that's always the last piece of information that is received.)
+ *
+ * This method is designed to wait for network requests that are issued during a page
+ * load, when retrieving page resources (scripts, styles, images). It has certain
+ * assumptions that can make it unsuitable for other types of network communication:
+ * - it waits for at least one network request to start and finish before returning
+ * - it waits only for request that were issued after it was called. Requests that are
+ * already in mid-flight will be ignored.
+ * - the request start and end times are overlapping. If a new request starts a moment
+ * after the previous one was finished, the wait will be ended in the "interim"
+ * period.
+ * @returns a promise that resolves when the wait is done.
+ * TODO: should be unified with whenDataAvailable in netmonitor-view.js
+ */
+ waitForAllRequestsFinished() {
+ return new Promise(resolve => {
+ // Key is the request id, value is a boolean - is request finished or not?
+ let requests = new Map();
+
+ function onRequest(_, id) {
+ requests.set(id, false);
+ }
+
+ function onTimings(_, id) {
+ requests.set(id, true);
+ maybeResolve();
+ }
+
+ function maybeResolve() {
+ // Have all the requests in the map finished yet?
+ if (![...requests.values()].every(finished => finished)) {
+ return;
+ }
+
+ // All requests are done - unsubscribe from events and resolve!
+ window.off(EVENTS.NETWORK_EVENT, onRequest);
+ window.off(EVENTS.RECEIVED_EVENT_TIMINGS, onTimings);
+ resolve();
+ }
+
+ window.on(EVENTS.NETWORK_EVENT, onRequest);
+ window.on(EVENTS.RECEIVED_EVENT_TIMINGS, onTimings);
+ });
+ },
};
/**
* Functions handling target-related lifetime events.
*/
function TargetEventsHandler() {
this._onTabNavigated = this._onTabNavigated.bind(this);
this._onTabDetached = this._onTabDetached.bind(this);