зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1555625 - Basic skeleton of side panel for WS frames. r=Honza
Implement basic skeleton of side panel for WS frames. Differential Revision: https://phabricator.services.mozilla.com/D34704 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
9e137b1e80
Коммит
1f04945904
|
@ -66,6 +66,10 @@ headersEmptyText=No headers for this request
|
|||
# headers tab of the network details pane for the filtering input.
|
||||
headersFilterText=Filter headers
|
||||
|
||||
# LOCALIZATION NOTE (webSocketsEmptyText): This is the text displayed in the
|
||||
# WebSockets tab of the network details pane when there are no frames available.
|
||||
webSocketsEmptyText=No WebSocket frames for this request
|
||||
|
||||
# LOCALIZATION NOTE (cookiesEmptyText): This is the text displayed in the
|
||||
# cookies tab of the network details pane when there are no cookies available.
|
||||
cookiesEmptyText=No cookies for this request
|
||||
|
@ -637,6 +641,10 @@ netmonitor.toolbar.waterfall=Timeline
|
|||
# in the network details pane identifying the headers tab.
|
||||
netmonitor.tab.headers=Headers
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.tab.webSockets): This is the label displayed
|
||||
# in the network details pane identifying the webSockets tab.
|
||||
netmonitor.tab.webSockets=WebSockets
|
||||
|
||||
# LOCALIZATION NOTE (netmonitor.tab.cookies): This is the label displayed
|
||||
# in the network details pane identifying the cookies tab.
|
||||
netmonitor.tab.cookies=Cookies
|
||||
|
|
|
@ -11,6 +11,7 @@ const selection = require("./selection");
|
|||
const sort = require("./sort");
|
||||
const timingMarkers = require("./timing-markers");
|
||||
const ui = require("./ui");
|
||||
const webSockets = require("./web-sockets");
|
||||
|
||||
Object.assign(exports,
|
||||
batching,
|
||||
|
@ -19,5 +20,6 @@ Object.assign(exports,
|
|||
selection,
|
||||
sort,
|
||||
timingMarkers,
|
||||
ui
|
||||
ui,
|
||||
webSockets,
|
||||
);
|
||||
|
|
|
@ -11,4 +11,5 @@ DevToolsModules(
|
|||
'sort.js',
|
||||
'timing-markers.js',
|
||||
'ui.js',
|
||||
'web-sockets.js',
|
||||
)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/* 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 { WS_ADD_FRAME } = require("../constants");
|
||||
|
||||
function addFrame(httpChannelId, data) {
|
||||
return {
|
||||
type: WS_ADD_FRAME,
|
||||
httpChannelId,
|
||||
data,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
addFrame,
|
||||
};
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const Services = require("Services");
|
||||
const {
|
||||
Component,
|
||||
createFactory,
|
||||
|
@ -17,6 +18,7 @@ const Tabbar = createFactory(require("devtools/client/shared/components/tabs/Tab
|
|||
const TabPanel = createFactory(require("devtools/client/shared/components/tabs/Tabs").TabPanel);
|
||||
const CookiesPanel = createFactory(require("./CookiesPanel"));
|
||||
const HeadersPanel = createFactory(require("./HeadersPanel"));
|
||||
const WebSocketsPanel = createFactory(require("./WebSocketsPanel"));
|
||||
const ParamsPanel = createFactory(require("./ParamsPanel"));
|
||||
const CachePanel = createFactory(require("./CachePanel"));
|
||||
const ResponsePanel = createFactory(require("./ResponsePanel"));
|
||||
|
@ -28,6 +30,7 @@ const COLLAPSE_DETAILS_PANE = L10N.getStr("collapseDetailsPane");
|
|||
const CACHE_TITLE = L10N.getStr("netmonitor.tab.cache");
|
||||
const COOKIES_TITLE = L10N.getStr("netmonitor.tab.cookies");
|
||||
const HEADERS_TITLE = L10N.getStr("netmonitor.tab.headers");
|
||||
const WEBSOCKETS_TITLE = L10N.getStr("netmonitor.tab.webSockets");
|
||||
const PARAMS_TITLE = L10N.getStr("netmonitor.tab.params");
|
||||
const RESPONSE_TITLE = L10N.getStr("netmonitor.tab.response");
|
||||
const SECURITY_TITLE = L10N.getStr("netmonitor.tab.security");
|
||||
|
@ -87,6 +90,11 @@ class TabboxPanel extends Component {
|
|||
return null;
|
||||
}
|
||||
|
||||
const channelId = request.channelId;
|
||||
const showWebSocketsPanel =
|
||||
request.cause.type === "websocket" &&
|
||||
Services.prefs.getBoolPref(
|
||||
"devtools.netmonitor.features.webSockets");
|
||||
return (
|
||||
Tabbar({
|
||||
activeTabId,
|
||||
|
@ -113,6 +121,14 @@ class TabboxPanel extends Component {
|
|||
request,
|
||||
}),
|
||||
),
|
||||
showWebSocketsPanel && TabPanel({
|
||||
id: PANELS.WEBSOCKETS,
|
||||
title: WEBSOCKETS_TITLE,
|
||||
},
|
||||
WebSocketsPanel({
|
||||
channelId,
|
||||
}),
|
||||
),
|
||||
TabPanel({
|
||||
id: PANELS.COOKIES,
|
||||
title: COOKIES_TITLE,
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/* 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 { Component } = require("devtools/client/shared/vendor/react");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const {
|
||||
connect,
|
||||
} = require("devtools/client/shared/redux/visibility-handler-connect");
|
||||
const { getFramesByChannelId } = require("../selectors/index");
|
||||
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const { table, tbody, thead, tr, td, th, div } = dom;
|
||||
|
||||
const { L10N } = require("../utils/l10n");
|
||||
const FRAMES_EMPTY_TEXT = L10N.getStr("webSocketsEmptyText");
|
||||
|
||||
class WebSocketsPanel extends Component {
|
||||
static get propTypes() {
|
||||
return {
|
||||
channelId: PropTypes.number,
|
||||
frames: PropTypes.array,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { frames } = this.props;
|
||||
|
||||
if (!frames) {
|
||||
return div({ className: "empty-notice" },
|
||||
FRAMES_EMPTY_TEXT
|
||||
);
|
||||
}
|
||||
|
||||
const rows = [];
|
||||
frames.forEach((frame, index) => {
|
||||
rows.push(
|
||||
tr(
|
||||
{ key: index,
|
||||
className: "frames-row" },
|
||||
td({ className: "frames-cell" }, frame.type),
|
||||
td({ className: "frames-cell" }, frame.httpChannelId),
|
||||
td({ className: "frames-cell" }, frame.payload),
|
||||
td({ className: "frames-cell" }, frame.opCode),
|
||||
td({ className: "frames-cell" }, frame.maskBit.toString()),
|
||||
td({ className: "frames-cell" }, frame.finBit.toString()),
|
||||
td({ className: "frames-cell" }, frame.timeStamp)
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
return table(
|
||||
{ className: "frames-list-table" },
|
||||
thead(
|
||||
{ className: "frames-head" },
|
||||
tr(
|
||||
{ className: "frames-row" },
|
||||
th({ className: "frames-headerCell" }, "Type"),
|
||||
th({ className: "frames-headerCell" }, "Channel ID"),
|
||||
th({ className: "frames-headerCell" }, "Payload"),
|
||||
th({ className: "frames-headerCell" }, "OpCode"),
|
||||
th({ className: "frames-headerCell" }, "MaskBit"),
|
||||
th({ className: "frames-headerCell" }, "FinBit"),
|
||||
th({ className: "frames-headerCell" }, "Time")
|
||||
)
|
||||
),
|
||||
tbody(
|
||||
{
|
||||
className: "frames-list-tableBody",
|
||||
},
|
||||
rows
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = connect((state, props) => ({
|
||||
frames: getFramesByChannelId(state, props.channelId),
|
||||
}))(WebSocketsPanel);
|
|
@ -47,4 +47,5 @@ DevToolsModules(
|
|||
'TabboxPanel.js',
|
||||
'TimingsPanel.js',
|
||||
'Toolbar.js',
|
||||
'WebSocketsPanel.js',
|
||||
)
|
||||
|
|
|
@ -79,6 +79,7 @@ class FirefoxDataProvider {
|
|||
isThirdPartyTrackingResource,
|
||||
referrerPolicy,
|
||||
blockedReason,
|
||||
channelId,
|
||||
} = data;
|
||||
|
||||
// Insert blocked reason in the payload queue as well, as we'll need it later
|
||||
|
@ -106,6 +107,7 @@ class FirefoxDataProvider {
|
|||
isThirdPartyTrackingResource,
|
||||
referrerPolicy,
|
||||
blockedReason,
|
||||
channelId,
|
||||
}, true);
|
||||
}
|
||||
|
||||
|
@ -343,6 +345,7 @@ class FirefoxDataProvider {
|
|||
isThirdPartyTrackingResource,
|
||||
referrerPolicy,
|
||||
blockedReason,
|
||||
channelId,
|
||||
} = networkInfo;
|
||||
|
||||
await this.addRequest(actor, {
|
||||
|
@ -356,6 +359,7 @@ class FirefoxDataProvider {
|
|||
isThirdPartyTrackingResource,
|
||||
referrerPolicy,
|
||||
blockedReason,
|
||||
channelId,
|
||||
});
|
||||
|
||||
this.emit(EVENTS.NETWORK_EVENT, actor);
|
||||
|
@ -426,11 +430,6 @@ class FirefoxDataProvider {
|
|||
* @param {string} extensions
|
||||
*/
|
||||
async onWebSocketOpened(httpChannelId, effectiveURI, protocols, extensions) {
|
||||
console.log("FirefoxDataProvider onWebSocketOpened: " +
|
||||
" httpChannelId: " + httpChannelId +
|
||||
" effectiveURI: " + effectiveURI +
|
||||
" protocols: " + protocols +
|
||||
" extensions: " + extensions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -441,10 +440,6 @@ class FirefoxDataProvider {
|
|||
* @param {string} reason
|
||||
*/
|
||||
async onWebSocketClosed(wasClean, code, reason) {
|
||||
console.log("FirefoxDataProvider onWebSocketClosed: " +
|
||||
" wasClean: " + wasClean +
|
||||
" code: " + code +
|
||||
" reason: " + reason);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -454,11 +449,7 @@ class FirefoxDataProvider {
|
|||
* @param {object} data websocket frame information
|
||||
*/
|
||||
async onFrameSent(httpChannelId, data) {
|
||||
await this.getLongString(data.payload).then(payload => {
|
||||
console.log("FirefoxDataProvider onFrameSent: " +
|
||||
" httpChannelId: " + httpChannelId +
|
||||
" onFrameSent: " + payload);
|
||||
});
|
||||
this.addFrame(httpChannelId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -468,11 +459,20 @@ class FirefoxDataProvider {
|
|||
* @param {object} data websocket frame information
|
||||
*/
|
||||
async onFrameReceived(httpChannelId, data) {
|
||||
await this.getLongString(data.payload).then(payload => {
|
||||
console.log("FirefoxDataProvider onFrameReceived: " +
|
||||
" httpChannelId: " + httpChannelId +
|
||||
" onFrameSent: " + payload);
|
||||
});
|
||||
this.addFrame(httpChannelId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new WebSocket frame to application state.
|
||||
*
|
||||
* @param {number} httpChannelId the channel ID
|
||||
* @param {object} data websocket frame information
|
||||
*/
|
||||
async addFrame(httpChannelId, data) {
|
||||
if (this.actionsEnabled && this.actions.addFrame) {
|
||||
await this.actions.addFrame(httpChannelId, data);
|
||||
}
|
||||
// TODO: Emit an event for test here
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,6 +34,7 @@ const actionTypes = {
|
|||
UPDATE_REQUEST: "UPDATE_REQUEST",
|
||||
WATERFALL_RESIZE: "WATERFALL_RESIZE",
|
||||
SET_COLUMNS_WIDTH: "SET_COLUMNS_WIDTH",
|
||||
WS_ADD_FRAME: "WS_ADD_FRAME",
|
||||
};
|
||||
|
||||
// Descriptions for what this frontend is currently doing.
|
||||
|
@ -154,11 +155,13 @@ const UPDATE_PROPS = [
|
|||
"isThirdPartyTrackingResource",
|
||||
"referrerPolicy",
|
||||
"blockedReason",
|
||||
"channelId",
|
||||
];
|
||||
|
||||
const PANELS = {
|
||||
COOKIES: "cookies",
|
||||
HEADERS: "headers",
|
||||
WEBSOCKETS: "webSockets",
|
||||
PARAMS: "params",
|
||||
RESPONSE: "response",
|
||||
CACHE: "cache",
|
||||
|
|
|
@ -27,6 +27,7 @@ const { Requests } = require("./reducers/requests");
|
|||
const { Sort } = require("./reducers/sort");
|
||||
const { TimingMarkers } = require("./reducers/timing-markers");
|
||||
const { UI, Columns, ColumnsData } = require("./reducers/ui");
|
||||
const { WebSockets } = require("./reducers/web-sockets");
|
||||
|
||||
/**
|
||||
* Configure state and middleware for the Network monitor tool.
|
||||
|
@ -44,6 +45,7 @@ function configureStore(connector, telemetry) {
|
|||
columns: getColumnState(),
|
||||
columnsData: getColumnsData(),
|
||||
}),
|
||||
webSockets: new WebSockets(),
|
||||
};
|
||||
|
||||
// Prepare middleware.
|
||||
|
|
|
@ -11,12 +11,14 @@ const { sortReducer } = require("./sort");
|
|||
const { filters } = require("./filters");
|
||||
const { timingMarkers } = require("./timing-markers");
|
||||
const { ui } = require("./ui");
|
||||
const { webSocketsReducer } = require("./web-sockets");
|
||||
const networkThrottling = require("devtools/client/shared/components/throttling/reducer");
|
||||
|
||||
module.exports = batchingReducer(
|
||||
combineReducers({
|
||||
requests: requestsReducer,
|
||||
sort: sortReducer,
|
||||
webSockets: webSocketsReducer,
|
||||
filters,
|
||||
timingMarkers,
|
||||
ui,
|
||||
|
|
|
@ -10,4 +10,5 @@ DevToolsModules(
|
|||
'sort.js',
|
||||
'timing-markers.js',
|
||||
'ui.js',
|
||||
'web-sockets.js',
|
||||
)
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/* 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 {
|
||||
WS_ADD_FRAME,
|
||||
} = require("../constants");
|
||||
|
||||
/**
|
||||
* This structure stores list of all WebSocket frames received
|
||||
* from the backend.
|
||||
*/
|
||||
function WebSockets() {
|
||||
return {
|
||||
// Map with all requests (key = channelId, value = array of frame objects)
|
||||
frames: new Map(),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This reducer is responsible for maintaining list of
|
||||
* WebSocket frames within the Network panel.
|
||||
*/
|
||||
function webSocketsReducer(state = WebSockets(), action) {
|
||||
switch (action.type) {
|
||||
// Appending new frame into the map.
|
||||
case WS_ADD_FRAME: {
|
||||
const nextState = { ...state };
|
||||
|
||||
const newFrame = {
|
||||
httpChannelId: action.httpChannelId,
|
||||
...action.data,
|
||||
};
|
||||
|
||||
nextState.frames = mapSet(state.frames, newFrame.httpChannelId, newFrame);
|
||||
|
||||
return nextState;
|
||||
}
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append new item into existing map and return new map.
|
||||
*/
|
||||
function mapSet(map, key, value) {
|
||||
const newMap = new Map(map);
|
||||
if (newMap.has(key)) {
|
||||
const framesArray = [...newMap.get(key)];
|
||||
framesArray.push(value);
|
||||
newMap.set(key, framesArray);
|
||||
return newMap;
|
||||
}
|
||||
return newMap.set(key, [value]);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
WebSockets,
|
||||
webSocketsReducer,
|
||||
};
|
|
@ -7,9 +7,11 @@
|
|||
const requests = require("./requests");
|
||||
const timingMarkers = require("./timing-markers");
|
||||
const ui = require("./ui");
|
||||
const webSockets = require("./web-sockets");
|
||||
|
||||
Object.assign(exports,
|
||||
requests,
|
||||
timingMarkers,
|
||||
ui
|
||||
ui,
|
||||
webSockets,
|
||||
);
|
||||
|
|
|
@ -7,4 +7,5 @@ DevToolsModules(
|
|||
'requests.js',
|
||||
'timing-markers.js',
|
||||
'ui.js',
|
||||
'web-sockets.js',
|
||||
)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/* 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";
|
||||
|
||||
function getFramesByChannelId(state, channelId) {
|
||||
return state.webSockets.frames.get(channelId);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getFramesByChannelId,
|
||||
};
|
|
@ -75,6 +75,10 @@ function getCleanedPacket(key, packet) {
|
|||
res.actor = existingPacket.actor;
|
||||
}
|
||||
|
||||
if (res.channelId) {
|
||||
res.channelId = existingPacket.channelId;
|
||||
}
|
||||
|
||||
if (res.message) {
|
||||
// Clean timeStamp on the message prop.
|
||||
res.message.timeStamp = existingPacket.message.timeStamp;
|
||||
|
|
|
@ -265,6 +265,7 @@ stubPackets.set(`GET request`, {
|
|||
"private": false,
|
||||
"isThirdPartyTrackingResource": false,
|
||||
"referrerPolicy": "no-referrer-when-downgrade",
|
||||
"channelId": 22673132355586,
|
||||
"from": "server1.conn0.child1/consoleActor2"
|
||||
});
|
||||
|
||||
|
@ -315,6 +316,7 @@ stubPackets.set(`XHR GET request`, {
|
|||
"private": false,
|
||||
"isThirdPartyTrackingResource": false,
|
||||
"referrerPolicy": "no-referrer-when-downgrade",
|
||||
"channelId": 22673132355587,
|
||||
"from": "server1.conn1.child1/consoleActor2"
|
||||
});
|
||||
|
||||
|
@ -365,6 +367,7 @@ stubPackets.set(`XHR POST request`, {
|
|||
"private": false,
|
||||
"isThirdPartyTrackingResource": false,
|
||||
"referrerPolicy": "no-referrer-when-downgrade",
|
||||
"channelId": 22673132355588,
|
||||
"from": "server1.conn2.child1/consoleActor2"
|
||||
});
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ const NetworkEventActor = protocol.ActorClassWithSpec(networkEventSpec, {
|
|||
isThirdPartyTrackingResource: this._isThirdPartyTrackingResource,
|
||||
referrerPolicy: this._referrerPolicy,
|
||||
blockedReason: this._blockedReason,
|
||||
channelId: this._channelId,
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ class WebConsoleFront extends FrontClassWithSpec(webconsoleSpec) {
|
|||
isThirdPartyTrackingResource: actor.isThirdPartyTrackingResource,
|
||||
referrerPolicy: actor.referrerPolicy,
|
||||
blockedReason: actor.blockedReason,
|
||||
channelId: actor.channelId,
|
||||
};
|
||||
this._networkRequests.set(actor.actor, networkInfo);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче