@editora/core 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/A11yCheckerPlugin.native-CZKpi3uF.mjs +475 -0
- package/dist/A11yCheckerPlugin.native-CZKpi3uF.mjs.map +1 -0
- package/dist/AnchorPlugin.native-7es9PVZ9.mjs +340 -0
- package/dist/AnchorPlugin.native-7es9PVZ9.mjs.map +1 -0
- package/dist/BackgroundColorPlugin.native-Dip5uqTg.mjs +449 -0
- package/dist/BackgroundColorPlugin.native-Dip5uqTg.mjs.map +1 -0
- package/dist/BlockquotePlugin.native-JFmOLsxN.mjs +48 -0
- package/dist/BlockquotePlugin.native-JFmOLsxN.mjs.map +1 -0
- package/dist/BoldPlugin.native-BAzzoqU5.mjs +45 -0
- package/dist/BoldPlugin.native-BAzzoqU5.mjs.map +1 -0
- package/dist/CapitalizationPlugin.native-DOMsh5R7.mjs +79 -0
- package/dist/CapitalizationPlugin.native-DOMsh5R7.mjs.map +1 -0
- package/dist/ChecklistPlugin.native-Dccs3nLe.mjs +153 -0
- package/dist/ChecklistPlugin.native-Dccs3nLe.mjs.map +1 -0
- package/dist/ClearFormattingPlugin.native-BZPDHswo.mjs +27 -0
- package/dist/ClearFormattingPlugin.native-BZPDHswo.mjs.map +1 -0
- package/dist/CodePlugin.native-DD9xFIid.mjs +1679 -0
- package/dist/CodePlugin.native-DD9xFIid.mjs.map +1 -0
- package/dist/CodeSamplePlugin.native-DMbEdO9j.mjs +326 -0
- package/dist/CodeSamplePlugin.native-DMbEdO9j.mjs.map +1 -0
- package/dist/CommentsPlugin.native-2zQV8Ia4.mjs +473 -0
- package/dist/CommentsPlugin.native-2zQV8Ia4.mjs.map +1 -0
- package/dist/DirectionPlugin.native-Be7wCzkI.mjs +59 -0
- package/dist/DirectionPlugin.native-Be7wCzkI.mjs.map +1 -0
- package/dist/DocumentManagerPlugin.native-BvZL5CSG.mjs +116 -0
- package/dist/DocumentManagerPlugin.native-BvZL5CSG.mjs.map +1 -0
- package/dist/EmbedIframePlugin.native-ifr9KLdN.mjs +461 -0
- package/dist/EmbedIframePlugin.native-ifr9KLdN.mjs.map +1 -0
- package/dist/EmojisPlugin.native-D6mJSnSR.mjs +1033 -0
- package/dist/EmojisPlugin.native-D6mJSnSR.mjs.map +1 -0
- package/dist/FontFamilyPlugin.native-BzS_9qbM.mjs +106 -0
- package/dist/FontFamilyPlugin.native-BzS_9qbM.mjs.map +1 -0
- package/dist/FontSizePlugin.native-DkLMLPue.mjs +186 -0
- package/dist/FontSizePlugin.native-DkLMLPue.mjs.map +1 -0
- package/dist/FootnotePlugin.native-BciVc9W6.mjs +128 -0
- package/dist/FootnotePlugin.native-BciVc9W6.mjs.map +1 -0
- package/dist/FullscreenPlugin.native-ChXyxeNw.mjs +77 -0
- package/dist/FullscreenPlugin.native-ChXyxeNw.mjs.map +1 -0
- package/dist/HeadingPlugin.native-DrLYwQnQ.mjs +64 -0
- package/dist/HeadingPlugin.native-DrLYwQnQ.mjs.map +1 -0
- package/dist/HistoryPlugin.native-DoDRifCf.mjs +89 -0
- package/dist/HistoryPlugin.native-DoDRifCf.mjs.map +1 -0
- package/dist/IndentPlugin.native-CbFugPoi.mjs +133 -0
- package/dist/IndentPlugin.native-CbFugPoi.mjs.map +1 -0
- package/dist/ItalicPlugin.native-CQjjDyUL.mjs +43 -0
- package/dist/ItalicPlugin.native-CQjjDyUL.mjs.map +1 -0
- package/dist/LineHeightPlugin.native-CWQT2FIa.mjs +73 -0
- package/dist/LineHeightPlugin.native-CWQT2FIa.mjs.map +1 -0
- package/dist/LinkPlugin.native-BdAOV-iu.mjs +206 -0
- package/dist/LinkPlugin.native-BdAOV-iu.mjs.map +1 -0
- package/dist/ListPlugin.native-CLFU5AUQ.mjs +59 -0
- package/dist/ListPlugin.native-CLFU5AUQ.mjs.map +1 -0
- package/dist/MathPlugin.native-DE_ii-LA.mjs +182 -0
- package/dist/MathPlugin.native-DE_ii-LA.mjs.map +1 -0
- package/dist/MediaManagerPlugin.native-DaYFDzNM.mjs +533 -0
- package/dist/MediaManagerPlugin.native-DaYFDzNM.mjs.map +1 -0
- package/dist/MergeTagPlugin.native-CrxyThyn.mjs +178 -0
- package/dist/MergeTagPlugin.native-CrxyThyn.mjs.map +1 -0
- package/dist/PageBreakPlugin.native-DDjcDyRW.mjs +172 -0
- package/dist/PageBreakPlugin.native-DDjcDyRW.mjs.map +1 -0
- package/dist/PreviewPlugin.native-DBvfpmIv.mjs +322 -0
- package/dist/PreviewPlugin.native-DBvfpmIv.mjs.map +1 -0
- package/dist/PrintPlugin.native-BUpm52VJ.mjs +311 -0
- package/dist/PrintPlugin.native-BUpm52VJ.mjs.map +1 -0
- package/dist/SpecialCharactersPlugin.native-x7a2SWXc.mjs +731 -0
- package/dist/SpecialCharactersPlugin.native-x7a2SWXc.mjs.map +1 -0
- package/dist/SpellCheckPlugin.native-B7yTh0iE.mjs +465 -0
- package/dist/SpellCheckPlugin.native-B7yTh0iE.mjs.map +1 -0
- package/dist/StrikethroughPlugin.native-ChaZLaXw.mjs +43 -0
- package/dist/StrikethroughPlugin.native-ChaZLaXw.mjs.map +1 -0
- package/dist/TablePlugin.native-EEWXn1-s.mjs +491 -0
- package/dist/TablePlugin.native-EEWXn1-s.mjs.map +1 -0
- package/dist/TemplatePlugin.native-BlSn1c9h.mjs +564 -0
- package/dist/TemplatePlugin.native-BlSn1c9h.mjs.map +1 -0
- package/dist/TextAlignmentPlugin.native-CQIs1m7R.mjs +97 -0
- package/dist/TextAlignmentPlugin.native-CQIs1m7R.mjs.map +1 -0
- package/dist/TextColorPlugin.native-D6SmTglm.mjs +432 -0
- package/dist/TextColorPlugin.native-D6SmTglm.mjs.map +1 -0
- package/dist/UnderlinePlugin.native-QpIcK4L2.mjs +35 -0
- package/dist/UnderlinePlugin.native-QpIcK4L2.mjs.map +1 -0
- package/dist/core.css +1 -0
- package/dist/documentManager-irzj9n3V.mjs +37627 -0
- package/dist/documentManager-irzj9n3V.mjs.map +1 -0
- package/dist/editorContainerHelpers-C7kdWnS0.mjs +27 -0
- package/dist/editorContainerHelpers-C7kdWnS0.mjs.map +1 -0
- package/dist/editora.min.js +519 -4
- package/dist/editora.min.js.map +1 -0
- package/dist/editora.umd.js +519 -4
- package/dist/editora.umd.js.map +1 -0
- package/dist/index-BF5RBhL9.js +4 -0
- package/dist/index-BF5RBhL9.js.map +1 -0
- package/dist/index-BPsf460l.mjs +1243 -0
- package/dist/index-BPsf460l.mjs.map +1 -0
- package/dist/index.cjs.js +517 -4
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.es-CuicffkQ.mjs +6665 -0
- package/dist/index.es-CuicffkQ.mjs.map +1 -0
- package/dist/index.esm.js +1403 -122
- package/dist/index.esm.js.map +1 -0
- package/dist/plugin-loader.js +55 -0
- package/dist/plugin-loader.js.map +1 -0
- package/dist/purify.es-CKpwg8Tk.mjs +471 -0
- package/dist/purify.es-CKpwg8Tk.mjs.map +1 -0
- package/dist/webcomponent-core.js +1243 -0
- package/dist/webcomponent-core.js.map +1 -0
- package/dist/webcomponent-core.min.css +1 -0
- package/dist/webcomponent-core.min.js +597 -0
- package/dist/webcomponent-core.min.js.map +1 -0
- package/dist/webcomponent.cjs.js +2 -0
- package/dist/webcomponent.cjs.js.map +1 -0
- package/dist/webcomponent.esm.js +6 -0
- package/dist/webcomponent.esm.js.map +1 -0
- package/dist/webcomponent.js +1286 -0
- package/dist/webcomponent.js.map +1 -0
- package/dist/webcomponent.min.css +1 -0
- package/dist/webcomponent.min.js +4076 -0
- package/dist/webcomponent.min.js.map +1 -0
- package/package.json +64 -6
package/dist/editora.min.js
CHANGED
|
@@ -1,7 +1,522 @@
|
|
|
1
|
-
var Editora=(function(s){"use strict";class l{constructor(e,t,i){this.doc=e,this.selection=t,this.schema=i}static create(e,t){const i=t||e.node("doc",{},[e.node("paragraph")]);return new l(i,{anchor:0,head:0},e)}apply(e,t){return new l(e,t||this.selection,this.schema)}}class f{constructor(e){this.listeners=[],this.pluginManager=e;const t=e.buildSchema();this.state=l.create(t),this.commands=e.getCommands()}setState(e){this.state=e,this.listeners.forEach(t=>t(e))}onChange(e){return this.listeners.push(e),()=>{this.listeners=this.listeners.filter(t=>t!==e)}}execCommand(e){const t=this.commands[e];if(!t)return!1;const i=t(this.state);return i?(this.setState(i),!0):!1}setContent(e){this.setState(this.state.apply(e))}getContent(){return this.state.doc}}class g{constructor(e,t){this.nodes=new Map(Object.entries(e)),this.marks=new Map(Object.entries(t))}node(e,t,i){return{type:e,attrs:t,content:i}}text(e,t){return{type:"text",text:e,marks:t}}}class y{constructor(){this.plugins=[]}register(e){this.plugins.push(e)}buildSchema(){const e={},t={};return this.plugins.forEach(i=>{i.nodes&&Object.assign(e,i.nodes),i.marks&&Object.assign(t,i.marks)}),new g(e,t)}getCommands(){const e={};return this.plugins.forEach(t=>{t.commands&&Object.assign(e,t.commands)}),e}getToolbarItems(){return this.plugins.flatMap(e=>e.toolbar||[])}}class p{constructor(e){this.initialized=!1,this.plugin=e}initialize(e){if(this.initialized)return console.warn(`Plugin "${this.plugin.name}" already initialized`),!1;try{return this.context=e,this.plugin.context?.initialize&&this.plugin.context.initialize(),this.plugin.context?.onEditorReady&&e.provider&&this.plugin.context.onEditorReady(e),this.initialized=!0,!0}catch(t){return console.error(`Failed to initialize plugin "${this.plugin.name}":`,t),!1}}destroy(){if(!this.initialized)return!1;try{return this.plugin.context?.destroy&&this.plugin.context.destroy(),this.initialized=!1,this.context=void 0,!0}catch(e){return console.error(`Failed to destroy plugin "${this.plugin.name}":`,e),!1}}executeCommand(e,...t){if(!this.initialized)return console.warn(`Plugin "${this.plugin.name}" not initialized, cannot execute command "${e}"`),null;try{const i=this.plugin.commands?.[e];return i?i(...t):(console.warn(`Command "${e}" not found in plugin "${this.plugin.name}"`),null)}catch(i){return console.error(`Error executing command "${e}" in plugin "${this.plugin.name}":`,i),null}}getName(){return this.plugin.name}isInitialized(){return this.initialized}getPlugin(){return this.plugin}getContext(){return this.context}}function S(a){return new p(a)}class k{constructor(e){this.shortcuts=new Map,this.enabled=!0,this.isMac=typeof navigator<"u"&&navigator.platform.toUpperCase().indexOf("MAC")>=0,e?.enabled===!1&&(this.enabled=!1),this.registerDefaultShortcuts(),e?.shortcuts&&e.shortcuts.forEach(t=>this.registerShortcut(t)),e?.customShortcuts&&Object.values(e.customShortcuts).forEach(t=>{this.registerShortcut(t)})}registerDefaultShortcuts(){this.registerShortcut({key:"b",ctrl:!this.isMac,meta:this.isMac,command:"toggleBold",description:"Bold",preventDefault:!0}),this.registerShortcut({key:"i",ctrl:!this.isMac,meta:this.isMac,command:"toggleItalic",description:"Italic",preventDefault:!0}),this.registerShortcut({key:"u",ctrl:!this.isMac,meta:this.isMac,command:"toggleUnderline",description:"Underline",preventDefault:!0}),this.registerShortcut({key:"d",ctrl:!this.isMac,meta:this.isMac,command:"toggleStrikethrough",description:"Strikethrough",preventDefault:!0}),this.registerShortcut({key:"z",ctrl:!this.isMac,meta:this.isMac,command:"undo",description:"Undo",preventDefault:!0}),this.registerShortcut({key:"z",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"redo",description:"Redo",preventDefault:!0}),this.registerShortcut({key:"y",ctrl:!this.isMac,meta:this.isMac,command:"redo",description:"Redo",preventDefault:!0});for(let e=1;e<=6;e++)this.registerShortcut({key:String(e),ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"setBlockType",params:`h${e}`,description:`Heading ${e}`,preventDefault:!0});this.registerShortcut({key:"7",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"setBlockType",params:"p",description:"Paragraph",preventDefault:!0}),this.registerShortcut({key:"7",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleOrderedList",description:"Numbered List",preventDefault:!0}),this.registerShortcut({key:"8",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleBulletList",description:"Bullet List",preventDefault:!0}),this.registerShortcut({key:"k",ctrl:!this.isMac,meta:this.isMac,command:"openLinkDialog",description:"Insert/Edit Link",preventDefault:!0}),this.registerShortcut({key:"e",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"insertCodeBlock",description:"Code Block",preventDefault:!0}),this.registerShortcut({key:"q",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleBlockquote",description:"Blockquote",preventDefault:!0}),this.registerShortcut({key:"l",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"setTextAlignment",params:"left",description:"Align Left",preventDefault:!0}),this.registerShortcut({key:"e",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"setTextAlignment",params:"center",description:"Align Center",preventDefault:!0}),this.registerShortcut({key:"r",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"setTextAlignment",params:"right",description:"Align Right",preventDefault:!0}),this.registerShortcut({key:"j",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"setTextAlignment",params:"justify",description:"Justify",preventDefault:!0}),this.registerShortcut({key:"\\",ctrl:!this.isMac,meta:this.isMac,command:"clearFormatting",description:"Clear Formatting",preventDefault:!0}),this.registerShortcut({key:"]",ctrl:!this.isMac,meta:this.isMac,command:"increaseIndent",description:"Indent",preventDefault:!0}),this.registerShortcut({key:"[",ctrl:!this.isMac,meta:this.isMac,command:"decreaseIndent",description:"Outdent",preventDefault:!0}),this.registerShortcut({key:"g",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"insertImage",description:"Insert Image",preventDefault:!0}),this.registerShortcut({key:"t",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"insertTable",description:"Insert Table",preventDefault:!0}),this.registerShortcut({key:"f11",command:"toggleFullscreen",description:"Toggle Fullscreen",preventDefault:!0}),this.registerShortcut({key:"p",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"togglePreview",description:"Preview",preventDefault:!0}),this.registerShortcut({key:"p",ctrl:!this.isMac,meta:this.isMac,command:"print",description:"Print",preventDefault:!0}),this.registerShortcut({key:"s",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"insertSpecialCharacter",description:"Insert Special Character",preventDefault:!0}),this.registerShortcut({key:"m",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"insertEmoji",description:"Insert Emoji",preventDefault:!0}),this.registerShortcut({key:"9",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleChecklist",description:"Checklist",preventDefault:!0}),this.registerShortcut({key:"a",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"toggleA11yChecker",description:"Accessibility Checker",preventDefault:!0}),this.registerShortcut({key:"F7",command:"toggleSpellCheck",description:"Spell Check",preventDefault:!0}),this.registerShortcut({key:"m",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"insertMath",description:"Insert Math",preventDefault:!0}),this.registerShortcut({key:"f",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"insertFootnote",description:"Insert Footnote",preventDefault:!0})}registerShortcut(e){const t=this.getShortcutKey(e);this.shortcuts.set(t,e)}unregisterShortcut(e){const t=this.getShortcutKey(e);this.shortcuts.delete(t)}getShortcutKey(e){const t=[];return e.ctrl&&t.push("ctrl"),e.alt&&t.push("alt"),e.shift&&t.push("shift"),e.meta&&t.push("meta"),t.push(e.key.toLowerCase()),t.join("+")}getEventKey(e){const t=[];return e.ctrlKey&&t.push("ctrl"),e.altKey&&t.push("alt"),e.shiftKey&&t.push("shift"),e.metaKey&&t.push("meta"),t.push(e.key.toLowerCase()),t.join("+")}handleKeyDown(e,t){if(!this.enabled)return!1;const i=this.getEventKey(e),r=this.shortcuts.get(i);return r?(r.preventDefault!==!1&&(e.preventDefault(),e.stopPropagation()),t(r.command,r.params),!0):!1}enable(){this.enabled=!0}disable(){this.enabled=!1}isEnabled(){return this.enabled}getAllShortcuts(){return Array.from(this.shortcuts.values())}getShortcutForCommand(e){return Array.from(this.shortcuts.values()).find(t=>t.command===e)}getShortcutDescription(e){const t=[];this.isMac?(e.meta&&t.push("⌘"),e.ctrl&&t.push("⌃"),e.alt&&t.push("⌥"),e.shift&&t.push("⇧")):(e.ctrl&&t.push("Ctrl"),e.alt&&t.push("Alt"),e.shift&&t.push("Shift"));const i=e.key.length===1?e.key.toUpperCase():e.key;return t.push(i),t.join("+")}getShortcutsHelp(){const e=this.getAllShortcuts(),t=new Map;e.forEach(r=>{const c=this.getShortcutCategory(r.command);t.has(c)||t.set(c,[]),t.get(c).push(r)});let i=`# Keyboard Shortcuts
|
|
1
|
+
var Editora=(function(c){"use strict";class y{constructor(t,e,i){this.doc=t,this.selection=e,this.schema=i}static create(t,e){const i=e||t.node("doc",{},[t.node("paragraph")]);return new y(i,{anchor:0,head:0},t)}apply(t,e){return new y(t,e||this.selection,this.schema)}}class S{constructor(t,e){this.nodes=new Map(Object.entries(t)),this.marks=new Map(Object.entries(e))}node(t,e,i){return{type:t,attrs:e,content:i}}text(t,e){return{type:"text",text:t,marks:e}}}class v{constructor(){this.plugins=[],this.pluginConfigs=new Map}register(t,e){if(this.plugins.push(t),e&&this.pluginConfigs.set(t.name,e),t.initialize){const i=this.pluginConfigs.get(t.name)||t.config;t.initialize(i)}}unregister(t){const e=this.plugins.findIndex(i=>i.name===t);if(e>-1){const i=this.plugins[e];i.destroy&&i.destroy(),this.plugins.splice(e,1),this.pluginConfigs.delete(t)}}getPlugin(t){return this.plugins.find(e=>e.name===t)}getPluginConfig(t){return this.pluginConfigs.get(t)}buildSchema(){const t={},e={};return this.plugins.forEach(i=>{i.nodes&&Object.assign(t,i.nodes),i.marks&&Object.assign(e,i.marks)}),new S(t,e)}getCommands(){const t={};return this.plugins.forEach(e=>{e.commands&&Object.assign(t,e.commands)}),t}getToolbarItems(){return this.plugins.flatMap(t=>t.toolbar||[])}async executePluginCommand(t,e,...i){const o=this.getPlugin(t);if(!o)throw new Error(`Plugin not found: ${t}`);const n=this.getPluginConfig(t)||o.config||{},r=n.mode||"local";try{switch(r){case"local":return o.executeLocal?o.executeLocal(e,...i):null;case"api":if(!o.executeAPI)throw new Error(`Plugin ${t} does not support API mode`);return await o.executeAPI(e,...i);case"hybrid":if(o.executeHybrid)return await o.executeHybrid(e,...i);try{if(o.executeAPI)return await o.executeAPI(e,...i)}catch(s){if(console.warn(`API execution failed for ${t}, falling back to local`,s),o.executeLocal&&n.fallbackToLocal!==!1)return o.executeLocal(e,...i);throw s}break;default:throw new Error(`Unknown plugin mode: ${r}`)}}catch(s){throw console.error(`Error executing command ${e} on plugin ${t}:`,s),s}}async destroyAll(){const t=this.plugins.filter(e=>e.destroy).map(e=>e.destroy());await Promise.all(t),this.plugins=[],this.pluginConfigs.clear()}}class z{constructor(t){if(this.listeners=[],t instanceof v)this.pluginManager=t;else{const i=t;this.pluginManager=new v,i.plugins&&Array.isArray(i.plugins)&&i.plugins.forEach(o=>{this.pluginManager.register(o)}),i.element&&(this.domElement=i.element,this.setupDOMElement(i))}const e=this.pluginManager.buildSchema();this.state=y.create(e),this.commands=this.pluginManager.getCommands()}setupDOMElement(t){this.domElement&&(t.enableToolbar!==!1&&t.toolbarElement?this.toolbarElement=t.toolbarElement:t.enableToolbar!==!1&&(this.toolbarElement=document.createElement("div"),this.toolbarElement.className="editora-toolbar-container",this.domElement.appendChild(this.toolbarElement)),this.contentElement=document.createElement("div"),this.contentElement.contentEditable="true",this.contentElement.className="editora-content",this.contentElement.style.minHeight="200px",this.contentElement.style.outline="none",this.contentElement.style.padding="12px",t.content&&(this.contentElement.innerHTML=t.content),this.domElement.appendChild(this.contentElement),this.contentElement.addEventListener("input",()=>{this.listeners.forEach(e=>e(this.state))}))}setupKeyboardShortcuts(t){const e={};t.forEach(i=>{i.shortcut&&(e[i.shortcut.toLowerCase()]=i.command)}),document.addEventListener("keydown",i=>{if(this.contentElement!==document.activeElement&&!(document.activeElement instanceof HTMLElement&&document.activeElement.contentEditable==="true"))return;const o=[];(i.ctrlKey||i.metaKey)&&o.push("ctrl"),i.shiftKey&&o.push("shift"),i.altKey&&o.push("alt");const n=i.key.toLowerCase(),r=o.length>0?`${o.join("+")}+${n}`:n,s=e[r];s&&(i.preventDefault(),this.execCommand(s))})}handleToolbarCommand(t,e){const o=this.pluginManager.getToolbarItems().find(n=>n.id&&n.id===t||n.command===t);o&&(e!==void 0?this.execCommand(o.command,e):this.execCommand(o.command))}setState(t){this.state=t,this.listeners.forEach(e=>e(t))}onChange(t){return this.listeners.push(t),()=>{this.listeners=this.listeners.filter(e=>e!==t)}}on(t,e){return t==="change"||t==="input"?this.onChange(e):()=>{}}getElement(){return this.contentElement||this.domElement||null}execCommand(t,e){const i=this.commands[t];if(!i)return console.warn(`Command not found: ${t}`),!1;let o;return e!==void 0?o=i(this.state,e):o=i(this.state),o?(this.setState(o),!0):!1}setContent(t){typeof t=="string"?this.contentElement&&(this.contentElement.innerHTML=t):this.setState(this.state.apply(t))}getContent(){return this.contentElement?this.contentElement.innerHTML:this.state.doc}destroy(){this.listeners=[],this.contentElement&&this.contentElement.removeEventListener("input",()=>{})}}class L{constructor(t){this.initialized=!1,this.plugin=t}initialize(t){var e,i;if(this.initialized)return console.warn(`Plugin "${this.plugin.name}" already initialized`),!1;try{return this.context=t,(e=this.plugin.context)!=null&&e.initialize&&this.plugin.context.initialize(),(i=this.plugin.context)!=null&&i.onEditorReady&&t.provider&&this.plugin.context.onEditorReady(t),this.initialized=!0,!0}catch(o){return console.error(`Failed to initialize plugin "${this.plugin.name}":`,o),!1}}destroy(){var t;if(!this.initialized)return!1;try{return(t=this.plugin.context)!=null&&t.destroy&&this.plugin.context.destroy(),this.initialized=!1,this.context=void 0,!0}catch(e){return console.error(`Failed to destroy plugin "${this.plugin.name}":`,e),!1}}executeCommand(t,...e){var i;if(!this.initialized)return console.warn(`Plugin "${this.plugin.name}" not initialized, cannot execute command "${t}"`),null;try{const o=(i=this.plugin.commands)==null?void 0:i[t];return o?o(...e):(console.warn(`Command "${t}" not found in plugin "${this.plugin.name}"`),null)}catch(o){return console.error(`Error executing command "${t}" in plugin "${this.plugin.name}":`,o),null}}getName(){return this.plugin.name}isInitialized(){return this.initialized}getPlugin(){return this.plugin}getContext(){return this.context}}function N(a){return new L(a)}class q{constructor(t){this.shortcuts=new Map,this.enabled=!0,this.isMac=typeof navigator!="undefined"&&navigator.platform.toUpperCase().indexOf("MAC")>=0,(t==null?void 0:t.enabled)===!1&&(this.enabled=!1),this.registerDefaultShortcuts(),t!=null&&t.shortcuts&&t.shortcuts.forEach(e=>this.registerShortcut(e)),t!=null&&t.customShortcuts&&Object.values(t.customShortcuts).forEach(e=>{this.registerShortcut(e)})}registerDefaultShortcuts(){this.registerShortcut({key:"b",ctrl:!this.isMac,meta:this.isMac,command:"toggleBold",description:"Bold",preventDefault:!0}),this.registerShortcut({key:"i",ctrl:!this.isMac,meta:this.isMac,command:"toggleItalic",description:"Italic",preventDefault:!0}),this.registerShortcut({key:"u",ctrl:!this.isMac,meta:this.isMac,command:"toggleUnderline",description:"Underline",preventDefault:!0}),this.registerShortcut({key:"d",ctrl:!this.isMac,meta:this.isMac,command:"toggleStrikethrough",description:"Strikethrough",preventDefault:!0}),this.registerShortcut({key:"z",ctrl:!this.isMac,meta:this.isMac,command:"undo",description:"Undo",preventDefault:!0}),this.registerShortcut({key:"z",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"redo",description:"Redo",preventDefault:!0}),this.registerShortcut({key:"y",ctrl:!this.isMac,meta:this.isMac,command:"redo",description:"Redo",preventDefault:!0});for(let t=1;t<=6;t++)this.registerShortcut({key:String(t),ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"setBlockType",params:`h${t}`,description:`Heading ${t}`,preventDefault:!0});this.registerShortcut({key:"7",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"setBlockType",params:"p",description:"Paragraph",preventDefault:!0}),this.registerShortcut({key:"7",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleOrderedList",description:"Numbered List",preventDefault:!0}),this.registerShortcut({key:"8",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleBulletList",description:"Bullet List",preventDefault:!0}),this.registerShortcut({key:"k",ctrl:!this.isMac,meta:this.isMac,command:"openLinkDialog",description:"Insert/Edit Link",preventDefault:!0}),this.registerShortcut({key:"e",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"insertCodeBlock",description:"Code Block",preventDefault:!0}),this.registerShortcut({key:"q",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleBlockquote",description:"Blockquote",preventDefault:!0}),this.registerShortcut({key:"l",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"setTextAlignment",params:"left",description:"Align Left",preventDefault:!0}),this.registerShortcut({key:"e",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"setTextAlignment",params:"center",description:"Align Center",preventDefault:!0}),this.registerShortcut({key:"r",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"setTextAlignment",params:"right",description:"Align Right",preventDefault:!0}),this.registerShortcut({key:"j",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"setTextAlignment",params:"justify",description:"Justify",preventDefault:!0}),this.registerShortcut({key:"\\",ctrl:!this.isMac,meta:this.isMac,command:"clearFormatting",description:"Clear Formatting",preventDefault:!0}),this.registerShortcut({key:"]",ctrl:!this.isMac,meta:this.isMac,command:"increaseIndent",description:"Indent",preventDefault:!0}),this.registerShortcut({key:"[",ctrl:!this.isMac,meta:this.isMac,command:"decreaseIndent",description:"Outdent",preventDefault:!0}),this.registerShortcut({key:"g",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"insertImage",description:"Insert Image",preventDefault:!0}),this.registerShortcut({key:"t",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"insertTable",description:"Insert Table",preventDefault:!0}),this.registerShortcut({key:"f11",command:"toggleFullscreen",description:"Toggle Fullscreen",preventDefault:!0}),this.registerShortcut({key:"p",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"togglePreview",description:"Preview",preventDefault:!0}),this.registerShortcut({key:"p",ctrl:!this.isMac,meta:this.isMac,command:"print",description:"Print",preventDefault:!0}),this.registerShortcut({key:"s",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"insertSpecialCharacter",description:"Insert Special Character",preventDefault:!0}),this.registerShortcut({key:"m",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"insertEmoji",description:"Insert Emoji",preventDefault:!0}),this.registerShortcut({key:"9",ctrl:!this.isMac,meta:this.isMac,shift:!0,command:"toggleChecklist",description:"Checklist",preventDefault:!0}),this.registerShortcut({key:"a",ctrl:!this.isMac,meta:this.isMac,shift:!0,alt:!0,command:"toggleA11yChecker",description:"Accessibility Checker",preventDefault:!0}),this.registerShortcut({key:"F7",command:"toggleSpellCheck",description:"Spell Check",preventDefault:!0}),this.registerShortcut({key:"m",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"insertMath",description:"Insert Math",preventDefault:!0}),this.registerShortcut({key:"f",ctrl:!this.isMac,meta:this.isMac,alt:!0,command:"insertFootnote",description:"Insert Footnote",preventDefault:!0})}registerShortcut(t){const e=this.getShortcutKey(t);this.shortcuts.set(e,t)}unregisterShortcut(t){const e=this.getShortcutKey(t);this.shortcuts.delete(e)}getShortcutKey(t){const e=[];return t.ctrl&&e.push("ctrl"),t.alt&&e.push("alt"),t.shift&&e.push("shift"),t.meta&&e.push("meta"),e.push(t.key.toLowerCase()),e.join("+")}getEventKey(t){const e=[];return t.ctrlKey&&e.push("ctrl"),t.altKey&&e.push("alt"),t.shiftKey&&e.push("shift"),t.metaKey&&e.push("meta"),e.push(t.key.toLowerCase()),e.join("+")}handleKeyDown(t,e){if(!this.enabled)return!1;const i=this.getEventKey(t),o=this.shortcuts.get(i);return o?(o.preventDefault!==!1&&(t.preventDefault(),t.stopPropagation()),e(o.command,o.params),!0):!1}enable(){this.enabled=!0}disable(){this.enabled=!1}isEnabled(){return this.enabled}getAllShortcuts(){return Array.from(this.shortcuts.values())}getShortcutForCommand(t){return Array.from(this.shortcuts.values()).find(e=>e.command===t)}getShortcutDescription(t){const e=[];this.isMac?(t.meta&&e.push("⌘"),t.ctrl&&e.push("⌃"),t.alt&&e.push("⌥"),t.shift&&e.push("⇧")):(t.ctrl&&e.push("Ctrl"),t.alt&&e.push("Alt"),t.shift&&e.push("Shift"));const i=t.key.length===1?t.key.toUpperCase():t.key;return e.push(i),e.join("+")}getShortcutsHelp(){const t=this.getAllShortcuts(),e=new Map;t.forEach(o=>{const n=this.getShortcutCategory(o.command);e.has(n)||e.set(n,[]),e.get(n).push(o)});let i=`# Keyboard Shortcuts
|
|
2
2
|
|
|
3
|
-
`;return
|
|
3
|
+
`;return e.forEach((o,n)=>{i+=`## ${n}
|
|
4
4
|
|
|
5
|
-
`,
|
|
5
|
+
`,o.forEach(r=>{const s=this.getShortcutDescription(r);i+=`- **${s}**: ${r.description||r.command}
|
|
6
6
|
`}),i+=`
|
|
7
|
-
`}),i}getShortcutCategory(e){return e.includes("toggle")&&(e.includes("Bold")||e.includes("Italic")||e.includes("Underline")||e.includes("Strike")||e.includes("Code")||e.includes("Super")||e.includes("Sub"))?"Text Formatting":e.includes("Heading")||e.includes("Paragraph")?"Block Formatting":e.includes("List")||e.includes("Checklist")?"Lists":e.includes("Alignment")||e.includes("Indent")?"Alignment & Indentation":e.includes("undo")||e.includes("redo")?"History":e.includes("insert")?"Insert":e.includes("find")||e.includes("replace")?"Find & Replace":e.includes("Accessibility")||e.includes("spell")?"Tools":"Other"}}function M(a={}){const{enabled:e=!1,provider:t="browser",apiUrl:i="",apiHeaders:r={},language:c="en",customDictionary:o=[],ignoreAllCaps:u=!0,ignoreNumbers:v=!0}=a;return{name:"spellcheck",context:{initialize:()=>{if(e)switch(console.log("[Spellcheck Plugin] Initialized",{provider:t,language:c}),t){case"browser":console.log("[Spellcheck] Using browser spellcheck");break;case"local":console.log("[Spellcheck] Using local dictionary (not implemented)");break;case"api":i?console.log("[Spellcheck] Using API:",i):console.warn("[Spellcheck] API provider selected but no apiUrl provided");break}},destroy:()=>{console.log("[Spellcheck Plugin] Destroyed")},onEditorReady:h=>{console.log("[Spellcheck Plugin] Editor ready")}},commands:{toggleSpellcheck:()=>(console.log("[Spellcheck] Toggle command (not implemented)"),null),addToDictionary:h=>(console.log("[Spellcheck] Add to dictionary:",h),null),checkSpelling:async()=>(console.log("[Spellcheck] Check spelling (not implemented)"),null)},toolbar:e?[{label:"Spellcheck",command:"toggleSpellcheck",icon:"Aa",type:"button"}]:[]}}function b(a={}){const{uploadUrl:e="",libraryUrl:t="",maxFileSize:i=10485760,allowedTypes:r=["image/jpeg","image/png","image/gif","image/webp"],headers:c={},withCredentials:o=!1,chunkSize:u=1048576,enableChunking:v=!0,onProgress:h,onError:m,onSuccess:D}=a;return{name:"media",context:{initialize:()=>{console.log("[Media Plugin] Initialized",{uploadUrl:e,libraryUrl:t,maxFileSize:i,allowedTypes:r}),e||console.warn("[Media] No uploadUrl provided - upload will not work")},destroy:()=>{console.log("[Media Plugin] Destroyed")},onEditorReady:n=>{console.log("[Media Plugin] Editor ready")}},commands:{insertImage:async n=>{if(console.log("[Media] Insert image command (not implemented)",n),!n)return console.log("[Media] No file provided - should open picker"),null;if(!r.includes(n.type)){const d=new Error(`File type ${n.type} not allowed`);return m?.(d),null}if(n.size>i){const d=new Error(`File size ${n.size} exceeds max ${i}`);return m?.(d),null}return null},openMediaLibrary:()=>(console.log("[Media] Open media library (not implemented)"),t||console.warn("[Media] No libraryUrl provided"),null),uploadMedia:async n=>(console.log("[Media] Upload media (not implemented)",{name:n.name,size:n.size,type:n.type}),null)},toolbar:[{label:"Image",command:"insertImage",icon:"🖼️",type:"button"},{label:"Media Library",command:"openMediaLibrary",icon:"📁",type:"button"}]}}return s.Editor=f,s.EditorState=l,s.KeyboardShortcutManager=k,s.PluginManager=y,s.PluginRuntime=p,s.Schema=g,s.createMediaPlugin=b,s.createPluginRuntime=S,s.createSpellcheckPlugin=M,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"}),s})({});
|
|
7
|
+
`}),i}getShortcutCategory(t){return t.includes("toggle")&&(t.includes("Bold")||t.includes("Italic")||t.includes("Underline")||t.includes("Strike")||t.includes("Code")||t.includes("Super")||t.includes("Sub"))?"Text Formatting":t.includes("Heading")||t.includes("Paragraph")?"Block Formatting":t.includes("List")||t.includes("Checklist")?"Lists":t.includes("Alignment")||t.includes("Indent")?"Alignment & Indentation":t.includes("undo")||t.includes("redo")?"History":t.includes("insert")?"Insert":t.includes("find")||t.includes("replace")?"Find & Replace":t.includes("Accessibility")||t.includes("spell")?"Tools":"Other"}}function R(a={}){const{enabled:t=!1,provider:e="browser",apiUrl:i="",apiHeaders:o={},language:n="en",customDictionary:r=[],ignoreAllCaps:s=!0,ignoreNumbers:l=!0}=a;return{name:"spellcheck",context:{initialize:()=>{if(t)switch(console.log("[Spellcheck Plugin] Initialized",{provider:e,language:n}),e){case"browser":console.log("[Spellcheck] Using browser spellcheck");break;case"local":console.log("[Spellcheck] Using local dictionary (not implemented)");break;case"api":i?console.log("[Spellcheck] Using API:",i):console.warn("[Spellcheck] API provider selected but no apiUrl provided");break}},destroy:()=>{console.log("[Spellcheck Plugin] Destroyed")},onEditorReady:m=>{console.log("[Spellcheck Plugin] Editor ready")}},commands:{toggleSpellcheck:()=>(console.log("[Spellcheck] Toggle command (not implemented)"),null),addToDictionary:m=>(console.log("[Spellcheck] Add to dictionary:",m),null),checkSpelling:async()=>(console.log("[Spellcheck] Check spelling (not implemented)"),null)},toolbar:t?[{label:"Spellcheck",command:"toggleSpellcheck",icon:"Aa",type:"button"}]:[]}}function B(a={}){const{uploadUrl:t="",libraryUrl:e="",maxFileSize:i=10485760,allowedTypes:o=["image/jpeg","image/png","image/gif","image/webp"],headers:n={},withCredentials:r=!1,chunkSize:s=1048576,enableChunking:l=!0,onProgress:m,onError:u,onSuccess:p}=a;return{name:"media",context:{initialize:()=>{console.log("[Media Plugin] Initialized",{uploadUrl:t,libraryUrl:e,maxFileSize:i,allowedTypes:o}),t||console.warn("[Media] No uploadUrl provided - upload will not work")},destroy:()=>{console.log("[Media Plugin] Destroyed")},onEditorReady:d=>{console.log("[Media Plugin] Editor ready")}},commands:{insertImage:async d=>{if(console.log("[Media] Insert image command (not implemented)",d),!d)return console.log("[Media] No file provided - should open picker"),null;if(!o.includes(d.type)){const h=new Error(`File type ${d.type} not allowed`);return u==null||u(h),null}if(d.size>i){const h=new Error(`File size ${d.size} exceeds max ${i}`);return u==null||u(h),null}return null},openMediaLibrary:()=>(console.log("[Media] Open media library (not implemented)"),e||console.warn("[Media] No libraryUrl provided"),null),uploadMedia:async d=>(console.log("[Media] Upload media (not implemented)",{name:d.name,size:d.size,type:d.type}),null)},toolbar:[{label:"Image",command:"insertImage",icon:"🖼️",type:"button"},{label:"Media Library",command:"openMediaLibrary",icon:"📁",type:"button"}]}}class M{constructor(t={}){this.commands=new Map,Object.entries(t).forEach(([e,i])=>{this.register(e,i)})}register(t,e){this.commands.has(t)&&console.warn(`Command ${t} is being overwritten`),this.commands.set(t,e)}unregister(t){this.commands.delete(t)}get(t){return this.commands.get(t)}has(t){return this.commands.has(t)}getCommandNames(){return Array.from(this.commands.keys())}clear(){this.commands.clear()}}class w{constructor(t={}){this.listeners=new Map,this.isReadonly=!1,this.isDestroyed=!1,this.isReadonly=t.readonly||!1,this.pluginManager=new v,t.plugins&&Array.isArray(t.plugins)&&t.plugins.forEach(i=>this.pluginManager.register(i));const e=this.pluginManager.buildSchema();this.state=y.create(e),this.commandRegistry=new M(this.pluginManager.getCommands())}execCommand(t,e){if(this.isReadonly)return console.warn("Cannot execute commands in readonly mode"),!1;if(this.isDestroyed)return console.warn("Cannot execute commands on destroyed editor"),!1;const i=this.commandRegistry.get(t);if(!i)return console.warn(`Command not found: ${t}`),!1;let o;return e!==void 0?o=i(this.state,e):o=i(this.state),o?(this.setState(o),this.emit("change",this.state),!0):!1}setState(t){this.isDestroyed||(this.state=t,this.emit("stateChange",t))}getState(){return this.state}setReadonly(t){this.isReadonly=t,this.emit("readonlyChange",t)}isReadOnly(){return this.isReadonly}on(t,e){return this.listeners.has(t)||this.listeners.set(t,[]),this.listeners.get(t).push(e),()=>{const i=this.listeners.get(t);if(i){const o=i.indexOf(e);o>-1&&i.splice(o,1)}}}emit(t,...e){const i=this.listeners.get(t);i&&i.forEach(o=>{try{o(...e)}catch(n){console.error(`Error in ${t} handler:`,n)}})}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.listeners.clear(),this.emit("destroy"))}isEditorDestroyed(){return this.isDestroyed}}class x{constructor(t,e={anchor:0,head:0}){this.doc=t,this.selection=e}getDocument(){return this.doc}setDocument(t){return new x(t,this.selection)}getSelection(){return{...this.selection}}setSelection(t){return new x(this.doc,t)}update(t,e){return new x(t||this.doc,e||this.selection)}getTextContent(){return""}isSelectionEmpty(){return this.selection.anchor===this.selection.head}}class E{constructor(t,e,i){this.config=t,this.plugins=e,this.pluginLoader=i}setCommandHandler(t){this.commandHandler=t}parseToolbarString(t){const e=[],i=t.split("|").map(s=>s.trim()),o=this.getAvailableToolbarItems(),n=new Map;o.forEach(s=>{s.command&&n.set(s.command,s),s.type==="group"&&s.label&&n.set(s.label,s)});const r={bold:"toggleBold",italic:"toggleItalic",underline:"toggleUnderline",strikethrough:"toggleStrikethrough",bullist:"toggleBulletList",numlist:"toggleOrderedList",checklist:"toggleChecklist",link:"openLinkDialog",image:"openImageDialog",table:"insertTable",anchor:"insertAnchor",code:"toggleSourceView",blockquote:"toggleBlockquote",undo:"undo",redo:"redo",textColor:"openTextColorPicker",backgroundColor:"openBackgroundColorPicker",fontSize:"fontSize",fontFamily:"setFontFamily",lineHeight:"setLineHeight",heading:"setBlockType",paragraph:"setParagraph",textAlignment:"setTextAlignment",direction:"setDirectionLTR",indent:"increaseIndent",outdent:"decreaseIndent",capitalization:"setCapitalization",math:"insertMath",specialCharacters:"insertSpecialCharacter",emojis:"openEmojiDialog",embedIframe:"openEmbedIframeDialog",fullscreen:"toggleFullscreen",preview:"togglePreview",print:"print",a11yChecker:"toggleA11yChecker",spellCheck:"toggleSpellCheck",comments:"addComment",showHideComments:"toggleComments",toggleComments:"toggleComments",footnote:"insertFootnote",mergeTags:"insertMergeTag",pageBreak:"insertPageBreak",template:"insertTemplate",importWord:"importWord",exportWord:"exportWord",exportPdf:"exportPdf",insertImage:"insertImage",insertVideo:"insertVideo",codeBlock:"insertCodeBlock"};return i.forEach(s=>{const l=[];s.split(/\s+/).filter(Boolean).forEach(u=>{if(u==="direction"){const h=n.get("setDirectionLTR"),g=n.get("setDirectionRTL");h&&l.push({id:"directionLTR",label:h.label,command:h.command,icon:h.icon,type:h.type||"button",options:h.options}),g&&l.push({id:"directionRTL",label:g.label,command:g.command,icon:g.icon,type:g.type||"button",options:g.options});return}if(u==="comments"){const h=n.get("addComment"),g=n.get("toggleComments");h&&l.push({id:"addComment",label:h.label,command:h.command,icon:h.icon,type:h.type||"button",options:h.options}),g&&l.push({id:"toggleComments",label:g.label,command:g.command,icon:g.icon,type:g.type||"button",options:g.options});return}const p=r[u]||u;let d=n.get(p);d||(d=n.get(u)),d&&l.push({id:u,label:d.label,command:d.command,icon:d.icon,type:d.type==="separator"?"separator":d.type||"button",options:d.options,items:d.items})}),l.length>0&&e.push(l)}),e}getAvailableToolbarItems(){return this.plugins.flatMap(e=>e.toolbar||[])}render(t){this.container=t,t.innerHTML="",t.className="editora-toolbar",this.config.sticky&&t.classList.add("editora-toolbar-sticky"),this.config.position&&t.classList.add(`editora-toolbar-${this.config.position}`);const e=this.config.items||this.getDefaultToolbarString(),i=this.parseToolbarString(e);i.forEach((o,n)=>{const r=document.createElement("div");if(r.className="editora-toolbar-group",o.forEach(s=>{this.appendToolbarButton(r,s)}),t.appendChild(r),n<i.length-1){const s=document.createElement("div");s.className="editora-toolbar-separator",t.appendChild(s)}})}appendToolbarButton(t,e){if(e.type==="separator"){const i=document.createElement("div");i.className="editora-toolbar-separator",t.appendChild(i)}else if(e.type==="dropdown"){const i=this.createDropdown(e);t.appendChild(i)}else if(e.type==="inline-menu"){const i=this.createInlineMenu(e);t.appendChild(i)}else if(e.type==="group"&&e.items&&e.items.length){const i=this.createGroupButton(e);t.appendChild(i)}else if(e.type==="input"){const i=this.createInput(e);t.appendChild(i)}else{const i=this.createButton(e);t.appendChild(i)}}createGroupButton(t){const e=document.createElement("div");if(e.className="editora-toolbar-group-button",e.title=t.label,t.icon)if(t.icon.startsWith("<svg")&&t.icon.endsWith("</svg>")){const i=document.createElement("span");i.className="editora-toolbar-icon",i.innerHTML=t.icon,e.appendChild(i)}else e.innerHTML=t.icon;if(t.items&&t.items.length){const i=document.createElement("div");i.className="editora-toolbar-group-items",t.items.forEach(o=>{this.appendToolbarButton(i,o)}),e.appendChild(i)}return e}createInput(t){const e=document.createElement("input");return e.className=`editora-toolbar-input ${t.label.toLowerCase().replace(/\s+/g,"-")}`,e.type="text",e.title=t.label,e.placeholder=t.placeholder||"",e.setAttribute("data-command",t.command),t.active&&e.classList.add("active"),t.disabled&&(e.disabled=!0),e.addEventListener("click",i=>{i.preventDefault(),this.commandHandler&&this.commandHandler(t.command)}),e}createButton(t){const e=document.createElement("button");if(e.className="editora-toolbar-button",e.type="button",e.title=t.label,e.setAttribute("data-command",t.command),t.icon)if(t.icon.startsWith("<svg")&&t.icon.endsWith("</svg>")){const i=document.createElement("span");i.className="editora-toolbar-icon",i.innerHTML=t.icon,e.appendChild(i)}else e.innerHTML=t.icon;else e.textContent=t.label;return t.active&&e.classList.add("active"),t.disabled&&(e.disabled=!0),e.addEventListener("click",i=>{i.preventDefault(),this.commandHandler&&this.commandHandler(t.command)}),e}createDropdown(t){const e=document.createElement("div");e.className="editora-toolbar-dropdown";const i=document.createElement("button");i.className="editora-toolbar-button editora-toolbar-dropdown-trigger",i.type="button",i.textContent=t.label;const o=document.createElement("div");o.className="editora-toolbar-dropdown-menu",o.style.display="none",t.options&&t.options.forEach(r=>{const s=document.createElement("button");s.className="editora-toolbar-dropdown-item",s.type="button",s.textContent=r.label,s.setAttribute("data-value",r.value),s.addEventListener("click",l=>{l.preventDefault(),this.commandHandler&&this.commandHandler(t.command,r.value),o.style.display="none"}),o.appendChild(s)}),i.addEventListener("click",r=>{r.preventDefault(),r.stopPropagation();const s=o.style.display==="block";o.style.display=s?"none":"block"});const n=r=>{e.contains(r.target)||(o.style.display="none")};return document.addEventListener("click",n),e._cleanupDropdown=()=>{document.removeEventListener("click",n)},e.appendChild(i),e.appendChild(o),e}createInlineMenu(t){const e=document.createElement("div");e.className="editora-toolbar-dropdown editora-toolbar-inline-menu";const i=document.createElement("button");if(i.className="editora-toolbar-button",i.type="button",i.title=t.label,t.icon)if(t.icon.startsWith("<svg")&&t.icon.endsWith("</svg>")){const n=document.createElement("span");n.className="editora-toolbar-icon",n.innerHTML=t.icon,i.appendChild(n)}else i.innerHTML=t.icon;else i.textContent=t.label;const o=document.createElement("div");return o.className="editora-toolbar-dropdown-menu",o.style.display="none",t.options&&t.options.forEach(n=>{const r=document.createElement("button");r.className="editora-toolbar-dropdown-item",r.type="button",r.textContent=n.label,r.setAttribute("data-value",n.value),r.addEventListener("click",s=>{s.preventDefault(),s.stopPropagation(),this.commandHandler&&this.commandHandler(t.command,n.value),o.style.display="none"}),o.appendChild(r)}),i.addEventListener("click",n=>{var s;n.preventDefault(),n.stopPropagation();const r=(s=this.container)==null?void 0:s.querySelectorAll(".editora-toolbar-dropdown-menu");r==null||r.forEach(l=>{l!==o&&(l.style.display="none")}),o.style.display=o.style.display==="none"?"block":"none"}),document.addEventListener("click",n=>{e.contains(n.target)||(o.style.display="none")}),e.appendChild(i),e.appendChild(o),e}getDefaultToolbarString(){return this.getAvailableToolbarItems().map(e=>e.command).join(" ")}updateButtonState(t,e){if(!this.container)return;const i=this.container.querySelector(`[data-command="${t}"]`);i&&(e.active!==void 0&&i.classList.toggle("active",e.active),e.disabled!==void 0&&(i.disabled=e.disabled))}destroy(){this.container&&(this.container.querySelectorAll(".editora-toolbar-dropdown").forEach(e=>{const i=e._cleanupDropdown;i&&i()}),this.container.innerHTML=""),this.commandHandler=void 0}}class T{constructor(t){this.visible=!1,this.config=t}create(t){const e=document.createElement("div");return e.className="editora-floating-toolbar",e.style.display="none",e.style.position="absolute",e.style.zIndex="1000",this.container=e,t.appendChild(e),e}show(t,e){this.container&&(this.container.style.display="block",this.container.style.left=`${t}px`,this.container.style.top=`${e}px`,this.visible=!0)}hide(){this.container&&(this.container.style.display="none",this.visible=!1)}updatePosition(t,e){!this.container||!this.visible||(this.container.style.left=`${t}px`,this.container.style.top=`${e}px`)}isVisible(){return this.visible}destroy(){this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container),this.container=void 0,this.visible=!1}}class I{constructor(t={}){this.statusInfo={},this.config=t}create(t){const e=document.createElement("div");return e.className="editora-statusbar",this.config.position&&e.classList.add(`editora-statusbar-${this.config.position}`),this.container=e,t.appendChild(e),e}update(t){this.statusInfo={...this.statusInfo,...t},this.render()}render(){if(!this.container)return;this.container.innerHTML="";const t=document.createElement("div");t.className="editora-statusbar-left";const e=document.createElement("div");e.className="editora-statusbar-right";const i=[];if(this.statusInfo.selectionInfo){const n=this.statusInfo.selectionInfo;n.startLine===n.endLine&&n.startColumn===n.endColumn?i.push(`Ln ${n.startLine}, Col ${n.startColumn}`):(n.startLine===n.endLine?i.push(`Ln ${n.startLine}, Col ${n.startColumn}-${n.endColumn}`):i.push(`Ln ${n.startLine}:${n.startColumn} - ${n.endLine}:${n.endColumn}`),i.push(`${n.selectedChars} chars selected`))}else if(this.statusInfo.cursorPosition){const n=this.statusInfo.cursorPosition;i.push(`Ln ${n.line}, Col ${n.column}`)}this.statusInfo.language&&i.push(this.statusInfo.language);const o=[];this.statusInfo.wordCount!==void 0&&o.push(`${this.statusInfo.wordCount} words`),this.statusInfo.charCount!==void 0&&o.push(`${this.statusInfo.charCount} chars`),this.statusInfo.lineCount!==void 0&&o.push(`${this.statusInfo.lineCount} lines`),this.statusInfo.custom&&Object.entries(this.statusInfo.custom).forEach(([n,r])=>{o.push(`${n}: ${r}`)}),i.forEach((n,r)=>{const s=document.createElement("span");if(s.className="editora-statusbar-item",s.textContent=n,t.appendChild(s),r<i.length-1){const l=document.createElement("span");l.className="editora-statusbar-separator",l.textContent="|",t.appendChild(l)}}),o.forEach((n,r)=>{const s=document.createElement("span");if(s.className="editora-statusbar-item",s.textContent=n,e.appendChild(s),r<o.length-1){const l=document.createElement("span");l.className="editora-statusbar-separator",l.textContent="|",e.appendChild(l)}}),this.container.appendChild(t),this.container.appendChild(e)}destroy(){this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container),this.container=void 0}}class f{constructor(t){this.config={closeOnEscape:!0,closeOnBackdrop:!0,...t},this.element=this.createElement(),this.attachEventListeners()}createElement(){const t=document.createElement("dialog");if(t.className="editora-dialog",this.config.width&&(t.style.width=this.config.width),this.config.height&&(t.style.height=this.config.height),t.innerHTML=`
|
|
8
|
+
<div class="editora-dialog-container">
|
|
9
|
+
<div class="editora-dialog-header">
|
|
10
|
+
<h3>${this.config.title}</h3>
|
|
11
|
+
<button class="editora-dialog-close" aria-label="Close">×</button>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="editora-dialog-body">
|
|
14
|
+
${typeof this.config.content=="string"?this.config.content:""}
|
|
15
|
+
</div>
|
|
16
|
+
<div class="editora-dialog-footer">
|
|
17
|
+
<button type="button" class="editora-btn editora-btn-cancel">Cancel</button>
|
|
18
|
+
<button type="button" class="editora-btn editora-btn-primary">OK</button>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
`,typeof this.config.content!="string"){const e=t.querySelector(".editora-dialog-body");e&&(e.innerHTML="",e.appendChild(this.config.content))}return t}attachEventListeners(){const t=this.element.querySelector(".editora-dialog-close");t==null||t.addEventListener("click",()=>this.close());const e=this.element.querySelector(".editora-btn-cancel");e==null||e.addEventListener("click",()=>{var o,n;(n=(o=this.config).onCancel)==null||n.call(o),this.close()});const i=this.element.querySelector(".editora-btn-primary");i==null||i.addEventListener("click",()=>this.handleSubmit()),this.config.closeOnEscape&&this.element.addEventListener("cancel",o=>{o.preventDefault(),this.close()}),this.config.closeOnBackdrop&&this.element.addEventListener("click",o=>{const n=this.element.getBoundingClientRect();(o.clientX<n.left||o.clientX>n.right||o.clientY<n.top||o.clientY>n.bottom)&&this.close()})}handleSubmit(){var e,i,o,n;const t=this.element.querySelector("form");if(t){const r=new FormData(t);(i=(e=this.config).onSubmit)==null||i.call(e,r)}else{const r=this.element.querySelectorAll("input, select, textarea"),s=new FormData;r.forEach(l=>{l.name&&s.append(l.name,l.value)}),(n=(o=this.config).onSubmit)==null||n.call(o,s)}this.close()}show(){document.body.appendChild(this.element),this.element.showModal()}close(){this.element.close(),this.element.remove()}destroy(){this.close()}}class O{constructor(t){this.isOpen=!1,this.config=t,this.selectedValue=t.value,this.element=this.createElement(),this.attachEventListeners()}createElement(){const t=document.createElement("div");t.className="editora-dropdown",this.config.width&&(t.style.width=this.config.width);const e=this.config.options.find(o=>o.value===this.selectedValue),i=(e==null?void 0:e.label)||this.config.placeholder||"Select...";return t.innerHTML=`
|
|
22
|
+
<button class="editora-dropdown-toggle" type="button">
|
|
23
|
+
<span class="editora-dropdown-label">${i}</span>
|
|
24
|
+
<span class="editora-dropdown-arrow">▼</span>
|
|
25
|
+
</button>
|
|
26
|
+
<div class="editora-dropdown-menu" style="display: none;">
|
|
27
|
+
${this.config.options.map(o=>`
|
|
28
|
+
<div class="editora-dropdown-item" data-value="${o.value}">
|
|
29
|
+
${o.icon?`<span class="editora-dropdown-icon">${o.icon}</span>`:""}
|
|
30
|
+
<span>${o.label}</span>
|
|
31
|
+
</div>
|
|
32
|
+
`).join("")}
|
|
33
|
+
</div>
|
|
34
|
+
`,t}attachEventListeners(){const t=this.element.querySelector(".editora-dropdown-toggle"),e=this.element.querySelector(".editora-dropdown-menu");t.addEventListener("click",o=>{o.stopPropagation(),this.isOpen=!this.isOpen,e.style.display=this.isOpen?"block":"none"}),this.element.querySelectorAll(".editora-dropdown-item").forEach(o=>{o.addEventListener("click",()=>{var r,s;const n=o.getAttribute("data-value");n&&(this.setValue(n),(s=(r=this.config).onChange)==null||s.call(r,n),this.close())})}),document.addEventListener("click",o=>{this.element.contains(o.target)||this.close()})}setValue(t){this.selectedValue=t;const e=this.config.options.find(o=>o.value===t),i=this.element.querySelector(".editora-dropdown-label");i&&e&&(i.textContent=e.label)}getValue(){return this.selectedValue}close(){this.isOpen=!1;const t=this.element.querySelector(".editora-dropdown-menu");t&&(t.style.display="none")}getElement(){return this.element}destroy(){this.element.remove()}}class U{constructor(t){this.defaultPresets=["#000000","#434343","#666666","#999999","#B7B7B7","#CCCCCC","#D9D9D9","#EFEFEF","#F3F3F3","#FFFFFF","#980000","#FF0000","#FF9900","#FFFF00","#00FF00","#00FFFF","#4A86E8","#0000FF","#9900FF","#FF00FF","#E6B8AF","#F4CCCC","#FCE5CD","#FFF2CC","#D9EAD3","#D0E0E3","#C9DAF8","#CFE2F3","#D9D2E9","#EAD1DC"],this.config={presetColors:this.defaultPresets,...t},this.selectedColor=t.value,this.element=this.createElement(),this.attachEventListeners()}createElement(){var e;const t=document.createElement("div");return t.className="editora-color-picker",t.innerHTML=`
|
|
35
|
+
<div class="editora-color-picker-input">
|
|
36
|
+
<input type="color" value="${this.selectedColor||"#000000"}" />
|
|
37
|
+
<input type="text" value="${this.selectedColor||"#000000"}" placeholder="#000000" />
|
|
38
|
+
</div>
|
|
39
|
+
<div class="editora-color-picker-presets">
|
|
40
|
+
${(e=this.config.presetColors)==null?void 0:e.map(i=>`
|
|
41
|
+
<button
|
|
42
|
+
class="editora-color-preset"
|
|
43
|
+
style="background-color: ${i};"
|
|
44
|
+
data-color="${i}"
|
|
45
|
+
title="${i}"
|
|
46
|
+
></button>
|
|
47
|
+
`).join("")}
|
|
48
|
+
</div>
|
|
49
|
+
`,t}attachEventListeners(){const t=this.element.querySelector('input[type="color"]'),e=this.element.querySelector('input[type="text"]');t.addEventListener("input",o=>{var r,s;const n=o.target.value;e.value=n,this.selectedColor=n,(s=(r=this.config).onChange)==null||s.call(r,n)}),e.addEventListener("input",o=>{var r,s;const n=o.target.value;/^#[0-9A-Fa-f]{6}$/.test(n)&&(t.value=n,this.selectedColor=n,(s=(r=this.config).onChange)==null||s.call(r,n))}),this.element.querySelectorAll(".editora-color-preset").forEach(o=>{o.addEventListener("click",()=>{var r,s;const n=o.getAttribute("data-color");n&&(t.value=n,e.value=n,this.selectedColor=n,(s=(r=this.config).onChange)==null||s.call(r,n))})})}getValue(){return this.selectedColor}setValue(t){this.selectedColor=t;const e=this.element.querySelector('input[type="color"]'),i=this.element.querySelector('input[type="text"]');e&&(e.value=t),i&&(i.value=t)}getElement(){return this.element}destroy(){this.element.remove()}}class W{constructor(t){const{initialUrl:e="",initialText:i="",onSubmit:o,onCancel:n}=t;this.dialog=new f({title:"Insert/Edit Link",content:this.createFormHTML(e,i),onSubmit:r=>{const s=(r.get("url")||"").trim(),l=(r.get("text")||"").trim(),m=r.get("openInNewTab")==="on";if(!s){alert("Please enter a URL");return}o({url:s,text:l,openInNewTab:m}),this.dialog.close()},onCancel:()=>{n==null||n(),this.dialog.close()},width:"500px"})}createFormHTML(t,e){return`
|
|
50
|
+
<form class="link-dialog-form">
|
|
51
|
+
<div class="form-group">
|
|
52
|
+
<label for="link-url">URL</label>
|
|
53
|
+
<input
|
|
54
|
+
type="url"
|
|
55
|
+
id="link-url"
|
|
56
|
+
name="url"
|
|
57
|
+
placeholder="https://example.com"
|
|
58
|
+
value="${this.escapeHtml(t)}"
|
|
59
|
+
required
|
|
60
|
+
autofocus
|
|
61
|
+
/>
|
|
62
|
+
<small>Enter the web address (URL) for the link</small>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
<div class="form-group">
|
|
66
|
+
<label for="link-text">Link Text</label>
|
|
67
|
+
<input
|
|
68
|
+
type="text"
|
|
69
|
+
id="link-text"
|
|
70
|
+
name="text"
|
|
71
|
+
placeholder="Click here"
|
|
72
|
+
value="${this.escapeHtml(e)}"
|
|
73
|
+
/>
|
|
74
|
+
<small>Text to display for the link (leave empty to use URL)</small>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
<div class="form-group">
|
|
78
|
+
<label class="checkbox-label">
|
|
79
|
+
<input
|
|
80
|
+
type="checkbox"
|
|
81
|
+
name="openInNewTab"
|
|
82
|
+
id="link-new-tab"
|
|
83
|
+
/>
|
|
84
|
+
<span>Open link in new tab</span>
|
|
85
|
+
</label>
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<div class="form-actions">
|
|
89
|
+
<button type="button" class="btn btn-secondary" data-action="cancel">
|
|
90
|
+
Cancel
|
|
91
|
+
</button>
|
|
92
|
+
<button type="submit" class="btn btn-primary">
|
|
93
|
+
Insert Link
|
|
94
|
+
</button>
|
|
95
|
+
</div>
|
|
96
|
+
</form>
|
|
97
|
+
`}escapeHtml(t){const e=document.createElement("div");return e.textContent=t,e.innerHTML}show(){this.dialog.show()}close(){this.dialog.close()}}class G{constructor(t){const{onSubmit:e,onCancel:i}=t;this.dialog=new f({title:"Insert Table",content:this.createFormHTML(),onSubmit:o=>{const n=parseInt(o.get("rows"),10),r=parseInt(o.get("cols"),10),s=o.get("headerRow")==="on";if(n<1||n>100){alert("Please enter a valid number of rows (1-100)");return}if(r<1||r>20){alert("Please enter a valid number of columns (1-20)");return}e({rows:n,cols:r,headerRow:s}),this.dialog.close()},onCancel:()=>{i==null||i(),this.dialog.close()},width:"400px"})}createFormHTML(){return`
|
|
98
|
+
<form class="table-dialog-form">
|
|
99
|
+
<div class="form-group">
|
|
100
|
+
<label for="table-rows">Rows</label>
|
|
101
|
+
<input
|
|
102
|
+
type="number"
|
|
103
|
+
id="table-rows"
|
|
104
|
+
name="rows"
|
|
105
|
+
min="1"
|
|
106
|
+
max="100"
|
|
107
|
+
value="3"
|
|
108
|
+
required
|
|
109
|
+
autofocus
|
|
110
|
+
/>
|
|
111
|
+
<small>Number of rows (1-100)</small>
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
<div class="form-group">
|
|
115
|
+
<label for="table-cols">Columns</label>
|
|
116
|
+
<input
|
|
117
|
+
type="number"
|
|
118
|
+
id="table-cols"
|
|
119
|
+
name="cols"
|
|
120
|
+
min="1"
|
|
121
|
+
max="20"
|
|
122
|
+
value="3"
|
|
123
|
+
required
|
|
124
|
+
/>
|
|
125
|
+
<small>Number of columns (1-20)</small>
|
|
126
|
+
</div>
|
|
127
|
+
|
|
128
|
+
<div class="form-group">
|
|
129
|
+
<label class="checkbox-label">
|
|
130
|
+
<input
|
|
131
|
+
type="checkbox"
|
|
132
|
+
name="headerRow"
|
|
133
|
+
id="table-header"
|
|
134
|
+
checked
|
|
135
|
+
/>
|
|
136
|
+
<span>Include header row</span>
|
|
137
|
+
</label>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
<div class="table-preview">
|
|
141
|
+
<strong>Preview:</strong>
|
|
142
|
+
<div id="table-preview-content" style="margin-top: 8px; font-size: 12px; color: #666;">
|
|
143
|
+
3 rows × 3 columns with header
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
<div class="form-actions">
|
|
148
|
+
<button type="button" class="btn btn-secondary" data-action="cancel">
|
|
149
|
+
Cancel
|
|
150
|
+
</button>
|
|
151
|
+
<button type="submit" class="btn btn-primary">
|
|
152
|
+
Insert Table
|
|
153
|
+
</button>
|
|
154
|
+
</div>
|
|
155
|
+
</form>
|
|
156
|
+
`}show(){this.dialog.show(),this.attachPreviewListeners()}close(){this.dialog.close()}attachPreviewListeners(){const t=document.querySelector(".table-dialog-form");if(!t)return;const e=t.querySelector("#table-rows"),i=t.querySelector("#table-cols"),o=t.querySelector("#table-header"),n=t.querySelector("#table-preview-content"),r=()=>{const s=parseInt((e==null?void 0:e.value)||"3",10),l=parseInt((i==null?void 0:i.value)||"3",10),m=o==null?void 0:o.checked;n&&(n.textContent=`${s} rows × ${l} columns${m?" with header":""}`)};e==null||e.addEventListener("input",r),i==null||i.addEventListener("input",r),o==null||o.addEventListener("change",r)}}class K{constructor(t){this.config=t;const{onSubmit:e,onCancel:i}=t;this.dialog=new f({title:"Insert Image",content:this.createFormHTML(),onSubmit:o=>{const n=(o.get("src")||"").trim(),r=(o.get("alt")||"").trim(),s=(o.get("width")||"").trim(),l=(o.get("height")||"").trim();if(!n){alert("Please enter an image URL or upload an image");return}e({src:n,alt:r,width:s||void 0,height:l||void 0}),this.dialog.close()},onCancel:()=>{i==null||i(),this.dialog.close()},width:"500px"})}createFormHTML(){return`
|
|
157
|
+
<form class="image-dialog-form">
|
|
158
|
+
${this.config.allowUpload?`
|
|
159
|
+
<div class="form-group">
|
|
160
|
+
<label for="image-upload">Upload Image</label>
|
|
161
|
+
<input
|
|
162
|
+
type="file"
|
|
163
|
+
id="image-upload"
|
|
164
|
+
accept="image/*"
|
|
165
|
+
/>
|
|
166
|
+
<small>Or upload an image from your computer</small>
|
|
167
|
+
</div>
|
|
168
|
+
<div class="form-divider">OR</div>
|
|
169
|
+
`:""}
|
|
170
|
+
|
|
171
|
+
<div class="form-group">
|
|
172
|
+
<label for="image-src">Image URL</label>
|
|
173
|
+
<input
|
|
174
|
+
type="url"
|
|
175
|
+
id="image-src"
|
|
176
|
+
name="src"
|
|
177
|
+
placeholder="https://example.com/image.jpg"
|
|
178
|
+
${this.config.allowUpload?"":"required autofocus"}
|
|
179
|
+
/>
|
|
180
|
+
<small>Enter the web address (URL) of the image</small>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
<div class="form-group">
|
|
184
|
+
<label for="image-alt">Alt Text</label>
|
|
185
|
+
<input
|
|
186
|
+
type="text"
|
|
187
|
+
id="image-alt"
|
|
188
|
+
name="alt"
|
|
189
|
+
placeholder="Description of the image"
|
|
190
|
+
/>
|
|
191
|
+
<small>Alternative text for accessibility (recommended)</small>
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
<div class="form-row">
|
|
195
|
+
<div class="form-group">
|
|
196
|
+
<label for="image-width">Width</label>
|
|
197
|
+
<input
|
|
198
|
+
type="text"
|
|
199
|
+
id="image-width"
|
|
200
|
+
name="width"
|
|
201
|
+
placeholder="auto"
|
|
202
|
+
/>
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
<div class="form-group">
|
|
206
|
+
<label for="image-height">Height</label>
|
|
207
|
+
<input
|
|
208
|
+
type="text"
|
|
209
|
+
id="image-height"
|
|
210
|
+
name="height"
|
|
211
|
+
placeholder="auto"
|
|
212
|
+
/>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
<div class="image-preview" id="image-preview" style="display: none;">
|
|
217
|
+
<strong>Preview:</strong>
|
|
218
|
+
<img id="preview-img" style="max-width: 100%; max-height: 200px; margin-top: 8px;" />
|
|
219
|
+
</div>
|
|
220
|
+
|
|
221
|
+
<div class="form-actions">
|
|
222
|
+
<button type="button" class="btn btn-secondary" data-action="cancel">
|
|
223
|
+
Cancel
|
|
224
|
+
</button>
|
|
225
|
+
<button type="submit" class="btn btn-primary">
|
|
226
|
+
Insert Image
|
|
227
|
+
</button>
|
|
228
|
+
</div>
|
|
229
|
+
</form>
|
|
230
|
+
`}show(){this.dialog.show(),this.attachImagePreview(),this.attachFileUpload()}close(){this.dialog.close()}attachImagePreview(){const t=document.querySelector(".image-dialog-form");if(!t)return;const e=t.querySelector("#image-src"),i=t.querySelector("#image-preview"),o=t.querySelector("#preview-img");e==null||e.addEventListener("input",()=>{const n=e.value.trim();n&&this.isValidImageUrl(n)?(o.src=n,i.style.display="block",o.onerror=()=>{i.style.display="none"}):i.style.display="none"})}attachFileUpload(){if(!this.config.allowUpload)return;const t=document.querySelector(".image-dialog-form");if(!t)return;const e=t.querySelector("#image-upload"),i=t.querySelector("#image-src");e==null||e.addEventListener("change",async o=>{var s;const n=(s=o.target.files)==null?void 0:s[0];if(!n)return;const r=new FileReader;r.onload=l=>{var u;const m=(u=l.target)==null?void 0:u.result;i.value=m,i.dispatchEvent(new Event("input"))},r.readAsDataURL(n)})}isValidImageUrl(t){try{return new URL(t),/\.(jpg|jpeg|png|gif|svg|webp|bmp)$/i.test(t)||t.startsWith("data:image/")}catch(e){return!1}}}class V{constructor(t){this.onSubmit=t.onSubmit;const e=this.createContent();this.dialog=new f({title:"Insert Math Equation",content:e,buttons:[{label:"Cancel",onClick:()=>this.dialog.close()},{label:"Insert",onClick:()=>this.handleSubmit(),primary:!0}]}),this.latexInput=e.querySelector("#math-latex"),this.previewDiv=e.querySelector("#math-preview"),this.displayTypeSelect=e.querySelector("#math-display-type"),this.latexInput.addEventListener("input",()=>this.updatePreview())}createContent(){const t=document.createElement("div");return t.className="math-dialog-content",t.style.minWidth="500px",t.innerHTML=`
|
|
231
|
+
<style>
|
|
232
|
+
.math-dialog-content {
|
|
233
|
+
display: flex;
|
|
234
|
+
flex-direction: column;
|
|
235
|
+
gap: 1rem;
|
|
236
|
+
}
|
|
237
|
+
.math-form-group {
|
|
238
|
+
display: flex;
|
|
239
|
+
flex-direction: column;
|
|
240
|
+
gap: 0.5rem;
|
|
241
|
+
}
|
|
242
|
+
.math-form-group label {
|
|
243
|
+
font-weight: 500;
|
|
244
|
+
color: #333;
|
|
245
|
+
}
|
|
246
|
+
.math-latex-input {
|
|
247
|
+
width: 100%;
|
|
248
|
+
min-height: 80px;
|
|
249
|
+
padding: 0.5rem;
|
|
250
|
+
border: 1px solid #ddd;
|
|
251
|
+
border-radius: 4px;
|
|
252
|
+
font-family: 'Courier New', monospace;
|
|
253
|
+
font-size: 14px;
|
|
254
|
+
resize: vertical;
|
|
255
|
+
}
|
|
256
|
+
.math-preview {
|
|
257
|
+
padding: 1rem;
|
|
258
|
+
background: #f9f9f9;
|
|
259
|
+
border: 1px solid #ddd;
|
|
260
|
+
border-radius: 4px;
|
|
261
|
+
min-height: 60px;
|
|
262
|
+
font-size: 18px;
|
|
263
|
+
text-align: center;
|
|
264
|
+
}
|
|
265
|
+
.math-preview:empty::before {
|
|
266
|
+
content: 'Preview will appear here...';
|
|
267
|
+
color: #999;
|
|
268
|
+
font-style: italic;
|
|
269
|
+
}
|
|
270
|
+
.math-symbols {
|
|
271
|
+
display: grid;
|
|
272
|
+
grid-template-columns: repeat(8, 1fr);
|
|
273
|
+
gap: 0.5rem;
|
|
274
|
+
padding: 0.5rem;
|
|
275
|
+
background: #f5f5f5;
|
|
276
|
+
border-radius: 4px;
|
|
277
|
+
}
|
|
278
|
+
.math-symbol-btn {
|
|
279
|
+
padding: 0.5rem;
|
|
280
|
+
border: 1px solid #ddd;
|
|
281
|
+
background: white;
|
|
282
|
+
border-radius: 4px;
|
|
283
|
+
cursor: pointer;
|
|
284
|
+
font-size: 18px;
|
|
285
|
+
transition: all 0.2s;
|
|
286
|
+
}
|
|
287
|
+
.math-symbol-btn:hover {
|
|
288
|
+
background: #e3f2fd;
|
|
289
|
+
border-color: #2196f3;
|
|
290
|
+
}
|
|
291
|
+
.math-display-select {
|
|
292
|
+
padding: 0.5rem;
|
|
293
|
+
border: 1px solid #ddd;
|
|
294
|
+
border-radius: 4px;
|
|
295
|
+
font-size: 14px;
|
|
296
|
+
}
|
|
297
|
+
</style>
|
|
298
|
+
|
|
299
|
+
<div class="math-form-group">
|
|
300
|
+
<label for="math-latex">LaTeX Expression:</label>
|
|
301
|
+
<textarea
|
|
302
|
+
id="math-latex"
|
|
303
|
+
class="math-latex-input"
|
|
304
|
+
placeholder="Enter LaTeX (e.g., x^2 + y^2 = r^2)"
|
|
305
|
+
></textarea>
|
|
306
|
+
</div>
|
|
307
|
+
|
|
308
|
+
<div class="math-form-group">
|
|
309
|
+
<label>Common Symbols:</label>
|
|
310
|
+
<div class="math-symbols">
|
|
311
|
+
<button class="math-symbol-btn" data-symbol="\\frac{a}{b}" title="Fraction">a/b</button>
|
|
312
|
+
<button class="math-symbol-btn" data-symbol="x^{2}" title="Superscript">x²</button>
|
|
313
|
+
<button class="math-symbol-btn" data-symbol="x_{i}" title="Subscript">xᵢ</button>
|
|
314
|
+
<button class="math-symbol-btn" data-symbol="\\sqrt{x}" title="Square root">√x</button>
|
|
315
|
+
<button class="math-symbol-btn" data-symbol="\\sum" title="Sum">∑</button>
|
|
316
|
+
<button class="math-symbol-btn" data-symbol="\\int" title="Integral">∫</button>
|
|
317
|
+
<button class="math-symbol-btn" data-symbol="\\pi" title="Pi">π</button>
|
|
318
|
+
<button class="math-symbol-btn" data-symbol="\\alpha" title="Alpha">α</button>
|
|
319
|
+
<button class="math-symbol-btn" data-symbol="\\beta" title="Beta">β</button>
|
|
320
|
+
<button class="math-symbol-btn" data-symbol="\\gamma" title="Gamma">γ</button>
|
|
321
|
+
<button class="math-symbol-btn" data-symbol="\\theta" title="Theta">θ</button>
|
|
322
|
+
<button class="math-symbol-btn" data-symbol="\\lambda" title="Lambda">λ</button>
|
|
323
|
+
<button class="math-symbol-btn" data-symbol="\\infty" title="Infinity">∞</button>
|
|
324
|
+
<button class="math-symbol-btn" data-symbol="\\leq" title="Less or equal">≤</button>
|
|
325
|
+
<button class="math-symbol-btn" data-symbol="\\geq" title="Greater or equal">≥</button>
|
|
326
|
+
<button class="math-symbol-btn" data-symbol="\\neq" title="Not equal">≠</button>
|
|
327
|
+
</div>
|
|
328
|
+
</div>
|
|
329
|
+
|
|
330
|
+
<div class="math-form-group">
|
|
331
|
+
<label for="math-preview">Preview:</label>
|
|
332
|
+
<div id="math-preview" class="math-preview"></div>
|
|
333
|
+
</div>
|
|
334
|
+
|
|
335
|
+
<div class="math-form-group">
|
|
336
|
+
<label for="math-display-type">Display Type:</label>
|
|
337
|
+
<select id="math-display-type" class="math-display-select">
|
|
338
|
+
<option value="inline">Inline (within text)</option>
|
|
339
|
+
<option value="block">Block (centered, new line)</option>
|
|
340
|
+
</select>
|
|
341
|
+
</div>
|
|
342
|
+
`,t.querySelectorAll(".math-symbol-btn").forEach(i=>{i.addEventListener("click",o=>{o.preventDefault();const n=i.getAttribute("data-symbol");if(n&&this.latexInput){const r=this.latexInput.selectionStart,s=this.latexInput.selectionEnd,l=this.latexInput.value;this.latexInput.value=l.substring(0,r)+n+l.substring(s),this.latexInput.focus(),this.latexInput.selectionStart=this.latexInput.selectionEnd=r+n.length,this.updatePreview()}})}),t}updatePreview(){const t=this.latexInput.value.trim();if(!t){this.previewDiv.textContent="";return}let e=t.replace(/\\frac\{([^}]+)\}\{([^}]+)\}/g,"($1)/($2)").replace(/\^\{([^}]+)\}/g,"^$1").replace(/\_\{([^}]+)\}/g,"_$1").replace(/\\sqrt\{([^}]+)\}/g,"√($1)").replace(/\\sum/g,"∑").replace(/\\int/g,"∫").replace(/\\pi/g,"π").replace(/\\alpha/g,"α").replace(/\\beta/g,"β").replace(/\\gamma/g,"γ").replace(/\\theta/g,"θ").replace(/\\lambda/g,"λ").replace(/\\infty/g,"∞").replace(/\\leq/g,"≤").replace(/\\geq/g,"≥").replace(/\\neq/g,"≠");this.previewDiv.textContent=e}handleSubmit(){const t=this.latexInput.value.trim();if(!t){alert("Please enter a LaTeX expression.");return}const e=this.displayTypeSelect.value;this.onSubmit({latex:t,display:e}),this.dialog.close()}show(){this.dialog.show(),this.latexInput.value="",this.previewDiv.textContent="",this.displayTypeSelect.value="inline",setTimeout(()=>this.latexInput.focus(),100)}close(){this.dialog.close()}}class _{constructor(t){this.characters={common:["©","®","™","§","¶","†","‡","•","‣","⁃","◦","▪","▫","◊","○","●","□","■","△","▲","▽","▼","◇","◆","★","☆"],arrows:["←","→","↑","↓","↔","↕","⇐","⇒","⇑","⇓","⇔","⇕","⟵","⟶","⟷","↖","↗","↘","↙","⇖","⇗","⇘","⇙"],currency:["$","€","£","¥","₹","₽","₩","₪","₦","฿","₴","₡","₵","₸","₫","₱","₲","₳","₭"],math:["±","×","÷","=","≠","≈","≡","≤","≥","<",">","∞","∑","∏","∫","∂","√","∛","∜","°","′","″","∠","∟","⊥","∥"],greek:["α","β","γ","δ","ε","ζ","η","θ","ι","κ","λ","μ","ν","ξ","ο","π","ρ","σ","τ","υ","φ","χ","ψ","ω","Α","Β","Γ","Δ","Ε","Ζ","Η","Θ"],punctuation:["‚","„","“","”","‘","’","«","»","‹","›","—","–","…","·","¡","¿","‰","′","″","‴"],superscript:["⁰","¹","²","³","⁴","⁵","⁶","⁷","⁸","⁹","⁺","⁻","⁼","⁽","⁾","ⁿ","ⁱ"],subscript:["₀","₁","₂","₃","₄","₅","₆","₇","₈","₉","₊","₋","₌","₍","₎"]},this.onSelect=t.onSelect;const e=this.createContent();this.dialog=new f({title:"Insert Special Character",content:e,buttons:[{label:"Close",onClick:()=>this.dialog.close()}]}),this.searchInput=e.querySelector("#char-search"),this.categorySelect=e.querySelector("#char-category"),this.charactersGrid=e.querySelector("#char-grid"),this.searchInput.addEventListener("input",()=>this.filterCharacters()),this.categorySelect.addEventListener("change",()=>this.updateGrid()),this.updateGrid()}createContent(){const t=document.createElement("div");return t.className="character-dialog-content",t.style.minWidth="500px",t.innerHTML=`
|
|
343
|
+
<style>
|
|
344
|
+
.character-dialog-content {
|
|
345
|
+
display: flex;
|
|
346
|
+
flex-direction: column;
|
|
347
|
+
gap: 1rem;
|
|
348
|
+
}
|
|
349
|
+
.char-controls {
|
|
350
|
+
display: flex;
|
|
351
|
+
gap: 0.5rem;
|
|
352
|
+
}
|
|
353
|
+
.char-search, .char-category {
|
|
354
|
+
padding: 0.5rem;
|
|
355
|
+
border: 1px solid #ddd;
|
|
356
|
+
border-radius: 4px;
|
|
357
|
+
font-size: 14px;
|
|
358
|
+
}
|
|
359
|
+
.char-search {
|
|
360
|
+
flex: 1;
|
|
361
|
+
}
|
|
362
|
+
.char-category {
|
|
363
|
+
min-width: 150px;
|
|
364
|
+
}
|
|
365
|
+
.char-grid {
|
|
366
|
+
display: grid;
|
|
367
|
+
grid-template-columns: repeat(10, 1fr);
|
|
368
|
+
gap: 0.5rem;
|
|
369
|
+
max-height: 300px;
|
|
370
|
+
overflow-y: auto;
|
|
371
|
+
padding: 1rem;
|
|
372
|
+
background: #f9f9f9;
|
|
373
|
+
border: 1px solid #ddd;
|
|
374
|
+
border-radius: 4px;
|
|
375
|
+
}
|
|
376
|
+
.char-button {
|
|
377
|
+
aspect-ratio: 1;
|
|
378
|
+
display: flex;
|
|
379
|
+
align-items: center;
|
|
380
|
+
justify-content: center;
|
|
381
|
+
padding: 0.5rem;
|
|
382
|
+
border: 1px solid #ddd;
|
|
383
|
+
background: white;
|
|
384
|
+
border-radius: 4px;
|
|
385
|
+
cursor: pointer;
|
|
386
|
+
font-size: 20px;
|
|
387
|
+
transition: all 0.2s;
|
|
388
|
+
}
|
|
389
|
+
.char-button:hover {
|
|
390
|
+
background: #e3f2fd;
|
|
391
|
+
border-color: #2196f3;
|
|
392
|
+
transform: scale(1.1);
|
|
393
|
+
}
|
|
394
|
+
.char-info {
|
|
395
|
+
padding: 0.5rem;
|
|
396
|
+
background: #f5f5f5;
|
|
397
|
+
border-radius: 4px;
|
|
398
|
+
font-size: 12px;
|
|
399
|
+
color: #666;
|
|
400
|
+
text-align: center;
|
|
401
|
+
}
|
|
402
|
+
</style>
|
|
403
|
+
|
|
404
|
+
<div class="char-controls">
|
|
405
|
+
<input
|
|
406
|
+
type="text"
|
|
407
|
+
id="char-search"
|
|
408
|
+
class="char-search"
|
|
409
|
+
placeholder="Search characters..."
|
|
410
|
+
/>
|
|
411
|
+
<select id="char-category" class="char-category">
|
|
412
|
+
<option value="all">All Categories</option>
|
|
413
|
+
<option value="common">Common Symbols</option>
|
|
414
|
+
<option value="arrows">Arrows</option>
|
|
415
|
+
<option value="currency">Currency</option>
|
|
416
|
+
<option value="math">Mathematics</option>
|
|
417
|
+
<option value="greek">Greek Letters</option>
|
|
418
|
+
<option value="punctuation">Punctuation</option>
|
|
419
|
+
<option value="superscript">Superscript</option>
|
|
420
|
+
<option value="subscript">Subscript</option>
|
|
421
|
+
</select>
|
|
422
|
+
</div>
|
|
423
|
+
|
|
424
|
+
<div id="char-grid" class="char-grid"></div>
|
|
425
|
+
|
|
426
|
+
<div class="char-info">
|
|
427
|
+
Click any character to insert it into your document.
|
|
428
|
+
</div>
|
|
429
|
+
`,t}updateGrid(){const t=this.categorySelect.value;this.charactersGrid.innerHTML="";let e=[];t==="all"?e=Object.values(this.characters).flat():e=this.characters[t]||[],e.forEach(i=>{const o=document.createElement("button");o.className="char-button",o.textContent=i,o.title=`Insert ${i} (U+${i.charCodeAt(0).toString(16).toUpperCase()})`,o.addEventListener("click",n=>{n.preventDefault(),this.handleSelect(i)}),this.charactersGrid.appendChild(o)})}filterCharacters(){const t=this.searchInput.value.toLowerCase();this.charactersGrid.querySelectorAll(".char-button").forEach(i=>{const o=i.textContent||"",n=`u+${o.charCodeAt(0).toString(16)}`,r=!t||o.includes(t)||n.includes(t);i.style.display=r?"flex":"none"})}handleSelect(t){this.onSelect(t),this.dialog.close()}show(){this.dialog.show(),this.searchInput.value="",this.categorySelect.value="all",this.updateGrid(),setTimeout(()=>this.searchInput.focus(),100)}close(){this.dialog.close()}}class X{constructor(t){this.emojis={popular:["😀","😃","😄","😁","😊","😍","🤩","😘","😗","😚","😙","🙂","🤗","🤔","🤨","😐","😑","😶","🙄","😏","👍","👎","👌","✌️","🤞","🤝","👏","🙌","👋","🤚","✋","🖐️","🖖","👊","✊","🤛","🤜","💪"],smileys:["😀","😃","😄","😁","😆","😅","🤣","😂","🙂","🙃","😉","😊","😇","🥰","😍","🤩","😘","😗","😚","😙","😋","😛","😜","🤪","😝","🤑","🤗","🤭","🤫","🤔"],emotions:["😳","😞","😟","😠","😡","🤬","😔","😕","🙁","😬","🥺","😣","😖","😫","😩","🥱","😤","😮","😱","😨","😰","😥","😢","😭","😪","😓","🤤","😴","😷","🤒"],gestures:["👍","👎","👌","✌️","🤞","🤟","🤘","🤙","👈","👉","👆","👇","☝️","👋","🤚","✋","🖐️","🖖","👏","🙌","👐","🤲","🤝","🙏","✍️","💅","🤳","💪","🦾","🦿"],people:["👶","👧","🧒","👦","👩","🧑","👨","👵","🧓","👴","👲","👳","🧕","👮","👷","💂","🕵️","👩⚕️","👨⚕️","👩🎓","👨🎓","👩🏫","👨🏫","👩⚖️","👨⚖️","👩🌾","👨🌾","👩🍳","👨🍳","👩🔧"],animals:["🐶","🐱","🐭","🐹","🐰","🦊","🐻","🐼","🐨","🐯","🦁","🐮","🐷","🐸","🐵","🙈","🙉","🙊","🐔","🐧","🐦","🐤","🐣","🐥","🦆","🦅","🦉","🦇","🐺","🐗"],nature:["🌵","🎄","🌲","🌳","🌴","🌱","🌿","☘️","🍀","🎍","🎋","🍃","🍂","🍁","🍄","🌾","💐","🌷","🌹","🥀","🌺","🌸","🌼","🌻","🌞","🌝","🌛","🌜","⭐","🌟"],food:["🍏","🍎","🍐","🍊","🍋","🍌","🍉","🍇","🍓","🍈","🍒","🍑","🥭","🍍","🥥","🥝","🍅","🍆","🥑","🥦","🥬","🥒","🌶️","🌽","🥕","🧄","🧅","🥔","🍠","🥐"],objects:["⌚","📱","💻","⌨️","🖥️","🖨️","🖱️","🕹️","💾","💿","📀","📷","📹","🎥","📞","☎️","📟","📠","📺","📻","🎙️","🎚️","🎛️","🧭","⏱️","⏰","📡","🔋","🔌","💡"],symbols:["❤️","🧡","💛","💚","💙","💜","🖤","🤍","🤎","💔","❣️","💕","💞","💓","💗","💖","💘","💝","✨","💫","⭐","🌟","✔️","✅","❌","❎","➕","➖","✖️","➗"],activities:["⚽","🏀","🏈","⚾","🥎","🎾","🏐","🏉","🥏","🎱","🪀","🏓","🏸","🏒","🏑","🥍","🏏","🪃","🥅","⛳","🪁","🏹","🎣","🤿","🥊","🥋","🎽","🛹","🛼","🛷"]},this.onSelect=t.onSelect;const e=this.createContent();this.dialog=new f({title:"Insert Emoji",content:e,buttons:[{label:"Close",onClick:()=>this.dialog.close()}]}),this.searchInput=e.querySelector("#emoji-search"),this.categorySelect=e.querySelector("#emoji-category"),this.emojisGrid=e.querySelector("#emoji-grid"),this.searchInput.addEventListener("input",()=>this.filterEmojis()),this.categorySelect.addEventListener("change",()=>this.updateGrid()),this.updateGrid()}createContent(){const t=document.createElement("div");return t.className="emoji-dialog-content",t.style.minWidth="500px",t.innerHTML=`
|
|
430
|
+
<style>
|
|
431
|
+
.emoji-dialog-content {
|
|
432
|
+
display: flex;
|
|
433
|
+
flex-direction: column;
|
|
434
|
+
gap: 1rem;
|
|
435
|
+
}
|
|
436
|
+
.emoji-controls {
|
|
437
|
+
display: flex;
|
|
438
|
+
gap: 0.5rem;
|
|
439
|
+
}
|
|
440
|
+
.emoji-search, .emoji-category {
|
|
441
|
+
padding: 0.5rem;
|
|
442
|
+
border: 1px solid #ddd;
|
|
443
|
+
border-radius: 4px;
|
|
444
|
+
font-size: 14px;
|
|
445
|
+
}
|
|
446
|
+
.emoji-search {
|
|
447
|
+
flex: 1;
|
|
448
|
+
}
|
|
449
|
+
.emoji-category {
|
|
450
|
+
min-width: 150px;
|
|
451
|
+
}
|
|
452
|
+
.emoji-grid {
|
|
453
|
+
display: grid;
|
|
454
|
+
grid-template-columns: repeat(10, 1fr);
|
|
455
|
+
gap: 0.5rem;
|
|
456
|
+
max-height: 350px;
|
|
457
|
+
overflow-y: auto;
|
|
458
|
+
padding: 1rem;
|
|
459
|
+
background: #f9f9f9;
|
|
460
|
+
border: 1px solid #ddd;
|
|
461
|
+
border-radius: 4px;
|
|
462
|
+
}
|
|
463
|
+
.emoji-button {
|
|
464
|
+
aspect-ratio: 1;
|
|
465
|
+
display: flex;
|
|
466
|
+
align-items: center;
|
|
467
|
+
justify-content: center;
|
|
468
|
+
padding: 0.5rem;
|
|
469
|
+
border: 1px solid #ddd;
|
|
470
|
+
background: white;
|
|
471
|
+
border-radius: 4px;
|
|
472
|
+
cursor: pointer;
|
|
473
|
+
font-size: 24px;
|
|
474
|
+
transition: all 0.2s;
|
|
475
|
+
}
|
|
476
|
+
.emoji-button:hover {
|
|
477
|
+
background: #fff3e0;
|
|
478
|
+
border-color: #ff9800;
|
|
479
|
+
transform: scale(1.15);
|
|
480
|
+
}
|
|
481
|
+
.emoji-info {
|
|
482
|
+
padding: 0.5rem;
|
|
483
|
+
background: #f5f5f5;
|
|
484
|
+
border-radius: 4px;
|
|
485
|
+
font-size: 12px;
|
|
486
|
+
color: #666;
|
|
487
|
+
text-align: center;
|
|
488
|
+
}
|
|
489
|
+
</style>
|
|
490
|
+
|
|
491
|
+
<div class="emoji-controls">
|
|
492
|
+
<input
|
|
493
|
+
type="text"
|
|
494
|
+
id="emoji-search"
|
|
495
|
+
class="emoji-search"
|
|
496
|
+
placeholder="Search emojis..."
|
|
497
|
+
/>
|
|
498
|
+
<select id="emoji-category" class="emoji-category">
|
|
499
|
+
<option value="all">All Emojis</option>
|
|
500
|
+
<option value="popular">Popular</option>
|
|
501
|
+
<option value="smileys">Smileys & Faces</option>
|
|
502
|
+
<option value="emotions">Emotions</option>
|
|
503
|
+
<option value="gestures">Gestures & Hands</option>
|
|
504
|
+
<option value="people">People</option>
|
|
505
|
+
<option value="animals">Animals</option>
|
|
506
|
+
<option value="nature">Nature</option>
|
|
507
|
+
<option value="food">Food & Drink</option>
|
|
508
|
+
<option value="objects">Objects</option>
|
|
509
|
+
<option value="symbols">Symbols</option>
|
|
510
|
+
<option value="activities">Activities & Sports</option>
|
|
511
|
+
</select>
|
|
512
|
+
</div>
|
|
513
|
+
|
|
514
|
+
<div id="emoji-grid" class="emoji-grid"></div>
|
|
515
|
+
|
|
516
|
+
<div class="emoji-info">
|
|
517
|
+
Click any emoji to insert it into your document.
|
|
518
|
+
</div>
|
|
519
|
+
`,t}updateGrid(){const t=this.categorySelect.value;this.emojisGrid.innerHTML="";let e=[];t==="all"?e=Object.values(this.emojis).flat():e=this.emojis[t]||[],e.forEach(i=>{const o=document.createElement("button");o.className="emoji-button",o.textContent=i,o.title=`Insert ${i}`,o.addEventListener("click",n=>{n.preventDefault(),this.handleSelect(i)}),this.emojisGrid.appendChild(o)})}filterEmojis(){const t=this.searchInput.value.toLowerCase();this.emojisGrid.querySelectorAll(".emoji-button").forEach(i=>{const o=i.textContent||"",n=!t||o.includes(t);i.style.display=n?"flex":"none"})}handleSelect(t){this.onSelect(t),this.dialog.close()}show(){this.dialog.show(),this.searchInput.value="",this.categorySelect.value="popular",this.updateGrid(),setTimeout(()=>this.searchInput.focus(),100)}close(){this.dialog.close()}}function D(a,t){const e=a.textContent||"",i=P(a,t.startContainer,t.startOffset),n=e.substring(0,i).split(`
|
|
520
|
+
`),r=n.length,s=n[n.length-1].length+1;return{line:r,column:s}}function P(a,t,e){var r;let i=0;const o=document.createTreeWalker(a,NodeFilter.SHOW_TEXT,null);let n=o.firstChild();for(;n;){if(n===t){i+=e;break}else n.nodeType===Node.TEXT_NODE&&(i+=((r=n.textContent)==null?void 0:r.length)||0);n=o.nextNode()}return i}function A(a){var i,o;const t=a.querySelectorAll("div, p, br, h1, h2, h3, h4, h5, h6, blockquote, li, pre");let e=1;if(t.length>0){e=t.length;const n=t[t.length-1];(n.tagName==="BR"||((i=n.innerHTML)==null?void 0:i.trim())===""||((o=n.textContent)==null?void 0:o.trim())==="")&&e++}else{const r=(a.textContent||"").split(`
|
|
521
|
+
`).length;e=Math.max(1,r)}return e}function H(a){const t=a.trim()?a.trim().split(/\s+/).length:0,e=a.length;return{words:t,chars:e}}function F(a,t){const e=a.toString();return{startLine:t.line,startColumn:t.column,endLine:t.line,endColumn:t.column+e.length,selectedChars:e.length,selectedWords:e.trim().split(/\s+/).filter(Boolean).length}}const k=class k{static resolve(t){const e={};if(Object.assign(e,this.EDITOR_DEFAULTS),t.pluginDefaults&&Object.assign(e,t.pluginDefaults),t.attributes){const i=this.parseAttributes(t.attributes);Object.assign(e,i)}return t.jsConfig&&Object.assign(e,t.jsConfig),e}static parseAttributes(t){const e={};for(const[i,o]of Object.entries(t)){const n=this.kebabToCamel(i);e[n]=this.parseAttributeValue(o)}return e}static parseAttributeValue(t){if(t==="true")return!0;if(t==="false")return!1;if(/^\d+$/.test(t))return parseInt(t,10);if(/^\d+\.\d+$/.test(t))return parseFloat(t);if(t.startsWith("{")||t.startsWith("["))try{return JSON.parse(t)}catch(e){return t}return t}static kebabToCamel(t){return t.replace(/-([a-z])/g,(e,i)=>i.toUpperCase())}static validate(t){const e=[];return t.height!==void 0&&typeof t.height=="number"&&t.height<0&&e.push("height must be a positive number"),t.width!==void 0&&typeof t.width=="number"&&t.width<0&&e.push("width must be a positive number"),t.plugins!==void 0&&!Array.isArray(t.plugins)&&typeof t.plugins!="string"&&e.push("plugins must be an array or string"),t.theme!==void 0&&typeof t.theme!="string"&&e.push("theme must be a string"),{valid:e.length===0,errors:e}}static getDefaults(){return{...this.EDITOR_DEFAULTS}}static merge(...t){const e={};for(const i of t)for(const[o,n]of Object.entries(i))n!=null&&(typeof n=="object"&&!Array.isArray(n)&&e[o]?e[o]=this.merge(e[o],n):e[o]=n);return e}};k.EDITOR_DEFAULTS={height:400,width:"100%",readonly:!1,disabled:!1,menubar:!0,toolbar:!0,plugins:[],theme:"light",content:"",placeholder:"Start typing...",autofocus:!1,autosave:!1,spellcheck:!1,language:"en"};let C=k;class Y{constructor(){this.loadedPlugins=new Map,this.pluginRegistry=new Map}register(t,e){this.pluginRegistry.set(t,e)}async load(t,e){if(this.loadedPlugins.has(t))return this.loadedPlugins.get(t);const i=this.pluginRegistry.get(t);if(!i)return console.warn(`Plugin not found: ${t}`),null;const o=await i();return e&&this.applyPluginConfig(o,e),this.loadedPlugins.set(t,o),o}async loadMultiple(t,e){return(await Promise.all(t.map(o=>this.load(o,e)))).filter(o=>o!==null)}async parsePluginString(t,e){const i=t.split(/\s+/).filter(Boolean);return this.loadMultiple(i,e)}applyPluginConfig(t,e){t.__pluginConfig=e}unload(t){this.loadedPlugins.delete(t)}clear(){this.loadedPlugins.clear()}getLoadedPlugins(){return Array.from(this.loadedPlugins.values())}getRegisteredPluginNames(){return Array.from(this.pluginRegistry.keys())}isLoaded(t){return this.loadedPlugins.has(t)}}class ${constructor(t={}){this.changeListeners=[],this.options=t,this.engine=new w({content:t.content,plugins:t.plugins||[],readonly:t.readonly}),t.onChange&&this.onChange(t.onChange),this.engine.on("change",()=>{const e=this.getHTML();this.changeListeners.forEach(i=>i(e))})}mount(t,e){this.contentElement=t,this.toolbarElement=e,this.contentElement.contentEditable=this.options.readonly?"false":"true",this.contentElement.className="rte-content",this.options.content&&(this.contentElement.innerHTML=this.options.content),this.options.toolbar!==!1&&this.toolbarElement&&(this.toolbar=new E({items:typeof this.options.toolbar=="string"?this.options.toolbar:void 0},this.options.plugins||[]),this.toolbar.setCommandHandler((i,o)=>{this.execCommand(i,o)}),this.toolbar.render(this.toolbarElement)),this.contentElement.addEventListener("input",()=>{const i=this.getHTML();this.changeListeners.forEach(o=>o(i))}),this.options.onInit&&this.options.onInit(this.getAPI())}getHTML(){var t;return((t=this.contentElement)==null?void 0:t.innerHTML)||""}setHTML(t){this.contentElement&&(this.contentElement.innerHTML=t)}execCommand(t,e){const i=this.engine.execCommand(t,e);return this.toolbar,i}focus(){var t;(t=this.contentElement)==null||t.focus()}blur(){var t;(t=this.contentElement)==null||t.blur()}onChange(t){return this.changeListeners.push(t),()=>{const e=this.changeListeners.indexOf(t);e>-1&&this.changeListeners.splice(e,1)}}registerCommand(t,e){if(typeof window!="undefined"){const i=window.__editorCommands||new Map;i.set(t,e),window.__editorCommands=i}}getState(){return{plugins:this.options.plugins,config:this.options,engine:this.engine.getState()}}getAPI(){var t;return{getHTML:()=>this.getHTML(),setHTML:e=>this.setHTML(e),execCommand:(e,i)=>this.execCommand(e,i),focus:()=>this.focus(),blur:()=>this.blur(),destroy:()=>this.destroy(),registerCommand:(e,i)=>this.registerCommand(e,i),onChange:e=>this.onChange(e),getState:()=>this.getState(),toolbar:{items:((t=this.options.plugins)==null?void 0:t.flatMap(e=>e.toolbar||[]))||[]}}}destroy(){var t;this.engine.destroy(),(t=this.toolbar)==null||t.destroy(),this.changeListeners=[],this.options.onDestroy&&this.options.onDestroy()}}function J(a){return new $(a)}class j{constructor(t){this.options=t,this.containerElement=t.element;const e=this.resolvePlugins(t.plugins);this.engine=new w({content:t.content,plugins:e,readonly:t.readonly}),this.initializeDOM()}resolvePlugins(t){return t?typeof t=="string"?(console.warn("String-based plugin loading not yet implemented for VanillaAdapter"),[]):t:[]}initializeDOM(){this.containerElement.innerHTML="",this.containerElement.classList.add("editora-editor"),this.options.enableToolbar!==!1&&this.options.toolbar!==!1&&(this.toolbarElement=document.createElement("div"),this.toolbarElement.className="editora-toolbar-container",this.containerElement.appendChild(this.toolbarElement),this.toolbar=new E({items:typeof this.options.toolbar=="string"?this.options.toolbar:void 0},this.options.plugins||[]),this.toolbar.setCommandHandler((t,e)=>{this.execCommand(t,e)}),this.toolbar.render(this.toolbarElement)),this.contentElement=document.createElement("div"),this.contentElement.className="editora-content",this.contentElement.contentEditable=this.options.readonly?"false":"true",this.contentElement.style.minHeight="200px",this.contentElement.style.outline="none",this.contentElement.style.padding="12px",this.options.content&&(this.contentElement.innerHTML=this.options.content),this.containerElement.appendChild(this.contentElement),this.contentElement.addEventListener("input",()=>{this.containerElement.dispatchEvent(new CustomEvent("change",{detail:{html:this.getContent()}}))})}getContent(){var t;return((t=this.contentElement)==null?void 0:t.innerHTML)||""}setContent(t){this.contentElement&&(this.contentElement.innerHTML=t)}execCommand(t,e){return this.engine.execCommand(t,e)}focus(){var t;(t=this.contentElement)==null||t.focus()}on(t,e){const i=o=>{e(o.detail)};return this.containerElement.addEventListener(t,i),()=>{this.containerElement.removeEventListener(t,i)}}destroy(){var t;this.engine.destroy(),(t=this.toolbar)==null||t.destroy(),this.containerElement.innerHTML=""}}const Q='.editora-editor{display:flex;flex-direction:column;border:1px solid #ddd;border-radius:4px;background:#fff;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;font-size:14px;overflow:hidden}.editora-editor *{box-sizing:border-box}.editora-theme-light{background:#fff;color:#333}.editora-theme-dark{background:#1e1e1e;color:#d4d4d4;border-color:#3c3c3c}.editora-toolbar{display:flex;align-items:center;gap:4px;padding:8px;background:#f5f5f5;border-bottom:1px solid #ddd;flex-wrap:wrap}.editora-theme-dark .editora-toolbar{background:#252526;border-bottom-color:#3c3c3c}.editora-toolbar-sticky{position:sticky;top:0;z-index:100;position:-webkit-sticky}.editora-toolbar-group{display:flex;align-items:center;gap:2px}.editora-toolbar-button{padding:6px 12px;border:1px solid #ccc;background:#fff;cursor:pointer;border-radius:3px;font-weight:600;font-size:14px;height:30px;display:flex;align-items:center;white-space:nowrap}.editora-toolbar-input.font-size{width:40px;padding:.25rem;text-align:center;font-size:14px;background:#fff;border:1px solid var(--rte-color-border-light);border-radius:var(--rte-radius-sm)}.editora-toolbar-group-items{display:flex;align-items:center;border:1px solid #ccc;.editora-toolbar-button{border:none;border-radius:0;&:first-child{border-right:1px solid #ccc;border-top-left-radius:3px;border-bottom-left-radius:3px}&:last-child{border-left:1px solid #ccc;border-top-right-radius:3px;border-bottom-right-radius:3px}}}.editora-theme-dark .editora-toolbar-button{color:#d4d4d4}.editora-toolbar-button:hover{background:#e0e0e0;border-color:#ccc}.editora-theme-dark .editora-toolbar-button:hover{background:#37373d;border-color:#555}.editora-toolbar-button:active,.editora-toolbar-button.active{background:#d0d0d0;border-color:#999}.editora-theme-dark .editora-toolbar-button:active,.editora-theme-dark .editora-toolbar-button.active{background:#2a2d2e;border-color:#666}.editora-toolbar-button:disabled{opacity:.5;cursor:not-allowed}.editora-toolbar-icon{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;line-height:1}.editora-toolbar-button svg,.editora-toolbar-icon svg{width:24px;height:24px;display:block}.editora-toolbar-separator{width:1px;height:24px;background:#ddd;margin:0 4px}.editora-theme-dark .editora-toolbar-separator{background:#3c3c3c}.editora-toolbar-dropdown{position:relative}.editora-toolbar-dropdown-menu{position:absolute;top:100%;left:0;min-width:150px;margin-top:4px;padding:4px 0;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-toolbar-dropdown-menu{background:#252526;border-color:#3c3c3c;box-shadow:0 2px 8px #00000080}.editora-toolbar-dropdown-item{display:block;width:100%;padding:8px 12px;border:none;background:transparent;color:#333;text-align:left;cursor:pointer;font-size:13px;transition:background .15s ease}.editora-theme-dark .editora-toolbar-dropdown-item{color:#d4d4d4}.editora-toolbar-dropdown-item:hover{background:#f5f5f5}.editora-theme-dark .editora-toolbar-dropdown-item:hover{background:#37373d}.editora-content{flex:1;min-height:200px;padding:16px;outline:none;overflow-y:auto;line-height:1.6}.editora-content:empty:before{content:attr(data-placeholder);color:#999;pointer-events:none}.editora-theme-dark .editora-content:empty:before{color:#6a6a6a}.editora-content h1{font-size:2em;margin:.67em 0;font-weight:600}.editora-content h2{font-size:1.5em;margin:.75em 0;font-weight:600}.editora-content h3{font-size:1.17em;margin:.83em 0;font-weight:600}.editora-content p{margin:1em 0}.editora-content ul,.editora-content ol{margin:1em 0;padding-left:2em}.editora-content a{color:#06c;text-decoration:underline}.editora-theme-dark .editora-content a{color:#4db8ff}.editora-content code{padding:2px 4px;background:#f5f5f5;border-radius:3px;font-family:Monaco,Menlo,Consolas,monospace;font-size:.9em}.editora-theme-dark .editora-content code{background:#1e1e1e}.editora-content pre{padding:12px;background:#f5f5f5;border-radius:4px;overflow-x:auto;margin:1em 0}.editora-theme-dark .editora-content pre{background:#1e1e1e}.editora-content blockquote{margin:1em 0;padding-left:1em;border-left:4px solid #ddd;color:#666}.editora-theme-dark .editora-content blockquote{border-left-color:#3c3c3c;color:#9a9a9a}.editora-floating-toolbar{position:absolute;padding:4px;background:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 8px #00000026;z-index:1000}.editora-theme-dark .editora-floating-toolbar{background:#252526;border-color:#3c3c3c;box-shadow:0 2px 8px #00000080}.editora-statusbar-container{display:flex;flex-direction:column}.editora-statusbar-left{display:flex;align-items:center;gap:8px}.editora-statusbar-right{display:flex;align-items:center;gap:8px;margin-left:auto}.editora-statusbar{display:flex;align-items:center;gap:12px;padding:6px 12px;background:#f5f5f5;border-top:1px solid #ddd;font-size:12px;color:#666}.editora-theme-dark .editora-statusbar{background:#252526;border-top-color:#3c3c3c;color:#9a9a9a}.editora-statusbar-item{white-space:nowrap}.editora-statusbar-separator{color:#ddd}.editora-theme-dark .editora-statusbar-separator{color:#3c3c3c}.editora-editor[readonly] .editora-content{background:#fafafa;cursor:not-allowed}.editora-theme-dark.editora-editor[readonly] .editora-content{background:#1a1a1a}.editora-editor:focus-within{border-color:#06c;box-shadow:0 0 0 3px #0066cc1a}.editora-theme-dark.editora-editor:focus-within{border-color:#4db8ff;box-shadow:0 0 0 3px #4db8ff1a}.editora-editor[disabled]{opacity:.6;pointer-events:none}@media(max-width:768px){.editora-toolbar{padding:4px}.editora-toolbar-button{min-width:28px;min-height:28px;padding:4px 8px;font-size:12px}.editora-content{padding:12px}}.editora-content ::selection{background:#06c3}.editora-theme-dark .editora-content ::selection{background:#4db8ff33}.editora-content table{border-collapse:collapse;width:100%;margin:1em 0}.editora-content th,.editora-content td{border:1px solid #ddd;padding:8px 12px;text-align:left}.editora-theme-dark .editora-content th,.editora-theme-dark .editora-content td{border-color:#3c3c3c}.editora-content th{background:#f5f5f5;font-weight:600}.editora-theme-dark .editora-content th{background:#252526}.editora-content img{max-width:100%;height:auto;border-radius:4px;display:block}.editora-content video{max-width:100%;height:auto;border-radius:4px;display:block}.editora-editor.loading{opacity:.7;pointer-events:none}.editora-editor.loading:after{content:"";position:absolute;top:50%;left:50%;width:24px;height:24px;margin:-12px 0 0 -12px;border:3px solid #ddd;border-top-color:#06c;border-radius:50%;animation:editora-spin .8s linear infinite}@keyframes editora-spin{to{transform:rotate(360deg)}}.toolbar-container-wrapper{display:flex;align-items:center;background:#fff;border-bottom:1px solid #e0e0e0;padding:0;margin:0;width:100%;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;line-height:1.5;position:relative}.toolbar-container-wrapper[data-toolbar-sticky=true]{position:sticky;top:0;z-index:999;box-shadow:0 2px 4px #0000001a}.toolbar-container-wrapper[data-toolbar-floating=true]{position:fixed;top:0;left:0;right:0;z-index:1000;box-shadow:0 4px 12px #00000026}.toolbar-container-wrapper[data-toolbar-position=bottom]{border-bottom:none;border-top:1px solid #e0e0e0}.toolbar-container-wrapper .toolbar-wrapper{display:flex;width:100%;padding:8px;gap:4px;flex-wrap:wrap;align-items:center}.toolbar-container-wrapper .toolbar{display:flex;width:100%;gap:4px;flex-wrap:wrap;align-items:center}.toolbar-container-wrapper .toolbar-container{display:flex;gap:4px;flex-wrap:wrap;align-items:center;flex:1;position:relative}.toolbar-container-wrapper .toolbar-item{display:flex;align-items:center;gap:2px}.toolbar-container-wrapper .toolbar-button{padding:6px 10px;border:1px solid #d1d5db;background:#fff;border-radius:4px;cursor:pointer;font-size:13px;display:flex;align-items:center;justify-content:center;gap:4px;transition:all .15s ease;min-height:32px;white-space:nowrap}.toolbar-container-wrapper .toolbar-button:hover{background-color:#f3f4f6;border-color:#9ca3af}.toolbar-container-wrapper .toolbar-button:active,.toolbar-container-wrapper .toolbar-button[data-active=true]{background-color:#06c;color:#fff;border-color:#0052a3;box-shadow:inset 0 1px 3px #0000001a}.toolbar-container-wrapper .toolbar-button:disabled{opacity:.5;cursor:not-allowed;background-color:#f9fafb}.toolbar-container-wrapper .toolbar-more-button{padding:6px 8px;font-size:16px;font-weight:500;line-height:1}.toolbar-container-wrapper .toolbar-separator{width:1px;height:24px;background-color:#d1d5db;margin:0 4px}.toolbar-container-wrapper .toolbar-icon{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;flex-shrink:0}.toolbar-container-wrapper .toolbar-icon svg{width:100%;height:100%}.toolbar-container-wrapper .toolbar-dropdown{position:relative;display:flex;align-items:center}.toolbar-container-wrapper .toolbar-dropdown-arrow{font-size:10px;margin-left:2px;line-height:1}.toolbar-container-wrapper .toolbar-dropdown-menu{position:absolute;top:100%;left:0;background:#fff;border:1px solid #d1d5db;border-radius:6px;box-shadow:0 4px 12px #00000026;z-index:1000;min-width:160px;padding:4px 0;margin-top:4px;display:none}.toolbar-container-wrapper .toolbar-dropdown-menu.show{display:block}.toolbar-container-wrapper .toolbar-dropdown-item{display:block;width:100%;padding:8px 12px;border:none;background:transparent;text-align:left;cursor:pointer;font-size:13px;color:#1f2937;transition:background-color .15s ease;font-family:inherit}.toolbar-container-wrapper .toolbar-dropdown-item:hover{background-color:#f3f4f6}.toolbar-container-wrapper .toolbar-dropdown-item:active{background-color:#e5e7eb}.toolbar-container-wrapper .toolbar-input{padding:6px 8px;border:1px solid #d1d5db;border-radius:4px;font-size:13px;font-family:inherit;background-color:#fff;color:#1f2937;transition:all .15s ease}.toolbar-container-wrapper .toolbar-input:focus{outline:none;border-color:#06c;box-shadow:0 0 0 3px #0066cc1a;background-color:#fff}.toolbar-container-wrapper .toolbar-input::placeholder{color:#9ca3af}.toolbar-overflow-menu{animation:slideDown .2s ease-out}@keyframes slideDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.toolbar-overflow-item{transition:background-color .15s ease}.floating-toolbar{user-select:none;-webkit-user-select:none;font-family:system-ui,-apple-system,sans-serif;font-size:14px;animation:fadeInUp .15s ease-out}@keyframes fadeInUp{0%{opacity:0;transform:translate(-50%) translateY(10px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.floating-toolbar-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:transparent;border-radius:4px;color:#495057;cursor:pointer;font-size:14px;font-weight:500;transition:all .15s ease;outline:none}.floating-toolbar-btn:hover{background:#f8f9fa;color:#212529}.floating-toolbar-btn:active{background:#e9ecef;transform:scale(.95)}.floating-toolbar-btn.floating-toolbar-toggle{color:#dc3545;font-weight:700}.floating-toolbar-btn.floating-toolbar-toggle:hover{background:#f8d7da;color:#721c24}.floating-toolbar-separator{width:1px;height:20px;background:#e1e5e9;margin:0 2px}@media(max-width:768px){.toolbar-container-wrapper .toolbar-button{padding:5px 8px;font-size:12px;min-height:28px}.toolbar-container-wrapper .toolbar-icon{width:16px;height:16px}.toolbar-container-wrapper .toolbar-dropdown-menu{min-width:140px}.toolbar-container-wrapper .toolbar-dropdown-item{padding:6px 10px;font-size:12px}.floating-toolbar{padding:4px;gap:2px}.floating-toolbar-btn{width:28px;height:28px;font-size:12px}}@media(max-width:480px){.toolbar-container-wrapper{padding:4px}.toolbar-container-wrapper .toolbar-wrapper{padding:4px;gap:2px}.toolbar-container-wrapper .toolbar-button{padding:4px 6px;font-size:11px;min-height:24px}.toolbar-container-wrapper .toolbar-icon{width:14px;height:14px}}.floating-toolbar{pointer-events:auto}.floating-toolbar{max-width:calc(100vw - 20px);overflow-x:auto}@media(prefers-color-scheme:dark){.floating-toolbar{background:#2d3748;border-color:#4a5568;color:#e2e8f0}.floating-toolbar-btn:hover{background:#4a5568;color:#f7fafc}.floating-toolbar-btn:active{background:#718096}.floating-toolbar-separator{background:#4a5568}}';function Z(){const a="editora-webcomponent-styles";if(!document.getElementById(a)){const t=document.createElement("style");t.id=a,t.textContent=Q,document.head.appendChild(t)}}class b extends HTMLElement{constructor(){if(super(),this.config={},this.isInitialized=!1,Z(),!this.hasAttribute("data-initial-content")){const t=this.innerHTML.trim();t&&this.setAttribute("data-initial-content",t)}}static get observedAttributes(){return["height","width","menubar","plugins","toolbar","toolbar-items","readonly","disabled","theme","placeholder","autofocus","language","spellcheck","statusbar"]}connectedCallback(){this.config=this.resolveConfig(),this.waitForPluginLoader().then(()=>{setTimeout(async()=>{await this.initialize()},0)})}async waitForPluginLoader(){if(b.__globalPluginLoader){this.pluginLoader=b.__globalPluginLoader;return}return new Promise(t=>{const e=()=>{b.__globalPluginLoader?(this.pluginLoader=b.__globalPluginLoader,t()):setTimeout(e,0)};e()})}disconnectedCallback(){this.destroy()}attributeChangedCallback(t,e,i){e!==i&&(this.config=this.resolveConfig(),this.handleAttributeChange(t,i))}async setConfig(t){this.jsConfig=t,this.config=this.resolveConfig(),this.isConnected&&(this.destroy(),await this.waitForPluginLoader(),await this.initialize())}async initialize(){if(this.querySelector(".editora-toolbar")||this.isInitialized)return;this.setAttribute("data-editora-editor","true"),this.config.height&&(this.style.height=typeof this.config.height=="number"?`${this.config.height}px`:this.config.height),this.config.width&&(this.style.width=typeof this.config.width=="number"?`${this.config.width}px`:this.config.width),this.classList.add("editora-editor"),this.config.theme&&this.classList.add(`editora-theme-${this.config.theme}`);const t=await this.loadPlugins();t.forEach(i=>{if(i.init&&typeof i.init=="function")try{i.init({editorElement:this})}catch(o){console.error(`[RichTextEditor] Error initializing plugin ${i.name}:`,o)}});const e=this.getAttribute("data-initial-content")||"";this.engine=new w({content:e,plugins:t,readonly:this.config.readonly}),this.createUI(t,e),this.setupEventListeners(),this.isInitialized=!0,this.dispatchEvent(new CustomEvent("editor-ready",{detail:{api:this.getAPI()},bubbles:!0}))}getInitialContent(){if(this.config.content)return this.config.content;const t=this.querySelector("[slot]");return t?t.innerHTML:this.hasChildNodes()?Array.from(this.childNodes).map(i=>i.nodeType===Node.TEXT_NODE?i.textContent:i.nodeType===Node.ELEMENT_NODE?i.outerHTML:"").join("").trim():""}async loadPlugins(){this.pluginLoader||await this.waitForPluginLoader();const t=[];if(this.config.plugins&&(typeof this.config.plugins=="string"&&this.config.plugins.length>0||Array.isArray(this.config.plugins)&&this.config.plugins.length>0)){if(typeof this.config.plugins=="string"){const i=await this.pluginLoader.parsePluginString(this.config.plugins);t.push(...i)}else if(Array.isArray(this.config.plugins))for(const i of this.config.plugins)if(typeof i=="string"){const o=await this.pluginLoader.load(i);o&&t.push(o)}else t.push(i)}else{const i=this.pluginLoader.getRegisteredPluginNames(),o=await this.pluginLoader.loadMultiple(i);t.push(...o)}return t}createUI(t,e){const i=this.querySelector('[slot="toolbar"]'),o=this.querySelector('[slot="statusbar"]');if(this.innerHTML="",this.config.toolbar!==!1&&!i){this.toolbarElement=document.createElement("div"),this.toolbarElement.className="editora-toolbar-container",this.appendChild(this.toolbarElement);const n=this.config.toolbarItems||this.config.toolbar;this.toolbar=new E({items:typeof n=="string"?n:void 0,sticky:this.config.toolbar&&typeof this.config.toolbar=="object"?this.config.toolbar.sticky:!1,position:"top"},t,this.pluginLoader),this.toolbar.setCommandHandler((r,s)=>{var m,u;if(this.contentElement){this.contentElement.focus();const p=window.getSelection();if(!p||p.rangeCount===0||!this.contentElement.contains(p.anchorNode)){const d=document.createRange(),h=this.contentElement.lastChild||this.contentElement;h.nodeType===Node.TEXT_NODE?d.setStart(h,((m=h.textContent)==null?void 0:m.length)||0):h.nodeType===Node.ELEMENT_NODE?(d.selectNodeContents(h),d.collapse(!1)):d.setStart(this.contentElement,0),d.collapse(!0),p==null||p.removeAllRanges(),p==null||p.addRange(d)}}const l=t.find(p=>p.commands&&p.commands[r]);if(l&&l.commands){const p=l.commands[r];if(typeof p=="function")try{return p(r==="toggleFullscreen"?this:s)}catch(d){return console.error(`[RichTextEditor] Error executing native command ${r}:`,d),!1}}return((u=this.engine)==null?void 0:u.execCommand(r,s))||!1}),this.toolbar.render(this.toolbarElement)}else i&&this.appendChild(i);this.contentElement=document.createElement("div"),this.contentElement.className="editora-content rte-content",this.contentElement.contentEditable=this.config.readonly?"false":"true",this.contentElement.setAttribute("role","textbox"),this.contentElement.setAttribute("aria-multiline","true"),this.config.placeholder&&this.contentElement.setAttribute("data-placeholder",this.config.placeholder);try{document.execCommand("defaultParagraphSeparator",!1,"p")}catch(n){console.warn("defaultParagraphSeparator not supported:",n)}if(e){const n=document.createElement("div");n.innerHTML=e.trim(),!Array.from(n.childNodes).some(s=>{if(s.nodeType===Node.ELEMENT_NODE){const l=s.tagName;return["P","DIV","H1","H2","H3","H4","H5","H6","UL","OL","BLOCKQUOTE","PRE"].includes(l)}return!1})&&e.trim()?this.contentElement.innerHTML=`<p>${e.trim()}</p>`:this.contentElement.innerHTML=e}else this.config.placeholder?this.contentElement.innerHTML="":this.contentElement.innerHTML="<p><br></p>";this.appendChild(this.contentElement),this.config.toolbar&&typeof this.config.toolbar=="object"&&this.config.toolbar.floating&&(this.floatingToolbar=new T({enabled:!0}),this.floatingToolbar.create(this)),o?this.appendChild(o):this.config.statusbar&&(this.statusBarElement=document.createElement("div"),this.statusBarElement.className="editora-statusbar-container",this.appendChild(this.statusBarElement),this.statusBar=new I({position:"bottom"}),this.statusBar.create(this.statusBarElement)),this.config.autofocus&&setTimeout(()=>{var n;return(n=this.contentElement)==null?void 0:n.focus()},0)}setupEventListeners(){if(!this.contentElement||!this.engine)return;this.contentElement.addEventListener("input",()=>{const e=this.contentElement.innerHTML;this.dispatchEvent(new CustomEvent("content-change",{detail:{html:e},bubbles:!0})),this.updateStatusBar()}),this.contentElement.addEventListener("focus",()=>{this.dispatchEvent(new Event("editor-focus",{bubbles:!0}))}),this.contentElement.addEventListener("blur",()=>{this.dispatchEvent(new Event("editor-blur",{bubbles:!0}))});const t=()=>{this.updateFloatingToolbar(),this.updateStatusBar()};document.addEventListener("selectionchange",t)}updateFloatingToolbar(){if(!this.floatingToolbar)return;const t=window.getSelection();if(!t||t.rangeCount===0){this.floatingToolbar.hide();return}const e=t.getRangeAt(0);if(e.collapsed){this.floatingToolbar.hide();return}const i=e.getBoundingClientRect();this.floatingToolbar.show(i.left,i.top-40)}updateStatusBar(){if(!this.statusBar||!this.contentElement)return;const t=this.contentElement.textContent||"",{words:e,chars:i}=H(t),o=A(this.contentElement),n=window.getSelection();let r,s;if(n&&n.rangeCount>0){const l=n.getRangeAt(0);r=D(this.contentElement,l),l.collapsed||(s=F(l,r),r=void 0)}this.statusBar.update({wordCount:e,charCount:i,lineCount:o,cursorPosition:r,selectionInfo:s})}handleAttributeChange(t,e){switch(t){case"readonly":this.contentElement&&(this.contentElement.contentEditable=e==="true"?"false":"true"),this.engine&&this.engine.setReadonly(e==="true");break;case"theme":this.classList.forEach(i=>{i.startsWith("editora-theme-")&&this.classList.remove(i)}),e&&this.classList.add(`editora-theme-${e}`);break;case"placeholder":this.contentElement&&this.contentElement.setAttribute("data-placeholder",e);break;case"toolbar":case"plugins":this.isConnected&&(this.destroy(),this.waitForPluginLoader().then(()=>{this.initialize().catch(i=>{console.error("[RichTextEditor] Error during attribute change re-initialization:",i)})}));break}}resolveConfig(){const t={};for(let e=0;e<this.attributes.length;e++){const i=this.attributes[e];t[i.name]=i.value}return C.resolve({jsConfig:this.jsConfig,attributes:t})}getAPI(){return{getContent:()=>{var t;return((t=this.contentElement)==null?void 0:t.innerHTML)||""},setContent:t=>{this.contentElement&&(this.contentElement.innerHTML=t)},execCommand:(t,e)=>{var i;return((i=this.engine)==null?void 0:i.execCommand(t,e))||!1},focus:()=>{var t;(t=this.contentElement)==null||t.focus()},blur:()=>{var t;(t=this.contentElement)==null||t.blur()},destroy:()=>{this.destroy()},on:(t,e)=>(this.addEventListener(t,e),()=>this.removeEventListener(t,e)),getConfig:()=>({...this.config}),setReadonly:t=>{this.setAttribute("readonly",t.toString())}}}destroy(){var t,e,i,o;(t=this.engine)==null||t.destroy(),(e=this.toolbar)==null||e.destroy(),(i=this.floatingToolbar)==null||i.destroy(),(o=this.statusBar)==null||o.destroy(),this.innerHTML="",this.isInitialized=!1,this.dispatchEvent(new Event("editor-destroy",{bubbles:!0}))}getContent(){var t;return((t=this.contentElement)==null?void 0:t.innerHTML)||""}setContent(t){this.contentElement&&(this.contentElement.innerHTML=t)}execCommand(t,e){var i;return((i=this.engine)==null?void 0:i.execCommand(t,e))||!1}focus(){var t;(t=this.contentElement)==null||t.focus()}blur(){var t;(t=this.contentElement)==null||t.blur()}}function tt(a){return new j(a)}function et(){typeof window!="undefined"&&!customElements.get("editora-editor")&&customElements.define("editora-editor",b)}return c.CharacterDialog=_,c.ColorPicker=U,c.CommandRegistry=M,c.ConfigResolver=C,c.Dialog=f,c.DocumentModel=x,c.Dropdown=O,c.Editor=z,c.EditorEngine=w,c.EditorState=y,c.EmojiDialog=X,c.FloatingToolbar=T,c.ImageDialog=K,c.KeyboardShortcutManager=q,c.LinkDialog=W,c.MathDialog=V,c.MediaPlugin=B,c.PluginLoader=Y,c.PluginManager=v,c.PluginRuntime=L,c.ReactAdapter=$,c.RichTextEditorElement=b,c.Schema=S,c.SpellcheckPlugin=R,c.StatusBar=I,c.TableDialog=G,c.ToolbarRenderer=E,c.VanillaAdapter=j,c.calculateTextStats=H,c.countLines=A,c.createEditor=tt,c.createPluginRuntime=N,c.createReactAdapter=J,c.getCursorPosition=D,c.getSelectionInfo=F,c.getTextOffset=P,c.initWebComponent=et,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"}),c})({});
|
|
522
|
+
//# sourceMappingURL=editora.min.js.map
|