Bug 1411889 - Record netmonitor reload time. r=Honza draft
authorAlexandre Poirot <poirot.alex@gmail.com>
Thu, 16 Nov 2017 01:37:46 -0800
changeset 701138 03e09e71ce0ca9e9aae2bd6c4dd7957404285ad7
parent 701134 a8885c780eae50a7957ed8bf7aebc856920e9b1d
child 741099 26981c2e08299ccbae2939810c924e39715d13ca
push id90083
push userbmo:poirot.alex@gmail.com
push dateTue, 21 Nov 2017 08:53:01 +0000
reviewersHonza
bugs1411889
milestone59.0a1
Bug 1411889 - Record netmonitor reload time. r=Honza MozReview-Commit-ID: EwXuODxvm8B
devtools/client/framework/toolbox.js
devtools/client/netmonitor/index.html
devtools/client/netmonitor/panel.js
devtools/client/netmonitor/src/connector/firefox-connector.js
devtools/client/netmonitor/src/connector/firefox-data-provider.js
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -1984,18 +1984,18 @@ Toolbox.prototype = {
     });
   },
 
   /**
    * Fired when user just started navigating away to another web page.
    */
   async _onWillNavigate() {
     let toolId = this.currentToolId;
-    // For now, only inspector and webconsole fires "reloaded" event
-    if (toolId != "inspector" && toolId != "webconsole") {
+    // For now, only inspector, webconsole and netmonitor fire "reloaded" event
+    if (toolId != "inspector" && toolId != "webconsole" && toolId != "netmonitor") {
       return;
     }
 
     let start = this.win.performance.now();
     let panel = this.getPanel(toolId);
     // Ignore the timing if the panel is still loading
     if (!panel) {
       return;
--- a/devtools/client/netmonitor/index.html
+++ b/devtools/client/netmonitor/index.html
@@ -40,24 +40,25 @@
       const store = configureStore(connector);
       const actions = bindActionCreators(require("./src/actions/index"), store.dispatch);
 
       // Inject to global window for testing
       window.store = store;
       window.connector = connector;
 
       window.Netmonitor = {
-        bootstrap({ toolbox }) {
+        bootstrap({ toolbox, panel }) {
           this.mount = document.querySelector("#mount");
 
           const connection = {
             tabConnection: {
               tabTarget: toolbox.target,
             },
             toolbox,
+            panel,
           };
 
           const openLink = (link) => {
             let parentDoc = toolbox.doc;
             let iframe = parentDoc.getElementById("toolbox-panel-iframe-netmonitor");
             let top = iframe.ownerDocument.defaultView.top;
             top.openUILinkIn(link, "tab");
           };
--- a/devtools/client/netmonitor/panel.js
+++ b/devtools/client/netmonitor/panel.js
@@ -11,16 +11,17 @@ function NetMonitorPanel(iframeWindow, t
 
 NetMonitorPanel.prototype = {
   async open() {
     if (!this.toolbox.target.isRemote) {
       await this.toolbox.target.makeRemote();
     }
     await this.panelWin.Netmonitor.bootstrap({
       toolbox: this.toolbox,
+      panel: this,
     });
     this.emit("ready");
     this.isReady = true;
     return this;
   },
 
   async destroy() {
     await this.panelWin.Netmonitor.destroy();
--- a/devtools/client/netmonitor/src/connector/firefox-connector.js
+++ b/devtools/client/netmonitor/src/connector/firefox-connector.js
@@ -10,16 +10,17 @@ const { ACTIVITY_TYPE, EVENTS } = requir
 const FirefoxDataProvider = require("./firefox-data-provider");
 
 class FirefoxConnector {
   constructor() {
     // Public methods
     this.connect = this.connect.bind(this);
     this.disconnect = this.disconnect.bind(this);
     this.willNavigate = this.willNavigate.bind(this);
+    this.navigate = this.navigate.bind(this);
     this.displayCachedEvents = this.displayCachedEvents.bind(this);
     this.onDocLoadingMarker = this.onDocLoadingMarker.bind(this);
     this.sendHTTPRequest = this.sendHTTPRequest.bind(this);
     this.setPreferences = this.setPreferences.bind(this);
     this.triggerActivity = this.triggerActivity.bind(this);
     this.getTabTarget = this.getTabTarget.bind(this);
     this.viewSourceInDebugger = this.viewSourceInDebugger.bind(this);
     this.requestData = this.requestData.bind(this);
@@ -29,32 +30,34 @@ class FirefoxConnector {
     this.getNetworkRequest = this.getNetworkRequest.bind(this);
   }
 
   async connect(connection, actions, getState) {
     this.actions = actions;
     this.getState = getState;
     this.tabTarget = connection.tabConnection.tabTarget;
     this.toolbox = connection.toolbox;
+    this.panel = connection.panel;
 
     this.webConsoleClient = this.tabTarget.activeConsole;
 
     this.dataProvider = new FirefoxDataProvider({
       webConsoleClient: this.webConsoleClient,
       actions: this.actions,
     });
 
     this.addListeners();
 
     // Listener for `will-navigate` event is (un)registered outside
     // of the `addListeners` and `removeListeners` methods since
     // these are used to pause/resume the connector.
     // Paused network panel should be automatically resumed when page
     // reload, so `will-navigate` listener needs to be there all the time.
     this.tabTarget.on("will-navigate", this.willNavigate);
+    this.tabTarget.on("navigate", this.navigate);
 
     // Don't start up waiting for timeline markers if the server isn't
     // recent enough to emit the markers we're interested in.
     if (this.tabTarget.getTrait("documentLoadingMarkers")) {
       this.timelineFront = new TimelineFront(this.tabTarget.client, this.tabTarget.form);
       this.timelineFront.on("doc-loading", this.onDocLoadingMarker);
       await this.timelineFront.start({ withDocLoadingEvents: true });
     }
@@ -115,16 +118,35 @@ class FirefoxConnector {
 
     // Resume is done automatically on page reload/navigation.
     let state = this.getState();
     if (!state.requests.recording) {
       this.actions.toggleRecording();
     }
   }
 
+  navigate() {
+    if (this.dataProvider.isPayloadQueueEmpty()) {
+      this.onReloaded();
+      return;
+    }
+    let listener = () => {
+      if (!this.dataProvider.isPayloadQueueEmpty()) {
+        return;
+      }
+      window.off(EVENTS.PAYLOAD_READY, listener);
+      this.onReloaded();
+    };
+    window.on(EVENTS.PAYLOAD_READY, listener);
+  }
+
+  onReloaded() {
+    this.panel.emit("reloaded");
+  }
+
   /**
    * Display any network events already in the cache.
    */
   displayCachedEvents() {
     for (let networkInfo of this.webConsoleClient.getNetworkEvents()) {
       // First add the request to the timeline.
       this.dataProvider.onNetworkEvent("networkEvent", networkInfo);
       // Then replay any updates already received.
--- a/devtools/client/netmonitor/src/connector/firefox-data-provider.js
+++ b/devtools/client/netmonitor/src/connector/firefox-data-provider.js
@@ -227,16 +227,25 @@ class FirefoxDataProvider {
    * @param {string} id request id
    * @return {boolean} return a queued payload item from queue.
    */
   getRequestFromQueue(id) {
     return this.payloadQueue.find((item) => item.id === id);
   }
 
   /**
+   * Public API used by the Toolbox: Tells if there is still any pending request.
+   *
+   * @return {boolean} returns true if the payload queue is empty
+   */
+  isPayloadQueueEmpty() {
+    return this.payloadQueue.length === 0;
+  }
+
+  /**
    * Return true if payload is ready (all data fetched from the backend)
    *
    * @param {string} id request id
    * @return {boolean} return whether a specific networkEvent has been updated completely.
    */
   isRequestPayloadReady(id) {
     let record = this.rdpRequestMap.get(id);
     if (!record) {