kempo-ui 0.3.8 → 0.3.10
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/dist/components/CodeEditor.js +96 -0
- package/dist/components/HtmlEditor.js +155 -30
- package/dist/components/codeEditorControls/CodeEditorControl.js +17 -0
- package/dist/components/codeEditorControls/ControlGroup.js +12 -0
- package/dist/components/codeEditorControls/ControlSpacer.js +6 -0
- package/dist/components/codeEditorControls/CopyCode.js +9 -0
- package/dist/components/codeEditorControls/EditorTheme.js +26 -0
- package/dist/components/codeEditorControls/FindReplace.js +7 -0
- package/dist/components/codeEditorControls/FoldAll.js +7 -0
- package/dist/components/codeEditorControls/FontSize.js +13 -0
- package/dist/components/codeEditorControls/FormatCode.js +9 -0
- package/dist/components/codeEditorControls/Fullscreen.js +12 -0
- package/dist/components/codeEditorControls/LanguageSelect.js +15 -0
- package/dist/components/codeEditorControls/Minimap.js +8 -0
- package/dist/components/codeEditorControls/Redo.js +7 -0
- package/dist/components/codeEditorControls/Undo.js +7 -0
- package/dist/components/codeEditorControls/WordWrap.js +8 -0
- package/dist/components/htmlEditorControls/AlignCenter.js +4 -4
- package/dist/components/htmlEditorControls/AlignJustify.js +4 -4
- package/dist/components/htmlEditorControls/AlignLeft.js +4 -4
- package/dist/components/htmlEditorControls/AlignRight.js +4 -4
- package/dist/components/htmlEditorControls/Bold.js +4 -4
- package/dist/components/htmlEditorControls/BulletList.js +4 -4
- package/dist/components/htmlEditorControls/ClearFormatting.js +4 -4
- package/dist/components/htmlEditorControls/CodeBlock.js +2 -2
- package/dist/components/htmlEditorControls/ControlGroup.js +2 -4
- package/dist/components/htmlEditorControls/CreateLink.js +3 -3
- package/dist/components/htmlEditorControls/FormatBlock.js +4 -4
- package/dist/components/htmlEditorControls/FormatCode.js +1 -0
- package/dist/components/htmlEditorControls/HtmlEditorControl.js +2 -2
- package/dist/components/htmlEditorControls/InlineCode.js +2 -2
- package/dist/components/htmlEditorControls/InsertTable.js +3 -3
- package/dist/components/htmlEditorControls/Italic.js +4 -4
- package/dist/components/htmlEditorControls/Mode.js +3 -3
- package/dist/components/htmlEditorControls/NumberList.js +4 -4
- package/dist/components/htmlEditorControls/Strikethrough.js +4 -4
- package/dist/components/htmlEditorControls/TextBackgroundColor.js +1 -1
- package/dist/components/htmlEditorControls/TextColor.js +1 -1
- package/dist/components/htmlEditorControls/Underline.js +4 -4
- package/docs/components/accordion.html +2 -0
- package/docs/components/aside.html +2 -0
- package/docs/components/card.html +2 -0
- package/docs/components/code-editor.html +491 -0
- package/docs/components/color-picker.html +2 -0
- package/docs/components/content-slider.html +2 -0
- package/docs/components/context.html +2 -0
- package/docs/components/dialog.html +2 -0
- package/docs/components/dropdown.html +2 -0
- package/docs/components/filter-list.html +2 -0
- package/docs/components/focus-capture.html +2 -0
- package/docs/components/html-editor.html +525 -212
- package/docs/components/hybrid-component.html +2 -0
- package/docs/components/icon.html +2 -0
- package/docs/components/import.html +2 -0
- package/docs/components/light-component.html +2 -0
- package/docs/components/nav-spacer.html +2 -0
- package/docs/components/nav.html +2 -0
- package/docs/components/photo-viewer.html +2 -0
- package/docs/components/resize.html +2 -0
- package/docs/components/shadow-component.html +2 -0
- package/docs/components/show-more.html +2 -0
- package/docs/components/sortable.html +2 -0
- package/docs/components/spinner.html +2 -0
- package/docs/components/split.html +2 -0
- package/docs/components/table.html +2 -0
- package/docs/components/tableControls.html +2 -0
- package/docs/components/tableCustomFields.html +2 -0
- package/docs/components/tableFetchRecords.html +2 -0
- package/docs/components/tableFieldSortHide.html +2 -0
- package/docs/components/tablePagination.html +2 -0
- package/docs/components/tablePlaceholder.html +2 -0
- package/docs/components/tableRecordEditing.html +2 -0
- package/docs/components/tableRecordFiltering.html +2 -0
- package/docs/components/tableRecordHiding.html +2 -0
- package/docs/components/tableRecordSearching.html +2 -0
- package/docs/components/tableRecordSelection.html +2 -0
- package/docs/components/tableRowControls.html +2 -0
- package/docs/components/tableServerSync.html +2 -0
- package/docs/components/tableSorting.html +2 -0
- package/docs/components/tabs.html +2 -0
- package/docs/components/tags.html +2 -0
- package/docs/components/theme-select.html +2 -0
- package/docs/components/theme-switcher.html +2 -0
- package/docs/components/timestamp.html +2 -0
- package/docs/components/toast.html +2 -0
- package/docs/components/toggle.html +2 -0
- package/docs/components/tree.html +2 -0
- package/docs/icons/auto_fix_high.svg +1 -0
- package/docs/icons/content_copy.svg +1 -0
- package/docs/icons/contrast.svg +1 -0
- package/docs/icons/frame_source.svg +1 -0
- package/docs/icons/fullscreen.svg +1 -0
- package/docs/icons/fullscreen_exit.svg +1 -0
- package/docs/icons/map.svg +1 -0
- package/docs/icons/redo.svg +1 -0
- package/docs/icons/text_decrease.svg +1 -0
- package/docs/icons/text_increase.svg +1 -0
- package/docs/icons/undo.svg +1 -0
- package/docs/icons/unfold_less.svg +1 -0
- package/docs/icons/unfold_more.svg +1 -0
- package/docs/icons/wrap_text.svg +1 -0
- package/docs/index.html +8 -0
- package/docs/src/components/CodeEditor.js +96 -0
- package/docs/src/components/HtmlEditor.js +155 -30
- package/docs/src/components/codeEditorControls/CodeEditorControl.js +17 -0
- package/docs/src/components/codeEditorControls/ControlGroup.js +12 -0
- package/docs/src/components/codeEditorControls/ControlSpacer.js +6 -0
- package/docs/src/components/codeEditorControls/CopyCode.js +9 -0
- package/docs/src/components/codeEditorControls/EditorTheme.js +26 -0
- package/docs/src/components/codeEditorControls/FindReplace.js +7 -0
- package/docs/src/components/codeEditorControls/FoldAll.js +7 -0
- package/docs/src/components/codeEditorControls/FontSize.js +13 -0
- package/docs/src/components/codeEditorControls/FormatCode.js +9 -0
- package/docs/src/components/codeEditorControls/Fullscreen.js +12 -0
- package/docs/src/components/codeEditorControls/LanguageSelect.js +15 -0
- package/docs/src/components/codeEditorControls/Minimap.js +8 -0
- package/docs/src/components/codeEditorControls/Redo.js +7 -0
- package/docs/src/components/codeEditorControls/Undo.js +7 -0
- package/docs/src/components/codeEditorControls/WordWrap.js +8 -0
- package/docs/src/components/htmlEditorControls/AlignCenter.js +4 -4
- package/docs/src/components/htmlEditorControls/AlignJustify.js +4 -4
- package/docs/src/components/htmlEditorControls/AlignLeft.js +4 -4
- package/docs/src/components/htmlEditorControls/AlignRight.js +4 -4
- package/docs/src/components/htmlEditorControls/Bold.js +4 -4
- package/docs/src/components/htmlEditorControls/BulletList.js +4 -4
- package/docs/src/components/htmlEditorControls/ClearFormatting.js +4 -4
- package/docs/src/components/htmlEditorControls/CodeBlock.js +2 -2
- package/docs/src/components/htmlEditorControls/ControlGroup.js +2 -4
- package/docs/src/components/htmlEditorControls/CreateLink.js +3 -3
- package/docs/src/components/htmlEditorControls/FormatBlock.js +4 -4
- package/docs/src/components/htmlEditorControls/FormatCode.js +1 -0
- package/docs/src/components/htmlEditorControls/HtmlEditorControl.js +2 -2
- package/docs/src/components/htmlEditorControls/InlineCode.js +2 -2
- package/docs/src/components/htmlEditorControls/InsertTable.js +3 -3
- package/docs/src/components/htmlEditorControls/Italic.js +4 -4
- package/docs/src/components/htmlEditorControls/Mode.js +3 -3
- package/docs/src/components/htmlEditorControls/NumberList.js +4 -4
- package/docs/src/components/htmlEditorControls/Strikethrough.js +4 -4
- package/docs/src/components/htmlEditorControls/TextBackgroundColor.js +1 -1
- package/docs/src/components/htmlEditorControls/TextColor.js +1 -1
- package/docs/src/components/htmlEditorControls/Underline.js +4 -4
- package/docs/utils/context.html +2 -0
- package/docs/utils/cookie.html +2 -0
- package/docs/utils/debounce.html +2 -0
- package/docs/utils/drag.html +2 -0
- package/docs/utils/elevation.html +2 -0
- package/docs/utils/formatTimestamp.html +2 -0
- package/docs/utils/object.html +2 -0
- package/docs/utils/propConverters.html +2 -0
- package/docs/utils/string.html +2 -0
- package/docs/utils/theme.html +2 -0
- package/docs/utils/toTitleCase.html +2 -0
- package/docs/utils/type.html +2 -0
- package/docs/utils/wait.html +2 -0
- package/docs-src/components/code-editor.page.html +235 -0
- package/docs-src/components/html-editor.page.html +528 -214
- package/docs-src/index.page.html +6 -0
- package/docs-src/nav.fragment.html +2 -0
- package/icons/auto_fix_high.svg +1 -0
- package/icons/content_copy.svg +1 -0
- package/icons/contrast.svg +1 -0
- package/icons/frame_source.svg +1 -0
- package/icons/fullscreen.svg +1 -0
- package/icons/fullscreen_exit.svg +1 -0
- package/icons/map.svg +1 -0
- package/icons/redo.svg +1 -0
- package/icons/text_decrease.svg +1 -0
- package/icons/text_increase.svg +1 -0
- package/icons/undo.svg +1 -0
- package/icons/unfold_less.svg +1 -0
- package/icons/unfold_more.svg +1 -0
- package/icons/wrap_text.svg +1 -0
- package/llm.txt +2 -1
- package/package.json +3 -3
- package/src/components/CodeEditor.js +495 -0
- package/src/components/HtmlEditor.js +527 -152
- package/src/components/codeEditorControls/CodeEditorControl.js +134 -0
- package/src/components/codeEditorControls/ControlGroup.js +70 -0
- package/src/components/codeEditorControls/ControlSpacer.js +23 -0
- package/src/components/codeEditorControls/CopyCode.js +37 -0
- package/src/components/codeEditorControls/EditorTheme.js +81 -0
- package/src/components/codeEditorControls/FindReplace.js +35 -0
- package/src/components/codeEditorControls/FoldAll.js +49 -0
- package/src/components/codeEditorControls/FontSize.js +45 -0
- package/src/components/codeEditorControls/FormatCode.js +37 -0
- package/src/components/codeEditorControls/Fullscreen.js +72 -0
- package/src/components/codeEditorControls/LanguageSelect.js +74 -0
- package/src/components/codeEditorControls/Minimap.js +60 -0
- package/src/components/codeEditorControls/Redo.js +35 -0
- package/src/components/codeEditorControls/Undo.js +35 -0
- package/src/components/codeEditorControls/WordWrap.js +60 -0
- package/src/components/htmlEditorControls/AlignCenter.js +2 -4
- package/src/components/htmlEditorControls/AlignJustify.js +2 -4
- package/src/components/htmlEditorControls/AlignLeft.js +2 -4
- package/src/components/htmlEditorControls/AlignRight.js +2 -4
- package/src/components/htmlEditorControls/Bold.js +2 -4
- package/src/components/htmlEditorControls/BulletList.js +2 -4
- package/src/components/htmlEditorControls/ClearFormatting.js +2 -4
- package/src/components/htmlEditorControls/CodeBlock.js +3 -19
- package/src/components/htmlEditorControls/ControlGroup.js +16 -41
- package/src/components/htmlEditorControls/CreateLink.js +3 -5
- package/src/components/htmlEditorControls/FormatBlock.js +2 -4
- package/src/components/htmlEditorControls/FormatCode.js +7 -0
- package/src/components/htmlEditorControls/HtmlEditorControl.js +43 -5
- package/src/components/htmlEditorControls/InlineCode.js +3 -5
- package/src/components/htmlEditorControls/InsertTable.js +9 -53
- package/src/components/htmlEditorControls/Italic.js +2 -4
- package/src/components/htmlEditorControls/Mode.js +2 -0
- package/src/components/htmlEditorControls/NumberList.js +2 -4
- package/src/components/htmlEditorControls/Strikethrough.js +2 -4
- package/src/components/htmlEditorControls/TextBackgroundColor.js +0 -6
- package/src/components/htmlEditorControls/TextColor.js +0 -6
- package/src/components/htmlEditorControls/Underline.js +2 -4
- package/tests/components/CodeEditor.browser-test.js +297 -0
- package/tests/components/HtmlEditor.browser-test.js +207 -0
- package/tests/components/codeEditorControls/CopyCode.browser-test.js +57 -0
- package/tests/components/codeEditorControls/EditorTheme.browser-test.js +70 -0
- package/tests/components/codeEditorControls/FindReplace.browser-test.js +57 -0
- package/tests/components/codeEditorControls/FoldAll.browser-test.js +92 -0
- package/tests/components/codeEditorControls/FontSize.browser-test.js +74 -0
- package/tests/components/codeEditorControls/Fullscreen.browser-test.js +152 -0
- package/tests/components/codeEditorControls/LanguageSelect.browser-test.js +82 -0
- package/tests/components/codeEditorControls/Minimap.browser-test.js +84 -0
- package/tests/components/codeEditorControls/ModeVisibility.browser-test.js +82 -0
- package/tests/components/codeEditorControls/UndoRedo.browser-test.js +85 -0
- package/tests/components/codeEditorControls/WordWrap.browser-test.js +95 -0
- package/tests/components/htmlEditorControls/Align.browser-test.js +203 -0
- package/tests/components/htmlEditorControls/Bold.browser-test.js +127 -0
- package/tests/components/htmlEditorControls/BulletList.browser-test.js +127 -0
- package/tests/components/htmlEditorControls/CharacterCount.browser-test.js +106 -0
- package/tests/components/htmlEditorControls/ClearFormatting.browser-test.js +127 -0
- package/tests/components/htmlEditorControls/CodeBlock.browser-test.js +143 -0
- package/tests/components/htmlEditorControls/ControlGroup.browser-test.js +116 -0
- package/tests/components/htmlEditorControls/ControlSpacer.browser-test.js +69 -0
- package/tests/components/htmlEditorControls/CreateLink.browser-test.js +129 -0
- package/tests/components/htmlEditorControls/DropdownControl.browser-test.js +138 -0
- package/tests/components/htmlEditorControls/FormatBlock.browser-test.js +163 -0
- package/tests/components/htmlEditorControls/FormatCode.browser-test.js +155 -0
- package/tests/components/htmlEditorControls/InlineCode.browser-test.js +127 -0
- package/tests/components/htmlEditorControls/InsertTable.browser-test.js +129 -0
- package/tests/components/htmlEditorControls/Italic.browser-test.js +127 -0
- package/tests/components/htmlEditorControls/Mode.browser-test.js +138 -0
- package/tests/components/htmlEditorControls/NumberList.browser-test.js +127 -0
- package/tests/components/htmlEditorControls/Strikethrough.browser-test.js +127 -0
- package/tests/components/htmlEditorControls/TextBackgroundColor.browser-test.js +136 -0
- package/tests/components/htmlEditorControls/TextColor.browser-test.js +136 -0
- package/tests/components/htmlEditorControls/Underline.browser-test.js +127 -0
- package/tests/components/htmlEditorControls/WordCount.browser-test.js +106 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import{html as t,css as e}from"../lit-all.min.js";import o from"./ShadowComponent.js";import i from"../utils/formatCode.js";import{getCalculatedTheme as s,subscribeToTheme as r}from"../utils/theme.js";export default class a extends o{static formAssociated=!0;static properties={name:{type:String,reflect:!0},value:{type:String,reflect:!0},language:{type:String,reflect:!0},monacoSrc:{type:String,attribute:"monaco-src"},controls:{type:String,reflect:!0},editorTheme:{type:String,attribute:"editor-theme",reflect:!0},hasTopToolbar:{type:Boolean,state:!0},hasBottomToolbar:{type:Boolean,state:!0},fullscreen:{type:Boolean,reflect:!0},wordWrap:{type:Boolean},minimapEnabled:{type:Boolean}};constructor(){super(),this.internals=this.attachInternals(),this.name="",this.value="",this.language="javascript",this.monacoSrc="",this.controls="",this.controlsLoaded=!1,this.hasTopToolbar=!1,this.hasBottomToolbar=!1,this.monacoEditor=null,this.skipValueSync=!1,this.editorTheme="auto",this.wordWrap=!0,this.minimapEnabled=!1,this.fontSize=14,this.fullscreen=!1}connectedCallback(){super.connectedCallback(),this.hasAttribute("value")&&(this.value=this.getAttribute("value")),this.slotObserver=new MutationObserver(()=>this.updateToolbarVisibility()),this.slotObserver.observe(this,{childList:!0,subtree:!0}),this.updateToolbarVisibility()}disconnectedCallback(){super.disconnectedCallback(),this.slotObserver?.disconnect(),this.monacoEditor?.dispose(),this.unsubscribeTheme?.(),this.fullscreen&&this.exitFullscreen()}updateToolbarVisibility(){const t=new Set(Array.from(this.children).map(t=>t.getAttribute("slot"))),e=this.constructor.controlSets[this.controls]??null;this.hasTopToolbar=!(!e?.topLeft&&!e?.topRight)||["toolbar-top","toolbar-top-left","toolbar-top-right"].some(e=>t.has(e)),this.hasBottomToolbar=!(!e?.bottomLeft&&!e?.bottomRight)||["toolbar-bottom","toolbar-bottom-left","toolbar-bottom-right"].some(e=>t.has(e))}updated(t){if(super.updated(t),t.has("controls")&&(this.updateToolbarVisibility(),this.controls&&"none"!==this.controls&&this.loadControls()),t.has("value")&&!this.skipValueSync&&(this.monacoEditor&&this.monacoEditor.getValue()!==this.value&&this.monacoEditor.setValue(this.value),this.updateFormValue(),this.dispatchEvent(new CustomEvent("change",{detail:{value:this.value},bubbles:!0}))),t.has("language")&&this.monacoEditor){const t=this.monacoEditor.getModel();t&&window.monaco.editor.setModelLanguage(t,this.language),this.dispatchEvent(new CustomEvent("language-changed",{detail:{language:this.language},bubbles:!0}))}t.has("editorTheme")&&this.monacoEditor&&(window.monaco.editor.setTheme(this.resolveMonacoTheme()),this.dispatchEvent(new CustomEvent("editor-theme-changed",{detail:{editorTheme:this.editorTheme},bubbles:!0}))),t.has("wordWrap")&&(this.monacoEditor?.updateOptions({wordWrap:this.wordWrap?"on":"off"}),this.dispatchEvent(new CustomEvent("word-wrap-changed",{detail:{wordWrap:this.wordWrap},bubbles:!0}))),t.has("minimapEnabled")&&(this.monacoEditor?.updateOptions({minimap:{enabled:this.minimapEnabled}}),this.dispatchEvent(new CustomEvent("minimap-changed",{detail:{minimapEnabled:this.minimapEnabled},bubbles:!0}))),t.has("fullscreen")&&(this.fullscreen||this.monacoEditor?.layout({width:0,height:0}),requestAnimationFrame(()=>this.monacoEditor?.layout()))}async firstUpdated(){this.monacoContainer=this.shadowRoot.querySelector(".monaco-editor-container"),await this.initMonaco(),this.dispatchEvent(new CustomEvent("ready",{detail:{value:this.value},bubbles:!0}))}async loadControls(){if(this.controlsLoaded)return;this.controlsLoaded=!0;const t=new URL("./codeEditorControls/",import.meta.url).href;await Promise.all([import(`${t}FormatCode.js`),import(`${t}CopyCode.js`),import(`${t}EditorTheme.js`),import(`${t}Undo.js`),import(`${t}Redo.js`),import(`${t}WordWrap.js`),import(`${t}Minimap.js`),import(`${t}FindReplace.js`),import(`${t}FontSize.js`),import(`${t}FoldAll.js`),import(`${t}LanguageSelect.js`),import(`${t}Fullscreen.js`),import(`${t}ControlGroup.js`),import(`${t}ControlSpacer.js`)]),this.requestUpdate()}async initMonaco(){if(!this.monacoEditor){if(this.monacoInitPromise)return this.monacoInitPromise;this.monacoInitPromise=this._initMonaco(),await this.monacoInitPromise,this.monacoInitPromise=null}}async _initMonaco(){const t=this.monacoSrc||window.kempo?.monacoUrl||"https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min";await new Promise((e,o)=>{if(window.monaco)return void e();if(window.require?.defined?.("vs/editor/editor.main"))return void e();const i=document.querySelector(`script[src="${t}/vs/loader.js"]`);if(i)return void i.addEventListener("load",()=>{window.require.config({paths:{vs:`${t}/vs`}}),window.require(["vs/editor/editor.main"],()=>e(),o)});const s=document.createElement("script");s.src=`${t}/vs/loader.js`,s.onload=()=>{window.require.config({paths:{vs:`${t}/vs`}}),window.require(["vs/editor/editor.main"],()=>e(),o)},s.onerror=o,document.head.appendChild(s)}),this.monacoEditor=window.monaco.editor.create(this.monacoContainer,{value:this.value,language:this.language,theme:this.resolveMonacoTheme(),minimap:{enabled:!1},wordWrap:"on",fontSize:14,scrollBeyondLastLine:!1,automaticLayout:!0,tabSize:2,padding:{top:8}});const e=document.querySelector('link[href*="monaco"][href*="editor.main.css"]');if(e){const t=document.createElement("link");t.rel="stylesheet",t.href=e.href,this.shadowRoot.appendChild(t)}this.unsubscribeTheme=r(()=>{this.monacoEditor&&"auto"===this.editorTheme&&window.monaco.editor.setTheme(this.resolveMonacoTheme())}),this.monacoEditor.onDidChangeModelContent(()=>{this.skipValueSync=!0,this.value=this.monacoEditor.getValue(),this.skipValueSync=!1,this.updateFormValue(),this.dispatchEvent(new CustomEvent("change",{detail:{value:this.value},bubbles:!0})),this.dispatchEvent(new CustomEvent("input",{detail:{value:this.value},bubbles:!0}))})}updateFormValue(){this.internals.setFormValue(this.getValue())}formResetCallback(){this.value=""}formStateRestoreCallback(t){this.value=t}getValue(){return this.monacoEditor?this.monacoEditor.getValue():this.value}setValue(t){return this.skipValueSync=!0,this.value=t,this.monacoEditor&&this.monacoEditor.setValue(t),this.updateFormValue(),this.skipValueSync=!1,this}clear(){return this.setValue("")}formatCode(){return this.monacoEditor?.getAction("editor.action.formatDocument")?.run(),this}selectAll(){if(!this.monacoEditor)return this;const t=this.monacoEditor.getModel();return t&&this.monacoEditor.setSelection(t.getFullModelRange()),this}getSelectedText(){return this.monacoEditor&&this.monacoEditor.getModel()?.getValueInRange(this.monacoEditor.getSelection())||""}focus(){return this.monacoEditor?.focus(),this}setLanguage(t){return this.language=t,this}setEditorTheme(t){return["auto","light","dark"].includes(t)&&(this.editorTheme=t),this}copyToClipboard(){return navigator.clipboard.writeText(this.getValue()),this}undo(){return this.monacoEditor?.trigger("toolbar","undo"),this}redo(){return this.monacoEditor?.trigger("toolbar","redo"),this}setWordWrap(t){return this.wordWrap=t,this}setMinimap(t){return this.minimapEnabled=t,this}toggleWordWrap(){return this.setWordWrap(!this.wordWrap)}toggleMinimap(){return this.setMinimap(!this.minimapEnabled)}openFind(){return this.monacoEditor?.getAction("actions.find")?.run(),this}increaseFontSize(){return this.fontSize=Math.min(this.fontSize+2,40),this.monacoEditor?.updateOptions({fontSize:this.fontSize}),this}decreaseFontSize(){return this.fontSize=Math.max(this.fontSize-2,8),this.monacoEditor?.updateOptions({fontSize:this.fontSize}),this}foldAll(){return this.monacoEditor?.getAction("editor.foldAll")?.run(),this}unfoldAll(){return this.monacoEditor?.getAction("editor.unfoldAll")?.run(),this}enterFullscreen(){return this.fullscreen=!0,document.body.classList.add("no-scroll"),this.dispatchEvent(new CustomEvent("fullscreen-changed",{detail:{fullscreen:!0},bubbles:!0})),this}exitFullscreen(){return this.fullscreen=!1,document.body.classList.remove("no-scroll"),this.dispatchEvent(new CustomEvent("fullscreen-changed",{detail:{fullscreen:!1},bubbles:!0})),this}toggleFullscreen(){return this.fullscreen?this.exitFullscreen():this.enterFullscreen()}resolveMonacoTheme(){return"dark"===this.editorTheme?"vs-dark":"light"===this.editorTheme?"vs":"dark"===s()?"vs-dark":"vs"}static controlSets={full:{topLeft:t`
|
|
2
|
+
<k-cec-group>
|
|
3
|
+
<k-cec-undo></k-cec-undo>
|
|
4
|
+
<k-cec-redo></k-cec-redo>
|
|
5
|
+
</k-cec-group>
|
|
6
|
+
<k-cec-group>
|
|
7
|
+
<k-cec-format-code></k-cec-format-code>
|
|
8
|
+
<k-cec-copy-code></k-cec-copy-code>
|
|
9
|
+
<k-cec-find-replace></k-cec-find-replace>
|
|
10
|
+
</k-cec-group>
|
|
11
|
+
<k-cec-group>
|
|
12
|
+
<k-cec-word-wrap></k-cec-word-wrap>
|
|
13
|
+
<k-cec-minimap></k-cec-minimap>
|
|
14
|
+
<k-cec-fold-all></k-cec-fold-all>
|
|
15
|
+
</k-cec-group>
|
|
16
|
+
<k-cec-font-size></k-cec-font-size>
|
|
17
|
+
`,topRight:t`
|
|
18
|
+
<k-cec-language></k-cec-language>
|
|
19
|
+
<k-cec-editor-theme></k-cec-editor-theme>
|
|
20
|
+
<k-cec-fullscreen></k-cec-fullscreen>
|
|
21
|
+
`,bottomLeft:null,bottomRight:null}};static styles=e`
|
|
22
|
+
:host {
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
gap: 0;
|
|
26
|
+
height: 400px;
|
|
27
|
+
background: var(--c_bg);
|
|
28
|
+
}
|
|
29
|
+
:host([fullscreen]) {
|
|
30
|
+
position: fixed;
|
|
31
|
+
top: 0;
|
|
32
|
+
left: 0;
|
|
33
|
+
width: 100vw;
|
|
34
|
+
height: 100vh;
|
|
35
|
+
z-index: 10000;
|
|
36
|
+
}
|
|
37
|
+
.toolbar-top,
|
|
38
|
+
.toolbar-bottom {
|
|
39
|
+
display: flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
background: var(--bg-secondary);
|
|
42
|
+
min-height: 40px;
|
|
43
|
+
}
|
|
44
|
+
.toolbar-start {
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-wrap: wrap;
|
|
47
|
+
align-items: center;
|
|
48
|
+
}
|
|
49
|
+
.toolbar-end {
|
|
50
|
+
display: flex;
|
|
51
|
+
flex-wrap: wrap-reverse;
|
|
52
|
+
align-items: center;
|
|
53
|
+
justify-content: flex-end;
|
|
54
|
+
margin-left: auto;
|
|
55
|
+
}
|
|
56
|
+
.editor-container {
|
|
57
|
+
position: relative;
|
|
58
|
+
flex: 1;
|
|
59
|
+
min-height: 0;
|
|
60
|
+
overflow: hidden;
|
|
61
|
+
}
|
|
62
|
+
.monaco-editor-container {
|
|
63
|
+
width: 100%;
|
|
64
|
+
height: 100%;
|
|
65
|
+
box-sizing: border-box;
|
|
66
|
+
overflow: auto;
|
|
67
|
+
border: 1px solid var(--border-color);
|
|
68
|
+
}
|
|
69
|
+
[hidden] {
|
|
70
|
+
display: none !important;
|
|
71
|
+
}
|
|
72
|
+
`;render(){const e=this.constructor.controlSets[this.controls]??{};return t`
|
|
73
|
+
${this.hasTopToolbar?t`
|
|
74
|
+
<div class="toolbar-top bb">
|
|
75
|
+
<div class="toolbar-start">
|
|
76
|
+
<slot name="toolbar-top-left">${e.topLeft??""}</slot>
|
|
77
|
+
</div>
|
|
78
|
+
<div class="toolbar-end">
|
|
79
|
+
<slot name="toolbar-top-right">${e.topRight??""}</slot>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
`:""}
|
|
83
|
+
<div class="editor-container">
|
|
84
|
+
<div class="monaco-editor-container"></div>
|
|
85
|
+
</div>
|
|
86
|
+
${this.hasBottomToolbar?t`
|
|
87
|
+
<div class="toolbar-bottom bt">
|
|
88
|
+
<div class="toolbar-start">
|
|
89
|
+
<slot name="toolbar-bottom-left">${e.bottomLeft??""}</slot>
|
|
90
|
+
</div>
|
|
91
|
+
<div class="toolbar-end">
|
|
92
|
+
<slot name="toolbar-bottom-right">${e.bottomRight??""}</slot>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
`:""}
|
|
96
|
+
`}}customElements.define("k-code-editor",a);
|
|
@@ -1,18 +1,70 @@
|
|
|
1
|
-
import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponent.js";import o from"../utils/formatCode.js";import l from"../utils/debounce.js";import{getCalculatedTheme as s,subscribeToTheme as r}from"../utils/theme.js";import a from"./Dialog.js";export default class n extends i{static formAssociated=!0;static properties={name:{type:String,reflect:!0},value:{type:String,reflect:!0},selection:{type:Object,state:!0},mode:{type:String,reflect:!0},lexicalSrc:{type:String,attribute:"lexical-src"},monacoSrc:{type:String,attribute:"monaco-src"},nodes:{type:String},hasTopToolbar:{type:Boolean,state:!0},hasBottomToolbar:{type:Boolean,state:!0}};constructor(){super(),this.internals=this.attachInternals(),this.name="",this.value="",this.selection=null,this.cursor=null,this.mode="visual",this.lexicalSrc="",this.monacoSrc="",this.nodes="",this.hasTopToolbar=!1,this.hasBottomToolbar=!1,this.skipValueSync=!1,this.lexicalValueSync=!1,this.savedSelection=null,this.lexicalEditor=null,this.monacoEditor=null,this.lx={},this.debouncedSyncValue=l(()=>this.syncValueFromLexical(),300)}connectedCallback(){super.connectedCallback(),this.hasAttribute("value")&&(this.value=this.getAttribute("value")),this.slotObserver=new MutationObserver(()=>this.updateToolbarVisibility()),this.slotObserver.observe(this,{childList:!0,subtree:!0}),this.updateToolbarVisibility()}disconnectedCallback(){super.disconnectedCallback(),this.slotObserver?.disconnect(),this.cleanupFns?.forEach(e=>e?.()),this.monacoEditor?.dispose(),this.unsubscribeTheme?.(),this.syncShadowSelection&&document.removeEventListener("selectionchange",this.syncShadowSelection)}updateToolbarVisibility(){this.hasTopToolbar=Array.from(this.children).some(e=>"toolbar-top"===e.getAttribute("slot")),this.hasBottomToolbar=Array.from(this.children).some(e=>"toolbar-bottom"===e.getAttribute("slot"))}updated(e){super.updated(e),e.has("value")&&!this.skipValueSync&&(this.lexicalValueSync?this.lexicalValueSync=!1:this.lexicalEditor&&"visual"===this.mode&&!this.isVisualCompatible(this.value)?(this.skipLexicalExport=!0,this.mode="code"):this.syncContentToEditors(),this.updateFormValue(),this.dispatchEvent(new CustomEvent("change",{detail:{value:this.value},bubbles:!0}))),e.has("mode")&&(this.handleModeSwitch(e.get("mode")),this.dispatchEvent(new CustomEvent("mode-changed",{detail:{mode:this.mode},bubbles:!0})))}async firstUpdated(){this.lexicalContainer=this.shadowRoot.querySelector(".lexical-editor"),this.monacoContainer=this.shadowRoot.querySelector(".monaco-editor-container"),await this.initLexical(),this.dispatchEvent(new CustomEvent("ready",{detail:{value:this.value},bubbles:!0}))}async loadNodeModules(){if(!this.nodes?.trim())return[];const e=new URL("./htmlEditorNodes/",import.meta.url).href;return(await Promise.all(this.nodes.split(",").map(e=>e.trim()).filter(Boolean).map(t=>import(`${e}${t}.js`)))).map(e=>e.default?.lexicalNode).filter(Boolean)}async loadLexicalModules(){const e=this.lexicalSrc||"https://esm.sh",t=t=>((e,t)=>`${e}/${t}@0.43.0`)(e,t),[i,o,l,s,r,a,n,c,d]=await Promise.all([import(t("lexical")),import(t("@lexical/rich-text")),import(t("@lexical/html")),import(t("@lexical/history")),import(t("@lexical/list")),import(t("@lexical/link")),import(t("@lexical/selection")),import(t("@lexical/table")),import(t("@lexical/code"))]);this.lx={lexical:i,richText:o,lexicalHtml:l,history:s,list:r,link:a,selection:n,table:c,code:d},this.StyledTextNode=class extends i.TextNode{static getType(){return"styled-text"}static clone(e){return new this(e.__text,e.__key)}static importDOM(){return{span:()=>({conversion:e=>{const t=e.getAttribute("style");if(!t)return null;const o=i.$createTextNode(e.textContent);return o.setStyle(t),{node:o}},priority:1})}}static importJSON(e){return i.$createTextNode(e.text)}exportJSON(){return{...super.exportJSON(),type:"styled-text"}}}}async initLexical(){await this.loadLexicalModules(),this.customNodes=await this.loadNodeModules(),this.nodeCompatCheckers=this.customNodes.filter(e=>"function"==typeof e.isVisualCompatible).map(e=>e.isVisualCompatible),this.nodePreprocessors=this.customNodes.filter(e=>"function"==typeof e.preprocessHtml).map(e=>e.preprocessHtml);const{lexical:e,richText:t,history:i,list:o,link:l,table:s,code:r}=this.lx,a={namespace:"KempoHtmlEditor",theme:{paragraph:"k-editor-p",heading:{h1:"k-editor-h1",h2:"k-editor-h2",h3:"k-editor-h3",h4:"k-editor-h4",h5:"k-editor-h5",h6:"k-editor-h6"},text:{underline:"td-u",strikethrough:"td-lt"},list:{ul:"k-editor-ul",ol:"k-editor-ol",listitem:"k-editor-li"},link:"k-editor-link",quote:"k-editor-quote",code:"k-editor-code-block",codeHighlight:{},table:"k-editor-table",tableCell:"k-editor-table-cell",tableCellHeader:"k-editor-table-cell-header"},nodes:[t.HeadingNode,t.QuoteNode,o.ListNode,o.ListItemNode,l.LinkNode,s.TableNode,s.TableCellNode,s.TableRowNode,r.CodeNode,r.CodeHighlightNode,this.StyledTextNode,...this.customNodes],onError:console.error,editorState:null};this.lexicalEditor=e.createEditor(a),this.lexicalEditor.setRootElement(this.lexicalContainer),this.cleanupFns=[t.registerRichText(this.lexicalEditor),i.registerHistory(this.lexicalEditor,i.createEmptyHistoryState(),300)],o.registerList&&this.cleanupFns.push(o.registerList(this.lexicalEditor)),s.registerTable&&this.cleanupFns.push(s.registerTable(this.lexicalEditor)),r.registerCodeHighlighting&&this.cleanupFns.push(r.registerCodeHighlighting(this.lexicalEditor)),l.registerLink&&this.cleanupFns.push(l.registerLink(this.lexicalEditor,{validateUrl:e=>{try{return new URL(e),!0}catch{return!1}}})),this.value&&(this.isVisualCompatible(this.value)?this.importHtmlToLexical(this.value):(this.skipLexicalExport=!0,this.mode="code")),this.lexicalEditor.registerUpdateListener(({dirtyElements:e,dirtyLeaves:t})=>{0===e.size&&0===t.size||(this.debouncedSyncValue(),this.dispatchEvent(new CustomEvent("input",{detail:{value:this.exportHtmlFromLexical()},bubbles:!0})))}),this.lexicalEditor.registerCommand(e.SELECTION_CHANGE_COMMAND,()=>(this.updateSelection(),!1),e.COMMAND_PRIORITY_LOW),this.syncShadowSelection=()=>{if("visual"!==this.mode||!this.lexicalEditor)return;const t=this.shadowRoot.getSelection?.();if(!t||0===t.rangeCount)return;const i=t.getRangeAt(0);this.lexicalContainer.contains(i.startContainer)&&(this.lexicalEditor.update(()=>{const i=e.$createRangeSelectionFromDom(t,this.lexicalEditor);i&&e.$setSelection(i)},{discrete:!0}),this.updateSelection())},document.addEventListener("selectionchange",this.syncShadowSelection)}async initMonaco(){if(!this.monacoEditor){if(this.monacoInitPromise)return this.monacoInitPromise;this.monacoInitPromise=this._initMonaco(),await this.monacoInitPromise,this.monacoInitPromise=null}}async _initMonaco(){const e=this.monacoSrc||"https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min";await new Promise((t,i)=>{if(window.monaco)return void t();if(window.require?.defined?.("vs/editor/editor.main"))return void t();const o=document.querySelector(`script[src="${e}/vs/loader.js"]`);if(o)return void o.addEventListener("load",()=>{window.require.config({paths:{vs:`${e}/vs`}}),window.require(["vs/editor/editor.main"],()=>t(),i)});const l=document.createElement("script");l.src=`${e}/vs/loader.js`,l.onload=()=>{window.require.config({paths:{vs:`${e}/vs`}}),window.require(["vs/editor/editor.main"],()=>t(),i)},l.onerror=i,document.head.appendChild(l)}),this.monacoEditor=window.monaco.editor.create(this.monacoContainer,{value:o(this.value),language:"html",theme:"dark"===s()?"vs-dark":"vs",minimap:{enabled:!1},wordWrap:"on",fontSize:14,scrollBeyondLastLine:!1,automaticLayout:!0,tabSize:2});const t=document.querySelector('link[href*="monaco"][href*="editor.main.css"]');if(t){const e=document.createElement("link");e.rel="stylesheet",e.href=t.href,this.shadowRoot.appendChild(e)}this.unsubscribeTheme=r(()=>{this.monacoEditor&&window.monaco.editor.setTheme("dark"===s()?"vs-dark":"vs")}),this.monacoEditor.onDidChangeModelContent(()=>{this.skipValueSync=!0,this.value=this.monacoEditor.getValue(),this.skipValueSync=!1,this.updateFormValue(),this.dispatchEvent(new CustomEvent("change",{detail:{value:this.value},bubbles:!0})),this.dispatchEvent(new CustomEvent("input",{detail:{value:this.value},bubbles:!0}))})}importHtmlToLexical(e){if(!this.lexicalEditor||!this.lx.lexicalHtml)return;const{lexical:t,lexicalHtml:i}=this.lx,o=(this.nodePreprocessors||[]).reduce((e,t)=>t(e),e);this.lexicalEditor.update(()=>{if(t.$getRoot().clear(),!o?.trim())return;const e=(new DOMParser).parseFromString(o,"text/html"),l=i.$generateNodesFromDOM(this.lexicalEditor,e);l.length>0&&t.$insertNodes(l)},{discrete:!0})}exportHtmlFromLexical(){if(!this.lexicalEditor||!this.lx.lexicalHtml)return this.value;let e="";return this.lexicalEditor.getEditorState().read(()=>{e=this.lx.lexicalHtml.$generateHtmlFromNodes(this.lexicalEditor,null)}),this.cleanExportedHtml(e)}isVisualCompatible(e){if(!e?.trim())return!0;const t=new Set(["script","style","meta","link","head","iframe","object","embed","canvas","video","audio","form","input","button","select","textarea","fieldset","label","noscript","template","slot","svg","math"]),i=this.nodeCompatCheckers||[],o=(new DOMParser).parseFromString(e,"text/html"),l=document.createTreeWalker(o.body,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT);let s;for(;s=l.nextNode();)if(!i.some(e=>e(s))){if(s.nodeType===Node.COMMENT_NODE)return!1;if(t.has(s.tagName?.toLowerCase()))return!1}return!0}cleanExportedHtml(e){const t=(new DOMParser).parseFromString(e,"text/html");return t.body.querySelectorAll("[class]").forEach(e=>{const t=Array.from(e.classList).filter(e=>!e.startsWith("k-editor-")&&"td-u"!==e&&"td-lt"!==e);0===t.length?e.removeAttribute("class"):e.className=t.join(" ")}),t.body.querySelectorAll("[style]").forEach(e=>{const t=e.style.cssText.replace(/white-space:\s*pre-wrap;?\s*/g,"").trim();t?e.style.cssText=t:e.removeAttribute("style")}),t.body.querySelectorAll("span:not([class]):not([style]):not([id])").forEach(e=>{e.attributes.length||e.replaceWith(...e.childNodes)}),t.body.querySelectorAll("b > strong, i > em, b > b, strong > strong, i > i, em > em").forEach(e=>{e.replaceWith(...e.childNodes)}),t.body.querySelectorAll("pre[data-highlight-language], code[data-highlight-language]").forEach(e=>{e.removeAttribute("data-highlight-language"),e.removeAttribute("data-language")}),t.body.innerHTML}syncValueFromLexical(){this.lexicalEditor&&(this.lexicalValueSync=!0,this.value=this.exportHtmlFromLexical(),this.updateFormValue())}syncContentToEditors(){"visual"===this.mode&&this.lexicalEditor&&this.importHtmlToLexical(this.value)}async handleModeSwitch(e){"code"===this.mode?(this.lexicalEditor&&!this.skipLexicalExport&&(this.value=this.exportHtmlFromLexical()),this.skipLexicalExport=!1,await this.initMonaco(),this.monacoEditor&&(this.monacoEditor.setValue(o(this.value)),this.monacoEditor.layout())):"visual"===this.mode&&(this.monacoEditor&&(this.value=this.monacoEditor.getValue()),this.lexicalEditor&&this.importHtmlToLexical(this.value)),this.requestUpdate()}updateFormValue(){this.internals.setFormValue(this.getValue())}formResetCallback(){this.value=""}formStateRestoreCallback(e){this.value=e}updateSelection=()=>{if("visual"!==this.mode||!this.lexicalEditor)return void(this.selection=null);const{lexical:e}=this.lx;this.lexicalEditor.getEditorState().read(()=>{const t=e.$getSelection();e.$isRangeSelection(t)&&!t.isCollapsed()?this.selection={text:t.getTextContent(),collapsed:!1}:(this.selection=null,this.cursor=t?{anchor:t.anchor,focus:t.focus}:null)})};setMode(e){return["visual","code"].includes(e)?"visual"!==e||this.isVisualCompatible(this.getValue())?(this.mode=e,this):(a.confirm("This html contains code that is not compatible with the visual editor, the incompatible code will be lost",t=>{t&&(this.mode=e)},{title:"Warning",confirmText:"Change Anyways"}),this):this}toggleMode(){return this.setMode("visual"===this.mode?"code":"visual")}getValue(){if("visual"===this.mode&&this.lexicalEditor)this.skipValueSync=!0,this.value=this.exportHtmlFromLexical(),this.skipValueSync=!1;else if("code"===this.mode&&this.monacoEditor)return this.monacoEditor.getValue();return this.value}setValue(e){return this.lexicalEditor&&"visual"===this.mode&&!this.isVisualCompatible(e)?(this.value=e,this.skipLexicalExport=!0,this.mode="code",this.updateFormValue(),this):(this.skipValueSync=!0,this.value=e,"visual"===this.mode?this.syncContentToEditors():"code"===this.mode&&this.monacoEditor&&this.monacoEditor.setValue(o(e)),this.updateFormValue(),this.skipValueSync=!1,this)}clear(){return this.setValue("")}bold(){return this.lexicalFormat("bold"),this}italic(){return this.lexicalFormat("italic"),this}underline(){return this.lexicalFormat("underline"),this}strikethrough(){return this.lexicalFormat("strikethrough"),this}orderedList(){return"visual"===this.mode&&this.lexicalEditor?(this.lexicalEditor.update(()=>{this.lx.list.$insertList("number")},{discrete:!0}),this):this}unorderedList(){return"visual"===this.mode&&this.lexicalEditor?(this.lexicalEditor.update(()=>{this.lx.list.$insertList("bullet")},{discrete:!0}),this):this}alignLeft(){return this.lexicalFormatElement("left"),this}alignCenter(){return this.lexicalFormatElement("center"),this}alignRight(){return this.lexicalFormatElement("right"),this}alignJustify(){return this.lexicalFormatElement("justify"),this}setTextColor(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,selection:i}=this.lx;return this.lexicalEditor.update(()=>{const o=t.$getSelection();t.$isRangeSelection(o)&&i.$patchStyleText(o,{color:e})},{discrete:!0}),this}removeTextColor(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,selection:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&t.$patchStyleText(i,{color:null})},{discrete:!0}),this}setTextBackgroundColor(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,selection:i}=this.lx;return this.lexicalEditor.update(()=>{const o=t.$getSelection();t.$isRangeSelection(o)&&i.$patchStyleText(o,{"background-color":e})},{discrete:!0}),this}removeTextBackgroundColor(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,selection:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&t.$patchStyleText(i,{"background-color":null})},{discrete:!0}),this}removeFormat(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,selection:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&(i.getNodes().forEach(t=>{e.$isTextNode(t)&&t.setFormat(0)}),t.$patchStyleText(i,{color:null,"background-color":null}))},{discrete:!0}),this}formatBlock(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,richText:i,code:o}=this.lx;return this.lexicalEditor.update(()=>{const l=t.$getSelection();if(!t.$isRangeSelection(l))return;const s=l.anchor.getNode().getTopLevelElementOrThrow(),r=o.$isCodeNode(s);let a;if("p"===e)a=t.$createParagraphNode();else if(e.match(/^h[1-6]$/))a=i.$createHeadingNode(e);else if("blockquote"===e)a=i.$createQuoteNode();else{if("pre"!==e)return;a=o.$createCodeNode()}if(r&&"pre"!==e){const e=s.getTextContent();s.replace(a),a.append(t.$createTextNode(e))}else{const e=s.getChildren();s.replace(a),e.forEach(e=>a.append(e))}a.selectEnd()},{discrete:!0}),this}insertHTML(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,lexicalHtml:i}=this.lx;return this.lexicalEditor.update(()=>{const o=(new DOMParser).parseFromString(e,"text/html"),l=i.$generateNodesFromDOM(this.lexicalEditor,o);t.$insertNodes(l)},{discrete:!0}),this}insertAtCursor(e){return this.insertHTML(e)}insertTable(e,t,i=!1,o=null){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:l,table:s}=this.lx;return this.lexicalEditor.update(()=>{const r=e+(i?1:0),a=[];for(let e=0;e<r;e++){const r=[];for(let a=0;a<t;a++){const t=i&&0===e,n=t?s.TableCellHeaderStates.ROW:s.TableCellHeaderStates.NO_STATUS,c=s.$createTableCellNode(n),d=o?.[e]?.[a]??(t?`Header ${a+1}`:""),h=l.$createParagraphNode();h.append(l.$createTextNode(d||" ")),c.append(h),r.push(c)}a.push(s.$createTableRowNode().append(...r))}const n=s.$createTableNode().append(...a),c=l.$getSelection();if(l.$isRangeSelection(c)){c.anchor.getNode().getTopLevelElementOrThrow().insertAfter(n);const e=l.$createParagraphNode();n.insertAfter(e),e.selectEnd()}else{const e=l.$getRoot();e.append(n),e.append(l.$createParagraphNode())}},{discrete:!0}),this}insertElementAtCursor(e){return this.insertHTML(e.outerHTML)}replaceSelectionWithElement(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,lexicalHtml:i}=this.lx;return this.lexicalEditor.update(()=>{const o=t.$getSelection();if(!t.$isRangeSelection(o))return;o.removeText();const l=(new DOMParser).parseFromString(e.outerHTML,"text/html"),s=i.$generateNodesFromDOM(this.lexicalEditor,l);t.$insertNodes(s)},{discrete:!0}),this}wrapSelection(e,t,i=null){if("visual"!==this.mode||!this.lexicalEditor)return this;const o=i||this.getSelectedText();return o?this.insertHTML(e+o+t):this}getSelection(){if("visual"!==this.mode||!this.lexicalEditor)return null;let e=null;const{lexical:t}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&!i.isCollapsed()&&(e={text:i.getTextContent(),html:i.getTextContent(),selection:i})}),e}getSelectedText(){let e="";if("visual"!==this.mode||!this.lexicalEditor)return e;const{lexical:t}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&(e=i.getTextContent())}),e}getSelectedHTML(){return this.getSelectedText()}selectAll(){if("visual"===this.mode&&this.lexicalEditor){const{lexical:e}=this.lx;this.lexicalEditor.update(()=>{e.$selectAll()},{discrete:!0})}else if(this.monacoEditor){const e=this.monacoEditor.getModel();e&&this.monacoEditor.setSelection(e.getFullModelRange())}return this}replaceSelection(e){return this.insertHTML(e)}deleteSelection(){return"visual"===this.mode?this.lexicalCmd("DELETE_CHARACTER_COMMAND",!1):this.monacoEditor&&this.monacoEditor.trigger("keyboard","deleteAllLeft",null),this}getValueWithSelectionMarkers(){if("visual"!==this.mode||!this.lexicalEditor)return{html:this.value,hasCursor:!1,hasSelection:!1,selectedText:""};let e={html:this.exportHtmlFromLexical(),hasCursor:!1,hasSelection:!1,selectedText:""};const{lexical:t}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&(i.isCollapsed()?e.hasCursor=!0:(e.hasSelection=!0,e.selectedText=i.getTextContent()))}),e}setValueFromSelectionMarkers(e){return this.setValue(e)}captureSelection(){return this.selection}restoreSavedSelection(){return!1}clearSavedSelection(){this.savedSelection=null}createLink(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{link:t}=this.lx;return this.lexicalEditor.update(()=>{t.$toggleLink(e)},{discrete:!0}),this}createLinkWithText(e,t){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:i,link:o}=this.lx;return this.lexicalEditor.update(()=>{const l=i.$getSelection();i.$isRangeSelection(l)&&!l.isCollapsed()&&l.removeText();const s=o.$createLinkNode(e);s.append(i.$createTextNode(t)),i.$insertNodes([s])},{discrete:!0}),this}unlink(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,link:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&i.getNodes().forEach(e=>{const i=e.getParent();i&&t.$isLinkNode?.(i)&&(i.getChildren().forEach(e=>i.insertBefore(e)),i.remove())})},{discrete:!0}),this}insertImage(e){return this.insertHTML(`<img src="${encodeURI(e)}" />`)}undo(){return this.lexicalCmd("UNDO_COMMAND",void 0),this}redo(){return this.lexicalCmd("REDO_COMMAND",void 0),this}lexicalCmd(e,t){if("visual"!==this.mode||!this.lexicalEditor)return;const i=this.lx.lexical?.[e];i&&this.lexicalEditor.dispatchCommand(i,t)}lexicalFormat(e){if("visual"!==this.mode||!this.lexicalEditor)return;const{lexical:t}=this.lx;this.lexicalEditor.update(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&i.formatText(e)},{discrete:!0})}lexicalFormatElement(e){"visual"===this.mode&&this.lexicalEditor&&this.lexicalEditor.dispatchCommand(this.lx.lexical.FORMAT_ELEMENT_COMMAND,e)}static styles=t`
|
|
1
|
+
import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponent.js";import o from"../utils/formatCode.js";import l from"../utils/debounce.js";import{getCalculatedTheme as r,subscribeToTheme as s}from"../utils/theme.js";import a from"./Dialog.js";export default class c extends i{static formAssociated=!0;static properties={name:{type:String,reflect:!0},value:{type:String,reflect:!0},selection:{type:Object,state:!0},mode:{type:String,reflect:!0},controls:{type:String,reflect:!0},lexicalSrc:{type:String,attribute:"lexical-src"},monacoSrc:{type:String,attribute:"monaco-src"},nodes:{type:String},hasTopToolbar:{type:Boolean,state:!0},hasBottomToolbar:{type:Boolean,state:!0},fullscreen:{type:Boolean,reflect:!0}};constructor(){super(),this.internals=this.attachInternals(),this.name="",this.value="",this.selection=null,this.cursor=null,this.mode="visual",this.controls="",this.controlsLoaded=!1,this.lexicalSrc="",this.monacoSrc="",this.nodes="",this.hasTopToolbar=!1,this.hasBottomToolbar=!1,this.skipValueSync=!1,this.lexicalValueSync=!1,this.savedSelection=null,this.lexicalEditor=null,this.monacoEditor=null,this.editorTheme="auto",this.wordWrap=!0,this.minimapEnabled=!1,this.fontSize=14,this.fullscreen=!1,this.lx={},this.debouncedSyncValue=l(()=>this.syncValueFromLexical(),300)}connectedCallback(){super.connectedCallback(),this.hasAttribute("value")&&(this.value=this.getAttribute("value")),this.slotObserver=new MutationObserver(()=>this.updateToolbarVisibility()),this.slotObserver.observe(this,{childList:!0,subtree:!0}),this.updateToolbarVisibility()}disconnectedCallback(){super.disconnectedCallback(),this.slotObserver?.disconnect(),this.cleanupFns?.forEach(e=>e?.()),this.monacoEditor?.dispose(),this.unsubscribeTheme?.(),this.syncShadowSelection&&document.removeEventListener("selectionchange",this.syncShadowSelection),this.fullscreen&&this.exitFullscreen()}updateToolbarVisibility(){const e=new Set(Array.from(this.children).map(e=>e.getAttribute("slot"))),t=this.constructor.controlSets[this.controls]??null;this.hasTopToolbar=!(!t?.topLeft&&!t?.topRight)||["toolbar-top","toolbar-top-left","toolbar-top-right"].some(t=>e.has(t)),this.hasBottomToolbar=!(!t?.bottomLeft&&!t?.bottomRight)||["toolbar-bottom","toolbar-bottom-left","toolbar-bottom-right"].some(t=>e.has(t))}updated(e){if(super.updated(e),e.has("controls")&&(this.updateToolbarVisibility(),this.controls&&"none"!==this.controls&&this.loadControls()),e.has("value")&&!this.skipValueSync&&(this.lexicalValueSync?this.lexicalValueSync=!1:this.lexicalEditor&&"visual"===this.mode&&!this.isVisualCompatible(this.value)?(this.skipLexicalExport=!0,this.mode="code"):this.syncContentToEditors(),this.updateFormValue(),this.dispatchEvent(new CustomEvent("change",{detail:{value:this.value},bubbles:!0}))),e.has("mode")){const t=window.scrollY;this.handleModeSwitch(e.get("mode")),this.dispatchEvent(new CustomEvent("mode-changed",{detail:{mode:this.mode},bubbles:!0})),requestAnimationFrame(()=>window.scrollTo(0,t))}e.has("fullscreen")&&requestAnimationFrame(()=>this.monacoEditor?.layout())}async firstUpdated(){this.lexicalContainer=this.shadowRoot.querySelector(".lexical-editor"),this.monacoContainer=this.shadowRoot.querySelector(".monaco-editor-container"),await this.initLexical(),this.dispatchEvent(new CustomEvent("ready",{detail:{value:this.value},bubbles:!0}))}async loadControls(){if(this.controlsLoaded)return;this.controlsLoaded=!0;const e=new URL("./htmlEditorControls/",import.meta.url).href;await Promise.all([import(`${e}Bold.js`),import(`${e}Italic.js`),import(`${e}Underline.js`),import(`${e}Strikethrough.js`),import(`${e}InlineCode.js`),import(`${e}DropdownControl.js`),import(`${e}FormatBlock.js`),import(`${e}CodeBlock.js`),import(`${e}BulletList.js`),import(`${e}NumberList.js`),import(`${e}AlignLeft.js`),import(`${e}AlignCenter.js`),import(`${e}AlignRight.js`),import(`${e}AlignJustify.js`),import(`${e}TextColor.js`),import(`${e}TextBackgroundColor.js`),import(`${e}ClearFormatting.js`),import(`${e}CreateLink.js`),import(`${e}InsertTable.js`),import(`${e}ControlGroup.js`),import(`${e}ControlSpacer.js`),import(`${e}Mode.js`),import(`${e}WordCount.js`),import(`${e}CharacterCount.js`)]);const t=new URL("./codeEditorControls/",import.meta.url).href;await Promise.all([import(`${t}FormatCode.js`),import(`${t}CopyCode.js`),import(`${t}Undo.js`),import(`${t}Redo.js`),import(`${t}WordWrap.js`),import(`${t}Minimap.js`),import(`${t}FindReplace.js`),import(`${t}FontSize.js`),import(`${t}FoldAll.js`),import(`${t}EditorTheme.js`),import(`${t}Fullscreen.js`),import(`${t}ControlGroup.js`)]),this.requestUpdate()}async loadNodeModules(){if(!this.nodes?.trim())return[];const e=new URL("./htmlEditorNodes/",import.meta.url).href;return(await Promise.all(this.nodes.split(",").map(e=>e.trim()).filter(Boolean).map(t=>import(`${e}${t}.js`)))).map(e=>e.default?.lexicalNode).filter(Boolean)}async loadLexicalModules(){const e=this.lexicalSrc||window.kempo?.lexicalUrl||"https://esm.sh",t=t=>((e,t)=>`${e}/${t}@0.43.0`)(e,t),[i,o,l,r,s,a,c,n,h]=await Promise.all([import(t("lexical")),import(t("@lexical/rich-text")),import(t("@lexical/html")),import(t("@lexical/history")),import(t("@lexical/list")),import(t("@lexical/link")),import(t("@lexical/selection")),import(t("@lexical/table")),import(t("@lexical/code"))]);this.lx={lexical:i,richText:o,lexicalHtml:l,history:r,list:s,link:a,selection:c,table:n,code:h},this.StyledTextNode=class extends i.TextNode{static getType(){return"styled-text"}static clone(e){return new this(e.__text,e.__key)}static importDOM(){return{span:()=>({conversion:e=>{const t=e.getAttribute("style");if(!t)return null;const o=i.$createTextNode(e.textContent);return o.setStyle(t),{node:o}},priority:1})}}static importJSON(e){return i.$createTextNode(e.text)}exportJSON(){return{...super.exportJSON(),type:"styled-text"}}}}async initLexical(){await this.loadLexicalModules(),this.customNodes=await this.loadNodeModules(),this.nodeCompatCheckers=this.customNodes.filter(e=>"function"==typeof e.isVisualCompatible).map(e=>e.isVisualCompatible),this.nodePreprocessors=this.customNodes.filter(e=>"function"==typeof e.preprocessHtml).map(e=>e.preprocessHtml);const{lexical:e,richText:t,history:i,list:o,link:l,table:r,code:s}=this.lx,a={namespace:"KempoHtmlEditor",theme:{paragraph:"k-editor-p",heading:{h1:"k-editor-h1",h2:"k-editor-h2",h3:"k-editor-h3",h4:"k-editor-h4",h5:"k-editor-h5",h6:"k-editor-h6"},text:{underline:"td-u",strikethrough:"td-lt"},list:{ul:"k-editor-ul",ol:"k-editor-ol",listitem:"k-editor-li"},link:"k-editor-link",quote:"k-editor-quote",code:"k-editor-code-block",codeHighlight:{},table:"k-editor-table",tableCell:"k-editor-table-cell",tableCellHeader:"k-editor-table-cell-header"},nodes:[t.HeadingNode,t.QuoteNode,o.ListNode,o.ListItemNode,l.LinkNode,r.TableNode,r.TableCellNode,r.TableRowNode,s.CodeNode,s.CodeHighlightNode,this.StyledTextNode,...this.customNodes],onError:console.error,editorState:null};this.lexicalEditor=e.createEditor(a),this.lexicalEditor.setRootElement(this.lexicalContainer),this.cleanupFns=[t.registerRichText(this.lexicalEditor),i.registerHistory(this.lexicalEditor,i.createEmptyHistoryState(),300)],o.registerList&&this.cleanupFns.push(o.registerList(this.lexicalEditor)),r.registerTable&&this.cleanupFns.push(r.registerTable(this.lexicalEditor)),s.registerCodeHighlighting&&this.cleanupFns.push(s.registerCodeHighlighting(this.lexicalEditor)),l.registerLink&&this.cleanupFns.push(l.registerLink(this.lexicalEditor,{validateUrl:e=>{try{return new URL(e),!0}catch{return!1}}})),this.value&&(this.isVisualCompatible(this.value)?this.importHtmlToLexical(this.value):(this.skipLexicalExport=!0,this.mode="code")),this.lexicalEditor.registerUpdateListener(({dirtyElements:e,dirtyLeaves:t})=>{0===e.size&&0===t.size||(this.debouncedSyncValue(),this.dispatchEvent(new CustomEvent("input",{detail:{value:this.exportHtmlFromLexical()},bubbles:!0})))}),this.lexicalEditor.registerCommand(e.SELECTION_CHANGE_COMMAND,()=>(this.updateSelection(),!1),e.COMMAND_PRIORITY_LOW),this.syncShadowSelection=()=>{if("visual"!==this.mode||!this.lexicalEditor)return;const t=this.shadowRoot.getSelection?.();if(!t||0===t.rangeCount)return;const i=t.getRangeAt(0);this.lexicalContainer.contains(i.startContainer)&&(this.lexicalEditor.update(()=>{const i=e.$createRangeSelectionFromDom(t,this.lexicalEditor);i&&e.$setSelection(i)},{discrete:!0}),this.updateSelection())},document.addEventListener("selectionchange",this.syncShadowSelection)}async initMonaco(){if(!this.monacoEditor){if(this.monacoInitPromise)return this.monacoInitPromise;this.monacoInitPromise=this._initMonaco(),await this.monacoInitPromise,this.monacoInitPromise=null}}async _initMonaco(){const e=this.monacoSrc||window.kempo?.monacoUrl||"https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min";await new Promise((t,i)=>{if(window.monaco)return void t();if(window.require?.defined?.("vs/editor/editor.main"))return void t();const o=document.querySelector(`script[src="${e}/vs/loader.js"]`);if(o)return void o.addEventListener("load",()=>{window.require.config({paths:{vs:`${e}/vs`}}),window.require(["vs/editor/editor.main"],()=>t(),i)});const l=document.createElement("script");l.src=`${e}/vs/loader.js`,l.onload=()=>{window.require.config({paths:{vs:`${e}/vs`}}),window.require(["vs/editor/editor.main"],()=>t(),i)},l.onerror=i,document.head.appendChild(l)}),this.monacoEditor=window.monaco.editor.create(this.monacoContainer,{value:o(this.value),language:"html",theme:this.resolveMonacoTheme(),minimap:{enabled:this.minimapEnabled},wordWrap:this.wordWrap?"on":"off",fontSize:this.fontSize,scrollBeyondLastLine:!1,automaticLayout:!0,tabSize:2,padding:{top:8}});const t=document.querySelector('link[href*="monaco"][href*="editor.main.css"]');if(t){const e=document.createElement("link");e.rel="stylesheet",e.href=t.href,this.shadowRoot.appendChild(e)}this.unsubscribeTheme=s(()=>{this.monacoEditor&&"auto"===this.editorTheme&&window.monaco.editor.setTheme(this.resolveMonacoTheme())}),this.monacoEditor.onDidChangeModelContent(()=>{this.skipValueSync=!0,this.value=this.monacoEditor.getValue(),this.skipValueSync=!1,this.updateFormValue(),this.dispatchEvent(new CustomEvent("change",{detail:{value:this.value},bubbles:!0})),this.dispatchEvent(new CustomEvent("input",{detail:{value:this.value},bubbles:!0}))})}importHtmlToLexical(e){if(!this.lexicalEditor||!this.lx.lexicalHtml)return;const{lexical:t,lexicalHtml:i}=this.lx,o=(this.nodePreprocessors||[]).reduce((e,t)=>t(e),e);this.lexicalEditor.update(()=>{if(t.$getRoot().clear(),!o?.trim())return;const e=(new DOMParser).parseFromString(o,"text/html"),l=i.$generateNodesFromDOM(this.lexicalEditor,e);l.length>0&&t.$insertNodes(l)},{discrete:!0})}exportHtmlFromLexical(){if(!this.lexicalEditor||!this.lx.lexicalHtml)return this.value;let e="";return this.lexicalEditor.getEditorState().read(()=>{e=this.lx.lexicalHtml.$generateHtmlFromNodes(this.lexicalEditor,null)}),this.cleanExportedHtml(e)}isVisualCompatible(e){if(!e?.trim())return!0;const t=new Set(["script","style","meta","link","head","iframe","object","embed","canvas","video","audio","form","input","button","select","textarea","fieldset","label","noscript","template","slot","svg","math"]),i=this.nodeCompatCheckers||[],o=(new DOMParser).parseFromString(e,"text/html"),l=document.createTreeWalker(o.body,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT);let r;for(;r=l.nextNode();)if(!i.some(e=>e(r))){if(r.nodeType===Node.COMMENT_NODE)return!1;if(t.has(r.tagName?.toLowerCase()))return!1}return!0}cleanExportedHtml(e){const t=(new DOMParser).parseFromString(e,"text/html");return t.body.querySelectorAll("[class]").forEach(e=>{const t=Array.from(e.classList).filter(e=>!e.startsWith("k-editor-")&&"td-u"!==e&&"td-lt"!==e);0===t.length?e.removeAttribute("class"):e.className=t.join(" ")}),t.body.querySelectorAll("[style]").forEach(e=>{const t=e.style.cssText.replace(/white-space:\s*pre-wrap;?\s*/g,"").trim();t?e.style.cssText=t:e.removeAttribute("style")}),t.body.querySelectorAll("span:not([class]):not([style]):not([id])").forEach(e=>{e.attributes.length||e.replaceWith(...e.childNodes)}),t.body.querySelectorAll("b > strong, i > em, b > b, strong > strong, i > i, em > em").forEach(e=>{e.replaceWith(...e.childNodes)}),t.body.querySelectorAll("pre[data-highlight-language], code[data-highlight-language]").forEach(e=>{e.removeAttribute("data-highlight-language"),e.removeAttribute("data-language")}),t.body.innerHTML}syncValueFromLexical(){this.lexicalEditor&&(this.lexicalValueSync=!0,this.value=this.exportHtmlFromLexical(),this.updateFormValue())}syncContentToEditors(){"visual"===this.mode&&this.lexicalEditor&&this.importHtmlToLexical(this.value)}async handleModeSwitch(e){"code"===this.mode?(this.lexicalEditor&&!this.skipLexicalExport&&(this.value=this.exportHtmlFromLexical()),this.skipLexicalExport=!1,await this.initMonaco(),this.monacoEditor&&(this.monacoEditor.setValue(o(this.value)),this.monacoEditor.layout())):"visual"===this.mode&&(this.monacoEditor&&(this.value=this.monacoEditor.getValue()),this.lexicalEditor&&this.importHtmlToLexical(this.value)),this.requestUpdate()}updateFormValue(){this.internals.setFormValue(this.getValue())}formResetCallback(){this.value=""}formStateRestoreCallback(e){this.value=e}updateSelection=()=>{if("visual"!==this.mode||!this.lexicalEditor)return void(this.selection=null);const{lexical:e}=this.lx;this.lexicalEditor.getEditorState().read(()=>{const t=e.$getSelection();e.$isRangeSelection(t)&&!t.isCollapsed()?this.selection={text:t.getTextContent(),collapsed:!1}:(this.selection=null,this.cursor=t?{anchor:t.anchor,focus:t.focus}:null)})};setMode(e){return["visual","code"].includes(e)?"visual"!==e||this.isVisualCompatible(this.getValue())?(this.mode=e,this):(a.confirm("This html contains code that is not compatible with the visual editor, the incompatible code will be lost",t=>{t&&(this.mode=e)},{title:"Warning",confirmText:"Change Anyways"}),this):this}toggleMode(){return this.setMode("visual"===this.mode?"code":"visual")}getValue(){if("visual"===this.mode&&this.lexicalEditor)this.skipValueSync=!0,this.value=this.exportHtmlFromLexical(),this.skipValueSync=!1;else if("code"===this.mode&&this.monacoEditor)return this.monacoEditor.getValue();return this.value}setValue(e){return this.lexicalEditor&&"visual"===this.mode&&!this.isVisualCompatible(e)?(this.value=e,this.skipLexicalExport=!0,this.mode="code",this.updateFormValue(),this):(this.skipValueSync=!0,this.value=e,"visual"===this.mode?this.syncContentToEditors():"code"===this.mode&&this.monacoEditor&&this.monacoEditor.setValue(o(e)),this.updateFormValue(),this.skipValueSync=!1,this)}clear(){return this.setValue("")}bold(){return this.lexicalFormat("bold"),this}italic(){return this.lexicalFormat("italic"),this}underline(){return this.lexicalFormat("underline"),this}strikethrough(){return this.lexicalFormat("strikethrough"),this}inlineCode(){return this.lexicalFormat("code"),this}orderedList(){return"visual"===this.mode&&this.lexicalEditor?(this.lexicalEditor.update(()=>{this.lx.list.$insertList("number")},{discrete:!0}),this):this}unorderedList(){return"visual"===this.mode&&this.lexicalEditor?(this.lexicalEditor.update(()=>{this.lx.list.$insertList("bullet")},{discrete:!0}),this):this}alignLeft(){return this.lexicalFormatElement("left"),this}alignCenter(){return this.lexicalFormatElement("center"),this}alignRight(){return this.lexicalFormatElement("right"),this}alignJustify(){return this.lexicalFormatElement("justify"),this}setTextColor(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,selection:i}=this.lx;return this.lexicalEditor.update(()=>{const o=t.$getSelection();t.$isRangeSelection(o)&&i.$patchStyleText(o,{color:e})},{discrete:!0}),this}removeTextColor(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,selection:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&t.$patchStyleText(i,{color:null})},{discrete:!0}),this}setTextBackgroundColor(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,selection:i}=this.lx;return this.lexicalEditor.update(()=>{const o=t.$getSelection();t.$isRangeSelection(o)&&i.$patchStyleText(o,{"background-color":e})},{discrete:!0}),this}removeTextBackgroundColor(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,selection:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&t.$patchStyleText(i,{"background-color":null})},{discrete:!0}),this}removeFormat(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,selection:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&(i.getNodes().forEach(t=>{e.$isTextNode(t)&&t.setFormat(0)}),t.$patchStyleText(i,{color:null,"background-color":null}))},{discrete:!0}),this}formatBlock(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,richText:i,code:o}=this.lx;return this.lexicalEditor.update(()=>{const l=t.$getSelection();if(!t.$isRangeSelection(l))return;const r=l.anchor.getNode().getTopLevelElementOrThrow(),s=o.$isCodeNode(r);let a;if("p"===e)a=t.$createParagraphNode();else if(e.match(/^h[1-6]$/))a=i.$createHeadingNode(e);else if("blockquote"===e)a=i.$createQuoteNode();else{if("pre"!==e)return;a=o.$createCodeNode()}if(s&&"pre"!==e){const e=r.getTextContent();r.replace(a),a.append(t.$createTextNode(e))}else{const e=r.getChildren();r.replace(a),e.forEach(e=>a.append(e))}a.selectEnd()},{discrete:!0}),this}isSelectionInCodeBlock(){if("visual"!==this.mode||!this.lexicalEditor)return!1;let e=!1;const{lexical:t,code:i}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const o=t.$getSelection();t.$isRangeSelection(o)&&(e=i.$isCodeNode(o.anchor.getNode().getTopLevelElementOrThrow()))}),e}getTableAtSelection(){if("visual"!==this.mode||!this.lexicalEditor)return null;let e=null;const{lexical:t,table:i}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const o=t.$getSelection();if(!t.$isRangeSelection(o))return;let l=o.anchor.getNode();for(;l;){if(i.$isTableNode(l)){const t=l.getChildren(),o=[];let r=!1,s=0;t.forEach((e,t)=>{const l=[];e.getChildren().forEach(e=>{0===t&&i.$isTableCellNode(e)&&e.getHeaderStyles()===i.TableCellHeaderStates.ROW&&(r=!0),l.push(e.getTextContent())}),l.length>s&&(s=l.length),o.push(l)}),e={key:l.getKey(),rows:r?t.length-1:t.length,cols:s,hasHeaders:r,cellData:o};break}l=l.getParent()}}),e}removeTableByKey(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t}=this.lx;return this.lexicalEditor.update(()=>{const i=t.$getNodeByKey(e);i&&i.remove()},{discrete:!0}),this}insertHTML(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,lexicalHtml:i}=this.lx;return this.lexicalEditor.update(()=>{const o=(new DOMParser).parseFromString(e,"text/html"),l=i.$generateNodesFromDOM(this.lexicalEditor,o);t.$insertNodes(l)},{discrete:!0}),this}insertAtCursor(e){return this.insertHTML(e)}insertTable(e,t,i=!1,o=null){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:l,table:r}=this.lx;return this.lexicalEditor.update(()=>{const s=e+(i?1:0),a=[];for(let e=0;e<s;e++){const s=[];for(let a=0;a<t;a++){const t=i&&0===e,c=t?r.TableCellHeaderStates.ROW:r.TableCellHeaderStates.NO_STATUS,n=r.$createTableCellNode(c),h=o?.[e]?.[a]??(t?`Header ${a+1}`:""),d=l.$createParagraphNode();d.append(l.$createTextNode(h||" ")),n.append(d),s.push(n)}a.push(r.$createTableRowNode().append(...s))}const c=r.$createTableNode().append(...a),n=l.$getSelection();if(l.$isRangeSelection(n)){n.anchor.getNode().getTopLevelElementOrThrow().insertAfter(c);const e=l.$createParagraphNode();c.insertAfter(e),e.selectEnd()}else{const e=l.$getRoot();e.append(c),e.append(l.$createParagraphNode())}},{discrete:!0}),this}insertElementAtCursor(e){return this.insertHTML(e.outerHTML)}replaceSelectionWithElement(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,lexicalHtml:i}=this.lx;return this.lexicalEditor.update(()=>{const o=t.$getSelection();if(!t.$isRangeSelection(o))return;o.removeText();const l=(new DOMParser).parseFromString(e.outerHTML,"text/html"),r=i.$generateNodesFromDOM(this.lexicalEditor,l);t.$insertNodes(r)},{discrete:!0}),this}wrapSelection(e,t,i=null){if("visual"!==this.mode||!this.lexicalEditor)return this;const o=i||this.getSelectedText();return o?this.insertHTML(e+o+t):this}getSelection(){if("visual"!==this.mode||!this.lexicalEditor)return null;let e=null;const{lexical:t}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&!i.isCollapsed()&&(e={text:i.getTextContent(),html:i.getTextContent(),selection:i})}),e}getSelectedText(){let e="";if("visual"!==this.mode||!this.lexicalEditor)return e;const{lexical:t}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&(e=i.getTextContent())}),e}getSelectedHTML(){return this.getSelectedText()}selectAll(){if("visual"===this.mode&&this.lexicalEditor){const{lexical:e}=this.lx;this.lexicalEditor.update(()=>{e.$selectAll()},{discrete:!0})}else if(this.monacoEditor){const e=this.monacoEditor.getModel();e&&this.monacoEditor.setSelection(e.getFullModelRange())}return this}replaceSelection(e){return this.insertHTML(e)}deleteSelection(){return"visual"===this.mode?this.lexicalCmd("DELETE_CHARACTER_COMMAND",!1):this.monacoEditor&&this.monacoEditor.trigger("keyboard","deleteAllLeft",null),this}getValueWithSelectionMarkers(){if("visual"!==this.mode||!this.lexicalEditor)return{html:this.value,hasCursor:!1,hasSelection:!1,selectedText:""};let e={html:this.exportHtmlFromLexical(),hasCursor:!1,hasSelection:!1,selectedText:""};const{lexical:t}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&(i.isCollapsed()?e.hasCursor=!0:(e.hasSelection=!0,e.selectedText=i.getTextContent()))}),e}setValueFromSelectionMarkers(e){return this.setValue(e)}captureSelection(){return this.selection}restoreSavedSelection(){return!1}clearSavedSelection(){this.savedSelection=null}createLink(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{link:t}=this.lx;return this.lexicalEditor.update(()=>{t.$toggleLink(e)},{discrete:!0}),this}createLinkWithText(e,t){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:i,link:o}=this.lx;return this.lexicalEditor.update(()=>{const l=i.$getSelection();i.$isRangeSelection(l)&&!l.isCollapsed()&&l.removeText();const r=o.$createLinkNode(e);r.append(i.$createTextNode(t)),i.$insertNodes([r])},{discrete:!0}),this}unlink(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,link:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&i.getNodes().forEach(e=>{const i=e.getParent();i&&t.$isLinkNode?.(i)&&(i.getChildren().forEach(e=>i.insertBefore(e)),i.remove())})},{discrete:!0}),this}insertImage(e){return this.insertHTML(`<img src="${encodeURI(e)}" />`)}undo(){return"code"===this.mode?this.monacoEditor?.trigger("toolbar","undo"):this.lexicalCmd("UNDO_COMMAND",void 0),this}redo(){return"code"===this.mode?this.monacoEditor?.trigger("toolbar","redo"):this.lexicalCmd("REDO_COMMAND",void 0),this}copyToClipboard(){return navigator.clipboard.writeText(this.getValue()),this}setEditorTheme(e){return["auto","light","dark"].includes(e)&&(this.editorTheme=e),this.monacoEditor&&window.monaco.editor.setTheme(this.resolveMonacoTheme()),this}openFind(){return this.monacoEditor?.getAction("actions.find")?.run(),this}foldAll(){return this.monacoEditor?.getAction("editor.foldAll")?.run(),this}unfoldAll(){return this.monacoEditor?.getAction("editor.unfoldAll")?.run(),this}enterFullscreen(){return this.fullscreen=!0,document.body.classList.add("no-scroll"),this.dispatchEvent(new CustomEvent("fullscreen-changed",{detail:{fullscreen:!0},bubbles:!0})),this}exitFullscreen(){return this.fullscreen=!1,document.body.classList.remove("no-scroll"),this.dispatchEvent(new CustomEvent("fullscreen-changed",{detail:{fullscreen:!1},bubbles:!0})),this}toggleFullscreen(){return this.fullscreen?this.exitFullscreen():this.enterFullscreen()}increaseFontSize(){return this.fontSize=Math.min(this.fontSize+2,40),this.monacoEditor?.updateOptions({fontSize:this.fontSize}),this}decreaseFontSize(){return this.fontSize=Math.max(this.fontSize-2,8),this.monacoEditor?.updateOptions({fontSize:this.fontSize}),this}setWordWrap(e){return this.wordWrap=e,this.monacoEditor?.updateOptions({wordWrap:e?"on":"off"}),this}setMinimap(e){return this.minimapEnabled=e,this.monacoEditor?.updateOptions({minimap:{enabled:e}}),this}resolveMonacoTheme(){return"dark"===this.editorTheme?"vs-dark":"light"===this.editorTheme?"vs":"dark"===r()?"vs-dark":"vs"}lexicalCmd(e,t){if("visual"!==this.mode||!this.lexicalEditor)return;const i=this.lx.lexical?.[e];i&&this.lexicalEditor.dispatchCommand(i,t)}lexicalFormat(e){if("visual"!==this.mode||!this.lexicalEditor)return;const{lexical:t}=this.lx;this.lexicalEditor.update(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&i.formatText(e)},{discrete:!0})}lexicalFormatElement(e){"visual"===this.mode&&this.lexicalEditor&&this.lexicalEditor.dispatchCommand(this.lx.lexical.FORMAT_ELEMENT_COMMAND,e)}render(){const t=this.constructor.controlSets[this.controls]??{};return e`
|
|
2
|
+
${this.hasTopToolbar?e`
|
|
3
|
+
<div class="toolbar-top bb">
|
|
4
|
+
<div class="toolbar-start">
|
|
5
|
+
<slot name="toolbar-top-left">${t.topLeft??""}</slot>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="toolbar-end">
|
|
8
|
+
<slot name="toolbar-top-right">${t.topRight??""}</slot>
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
`:""}
|
|
12
|
+
<div class="editor-container">
|
|
13
|
+
<div
|
|
14
|
+
class="lexical-editor"
|
|
15
|
+
contenteditable="true"
|
|
16
|
+
?hidden=${"visual"!==this.mode}
|
|
17
|
+
></div>
|
|
18
|
+
<div
|
|
19
|
+
class="monaco-editor-container"
|
|
20
|
+
?hidden=${"code"!==this.mode}
|
|
21
|
+
></div>
|
|
22
|
+
</div>
|
|
23
|
+
${this.hasBottomToolbar?e`
|
|
24
|
+
<div class="toolbar-bottom bt">
|
|
25
|
+
<div class="toolbar-start">
|
|
26
|
+
<slot name="toolbar-bottom-left">${t.bottomLeft??""}</slot>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="toolbar-end">
|
|
29
|
+
<slot name="toolbar-bottom-right">${t.bottomRight??""}</slot>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
`:""}
|
|
33
|
+
`}static styles=t`
|
|
2
34
|
:host {
|
|
3
35
|
display: flex;
|
|
4
36
|
flex-direction: column;
|
|
5
37
|
gap: 0;
|
|
6
|
-
height:
|
|
38
|
+
height: 400px;
|
|
39
|
+
background: var(--c_bg, rgb(249, 249, 249));
|
|
40
|
+
}
|
|
41
|
+
:host([fullscreen]) {
|
|
42
|
+
position: fixed;
|
|
43
|
+
top: 0;
|
|
44
|
+
left: 0;
|
|
45
|
+
width: 100vw !important;
|
|
46
|
+
height: 100vh !important;
|
|
47
|
+
z-index: 10000;
|
|
7
48
|
}
|
|
8
49
|
.toolbar-top,
|
|
9
50
|
.toolbar-bottom {
|
|
10
51
|
display: flex;
|
|
11
|
-
flex-wrap: wrap;
|
|
12
52
|
align-items: center;
|
|
13
|
-
gap: 0;
|
|
14
53
|
background: var(--bg-secondary);
|
|
15
54
|
min-height: 40px;
|
|
55
|
+
width: 100%;
|
|
56
|
+
}
|
|
57
|
+
.toolbar-start {
|
|
58
|
+
display: flex;
|
|
59
|
+
flex-wrap: wrap;
|
|
60
|
+
align-items: center;
|
|
61
|
+
}
|
|
62
|
+
.toolbar-end {
|
|
63
|
+
display: flex;
|
|
64
|
+
flex-wrap: wrap-reverse;
|
|
65
|
+
align-items: center;
|
|
66
|
+
justify-content: flex-end;
|
|
67
|
+
margin-left: auto;
|
|
16
68
|
}
|
|
17
69
|
.editor-container {
|
|
18
70
|
position: relative;
|
|
@@ -86,29 +138,102 @@ import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponen
|
|
|
86
138
|
.monaco-editor-container {
|
|
87
139
|
border: 1px solid var(--border-color);
|
|
88
140
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
141
|
+
`;static controlSets={minimal:{topLeft:e`
|
|
142
|
+
<k-hec-group>
|
|
143
|
+
<k-hec-bold></k-hec-bold>
|
|
144
|
+
<k-hec-italic></k-hec-italic>
|
|
145
|
+
<k-hec-underline></k-hec-underline>
|
|
146
|
+
</k-hec-group>
|
|
147
|
+
<k-hec-group>
|
|
148
|
+
<k-hec-bullet-list></k-hec-bullet-list>
|
|
149
|
+
<k-hec-number-list></k-hec-number-list>
|
|
150
|
+
</k-hec-group>
|
|
151
|
+
`,topRight:null,bottomLeft:null,bottomRight:null},normal:{topLeft:e`
|
|
152
|
+
<k-hec-group>
|
|
153
|
+
<k-hec-bold></k-hec-bold>
|
|
154
|
+
<k-hec-italic></k-hec-italic>
|
|
155
|
+
<k-hec-underline></k-hec-underline>
|
|
156
|
+
<k-hec-strikethrough></k-hec-strikethrough>
|
|
157
|
+
</k-hec-group>
|
|
158
|
+
<k-hec-inline-code></k-hec-inline-code>
|
|
159
|
+
<k-hec-dropdown>
|
|
160
|
+
<k-icon slot="icon" name="format_paragraph"></k-icon>
|
|
161
|
+
<span slot="label">Text Style</span>
|
|
162
|
+
<k-hec-format-block tag="p">Paragraph</k-hec-format-block>
|
|
163
|
+
<k-hec-format-block tag="h1">Heading 1</k-hec-format-block>
|
|
164
|
+
<k-hec-format-block tag="h2">Heading 2</k-hec-format-block>
|
|
165
|
+
<k-hec-format-block tag="h3">Heading 3</k-hec-format-block>
|
|
166
|
+
<k-hec-format-block tag="blockquote">Blockquote</k-hec-format-block>
|
|
167
|
+
<k-hec-code-block></k-hec-code-block>
|
|
168
|
+
</k-hec-dropdown>
|
|
169
|
+
<k-hec-group>
|
|
170
|
+
<k-hec-bullet-list></k-hec-bullet-list>
|
|
171
|
+
<k-hec-number-list></k-hec-number-list>
|
|
172
|
+
</k-hec-group>
|
|
173
|
+
`,topRight:e`
|
|
174
|
+
<k-hec-group>
|
|
175
|
+
<k-hec-align-left></k-hec-align-left>
|
|
176
|
+
<k-hec-align-center></k-hec-align-center>
|
|
177
|
+
<k-hec-align-right></k-hec-align-right>
|
|
178
|
+
</k-hec-group>
|
|
179
|
+
<k-hec-create-link></k-hec-create-link>
|
|
180
|
+
<k-cec-format-code></k-cec-format-code>
|
|
181
|
+
<k-hec-mode></k-hec-mode>
|
|
182
|
+
`,bottomLeft:e`<k-hec-word-count></k-hec-word-count>`,bottomRight:null},full:{topLeft:e`
|
|
183
|
+
<k-hec-group>
|
|
184
|
+
<k-hec-bold></k-hec-bold>
|
|
185
|
+
<k-hec-italic></k-hec-italic>
|
|
186
|
+
<k-hec-underline></k-hec-underline>
|
|
187
|
+
<k-hec-strikethrough></k-hec-strikethrough>
|
|
188
|
+
</k-hec-group>
|
|
189
|
+
<k-hec-inline-code></k-hec-inline-code>
|
|
190
|
+
<k-hec-dropdown>
|
|
191
|
+
<k-icon slot="icon" name="format_paragraph"></k-icon>
|
|
192
|
+
<span slot="label">Text Style</span>
|
|
193
|
+
<k-hec-format-block tag="p">Paragraph</k-hec-format-block>
|
|
194
|
+
<k-hec-format-block tag="h1">Heading 1</k-hec-format-block>
|
|
195
|
+
<k-hec-format-block tag="h2">Heading 2</k-hec-format-block>
|
|
196
|
+
<k-hec-format-block tag="h3">Heading 3</k-hec-format-block>
|
|
197
|
+
<k-hec-format-block tag="blockquote">Blockquote</k-hec-format-block>
|
|
198
|
+
<k-hec-code-block></k-hec-code-block>
|
|
199
|
+
</k-hec-dropdown>
|
|
200
|
+
<k-hec-group>
|
|
201
|
+
<k-hec-bullet-list></k-hec-bullet-list>
|
|
202
|
+
<k-hec-number-list></k-hec-number-list>
|
|
203
|
+
</k-hec-group>
|
|
204
|
+
`,topRight:e`
|
|
205
|
+
<k-hec-group>
|
|
206
|
+
<k-hec-align-left></k-hec-align-left>
|
|
207
|
+
<k-hec-align-center></k-hec-align-center>
|
|
208
|
+
<k-hec-align-right></k-hec-align-right>
|
|
209
|
+
<k-hec-align-justify></k-hec-align-justify>
|
|
210
|
+
</k-hec-group>
|
|
211
|
+
<k-hec-create-link></k-hec-create-link>
|
|
212
|
+
<k-hec-group>
|
|
213
|
+
<k-hec-text-color></k-hec-text-color>
|
|
214
|
+
<k-hec-text-background-color></k-hec-text-background-color>
|
|
215
|
+
</k-hec-group>
|
|
216
|
+
<k-hec-clear-formatting></k-hec-clear-formatting>
|
|
217
|
+
<k-hec-insert-table></k-hec-insert-table>
|
|
218
|
+
<k-cec-group>
|
|
219
|
+
<k-cec-undo></k-cec-undo>
|
|
220
|
+
<k-cec-redo></k-cec-redo>
|
|
221
|
+
</k-cec-group>
|
|
222
|
+
<k-cec-group>
|
|
223
|
+
<k-cec-format-code></k-cec-format-code>
|
|
224
|
+
<k-cec-copy-code></k-cec-copy-code>
|
|
225
|
+
<k-cec-find-replace></k-cec-find-replace>
|
|
226
|
+
</k-cec-group>
|
|
227
|
+
<k-cec-group>
|
|
228
|
+
<k-cec-word-wrap></k-cec-word-wrap>
|
|
229
|
+
<k-cec-minimap></k-cec-minimap>
|
|
230
|
+
<k-cec-fold-all></k-cec-fold-all>
|
|
231
|
+
</k-cec-group>
|
|
232
|
+
<k-cec-font-size></k-cec-font-size>
|
|
233
|
+
<k-cec-editor-theme></k-cec-editor-theme>
|
|
234
|
+
<k-hec-mode></k-hec-mode>
|
|
235
|
+
<k-cec-fullscreen></k-cec-fullscreen>
|
|
236
|
+
`,bottomLeft:e`
|
|
237
|
+
<k-hec-word-count></k-hec-word-count>
|
|
238
|
+
<k-hec-character-count></k-hec-character-count>
|
|
239
|
+
`,bottomRight:null},"":{topLeft:null,topRight:null,bottomLeft:null,bottomRight:null}}}customElements.define("k-html-editor",c);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import t from"../ShadowComponent.js";import{css as e}from"../../lit-all.min.js";export default class s extends t{static properties={btnClass:{type:String,attribute:"btn-class"},groupBtnClass:{type:String,attribute:"group-btn-class"},groupLastBtnClass:{type:String,attribute:"group-last-btn-class"},hidden:{type:Boolean,reflect:!0}};constructor(){super(),this.btnClass="b r mq ph",this.groupBtnClass="br ph",this.groupLastBtnClass="ph",this.hidden=!1}connectedCallback(){super.connectedCallback(),this.updateModeVisibility();const t=this.editor;"K-HTML-EDITOR"===t?.tagName&&(this.modeHandler=()=>this.updateModeVisibility(),t.addEventListener("mode-changed",this.modeHandler))}disconnectedCallback(){super.disconnectedCallback(),this.modeHandler&&(this.editor?.removeEventListener("mode-changed",this.modeHandler),this.modeHandler=null)}updated(t){super.updated(t),t.has("hidden")&&this.dispatchEvent(new CustomEvent("control_visibility_change",{bubbles:!0}))}updateModeVisibility(){const t=this.editor;if("K-HTML-EDITOR"===t?.tagName){const e="code"!==t.mode;this.hidden!==e&&(this.hidden=e,this.dispatchEvent(new CustomEvent("control_visibility_change",{bubbles:!0})))}}get editor(){const t=t=>"K-CODE-EDITOR"===t?.tagName||"K-HTML-EDITOR"===t?.tagName;let e=this.getRootNode();for(;e instanceof ShadowRoot;){const s=e.host;if(t(s))return s;e=s.getRootNode()}let s=this.parentElement;for(;s;){if(t(s))return s;s=s.parentElement}return null}get isInGroup(){const t=this.parentElement;return t&&"K-CEC-GROUP"===t.tagName}get isLastInGroup(){if(!this.isInGroup)return!1;const t=Array.from(this.parentElement.children).filter(t=>t.tagName.startsWith("K-CEC-")&&"K-CEC-SPACER"!==t.tagName);return t[t.length-1]===this}get buttonClasses(){let t;return t=this.isInGroup?this.isLastInGroup?this.groupLastBtnClass:this.groupBtnClass:this.btnClass,`no-btn icon-btn ${t}`.trim()}static styles=e`
|
|
2
|
+
:host {
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
}
|
|
6
|
+
:host([hidden]) {
|
|
7
|
+
display: none !important;
|
|
8
|
+
}
|
|
9
|
+
button {
|
|
10
|
+
cursor: pointer;
|
|
11
|
+
display: inline-flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
min-width: 2rem;
|
|
15
|
+
min-height: 2rem;
|
|
16
|
+
}
|
|
17
|
+
`}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import t from"../ShadowComponent.js";import{html as e,css as i}from"../../lit-all.min.js";export default class s extends t{static properties={hidden:{type:Boolean,reflect:!0}};constructor(){super(),this.hidden=!1}connectedCallback(){super.connectedCallback(),this.hasAttribute("class")||this.setAttribute("class","b r mq"),this.addEventListener("control_visibility_change",this.checkVisibility)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("control_visibility_change",this.checkVisibility)}checkVisibility=t=>{if(t.target===this)return;const e=this.hidden;this.hidden=Array.from(this.children).every(t=>!0===t.hidden),this.hidden!==e&&this.dispatchEvent(new CustomEvent("control_visibility_change",{bubbles:!0}))};static styles=i`
|
|
2
|
+
:host {
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
}
|
|
5
|
+
:host([hidden]) {
|
|
6
|
+
display: none !important;
|
|
7
|
+
}
|
|
8
|
+
::slotted(*) {
|
|
9
|
+
margin-top: -1px;
|
|
10
|
+
margin-bottom: -1px;
|
|
11
|
+
}
|
|
12
|
+
`;render(){return e`<slot></slot>`}}customElements.define("k-cec-group",s);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import t from"./CodeEditorControl.js";import{html as o,css as e}from"../../lit-all.min.js";import"../Icon.js";export default class s extends t{static styles=[t.styles,e`
|
|
2
|
+
:host {
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
}
|
|
5
|
+
`];handleClick=()=>{this.editor?.copyToClipboard()};render(){return o`
|
|
6
|
+
<button class="${this.buttonClasses}" @click="${this.handleClick}" title="Copy Code">
|
|
7
|
+
<k-icon name="content_copy"></k-icon>
|
|
8
|
+
</button>
|
|
9
|
+
`}}customElements.define("k-cec-copy-code",s);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import e from"./CodeEditorControl.js";import{html as t,css as o}from"../../lit-all.min.js";import"../Icon.js";export default class i extends e{static properties={value:{type:String,state:!0}};constructor(){super(),this.value="auto"}connectedCallback(){super.connectedCallback();const e=this.editor;e&&(this.value=e.editorTheme||"auto",this.themeHandler=e=>{this.value=e.detail.editorTheme},e.addEventListener("editor-theme-changed",this.themeHandler))}disconnectedCallback(){super.disconnectedCallback(),this.editor?.removeEventListener("editor-theme-changed",this.themeHandler),this.themeHandler=null}handleChange=e=>{this.editor?.setEditorTheme(e.target.value)};static styles=[e.styles,o`
|
|
2
|
+
:host {
|
|
3
|
+
background-color: var(--input_bg);
|
|
4
|
+
color: var(--input_tc);
|
|
5
|
+
border: var(--input_border_width) solid var(--c_input_border);
|
|
6
|
+
border-radius: var(--radius);
|
|
7
|
+
transition: box-shadow var(--animation_ms);
|
|
8
|
+
position: relative;
|
|
9
|
+
}
|
|
10
|
+
k-icon {
|
|
11
|
+
pointer-events: none;
|
|
12
|
+
position: absolute;
|
|
13
|
+
left: 0.5rem;
|
|
14
|
+
}
|
|
15
|
+
select {
|
|
16
|
+
padding-left: 2rem;
|
|
17
|
+
border: 0;
|
|
18
|
+
}
|
|
19
|
+
`];render(){return t`
|
|
20
|
+
<k-icon name="contrast" style="font-size: 1.125rem; opacity: 0.7;"></k-icon>
|
|
21
|
+
<select .value=${this.value} @change=${this.handleChange} title="Editor Theme">
|
|
22
|
+
<option value="auto">Auto</option>
|
|
23
|
+
<option value="light">Light</option>
|
|
24
|
+
<option value="dark">Dark</option>
|
|
25
|
+
</select>
|
|
26
|
+
`}}customElements.define("k-cec-editor-theme",i);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import e from"./CodeEditorControl.js";import{html as t,css as i}from"../../lit-all.min.js";import"../Icon.js";export default class s extends e{static styles=[e.styles,i`
|
|
2
|
+
:host { display: inline-flex; }
|
|
3
|
+
`];handleClick=()=>{this.editor?.openFind()};render(){return t`
|
|
4
|
+
<button class="${this.buttonClasses}" @click="${this.handleClick}" title="Find & Replace">
|
|
5
|
+
<k-icon name="search"></k-icon>
|
|
6
|
+
</button>
|
|
7
|
+
`}}customElements.define("k-cec-find-replace",s);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import l from"./CodeEditorControl.js";import{html as t,css as o}from"../../lit-all.min.js";import"../Icon.js";export default class e extends l{static properties={folded:{type:Boolean,state:!0}};constructor(){super(),this.folded=!1}handleClick=()=>{this.folded=!this.folded,this.folded?this.editor?.foldAll():this.editor?.unfoldAll()};static styles=[l.styles,o`
|
|
2
|
+
:host { display: inline-flex; }
|
|
3
|
+
`];render(){return t`
|
|
4
|
+
<button class="${this.buttonClasses}" @click="${this.handleClick}" title="${this.folded?"Unfold All":"Fold All"}">
|
|
5
|
+
<k-icon name="${this.folded?"unfold_more":"unfold_less"}"></k-icon>
|
|
6
|
+
</button>
|
|
7
|
+
`}}customElements.define("k-cec-fold-all",e);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import e from"./CodeEditorControl.js";import{html as t,css as s}from"../../lit-all.min.js";import"../Icon.js";export default class n extends e{static styles=[e.styles,s`
|
|
2
|
+
:host {
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
gap: 0;
|
|
5
|
+
}
|
|
6
|
+
`];handleIncrease=()=>{this.editor?.increaseFontSize()};handleDecrease=()=>{this.editor?.decreaseFontSize()};render(){return t`
|
|
7
|
+
<button class="${this.buttonClasses}" @click="${this.handleDecrease}" title="Decrease Font Size">
|
|
8
|
+
<k-icon name="text_decrease"></k-icon>
|
|
9
|
+
</button>
|
|
10
|
+
<button class="${this.buttonClasses}" @click="${this.handleIncrease}" title="Increase Font Size">
|
|
11
|
+
<k-icon name="text_increase"></k-icon>
|
|
12
|
+
</button>
|
|
13
|
+
`}}customElements.define("k-cec-font-size",n);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import t from"./CodeEditorControl.js";import{html as e,css as o}from"../../lit-all.min.js";import"../Icon.js";export default class s extends t{static styles=[t.styles,o`
|
|
2
|
+
:host {
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
}
|
|
5
|
+
`];handleClick=()=>{this.editor?.formatCode()};render(){return e`
|
|
6
|
+
<button class="${this.buttonClasses}" @click="${this.handleClick}" title="Format Code">
|
|
7
|
+
<k-icon name="frame_source"></k-icon>
|
|
8
|
+
</button>
|
|
9
|
+
`}}customElements.define("k-cec-format-code",s);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import e from"./CodeEditorControl.js";import{html as l,css as s}from"../../lit-all.min.js";import"../Icon.js";export default class t extends e{static properties={fullscreen:{type:Boolean,state:!0}};constructor(){super(),this.fullscreen=!1}connectedCallback(){super.connectedCallback();const e=this.editor;e&&(this.fullscreen=e.fullscreen,this.fullscreenHandler=()=>{this.fullscreen=e.fullscreen},e.addEventListener("fullscreen-changed",this.fullscreenHandler))}disconnectedCallback(){super.disconnectedCallback(),this.editor?.removeEventListener("fullscreen-changed",this.fullscreenHandler),this.fullscreenHandler=null}updateModeVisibility(){}handleClick=()=>{this.editor?.toggleFullscreen()};static styles=[e.styles,s`
|
|
2
|
+
:host { display: inline-flex; }
|
|
3
|
+
button.active { background: var(--primary-bg, rgba(0,120,212,0.15)); }
|
|
4
|
+
`];render(){return l`
|
|
5
|
+
<button
|
|
6
|
+
class="${this.buttonClasses} ${this.fullscreen?"active":""}"
|
|
7
|
+
@click="${this.handleClick}"
|
|
8
|
+
title="${this.fullscreen?"Exit Fullscreen":"Fullscreen"}"
|
|
9
|
+
>
|
|
10
|
+
<k-icon name="${this.fullscreen?"fullscreen_exit":"fullscreen"}"></k-icon>
|
|
11
|
+
</button>
|
|
12
|
+
`}}customElements.define("k-cec-fullscreen",t);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import e from"./CodeEditorControl.js";import{html as a,css as t}from"../../lit-all.min.js";import"../Icon.js";const l=["javascript","typescript","html","css","json","markdown","python","java","csharp","cpp","go","rust","php","ruby","sql","xml","yaml","shell","plaintext"];export default class n extends e{static properties={value:{type:String,state:!0}};constructor(){super(),this.value="javascript"}connectedCallback(){super.connectedCallback();const e=this.editor;e&&(this.value=e.language||"javascript",this.languageHandler=e=>{this.value=e.detail.language},e.addEventListener("language-changed",this.languageHandler))}disconnectedCallback(){super.disconnectedCallback(),this.editor?.removeEventListener("language-changed",this.languageHandler),this.languageHandler=null}handleChange=e=>{this.editor?.setLanguage(e.target.value)};static styles=[e.styles,t`
|
|
2
|
+
:host {
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
padding: 0 0.25rem;
|
|
6
|
+
gap: 0.25rem;
|
|
7
|
+
background-color:
|
|
8
|
+
}
|
|
9
|
+
`];render(){return a`
|
|
10
|
+
<select .value=${this.value} @change=${this.handleChange} title="Language">
|
|
11
|
+
${l.map(e=>a`
|
|
12
|
+
<option value="${e}" ?selected=${this.value===e}>${e}</option>
|
|
13
|
+
`)}
|
|
14
|
+
</select>
|
|
15
|
+
`}}customElements.define("k-cec-language",n);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import i from"./CodeEditorControl.js";import{html as t,css as e}from"../../lit-all.min.js";import"../Icon.js";export default class n extends i{static properties={active:{type:Boolean,state:!0}};constructor(){super(),this.active=!1}connectedCallback(){super.connectedCallback();const i=this.editor;i&&(this.active=i.minimapEnabled,this.minimapHandler=i=>{this.active=i.detail.minimapEnabled},i.addEventListener("minimap-changed",this.minimapHandler))}disconnectedCallback(){super.disconnectedCallback(),this.editor?.removeEventListener("minimap-changed",this.minimapHandler),this.minimapHandler=null}handleClick=()=>{this.editor?.toggleMinimap()};static styles=[i.styles,e`
|
|
2
|
+
:host { display: inline-flex; }
|
|
3
|
+
button.active { background: var(--primary-bg, rgba(0,120,212,0.15)); }
|
|
4
|
+
`];render(){return t`
|
|
5
|
+
<button class="${this.buttonClasses} ${this.active?"active":""}" @click="${this.handleClick}" title="Toggle Minimap">
|
|
6
|
+
<k-icon name="map"></k-icon>
|
|
7
|
+
</button>
|
|
8
|
+
`}}customElements.define("k-cec-minimap",n);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import t from"./CodeEditorControl.js";import{html as e,css as o}from"../../lit-all.min.js";import"../Icon.js";export default class s extends t{static styles=[t.styles,o`
|
|
2
|
+
:host { display: inline-flex; }
|
|
3
|
+
`];handleClick=()=>{this.editor?.redo()};render(){return e`
|
|
4
|
+
<button class="${this.buttonClasses}" @click="${this.handleClick}" title="Redo">
|
|
5
|
+
<k-icon name="redo"></k-icon>
|
|
6
|
+
</button>
|
|
7
|
+
`}}customElements.define("k-cec-redo",s);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import t from"./CodeEditorControl.js";import{html as e,css as o}from"../../lit-all.min.js";import"../Icon.js";export default class s extends t{static styles=[t.styles,o`
|
|
2
|
+
:host { display: inline-flex; }
|
|
3
|
+
`];handleClick=()=>{this.editor?.undo()};render(){return e`
|
|
4
|
+
<button class="${this.buttonClasses}" @click="${this.handleClick}" title="Undo">
|
|
5
|
+
<k-icon name="undo"></k-icon>
|
|
6
|
+
</button>
|
|
7
|
+
`}}customElements.define("k-cec-undo",s);
|