blob: 1d2fc78d0f1cb4888542a668da8530ea7c09f493 [file] [log] [blame]
/*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @implements {UI.ContextMenu.Provider}
* @implements {UI.ViewLocationResolver}
*/
Network.NetworkPanel = class extends UI.Panel {
constructor() {
super('network');
this.registerRequiredCSS('network/networkPanel.css');
this._networkLogShowOverviewSetting = Common.settings.createSetting('networkLogShowOverview', true);
this._networkLogLargeRowsSetting = Common.settings.createSetting('networkLogLargeRows', false);
this._networkRecordFilmStripSetting = Common.settings.createSetting('networkRecordFilmStripSetting', false);
this._toggleRecordAction = /** @type {!UI.Action }*/ (UI.actionRegistry.action('network.toggle-recording'));
/** @type {number|undefined} */
this._pendingStopTimer;
/** @type {?Network.NetworkItemView} */
this._networkItemView = null;
/** @type {?PerfUI.FilmStripView} */
this._filmStripView = null;
/** @type {?Network.NetworkPanel.FilmStripRecorder} */
this._filmStripRecorder = null;
const panel = new UI.VBox();
this._panelToolbar = new UI.Toolbar('', panel.contentElement);
this._filterBar = new UI.FilterBar('networkPanel', true);
this._filterBar.show(panel.contentElement);
this._filmStripPlaceholderElement = panel.contentElement.createChild('div', 'network-film-strip-placeholder');
// Create top overview component.
this._overviewPane = new PerfUI.TimelineOverviewPane('network');
this._overviewPane.addEventListener(
PerfUI.TimelineOverviewPane.Events.WindowChanged, this._onWindowChanged.bind(this));
this._overviewPane.element.id = 'network-overview-panel';
this._networkOverview = new Network.NetworkOverview();
this._overviewPane.setOverviewControls([this._networkOverview]);
this._overviewPlaceholderElement = panel.contentElement.createChild('div');
this._calculator = new Network.NetworkTransferTimeCalculator();
this._splitWidget = new UI.SplitWidget(true, false, 'networkPanelSplitViewState');
this._splitWidget.hideMain();
this._splitWidget.show(panel.contentElement);
panel.setDefaultFocusedChild(this._filterBar);
const initialSidebarWidth = 225;
const splitWidget = new UI.SplitWidget(true, false, 'networkPanelSidebarState', initialSidebarWidth);
splitWidget.hideSidebar();
splitWidget.enableShowModeSaving();
splitWidget.element.tabIndex = 0;
splitWidget.show(this.element);
this._sidebarLocation = UI.viewManager.createTabbedLocation(async () => {
UI.viewManager.showView('network');
splitWidget.showBoth();
}, 'network-sidebar', true);
const tabbedPane = this._sidebarLocation.tabbedPane();
tabbedPane.setMinimumSize(100, 25);
tabbedPane.element.classList.add('network-tabbed-pane');
tabbedPane.element.addEventListener('keydown', event => {
if (event.key !== 'Escape')
return;
splitWidget.hideSidebar();
event.consume();
});
const closeSidebar = new UI.ToolbarButton(Common.UIString('Close'), 'largeicon-delete');
closeSidebar.addEventListener(UI.ToolbarButton.Events.Click, () => splitWidget.hideSidebar());
tabbedPane.rightToolbar().appendToolbarItem(closeSidebar);
splitWidget.setSidebarWidget(tabbedPane);
splitWidget.setMainWidget(panel);
splitWidget.setDefaultFocusedChild(panel);
this.setDefaultFocusedChild(splitWidget);
this._progressBarContainer = createElement('div');
/** @type {!Network.NetworkLogView} */
this._networkLogView =
new Network.NetworkLogView(this._filterBar, this._progressBarContainer, this._networkLogLargeRowsSetting);
this._splitWidget.setSidebarWidget(this._networkLogView);
this._detailsWidget = new UI.VBox();
this._detailsWidget.element.classList.add('network-details-view');
this._splitWidget.setMainWidget(this._detailsWidget);
this._closeButtonElement = createElement('div', 'dt-close-button');
this._closeButtonElement.addEventListener('click', this._showRequest.bind(this, null), false);
this._closeButtonElement.style.margin = '0 5px';
this._networkLogShowOverviewSetting.addChangeListener(this._toggleShowOverview, this);
this._networkLogLargeRowsSetting.addChangeListener(this._toggleLargerRequests, this);
this._networkRecordFilmStripSetting.addChangeListener(this._toggleRecordFilmStrip, this);
this._preserveLogSetting = Common.moduleSetting('network_log.preserve-log');
this._offlineCheckbox = MobileThrottling.throttlingManager().createOfflineToolbarCheckbox();
this._throttlingSelect = this._createThrottlingConditionsSelect();
this._setupToolbarButtons(splitWidget);
this._toggleRecord(true);
this._toggleShowOverview();
this._toggleLargerRequests();
this._toggleRecordFilmStrip();
this._updateUI();
SDK.targetManager.addModelListener(
SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.WillReloadPage, this._willReloadPage, this);
SDK.targetManager.addModelListener(SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.Load, this._load, this);
this._networkLogView.addEventListener(Network.NetworkLogView.Events.RequestSelected, this._onRequestSelected, this);
BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestAdded, this._onUpdateRequest, this);
BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.RequestUpdated, this._onUpdateRequest, this);
BrowserSDK.networkLog.addEventListener(BrowserSDK.NetworkLog.Events.Reset, this._onNetworkLogReset, this);
}
/**
* @param {!Array<{filterType: !Network.NetworkLogView.FilterType, filterValue: string}>} filters
*/
static revealAndFilter(filters) {
const panel = Network.NetworkPanel._instance();
let filterString = '';
for (const filter of filters)
filterString += `${filter.filterType}:${filter.filterValue} `;
panel._networkLogView.setTextFilterValue(filterString);
UI.viewManager.showView('network');
}
/**
* @return {!Network.NetworkPanel}
*/
static _instance() {
return /** @type {!Network.NetworkPanel} */ (self.runtime.sharedInstance(Network.NetworkPanel));
}
/**
* @return {!UI.ToolbarCheckbox}
*/
offlineCheckboxForTest() {
return this._offlineCheckbox;
}
/**
* @return {!UI.ToolbarComboBox}
*/
throttlingSelectForTest() {
return this._throttlingSelect;
}
/**
* @param {!Common.Event} event
*/
_onWindowChanged(event) {
const startTime = Math.max(this._calculator.minimumBoundary(), event.data.startTime / 1000);
const endTime = Math.min(this._calculator.maximumBoundary(), event.data.endTime / 1000);
this._networkLogView.setWindow(startTime, endTime);
}
_setupToolbarButtons(splitWidget) {
const searchToggle = new UI.ToolbarToggle('Search', 'largeicon-search');
function updateSidebarToggle() {
searchToggle.setToggled(splitWidget.showMode() !== UI.SplitWidget.ShowMode.OnlyMain);
}
this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._toggleRecordAction));
const clearButton = new UI.ToolbarButton(Common.UIString('Clear'), 'largeicon-clear');
clearButton.addEventListener(UI.ToolbarButton.Events.Click, () => BrowserSDK.networkLog.reset(), this);
this._panelToolbar.appendToolbarItem(clearButton);
this._panelToolbar.appendSeparator();
const recordFilmStripButton = new UI.ToolbarSettingToggle(
this._networkRecordFilmStripSetting, 'largeicon-camera', Common.UIString('Capture screenshots'));
this._panelToolbar.appendToolbarItem(recordFilmStripButton);
this._panelToolbar.appendToolbarItem(this._filterBar.filterButton());
updateSidebarToggle();
splitWidget.addEventListener(UI.SplitWidget.Events.ShowModeChanged, updateSidebarToggle);
searchToggle.addEventListener(UI.ToolbarButton.Events.Click, () => {
if (splitWidget.showMode() === UI.SplitWidget.ShowMode.OnlyMain)
splitWidget.showBoth();
else
splitWidget.hideSidebar();
});
this._panelToolbar.appendToolbarItem(searchToggle);
this._panelToolbar.appendSeparator();
this._panelToolbar.appendText(Common.UIString('View:'));
const largerRequestsButton = new UI.ToolbarSettingToggle(
this._networkLogLargeRowsSetting, 'largeicon-large-list', Common.UIString('Use large request rows'),
Common.UIString('Use small request rows'));
this._panelToolbar.appendToolbarItem(largerRequestsButton);
const showOverviewButton = new UI.ToolbarSettingToggle(
this._networkLogShowOverviewSetting, 'largeicon-waterfall', Common.UIString('Show overview'),
Common.UIString('Hide overview'));
this._panelToolbar.appendToolbarItem(showOverviewButton);
this._panelToolbar.appendToolbarItem(new UI.ToolbarSettingCheckbox(
Common.moduleSetting('network.group-by-frame'), '', Common.UIString('Group by frame')));
this._panelToolbar.appendSeparator();
this._panelToolbar.appendToolbarItem(new UI.ToolbarSettingCheckbox(
this._preserveLogSetting, Common.UIString('Do not clear log on page reload / navigation'),
Common.UIString('Preserve log')));
const disableCacheCheckbox = new UI.ToolbarSettingCheckbox(
Common.moduleSetting('cacheDisabled'), Common.UIString('Disable cache (while DevTools is open)'),
Common.UIString('Disable cache'));
this._panelToolbar.appendToolbarItem(disableCacheCheckbox);
this._panelToolbar.appendSeparator();
this._panelToolbar.appendToolbarItem(this._offlineCheckbox);
this._panelToolbar.appendToolbarItem(this._throttlingSelect);
this._panelToolbar.appendToolbarItem(new UI.ToolbarItem(this._progressBarContainer));
}
/**
* @return {!UI.ToolbarComboBox}
*/
_createThrottlingConditionsSelect() {
const toolbarItem = new UI.ToolbarComboBox(null);
toolbarItem.setTitle(ls`Throttling`);
toolbarItem.setMaxWidth(160);
MobileThrottling.throttlingManager().decorateSelectWithNetworkThrottling(toolbarItem.selectElement());
return toolbarItem;
}
_toggleRecording() {
if (!this._preserveLogSetting.get() && !this._toggleRecordAction.toggled())
BrowserSDK.networkLog.reset();
this._toggleRecord(!this._toggleRecordAction.toggled());
}
/**
* @param {boolean} toggled
*/
_toggleRecord(toggled) {
this._toggleRecordAction.setToggled(toggled);
this._networkLogView.setRecording(toggled);
if (!toggled && this._filmStripRecorder)
this._filmStripRecorder.stopRecording(this._filmStripAvailable.bind(this));
// TODO(einbinder) This should be moved to a setting/action that NetworkLog owns but NetworkPanel controls, but
// always be present in the command menu.
BrowserSDK.networkLog.setIsRecording(toggled);
}
/**
* @param {?SDK.FilmStripModel} filmStripModel
*/
_filmStripAvailable(filmStripModel) {
if (!filmStripModel)
return;
const calculator = this._networkLogView.timeCalculator();
this._filmStripView.setModel(filmStripModel, calculator.minimumBoundary() * 1000, calculator.boundarySpan() * 1000);
this._networkOverview.setFilmStripModel(filmStripModel);
const timestamps = filmStripModel.frames().map(mapTimestamp);
/**
* @param {!SDK.FilmStripModel.Frame} frame
* @return {number}
*/
function mapTimestamp(frame) {
return frame.timestamp / 1000;
}
this._networkLogView.addFilmStripFrames(timestamps);
}
_onNetworkLogReset() {
Network.BlockedURLsPane.reset();
if (!this._preserveLogSetting.get()) {
this._calculator.reset();
this._overviewPane.reset();
}
if (this._filmStripView)
this._resetFilmStripView();
}
/**
* @param {!Common.Event} event
*/
_willReloadPage(event) {
this._toggleRecord(true);
if (this._pendingStopTimer) {
clearTimeout(this._pendingStopTimer);
delete this._pendingStopTimer;
}
if (this.isShowing() && this._filmStripRecorder)
this._filmStripRecorder.startRecording();
}
/**
* @param {!Common.Event} event
*/
_load(event) {
if (this._filmStripRecorder && this._filmStripRecorder.isRecording()) {
this._pendingStopTimer =
setTimeout(this._stopFilmStripRecording.bind(this), Network.NetworkPanel.displayScreenshotDelay);
}
}
_stopFilmStripRecording() {
this._filmStripRecorder.stopRecording(this._filmStripAvailable.bind(this));
delete this._pendingStopTimer;
}
_toggleLargerRequests() {
this._updateUI();
}
_toggleShowOverview() {
const toggled = this._networkLogShowOverviewSetting.get();
if (toggled)
this._overviewPane.show(this._overviewPlaceholderElement);
else
this._overviewPane.detach();
this.doResize();
}
_toggleRecordFilmStrip() {
const toggled = this._networkRecordFilmStripSetting.get();
if (toggled && !this._filmStripRecorder) {
this._filmStripView = new PerfUI.FilmStripView();
this._filmStripView.setMode(PerfUI.FilmStripView.Modes.FrameBased);
this._filmStripView.element.classList.add('network-film-strip');
this._filmStripRecorder =
new Network.NetworkPanel.FilmStripRecorder(this._networkLogView.timeCalculator(), this._filmStripView);
this._filmStripView.show(this._filmStripPlaceholderElement);
this._filmStripView.addEventListener(PerfUI.FilmStripView.Events.FrameSelected, this._onFilmFrameSelected, this);
this._filmStripView.addEventListener(PerfUI.FilmStripView.Events.FrameEnter, this._onFilmFrameEnter, this);
this._filmStripView.addEventListener(PerfUI.FilmStripView.Events.FrameExit, this._onFilmFrameExit, this);
this._resetFilmStripView();
}
if (!toggled && this._filmStripRecorder) {
this._filmStripView.detach();
this._filmStripView = null;
this._filmStripRecorder = null;
}
}
_resetFilmStripView() {
this._filmStripView.reset();
this._filmStripView.setStatusText(Common.UIString(
'Hit %s to reload and capture filmstrip.',
UI.shortcutRegistry.shortcutDescriptorsForAction('inspector_main.reload')[0].name));
}
/**
* @override
* @return {!Array.<!Element>}
*/
elementsToRestoreScrollPositionsFor() {
return this._networkLogView.elementsToRestoreScrollPositionsFor();
}
/**
* @override
*/
wasShown() {
UI.context.setFlavor(Network.NetworkPanel, this);
}
/**
* @override
*/
willHide() {
UI.context.setFlavor(Network.NetworkPanel, null);
}
/**
* @param {!SDK.NetworkRequest} request
*/
revealAndHighlightRequest(request) {
this._showRequest(null);
if (request)
this._networkLogView.revealAndHighlightRequest(request);
}
/**
* @param {!SDK.NetworkRequest} request
* @return {!Promise<?Network.NetworkItemView>}
*/
async selectRequest(request) {
await UI.viewManager.showView('network');
this._networkLogView.selectRequest(request);
return this._networkItemView;
}
/**
* @param {!Common.Event} event
*/
_onRowSizeChanged(event) {
this._updateUI();
}
/**
* @param {!Common.Event} event
*/
_onRequestSelected(event) {
const request = /** @type {?SDK.NetworkRequest} */ (event.data);
this._showRequest(request);
}
/**
* @param {?SDK.NetworkRequest} request
*/
_showRequest(request) {
if (this._networkItemView) {
this._networkItemView.detach();
this._networkItemView = null;
}
if (request) {
this._networkItemView = new Network.NetworkItemView(request, this._networkLogView.timeCalculator());
this._networkItemView.leftToolbar().appendToolbarItem(new UI.ToolbarItem(this._closeButtonElement));
this._networkItemView.show(this._detailsWidget.element);
this._splitWidget.showBoth();
} else {
this._splitWidget.hideMain();
this._networkLogView.clearSelection();
}
this._updateUI();
}
_updateUI() {
this._detailsWidget.element.classList.toggle(
'network-details-view-tall-header', this._networkLogLargeRowsSetting.get());
this._networkLogView.switchViewMode(!this._splitWidget.isResizable());
}
/**
* @override
* @param {!Event} event
* @param {!UI.ContextMenu} contextMenu
* @param {!Object} target
* @this {Network.NetworkPanel}
*/
appendApplicableItems(event, contextMenu, target) {
/**
* @this {Network.NetworkPanel}
*/
function reveal(request) {
UI.viewManager.showView('network').then(this.revealAndHighlightRequest.bind(this, request));
}
/**
* @this {Network.NetworkPanel}
*/
function appendRevealItem(request) {
contextMenu.revealSection().appendItem(Common.UIString('Reveal in Network panel'), reveal.bind(this, request));
}
if (event.target.isSelfOrDescendant(this.element))
return;
if (target instanceof SDK.Resource) {
const resource = /** @type {!SDK.Resource} */ (target);
if (resource.request)
appendRevealItem.call(this, resource.request);
return;
}
if (target instanceof Workspace.UISourceCode) {
const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (target);
const resource = Bindings.resourceForURL(uiSourceCode.url());
if (resource && resource.request)
appendRevealItem.call(this, resource.request);
return;
}
if (!(target instanceof SDK.NetworkRequest))
return;
const request = /** @type {!SDK.NetworkRequest} */ (target);
if (this._networkItemView && this._networkItemView.isShowing() && this._networkItemView.request() === request)
return;
appendRevealItem.call(this, request);
}
/**
* @param {!Common.Event} event
*/
_onFilmFrameSelected(event) {
const timestamp = /** @type {number} */ (event.data);
this._overviewPane.setWindowTimes(0, timestamp);
}
/**
* @param {!Common.Event} event
*/
_onFilmFrameEnter(event) {
const timestamp = /** @type {number} */ (event.data);
this._networkOverview.selectFilmStripFrame(timestamp);
this._networkLogView.selectFilmStripFrame(timestamp / 1000);
}
/**
* @param {!Common.Event} event
*/
_onFilmFrameExit(event) {
this._networkOverview.clearFilmStripFrame();
this._networkLogView.clearFilmStripFrame();
}
/**
* @param {!Common.Event} event
*/
_onUpdateRequest(event) {
const request = /** @type {!SDK.NetworkRequest} */ (event.data);
this._calculator.updateBoundaries(request);
// FIXME: Unify all time units across the frontend!
this._overviewPane.setBounds(this._calculator.minimumBoundary() * 1000, this._calculator.maximumBoundary() * 1000);
this._networkOverview.updateRequest(request);
this._overviewPane.scheduleUpdate();
}
/**
* @override
* @param {string} locationName
* @return {?UI.ViewLocation}
*/
resolveLocation(locationName) {
if (locationName === 'network-sidebar')
return this._sidebarLocation;
return null;
}
};
Network.NetworkPanel.displayScreenshotDelay = 1000;
/**
* @implements {UI.ContextMenu.Provider}
* @unrestricted
*/
Network.NetworkPanel.ContextMenuProvider = class {
/**
* @override
* @param {!Event} event
* @param {!UI.ContextMenu} contextMenu
* @param {!Object} target
*/
appendApplicableItems(event, contextMenu, target) {
Network.NetworkPanel._instance().appendApplicableItems(event, contextMenu, target);
}
};
/**
* @implements {Common.Revealer}
* @unrestricted
*/
Network.NetworkPanel.RequestRevealer = class {
/**
* @override
* @param {!Object} request
* @return {!Promise}
*/
reveal(request) {
if (!(request instanceof SDK.NetworkRequest))
return Promise.reject(new Error('Internal error: not a network request'));
const panel = Network.NetworkPanel._instance();
return UI.viewManager.showView('network').then(panel.revealAndHighlightRequest.bind(panel, request));
}
};
/**
* @implements {SDK.TracingManagerClient}
*/
Network.NetworkPanel.FilmStripRecorder = class {
/**
* @param {!Network.NetworkTimeCalculator} timeCalculator
* @param {!PerfUI.FilmStripView} filmStripView
*/
constructor(timeCalculator, filmStripView) {
/** @type {?SDK.TracingManager} */
this._tracingManager = null;
/** @type {?SDK.ResourceTreeModel} */
this._resourceTreeModel = null;
this._timeCalculator = timeCalculator;
this._filmStripView = filmStripView;
/** @type {?SDK.TracingModel} */
this._tracingModel = null;
/** @type {?function(?SDK.FilmStripModel)} */
this._callback = null;
}
/**
* @override
* @param {!Array.<!SDK.TracingManager.EventPayload>} events
*/
traceEventsCollected(events) {
if (this._tracingModel)
this._tracingModel.addEvents(events);
}
/**
* @override
*/
tracingComplete() {
if (!this._tracingModel || !this._tracingManager)
return;
this._tracingModel.tracingComplete();
this._tracingManager = null;
this._callback(new SDK.FilmStripModel(this._tracingModel, this._timeCalculator.minimumBoundary() * 1000));
this._callback = null;
if (this._resourceTreeModel)
this._resourceTreeModel.resumeReload();
this._resourceTreeModel = null;
}
/**
* @override
*/
tracingBufferUsage() {
}
/**
* @override
* @param {number} progress
*/
eventsRetrievalProgress(progress) {
}
startRecording() {
this._filmStripView.reset();
this._filmStripView.setStatusText(Common.UIString('Recording frames...'));
const tracingManagers = SDK.targetManager.models(SDK.TracingManager);
if (this._tracingManager || !tracingManagers.length)
return;
this._tracingManager = tracingManagers[0];
this._resourceTreeModel = this._tracingManager.target().model(SDK.ResourceTreeModel);
if (this._tracingModel)
this._tracingModel.dispose();
this._tracingModel = new SDK.TracingModel(new Bindings.TempFileBackingStorage());
this._tracingManager.start(this, '-*,disabled-by-default-devtools.screenshot', '');
}
/**
* @return {boolean}
*/
isRecording() {
return !!this._tracingManager;
}
/**
* @param {function(?SDK.FilmStripModel)} callback
*/
stopRecording(callback) {
if (!this._tracingManager)
return;
this._tracingManager.stop();
if (this._resourceTreeModel)
this._resourceTreeModel.suspendReload();
this._callback = callback;
this._filmStripView.setStatusText(Common.UIString('Fetching frames...'));
}
};
/**
* @implements {UI.ActionDelegate}
*/
Network.NetworkPanel.ActionDelegate = class {
/**
* @override
* @param {!UI.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction(context, actionId) {
const panel = UI.context.flavor(Network.NetworkPanel);
console.assert(panel && panel instanceof Network.NetworkPanel);
switch (actionId) {
case 'network.toggle-recording':
panel._toggleRecording();
return true;
case 'network.hide-request-details':
if (!panel._networkItemView)
return false;
panel._showRequest(null);
return true;
case 'network.search':
const selection = UI.inspectorView.element.window().getSelection();
let queryCandidate = '';
if (selection.rangeCount)
queryCandidate = selection.toString().replace(/\r?\n.*/, '');
Network.SearchNetworkView.openSearch(queryCandidate);
return true;
}
return false;
}
};
/**
* @implements {Common.Revealer}
*/
Network.NetworkPanel.RequestLocationRevealer = class {
/**
* @override
* @param {!Object} match
* @return {!Promise}
*/
async reveal(match) {
const location = /** @type {!Network.UIRequestLocation} */ (match);
const view = await Network.NetworkPanel._instance().selectRequest(location.request);
if (!view)
return;
if (location.searchMatch)
await view.revealResponseBody(location.searchMatch.lineNumber);
if (location.requestHeader)
view.revealRequestHeader(location.requestHeader.name);
if (location.responseHeader)
view.revealResponseHeader(location.responseHeader.name);
}
};
Network.SearchNetworkView = class extends Search.SearchView {
constructor() {
super('network');
}
/**
* @param {string} query
* @param {boolean=} searchImmediately
* @return {!Promise<!Search.SearchView>}
*/
static async openSearch(query, searchImmediately) {
await UI.viewManager.showView('network.search-network-tab');
const searchView =
/** @type {!Network.SearchNetworkView} */ (self.runtime.sharedInstance(Network.SearchNetworkView));
searchView.toggle(query, !!searchImmediately);
return searchView;
}
/**
* @override
* @return {!Search.SearchScope}
*/
createScope() {
return new Network.NetworkSearchScope();
}
};