export class CallStackSidebarPane extends UI.SimpleView{constructor(){super(Common.UIString('Call Stack'),true);this.registerRequiredCSS('sources/callStackSidebarPane.css');this._blackboxedMessageElement=this._createBlackboxedMessageElement();this.contentElement.appendChild(this._blackboxedMessageElement);this._notPausedMessageElement=this.contentElement.createChild('div','gray-info-message');this._notPausedMessageElement.textContent=Common.UIString('Not paused');this._notPausedMessageElement.tabIndex=-1;this._items=new UI.ListModel();this._list=new UI.ListControl(this._items,this,UI.ListMode.NonViewport);this.contentElement.appendChild(this._list.element);this._list.element.addEventListener('contextmenu',this._onContextMenu.bind(this),false);self.onInvokeElement(this._list.element,event=>{const item=this._list.itemForNode((event.target));if(item){this._activateItem(item);event.consume(true);}});this._showMoreMessageElement=this._createShowMoreMessageElement();this._showMoreMessageElement.classList.add('hidden');this.contentElement.appendChild(this._showMoreMessageElement);this._showBlackboxed=false;this._locationPool=new Bindings.LiveLocationPool();this._updateThrottler=new Common.Throttler(100);this._maxAsyncStackChainDepth=defaultMaxAsyncStackChainDepth;this._update();this._updateItemThrottler=new Common.Throttler(100);this._scheduledForUpdateItems=new Set();}
flavorChanged(object){this._showBlackboxed=false;this._maxAsyncStackChainDepth=defaultMaxAsyncStackChainDepth;this._update();}
_update(){this._updateThrottler.schedule(()=>this._doUpdate());}
async _doUpdate(){this._locationPool.disposeAll();const details=self.UI.context.flavor(SDK.DebuggerPausedDetails);if(!details){this.setDefaultFocusedElement(this._notPausedMessageElement);this._notPausedMessageElement.classList.remove('hidden');this._blackboxedMessageElement.classList.add('hidden');this._showMoreMessageElement.classList.add('hidden');this._items.replaceAll([]);self.UI.context.setFlavor(SDK.DebuggerModel.CallFrame,null);return;}
let debuggerModel=details.debuggerModel;this._notPausedMessageElement.classList.add('hidden');const items=details.callFrames.map(frame=>{const item=Item.createForDebuggerCallFrame(frame,this._locationPool,this._refreshItem.bind(this));item[debuggerCallFrameSymbol]=frame;return item;});let asyncStackTrace=details.asyncStackTrace;if(!asyncStackTrace&&details.asyncStackTraceId){if(details.asyncStackTraceId.debuggerId){debuggerModel=SDK.DebuggerModel.modelForDebuggerId(details.asyncStackTraceId.debuggerId);}
asyncStackTrace=debuggerModel?await debuggerModel.fetchAsyncStackTrace(details.asyncStackTraceId):null;}
let peviousStackTrace=details.callFrames;let maxAsyncStackChainDepth=this._maxAsyncStackChainDepth;while(asyncStackTrace&&maxAsyncStackChainDepth>0){let title='';const isAwait=asyncStackTrace.description==='async function';if(isAwait&&peviousStackTrace.length&&asyncStackTrace.callFrames.length){const lastPreviousFrame=peviousStackTrace[peviousStackTrace.length-1];const lastPreviousFrameName=UI.beautifyFunctionName(lastPreviousFrame.functionName);title=UI.asyncStackTraceLabel('await in '+lastPreviousFrameName);}else{title=UI.asyncStackTraceLabel(asyncStackTrace.description);}
items.push(...Item.createItemsForAsyncStack(title,debuggerModel,asyncStackTrace.callFrames,this._locationPool,this._refreshItem.bind(this)));--maxAsyncStackChainDepth;peviousStackTrace=asyncStackTrace.callFrames;if(asyncStackTrace.parent){asyncStackTrace=asyncStackTrace.parent;}else if(asyncStackTrace.parentId){if(asyncStackTrace.parentId.debuggerId){debuggerModel=SDK.DebuggerModel.modelForDebuggerId(asyncStackTrace.parentId.debuggerId);}
asyncStackTrace=debuggerModel?await debuggerModel.fetchAsyncStackTrace(asyncStackTrace.parentId):null;}else{asyncStackTrace=null;}}
this._showMoreMessageElement.classList.toggle('hidden',!asyncStackTrace);this._items.replaceAll(items);if(this._maxAsyncStackChainDepth===defaultMaxAsyncStackChainDepth){this._list.selectNextItem(true,false);const selectedItem=this._list.selectedItem();if(selectedItem){this._activateItem(selectedItem);}}
this._updatedForTest();}
_updatedForTest(){}
_refreshItem(item){this._scheduledForUpdateItems.add(item);this._updateItemThrottler.schedule(innerUpdate.bind(this));function innerUpdate(){const items=Array.from(this._scheduledForUpdateItems);this._scheduledForUpdateItems.clear();this._muteActivateItem=true;if(!this._showBlackboxed&&this._items.every(item=>item.isBlackboxed)){this._showBlackboxed=true;for(let i=0;i<this._items.length;++i){this._list.refreshItemByIndex(i);}
this._blackboxedMessageElement.classList.toggle('hidden',true);}else{const itemsSet=new Set(items);let hasBlackboxed=false;for(let i=0;i<this._items.length;++i){const item=this._items.at(i);if(itemsSet.has(item)){this._list.refreshItemByIndex(i);}
hasBlackboxed=hasBlackboxed||item.isBlackboxed;}
this._blackboxedMessageElement.classList.toggle('hidden',this._showBlackboxed||!hasBlackboxed);}
delete this._muteActivateItem;return Promise.resolve();}}
createElementForItem(item){const element=createElementWithClass('div','call-frame-item');const title=element.createChild('div','call-frame-item-title');title.createChild('div','call-frame-title-text').textContent=item.title;if(item.isAsyncHeader){element.classList.add('async-header');}else{const linkElement=element.createChild('div','call-frame-location');linkElement.textContent=item.linkText.trimMiddle(30);linkElement.title=item.linkText;element.classList.toggle('blackboxed-call-frame',item.isBlackboxed);if(item.isBlackboxed){UI.ARIAUtils.setDescription(element,ls`blackboxed`);}
if(!item[debuggerCallFrameSymbol]){UI.ARIAUtils.setDisabled(element,true);}}
const isSelected=item[debuggerCallFrameSymbol]===self.UI.context.flavor(SDK.DebuggerModel.CallFrame);element.classList.toggle('selected',isSelected);UI.ARIAUtils.setSelected(element,isSelected);element.classList.toggle('hidden',!this._showBlackboxed&&item.isBlackboxed);element.appendChild(UI.Icon.create('smallicon-thick-right-arrow','selected-call-frame-icon'));element.tabIndex=item===this._list.selectedItem()?0:-1;return element;}
heightForItem(item){console.assert(false);return 0;}
isItemSelectable(item){return true;}
selectedItemChanged(from,to,fromElement,toElement){if(fromElement){fromElement.tabIndex=-1;}
if(toElement){this.setDefaultFocusedElement(toElement);toElement.tabIndex=0;if(this.hasFocus()){toElement.focus();}}}
updateSelectedItemARIA(fromElement,toElement){return true;}
_createBlackboxedMessageElement(){const element=createElementWithClass('div','blackboxed-message');element.createChild('span');const showAllLink=element.createChild('span','link');showAllLink.textContent=Common.UIString('Show blackboxed frames');UI.ARIAUtils.markAsLink(showAllLink);showAllLink.tabIndex=0;const showAll=()=>{this._showBlackboxed=true;for(const item of this._items){this._refreshItem(item);}
this._blackboxedMessageElement.classList.toggle('hidden',true);};showAllLink.addEventListener('click',showAll);showAllLink.addEventListener('keydown',event=>isEnterKey(event)&&showAll());return element;}
_createShowMoreMessageElement(){const element=createElementWithClass('div','show-more-message');element.createChild('span');const showAllLink=element.createChild('span','link');showAllLink.textContent=Common.UIString('Show more');showAllLink.addEventListener('click',()=>{this._maxAsyncStackChainDepth+=defaultMaxAsyncStackChainDepth;this._update();},false);return element;}
_onContextMenu(event){const item=this._list.itemForNode((event.target));if(!item){return;}
const contextMenu=new UI.ContextMenu(event);const debuggerCallFrame=item[debuggerCallFrameSymbol];if(debuggerCallFrame){contextMenu.defaultSection().appendItem(Common.UIString('Restart frame'),()=>debuggerCallFrame.restart());}
contextMenu.defaultSection().appendItem(Common.UIString('Copy stack trace'),this._copyStackTrace.bind(this));if(item.uiLocation){this.appendBlackboxURLContextMenuItems(contextMenu,item.uiLocation.uiSourceCode);}
contextMenu.show();}
_onClick(event){const item=this._list.itemForNode((event.target));if(item){this._activateItem(item);}}
_activateItem(item){const uiLocation=item.uiLocation;if(this._muteActivateItem||!uiLocation){return;}
this._list.selectItem(item);const debuggerCallFrame=item[debuggerCallFrameSymbol];const oldItem=this.activeCallFrameItem();if(debuggerCallFrame&&oldItem!==item){debuggerCallFrame.debuggerModel.setSelectedCallFrame(debuggerCallFrame);self.UI.context.setFlavor(SDK.DebuggerModel.CallFrame,debuggerCallFrame);if(oldItem){this._refreshItem(oldItem);}
this._refreshItem(item);}else{Common.Revealer.reveal(uiLocation);}}
activeCallFrameItem(){const callFrame=self.UI.context.flavor(SDK.DebuggerModel.CallFrame);if(callFrame){return this._items.find(callFrameItem=>callFrameItem[debuggerCallFrameSymbol]===callFrame)||null;}
return null;}
appendBlackboxURLContextMenuItems(contextMenu,uiSourceCode){const binding=self.Persistence.persistence.binding(uiSourceCode);if(binding){uiSourceCode=binding.network;}
if(uiSourceCode.project().type()===Workspace.projectTypes.FileSystem){return;}
const canBlackbox=self.Bindings.blackboxManager.canBlackboxUISourceCode(uiSourceCode);const isBlackboxed=self.Bindings.blackboxManager.isBlackboxedUISourceCode(uiSourceCode);const isContentScript=uiSourceCode.project().type()===Workspace.projectTypes.ContentScripts;const manager=self.Bindings.blackboxManager;if(canBlackbox){if(isBlackboxed){contextMenu.defaultSection().appendItem(Common.UIString('Stop blackboxing'),manager.unblackboxUISourceCode.bind(manager,uiSourceCode));}else{contextMenu.defaultSection().appendItem(Common.UIString('Blackbox script'),manager.blackboxUISourceCode.bind(manager,uiSourceCode));}}
if(isContentScript){if(isBlackboxed){contextMenu.defaultSection().appendItem(Common.UIString('Stop blackboxing all content scripts'),manager.blackboxContentScripts.bind(manager));}else{contextMenu.defaultSection().appendItem(Common.UIString('Blackbox all content scripts'),manager.unblackboxContentScripts.bind(manager));}}}
_selectNextCallFrameOnStack(){const oldItem=this.activeCallFrameItem();const startIndex=oldItem?this._items.indexOf(oldItem)+1:0;for(let i=startIndex;i<this._items.length;i++){const newItem=this._items.at(i);if(newItem[debuggerCallFrameSymbol]){this._activateItem(newItem);break;}}}
_selectPreviousCallFrameOnStack(){const oldItem=this.activeCallFrameItem();const startIndex=oldItem?this._items.indexOf(oldItem)-1:this._items.length-1;for(let i=startIndex;i>=0;i--){const newItem=this._items.at(i);if(newItem[debuggerCallFrameSymbol]){this._activateItem(newItem);break;}}}
_copyStackTrace(){const text=[];for(const item of this._items){let itemText=item.title;if(item.uiLocation){itemText+=' ('+item.uiLocation.linkText(true)+')';}
text.push(itemText);}
Host.InspectorFrontendHost.copyText(text.join('\n'));}}
export const debuggerCallFrameSymbol=Symbol('debuggerCallFrame');export const elementSymbol=Symbol('element');export const defaultMaxAsyncStackChainDepth=32;export class ActionDelegate{handleAction(context,actionId){const callStackSidebarPane=self.runtime.sharedInstance(CallStackSidebarPane);switch(actionId){case'debugger.next-call-frame':callStackSidebarPane._selectNextCallFrameOnStack();return true;case'debugger.previous-call-frame':callStackSidebarPane._selectPreviousCallFrameOnStack();return true;}
return false;}}
export class Item{static createForDebuggerCallFrame(frame,locationPool,updateDelegate){const item=new Item(UI.beautifyFunctionName(frame.functionName),updateDelegate);self.Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(frame.location(),item._update.bind(item),locationPool);return item;}
static createItemsForAsyncStack(title,debuggerModel,frames,locationPool,updateDelegate){const whiteboxedItemsSymbol=Symbol('whiteboxedItems');const asyncHeaderItem=new Item(title,updateDelegate);asyncHeaderItem[whiteboxedItemsSymbol]=new Set();asyncHeaderItem.isAsyncHeader=true;const asyncFrameItems=frames.map(frame=>{const item=new Item(UI.beautifyFunctionName(frame.functionName),update);const rawLocation=debuggerModel?debuggerModel.createRawLocationByScriptId(frame.scriptId,frame.lineNumber,frame.columnNumber):null;if(!rawLocation){item.linkText=(frame.url||'<unknown>')+':'+(frame.lineNumber+1);item.updateDelegate(item);}else{self.Bindings.debuggerWorkspaceBinding.createCallFrameLiveLocation(rawLocation,item._update.bind(item),locationPool);}
return item;});updateDelegate(asyncHeaderItem);return[asyncHeaderItem,...asyncFrameItems];function update(item){updateDelegate(item);let shouldUpdate=false;const items=asyncHeaderItem[whiteboxedItemsSymbol];if(item.isBlackboxed){items.delete(item);shouldUpdate=items.size===0;}else{shouldUpdate=items.size===0;items.add(item);}
asyncHeaderItem.isBlackboxed=asyncHeaderItem[whiteboxedItemsSymbol].size===0;if(shouldUpdate){updateDelegate(asyncHeaderItem);}}}
constructor(title,updateDelegate){this.isBlackboxed=false;this.title=title;this.linkText='';this.uiLocation=null;this.isAsyncHeader=false;this.updateDelegate=updateDelegate;}
_update(liveLocation){const uiLocation=liveLocation.uiLocation();this.isBlackboxed=uiLocation?self.Bindings.blackboxManager.isBlackboxedUISourceCode(uiLocation.uiSourceCode):false;this.linkText=uiLocation?uiLocation.linkText():'';this.uiLocation=uiLocation;this.updateDelegate(this);}}