@yuebai008/cli
Version:
Command line interface for rapid qg-minigame development
1 lines • 18.1 kB
JavaScript
import*as Common from"../../core/common/common.js";import*as Host from"../../core/host/host.js";import*as Root from"../../core/root/root.js";import*as FormatterActions from"../../entrypoints/formatter_worker/FormatterActions.js";import*as IssuesManager from"../../models/issues_manager/issues_manager.js";import*as Persistence from"../../models/persistence/persistence.js";import*as TextUtils from"../../models/text_utils/text_utils.js";import*as Workspace from"../../models/workspace/workspace.js";import*as CodeMirror from"../../third_party/codemirror.next/codemirror.next.js";import*as IconButton from"../../ui/components/icon_button/icon_button.js";import*as IssueCounter from"../../ui/components/issue_counter/issue_counter.js";import*as SourceFrame from"../../ui/legacy/components/source_frame/source_frame.js";import*as UI from"../../ui/legacy/legacy.js";import{CoveragePlugin}from"./CoveragePlugin.js";import{CSSPlugin}from"./CSSPlugin.js";import{DebuggerPlugin}from"./DebuggerPlugin.js";import{MemoryProfilePlugin,PerformanceProfilePlugin}from"./ProfilePlugin.js";import{ResourceOriginPlugin}from"./ResourceOriginPlugin.js";import{SnippetsPlugin}from"./SnippetsPlugin.js";import{SourcesPanel}from"./SourcesPanel.js";function sourceFramePlugins(){return[CSSPlugin,DebuggerPlugin,SnippetsPlugin,ResourceOriginPlugin,CoveragePlugin,MemoryProfilePlugin,PerformanceProfilePlugin]}export class UISourceCodeFrame extends(Common.ObjectWrapper.eventMixin(SourceFrame.SourceFrame.SourceFrameImpl)){uiSourceCodeInternal;muteSourceCodeEvents;persistenceBinding;uiSourceCodeEventListeners;messageAndDecorationListeners;boundOnBindingChanged;plugins=[];errorPopoverHelper;#e=!1;constructor(e){super((()=>this.workingCopy())),this.uiSourceCodeInternal=e,this.muteSourceCodeEvents=!1,this.persistenceBinding=Persistence.Persistence.PersistenceImpl.instance().binding(e),this.uiSourceCodeEventListeners=[],this.messageAndDecorationListeners=[],this.boundOnBindingChanged=this.onBindingChanged.bind(this),Common.Settings.Settings.instance().moduleSetting("persistenceNetworkOverridesEnabled").addChangeListener(this.onNetworkPersistenceChanged,this),this.errorPopoverHelper=new UI.PopoverHelper.PopoverHelper(this.textEditor.editor.contentDOM,this.getErrorPopoverContent.bind(this)),this.errorPopoverHelper.setHasPadding(!0),this.errorPopoverHelper.setTimeout(100,100),this.initializeUISourceCode()}async workingCopy(){return this.uiSourceCodeInternal.isDirty()?{content:this.uiSourceCodeInternal.workingCopy(),isEncoded:!1}:this.uiSourceCodeInternal.requestContent()}editorConfiguration(e){return[super.editorConfiguration(e),rowMessages(this.allMessages()),pluginCompartment.of(this.plugins.map((e=>e.editorExtension())))]}onFocus(){super.onFocus(),UI.Context.Context.instance().setFlavor(UISourceCodeFrame,this)}onBlur(){super.onBlur(),UI.Context.Context.instance().setFlavor(UISourceCodeFrame,null)}installMessageAndDecorationListeners(){if(this.persistenceBinding){const e=this.persistenceBinding.network,t=this.persistenceBinding.fileSystem;this.messageAndDecorationListeners=[e.addEventListener(Workspace.UISourceCode.Events.MessageAdded,this.onMessageAdded,this),e.addEventListener(Workspace.UISourceCode.Events.MessageRemoved,this.onMessageRemoved,this),e.addEventListener(Workspace.UISourceCode.Events.DecorationChanged,this.onDecorationChanged,this),t.addEventListener(Workspace.UISourceCode.Events.MessageAdded,this.onMessageAdded,this),t.addEventListener(Workspace.UISourceCode.Events.MessageRemoved,this.onMessageRemoved,this)]}else this.messageAndDecorationListeners=[this.uiSourceCodeInternal.addEventListener(Workspace.UISourceCode.Events.MessageAdded,this.onMessageAdded,this),this.uiSourceCodeInternal.addEventListener(Workspace.UISourceCode.Events.MessageRemoved,this.onMessageRemoved,this),this.uiSourceCodeInternal.addEventListener(Workspace.UISourceCode.Events.DecorationChanged,this.onDecorationChanged,this)]}uiSourceCode(){return this.uiSourceCodeInternal}setUISourceCode(e){const t=e.contentLoaded()?Promise.resolve():e.requestContent(),s=this.uiSourceCodeInternal;t.then((async()=>{this.uiSourceCodeInternal===s&&(this.unloadUISourceCode(),this.uiSourceCodeInternal=e,e.workingCopy()!==this.textEditor.state.doc.toString()?await this.setDeferredContent(Promise.resolve(e.workingCopyContent())):this.reloadPlugins(),this.initializeUISourceCode())}),console.error)}unloadUISourceCode(){Common.EventTarget.removeEventListeners(this.messageAndDecorationListeners),Common.EventTarget.removeEventListeners(this.uiSourceCodeEventListeners),this.uiSourceCodeInternal.removeWorkingCopyGetter(),Persistence.Persistence.PersistenceImpl.instance().unsubscribeFromBindingEvent(this.uiSourceCodeInternal,this.boundOnBindingChanged)}initializeUISourceCode(){this.uiSourceCodeEventListeners=[this.uiSourceCodeInternal.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged,this.onWorkingCopyChanged,this),this.uiSourceCodeInternal.addEventListener(Workspace.UISourceCode.Events.WorkingCopyCommitted,this.onWorkingCopyCommitted,this),this.uiSourceCodeInternal.addEventListener(Workspace.UISourceCode.Events.TitleChanged,this.onTitleChanged,this)],Persistence.Persistence.PersistenceImpl.instance().subscribeForBindingEvent(this.uiSourceCodeInternal,this.boundOnBindingChanged),this.installMessageAndDecorationListeners(),this.updateStyle();const e=FormatterActions.FORMATTABLE_MEDIA_TYPES.includes(this.contentType)&&!this.uiSourceCodeInternal.project().canSetFileContent()&&null===Persistence.Persistence.PersistenceImpl.instance().binding(this.uiSourceCodeInternal),t=Root.Runtime.experiments.isEnabled("sourcesPrettyPrint")&&!this.uiSourceCodeInternal.contentType().isFromSourceMap();this.setCanPrettyPrint(e,t)}wasShown(){super.wasShown(),this.setEditable(this.canEditSourceInternal())}willHide(){for(const e of this.plugins)e.willHide();super.willHide(),UI.Context.Context.instance().setFlavor(UISourceCodeFrame,null),this.uiSourceCodeInternal.removeWorkingCopyGetter()}getContentType(){const e=Persistence.Persistence.PersistenceImpl.instance().binding(this.uiSourceCodeInternal),t=e?e.network.mimeType():this.uiSourceCodeInternal.mimeType();return Common.ResourceType.ResourceType.simplifyContentType(t)}canEditSourceInternal(){return!this.hasLoadError()&&(!this.uiSourceCodeInternal.editDisabled()&&("application/wasm"!==this.uiSourceCodeInternal.mimeType()&&(!!Persistence.Persistence.PersistenceImpl.instance().binding(this.uiSourceCodeInternal)||(!!this.uiSourceCodeInternal.project().canSetFileContent()||!this.uiSourceCodeInternal.project().isServiceProject()&&(!(this.uiSourceCodeInternal.project().type()!==Workspace.Workspace.projectTypes.Network||!Persistence.NetworkPersistenceManager.NetworkPersistenceManager.instance().active())||(!this.pretty||!this.uiSourceCodeInternal.contentType().hasScripts())&&this.uiSourceCodeInternal.contentType()!==Common.ResourceType.resourceTypes.Document)))))}onNetworkPersistenceChanged(){this.setEditable(this.canEditSourceInternal())}commitEditing(){this.uiSourceCodeInternal.isDirty()&&(this.muteSourceCodeEvents=!0,this.uiSourceCodeInternal.commitWorkingCopy(),this.muteSourceCodeEvents=!1)}async setContent(e){this.disposePlugins(),this.loadPlugins(),await super.setContent(e);for(const e of this.plugins)e.editorInitialized(this.textEditor);this.#t(),Common.EventTarget.fireEvent("source-file-loaded",this.uiSourceCodeInternal.displayName(!0))}createMessage(e){const{lineNumber:t,columnNumber:s}=this.uiLocationToEditorLocation(e.lineNumber(),e.columnNumber());return new RowMessage(e,t,s)}allMessages(){return(null!==this.persistenceBinding?[...this.persistenceBinding.network.messages(),...this.persistenceBinding.fileSystem.messages()]:[...this.uiSourceCodeInternal.messages()]).map((e=>this.createMessage(e)))}onTextChanged(){const e=this.pretty;super.onTextChanged(),this.errorPopoverHelper.hidePopover(),SourcesPanel.instance().updateLastModificationTime(),this.muteSourceCodeEvents=!0,this.isClean()?this.uiSourceCodeInternal.resetWorkingCopy():this.uiSourceCodeInternal.setWorkingCopyGetter((()=>this.textEditor.state.sliceDoc())),this.muteSourceCodeEvents=!1,e!==this.pretty&&(this.updateStyle(),this.reloadPlugins())}onWorkingCopyChanged(){this.muteSourceCodeEvents||this.maybeSetContent(this.uiSourceCodeInternal.workingCopyContent())}onWorkingCopyCommitted(){this.muteSourceCodeEvents||this.maybeSetContent(this.uiSourceCode().workingCopyContent()),this.contentCommitted(),this.updateStyle()}reloadPlugins(){this.disposePlugins(),this.loadPlugins();const e=this.textEditor;e.dispatch({effects:pluginCompartment.reconfigure(this.plugins.map((e=>e.editorExtension())))});for(const t of this.plugins)t.editorInitialized(e)}onTitleChanged(){this.updateLanguageMode("").then((()=>this.reloadPlugins()),console.error)}loadPlugins(){const e=Persistence.Persistence.PersistenceImpl.instance().binding(this.uiSourceCodeInternal),t=e?e.network:this.uiSourceCodeInternal;for(const e of sourceFramePlugins())e.accepts(t)&&this.plugins.push(new e(t,this));this.dispatchEventToListeners(Events.ToolbarItemsChanged)}disposePlugins(){for(const e of this.plugins)e.dispose();this.plugins=[]}onBindingChanged(){const e=Persistence.Persistence.PersistenceImpl.instance().binding(this.uiSourceCodeInternal);e!==this.persistenceBinding&&(this.unloadUISourceCode(),this.persistenceBinding=e,this.initializeUISourceCode(),this.reloadMessages(),this.reloadPlugins())}reloadMessages(){const e=this.allMessages(),{editor:t}=this.textEditor;t.dispatch({effects:setRowMessages.of(RowMessages.create(e))})}updateStyle(){this.setEditable(this.canEditSourceInternal())}maybeSetContent(e){this.textEditor.state.doc.toString()!==e.content&&this.setDeferredContent(Promise.resolve(e))}populateTextAreaContextMenu(e,t,s){super.populateTextAreaContextMenu(e,t,s),e.appendApplicableItems(this.uiSourceCodeInternal);const o=this.editorLocationToUILocation(t,s);e.appendApplicableItems(new Workspace.UISourceCode.UILocation(this.uiSourceCodeInternal,o.lineNumber,o.columnNumber));for(const o of this.plugins)o.populateTextAreaContextMenu(e,t,s)}populateLineGutterContextMenu(e,t){super.populateLineGutterContextMenu(e,t);for(const s of this.plugins)s.populateLineGutterContextMenu(e,t)}dispose(){this.errorPopoverHelper.dispose(),this.disposePlugins(),this.unloadUISourceCode(),this.textEditor.editor.destroy(),this.detach(),Common.Settings.Settings.instance().moduleSetting("persistenceNetworkOverridesEnabled").removeChangeListener(this.onNetworkPersistenceChanged,this)}onMessageAdded(e){const{editor:t}=this.textEditor,s=t.state.field(showRowMessages,!1);if(s){const o=this.createMessage(e.data);t.dispatch({effects:setRowMessages.of(s.messages.add(o))})}}onMessageRemoved(e){const{editor:t}=this.textEditor,s=t.state.field(showRowMessages,!1);if(s){const o=this.createMessage(e.data);t.dispatch({effects:setRowMessages.of(s.messages.remove(o))})}}onDecorationChanged(e){for(const t of this.plugins)t.decorationChanged(e.data,this.textEditor)}async toolbarItems(){const e=await super.toolbarItems(),t=[];for(const s of this.plugins)e.push(...s.leftToolbarItems()),t.push(...s.rightToolbarItems());return t.length?[...e,new UI.Toolbar.ToolbarSeparator(!0),...t]:e}getErrorPopoverContent(e){const t=e,s=e.target,o=s.enclosingNodeOrSelfWithClass("cm-messageIcon-error")||s.enclosingNodeOrSelfWithClass("cm-messageIcon-issue");if(!o)return null;const n=this.textEditor.state.field(showRowMessages,!1);if(!n||0===n.messages.rows.length)return null;const{editor:r}=this.textEditor,i=r.posAtCoords(t);if(null===i)return null;const a=r.state.doc.lineAt(i);if(i!==a.to)return null;const c=n.messages.rows.find((e=>e[0].lineNumber()===a.number-1));if(!c)return null;const d=o.classList.contains("cm-messageIcon-issue"),u=c.filter((e=>e.level()===Workspace.UISourceCode.Message.Level.Issue===d));if(!u.length)return null;const l=o?o.boxInWindow():new AnchorBox(t.clientX,t.clientY,1,1),g=countDuplicates(u),h=document.createElement("div");h.classList.add("text-editor-messages-description-container");for(let e=0;e<u.length;e++)g[e]&&h.appendChild(renderMessage(u[e],g[e]));return{box:l,hide(){},show:async e=>(e.contentElement.append(h),!0)}}#t(){if(this.#e)return;this.#e=!0;const e=Common.ResourceType.ResourceType.mimeFromURL(this.uiSourceCodeInternal.url()),t=Common.ResourceType.ResourceType.mediaTypeForMetrics(e??"",this.uiSourceCodeInternal.contentType().isFromSourceMap(),TextUtils.TextUtils.isMinified(this.uiSourceCodeInternal.content()));Host.userMetrics.sourcesPanelFileOpened(t)}}function getIconDataForLevel(e){return e===Workspace.UISourceCode.Message.Level.Error?{color:"var(--icon-error)",width:"16px",height:"14px",iconName:"cross-circle-filled"}:e===Workspace.UISourceCode.Message.Level.Warning?{color:"var(--icon-warning)",width:"18px",height:"14px",iconName:"warning-filled"}:e===Workspace.UISourceCode.Message.Level.Issue?{color:"var(--icon-warning)",width:"17px",height:"14px",iconName:"issue-exclamation-filled"}:{color:"var(--icon-error)",width:"16px",height:"14px",iconName:"cross-circle-filled"}}function getBubbleTypePerLevel(e){switch(e){case Workspace.UISourceCode.Message.Level.Error:return"error";case Workspace.UISourceCode.Message.Level.Warning:case Workspace.UISourceCode.Message.Level.Issue:return"warning"}}function messageLevelComparator(e,t){const s={[Workspace.UISourceCode.Message.Level.Issue]:2,[Workspace.UISourceCode.Message.Level.Warning]:3,[Workspace.UISourceCode.Message.Level.Error]:4};return s[e.level()]-s[t.level()]}function getIconDataForMessage(e){return e.origin instanceof IssuesManager.SourceFrameIssuesManager.IssueMessage?{...IssueCounter.IssueCounter.getIssueKindIconData(e.origin.getIssueKind()),width:"12px",height:"12px"}:getIconDataForLevel(e.level())}export var Events;!function(e){e.ToolbarItemsChanged="ToolbarItemsChanged"}(Events||(Events={}));const pluginCompartment=new CodeMirror.Compartment;class RowMessage{origin;#s;#o;constructor(e,t,s){this.origin=e,this.#s=t,this.#o=s}level(){return this.origin.level()}text(){return this.origin.text()}clickHandler(){return this.origin.clickHandler()}lineNumber(){return this.#s}columnNumber(){return this.#o}isEqual(e){return this.origin.isEqual(e.origin)}}function addMessage(e,t){const s=t.lineNumber();let o=0;for(;o<e.length;o++){const n=e[o][0].lineNumber()-s;if(0===n)return e[o]=e[o].concat(t),e;if(n>0)break}return e.splice(o,0,[t]),e}function removeMessage(e,t){for(let s=0;s<e.length;s++)if(e[s][0].lineNumber()===t.lineNumber()){const o=e[s].filter((e=>!e.isEqual(t)));o.length?e[s]=o:e.splice(s,1);break}}class RowMessages{rows;constructor(e){this.rows=e}static create(e){const t=[];for(const s of e)addMessage(t,s);return new RowMessages(t)}remove(e){const t=this.rows.slice();return removeMessage(t,e),new RowMessages(t)}add(e){return new RowMessages(addMessage(this.rows.slice(),e))}}const setRowMessages=CodeMirror.StateEffect.define(),underlineMark=CodeMirror.Decoration.mark({class:"cm-waveUnderline"});class MessageWidget extends CodeMirror.WidgetType{messages;constructor(e){super(),this.messages=e}eq(e){return e.messages===this.messages}toDOM(){const e=document.createElement("span");e.classList.add("cm-messageIcon");const t=this.messages.filter((e=>e.level()!==Workspace.UISourceCode.Message.Level.Issue));if(t.length){const s=t.sort(messageLevelComparator)[t.length-1],o=e.appendChild(new IconButton.Icon.Icon);o.data=getIconDataForLevel(s.level()),o.classList.add("cm-messageIcon-error")}const s=this.messages.find((e=>e.level()===Workspace.UISourceCode.Message.Level.Issue));if(s){const t=e.appendChild(new IconButton.Icon.Icon);t.data=getIconDataForLevel(Workspace.UISourceCode.Message.Level.Issue),t.classList.add("cm-messageIcon-issue"),t.addEventListener("click",(()=>(s.clickHandler()||Math.min)()))}return e}ignoreEvents(){return!0}}class RowMessageDecorations{messages;decorations;constructor(e,t){this.messages=e,this.decorations=t}static create(e,t){const s=new CodeMirror.RangeSetBuilder;for(const o of e.rows){const e=t.line(o[0].lineNumber()+1),n=o.reduce(((e,t)=>Math.min(e,t.columnNumber()||0)),e.length);n<e.length&&s.add(e.from+n,e.to,underlineMark),s.add(e.to,e.to,CodeMirror.Decoration.widget({side:1,widget:new MessageWidget(o)}))}return new RowMessageDecorations(e,s.finish())}apply(e){let t=this;e.docChanged&&(t=new RowMessageDecorations(this.messages,this.decorations.map(e.changes)));for(const s of e.effects)s.is(setRowMessages)&&(t=RowMessageDecorations.create(s.value,e.state.doc));return t}}const showRowMessages=CodeMirror.StateField.define({create:e=>RowMessageDecorations.create(new RowMessages([]),e.doc),update:(e,t)=>e.apply(t),provide:e=>CodeMirror.Prec.lowest(CodeMirror.EditorView.decorations.from(e,(e=>e.decorations)))});function countDuplicates(e){const t=[];for(let s=0;s<e.length;s++){t[s]=0;for(let o=0;o<=s;o++)if(e[o].isEqual(e[s])){t[o]++;break}}return t}function renderMessage(e,t){const s=document.createElement("div");if(s.classList.add("text-editor-row-message"),s.style.display="flex",s.style.alignItems="center",s.style.gap="4px",1===t){const t=s.appendChild(new IconButton.Icon.Icon);t.data=getIconDataForMessage(e),t.classList.add("text-editor-row-message-icon"),t.addEventListener("click",(()=>(e.clickHandler()||Math.min)()))}else{const o=document.createElement("span",{is:"dt-small-bubble"});o.textContent=String(t),o.classList.add("text-editor-row-message-repeat-count"),o.style.flexShrink="0",s.appendChild(o),o.type=getBubbleTypePerLevel(e.level())}const o=s.createChild("div");for(const t of e.text().split("\n"))o.createChild("div").textContent=t;return s}const rowMessageTheme=CodeMirror.EditorView.baseTheme({".cm-tooltip-message":{padding:"4px"},".cm-waveUnderline":{backgroundImage:"var(--image-file-errorWave)",backgroundRepeat:"repeat-x",backgroundPosition:"bottom",paddingBottom:"1px"},".cm-messageIcon":{cursor:"pointer","& > *":{verticalAlign:"text-bottom",marginLeft:"2px"}},".cm-messageIcon-issue, .cm-messageIcon-error":{marginTop:"-1px",marginBottom:"-1px"}});function rowMessages(e){return[showRowMessages.init((t=>RowMessageDecorations.create(RowMessages.create(e),t.doc))),rowMessageTheme]}