Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@editora/code

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@editora/code - npm Package Compare versions

Comparing version
1.0.1
to
1.0.2
+448
dist/index.cjs.js
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const s=require("@editora/light-code-editor"),x='[data-theme="dark"], .dark, .editora-theme-dark',z=`/* Source Editor Dialog Styles */
.rte-source-editor-overlay {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
width: 100vw !important;
height: 100vh !important;
background-color: rgba(0, 0, 0, 0.6) !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
z-index: 10000 !important;
padding: 20px !important;
box-sizing: border-box !important;
margin: 0 !important;
}
.rte-source-editor-overlay.fullscreen {
padding: 0 !important;
}
.rte-source-editor-modal {
background: white;
border-radius: 8px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
width: 100%;
max-width: 1200px;
max-height: 90vh;
display: flex;
flex-direction: column;
overflow: hidden;
position: relative;
}
.rte-source-editor-overlay.fullscreen .rte-source-editor-modal {
border-radius: 0;
max-width: 100%;
max-height: 100vh;
width: 100%;
height: 100vh;
}
.rte-source-editor-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
border-bottom: 1px solid #e1e5e9;
background: #f8f9fa;
border-radius: 8px 8px 0 0;
}
.rte-source-editor-overlay.fullscreen .rte-source-editor-header {
border-radius: 0;
}
.rte-source-editor-header h2 {
margin: 0;
font-size: 18px;
font-weight: 600;
color: #1a1a1a;
}
.rte-source-editor-header-toolbar {
display: flex;
gap: 8px;
margin-left: auto;
margin-right: 16px;
}
.rte-source-editor-toolbar-btn {
background: none;
border: none;
cursor: pointer;
padding: 6px;
border-radius: 4px;
font-size: 16px;
line-height: 1;
transition: all 0.2s ease;
color: #666;
}
.rte-source-editor-toolbar-btn:hover:not(:disabled) {
background: #e1e5e9;
color: #1a1a1a;
}
.rte-source-editor-toolbar-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.rte-source-editor-toolbar-btn.active {
background: #007acc;
color: white;
}
.rte-source-editor-toolbar-btn.active:hover {
background: #0056b3;
}
.rte-source-editor-header-actions {
display: flex;
gap: 8px;
}
.rte-source-editor-fullscreen-btn,
.rte-source-editor-close-btn {
background: none;
border: none;
cursor: pointer;
padding: 4px;
border-radius: 4px;
color: #666;
font-size: 16px;
line-height: 1;
transition: all 0.2s ease;
}
.rte-source-editor-fullscreen-btn:hover,
.rte-source-editor-close-btn:hover {
background: #e1e5e9;
color: #1a1a1a;
}
.rte-source-editor-body {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.rte-source-editor-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px;
color: #666;
position: absolute;
z-index: 9;
margin: 0 auto;
width: 100%;
top: 44%;
}
.rte-source-editor-spinner {
width: 32px;
height: 32px;
border: 3px solid #e1e5e9;
border-top: 3px solid #007acc;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 16px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.rte-source-editor-error {
background: #fee;
color: #c53030;
padding: 12px 16px;
border-left: 4px solid #c53030;
margin: 16px;
border-radius: 4px;
font-size: 14px;
}
.rte-source-editor-content {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.rte-source-editor-warning {
background: #fefcbf;
color: #744210;
padding: 8px 16px;
font-size: 12px;
font-weight: 500;
border-bottom: 1px solid #f6e05e;
}
.rte-source-editor-codemirror {
flex: 1;
overflow: auto;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 14px;
line-height: 1.5;
}
.rte-source-editor-codemirror .cm-editor {
height: 100%;
}
.rte-source-editor-codemirror .cm-focused {
outline: none;
}
.rte-source-editor-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
border-top: 1px solid #e1e5e9;
background: #f8f9fa;
border-radius: 0 0 8px 8px;
}
.rte-source-editor-overlay.fullscreen .rte-source-editor-footer {
border-radius: 0;
}
.rte-source-editor-footer-info {
font-size: 12px;
color: #666;
}
.unsaved-changes {
color: #d69e2e;
font-weight: 500;
}
.rte-source-editor-footer-actions {
display: flex;
gap: 12px;
}
.rte-source-editor-btn {
padding: 8px 16px;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
border: 1px solid transparent;
transition: all 0.2s ease;
}
.rte-source-editor-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.rte-source-editor-btn-cancel {
background: white;
border-color: #d1d5db;
color: #374151;
}
.rte-source-editor-btn-cancel:hover:not(:disabled) {
background: #f9fafb;
border-color: #9ca3af;
}
.rte-source-editor-btn-save {
background: #007acc;
color: white;
}
.rte-source-editor-btn-save:hover:not(:disabled) {
background: #0056b3;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-modal {
background: #1e1e1e;
color: #f8f9fa;
border: 1px solid #434d5f;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-header,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-footer {
background: #2a3442;
border-color: #434d5f;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-header h2 {
color: #f8f9fa;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-fullscreen-btn,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-close-btn {
color: #c1cede;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn:hover:not(:disabled),
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-fullscreen-btn:hover,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-close-btn:hover {
background: #404a5a;
color: #f8fafc;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn.active {
background: #3b82f6;
color: #ffffff;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn.active:hover {
background: #2563eb;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-loading,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-footer-info {
color: #cbd5e1;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-spinner {
border-color: #3f4b60;
border-top-color: #58a6ff;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-error {
background: #3f2124;
color: #fecaca;
border-color: #ef4444;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-warning {
background: #3b3220;
color: #fde68a;
border-color: #f59e0b;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-cancel {
background: #334155;
border-color: #475569;
color: #f1f5f9;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-cancel:hover:not(:disabled) {
background: #475569;
border-color: #64748b;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-save {
background: #3b82f6;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-save:hover:not(:disabled) {
background: #2563eb;
}
/* Responsive design */
@media (max-width: 768px) {
.rte-source-editor-overlay {
padding: 10px;
}
.rte-source-editor-modal {
max-height: 95vh;
}
.rte-source-editor-header {
padding: 12px 16px;
}
.rte-source-editor-footer {
padding: 12px 16px;
flex-direction: column;
gap: 12px;
align-items: stretch;
}
.rte-source-editor-footer-actions {
justify-content: stretch;
}
.rte-source-editor-btn {
flex: 1;
text-align: center;
}
}`,q=()=>({name:"code",toolbar:[{label:"Source",command:"toggleSourceView",icon:'<svg width="24" height="24" focusable="false"><g fill-rule="nonzero"><path d="M9.8 15.7c.3.3.3.8 0 1-.3.4-.9.4-1.2 0l-4.4-4.1a.8.8 0 0 1 0-1.2l4.4-4.2c.3-.3.9-.3 1.2 0 .3.3.3.8 0 1.1L6 12l3.8 3.7ZM14.2 15.7c-.3.3-.3.8 0 1 .4.4.9.4 1.2 0l4.4-4.1c.3-.3.3-.9 0-1.2l-4.4-4.2a.8.8 0 0 0-1.2 0c-.3.3-.3.8 0 1.1L18 12l-3.8 3.7Z"></path></g></svg>',shortcut:"Mod-Shift-S"}],commands:{toggleSourceView:()=>{const l=(()=>{const r=window.getSelection();if(r&&r.anchorNode){let e=r.anchorNode instanceof HTMLElement?r.anchorNode:r.anchorNode.parentElement;for(;e;){if(e.classList?.contains("rte-content"))return e;e=e.parentElement}}if(document.activeElement){let e=document.activeElement;if(e.classList?.contains("rte-content"))return e;for(;e&&e!==document.body;){if(e.classList?.contains("rte-content"))return e;const n=e.querySelector(".rte-content");if(n)return n;e=e.parentElement}}const o=document.querySelector("[data-editora-editor]");if(o){const e=o.querySelector(".rte-content");if(e)return e}return document.querySelector(".rte-content")})();if(!l)return console.error("[CodePlugin] Editor content area not found"),alert("Editor content area not found. Please click inside the editor first."),!1;const y=l.innerHTML,k=r=>{let o="",e=0;const n=2,u=r.split(/(<\/?[a-zA-Z][^>]*>)/);for(const i of u)i.trim()&&(i.match(/^<\/[a-zA-Z]/)?(e=Math.max(0,e-1),o+=`
`+" ".repeat(e*n)+i):i.match(/^<[a-zA-Z]/)&&!i.match(/\/>$/)?(o+=`
`+" ".repeat(e*n)+i,e++):i.match(/^<[a-zA-Z].*\/>$/)?o+=`
`+" ".repeat(e*n)+i:o+=i.trim());return o.trim()};return(()=>{let r=null,o="dark",e=!1,n=!1,u=!1;const i=y,E=!!l.closest(x)||document.body.matches(x)||document.documentElement.matches(x),a=document.createElement("div");a.className="rte-source-editor-overlay",E&&a.classList.add("rte-theme-dark");const c=document.createElement("div");c.className="rte-source-editor-modal",c.setAttribute("role","dialog"),c.setAttribute("aria-modal","true"),c.setAttribute("aria-labelledby","source-editor-title");const d=document.createElement("div");d.className="rte-source-editor-header",d.innerHTML=`
<h2 id="source-editor-title">Source Editor</h2>
<div class="rte-source-editor-header-toolbar">
<button class="rte-source-editor-toolbar-btn theme-toggle-btn" title="Switch theme">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="5"/>
<line x1="12" y1="1" x2="12" y2="3"/>
<line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/>
<line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
</button>
<button class="rte-source-editor-toolbar-btn readonly-toggle-btn" title="Toggle read-only">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
</svg>
</button>
</div>
<div class="rte-source-editor-header-actions">
<button class="rte-source-editor-fullscreen-btn" title="Toggle fullscreen">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>
</svg>
</button>
<button class="rte-source-editor-close-btn" aria-label="Close source editor">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="18" y1="6" x2="6" y2="18"/>
<line x1="6" y1="6" x2="18" y2="18"/>
</svg>
</button>
</div>
`;const p=document.createElement("div");p.className="rte-source-editor-body";const m=document.createElement("div");m.className="rte-source-editor-content";const v=document.createElement("div");v.className="rte-source-editor-warning",v.textContent="⚠️ Advanced users only. Invalid HTML may break the editor.";const h=document.createElement("div");h.className="rte-source-editor-light-editor",h.style.height="400px",m.appendChild(v),m.appendChild(h),p.appendChild(m);const b=document.createElement("div");if(b.className="rte-source-editor-footer",b.innerHTML=`
<div class="rte-source-editor-footer-info">
<span class="unsaved-changes" style="display: none;">• Unsaved changes</span>
</div>
<div class="rte-source-editor-footer-actions">
<button class="rte-source-editor-btn rte-source-editor-btn-cancel">Cancel</button>
<button class="rte-source-editor-btn rte-source-editor-btn-save">Save</button>
</div>
`,c.appendChild(d),c.appendChild(p),c.appendChild(b),a.appendChild(c),!document.getElementById("rte-source-editor-styles")){const t=document.createElement("style");t.id="rte-source-editor-styles",t.textContent=z,document.head.appendChild(t)}document.body.appendChild(a);try{r=s.createEditor(h,{value:k(y),theme:"dark",readOnly:!1,extensions:[new s.LineNumbersExtension,new s.ThemeExtension,new s.ReadOnlyExtension,new s.BracketMatchingExtension,new s.SearchExtension,new s.CodeFoldingExtension,new s.SyntaxHighlightingExtension]}),r.on("change",()=>{u=(r?.getValue()||"")!==k(i);const f=b.querySelector(".unsaved-changes");f&&(f.style.display=u?"inline":"none")}),setTimeout(()=>r?.focus(),100)}catch(t){console.error("Failed to initialize code editor:",t)}const M=()=>{o=o==="dark"?"light":"dark",r?.setTheme(o);const t=d.querySelector(".theme-toggle-btn");t&&o==="light"&&(t.innerHTML=`
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
</svg>
`)},S=()=>{e=!e,r?.setReadOnly(e);const t=d.querySelector(".readonly-toggle-btn");t&&(e?(t.classList.add("active"),t.innerHTML=`
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
<circle cx="12" cy="16" r="1"/>
<path d="M7 11V7a5 5 0 0 1 10 0v4"/>
</svg>
`):(t.classList.remove("active"),t.innerHTML=`
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
</svg>
`))},C=()=>{n=!n,n?(a.classList.add("fullscreen"),h.style.height="calc(100vh - 200px)"):(a.classList.remove("fullscreen"),h.style.height="400px");const t=d.querySelector(".rte-source-editor-fullscreen-btn");t&&(t.innerHTML=n?`
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 0 2-2h3M3 16h3a2 2 0 0 0 2 2v3"/>
</svg>
`:`
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>
</svg>
`)},g=()=>{r&&(r.destroy(),r=null),document.body.removeChild(a)},L=()=>{u&&!confirm("You have unsaved changes. Are you sure you want to cancel?")||g()},T=()=>{try{const t=r?.getValue()||"",f=document.createElement("div");f.innerHTML=t,f.querySelectorAll('script, iframe[src^="javascript:"], object, embed').forEach(H=>H.remove()),l.innerHTML=f.innerHTML;try{l.dispatchEvent(new InputEvent("input",{bubbles:!0,cancelable:!1,inputType:"insertReplacementText"}))}catch{l.dispatchEvent(new Event("input",{bubbles:!0}))}l.dispatchEvent(new Event("change",{bubbles:!0})),u=!1,g()}catch(t){alert("Failed to update HTML. Please check your syntax."),console.error("HTML update error:",t)}};d.querySelector(".theme-toggle-btn")?.addEventListener("click",M),d.querySelector(".readonly-toggle-btn")?.addEventListener("click",S),d.querySelector(".rte-source-editor-fullscreen-btn")?.addEventListener("click",C),d.querySelector(".rte-source-editor-close-btn")?.addEventListener("click",g),b.querySelector(".rte-source-editor-btn-cancel")?.addEventListener("click",L),b.querySelector(".rte-source-editor-btn-save")?.addEventListener("click",T),a.addEventListener("click",t=>{t.target===a&&g()});const w=t=>{t.key==="Escape"&&(g(),document.removeEventListener("keydown",w))};document.addEventListener("keydown",w)})(),!0}},keymap:{"Mod-Shift-s":"toggleSourceView","Mod-Shift-S":"toggleSourceView"}});exports.CodePlugin=q;
import { createEditor as H, LineNumbersExtension as z, ThemeExtension as q, ReadOnlyExtension as B, BracketMatchingExtension as N, SearchExtension as A, CodeFoldingExtension as R, SyntaxHighlightingExtension as D } from "@editora/light-code-editor";
const v = '[data-theme="dark"], .dark, .editora-theme-dark', O = `/* Source Editor Dialog Styles */
.rte-source-editor-overlay {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
width: 100vw !important;
height: 100vh !important;
background-color: rgba(0, 0, 0, 0.6) !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
z-index: 10000 !important;
padding: 20px !important;
box-sizing: border-box !important;
margin: 0 !important;
}
.rte-source-editor-overlay.fullscreen {
padding: 0 !important;
}
.rte-source-editor-modal {
background: white;
border-radius: 8px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
width: 100%;
max-width: 1200px;
max-height: 90vh;
display: flex;
flex-direction: column;
overflow: hidden;
position: relative;
}
.rte-source-editor-overlay.fullscreen .rte-source-editor-modal {
border-radius: 0;
max-width: 100%;
max-height: 100vh;
width: 100%;
height: 100vh;
}
.rte-source-editor-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
border-bottom: 1px solid #e1e5e9;
background: #f8f9fa;
border-radius: 8px 8px 0 0;
}
.rte-source-editor-overlay.fullscreen .rte-source-editor-header {
border-radius: 0;
}
.rte-source-editor-header h2 {
margin: 0;
font-size: 18px;
font-weight: 600;
color: #1a1a1a;
}
.rte-source-editor-header-toolbar {
display: flex;
gap: 8px;
margin-left: auto;
margin-right: 16px;
}
.rte-source-editor-toolbar-btn {
background: none;
border: none;
cursor: pointer;
padding: 6px;
border-radius: 4px;
font-size: 16px;
line-height: 1;
transition: all 0.2s ease;
color: #666;
}
.rte-source-editor-toolbar-btn:hover:not(:disabled) {
background: #e1e5e9;
color: #1a1a1a;
}
.rte-source-editor-toolbar-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.rte-source-editor-toolbar-btn.active {
background: #007acc;
color: white;
}
.rte-source-editor-toolbar-btn.active:hover {
background: #0056b3;
}
.rte-source-editor-header-actions {
display: flex;
gap: 8px;
}
.rte-source-editor-fullscreen-btn,
.rte-source-editor-close-btn {
background: none;
border: none;
cursor: pointer;
padding: 4px;
border-radius: 4px;
color: #666;
font-size: 16px;
line-height: 1;
transition: all 0.2s ease;
}
.rte-source-editor-fullscreen-btn:hover,
.rte-source-editor-close-btn:hover {
background: #e1e5e9;
color: #1a1a1a;
}
.rte-source-editor-body {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.rte-source-editor-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px;
color: #666;
position: absolute;
z-index: 9;
margin: 0 auto;
width: 100%;
top: 44%;
}
.rte-source-editor-spinner {
width: 32px;
height: 32px;
border: 3px solid #e1e5e9;
border-top: 3px solid #007acc;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 16px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.rte-source-editor-error {
background: #fee;
color: #c53030;
padding: 12px 16px;
border-left: 4px solid #c53030;
margin: 16px;
border-radius: 4px;
font-size: 14px;
}
.rte-source-editor-content {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.rte-source-editor-warning {
background: #fefcbf;
color: #744210;
padding: 8px 16px;
font-size: 12px;
font-weight: 500;
border-bottom: 1px solid #f6e05e;
}
.rte-source-editor-codemirror {
flex: 1;
overflow: auto;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 14px;
line-height: 1.5;
}
.rte-source-editor-codemirror .cm-editor {
height: 100%;
}
.rte-source-editor-codemirror .cm-focused {
outline: none;
}
.rte-source-editor-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
border-top: 1px solid #e1e5e9;
background: #f8f9fa;
border-radius: 0 0 8px 8px;
}
.rte-source-editor-overlay.fullscreen .rte-source-editor-footer {
border-radius: 0;
}
.rte-source-editor-footer-info {
font-size: 12px;
color: #666;
}
.unsaved-changes {
color: #d69e2e;
font-weight: 500;
}
.rte-source-editor-footer-actions {
display: flex;
gap: 12px;
}
.rte-source-editor-btn {
padding: 8px 16px;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
border: 1px solid transparent;
transition: all 0.2s ease;
}
.rte-source-editor-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.rte-source-editor-btn-cancel {
background: white;
border-color: #d1d5db;
color: #374151;
}
.rte-source-editor-btn-cancel:hover:not(:disabled) {
background: #f9fafb;
border-color: #9ca3af;
}
.rte-source-editor-btn-save {
background: #007acc;
color: white;
}
.rte-source-editor-btn-save:hover:not(:disabled) {
background: #0056b3;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-modal {
background: #1e1e1e;
color: #f8f9fa;
border: 1px solid #434d5f;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-header,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-footer {
background: #2a3442;
border-color: #434d5f;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-header h2 {
color: #f8f9fa;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-fullscreen-btn,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-close-btn {
color: #c1cede;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn:hover:not(:disabled),
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-fullscreen-btn:hover,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-close-btn:hover {
background: #404a5a;
color: #f8fafc;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn.active {
background: #3b82f6;
color: #ffffff;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn.active:hover {
background: #2563eb;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-loading,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-footer-info {
color: #cbd5e1;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-spinner {
border-color: #3f4b60;
border-top-color: #58a6ff;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-error {
background: #3f2124;
color: #fecaca;
border-color: #ef4444;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-warning {
background: #3b3220;
color: #fde68a;
border-color: #f59e0b;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-cancel {
background: #334155;
border-color: #475569;
color: #f1f5f9;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-cancel:hover:not(:disabled) {
background: #475569;
border-color: #64748b;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-save {
background: #3b82f6;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-save:hover:not(:disabled) {
background: #2563eb;
}
/* Responsive design */
@media (max-width: 768px) {
.rte-source-editor-overlay {
padding: 10px;
}
.rte-source-editor-modal {
max-height: 95vh;
}
.rte-source-editor-header {
padding: 12px 16px;
}
.rte-source-editor-footer {
padding: 12px 16px;
flex-direction: column;
gap: 12px;
align-items: stretch;
}
.rte-source-editor-footer-actions {
justify-content: stretch;
}
.rte-source-editor-btn {
flex: 1;
text-align: center;
}
}`, I = () => ({
name: "code",
// Toolbar button configuration
toolbar: [
{
label: "Source",
command: "toggleSourceView",
// type: "button",
icon: '<svg width="24" height="24" focusable="false"><g fill-rule="nonzero"><path d="M9.8 15.7c.3.3.3.8 0 1-.3.4-.9.4-1.2 0l-4.4-4.1a.8.8 0 0 1 0-1.2l4.4-4.2c.3-.3.9-.3 1.2 0 .3.3.3.8 0 1.1L6 12l3.8 3.7ZM14.2 15.7c-.3.3-.3.8 0 1 .4.4.9.4 1.2 0l4.4-4.1c.3-.3.3-.9 0-1.2l-4.4-4.2a.8.8 0 0 0-1.2 0c-.3.3-.3.8 0 1.1L18 12l-3.8 3.7Z"></path></g></svg>',
shortcut: "Mod-Shift-S"
}
],
// Native command implementations
commands: {
/**
* Toggle HTML source view
* Opens a dialog to edit raw HTML
*/
toggleSourceView: () => {
const s = (() => {
const r = window.getSelection();
if (r && r.anchorNode) {
let e = r.anchorNode instanceof HTMLElement ? r.anchorNode : r.anchorNode.parentElement;
for (; e; ) {
if (e.classList?.contains("rte-content"))
return e;
e = e.parentElement;
}
}
if (document.activeElement) {
let e = document.activeElement;
if (e.classList?.contains("rte-content"))
return e;
for (; e && e !== document.body; ) {
if (e.classList?.contains("rte-content"))
return e;
const n = e.querySelector(
".rte-content"
);
if (n) return n;
e = e.parentElement;
}
}
const o = document.querySelector("[data-editora-editor]");
if (o) {
const e = o.querySelector(
".rte-content"
);
if (e) return e;
}
return document.querySelector(".rte-content");
})();
if (!s)
return console.error("[CodePlugin] Editor content area not found"), alert(
"Editor content area not found. Please click inside the editor first."
), !1;
const x = s.innerHTML, y = (r) => {
let o = "", e = 0;
const n = 2, l = r.split(/(<\/?[a-zA-Z][^>]*>)/);
for (const i of l)
i.trim() && (i.match(/^<\/[a-zA-Z]/) ? (e = Math.max(0, e - 1), o += `
` + " ".repeat(e * n) + i) : i.match(/^<[a-zA-Z]/) && !i.match(/\/>$/) ? (o += `
` + " ".repeat(e * n) + i, e++) : i.match(/^<[a-zA-Z].*\/>$/) ? o += `
` + " ".repeat(e * n) + i : o += i.trim());
return o.trim();
};
return (() => {
let r = null, o = "dark", e = !1, n = !1, l = !1;
const i = x, w = !!s.closest(v) || document.body.matches(v) || document.documentElement.matches(v), a = document.createElement("div");
a.className = "rte-source-editor-overlay", w && a.classList.add("rte-theme-dark");
const c = document.createElement("div");
c.className = "rte-source-editor-modal", c.setAttribute("role", "dialog"), c.setAttribute("aria-modal", "true"), c.setAttribute("aria-labelledby", "source-editor-title");
const d = document.createElement("div");
d.className = "rte-source-editor-header", d.innerHTML = `
<h2 id="source-editor-title">Source Editor</h2>
<div class="rte-source-editor-header-toolbar">
<button class="rte-source-editor-toolbar-btn theme-toggle-btn" title="Switch theme">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="5"/>
<line x1="12" y1="1" x2="12" y2="3"/>
<line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/>
<line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
</button>
<button class="rte-source-editor-toolbar-btn readonly-toggle-btn" title="Toggle read-only">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
</svg>
</button>
</div>
<div class="rte-source-editor-header-actions">
<button class="rte-source-editor-fullscreen-btn" title="Toggle fullscreen">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>
</svg>
</button>
<button class="rte-source-editor-close-btn" aria-label="Close source editor">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="18" y1="6" x2="6" y2="18"/>
<line x1="6" y1="6" x2="18" y2="18"/>
</svg>
</button>
</div>
`;
const g = document.createElement("div");
g.className = "rte-source-editor-body";
const m = document.createElement("div");
m.className = "rte-source-editor-content";
const p = document.createElement("div");
p.className = "rte-source-editor-warning", p.textContent = "⚠️ Advanced users only. Invalid HTML may break the editor.";
const u = document.createElement("div");
u.className = "rte-source-editor-light-editor", u.style.height = "400px", m.appendChild(p), m.appendChild(u), g.appendChild(m);
const h = document.createElement("div");
if (h.className = "rte-source-editor-footer", h.innerHTML = `
<div class="rte-source-editor-footer-info">
<span class="unsaved-changes" style="display: none;">• Unsaved changes</span>
</div>
<div class="rte-source-editor-footer-actions">
<button class="rte-source-editor-btn rte-source-editor-btn-cancel">Cancel</button>
<button class="rte-source-editor-btn rte-source-editor-btn-save">Save</button>
</div>
`, c.appendChild(d), c.appendChild(g), c.appendChild(h), a.appendChild(c), !document.getElementById("rte-source-editor-styles")) {
const t = document.createElement("style");
t.id = "rte-source-editor-styles", t.textContent = O, document.head.appendChild(t);
}
document.body.appendChild(a);
try {
r = H(u, {
value: y(x),
theme: "dark",
readOnly: !1,
extensions: [
new z(),
new q(),
new B(),
new N(),
new A(),
new R(),
new D()
]
}), r.on("change", () => {
l = (r?.getValue() || "") !== y(i);
const b = h.querySelector(
".unsaved-changes"
);
b && (b.style.display = l ? "inline" : "none");
}), setTimeout(() => r?.focus(), 100);
} catch (t) {
console.error("Failed to initialize code editor:", t);
}
const E = () => {
o = o === "dark" ? "light" : "dark", r?.setTheme(o);
const t = d.querySelector(".theme-toggle-btn");
t && o === "light" && (t.innerHTML = `
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
</svg>
`);
}, M = () => {
e = !e, r?.setReadOnly(e);
const t = d.querySelector(".readonly-toggle-btn");
t && (e ? (t.classList.add("active"), t.innerHTML = `
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
<circle cx="12" cy="16" r="1"/>
<path d="M7 11V7a5 5 0 0 1 10 0v4"/>
</svg>
`) : (t.classList.remove("active"), t.innerHTML = `
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
</svg>
`));
}, S = () => {
n = !n, n ? (a.classList.add("fullscreen"), u.style.height = "calc(100vh - 200px)") : (a.classList.remove("fullscreen"), u.style.height = "400px");
const t = d.querySelector(
".rte-source-editor-fullscreen-btn"
);
t && (t.innerHTML = n ? `
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 0 2-2h3M3 16h3a2 2 0 0 0 2 2v3"/>
</svg>
` : `
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>
</svg>
`);
}, f = () => {
r && (r.destroy(), r = null), document.body.removeChild(a);
}, L = () => {
l && !confirm(
"You have unsaved changes. Are you sure you want to cancel?"
) || f();
}, C = () => {
try {
const t = r?.getValue() || "", b = document.createElement("div");
b.innerHTML = t, b.querySelectorAll(
'script, iframe[src^="javascript:"], object, embed'
).forEach((T) => T.remove()), s.innerHTML = b.innerHTML;
try {
s.dispatchEvent(
new InputEvent("input", {
bubbles: !0,
cancelable: !1,
inputType: "insertReplacementText"
})
);
} catch {
s.dispatchEvent(
new Event("input", { bubbles: !0 })
);
}
s.dispatchEvent(
new Event("change", { bubbles: !0 })
), l = !1, f();
} catch (t) {
alert("Failed to update HTML. Please check your syntax."), console.error("HTML update error:", t);
}
};
d.querySelector(".theme-toggle-btn")?.addEventListener("click", E), d.querySelector(".readonly-toggle-btn")?.addEventListener("click", M), d.querySelector(".rte-source-editor-fullscreen-btn")?.addEventListener("click", S), d.querySelector(".rte-source-editor-close-btn")?.addEventListener("click", f), h.querySelector(".rte-source-editor-btn-cancel")?.addEventListener("click", L), h.querySelector(".rte-source-editor-btn-save")?.addEventListener("click", C), a.addEventListener("click", (t) => {
t.target === a && f();
});
const k = (t) => {
t.key === "Escape" && (f(), document.removeEventListener("keydown", k));
};
document.addEventListener("keydown", k);
})(), !0;
}
},
// Keyboard shortcuts
keymap: {
"Mod-Shift-s": "toggleSourceView",
"Mod-Shift-S": "toggleSourceView"
}
});
export {
I as CodePlugin
};
+11
-3
{
"name": "@editora/code",
"version": "1.0.1",
"version": "1.0.2",
"description": "Source Code Editor plugin for Rich Text Editor",

@@ -24,3 +24,3 @@ "authors": [

"peerDependencies": {
"@editora/core": "^1.0.5"
"@editora/core": "^1.0.6"
},

@@ -41,3 +41,11 @@ "devDependencies": {

"author": "",
"license": "MIT"
"license": "MIT",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.esm.js",
"require": "./dist/index.cjs.js",
"default": "./dist/index.esm.js"
}
}
}
import { createEditor as H, LineNumbersExtension as z, ThemeExtension as q, ReadOnlyExtension as B, BracketMatchingExtension as N, SearchExtension as A, CodeFoldingExtension as R, SyntaxHighlightingExtension as D } from "@editora/light-code-editor";
const v = '[data-theme="dark"], .dark, .editora-theme-dark', O = `/* Source Editor Dialog Styles */
.rte-source-editor-overlay {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
width: 100vw !important;
height: 100vh !important;
background-color: rgba(0, 0, 0, 0.6) !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
z-index: 10000 !important;
padding: 20px !important;
box-sizing: border-box !important;
margin: 0 !important;
}
.rte-source-editor-overlay.fullscreen {
padding: 0 !important;
}
.rte-source-editor-modal {
background: white;
border-radius: 8px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
width: 100%;
max-width: 1200px;
max-height: 90vh;
display: flex;
flex-direction: column;
overflow: hidden;
position: relative;
}
.rte-source-editor-overlay.fullscreen .rte-source-editor-modal {
border-radius: 0;
max-width: 100%;
max-height: 100vh;
width: 100%;
height: 100vh;
}
.rte-source-editor-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
border-bottom: 1px solid #e1e5e9;
background: #f8f9fa;
border-radius: 8px 8px 0 0;
}
.rte-source-editor-overlay.fullscreen .rte-source-editor-header {
border-radius: 0;
}
.rte-source-editor-header h2 {
margin: 0;
font-size: 18px;
font-weight: 600;
color: #1a1a1a;
}
.rte-source-editor-header-toolbar {
display: flex;
gap: 8px;
margin-left: auto;
margin-right: 16px;
}
.rte-source-editor-toolbar-btn {
background: none;
border: none;
cursor: pointer;
padding: 6px;
border-radius: 4px;
font-size: 16px;
line-height: 1;
transition: all 0.2s ease;
color: #666;
}
.rte-source-editor-toolbar-btn:hover:not(:disabled) {
background: #e1e5e9;
color: #1a1a1a;
}
.rte-source-editor-toolbar-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.rte-source-editor-toolbar-btn.active {
background: #007acc;
color: white;
}
.rte-source-editor-toolbar-btn.active:hover {
background: #0056b3;
}
.rte-source-editor-header-actions {
display: flex;
gap: 8px;
}
.rte-source-editor-fullscreen-btn,
.rte-source-editor-close-btn {
background: none;
border: none;
cursor: pointer;
padding: 4px;
border-radius: 4px;
color: #666;
font-size: 16px;
line-height: 1;
transition: all 0.2s ease;
}
.rte-source-editor-fullscreen-btn:hover,
.rte-source-editor-close-btn:hover {
background: #e1e5e9;
color: #1a1a1a;
}
.rte-source-editor-body {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.rte-source-editor-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px;
color: #666;
position: absolute;
z-index: 9;
margin: 0 auto;
width: 100%;
top: 44%;
}
.rte-source-editor-spinner {
width: 32px;
height: 32px;
border: 3px solid #e1e5e9;
border-top: 3px solid #007acc;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 16px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.rte-source-editor-error {
background: #fee;
color: #c53030;
padding: 12px 16px;
border-left: 4px solid #c53030;
margin: 16px;
border-radius: 4px;
font-size: 14px;
}
.rte-source-editor-content {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.rte-source-editor-warning {
background: #fefcbf;
color: #744210;
padding: 8px 16px;
font-size: 12px;
font-weight: 500;
border-bottom: 1px solid #f6e05e;
}
.rte-source-editor-codemirror {
flex: 1;
overflow: auto;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 14px;
line-height: 1.5;
}
.rte-source-editor-codemirror .cm-editor {
height: 100%;
}
.rte-source-editor-codemirror .cm-focused {
outline: none;
}
.rte-source-editor-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
border-top: 1px solid #e1e5e9;
background: #f8f9fa;
border-radius: 0 0 8px 8px;
}
.rte-source-editor-overlay.fullscreen .rte-source-editor-footer {
border-radius: 0;
}
.rte-source-editor-footer-info {
font-size: 12px;
color: #666;
}
.unsaved-changes {
color: #d69e2e;
font-weight: 500;
}
.rte-source-editor-footer-actions {
display: flex;
gap: 12px;
}
.rte-source-editor-btn {
padding: 8px 16px;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
border: 1px solid transparent;
transition: all 0.2s ease;
}
.rte-source-editor-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.rte-source-editor-btn-cancel {
background: white;
border-color: #d1d5db;
color: #374151;
}
.rte-source-editor-btn-cancel:hover:not(:disabled) {
background: #f9fafb;
border-color: #9ca3af;
}
.rte-source-editor-btn-save {
background: #007acc;
color: white;
}
.rte-source-editor-btn-save:hover:not(:disabled) {
background: #0056b3;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-modal {
background: #1e1e1e;
color: #f8f9fa;
border: 1px solid #434d5f;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-header,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-footer {
background: #2a3442;
border-color: #434d5f;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-header h2 {
color: #f8f9fa;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-fullscreen-btn,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-close-btn {
color: #c1cede;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn:hover:not(:disabled),
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-fullscreen-btn:hover,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-close-btn:hover {
background: #404a5a;
color: #f8fafc;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn.active {
background: #3b82f6;
color: #ffffff;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn.active:hover {
background: #2563eb;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-loading,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-footer-info {
color: #cbd5e1;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-spinner {
border-color: #3f4b60;
border-top-color: #58a6ff;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-error {
background: #3f2124;
color: #fecaca;
border-color: #ef4444;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-warning {
background: #3b3220;
color: #fde68a;
border-color: #f59e0b;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-cancel {
background: #334155;
border-color: #475569;
color: #f1f5f9;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-cancel:hover:not(:disabled) {
background: #475569;
border-color: #64748b;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-save {
background: #3b82f6;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-save:hover:not(:disabled) {
background: #2563eb;
}
/* Responsive design */
@media (max-width: 768px) {
.rte-source-editor-overlay {
padding: 10px;
}
.rte-source-editor-modal {
max-height: 95vh;
}
.rte-source-editor-header {
padding: 12px 16px;
}
.rte-source-editor-footer {
padding: 12px 16px;
flex-direction: column;
gap: 12px;
align-items: stretch;
}
.rte-source-editor-footer-actions {
justify-content: stretch;
}
.rte-source-editor-btn {
flex: 1;
text-align: center;
}
}`, P = () => ({
name: "code",
// Toolbar button configuration
toolbar: [
{
label: "Source",
command: "toggleSourceView",
type: "button",
icon: "<>",
shortcut: "Mod-Shift-S"
}
],
// Native command implementations
commands: {
/**
* Toggle HTML source view
* Opens a dialog to edit raw HTML
*/
toggleSourceView: () => {
const f = (() => {
const r = window.getSelection();
if (r && r.anchorNode) {
let e = r.anchorNode instanceof HTMLElement ? r.anchorNode : r.anchorNode.parentElement;
for (; e; ) {
if (e.classList?.contains("rte-content"))
return e;
e = e.parentElement;
}
}
if (document.activeElement) {
let e = document.activeElement;
if (e.classList?.contains("rte-content"))
return e;
for (; e && e !== document.body; ) {
if (e.classList?.contains("rte-content"))
return e;
const n = e.querySelector(".rte-content");
if (n) return n;
e = e.parentElement;
}
}
const o = document.querySelector("[data-editora-editor]");
if (o) {
const e = o.querySelector(".rte-content");
if (e) return e;
}
return document.querySelector(".rte-content");
})();
if (!f)
return console.error("[CodePlugin] Editor content area not found"), alert("Editor content area not found. Please click inside the editor first."), !1;
const x = f.innerHTML, y = (r) => {
let o = "", e = 0;
const n = 2, s = r.split(/(<\/?[a-zA-Z][^>]*>)/);
for (const i of s)
i.trim() && (i.match(/^<\/[a-zA-Z]/) ? (e = Math.max(0, e - 1), o += `
` + " ".repeat(e * n) + i) : i.match(/^<[a-zA-Z]/) && !i.match(/\/>$/) ? (o += `
` + " ".repeat(e * n) + i, e++) : i.match(/^<[a-zA-Z].*\/>$/) ? o += `
` + " ".repeat(e * n) + i : o += i.trim());
return o.trim();
};
return (() => {
let r = null, o = "dark", e = !1, n = !1, s = !1;
const i = x, w = !!f.closest(v) || document.body.matches(v) || document.documentElement.matches(v), a = document.createElement("div");
a.className = "rte-source-editor-overlay", w && a.classList.add("rte-theme-dark");
const c = document.createElement("div");
c.className = "rte-source-editor-modal", c.setAttribute("role", "dialog"), c.setAttribute("aria-modal", "true"), c.setAttribute("aria-labelledby", "source-editor-title");
const d = document.createElement("div");
d.className = "rte-source-editor-header", d.innerHTML = `
<h2 id="source-editor-title">Source Editor</h2>
<div class="rte-source-editor-header-toolbar">
<button class="rte-source-editor-toolbar-btn theme-toggle-btn" title="Switch theme">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="5"/>
<line x1="12" y1="1" x2="12" y2="3"/>
<line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/>
<line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
</button>
<button class="rte-source-editor-toolbar-btn readonly-toggle-btn" title="Toggle read-only">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
</svg>
</button>
</div>
<div class="rte-source-editor-header-actions">
<button class="rte-source-editor-fullscreen-btn" title="Toggle fullscreen">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>
</svg>
</button>
<button class="rte-source-editor-close-btn" aria-label="Close source editor">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="18" y1="6" x2="6" y2="18"/>
<line x1="6" y1="6" x2="18" y2="18"/>
</svg>
</button>
</div>
`;
const g = document.createElement("div");
g.className = "rte-source-editor-body";
const m = document.createElement("div");
m.className = "rte-source-editor-content";
const p = document.createElement("div");
p.className = "rte-source-editor-warning", p.textContent = "⚠️ Advanced users only. Invalid HTML may break the editor.";
const l = document.createElement("div");
l.className = "rte-source-editor-light-editor", l.style.height = "400px", m.appendChild(p), m.appendChild(l), g.appendChild(m);
const u = document.createElement("div");
if (u.className = "rte-source-editor-footer", u.innerHTML = `
<div class="rte-source-editor-footer-info">
<span class="unsaved-changes" style="display: none;">• Unsaved changes</span>
</div>
<div class="rte-source-editor-footer-actions">
<button class="rte-source-editor-btn rte-source-editor-btn-cancel">Cancel</button>
<button class="rte-source-editor-btn rte-source-editor-btn-save">Save</button>
</div>
`, c.appendChild(d), c.appendChild(g), c.appendChild(u), a.appendChild(c), !document.getElementById("rte-source-editor-styles")) {
const t = document.createElement("style");
t.id = "rte-source-editor-styles", t.textContent = O, document.head.appendChild(t);
}
document.body.appendChild(a);
try {
r = H(l, {
value: y(x),
theme: "dark",
readOnly: !1,
extensions: [
new z(),
new q(),
new B(),
new N(),
new A(),
new R(),
new D()
]
}), r.on("change", () => {
s = (r?.getValue() || "") !== y(i);
const h = u.querySelector(".unsaved-changes");
h && (h.style.display = s ? "inline" : "none");
}), setTimeout(() => r?.focus(), 100);
} catch (t) {
console.error("Failed to initialize code editor:", t);
}
const E = () => {
o = o === "dark" ? "light" : "dark", r?.setTheme(o);
const t = d.querySelector(".theme-toggle-btn");
t && o === "light" && (t.innerHTML = `
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
</svg>
`);
}, S = () => {
e = !e, r?.setReadOnly(e);
const t = d.querySelector(".readonly-toggle-btn");
t && (e ? (t.classList.add("active"), t.innerHTML = `
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
<circle cx="12" cy="16" r="1"/>
<path d="M7 11V7a5 5 0 0 1 10 0v4"/>
</svg>
`) : (t.classList.remove("active"), t.innerHTML = `
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
</svg>
`));
}, M = () => {
n = !n, n ? (a.classList.add("fullscreen"), l.style.height = "calc(100vh - 200px)") : (a.classList.remove("fullscreen"), l.style.height = "400px");
const t = d.querySelector(".rte-source-editor-fullscreen-btn");
t && (t.innerHTML = n ? `
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 0 2-2h3M3 16h3a2 2 0 0 0 2 2v3"/>
</svg>
` : `
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>
</svg>
`);
}, b = () => {
r && (r.destroy(), r = null), document.body.removeChild(a);
}, C = () => {
s && !confirm("You have unsaved changes. Are you sure you want to cancel?") || b();
}, L = () => {
try {
const t = r?.getValue() || "", h = document.createElement("div");
h.innerHTML = t, h.querySelectorAll('script, iframe[src^="javascript:"], object, embed').forEach((T) => T.remove()), f.innerHTML = h.innerHTML, s = !1, b();
} catch (t) {
alert("Failed to update HTML. Please check your syntax."), console.error("HTML update error:", t);
}
};
d.querySelector(".theme-toggle-btn")?.addEventListener("click", E), d.querySelector(".readonly-toggle-btn")?.addEventListener("click", S), d.querySelector(".rte-source-editor-fullscreen-btn")?.addEventListener("click", M), d.querySelector(".rte-source-editor-close-btn")?.addEventListener("click", b), u.querySelector(".rte-source-editor-btn-cancel")?.addEventListener("click", C), u.querySelector(".rte-source-editor-btn-save")?.addEventListener("click", L), a.addEventListener("click", (t) => {
t.target === a && b();
});
const k = (t) => {
t.key === "Escape" && (b(), document.removeEventListener("keydown", k));
};
document.addEventListener("keydown", k);
})(), !0;
}
},
// Keyboard shortcuts
keymap: {
"Mod-Shift-s": "toggleSourceView",
"Mod-Shift-S": "toggleSourceView"
}
});
export {
P as CodePlugin
};
(function(l,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("@editora/light-code-editor")):typeof define=="function"&&define.amd?define(["exports","@editora/light-code-editor"],n):(l=typeof globalThis<"u"?globalThis:l||self,n(l.line_heightPlugin={},l.LightCodeEditor))})(this,(function(l,n){"use strict";const v='[data-theme="dark"], .dark, .editora-theme-dark',S=`/* Source Editor Dialog Styles */
.rte-source-editor-overlay {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
width: 100vw !important;
height: 100vh !important;
background-color: rgba(0, 0, 0, 0.6) !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
z-index: 10000 !important;
padding: 20px !important;
box-sizing: border-box !important;
margin: 0 !important;
}
.rte-source-editor-overlay.fullscreen {
padding: 0 !important;
}
.rte-source-editor-modal {
background: white;
border-radius: 8px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
width: 100%;
max-width: 1200px;
max-height: 90vh;
display: flex;
flex-direction: column;
overflow: hidden;
position: relative;
}
.rte-source-editor-overlay.fullscreen .rte-source-editor-modal {
border-radius: 0;
max-width: 100%;
max-height: 100vh;
width: 100%;
height: 100vh;
}
.rte-source-editor-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
border-bottom: 1px solid #e1e5e9;
background: #f8f9fa;
border-radius: 8px 8px 0 0;
}
.rte-source-editor-overlay.fullscreen .rte-source-editor-header {
border-radius: 0;
}
.rte-source-editor-header h2 {
margin: 0;
font-size: 18px;
font-weight: 600;
color: #1a1a1a;
}
.rte-source-editor-header-toolbar {
display: flex;
gap: 8px;
margin-left: auto;
margin-right: 16px;
}
.rte-source-editor-toolbar-btn {
background: none;
border: none;
cursor: pointer;
padding: 6px;
border-radius: 4px;
font-size: 16px;
line-height: 1;
transition: all 0.2s ease;
color: #666;
}
.rte-source-editor-toolbar-btn:hover:not(:disabled) {
background: #e1e5e9;
color: #1a1a1a;
}
.rte-source-editor-toolbar-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.rte-source-editor-toolbar-btn.active {
background: #007acc;
color: white;
}
.rte-source-editor-toolbar-btn.active:hover {
background: #0056b3;
}
.rte-source-editor-header-actions {
display: flex;
gap: 8px;
}
.rte-source-editor-fullscreen-btn,
.rte-source-editor-close-btn {
background: none;
border: none;
cursor: pointer;
padding: 4px;
border-radius: 4px;
color: #666;
font-size: 16px;
line-height: 1;
transition: all 0.2s ease;
}
.rte-source-editor-fullscreen-btn:hover,
.rte-source-editor-close-btn:hover {
background: #e1e5e9;
color: #1a1a1a;
}
.rte-source-editor-body {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.rte-source-editor-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px;
color: #666;
position: absolute;
z-index: 9;
margin: 0 auto;
width: 100%;
top: 44%;
}
.rte-source-editor-spinner {
width: 32px;
height: 32px;
border: 3px solid #e1e5e9;
border-top: 3px solid #007acc;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 16px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.rte-source-editor-error {
background: #fee;
color: #c53030;
padding: 12px 16px;
border-left: 4px solid #c53030;
margin: 16px;
border-radius: 4px;
font-size: 14px;
}
.rte-source-editor-content {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.rte-source-editor-warning {
background: #fefcbf;
color: #744210;
padding: 8px 16px;
font-size: 12px;
font-weight: 500;
border-bottom: 1px solid #f6e05e;
}
.rte-source-editor-codemirror {
flex: 1;
overflow: auto;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 14px;
line-height: 1.5;
}
.rte-source-editor-codemirror .cm-editor {
height: 100%;
}
.rte-source-editor-codemirror .cm-focused {
outline: none;
}
.rte-source-editor-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
border-top: 1px solid #e1e5e9;
background: #f8f9fa;
border-radius: 0 0 8px 8px;
}
.rte-source-editor-overlay.fullscreen .rte-source-editor-footer {
border-radius: 0;
}
.rte-source-editor-footer-info {
font-size: 12px;
color: #666;
}
.unsaved-changes {
color: #d69e2e;
font-weight: 500;
}
.rte-source-editor-footer-actions {
display: flex;
gap: 12px;
}
.rte-source-editor-btn {
padding: 8px 16px;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
border: 1px solid transparent;
transition: all 0.2s ease;
}
.rte-source-editor-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.rte-source-editor-btn-cancel {
background: white;
border-color: #d1d5db;
color: #374151;
}
.rte-source-editor-btn-cancel:hover:not(:disabled) {
background: #f9fafb;
border-color: #9ca3af;
}
.rte-source-editor-btn-save {
background: #007acc;
color: white;
}
.rte-source-editor-btn-save:hover:not(:disabled) {
background: #0056b3;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-modal {
background: #1e1e1e;
color: #f8f9fa;
border: 1px solid #434d5f;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-header,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-footer {
background: #2a3442;
border-color: #434d5f;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-header h2 {
color: #f8f9fa;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-fullscreen-btn,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-close-btn {
color: #c1cede;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn:hover:not(:disabled),
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-fullscreen-btn:hover,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-close-btn:hover {
background: #404a5a;
color: #f8fafc;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn.active {
background: #3b82f6;
color: #ffffff;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-toolbar-btn.active:hover {
background: #2563eb;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-loading,
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-footer-info {
color: #cbd5e1;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-spinner {
border-color: #3f4b60;
border-top-color: #58a6ff;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-error {
background: #3f2124;
color: #fecaca;
border-color: #ef4444;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-warning {
background: #3b3220;
color: #fde68a;
border-color: #f59e0b;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-cancel {
background: #334155;
border-color: #475569;
color: #f1f5f9;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-cancel:hover:not(:disabled) {
background: #475569;
border-color: #64748b;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-save {
background: #3b82f6;
}
.rte-source-editor-overlay.rte-theme-dark .rte-source-editor-btn-save:hover:not(:disabled) {
background: #2563eb;
}
/* Responsive design */
@media (max-width: 768px) {
.rte-source-editor-overlay {
padding: 10px;
}
.rte-source-editor-modal {
max-height: 95vh;
}
.rte-source-editor-header {
padding: 12px 16px;
}
.rte-source-editor-footer {
padding: 12px 16px;
flex-direction: column;
gap: 12px;
align-items: stretch;
}
.rte-source-editor-footer-actions {
justify-content: stretch;
}
.rte-source-editor-btn {
flex: 1;
text-align: center;
}
}`,M=()=>({name:"code",toolbar:[{label:"Source",command:"toggleSourceView",type:"button",icon:"<>",shortcut:"Mod-Shift-S"}],commands:{toggleSourceView:()=>{const p=(()=>{const r=window.getSelection();if(r&&r.anchorNode){let e=r.anchorNode instanceof HTMLElement?r.anchorNode:r.anchorNode.parentElement;for(;e;){if(e.classList?.contains("rte-content"))return e;e=e.parentElement}}if(document.activeElement){let e=document.activeElement;if(e.classList?.contains("rte-content"))return e;for(;e&&e!==document.body;){if(e.classList?.contains("rte-content"))return e;const i=e.querySelector(".rte-content");if(i)return i;e=e.parentElement}}const o=document.querySelector("[data-editora-editor]");if(o){const e=o.querySelector(".rte-content");if(e)return e}return document.querySelector(".rte-content")})();if(!p)return console.error("[CodePlugin] Editor content area not found"),alert("Editor content area not found. Please click inside the editor first."),!1;const k=p.innerHTML,w=r=>{let o="",e=0;const i=2,u=r.split(/(<\/?[a-zA-Z][^>]*>)/);for(const d of u)d.trim()&&(d.match(/^<\/[a-zA-Z]/)?(e=Math.max(0,e-1),o+=`
`+" ".repeat(e*i)+d):d.match(/^<[a-zA-Z]/)&&!d.match(/\/>$/)?(o+=`
`+" ".repeat(e*i)+d,e++):d.match(/^<[a-zA-Z].*\/>$/)?o+=`
`+" ".repeat(e*i)+d:o+=d.trim());return o.trim()};return(()=>{let r=null,o="dark",e=!1,i=!1,u=!1;const d=k,L=!!p.closest(v)||document.body.matches(v)||document.documentElement.matches(v),a=document.createElement("div");a.className="rte-source-editor-overlay",L&&a.classList.add("rte-theme-dark");const s=document.createElement("div");s.className="rte-source-editor-modal",s.setAttribute("role","dialog"),s.setAttribute("aria-modal","true"),s.setAttribute("aria-labelledby","source-editor-title");const c=document.createElement("div");c.className="rte-source-editor-header",c.innerHTML=`
<h2 id="source-editor-title">Source Editor</h2>
<div class="rte-source-editor-header-toolbar">
<button class="rte-source-editor-toolbar-btn theme-toggle-btn" title="Switch theme">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="5"/>
<line x1="12" y1="1" x2="12" y2="3"/>
<line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/>
<line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
</button>
<button class="rte-source-editor-toolbar-btn readonly-toggle-btn" title="Toggle read-only">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
</svg>
</button>
</div>
<div class="rte-source-editor-header-actions">
<button class="rte-source-editor-fullscreen-btn" title="Toggle fullscreen">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>
</svg>
</button>
<button class="rte-source-editor-close-btn" aria-label="Close source editor">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="18" y1="6" x2="6" y2="18"/>
<line x1="6" y1="6" x2="18" y2="18"/>
</svg>
</button>
</div>
`;const x=document.createElement("div");x.className="rte-source-editor-body";const g=document.createElement("div");g.className="rte-source-editor-content";const y=document.createElement("div");y.className="rte-source-editor-warning",y.textContent="⚠️ Advanced users only. Invalid HTML may break the editor.";const h=document.createElement("div");h.className="rte-source-editor-light-editor",h.style.height="400px",g.appendChild(y),g.appendChild(h),x.appendChild(g);const f=document.createElement("div");if(f.className="rte-source-editor-footer",f.innerHTML=`
<div class="rte-source-editor-footer-info">
<span class="unsaved-changes" style="display: none;">• Unsaved changes</span>
</div>
<div class="rte-source-editor-footer-actions">
<button class="rte-source-editor-btn rte-source-editor-btn-cancel">Cancel</button>
<button class="rte-source-editor-btn rte-source-editor-btn-save">Save</button>
</div>
`,s.appendChild(c),s.appendChild(x),s.appendChild(f),a.appendChild(s),!document.getElementById("rte-source-editor-styles")){const t=document.createElement("style");t.id="rte-source-editor-styles",t.textContent=S,document.head.appendChild(t)}document.body.appendChild(a);try{r=n.createEditor(h,{value:w(k),theme:"dark",readOnly:!1,extensions:[new n.LineNumbersExtension,new n.ThemeExtension,new n.ReadOnlyExtension,new n.BracketMatchingExtension,new n.SearchExtension,new n.CodeFoldingExtension,new n.SyntaxHighlightingExtension]}),r.on("change",()=>{u=(r?.getValue()||"")!==w(d);const b=f.querySelector(".unsaved-changes");b&&(b.style.display=u?"inline":"none")}),setTimeout(()=>r?.focus(),100)}catch(t){console.error("Failed to initialize code editor:",t)}const C=()=>{o=o==="dark"?"light":"dark",r?.setTheme(o);const t=c.querySelector(".theme-toggle-btn");t&&o==="light"&&(t.innerHTML=`
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
</svg>
`)},T=()=>{e=!e,r?.setReadOnly(e);const t=c.querySelector(".readonly-toggle-btn");t&&(e?(t.classList.add("active"),t.innerHTML=`
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
<circle cx="12" cy="16" r="1"/>
<path d="M7 11V7a5 5 0 0 1 10 0v4"/>
</svg>
`):(t.classList.remove("active"),t.innerHTML=`
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
</svg>
`))},H=()=>{i=!i,i?(a.classList.add("fullscreen"),h.style.height="calc(100vh - 200px)"):(a.classList.remove("fullscreen"),h.style.height="400px");const t=c.querySelector(".rte-source-editor-fullscreen-btn");t&&(t.innerHTML=i?`
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 0 2-2h3M3 16h3a2 2 0 0 0 2 2v3"/>
</svg>
`:`
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/>
</svg>
`)},m=()=>{r&&(r.destroy(),r=null),document.body.removeChild(a)},z=()=>{u&&!confirm("You have unsaved changes. Are you sure you want to cancel?")||m()},q=()=>{try{const t=r?.getValue()||"",b=document.createElement("div");b.innerHTML=t,b.querySelectorAll('script, iframe[src^="javascript:"], object, embed').forEach(B=>B.remove()),p.innerHTML=b.innerHTML,u=!1,m()}catch(t){alert("Failed to update HTML. Please check your syntax."),console.error("HTML update error:",t)}};c.querySelector(".theme-toggle-btn")?.addEventListener("click",C),c.querySelector(".readonly-toggle-btn")?.addEventListener("click",T),c.querySelector(".rte-source-editor-fullscreen-btn")?.addEventListener("click",H),c.querySelector(".rte-source-editor-close-btn")?.addEventListener("click",m),f.querySelector(".rte-source-editor-btn-cancel")?.addEventListener("click",z),f.querySelector(".rte-source-editor-btn-save")?.addEventListener("click",q),a.addEventListener("click",t=>{t.target===a&&m()});const E=t=>{t.key==="Escape"&&(m(),document.removeEventListener("keydown",E))};document.addEventListener("keydown",E)})(),!0}},keymap:{"Mod-Shift-s":"toggleSourceView","Mod-Shift-S":"toggleSourceView"}});l.CodePlugin=M,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));