ngx-xtroedge-cms 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +223 -0
- package/dist/index.d.ts +223 -0
- package/dist/index.js +1515 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1488 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/styles.ts","../src/xtroedge-cms.ts"],"sourcesContent":["export { XtroedgeCMS } from './xtroedge-cms';\r\nexport type {\r\n XtroedgeCmsConfig,\r\n PageTextEntry,\r\n WebPageContent,\r\n EditHistoryEntry,\r\n} from './types';\r\n","export const CMS_STYLES = `\r\n/* ===== XTROEDGE CMS ===== */\r\n\r\n/* LOADER */\r\n.lcms-loader-overlay {\r\n position: fixed; inset: 0; z-index: 10003;\r\n display: flex; align-items: center; justify-content: center;\r\n background: rgba(15, 5, 30, 0.45);\r\n backdrop-filter: blur(12px) saturate(1.4);\r\n -webkit-backdrop-filter: blur(12px) saturate(1.4);\r\n}\r\n.lcms-loader-content { display: flex; flex-direction: column; align-items: center; gap: 28px; }\r\n.lcms-orbit-loader { position: relative; width: 90px; height: 90px; }\r\n.lcms-orbit { position: absolute; inset: 0; border-radius: 50%; border: 1px solid transparent; }\r\n.lcms-orbit-1 { border-top-color: rgba(103,34,251,0.5); animation: lcmsSpin 2.4s linear infinite; }\r\n.lcms-orbit-2 { inset: 10px; border-right-color: rgba(139,92,246,0.5); animation: lcmsSpin 3.2s linear infinite reverse; }\r\n.lcms-orbit-3 { inset: 20px; border-bottom-color: rgba(167,139,250,0.5); animation: lcmsSpin 4.2s linear infinite; }\r\n.lcms-particle {\r\n position: absolute; width: 8px; height: 8px; border-radius: 50%; top: -4px; left: 50%; margin-left: -4px;\r\n box-shadow: 0 0 12px 3px currentColor;\r\n}\r\n.lcms-orbit-1 .lcms-particle { background: #6722FB; color: #6722FB; }\r\n.lcms-orbit-2 .lcms-particle { background: #8B5CF6; color: #8B5CF6; top: 50%; left: auto; right: -4px; margin-left: 0; margin-top: -4px; }\r\n.lcms-orbit-3 .lcms-particle { background: #A78BFA; color: #A78BFA; top: auto; bottom: -4px; }\r\n.lcms-core-glow {\r\n position: absolute; width: 30px; height: 30px; top: 50%; left: 50%; transform: translate(-50%,-50%);\r\n border-radius: 50%; background: radial-gradient(circle, rgba(103,34,251,0.4), transparent 70%);\r\n animation: lcmsPulse 2s ease-in-out infinite;\r\n}\r\n.lcms-core {\r\n position: absolute; width: 12px; height: 12px; top: 50%; left: 50%; transform: translate(-50%,-50%);\r\n border-radius: 50%; background: linear-gradient(135deg, #6722FB, #A78BFA);\r\n box-shadow: 0 0 20px rgba(103,34,251,0.6);\r\n}\r\n.lcms-loader-text {\r\n font-family: system-ui, -apple-system, sans-serif; font-size: 12px; font-weight: 600;\r\n color: rgba(255,255,255,0.5); letter-spacing: 4px; text-transform: uppercase;\r\n animation: lcmsBreath 2.5s ease-in-out infinite;\r\n}\r\n@keyframes lcmsSpin { to { transform: rotate(360deg); } }\r\n@keyframes lcmsPulse { 0%,100% { transform: translate(-50%,-50%) scale(1); opacity: 0.5; } 50% { transform: translate(-50%,-50%) scale(1.8); opacity: 0.2; } }\r\n@keyframes lcmsBreath { 0%,100% { letter-spacing: 4px; opacity: 0.5; } 50% { letter-spacing: 6px; opacity: 0.8; } }\r\n\r\n/* TOAST */\r\n.lcms-toast {\r\n position: fixed; top: 24px; left: 50%; transform: translateX(-50%); z-index: 10004;\r\n padding: 10px 20px; border-radius: 10px; font-size: 13px; font-weight: 600;\r\n font-family: system-ui, -apple-system, sans-serif; color: white;\r\n display: flex; align-items: center; gap: 8px;\r\n box-shadow: 0 8px 32px rgba(103,34,251,0.25);\r\n animation: lcmsToastIn 0.3s ease, lcmsToastOut 0.3s ease 2.7s forwards; white-space: nowrap;\r\n}\r\n.lcms-toast-success { background: linear-gradient(135deg, #6722FB, #8B5CF6); }\r\n.lcms-toast-error { background: linear-gradient(135deg, #dc2626, #ef4444); }\r\n@keyframes lcmsToastIn { from { opacity: 0; transform: translateX(-50%) translateY(-12px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }\r\n@keyframes lcmsToastOut { from { opacity: 1; transform: translateX(-50%) translateY(0); } to { opacity: 0; transform: translateX(-50%) translateY(-12px); } }\r\n\r\n/* FAB */\r\n.lcms-fab { position: fixed; z-index: 10001; user-select: none; touch-action: none; }\r\n.lcms-fab-btn {\r\n width: 52px; height: 52px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.2);\r\n background: rgba(103,34,251,0.35); color: white;\r\n backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);\r\n cursor: grab; display: flex; align-items: center; justify-content: center;\r\n box-shadow: 0 4px 20px rgba(103,34,251,0.3), inset 0 1px 0 rgba(255,255,255,0.15);\r\n transition: transform 0.2s, box-shadow 0.2s, background 0.2s; position: relative;\r\n}\r\n.lcms-fab-btn:not(.lcms-fab-active) { background: rgba(103,34,251,0.25); box-shadow: 0 4px 16px rgba(0,0,0,0.2), inset 0 1px 0 rgba(255,255,255,0.1); }\r\n.lcms-fab-btn.lcms-fab-active { background: rgba(103,34,251,0.4); box-shadow: 0 4px 24px rgba(103,34,251,0.4), 0 0 16px rgba(103,34,251,0.2), inset 0 1px 0 rgba(255,255,255,0.2); }\r\n.lcms-fab-btn:hover { transform: scale(1.08); background: rgba(103,34,251,0.5); box-shadow: 0 6px 28px rgba(103,34,251,0.4), inset 0 1px 0 rgba(255,255,255,0.2); }\r\n.lcms-badge {\r\n position: absolute; top: -4px; right: -4px; background: #ef4444; color: white;\r\n font-size: 11px; font-weight: 700; width: 20px; height: 20px; border-radius: 50%;\r\n display: flex; align-items: center; justify-content: center; border: 2px solid white;\r\n}\r\n\r\n/* PANEL */\r\n.lcms-panel {\r\n background: rgba(30,15,60,0.55); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);\r\n border: 1px solid rgba(139,92,246,0.25); border-radius: 16px; padding: 16px; min-width: 230px;\r\n box-shadow: 0 8px 32px rgba(0,0,0,0.25), inset 0 1px 0 rgba(255,255,255,0.06);\r\n color: white; font-family: system-ui, -apple-system, sans-serif;\r\n animation: lcmsPanelIn 0.25s ease; position: absolute;\r\n}\r\n@keyframes lcmsPanelIn { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } }\r\n\r\n.lcms-panel-header { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }\r\n.lcms-toggle { display: flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; }\r\n.lcms-toggle input { display: none; }\r\n.lcms-toggle-slider {\r\n width: 36px; height: 20px; border-radius: 10px; position: relative;\r\n background: rgba(255,255,255,0.15); transition: background 0.25s;\r\n}\r\n.lcms-toggle-slider::after {\r\n content: ''; position: absolute; width: 16px; height: 16px; border-radius: 50%;\r\n top: 2px; left: 2px; background: rgba(255,255,255,0.6); transition: transform 0.25s, background 0.25s;\r\n}\r\n.lcms-toggle input:checked + .lcms-toggle-slider { background: #6722FB; }\r\n.lcms-toggle input:checked + .lcms-toggle-slider::after { transform: translateX(16px); background: white; }\r\n.lcms-toggle-label { font-size: 12px; font-weight: 700; color: rgba(255,255,255,0.5); letter-spacing: 0.5px; transition: color 0.25s; }\r\n.lcms-toggle input:checked ~ .lcms-toggle-label { color: #a78bfa; }\r\n.lcms-lang-switch { display: flex; border: 1px solid rgba(103,34,251,0.4); border-radius: 6px; overflow: hidden; margin-left: auto; }\r\n.lcms-lang-btn { background: transparent; border: none; color: rgba(255,255,255,0.45); padding: 3px 12px; font-size: 11px; font-weight: 600; cursor: pointer; transition: all 0.2s; }\r\n.lcms-lang-btn.active { background: #6722FB; color: white; }\r\n.lcms-lang-btn:hover:not(.active) { color: white; background: rgba(103,34,251,0.2); }\r\n.lcms-close-btn { background: transparent; border: none; color: rgba(255,255,255,0.4); cursor: pointer; padding: 2px; display: flex; transition: color 0.2s; }\r\n.lcms-close-btn:hover { color: white; }\r\n.lcms-changes-info { font-size: 12px; color: #a78bfa; margin-bottom: 10px; padding-left: 2px; }\r\n\r\n.lcms-undo-row { display: flex; gap: 6px; margin-bottom: 12px; }\r\n.lcms-icon-btn {\r\n width: 36px; height: 32px; border-radius: 8px; border: 1px solid rgba(103,34,251,0.3);\r\n background: rgba(103,34,251,0.1); color: rgba(255,255,255,0.8); cursor: pointer;\r\n display: flex; align-items: center; justify-content: center; transition: all 0.2s;\r\n}\r\n.lcms-icon-btn:hover:not(:disabled) { background: rgba(103,34,251,0.25); border-color: rgba(103,34,251,0.5); color: white; }\r\n.lcms-icon-btn:disabled { opacity: 0.25; cursor: not-allowed; }\r\n\r\n.lcms-history-btn {\r\n width: 100%; padding: 7px 12px; border-radius: 8px;\r\n border: 1px dashed rgba(139,92,246,0.35); background: rgba(103,34,251,0.08);\r\n color: rgba(255,255,255,0.6); font-size: 12px; font-weight: 500; cursor: pointer;\r\n display: flex; align-items: center; justify-content: center; gap: 6px;\r\n transition: all 0.2s; margin-bottom: 12px; font-family: system-ui, -apple-system, sans-serif;\r\n}\r\n.lcms-history-btn:hover { background: rgba(103,34,251,0.18); border-color: rgba(139,92,246,0.5); color: white; }\r\n.lcms-history-btn.active { background: rgba(103,34,251,0.25); border-color: #6722FB; border-style: solid; color: white; }\r\n\r\n.lcms-history-panel { margin-top: 8px; border-top: 1px solid rgba(139,92,246,0.15); padding-top: 10px; }\r\n.lcms-history-title { font-size: 11px; font-weight: 700; color: rgba(255,255,255,0.5); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; }\r\n.lcms-history-empty { font-size: 12px; color: rgba(255,255,255,0.3); text-align: center; padding: 12px 0; }\r\n.lcms-history-list { max-height: 200px; overflow-y: auto; display: flex; flex-direction: column; gap: 4px; }\r\n.lcms-history-list::-webkit-scrollbar { width: 4px; }\r\n.lcms-history-list::-webkit-scrollbar-track { background: transparent; }\r\n.lcms-history-list::-webkit-scrollbar-thumb { background: rgba(103,34,251,0.3); border-radius: 4px; }\r\n.lcms-history-item {\r\n width: 100%; text-align: left; background: rgba(103,34,251,0.06);\r\n border: 1px solid rgba(103,34,251,0.12); border-radius: 8px; padding: 8px 10px;\r\n cursor: pointer; transition: all 0.2s; color: white; font-family: system-ui, -apple-system, sans-serif;\r\n}\r\n.lcms-history-item:hover { background: rgba(103,34,251,0.15); border-color: rgba(103,34,251,0.3); }\r\n.lcms-history-label { font-size: 12px; font-weight: 500; margin-bottom: 2px; }\r\n.lcms-history-meta { font-size: 10px; color: rgba(255,255,255,0.4); display: flex; align-items: center; gap: 6px; }\r\n.lcms-history-lang { background: rgba(103,34,251,0.2); padding: 1px 5px; border-radius: 3px; font-size: 9px; font-weight: 600; color: #a78bfa; }\r\n\r\n.lcms-actions { display: flex; flex-direction: column; gap: 6px; }\r\n.lcms-actions button {\r\n width: 100%; padding: 9px 14px; border-radius: 8px; font-size: 12px; font-weight: 600;\r\n cursor: pointer; transition: all 0.2s; display: flex; align-items: center; justify-content: center; gap: 6px; border: none;\r\n font-family: system-ui, -apple-system, sans-serif;\r\n}\r\n.lcms-btn-save { background: #6722FB; color: white; }\r\n.lcms-btn-save:hover { background: #7c3aed; }\r\n.lcms-btn-save:disabled { background: rgba(103,34,251,0.2); color: rgba(255,255,255,0.35); cursor: not-allowed; }\r\n.lcms-btn-publish { background: linear-gradient(135deg, #22c55e, #16a34a); color: white; }\r\n.lcms-btn-publish:hover { background: linear-gradient(135deg, #16a34a, #15803d); }\r\n.lcms-btn-publish:disabled { background: rgba(103,34,251,0.2); color: rgba(255,255,255,0.35); cursor: not-allowed; }\r\n.lcms-btn-cancel { background: transparent; color: rgba(255,255,255,0.5); border: 1px solid rgba(103,34,251,0.25) !important; }\r\n.lcms-btn-cancel:hover { color: white; border-color: rgba(103,34,251,0.5) !important; background: rgba(103,34,251,0.08); }\r\n.lcms-btn-cancel:disabled { opacity: 0.3; cursor: not-allowed; }\r\n\r\n.lcms-spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.3); border-top-color: white; border-radius: 50%; animation: lcmsSpin 0.6s linear infinite; }\r\n\r\n/* IMAGE UPLOAD OVERLAY */\r\n.lcms-img-upload-overlay {\r\n position: fixed; inset: 0; z-index: 10005;\r\n display: flex; align-items: center; justify-content: center;\r\n background: rgba(15, 5, 30, 0.5); backdrop-filter: blur(8px);\r\n}\r\n.lcms-img-upload-content {\r\n display: flex; flex-direction: column; align-items: center; gap: 16px;\r\n color: white; font-family: system-ui, -apple-system, sans-serif;\r\n font-size: 13px; font-weight: 600;\r\n}\r\n.lcms-spinner-lg { width: 36px; height: 36px; border: 3px solid rgba(255,255,255,0.2); border-top-color: #6722FB; border-radius: 50%; animation: lcmsSpin 0.6s linear infinite; }\r\n\r\n/* HIDDEN ELEMENTS */\r\n.lcms-hidden { display: none !important; }\r\n`;\r\n","import { CMS_STYLES } from './styles';\r\nimport type {\r\n XtroedgeCmsConfig, PageTextEntry, WebPageContent,\r\n EditHistoryEntry, ManagedElementInfo, ManagedImageInfo\r\n} from './types';\r\n\r\n// ===== SVG Icons =====\r\nconst ICON = {\r\n edit: '<svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><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>',\r\n close: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>',\r\n undo: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"1 4 1 10 7 10\"/><path d=\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\"/></svg>',\r\n redo: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"23 4 23 10 17 10\"/><path d=\"M20.49 15a9 9 0 1 1-2.13-9.36L23 10\"/></svg>',\r\n history: '<svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><polyline points=\"12 6 12 12 16 14\"/></svg>',\r\n save: '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z\"/><polyline points=\"17 21 17 13 7 13 7 21\"/><polyline points=\"7 3 7 8 15 8\"/></svg>',\r\n publish: '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"17 1 21 5 17 9\"/><path d=\"M3 11V9a4 4 0 0 1 4-4h14\"/></svg>',\r\n image: '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/></svg>',\r\n check: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6L9 17l-5-5\"/></svg>',\r\n error: '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/></svg>',\r\n};\r\n\r\n// ===== IndexedDB constants =====\r\nconst DB_NAME = 'xtroedge_cms_history';\r\nconst STORE_NAME = 'history';\r\n\r\n// ===== Default editable tags =====\r\nconst DEFAULT_EDITABLE_TAGS = [\r\n 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\r\n 'p', 'span', 'b', 'strong', 'i', 'em',\r\n 'a', 'button', 'li', 'label', 'small', 'blockquote', 'td', 'th',\r\n];\r\n\r\nexport class XtroedgeCMS {\r\n // ===== Config =====\r\n private config: Required<Pick<XtroedgeCmsConfig, 'apiBase'>> & XtroedgeCmsConfig;\r\n private containerSelector: string;\r\n private editableTags: string[];\r\n private languages: string[];\r\n private defaultLanguage: string;\r\n private highlightColor: string;\r\n private historyRetentionMs: number;\r\n\r\n // ===== State =====\r\n private editMode = false;\r\n private currentLang = 'en';\r\n private pageTexts: { [key: string]: PageTextEntry } = {};\r\n private pageImages: { [key: string]: string } = {};\r\n private originalTexts: { [key: string]: PageTextEntry } = {};\r\n private originalImages: { [key: string]: string } = {};\r\n private unsavedChanges = 0;\r\n private isSaving = false;\r\n private isPublishing = false;\r\n private loading = false;\r\n private canUndo = false;\r\n private canRedo = false;\r\n private showHistory = false;\r\n private historyList: EditHistoryEntry[] = [];\r\n private isOpen = false;\r\n private isEditAllowed = false;\r\n private imageUploading = false;\r\n private toastMessage = '';\r\n private toastType: 'success' | 'error' = 'success';\r\n\r\n // ===== Undo/Redo =====\r\n private undoStack: string[] = [];\r\n private redoStack: string[] = [];\r\n private dirtyKeys = new Set<string>();\r\n private dirtyImageKeys = new Set<string>();\r\n private registeredKeys = new Set<string>();\r\n\r\n // ===== DOM =====\r\n private managedElements = new Map<HTMLElement, ManagedElementInfo>();\r\n private managedImages = new Map<HTMLImageElement, ManagedImageInfo>();\r\n private autoDetectedElements = new Set<HTMLElement>();\r\n private observer: MutationObserver | null = null;\r\n private scanTimeout: ReturnType<typeof setTimeout> | null = null;\r\n private activeImageEl: HTMLImageElement | null = null;\r\n private imageCtxMenu: HTMLElement | null = null;\r\n\r\n // ===== Navigation =====\r\n private currentSlug = '';\r\n private currentTitle = '';\r\n private origPushState: typeof history.pushState | null = null;\r\n private origReplaceState: typeof history.replaceState | null = null;\r\n\r\n // ===== UI Elements =====\r\n private styleEl: HTMLStyleElement | null = null;\r\n private rootEl: HTMLElement | null = null;\r\n private loaderEl: HTMLElement | null = null;\r\n private toastEl: HTMLElement | null = null;\r\n private fabEl: HTMLElement | null = null;\r\n private fabBtn: HTMLButtonElement | null = null;\r\n private badgeEl: HTMLElement | null = null;\r\n private panelEl: HTMLElement | null = null;\r\n private editToggle: HTMLInputElement | null = null;\r\n private langSwitchEl: HTMLElement | null = null;\r\n private changesInfoEl: HTMLElement | null = null;\r\n private undoBtn: HTMLButtonElement | null = null;\r\n private redoBtn: HTMLButtonElement | null = null;\r\n private historyBtnEl: HTMLButtonElement | null = null;\r\n private historyPanelEl: HTMLElement | null = null;\r\n private historyListEl: HTMLElement | null = null;\r\n private saveBtn: HTMLButtonElement | null = null;\r\n private publishBtn: HTMLButtonElement | null = null;\r\n private cancelBtn: HTMLButtonElement | null = null;\r\n private actionsEl: HTMLElement | null = null;\r\n private editModeContent: HTMLElement | null = null;\r\n private fileInput: HTMLInputElement | null = null;\r\n private imgOverlay: HTMLElement | null = null;\r\n\r\n // ===== FAB Drag =====\r\n private posX = 20;\r\n private posY = 20;\r\n private isDragging = false;\r\n private dragStartX = 0;\r\n private dragStartY = 0;\r\n private startPosX = 0;\r\n private startPosY = 0;\r\n private hasMoved = false;\r\n\r\n // ===== Timers =====\r\n private toastTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\n // ===== IndexedDB =====\r\n private db: IDBDatabase | null = null;\r\n\r\n // ===== Bound handlers =====\r\n private boundMouseMove: (e: MouseEvent) => void;\r\n private boundMouseUp: () => void;\r\n private boundTouchMove: (e: TouchEvent) => void;\r\n private boundTouchEnd: () => void;\r\n private boundPopState: () => void;\r\n private boundHashChange: () => void;\r\n\r\n // ===== i18n cache =====\r\n private translationCache = new Map<string, string>();\r\n\r\n constructor(config: XtroedgeCmsConfig) {\r\n this.config = config as any;\r\n this.containerSelector = config.containerSelector || 'body';\r\n this.editableTags = (config.editableTags || DEFAULT_EDITABLE_TAGS).map(t => t.toLowerCase());\r\n this.languages = config.languages || ['en'];\r\n this.defaultLanguage = config.defaultLanguage || this.languages[0] || 'en';\r\n this.highlightColor = config.highlightColor || '#6722FB';\r\n this.historyRetentionMs = (config.historyRetentionDays || 7) * 24 * 60 * 60 * 1000;\r\n this.currentLang = this.defaultLanguage;\r\n\r\n // Bind handlers\r\n this.boundMouseMove = (e) => this.onDragMove(e);\r\n this.boundMouseUp = () => this.onDragEnd();\r\n this.boundTouchMove = (e) => this.onTouchMove(e);\r\n this.boundTouchEnd = () => this.onTouchEnd();\r\n this.boundPopState = () => this.handleNavigation();\r\n this.boundHashChange = () => this.handleNavigation();\r\n }\r\n\r\n // ===============================================\r\n // PUBLIC API\r\n // ===============================================\r\n\r\n init(): void {\r\n this.posY = window.innerHeight - 72;\r\n this.injectStyles();\r\n this.buildUI();\r\n this.interceptNavigation();\r\n\r\n // MutationObserver for auto-scanning\r\n this.observer = new MutationObserver(() => {\r\n if (this.scanTimeout) clearTimeout(this.scanTimeout);\r\n this.scanTimeout = setTimeout(() => this.autoDetectAndScan(), 150);\r\n });\r\n this.observer.observe(document.body, { childList: true, subtree: true });\r\n\r\n // Listen for navigation events\r\n window.addEventListener('popstate', this.boundPopState);\r\n window.addEventListener('hashchange', this.boundHashChange);\r\n\r\n // Initial navigation\r\n this.handleNavigation();\r\n }\r\n\r\n destroy(): void {\r\n this.cleanupManagedElements();\r\n\r\n // Remove UI\r\n this.styleEl?.remove();\r\n this.rootEl?.remove();\r\n\r\n // Remove listeners\r\n window.removeEventListener('popstate', this.boundPopState);\r\n window.removeEventListener('hashchange', this.boundHashChange);\r\n document.removeEventListener('mousemove', this.boundMouseMove);\r\n document.removeEventListener('mouseup', this.boundMouseUp);\r\n document.removeEventListener('touchmove', this.boundTouchMove);\r\n document.removeEventListener('touchend', this.boundTouchEnd);\r\n\r\n // Restore navigation\r\n if (this.origPushState) history.pushState = this.origPushState;\r\n if (this.origReplaceState) history.replaceState = this.origReplaceState;\r\n\r\n // Disconnect observer\r\n this.observer?.disconnect();\r\n if (this.scanTimeout) clearTimeout(this.scanTimeout);\r\n if (this.toastTimer) clearTimeout(this.toastTimer);\r\n\r\n this.db?.close();\r\n }\r\n\r\n // ===============================================\r\n // STYLES INJECTION\r\n // ===============================================\r\n\r\n private injectStyles(): void {\r\n if (document.getElementById('xtroedge-cms-styles')) return;\r\n this.styleEl = document.createElement('style');\r\n this.styleEl.id = 'xtroedge-cms-styles';\r\n this.styleEl.textContent = CMS_STYLES;\r\n document.head.appendChild(this.styleEl);\r\n }\r\n\r\n // ===============================================\r\n // NAVIGATION INTERCEPTION\r\n // ===============================================\r\n\r\n private interceptNavigation(): void {\r\n this.origPushState = history.pushState.bind(history);\r\n this.origReplaceState = history.replaceState.bind(history);\r\n const self = this;\r\n history.pushState = function (...args) {\r\n self.origPushState!(...args);\r\n setTimeout(() => self.handleNavigation(), 0);\r\n };\r\n history.replaceState = function (...args) {\r\n self.origReplaceState!(...args);\r\n setTimeout(() => self.handleNavigation(), 0);\r\n };\r\n }\r\n\r\n private handleNavigation(): void {\r\n const url = window.location.href;\r\n const pathname = window.location.pathname || '/';\r\n const hash = window.location.hash || '';\r\n\r\n // Support hash routing: #/page?edit=true\r\n let path: string;\r\n let searchStr: string;\r\n if (hash.startsWith('#/') || hash.startsWith('#!')) {\r\n const hashPath = hash.replace(/^#[!/]*/, '');\r\n const qIdx = hashPath.indexOf('?');\r\n path = qIdx >= 0 ? hashPath.substring(0, qIdx) : hashPath;\r\n searchStr = qIdx >= 0 ? hashPath.substring(qIdx) : '';\r\n } else {\r\n path = pathname.replace(/^\\//, '') || 'home';\r\n searchStr = window.location.search;\r\n }\r\n\r\n const slug = '/' + (path.replace(/^\\//, '') || 'home');\r\n const params = new URLSearchParams(searchStr);\r\n const editViaParam = params.get('edit') === 'true';\r\n\r\n this.isEditAllowed = editViaParam || sessionStorage.getItem('builder_edit_mode') === 'true';\r\n\r\n if (slug !== this.currentSlug) {\r\n this.cleanupManagedElements();\r\n this.currentSlug = slug;\r\n this.currentTitle = (path.replace(/^\\//, '') || 'home').replace(/-/g, ' ').replace(/\\b\\w/g, c => c.toUpperCase()) + ' Page';\r\n this.resetAll();\r\n }\r\n\r\n // Restore edit mode\r\n const editFromSession = sessionStorage.getItem('builder_edit_mode') === 'true';\r\n if (editViaParam || editFromSession) {\r\n this.editMode = true;\r\n }\r\n this.currentLang = this.detectCurrentLanguage();\r\n\r\n // Show loader\r\n this.setLoading(true);\r\n\r\n // Auto-detect after DOM settles, then load content\r\n const loadDraft = editViaParam || editFromSession;\r\n setTimeout(() => {\r\n this.loadTranslationsAndInit(loadDraft);\r\n }, 300);\r\n }\r\n\r\n // ===============================================\r\n // BUILD UI\r\n // ===============================================\r\n\r\n private buildUI(): void {\r\n this.rootEl = document.createElement('div');\r\n this.rootEl.id = 'xtroedge-cms-root';\r\n\r\n // Loader\r\n this.loaderEl = this.createElement('div', 'lcms-loader-overlay lcms-hidden');\r\n this.loaderEl.innerHTML = `<div class=\"lcms-loader-content\">\r\n <div class=\"lcms-orbit-loader\">\r\n <div class=\"lcms-orbit lcms-orbit-1\"><span class=\"lcms-particle\"></span></div>\r\n <div class=\"lcms-orbit lcms-orbit-2\"><span class=\"lcms-particle\"></span></div>\r\n <div class=\"lcms-orbit lcms-orbit-3\"><span class=\"lcms-particle\"></span></div>\r\n <div class=\"lcms-core-glow\"></div>\r\n <div class=\"lcms-core\"></div>\r\n </div>\r\n <span class=\"lcms-loader-text\">Loading</span>\r\n </div>`;\r\n this.rootEl.appendChild(this.loaderEl);\r\n\r\n // Toast\r\n this.toastEl = this.createElement('div', 'lcms-toast lcms-hidden');\r\n this.rootEl.appendChild(this.toastEl);\r\n\r\n // FAB\r\n this.fabEl = this.createElement('div', 'lcms-fab');\r\n this.fabEl.style.left = this.posX + 'px';\r\n this.fabEl.style.top = this.posY + 'px';\r\n this.fabEl.addEventListener('mousedown', (e) => this.onDragStart(e));\r\n this.fabEl.addEventListener('touchstart', (e) => this.onTouchStart(e), { passive: true });\r\n\r\n // FAB button\r\n this.fabBtn = document.createElement('button');\r\n this.fabBtn.className = 'lcms-fab-btn';\r\n this.fabBtn.innerHTML = ICON.edit;\r\n this.fabBtn.addEventListener('click', (e) => this.onFabClick(e));\r\n this.badgeEl = this.createElement('span', 'lcms-badge lcms-hidden');\r\n this.fabBtn.appendChild(this.badgeEl);\r\n this.fabEl.appendChild(this.fabBtn);\r\n\r\n // Panel\r\n this.panelEl = this.createElement('div', 'lcms-panel lcms-hidden');\r\n this.buildPanel();\r\n this.fabEl.appendChild(this.panelEl);\r\n\r\n this.rootEl.appendChild(this.fabEl);\r\n\r\n // Hidden file input\r\n this.fileInput = document.createElement('input');\r\n this.fileInput.type = 'file';\r\n this.fileInput.accept = 'image/*';\r\n this.fileInput.style.display = 'none';\r\n this.fileInput.addEventListener('change', (e) => this.onImageFileSelected(e));\r\n this.rootEl.appendChild(this.fileInput);\r\n\r\n // Image upload overlay\r\n this.imgOverlay = this.createElement('div', 'lcms-img-upload-overlay lcms-hidden');\r\n this.imgOverlay.innerHTML = `<div class=\"lcms-img-upload-content\"><div class=\"lcms-spinner-lg\"></div><span>Uploading image...</span></div>`;\r\n this.rootEl.appendChild(this.imgOverlay);\r\n\r\n document.body.appendChild(this.rootEl);\r\n }\r\n\r\n private buildPanel(): void {\r\n if (!this.panelEl) return;\r\n\r\n // Header\r\n const header = this.createElement('div', 'lcms-panel-header');\r\n\r\n // Edit toggle\r\n const toggleLabel = this.createElement('label', 'lcms-toggle');\r\n toggleLabel.addEventListener('click', (e) => e.stopPropagation());\r\n this.editToggle = document.createElement('input');\r\n this.editToggle.type = 'checkbox';\r\n this.editToggle.checked = this.editMode;\r\n this.editToggle.addEventListener('change', (e) => this.toggleEditMode(e));\r\n const slider = this.createElement('span', 'lcms-toggle-slider');\r\n const labelText = this.createElement('span', 'lcms-toggle-label');\r\n labelText.textContent = 'Edit';\r\n toggleLabel.appendChild(this.editToggle);\r\n toggleLabel.appendChild(slider);\r\n toggleLabel.appendChild(labelText);\r\n header.appendChild(toggleLabel);\r\n\r\n // Language switch\r\n this.langSwitchEl = this.createElement('div', 'lcms-lang-switch lcms-hidden');\r\n this.buildLangButtons();\r\n header.appendChild(this.langSwitchEl);\r\n\r\n // Close button\r\n const closeBtn = document.createElement('button');\r\n closeBtn.className = 'lcms-close-btn';\r\n closeBtn.innerHTML = ICON.close;\r\n closeBtn.addEventListener('click', (e) => { e.stopPropagation(); this.togglePanel(); });\r\n header.appendChild(closeBtn);\r\n\r\n this.panelEl.appendChild(header);\r\n\r\n // Edit mode content (hidden when edit mode off)\r\n this.editModeContent = this.createElement('div', 'lcms-hidden');\r\n\r\n // Changes info\r\n this.changesInfoEl = this.createElement('div', 'lcms-changes-info lcms-hidden');\r\n this.editModeContent.appendChild(this.changesInfoEl);\r\n\r\n // Undo/Redo row\r\n const undoRow = this.createElement('div', 'lcms-undo-row');\r\n this.undoBtn = document.createElement('button');\r\n this.undoBtn.className = 'lcms-icon-btn';\r\n this.undoBtn.innerHTML = ICON.undo;\r\n this.undoBtn.disabled = true;\r\n this.undoBtn.addEventListener('click', (e) => { e.stopPropagation(); this.onUndo(); });\r\n this.redoBtn = document.createElement('button');\r\n this.redoBtn.className = 'lcms-icon-btn';\r\n this.redoBtn.innerHTML = ICON.redo;\r\n this.redoBtn.disabled = true;\r\n this.redoBtn.addEventListener('click', (e) => { e.stopPropagation(); this.onRedo(); });\r\n undoRow.appendChild(this.undoBtn);\r\n undoRow.appendChild(this.redoBtn);\r\n this.editModeContent.appendChild(undoRow);\r\n\r\n // History button\r\n this.historyBtnEl = document.createElement('button');\r\n this.historyBtnEl.className = 'lcms-history-btn';\r\n this.historyBtnEl.innerHTML = `${ICON.history} History (7 days)`;\r\n this.historyBtnEl.addEventListener('click', (e) => { e.stopPropagation(); this.toggleHistory(); });\r\n this.editModeContent.appendChild(this.historyBtnEl);\r\n\r\n // History panel\r\n this.historyPanelEl = this.createElement('div', 'lcms-history-panel lcms-hidden');\r\n const historyTitle = this.createElement('div', 'lcms-history-title');\r\n historyTitle.textContent = 'Edit History';\r\n this.historyPanelEl.appendChild(historyTitle);\r\n this.historyListEl = this.createElement('div', 'lcms-history-list');\r\n this.historyPanelEl.appendChild(this.historyListEl);\r\n this.editModeContent.appendChild(this.historyPanelEl);\r\n\r\n // Actions\r\n this.actionsEl = this.createElement('div', 'lcms-actions');\r\n this.saveBtn = document.createElement('button');\r\n this.saveBtn.className = 'lcms-btn-save';\r\n this.saveBtn.innerHTML = `${ICON.save} Save Draft`;\r\n this.saveBtn.addEventListener('click', (e) => { e.stopPropagation(); this.saveChanges(); });\r\n this.publishBtn = document.createElement('button');\r\n this.publishBtn.className = 'lcms-btn-publish';\r\n this.publishBtn.innerHTML = `${ICON.publish} Publish`;\r\n this.publishBtn.addEventListener('click', (e) => { e.stopPropagation(); this.publishChanges(); });\r\n this.cancelBtn = document.createElement('button');\r\n this.cancelBtn.className = 'lcms-btn-cancel';\r\n this.cancelBtn.textContent = 'Cancel';\r\n this.cancelBtn.addEventListener('click', (e) => { e.stopPropagation(); this.cancelEditing(); });\r\n this.actionsEl.appendChild(this.saveBtn);\r\n this.actionsEl.appendChild(this.publishBtn);\r\n this.actionsEl.appendChild(this.cancelBtn);\r\n this.editModeContent.appendChild(this.actionsEl);\r\n\r\n this.panelEl.appendChild(this.editModeContent);\r\n }\r\n\r\n private buildLangButtons(): void {\r\n if (!this.langSwitchEl) return;\r\n this.langSwitchEl.innerHTML = '';\r\n for (const lang of this.languages) {\r\n const btn = document.createElement('button');\r\n btn.className = 'lcms-lang-btn' + (this.currentLang === lang ? ' active' : '');\r\n btn.textContent = lang.toUpperCase();\r\n btn.addEventListener('click', (e) => { e.stopPropagation(); this.switchLang(lang); });\r\n this.langSwitchEl.appendChild(btn);\r\n }\r\n }\r\n\r\n // ===============================================\r\n // UI UPDATE\r\n // ===============================================\r\n\r\n private updateUI(): void {\r\n // FAB visibility\r\n if (this.fabEl) {\r\n this.fabEl.style.display = this.isEditAllowed ? '' : 'none';\r\n }\r\n\r\n // FAB button vs panel\r\n if (this.fabBtn) {\r\n this.fabBtn.style.display = this.isOpen ? 'none' : '';\r\n this.fabBtn.classList.toggle('lcms-fab-active', this.editMode);\r\n }\r\n if (this.panelEl) {\r\n this.panelEl.classList.toggle('lcms-hidden', !this.isOpen);\r\n // Position panel\r\n if (this.isOpen) {\r\n const openUp = this.posY > window.innerHeight / 2;\r\n const openLeft = this.posX > window.innerWidth / 2;\r\n this.panelEl.style.bottom = openUp ? '0' : '';\r\n this.panelEl.style.top = openUp ? '' : '0';\r\n this.panelEl.style.right = openLeft ? '0' : '';\r\n this.panelEl.style.left = openLeft ? '' : '0';\r\n }\r\n }\r\n\r\n // Badge\r\n if (this.badgeEl) {\r\n this.badgeEl.classList.toggle('lcms-hidden', this.unsavedChanges === 0);\r\n this.badgeEl.textContent = String(this.unsavedChanges);\r\n }\r\n\r\n // Edit toggle\r\n if (this.editToggle) this.editToggle.checked = this.editMode;\r\n\r\n // Lang switch\r\n if (this.langSwitchEl) {\r\n this.langSwitchEl.classList.toggle('lcms-hidden', !this.editMode || this.languages.length <= 1);\r\n // Update active button\r\n const btns = this.langSwitchEl.querySelectorAll('.lcms-lang-btn');\r\n btns.forEach(btn => {\r\n (btn as HTMLElement).classList.toggle('active', btn.textContent === this.currentLang.toUpperCase());\r\n });\r\n }\r\n\r\n // Edit mode content\r\n if (this.editModeContent) {\r\n this.editModeContent.classList.toggle('lcms-hidden', !this.editMode);\r\n }\r\n\r\n // Changes info\r\n if (this.changesInfoEl) {\r\n this.changesInfoEl.classList.toggle('lcms-hidden', this.unsavedChanges === 0);\r\n this.changesInfoEl.textContent = `${this.unsavedChanges} unsaved change${this.unsavedChanges > 1 ? 's' : ''}`;\r\n }\r\n\r\n // Undo/Redo\r\n if (this.undoBtn) this.undoBtn.disabled = !this.canUndo;\r\n if (this.redoBtn) this.redoBtn.disabled = !this.canRedo;\r\n\r\n // History button\r\n if (this.historyBtnEl) this.historyBtnEl.classList.toggle('active', this.showHistory);\r\n if (this.historyPanelEl) this.historyPanelEl.classList.toggle('lcms-hidden', !this.showHistory);\r\n\r\n // Save/Publish buttons\r\n if (this.saveBtn) {\r\n this.saveBtn.disabled = this.isSaving || this.isPublishing || this.unsavedChanges === 0;\r\n this.saveBtn.innerHTML = this.isSaving ? '<span class=\"lcms-spinner\"></span> Saving...' : `${ICON.save} Save Draft`;\r\n }\r\n if (this.publishBtn) {\r\n this.publishBtn.disabled = this.isSaving || this.isPublishing;\r\n this.publishBtn.innerHTML = this.isPublishing ? '<span class=\"lcms-spinner\"></span> Publishing...' : `${ICON.publish} Publish`;\r\n }\r\n if (this.cancelBtn) {\r\n this.cancelBtn.disabled = this.isSaving || this.isPublishing;\r\n }\r\n\r\n // Loader\r\n if (this.loaderEl) this.loaderEl.classList.toggle('lcms-hidden', !this.loading);\r\n\r\n // Image overlay\r\n if (this.imgOverlay) this.imgOverlay.classList.toggle('lcms-hidden', !this.imageUploading);\r\n }\r\n\r\n // ===============================================\r\n // DOM SCANNING\r\n // ===============================================\r\n\r\n private autoDetectAndScan(): void {\r\n this.autoDetectElements();\r\n this.scanDOM();\r\n this.scanImages();\r\n }\r\n\r\n private autoDetectElements(): void {\r\n const container = document.querySelector(this.containerSelector);\r\n if (!container) return;\r\n\r\n // Clean up stale auto-detected elements\r\n for (const el of this.autoDetectedElements) {\r\n if (!document.contains(el)) this.autoDetectedElements.delete(el);\r\n }\r\n\r\n // Tag counter for key generation\r\n const tagCounters: { [tag: string]: number } = {};\r\n\r\n const selector = this.editableTags.join(',');\r\n const elements = container.querySelectorAll<HTMLElement>(selector);\r\n\r\n elements.forEach(el => {\r\n // Skip already tagged or CMS-internal\r\n if (el.hasAttribute('data-cms')) return;\r\n if (el.closest('#xtroedge-cms-root, script, style, noscript')) return;\r\n\r\n // Skip elements with too many children (likely wrappers, not text)\r\n if (el.children.length > 3) return;\r\n\r\n // Get direct text content\r\n const text = this.getDirectTextContent(el).trim();\r\n if (text.length < 2) return;\r\n\r\n // Generate stable key\r\n const tag = el.tagName.toLowerCase();\r\n if (!tagCounters[tag]) tagCounters[tag] = 0;\r\n const key = `xcms_${tag}_${tagCounters[tag]}`;\r\n tagCounters[tag]++;\r\n\r\n el.setAttribute('data-cms', key);\r\n this.autoDetectedElements.add(el);\r\n });\r\n }\r\n\r\n private scanDOM(): void {\r\n const elements = document.querySelectorAll<HTMLElement>('[data-cms]');\r\n elements.forEach(el => {\r\n if (el.closest('#xtroedge-cms-root')) return;\r\n const key = el.getAttribute('data-cms')!;\r\n this.registeredKeys.add(key);\r\n if (!this.managedElements.has(el)) {\r\n this.attachElement(el, key);\r\n }\r\n });\r\n // Cleanup removed elements\r\n for (const [el] of this.managedElements) {\r\n if (!document.contains(el)) this.detachElement(el);\r\n }\r\n }\r\n\r\n private scanImages(): void {\r\n const container = document.querySelector(this.containerSelector);\r\n if (!container) return;\r\n const currentImages = { ...this.pageImages };\r\n let hasNew = false;\r\n const images = container.querySelectorAll<HTMLImageElement>('img');\r\n images.forEach(img => {\r\n if (img.closest('#xtroedge-cms-root')) return;\r\n if (this.managedImages.has(img)) return;\r\n const src = img.getAttribute('src') || '';\r\n if (!src || src.startsWith('data:')) return;\r\n this.attachImage(img, src);\r\n if (!currentImages[src]) {\r\n currentImages[src] = src;\r\n hasNew = true;\r\n }\r\n });\r\n if (hasNew) {\r\n this.pageImages = currentImages;\r\n this.originalImages = JSON.parse(JSON.stringify(currentImages));\r\n }\r\n for (const [img] of this.managedImages) {\r\n if (!document.contains(img)) this.detachImage(img);\r\n }\r\n }\r\n\r\n private getDirectTextContent(el: HTMLElement): string {\r\n let text = '';\r\n for (let i = 0; i < el.childNodes.length; i++) {\r\n if (el.childNodes[i].nodeType === Node.TEXT_NODE) {\r\n text += el.childNodes[i].textContent || '';\r\n }\r\n }\r\n return text;\r\n }\r\n\r\n // ===============================================\r\n // ELEMENT EDITING\r\n // ===============================================\r\n\r\n private attachElement(el: HTMLElement, key: string): void {\r\n const blurHandler = () => {\r\n const text = el.textContent?.trim() || '';\r\n const currentVal = this.getPageText(key);\r\n if (text !== currentVal) this.onTextChanged(key, text);\r\n };\r\n const keydownHandler = (e: KeyboardEvent) => {\r\n if (e.key === 'Enter') { e.preventDefault(); el.blur(); }\r\n };\r\n const inputHandler = () => {\r\n const text = el.textContent?.trim() || '';\r\n const currentVal = this.getPageText(key);\r\n if (text !== currentVal) this.onTextChanged(key, text);\r\n };\r\n this.managedElements.set(el, { key, blurHandler, keydownHandler, inputHandler });\r\n if (this.editMode) this.enableElementEdit(el, key, blurHandler, keydownHandler, inputHandler);\r\n }\r\n\r\n private detachElement(el: HTMLElement): void {\r\n const info = this.managedElements.get(el);\r\n if (info) {\r\n el.removeEventListener('blur', info.blurHandler);\r\n el.removeEventListener('keydown', info.keydownHandler as EventListener);\r\n el.removeEventListener('input', info.inputHandler);\r\n el.removeAttribute('contenteditable');\r\n this.managedElements.delete(el);\r\n }\r\n }\r\n\r\n private enableElementEdit(el: HTMLElement, _key: string, blurH: (e: Event) => void, keyH: (e: KeyboardEvent) => void, inputH: (e: Event) => void): void {\r\n const val = this.getPageText(_key);\r\n if (val) el.textContent = val;\r\n el.setAttribute('contenteditable', 'true');\r\n el.style.borderBottom = `2px dashed ${this.highlightColor}`;\r\n el.style.padding = '2px 4px';\r\n el.style.borderRadius = '3px';\r\n el.style.cursor = 'text';\r\n el.style.outline = 'none';\r\n el.style.transition = 'background 0.2s';\r\n el.style.minWidth = '20px';\r\n el.addEventListener('blur', blurH);\r\n el.addEventListener('keydown', keyH as EventListener);\r\n el.addEventListener('input', inputH);\r\n }\r\n\r\n private disableElementEdit(el: HTMLElement, _key: string, blurH: (e: Event) => void, keyH: (e: KeyboardEvent) => void, inputH: (e: Event) => void): void {\r\n el.removeAttribute('contenteditable');\r\n el.style.borderBottom = '';\r\n el.style.padding = '';\r\n el.style.borderRadius = '';\r\n el.style.cursor = '';\r\n el.style.outline = '';\r\n el.style.transition = '';\r\n el.style.minWidth = '';\r\n const val = this.getPageText(_key);\r\n if (val) el.textContent = val;\r\n el.removeEventListener('blur', blurH);\r\n el.removeEventListener('keydown', keyH as EventListener);\r\n el.removeEventListener('input', inputH);\r\n }\r\n\r\n private applyEditMode(editMode: boolean): void {\r\n for (const [el, info] of this.managedElements) {\r\n if (editMode) this.enableElementEdit(el, info.key, info.blurHandler, info.keydownHandler, info.inputHandler);\r\n else this.disableElementEdit(el, info.key, info.blurHandler, info.keydownHandler, info.inputHandler);\r\n }\r\n this.applyImageEditMode(editMode);\r\n }\r\n\r\n private updateElementTexts(): void {\r\n this.observer?.disconnect();\r\n for (const [el, info] of this.managedElements) {\r\n if (document.activeElement === el) continue;\r\n const val = this.getPageText(info.key);\r\n if (val && el.textContent !== val) el.textContent = val;\r\n }\r\n this.observer?.observe(document.body, { childList: true, subtree: true });\r\n }\r\n\r\n private cleanupManagedElements(): void {\r\n for (const [el] of this.managedElements) this.detachElement(el);\r\n this.managedElements.clear();\r\n for (const el of this.autoDetectedElements) el.removeAttribute('data-cms');\r\n this.autoDetectedElements.clear();\r\n this.cleanupManagedImages();\r\n }\r\n\r\n // ===============================================\r\n // IMAGE MANAGEMENT\r\n // ===============================================\r\n\r\n private attachImage(img: HTMLImageElement, key: string): void {\r\n const ctxHandler = (e: MouseEvent) => {\r\n if (!this.editMode) return;\r\n e.preventDefault();\r\n e.stopPropagation();\r\n this.showImageContextMenu(e.clientX, e.clientY, img);\r\n };\r\n this.managedImages.set(img, { key, ctxHandler });\r\n if (this.editMode) this.enableImageEdit(img, ctxHandler);\r\n }\r\n\r\n private detachImage(img: HTMLImageElement): void {\r\n const info = this.managedImages.get(img);\r\n if (info) {\r\n img.removeEventListener('contextmenu', info.ctxHandler);\r\n img.style.outline = '';\r\n img.style.cursor = '';\r\n this.managedImages.delete(img);\r\n }\r\n }\r\n\r\n private cleanupManagedImages(): void {\r\n for (const [img] of this.managedImages) this.detachImage(img);\r\n this.managedImages.clear();\r\n this.dismissImageCtxMenu();\r\n }\r\n\r\n private applyImageEditMode(editMode: boolean): void {\r\n for (const [img, info] of this.managedImages) {\r\n if (editMode) this.enableImageEdit(img, info.ctxHandler);\r\n else this.disableImageEdit(img, info.ctxHandler);\r\n }\r\n if (!editMode) this.dismissImageCtxMenu();\r\n }\r\n\r\n private enableImageEdit(img: HTMLImageElement, ctxHandler: (e: MouseEvent) => void): void {\r\n img.style.outline = `2px dashed ${this.highlightColor}`;\r\n img.style.cursor = 'context-menu';\r\n img.addEventListener('contextmenu', ctxHandler);\r\n }\r\n\r\n private disableImageEdit(img: HTMLImageElement, ctxHandler: (e: MouseEvent) => void): void {\r\n img.style.outline = '';\r\n img.style.cursor = '';\r\n img.removeEventListener('contextmenu', ctxHandler);\r\n }\r\n\r\n private showImageContextMenu(x: number, y: number, img: HTMLImageElement): void {\r\n this.dismissImageCtxMenu();\r\n const menu = document.createElement('div');\r\n Object.assign(menu.style, {\r\n position: 'fixed', zIndex: '10005', minWidth: '160px',\r\n background: 'rgba(30,15,60,0.85)', backdropFilter: 'blur(16px)', webkitBackdropFilter: 'blur(16px)',\r\n border: '1px solid rgba(139,92,246,0.3)', borderRadius: '10px', padding: '4px',\r\n boxShadow: '0 8px 32px rgba(0,0,0,0.4)', fontFamily: 'system-ui, -apple-system, sans-serif',\r\n left: Math.min(x, window.innerWidth - 180) + 'px',\r\n top: Math.min(y, window.innerHeight - 50) + 'px',\r\n });\r\n const btn = document.createElement('button');\r\n Object.assign(btn.style, {\r\n width: '100%', padding: '8px 12px', border: 'none', borderRadius: '7px',\r\n background: 'transparent', color: 'white', fontSize: '12px', fontWeight: '500',\r\n cursor: 'pointer', display: 'flex', alignItems: 'center', gap: '8px',\r\n });\r\n btn.innerHTML = `${ICON.image} Upload Image`;\r\n btn.addEventListener('mouseenter', () => btn.style.background = 'rgba(103,34,251,0.3)');\r\n btn.addEventListener('mouseleave', () => btn.style.background = 'transparent');\r\n btn.addEventListener('click', () => {\r\n this.activeImageEl = img;\r\n if (this.fileInput) { this.fileInput.value = ''; this.fileInput.click(); }\r\n this.dismissImageCtxMenu();\r\n });\r\n menu.appendChild(btn);\r\n document.body.appendChild(menu);\r\n this.imageCtxMenu = menu;\r\n\r\n const closeHandler = (e: MouseEvent) => {\r\n if (!menu.contains(e.target as Node)) {\r\n this.dismissImageCtxMenu();\r\n document.removeEventListener('mousedown', closeHandler);\r\n }\r\n };\r\n setTimeout(() => document.addEventListener('mousedown', closeHandler), 0);\r\n }\r\n\r\n private dismissImageCtxMenu(): void {\r\n if (this.imageCtxMenu) {\r\n this.imageCtxMenu.remove();\r\n this.imageCtxMenu = null;\r\n }\r\n }\r\n\r\n private onImageFileSelected(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n const file = input.files?.[0];\r\n if (!file || !this.activeImageEl) return;\r\n\r\n this.imageUploading = true;\r\n this.updateUI();\r\n\r\n const reader = new FileReader();\r\n reader.onload = () => {\r\n const dataUrl = reader.result as string;\r\n this.uploadImageToApi(dataUrl);\r\n };\r\n reader.readAsDataURL(file);\r\n }\r\n\r\n private async uploadImageToApi(dataUrl: string): Promise<void> {\r\n try {\r\n const res = await fetch(`${this.config.apiBase}/web/upload-image`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ url: dataUrl }),\r\n });\r\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\r\n const data = await res.json();\r\n const baseUrl = this.config.imageBaseUrl || new URL(this.config.apiBase).origin;\r\n const fullUrl = baseUrl + data.path;\r\n if (this.activeImageEl) {\r\n const key = this.managedImages.get(this.activeImageEl)?.key || '';\r\n this.activeImageEl.src = fullUrl;\r\n this.onImageChanged(key, fullUrl);\r\n }\r\n this.imageUploading = false;\r\n this.activeImageEl = null;\r\n this.updateUI();\r\n this.showToast('Image updated!', 'success');\r\n } catch (err) {\r\n this.imageUploading = false;\r\n this.activeImageEl = null;\r\n this.updateUI();\r\n this.showToast('Image upload failed.', 'error');\r\n this.config.onError?.('upload-image', err);\r\n }\r\n }\r\n\r\n private applyPageImages(): void {\r\n for (const [img, info] of this.managedImages) {\r\n const url = this.pageImages[info.key];\r\n if (url && img.src !== url) img.src = url;\r\n }\r\n }\r\n\r\n // ===============================================\r\n // TEXT STATE\r\n // ===============================================\r\n\r\n private getPageText(key: string): string {\r\n return this.pageTexts[key]?.[this.currentLang] || '';\r\n }\r\n\r\n private onTextChanged(key: string, newValue: string): void {\r\n this.undoStack.push(this.createSnapshot());\r\n this.redoStack = [];\r\n this.canUndo = true;\r\n this.canRedo = false;\r\n\r\n if (!this.pageTexts[key]) this.pageTexts[key] = {};\r\n this.pageTexts[key] = { ...this.pageTexts[key], [this.currentLang]: newValue };\r\n this.dirtyKeys.add(key);\r\n this.unsavedChanges = this.dirtyKeys.size + this.dirtyImageKeys.size;\r\n this.pushHistory(key, this.currentLang);\r\n this.updateUI();\r\n }\r\n\r\n private onImageChanged(key: string, url: string): void {\r\n this.undoStack.push(this.createSnapshot());\r\n this.redoStack = [];\r\n this.canUndo = true;\r\n this.canRedo = false;\r\n\r\n this.pageImages = { ...this.pageImages, [key]: url };\r\n this.dirtyImageKeys.add(key);\r\n this.unsavedChanges = this.dirtyKeys.size + this.dirtyImageKeys.size;\r\n this.pushHistory(key, 'img');\r\n this.updateUI();\r\n }\r\n\r\n private createSnapshot(): string {\r\n return JSON.stringify({ texts: this.pageTexts, images: this.pageImages });\r\n }\r\n\r\n private applySnapshot(raw: string): void {\r\n const data = JSON.parse(raw);\r\n if (data.texts) {\r\n this.pageTexts = data.texts;\r\n if (data.images) this.pageImages = data.images;\r\n } else {\r\n this.pageTexts = data;\r\n }\r\n }\r\n\r\n // ===============================================\r\n // UNDO / REDO\r\n // ===============================================\r\n\r\n private onUndo(): void {\r\n if (this.undoStack.length === 0) return;\r\n this.redoStack.push(this.createSnapshot());\r\n this.applySnapshot(this.undoStack.pop()!);\r\n this.canUndo = this.undoStack.length > 0;\r\n this.canRedo = true;\r\n this.recalcDirtyKeys();\r\n this.updateElementTexts();\r\n this.applyPageImages();\r\n this.updateUI();\r\n }\r\n\r\n private onRedo(): void {\r\n if (this.redoStack.length === 0) return;\r\n this.undoStack.push(this.createSnapshot());\r\n this.applySnapshot(this.redoStack.pop()!);\r\n this.canUndo = true;\r\n this.canRedo = this.redoStack.length > 0;\r\n this.recalcDirtyKeys();\r\n this.updateElementTexts();\r\n this.applyPageImages();\r\n this.updateUI();\r\n }\r\n\r\n private recalcDirtyKeys(): void {\r\n this.dirtyKeys.clear();\r\n for (const key of this.registeredKeys) {\r\n if (JSON.stringify(this.pageTexts[key]) !== JSON.stringify(this.originalTexts[key])) {\r\n this.dirtyKeys.add(key);\r\n }\r\n }\r\n this.unsavedChanges = this.dirtyKeys.size + this.dirtyImageKeys.size;\r\n }\r\n\r\n private resetAll(): void {\r\n this.dirtyKeys.clear();\r\n this.dirtyImageKeys.clear();\r\n this.unsavedChanges = 0;\r\n this.undoStack = [];\r\n this.redoStack = [];\r\n this.canUndo = false;\r\n this.canRedo = false;\r\n this.updateUI();\r\n }\r\n\r\n private resetAfterSave(): void {\r\n this.dirtyKeys.clear();\r\n this.dirtyImageKeys.clear();\r\n this.unsavedChanges = 0;\r\n this.originalTexts = JSON.parse(JSON.stringify(this.pageTexts));\r\n this.originalImages = JSON.parse(JSON.stringify(this.pageImages));\r\n }\r\n\r\n private cancelEditing(): void {\r\n this.pageTexts = JSON.parse(JSON.stringify(this.originalTexts));\r\n this.pageImages = JSON.parse(JSON.stringify(this.originalImages));\r\n this.dirtyKeys.clear();\r\n this.dirtyImageKeys.clear();\r\n this.unsavedChanges = 0;\r\n this.updateElementTexts();\r\n this.applyPageImages();\r\n this.updateUI();\r\n }\r\n\r\n // ===============================================\r\n // API\r\n // ===============================================\r\n\r\n private async loadTranslationsAndInit(loadDraft: boolean): Promise<void> {\r\n if (this.config.i18nBasePath) {\r\n try {\r\n const lang = this.currentLang;\r\n const res = await fetch(`${this.config.i18nBasePath}/${lang}.json`);\r\n if (res.ok) {\r\n const translations = await res.json();\r\n this.translationCache.clear();\r\n this.flattenTranslations(translations, '', this.getPageSection());\r\n }\r\n } catch { /* ignore */ }\r\n }\r\n\r\n this.autoDetectAndScan();\r\n if (this.editMode) this.applyEditMode(true);\r\n if (loadDraft) this.loadPageContent('draft');\r\n else this.loadPublishedContent();\r\n this.updateUI();\r\n }\r\n\r\n private flattenTranslations(obj: any, prefix: string, pageSection: string): void {\r\n for (const k of Object.keys(obj)) {\r\n const fullKey = prefix ? `${prefix}.${k}` : k;\r\n if (typeof obj[k] === 'string') {\r\n const text = obj[k].trim();\r\n if (text.length >= 2) {\r\n const existing = this.translationCache.get(text);\r\n if (!existing || fullKey.toUpperCase().startsWith(pageSection)) {\r\n this.translationCache.set(text, fullKey);\r\n }\r\n }\r\n } else if (typeof obj[k] === 'object' && obj[k] !== null && !Array.isArray(obj[k])) {\r\n this.flattenTranslations(obj[k], fullKey, pageSection);\r\n }\r\n }\r\n }\r\n\r\n private getPageSection(): string {\r\n return this.currentSlug.replace(/^\\//, '').replace(/-/g, '_').toUpperCase();\r\n }\r\n\r\n private async loadPageContent(status: 'draft' | 'published'): Promise<void> {\r\n this.setLoading(true);\r\n this.cleanOldHistory();\r\n\r\n try {\r\n const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=${status}`);\r\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\r\n const page: WebPageContent = await res.json();\r\n const texts = page?.published_content?.texts || page?.content?.texts;\r\n if (texts) {\r\n this.pageTexts = JSON.parse(JSON.stringify(texts));\r\n } else {\r\n this.buildDefaultTexts();\r\n }\r\n const images = page?.published_content?.images || page?.content?.images;\r\n if (images) {\r\n this.pageImages = JSON.parse(JSON.stringify(images));\r\n this.applyPageImages();\r\n }\r\n this.originalTexts = JSON.parse(JSON.stringify(this.pageTexts));\r\n this.originalImages = JSON.parse(JSON.stringify(this.pageImages));\r\n this.resetAll();\r\n this.updateElementTexts();\r\n } catch {\r\n this.buildDefaultTexts();\r\n this.originalTexts = JSON.parse(JSON.stringify(this.pageTexts));\r\n this.originalImages = JSON.parse(JSON.stringify(this.pageImages));\r\n this.resetAll();\r\n } finally {\r\n this.setLoading(false);\r\n }\r\n }\r\n\r\n private async loadPublishedContent(): Promise<void> {\r\n this.setLoading(true);\r\n\r\n try {\r\n const res = await fetch(`${this.config.apiBase}/web-page/get?slug=${encodeURIComponent(this.currentSlug)}&status=published`);\r\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\r\n const page: WebPageContent = await res.json();\r\n const texts = page?.published_content?.texts;\r\n if (texts && Object.keys(texts).length > 0) {\r\n this.pageTexts = JSON.parse(JSON.stringify(texts));\r\n this.updateElementTexts();\r\n }\r\n const images = page?.published_content?.images;\r\n if (images && Object.keys(images).length > 0) {\r\n this.pageImages = JSON.parse(JSON.stringify(images));\r\n this.applyPageImages();\r\n }\r\n } catch { /* ignore - use current DOM text */ }\r\n finally { this.setLoading(false); }\r\n }\r\n\r\n private buildDefaultTexts(): void {\r\n const texts: { [key: string]: PageTextEntry } = {};\r\n for (const key of this.registeredKeys) {\r\n const el = document.querySelector(`[data-cms=\"${key}\"]`);\r\n const val = el?.textContent?.trim() || '';\r\n texts[key] = { [this.currentLang]: val };\r\n }\r\n this.pageTexts = texts;\r\n\r\n // Load other languages from i18n files if available\r\n if (this.config.i18nBasePath) {\r\n const otherLangs = this.languages.filter(l => l !== this.currentLang);\r\n for (const lang of otherLangs) {\r\n fetch(`${this.config.i18nBasePath}/${lang}.json`)\r\n .then(r => r.json())\r\n .then(translations => {\r\n const updated = { ...this.pageTexts };\r\n for (const key of this.registeredKeys) {\r\n // Try to resolve key path in translations\r\n const parts = key.split('.');\r\n let val: any = translations;\r\n for (const part of parts) { val = val?.[part]; }\r\n if (val && typeof val === 'string') {\r\n updated[key] = { ...updated[key], [lang]: val };\r\n }\r\n }\r\n this.pageTexts = updated;\r\n this.originalTexts = JSON.parse(JSON.stringify(updated));\r\n this.updateElementTexts();\r\n })\r\n .catch(() => { /* ignore */ });\r\n }\r\n }\r\n }\r\n\r\n private async saveChanges(): Promise<void> {\r\n this.isSaving = true;\r\n this.updateUI();\r\n const payload = {\r\n slug: this.currentSlug,\r\n title: this.currentTitle,\r\n content: { texts: this.pageTexts, images: this.pageImages }\r\n };\r\n\r\n try {\r\n const res = await fetch(`${this.config.apiBase}/web_page/save`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(payload),\r\n });\r\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\r\n this.isSaving = false;\r\n this.resetAfterSave();\r\n this.updateUI();\r\n this.showToast('Draft saved successfully!', 'success');\r\n this.config.onSaved?.();\r\n } catch (err) {\r\n this.isSaving = false;\r\n this.updateUI();\r\n this.showToast('Save failed. Please try again.', 'error');\r\n this.config.onError?.('save', err);\r\n }\r\n }\r\n\r\n private async publishChanges(): Promise<void> {\r\n this.isPublishing = true;\r\n this.updateUI();\r\n const payload = {\r\n slug: this.currentSlug,\r\n title: this.currentTitle,\r\n published_content: { texts: this.pageTexts, images: this.pageImages }\r\n };\r\n\r\n try {\r\n const res = await fetch(`${this.config.apiBase}/web_page/publish`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify(payload),\r\n });\r\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\r\n this.isPublishing = false;\r\n this.resetAfterSave();\r\n this.updateUI();\r\n this.showToast('Published successfully!', 'success');\r\n this.config.onPublished?.();\r\n } catch (err) {\r\n this.isPublishing = false;\r\n this.updateUI();\r\n this.showToast('Publish failed. Please try again.', 'error');\r\n this.config.onError?.('publish', err);\r\n }\r\n }\r\n\r\n // ===============================================\r\n // HISTORY (IndexedDB)\r\n // ===============================================\r\n\r\n private async toggleHistory(): Promise<void> {\r\n this.showHistory = !this.showHistory;\r\n if (this.showHistory) await this.loadHistory();\r\n this.updateUI();\r\n }\r\n\r\n private async loadHistory(): Promise<void> {\r\n try {\r\n const db = await this.openDB();\r\n const entries = await new Promise<EditHistoryEntry[]>((resolve, reject) => {\r\n const tx = db.transaction(STORE_NAME, 'readonly');\r\n const store = tx.objectStore(STORE_NAME);\r\n const index = store.index('slug');\r\n const req = index.getAll(this.currentSlug);\r\n req.onsuccess = () => resolve((req.result as EditHistoryEntry[]).sort((a, b) => b.timestamp - a.timestamp).slice(0, 30));\r\n req.onerror = () => reject(req.error);\r\n });\r\n this.historyList = entries;\r\n this.renderHistoryList();\r\n } catch { /* ignore */ }\r\n }\r\n\r\n private renderHistoryList(): void {\r\n if (!this.historyListEl) return;\r\n this.historyListEl.innerHTML = '';\r\n if (this.historyList.length === 0) {\r\n const empty = this.createElement('div', 'lcms-history-empty');\r\n empty.textContent = 'No history yet';\r\n this.historyListEl.appendChild(empty);\r\n return;\r\n }\r\n for (const entry of this.historyList) {\r\n const item = document.createElement('button');\r\n item.className = 'lcms-history-item';\r\n const labelEl = this.createElement('div', 'lcms-history-label');\r\n labelEl.textContent = entry.label;\r\n const metaEl = this.createElement('div', 'lcms-history-meta');\r\n const langEl = this.createElement('span', 'lcms-history-lang');\r\n langEl.textContent = entry.lang.toUpperCase();\r\n const dateText = document.createTextNode(' ' + this.formatDate(entry.timestamp));\r\n metaEl.appendChild(langEl);\r\n metaEl.appendChild(dateText);\r\n item.appendChild(labelEl);\r\n item.appendChild(metaEl);\r\n item.addEventListener('click', (e) => { e.stopPropagation(); this.restoreHistory(entry); });\r\n this.historyListEl.appendChild(item);\r\n }\r\n }\r\n\r\n private restoreHistory(entry: EditHistoryEntry): void {\r\n this.undoStack.push(this.createSnapshot());\r\n this.canUndo = true;\r\n this.applySnapshot(entry.snapshot);\r\n this.recalcDirtyKeys();\r\n this.showHistory = false;\r\n this.updateElementTexts();\r\n this.applyPageImages();\r\n this.updateUI();\r\n this.showToast('Restored from history', 'success');\r\n }\r\n\r\n private pushHistory(key: string, lang: string): void {\r\n const isImage = lang === 'img';\r\n const shortKey = isImage ? key.split('/').pop() || 'image' : (key.split('_').pop() || key);\r\n const label = isImage ? `Changed ${shortKey}` : `Edited ${shortKey}`;\r\n this.openDB().then(db => {\r\n const tx = db.transaction(STORE_NAME, 'readwrite');\r\n tx.objectStore(STORE_NAME).add({\r\n slug: this.currentSlug, timestamp: Date.now(),\r\n label, lang,\r\n snapshot: JSON.stringify({ texts: this.pageTexts, images: this.pageImages })\r\n });\r\n }).catch(() => { /* ignore */ });\r\n }\r\n\r\n private async cleanOldHistory(): Promise<void> {\r\n try {\r\n const db = await this.openDB();\r\n const cutoff = Date.now() - this.historyRetentionMs;\r\n const tx = db.transaction(STORE_NAME, 'readwrite');\r\n const index = tx.objectStore(STORE_NAME).index('timestamp');\r\n const req = index.openCursor(IDBKeyRange.upperBound(cutoff));\r\n req.onsuccess = () => { const c = req.result; if (c) { c.delete(); c.continue(); } };\r\n } catch { /* ignore */ }\r\n }\r\n\r\n private openDB(): Promise<IDBDatabase> {\r\n if (this.db) return Promise.resolve(this.db);\r\n return new Promise((resolve, reject) => {\r\n const req = indexedDB.open(DB_NAME, 1);\r\n req.onupgradeneeded = () => {\r\n const db = req.result;\r\n if (!db.objectStoreNames.contains(STORE_NAME)) {\r\n const store = db.createObjectStore(STORE_NAME, { keyPath: 'id', autoIncrement: true });\r\n store.createIndex('slug', 'slug', { unique: false });\r\n store.createIndex('timestamp', 'timestamp', { unique: false });\r\n }\r\n };\r\n req.onsuccess = () => { this.db = req.result; resolve(this.db); };\r\n req.onerror = () => reject(req.error);\r\n });\r\n }\r\n\r\n // ===============================================\r\n // TOAST\r\n // ===============================================\r\n\r\n private showToast(message: string, type: 'success' | 'error'): void {\r\n if (!this.toastEl) return;\r\n this.toastMessage = message;\r\n this.toastType = type;\r\n\r\n const icon = type === 'success' ? ICON.check : ICON.error;\r\n this.toastEl.className = `lcms-toast lcms-toast-${type}`;\r\n this.toastEl.innerHTML = `${icon} ${message}`;\r\n\r\n if (this.toastTimer) clearTimeout(this.toastTimer);\r\n this.toastTimer = setTimeout(() => {\r\n if (this.toastEl) this.toastEl.classList.add('lcms-hidden');\r\n }, 3000);\r\n }\r\n\r\n // ===============================================\r\n // FAB & PANEL\r\n // ===============================================\r\n\r\n private onFabClick(e: Event): void {\r\n e.stopPropagation();\r\n if (this.hasMoved) return;\r\n this.isOpen = !this.isOpen;\r\n this.updateUI();\r\n }\r\n\r\n private togglePanel(): void {\r\n if (!this.hasMoved) {\r\n this.isOpen = !this.isOpen;\r\n this.updateUI();\r\n }\r\n }\r\n\r\n private toggleEditMode(e: Event): void {\r\n e.stopPropagation();\r\n const checked = (e.target as HTMLInputElement).checked;\r\n if (checked) {\r\n sessionStorage.setItem('builder_edit_mode', 'true');\r\n this.editMode = true;\r\n this.currentLang = this.detectCurrentLanguage();\r\n this.applyEditMode(true);\r\n this.loadPageContent('draft');\r\n } else {\r\n sessionStorage.removeItem('builder_edit_mode');\r\n this.editMode = false;\r\n this.applyEditMode(false);\r\n }\r\n this.updateUI();\r\n this.config.onEditModeChanged?.(this.editMode);\r\n }\r\n\r\n private switchLang(lang: string): void {\r\n this.currentLang = lang;\r\n this.updateElementTexts();\r\n this.buildLangButtons();\r\n this.updateUI();\r\n this.config.onLangChanged?.(lang);\r\n }\r\n\r\n // ===============================================\r\n // FAB DRAG\r\n // ===============================================\r\n\r\n private onDragStart(e: MouseEvent): void {\r\n if ((e.target as HTMLElement).closest('button:not(.lcms-fab-btn)') || (e.target as HTMLElement).closest('.lcms-panel')) return;\r\n this.isDragging = true;\r\n this.hasMoved = false;\r\n this.dragStartX = e.clientX;\r\n this.dragStartY = e.clientY;\r\n this.startPosX = this.posX;\r\n this.startPosY = this.posY;\r\n document.addEventListener('mousemove', this.boundMouseMove);\r\n document.addEventListener('mouseup', this.boundMouseUp);\r\n }\r\n\r\n private onDragMove(e: MouseEvent): void {\r\n if (!this.isDragging || !this.fabEl) return;\r\n const dx = e.clientX - this.dragStartX, dy = e.clientY - this.dragStartY;\r\n if (Math.abs(dx) > 3 || Math.abs(dy) > 3) this.hasMoved = true;\r\n this.posX = Math.max(0, Math.min(window.innerWidth - 60, this.startPosX + dx));\r\n this.posY = Math.max(0, Math.min(window.innerHeight - 60, this.startPosY + dy));\r\n this.fabEl.style.left = this.posX + 'px';\r\n this.fabEl.style.top = this.posY + 'px';\r\n }\r\n\r\n private onDragEnd(): void {\r\n this.isDragging = false;\r\n document.removeEventListener('mousemove', this.boundMouseMove);\r\n document.removeEventListener('mouseup', this.boundMouseUp);\r\n }\r\n\r\n private onTouchStart(e: TouchEvent): void {\r\n if ((e.target as HTMLElement).closest('button:not(.lcms-fab-btn)') || (e.target as HTMLElement).closest('.lcms-panel')) return;\r\n const t = e.touches[0];\r\n this.isDragging = true;\r\n this.hasMoved = false;\r\n this.dragStartX = t.clientX;\r\n this.dragStartY = t.clientY;\r\n this.startPosX = this.posX;\r\n this.startPosY = this.posY;\r\n document.addEventListener('touchmove', this.boundTouchMove, { passive: false });\r\n document.addEventListener('touchend', this.boundTouchEnd);\r\n }\r\n\r\n private onTouchMove(e: TouchEvent): void {\r\n if (!this.isDragging || !this.fabEl) return;\r\n e.preventDefault();\r\n const t = e.touches[0];\r\n const dx = t.clientX - this.dragStartX, dy = t.clientY - this.dragStartY;\r\n if (Math.abs(dx) > 3 || Math.abs(dy) > 3) this.hasMoved = true;\r\n this.posX = Math.max(0, Math.min(window.innerWidth - 60, this.startPosX + dx));\r\n this.posY = Math.max(0, Math.min(window.innerHeight - 60, this.startPosY + dy));\r\n this.fabEl.style.left = this.posX + 'px';\r\n this.fabEl.style.top = this.posY + 'px';\r\n }\r\n\r\n private onTouchEnd(): void {\r\n this.isDragging = false;\r\n document.removeEventListener('touchmove', this.boundTouchMove);\r\n document.removeEventListener('touchend', this.boundTouchEnd);\r\n }\r\n\r\n // ===============================================\r\n // HELPERS\r\n // ===============================================\r\n\r\n private setLoading(val: boolean): void {\r\n this.loading = val;\r\n this.updateUI();\r\n }\r\n\r\n private detectCurrentLanguage(): string {\r\n const htmlLang = document.documentElement.getAttribute('lang');\r\n if (htmlLang && this.languages.includes(htmlLang)) return htmlLang;\r\n const stored = localStorage.getItem('selectedLanguage');\r\n if (stored && this.languages.includes(stored)) return stored;\r\n return this.defaultLanguage;\r\n }\r\n\r\n private createElement(tag: string, className: string): HTMLElement {\r\n const el = document.createElement(tag);\r\n el.className = className;\r\n return el;\r\n }\r\n\r\n private formatDate(timestamp: number): string {\r\n const d = new Date(timestamp);\r\n const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\r\n const h = d.getHours();\r\n const m = d.getMinutes().toString().padStart(2, '0');\r\n const ampm = h >= 12 ? 'PM' : 'AM';\r\n const h12 = h % 12 || 12;\r\n return `${months[d.getMonth()]} ${d.getDate()}, ${h12}:${m} ${ampm}`;\r\n }\r\n\r\n // ===============================================\r\n // STATIC CONVENIENCE\r\n // ===============================================\r\n\r\n /** Quick init - create and start CMS in one call */\r\n static create(config: XtroedgeCmsConfig): XtroedgeCMS {\r\n const cms = new XtroedgeCMS(config);\r\n cms.init();\r\n return cms;\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
|