import{Events,PerformanceModel}from'./PerformanceModel.js';import{Client,TimelineController}from'./TimelineController.js';import{TimelineEventOverview,TimelineEventOverviewCoverage,TimelineEventOverviewCPUActivity,TimelineEventOverviewFrames,TimelineEventOverviewInput,TimelineEventOverviewMemory,TimelineEventOverviewNetwork,TimelineEventOverviewResponsiveness,TimelineFilmStripOverview,}from'./TimelineEventOverview.js';import{TimelineFlameChartView}from'./TimelineFlameChartView.js';import{TimelineHistoryManager}from'./TimelineHistoryManager.js';import{TimelineLoader}from'./TimelineLoader.js';import{TimelineUIUtils}from'./TimelineUIUtils.js';import{UIDevtoolsController}from'./UIDevtoolsController.js';import{UIDevtoolsUtils}from'./UIDevtoolsUtils.js';export class TimelinePanel extends UI.Panel{constructor(){super('timeline');this.registerRequiredCSS('timeline/timelinePanel.css');this.element.addEventListener('contextmenu',this._contextMenu.bind(this),false);this._dropTarget=new UI.DropTarget(this.element,[UI.DropTarget.Type.File,UI.DropTarget.Type.URI],Common.UIString('Drop timeline file or URL here'),this._handleDrop.bind(this));this._recordingOptionUIControls=[];this._state=State.Idle;this._recordingPageReload=false;this._millisecondsToRecordAfterLoadEvent=3000;this._toggleRecordAction=(self.UI.actionRegistry.action('timeline.toggle-recording'));this._recordReloadAction=(self.UI.actionRegistry.action('timeline.record-reload'));this._historyManager=new TimelineHistoryManager();this._performanceModel=null;this._viewModeSetting=self.Common.settings.createSetting('timelineViewMode',ViewMode.FlameChart);this._disableCaptureJSProfileSetting=self.Common.settings.createSetting('timelineDisableJSSampling',false);this._disableCaptureJSProfileSetting.setTitle(Common.UIString('Disable JavaScript samples'));this._captureLayersAndPicturesSetting=self.Common.settings.createSetting('timelineCaptureLayersAndPictures',false);this._captureLayersAndPicturesSetting.setTitle(Common.UIString('Enable advanced paint instrumentation (slow)'));this._showScreenshotsSetting=self.Common.settings.createSetting('timelineShowScreenshots',true);this._showScreenshotsSetting.setTitle(Common.UIString('Screenshots'));this._showScreenshotsSetting.addChangeListener(this._updateOverviewControls,this);this._startCoverage=self.Common.settings.createSetting('timelineStartCoverage',false);this._startCoverage.setTitle(ls`Coverage`);if(!Root.Runtime.experiments.isEnabled('recordCoverageWithPerformanceTracing')){this._startCoverage.set(false);}
this._showMemorySetting=self.Common.settings.createSetting('timelineShowMemory',false);this._showMemorySetting.setTitle(Common.UIString('Memory'));this._showMemorySetting.addChangeListener(this._onModeChanged,this);const timelineToolbarContainer=this.element.createChild('div','timeline-toolbar-container');this._panelToolbar=new UI.Toolbar('timeline-main-toolbar',timelineToolbarContainer);this._panelRightToolbar=new UI.Toolbar('',timelineToolbarContainer);this._createSettingsPane();this._updateShowSettingsToolbarButton();this._timelinePane=new UI.VBox();this._timelinePane.show(this.element);const topPaneElement=this._timelinePane.element.createChild('div','hbox');topPaneElement.id='timeline-overview-panel';this._overviewPane=new PerfUI.TimelineOverviewPane('timeline');this._overviewPane.addEventListener(PerfUI.TimelineOverviewPane.Events.WindowChanged,this._onOverviewWindowChanged.bind(this));this._overviewPane.show(topPaneElement);this._overviewControls=[];this._statusPaneContainer=this._timelinePane.element.createChild('div','status-pane-container fill');this._createFileSelector();self.SDK.targetManager.addModelListener(SDK.ResourceTreeModel,SDK.ResourceTreeModel.Events.Load,this._loadEventFired,this);this._flameChart=new TimelineFlameChartView(this);this._searchableView=new UI.SearchableView(this._flameChart);this._searchableView.setMinimumSize(0,100);this._searchableView.element.classList.add('searchable-view');this._searchableView.show(this._timelinePane.element);this._flameChart.show(this._searchableView.element);this._flameChart.setSearchableView(this._searchableView);this._onModeChanged();this._populateToolbar();this._showLandingPage();this._updateTimelineControls();self.Extensions.extensionServer.addEventListener(Extensions.ExtensionServer.Events.TraceProviderAdded,this._appendExtensionsToToolbar,this);self.SDK.targetManager.addEventListener(SDK.TargetManager.Events.SuspendStateChanged,this._onSuspendStateChanged,this);}
static instance(){return(self.runtime.sharedInstance(TimelinePanel));}
searchableView(){return this._searchableView;}
wasShown(){self.UI.context.setFlavor(TimelinePanel,this);Host.userMetrics.panelLoaded('timeline','DevTools.Launch.Timeline');}
willHide(){self.UI.context.setFlavor(TimelinePanel,null);this._historyManager.cancelIfShowing();}
loadFromEvents(events){if(this._state!==State.Idle){return;}
this._prepareToLoadTimeline();this._loader=TimelineLoader.loadFromEvents(events,this);}
_onOverviewWindowChanged(event){const left=event.data.startTime;const right=event.data.endTime;this._performanceModel.setWindow({left,right},true);}
_onModelWindowChanged(event){const window=(event.data.window);this._overviewPane.setWindowTimes(window.left,window.right);}
_setState(state){this._state=state;this._updateTimelineControls();}
_createSettingCheckbox(setting,tooltip){const checkboxItem=new UI.ToolbarSettingCheckbox(setting,tooltip);this._recordingOptionUIControls.push(checkboxItem);return checkboxItem;}
_populateToolbar(){this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._toggleRecordAction));this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButton(this._recordReloadAction));this._clearButton=new UI.ToolbarButton(Common.UIString('Clear'),'largeicon-clear');this._clearButton.addEventListener(UI.ToolbarButton.Events.Click,()=>this._onClearButton());this._panelToolbar.appendToolbarItem(this._clearButton);this._loadButton=new UI.ToolbarButton(Common.UIString('Load profile...'),'largeicon-load');this._loadButton.addEventListener(UI.ToolbarButton.Events.Click,()=>this._selectFileToLoad());this._saveButton=new UI.ToolbarButton(Common.UIString('Save profile...'),'largeicon-download');this._saveButton.addEventListener(UI.ToolbarButton.Events.Click,()=>this._saveToFile());this._panelToolbar.appendSeparator();this._panelToolbar.appendToolbarItem(this._loadButton);this._panelToolbar.appendToolbarItem(this._saveButton);this._panelToolbar.appendSeparator();this._panelToolbar.appendToolbarItem(this._historyManager.button());this._panelToolbar.appendSeparator();this._panelToolbar.appendSeparator();this._showScreenshotsToolbarCheckbox=this._createSettingCheckbox(this._showScreenshotsSetting,Common.UIString('Capture screenshots'));this._panelToolbar.appendToolbarItem(this._showScreenshotsToolbarCheckbox);this._showMemoryToolbarCheckbox=this._createSettingCheckbox(this._showMemorySetting,Common.UIString('Show memory timeline'));this._panelToolbar.appendToolbarItem(this._showMemoryToolbarCheckbox);if(Root.Runtime.experiments.isEnabled('recordCoverageWithPerformanceTracing')){this._startCoverageCheckbox=this._createSettingCheckbox(this._startCoverage,ls`Record coverage with performance trace`);this._panelToolbar.appendToolbarItem(this._startCoverageCheckbox);}
this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButtonForId('components.collect-garbage'));this._panelRightToolbar.appendSeparator();this._panelRightToolbar.appendToolbarItem(this._showSettingsPaneButton);}
_createSettingsPane(){this._showSettingsPaneSetting=self.Common.settings.createSetting('timelineShowSettingsToolbar',false);this._showSettingsPaneButton=new UI.ToolbarSettingToggle(this._showSettingsPaneSetting,'largeicon-settings-gear',Common.UIString('Capture settings'));self.SDK.multitargetNetworkManager.addEventListener(SDK.MultitargetNetworkManager.Events.ConditionsChanged,this._updateShowSettingsToolbarButton,this);MobileThrottling.throttlingManager().addEventListener(MobileThrottling.ThrottlingManager.Events.RateChanged,this._updateShowSettingsToolbarButton,this);this._disableCaptureJSProfileSetting.addChangeListener(this._updateShowSettingsToolbarButton,this);this._captureLayersAndPicturesSetting.addChangeListener(this._updateShowSettingsToolbarButton,this);this._settingsPane=new UI.HBox();this._settingsPane.element.classList.add('timeline-settings-pane');this._settingsPane.show(this.element);const captureToolbar=new UI.Toolbar('',this._settingsPane.element);captureToolbar.element.classList.add('flex-auto');captureToolbar.makeVertical();captureToolbar.appendToolbarItem(this._createSettingCheckbox(this._disableCaptureJSProfileSetting,Common.UIString('Disables JavaScript sampling, reduces overhead when running against mobile devices')));captureToolbar.appendToolbarItem(this._createSettingCheckbox(this._captureLayersAndPicturesSetting,Common.UIString('Captures advanced paint instrumentation, introduces significant performance overhead')));const throttlingPane=new UI.VBox();throttlingPane.element.classList.add('flex-auto');throttlingPane.show(this._settingsPane.element);const networkThrottlingToolbar=new UI.Toolbar('',throttlingPane.element);networkThrottlingToolbar.appendText(Common.UIString('Network:'));this._networkThrottlingSelect=this._createNetworkConditionsSelect();networkThrottlingToolbar.appendToolbarItem(this._networkThrottlingSelect);const cpuThrottlingToolbar=new UI.Toolbar('',throttlingPane.element);cpuThrottlingToolbar.appendText(Common.UIString('CPU:'));this._cpuThrottlingSelect=MobileThrottling.throttlingManager().createCPUThrottlingSelector();cpuThrottlingToolbar.appendToolbarItem(this._cpuThrottlingSelect);this._showSettingsPaneSetting.addChangeListener(this._updateSettingsPaneVisibility.bind(this));this._updateSettingsPaneVisibility();}
_appendExtensionsToToolbar(event){const provider=(event.data);const setting=TimelinePanel._settingForTraceProvider(provider);const checkbox=this._createSettingCheckbox(setting,provider.longDisplayName());this._panelToolbar.appendToolbarItem(checkbox);}
static _settingForTraceProvider(traceProvider){let setting=traceProvider[traceProviderSettingSymbol];if(!setting){const providerId=traceProvider.persistentIdentifier();setting=self.Common.settings.createSetting(providerId,false);setting.setTitle(traceProvider.shortDisplayName());traceProvider[traceProviderSettingSymbol]=setting;}
return setting;}
_createNetworkConditionsSelect(){const toolbarItem=new UI.ToolbarComboBox(null,ls`Network conditions`);toolbarItem.setMaxWidth(140);MobileThrottling.throttlingManager().decorateSelectWithNetworkThrottling(toolbarItem.selectElement());return toolbarItem;}
_prepareToLoadTimeline(){console.assert(this._state===State.Idle);this._setState(State.Loading);if(this._performanceModel){this._performanceModel.dispose();this._performanceModel=null;}}
_createFileSelector(){if(this._fileSelectorElement){this._fileSelectorElement.remove();}
this._fileSelectorElement=UI.createFileSelectorElement(this._loadFromFile.bind(this));this._timelinePane.element.appendChild(this._fileSelectorElement);}
_contextMenu(event){const contextMenu=new UI.ContextMenu(event);contextMenu.appendItemsAtLocation('timelineMenu');contextMenu.show();}
async _saveToFile(){if(this._state!==State.Idle){return;}
const performanceModel=this._performanceModel;if(!performanceModel){return;}
const now=new Date();const fileName='Profile-'+now.toISO8601Compact()+'.json';const stream=new Bindings.FileOutputStream();const accepted=await stream.open(fileName);if(!accepted){return;}
const error=await performanceModel.save(stream);if(!error){return;}
self.Common.console.error(Common.UIString('Failed to save timeline: %s (%s, %s)',error.message,error.name,error.code));}
async _showHistory(){const model=await this._historyManager.showHistoryDropDown();if(model&&model!==this._performanceModel){this._setModel(model);}}
_navigateHistory(direction){const model=this._historyManager.navigate(direction);if(model&&model!==this._performanceModel){this._setModel(model);}
return true;}
_selectFileToLoad(){this._fileSelectorElement.click();}
_loadFromFile(file){if(this._state!==State.Idle){return;}
this._prepareToLoadTimeline();this._loader=TimelineLoader.loadFromFile(file,this);this._createFileSelector();}
_loadFromURL(url){if(this._state!==State.Idle){return;}
this._prepareToLoadTimeline();this._loader=TimelineLoader.loadFromURL(url,this);}
_updateOverviewControls(){this._overviewControls=[];this._overviewControls.push(new TimelineEventOverviewResponsiveness());if(Root.Runtime.experiments.isEnabled('inputEventsOnTimelineOverview')){this._overviewControls.push(new TimelineEventOverviewInput());}
this._overviewControls.push(new TimelineEventOverviewFrames());this._overviewControls.push(new TimelineEventOverviewCPUActivity());this._overviewControls.push(new TimelineEventOverviewNetwork());if(this._showScreenshotsSetting.get()&&this._performanceModel&&this._performanceModel.filmStripModel().frames().length){this._overviewControls.push(new TimelineFilmStripOverview());}
if(this._showMemorySetting.get()){this._overviewControls.push(new TimelineEventOverviewMemory());}
if(this._startCoverage.get()){this._overviewControls.push(new TimelineEventOverviewCoverage());}
for(const control of this._overviewControls){control.setModel(this._performanceModel);}
this._overviewPane.setOverviewControls(this._overviewControls);}
_onModeChanged(){this._updateOverviewControls();this.doResize();this.select(null);}
_updateSettingsPaneVisibility(){if(this._showSettingsPaneSetting.get()){this._settingsPane.showWidget();}else{this._settingsPane.hideWidget();}}
_updateShowSettingsToolbarButton(){const messages=[];if(MobileThrottling.throttlingManager().cpuThrottlingRate()!==1){messages.push(Common.UIString('- CPU throttling is enabled'));}
if(self.SDK.multitargetNetworkManager.isThrottling()){messages.push(Common.UIString('- Network throttling is enabled'));}
if(this._captureLayersAndPicturesSetting.get()){messages.push(Common.UIString('- Significant overhead due to paint instrumentation'));}
if(this._disableCaptureJSProfileSetting.get()){messages.push(Common.UIString('- JavaScript sampling is disabled'));}
this._showSettingsPaneButton.setDefaultWithRedColor(messages.length);this._showSettingsPaneButton.setToggleWithRedColor(messages.length);if(messages.length){const tooltipElement=createElement('div');messages.forEach(message=>{tooltipElement.createChild('div').textContent=message;});this._showSettingsPaneButton.setTitle(tooltipElement);}else{this._showSettingsPaneButton.setTitle(Common.UIString('Capture settings'));}}
_setUIControlsEnabled(enabled){this._recordingOptionUIControls.forEach(control=>control.setEnabled(enabled));}
async _startRecording(){console.assert(!this._statusPane,'Status pane is already opened.');this._setState(State.StartPending);const recordingOptions={enableJSSampling:!this._disableCaptureJSProfileSetting.get(),capturePictures:this._captureLayersAndPicturesSetting.get(),captureFilmStrip:this._showScreenshotsSetting.get(),startCoverage:this._startCoverage.get()};if(recordingOptions.startCoverage){await self.UI.viewManager.showView('coverage').then(()=>self.UI.viewManager.view('coverage').widget()).then(widget=>widget.ensureRecordingStarted());}
this._showRecordingStarted();const enabledTraceProviders=self.Extensions.extensionServer.traceProviders().filter(provider=>TimelinePanel._settingForTraceProvider(provider).get());const mainTarget=(self.SDK.targetManager.mainTarget());if(UIDevtoolsUtils.isUiDevTools()){this._controller=new UIDevtoolsController(mainTarget,this);}else{this._controller=new TimelineController(mainTarget,this);}
this._setUIControlsEnabled(false);this._hideLandingPage();const response=await this._controller.startRecording(recordingOptions,enabledTraceProviders);if(response[Protocol.Error]){this._recordingFailed(response[Protocol.Error]);}else{this._recordingStarted();}}
async _stopRecording(){if(this._statusPane){this._statusPane.finish();this._statusPane.updateStatus(Common.UIString('Stopping timeline\u2026'));this._statusPane.updateProgressBar(Common.UIString('Received'),0);}
this._setState(State.StopPending);if(this._startCoverage.get()){await UI.viewManager.showView('coverage').then(()=>UI.viewManager.view('coverage').widget()).then(widget=>widget.stopRecording());}
const model=await this._controller.stopRecording();this._performanceModel=model;this._setUIControlsEnabled(true);this._controller.dispose();this._controller=null;}
_recordingFailed(error){if(this._statusPane){this._statusPane.hide();}
this._statusPane=new StatusPane({description:error},()=>this.loadingComplete(null));this._statusPane.showPane(this._statusPaneContainer);this._statusPane.updateStatus(ls`Recording failed`);this._statusPane.updateButton(ls`Close`);this._setState(State.RecordingFailed);this._performanceModel=null;this._setUIControlsEnabled(false);this._controller.dispose();this._controller=null;}
_onSuspendStateChanged(){this._updateTimelineControls();}
_updateTimelineControls(){const state=State;this._toggleRecordAction.setToggled(this._state===state.Recording);this._toggleRecordAction.setEnabled(this._state===state.Recording||this._state===state.Idle);this._recordReloadAction.setEnabled(this._state===state.Idle);this._historyManager.setEnabled(this._state===state.Idle);this._clearButton.setEnabled(this._state===state.Idle);this._panelToolbar.setEnabled(this._state!==state.Loading);this._panelRightToolbar.setEnabled(this._state!==state.Loading);this._dropTarget.setEnabled(this._state===state.Idle);this._loadButton.setEnabled(this._state===state.Idle);this._saveButton.setEnabled(this._state===state.Idle&&!!this._performanceModel);}
_toggleRecording(){if(this._state===State.Idle){this._recordingPageReload=false;this._startRecording();Host.userMetrics.actionTaken(Host.UserMetrics.Action.TimelineStarted);}else if(this._state===State.Recording){this._stopRecording();}}
_recordReload(){if(this._state!==State.Idle){return;}
this._recordingPageReload=true;this._startRecording();Host.userMetrics.actionTaken(Host.UserMetrics.Action.TimelinePageReloadStarted);}
_onClearButton(){this._historyManager.clear();this._clear();}
_clear(){this._showLandingPage();this._reset();}
_reset(){self.runtime.sharedInstance(PerfUI.LineLevelProfile.Performance).reset();this._setModel(null);}
_applyFilters(model){if(model.timelineModel().isGenericTrace()||Root.Runtime.experiments.isEnabled('timelineShowAllEvents')){return;}
model.setFilters([TimelineUIUtils.visibleEventsFilter()]);}
_setModel(model){if(this._performanceModel){this._performanceModel.removeEventListener(Events.WindowChanged,this._onModelWindowChanged,this);}
this._performanceModel=model;if(model){this._applyFilters(model);}
this._flameChart.setModel(model);this._updateOverviewControls();this._overviewPane.reset();if(model){this._performanceModel.addEventListener(Events.WindowChanged,this._onModelWindowChanged,this);this._overviewPane.setBounds(model.timelineModel().minimumRecordTime(),model.timelineModel().maximumRecordTime());const lineLevelProfile=self.runtime.sharedInstance(PerfUI.LineLevelProfile.Performance);lineLevelProfile.reset();for(const profile of model.timelineModel().cpuProfiles()){lineLevelProfile.appendCPUProfile(profile);}
this._setMarkers(model.timelineModel());this._flameChart.setSelection(null);this._overviewPane.setWindowTimes(model.window().left,model.window().right);}
for(const control of this._overviewControls){control.setModel(model);}
if(this._flameChart){this._flameChart.resizeToPreferredHeights();}
this._updateTimelineControls();}
_recordingStarted(){if(this._recordingPageReload){const target=this._controller.mainTarget();const resourceModel=target.model(SDK.ResourceTreeModel);if(resourceModel){resourceModel.reloadPage();}}
this._reset();this._setState(State.Recording);this._showRecordingStarted();this._statusPane.enableAndFocusStopButton();this._statusPane.updateStatus(Common.UIString('Profiling\u2026'));this._statusPane.updateProgressBar(Common.UIString('Buffer usage'),0);this._statusPane.startTimer();this._hideLandingPage();}
recordingProgress(usage){this._statusPane.updateProgressBar(Common.UIString('Buffer usage'),usage*100);}
_showLandingPage(){if(this._landingPage){this._landingPage.show(this._statusPaneContainer);return;}
function encloseWithTag(tagName,contents){const e=createElement(tagName);e.textContent=contents;return e;}
const learnMoreNode=UI.XLink.create('https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/',Common.UIString('Learn\xa0more'));const recordKey=encloseWithTag('b',self.UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.toggle-recording')[0].name);const reloadKey=encloseWithTag('b',self.UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.record-reload')[0].name);const navigateNode=encloseWithTag('b',Common.UIString('WASD'));this._landingPage=new UI.VBox();this._landingPage.contentElement.classList.add('timeline-landing-page','fill');const centered=this._landingPage.contentElement.createChild('div');const recordButton=UI.createInlineButton(UI.Toolbar.createActionButton(this._toggleRecordAction));const reloadButton=UI.createInlineButton(UI.Toolbar.createActionButtonForId('timeline.record-reload'));centered.createChild('p').appendChild(UI.formatLocalized('Click the record button %s or hit %s to start a new recording.\nClick the reload button %s or hit %s to record the page load.',[recordButton,recordKey,reloadButton,reloadKey]));centered.createChild('p').appendChild(UI.formatLocalized('After recording, select an area of interest in the overview by dragging.\nThen, zoom and pan the timeline with the mousewheel or %s keys.\n%s',[navigateNode,learnMoreNode]));this._landingPage.show(this._statusPaneContainer);}
_hideLandingPage(){this._landingPage.detach();}
loadingStarted(){this._hideLandingPage();if(this._statusPane){this._statusPane.hide();}
this._statusPane=new StatusPane({showProgress:true},this._cancelLoading.bind(this));this._statusPane.showPane(this._statusPaneContainer);this._statusPane.updateStatus(Common.UIString('Loading profile\u2026'));if(!this._loader){this._statusPane.finish();}
this.loadingProgress(0);}
loadingProgress(progress){if(typeof progress==='number'){this._statusPane.updateProgressBar(Common.UIString('Received'),progress*100);}}
processingStarted(){this._statusPane.updateStatus(Common.UIString('Processing profile\u2026'));}
loadingComplete(tracingModel){delete this._loader;this._setState(State.Idle);if(this._statusPane){this._statusPane.hide();}
delete this._statusPane;if(!tracingModel){this._clear();return;}
if(!this._performanceModel){this._performanceModel=new PerformanceModel();}
this._performanceModel.setTracingModel(tracingModel);this._setModel(this._performanceModel);this._historyManager.addRecording(this._performanceModel);if(this._startCoverage.get()){UI.viewManager.showView('coverage').then(()=>UI.viewManager.view('coverage').widget()).then(widget=>widget.processBacklog()).then(()=>this._updateOverviewControls());}}
_showRecordingStarted(){if(this._statusPane){return;}
this._statusPane=new StatusPane({showTimer:true,showProgress:true},this._stopRecording.bind(this));this._statusPane.showPane(this._statusPaneContainer);this._statusPane.updateStatus(Common.UIString('Initializing profiler\u2026'));}
_cancelLoading(){if(this._loader){this._loader.cancel();}}
_setMarkers(timelineModel){const markers=new Map();const recordTypes=TimelineModel.TimelineModel.RecordType;const zeroTime=timelineModel.minimumRecordTime();for(const event of timelineModel.timeMarkerEvents()){if(event.name===recordTypes.TimeStamp||event.name===recordTypes.ConsoleTime){continue;}
markers.set(event.startTime,TimelineUIUtils.createEventDivider(event,zeroTime));}
this._overviewPane.setMarkers(markers);}
async _loadEventFired(event){if(this._state!==State.Recording||!this._recordingPageReload||this._controller.mainTarget()!==event.data.resourceTreeModel.target()){return;}
const controller=this._controller;await new Promise(r=>setTimeout(r,this._millisecondsToRecordAfterLoadEvent));if(controller!==this._controller||this._state!==State.Recording){return;}
this._stopRecording();}
_frameForSelection(selection){switch(selection.type()){case TimelineSelection.Type.Frame:return(selection.object());case TimelineSelection.Type.Range:return null;case TimelineSelection.Type.TraceEvent:return this._performanceModel.frameModel().frames(selection._endTime,selection._endTime)[0];default:console.assert(false,'Should never be reached');return null;}}
_jumpToFrame(offset){const currentFrame=this._selection&&this._frameForSelection(this._selection);if(!currentFrame){return;}
const frames=this._performanceModel.frames();let index=frames.indexOf(currentFrame);console.assert(index>=0,'Can\'t find current frame in the frame list');index=Number.constrain(index+offset,0,frames.length-1);const frame=frames[index];this._revealTimeRange(frame.startTime,frame.endTime);this.select(TimelineSelection.fromFrame(frame));return true;}
select(selection){this._selection=selection;this._flameChart.setSelection(selection);}
selectEntryAtTime(events,time){if(!events){return;}
for(let index=events.upperBound(time,(time,event)=>time-event.startTime)-1;index>=0;--index){const event=events[index];const endTime=event.endTime||event.startTime;if(SDK.TracingModel.isTopLevelEvent(event)&&endTime<time){break;}
if(this._performanceModel.isVisible(event)&&endTime>=time){this.select(TimelineSelection.fromTraceEvent(event));return;}}
this.select(null);}
highlightEvent(event){this._flameChart.highlightEvent(event);}
_revealTimeRange(startTime,endTime){const window=this._performanceModel.window();let offset=0;if(window.right<endTime){offset=endTime-window.right;}else if(window.left>startTime){offset=startTime-window.left;}
this._performanceModel.setWindow({left:window.left+offset,right:window.right+offset},true);}
_handleDrop(dataTransfer){const items=dataTransfer.items;if(!items.length){return;}
const item=items[0];if(item.kind==='string'){const url=dataTransfer.getData('text/uri-list');if(new Common.ParsedURL(url).isValid){this._loadFromURL(url);}}else if(item.kind==='file'){const entry=items[0].webkitGetAsEntry();if(!entry.isFile){return;}
entry.file(this._loadFromFile.bind(this));}}}
export const State={Idle:Symbol('Idle'),StartPending:Symbol('StartPending'),Recording:Symbol('Recording'),StopPending:Symbol('StopPending'),Loading:Symbol('Loading'),RecordingFailed:Symbol('RecordingFailed')};export const ViewMode={FlameChart:'FlameChart',BottomUp:'BottomUp',CallTree:'CallTree',EventLog:'EventLog'};export const rowHeight=18;export const headerHeight=20;export class TimelineSelection{constructor(type,startTime,endTime,object){this._type=type;this._startTime=startTime;this._endTime=endTime;this._object=object||null;}
static fromFrame(frame){return new TimelineSelection(TimelineSelection.Type.Frame,frame.startTime,frame.endTime,frame);}
static fromNetworkRequest(request){return new TimelineSelection(TimelineSelection.Type.NetworkRequest,request.startTime,request.endTime||request.startTime,request);}
static fromTraceEvent(event){return new TimelineSelection(TimelineSelection.Type.TraceEvent,event.startTime,event.endTime||(event.startTime+1),event);}
static fromRange(startTime,endTime){return new TimelineSelection(TimelineSelection.Type.Range,startTime,endTime);}
type(){return this._type;}
object(){return this._object;}
startTime(){return this._startTime;}
endTime(){return this._endTime;}}
TimelineSelection.Type={Frame:'Frame',NetworkRequest:'NetworkRequest',TraceEvent:'TraceEvent',Range:'Range'};export class TimelineModeViewDelegate{select(selection){}
selectEntryAtTime(events,time){}
highlightEvent(event){}}
export class StatusPane extends UI.VBox{constructor(options,stopCallback){super(true);this.registerRequiredCSS('timeline/timelineStatusDialog.css');this.contentElement.classList.add('timeline-status-dialog');const statusLine=this.contentElement.createChild('div','status-dialog-line status');statusLine.createChild('div','label').textContent=Common.UIString('Status');this._status=statusLine.createChild('div','content');UI.ARIAUtils.markAsStatus(this._status);if(options.showTimer){const timeLine=this.contentElement.createChild('div','status-dialog-line time');timeLine.createChild('div','label').textContent=Common.UIString('Time');this._time=timeLine.createChild('div','content');}
if(options.showProgress){const progressLine=this.contentElement.createChild('div','status-dialog-line progress');this._progressLabel=progressLine.createChild('div','label');this._progressBar=progressLine.createChild('div','indicator-container').createChild('div','indicator');UI.ARIAUtils.markAsProgressBar(this._progressBar);}
if(typeof options.description==='string'){const descriptionLine=this.contentElement.createChild('div','status-dialog-line description');descriptionLine.createChild('div','label').textContent=ls`Description`;this._description=descriptionLine.createChild('div','content');this._description.innerText=options.description;}
this._stopButton=UI.createTextButton(Common.UIString('Stop'),stopCallback,'',true);this._stopButton.disabled=true;this.contentElement.createChild('div','stop-button').appendChild(this._stopButton);}
finish(){this._stopTimer();this._stopButton.disabled=true;}
hide(){this.element.parentNode.classList.remove('tinted');this.element.remove();}
showPane(parent){this.show(parent);parent.classList.add('tinted');}
enableAndFocusStopButton(){this._stopButton.disabled=false;this._stopButton.focus();}
updateStatus(text){this._status.textContent=text;}
updateProgressBar(activity,percent){this._progressLabel.textContent=activity;this._progressBar.style.width=percent.toFixed(1)+'%';UI.ARIAUtils.setValueNow(this._progressBar,percent);this._updateTimer();}
updateButton(caption){this._stopButton.innerText=caption;}
startTimer(){this._startTime=Date.now();this._timeUpdateTimer=setInterval(this._updateTimer.bind(this,false),1000);this._updateTimer();}
_stopTimer(){if(!this._timeUpdateTimer){return;}
clearInterval(this._timeUpdateTimer);this._updateTimer(true);delete this._timeUpdateTimer;}
_updateTimer(precise){if(!this._timeUpdateTimer){return;}
const elapsed=(Date.now()-this._startTime)/1000;this._time.textContent=Common.UIString('%s\xa0sec',elapsed.toFixed(precise?1:0));}}
export class LoadTimelineHandler{handleQueryParam(value){self.UI.viewManager.showView('timeline').then(()=>{TimelinePanel.instance()._loadFromURL(window.decodeURIComponent(value));});}}
export class ActionDelegate{handleAction(context,actionId){const panel=self.UI.context.flavor(TimelinePanel);console.assert(panel&&panel instanceof TimelinePanel);switch(actionId){case'timeline.toggle-recording':panel._toggleRecording();return true;case'timeline.record-reload':panel._recordReload();return true;case'timeline.save-to-file':panel._saveToFile();return true;case'timeline.load-from-file':panel._selectFileToLoad();return true;case'timeline.jump-to-previous-frame':panel._jumpToFrame(-1);return true;case'timeline.jump-to-next-frame':panel._jumpToFrame(1);return true;case'timeline.show-history':panel._showHistory();return true;case'timeline.previous-recording':panel._navigateHistory(1);return true;case'timeline.next-recording':panel._navigateHistory(-1);return true;}
return false;}}
export const traceProviderSettingSymbol=Symbol('traceProviderSetting');