import{CoveragePlugin}from'./CoveragePlugin.js';import{CSSPlugin}from'./CSSPlugin.js';import{DebuggerPlugin}from'./DebuggerPlugin.js';import{GutterDiffPlugin}from'./GutterDiffPlugin.js';import{JavaScriptCompilerPlugin}from'./JavaScriptCompilerPlugin.js';import{Plugin}from'./Plugin.js';import{ScriptOriginPlugin}from'./ScriptOriginPlugin.js';import{SnippetsPlugin}from'./SnippetsPlugin.js';import{SourcesPanel}from'./SourcesPanel.js';export class UISourceCodeFrame extends SourceFrame.SourceFrame{constructor(uiSourceCode){super(workingCopy);this._uiSourceCode=uiSourceCode;if(Root.Runtime.experiments.isEnabled('sourceDiff')){this._diff=new SourceFrame.SourceCodeDiff(this.textEditor);}
this._muteSourceCodeEvents=false;this._isSettingContent=false;this._persistenceBinding=self.Persistence.persistence.binding(uiSourceCode);this._rowMessageBuckets=new Map();this._typeDecorationsPending=new Set();this._uiSourceCodeEventListeners=[];this._messageAndDecorationListeners=[];this._boundOnBindingChanged=this._onBindingChanged.bind(this);this.textEditor.addEventListener(SourceFrame.SourcesTextEditor.Events.EditorBlurred,()=>self.UI.context.setFlavor(UISourceCodeFrame,null));this.textEditor.addEventListener(SourceFrame.SourcesTextEditor.Events.EditorFocused,()=>self.UI.context.setFlavor(UISourceCodeFrame,this));self.Common.settings.moduleSetting('persistenceNetworkOverridesEnabled').addChangeListener(this._onNetworkPersistenceChanged,this);this._errorPopoverHelper=new UI.PopoverHelper(this.element,this._getErrorPopoverContent.bind(this));this._errorPopoverHelper.setHasPadding(true);this._errorPopoverHelper.setTimeout(100,100);this._plugins=[];this._initializeUISourceCode();function workingCopy(){if(uiSourceCode.isDirty()){return Promise.resolve({content:uiSourceCode.workingCopy(),isEncoded:false});}
return uiSourceCode.requestContent();}}
_installMessageAndDecorationListeners(){if(this._persistenceBinding){const networkSourceCode=this._persistenceBinding.network;const fileSystemSourceCode=this._persistenceBinding.fileSystem;this._messageAndDecorationListeners=[networkSourceCode.addEventListener(Workspace.UISourceCode.Events.MessageAdded,this._onMessageAdded,this),networkSourceCode.addEventListener(Workspace.UISourceCode.Events.MessageRemoved,this._onMessageRemoved,this),networkSourceCode.addEventListener(Workspace.UISourceCode.Events.LineDecorationAdded,this._onLineDecorationAdded,this),networkSourceCode.addEventListener(Workspace.UISourceCode.Events.LineDecorationRemoved,this._onLineDecorationRemoved,this),fileSystemSourceCode.addEventListener(Workspace.UISourceCode.Events.MessageAdded,this._onMessageAdded,this),fileSystemSourceCode.addEventListener(Workspace.UISourceCode.Events.MessageRemoved,this._onMessageRemoved,this),];}else{this._messageAndDecorationListeners=[this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.MessageAdded,this._onMessageAdded,this),this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.MessageRemoved,this._onMessageRemoved,this),this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.LineDecorationAdded,this._onLineDecorationAdded,this),this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.LineDecorationRemoved,this._onLineDecorationRemoved,this)];}}
uiSourceCode(){return this._uiSourceCode;}
setUISourceCode(uiSourceCode){this._unloadUISourceCode();this._uiSourceCode=uiSourceCode;if(uiSourceCode.contentLoaded()){if(uiSourceCode.workingCopy()!==this.textEditor.text()){this._innerSetContent(uiSourceCode.workingCopy());}}else{uiSourceCode.requestContent().then(()=>{if(this._uiSourceCode!==uiSourceCode){return;}
if(uiSourceCode.workingCopy()!==this.textEditor.text()){this._innerSetContent(uiSourceCode.workingCopy());}});}
this._initializeUISourceCode();}
_unloadUISourceCode(){this._disposePlugins();for(const message of this._allMessages()){this._removeMessageFromSource(message);}
Common.EventTarget.removeEventListeners(this._messageAndDecorationListeners);Common.EventTarget.removeEventListeners(this._uiSourceCodeEventListeners);this._uiSourceCode.removeWorkingCopyGetter();self.Persistence.persistence.unsubscribeFromBindingEvent(this._uiSourceCode,this._boundOnBindingChanged);}
_initializeUISourceCode(){this._uiSourceCodeEventListeners=[this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged,this._onWorkingCopyChanged,this),this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyCommitted,this._onWorkingCopyCommitted,this),this._uiSourceCode.addEventListener(Workspace.UISourceCode.Events.TitleChanged,this._refreshHighlighterType,this)];self.Persistence.persistence.subscribeForBindingEvent(this._uiSourceCode,this._boundOnBindingChanged);for(const message of this._allMessages()){this._addMessageToSource(message);}
this._installMessageAndDecorationListeners();this._updateStyle();this._decorateAllTypes();this._refreshHighlighterType();if(Root.Runtime.experiments.isEnabled('sourcesPrettyPrint')){const supportedPrettyTypes=new Set(['text/html','text/css','text/javascript']);this.setCanPrettyPrint(supportedPrettyTypes.has(this.highlighterType()),true);}
this._ensurePluginsLoaded();}
wasShown(){super.wasShown();setImmediate(this._updateBucketDecorations.bind(this));this.setEditable(this._canEditSource());for(const plugin of this._plugins){plugin.wasShown();}}
willHide(){for(const plugin of this._plugins){plugin.willHide();}
super.willHide();self.UI.context.setFlavor(UISourceCodeFrame,null);this._uiSourceCode.removeWorkingCopyGetter();}
_refreshHighlighterType(){const binding=self.Persistence.persistence.binding(this._uiSourceCode);const highlighterType=binding?binding.network.mimeType():this._uiSourceCode.mimeType();if(this.highlighterType()===highlighterType){return;}
this._disposePlugins();this.setHighlighterType(highlighterType);this._ensurePluginsLoaded();}
_canEditSource(){if(this.hasLoadError()){return false;}
if(self.Persistence.persistence.binding(this._uiSourceCode)){return true;}
if(this._uiSourceCode.project().canSetFileContent()){return true;}
if(this._uiSourceCode.project().isServiceProject()){return false;}
if(this._uiSourceCode.project().type()===Workspace.projectTypes.Network&&self.Persistence.networkPersistenceManager.active()){return true;}
if(this.pretty&&this._uiSourceCode.contentType().hasScripts()){return false;}
return this._uiSourceCode.contentType()!==Common.resourceTypes.Document;}
_onNetworkPersistenceChanged(){this.setEditable(this._canEditSource());}
commitEditing(){if(!this._uiSourceCode.isDirty()){return;}
this._muteSourceCodeEvents=true;this._uiSourceCode.commitWorkingCopy();this._muteSourceCodeEvents=false;}
setContent(content,loadError){this._disposePlugins();this._rowMessageBuckets.clear();super.setContent(content,loadError);for(const message of this._allMessages()){this._addMessageToSource(message);}
this._decorateAllTypes();this._ensurePluginsLoaded();}
_allMessages(){if(this._persistenceBinding){const combinedSet=this._persistenceBinding.network.messages();combinedSet.addAll(this._persistenceBinding.fileSystem.messages());return combinedSet;}
return this._uiSourceCode.messages();}
onTextChanged(oldRange,newRange){const wasPretty=this.pretty;super.onTextChanged(oldRange,newRange);this._errorPopoverHelper.hidePopover();if(this._isSettingContent){return;}
SourcesPanel.instance().updateLastModificationTime();this._muteSourceCodeEvents=true;if(this.isClean()){this._uiSourceCode.resetWorkingCopy();}else{this._uiSourceCode.setWorkingCopyGetter(this.textEditor.text.bind(this.textEditor));}
this._muteSourceCodeEvents=false;if(wasPretty!==this.pretty){this._updateStyle();this._disposePlugins();this._ensurePluginsLoaded();}}
_onWorkingCopyChanged(event){if(this._muteSourceCodeEvents){return;}
this._innerSetContent(this._uiSourceCode.workingCopy());}
_onWorkingCopyCommitted(event){if(!this._muteSourceCodeEvents){this._innerSetContent(this._uiSourceCode.workingCopy());}
this.contentCommitted();this._updateStyle();}
_ensurePluginsLoaded(){if(!this.loaded||this._plugins.length){return;}
const binding=self.Persistence.persistence.binding(this._uiSourceCode);const pluginUISourceCode=binding?binding.network:this._uiSourceCode;if(DebuggerPlugin.accepts(pluginUISourceCode)){this._plugins.push(new DebuggerPlugin(this.textEditor,pluginUISourceCode,this.transformer()));}
if(CSSPlugin.accepts(pluginUISourceCode)){this._plugins.push(new CSSPlugin(this.textEditor));}
if(!this.pretty&&JavaScriptCompilerPlugin.accepts(pluginUISourceCode)){this._plugins.push(new JavaScriptCompilerPlugin(this.textEditor,pluginUISourceCode));}
if(SnippetsPlugin.accepts(pluginUISourceCode)){this._plugins.push(new SnippetsPlugin(this.textEditor,pluginUISourceCode));}
if(ScriptOriginPlugin.accepts(pluginUISourceCode)){this._plugins.push(new ScriptOriginPlugin(this.textEditor,pluginUISourceCode));}
if(!this.pretty&&Root.Runtime.experiments.isEnabled('sourceDiff')&&GutterDiffPlugin.accepts(pluginUISourceCode)){this._plugins.push(new GutterDiffPlugin(this.textEditor,pluginUISourceCode));}
if(CoveragePlugin.accepts(pluginUISourceCode)){this._plugins.push(new CoveragePlugin(this.textEditor,pluginUISourceCode));}
this.dispatchEventToListeners(Events.ToolbarItemsChanged);for(const plugin of this._plugins){plugin.wasShown();}}
_disposePlugins(){this.textEditor.operation(()=>{for(const plugin of this._plugins){plugin.dispose();}});this._plugins=[];}
_onBindingChanged(){const binding=self.Persistence.persistence.binding(this._uiSourceCode);if(binding===this._persistenceBinding){return;}
this._unloadUISourceCode();this._persistenceBinding=binding;this._initializeUISourceCode();}
_updateStyle(){this.setEditable(this._canEditSource());}
_innerSetContent(content){this._isSettingContent=true;const oldContent=this.textEditor.text();if(this._diff){this._diff.highlightModifiedLines(oldContent,content);}
if(oldContent!==content){this.setContent(content,null);}
this._isSettingContent=false;}
async populateTextAreaContextMenu(contextMenu,editorLineNumber,editorColumnNumber){await super.populateTextAreaContextMenu(contextMenu,editorLineNumber,editorColumnNumber);contextMenu.appendApplicableItems(this._uiSourceCode);const location=this.transformer().editorToRawLocation(editorLineNumber,editorColumnNumber);contextMenu.appendApplicableItems(new Workspace.UILocation(this._uiSourceCode,location[0],location[1]));contextMenu.appendApplicableItems(this);for(const plugin of this._plugins){await plugin.populateTextAreaContextMenu(contextMenu,editorLineNumber,editorColumnNumber);}}
dispose(){this._errorPopoverHelper.dispose();this._unloadUISourceCode();this.textEditor.dispose();this.detach();self.Common.settings.moduleSetting('persistenceNetworkOverridesEnabled').removeChangeListener(this._onNetworkPersistenceChanged,this);}
_onMessageAdded(event){const message=(event.data);this._addMessageToSource(message);}
_addMessageToSource(message){if(!this.loaded){return;}
const editorLocation=this.transformer().rawToEditorLocation(message.lineNumber(),message.columnNumber());let editorLineNumber=editorLocation[0];if(editorLineNumber>=this.textEditor.linesCount){editorLineNumber=this.textEditor.linesCount-1;}
if(editorLineNumber<0){editorLineNumber=0;}
let messageBucket=this._rowMessageBuckets.get(editorLineNumber);if(!messageBucket){messageBucket=new RowMessageBucket(this,this.textEditor,editorLineNumber);this._rowMessageBuckets.set(editorLineNumber,messageBucket);}
messageBucket.addMessage(message);}
_onMessageRemoved(event){const message=(event.data);this._removeMessageFromSource(message);}
_removeMessageFromSource(message){if(!this.loaded){return;}
const editorLocation=this.transformer().rawToEditorLocation(message.lineNumber(),message.columnNumber());let editorLineNumber=editorLocation[0];if(editorLineNumber>=this.textEditor.linesCount){editorLineNumber=this.textEditor.linesCount-1;}
if(editorLineNumber<0){editorLineNumber=0;}
const messageBucket=this._rowMessageBuckets.get(editorLineNumber);if(!messageBucket){return;}
messageBucket.removeMessage(message);if(!messageBucket.uniqueMessagesCount()){messageBucket.detachFromEditor();this._rowMessageBuckets.delete(editorLineNumber);}}
_getErrorPopoverContent(event){const element=event.target.enclosingNodeOrSelfWithClass('text-editor-line-decoration-icon')||event.target.enclosingNodeOrSelfWithClass('text-editor-line-decoration-wave');if(!element){return null;}
const anchor=element.enclosingNodeOrSelfWithClass('text-editor-line-decoration-icon')?element.boxInWindow():new AnchorBox(event.clientX,event.clientY,1,1);return{box:anchor,show:popover=>{const messageBucket=element.enclosingNodeOrSelfWithClass('text-editor-line-decoration')._messageBucket;const messagesOutline=messageBucket.messagesDescription();popover.contentElement.appendChild(messagesOutline);return Promise.resolve(true);}};}
_updateBucketDecorations(){for(const bucket of this._rowMessageBuckets.values()){bucket._updateDecoration();}}
_onLineDecorationAdded(event){const marker=(event.data);this._decorateTypeThrottled(marker.type());}
_onLineDecorationRemoved(event){const marker=(event.data);this._decorateTypeThrottled(marker.type());}
async _decorateTypeThrottled(type){if(this._typeDecorationsPending.has(type)){return;}
this._typeDecorationsPending.add(type);const decorator=await self.runtime.extensions(SourceFrame.LineDecorator).find(extension=>extension.descriptor()['decoratorType']===type).instance();this._typeDecorationsPending.delete(type);this.textEditor.codeMirror().operation(()=>{decorator.decorate(this._persistenceBinding?this._persistenceBinding.network:this.uiSourceCode(),this.textEditor,type);});}
_decorateAllTypes(){if(!this.loaded){return;}
for(const extension of self.runtime.extensions(SourceFrame.LineDecorator)){const type=extension.descriptor()['decoratorType'];if(this._uiSourceCode.decorationsForType(type)){this._decorateTypeThrottled(type);}}}
async toolbarItems(){const leftToolbarItems=await super.toolbarItems();const rightToolbarItems=[];for(const plugin of this._plugins){leftToolbarItems.push(...plugin.leftToolbarItems());rightToolbarItems.push(...await plugin.rightToolbarItems());}
if(!rightToolbarItems.length){return leftToolbarItems;}
return[...leftToolbarItems,new UI.ToolbarSeparator(true),...rightToolbarItems];}
async populateLineGutterContextMenu(contextMenu,lineNumber){await super.populateLineGutterContextMenu(contextMenu,lineNumber);for(const plugin of this._plugins){await plugin.populateLineGutterContextMenu(contextMenu,lineNumber);}}}
export const iconClassPerLevel={};iconClassPerLevel[Workspace.UISourceCode.Message.Level.Error]='smallicon-error';iconClassPerLevel[Workspace.UISourceCode.Message.Level.Warning]='smallicon-warning';export const bubbleTypePerLevel={};bubbleTypePerLevel[Workspace.UISourceCode.Message.Level.Error]='error';bubbleTypePerLevel[Workspace.UISourceCode.Message.Level.Warning]='warning';export const lineClassPerLevel={};lineClassPerLevel[Workspace.UISourceCode.Message.Level.Error]='text-editor-line-with-error';lineClassPerLevel[Workspace.UISourceCode.Message.Level.Warning]='text-editor-line-with-warning';export class RowMessage{constructor(message){this._message=message;this._repeatCount=1;this.element=createElementWithClass('div','text-editor-row-message');this._icon=this.element.createChild('label','','dt-icon-label');this._icon.type=iconClassPerLevel[message.level()];this._repeatCountElement=this.element.createChild('span','text-editor-row-message-repeat-count hidden','dt-small-bubble');this._repeatCountElement.type=bubbleTypePerLevel[message.level()];const linesContainer=this.element.createChild('div');const lines=this._message.text().split('\n');for(let i=0;i<lines.length;++i){const messageLine=linesContainer.createChild('div');messageLine.textContent=lines[i];}}
message(){return this._message;}
repeatCount(){return this._repeatCount;}
setRepeatCount(repeatCount){if(this._repeatCount===repeatCount){return;}
this._repeatCount=repeatCount;this._updateMessageRepeatCount();}
_updateMessageRepeatCount(){this._repeatCountElement.textContent=this._repeatCount;const showRepeatCount=this._repeatCount>1;this._repeatCountElement.classList.toggle('hidden',!showRepeatCount);this._icon.classList.toggle('hidden',showRepeatCount);}}
export class RowMessageBucket{constructor(sourceFrame,textEditor,editorLineNumber){this._sourceFrame=sourceFrame;this.textEditor=textEditor;this._lineHandle=textEditor.textEditorPositionHandle(editorLineNumber,0);this._decoration=createElementWithClass('div','text-editor-line-decoration');this._decoration._messageBucket=this;this._wave=this._decoration.createChild('div','text-editor-line-decoration-wave');this._icon=this._wave.createChild('span','text-editor-line-decoration-icon','dt-icon-label');this._decorationStartColumn=null;this._messagesDescriptionElement=createElementWithClass('div','text-editor-messages-description-container');this._messages=[];this._level=null;}
_updateWavePosition(editorLineNumber,columnNumber){editorLineNumber=Math.min(editorLineNumber,this.textEditor.linesCount-1);const lineText=this.textEditor.line(editorLineNumber);columnNumber=Math.min(columnNumber,lineText.length);const lineIndent=TextUtils.TextUtils.lineIndent(lineText).length;const startColumn=Math.max(columnNumber-1,lineIndent);if(this._decorationStartColumn===startColumn){return;}
if(this._decorationStartColumn!==null){this.textEditor.removeDecoration(this._decoration,editorLineNumber);}
this.textEditor.addDecoration(this._decoration,editorLineNumber,startColumn);this._decorationStartColumn=startColumn;}
messagesDescription(){this._messagesDescriptionElement.removeChildren();UI.appendStyle(this._messagesDescriptionElement,'source_frame/messagesPopover.css');for(let i=0;i<this._messages.length;++i){this._messagesDescriptionElement.appendChild(this._messages[i].element);}
return this._messagesDescriptionElement;}
detachFromEditor(){const position=this._lineHandle.resolve();if(!position){return;}
const editorLineNumber=position.lineNumber;if(this._level){this.textEditor.toggleLineClass(editorLineNumber,lineClassPerLevel[this._level],false);}
if(this._decorationStartColumn!==null){this.textEditor.removeDecoration(this._decoration,editorLineNumber);this._decorationStartColumn=null;}}
uniqueMessagesCount(){return this._messages.length;}
addMessage(message){for(let i=0;i<this._messages.length;++i){const rowMessage=this._messages[i];if(rowMessage.message().isEqual(message)){rowMessage.setRepeatCount(rowMessage.repeatCount()+1);return;}}
const rowMessage=new RowMessage(message);this._messages.push(rowMessage);this._updateDecoration();}
removeMessage(message){for(let i=0;i<this._messages.length;++i){const rowMessage=this._messages[i];if(!rowMessage.message().isEqual(message)){continue;}
rowMessage.setRepeatCount(rowMessage.repeatCount()-1);if(!rowMessage.repeatCount()){this._messages.splice(i,1);}
this._updateDecoration();return;}}
_updateDecoration(){if(!this._sourceFrame.isShowing()){return;}
if(!this._messages.length){return;}
const position=this._lineHandle.resolve();if(!position){return;}
const editorLineNumber=position.lineNumber;let columnNumber=Number.MAX_VALUE;let maxMessage=null;for(let i=0;i<this._messages.length;++i){const message=this._messages[i].message();const editorLocation=this._sourceFrame.transformer().rawToEditorLocation(editorLineNumber,message.columnNumber());columnNumber=Math.min(columnNumber,editorLocation[1]);if(!maxMessage||Workspace.UISourceCode.Message.messageLevelComparator(maxMessage,message)<0){maxMessage=message;}}
this._updateWavePosition(editorLineNumber,columnNumber);if(this._level===maxMessage.level()){return;}
if(this._level){this.textEditor.toggleLineClass(editorLineNumber,lineClassPerLevel[this._level],false);this._icon.type='';}
this._level=maxMessage.level();if(!this._level){return;}
this.textEditor.toggleLineClass(editorLineNumber,lineClassPerLevel[this._level],true);this._icon.type=iconClassPerLevel[this._level];}}
Workspace.UISourceCode.Message._messageLevelPriority={'Warning':3,'Error':4};Workspace.UISourceCode.Message.messageLevelComparator=function(a,b){return Workspace.UISourceCode.Message._messageLevelPriority[a.level()]-
Workspace.UISourceCode.Message._messageLevelPriority[b.level()];};export const Events={ToolbarItemsChanged:Symbol('ToolbarItemsChanged')};