on-codemerge
Version:
A WYSIWYG editor for on-codemerge is a user-friendly interface that allows users to edit and view their code in real time, exactly as it will appear in the final product
3 lines (2 loc) • 5.23 kB
JavaScript
/*! on-codemerge v1.3.1 @author Pavel Kuzmin @license MIT @homepage https://s00d.github.io/on-codemerge/ @repository git+https://github.com/s00d/on-codemerge.git Copyright (c) 2026 Pavel Kuzmin - Built on 2026-07-02T13:39:17.947Z */
"use strict";var s=Object.defineProperty;var a=(o,t,e)=>t in o?s(o,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[t]=e;var c=(o,t,e)=>a(o,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("../../../icons/delete.svg.cjs"),k=require("../../../icons/duplicate.svg.cjs"),h=require("../../../icons/move.svg.cjs"),l=require("../../../icons/split-horizontal.svg.cjs"),u=require("../../../icons/split-vertical.svg.cjs"),d=require("../../../core/ui/ContextMenu.cjs"),m=require("../commands/SplitBlockCommand.cjs"),B=require("../commands/MergeBlocksCommand.cjs"),p=require("../commands/BlockCommand.cjs"),v=require("../commands/DuplicateBlockCommand.cjs"),b=require("../commands/DeleteBlockCommand.cjs");class x{constructor(t){c(this,"editor");c(this,"contextMenu");c(this,"activeBlock",null);this.editor=t,this.contextMenu=new d.ContextMenu(t,[{title:t.t("Insert"),icon:"➕",subMenu:[{title:t.t("Text Block"),action:"insert-text",onClick:()=>this.handleAction("insert-text")},{title:t.t("Container Block"),action:"insert-container",onClick:()=>this.handleAction("insert-container")},{title:t.t("Split Container"),action:"insert-split",onClick:()=>this.handleAction("insert-split")}]},{title:t.t("Split"),icon:l.default,subMenu:[{title:t.t("Horizontally"),icon:l.default,action:"split-horizontal",onClick:()=>this.handleAction("split-horizontal")},{title:t.t("Vertically"),icon:u.default,action:"split-vertical",onClick:()=>this.handleAction("split-vertical")}]},{title:t.t("Merge"),icon:"🔗",action:"merge",onClick:()=>this.handleAction("merge")},{type:"divider"},{title:t.t("Move"),icon:h.default,subMenu:[{title:t.t("Up"),action:"move-up",onClick:()=>this.handleAction("move-up")},{title:t.t("Down"),action:"move-down",onClick:()=>this.handleAction("move-down")}]},{title:t.t("Duplicate"),icon:k.default,action:"duplicate",onClick:()=>this.handleAction("duplicate")},{type:"divider"},{title:t.t("Settings"),icon:"🔧",subMenu:[{title:t.t("Make Editable"),action:"make-editable",onClick:()=>this.handleAction("make-editable")},{title:t.t("Make Read-only"),action:"make-readonly",onClick:()=>this.handleAction("make-readonly")}]},{title:t.t("Remove"),icon:r.default,action:"remove",className:"text-red-600",onClick:()=>this.handleAction("remove")}],{orientation:"vertical"})}handleAction(t){if(this.activeBlock){switch(t){case"insert-text":this.insertBlock("text");break;case"insert-container":this.insertBlock("container");break;case"insert-split":this.insertBlock("split");break;case"split-horizontal":this.splitBlock("horizontal");break;case"split-vertical":this.splitBlock("vertical");break;case"merge":this.mergeBlocks();break;case"move-up":this.moveBlock("up");break;case"move-down":this.moveBlock("down");break;case"duplicate":this.duplicateBlock();break;case"make-editable":this.setBlockEditable(!0);break;case"make-readonly":this.setBlockEditable(!1);break;case"remove":this.removeBlock();break}this.hide()}}insertBlock(t){new p.BlockCommand(this.editor).execute({type:t})}splitBlock(t){if(!this.activeBlock||!this.canSplit(this.activeBlock))return;const e=new m.SplitBlockCommand(this.editor);e.setData({direction:t,block:this.activeBlock}),e.execute()}mergeBlocks(){if(!this.activeBlock)return;const t=this.getAdjacentBlocks(this.activeBlock);if(t.length<2)return;const e=new B.MergeBlocksCommand(this.editor);e.setData({blocks:t}),e.execute()}moveBlock(t){var e,n;if(this.activeBlock)if(t==="up"){const i=this.activeBlock.previousElementSibling;i&&i.classList.contains("editor-block")&&((e=i.parentNode)==null||e.insertBefore(this.activeBlock,i))}else{const i=this.activeBlock.nextElementSibling;i&&i.classList.contains("editor-block")&&((n=i.parentNode)==null||n.insertBefore(i,this.activeBlock))}}duplicateBlock(){if(!this.activeBlock)return;const t=new v.DuplicateBlockCommand(this.editor);t.setData({block:this.activeBlock}),t.execute()}setBlockEditable(t){if(!this.activeBlock)return;const e=this.activeBlock.querySelector(".block-content");e&&(e.contentEditable=t.toString())}removeBlock(){if(!this.activeBlock)return;const t=new b.DeleteBlockCommand(this.editor);t.setBlock(this.activeBlock),t.execute()}canSplit(t){return t.classList.contains("editor-block")&&!t.classList.contains("split-container")&&t.getAttribute("data-block-type")==="text"}getAdjacentBlocks(t){const e=[];e.push(t);let n=t.previousElementSibling;for(;n&&n.classList.contains("editor-block")&&n.getAttribute("data-block-type")==="text";)e.unshift(n),n=n.previousElementSibling;let i=t.nextElementSibling;for(;i&&i.classList.contains("editor-block")&&i.getAttribute("data-block-type")==="text";)e.push(i),i=i.nextElementSibling;return e}show(t,e,n){this.activeBlock=t,this.contextMenu.show(t,e,n)}hide(){this.contextMenu.hide(),this.activeBlock=null}destroy(){this.contextMenu&&typeof this.contextMenu.destroy=="function"&&this.contextMenu.destroy(),this.editor=null,this.contextMenu=null,this.activeBlock=null}}exports.BlockContextMenu=x;