@editora/light-code-editor 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +274 -0
- package/dist/index.es.js +1116 -0
- package/dist/index.umd.js +166 -0
- package/dist/light-code-editor.css +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
(function(c,f){typeof exports=="object"&&typeof module<"u"?f(exports):typeof define=="function"&&define.amd?define(["exports"],f):(c=typeof globalThis<"u"?globalThis:c||self,f(c.LightCodeEditor={}))})(this,(function(c){"use strict";class f{constructor(e=""){this._lines=[],this._version=0,this.setText(e)}getLine(e){return this._lines[e]||""}getLines(){return[...this._lines]}getLineCount(){return this._lines.length}getText(){return this._lines.join(`
|
|
2
|
+
`)}setText(e){this._lines=e.split(`
|
|
3
|
+
`),this._version++}getTextInRange(e){if(e.start.line===e.end.line)return this.getLine(e.start.line).substring(e.start.column,e.end.column);const t=[];t.push(this.getLine(e.start.line).substring(e.start.column));for(let n=e.start.line+1;n<e.end.line;n++)t.push(this.getLine(n));return e.end.line<this.getLineCount()&&t.push(this.getLine(e.end.line).substring(0,e.end.column)),t.join(`
|
|
4
|
+
`)}replaceRange(e,t){const n=this.getTextInRange(e);if(e.start.line===e.end.line){const i=this.getLine(e.start.line),s=i.substring(0,e.start.column)+t+i.substring(e.end.column);this._lines[e.start.line]=s}else{const i=this.getLine(e.start.line),s=this.getLine(e.end.line),o=i.substring(0,e.start.column)+t,h=s.substring(e.end.column),r=t.split(`
|
|
5
|
+
`);r[0]=o+r[0],r[r.length-1]=r[r.length-1]+h,this._lines.splice(e.start.line,e.end.line-e.start.line+1,...r)}return this._version++,{range:e,text:t,oldText:n}}insertText(e,t){const n={start:e,end:e};return this.replaceRange(n,t)}deleteRange(e){return this.replaceRange(e,"")}positionToOffset(e){let t=0;for(let n=0;n<e.line;n++)t+=this.getLine(n).length+1;return t+=e.column,t}offsetToPosition(e){let t=e;for(let n=0;n<this.getLineCount();n++){const i=this.getLine(n).length;if(t<=i)return{line:n,column:t};t-=i+1}return{line:this.getLineCount()-1,column:this.getLine(this.getLineCount()-1).length}}isValidPosition(e){return!(e.line<0||e.line>=this.getLineCount()||e.column<0||e.column>this.getLine(e.line).length)}isValidRange(e){return this.isValidPosition(e.start)&&this.isValidPosition(e.end)}getVersion(){return this._version}clone(){const e=new f;return e._lines=[...this._lines],e._version=this._version,e}}class y{constructor(e){this.gutterWidth=50,this.lineHeight=21,this.container=e,this.createDOM()}createDOM(){this.container.innerHTML="";const e=document.createElement("div");e.style.cssText=`
|
|
6
|
+
position: relative;
|
|
7
|
+
display: flex;
|
|
8
|
+
width: 100%;
|
|
9
|
+
height: 100%;
|
|
10
|
+
background: var(--editor-background, #1e1e1e);
|
|
11
|
+
color: var(--editor-foreground, #f8f9fa);
|
|
12
|
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
13
|
+
font-size: 14px;
|
|
14
|
+
line-height: ${this.lineHeight}px;
|
|
15
|
+
overflow: hidden;
|
|
16
|
+
`,this.lineNumbersElement=document.createElement("div"),this.lineNumbersElement.style.cssText=`
|
|
17
|
+
position: sticky;
|
|
18
|
+
left: 0;
|
|
19
|
+
top: 0;
|
|
20
|
+
width: ${this.gutterWidth}px;
|
|
21
|
+
background: var(--editor-gutter-background, #252526);
|
|
22
|
+
color: var(--editor-gutter-foreground, #858585);
|
|
23
|
+
padding: 0;
|
|
24
|
+
text-align: right;
|
|
25
|
+
border-right: 1px solid var(--editor-gutter-border, #3e3e42);
|
|
26
|
+
user-select: none;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
z-index: 1;
|
|
29
|
+
`,this.contentElement=document.createElement("div"),this.contentElement.style.cssText=`
|
|
30
|
+
flex: 1;
|
|
31
|
+
padding: 0;
|
|
32
|
+
background: transparent;
|
|
33
|
+
border: none;
|
|
34
|
+
outline: none;
|
|
35
|
+
white-space: pre;
|
|
36
|
+
overflow-x: auto;
|
|
37
|
+
overflow-y: auto;
|
|
38
|
+
min-height: 400px;
|
|
39
|
+
font-family: inherit;
|
|
40
|
+
font-size: inherit;
|
|
41
|
+
line-height: inherit;
|
|
42
|
+
color: inherit;
|
|
43
|
+
tab-size: 2;
|
|
44
|
+
-moz-tab-size: 2;
|
|
45
|
+
`,this.contentElement.contentEditable="true",this.contentElement.spellcheck=!1,e.appendChild(this.lineNumbersElement),e.appendChild(this.contentElement),this.container.appendChild(e),this.updateLineNumbers(1)}updateLineNumbers(e){const t=Math.max(e,20),n=Array.from({length:t},(i,s)=>s+1);this.lineNumbersElement.innerHTML=n.map(i=>`<div style="height: ${this.lineHeight}px; line-height: ${this.lineHeight}px; padding-right: 12px;">${i}</div>`).join("")}getContentElement(){return this.contentElement}getLineNumbersElement(){return this.lineNumbersElement}getText(){return this.contentElement.textContent||""}setText(e){this.contentElement.textContent=e;const t=e.split(`
|
|
46
|
+
`).length;this.updateLineNumbers(t)}getCursorPosition(){const e=window.getSelection();if(!e||e.rangeCount===0)return{line:0,column:0};const t=e.getRangeAt(0),n=t.cloneRange();n.selectNodeContents(this.contentElement),n.setEnd(t.endContainer,t.endOffset);const s=n.toString().split(`
|
|
47
|
+
`);return{line:s.length-1,column:s[s.length-1].length}}setCursorPosition(e){const n=this.getText().split(`
|
|
48
|
+
`),i=Math.min(e.line,n.length-1),s=Math.min(e.column,n[i]?.length||0);let o=0;for(let m=0;m<i;m++)o+=n[m].length+1;o+=s;const h=document.createRange(),r=window.getSelection();let l=0,d=null,a=0;const g=document.createTreeWalker(this.contentElement,NodeFilter.SHOW_TEXT,null);let x;for(;x=g.nextNode();){const m=x.textContent?.length||0;if(l+m>=o){d=x,a=o-l;break}l+=m}if(d)try{h.setStart(d,a),h.setEnd(d,a),r?.removeAllRanges(),r?.addRange(h)}catch(m){console.warn("Could not set cursor position:",m)}}getSelectionRange(){const e=window.getSelection();if(!e||e.rangeCount===0||e.isCollapsed)return;const t=e.getRangeAt(0),n=t.cloneRange();n.selectNodeContents(this.contentElement),n.setEnd(t.startContainer,t.startOffset);const s=n.toString().split(`
|
|
49
|
+
`),o=t.cloneRange();o.selectNodeContents(this.contentElement),o.setEnd(t.endContainer,t.endOffset);const r=o.toString().split(`
|
|
50
|
+
`);return{start:{line:s.length-1,column:s[s.length-1].length},end:{line:r.length-1,column:r[r.length-1].length}}}setSelectionRange(e){this.setCursorPosition(e.start)}focus(){this.contentElement.focus()}blur(){this.contentElement.blur()}setReadOnly(e){this.contentElement.contentEditable=e?"false":"true"}applyTheme(e){Object.entries(e).forEach(([t,n])=>{this.container.style.setProperty(`--${t}`,n)})}scrollToPosition(e){const t=this.lineNumbersElement.children[e.line];t&&t.scrollIntoView({block:"center",behavior:"smooth"})}getScrollTop(){return this.contentElement.scrollTop}setScrollTop(e){this.contentElement.scrollTop=e,this.lineNumbersElement.scrollTop=e}destroy(){this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container)}}class p{constructor(e,t={}){this.extensions=new Map,this.commands=new Map,this.eventListeners=new Map,this.folds=[],this.currentTheme="default",this.isDestroyed=!1,this.config={value:"",theme:"default",readOnly:!1,tabSize:2,lineWrapping:!1,lineNumbers:!0,...t},this.textModel=new f(this.config.value),this.view=new y(e),this.view.setText(this.textModel.getText()),this.view.setReadOnly(this.config.readOnly||!1),this.setupEventHandlers(),this.config.extensions&&this.config.extensions.forEach(n=>this.addExtension(n)),this.setTheme(this.config.theme)}getTextModel(){return this.textModel}getView(){return this.view}getConfig(){return{...this.config}}getKeymapExtension(){return this.extensions.get("keymap")}setupEventHandlers(){const e=this.view.getContentElement();e.addEventListener("input",()=>{const t=this.view.getText(),n=this.textModel.getText();t!==n&&(this.textModel.setText(t),this.emit("change",[{range:this.getFullRange(),text:t,oldText:n}]),this.updateLineNumbers())}),e.addEventListener("selectionchange",()=>{const t=this.getCursor(),n=this.getSelection();this.emit("cursor",t),n&&this.emit("selection",n)}),e.addEventListener("keydown",t=>{this.emit("keydown",t);for(const n of this.extensions.values())if(n.onKeyDown&&n.onKeyDown(t)===!1){t.preventDefault(),t.stopPropagation();return}}),e.addEventListener("mousedown",t=>{this.emit("mousedown",t);for(const n of this.extensions.values())if(n.onMouseDown&&n.onMouseDown(t)===!1){t.preventDefault(),t.stopPropagation();return}}),e.addEventListener("focus",()=>{this.emit("focus")}),e.addEventListener("blur",()=>{this.emit("blur")})}updateLineNumbers(){const e=this.textModel.getLineCount();this.view.updateLineNumbers(e)}getFullRange(){return{start:{line:0,column:0},end:{line:this.textModel.getLineCount()-1,column:this.textModel.getLine(this.textModel.getLineCount()-1).length}}}emit(e,...t){const n=this.eventListeners.get(e);n&&n.forEach(i=>i(...t))}getValue(){return this.textModel.getText()}setValue(e){this.textModel.setText(e),this.view.setText(e),this.updateLineNumbers(),this.emit("change",[{range:this.getFullRange(),text:e,oldText:this.getValue()}])}getState(){return{text:this.getValue(),cursor:this.getCursor(),selection:this.getSelection(),readOnly:this.config.readOnly||!1,theme:this.currentTheme}}getCursor(){const e=this.view.getCursorPosition();return{position:e,anchor:e}}setCursor(e){this.view.setCursorPosition(e),this.emit("cursor",this.getCursor())}getSelection(){return this.view.getSelectionRange()}setSelection(e){this.view.setSelectionRange(e),this.emit("selection",e)}setTheme(e){this.currentTheme=e;const t={"editor-background":e==="dark"?"#1e1e1e":"#ffffff","editor-foreground":e==="dark"?"#f8f9fa":"#1a1a1a","editor-gutter-background":e==="dark"?"#252526":"#f8f9fa","editor-gutter-foreground":e==="dark"?"#858585":"#666666","editor-gutter-border":e==="dark"?"#3e3e42":"#e1e5e9"};this.view.applyTheme(t)}setReadOnly(e){this.config.readOnly=e,this.view.setReadOnly(e)}addExtension(e){if(this.extensions.has(e.name))throw new Error(`Extension '${e.name}' already exists`);this.extensions.set(e.name,e),e.setup(this)}removeExtension(e){const t=this.extensions.get(e);t&&t.destroy&&t.destroy(),this.extensions.delete(e)}executeCommand(e,...t){const n=this.commands.get(e);n?n(this,...t):console.warn(`Command '${e}' not found`)}registerCommand(e,t){this.commands.set(e,t)}search(e,t={}){const n={caseSensitive:!1,regex:!1,...t},i=[],s=this.getValue();s.split(`
|
|
51
|
+
`);let o=n.caseSensitive?s:s.toLowerCase(),h=n.caseSensitive?e:e.toLowerCase();if(n.regex){const r=new RegExp(h,n.caseSensitive?"g":"gi");let l;for(;(l=r.exec(o))!==null;){const d=this.textModel.offsetToPosition(l.index),a=this.textModel.offsetToPosition(l.index+l[0].length);i.push({range:{start:d,end:a},match:l[0]})}}else{let r=0,l=o.indexOf(h,r);for(;l!==-1;){const d=l+e.length,a=this.textModel.offsetToPosition(l),g=this.textModel.offsetToPosition(d);i.push({range:{start:a,end:g},match:s.substring(l,d)}),r=d,l=o.indexOf(h,r)}}return i}replace(e,t){const n=this.textModel.replaceRange(e,t);this.view.setText(this.getValue()),this.emit("change",[n])}replaceAll(e,t,n={}){const i=this.search(e,n);let s=0;for(let o=i.length-1;o>=0;o--)this.replace(i[o].range,t),s++;return s}fold(e){const t={start:e.start,end:e.end,collapsed:!0,level:0};this.folds.push(t)}unfold(e){this.folds=this.folds.filter(t=>!(t.start.line===e.start.line&&t.end.line===e.end.line))}getFolds(){return[...this.folds]}focus(){this.view.focus()}blur(){this.view.blur()}destroy(){if(!this.isDestroyed){this.isDestroyed=!0;for(const e of this.extensions.values())e.destroy&&e.destroy();this.extensions.clear(),this.view.destroy(),this.commands.clear(),this.eventListeners.clear()}}on(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,[]),this.eventListeners.get(e).push(t)}off(e,t){if(!this.eventListeners.has(e))return;const n=this.eventListeners.get(e);if(t){const i=n.indexOf(t);i!==-1&&n.splice(i,1)}else n.length=0}}class b{constructor(e){this.name="keymap",this.editor=null,this.keymap={},this.isMac=navigator.platform.toUpperCase().indexOf("MAC")>=0,this.keymap=e||this.getDefaultKeymap()}setup(e){this.editor=e,e.on("keydown",t=>this.handleKeyDown(t))}handleKeyDown(e){if(!this.editor)return;const t=this.findMatchingBinding(e);if(t)return this.editor.executeCommand(t.command),e.preventDefault(),e.stopPropagation(),!1}findMatchingBinding(e){const{key:t,ctrlKey:n,altKey:i,shiftKey:s,metaKey:o}=e,h=t.toLowerCase(),r=this.keymap[h];if(!r)return null;for(const l of r)if((l.ctrlKey===n||!l.ctrlKey&&!n)&&(l.altKey===i||!l.altKey&&!i)&&(l.shiftKey===s||!l.shiftKey&&!s)&&(l.metaKey===o||!l.metaKey&&!o))return l;return null}getDefaultKeymap(){const e={};return this.addBinding(e,"f",{ctrlKey:!this.isMac,metaKey:this.isMac},"find"),this.addBinding(e,"h",{ctrlKey:!this.isMac,metaKey:this.isMac},"replace"),this.addBinding(e,"f3",{},"findNext"),this.addBinding(e,"f3",{shiftKey:!0},"findPrev"),this.addBinding(e,"g",{ctrlKey:!this.isMac,metaKey:this.isMac},"findNext"),this.addBinding(e,"[",{ctrlKey:!this.isMac,metaKey:this.isMac,shiftKey:!0},"fold"),this.addBinding(e,"]",{ctrlKey:!this.isMac,metaKey:this.isMac,shiftKey:!0},"unfold"),this.addBinding(e,"s",{ctrlKey:!this.isMac,metaKey:this.isMac},"save"),this.addBinding(e,"z",{ctrlKey:!this.isMac,metaKey:this.isMac},"undo"),this.addBinding(e,"y",{ctrlKey:!this.isMac,metaKey:this.isMac},"redo"),this.addBinding(e,"z",{ctrlKey:!this.isMac,metaKey:this.isMac,shiftKey:!0},"redo"),this.addBinding(e,"t",{ctrlKey:!this.isMac,metaKey:this.isMac,shiftKey:!0},"toggleTheme"),e}addBinding(e,t,n,i){const s=t.toLowerCase();e[s]||(e[s]=[]),e[s].push({key:s,command:i,...n})}setKeymap(e){this.keymap={...e}}addKeyBinding(e){const t=e.key.toLowerCase();this.keymap[t]||(this.keymap[t]=[]),this.keymap[t]=this.keymap[t].filter(n=>n.command!==e.command),this.keymap[t].push({...e,key:t})}removeKeyBinding(e,t){const n=e.toLowerCase();t?this.keymap[n]&&(this.keymap[n]=this.keymap[n].filter(i=>i.command!==t),this.keymap[n].length===0&&delete this.keymap[n]):delete this.keymap[n]}getKeymap(){return{...this.keymap}}getBindingsForCommand(e){const t=[];for(const n in this.keymap)for(const i of this.keymap[n])i.command===e&&t.push({...i});return t}getPlatformInfo(){return{isMac:this.isMac,platform:navigator.platform}}destroy(){this.keymap={},this.editor=null}}class v{constructor(){this.name="line-numbers",this.editor=null,this.lineNumbersElement=null,this.isEnabled=!0}setup(e){this.editor=e,this.createLineNumbers(),e.registerCommand("toggleLineNumbers",()=>{this.toggle()}),e.on("change",()=>{this.updateLineNumbers()}),this.updateLineNumbers()}createLineNumbers(){if(!this.editor)return;const e=this.editor.getView();if(!e.container)return;this.lineNumbersElement=document.createElement("div"),this.lineNumbersElement.style.cssText=`
|
|
52
|
+
position: absolute;
|
|
53
|
+
left: 0;
|
|
54
|
+
top: 0;
|
|
55
|
+
bottom: 0;
|
|
56
|
+
width: 50px;
|
|
57
|
+
background: var(--editor-gutter-background, #252526);
|
|
58
|
+
color: var(--editor-gutter-foreground, #858585);
|
|
59
|
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
60
|
+
font-size: 14px;
|
|
61
|
+
line-height: 21px;
|
|
62
|
+
padding: 0;
|
|
63
|
+
text-align: right;
|
|
64
|
+
border-right: 1px solid var(--editor-gutter-border, #3e3e42);
|
|
65
|
+
user-select: none;
|
|
66
|
+
overflow: hidden;
|
|
67
|
+
z-index: 1;
|
|
68
|
+
pointer-events: none;
|
|
69
|
+
`;const n=e.getContentElement();n&&n.parentNode&&(n.parentNode.insertBefore(this.lineNumbersElement,n),n.style.marginLeft="60px")}updateLineNumbers(){if(!this.lineNumbersElement||!this.editor||!this.isEnabled)return;const e=this.editor.getValue().split(`
|
|
70
|
+
`).length,t=Array.from({length:Math.max(e,20)},(n,i)=>i+1);this.lineNumbersElement.innerHTML=t.map(n=>`<div style="height: 21px; line-height: 21px; padding-right: 12px;">${n}</div>`).join("")}toggle(){this.isEnabled=!this.isEnabled,this.lineNumbersElement&&(this.lineNumbersElement.style.display=this.isEnabled?"block":"none");const e=this.editor.getView().getContentElement();e&&(e.style.marginLeft=this.isEnabled?"60px":"0"),this.updateLineNumbers()}destroy(){this.lineNumbersElement&&this.lineNumbersElement.parentNode&&this.lineNumbersElement.parentNode.removeChild(this.lineNumbersElement),this.lineNumbersElement=null,this.editor=null}}class E{constructor(){this.name="theme",this.editor=null,this.currentTheme="dark"}setup(e){this.editor=e,e.registerCommand("setTheme",t=>{this.setTheme(t)}),e.registerCommand("toggleTheme",()=>{this.toggleTheme()}),this.setTheme(this.currentTheme)}setTheme(e){this.editor&&(this.currentTheme=e,this.editor.setTheme(e))}toggleTheme(){const e=this.currentTheme==="dark"?"light":"dark";this.setTheme(e)}getCurrentTheme(){return this.currentTheme}destroy(){this.editor=null}}class w{constructor(){this.name="read-only",this.editor=null,this.isReadOnly=!1}setup(e){this.editor=e,e.registerCommand("setReadOnly",t=>{this.setReadOnly(t)}),e.registerCommand("toggleReadOnly",()=>{this.toggleReadOnly()}),e.on("keydown",t=>{if(t.ctrlKey&&t.key==="r")return t.preventDefault(),this.toggleReadOnly(),!1})}setReadOnly(e){this.editor&&(this.isReadOnly=e,this.editor.setReadOnly(e))}toggleReadOnly(){this.setReadOnly(!this.isReadOnly)}isCurrentlyReadOnly(){return this.isReadOnly}destroy(){this.editor=null}}class k{constructor(){this.name="search",this.editor=null,this.searchUI=null,this.isVisible=!1,this.currentResults=[],this.currentIndex=-1}setup(e){this.editor=e,e.registerCommand("find",()=>{this.showSearch()}),e.registerCommand("findNext",()=>{this.findNext()}),e.registerCommand("findPrev",()=>{this.findPrev()}),e.registerCommand("replace",()=>{this.showReplace()}),e.registerCommand("replaceAll",(t,n)=>{this.replaceAll(t,n)})}showSearch(){if(this.editor&&(this.searchUI||this.createSearchUI(),this.isVisible=!0,this.searchUI)){this.searchUI.style.display="block";const e=this.searchUI.querySelector("input");e&&(e.focus(),e.select())}}showReplace(){this.showSearch();const e=this.searchUI?.querySelector(".search-replace-input");e&&(e.style.display="block",e.focus());const t=this.searchUI?.querySelector(".search-status");t&&(t.textContent="Replace mode - Enter to replace, Shift+Enter to replace all")}hideSearch(){this.isVisible=!1,this.searchUI&&(this.searchUI.style.display="none"),this.clearHighlights()}createSearchUI(){if(!this.editor)return;const e=document.querySelector(".rte-source-editor-modal");if(!e)return;this.searchUI=document.createElement("div"),this.searchUI.style.cssText=`
|
|
71
|
+
position: absolute;
|
|
72
|
+
top: 10px;
|
|
73
|
+
right: 10px;
|
|
74
|
+
background: var(--editor-background, #1e1e1e);
|
|
75
|
+
border: 1px solid var(--editor-gutter-border, #3e3e42);
|
|
76
|
+
border-radius: 4px;
|
|
77
|
+
padding: 8px;
|
|
78
|
+
z-index: 1000;
|
|
79
|
+
display: none;
|
|
80
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
81
|
+
min-width: 250px;
|
|
82
|
+
`,this.searchUI.innerHTML=`
|
|
83
|
+
<div style="display: flex; align-items: center; gap: 4px; margin-bottom: 4px;">
|
|
84
|
+
<input type="text" placeholder="Find..." style="
|
|
85
|
+
flex: 1;
|
|
86
|
+
padding: 4px 8px;
|
|
87
|
+
background: var(--editor-gutter-background, #252526);
|
|
88
|
+
color: var(--editor-foreground, #f8f9fa);
|
|
89
|
+
border: 1px solid var(--editor-gutter-border, #3e3e42);
|
|
90
|
+
border-radius: 3px;
|
|
91
|
+
font-size: 12px;
|
|
92
|
+
outline: none;
|
|
93
|
+
" />
|
|
94
|
+
<button class="search-prev" style="
|
|
95
|
+
padding: 2px 6px;
|
|
96
|
+
background: var(--editor-gutter-background, #252526);
|
|
97
|
+
color: var(--editor-gutter-foreground, #858585);
|
|
98
|
+
border: 1px solid var(--editor-gutter-border, #3e3e42);
|
|
99
|
+
border-radius: 3px;
|
|
100
|
+
cursor: pointer;
|
|
101
|
+
font-size: 11px;
|
|
102
|
+
">↑</button>
|
|
103
|
+
<button class="search-next" style="
|
|
104
|
+
padding: 2px 6px;
|
|
105
|
+
background: var(--editor-gutter-background, #252526);
|
|
106
|
+
color: var(--editor-gutter-foreground, #858585);
|
|
107
|
+
border: 1px solid var(--editor-gutter-border, #3e3e42);
|
|
108
|
+
border-radius: 3px;
|
|
109
|
+
cursor: pointer;
|
|
110
|
+
font-size: 11px;
|
|
111
|
+
">↓</button>
|
|
112
|
+
<button class="search-close" style="
|
|
113
|
+
padding: 2px 6px;
|
|
114
|
+
background: var(--editor-gutter-background, #252526);
|
|
115
|
+
color: var(--editor-gutter-foreground, #858585);
|
|
116
|
+
border: 1px solid var(--editor-gutter-border, #3e3e42);
|
|
117
|
+
border-radius: 3px;
|
|
118
|
+
cursor: pointer;
|
|
119
|
+
font-size: 11px;
|
|
120
|
+
">×</button>
|
|
121
|
+
</div>
|
|
122
|
+
<div class="search-status" style="
|
|
123
|
+
font-size: 11px;
|
|
124
|
+
color: var(--editor-gutter-foreground, #858585);
|
|
125
|
+
text-align: center;
|
|
126
|
+
"></div>
|
|
127
|
+
<input type="text" class="search-replace-input" placeholder="Replace with..." style="
|
|
128
|
+
width: 100%;
|
|
129
|
+
padding: 4px 8px;
|
|
130
|
+
background: var(--editor-gutter-background, #252526);
|
|
131
|
+
color: var(--editor-foreground, #f8f9fa);
|
|
132
|
+
border: 1px solid var(--editor-gutter-border, #3e3e42);
|
|
133
|
+
border-radius: 3px;
|
|
134
|
+
font-size: 12px;
|
|
135
|
+
outline: none;
|
|
136
|
+
display: none;
|
|
137
|
+
margin-top: 4px;
|
|
138
|
+
" />
|
|
139
|
+
`;const t=this.searchUI.querySelector("input"),n=this.searchUI.querySelector(".search-replace-input"),i=this.searchUI.querySelector(".search-prev"),s=this.searchUI.querySelector(".search-next"),o=this.searchUI.querySelector(".search-close");t.addEventListener("input",()=>{this.performSearch(t.value)}),t.addEventListener("keydown",h=>{h.key==="Enter"&&(h.preventDefault(),h.shiftKey?this.findPrev():this.findNext())}),n.addEventListener("keydown",h=>{h.key==="Enter"&&(h.preventDefault(),h.shiftKey?this.replaceAll(t.value,n.value):this.replaceCurrent(t.value,n.value))}),i.addEventListener("click",()=>this.findPrev()),s.addEventListener("click",()=>this.findNext()),o.addEventListener("click",()=>this.hideSearch()),e.appendChild(this.searchUI)}performSearch(e){if(!this.editor||!e.trim()){this.clearHighlights(),this.updateStatus("");return}const t=this.editor.getValue(),n=[];let i=t.toLowerCase().indexOf(e.toLowerCase());for(;i!==-1;){const s=this.getPositionFromOffset(t,i),o=this.getPositionFromOffset(t,i+e.length);n.push({range:{start:s,end:o},match:t.substring(i,i+e.length)}),i=t.toLowerCase().indexOf(e.toLowerCase(),i+1)}this.currentResults=n,this.currentIndex=this.currentResults.length>0?0:-1,this.updateHighlights(),this.updateStatus(`${this.currentResults.length} matches`)}getPositionFromOffset(e,t){const n=e.substring(0,t).split(`
|
|
140
|
+
`),i=n.length-1,s=n[n.length-1].length;return{line:i,column:s}}findNext(){this.currentResults.length!==0&&(this.currentIndex=(this.currentIndex+1)%this.currentResults.length,this.updateHighlights())}findPrev(){this.currentResults.length!==0&&(this.currentIndex=this.currentIndex<=0?this.currentResults.length-1:this.currentIndex-1,this.updateHighlights())}replaceCurrent(e,t){if(!this.editor||!e.trim()||this.currentIndex===-1)return;const n=this.currentResults[this.currentIndex];if(!n)return;const i=this.editor.getValue(),s=this.getOffsetFromPosition(i,n.range.start),o=i.substring(0,s),h=i.substring(s+e.length),r=o+t+h;this.editor.setValue(r),this.performSearch(e),this.updateStatus("Replaced current occurrence")}replaceAll(e,t){if(!this.editor||!e.trim())return;let n=this.editor.getValue(),i=0,s=n.toLowerCase().indexOf(e.toLowerCase());for(;s!==-1;)n=n.substring(0,s)+t+n.substring(s+e.length),i++,s=n.toLowerCase().indexOf(e.toLowerCase(),s+t.length);i>0&&(this.editor.setValue(n),this.updateStatus(`Replaced ${i} occurrences`))}getOffsetFromPosition(e,t){const n=e.split(`
|
|
141
|
+
`);let i=0;for(let s=0;s<t.line;s++)i+=n[s].length+1;return i+=t.column,i}updateHighlights(){this.clearHighlights(),!(this.currentResults.length===0||this.currentIndex===-1)&&(this.currentResults[this.currentIndex],this.updateStatus(`${this.currentResults.length} matches (showing ${this.currentIndex+1}/${this.currentResults.length})`))}clearHighlights(){}updateStatus(e){const t=this.searchUI?.querySelector(".search-status");t&&(t.textContent=e)}destroy(){this.searchUI&&this.searchUI.parentNode&&this.searchUI.parentNode.removeChild(this.searchUI),this.searchUI=null,this.editor=null}}class C{constructor(){this.name="bracket-matching",this.editor=null,this.bracketPairs={"(":")","[":"]","{":"}","<":">"},this.reverseBracketPairs={")":"(","]":"[","}":"{",">":"<"},this.currentMatch=null}setup(e){this.editor=e,e.on("cursor",()=>{this.updateBracketMatching()}),e.on("change",()=>{this.updateBracketMatching()})}updateBracketMatching(){if(!this.editor)return;const e=this.editor.getCursor(),t=this.editor.getValue();this.clearBracketHighlighting();const n=this.getBracketAtPosition(t,e.position);if(!n)return;const i=this.findMatchingBracket(t,n);i&&(this.currentMatch=i,this.highlightBrackets(i))}getBracketAtPosition(e,t){const n=e.split(`
|
|
142
|
+
`);if(t.line>=n.length)return null;const i=n[t.line];if(t.column>=i.length)return null;const s=i[t.column];return this.bracketPairs[s]||this.reverseBracketPairs[s]?{char:s,position:t}:null}findMatchingBracket(e,t){const n=e.split(`
|
|
143
|
+
`),i=t.position.line,s=t.position.column,o=t.char;return this.bracketPairs[o]?this.findClosingBracket(e,n,i,s,o):this.reverseBracketPairs[o]?this.findOpeningBracket(e,n,i,s,o):null}findClosingBracket(e,t,n,i,s){const o=this.bracketPairs[s];let h=0;for(let r=n;r<t.length;r++){const l=t[r],d=r===n?i:0;for(let a=d;a<l.length;a++){const g=l[a];if(g===s)h++;else if(g===o&&(h--,h===0))return{open:{start:{line:n,column:i},end:{line:n,column:i+1}},close:{start:{line:r,column:a},end:{line:r,column:a+1}},type:s}}}return null}findOpeningBracket(e,t,n,i,s){const o=this.reverseBracketPairs[s];let h=0;for(let r=n;r>=0;r--){const l=t[r],d=r===n?i:l.length-1;for(let a=d;a>=0;a--){const g=l[a];if(g===s)h++;else if(g===o&&(h--,h===0))return{open:{start:{line:r,column:a},end:{line:r,column:a+1}},close:{start:{line:n,column:i},end:{line:n,column:i+1}},type:o}}}return null}highlightBrackets(e){console.log("Bracket match found:",e)}clearBracketHighlighting(){this.currentMatch=null}getCurrentMatch(){return this.currentMatch}destroy(){this.clearBracketHighlighting(),this.editor=null}}class L{constructor(){this.name="code-folding",this.editor=null,this.foldIndicators=[],this.foldingUI=null}setup(e){this.editor=e,e.registerCommand("fold",()=>{console.log("Fold command executed - folding not yet implemented"),this.foldAtCursor()}),e.registerCommand("unfold",()=>{console.log("Unfold command executed - unfolding not yet implemented"),this.unfoldAtCursor()}),e.registerCommand("foldAll",()=>{console.log("Fold all command executed - folding not yet implemented"),this.foldAll()}),e.registerCommand("unfoldAll",()=>{console.log("Unfold all command executed - unfolding not yet implemented"),this.unfoldAll()}),e.on("change",()=>{this.updateFoldIndicators()}),this.createFoldingUI(),this.updateFoldIndicators()}createFoldingUI(){if(!this.editor)return;const e=document.querySelector(".rte-source-editor-modal");e&&(this.foldingUI=document.createElement("div"),this.foldingUI.style.cssText=`
|
|
144
|
+
position: absolute;
|
|
145
|
+
left: 40px;
|
|
146
|
+
top: 0;
|
|
147
|
+
bottom: 0;
|
|
148
|
+
width: 20px;
|
|
149
|
+
pointer-events: none;
|
|
150
|
+
z-index: 2;
|
|
151
|
+
`,e.appendChild(this.foldingUI))}updateFoldIndicators(){if(!this.editor||!this.foldingUI)return;this.foldingUI.innerHTML="",this.foldIndicators=[];const t=this.editor.getValue().split(`
|
|
152
|
+
`);this.findFoldableLines(t).forEach(i=>{this.createFoldIndicator(i)})}findFoldableLines(e){const t=[];for(let n=0;n<e.length;n++){const i=e[n].trim();(i.startsWith("{")||i.startsWith("function")||i.startsWith("class")||i.startsWith("if")||i.includes("=>")||i.startsWith("for")||i.startsWith("while")||i.startsWith("try"))&&t.push(n)}return t}createFoldIndicator(e){if(!this.foldingUI)return;const t=document.createElement("div");t.style.cssText=`
|
|
153
|
+
position: absolute;
|
|
154
|
+
left: 0;
|
|
155
|
+
top: ${e*21}px;
|
|
156
|
+
width: 20px;
|
|
157
|
+
height: 21px;
|
|
158
|
+
display: flex;
|
|
159
|
+
align-items: center;
|
|
160
|
+
justify-content: center;
|
|
161
|
+
cursor: pointer;
|
|
162
|
+
pointer-events: auto;
|
|
163
|
+
color: var(--editor-gutter-foreground, #858585);
|
|
164
|
+
font-size: 10px;
|
|
165
|
+
user-select: none;
|
|
166
|
+
`,t.innerHTML="▶",t.title="Code folding not yet implemented - click shows fold indicators",t.addEventListener("click",()=>{console.log(`Fold toggle clicked at line ${e} - implementation pending`)}),this.foldingUI.appendChild(t),this.foldIndicators.push(t)}foldAtCursor(){console.log("foldAtCursor called - implementation pending")}unfoldAtCursor(){console.log("unfoldAtCursor called - implementation pending")}foldAll(){console.log("foldAll called - implementation pending")}unfoldAll(){console.log("unfoldAll called - implementation pending")}destroy(){this.foldingUI&&this.foldingUI.parentNode&&this.foldingUI.parentNode.removeChild(this.foldingUI),this.foldingUI=null,this.foldIndicators=[],this.editor=null}}class T{constructor(){this.name="syntax-highlighting",this.editor=null,this.currentTheme="dark"}setup(e){this.editor=e,console.log("SyntaxHighlightingExtension: Isolated extension loaded - ready for use")}setTheme(e){this.currentTheme=e,console.log(`SyntaxHighlightingExtension: Theme changed to ${e}`)}getSyntaxColors(){return this.currentTheme==="dark"?{tag:"#569cd6",comment:"#6a9955",attrValue:"#ce9178",text:"#d4d4d4"}:{tag:"#0000ff",comment:"#008000",attrValue:"#a31515",text:"#000000"}}highlightHTML(e){const t=this.getSyntaxColors();let n=e;return n=n.replace(/(<\/?[\w:-]+(?:\s[^>]*?)?\/?>)/g,`<span style="color: ${t.tag};">$1</span>`),n=n.replace(/(<!--[\s\S]*?-->)/g,`<span style="color: ${t.comment};">$1</span>`),n=n.replace(/("[^"]*"|'[^']*')/g,`<span style="color: ${t.attrValue};">$1</span>`),n}shouldHighlight(e){return/<\/?[\w:-]+|<!--/.test(e)}destroy(){this.editor=null,console.log("SyntaxHighlightingExtension: Extension destroyed")}}function M(u,e){const t={...e};return t.extensions||(t.extensions=[]),t.extensions.some(i=>i.name==="keymap")||t.extensions.unshift(new b(t.keymap)),new p(u,t)}c.BracketMatchingExtension=C,c.CodeFoldingExtension=L,c.EditorCore=p,c.KeymapExtension=b,c.LineNumbersExtension=v,c.ReadOnlyExtension=w,c.SearchExtension=k,c.SyntaxHighlightingExtension=T,c.TextModel=f,c.ThemeExtension=E,c.View=y,c.createEditor=M,c.default=p,Object.defineProperties(c,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.rte-light-editor{position:relative;width:100%;height:400px;border:1px solid #ccc;border-radius:4px;overflow:hidden;font-family:Monaco,Menlo,Ubuntu Mono,monospace;font-size:14px;line-height:21px}.rte-light-editor-content{position:relative;width:100%;height:100%;padding:8px;margin:0;border:none;outline:none;resize:none;font-family:inherit;font-size:inherit;line-height:inherit;white-space:pre-wrap;word-wrap:break-word;overflow:auto;background:transparent}.rte-light-editor-gutter{position:absolute;left:0;top:0;bottom:0;width:50px;padding:8px 0;text-align:right;border-right:1px solid #e0e0e0;background:#f8f8f8;color:#999;font-size:12px;line-height:21px;-webkit-user-select:none;user-select:none;overflow:hidden}.rte-light-editor-gutter.dark{border-right-color:#3e3e3e;background:#1e1e1e;color:#666}.rte-syntax-highlight-overlay{position:absolute;inset:0 0 0 50px;pointer-events:none;font-family:inherit;font-size:inherit;line-height:inherit;white-space:pre-wrap;word-wrap:break-word;overflow:hidden;z-index:5;background:transparent;color:transparent}.syntax-html-tag{color:#569cd6!important}.syntax-html-comment{color:#6a9955!important}.syntax-html-attr-value{color:#ce9178!important}.dark .syntax-html-tag{color:#569cd6!important}.dark .syntax-html-comment{color:#6a9955!important}.dark .syntax-html-attr-value{color:#ce9178!important}.light .syntax-html-tag{color:#00f!important}.light .syntax-html-comment{color:green!important}.light .syntax-html-attr-value{color:#a31515!important}.rte-light-editor.dark{background:#1e1e1e;color:#d4d4d4;border-color:#3e3e3e}.rte-light-editor.dark .rte-light-editor-content{background:#1e1e1e;color:#d4d4d4}.rte-light-editor.light{background:#fff;color:#000;border-color:#e0e0e0}.rte-light-editor.light .rte-light-editor-content{background:#fff;color:#000}.rte-light-editor.readonly .rte-light-editor-content{cursor:not-allowed;opacity:.7}.rte-light-editor.readonly .rte-light-editor-content:after{content:"";position:absolute;inset:0;background:#ffffff1a;pointer-events:none}.rte-light-editor.focused{border-color:#007acc;box-shadow:0 0 0 2px #007acc33}.rte-light-editor-content::selection{background:#007acc33}.rte-light-editor.dark .rte-light-editor-content::selection{background:#007acc4d}.rte-light-editor-content::-webkit-scrollbar{width:12px;height:12px}.rte-light-editor-content::-webkit-scrollbar-track{background:#f1f1f1}.rte-light-editor.dark .rte-light-editor-content::-webkit-scrollbar-track{background:#2d2d2d}.rte-light-editor-content::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:6px}.rte-light-editor.dark .rte-light-editor-content::-webkit-scrollbar-thumb{background:#555}.rte-light-editor-content::-webkit-scrollbar-thumb:hover{background:#a8a8a8}.rte-light-editor.dark .rte-light-editor-content::-webkit-scrollbar-thumb:hover{background:#666}.bracket-match{background:#007acc1a;border-radius:2px}.dark .bracket-match{background:#007acc33}.search-match{background:#ffff004d;border-radius:2px}.search-match.current{background:#ff09;border:1px solid #ffcc00}.fold-indicator{position:absolute;left:35px;width:12px;height:12px;cursor:pointer;opacity:.5;transition:opacity .2s}.fold-indicator:hover{opacity:1}.fold-indicator.expanded:before{content:"▼";font-size:10px;color:#666}.fold-indicator.collapsed:before{content:"▶";font-size:10px;color:#666}.dark .fold-indicator.expanded:before,.dark .fold-indicator.collapsed:before{color:#999}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@editora/light-code-editor",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Lightweight, extensible code editor library inspired by CodeMirror",
|
|
5
|
+
"authors": [
|
|
6
|
+
"Ajay Kumar <ajaykr089@gmail.com>"
|
|
7
|
+
],
|
|
8
|
+
"main": "dist/index.umd.js",
|
|
9
|
+
"module": "dist/index.es.js",
|
|
10
|
+
"types": "dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.es.js",
|
|
14
|
+
"require": "./dist/index.umd.js",
|
|
15
|
+
"types": "./dist/index.d.ts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "vite build",
|
|
23
|
+
"dev": "vite build --watch",
|
|
24
|
+
"clean": "rm -rf dist"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"code-editor",
|
|
28
|
+
"codemirror",
|
|
29
|
+
"lightweight",
|
|
30
|
+
"extensible",
|
|
31
|
+
"typescript"
|
|
32
|
+
],
|
|
33
|
+
"author": "Ajay Kumar <ajaykr089@gmail.com>",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/react": "^18.0.0",
|
|
37
|
+
"typescript": "^5.0.0",
|
|
38
|
+
"vite": "^7.3.1"
|
|
39
|
+
},
|
|
40
|
+
"gitHead": "694494db58b809f0dcf24501696284faa1ab68a5"
|
|
41
|
+
}
|