--- a/devtools/client/netmonitor/index.js
+++ b/devtools/client/netmonitor/index.js
@@ -6,16 +6,17 @@
/**
* This script is the entry point of devtools-launchpad. Make netmonitor possible
* to run on standalone browser tab without chrome privilege.
* See README.md for more information.
*/
const React = require("react");
const ReactDOM = require("react-dom");
+const { bindActionCreators } = require("redux");
const { bootstrap, renderRoot } = require("devtools-launchpad");
const { EventEmitter } = require("devtools-modules");
const { Services: { appinfo, pref }} = require("devtools-modules");
const { configureStore } = require("./src/utils/create-store");
require("./src/assets/styles/netmonitor.css");
EventEmitter.decorate(window);
@@ -33,16 +34,17 @@ pref("devtools.netmonitor.har.includeRes
pref("devtools.netmonitor.har.compress", false);
pref("devtools.netmonitor.har.forceExport", false);
pref("devtools.netmonitor.har.pageLoadedTimeout", 1500);
pref("devtools.netmonitor.har.enableAutoExportToFile", false);
pref("devtools.webconsole.persistlog", false);
const App = require("./src/components/app");
const store = window.gStore = configureStore();
+const actions = bindActionCreators(require("./src/actions"), store.dispatch);
const { NetMonitorController } = require("./src/netmonitor-controller");
/**
* Stylesheet links in devtools xhtml files are using chrome or resource URLs.
* Rewrite the href attribute to remove the protocol. web-server.js contains redirects
* to map CSS urls to the proper file. Supports urls using:
* - devtools/client/
* - devtools/content/
@@ -64,10 +66,10 @@ window.addEventListener("DOMContentLoade
}
});
bootstrap(React, ReactDOM).then(connection => {
if (!connection) {
return;
}
renderRoot(React, ReactDOM, App, store);
- NetMonitorController.startupNetMonitor(connection);
+ NetMonitorController.startupNetMonitor(connection, actions);
});
--- a/devtools/client/netmonitor/src/netmonitor-controller.js
+++ b/devtools/client/netmonitor/src/netmonitor-controller.js
@@ -2,46 +2,46 @@
* 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 { TimelineFront } = require("devtools/shared/fronts/timeline");
const { CurlUtils } = require("devtools/client/shared/curl");
const { ACTIVITY_TYPE, EVENTS } = require("./constants");
-const Actions = require("./actions/index");
+const {
+ getRequestById,
+ getDisplayedRequestById,
+} = require("./selectors/index");
const {
fetchHeaders,
formDataURI,
} = require("./utils/request-utils");
const {
getLongString,
getWebConsoleClient,
onFirefoxConnect,
onFirefoxDisconnect,
} = require("./utils/client");
-const {
- getRequestById,
- getDisplayedRequestById,
-} = require("./selectors/index");
/**
* Object defining the network monitor controller components.
*/
var NetMonitorController = {
/**
* Initializes the view and connects the monitor client.
*
* @param {Object} connection connection data wrapper
* @return {Object} A promise that is resolved when the monitor finishes startup.
*/
- startupNetMonitor(connection) {
+ startupNetMonitor(connection, actions) {
if (this._startup) {
return this._startup;
}
+ this.actions = actions;
this._startup = new Promise(async (resolve) => {
await this.connect(connection);
resolve();
});
return this._startup;
},
/**
@@ -50,17 +50,17 @@ var NetMonitorController = {
* @return object
* A promise that is resolved when the monitor finishes shutdown.
*/
shutdownNetMonitor() {
if (this._shutdown) {
return this._shutdown;
}
this._shutdown = new Promise(async (resolve) => {
- window.gStore.dispatch(Actions.batchReset());
+ this.actions.batchReset();
onFirefoxDisconnect(this._target);
this._target.off("close", this._onTabDetached);
this.NetworkEventsHandler.disconnect();
await this.disconnect();
resolve();
});
return this._shutdown;
@@ -100,17 +100,17 @@ var NetMonitorController = {
};
await connectTimeline();
onFirefoxConnect(this._target);
this._target.on("close", this._onTabDetached);
this.webConsoleClient = getWebConsoleClient();
this.NetworkEventsHandler = new NetworkEventsHandler();
- this.NetworkEventsHandler.connect();
+ this.NetworkEventsHandler.connect(this.actions);
window.emit(EVENTS.CONNECTED);
resolve();
this._connected = true;
});
return this._connection;
},
@@ -255,25 +255,25 @@ var NetMonitorController = {
// 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(window.gStore.getState(), requestId);
if (!request) {
// Reset filters so that the request is visible.
- window.gStore.dispatch(Actions.toggleRequestFilterType("all"));
+ this.actions.toggleRequestFilterType("all");
request = getDisplayedRequestById(window.gStore.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);
- window.gStore.dispatch(Actions.selectRequest(request.id));
+ this.actions.selectRequest(request.id);
resolve();
}
};
inspector();
if (!request) {
window.on(EVENTS.REQUEST_ADDED, inspector);
}
@@ -397,31 +397,32 @@ NetworkEventsHandler.prototype = {
get timelineFront() {
return NetMonitorController.timelineFront;
},
/**
* Connect to the current target client.
*/
- connect: function () {
+ connect(actions) {
+ this.actions = actions;
this.webConsoleClient.on("networkEvent", this._onNetworkEvent);
this.webConsoleClient.on("networkEventUpdate", this._onNetworkEventUpdate);
if (this.timelineFront) {
this.timelineFront.on("doc-loading", this._onDocLoadingMarker);
}
this._displayCachedEvents();
},
/**
* Disconnect from the client.
*/
- disconnect: function () {
+ disconnect() {
if (!this.client) {
return;
}
this.webConsoleClient.off("networkEvent", this._onNetworkEvent);
this.webConsoleClient.off("networkEventUpdate", this._onNetworkEventUpdate);
if (this.timelineFront) {
this.timelineFront.off("doc-loading", this._onDocLoadingMarker);
@@ -448,17 +449,17 @@ NetworkEventsHandler.prototype = {
},
/**
* The "DOMContentLoaded" and "Load" events sent by the timeline actor.
* @param object marker
*/
_onDocLoadingMarker: function (marker) {
window.emit(EVENTS.TIMELINE_EVENT, marker);
- window.gStore.dispatch(Actions.addTimingMarker(marker));
+ this.actions.addTimingMarker(marker);
},
/**
* The "networkEvent" message type handler.
*
* @param string type
* Message type.
* @param object networkInfo
@@ -479,82 +480,81 @@ NetworkEventsHandler.prototype = {
);
window.emit(EVENTS.NETWORK_EVENT, actor);
},
addRequest(id, data) {
let { method, url, isXHR, cause, startedDateTime, fromCache,
fromServiceWorker } = data;
- window.gStore.dispatch(Actions.addRequest(
+ this.actions.addRequest(
id,
{
// Convert the received date/time string to a unix timestamp.
startedMillis: Date.parse(startedDateTime),
method,
url,
isXHR,
cause,
fromCache,
fromServiceWorker,
},
true
- ))
+ )
.then(() => window.emit(EVENTS.REQUEST_ADDED, id));
},
async updateRequest(id, data) {
- const action = Actions.updateRequest(id, data, true);
- await window.gStore.dispatch(action);
+ await this.actions.updateRequest(id, data, true);
let {
responseContent,
responseCookies,
responseHeaders,
requestCookies,
requestHeaders,
requestPostData,
- } = action.data;
- let request = getRequestById(window.gStore.getState(), action.id);
+ } = data;
+ let request = getRequestById(window.gStore.getState(), id);
if (requestHeaders && requestHeaders.headers && requestHeaders.headers.length) {
let headers = await fetchHeaders(requestHeaders, getLongString);
if (headers) {
- await window.gStore.dispatch(Actions.updateRequest(
- action.id,
+ await this.actions.updateRequest(
+ id,
{ requestHeaders: headers },
true,
- ));
+ );
}
}
if (responseHeaders && responseHeaders.headers && responseHeaders.headers.length) {
let headers = await fetchHeaders(responseHeaders, getLongString);
if (headers) {
- await window.gStore.dispatch(Actions.updateRequest(
- action.id,
+ await this.actions.updateRequest(
+ id,
{ responseHeaders: headers },
true,
- ));
+ );
}
}
if (request && responseContent && responseContent.content) {
let { mimeType } = request;
let { text, encoding } = responseContent.content;
let response = await getLongString(text);
let payload = {};
if (mimeType.includes("image/")) {
payload.responseContentDataUri = formDataURI(mimeType, encoding, response);
}
responseContent.content.text = response;
payload.responseContent = responseContent;
- await window.gStore.dispatch(Actions.updateRequest(action.id, payload, true));
+ await this.actions.updateRequest(id, payload, true);
if (mimeType.includes("image/")) {
window.emit(EVENTS.RESPONSE_IMAGE_THUMBNAIL_DISPLAYED);
}
}
// Search the POST data upload stream for request headers and add
// them as a separate property, different from the classic headers.
@@ -565,17 +565,17 @@ NetworkEventsHandler.prototype = {
const headersSize = headers.reduce((acc, { name, value }) => {
return acc + name.length + value.length + 2;
}, 0);
let payload = {};
requestPostData.postData.text = postData;
payload.requestPostData = Object.assign({}, requestPostData);
payload.requestHeadersFromUploadStream = { headers, headersSize };
- await window.gStore.dispatch(Actions.updateRequest(action.id, payload, true));
+ await this.actions.updateRequest(id, payload, true);
}
// Fetch request and response cookies long value.
// Actor does not provide full sized cookie value when the value is too long
// To display values correctly, we need fetch them in each request.
if (requestCookies) {
let reqCookies = [];
// request store cookies in requestCookies or requestCookies.cookies
@@ -584,20 +584,17 @@ NetworkEventsHandler.prototype = {
// make sure cookies is iterable
if (typeof cookies[Symbol.iterator] === "function") {
for (let cookie of cookies) {
reqCookies.push(Object.assign({}, cookie, {
value: await getLongString(cookie.value),
}));
}
if (reqCookies.length) {
- await window.gStore.dispatch(Actions.updateRequest(
- action.id,
- { requestCookies: reqCookies },
- true));
+ await this.actions.updateRequest(id, { requestCookies: reqCookies }, true);
}
}
}
if (responseCookies) {
let resCookies = [];
// response store cookies in responseCookies or responseCookies.cookies
let cookies = responseCookies.cookies ?
@@ -605,20 +602,17 @@ NetworkEventsHandler.prototype = {
// make sure cookies is iterable
if (typeof cookies[Symbol.iterator] === "function") {
for (let cookie of cookies) {
resCookies.push(Object.assign({}, cookie, {
value: await getLongString(cookie.value),
}));
}
if (resCookies.length) {
- await window.gStore.dispatch(Actions.updateRequest(
- action.id,
- { responseCookies: resCookies },
- true));
+ await this.actions.updateRequest(id, { responseCookies: resCookies }, true);
}
}
}
},
/**
* The "networkEventUpdate" message type handler.
*