UNPKG

web-code-editor

Version:
1 lines 14.5 kB
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.WebCodeEditor=t():e.WebCodeEditor=t()}(this,(function(){return(()=>{"use strict";var e={d:(t,s)=>{for(var i in s)e.o(s,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:s[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};function s(e,t={}){const s=document.createElement(e);if(t.id&&(s.id=t.id),t.className&&(s.className=t.className),t.textContent&&(s.textContent=t.textContent),t.innerHTML&&(s.innerHTML=t.innerHTML),t.style&&Object.assign(s.style,t.style),t.attrs&&Object.assign(s,t.attrs),t.click&&s.addEventListener("click",(e=>t.click(e))),t.parent&&t.parent.append(s),t.children&&t.children.forEach((e=>s.append(e))),t.events)for(const e in t.events)s.addEventListener(e,t.events[e]);return s}e.r(t),e.d(t,{WebCodeEditor:()=>P});const i="web-code-editor",n="pane1",r="pane2",a="pane3",l="active",h="editor-container",o="editor-textarea",c="title-tabs",d="custom-codeMirror",p="item",u="close-icon",m="open",w="mask",f="item create",g="right-menu",b="divide",v="item",y="item file",k="item dir",x="msg",E="field",M="files",C="image-container",D="image",T="open-dir-btn",L="new-is-invalid",N={openFolder:"打开文件夹",selectFolder:"选择文件夹",close:"关闭",closeAll:"全部关闭",closeOther:"全部其它",closeRight:"关闭到右侧",openRight:"右侧打开",delete:"删除",newFile:"新建文件",newDir:"新建文件夹",errMeg:"必须提供文件或文件名",save:"保存"},O={md:"markdown",ts:"typescript",js:"javascript",pl:"perl",kt:"kotlin",py:"python",php:"php",json:"json",yml:"yaml",yaml:"yaml",sh:"shell",css:"css",scss:"scss",less:"less",lua:"lua",java:"java",ini:"ini",env:"ini",bat:"bat",coffee:"coffee",cpp:"cpp","c++":"cpp",cc:"cpp",hpp:"cpp",c:"cpp","c#":"csharp",dart:"dart",dockerfile:"dockerfile",go:"go",html:"html",pug:"pug",rb:"ruby",rs:"rust",xml:"xml"};class F{listeners=[];w$;r$;constructor(){const{writable:e,readable:t}=new TransformStream;this.w$=e.getWriter(),this.r$=t.getReader(),this._listener()}async _listener(){for(;;){const{value:e,done:t}=await this.r$.read();if(t){this.listeners.filter((e=>e.complete)).forEach((e=>e.complete()));break}this.listeners.filter((e=>e.next)).forEach((t=>t.next(e)))}}subscribe(e){return"function"==typeof e&&(e={next:e}),this.listeners.push(e),()=>{const t=this.listeners.findIndex((t=>t===e));this.listeners.splice(t,1)}}complete(){this.w$.close(),this.r$.cancel()}error(e){this.listeners.filter((e=>e.error)).forEach((t=>t.error(e)))}next(e){this.w$.write(e)}}class S{wce;constructor(e){this.wce=e}show(...e){this.el.style.display="block"}hide(...e){this.el.style.display="none"}clear(...e){this.el.innerHTML=""}remove(){this.el.remove()}showMask(...e){return this.wce.mask.show(...e)}hideMask(...e){this.wce.mask.hide(...e)}evContextmenu(e){this.el.addEventListener("contextmenu",(t=>{t.preventDefault(),t.stopPropagation(),e&&("function"==typeof e?e(t):Array.isArray(e)&&this.wce.rightMenu.show(e,t.clientX,t.clientY))}))}evKeydown(e){this.el.addEventListener("keydown",(t=>{e(t)}))}evWheel(e){this.el.addEventListener("wheel",(t=>{e(t)}))}}class P{initCodeMirror;rootEl;pane1;pane2;pane3;rightMenu;mask;get titleTabs(){return this.pane3.titleTabs}get editor(){return this.pane3.codeContainer.editor}constructor(e,t,n){this.initCodeMirror=t;const r="string"==typeof e?function(e,t=document){return t.querySelector(e)}(e):e;if(!r)throw"not root container!";n?.staticText&&Object.assign(N,n.staticText),n?.languageMap&&Object.assign(O,n.languageMap),this.rootEl=s("div",{className:i,parent:r,events:{pointerup:()=>this.pane2.isDown=!1,mousemove:e=>{this.pane2.isDown&&(this.pane1.width=e.clientX)}}}),this.pane1=new j(this),this.pane2=new $(this),this.pane3=new W(this),this.mask=new z(this),this.rightMenu=new R(this)}async showDirectoryPicker(){try{this.addDir(await window.showDirectoryPicker())}catch(e){throw console.error(e),e}}async addDir(e){new B(this,e,this.pane1.menus,e)}}class j extends S{el=s("div",{className:n,parent:this.wce.rootEl,attrs:{tabindex:0},events:{keydown:e=>{"Escape"===e.key&&(this.wce.mask.hide(),this.wce.rightMenu.hide())}}});menus=s("ul",{className:M,parent:this.el});openDirBtn=s("div",{className:T,textContent:N.openFolder,parent:this.el,click:e=>{e.stopPropagation(),this.clickBtn()}});constructor(e){super(e),this.evContextmenu([{text:N.selectFolder,click:this.clickBtn}])}set width(e){this.el.style.width=e+"px"}get isEmptyDir(){return""===this.menus.innerHTML.trim()}clickBtn=()=>{this.wce.showDirectoryPicker().then((()=>{this.hideBtn()}))};showBtn(){this.openDirBtn.style.display="block"}hideBtn(){this.openDirBtn.style.display="none"}}class $ extends S{isDown=!1;el=s("div",{className:r,parent:this.wce.rootEl,events:{pointerdown:()=>this.isDown=!0,pointerup:()=>this.isDown=!1}});constructor(e){super(e)}}class W extends S{el=s("div",{className:a,parent:this.wce.rootEl});containerEl=s("section",{className:h,parent:this.el});titleTabs=new A(this.wce,this.el);imageContainer=new _(this.wce,this.containerEl);codeContainer=new K(this.wce,this.containerEl);constructor(e){super(e)}}class z extends S{el;close$=new F;constructor(e){super(e),this.el=s("div",{className:w,parent:e.rootEl,click:e=>{this.close$.next(e),this.hide()}}),this.evContextmenu((e=>{this.wce.rightMenu.move(e.clientX,e.clientY)}))}bg(e){return this.el.style.background=e,this}show(e){if(super.show(),e)return this.close$.subscribe(e)}}class R extends S{el;constructor(e){super(e),this.el=s("ul",{className:g,parent:e.rootEl}),this.evContextmenu(),this.wce.mask.close$.subscribe((()=>{this.hide()}))}show(e,t=0,i=0){this.clear();for(const t of e){s("li",{className:v+(t.divide?` ${b}`:""),innerHTML:`<span class="text">${t.text}</span>`,parent:this.el,click:e=>{this.hideMask(),this.hide(),t.click(e)}})}this.showMask(),super.show(),this.move(t,i)}move(e,t){this.el.style.left=e+"px",this.el.style.top=t+"px"}}class I extends S{hFile;dirMenu;el;file;async getType(){return this.file||(this.file=await this.hFile.getFile()),this.file.type}async getSize(){return this.file||(this.file=await this.hFile.getFile()),this.file.size}constructor(e,t,i){super(e),this.hFile=t,this.dirMenu=i,this.el=s("li",{className:y,innerHTML:`<span>${t.name}</span>`,parent:i.files,click:this.menuClick}),this.evContextmenu([{text:N.openRight,click:this.menuClick},{text:N.delete,click:this.del}])}menuClick=e=>{e.stopPropagation(),this.wce.titleTabs.add(this)};get name(){return this.hFile.name}del=()=>{this.dirMenu.hDir.removeEntry(this.name).then((()=>{this.wce.titleTabs.closeTab(this),this.el.remove()}))}}class V extends S{dirMenu;el;msgEl=s("div",{className:x});input;unsubscribe;constructor(e,t,i=""){super(e.wce),this.dirMenu=e,this.el=s("li",{className:f,parent:e.files,click:e=>e.stopPropagation()});const n=s("div",{className:E,parent:this.el,children:[this.msgEl]});this.input=s("input",{parent:n,attrs:{required:!0,value:i},events:{input:()=>this.showeErrMsg(),keydown:e=>{e.stopPropagation(),"Enter"===e.key&&(this.showeErrMsg(),this.isValid&&(t(this.value),this.hideMask(),this.remove(),this.unsubscribe())),"Escape"===e.key&&(this.hideMask(),this.remove(),this.unsubscribe())}}}),this.input.focus(),this.unsubscribe=this.showMask((()=>{this.isValid&&t(this.value),this.remove(),this.unsubscribe()}))}showeErrMsg(){this.isValid?this.msgEl.style.display="none":(this.msgEl.style.display="block",this.msgEl.textContent=N.errMeg)}get isValid(){const e=!!this.value.trim();return e?this.input.classList.remove(L):this.input.classList.add(L),e}get value(){return this.input.value}}class B extends S{hDir;parent;hParentDir;el;files=s("ul",{className:M});isInit=!1;constructor(e,t,i,n){super(e),this.hDir=t,this.parent=i,this.hParentDir=n,this.el=s("li",{className:k,innerHTML:`<span>${this.name}</span>`,parent:i,click:this.clickMenu,children:[this.files]}),this.evContextmenu([{text:N.newFile,click:this.newFile},{text:N.newDir,click:this.newDir},{text:this.isRootDir?N.close:N.delete,click:this.delDir}])}get isOpen(){return this.files.classList.contains(m)}set isOpen(e){e?(this.isInit||this.createChildren(),this.files.classList.add(m),this.el.classList.add(m)):(this.files.classList.remove(m),this.el.classList.remove(m))}toggle(){this.isOpen=!this.isOpen}get name(){return this.hDir.name}get isRootDir(){return this.hDir===this.hParentDir}async createChildren(){const e=[],t=[],s=[],i=[];for await(const[n,r]of this.hDir)"directory"===r.kind?r.name.startsWith(".")?e.push(r):t.push(r):r.name.startsWith(".")?s.push(r):i.push(r);[...e,...t].forEach((e=>{new B(this.wce,e,this.files,this.hDir)})),[...s,...i].forEach((e=>{new I(this.wce,e,this)})),this.isInit=!0}clickMenu=e=>{e.stopPropagation(),e.currentTarget===this.el&&this.toggle()};newFile=()=>{this.isOpen||(this.isOpen=!0),new V(this,(async e=>{const t=await this.hDir.getFileHandle(e,{create:!0}),s=new I(this.wce,t,this);this.wce.titleTabs.add(s),this.wce.editor.focus()}))};newDir=()=>{this.isOpen||(this.isOpen=!0),new V(this,(async e=>{const t=await this.hDir.getDirectoryHandle(e,{create:!0});new B(this.wce,t,this.files,this.hDir)}))};delDir=()=>{this.el.remove(),this.wce.titleTabs.closeWithDir(this.hDir),this.isRootDir?this.wce.pane1.isEmptyDir&&this.wce.pane1.showBtn():this.hParentDir.removeEntry(this.name,{recursive:!0})}}class H extends S{tabs;fileMenu;el;isImage=!1;get hFile(){return this.fileMenu.hFile}constructor(e,t){super(e.wce),this.tabs=e,this.fileMenu=t,this.el=s("li",{className:p,textContent:t.name,parent:e.el,click:this.click,children:[s("span",{className:u,textContent:"✖️",click:this.close})]}),this.evContextmenu([{text:N.save,click:()=>this.save(this.wce.editor.getValue())},{divide:!0,text:N.close,click:this.close},{text:N.closeAll,click:e.closeAllTab},{text:N.closeOther,click:()=>e.closeOtherTab(this)},{text:N.closeRight,click:()=>e.closeRightTab(this)}])}get isVisible(){const e=this.tabs.el,t=this.el;return t.offsetLeft>=e.scrollLeft&&t.offsetLeft+(t.clientWidth-20)<e.clientWidth+e.scrollLeft}async save(e){const t=await this.fileMenu.hFile.createWritable();await t.write(e),await t.close()}get isActive(){return this.el.classList.contains(l)}active(e){e?this.el.classList.add(l):this.el.classList.remove(l)}async text(){const e=await this.fileMenu.hFile.getFile();return this.isImage=e.type.includes("image"),this.isImage?window.URL.createObjectURL(e):await e.text()}click=e=>{e.stopPropagation(),this.tabs.setCurrent(this)};close=e=>{e.stopPropagation(),this.tabs.closeTab(this.fileMenu)}}class A extends S{el;current;tabs=[];constructor(e,t){super(e),this.el=s("ul",{className:c,parent:t}),this.evContextmenu()}scrollToRight(){this.el.scrollTo({top:0,left:this.el.scrollWidth})}scrollToCurrent(){const e=this.current?.el.offsetLeft??0;this.el.scrollTo({top:0,left:e})}get last(){return this.tabs[this.tabs.length-1]}clear(){super.clear(),this.tabs=[],this.wce.editor.setValue(""),this.wce.pane3.imageContainer.hide(),this.wce.pane3.codeContainer.hide()}async setCurrent(e){this.current=e,this.tabs.forEach((t=>t.active(t===e)));const t=await e.text();if(e.isImage)this.wce.pane3.imageContainer.show(t);else{this.wce.pane3.imageContainer.hide(),this.wce.editor.setValue(t);let s=e.fileMenu.name.split(".");const i=s[s.length-1];let n=i;for(const e of Object.keys(O))if(e.toUpperCase()===i.toUpperCase()){n=O[e];break}window.monaco&&window.monaco.editor.setModelLanguage(this.wce.editor.getModel(),n)}e.isVisible||this.scrollToCurrent()}nextTab(e){return this.tabs[e+1]??this.tabs[e-1]??null}closeTab=e=>{const t=this.tabs.find((t=>t.fileMenu===e));if(!t)return;const s=this.tabs.indexOf(t);if(t.isActive){const e=this.nextTab(s);e?this.setCurrent(e):(this.wce.editor.setValue(""),this.wce.pane3.imageContainer.hide(),this.wce.pane3.codeContainer.hide())}t.el.remove(),t.isImage&&this.wce.pane3.imageContainer.hide(),this.tabs.splice(s,1)};async closeWithDir(e){const t=[];for(const s of this.tabs){await e.resolve(s.hFile)&&t.push(s.fileMenu)}t.forEach((e=>this.closeTab(e)))}closeAllTab=()=>{this.tabs.forEach((e=>{e.el.remove()})),this.tabs=[],this.wce.pane3.imageContainer.hide(),this.wce.pane3.codeContainer.hide()};closeOtherTab=e=>{this.tabs.forEach((t=>{t!==e&&t.remove()})),this.tabs=[e],e.isImage&&this.wce.pane3.imageContainer.hide(),this.setCurrent(e)};closeRightTab=e=>{const t=this.tabs.indexOf(e);let s=!1;this.tabs.forEach(((e,i)=>{i>t&&(s=e.isActive,e.remove())})),this.tabs.splice(t+1,this.tabs.length),s&&this.setCurrent(this.last)};add(e){const t=this.tabs.find((t=>t.fileMenu===e));if(t)this.setCurrent(t);else{const t=new H(this,e);this.tabs.push(t),this.setCurrent(t)}}}class _ extends S{el;imgEl=s("img");imageEl=s("div",{className:D,children:[this.imgEl]});scale=1;constructor(e,t){super(e),this.el=s("div",{parent:t,className:C,children:[this.imageEl]}),this.evContextmenu(),this.listenerScaleImage()}resize=e=>{e.stopPropagation(),e.ctrlKey&&(e.preventDefault(),this.scale+=-.001*e.deltaY,this.imgEl.style.transform=`scale(${this.scale})`)};reset=()=>{this.scale=1,this.imgEl.style.transform=`scale(${this.scale})`};listenerScaleImage(){this.imgEl.addEventListener("dblclick",this.reset),this.imageEl.addEventListener("wheel",this.resize),this.imgEl.addEventListener("wheel",this.resize)}show(e){this.imgEl.src=e,this.wce.pane3.codeContainer.hide(),super.show()}hide(){super.hide(),this.wce.pane3.codeContainer.show()}}class K extends S{parent;code=s("code",{style:{display:"block",height:"100%",width:"100%"}});el;editor;fontSize;constructor(e,t){super(e),this.parent=t,this.el=s("pre",{className:o,parent:this.parent,children:[this.code]}),this.editor=e.initCodeMirror(this.code),this.evKeydown((e=>{e.ctrlKey&&"KeyS"===e.code&&(e.preventDefault(),this.wce.titleTabs.current?.save(this.editor.getValue()))})),this.handle_codeMirror(),this.handle_monacoEditor()}handle_codeMirror(){const e=this.code.querySelector(".CodeMirror");e&&(e.classList.add(d),this.fontSize=parseFloat(getComputedStyle(e).fontSize),this.evWheel((t=>{t.ctrlKey&&(t.preventDefault(),this.fontSize+=-.01*t.deltaY,this.fontSize=Math.max(12,this.fontSize),e.style.fontSize=`${this.fontSize}px`)})))}handle_monacoEditor(){const e=this.code.querySelector(".monaco-editor");e&&(e.style.width="100%",e.style.height="100%")}}return t})()}));