@yuebai008/cli
Version:
Command line interface for rapid qg-minigame development
1 lines • 36.8 kB
JavaScript
import*as Common from"../../core/common/common.js";import*as Host from"../../core/host/host.js";import*as i18n from"../../core/i18n/i18n.js";import*as Platform from"../../core/platform/platform.js";import*as Root from"../../core/root/root.js";import*as SDK from"../../core/sdk/sdk.js";import*as TraceEngine from"../../models/trace/trace.js";import*as PanelFeedback from"../../ui/components/panel_feedback/panel_feedback.js";import*as PerfUI from"../../ui/legacy/components/perf_ui/perf_ui.js";import*as UI from"../../ui/legacy/legacy.js";import*as MobileThrottling from"../mobile_throttling/mobile_throttling.js";import historyToolbarButtonStyles from"./historyToolbarButton.css.js";import{Events,PerformanceModel}from"./PerformanceModel.js";import{cpuprofileJsonGenerator,traceJsonGenerator}from"./SaveFileFormatter.js";import{TimelineController}from"./TimelineController.js";import{TimelineFlameChartView}from"./TimelineFlameChartView.js";import{TimelineHistoryManager}from"./TimelineHistoryManager.js";import{TimelineLoader}from"./TimelineLoader.js";import{TimelineMiniMap}from"./TimelineMiniMap.js";import timelinePanelStyles from"./timelinePanel.css.js";import{TimelineSelection}from"./TimelineSelection.js";import timelineStatusDialogStyles from"./timelineStatusDialog.css.js";import{TimelineUIUtils}from"./TimelineUIUtils.js";import{UIDevtoolsController}from"./UIDevtoolsController.js";import{UIDevtoolsUtils}from"./UIDevtoolsUtils.js";const UIStrings={dropTimelineFileOrUrlHere:"Drop timeline file or URL here",disableJavascriptSamples:"Disable JavaScript samples",enableAdvancedPaint:"Enable advanced paint instrumentation (slow)",screenshots:"Screenshots",memory:"Memory",clear:"Clear",loadProfile:"Load profile…",saveProfile:"Save profile…",captureScreenshots:"Capture screenshots",showMemoryTimeline:"Show memory timeline",captureSettings:"Capture settings",disablesJavascriptSampling:"Disables JavaScript sampling, reduces overhead when running against mobile devices",capturesAdvancedPaint:"Captures advanced paint instrumentation, introduces significant performance overhead",network:"Network:",cpu:"CPU:",networkConditions:"Network conditions",failedToSaveTimelineSS:"Failed to save timeline: {PH1} ({PH2})",CpuThrottlingIsEnabled:"- CPU throttling is enabled",NetworkThrottlingIsEnabled:"- Network throttling is enabled",HardwareConcurrencyIsEnabled:"- Hardware concurrency override is enabled",SignificantOverheadDueToPaint:"- Significant overhead due to paint instrumentation",JavascriptSamplingIsDisabled:"- JavaScript sampling is disabled",stoppingTimeline:"Stopping timeline…",received:"Received",close:"Close",recordingFailed:"Recording failed",profiling:"Profiling…",bufferUsage:"Buffer usage",learnmore:"Learn more",wasd:"WASD",clickTheRecordButtonSOrHitSTo:"Click the record button {PH1} or hit {PH2} to start a new recording.",clickTheReloadButtonSOrHitSTo:"Click the reload button {PH1} or hit {PH2} to record the page load.",afterRecordingSelectAnAreaOf:"After recording, select an area of interest in the overview by dragging. Then, zoom and pan the timeline with the mousewheel or {PH1} keys. {PH2}",loadingProfile:"Loading profile…",processingProfile:"Processing profile…",initializingProfiler:"Initializing profiler…",status:"Status",time:"Time",description:"Description",stop:"Stop",ssec:"{PH1} sec"},str_=i18n.i18n.registerUIStrings("panels/timeline/TimelinePanel.ts",UIStrings),i18nString=i18n.i18n.getLocalizedString.bind(void 0,str_);let timelinePanelInstance,isNode,loadTimelineHandlerInstance,actionDelegateInstance;export class TimelinePanel extends UI.Panel.Panel{dropTarget;recordingOptionUIControls;state;recordingPageReload;millisecondsToRecordAfterLoadEvent;toggleRecordAction;recordReloadAction;#e;performanceModel;disableCaptureJSProfileSetting;captureLayersAndPicturesSetting;showScreenshotsSetting;showMemorySetting;panelToolbar;panelRightToolbar;timelinePane;#t=new TimelineMiniMap;statusPaneContainer;flameChart;searchableViewInternal;showSettingsPaneButton;showSettingsPaneSetting;settingsPane;controller;cpuProfiler;clearButton;loadButton;saveButton;statusPane;landingPage;loader;showScreenshotsToolbarCheckbox;showMemoryToolbarCheckbox;networkThrottlingSelect;cpuThrottlingSelect;fileSelectorElement;selection;traceLoadStart;primaryPageTargetPromiseCallback=e=>{};primaryPageTargetPromise=new Promise((e=>{this.primaryPageTargetPromiseCallback=e}));#i;#n=-1;constructor(e=!1){super("timeline"),this.#i=e?TraceEngine.TraceModel.Model.createWithAllHandlers():TraceEngine.TraceModel.Model.createWithRequiredHandlersForMigration(),this.element.addEventListener("contextmenu",this.contextMenu.bind(this),!1),this.dropTarget=new UI.DropTarget.DropTarget(this.element,[UI.DropTarget.Type.File,UI.DropTarget.Type.URI],i18nString(UIStrings.dropTimelineFileOrUrlHere),this.handleDrop.bind(this)),this.recordingOptionUIControls=[],this.state=State.Idle,this.recordingPageReload=!1,this.millisecondsToRecordAfterLoadEvent=5e3,this.toggleRecordAction=UI.ActionRegistry.ActionRegistry.instance().action("timeline.toggle-recording"),this.recordReloadAction=UI.ActionRegistry.ActionRegistry.instance().action("timeline.record-reload"),this.#e=new TimelineHistoryManager,this.performanceModel=null,this.traceLoadStart=null,this.disableCaptureJSProfileSetting=Common.Settings.Settings.instance().createSetting("timelineDisableJSSampling",!1),this.disableCaptureJSProfileSetting.setTitle(i18nString(UIStrings.disableJavascriptSamples)),this.captureLayersAndPicturesSetting=Common.Settings.Settings.instance().createSetting("timelineCaptureLayersAndPictures",!1),this.captureLayersAndPicturesSetting.setTitle(i18nString(UIStrings.enableAdvancedPaint)),this.showScreenshotsSetting=Common.Settings.Settings.instance().createSetting("timelineShowScreenshots",!isNode),this.showScreenshotsSetting.setTitle(i18nString(UIStrings.screenshots)),this.showScreenshotsSetting.addChangeListener(this.updateOverviewControls,this),this.showMemorySetting=Common.Settings.Settings.instance().createSetting("timelineShowMemory",!1),this.showMemorySetting.setTitle(i18nString(UIStrings.memory)),this.showMemorySetting.addChangeListener(this.onModeChanged,this);const t=this.element.createChild("div","timeline-toolbar-container");this.panelToolbar=new UI.Toolbar.Toolbar("timeline-main-toolbar",t),this.panelToolbar.makeWrappable(!0),this.panelRightToolbar=new UI.Toolbar.Toolbar("",t),isNode||(this.createSettingsPane(),this.updateShowSettingsToolbarButton()),this.timelinePane=new UI.Widget.VBox,this.timelinePane.show(this.element);const i=this.timelinePane.element.createChild("div","hbox");if(i.id="timeline-overview-panel",this.#t.show(i),this.#t.addEventListener(PerfUI.TimelineOverviewPane.Events.WindowChanged,this.onOverviewWindowChanged.bind(this)),this.statusPaneContainer=this.timelinePane.element.createChild("div","status-pane-container fill"),this.createFileSelector(),SDK.TargetManager.TargetManager.instance().addModelListener(SDK.ResourceTreeModel.ResourceTreeModel,SDK.ResourceTreeModel.Events.Load,this.loadEventFired,this),this.flameChart=new TimelineFlameChartView(this),this.searchableViewInternal=new UI.SearchableView.SearchableView(this.flameChart,null),this.searchableViewInternal.setMinimumSize(0,100),this.searchableViewInternal.element.classList.add("searchable-view"),this.searchableViewInternal.show(this.timelinePane.element),this.flameChart.show(this.searchableViewInternal.element),this.flameChart.setSearchableView(this.searchableViewInternal),this.searchableViewInternal.hideWidget(),this.onModeChanged(),this.populateToolbar(),this.showLandingPage(),this.updateTimelineControls(),SDK.TargetManager.TargetManager.instance().addEventListener(SDK.TargetManager.Events.SuspendStateChanged,this.onSuspendStateChanged,this),Root.Runtime.experiments.isEnabled("timelineAsConsoleProfileResultPanel")){const e=SDK.TargetManager.TargetManager.instance().models(SDK.CPUProfilerModel.CPUProfilerModel);for(const t of e)for(const e of t.registeredConsoleProfileMessages)this.consoleProfileFinished(e);SDK.TargetManager.TargetManager.instance().observeModels(SDK.CPUProfilerModel.CPUProfilerModel,{modelAdded:e=>{e.addEventListener(SDK.CPUProfilerModel.Events.ConsoleProfileFinished,(e=>this.consoleProfileFinished(e.data)))},modelRemoved:e=>{}})}SDK.TargetManager.TargetManager.instance().observeTargets({targetAdded:e=>{e===SDK.TargetManager.TargetManager.instance().primaryPageTarget()&&this.primaryPageTargetPromiseCallback(e)},targetRemoved:e=>{}})}static instance(e={forceNew:null,isNode:!1,fullTraceEngine:!1}){const{forceNew:t,isNode:i}=e;return isNode=i,timelinePanelInstance&&!t||(timelinePanelInstance=new TimelinePanel(e.fullTraceEngine)),timelinePanelInstance}searchableView(){return this.searchableViewInternal}wasShown(){super.wasShown(),UI.Context.Context.instance().setFlavor(TimelinePanel,this),this.registerCSSFiles([timelinePanelStyles]),Host.userMetrics.panelLoaded("timeline","DevTools.Launch.Timeline")}willHide(){UI.Context.Context.instance().setFlavor(TimelinePanel,null),this.#e.cancelIfShowing()}loadFromEvents(e){this.state===State.Idle&&(this.prepareToLoadTimeline(),this.loader=TimelineLoader.loadFromEvents(e,this))}loadFromCpuProfile(e,t){this.state===State.Idle&&(this.prepareToLoadTimeline(),this.loader=TimelineLoader.loadFromCpuProfile(e,this,t))}onOverviewWindowChanged(e){if(!this.performanceModel)return;const t=e.data.startTime>0?e.data.startTime:this.performanceModel.minimumRecordTime(),i=Number.isFinite(e.data.endTime)?e.data.endTime:this.performanceModel.maximumRecordTime();this.performanceModel.setWindow({left:t,right:i},!0)}onModelWindowChanged(e){const t=e.data.window;this.#t.setWindowTimes(t.left,t.right)}setState(e){this.state=e,this.updateTimelineControls()}createSettingCheckbox(e,t){const i=new UI.Toolbar.ToolbarSettingCheckbox(e,t);return this.recordingOptionUIControls.push(i),i}populateToolbar(){this.panelToolbar.appendToolbarItem(UI.Toolbar.Toolbar.createActionButton(this.toggleRecordAction)),this.panelToolbar.appendToolbarItem(UI.Toolbar.Toolbar.createActionButton(this.recordReloadAction)),this.clearButton=new UI.Toolbar.ToolbarButton(i18nString(UIStrings.clear),"clear"),this.clearButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click,(()=>this.onClearButton())),this.panelToolbar.appendToolbarItem(this.clearButton),this.loadButton=new UI.Toolbar.ToolbarButton(i18nString(UIStrings.loadProfile),"import"),this.loadButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click,(()=>{Host.userMetrics.actionTaken(Host.UserMetrics.Action.PerfPanelTraceImported),this.selectFileToLoad()})),this.saveButton=new UI.Toolbar.ToolbarButton(i18nString(UIStrings.saveProfile),"download"),this.saveButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click,(e=>{Host.userMetrics.actionTaken(Host.UserMetrics.Action.PerfPanelTraceExported),this.saveToFile()})),this.panelToolbar.appendSeparator(),this.panelToolbar.appendToolbarItem(this.loadButton),this.panelToolbar.appendToolbarItem(this.saveButton),this.panelToolbar.appendSeparator(),this.panelToolbar.appendToolbarItem(this.#e.button()),this.panelToolbar.registerCSSFiles([historyToolbarButtonStyles]),this.panelToolbar.appendSeparator(),this.panelToolbar.appendSeparator(),isNode||(this.showScreenshotsToolbarCheckbox=this.createSettingCheckbox(this.showScreenshotsSetting,i18nString(UIStrings.captureScreenshots)),this.panelToolbar.appendToolbarItem(this.showScreenshotsToolbarCheckbox)),this.showMemoryToolbarCheckbox=this.createSettingCheckbox(this.showMemorySetting,i18nString(UIStrings.showMemoryTimeline)),this.panelToolbar.appendToolbarItem(this.showMemoryToolbarCheckbox),this.panelToolbar.appendToolbarItem(UI.Toolbar.Toolbar.createActionButtonForId("components.collect-garbage")),isNode||(this.panelRightToolbar.appendSeparator(),this.panelRightToolbar.appendToolbarItem(this.showSettingsPaneButton))}createSettingsPane(){this.showSettingsPaneSetting=Common.Settings.Settings.instance().createSetting("timelineShowSettingsToolbar",!1),this.showSettingsPaneButton=new UI.Toolbar.ToolbarSettingToggle(this.showSettingsPaneSetting,"gear",i18nString(UIStrings.captureSettings),"gear-filled"),SDK.NetworkManager.MultitargetNetworkManager.instance().addEventListener(SDK.NetworkManager.MultitargetNetworkManager.Events.ConditionsChanged,this.updateShowSettingsToolbarButton,this),SDK.CPUThrottlingManager.CPUThrottlingManager.instance().addEventListener(SDK.CPUThrottlingManager.Events.RateChanged,this.updateShowSettingsToolbarButton,this),SDK.CPUThrottlingManager.CPUThrottlingManager.instance().addEventListener(SDK.CPUThrottlingManager.Events.HardwareConcurrencyChanged,this.updateShowSettingsToolbarButton,this),this.disableCaptureJSProfileSetting.addChangeListener(this.updateShowSettingsToolbarButton,this),this.captureLayersAndPicturesSetting.addChangeListener(this.updateShowSettingsToolbarButton,this),this.settingsPane=new UI.Widget.HBox,this.settingsPane.element.classList.add("timeline-settings-pane"),this.settingsPane.show(this.element);const e=new UI.Toolbar.Toolbar("",this.settingsPane.element);e.element.classList.add("flex-auto"),e.makeVertical(),e.appendToolbarItem(this.createSettingCheckbox(this.disableCaptureJSProfileSetting,i18nString(UIStrings.disablesJavascriptSampling))),e.appendToolbarItem(this.createSettingCheckbox(this.captureLayersAndPicturesSetting,i18nString(UIStrings.capturesAdvancedPaint)));const t=new UI.Widget.VBox;t.element.classList.add("flex-auto"),t.show(this.settingsPane.element);const i=new UI.Toolbar.Toolbar("",t.element);i.appendText(i18nString(UIStrings.cpu)),this.cpuThrottlingSelect=MobileThrottling.ThrottlingManager.throttlingManager().createCPUThrottlingSelector(),i.appendToolbarItem(this.cpuThrottlingSelect);const n=new UI.Toolbar.Toolbar("",t.element);n.appendText(i18nString(UIStrings.network)),this.networkThrottlingSelect=this.createNetworkConditionsSelect(),n.appendToolbarItem(this.networkThrottlingSelect);const r=new UI.Widget.VBox;r.element.classList.add("flex-auto"),r.show(this.settingsPane.element);const{toggle:a,input:o,reset:s,warning:l}=MobileThrottling.ThrottlingManager.throttlingManager().createHardwareConcurrencySelector(),d=new UI.Toolbar.Toolbar("",r.element);d.registerCSSFiles([timelinePanelStyles]),o.element.classList.add("timeline-concurrency-input"),d.appendToolbarItem(a),d.appendToolbarItem(o),d.appendToolbarItem(s),d.appendToolbarItem(l),this.showSettingsPaneSetting.addChangeListener(this.updateSettingsPaneVisibility.bind(this)),this.updateSettingsPaneVisibility()}createNetworkConditionsSelect(){const e=new UI.Toolbar.ToolbarComboBox(null,i18nString(UIStrings.networkConditions));return e.setMaxWidth(140),MobileThrottling.ThrottlingManager.throttlingManager().decorateSelectWithNetworkThrottling(e.selectElement()),e}prepareToLoadTimeline(){console.assert(this.state===State.Idle),this.setState(State.Loading),this.performanceModel&&(this.performanceModel=null)}createFileSelector(){this.fileSelectorElement&&this.fileSelectorElement.remove(),this.fileSelectorElement=UI.UIUtils.createFileSelectorElement(this.loadFromFile.bind(this)),this.timelinePane.element.appendChild(this.fileSelectorElement)}contextMenu(e){const t=new UI.ContextMenu.ContextMenu(e);t.appendItemsAtLocation("timelineMenu"),t.show()}async saveToFile(){if(this.state!==State.Idle)return;if(!this.performanceModel)return;const e=this.#i.traceEvents(this.#n),t=this.#i.metadata(this.#n);if(!e)return;const i=Platform.DateUtilities.toISO8601Compact(new Date);let n;n="CPUProfile"===t?.dataOrigin?`CPU-${i}.cpuprofile`:`Trace-${i}.json`;try{const i=await window.showSaveFilePicker({suggestedName:n}),r=new TextEncoder;let a;if("CPUProfile"===t?.dataOrigin){const t=e.find((e=>"CpuProfile"===e.name));if(!t||!t.args?.data)return;const i=t.args?.data;if(i.hasOwnProperty("cpuProfile")){const e=i.cpuProfile;a=cpuprofileJsonGenerator(e)}}else{const i=traceJsonGenerator(e,t);a=Array.from(i).join("")}const o=r.encode(a),s=await i.createWritable();await s.write(o),await s.close()}catch(e){if(console.error(e.stack),"AbortError"===e.name)return;Common.Console.Console.instance().error(i18nString(UIStrings.failedToSaveTimelineSS,{PH1:e.message,PH2:e.name}))}}async showHistory(){const e=await this.#e.showHistoryDropDown();e&&e.legacyModel!==this.performanceModel&&this.setModel(e.legacyModel,null,e.traceParseDataIndex)}navigateHistory(e){const t=this.#e.navigate(e);return t&&t.legacyModel!==this.performanceModel&&this.setModel(t.legacyModel,null,t.traceParseDataIndex),!0}selectFileToLoad(){this.fileSelectorElement&&this.fileSelectorElement.click()}async loadFromFile(e){this.state===State.Idle&&(this.prepareToLoadTimeline(),this.loader=await TimelineLoader.loadFromFile(e,this),this.createFileSelector())}async loadFromURL(e){this.state===State.Idle&&(this.prepareToLoadTimeline(),this.loader=await TimelineLoader.loadFromURL(e,this))}updateOverviewControls(){const e=this.#i.traceParsedData(this.#n);this.#t.setData({performanceModel:this.performanceModel,traceParsedData:e,settings:{showScreenshots:this.showScreenshotsSetting.get(),showMemory:this.showMemorySetting.get()}})}onModeChanged(){this.updateOverviewControls(),this.doResize(),this.select(null)}updateSettingsPaneVisibility(){isNode||(this.showSettingsPaneSetting.get()?this.settingsPane.showWidget():this.settingsPane.hideWidget())}updateShowSettingsToolbarButton(){const e=[];if(1!==SDK.CPUThrottlingManager.CPUThrottlingManager.instance().cpuThrottlingRate()&&e.push(i18nString(UIStrings.CpuThrottlingIsEnabled)),MobileThrottling.ThrottlingManager.throttlingManager().hardwareConcurrencyOverrideEnabled&&e.push(i18nString(UIStrings.HardwareConcurrencyIsEnabled)),SDK.NetworkManager.MultitargetNetworkManager.instance().isThrottling()&&e.push(i18nString(UIStrings.NetworkThrottlingIsEnabled)),this.captureLayersAndPicturesSetting.get()&&e.push(i18nString(UIStrings.SignificantOverheadDueToPaint)),this.disableCaptureJSProfileSetting.get()&&e.push(i18nString(UIStrings.JavascriptSamplingIsDisabled)),this.showSettingsPaneButton.setDefaultWithRedColor(e.length>0),this.showSettingsPaneButton.setToggleWithRedColor(e.length>0),e.length){const t=document.createElement("div");e.forEach((e=>{t.createChild("div").textContent=e})),this.showSettingsPaneButton.setTitle(t.textContent||"")}else this.showSettingsPaneButton.setTitle(i18nString(UIStrings.captureSettings))}setUIControlsEnabled(e){this.recordingOptionUIControls.forEach((t=>t.setEnabled(e)))}async#r(){if(!this.controller)return Platform.DevToolsPath.EmptyUrlString;const e=this.controller.primaryPageTarget.inspectedURL(),t=this.controller.primaryPageTarget.model(SDK.ResourceTreeModel.ResourceTreeModel),i=t&&await t.navigationHistory();if(!t||!i)return e;const{currentIndex:n,entries:r}=i;return r[n].url}async#a(){const e=new Promise((async(e,t)=>{if(!this.controller)return void t("Could not find TimelineController");const i=this.controller.primaryPageTarget.model(SDK.ResourceTreeModel.ResourceTreeModel);i?(i.addEventListener(SDK.ResourceTreeModel.Events.FrameNavigated,(function n(r){"about:blank"===r.data.url?e():t(`Unexpected navigation to ${r.data.url}`),i?.removeEventListener(SDK.ResourceTreeModel.Events.FrameNavigated,n)})),await i.navigate("about:blank")):t("Could not load resourceModel")}));await e}async#o(){try{const e=SDK.TargetManager.TargetManager.instance().targets().find((e=>e.type()===SDK.Target.Type.Node));if(!e)throw new Error("Could not load any Node target.");if(e&&(this.cpuProfiler=e.model(SDK.CPUProfilerModel.CPUProfilerModel)),this.setUIControlsEnabled(!1),this.hideLandingPage(),!this.cpuProfiler)throw new Error("No Node target is found.");await SDK.TargetManager.TargetManager.instance().suspendAllTargets("performance-timeline"),await this.cpuProfiler.startRecording(),this.recordingStarted()}catch(e){await this.recordingFailed(e.message)}}async#s(){try{const e=SDK.TargetManager.TargetManager.instance().primaryPageTarget();if(!e)throw new Error("Could not load primary page target.");if(UIDevtoolsUtils.isUiDevTools()?this.controller=new UIDevtoolsController(e,this):this.controller=new TimelineController(e,this),this.setUIControlsEnabled(!1),this.hideLandingPage(),!this.controller)throw new Error("Could not create Timeline controller");const t=await this.#r();this.recordingPageReload&&await this.#a();const i={enableJSSampling:!this.disableCaptureJSProfileSetting.get(),capturePictures:this.captureLayersAndPicturesSetting.get(),captureFilmStrip:this.showScreenshotsSetting.get()},n=await this.controller.startRecording(i);if(n.getError())throw new Error(n.getError());const r=this.recordingPageReload?{navigateToUrl:t}:void 0;this.recordingStarted(r)}catch(e){await this.recordingFailed(e.message)}}async startRecording(){console.assert(!this.statusPane,"Status pane is already opened."),this.setState(State.StartPending),this.showRecordingStarted(),isNode?await this.#o():await this.#s()}async stopRecording(){if(this.statusPane&&(this.statusPane.finish(),this.statusPane.updateStatus(i18nString(UIStrings.stoppingTimeline)),this.statusPane.updateProgressBar(i18nString(UIStrings.received),0)),this.setState(State.StopPending),this.controller)return this.performanceModel=this.controller.getPerformanceModel(),await this.controller.stopRecording(),this.setUIControlsEnabled(!0),await this.controller.dispose(),void(this.controller=null);if(this.cpuProfiler){const e=await this.cpuProfiler.stopRecording();this.setState(State.Idle),this.loadFromCpuProfile(e),this.setUIControlsEnabled(!0),this.cpuProfiler=null,await SDK.TargetManager.TargetManager.instance().resumeAllTargets()}}async recordingFailed(e){this.statusPane&&this.statusPane.remove(),this.statusPane=new StatusPane({description:e,buttonText:i18nString(UIStrings.close),buttonDisabled:!1,showProgress:void 0,showTimer:void 0},(()=>this.loadingComplete(null,null,!1))),this.statusPane.showPane(this.statusPaneContainer),this.statusPane.updateStatus(i18nString(UIStrings.recordingFailed)),this.setState(State.RecordingFailed),this.performanceModel=null,this.traceLoadStart=null,this.setUIControlsEnabled(!0),this.controller&&(await this.controller.dispose(),this.controller=null),SDK.TargetManager.TargetManager.instance().resumeAllTargets()}onSuspendStateChanged(){this.updateTimelineControls()}consoleProfileFinished(e){this.loadFromCpuProfile(e.cpuProfile,e.title),UI.InspectorView.InspectorView.instance().showPanel("timeline")}updateTimelineControls(){const e=State;this.toggleRecordAction.setToggled(this.state===e.Recording),this.toggleRecordAction.setEnabled(this.state===e.Recording||this.state===e.Idle),this.recordReloadAction.setEnabled(!isNode&&this.state===e.Idle),this.#e.setEnabled(this.state===e.Idle),this.clearButton.setEnabled(this.state===e.Idle),this.panelToolbar.setEnabled(this.state!==e.Loading),this.panelRightToolbar.setEnabled(this.state!==e.Loading),this.dropTarget.setEnabled(this.state===e.Idle),this.loadButton.setEnabled(this.state===e.Idle),this.saveButton.setEnabled(this.state===e.Idle&&Boolean(this.performanceModel))}async toggleRecording(){this.state===State.Idle?(this.recordingPageReload=!1,await this.startRecording(),Host.userMetrics.actionTaken(Host.UserMetrics.Action.TimelineStarted)):this.state===State.Recording&&await this.stopRecording()}recordReload(){this.state===State.Idle&&(this.recordingPageReload=!0,this.startRecording(),Host.userMetrics.actionTaken(Host.UserMetrics.Action.TimelinePageReloadStarted))}onClearButton(){this.#e.clear(),this.clear()}clear(){this.statusPane&&this.statusPane.remove(),this.showLandingPage(),this.reset()}reset(){PerfUI.LineLevelProfile.Performance.instance().reset(),this.performanceModel&&this.performanceModel.removeEventListener(Events.NamesResolved,this.updateModelAndFlameChart,this),this.setModel(null)}applyFilters(e,t=null){e.timelineModel().isGenericTrace()||Root.Runtime.experiments.isEnabled("timelineShowAllEvents")||e.setFilters(t?[t]:[TimelineUIUtils.visibleEventsFilter()])}setModel(e,t=null,i=-1){this.performanceModel&&this.performanceModel.removeEventListener(Events.WindowChanged,this.onModelWindowChanged,this),this.performanceModel=e,e?(this.searchableViewInternal.showWidget(),this.applyFilters(e,t)):this.searchableViewInternal.hideWidget(),this.#n=i;const n=this.#i.traceParsedData(this.#n);if(this.flameChart.setModel(e,n),this.updateOverviewControls(),this.#t.reset(),e&&this.performanceModel){this.performanceModel.addEventListener(Events.WindowChanged,this.onModelWindowChanged,this),this.#t.setBounds(TraceEngine.Types.Timing.MilliSeconds(e.timelineModel().minimumRecordTime()),TraceEngine.Types.Timing.MilliSeconds(e.timelineModel().maximumRecordTime())),PerfUI.LineLevelProfile.Performance.instance().reset();for(const t of e.timelineModel().cpuProfiles())PerfUI.LineLevelProfile.Performance.instance().appendCPUProfile(t.cpuProfileData,t.target);this.flameChart.setSelection(null),this.#t.setWindowTimes(e.window().left,e.window().right)}this.updateOverviewControls(),this.flameChart&&this.flameChart.resizeToPreferredHeights(),this.updateTimelineControls()}recordingStarted(e){if(e&&this.recordingPageReload&&this.controller){const t=this.controller?.primaryPageTarget.model(SDK.ResourceTreeModel.ResourceTreeModel);if(!t)return void this.recordingFailed("Could not navigate to original URL");t.navigate(e.navigateToUrl)}this.reset(),this.setState(State.Recording),this.showRecordingStarted(),this.statusPane&&(this.statusPane.enableAndFocusButton(),this.statusPane.updateStatus(i18nString(UIStrings.profiling)),this.statusPane.updateProgressBar(i18nString(UIStrings.bufferUsage),0),this.statusPane.startTimer()),this.hideLandingPage()}recordingProgress(e){this.statusPane&&this.statusPane.updateProgressBar(i18nString(UIStrings.bufferUsage),100*e)}showLandingPage(){if(this.updateSettingsPaneVisibility(),this.landingPage)return void this.landingPage.show(this.statusPaneContainer);function e(e,t){const i=document.createElement(e);return i.textContent=t,i}const t=UI.XLink.XLink.create("https://developer.chrome.com/docs/devtools/evaluate-performance/",i18nString(UIStrings.learnmore)),i=e("b",UI.ShortcutRegistry.ShortcutRegistry.instance().shortcutsForAction("timeline.toggle-recording")[0].title()),n=e("b",UI.ShortcutRegistry.ShortcutRegistry.instance().shortcutsForAction("timeline.record-reload")[0].title()),r=e("b",i18nString(UIStrings.wasd));this.landingPage=new UI.Widget.VBox,this.landingPage.contentElement.classList.add("timeline-landing-page","fill");const a=this.landingPage.contentElement.createChild("div"),o=UI.UIUtils.createInlineButton(UI.Toolbar.Toolbar.createActionButton(this.toggleRecordAction)),s=UI.UIUtils.createInlineButton(UI.Toolbar.Toolbar.createActionButtonForId("timeline.record-reload"));if(a.createChild("p").appendChild(i18n.i18n.getFormatLocalizedString(str_,UIStrings.clickTheRecordButtonSOrHitSTo,{PH1:o,PH2:i})),a.createChild("p").appendChild(i18n.i18n.getFormatLocalizedString(str_,UIStrings.clickTheReloadButtonSOrHitSTo,{PH1:s,PH2:n})),a.createChild("p").appendChild(i18n.i18n.getFormatLocalizedString(str_,UIStrings.afterRecordingSelectAnAreaOf,{PH1:r,PH2:t})),isNode){const e=new PanelFeedback.PanelFeedback.PanelFeedback;e.data={feedbackUrl:"https://bugs.chromium.org/p/chromium/issues/detail?id=1354548",quickStartUrl:"https://developer.chrome.com/blog/js-profiler-deprecation/",quickStartLinkText:i18nString(UIStrings.learnmore)},a.appendChild(e);const t=new PanelFeedback.FeedbackButton.FeedbackButton;t.data={feedbackUrl:"https://bugs.chromium.org/p/chromium/issues/detail?id=1354548"},a.appendChild(t)}this.landingPage.show(this.statusPaneContainer)}hideLandingPage(){this.landingPage.detach(),this.showSettingsPaneButton?.setToggled(!1),this.settingsPane?.hideWidget()}async loadingStarted(){this.hideLandingPage(),this.statusPane&&this.statusPane.remove(),this.statusPane=new StatusPane({showProgress:!0,showTimer:void 0,buttonDisabled:void 0,buttonText:void 0,description:void 0},(()=>this.cancelLoading())),this.statusPane.showPane(this.statusPaneContainer),this.statusPane.updateStatus(i18nString(UIStrings.loadingProfile)),this.loader||this.statusPane.finish(),this.traceLoadStart=performance.now(),await this.loadingProgress(0)}async loadingProgress(e){"number"==typeof e&&this.statusPane&&this.statusPane.updateProgressBar(i18nString(UIStrings.received),100*e)}async processingStarted(){this.statusPane&&this.statusPane.updateStatus(i18nString(UIStrings.processingProfile))}updateModelAndFlameChart(){this.performanceModel&&(this.setModel(this.performanceModel),this.flameChart.updateColorMapper())}async loadingComplete(e,t=null,i){this.#i.resetProcessor(),delete this.loader;const n=this.state===State.StopPending;if(this.setState(State.Idle),e){this.performanceModel||(this.performanceModel=new PerformanceModel);try{await Promise.all([this.performanceModel.setTracingModel(e,n),this.#l(e,n,i,this.performanceModel.recordStartTime())]),this.#n=this.#i.size()-1,this.setModel(this.performanceModel,t,this.#n),this.statusPane&&this.statusPane.remove(),this.statusPane=null,this.performanceModel.hasEventListeners(Events.NamesResolved)||this.performanceModel.addEventListener(Events.NamesResolved,this.updateModelAndFlameChart,this);const r=this.#i.traceParsedData(this.#n);if(!r)throw new Error(`Could not get trace data at index ${this.#n}`);this.#e.addRecording({data:{legacyModel:this.performanceModel,traceParseDataIndex:this.#n},filmStripForPreview:TraceEngine.Extras.FilmStrip.fromTraceData(r),traceParsedData:r})}catch(e){this.recordingFailed(e.message),console.error(e)}finally{this.recordTraceLoadMetric()}}else this.clear()}recordTraceLoadMetric(){if(!this.traceLoadStart)return;const e=this.traceLoadStart;requestAnimationFrame((()=>{setTimeout((()=>{const t=performance.now(),i=performance.measure("TraceLoad",{start:e,end:t});Host.userMetrics.performanceTraceLoad(i)}),0)}))}async#l(e,t,i,n){const r=t&&!i?await TraceEngine.Extras.Metadata.forNewRecording(n):{};return r.dataOrigin=i?"CPUProfile":"TraceEvents",this.#i.parse(e.allRawEvents(),{metadata:r,isFreshRecording:t})}loadingCompleteForTest(){}showRecordingStarted(){this.statusPane||(this.statusPane=new StatusPane({showTimer:!0,showProgress:!0,buttonDisabled:!0,description:void 0,buttonText:void 0},(()=>this.stopRecording())),this.statusPane.showPane(this.statusPaneContainer),this.statusPane.updateStatus(i18nString(UIStrings.initializingProfiler)))}cancelLoading(){this.loader&&this.loader.cancel()}async loadEventFired(e){if(this.state!==State.Recording||!this.recordingPageReload||!this.controller||this.controller.primaryPageTarget!==e.data.resourceTreeModel.target())return;const t=this.controller;await new Promise((e=>window.setTimeout(e,this.millisecondsToRecordAfterLoadEvent))),t===this.controller&&this.state===State.Recording&&this.stopRecording()}frameForSelection(e){return TimelineSelection.isFrameObject(e.object)?e.object:TimelineSelection.isRangeSelection(e.object)||TimelineSelection.isSyntheticNetworkRequestDetailsEventSelection(e.object)?null:TimelineSelection.isTraceEventSelection(e.object)?this.performanceModel?this.performanceModel.frameModel().getFramesWithinWindow(e.endTime,e.endTime)[0]:null:(console.assert(!1,"Should never be reached"),null)}jumpToFrame(e){const t=this.selection&&this.frameForSelection(this.selection);if(!t||!this.performanceModel)return;const i=this.performanceModel.frames();let n=i.indexOf(t);console.assert(n>=0,"Can't find current frame in the frame list"),n=Platform.NumberUtilities.clamp(n+e,0,i.length-1);const r=i[n];return this.revealTimeRange(r.startTime,r.endTime),this.select(TimelineSelection.fromFrame(r)),!0}select(e){this.selection=e,this.flameChart.setSelection(e)}selectEntryAtTime(e,t){if(e){for(let i=Platform.ArrayUtilities.upperBound(e,t,((e,t)=>e-t.startTime))-1;i>=0;--i){const n=e[i],r=n.endTime||n.startTime;if(TraceEngine.Legacy.TracingModel.isTopLevelEvent(n)&&r<t)break;if(this.performanceModel&&this.performanceModel.isVisible(n)&&r>=t)return void this.select(TimelineSelection.fromTraceEvent(n))}this.select(null)}}highlightEvent(e){this.flameChart.highlightEvent(e)}revealTimeRange(e,t){if(!this.performanceModel)return;const i=this.performanceModel.window();let n=0;i.right<t?n=t-i.right:i.left>e&&(n=e-i.left),this.performanceModel.setWindow({left:i.left+n,right:i.right+n},!0)}handleDrop(e){const t=e.items;if(!t.length)return;const i=t[0];if(Host.userMetrics.actionTaken(Host.UserMetrics.Action.PerfPanelTraceImported),"string"===i.kind){const t=e.getData("text/uri-list");new Common.ParsedURL.ParsedURL(t).isValid&&this.loadFromURL(t)}else if("file"===i.kind){const e=t[0].getAsFile();if(!e)return;this.loadFromFile(e)}}}export var State;!function(e){e.Idle="Idle",e.StartPending="StartPending",e.Recording="Recording",e.StopPending="StopPending",e.Loading="Loading",e.RecordingFailed="RecordingFailed"}(State||(State={}));export const rowHeight=18;export const headerHeight=20;export class StatusPane extends UI.Widget.VBox{status;time;progressLabel;progressBar;description;button;startTime;timeUpdateTimer;constructor(e,t){super(!0),this.contentElement.classList.add("timeline-status-dialog");const i=this.contentElement.createChild("div","status-dialog-line status");if(i.createChild("div","label").textContent=i18nString(UIStrings.status),this.status=i.createChild("div","content"),UI.ARIAUtils.markAsStatus(this.status),e.showTimer){const e=this.contentElement.createChild("div","status-dialog-line time");e.createChild("div","label").textContent=i18nString(UIStrings.time),this.time=e.createChild("div","content")}if(e.showProgress){const e=this.contentElement.createChild("div","status-dialog-line progress");this.progressLabel=e.createChild("div","label"),this.progressBar=e.createChild("div","indicator-container").createChild("div","indicator"),UI.ARIAUtils.markAsProgressBar(this.progressBar)}if("string"==typeof e.description){const t=this.contentElement.createChild("div","status-dialog-line description");t.createChild("div","label").textContent=i18nString(UIStrings.description),this.description=t.createChild("div","content"),this.description.innerText=e.description}const n=e.buttonText||i18nString(UIStrings.stop);this.button=UI.UIUtils.createTextButton(n,t,"",!0),this.button.disabled=!1==!e.buttonDisabled,this.contentElement.createChild("div","stop-button").appendChild(this.button)}finish(){this.stopTimer(),this.button.disabled=!0}remove(){this.element.parentNode.classList.remove("tinted"),this.arrangeDialog(this.element.parentNode),this.stopTimer(),this.element.remove()}showPane(e){this.arrangeDialog(e),this.show(e),e.classList.add("tinted")}enableAndFocusButton(){this.button.disabled=!1,this.button.focus()}updateStatus(e){this.status.textContent=e}updateProgressBar(e,t){this.progressLabel.textContent=e,this.progressBar.style.width=t.toFixed(1)+"%",UI.ARIAUtils.setValueNow(this.progressBar,t),this.updateTimer()}startTimer(){this.startTime=Date.now(),this.timeUpdateTimer=window.setInterval(this.updateTimer.bind(this,!1),1e3),this.updateTimer()}stopTimer(){this.timeUpdateTimer&&(clearInterval(this.timeUpdateTimer),this.updateTimer(!0),delete this.timeUpdateTimer)}updateTimer(e){if(this.arrangeDialog(this.element.parentNode),!this.timeUpdateTimer||!this.time)return;const t=(Date.now()-this.startTime)/1e3;this.time.textContent=i18nString(UIStrings.ssec,{PH1:t.toFixed(e?1:0)})}arrangeDialog(e){const t=e.clientWidth<325;this.element.classList.toggle("small-dialog",t),this.contentElement.classList.toggle("small-dialog",t)}wasShown(){super.wasShown(),this.registerCSSFiles([timelineStatusDialogStyles])}}export class LoadTimelineHandler{static instance(e={forceNew:null}){const{forceNew:t}=e;return loadTimelineHandlerInstance&&!t||(loadTimelineHandlerInstance=new LoadTimelineHandler),loadTimelineHandlerInstance}handleQueryParam(e){UI.ViewManager.ViewManager.instance().showView("timeline").then((async()=>{await TimelinePanel.instance().loadFromURL(window.decodeURIComponent(e))}))}}export class ActionDelegate{static instance(e={forceNew:null}){const{forceNew:t}=e;return actionDelegateInstance&&!t||(actionDelegateInstance=new ActionDelegate),actionDelegateInstance}handleAction(e,t){const i=UI.Context.Context.instance().flavor(TimelinePanel);switch(console.assert(i&&i instanceof TimelinePanel),t){case"timeline.toggle-recording":return i.toggleRecording(),!0;case"timeline.record-reload":return i.recordReload(),!0;case"timeline.save-to-file":return i.saveToFile(),!0;case"timeline.load-from-file":return i.selectFileToLoad(),!0;case"timeline.jump-to-previous-frame":return i.jumpToFrame(-1),!0;case"timeline.jump-to-next-frame":return i.jumpToFrame(1),!0;case"timeline.show-history":return i.showHistory(),!0;case"timeline.previous-recording":return i.navigateHistory(1),!0;case"timeline.next-recording":return i.navigateHistory(-1),!0}return!1}}