import{DataDisplayDelegate,Events as ProfileHeaderEvents,ProfileEvents as ProfileTypeEvents,ProfileHeader,ProfileType}from'./ProfileHeader.js';import{Events as ProfileLauncherEvents,ProfileLauncherView}from'./ProfileLauncherView.js';import{ProfileSidebarTreeElement}from'./ProfileSidebarTreeElement.js';import{instance}from'./ProfileTypeRegistry.js';export class ProfilesPanel extends UI.PanelWithSidebar{constructor(name,profileTypes,recordingActionId){super(name);this._profileTypes=profileTypes;this.registerRequiredCSS('profiler/heapProfiler.css');this.registerRequiredCSS('profiler/profilesPanel.css');this.registerRequiredCSS('object_ui/objectValue.css');const mainContainer=new UI.VBox();this.splitWidget().setMainWidget(mainContainer);this.profilesItemTreeElement=new ProfilesSidebarTreeElement(this);this._sidebarTree=new UI.TreeOutlineInShadow();this._sidebarTree.registerRequiredCSS('profiler/profilesSidebarTree.css');this._sidebarTree.element.classList.add('profiles-sidebar-tree-box');this.panelSidebarElement().appendChild(this._sidebarTree.element);this._sidebarTree.appendChild(this.profilesItemTreeElement);this._sidebarTree.element.addEventListener('keydown',this._onKeyDown.bind(this),false);this.profileViews=createElement('div');this.profileViews.id='profile-views';this.profileViews.classList.add('vbox');mainContainer.element.appendChild(this.profileViews);this._toolbarElement=createElementWithClass('div','profiles-toolbar');mainContainer.element.insertBefore(this._toolbarElement,mainContainer.element.firstChild);this.panelSidebarElement().classList.add('profiles-tree-sidebar');const toolbarContainerLeft=createElementWithClass('div','profiles-toolbar');this.panelSidebarElement().insertBefore(toolbarContainerLeft,this.panelSidebarElement().firstChild);const toolbar=new UI.Toolbar('',toolbarContainerLeft);this._toggleRecordAction=(self.UI.actionRegistry.action(recordingActionId));this._toggleRecordButton=UI.Toolbar.createActionButton(this._toggleRecordAction);toolbar.appendToolbarItem(this._toggleRecordButton);this.clearResultsButton=new UI.ToolbarButton(Common.UIString('Clear all profiles'),'largeicon-clear');this.clearResultsButton.addEventListener(UI.ToolbarButton.Events.Click,this._reset,this);toolbar.appendToolbarItem(this.clearResultsButton);toolbar.appendSeparator();toolbar.appendToolbarItem(UI.Toolbar.createActionButtonForId('components.collect-garbage'));this._profileViewToolbar=new UI.Toolbar('',this._toolbarElement);this._profileGroups={};this._launcherView=new ProfileLauncherView(this);this._launcherView.addEventListener(ProfileLauncherEvents.ProfileTypeSelected,this._onProfileTypeSelected,this);this._profileToView=[];this._typeIdToSidebarSection={};const types=this._profileTypes;for(let i=0;i<types.length;i++){this._registerProfileType(types[i]);}
this._launcherView.restoreSelectedProfileType();this.profilesItemTreeElement.select();this._showLauncherView();this._createFileSelectorElement();this.element.addEventListener('contextmenu',this._handleContextMenuEvent.bind(this),false);self.SDK.targetManager.addEventListener(SDK.TargetManager.Events.SuspendStateChanged,this._onSuspendStateChanged,this);self.UI.context.addFlavorChangeListener(SDK.CPUProfilerModel,this._updateProfileTypeSpecificUI,this);self.UI.context.addFlavorChangeListener(SDK.HeapProfilerModel,this._updateProfileTypeSpecificUI,this);}
_onKeyDown(event){let handled=false;if(event.key==='ArrowDown'&&!event.altKey){handled=this._sidebarTree.selectNext();}else if(event.key==='ArrowUp'&&!event.altKey){handled=this._sidebarTree.selectPrevious();}
if(handled){event.consume(true);}}
searchableView(){return this.visibleView&&this.visibleView.searchableView?this.visibleView.searchableView():null;}
_createFileSelectorElement(){if(this._fileSelectorElement){this.element.removeChild(this._fileSelectorElement);}
this._fileSelectorElement=UI.createFileSelectorElement(this._loadFromFile.bind(this));ProfilesPanel._fileSelectorElement=this._fileSelectorElement;this.element.appendChild(this._fileSelectorElement);}
_findProfileTypeByExtension(fileName){return this._profileTypes.find(type=>!!type.fileExtension()&&fileName.endsWith(type.fileExtension()||''))||null;}
async _loadFromFile(file){this._createFileSelectorElement();const profileType=this._findProfileTypeByExtension(file.name);if(!profileType){const extensions=new Set(this._profileTypes.map(type=>type.fileExtension()).filter(ext=>ext));self.Common.console.error(Common.UIString(`Can't load file. Supported file extensions: '%s'.`,Array.from(extensions).join(`', '`)));return;}
if(!!profileType.profileBeingRecorded()){self.Common.console.error(Common.UIString(`Can't load profile while another profile is being recorded.`));return;}
const error=await profileType.loadFromFile(file);if(error){UI.MessageDialog.show(Common.UIString('Profile loading failed: %s.',error.message));}}
toggleRecord(){if(!this._toggleRecordAction.enabled()){return true;}
const toggleButton=this.element.ownerDocument.deepActiveElement();const type=this._selectedProfileType;const isProfiling=type.buttonClicked();this._updateToggleRecordAction(isProfiling);if(isProfiling){this._launcherView.profileStarted();if(type.hasTemporaryView()){this.showProfile(type.profileBeingRecorded());}}else{this._launcherView.profileFinished();}
if(toggleButton){toggleButton.focus();}
return true;}
_onSuspendStateChanged(){this._updateToggleRecordAction(this._toggleRecordAction.toggled());}
_updateToggleRecordAction(toggled){const hasSelectedTarget=!!(self.UI.context.flavor(SDK.CPUProfilerModel)||self.UI.context.flavor(SDK.HeapProfilerModel));const enable=toggled||(!self.SDK.targetManager.allTargetsSuspended()&&hasSelectedTarget);this._toggleRecordAction.setEnabled(enable);this._toggleRecordAction.setToggled(toggled);if(enable){this._toggleRecordButton.setTitle(this._selectedProfileType?this._selectedProfileType.buttonTooltip:'');}else{this._toggleRecordButton.setTitle(UI.anotherProfilerActiveLabel());}
if(this._selectedProfileType){this._launcherView.updateProfileType(this._selectedProfileType,enable);}}
_profileBeingRecordedRemoved(){this._updateToggleRecordAction(false);this._launcherView.profileFinished();}
_onProfileTypeSelected(event){this._selectedProfileType=(event.data);this._updateProfileTypeSpecificUI();}
_updateProfileTypeSpecificUI(){this._updateToggleRecordAction(this._toggleRecordAction.toggled());}
_reset(){this._profileTypes.forEach(type=>type.reset());delete this.visibleView;this._profileGroups={};this._updateToggleRecordAction(false);this._launcherView.profileFinished();this._sidebarTree.element.classList.remove('some-expandable');this._launcherView.detach();this.profileViews.removeChildren();this._profileViewToolbar.removeToolbarItems();this.clearResultsButton.element.classList.remove('hidden');this.profilesItemTreeElement.select();this._showLauncherView();}
_showLauncherView(){this.closeVisibleView();this._profileViewToolbar.removeToolbarItems();this._launcherView.show(this.profileViews);this.visibleView=this._launcherView;this._toolbarElement.classList.add('hidden');}
_registerProfileType(profileType){this._launcherView.addProfileType(profileType);const profileTypeSection=new ProfileTypeSidebarSection(this,profileType);this._typeIdToSidebarSection[profileType.id]=profileTypeSection;this._sidebarTree.appendChild(profileTypeSection);profileTypeSection.childrenListElement.addEventListener('contextmenu',this._handleContextMenuEvent.bind(this),false);function onAddProfileHeader(event){this._addProfileHeader((event.data));}
function onRemoveProfileHeader(event){this._removeProfileHeader((event.data));}
function profileComplete(event){this.showProfile((event.data));}
profileType.addEventListener(ProfileTypeEvents.ViewUpdated,this._updateProfileTypeSpecificUI,this);profileType.addEventListener(ProfileTypeEvents.AddProfileHeader,onAddProfileHeader,this);profileType.addEventListener(ProfileTypeEvents.RemoveProfileHeader,onRemoveProfileHeader,this);profileType.addEventListener(ProfileTypeEvents.ProfileComplete,profileComplete,this);const profiles=profileType.getProfiles();for(let i=0;i<profiles.length;i++){this._addProfileHeader(profiles[i]);}}
_handleContextMenuEvent(event){const contextMenu=new UI.ContextMenu(event);if(this.panelSidebarElement().isSelfOrAncestor(event.srcElement)){contextMenu.defaultSection().appendItem(Common.UIString('Load\u2026'),this._fileSelectorElement.click.bind(this._fileSelectorElement));}
contextMenu.show();}
showLoadFromFileDialog(){this._fileSelectorElement.click();}
_addProfileHeader(profile){const profileType=profile.profileType();const typeId=profileType.id;this._typeIdToSidebarSection[typeId].addProfileHeader(profile);if(!this.visibleView||this.visibleView===this._launcherView){this.showProfile(profile);}}
_removeProfileHeader(profile){if(profile.profileType().profileBeingRecorded()===profile){this._profileBeingRecordedRemoved();}
const i=this._indexOfViewForProfile(profile);if(i!==-1){this._profileToView.splice(i,1);}
const typeId=profile.profileType().id;const sectionIsEmpty=this._typeIdToSidebarSection[typeId].removeProfileHeader(profile);if(sectionIsEmpty){this.profilesItemTreeElement.select();this._showLauncherView();}}
showProfile(profile){if(!profile||(profile.profileType().profileBeingRecorded()===profile)&&!profile.profileType().hasTemporaryView()){return null;}
const view=this.viewForProfile(profile);if(view===this.visibleView){return view;}
this.closeVisibleView();view.show(this.profileViews);this._toolbarElement.classList.remove('hidden');this.visibleView=view;const profileTypeSection=this._typeIdToSidebarSection[profile.profileType().id];const sidebarElement=profileTypeSection.sidebarElementForProfile(profile);sidebarElement.revealAndSelect();this._profileViewToolbar.removeToolbarItems();view.toolbarItems().then(items=>{items.map(item=>this._profileViewToolbar.appendToolbarItem(item));});return view;}
showObject(snapshotObjectId,perspectiveName){}
async linkifyObject(nodeIndex){return null;}
viewForProfile(profile){const index=this._indexOfViewForProfile(profile);if(index!==-1){return this._profileToView[index].view;}
const view=profile.createView(this);view.element.classList.add('profile-view');this._profileToView.push({profile:profile,view:view});return view;}
_indexOfViewForProfile(profile){return this._profileToView.findIndex(item=>item.profile===profile);}
closeVisibleView(){if(this.visibleView){this.visibleView.detach();}
delete this.visibleView;}
focus(){this._sidebarTree.focus();}}
export class ProfileTypeSidebarSection extends UI.TreeElement{constructor(dataDisplayDelegate,profileType){super(profileType.treeItemTitle.escapeHTML(),true);this.selectable=false;this._dataDisplayDelegate=dataDisplayDelegate;this._profileTreeElements=[];this._profileGroups={};this.expand();this.hidden=true;this.setCollapsible(false);}
addProfileHeader(profile){this.hidden=false;const profileType=profile.profileType();let sidebarParent=this;const profileTreeElement=(profile.createSidebarTreeElement(this._dataDisplayDelegate));this._profileTreeElements.push(profileTreeElement);if(!profile.fromFile()&&profileType.profileBeingRecorded()!==profile){const profileTitle=profile.title;let group=this._profileGroups[profileTitle];if(!group){group=new ProfileGroup();this._profileGroups[profileTitle]=group;}
group.profileSidebarTreeElements.push(profileTreeElement);const groupSize=group.profileSidebarTreeElements.length;if(groupSize===2){group.sidebarTreeElement=new ProfileGroupSidebarTreeElement(this._dataDisplayDelegate,profile.title);const firstProfileTreeElement=group.profileSidebarTreeElements[0];const index=this.children().indexOf(firstProfileTreeElement);this.insertChild(group.sidebarTreeElement,index);const selected=firstProfileTreeElement.selected;this.removeChild(firstProfileTreeElement);group.sidebarTreeElement.appendChild(firstProfileTreeElement);if(selected){firstProfileTreeElement.revealAndSelect();}
firstProfileTreeElement.setSmall(true);firstProfileTreeElement.setMainTitle(Common.UIString('Run %d',1));this.treeOutline.element.classList.add('some-expandable');}
if(groupSize>=2){sidebarParent=group.sidebarTreeElement;profileTreeElement.setSmall(true);profileTreeElement.setMainTitle(Common.UIString('Run %d',groupSize));}}
sidebarParent.appendChild(profileTreeElement);}
removeProfileHeader(profile){const index=this._sidebarElementIndex(profile);if(index===-1){return false;}
const profileTreeElement=this._profileTreeElements[index];this._profileTreeElements.splice(index,1);let sidebarParent=this;const group=this._profileGroups[profile.title];if(group){const groupElements=group.profileSidebarTreeElements;groupElements.splice(groupElements.indexOf(profileTreeElement),1);if(groupElements.length===1){const pos=sidebarParent.children().indexOf((group.sidebarTreeElement));group.sidebarTreeElement.removeChild(groupElements[0]);this.insertChild(groupElements[0],pos);groupElements[0].setSmall(false);groupElements[0].setMainTitle(profile.title);this.removeChild(group.sidebarTreeElement);}
if(groupElements.length!==0){sidebarParent=group.sidebarTreeElement;}}
sidebarParent.removeChild(profileTreeElement);profileTreeElement.dispose();if(this.childCount()){return false;}
this.hidden=true;return true;}
sidebarElementForProfile(profile){const index=this._sidebarElementIndex(profile);return index===-1?null:this._profileTreeElements[index];}
_sidebarElementIndex(profile){const elements=this._profileTreeElements;for(let i=0;i<elements.length;i++){if(elements[i].profile===profile){return i;}}
return-1;}
onattach(){this.listItemElement.classList.add('profiles-tree-section');}}
export class ProfileGroup{constructor(){this.profileSidebarTreeElements=[];this.sidebarTreeElement=null;}}
export class ProfileGroupSidebarTreeElement extends UI.TreeElement{constructor(dataDisplayDelegate,title){super('',true);this.selectable=false;this._dataDisplayDelegate=dataDisplayDelegate;this._title=title;this.expand();this.toggleOnClick=true;}
onselect(){const hasChildren=this.childCount()>0;if(hasChildren){this._dataDisplayDelegate.showProfile(this.lastChild().profile);}
return hasChildren;}
onattach(){this.listItemElement.classList.add('profile-group-sidebar-tree-item');this.listItemElement.createChild('div','icon');this.listItemElement.createChild('div','titles no-subtitle').createChild('span','title-container').createChild('span','title').textContent=this._title;}}
export class ProfilesSidebarTreeElement extends UI.TreeElement{constructor(panel){super('',false);this.selectable=true;this._panel=panel;}
onselect(){this._panel._showLauncherView();return true;}
onattach(){this.listItemElement.classList.add('profile-launcher-view-tree-item');this.listItemElement.createChild('div','icon');this.listItemElement.createChild('div','titles no-subtitle').createChild('span','title-container').createChild('span','title').textContent=Common.UIString('Profiles');}}
export class JSProfilerPanel extends ProfilesPanel{constructor(){const registry=instance;super('js_profiler',[registry.cpuProfileType],'profiler.js-toggle-recording');}
wasShown(){self.UI.context.setFlavor(JSProfilerPanel,this);}
willHide(){self.UI.context.setFlavor(JSProfilerPanel,null);}
handleAction(context,actionId){const panel=self.UI.context.flavor(JSProfilerPanel);console.assert(panel&&panel instanceof JSProfilerPanel);panel.toggleRecord();return true;}}