import*as Bindings from'../bindings/bindings.js';import*as Common from'../common/common.js';import*as Host from'../host/host.js';import*as MobileThrottling from'../mobile_throttling/mobile_throttling.js';import*as SDK from'../sdk/sdk.js';import*as Search from'../search/search.js';import*as UI from'../ui/ui.js';import*as Workspace from'../workspace/workspace.js';import{BlockedURLsPane}from'./BlockedURLsPane.js';import{Events}from'./NetworkDataGridNode.js';import{NetworkItemView}from'./NetworkItemView.js';import{FilterType,NetworkLogView}from'./NetworkLogView.js';import{NetworkOverview}from'./NetworkOverview.js';import{NetworkSearchScope,UIRequestLocation}from'./NetworkSearchScope.js';import{NetworkTimeCalculator,NetworkTransferTimeCalculator}from'./NetworkTimeCalculator.js';export class NetworkPanel extends UI.Panel.Panel{constructor(){super('network');this.registerRequiredCSS('network/networkPanel.css');this._networkLogShowOverviewSetting=self.Common.settings.createSetting('networkLogShowOverview',true);this._networkLogLargeRowsSetting=self.Common.settings.createSetting('networkLogLargeRows',false);this._networkRecordFilmStripSetting=self.Common.settings.createSetting('networkRecordFilmStripSetting',false);this._toggleRecordAction=(self.UI.actionRegistry.action('network.toggle-recording'));this._pendingStopTimer;this._networkItemView=null;this._filmStripView=null;this._filmStripRecorder=null;this._currentRequest=null;const panel=new UI.Widget.VBox();const networkToolbarContainer=panel.contentElement.createChild('div','network-toolbar-container');this._panelToolbar=new UI.Toolbar.Toolbar('',networkToolbarContainer);this._rightToolbar=new UI.Toolbar.Toolbar('',networkToolbarContainer);this._filterBar=new UI.FilterBar.FilterBar('networkPanel',true);this._filterBar.show(panel.contentElement);this._filterBar.addEventListener(UI.FilterBar.FilterBar.Events.Changed,this._handleFilterChanged.bind(this));this._settingsPane=new UI.Widget.HBox();this._settingsPane.element.classList.add('network-settings-pane');this._settingsPane.show(panel.contentElement);this._showSettingsPaneSetting=self.Common.settings.createSetting('networkShowSettingsToolbar',false);this._showSettingsPaneSetting.addChangeListener(this._updateSettingsPaneVisibility.bind(this));this._updateSettingsPaneVisibility();this._filmStripPlaceholderElement=panel.contentElement.createChild('div','network-film-strip-placeholder');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 NetworkOverview();this._overviewPane.setOverviewControls([this._networkOverview]);this._overviewPlaceholderElement=panel.contentElement.createChild('div');this._calculator=new NetworkTransferTimeCalculator();this._splitWidget=new UI.SplitWidget.SplitWidget(true,false,'networkPanelSplitViewState');this._splitWidget.hideMain();this._splitWidget.show(panel.contentElement);panel.setDefaultFocusedChild(this._filterBar);const initialSidebarWidth=225;const splitWidget=new UI.SplitWidget.SplitWidget(true,false,'networkPanelSidebarState',initialSidebarWidth);splitWidget.hideSidebar();splitWidget.enableShowModeSaving();splitWidget.show(this.element);this._sidebarLocation=self.UI.viewManager.createTabbedLocation(async()=>{self.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.Toolbar.ToolbarButton(Common.UIString.UIString('Close'),'largeicon-delete');closeSidebar.addEventListener(UI.Toolbar.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');this._networkLogView=new NetworkLogView(this._filterBar,this._progressBarContainer,this._networkLogLargeRowsSetting);this._splitWidget.setSidebarWidget(this._networkLogView);this._fileSelectorElement=UI.UIUtils.createFileSelectorElement(this._networkLogView.onLoadFromFile.bind(this._networkLogView));panel.element.appendChild(this._fileSelectorElement);this._detailsWidget=new UI.Widget.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',async()=>await self.UI.actionRegistry.action('network.hide-request-details').execute(),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=self.Common.settings.moduleSetting('network_log.preserve-log');this._throttlingSelect=this._createThrottlingConditionsSelect();this._setupToolbarButtons(splitWidget);this._toggleRecord(true);this._toggleShowOverview();this._toggleLargerRequests();this._toggleRecordFilmStrip();this._updateUI();self.SDK.targetManager.addModelListener(SDK.ResourceTreeModel.ResourceTreeModel,SDK.ResourceTreeModel.Events.WillReloadPage,this._willReloadPage,this);self.SDK.targetManager.addModelListener(SDK.ResourceTreeModel.ResourceTreeModel,SDK.ResourceTreeModel.Events.Load,this._load,this);this._networkLogView.addEventListener(Events.RequestSelected,this._onRequestSelected,this);this._networkLogView.addEventListener(Events.RequestActivated,this._onRequestActivated,this);self.SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestAdded,this._onUpdateRequest,this);self.SDK.networkLog.addEventListener(SDK.NetworkLog.Events.RequestUpdated,this._onUpdateRequest,this);self.SDK.networkLog.addEventListener(SDK.NetworkLog.Events.Reset,this._onNetworkLogReset,this);}
static revealAndFilter(filters){const panel=NetworkPanel._instance();let filterString='';for(const filter of filters){filterString+=`${filter.filterType}:${filter.filterValue} `;}
panel._networkLogView.setTextFilterValue(filterString);self.UI.viewManager.showView('network');}
static _instance(){return(self.runtime.sharedInstance(NetworkPanel));}
throttlingSelectForTest(){return this._throttlingSelect;}
_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.Toolbar.ToolbarToggle(ls`Search`,'largeicon-search');function updateSidebarToggle(){const isSidebarShowing=splitWidget.showMode()!==UI.SplitWidget.ShowMode.OnlyMain;searchToggle.setToggled(isSidebarShowing);if(!isSidebarShowing){searchToggle.element.focus();}}
this._panelToolbar.appendToolbarItem(UI.Toolbar.Toolbar.createActionButton(this._toggleRecordAction));const clearButton=new UI.Toolbar.ToolbarButton(Common.UIString.UIString('Clear'),'largeicon-clear');clearButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click,()=>self.SDK.networkLog.reset(),this);this._panelToolbar.appendToolbarItem(clearButton);this._panelToolbar.appendSeparator();this._panelToolbar.appendToolbarItem(this._filterBar.filterButton());updateSidebarToggle();splitWidget.addEventListener(UI.SplitWidget.Events.ShowModeChanged,updateSidebarToggle);searchToggle.addEventListener(UI.Toolbar.ToolbarButton.Events.Click,async()=>await self.UI.actionRegistry.action('network.search').execute());this._panelToolbar.appendToolbarItem(searchToggle);this._panelToolbar.appendSeparator();this._panelToolbar.appendToolbarItem(new UI.Toolbar.ToolbarSettingCheckbox(this._preserveLogSetting,Common.UIString.UIString('Do not clear log on page reload / navigation'),Common.UIString.UIString('Preserve log')));const disableCacheCheckbox=new UI.Toolbar.ToolbarSettingCheckbox(self.Common.settings.moduleSetting('cacheDisabled'),Common.UIString.UIString('Disable cache (while DevTools is open)'),Common.UIString.UIString('Disable cache'));this._panelToolbar.appendToolbarItem(disableCacheCheckbox);this._panelToolbar.appendSeparator();this._panelToolbar.appendToolbarItem(this._throttlingSelect);this._rightToolbar.appendToolbarItem(new UI.Toolbar.ToolbarItem(this._progressBarContainer));this._rightToolbar.appendSeparator();this._rightToolbar.appendToolbarItem(new UI.Toolbar.ToolbarSettingToggle(this._showSettingsPaneSetting,'largeicon-settings-gear',ls`Network settings`));const settingsToolbarLeft=new UI.Toolbar.Toolbar('',this._settingsPane.element);settingsToolbarLeft.makeVertical();settingsToolbarLeft.appendToolbarItem(new UI.Toolbar.ToolbarSettingCheckbox(this._networkLogLargeRowsSetting,'',ls`Use large request rows`));settingsToolbarLeft.appendToolbarItem(new UI.Toolbar.ToolbarSettingCheckbox(this._networkLogShowOverviewSetting,'',ls`Show overview`));const settingsToolbarRight=new UI.Toolbar.Toolbar('',this._settingsPane.element);settingsToolbarRight.makeVertical();settingsToolbarRight.appendToolbarItem(new UI.Toolbar.ToolbarSettingCheckbox(self.Common.settings.moduleSetting('network.group-by-frame'),'',ls`Group by frame`));settingsToolbarRight.appendToolbarItem(new UI.Toolbar.ToolbarSettingCheckbox(this._networkRecordFilmStripSetting,'',ls`Capture screenshots`));this._panelToolbar.appendSeparator();const importHarButton=new UI.Toolbar.ToolbarButton(ls`Import HAR file...`,'largeicon-load');importHarButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click,()=>this._fileSelectorElement.click(),this);this._panelToolbar.appendToolbarItem(importHarButton);const exportHarButton=new UI.Toolbar.ToolbarButton(ls`Export HAR...`,'largeicon-download');exportHarButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click,()=>this._networkLogView.exportAll(),this);this._panelToolbar.appendToolbarItem(exportHarButton);}
_updateSettingsPaneVisibility(){this._settingsPane.element.classList.toggle('hidden',!this._showSettingsPaneSetting.get());}
_createThrottlingConditionsSelect(){const toolbarItem=new UI.Toolbar.ToolbarComboBox(null,ls`Throttling`);toolbarItem.setMaxWidth(160);MobileThrottling.ThrottlingManager.throttlingManager().decorateSelectWithNetworkThrottling(toolbarItem.selectElement());return toolbarItem;}
_toggleRecording(){if(!this._preserveLogSetting.get()&&!this._toggleRecordAction.toggled()){self.SDK.networkLog.reset();}
this._toggleRecord(!this._toggleRecordAction.toggled());}
_toggleRecord(toggled){this._toggleRecordAction.setToggled(toggled);this._networkLogView.setRecording(toggled);if(!toggled&&this._filmStripRecorder){this._filmStripRecorder.stopRecording(this._filmStripAvailable.bind(this));}
self.SDK.networkLog.setIsRecording(toggled);}
_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);function mapTimestamp(frame){return frame.timestamp/1000;}
this._networkLogView.addFilmStripFrames(timestamps);}
_onNetworkLogReset(){BlockedURLsPane.reset();if(!this._preserveLogSetting.get()){this._calculator.reset();this._overviewPane.reset();}
if(this._filmStripView){this._resetFilmStripView();}}
_willReloadPage(event){this._toggleRecord(true);if(this._pendingStopTimer){clearTimeout(this._pendingStopTimer);delete this._pendingStopTimer;}
if(this.isShowing()&&this._filmStripRecorder){this._filmStripRecorder.startRecording();}}
_load(event){if(this._filmStripRecorder&&this._filmStripRecorder.isRecording()){this._pendingStopTimer=setTimeout(this._stopFilmStripRecording.bind(this),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 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(){const reloadShortcutDescriptor=self.UI.shortcutRegistry.shortcutDescriptorsForAction('inspector_main.reload')[0];this._filmStripView.reset();if(reloadShortcutDescriptor){this._filmStripView.setStatusText(Common.UIString.UIString('Hit %s to reload and capture filmstrip.',reloadShortcutDescriptor.name));}}
elementsToRestoreScrollPositionsFor(){return this._networkLogView.elementsToRestoreScrollPositionsFor();}
wasShown(){self.UI.context.setFlavor(NetworkPanel,this);Host.userMetrics.panelLoaded('network','DevTools.Launch.Network');}
willHide(){self.UI.context.setFlavor(NetworkPanel,null);}
revealAndHighlightRequest(request){this._hideRequestPanel();if(request){this._networkLogView.revealAndHighlightRequest(request);}}
async selectRequest(request){await self.UI.viewManager.showView('network');this._networkLogView.selectRequest(request);return this._networkItemView;}
_handleFilterChanged(event){this._hideRequestPanel();}
_onRowSizeChanged(event){this._updateUI();}
_onRequestSelected(event){const request=(event.data);this._currentRequest=request;this._networkOverview.setHighlightedRequest(request);this._updateNetworkItemView();}
_onRequestActivated(event){const showPanel=(event.data);if(showPanel){this._showRequestPanel();}else{this._hideRequestPanel();}}
_showRequestPanel(){this._clearNetworkItemView();if(this._currentRequest){this._createNetworkItemView();}
this._updateUI();}
_hideRequestPanel(){this._clearNetworkItemView();this._splitWidget.hideMain();this._updateUI();}
_updateNetworkItemView(){if(this._splitWidget.showMode()===UI.SplitWidget.ShowMode.Both){this._clearNetworkItemView();this._createNetworkItemView();this._updateUI();}}
_clearNetworkItemView(){if(this._networkItemView){this._networkItemView.detach();this._networkItemView=null;}}
_createNetworkItemView(){if(!this._currentRequest){return;}
this._networkItemView=new NetworkItemView(this._currentRequest,this._networkLogView.timeCalculator());this._networkItemView.leftToolbar().appendToolbarItem(new UI.Toolbar.ToolbarItem(this._closeButtonElement));this._networkItemView.show(this._detailsWidget.element);this._splitWidget.showBoth();}
_updateUI(){this._detailsWidget.element.classList.toggle('network-details-view-tall-header',this._networkLogLargeRowsSetting.get());this._networkLogView.switchViewMode(!this._splitWidget.isResizable());}
appendApplicableItems(event,contextMenu,target){function reveal(request){self.UI.viewManager.showView('network').then(this.revealAndHighlightRequest.bind(this,request));}
function appendRevealItem(request){contextMenu.revealSection().appendItem(Common.UIString.UIString('Reveal in Network panel'),reveal.bind(this,request));}
if(event.target.isSelfOrDescendant(this.element)){return;}
if(target instanceof SDK.Resource.Resource){const resource=(target);if(resource.request){appendRevealItem.call(this,resource.request);}
return;}
if(target instanceof Workspace.UISourceCode.UISourceCode){const uiSourceCode=(target);const resource=Bindings.ResourceUtils.resourceForURL(uiSourceCode.url());if(resource&&resource.request){appendRevealItem.call(this,resource.request);}
return;}
if(!(target instanceof SDK.NetworkRequest.NetworkRequest)){return;}
const request=(target);if(this._networkItemView&&this._networkItemView.isShowing()&&this._networkItemView.request()===request){return;}
appendRevealItem.call(this,request);}
_onFilmFrameSelected(event){const timestamp=(event.data);this._overviewPane.setWindowTimes(0,timestamp);}
_onFilmFrameEnter(event){const timestamp=(event.data);this._networkOverview.selectFilmStripFrame(timestamp);this._networkLogView.selectFilmStripFrame(timestamp/1000);}
_onFilmFrameExit(event){this._networkOverview.clearFilmStripFrame();this._networkLogView.clearFilmStripFrame();}
_onUpdateRequest(event){const request=(event.data);this._calculator.updateBoundaries(request);this._overviewPane.setBounds(this._calculator.minimumBoundary()*1000,this._calculator.maximumBoundary()*1000);this._networkOverview.updateRequest(request);this._overviewPane.scheduleUpdate();}
resolveLocation(locationName){if(locationName==='network-sidebar'){return this._sidebarLocation;}
return null;}}
export const displayScreenshotDelay=1000;export class ContextMenuProvider{appendApplicableItems(event,contextMenu,target){NetworkPanel._instance().appendApplicableItems(event,contextMenu,target);}}
export class RequestRevealer{reveal(request){if(!(request instanceof SDK.NetworkRequest.NetworkRequest)){return Promise.reject(new Error('Internal error: not a network request'));}
const panel=NetworkPanel._instance();return self.UI.viewManager.showView('network').then(panel.revealAndHighlightRequest.bind(panel,request));}}
export class FilmStripRecorder{constructor(timeCalculator,filmStripView){this._tracingManager=null;this._resourceTreeModel=null;this._timeCalculator=timeCalculator;this._filmStripView=filmStripView;this._tracingModel=null;this._callback=null;}
traceEventsCollected(events){if(this._tracingModel){this._tracingModel.addEvents(events);}}
tracingComplete(){if(!this._tracingModel||!this._tracingManager){return;}
this._tracingModel.tracingComplete();this._tracingManager=null;this._callback(new SDK.FilmStripModel.FilmStripModel(this._tracingModel,this._timeCalculator.minimumBoundary()*1000));this._callback=null;if(this._resourceTreeModel){this._resourceTreeModel.resumeReload();}
this._resourceTreeModel=null;}
tracingBufferUsage(){}
eventsRetrievalProgress(progress){}
startRecording(){this._filmStripView.reset();this._filmStripView.setStatusText(Common.UIString.UIString('Recording frames...'));const tracingManagers=self.SDK.targetManager.models(SDK.TracingManager.TracingManager);if(this._tracingManager||!tracingManagers.length){return;}
this._tracingManager=tracingManagers[0];this._resourceTreeModel=this._tracingManager.target().model(SDK.ResourceTreeModel.ResourceTreeModel);if(this._tracingModel){this._tracingModel.dispose();}
this._tracingModel=new SDK.TracingModel.TracingModel(new Bindings.TempFile.TempFileBackingStorage());this._tracingManager.start(this,'-*,disabled-by-default-devtools.screenshot','');Host.userMetrics.actionTaken(Host.UserMetrics.Action.FilmStripStartedRecording);}
isRecording(){return!!this._tracingManager;}
stopRecording(callback){if(!this._tracingManager){return;}
this._tracingManager.stop();if(this._resourceTreeModel){this._resourceTreeModel.suspendReload();}
this._callback=callback;this._filmStripView.setStatusText(Common.UIString.UIString('Fetching frames...'));}}
export class ActionDelegate{handleAction(context,actionId){const panel=self.UI.context.flavor(NetworkPanel);console.assert(panel&&panel instanceof NetworkPanel);switch(actionId){case'network.toggle-recording':panel._toggleRecording();return true;case'network.hide-request-details':if(!panel._networkItemView){return false;}
panel._hideRequestPanel();panel._networkLogView.resetFocus();return true;case'network.search':const selection=self.UI.inspectorView.element.window().getSelection();let queryCandidate='';if(selection.rangeCount){queryCandidate=selection.toString().replace(/\r?\n.*/,'');}
SearchNetworkView.openSearch(queryCandidate);return true;}
return false;}}
export class RequestLocationRevealer{async reveal(match){const location=(match);const view=await 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);}}}
export class SearchNetworkView extends Search.SearchView.SearchView{constructor(){super('network');}
static async openSearch(query,searchImmediately){await self.UI.viewManager.showView('network.search-network-tab');const searchView=(self.runtime.sharedInstance(SearchNetworkView));searchView.toggle(query,!!searchImmediately);return searchView;}
createScope(){return new NetworkSearchScope();}}