diff --git a/browser/components/extensions/test/browser/browser_ext_devtools_network.js b/browser/components/extensions/test/browser/browser_ext_devtools_network.js index f7b1589c19e2..b54681fa4868 100644 --- a/browser/components/extensions/test/browser/browser_ext_devtools_network.js +++ b/browser/components/extensions/test/browser/browser_ext_devtools_network.js @@ -76,11 +76,15 @@ function devtools_page() { browser.devtools.network.onRequestFinished.removeListener(requestFinishedListener); }; + browser.devtools.network.onRequestFinished.addListener(requestFinishedListener); +} - browser.test.onMessage.addListener(msg => { - if (msg === "addOnRequestFinishedListener") { - browser.devtools.network.onRequestFinished.addListener(requestFinishedListener); - } +function waitForRequestAdded(toolbox) { + return new Promise(resolve => { + let netPanel = toolbox.getPanel("netmonitor"); + netPanel.panelWin.once("NetMonitor:RequestAdded", () => { + resolve(); + }); }); } @@ -104,26 +108,6 @@ let extData = { }, }; -function waitForRequestAdded(toolbox) { - return new Promise(async resolve => { - let netPanel = await toolbox.getNetMonitorAPI(); - netPanel.once("NetMonitor:RequestAdded", () => { - resolve(); - }); - }); -} - -async function navigateToolboxTarget(extension, toolbox) { - extension.sendMessage("navigate"); - - // Wait till the navigation is complete. - await Promise.all([ - extension.awaitMessage("tabUpdated"), - extension.awaitMessage("onNavigatedFired"), - waitForRequestAdded(toolbox), - ]); -} - /** * Test for `chrome.devtools.network.onNavigate()` API */ @@ -178,14 +162,35 @@ add_task(async function test_devtools_network_get_har() { let toolbox = await gDevTools.showToolbox(target, "webconsole"); info("Developer toolbox opened."); - // Get HAR, it should be empty since no data collected yet. + // Get HAR, it should be empty since the Net panel wasn't selected. const getHAREmptyPromise = extension.awaitMessage("getHAR-result"); extension.sendMessage("getHAR"); const getHAREmptyResult = await getHAREmptyPromise; is(getHAREmptyResult.entries.length, 0, "HAR log should be empty"); + // Select the Net panel. + await toolbox.selectTool("netmonitor"); + + // Get HAR again, it should be empty because the Panel is selected + // but no data collected yet. + const getHAREmptyPromiseWithPanel = extension.awaitMessage("getHAR-result"); + extension.sendMessage("getHAR"); + const emptyResultWithPanel = await getHAREmptyPromiseWithPanel; + is(emptyResultWithPanel.entries.length, 0, "HAR log should be empty"); + // Reload the page to collect some HTTP requests. - await navigateToolboxTarget(extension, toolbox); + extension.sendMessage("navigate"); + + // Wait till the navigation is complete and request + // added into the net panel. + await Promise.all([ + extension.awaitMessage("tabUpdated"), + extension.awaitMessage("onNavigatedFired"), + extension.awaitMessage("onRequestFinished"), + extension.awaitMessage("onRequestFinished-callbackExecuted"), + extension.awaitMessage("onRequestFinished-promiseResolved"), + waitForRequestAdded(toolbox), + ]); // Get HAR, it should not be empty now. const getHARPromise = extension.awaitMessage("getHAR-result"); @@ -193,17 +198,6 @@ add_task(async function test_devtools_network_get_har() { const getHARResult = await getHARPromise; is(getHARResult.entries.length, 1, "HAR log should not be empty"); - // Select the Net panel and reload page again. - await toolbox.selectTool("netmonitor"); - await navigateToolboxTarget(extension, toolbox); - - // Get HAR again, it should not be empty even if - // the Network panel is selected now. - const getHAREmptyPromiseWithPanel = extension.awaitMessage("getHAR-result"); - extension.sendMessage("getHAR"); - const emptyResultWithPanel = await getHAREmptyPromiseWithPanel; - is(emptyResultWithPanel.entries.length, 1, "HAR log should not be empty"); - // Shutdown await gDevTools.closeToolbox(target); @@ -223,23 +217,25 @@ add_task(async function test_devtools_network_on_request_finished() { await extension.startup(); await extension.awaitMessage("ready"); + let target = gDevTools.getTargetForTab(tab); // Open the Toolbox - let toolbox = await gDevTools.showToolbox(target, "webconsole"); + let toolbox = await gDevTools.showToolbox(target, "netmonitor"); info("Developer toolbox opened."); - // Wait the extension to subscribe the onRequestFinished listener. - await extension.sendMessage("addOnRequestFinishedListener"); + // Reload and wait for onRequestFinished event. + extension.sendMessage("navigate"); - // Reload the page - await navigateToolboxTarget(extension, toolbox); + await Promise.all([ + extension.awaitMessage("tabUpdated"), + extension.awaitMessage("onNavigatedFired"), + waitForRequestAdded(toolbox), + ]); - info("Wait for an onRequestFinished event"); await extension.awaitMessage("onRequestFinished"); // Wait for response content being fetched. - info("Wait for request.getBody results"); let [callbackRes, promiseRes] = await Promise.all([ extension.awaitMessage("onRequestFinished-callbackExecuted"), extension.awaitMessage("onRequestFinished-promiseResolved"), @@ -249,6 +245,7 @@ add_task(async function test_devtools_network_on_request_finished() { "The expected content has been retrieved."); is(callbackRes[1], "text/html; charset=utf-8", "The expected content has been retrieved."); + is(promiseRes[0], callbackRes[0], "The resolved value is equal to the one received in the callback API mode"); is(promiseRes[1], callbackRes[1], diff --git a/devtools/client/framework/toolbox.js b/devtools/client/framework/toolbox.js index 33ee4822f3d6..802fc16cab6a 100644 --- a/devtools/client/framework/toolbox.js +++ b/devtools/client/framework/toolbox.js @@ -74,8 +74,6 @@ loader.lazyRequireGetter(this, "buildHarLog", "devtools/client/netmonitor/src/har/har-builder-utils", true); loader.lazyRequireGetter(this, "getKnownDeviceFront", "devtools/shared/fronts/device", true); -loader.lazyRequireGetter(this, "NetMonitorAPI", - "devtools/client/netmonitor/src/api", true); loader.lazyGetter(this, "domNodeConstants", () => { return require("devtools/shared/dom-node-constants"); @@ -118,12 +116,14 @@ function Toolbox(target, selectedTool, hostType, contentWindow, frameId) { this._initInspector = null; this._inspector = null; this._styleSheets = null; - this._netMonitorAPI = null; // Map of frames (id => frame-info) and currently selected frame id. this.frameMap = new Map(); this.selectedFrameId = null; + // List of listeners for `devtools.network.onRequestFinished` WebExt API + this._requestFinishedListeners = new Set(); + this._toolRegistered = this._toolRegistered.bind(this); this._toolUnregistered = this._toolUnregistered.bind(this); this._onWillNavigate = this._onWillNavigate.bind(this); @@ -2687,6 +2687,7 @@ Toolbox.prototype = { this._sourceMapURLService.destroy(); this._sourceMapURLService = null; } + if (this._sourceMapService) { this._sourceMapService.stopSourceMapWorker(); this._sourceMapService = null; @@ -2784,11 +2785,6 @@ Toolbox.prototype = { // target. deferred.resolve(settleAll(outstanding) .catch(console.error) - .then(() => { - let api = this._netMonitorAPI; - this._netMonitorAPI = null; - return api ? api.destroy() : null; - }, console.error) .then(() => { this._removeHostListeners(); @@ -3048,39 +3044,22 @@ Toolbox.prototype = { // Support for WebExtensions API (`devtools.network.*`) - /** - * Return Netmonitor API object. This object offers Network monitor - * public API that can be consumed by other panels or WE API. - */ - getNetMonitorAPI: async function() { - let netPanel = this.getPanel("netmonitor"); - - // Return Net panel if it exists. - if (netPanel) { - return netPanel.panelWin.Netmonitor.api; - } - - if (this._netMonitorAPI) { - return this._netMonitorAPI; - } - - // Create and initialize Network monitor API object. - // This object is only connected to the backend - not to the UI. - this._netMonitorAPI = new NetMonitorAPI(); - await this._netMonitorAPI.connect(this); - - return this._netMonitorAPI; - }, - /** * Returns data (HAR) collected by the Network panel. */ getHARFromNetMonitor: async function() { - let netMonitor = await this.getNetMonitorAPI(); - let har = await netMonitor.getHar(); + let netPanel = this.getPanel("netmonitor"); - // Return default empty HAR file if needed. - har = har || buildHarLog(Services.appinfo); + // The panel doesn't have to exist (it must be selected + // by the user at least once to be created). + // Return default empty HAR log in such case. + if (!netPanel) { + let har = await buildHarLog(Services.appinfo); + return har.log; + } + + // Use Netmonitor object to get the current HAR log. + let har = await netPanel.panelWin.Netmonitor.getHar(); // Return the log directly to be compatible with // Chrome WebExtension API. @@ -3095,26 +3074,24 @@ Toolbox.prototype = { * a function that takes ({harEntry, requestId}) * as first argument. */ - addRequestFinishedListener: async function(listener) { - let netMonitor = await this.getNetMonitorAPI(); - netMonitor.addRequestFinishedListener(listener); + addRequestFinishedListener: function(listener) { + // Log console message informing the extension developer + // that the Network panel needs to be selected at least + // once in order to receive `onRequestFinished` events. + let message = "The Network panel needs to be selected at least" + + " once in order to receive 'onRequestFinished' events."; + this.target.logWarningInPage(message, "har"); + + // Add the listener into internal list. + this._requestFinishedListeners.add(listener); }, - removeRequestFinishedListener: async function(listener) { - let netMonitor = await this.getNetMonitorAPI(); - netMonitor.removeRequestFinishedListener(listener); + removeRequestFinishedListener: function(listener) { + this._requestFinishedListeners.delete(listener); + }, - // Destroy Network monitor API object if the following is true: - // 1) there is no listener - // 2) the Net panel doesn't exist/use the API object (if the panel - // exists it's also responsible for destroying it, - // see `NetMonitorPanel.open` for more details) - let netPanel = this.getPanel("netmonitor"); - let hasListeners = netMonitor.hasRequestFinishedListeners(); - if (this._netMonitorAPI && !hasListeners && !netPanel) { - this._netMonitorAPI.destroy(); - this._netMonitorAPI = null; - } + getRequestFinishedListeners: function() { + return this._requestFinishedListeners; }, /** @@ -3125,9 +3102,17 @@ Toolbox.prototype = { * Id of the request for which the response content * should be fetched. */ - fetchResponseContent: async function(requestId) { - let netMonitor = await this.getNetMonitorAPI(); - return netMonitor.fetchResponseContent(requestId); + fetchResponseContent: function(requestId) { + let netPanel = this.getPanel("netmonitor"); + + // The panel doesn't have to exist (it must be selected + // by the user at least once to be created). + // Return undefined content in such case. + if (!netPanel) { + return Promise.resolve({content: {}}); + } + + return netPanel.panelWin.Netmonitor.fetchResponseContent(requestId); }, // Support management of installed WebExtensions that provide a devtools_page. diff --git a/devtools/client/netmonitor/initializer.js b/devtools/client/netmonitor/initializer.js index f5baf9e45691..3eeb467fee96 100644 --- a/devtools/client/netmonitor/initializer.js +++ b/devtools/client/netmonitor/initializer.js @@ -1,7 +1,6 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* exported initialize */ "use strict"; @@ -17,52 +16,185 @@ const require = window.windowRequire = BrowserLoader({ window, }).require; -const { NetMonitorAPI } = require("./src/api"); -const { NetMonitorApp } = require("./src/app"); const EventEmitter = require("devtools/shared/event-emitter"); +const { createFactory } = require("devtools/client/shared/vendor/react"); +const { render, unmountComponentAtNode } = require("devtools/client/shared/vendor/react-dom"); +const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider); +const { bindActionCreators } = require("devtools/client/shared/vendor/redux"); +const { Connector } = require("./src/connector/index"); +const { configureStore } = require("./src/create-store"); +const App = createFactory(require("./src/components/App")); +const { EVENTS } = require("./src/constants"); +const { + getDisplayedRequestById, + getSortedRequests +} = require("./src/selectors/index"); // Inject EventEmitter into global window. EventEmitter.decorate(window); -/** - * This is the initialization point for the Network monitor. - * - * @param {Object} api Allows reusing existing API object. - */ -function initialize(api) { - const app = new NetMonitorApp(api); +// Configure store/state object. +let connector = new Connector(); +const store = configureStore(connector); +const actions = bindActionCreators(require("./src/actions/index"), store.dispatch); - // Inject to global window for testing - window.Netmonitor = app; - window.api = api; - window.store = app.api.store; - window.connector = app.api.connector; - window.actions = app.api.actions; - - return app; -} +// Inject to global window for testing +window.store = store; +window.connector = connector; +window.actions = actions; /** - * The following code is used to open Network monitor in a tab. - * Like the Launchpad, but without Launchpad. - * - * For example: - * chrome://devtools/content/netmonitor/index.html?type=process - * loads the netmonitor for the parent process, exactly like the - * one in the browser toolbox - * - * It's also possible to connect to a tab. - * 1) go in about:debugging - * 2) In menu Tabs, click on a Debug button for particular tab - * - * This will open an about:devtools-toolbox url, from which you can - * take type and id query parameters and reuse them for the chrome url - * of the netmonitor - * - * chrome://devtools/content/netmonitor/index.html?type=tab&id=1234 URLs - * where 1234 is the tab id, you can retrieve from about:debugging#tabs links. - * Simply copy the id from about:devtools-toolbox?type=tab&id=1234 URLs. + * Global Netmonitor object in this panel. This object can be consumed + * by other panels (e.g. Console is using inspectRequest), by the + * Launchpad (bootstrap), WebExtension API (getHAR), etc. */ +window.Netmonitor = { + bootstrap({ toolbox, panel }) { + this.mount = document.querySelector("#mount"); + this.toolbox = toolbox; + + 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.openWebLinkIn(link, "tab"); + }; + + const openSplitConsole = (err) => { + toolbox.openSplitConsole().then(() => { + toolbox.target.logErrorInPage(err, "har"); + }); + }; + + this.onRequestAdded = this.onRequestAdded.bind(this); + window.on(EVENTS.REQUEST_ADDED, this.onRequestAdded); + + // Render the root Application component. + const sourceMapService = toolbox.sourceMapURLService; + const app = App({ + actions, + connector, + openLink, + openSplitConsole, + sourceMapService + }); + render(Provider({ store }, app), this.mount); + + // Connect to the Firefox backend by default. + return connector.connectFirefox(connection, actions, store.getState); + }, + + destroy() { + unmountComponentAtNode(this.mount); + window.off(EVENTS.REQUEST_ADDED, this.onRequestAdded); + return connector.disconnect(); + }, + + // Support for WebExtensions API + + /** + * Support for `devtools.network.getHAR` (get collected data as HAR) + */ + getHar() { + let { HarExporter } = require("devtools/client/netmonitor/src/har/har-exporter"); + let state = store.getState(); + + let options = { + connector, + items: getSortedRequests(state), + // Always generate HAR log even if there are no requests. + forceExport: true, + }; + + return HarExporter.getHar(options); + }, + + /** + * Support for `devtools.network.onRequestFinished`. A hook for + * every finished HTTP request used by WebExtensions API. + */ + onRequestAdded(requestId) { + let listeners = this.toolbox.getRequestFinishedListeners(); + if (!listeners.size) { + return; + } + + let { HarExporter } = require("devtools/client/netmonitor/src/har/har-exporter"); + let options = { + connector, + includeResponseBodies: false, + items: [getDisplayedRequestById(store.getState(), requestId)], + }; + + // Build HAR for specified request only. + HarExporter.getHar(options).then(har => { + let harEntry = har.log.entries[0]; + delete harEntry.pageref; + listeners.forEach(listener => listener({ + harEntry, + requestId, + })); + }); + }, + + /** + * Support for `Request.getContent` WebExt API (lazy loading response body) + */ + fetchResponseContent(requestId) { + return connector.requestData(requestId, "responseContent"); + }, + + /** + * Selects the specified request in the waterfall and opens the details view. + * This is a firefox toolbox specific API, which providing an ability to inspect + * a network request directly from other internal toolbox panel. + * + * @param {string} requestId The actor ID of the request to inspect. + * @return {object} A promise resolved once the task finishes. + */ + inspectRequest(requestId) { + // Look for the request in the existing ones or wait for it to appear, if + // the network monitor is still loading. + return new Promise((resolve) => { + let request = null; + let inspector = () => { + request = getDisplayedRequestById(store.getState(), requestId); + if (!request) { + // Reset filters so that the request is visible. + actions.toggleRequestFilterType("all"); + request = getDisplayedRequestById(store.getState(), requestId); + } + + // If the request was found, select it. Otherwise this function will be + // called again once new requests arrive. + if (request) { + window.off(EVENTS.REQUEST_ADDED, inspector); + actions.selectRequest(request.id); + resolve(); + } + }; + + inspector(); + + if (!request) { + window.on(EVENTS.REQUEST_ADDED, inspector); + } + }); + } +}; + +// Implement support for: +// chrome://devtools/content/netmonitor/index.html?type=tab&id=1234 URLs +// where 1234 is the tab id, you can retrieve from about:debugging#tabs links. +// Simply copy the id from about:devtools-toolbox?type=tab&id=1234 URLs. // URL constructor doesn't support chrome: scheme let href = window.location.href.replace(/chrome:/, "http://"); @@ -90,13 +222,7 @@ if (window.location.protocol === "chrome:" && url.search.length > 1) { } }; - let api = new NetMonitorAPI(); - await api.connect(toolbox); - let app = window.initialize(api); - app.bootstrap({ - toolbox, - document: window.document, - }); + window.Netmonitor.bootstrap({ toolbox }); } catch (err) { window.alert("Unable to start the network monitor:" + err); } diff --git a/devtools/client/netmonitor/panel.js b/devtools/client/netmonitor/panel.js index 1cb9d81db007..ff3a084f1216 100644 --- a/devtools/client/netmonitor/panel.js +++ b/devtools/client/netmonitor/panel.js @@ -14,22 +14,12 @@ NetMonitorPanel.prototype = { if (!this.toolbox.target.isRemote) { await this.toolbox.target.makeRemote(); } - - // Reuse an existing Network monitor API object if available. - // It could have been created for WE API before Net panel opens. - let api = await this.toolbox.getNetMonitorAPI(); - let app = this.panelWin.initialize(api); - - // Connect the application object to the UI. - await app.bootstrap({ + await this.panelWin.Netmonitor.bootstrap({ toolbox: this.toolbox, - document: this.panelWin.document, + panel: this, }); - - // Ready to go! this.emit("ready"); this.isReady = true; - return this; }, diff --git a/devtools/client/netmonitor/src/api.js b/devtools/client/netmonitor/src/api.js deleted file mode 100644 index 2a7a888ef27e..000000000000 --- a/devtools/client/netmonitor/src/api.js +++ /dev/null @@ -1,197 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const EventEmitter = require("devtools/shared/event-emitter"); - -const { bindActionCreators } = require("devtools/client/shared/vendor/redux"); -const { Connector } = require("./connector/index"); -const { configureStore } = require("./create-store"); -const { EVENTS } = require("./constants"); -const Actions = require("./actions/index"); - -const { - getDisplayedRequestById, - getSortedRequests -} = require("./selectors/index"); - -/** - * API object for NetMonitor panel (like a facade). This object can be - * consumed by other panels, WebExtension API, etc. - * - * This object doesn't depend on the panel UI and can be created - * and used even if the Network panel UI doesn't exist. - */ -function NetMonitorAPI() { - EventEmitter.decorate(this); - - // Connector to the backend. - this.connector = new Connector(); - - // Configure store/state object. - this.store = configureStore(this.connector); - - // List of listeners for `devtools.network.onRequestFinished` WebExt API - this._requestFinishedListeners = new Set(); - - // Bind event handlers - this.onRequestAdded = this.onRequestAdded.bind(this); - this.actions = bindActionCreators(Actions, this.store.dispatch); -} - -NetMonitorAPI.prototype = { - async connect(toolbox) { - // Bail out if already connected. - if (this.toolbox) { - return; - } - - this.toolbox = toolbox; - - // Register listener for new requests (utilized by WebExtension API). - this.on(EVENTS.REQUEST_ADDED, this.onRequestAdded); - - // Initialize connection to the backend. Pass `this` as the owner, - // so this object can receive all emitted events. - const connection = { - tabConnection: { - tabTarget: toolbox.target, - }, - toolbox, - owner: this, - }; - - await this.connectBackend(this.connector, connection, this.actions, - this.store.getState); - }, - - /** - * Clean up (unmount from DOM, remove listeners, disconnect). - */ - async destroy() { - this.off(EVENTS.REQUEST_ADDED, this.onRequestAdded); - - await this.connector.disconnect(); - - if (this.harExportConnector) { - await this.harExportConnector.disconnect(); - } - }, - - /** - * Connect to the Firefox backend by default. - * - * As soon as connections to different back-ends is supported - * this function should be responsible for picking the right API. - */ - async connectBackend(connector, connection, actions, getState) { - // The connection might happen during Toolbox initialization - // so make sure the target is ready. - await connection.tabConnection.tabTarget.makeRemote(); - return connector.connectFirefox(connection, actions, getState); - }, - - // HAR - - /** - * Support for `devtools.network.getHAR` (get collected data as HAR) - */ - async getHar() { - let { HarExporter } = require("devtools/client/netmonitor/src/har/har-exporter"); - let state = this.store.getState(); - - let options = { - connector: this.connector, - items: getSortedRequests(state), - }; - - return HarExporter.getHar(options); - }, - - /** - * Support for `devtools.network.onRequestFinished`. A hook for - * every finished HTTP request used by WebExtensions API. - */ - async onRequestAdded(requestId) { - if (!this._requestFinishedListeners.size) { - return; - } - - let { HarExporter } = require("devtools/client/netmonitor/src/har/har-exporter"); - - let connector = await this.getHarExportConnector(); - let request = getDisplayedRequestById(this.store.getState(), requestId); - if (!request) { - console.error("HAR: request not found " + requestId); - return; - } - - let options = { - connector, - includeResponseBodies: false, - items: [request], - }; - - let har = await HarExporter.getHar(options); - - // There is page so remove the page reference. - let harEntry = har.log.entries[0]; - delete harEntry.pageref; - - this._requestFinishedListeners.forEach(listener => listener({ - harEntry, - requestId, - })); - }, - - /** - * Support for `Request.getContent` WebExt API (lazy loading response body) - */ - async fetchResponseContent(requestId) { - return this.connector.requestData(requestId, "responseContent"); - }, - - /** - * Add listener for `onRequestFinished` events. - * - * @param {Object} listener - * The listener to be called it's expected to be - * a function that takes ({harEntry, requestId}) - * as first argument. - */ - addRequestFinishedListener: function(listener) { - this._requestFinishedListeners.add(listener); - }, - - removeRequestFinishedListener: function(listener) { - this._requestFinishedListeners.delete(listener); - }, - - hasRequestFinishedListeners: function() { - return this._requestFinishedListeners.size > 0; - }, - - /** - * Separate connector for HAR export. - */ - async getHarExportConnector() { - if (this.harExportConnector) { - return this.harExportConnector; - } - - const connection = { - tabConnection: { - tabTarget: this.toolbox.target, - }, - toolbox: this.toolbox, - }; - - this.harExportConnector = new Connector(); - await this.connectBackend(this.harExportConnector, connection); - return this.harExportConnector; - }, -}; - -exports.NetMonitorAPI = NetMonitorAPI; diff --git a/devtools/client/netmonitor/src/app.js b/devtools/client/netmonitor/src/app.js deleted file mode 100644 index 8f7524981957..000000000000 --- a/devtools/client/netmonitor/src/app.js +++ /dev/null @@ -1,124 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const { createFactory } = require("devtools/client/shared/vendor/react"); -const { render, unmountComponentAtNode } = require("devtools/client/shared/vendor/react-dom"); -const Provider = createFactory(require("devtools/client/shared/vendor/react-redux").Provider); -const App = createFactory(require("./components/App")); -const { EVENTS } = require("./constants"); - -const { - getDisplayedRequestById, -} = require("./selectors/index"); - -/** - * Global App object for Network panel. This object depends - * on the UI and can't be created independently. - * - * This object can be consumed by other panels (e.g. Console - * is using inspectRequest), by the Launchpad (bootstrap), etc. - * - * @param {Object} api An existing API object to be reused. - */ -function NetMonitorApp(api) { - this.api = api; -} - -NetMonitorApp.prototype = { - async bootstrap({ toolbox, document }) { - // Get the root element for mounting. - this.mount = document.querySelector("#mount"); - - 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"); - }; - - const openSplitConsole = (err) => { - toolbox.openSplitConsole().then(() => { - toolbox.target.logErrorInPage(err, "har"); - }); - }; - - let { - actions, - connector, - store, - } = this.api; - - const sourceMapService = toolbox.sourceMapURLService; - const app = App({ - actions, - connector, - openLink, - openSplitConsole, - sourceMapService - }); - - // Render the root Application component. - render(Provider({ store: store }, app), this.mount); - }, - - /** - * Clean up (unmount from DOM, remove listeners, disconnect). - */ - async destroy() { - unmountComponentAtNode(this.mount); - - // Make sure to destroy the API object. It's usually destroyed - // in the Toolbox destroy method, but we need it here for case - // where the Network panel is initialized without the toolbox - // and running in a tab (see initialize.js for details). - await this.api.destroy(); - }, - - /** - * Selects the specified request in the waterfall and opens the details view. - * This is a firefox toolbox specific API, which providing an ability to inspect - * a network request directly from other internal toolbox panel. - * - * @param {string} requestId The actor ID of the request to inspect. - * @return {object} A promise resolved once the task finishes. - */ - async inspectRequest(requestId) { - let { - actions, - store, - } = this.api; - - // Look for the request in the existing ones or wait for it to appear, - // if the network monitor is still loading. - return new Promise((resolve) => { - let request = null; - let inspector = () => { - request = getDisplayedRequestById(store.getState(), requestId); - if (!request) { - // Reset filters so that the request is visible. - actions.toggleRequestFilterType("all"); - request = getDisplayedRequestById(store.getState(), requestId); - } - - // If the request was found, select it. Otherwise this function will be - // called again once new requests arrive. - if (request) { - this.api.off(EVENTS.REQUEST_ADDED, inspector); - actions.selectRequest(request.id); - resolve(); - } - }; - - inspector(); - - if (!request) { - this.api.on(EVENTS.REQUEST_ADDED, inspector); - } - }); - } -}; - -exports.NetMonitorApp = NetMonitorApp; diff --git a/devtools/client/netmonitor/src/connector/chrome-connector.js b/devtools/client/netmonitor/src/connector/chrome-connector.js index 6f406c702ba9..4e18ddff6172 100644 --- a/devtools/client/netmonitor/src/connector/chrome-connector.js +++ b/devtools/client/netmonitor/src/connector/chrome-connector.js @@ -98,4 +98,4 @@ class ChromeConnector { } } -module.exports = ChromeConnector; +module.exports = new ChromeConnector(); diff --git a/devtools/client/netmonitor/src/connector/firefox-connector.js b/devtools/client/netmonitor/src/connector/firefox-connector.js index 078c861ce66e..e7b450e59755 100644 --- a/devtools/client/netmonitor/src/connector/firefox-connector.js +++ b/devtools/client/netmonitor/src/connector/firefox-connector.js @@ -35,28 +35,18 @@ class FirefoxConnector { this.getNetworkRequest = this.getNetworkRequest.bind(this); } - /** - * Connect to the backend. - * - * @param {Object} connection object with e.g. reference to the Toolbox. - * @param {Object} actions (optional) is used to fire Redux actions to update store. - * @param {Object} getState (optional) is used to get access to the state. - */ async connect(connection, actions, getState) { this.actions = actions; this.getState = getState; this.tabTarget = connection.tabConnection.tabTarget; this.toolbox = connection.toolbox; - - // The owner object (NetMonitorAPI) received all events. - this.owner = connection.owner; + this.panel = connection.panel; this.webConsoleClient = this.tabTarget.activeConsole; this.dataProvider = new FirefoxDataProvider({ webConsoleClient: this.webConsoleClient, actions: this.actions, - owner: this.owner, }); await this.addListeners(); @@ -66,32 +56,25 @@ class FirefoxConnector { // 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. - if (this.tabTarget) { - this.tabTarget.on("will-navigate", this.willNavigate); - this.tabTarget.on("navigate", this.navigate); - } + this.tabTarget.on("will-navigate", this.willNavigate); + this.tabTarget.on("navigate", this.navigate); - // Displaying cache events is only intended for the UI panel. - if (this.actions) { - this.displayCachedEvents(); - } + this.displayCachedEvents(); } async disconnect() { - if (this.actions) { - this.actions.batchReset(); - } + this.actions.batchReset(); await this.removeListeners(); if (this.tabTarget) { - this.tabTarget.off("will-navigate", this.willNavigate); - this.tabTarget.off("navigate", this.navigate); + this.tabTarget.off("will-navigate"); this.tabTarget = null; } this.webConsoleClient = null; this.dataProvider = null; + this.panel = null; } async pause() { @@ -149,22 +132,18 @@ class FirefoxConnector { } willNavigate() { - if (this.actions) { - if (!Services.prefs.getBoolPref("devtools.netmonitor.persistlog")) { - this.actions.batchReset(); - this.actions.clearRequests(); - } else { - // If the log is persistent, just clear all accumulated timing markers. - this.actions.clearTimingMarkers(); - } + if (!Services.prefs.getBoolPref("devtools.netmonitor.persistlog")) { + this.actions.batchReset(); + this.actions.clearRequests(); + } else { + // If the log is persistent, just clear all accumulated timing markers. + this.actions.clearTimingMarkers(); } // Resume is done automatically on page reload/navigation. - if (this.actions && this.getState) { - let state = this.getState(); - if (!state.requests.recording) { - this.actions.toggleRecording(); - } + let state = this.getState(); + if (!state.requests.recording) { + this.actions.toggleRecording(); } } @@ -177,24 +156,19 @@ class FirefoxConnector { if (this.dataProvider && !this.dataProvider.isPayloadQueueEmpty()) { return; } - if (this.owner) { - this.owner.off(EVENTS.PAYLOAD_READY, listener); - } + window.off(EVENTS.PAYLOAD_READY, listener); // Netmonitor may already be destroyed, // so do not try to notify the listeners if (this.dataProvider) { this.onReloaded(); } }; - if (this.owner) { - this.owner.on(EVENTS.PAYLOAD_READY, listener); - } + window.on(EVENTS.PAYLOAD_READY, listener); } onReloaded() { - let panel = this.toolbox.getPanel("netmonitor"); - if (panel) { - panel.emit("reloaded"); + if (this.panel) { + this.panel.emit("reloaded"); } } @@ -230,12 +204,8 @@ class FirefoxConnector { "dom-interactive" : "dom-complete", time: marker.unixTime / 1000 }; - - if (this.actions) { - this.actions.addTimingMarker(event); - } - - this.emit(EVENTS.TIMELINE_EVENT, event); + this.actions.addTimingMarker(event); + window.emit(EVENTS.TIMELINE_EVENT, event); } /** @@ -246,11 +216,8 @@ class FirefoxConnector { * @param {object} marker */ onDocEvent(event) { - if (this.actions) { - this.actions.addTimingMarker(event); - } - - this.emit(EVENTS.TIMELINE_EVENT, event); + this.actions.addTimingMarker(event); + window.emit(EVENTS.TIMELINE_EVENT, event); } /** @@ -404,22 +371,9 @@ class FirefoxConnector { } getTimingMarker(name) { - if (!this.getState) { - return -1; - } - let state = this.getState(); return getDisplayedTimingMarker(state, name); } - - /** - * Fire events for the owner object. - */ - emit(type, data) { - if (this.owner) { - this.owner.emit(type, data); - } - } } -module.exports = FirefoxConnector; +module.exports = new FirefoxConnector(); diff --git a/devtools/client/netmonitor/src/connector/firefox-data-provider.js b/devtools/client/netmonitor/src/connector/firefox-data-provider.js index ea1dee933901..99885d84644c 100644 --- a/devtools/client/netmonitor/src/connector/firefox-data-provider.js +++ b/devtools/client/netmonitor/src/connector/firefox-data-provider.js @@ -18,19 +18,11 @@ const { fetchHeaders } = require("../utils/request-utils"); * or not. */ class FirefoxDataProvider { - /** - * Constructor for data provider - * - * @param {Object} webConcoleClient represents the client object for Console actor. - * @param {Object} actions set of actions fired during data fetching process - * @params {Object} owner all events are fired on this object - */ - constructor({webConsoleClient, actions, owner}) { + constructor({webConsoleClient, actions}) { // Options this.webConsoleClient = webConsoleClient; - this.actions = actions || {}; + this.actions = actions; this.actionsEnabled = true; - this.owner = owner; // Internal properties this.payloadQueue = new Map(); @@ -92,7 +84,7 @@ class FirefoxDataProvider { }, true); } - this.emit(EVENTS.REQUEST_ADDED, id); + emit(EVENTS.REQUEST_ADDED, id); } /** @@ -322,7 +314,7 @@ class FirefoxDataProvider { url, }); - this.emit(EVENTS.NETWORK_EVENT, actor); + emit(EVENTS.NETWORK_EVENT, actor); } /** @@ -349,7 +341,7 @@ class FirefoxDataProvider { statusText: networkInfo.response.statusText, headersSize: networkInfo.response.headersSize }); - this.emit(EVENTS.STARTED_RECEIVING_RESPONSE, actor); + emit(EVENTS.STARTED_RECEIVING_RESPONSE, actor); break; case "responseContent": this.pushRequestToQueue(actor, { @@ -375,7 +367,7 @@ class FirefoxDataProvider { this.onPayloadDataReceived(actor); - this.emit(EVENTS.NETWORK_EVENT_UPDATED, actor); + emit(EVENTS.NETWORK_EVENT_UPDATED, actor); } /** @@ -401,7 +393,7 @@ class FirefoxDataProvider { // This event is fired only once per request, once all the properties are fetched // from `onNetworkEventUpdate`. There should be no more RDP requests after this. - this.emit(EVENTS.PAYLOAD_READY, actor); + emit(EVENTS.PAYLOAD_READY, actor); } /** @@ -471,7 +463,7 @@ class FirefoxDataProvider { let updatingEventName = `UPDATING_${method.replace(/([A-Z])/g, "_$1").toUpperCase()}`; // Emit event that tell we just start fetching some data - this.emit(EVENTS[updatingEventName], actor); + emit(EVENTS[updatingEventName], actor); let response = await new Promise((resolve, reject) => { // Do a RDP request to fetch data from the actor. @@ -508,7 +500,7 @@ class FirefoxDataProvider { let payload = await this.updateRequest(response.from, { requestHeaders: response }); - this.emit(EVENTS.RECEIVED_REQUEST_HEADERS, response.from); + emit(EVENTS.RECEIVED_REQUEST_HEADERS, response.from); return payload.requestHeaders; } @@ -521,7 +513,7 @@ class FirefoxDataProvider { let payload = await this.updateRequest(response.from, { responseHeaders: response }); - this.emit(EVENTS.RECEIVED_RESPONSE_HEADERS, response.from); + emit(EVENTS.RECEIVED_RESPONSE_HEADERS, response.from); return payload.responseHeaders; } @@ -534,7 +526,7 @@ class FirefoxDataProvider { let payload = await this.updateRequest(response.from, { requestCookies: response }); - this.emit(EVENTS.RECEIVED_REQUEST_COOKIES, response.from); + emit(EVENTS.RECEIVED_REQUEST_COOKIES, response.from); return payload.requestCookies; } @@ -547,7 +539,7 @@ class FirefoxDataProvider { let payload = await this.updateRequest(response.from, { requestPostData: response }); - this.emit(EVENTS.RECEIVED_REQUEST_POST_DATA, response.from); + emit(EVENTS.RECEIVED_REQUEST_POST_DATA, response.from); return payload.requestPostData; } @@ -560,7 +552,7 @@ class FirefoxDataProvider { let payload = await this.updateRequest(response.from, { securityInfo: response.securityInfo }); - this.emit(EVENTS.RECEIVED_SECURITY_INFO, response.from); + emit(EVENTS.RECEIVED_SECURITY_INFO, response.from); return payload.securityInfo; } @@ -573,7 +565,7 @@ class FirefoxDataProvider { let payload = await this.updateRequest(response.from, { responseCookies: response }); - this.emit(EVENTS.RECEIVED_RESPONSE_COOKIES, response.from); + emit(EVENTS.RECEIVED_RESPONSE_COOKIES, response.from); return payload.responseCookies; } @@ -590,7 +582,7 @@ class FirefoxDataProvider { mimeType: response.content.mimeType, responseContent: response, }); - this.emit(EVENTS.RECEIVED_RESPONSE_CONTENT, response.from); + emit(EVENTS.RECEIVED_RESPONSE_CONTENT, response.from); return payload.responseContent; } @@ -603,7 +595,7 @@ class FirefoxDataProvider { let payload = await this.updateRequest(response.from, { eventTimings: response }); - this.emit(EVENTS.RECEIVED_EVENT_TIMINGS, response.from); + emit(EVENTS.RECEIVED_EVENT_TIMINGS, response.from); return payload.eventTimings; } @@ -616,17 +608,17 @@ class FirefoxDataProvider { let payload = await this.updateRequest(response.from, { stacktrace: response.stacktrace }); - this.emit(EVENTS.RECEIVED_EVENT_STACKTRACE, response.from); + emit(EVENTS.RECEIVED_EVENT_STACKTRACE, response.from); return payload.stacktrace; } +} - /** - * Fire events for the owner object. - */ - emit(type, data) { - if (this.owner) { - this.owner.emit(type, data); - } +/** + * Guard 'emit' to avoid exception in non-window environment. + */ +function emit(type, data) { + if (typeof window != "undefined") { + window.emit(type, data); } } diff --git a/devtools/client/netmonitor/src/connector/index.js b/devtools/client/netmonitor/src/connector/index.js index a14f65dda30a..7c748ad7b47f 100644 --- a/devtools/client/netmonitor/src/connector/index.js +++ b/devtools/client/netmonitor/src/connector/index.js @@ -54,14 +54,12 @@ class Connector { } connectChrome(connection, actions, getState) { - let ChromeConnector = require("./chrome-connector"); - this.connector = new ChromeConnector(); + this.connector = require("./chrome-connector"); return this.connector.connect(connection, actions, getState); } connectFirefox(connection, actions, getState) { - let FirefoxConnector = require("./firefox-connector"); - this.connector = new FirefoxConnector(); + this.connector = require("./firefox-connector"); return this.connector.connect(connection, actions, getState); } diff --git a/devtools/client/netmonitor/src/har/har-exporter.js b/devtools/client/netmonitor/src/har/har-exporter.js index ceb35c20ab4a..387ad70bf7c8 100644 --- a/devtools/client/netmonitor/src/har/har-exporter.js +++ b/devtools/client/netmonitor/src/har/har-exporter.js @@ -126,9 +126,7 @@ const HarExporter = { * Configuration object, see save() for detailed description. */ getHar: function(options) { - return this.fetchHarData(options).then(data => { - return data ? JSON.parse(data) : null; - }); + return this.fetchHarData(options).then(JSON.parse); }, // Helpers diff --git a/devtools/client/netmonitor/src/moz.build b/devtools/client/netmonitor/src/moz.build index dafa29444650..ddaa7a426c44 100644 --- a/devtools/client/netmonitor/src/moz.build +++ b/devtools/client/netmonitor/src/moz.build @@ -15,8 +15,6 @@ DIRS += [ ] DevToolsModules( - 'api.js', - 'app.js', 'constants.js', 'create-store.js', ) diff --git a/devtools/client/netmonitor/test/browser_net_brotli.js b/devtools/client/netmonitor/test/browser_net_brotli.js index 653c01f096b4..4a42f8f9c7ea 100644 --- a/devtools/client/netmonitor/test/browser_net_brotli.js +++ b/devtools/client/netmonitor/test/browser_net_brotli.js @@ -48,7 +48,7 @@ add_task(async function() { }); wait = waitForDOM(document, ".CodeMirror-code"); - let onResponseContent = monitor.panelWin.api.once(EVENTS.RECEIVED_RESPONSE_CONTENT); + let onResponseContent = monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_CONTENT); store.dispatch(Actions.toggleNetworkDetails()); EventUtils.sendMouseEvent({ type: "click" }, document.querySelector("#response-tab")); diff --git a/devtools/client/netmonitor/test/browser_net_columns_time.js b/devtools/client/netmonitor/test/browser_net_columns_time.js index 6c8a86a805e7..b12f4f15a873 100644 --- a/devtools/client/netmonitor/test/browser_net_columns_time.js +++ b/devtools/client/netmonitor/test/browser_net_columns_time.js @@ -32,7 +32,7 @@ add_task(async function() { }); let onNetworkEvents = waitForNetworkEvents(monitor, 1); - let onEventTimings = waitFor(monitor.panelWin.api, EVENTS.RECEIVED_EVENT_TIMINGS); + let onEventTimings = waitFor(monitor.panelWin, EVENTS.RECEIVED_EVENT_TIMINGS); tab.linkedBrowser.reload(); await Promise.all([onNetworkEvents, onEventTimings]); diff --git a/devtools/client/netmonitor/test/browser_net_content-type.js b/devtools/client/netmonitor/test/browser_net_content-type.js index 1ba505f7d396..6f58becad513 100644 --- a/devtools/client/netmonitor/test/browser_net_content-type.js +++ b/devtools/client/netmonitor/test/browser_net_content-type.js @@ -268,7 +268,7 @@ add_task(async function() { } async function selectIndexAndWaitForJSONView(index) { - let onResponseContent = monitor.panelWin.api.once(EVENTS.RECEIVED_RESPONSE_CONTENT); + let onResponseContent = monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_CONTENT); let tabpanel = document.querySelector("#response-panel"); let waitDOM = waitForDOM(tabpanel, ".treeTable"); store.dispatch(Actions.selectRequestByIndex(index)); @@ -281,7 +281,7 @@ add_task(async function() { } async function selectIndexAndWaitForImageView(index) { - let onResponseContent = monitor.panelWin.api.once(EVENTS.RECEIVED_RESPONSE_CONTENT); + let onResponseContent = monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_CONTENT); let tabpanel = document.querySelector("#response-panel"); let waitDOM = waitForDOM(tabpanel, ".response-image"); store.dispatch(Actions.selectRequestByIndex(index)); diff --git a/devtools/client/netmonitor/test/browser_net_pane-toggle.js b/devtools/client/netmonitor/test/browser_net_pane-toggle.js index 7e25a89c0e6f..0b37d23d0c8c 100644 --- a/devtools/client/netmonitor/test/browser_net_pane-toggle.js +++ b/devtools/client/netmonitor/test/browser_net_pane-toggle.js @@ -28,7 +28,7 @@ add_task(async function() { is(getSelectedRequest(store.getState()), null, "There should be no selected item in the requests menu."); - let networkEvent = monitor.panelWin.api.once(EVENTS.NETWORK_EVENT); + let networkEvent = monitor.panelWin.once(EVENTS.NETWORK_EVENT); tab.linkedBrowser.reload(); await networkEvent; diff --git a/devtools/client/netmonitor/test/browser_net_pause.js b/devtools/client/netmonitor/test/browser_net_pause.js index 70c32a7103a5..2b007052c016 100644 --- a/devtools/client/netmonitor/test/browser_net_pause.js +++ b/devtools/client/netmonitor/test/browser_net_pause.js @@ -24,11 +24,11 @@ add_task(async function() { assertRequestCount(store, 1); let noRequest = true; - monitor.panelWin.api.once(EVENTS.NETWORK_EVENT, () => { + monitor.panelWin.once(EVENTS.NETWORK_EVENT, () => { noRequest = false; }); - monitor.panelWin.api.once(EVENTS.NETWORK_EVENT_UPDATED, () => { + monitor.panelWin.once(EVENTS.NETWORK_EVENT_UPDATED, () => { noRequest = false; }); diff --git a/devtools/client/netmonitor/test/browser_net_security-tab-visibility.js b/devtools/client/netmonitor/test/browser_net_security-tab-visibility.js index 8930177b655f..e8f320118b46 100644 --- a/devtools/client/netmonitor/test/browser_net_security-tab-visibility.js +++ b/devtools/client/netmonitor/test/browser_net_security-tab-visibility.js @@ -41,7 +41,7 @@ add_task(async function() { for (let testcase of TEST_DATA) { info("Testing Security tab visibility for " + testcase.desc); - let onNewItem = monitor.panelWin.api.once(EVENTS.NETWORK_EVENT); + let onNewItem = monitor.panelWin.once(EVENTS.NETWORK_EVENT); let onComplete = testcase.isBroken ? waitForSecurityBrokenNetworkEvent() : waitForNetworkEvents(monitor, 1); @@ -106,7 +106,7 @@ add_task(async function() { ]; let promises = awaitedEvents.map((event) => { - return monitor.panelWin.api.once(EVENTS[event]); + return monitor.panelWin.once(EVENTS[event]); }); return Promise.all(promises); diff --git a/devtools/client/netmonitor/test/browser_net_simple-request-data.js b/devtools/client/netmonitor/test/browser_net_simple-request-data.js index e9bac9d17263..0b4d4fc7c52e 100644 --- a/devtools/client/netmonitor/test/browser_net_simple-request-data.js +++ b/devtools/client/netmonitor/test/browser_net_simple-request-data.js @@ -34,7 +34,7 @@ function test() { function expectEvent(evt, cb) { promiseList.push(new Promise((resolve, reject) => { - monitor.panelWin.api.once(evt, _ => { + monitor.panelWin.once(evt, _ => { cb().then(resolve, reject); }); })); @@ -151,7 +151,7 @@ function test() { ); }); - monitor.panelWin.api.once(EVENTS.RECEIVED_REQUEST_POST_DATA, () => { + monitor.panelWin.once(EVENTS.RECEIVED_REQUEST_POST_DATA, () => { ok(false, "Trap listener: this request doesn't have any post data."); }); diff --git a/devtools/client/netmonitor/test/browser_net_simple-request-details.js b/devtools/client/netmonitor/test/browser_net_simple-request-details.js index a0a6c9cc145a..ecbfd888a136 100644 --- a/devtools/client/netmonitor/test/browser_net_simple-request-details.js +++ b/devtools/client/netmonitor/test/browser_net_simple-request-details.js @@ -161,7 +161,7 @@ add_task(async function() { } async function testCookiesTab() { - let onEvent = monitor.panelWin.api.once(EVENTS.TAB_UPDATED); + let onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED); EventUtils.sendMouseEvent({ type: "mousedown" }, document.querySelectorAll("#details-pane tab")[1]); await onEvent; @@ -204,7 +204,7 @@ add_task(async function() { } async function testResponseTab() { - let onEvent = monitor.panelWin.api.once(EVENTS.TAB_UPDATED); + let onEvent = monitor.panelWin.once(EVENTS.TAB_UPDATED); EventUtils.sendMouseEvent({ type: "mousedown" }, document.querySelectorAll("#details-pane tab")[3]); await onEvent; diff --git a/devtools/client/netmonitor/test/head.js b/devtools/client/netmonitor/test/head.js index 68fe119d93b9..0dcb8e132a08 100644 --- a/devtools/client/netmonitor/test/head.js +++ b/devtools/client/netmonitor/test/head.js @@ -155,13 +155,13 @@ function waitForTimelineMarkers(monitor) { info(`Got marker: ${marker.name}`); markers.push(marker); if (markers.length == 2) { - monitor.panelWin.api.off(EVENTS.TIMELINE_EVENT, handleTimelineEvent); + monitor.panelWin.off(EVENTS.TIMELINE_EVENT, handleTimelineEvent); info("Got two timeline markers, done waiting"); resolve(markers); } } - monitor.panelWin.api.on(EVENTS.TIMELINE_EVENT, handleTimelineEvent); + monitor.panelWin.on(EVENTS.TIMELINE_EVENT, handleTimelineEvent); }); } @@ -212,14 +212,14 @@ function waitForAllRequestsFinished(monitor) { } // All requests are done - unsubscribe from events and resolve! - window.api.off(EVENTS.NETWORK_EVENT, onRequest); - window.api.off(EVENTS.PAYLOAD_READY, onTimings); + window.off(EVENTS.NETWORK_EVENT, onRequest); + window.off(EVENTS.PAYLOAD_READY, onTimings); info("All requests finished"); resolve(); } - window.api.on(EVENTS.NETWORK_EVENT, onRequest); - window.api.on(EVENTS.PAYLOAD_READY, onTimings); + window.on(EVENTS.NETWORK_EVENT, onRequest); + window.on(EVENTS.PAYLOAD_READY, onTimings); }); } @@ -248,12 +248,12 @@ let updatedTypes = [ // Start collecting all networkEventUpdate event when panel is opened. // removeTab() should be called once all corresponded RECEIVED_* events finished. function startNetworkEventUpdateObserver(panelWin) { - updatingTypes.forEach((type) => panelWin.api.on(type, actor => { + updatingTypes.forEach((type) => panelWin.on(type, actor => { let key = actor + "-" + updatedTypes[updatingTypes.indexOf(type)]; finishedQueue[key] = finishedQueue[key] ? finishedQueue[key] + 1 : 1; })); - updatedTypes.forEach((type) => panelWin.api.on(type, actor => { + updatedTypes.forEach((type) => panelWin.on(type, actor => { let key = actor + "-" + type; finishedQueue[key] = finishedQueue[key] ? finishedQueue[key] - 1 : -1; })); @@ -389,14 +389,14 @@ function waitForNetworkEvents(monitor, getRequests) { // Wait until networkEvent & payloadReady finish for each request. if (networkEvent >= getRequests && payloadReady >= getRequests) { - panel.api.off(EVENTS.NETWORK_EVENT, onNetworkEvent); - panel.api.off(EVENTS.PAYLOAD_READY, onPayloadReady); + panel.off(EVENTS.NETWORK_EVENT, onNetworkEvent); + panel.off(EVENTS.PAYLOAD_READY, onPayloadReady); executeSoon(resolve); } } - panel.api.on(EVENTS.NETWORK_EVENT, onNetworkEvent); - panel.api.on(EVENTS.PAYLOAD_READY, onPayloadReady); + panel.on(EVENTS.NETWORK_EVENT, onNetworkEvent); + panel.on(EVENTS.PAYLOAD_READY, onPayloadReady); }); } @@ -563,7 +563,7 @@ function verifyRequestItemTarget(document, requestList, requestItem, method, /** * Helper function for waiting for an event to fire before resolving a promise. - * Example: waitFor(aMonitor.panelWin.api, EVENT_NAME); + * Example: waitFor(aMonitor.panelWin, EVENT_NAME); * * @param object subject * The event emitter object that is being listened to. @@ -737,7 +737,7 @@ async function showColumn(monitor, column) { */ async function selectIndexAndWaitForSourceEditor(monitor, index) { let document = monitor.panelWin.document; - let onResponseContent = monitor.panelWin.api.once(EVENTS.RECEIVED_RESPONSE_CONTENT); + let onResponseContent = monitor.panelWin.once(EVENTS.RECEIVED_RESPONSE_CONTENT); // Select the request first, as it may try to fetch whatever is the current request's // responseContent if we select the ResponseTab first. EventUtils.sendMouseEvent({ type: "mousedown" }, diff --git a/devtools/client/webconsole/test/mochitest/browser_webconsole_network_attach.js b/devtools/client/webconsole/test/mochitest/browser_webconsole_network_attach.js index 2c8d0c8dff25..74095906230b 100644 --- a/devtools/client/webconsole/test/mochitest/browser_webconsole_network_attach.js +++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_network_attach.js @@ -18,7 +18,7 @@ add_task(async function task() { let toolbox = gDevTools.getToolbox(target); let monitor = toolbox.getCurrentPanel(); - let netReady = monitor.panelWin.api.once("NetMonitor:PayloadReady"); + let netReady = monitor.panelWin.once("NetMonitor:PayloadReady"); // Fire an XHR POST request. await ContentTask.spawn(gBrowser.selectedBrowser, null, function() { @@ -69,7 +69,7 @@ async function testNetworkMessage(messageNode) { } /** - * Wait until all lazily fetch requests in netmonitor get finished. + * Wait until all lazily fetch requests in netmonitor get finsished. * Otherwise test will be shutdown too early and cause failure. */ async function waitForLazyRequests(toolbox) {