mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-11 14:14:36 +08:00
Move and rename files. NOAUTOREVERT=true NOPRESUBMIT=true NOTREECHECKS=true Bug: 768828 TBR=darin@chromium.org NOTRY=true Change-Id: I66d3b155808bc5bdbf237b80208e1e552bcf7f28 Reviewed-on: https://chromium-review.googlesource.com/1001153 Reviewed-by: Blink Reformat <blink-reformat@chromium.org> Commit-Queue: Blink Reformat <blink-reformat@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#549061} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 0aee4434a4dba42a42abaea9bfbc0cd196a63bc1
286 lines
9.6 KiB
JavaScript
286 lines
9.6 KiB
JavaScript
// Copyright 2018 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
ProtocolMonitor.ProtocolMonitor = class extends UI.VBox {
|
|
constructor() {
|
|
super(true);
|
|
this._nodes = [];
|
|
this._recordingListeners = null;
|
|
this._started = false;
|
|
this._startTime = 0;
|
|
this._nodeForId = {};
|
|
this._filter = node => true;
|
|
this._columns = [
|
|
{id: 'method', title: ls`Method`, visible: true, sortable: true, weight: 60},
|
|
{id: 'direction', title: ls`Direction`, visible: false, sortable: true, hideable: true, weight: 30},
|
|
{id: 'request', title: ls`Request`, visible: true, hideable: true, weight: 60},
|
|
{id: 'response', title: ls`Response`, visible: true, hideable: true, weight: 60},
|
|
{id: 'timestamp', title: ls`Timestamp`, visible: false, sortable: true, hideable: true, weight: 30}
|
|
];
|
|
|
|
this.registerRequiredCSS('protocol_monitor/protocolMonitor.css');
|
|
const topToolbar = new UI.Toolbar('protocol-monitor-toolbar', this.contentElement);
|
|
const recordButton = new UI.ToolbarToggle(ls`Record`, 'largeicon-start-recording', 'largeicon-stop-recording');
|
|
recordButton.addEventListener(UI.ToolbarButton.Events.Click, () => {
|
|
recordButton.setToggled(!recordButton.toggled());
|
|
this._setRecording(recordButton.toggled());
|
|
});
|
|
recordButton.setToggleWithRedColor(true);
|
|
topToolbar.appendToolbarItem(recordButton);
|
|
recordButton.setToggled(true);
|
|
|
|
const clearButton = new UI.ToolbarButton(ls`Clear all`, 'largeicon-clear');
|
|
clearButton.addEventListener(UI.ToolbarButton.Events.Click, () => {
|
|
this._dataGrid.rootNode().removeChildren();
|
|
this._nodes = [];
|
|
this._nodeForId = {};
|
|
});
|
|
topToolbar.appendToolbarItem(clearButton);
|
|
|
|
const split = new UI.SplitWidget(true, true, 'protocol-monitor-panel-split', 250);
|
|
split.show(this.contentElement);
|
|
this._dataGrid = new DataGrid.SortableDataGrid(this._columns);
|
|
this._dataGrid.element.style.flex = '1';
|
|
this._infoWidget = new ProtocolMonitor.ProtocolMonitor.InfoWidget();
|
|
split.setMainWidget(this._dataGrid.asWidget());
|
|
split.setSidebarWidget(this._infoWidget);
|
|
this._dataGrid.addEventListener(
|
|
DataGrid.DataGrid.Events.SelectedNode, event => this._infoWidget.render(event.data.data));
|
|
this._dataGrid.addEventListener(DataGrid.DataGrid.Events.DeselectedNode, event => this._infoWidget.render(null));
|
|
this._dataGrid.setHeaderContextMenuCallback(this._innerHeaderContextMenu.bind(this));
|
|
|
|
this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortDataGrid.bind(this));
|
|
this._dataGrid.setStickToBottom(true);
|
|
this._dataGrid.sortNodes(DataGrid.SortableDataGrid.NumericComparator.bind(null, 'timestamp'), false);
|
|
this._updateColumnVisibility();
|
|
|
|
const keys = ['method', 'request', 'response', 'direction'];
|
|
this._filterParser = new TextUtils.FilterParser(keys);
|
|
this._suggestionBuilder = new UI.FilterSuggestionBuilder(keys);
|
|
|
|
this._textFilterUI =
|
|
new UI.ToolbarInput(ls`Filter`, 1, .2, '', this._suggestionBuilder.completions.bind(this._suggestionBuilder));
|
|
this._textFilterUI.addEventListener(UI.ToolbarInput.Event.TextChanged, event => {
|
|
const query = /** @type {string} */ (event.data);
|
|
const filters = this._filterParser.parse(query);
|
|
this._filter = node => {
|
|
for (const {key, text, negative} of filters) {
|
|
if (!(key in node.data) || !text)
|
|
continue;
|
|
const found = JSON.stringify(node.data[key]).indexOf(text) !== -1;
|
|
if (found === negative)
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
this._filterNodes();
|
|
});
|
|
topToolbar.appendToolbarItem(this._textFilterUI);
|
|
}
|
|
|
|
_filterNodes() {
|
|
for (const node of this._nodes) {
|
|
if (this._filter(node)) {
|
|
if (!node.parent)
|
|
this._dataGrid.insertChild(node);
|
|
} else {
|
|
node.remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {!UI.ContextMenu} contextMenu
|
|
*/
|
|
_innerHeaderContextMenu(contextMenu) {
|
|
const columnConfigs = this._columns.filter(columnConfig => columnConfig.hideable);
|
|
for (const columnConfig of columnConfigs) {
|
|
contextMenu.headerSection().appendCheckboxItem(
|
|
columnConfig.title, this._toggleColumnVisibility.bind(this, columnConfig), columnConfig.visible);
|
|
}
|
|
contextMenu.show();
|
|
}
|
|
|
|
/**
|
|
* @param {!Object} columnConfig
|
|
*/
|
|
_toggleColumnVisibility(columnConfig) {
|
|
columnConfig.visible = !columnConfig.visible;
|
|
this._updateColumnVisibility();
|
|
}
|
|
|
|
_updateColumnVisibility() {
|
|
const visibleColumns = /** @type {!Object.<string, boolean>} */ ({});
|
|
for (const columnConfig of this._columns)
|
|
visibleColumns[columnConfig.id] = columnConfig.visible;
|
|
this._dataGrid.setColumnsVisiblity(visibleColumns);
|
|
}
|
|
|
|
_sortDataGrid() {
|
|
const sortColumnId = this._dataGrid.sortColumnId();
|
|
if (!sortColumnId)
|
|
return;
|
|
|
|
let columnIsNumeric = true;
|
|
switch (sortColumnId) {
|
|
case 'method':
|
|
case 'direction':
|
|
columnIsNumeric = false;
|
|
break;
|
|
}
|
|
|
|
|
|
const comparator =
|
|
columnIsNumeric ? DataGrid.SortableDataGrid.NumericComparator : DataGrid.SortableDataGrid.StringComparator;
|
|
this._dataGrid.sortNodes(comparator.bind(null, sortColumnId), !this._dataGrid.isSortOrderAscending());
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
wasShown() {
|
|
if (this._started)
|
|
return;
|
|
this._started = true;
|
|
this._startTime = Date.now();
|
|
this._setRecording(true);
|
|
}
|
|
|
|
/**
|
|
* @param {boolean} recording
|
|
*/
|
|
_setRecording(recording) {
|
|
if (this._recordingListeners) {
|
|
Common.EventTarget.removeEventListeners(this._recordingListeners);
|
|
this._recordingListeners = null;
|
|
}
|
|
|
|
if (recording) {
|
|
this._recordingListeners = [
|
|
SDK.targetManager.mainTarget().addEventListener(
|
|
Protocol.TargetBase.Events.MessageReceived, this._messageRecieved, this),
|
|
SDK.targetManager.mainTarget().addEventListener(Protocol.TargetBase.Events.MessageSent, this._messageSent, this)
|
|
];
|
|
}
|
|
}
|
|
|
|
_messageRecieved(event) {
|
|
const message = event.data.message;
|
|
if ('id' in message) {
|
|
const node = this._nodeForId[message.id];
|
|
if (!node)
|
|
return;
|
|
node.data.response = message.result;
|
|
node.refresh();
|
|
if (this._dataGrid.selectedNode === node)
|
|
this._infoWidget.render(node.data);
|
|
return;
|
|
}
|
|
const node = new ProtocolMonitor.ProtocolMonitor.ProtocolNode({
|
|
method: message.method,
|
|
direction: 'recieved',
|
|
response: message.params,
|
|
timestamp: Date.now() - this._startTime,
|
|
request: ''
|
|
});
|
|
this._nodes.push(node);
|
|
if (this._filter(node))
|
|
this._dataGrid.insertChild(node);
|
|
}
|
|
|
|
_messageSent(event) {
|
|
const message = event.data;
|
|
const node = new ProtocolMonitor.ProtocolMonitor.ProtocolNode({
|
|
method: message.method,
|
|
direction: 'sent',
|
|
request: message.params,
|
|
timestamp: Date.now() - this._startTime,
|
|
response: '(pending)',
|
|
id: message.id
|
|
});
|
|
this._nodeForId[message.id] = node;
|
|
this._nodes.push(node);
|
|
if (this._filter(node))
|
|
this._dataGrid.insertChild(node);
|
|
}
|
|
};
|
|
|
|
ProtocolMonitor.ProtocolMonitor.ProtocolNode = class extends DataGrid.SortableDataGridNode {
|
|
constructor(data) {
|
|
super(data);
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
* @param {string} columnId
|
|
* @return {!Element}
|
|
*/
|
|
createCell(columnId) {
|
|
switch (columnId) {
|
|
case 'response':
|
|
if (!this.data[columnId] && this.data.direction === 'send') {
|
|
const cell = this.createTD(columnId);
|
|
cell.textContent = '(pending)';
|
|
return cell;
|
|
}
|
|
// fall through
|
|
case 'request': {
|
|
const cell = this.createTD(columnId);
|
|
const obj = SDK.RemoteObject.fromLocalObject(this.data[columnId]);
|
|
cell.textContent = obj.description.trimEnd(50);
|
|
cell.classList.add('source-code');
|
|
return cell;
|
|
}
|
|
|
|
case 'timestamp': {
|
|
const cell = this.createTD(columnId);
|
|
cell.textContent = ls`${this.data[columnId]} ms`;
|
|
return cell;
|
|
}
|
|
}
|
|
return super.createCell(columnId);
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
element() {
|
|
const element = super.element();
|
|
element.classList.toggle('protocol-message-sent', this.data.direction === 'sent');
|
|
element.classList.toggle('protocol-message-recieved', this.data.direction !== 'sent');
|
|
return element;
|
|
}
|
|
};
|
|
|
|
|
|
ProtocolMonitor.ProtocolMonitor.InfoWidget = class extends UI.VBox {
|
|
constructor() {
|
|
super();
|
|
this._tabbedPane = new UI.TabbedPane();
|
|
this._tabbedPane.appendTab('request', 'Request', new UI.Widget());
|
|
this._tabbedPane.appendTab('response', 'Response', new UI.Widget());
|
|
this._tabbedPane.show(this.contentElement);
|
|
this._tabbedPane.selectTab('response');
|
|
this.render(null);
|
|
}
|
|
|
|
/**
|
|
* @param {?{method: string, direction: string, request: ?Object, response: ?Object, timestamp: number}} data
|
|
*/
|
|
render(data) {
|
|
const requestEnabled = data && data.direction === 'sent';
|
|
this._tabbedPane.setTabEnabled('request', !!requestEnabled);
|
|
if (!data) {
|
|
this._tabbedPane.changeTabView('request', new UI.EmptyWidget(ls`No message selected`));
|
|
this._tabbedPane.changeTabView('response', new UI.EmptyWidget(ls`No message selected`));
|
|
return;
|
|
}
|
|
if (!requestEnabled)
|
|
this._tabbedPane.selectTab('response');
|
|
|
|
this._tabbedPane.changeTabView('request', SourceFrame.JSONView.createViewSync(data.request));
|
|
this._tabbedPane.changeTabView('response', SourceFrame.JSONView.createViewSync(data.response));
|
|
}
|
|
};
|