@wrrdev/fenix-ui 1.1.13 → 1.1.15

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.
Files changed (161) hide show
  1. package/README.md +6 -5
  2. package/dist/components/autocomplete/autocomplete.d.ts +11 -5
  3. package/dist/components/autocomplete/autocomplete.d.ts.map +1 -1
  4. package/dist/components/autocomplete/autocomplete.js +18 -2
  5. package/dist/components/autocomplete/autocomplete.js.map +1 -1
  6. package/dist/components/button/button.d.ts +15 -0
  7. package/dist/components/button/button.d.ts.map +1 -1
  8. package/dist/components/button/button.js +20 -1
  9. package/dist/components/button/button.js.map +1 -1
  10. package/dist/components/checkbox/checkbox.d.ts +20 -4
  11. package/dist/components/checkbox/checkbox.d.ts.map +1 -1
  12. package/dist/components/checkbox/checkbox.js +39 -2
  13. package/dist/components/checkbox/checkbox.js.map +1 -1
  14. package/dist/components/datepicker/datepicker.d.ts +16 -2
  15. package/dist/components/datepicker/datepicker.d.ts.map +1 -1
  16. package/dist/components/datepicker/datepicker.js +46 -2
  17. package/dist/components/datepicker/datepicker.js.map +1 -1
  18. package/dist/components/editor/commands.d.ts +27 -0
  19. package/dist/components/editor/commands.d.ts.map +1 -0
  20. package/dist/components/editor/commands.js +235 -0
  21. package/dist/components/editor/commands.js.map +1 -0
  22. package/dist/components/editor/editor.d.ts +83 -0
  23. package/dist/components/editor/editor.d.ts.map +1 -0
  24. package/dist/components/editor/editor.js +1951 -0
  25. package/dist/components/editor/editor.js.map +1 -0
  26. package/dist/components/editor/index.d.ts +12 -0
  27. package/dist/components/editor/index.d.ts.map +1 -0
  28. package/dist/components/editor/index.js +7 -0
  29. package/dist/components/editor/index.js.map +1 -0
  30. package/dist/components/editor/normalize-html.d.ts +33 -0
  31. package/dist/components/editor/normalize-html.d.ts.map +1 -0
  32. package/dist/components/editor/normalize-html.js +316 -0
  33. package/dist/components/editor/normalize-html.js.map +1 -0
  34. package/dist/components/editor/sanitize-html.d.ts +37 -0
  35. package/dist/components/editor/sanitize-html.d.ts.map +1 -0
  36. package/dist/components/editor/sanitize-html.js +247 -0
  37. package/dist/components/editor/sanitize-html.js.map +1 -0
  38. package/dist/components/editor/schema.d.ts +36 -0
  39. package/dist/components/editor/schema.d.ts.map +1 -0
  40. package/dist/components/editor/schema.js +232 -0
  41. package/dist/components/editor/schema.js.map +1 -0
  42. package/dist/components/editor/selection.d.ts +22 -0
  43. package/dist/components/editor/selection.d.ts.map +1 -0
  44. package/dist/components/editor/selection.js +97 -0
  45. package/dist/components/editor/selection.js.map +1 -0
  46. package/dist/components/editor/styles.d.ts +10 -0
  47. package/dist/components/editor/styles.d.ts.map +1 -0
  48. package/dist/components/editor/styles.js +446 -0
  49. package/dist/components/editor/styles.js.map +1 -0
  50. package/dist/components/editor/table-utils.d.ts +33 -0
  51. package/dist/components/editor/table-utils.d.ts.map +1 -0
  52. package/dist/components/editor/table-utils.js +150 -0
  53. package/dist/components/editor/table-utils.js.map +1 -0
  54. package/dist/components/fileupload/fileupload.d.ts +10 -2
  55. package/dist/components/fileupload/fileupload.d.ts.map +1 -1
  56. package/dist/components/fileupload/fileupload.js +17 -2
  57. package/dist/components/fileupload/fileupload.js.map +1 -1
  58. package/dist/components/floatlabel/floatlabel.d.ts +9 -3
  59. package/dist/components/floatlabel/floatlabel.d.ts.map +1 -1
  60. package/dist/components/floatlabel/floatlabel.js +22 -7
  61. package/dist/components/floatlabel/floatlabel.js.map +1 -1
  62. package/dist/components/input/input.d.ts +18 -7
  63. package/dist/components/input/input.d.ts.map +1 -1
  64. package/dist/components/input/input.js +33 -3
  65. package/dist/components/input/input.js.map +1 -1
  66. package/dist/components/knob/knob.d.ts +7 -3
  67. package/dist/components/knob/knob.d.ts.map +1 -1
  68. package/dist/components/knob/knob.js +4 -2
  69. package/dist/components/knob/knob.js.map +1 -1
  70. package/dist/components/multiselect/multiselect.d.ts +13 -3
  71. package/dist/components/multiselect/multiselect.d.ts.map +1 -1
  72. package/dist/components/multiselect/multiselect.js +27 -2
  73. package/dist/components/multiselect/multiselect.js.map +1 -1
  74. package/dist/components/radio/radio.d.ts +27 -4
  75. package/dist/components/radio/radio.d.ts.map +1 -1
  76. package/dist/components/radio/radio.js +67 -8
  77. package/dist/components/radio/radio.js.map +1 -1
  78. package/dist/components/rating/rating.d.ts +8 -4
  79. package/dist/components/rating/rating.d.ts.map +1 -1
  80. package/dist/components/rating/rating.js +5 -2
  81. package/dist/components/rating/rating.js.map +1 -1
  82. package/dist/components/select/select.d.ts +9 -3
  83. package/dist/components/select/select.d.ts.map +1 -1
  84. package/dist/components/select/select.js +11 -2
  85. package/dist/components/select/select.js.map +1 -1
  86. package/dist/components/slider/slider.d.ts +12 -6
  87. package/dist/components/slider/slider.d.ts.map +1 -1
  88. package/dist/components/slider/slider.js +10 -2
  89. package/dist/components/slider/slider.js.map +1 -1
  90. package/dist/components/switch/switch.d.ts +20 -4
  91. package/dist/components/switch/switch.d.ts.map +1 -1
  92. package/dist/components/switch/switch.js +40 -2
  93. package/dist/components/switch/switch.js.map +1 -1
  94. package/dist/components/textarea/textarea.d.ts +12 -5
  95. package/dist/components/textarea/textarea.d.ts.map +1 -1
  96. package/dist/components/textarea/textarea.js +12 -2
  97. package/dist/components/textarea/textarea.js.map +1 -1
  98. package/dist/components/toast/toast.d.ts +27 -15
  99. package/dist/components/toast/toast.d.ts.map +1 -1
  100. package/dist/components/toast/toast.js +205 -32
  101. package/dist/components/toast/toast.js.map +1 -1
  102. package/dist/components/toggle-button-group/toggle-button-group.d.ts +13 -5
  103. package/dist/components/toggle-button-group/toggle-button-group.d.ts.map +1 -1
  104. package/dist/components/toggle-button-group/toggle-button-group.js +19 -2
  105. package/dist/components/toggle-button-group/toggle-button-group.js.map +1 -1
  106. package/dist/core/base.d.ts +7 -0
  107. package/dist/core/base.d.ts.map +1 -1
  108. package/dist/core/base.js +4 -1
  109. package/dist/core/base.js.map +1 -1
  110. package/dist/core/form-element.d.ts +81 -0
  111. package/dist/core/form-element.d.ts.map +1 -0
  112. package/dist/core/form-element.js +129 -0
  113. package/dist/core/form-element.js.map +1 -0
  114. package/dist/core/jsx.d.ts +25 -1
  115. package/dist/core/jsx.d.ts.map +1 -1
  116. package/dist/core/jsx.js.map +1 -1
  117. package/dist/core/presets.d.ts +8 -3
  118. package/dist/core/presets.d.ts.map +1 -1
  119. package/dist/core/presets.js +6 -17
  120. package/dist/core/presets.js.map +1 -1
  121. package/dist/core/types.d.ts +4 -0
  122. package/dist/core/types.d.ts.map +1 -1
  123. package/dist/core/vue.d.ts +3 -1
  124. package/dist/core/vue.d.ts.map +1 -1
  125. package/dist/core/vue.js.map +1 -1
  126. package/dist/docs/app.d.ts.map +1 -1
  127. package/dist/docs/componentes/autocomplete.doc.d.ts.map +1 -1
  128. package/dist/docs/componentes/checkbox.doc.d.ts.map +1 -1
  129. package/dist/docs/componentes/datepicker.doc.d.ts.map +1 -1
  130. package/dist/docs/componentes/editor.doc.d.ts +6 -0
  131. package/dist/docs/componentes/editor.doc.d.ts.map +1 -0
  132. package/dist/docs/componentes/fileupload.doc.d.ts.map +1 -1
  133. package/dist/docs/componentes/index.d.ts.map +1 -1
  134. package/dist/docs/componentes/input.doc.d.ts.map +1 -1
  135. package/dist/docs/componentes/knob.doc.d.ts.map +1 -1
  136. package/dist/docs/componentes/multiselect.doc.d.ts.map +1 -1
  137. package/dist/docs/componentes/rating.doc.d.ts.map +1 -1
  138. package/dist/docs/componentes/select.doc.d.ts.map +1 -1
  139. package/dist/docs/componentes/slider.doc.d.ts.map +1 -1
  140. package/dist/docs/componentes/switch.doc.d.ts.map +1 -1
  141. package/dist/docs/componentes/textarea.doc.d.ts.map +1 -1
  142. package/dist/docs/componentes/toast.doc.d.ts.map +1 -1
  143. package/dist/docs/componentes/toggle-button-group.doc.d.ts.map +1 -1
  144. package/dist/docs/frameworks.d.ts +75 -0
  145. package/dist/docs/frameworks.d.ts.map +1 -0
  146. package/dist/docs/ui/code.d.ts +4 -0
  147. package/dist/docs/ui/code.d.ts.map +1 -1
  148. package/dist/fenix-ui.umd.min.js +786 -254
  149. package/dist/fenix-ui2.esm.js.map +1 -1
  150. package/dist/fenix-ui4.esm.js +4396 -172
  151. package/dist/fenix-ui4.esm.js.map +1 -1
  152. package/dist/fenix-ui5.esm.js +1 -0
  153. package/dist/fenix-ui5.esm.js.map +1 -1
  154. package/dist/index.d.ts +2 -0
  155. package/dist/index.d.ts.map +1 -1
  156. package/dist/index.js +18 -1
  157. package/dist/index.js.map +1 -1
  158. package/dist/plugins/auto-import.d.ts.map +1 -1
  159. package/dist/plugins/auto-import.js +1 -0
  160. package/dist/plugins/auto-import.js.map +1 -1
  161. package/package.json +5 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.js","sources":["../../../src/components/editor/editor.ts"],"sourcesContent":["import { FxFormElement } from '../../core/form-element';\nimport { defineElement } from '../../core/define';\nimport { esc } from '../../core/sanitize';\nimport { FENIX_ICON_BASE_CSS, fenixIconHtml } from '../../icons/base-css';\nimport { loadFenixIconsFont } from '../../icons/font';\nimport { sanitizeBody, sanitizeEmbedUrl, sanitizeLinkUrl, sanitizeMediaUrl } from './sanitize-html';\nimport { normalizeElement } from './normalize-html';\nimport { EDITOR_STYLES } from './styles';\nimport {\n closestInEditor,\n getBlock,\n getRange,\n placeCaretAtEnd,\n restoreRange,\n saveRange,\n} from './selection';\nimport {\n align,\n applyLink,\n escapeAttr,\n escapeText,\n formatBlock,\n indent,\n insertHtml,\n nativeExec,\n removeFormat,\n toggleInline,\n toggleList,\n unlink,\n} from './commands';\nimport { mergeSelectedCells, splitCell as splitTableCell } from './table-utils';\n\nexport type FxEditorToolbar = 'minimal' | 'basic' | 'standard' | 'full' | 'none';\nexport type FxEditorPasteMode = 'clean' | 'plain';\n\nexport interface FxEditorChangeDetail {\n value: string;\n html: string;\n text: string;\n}\n\nexport type FxEditorUploadResult = string | { url: string; alt?: string; width?: string };\n\ninterface DialogField {\n name: string;\n label: string;\n type?: 'text' | 'url' | 'number' | 'select';\n value?: string;\n placeholder?: string;\n options?: Array<{ value: string; label: string }>;\n}\n\ninterface DialogResult {\n [key: string]: string;\n}\n\nconst MAX_PASTE_BYTES = 1024 * 1024;\nconst MAX_IMAGE_BYTES = 8 * 1024 * 1024;\nconst LARGE_DOC_CHARS = 20_000;\nconst EMIT_DEBOUNCE_MS = 140;\nconst HISTORY_LIMIT = 50;\n\nconst QUICK_SVG = {\n left: '<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" aria-hidden=\"true\"><path d=\"M4 6h16M4 10h10M4 14h16M4 18h10\"/></svg>',\n center: '<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" aria-hidden=\"true\"><path d=\"M4 6h16M7 10h10M4 14h16M7 18h10\"/></svg>',\n right: '<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" aria-hidden=\"true\"><path d=\"M4 6h16M10 10h10M4 14h16M10 18h10\"/></svg>',\n delete: '<svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M3 6h18M8 6V4h8v2M6 6l1 15h10l1-15M10 10v7M14 10v7\"/></svg>',\n} as const;\n\n/**\n * <fx-editor> — editor de texto rico nativo.\n *\n * Form-associated: com `name` entra no FormData com o HTML sanitizado.\n * O atributo `value` é o conteúdo inicial (como o texto de um <textarea>);\n * a propriedade `value` é o conteúdo atual.\n */\nexport class FxEditor extends FxFormElement {\n static override styles = `${FENIX_ICON_BASE_CSS}\\n${EDITOR_STYLES}`;\n\n static override get observedAttributes(): string[] {\n return [\n 'toolbar', 'features', 'placeholder', 'readonly', 'disabled', 'required',\n 'full', 'error', 'invalid', 'success', 'valid', 'show-count',\n 'paste-mode', 'min-height', 'max-height', 'fullscreen', 'maxlength',\n ];\n }\n\n /** Callback opcional de upload de imagem. */\n uploadImage?: (file: File) => Promise<FxEditorUploadResult>;\n /** Hook opcional de sanitização extra (roda depois do sanitizador interno). */\n sanitizeHtml?: (html: string) => string;\n\n #built = false;\n #eventsBound = false;\n #initialized = false;\n #defaultValue = '';\n #value = '';\n #dirty = false;\n #sourceMode = false;\n #lastRange: Range | null = null;\n #rafId = 0;\n #emitTimer: ReturnType<typeof setTimeout> | null = null;\n #lastLimitError = 0;\n #snapshotTimer: ReturnType<typeof setTimeout> | null = null;\n #history: string[] = [];\n #historyIndex = -1;\n #imagePicker: HTMLInputElement | null = null;\n #mediaFigure: HTMLElement | null = null;\n #linkAnchor: HTMLAnchorElement | null = null;\n #resizeDispose: (() => void) | null = null;\n #dialogReturnFocus: HTMLElement | null = null;\n #dialogResolve: ((result: DialogResult | null) => void) | null = null;\n #disposers: Array<() => void> = [];\n #selectionRaf = 0;\n #bodyOverflow = '';\n\n get editor(): HTMLElement | null {\n return this.root.querySelector<HTMLElement>('.content');\n }\n\n get source(): HTMLTextAreaElement | null {\n return this.root.querySelector<HTMLTextAreaElement>('.source');\n }\n\n get toolbarEl(): HTMLElement | null {\n return this.root.querySelector<HTMLElement>('.toolbar');\n }\n\n get value(): string {\n if (this.#sourceMode && this.source) return this.#serialize();\n if (this.#dirty) this.#value = this.#serialize();\n return this.#value;\n }\n\n set value(next: string) {\n const clean = this.#cleanHtml(next ?? '');\n this.#value = clean;\n this.#dirty = false;\n if (!this.#defaultValue) this.#defaultValue = clean;\n this.#applyValue(clean);\n this.updateFormValue();\n }\n\n get html(): string { return this.value; }\n set html(next: string) { this.value = next; }\n\n get text(): string {\n return (this.editor?.textContent ?? '').replace(/\\u200b/g, '').trim();\n }\n\n get defaultValue(): string { return this.#defaultValue; }\n set defaultValue(next: string) {\n this.#defaultValue = this.#cleanHtml(next ?? '');\n if (!this.#dirty) this.value = this.#defaultValue;\n }\n\n get disabled(): boolean { return this.hasAttr('disabled'); }\n set disabled(value: boolean) { this.toggleAttr('disabled', Boolean(value)); }\n\n get readonly(): boolean { return this.hasAttr('readonly'); }\n set readonly(value: boolean) { this.toggleAttr('readonly', Boolean(value)); }\n\n get required(): boolean { return this.hasAttr('required'); }\n set required(value: boolean) { this.toggleAttr('required', Boolean(value)); }\n\n get placeholder(): string { return this.getAttr('placeholder'); }\n set placeholder(value: string) { this.setAttribute('placeholder', value); }\n\n get toolbar(): FxEditorToolbar {\n const value = this.getAttr('toolbar', 'standard') as FxEditorToolbar;\n return ['minimal', 'basic', 'standard', 'full', 'none'].includes(value) ? value : 'standard';\n }\n set toolbar(value: FxEditorToolbar) { this.setAttribute('toolbar', value); }\n\n get pasteMode(): FxEditorPasteMode {\n return this.getAttr('paste-mode', 'clean') === 'plain' ? 'plain' : 'clean';\n }\n set pasteMode(value: FxEditorPasteMode) { this.setAttribute('paste-mode', value); }\n\n get fullscreen(): boolean { return this.hasAttr('fullscreen'); }\n set fullscreen(value: boolean) { this.toggleAttr('fullscreen', Boolean(value)); }\n\n /** Limite de caracteres de texto (0 desativa). Padrão: 30.000. */\n get maxlength(): number {\n const value = Number.parseInt(this.getAttr('maxlength', '30000'), 10);\n return Number.isFinite(value) && value > 0 ? value : 0;\n }\n set maxlength(value: number) {\n if (Number.isFinite(value) && value >= 0) this.setAttribute('maxlength', String(Math.floor(value)));\n else this.removeAttribute('maxlength');\n }\n\n protected override connectedCallback(): void {\n loadFenixIconsFont();\n super.connectedCallback();\n if (this.fullscreen) this.#syncBodyOverflow();\n\n if (!this.#initialized) {\n this.#initialized = true;\n const initial = this.#value || this.getAttr('value') || this.innerHTML;\n this.replaceChildren();\n this.#defaultValue = this.#cleanHtml(initial);\n this.#value = this.#defaultValue;\n this.#applyValue(this.#defaultValue);\n this.updateFormValue();\n this.#pushHistory(this.#value);\n this.dispatchEvent(new CustomEvent('ready', { bubbles: true, composed: true }));\n } else if (this.#built && !this.#eventsBound) {\n this.#bindEvents();\n this.#eventsBound = true;\n }\n\n this.#bindGlobalSelection();\n }\n\n protected override disconnectedCallback(): void {\n for (const dispose of this.#disposers) dispose();\n this.#disposers = [];\n this.#eventsBound = false;\n cancelAnimationFrame(this.#rafId);\n cancelAnimationFrame(this.#selectionRaf);\n if (this.#emitTimer) clearTimeout(this.#emitTimer);\n if (this.#snapshotTimer) clearTimeout(this.#snapshotTimer);\n this.#endResize();\n this.#hideMediaOverlay();\n this.#hideLinkOverlay();\n if (this.hasAttr('fullscreen')) document.body.style.overflow = this.#bodyOverflow;\n this.#releaseDialog(null);\n super.disconnectedCallback();\n }\n\n protected override attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue || !this.#built) return;\n if (name === 'toolbar' || name === 'features') this.#renderToolbar();\n if (name === 'fullscreen') this.#syncBodyOverflow();\n this.#syncChrome();\n }\n\n override formResetCallback(): void {\n this.#dirty = false;\n this.value = this.#defaultValue;\n }\n\n protected override getFormValue(): string | FormData | null {\n return this.hasAttr('disabled') ? null : this.value;\n }\n\n protected override render(): void {\n if (this.#built) return;\n\n this.setTemplate(`\n <div class=\"editor\" part=\"editor\">\n <div class=\"toolbar\" part=\"toolbar\" role=\"toolbar\" aria-label=\"Formatação\" aria-orientation=\"horizontal\"></div>\n <div class=\"body\">\n <div class=\"content\" part=\"content\" contenteditable=\"true\" role=\"textbox\"\n aria-multiline=\"true\" spellcheck=\"true\"></div>\n <textarea class=\"source\" part=\"source\" spellcheck=\"false\" hidden aria-label=\"HTML do conteúdo\"></textarea>\n <div class=\"media-overlay\" part=\"media-overlay\" hidden>\n <span class=\"media-handle nw\" data-handle=\"nw\"></span>\n <span class=\"media-handle ne\" data-handle=\"ne\"></span>\n <span class=\"media-handle sw\" data-handle=\"sw\"></span>\n <span class=\"media-handle se\" data-handle=\"se\"></span>\n <span class=\"media-size\"></span>\n <button type=\"button\" class=\"media-delete\" data-media-action=\"delete\" aria-label=\"Excluir mídia\" title=\"Excluir mídia\">${fenixIconHtml('delete')}</button>\n </div>\n <div class=\"link-overlay\" part=\"link-overlay\" hidden>\n <button type=\"button\" data-link-action=\"open\">Abrir</button>\n <button type=\"button\" data-link-action=\"edit\">Editar</button>\n <button type=\"button\" data-link-action=\"remove\">Remover</button>\n </div>\n </div>\n <div class=\"statusbar\" part=\"statusbar\">\n <span class=\"count\"></span>\n <span class=\"source-actions\" hidden>\n <button type=\"button\" class=\"btn source-apply\">Aplicar</button>\n <button type=\"button\" class=\"btn source-cancel\">Cancelar</button>\n </span>\n <slot name=\"footer\"></slot>\n </div>\n <input type=\"file\" class=\"image-picker\" accept=\"image/*\" hidden>\n <div class=\"backdrop\" part=\"dialog\" hidden>\n <div class=\"dialog\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"fx-editor-dialog-title\">\n <header>\n <h3 id=\"fx-editor-dialog-title\"></h3>\n <button type=\"button\" class=\"dialog-close\" aria-label=\"Fechar\">×</button>\n </header>\n <div class=\"dialog-body\"></div>\n <footer>\n <button type=\"button\" class=\"btn dialog-cancel\">Cancelar</button>\n <button type=\"button\" class=\"btn dialog-ok\">Aplicar</button>\n </footer>\n </div>\n </div>\n </div>\n `);\n\n this.#built = true;\n this.#imagePicker = this.root.querySelector<HTMLInputElement>('.image-picker');\n this.#bindEvents();\n this.#eventsBound = true;\n this.#renderToolbar();\n this.#syncChrome();\n }\n\n #on(\n target: EventTarget,\n type: string,\n handler: (event: Event) => void,\n options?: AddEventListenerOptions,\n ): void {\n target.addEventListener(type, handler, options);\n this.#disposers.push(() => target.removeEventListener(type, handler, options));\n }\n\n #bindEvents(): void {\n const editor = this.editor;\n const toolbar = this.toolbarEl;\n if (!editor || !toolbar) return;\n\n this.#on(toolbar, 'mousedown', (event) => {\n const target = event.target as HTMLElement;\n this.#lastRange = saveRange(editor) ?? this.#lastRange;\n this.#hideLinkOverlay();\n if (target.closest('button')) event.preventDefault();\n });\n\n this.#on(toolbar, 'click', (event) => {\n const target = (event.target as HTMLElement).closest<HTMLElement>('[data-cmd],[data-action]');\n if (!target || (target as HTMLButtonElement).disabled) return;\n const cmd = target.dataset.cmd;\n const action = target.dataset.action;\n if (cmd) this.#execCommand(cmd);\n else if (action) this.#action(action);\n });\n\n this.#on(toolbar, 'change', (event) => {\n const select = (event.target as HTMLElement).closest<HTMLSelectElement>('[data-block]');\n if (!select) return;\n this.#restoreSelection();\n formatBlock(editor, select.value || 'p');\n this.#afterCommand();\n });\n\n this.#on(toolbar, 'input', (event) => {\n const input = (event.target as HTMLElement).closest<HTMLInputElement>('[data-color]');\n if (!input) return;\n this.#restoreSelection();\n nativeExec('styleWithCSS', 'true');\n nativeExec(input.dataset.color ?? 'foreColor', input.value);\n this.#afterCommand();\n });\n\n this.#on(toolbar, 'keydown', (event) => this.#handleToolbarKeydown(event as KeyboardEvent));\n this.#on(toolbar, 'focusin', (event) => {\n const button = (event.target as HTMLElement).closest<HTMLElement>('.tb-btn');\n if (button) this.#moveToolbarTabStop(button);\n });\n\n this.#on(editor, 'input', (event) => {\n event.stopPropagation();\n this.#hideLinkOverlay();\n this.#dirty = true;\n this.#updateEmpty();\n this.#scheduleEmit();\n this.#scheduleSnapshot();\n });\n\n this.#on(editor, 'focus', () => {\n this.dispatchEvent(new CustomEvent('focus', { bubbles: true, composed: true }));\n });\n\n this.#on(editor, 'blur', () => {\n this.#lastRange = saveRange(editor) ?? this.#lastRange;\n this.#emitNow();\n this.#emitChange();\n this.dispatchEvent(new CustomEvent('blur', { bubbles: true, composed: true }));\n });\n\n this.#on(editor, 'keydown', (event) => this.#handleKeydown(event as KeyboardEvent));\n this.#on(editor, 'beforeinput', (event) => this.#handleBeforeInput(event as InputEvent));\n this.#on(editor, 'paste', (event) => this.#handlePaste(event as ClipboardEvent));\n this.#on(editor, 'dragover', (event) => event.preventDefault());\n this.#on(editor, 'drop', (event) => this.#handleDrop(event as DragEvent));\n this.#on(editor, 'dblclick', (event) => this.#handleDoubleClick(event as MouseEvent));\n this.#on(editor, 'click', (event) => this.#handleEditorClick(event as MouseEvent));\n this.#on(editor, 'scroll', () => { this.#positionMediaOverlay(); this.#positionLinkOverlay(); }, { passive: true });\n this.#on(window, 'resize', () => { this.#positionMediaOverlay(); this.#positionLinkOverlay(); });\n\n const overlay = this.root.querySelector<HTMLElement>('.media-overlay');\n if (overlay) {\n this.#on(overlay, 'pointerdown', (event) => this.#startResize(event as PointerEvent));\n this.#on(overlay, 'click', (event) => {\n const action = (event.target as HTMLElement).closest<HTMLElement>('[data-media-action]');\n if (action?.dataset.mediaAction === 'delete') this.#deleteMediaFigure();\n });\n }\n\n const linkOverlay = this.root.querySelector<HTMLElement>('.link-overlay');\n if (linkOverlay) {\n this.#on(linkOverlay, 'click', (event) => this.#handleLinkOverlayClick(event as MouseEvent));\n }\n\n if (this.source) {\n this.#on(this.source, 'input', () => {\n this.#dirty = true;\n this.#scheduleEmit();\n });\n }\n\n if (this.#imagePicker) {\n this.#on(this.#imagePicker, 'change', () => {\n const file = this.#imagePicker?.files?.[0];\n if (file) void this.#handleImageFile(file);\n if (this.#imagePicker) this.#imagePicker.value = '';\n });\n }\n\n const backdrop = this.root.querySelector<HTMLElement>('.backdrop');\n if (backdrop) {\n this.#on(backdrop, 'click', (event) => {\n if (event.target === backdrop) this.#releaseDialog(null);\n });\n this.#on(backdrop, 'keydown', (event) => this.#trapDialogFocus(event as KeyboardEvent));\n }\n\n const dialogBody = this.root.querySelector<HTMLElement>('.dialog-body');\n if (dialogBody) {\n this.#on(dialogBody, 'keydown', (event) => {\n const target = event.target as HTMLElement;\n if ((event as KeyboardEvent).key === 'Enter' && target.tagName !== 'BUTTON') {\n event.preventDefault();\n this.#submitDialog();\n }\n });\n }\n\n for (const selector of ['.dialog-close', '.dialog-cancel']) {\n const btn = this.root.querySelector<HTMLButtonElement>(selector);\n if (btn) this.#on(btn, 'click', () => this.#releaseDialog(null));\n }\n\n const ok = this.root.querySelector<HTMLButtonElement>('.dialog-ok');\n if (ok) this.#on(ok, 'click', () => this.#submitDialog());\n\n const applySource = this.root.querySelector<HTMLButtonElement>('.source-apply');\n if (applySource) this.#on(applySource, 'click', () => this.#applySource());\n\n const cancelSource = this.root.querySelector<HTMLButtonElement>('.source-cancel');\n if (cancelSource) this.#on(cancelSource, 'click', () => this.#cancelSource());\n }\n\n #syncChrome(): void {\n const editor = this.editor;\n if (!editor) return;\n\n const locked = this.disabled || this.readonly;\n editor.setAttribute('contenteditable', locked ? 'false' : 'true');\n editor.setAttribute('aria-readonly', String(this.readonly));\n editor.setAttribute('aria-disabled', String(this.disabled));\n\n if (this.placeholder) editor.setAttribute('data-placeholder', this.placeholder);\n else editor.removeAttribute('data-placeholder');\n\n const toolbar = this.toolbarEl;\n toolbar?.toggleAttribute('hidden', this.toolbar === 'none' || this.readonly);\n\n for (const control of Array.from(this.root.querySelectorAll<HTMLButtonElement | HTMLInputElement | HTMLSelectElement>(\n '.tb-btn, .tb-select, .tb-color input',\n ))) {\n const isSourceToggle = control.closest('[data-action=\"source\"]') !== null;\n const isFullscreenToggle = control.closest('[data-action=\"fullscreen\"]') !== null;\n control.disabled = this.readonly || this.disabled || (this.#sourceMode && !isSourceToggle && !isFullscreenToggle);\n }\n\n this.#applyCssVars();\n this.#updateEmpty();\n this.#updateCount();\n this.#validate();\n this.#updateSourceUi();\n const fullscreenButton = this.root.querySelector<HTMLElement>('[data-action=\"fullscreen\"]');\n fullscreenButton?.classList.toggle('active', this.fullscreen);\n fullscreenButton?.setAttribute('aria-pressed', String(this.fullscreen));\n if (locked || this.#sourceMode) this.#hideMediaOverlay();\n }\n\n #applyCssVars(): void {\n const min = this.getAttr('min-height');\n const max = this.getAttr('max-height');\n if (min) this.style.setProperty('--fx-editor-min-height', min);\n else this.style.removeProperty('--fx-editor-min-height');\n if (max) this.style.setProperty('--fx-editor-max-height', max);\n else this.style.removeProperty('--fx-editor-max-height');\n }\n\n #updateEmpty(): void {\n const editor = this.editor;\n if (!editor) return;\n const empty = !editor.textContent?.trim() && !editor.querySelector('img,video,iframe,table,hr');\n editor.classList.toggle('is-empty', empty);\n }\n\n #updateCount(): void {\n const count = this.root.querySelector<HTMLElement>('.count');\n if (!count) return;\n const statusbar = this.root.querySelector<HTMLElement>('.statusbar');\n const hasFooter = this.querySelector('[slot=\"footer\"]') !== null;\n if (statusbar) statusbar.hidden = !this.#sourceMode && !this.hasAttr('show-count') && !hasFooter;\n if (!this.hasAttr('show-count')) {\n count.textContent = '';\n return;\n }\n const text = this.text;\n const words = text ? text.split(/\\s+/).filter(Boolean).length : 0;\n count.textContent = `${words} palavra${words === 1 ? '' : 's'} · ${text.length} caractere${text.length === 1 ? '' : 's'}`;\n }\n\n #fits(extra: number): boolean {\n const max = this.maxlength;\n if (!max) return true;\n const editor = this.editor;\n const range = editor ? getRange(editor, this.#lastRange) : null;\n const selected = range && !range.collapsed ? range.toString().length : 0;\n return this.text.length - selected + extra <= max;\n }\n\n #limitError(): void {\n const now = Date.now();\n if (now - this.#lastLimitError < 1200) return;\n this.#lastLimitError = now;\n this.#error(`Limite de ${this.maxlength.toLocaleString('pt-BR')} caracteres atingido.`);\n }\n\n #validate(): void {\n if (!this.internals || typeof this.internals.setValidity !== 'function') return;\n try {\n if (this.required && !this.text) {\n this.internals.setValidity(\n { valueMissing: true },\n 'Preencha este campo.',\n this.editor ?? undefined,\n );\n } else {\n this.internals.setValidity({});\n }\n } catch {\n /* ambientes sem validação nativa (jsdom) */\n }\n }\n\n /** Sanitiza + normaliza em uma única parseada do HTML. */\n #cleanHtml(html: string, forEditor = false): string {\n const body = sanitizeBody(html);\n if (!body) return forEditor ? '<p><br></p>' : '';\n return normalizeElement(body, { forEditor });\n }\n\n #serialize(): string {\n if (this.#sourceMode && this.source) {\n return this.#cleanHtml(this.source.value);\n }\n const editor = this.editor;\n if (!editor) return '';\n if (!editor.textContent?.trim() && !editor.querySelector('img,video,iframe,table,hr')) return '';\n let clean = this.#cleanHtml(editor.innerHTML);\n if (this.sanitizeHtml) {\n clean = this.#cleanHtml(this.sanitizeHtml(clean));\n }\n return clean;\n }\n\n #applyValue(html: string): void {\n const editor = this.editor;\n if (!editor) return;\n this.#hideMediaOverlay();\n const normalized = this.#cleanHtml(html, true);\n if (editor.innerHTML !== normalized) editor.innerHTML = normalized;\n this.#hideLinkOverlay();\n this.#hideMediaOverlay();\n this.#decorateMediaFigures();\n this.#updateEmpty();\n this.#updateCount();\n }\n\n #scheduleEmit(): void {\n cancelAnimationFrame(this.#rafId);\n if (this.#emitTimer) {\n clearTimeout(this.#emitTimer);\n this.#emitTimer = null;\n }\n const size = this.editor?.textContent?.length ?? 0;\n if (size < LARGE_DOC_CHARS) {\n this.#rafId = requestAnimationFrame(() => this.#emitNow());\n return;\n }\n // Documentos grandes: evita serializar a cada frame enquanto o usuário digita.\n this.#emitTimer = setTimeout(() => {\n this.#emitTimer = null;\n this.#emitNow();\n }, EMIT_DEBOUNCE_MS);\n }\n\n #emitNow(): void {\n cancelAnimationFrame(this.#rafId);\n if (this.#emitTimer) {\n clearTimeout(this.#emitTimer);\n this.#emitTimer = null;\n }\n const value = this.#serialize();\n this.#value = value;\n this.#dirty = false;\n const detail: FxEditorChangeDetail = { value, html: value, text: this.text };\n for (const type of ['input', 'valueChange']) {\n this.dispatchEvent(new CustomEvent(type, { bubbles: true, composed: true, detail }));\n }\n this.#updateCount();\n this.#validate();\n }\n\n #emitChange(): void {\n const value = this.value;\n const detail: FxEditorChangeDetail = { value, html: value, text: this.text };\n this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail }));\n }\n\n #pushHistory(html: string): void {\n if (this.#history[this.#historyIndex] === html) return;\n this.#history = this.#history.slice(0, this.#historyIndex + 1);\n this.#history.push(html);\n if (this.#history.length > HISTORY_LIMIT) this.#history.shift();\n this.#historyIndex = this.#history.length - 1;\n }\n\n #scheduleSnapshot(): void {\n if (this.#snapshotTimer) clearTimeout(this.#snapshotTimer);\n this.#snapshotTimer = setTimeout(() => {\n this.#pushHistory(this.#dirty ? this.#serialize() : this.#value);\n }, 600);\n }\n\n #historyUndo(): void {\n if (this.#historyIndex <= 0) return;\n this.#historyIndex--;\n this.#applyValue(this.#history[this.#historyIndex]);\n if (this.editor) placeCaretAtEnd(this.editor);\n this.#afterCommand();\n }\n\n #historyRedo(): void {\n if (this.#historyIndex >= this.#history.length - 1) return;\n this.#historyIndex++;\n this.#applyValue(this.#history[this.#historyIndex]);\n if (this.editor) placeCaretAtEnd(this.editor);\n this.#afterCommand();\n }\n\n #bindGlobalSelection(): void {\n const handler = (): void => {\n const editor = this.editor;\n if (!editor) return;\n const range = getRange(editor, this.#lastRange);\n if (!range) return;\n this.#lastRange = range.cloneRange();\n cancelAnimationFrame(this.#selectionRaf);\n this.#selectionRaf = requestAnimationFrame(() => this.#updateToolbar());\n };\n document.addEventListener('selectionchange', handler);\n this.#disposers.push(() => document.removeEventListener('selectionchange', handler));\n }\n\n #restoreSelection(): void {\n const editor = this.editor;\n if (!editor) return;\n if (this.#lastRange) restoreRange(editor, this.#lastRange);\n else editor.focus({ preventScroll: true });\n }\n\n #syncBodyOverflow(): void {\n if (this.fullscreen) {\n this.#bodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n } else {\n document.body.style.overflow = this.#bodyOverflow;\n }\n }\n\n #updateSourceUi(): void {\n const source = this.source;\n const content = this.editor;\n const actions = this.root.querySelector<HTMLElement>('.source-actions');\n if (actions) actions.toggleAttribute('hidden', !this.#sourceMode);\n if (source) source.hidden = !this.#sourceMode;\n if (content) content.hidden = this.#sourceMode;\n const toggle = this.root.querySelector<HTMLElement>('[data-action=\"source\"]');\n toggle?.classList.toggle('active', this.#sourceMode);\n toggle?.setAttribute('aria-pressed', String(this.#sourceMode));\n }\n\n #releaseDialog(result: DialogResult | null): void {\n const backdrop = this.root.querySelector<HTMLElement>('.backdrop');\n backdrop?.setAttribute('hidden', '');\n const resolve = this.#dialogResolve;\n this.#dialogResolve = null;\n const returnFocus = this.#dialogReturnFocus;\n this.#dialogReturnFocus = null;\n resolve?.(result);\n if (returnFocus && returnFocus.isConnected) returnFocus.focus({ preventScroll: true });\n else this.#restoreSelection();\n }\n\n #renderToolbar(): void {\n const toolbar = this.toolbarEl;\n if (!toolbar) return;\n\n const preset = this.toolbar;\n if (preset === 'none') {\n toolbar.innerHTML = '';\n toolbar.hidden = true;\n return;\n }\n toolbar.hidden = false;\n\n const features = new Set(\n this.getAttr('features').split(',').map((item) => item.trim()).filter(Boolean),\n );\n const has = (feature: string): boolean => features.size === 0 || features.has(feature);\n\n const button = (cmd: string, icon: string, label: string, action = ''): string =>\n `<button type=\"button\" class=\"tb-btn\" tabindex=\"-1\" ${action ? `data-action=\"${action}\"` : `data-cmd=\"${cmd}\"`} title=\"${label}\" aria-label=\"${label}\" aria-pressed=\"false\">${fenixIconHtml(icon)}</button>`;\n\n const select = `<select class=\"tb-select\" data-block aria-label=\"Formato do bloco\">\n <option value=\"p\">Parágrafo</option>\n <option value=\"h1\">Título 1</option>\n <option value=\"h2\">Título 2</option>\n <option value=\"h3\">Título 3</option>\n <option value=\"h4\">Título 4</option>\n <option value=\"blockquote\">Citação</option>\n <option value=\"pre\">Código</option>\n </select>`;\n\n const history = button('undo', 'undo', 'Desfazer') + button('redo', 'redo', 'Refazer');\n const inline = [\n button('bold', 'format_bold', 'Negrito'),\n button('italic', 'format_italic', 'Itálico'),\n button('underline', 'format_underlined', 'Sublinhado'),\n button('strikeThrough', 'format_strikethrough', 'Riscado'),\n button('code', 'code', 'Código inline'),\n button('removeFormat', 'format_clear', 'Limpar formatação'),\n ].join('');\n const color = [\n `<label class=\"tb-color\" title=\"Cor do texto\"><input type=\"color\" data-color=\"foreColor\" value=\"#111827\" aria-label=\"Cor do texto\"></label>`,\n `<label class=\"tb-color\" title=\"Realçar texto\"><input type=\"color\" data-color=\"hiliteColor\" value=\"#fef08a\" aria-label=\"Realçar texto\"></label>`,\n ].join('');\n const alignGroup = [\n button('justifyLeft', 'format_align_left', 'Alinhar à esquerda'),\n button('justifyCenter', 'format_align_center', 'Centralizar'),\n button('justifyRight', 'format_align_right', 'Alinhar à direita'),\n button('justifyFull', 'format_align_justify', 'Justificar'),\n ].join('');\n const indentation = [\n button('outdent', 'format_indent_decrease', 'Diminuir recuo', 'outdent'),\n button('indent', 'format_indent_increase', 'Aumentar recuo', 'indent'),\n ].join('');\n const lists = [\n button('insertUnorderedList', 'format_list_bulleted', 'Lista com marcadores'),\n button('insertOrderedList', 'format_list_numbered', 'Lista numerada'),\n ].join('');\n const blocks = button('', 'format_quote', 'Citação', 'blockquote') + button('', 'code_blocks', 'Bloco de código', 'codeblock');\n\n const insert: string[] = [];\n if (has('link')) {\n insert.push(button('', 'link', 'Link (Ctrl+K)', 'link'));\n insert.push(button('', 'link_off', 'Remover link', 'unlink'));\n }\n if (preset !== 'minimal') {\n if (has('image')) insert.push(button('', 'image', 'Imagem', 'image'));\n if (has('video')) insert.push(button('', 'videocam', 'Vídeo', 'video'));\n if (has('table')) insert.push(button('', 'table', 'Tabela', 'table'));\n if (has('columns')) insert.push(button('', 'view_column', 'Colunas', 'columns'));\n insert.push(button('insertHorizontalRule', 'horizontal_rule', 'Linha horizontal'));\n }\n\n const tools: string[] = [];\n if (preset === 'standard' || preset === 'full') {\n if (has('source')) tools.push(button('', 'code', 'Ver HTML', 'source'));\n if (has('fullscreen')) tools.push(button('', 'fullscreen', 'Tela cheia', 'fullscreen'));\n }\n\n const groups: string[] = [history, select + inline];\n if (preset !== 'minimal') groups.push(lists);\n if (preset !== 'minimal' && preset !== 'basic') {\n groups.push(color, alignGroup, indentation, blocks);\n }\n if (insert.length) groups.push(insert.join(''));\n if (tools.length) groups.push(tools.join(''));\n\n toolbar.innerHTML =\n groups.map((group) => `<div class=\"tb-group\">${group}</div>`).join('') +\n `<div class=\"panel\" data-panel hidden></div>`;\n toolbar.querySelector<HTMLElement>('.tb-btn')?.setAttribute('tabindex', '0');\n }\n\n #updateToolbar(): void {\n const editor = this.editor;\n if (!editor) return;\n const range = getRange(editor, this.#lastRange);\n if (!range) return;\n\n const setActive = (cmd: string, active: boolean): void => {\n const button = this.root.querySelector<HTMLButtonElement>(`[data-cmd=\"${cmd}\"]`);\n if (!button) return;\n button.classList.toggle('active', active);\n button.setAttribute('aria-pressed', String(active));\n };\n\n const ancestor = (selector: string): boolean => {\n const node = range.startContainer;\n const el = node.nodeType === Node.ELEMENT_NODE ? (node as Element) : node.parentElement;\n const match = el?.closest(selector);\n return Boolean(match && editor.contains(match));\n };\n\n setActive('bold', ancestor('strong,b'));\n setActive('italic', ancestor('em,i'));\n setActive('underline', ancestor('u'));\n setActive('strikeThrough', ancestor('s,del,strike'));\n setActive('code', ancestor('code'));\n setActive('insertUnorderedList', ancestor('ul'));\n setActive('insertOrderedList', ancestor('ol'));\n\n const block = getBlock(editor, range);\n const blockTag = block?.tagName.toLowerCase() ?? 'p';\n const blockSelect = this.root.querySelector<HTMLSelectElement>('[data-block]');\n if (blockSelect) {\n const value = Array.from(blockSelect.options).some((option) => option.value === blockTag)\n ? blockTag\n : 'p';\n blockSelect.value = value;\n }\n\n const alignment = block ? (block.style.textAlign || 'left') : 'left';\n setActive('justifyLeft', alignment === 'left' || alignment === 'start' || alignment === '');\n setActive('justifyCenter', alignment === 'center');\n setActive('justifyRight', alignment === 'right' || alignment === 'end');\n setActive('justifyFull', alignment === 'justify');\n }\n\n #handleToolbarKeydown(event: KeyboardEvent): void {\n const active = this.root.activeElement as HTMLElement | null;\n if (!active || !active.classList.contains('tb-btn')) return;\n if (!['ArrowRight', 'ArrowLeft', 'Home', 'End'].includes(event.key)) return;\n\n const controls = Array.from(\n this.toolbarEl?.querySelectorAll<HTMLElement>(\n '.tb-btn:not(:disabled), .tb-select:not(:disabled), .tb-color input:not(:disabled)',\n ) ?? [],\n );\n if (!controls.length) return;\n\n event.preventDefault();\n let index = controls.indexOf(active);\n if (event.key === 'Home') index = 0;\n else if (event.key === 'End') index = controls.length - 1;\n else index = (index + (event.key === 'ArrowRight' ? 1 : -1) + controls.length) % controls.length;\n\n const next = controls[index];\n if (!next) return;\n this.#moveToolbarTabStop(next);\n next.focus();\n }\n\n #moveToolbarTabStop(active: HTMLElement): void {\n this.toolbarEl?.querySelectorAll<HTMLElement>('.tb-btn').forEach((button) => {\n button.setAttribute('tabindex', button === active ? '0' : '-1');\n });\n }\n\n #trapDialogFocus(event: KeyboardEvent): void {\n if (!this.#dialogResolve || event.key !== 'Tab') return;\n const dialog = this.root.querySelector<HTMLElement>('.dialog');\n if (!dialog) return;\n\n const focusables = Array.from(\n dialog.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), a[href], [tabindex]:not([tabindex=\"-1\"])',\n ),\n );\n if (!focusables.length) return;\n\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n const active = this.root.activeElement;\n\n if (event.shiftKey && (active === first || !active || !dialog.contains(active))) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && (active === last || !active || !dialog.contains(active))) {\n event.preventDefault();\n first.focus();\n }\n }\n\n #execCommand(cmd: string): void {\n const editor = this.editor;\n if (!editor) return;\n this.#restoreSelection();\n\n switch (cmd) {\n case 'undo':\n if (!nativeExec('undo')) this.#historyUndo();\n break;\n case 'redo':\n if (!nativeExec('redo')) this.#historyRedo();\n break;\n case 'bold':\n toggleInline(editor, 'strong');\n break;\n case 'italic':\n toggleInline(editor, 'em');\n break;\n case 'underline':\n toggleInline(editor, 'u');\n break;\n case 'strikeThrough':\n toggleInline(editor, 's');\n break;\n case 'code':\n toggleInline(editor, 'code');\n break;\n case 'justifyLeft':\n align(editor, 'left');\n break;\n case 'justifyCenter':\n align(editor, 'center');\n break;\n case 'justifyRight':\n align(editor, 'right');\n break;\n case 'justifyFull':\n align(editor, 'justify');\n break;\n case 'insertUnorderedList':\n toggleList(editor, false);\n break;\n case 'insertOrderedList':\n toggleList(editor, true);\n break;\n case 'removeFormat':\n removeFormat(editor);\n break;\n case 'insertHorizontalRule':\n insertHtml(editor, '<hr><p><br></p>');\n break;\n case 'foreColor':\n case 'hiliteColor':\n nativeExec('styleWithCSS', 'true');\n nativeExec(cmd, this.root.querySelector<HTMLInputElement>(`[data-color=\"${cmd}\"]`)?.value);\n break;\n default:\n nativeExec(cmd);\n }\n\n this.#afterCommand();\n }\n\n #afterCommand(): void {\n this.#dirty = true;\n this.#hideLinkOverlay();\n this.#decorateMediaFigures();\n this.#updateEmpty();\n this.#scheduleEmit();\n this.#scheduleSnapshot();\n this.#updateToolbar();\n }\n\n #action(action: string): void {\n const editor = this.editor;\n if (!editor) return;\n\n switch (action) {\n case 'link':\n void this.#openLinkDialog();\n break;\n case 'image':\n void this.#openImageDialog();\n break;\n case 'video':\n void this.#openVideoDialog();\n break;\n case 'table':\n this.#showTablePanel();\n break;\n case 'columns':\n this.#showColumnsPanel();\n break;\n case 'source':\n this.#toggleSource();\n break;\n case 'fullscreen':\n this.fullscreen = !this.fullscreen;\n break;\n case 'blockquote':\n this.#restoreSelection();\n formatBlock(editor, 'blockquote');\n this.#afterCommand();\n break;\n case 'codeblock':\n this.#restoreSelection();\n formatBlock(editor, 'pre');\n this.#afterCommand();\n break;\n case 'indent':\n this.#restoreSelection();\n indent(editor, 24);\n this.#afterCommand();\n break;\n case 'outdent':\n this.#restoreSelection();\n indent(editor, -24);\n this.#afterCommand();\n break;\n case 'clear':\n this.#restoreSelection();\n removeFormat(editor);\n this.#afterCommand();\n break;\n case 'unlink':\n this.#restoreSelection();\n unlink(editor);\n this.#afterCommand();\n break;\n }\n }\n\n #handleKeydown(event: KeyboardEvent): void {\n if (event.isComposing) return;\n\n const active = this.root.activeElement;\n const overlay = this.root.querySelector<HTMLElement>('.media-overlay');\n if (\n this.#mediaFigure &&\n (event.key === 'Delete' || event.key === 'Backspace') &&\n (active === this.#mediaFigure ||\n this.#mediaFigure.contains(active) ||\n Boolean(overlay && active && overlay.contains(active)))\n ) {\n event.preventDefault();\n this.#deleteMediaFigure();\n return;\n }\n\n const mod = event.ctrlKey || event.metaKey;\n const key = event.key.toLowerCase();\n\n if (mod && !event.altKey) {\n if (key === 'b') { event.preventDefault(); this.#execCommand('bold'); return; }\n if (key === 'i') { event.preventDefault(); this.#execCommand('italic'); return; }\n if (key === 'u') { event.preventDefault(); this.#execCommand('underline'); return; }\n if (key === 'k') { event.preventDefault(); void this.#openLinkDialog(); return; }\n if (key === 'z' && !event.shiftKey) { event.preventDefault(); this.#execCommand('undo'); return; }\n if (key === 'y' || (key === 'z' && event.shiftKey)) { event.preventDefault(); this.#execCommand('redo'); return; }\n }\n\n if (event.key === 'Escape') {\n if (this.#dialogResolve) this.#releaseDialog(null);\n else if (this.#sourceMode) this.#cancelSource();\n else if (this.fullscreen) this.fullscreen = false;\n else if (this.#linkAnchor) this.#hideLinkOverlay();\n else if (this.#mediaFigure) this.#hideMediaOverlay();\n else this.#hidePanel();\n return;\n }\n\n if (event.key === 'Tab' && this.#tabInTable(event.shiftKey)) {\n event.preventDefault();\n }\n }\n\n #tabInTable(backwards: boolean): boolean {\n const editor = this.editor;\n if (!editor) return false;\n const range = getRange(editor, this.#lastRange);\n if (!range) return false;\n const cell = closestInEditor<HTMLTableCellElement>(editor, range.startContainer, 'td,th');\n const table = cell?.closest('table');\n if (!cell || !table) return false;\n\n const cells = Array.from(table.querySelectorAll<HTMLTableCellElement>('td,th'));\n let index = cells.indexOf(cell);\n if (index < 0) return false;\n\n if (backwards) {\n index = Math.max(0, index - 1);\n } else {\n index++;\n if (index >= cells.length) {\n const row = cell.parentElement as HTMLTableRowElement | null;\n if (!row) return false;\n const clone = row.cloneNode(true) as HTMLTableRowElement;\n for (const cloned of Array.from(clone.querySelectorAll<HTMLTableCellElement>('td,th'))) {\n cloned.innerHTML = '<p><br></p>';\n }\n row.after(clone);\n cells.push(...Array.from(clone.querySelectorAll<HTMLTableCellElement>('td,th')));\n index = cells.indexOf(clone.querySelector<HTMLTableCellElement>('td,th')!);\n }\n }\n\n const target = cells[index];\n if (!target) return false;\n const next = document.createRange();\n next.selectNodeContents(target);\n next.collapse(true);\n const selection = document.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(next);\n return true;\n }\n\n #handleBeforeInput(event: InputEvent): void {\n if (this.disabled || this.readonly || !this.maxlength) return;\n const type = event.inputType;\n if (\n type === 'insertFromPaste' ||\n type === 'insertFromDrop' ||\n type.startsWith('history') ||\n type.startsWith('format')\n ) {\n return;\n }\n const extra = event.data?.length ?? (type === 'insertParagraph' || type === 'insertLineBreak' ? 1 : 0);\n if (!extra) return;\n if (!this.#fits(extra)) {\n event.preventDefault();\n this.#limitError();\n }\n }\n\n #handlePaste(event: ClipboardEvent): void {\n const clipboard = event.clipboardData;\n if (!clipboard) return;\n\n const file = Array.from(clipboard.files ?? []).find((item) => item.type.startsWith('image/'));\n if (file) {\n event.preventDefault();\n void this.#handleImageFile(file);\n return;\n }\n\n const html = clipboard.getData('text/html');\n const text = clipboard.getData('text/plain');\n if (html.length > MAX_PASTE_BYTES || text.length > MAX_PASTE_BYTES) return;\n\n event.preventDefault();\n if (!this.#fits(text.length)) {\n this.#limitError();\n return;\n }\n if (this.pasteMode === 'plain' || !html) {\n this.#insertPlainText(text);\n return;\n }\n\n const clean = this.#cleanHtml(html);\n if (!clean) {\n this.#insertPlainText(text);\n return;\n }\n\n this.#restoreSelection();\n insertHtml(this.editor!, clean);\n this.#afterCommand();\n }\n\n #handleDrop(event: DragEvent): void {\n const transfer = event.dataTransfer;\n if (!transfer) return;\n event.preventDefault();\n\n const file = Array.from(transfer.files ?? []).find((item) => item.type.startsWith('image/'));\n if (file) {\n void this.#handleImageFile(file);\n return;\n }\n\n const html = transfer.getData('text/html');\n const text = transfer.getData('text/plain');\n if (!this.#fits(text.length)) {\n this.#limitError();\n return;\n }\n if (html) {\n insertHtml(this.editor!, this.#cleanHtml(html));\n this.#afterCommand();\n } else if (text) {\n this.#insertPlainText(text);\n }\n }\n\n #insertPlainText(text: string): void {\n const paragraphs = text\n .replace(/\\r\\n/g, '\\n')\n .split(/\\n{2,}/)\n .map((block) => `<p>${escapeText(block).replace(/\\n/g, '<br>')}</p>`)\n .join('');\n insertHtml(this.editor!, paragraphs || '<p><br></p>');\n this.#afterCommand();\n }\n\n #toggleSource(): void {\n if (this.#sourceMode) {\n this.#applySource();\n return;\n }\n const source = this.source;\n if (!source) return;\n source.value = this.#serialize();\n this.#sourceMode = true;\n this.#syncChrome();\n source.focus();\n }\n\n #applySource(): void {\n const source = this.source;\n if (!source) return;\n const clean = this.#cleanHtml(source.value);\n this.#sourceMode = false;\n this.#value = clean;\n this.#dirty = false;\n this.#applyValue(clean);\n this.#syncChrome();\n this.updateFormValue();\n this.#emitChange();\n this.#afterCommand();\n }\n\n #cancelSource(): void {\n this.#sourceMode = false;\n this.#applyValue(this.#value);\n this.#syncChrome();\n }\n\n #openDialog(title: string, fields: DialogField[]): Promise<DialogResult | null> {\n const backdrop = this.root.querySelector<HTMLElement>('.backdrop');\n const titleEl = this.root.querySelector<HTMLElement>('.dialog h3');\n const body = this.root.querySelector<HTMLElement>('.dialog-body');\n if (!backdrop || !titleEl || !body) return Promise.resolve(null);\n\n titleEl.textContent = title;\n body.innerHTML = fields.map((field) => this.#fieldHtml(field)).join('');\n this.#dialogReturnFocus = (this.root.activeElement as HTMLElement | null) ?? this.editor;\n backdrop.removeAttribute('hidden');\n\n const first = body.querySelector<HTMLInputElement | HTMLSelectElement>('input,select');\n first?.focus();\n\n return new Promise((resolve) => {\n this.#dialogResolve = resolve;\n });\n }\n\n #fieldHtml(field: DialogField): string {\n const label = esc(field.label);\n if (field.type === 'select') {\n const options = (field.options ?? [])\n .map((option) => `<option value=\"${esc(option.value)}\" ${option.value === field.value ? 'selected' : ''}>${esc(option.label)}</option>`)\n .join('');\n return `<label class=\"field\"><span>${label}</span><select data-field=\"${esc(field.name)}\">${options}</select></label>`;\n }\n const type = field.type === 'url' ? 'url' : field.type === 'number' ? 'number' : 'text';\n return `<label class=\"field\"><span>${label}</span><input data-field=\"${esc(field.name)}\" type=\"${type}\" value=\"${esc(field.value ?? '')}\" placeholder=\"${esc(field.placeholder ?? '')}\"></label>`;\n }\n\n #submitDialog(): void {\n const body = this.root.querySelector<HTMLElement>('.dialog-body');\n if (!body) return;\n const result: DialogResult = {};\n for (const field of Array.from(body.querySelectorAll<HTMLInputElement | HTMLSelectElement>('[data-field]'))) {\n result[field.dataset.field ?? ''] = field.value.trim();\n }\n this.#releaseDialog(result);\n }\n\n async #openLinkDialog(existing?: HTMLAnchorElement): Promise<void> {\n this.#hideLinkOverlay();\n const editor = this.editor;\n if (!editor) return;\n if (existing) this.#selectAnchor(existing);\n let range = getRange(editor, this.#lastRange);\n if (!range) {\n placeCaretAtEnd(editor);\n range = getRange(editor);\n this.#lastRange = range?.cloneRange() ?? null;\n }\n const anchor = existing ?? closestInEditor<HTMLAnchorElement>(editor, range?.startContainer ?? null, 'a');\n const selected = range && !range.collapsed ? range.toString() : (anchor?.textContent ?? '');\n\n const result = await this.#openDialog('Link', [\n { name: 'url', label: 'URL', type: 'url', value: anchor?.getAttribute('href') ?? '', placeholder: 'https://...' },\n { name: 'text', label: 'Texto (quando não há seleção)', value: selected, placeholder: 'Texto do link' },\n {\n name: 'target',\n label: 'Abrir em',\n type: 'select',\n value: anchor?.getAttribute('target') ?? '_blank',\n options: [\n { value: '_blank', label: 'Nova aba' },\n { value: '_self', label: 'Mesma aba' },\n ],\n },\n ]);\n if (!result) return;\n\n const href = sanitizeLinkUrl(result.url ?? '');\n if (!href) {\n this.#error('URL de link inválida.');\n return;\n }\n\n const target = result.target === '_self' ? '_self' : '_blank';\n const label = (result.text ?? '').trim() || (anchor ? undefined : selected || href);\n if (anchor) {\n anchor.setAttribute('href', href);\n anchor.setAttribute('target', target);\n anchor.setAttribute('rel', 'noopener noreferrer');\n if (label) anchor.textContent = label;\n this.#afterCommand();\n this.#restoreSelection();\n return;\n }\n\n this.#restoreSelection();\n applyLink(editor, href, label ?? (selected || href), target);\n this.#afterCommand();\n }\n\n async #openImageDialog(existing?: HTMLImageElement): Promise<void> {\n this.#hideMediaOverlay();\n const figure = existing?.closest('figure');\n const caption = figure?.querySelector('figcaption')?.textContent ?? '';\n const alignValue = figure?.getAttribute('data-align') ?? 'center';\n const widthValue = figure?.style.width?.replace('%', '') || '100';\n\n const dialog = this.#openDialog(existing ? 'Editar imagem' : 'Inserir imagem', [\n { name: 'src', label: 'URL da imagem', type: 'url', value: existing?.getAttribute('src') ?? '', placeholder: 'https://...' },\n { name: 'alt', label: 'Texto alternativo', value: existing?.getAttribute('alt') ?? '' },\n { name: 'caption', label: 'Legenda', value: caption },\n {\n name: 'width',\n label: 'Largura',\n type: 'select',\n value: widthValue,\n options: [\n { value: '25', label: '25%' },\n { value: '50', label: '50%' },\n { value: '75', label: '75%' },\n { value: '100', label: '100%' },\n ],\n },\n {\n name: 'align',\n label: 'Alinhamento',\n type: 'select',\n value: alignValue,\n options: [\n { value: 'left', label: 'Esquerda' },\n { value: 'center', label: 'Centro' },\n { value: 'right', label: 'Direita' },\n ],\n },\n ]);\n\n const body = this.root.querySelector<HTMLElement>('.dialog-body');\n if (body) {\n const upload = document.createElement('button');\n upload.type = 'button';\n upload.className = 'btn';\n upload.textContent = 'Escolher arquivo…';\n upload.addEventListener('click', () => {\n this.#releaseDialog(null);\n this.#imagePicker?.click();\n });\n body.appendChild(upload);\n }\n\n const result = await dialog;\n if (!result) return;\n const src = sanitizeMediaUrl(result.src ?? '', 'img');\n if (!src) {\n this.#error('URL de imagem inválida.');\n return;\n }\n\n if (existing && figure) {\n existing.setAttribute('src', src);\n existing.setAttribute('alt', result.alt ?? '');\n figure.setAttribute('data-align', result.align || 'center');\n figure.style.width = `${result.width || 100}%`;\n const cap = figure.querySelector('figcaption');\n if (result.caption) {\n if (cap) cap.textContent = result.caption;\n else figure.insertAdjacentHTML('beforeend', `<figcaption>${escapeText(result.caption)}</figcaption>`);\n } else {\n cap?.remove();\n }\n this.#afterCommand();\n return;\n }\n\n this.#restoreSelection();\n this.#insertImage(src, result.alt ?? '', result.caption ?? '', result.width || '100', result.align || 'center');\n }\n\n #toEmbedUrl(value: string): string {\n try {\n const url = new URL(value);\n const host = url.hostname.replace(/^www\\./, '');\n if (host === 'youtu.be') {\n return `https://www.youtube-nocookie.com/embed/${url.pathname.slice(1)}`;\n }\n if (host === 'youtube.com' || host === 'm.youtube.com') {\n const id = url.searchParams.get('v');\n if (id) return `https://www.youtube-nocookie.com/embed/${id}`;\n if (url.pathname.startsWith('/shorts/')) {\n return `https://www.youtube-nocookie.com/embed/${url.pathname.split('/')[2] ?? ''}`;\n }\n }\n if (host === 'vimeo.com') {\n const id = url.pathname.split('/').filter(Boolean)[0];\n if (id) return `https://player.vimeo.com/video/${id}`;\n }\n return value;\n } catch {\n return value;\n }\n }\n\n async #openVideoDialog(): Promise<void> {\n const result = await this.#openDialog('Inserir vídeo', [\n { name: 'src', label: 'URL do vídeo ou embed', type: 'url', placeholder: 'https://.../video.mp4 ou YouTube/Vimeo' },\n { name: 'caption', label: 'Legenda', value: '' },\n {\n name: 'width',\n label: 'Largura',\n type: 'select',\n value: '100',\n options: [\n { value: '50', label: '50%' },\n { value: '75', label: '75%' },\n { value: '100', label: '100%' },\n ],\n },\n {\n name: 'align',\n label: 'Alinhamento',\n type: 'select',\n value: 'center',\n options: [\n { value: 'left', label: 'Esquerda' },\n { value: 'center', label: 'Centro' },\n { value: 'right', label: 'Direita' },\n ],\n },\n ]);\n if (!result) return;\n\n const src = result.src ?? '';\n const embed = sanitizeEmbedUrl(this.#toEmbedUrl(src));\n if (embed) {\n this.#restoreSelection();\n this.#insertEmbed(embed, result.caption ?? '', result.width || '100', result.align || 'center');\n return;\n }\n\n const media = sanitizeMediaUrl(src, 'video');\n if (!media) {\n this.#error('URL de vídeo inválida.');\n return;\n }\n\n this.#restoreSelection();\n this.#insertVideo(media, result.caption ?? '', result.width || '100', result.align || 'center');\n }\n\n #decorateMediaFigures(): void {\n const editor = this.editor;\n if (!editor || this.#sourceMode) return;\n\n for (const figure of Array.from(\n editor.querySelectorAll<HTMLElement>('figure.fx-image, figure.fx-video, figure.fx-embed'),\n )) {\n if (figure.querySelector(':scope > .fx-media-quick')) {\n this.#syncQuickActions(figure);\n continue;\n }\n\n for (const kind of ['left', 'center', 'right', 'delete'] as const) {\n const label =\n kind === 'delete'\n ? 'Excluir mídia'\n : kind === 'left'\n ? 'Alinhar à esquerda'\n : kind === 'center'\n ? 'Centralizar'\n : 'Alinhar à direita';\n const button = document.createElement('button');\n button.type = 'button';\n button.className = `fx-media-quick quick-${kind}`;\n button.title = label;\n button.setAttribute('aria-label', label);\n if (kind === 'delete') button.dataset.mediaDelete = '';\n else button.dataset.mediaAlign = kind;\n button.innerHTML = QUICK_SVG[kind];\n button.addEventListener('click', (event) => {\n event.preventDefault();\n event.stopPropagation();\n if (kind === 'delete') {\n figure.remove();\n this.#hideMediaOverlay();\n this.#afterCommand();\n } else {\n figure.setAttribute('data-align', kind);\n this.#syncQuickActions(figure);\n this.#afterCommand();\n }\n });\n figure.appendChild(button);\n }\n\n this.#syncQuickActions(figure);\n }\n }\n\n #syncQuickActions(figure: HTMLElement): void {\n const align = figure.getAttribute('data-align') || 'center';\n for (const button of Array.from(\n figure.querySelectorAll<HTMLElement>(':scope > .fx-media-quick[data-media-align]'),\n )) {\n button.classList.toggle('active', button.dataset.mediaAlign === align);\n }\n }\n\n #selectAnchor(anchor: HTMLAnchorElement): void {\n const editor = this.editor;\n if (!editor) return;\n editor.focus({ preventScroll: true });\n const range = document.createRange();\n range.selectNodeContents(anchor);\n const selection = document.getSelection();\n if (!selection) return;\n selection.removeAllRanges();\n selection.addRange(range);\n this.#lastRange = range.cloneRange();\n }\n\n #handleLinkOverlayClick(event: MouseEvent): void {\n const action = (event.target as HTMLElement).closest<HTMLElement>('[data-link-action]');\n const anchor = this.#linkAnchor;\n if (!action || !anchor) return;\n event.preventDefault();\n event.stopPropagation();\n const kind = action.dataset.linkAction;\n if (kind === 'open') this.#openLink(anchor);\n else if (kind === 'edit') void this.#openLinkDialog(anchor);\n else if (kind === 'remove') this.#removeLink(anchor);\n }\n\n #openLink(anchor: HTMLAnchorElement): void {\n const href = anchor.getAttribute('href') ?? '';\n if (!href) return;\n this.#hideLinkOverlay();\n const target = anchor.getAttribute('target') === '_self' ? '_self' : '_blank';\n window.open(href, target, target === '_blank' ? 'noopener,noreferrer' : undefined);\n }\n\n #removeLink(anchor: HTMLAnchorElement): void {\n const parent = anchor.parentNode;\n if (!parent) return;\n while (anchor.firstChild) parent.insertBefore(anchor.firstChild, anchor);\n anchor.remove();\n this.#hideLinkOverlay();\n this.#afterCommand();\n this.editor?.focus({ preventScroll: true });\n }\n\n #showLinkOverlay(anchor: HTMLAnchorElement): void {\n this.#linkAnchor = anchor;\n const overlay = this.root.querySelector<HTMLElement>('.link-overlay');\n if (!overlay) return;\n const target = anchor.getAttribute('target') === '_self' ? 'mesma janela' : 'nova aba';\n const open = overlay.querySelector<HTMLElement>('[data-link-action=\"open\"]');\n if (open) open.title = `Abrir na ${target}`;\n overlay.hidden = false;\n this.#positionLinkOverlay();\n }\n\n #hideLinkOverlay(): void {\n this.#linkAnchor = null;\n const overlay = this.root.querySelector<HTMLElement>('.link-overlay');\n if (overlay) overlay.hidden = true;\n }\n\n #positionLinkOverlay(): void {\n const overlay = this.root.querySelector<HTMLElement>('.link-overlay');\n const anchor = this.#linkAnchor;\n const editor = this.editor;\n if (!overlay) return;\n if (!anchor || !editor || this.#sourceMode || !anchor.isConnected || !editor.contains(anchor)) {\n overlay.hidden = true;\n return;\n }\n\n const body = overlay.parentElement;\n if (!body) return;\n const bodyRect = body.getBoundingClientRect();\n const rect = anchor.getBoundingClientRect();\n if (!rect.width || !rect.height || rect.bottom < bodyRect.top || rect.top > bodyRect.bottom) {\n overlay.hidden = true;\n return;\n }\n\n overlay.hidden = false;\n const width = overlay.offsetWidth || 180;\n const height = overlay.offsetHeight || 30;\n const left = Math.max(4, Math.min(rect.left - bodyRect.left, bodyRect.width - width - 4));\n let top = rect.bottom - bodyRect.top + 6;\n if (top + height > bodyRect.height) top = rect.top - bodyRect.top - height - 6;\n overlay.style.left = `${left}px`;\n overlay.style.top = `${Math.max(4, top)}px`;\n }\n\n #handleEditorClick(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n const anchor = target.closest<HTMLAnchorElement>('a[href]');\n if (anchor && this.editor?.contains(anchor)) {\n this.#hideMediaOverlay();\n this.#showLinkOverlay(anchor);\n if (event.ctrlKey || event.metaKey) {\n event.preventDefault();\n this.#openLink(anchor);\n }\n return;\n }\n\n this.#hideLinkOverlay();\n const figure = target.closest<HTMLElement>('figure.fx-image, figure.fx-video, figure.fx-embed');\n if (figure) this.#showMediaOverlay(figure);\n else this.#hideMediaOverlay();\n }\n\n #showMediaOverlay(figure: HTMLElement): void {\n this.#mediaFigure = figure;\n figure.setAttribute('tabindex', '0');\n if (figure.classList.contains('fx-image')) figure.focus({ preventScroll: true });\n const overlay = this.root.querySelector<HTMLElement>('.media-overlay');\n if (!overlay) return;\n overlay.hidden = false;\n this.#positionMediaOverlay();\n }\n\n #hideMediaOverlay(): void {\n this.#mediaFigure?.removeAttribute('tabindex');\n this.#mediaFigure = null;\n const overlay = this.root.querySelector<HTMLElement>('.media-overlay');\n if (!overlay) return;\n overlay.hidden = true;\n const size = overlay.querySelector<HTMLElement>('.media-size');\n if (size) size.textContent = '';\n }\n\n #deleteMediaFigure(): void {\n const figure = this.#mediaFigure;\n if (!figure) return;\n figure.remove();\n this.#hideMediaOverlay();\n this.#afterCommand();\n this.editor?.focus({ preventScroll: true });\n }\n\n #positionMediaOverlay(): void {\n const overlay = this.root.querySelector<HTMLElement>('.media-overlay');\n const figure = this.#mediaFigure;\n const editor = this.editor;\n if (!overlay) return;\n if (!figure || !editor || this.#sourceMode || !figure.isConnected || !editor.contains(figure)) {\n overlay.hidden = true;\n return;\n }\n\n const body = overlay.parentElement;\n if (!body) return;\n const bodyRect = body.getBoundingClientRect();\n const rect = figure.getBoundingClientRect();\n if (!rect.width || !rect.height || rect.bottom < bodyRect.top || rect.top > bodyRect.bottom) {\n overlay.hidden = true;\n return;\n }\n\n overlay.hidden = false;\n overlay.style.left = `${rect.left - bodyRect.left}px`;\n overlay.style.top = `${rect.top - bodyRect.top}px`;\n overlay.style.width = `${rect.width}px`;\n overlay.style.height = `${rect.height}px`;\n\n const size = overlay.querySelector<HTMLElement>('.media-size');\n if (size) size.textContent = `${Math.round(rect.width)} × ${Math.round(rect.height)}`;\n }\n\n #startResize(event: PointerEvent): void {\n const handle = (event.target as HTMLElement).closest<HTMLElement>('[data-handle]');\n const figure = this.#mediaFigure;\n const editor = this.editor;\n if (!handle || !figure || !editor) return;\n\n event.preventDefault();\n event.stopPropagation();\n this.#endResize();\n\n const parent = figure.parentElement;\n if (!parent) return;\n const parentWidth = parent.getBoundingClientRect().width || editor.clientWidth;\n if (!parentWidth) return;\n\n const rect = figure.getBoundingClientRect();\n const startWidth = rect.width\n ? (rect.width / parentWidth) * 100\n : Number.parseFloat(figure.style.width) || 100;\n const startX = event.clientX;\n const direction = handle.dataset.handle?.includes('w') ? -1 : 1;\n\n const move = (moveEvent: PointerEvent): void => {\n const deltaPct = ((moveEvent.clientX - startX) * direction * 100) / parentWidth;\n const width = Math.min(100, Math.max(15, startWidth + deltaPct));\n figure.style.width = `${width.toFixed(1).replace(/\\.0$/, '')}%`;\n this.#positionMediaOverlay();\n };\n\n const up = (): void => {\n this.#endResize();\n this.#afterCommand();\n this.#positionMediaOverlay();\n };\n\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up, { once: true });\n window.addEventListener('pointercancel', up, { once: true });\n this.#resizeDispose = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n window.removeEventListener('pointercancel', up);\n };\n }\n\n #endResize(): void {\n this.#resizeDispose?.();\n this.#resizeDispose = null;\n }\n\n #handleDoubleClick(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n const image = target.closest<HTMLImageElement>('img');\n if (image) {\n event.preventDefault();\n void this.#openImageDialog(image);\n }\n }\n\n #insertImage(src: string, alt: string, caption: string, width: string, align: string): void {\n const html =\n `<figure class=\"fx-image\" contenteditable=\"false\" data-align=\"${escapeAttr(align)}\" style=\"width:${escapeAttr(width)}%\">` +\n `<img src=\"${escapeAttr(src)}\" alt=\"${escapeAttr(alt)}\" loading=\"lazy\" decoding=\"async\">` +\n `${caption ? `<figcaption>${escapeText(caption)}</figcaption>` : ''}` +\n `</figure><p><br></p>`;\n insertHtml(this.editor!, html);\n this.#afterCommand();\n }\n\n #insertVideo(src: string, caption: string, width: string, align = 'center'): void {\n const html =\n `<figure class=\"fx-video\" contenteditable=\"false\" data-align=\"${escapeAttr(align)}\" style=\"width:${escapeAttr(width)}%\">` +\n `<video controls preload=\"metadata\" src=\"${escapeAttr(src)}\" style=\"width:100%\"></video>` +\n `${caption ? `<figcaption>${escapeText(caption)}</figcaption>` : ''}` +\n `</figure><p><br></p>`;\n insertHtml(this.editor!, html);\n this.#afterCommand();\n }\n\n #insertEmbed(src: string, caption: string, width: string, align = 'center'): void {\n const html =\n `<figure class=\"fx-embed\" contenteditable=\"false\" data-align=\"${escapeAttr(align)}\" style=\"width:${escapeAttr(width)}%\">` +\n `<iframe src=\"${escapeAttr(src)}\" title=\"${escapeAttr(caption || 'Vídeo')}\" loading=\"lazy\" allowfullscreen ` +\n `sandbox=\"allow-scripts allow-same-origin allow-presentation\" referrerpolicy=\"strict-origin-when-cross-origin\" ` +\n `style=\"width:100%;aspect-ratio:16/9;border:0\"></iframe>` +\n `${caption ? `<figcaption>${escapeText(caption)}</figcaption>` : ''}` +\n `</figure><p><br></p>`;\n insertHtml(this.editor!, html);\n this.#afterCommand();\n }\n\n #insertTable(rows: number, cols: number): void {\n const rowCount = Math.min(20, Math.max(1, rows));\n const colCount = Math.min(12, Math.max(1, cols));\n const width = (100 / colCount).toFixed(4).replace(/\\.?0+$/, '');\n const colsHtml = `<colgroup>${Array.from({ length: colCount }, () => `<col style=\"width:${width}%\">`).join('')}</colgroup>`;\n const head = `<thead><tr>${Array.from({ length: colCount }, () => '<th scope=\"col\"><p><br></p></th>').join('')}</tr></thead>`;\n const bodyRows = Math.max(0, rowCount - 1);\n const body = bodyRows\n ? `<tbody>${Array.from({ length: bodyRows }, () =>\n `<tr>${Array.from({ length: colCount }, () => '<td><p><br></p></td>').join('')}</tr>`,\n ).join('')}</tbody>`\n : '';\n\n const html =\n `<figure class=\"fx-table\"><table>${colsHtml}${head}${body}</table></figure><p><br></p>`;\n insertHtml(this.editor!, html);\n this.#afterCommand();\n }\n\n #insertColumns(cols: number): void {\n const count = Math.min(4, Math.max(1, cols));\n const width = (100 / count).toFixed(4).replace(/\\.?0+$/, '');\n const cells = Array.from(\n { length: count },\n () => `<td style=\"width:${width}%;vertical-align:top;padding:8px\"><p><br></p></td>`,\n ).join('');\n const html =\n `<table class=\"fx-grid\" role=\"presentation\" data-cols=\"${count}\" data-stack=\"sm\" ` +\n `style=\"width:100%;border-collapse:collapse\"><tbody><tr>${cells}</tr></tbody></table><p><br></p>`;\n insertHtml(this.editor!, html);\n this.#afterCommand();\n }\n\n #showTablePanel(): void {\n const panel = this.root.querySelector<HTMLElement>('[data-panel]');\n if (!panel) return;\n const table = this.#currentTable();\n\n const grid = Array.from({ length: 64 }, (_, index) => {\n const rows = Math.floor(index / 8) + 1;\n const cols = (index % 8) + 1;\n return `<button type=\"button\" data-grid=\"${rows},${cols}\" aria-label=\"${rows} por ${cols}\"></button>`;\n }).join('');\n\n panel.innerHTML =\n `<p class=\"panel-title\">Inserir tabela</p><div class=\"grid-picker\">${grid}</div>` +\n (table\n ? `<p class=\"panel-title\" style=\"margin-top:8px\">Tabela atual</p><div class=\"panel-actions\">` +\n `<button type=\"button\" class=\"btn\" data-table-action=\"add-row\">+ Linha</button>` +\n `<button type=\"button\" class=\"btn\" data-table-action=\"add-col\">+ Coluna</button>` +\n `<button type=\"button\" class=\"btn\" data-table-action=\"del-row\">− Linha</button>` +\n `<button type=\"button\" class=\"btn\" data-table-action=\"del-col\">− Coluna</button>` +\n `<button type=\"button\" class=\"btn\" data-table-action=\"toggle-header\">Cabeçalho</button>` +\n `<button type=\"button\" class=\"btn\" data-table-action=\"merge-cells\">Mesclar</button>` +\n `<button type=\"button\" class=\"btn\" data-table-action=\"split-cell\">Dividir</button>` +\n `<button type=\"button\" class=\"btn\" data-table-action=\"del-table\">Excluir tabela</button>` +\n `</div>`\n : '');\n panel.removeAttribute('hidden');\n\n panel.querySelectorAll<HTMLButtonElement>('[data-grid]').forEach((button) => {\n button.addEventListener('click', () => {\n const [rows, cols] = (button.dataset.grid ?? '').split(',').map(Number);\n this.#hidePanel();\n this.#insertTable(rows, cols);\n });\n });\n panel.querySelectorAll<HTMLButtonElement>('[data-table-action]').forEach((button) => {\n button.addEventListener('click', () => {\n this.#tableAction(button.dataset.tableAction ?? '');\n this.#hidePanel();\n });\n });\n }\n\n #showColumnsPanel(): void {\n const panel = this.root.querySelector<HTMLElement>('[data-panel]');\n if (!panel) return;\n panel.innerHTML =\n `<p class=\"panel-title\">Inserir colunas</p><div class=\"panel-actions\">` +\n [1, 2, 3, 4]\n .map((count) => `<button type=\"button\" class=\"btn\" data-columns=\"${count}\">${count}</button>`)\n .join('') +\n `</div>`;\n panel.removeAttribute('hidden');\n panel.querySelectorAll<HTMLButtonElement>('[data-columns]').forEach((button) => {\n button.addEventListener('click', () => {\n this.#hidePanel();\n this.#insertColumns(Number(button.dataset.columns ?? 1));\n });\n });\n }\n\n #hidePanel(): void {\n this.root.querySelector<HTMLElement>('[data-panel]')?.setAttribute('hidden', '');\n }\n\n #currentTable(): HTMLTableElement | null {\n const editor = this.editor;\n if (!editor) return null;\n const range = getRange(editor, this.#lastRange);\n return closestInEditor<HTMLTableElement>(editor, range?.startContainer ?? null, 'table');\n }\n\n #tableAction(action: string): void {\n const table = this.#currentTable();\n if (!table) return;\n const editor = this.editor;\n const range = editor ? getRange(editor, this.#lastRange) : null;\n const cell = editor\n ? closestInEditor<HTMLTableCellElement>(editor, range?.startContainer ?? null, 'td,th')\n : null;\n const row = cell?.parentElement as HTMLTableRowElement | null;\n\n if (action === 'merge-cells') {\n if (!range) return;\n const merged = mergeSelectedCells(table, range);\n if (!merged) return;\n placeCaretAtEnd(merged);\n this.#afterCommand();\n return;\n }\n\n if (action === 'split-cell') {\n if (!cell) return;\n const created = splitTableCell(table, cell);\n if (!created.length) return;\n placeCaretAtEnd(cell);\n this.#afterCommand();\n return;\n }\n\n if (action === 'add-row' && row) {\n const clone = row.cloneNode(true) as HTMLTableRowElement;\n for (const cloneCell of Array.from(clone.querySelectorAll<HTMLTableCellElement>('td,th'))) {\n cloneCell.innerHTML = '<p><br></p>';\n }\n row.after(clone);\n } else if (action === 'add-col' && cell) {\n const index = Array.from(row?.children ?? []).indexOf(cell);\n for (const currentRow of Array.from(table.rows)) {\n const target = currentRow.cells[Math.max(0, index)];\n const clone = (target ?? currentRow.cells[currentRow.cells.length - 1])?.cloneNode(false) as HTMLTableCellElement | undefined;\n if (!clone) continue;\n clone.innerHTML = '<p><br></p>';\n currentRow.insertBefore(clone, target?.nextSibling ?? null);\n }\n } else if (action === 'del-row' && row && table.rows.length > 1) {\n row.remove();\n } else if (action === 'del-col' && cell && table.rows[0]?.cells.length > 1) {\n const index = Array.from(row?.children ?? []).indexOf(cell);\n for (const currentRow of Array.from(table.rows)) {\n currentRow.cells[index]?.remove();\n }\n } else if (action === 'toggle-header') {\n const thead = table.tHead;\n if (thead && thead.rows.length) {\n const headerRow = thead.rows[0];\n for (const headerCell of Array.from(headerRow.cells)) {\n const td = document.createElement('td');\n td.innerHTML = headerCell.innerHTML;\n headerCell.replaceWith(td);\n }\n const tbody = table.tBodies[0] ?? table.createTBody();\n tbody.insertBefore(headerRow, tbody.firstChild);\n thead.remove();\n } else {\n const firstRow = table.rows[0];\n if (firstRow) {\n for (const firstCell of Array.from(firstRow.cells)) {\n const th = document.createElement('th');\n th.setAttribute('scope', 'col');\n th.innerHTML = firstCell.innerHTML;\n firstCell.replaceWith(th);\n }\n table.createTHead().appendChild(firstRow);\n }\n }\n } else if (action === 'del-table') {\n const figure = table.closest('figure.fx-table');\n (figure ?? table).remove();\n }\n\n this.#afterCommand();\n }\n\n async #handleImageFile(file: File): Promise<void> {\n if (!file.type.startsWith('image/')) {\n this.#error('O arquivo selecionado não é uma imagem.');\n return;\n }\n if (file.type === 'image/svg+xml') {\n this.#error('SVG não é permitido por segurança. Use PNG, JPEG, WebP ou GIF.');\n return;\n }\n if (file.size > MAX_IMAGE_BYTES) {\n this.#error('Imagem muito grande (máximo 8 MB).');\n return;\n }\n\n let src = '';\n let alt = file.name.replace(/\\.[a-z0-9]+$/i, '');\n\n try {\n if (this.uploadImage) {\n const uploaded = await this.uploadImage(file);\n if (typeof uploaded === 'string') src = uploaded;\n else {\n src = uploaded.url;\n if (uploaded.alt) alt = uploaded.alt;\n }\n } else {\n src = await this.#fileToDataUrl(file);\n }\n } catch {\n this.#error('Não foi possível processar a imagem.');\n return;\n }\n\n if (!src || !sanitizeMediaUrl(src, 'img')) {\n this.#error('A imagem resultante não tem uma URL segura.');\n return;\n }\n\n this.#restoreSelection();\n this.#insertImage(src, alt, '', '100', 'center');\n }\n\n async #fileToDataUrl(file: File): Promise<string> {\n const dataUrl = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(String(reader.result ?? ''));\n reader.onerror = () => reject(new Error('read-error'));\n reader.readAsDataURL(file);\n });\n\n if (file.type === 'image/gif') return dataUrl;\n\n return new Promise<string>((resolve) => {\n const image = new Image();\n image.onload = () => {\n const maxWidth = 1600;\n const scale = Math.min(1, maxWidth / (image.naturalWidth || maxWidth));\n if (scale >= 1) {\n resolve(dataUrl);\n return;\n }\n\n const canvas = document.createElement('canvas');\n canvas.width = Math.round((image.naturalWidth || maxWidth) * scale);\n canvas.height = Math.round((image.naturalHeight || maxWidth) * scale);\n const context = canvas.getContext('2d');\n if (!context) {\n resolve(dataUrl);\n return;\n }\n context.drawImage(image, 0, 0, canvas.width, canvas.height);\n resolve(canvas.toDataURL('image/webp', 0.85));\n };\n image.onerror = () => resolve(dataUrl);\n image.src = dataUrl;\n });\n }\n\n #error(message: string): void {\n this.dispatchEvent(\n new CustomEvent('editor-error', {\n bubbles: true,\n composed: true,\n detail: { message },\n }),\n );\n }\n\n /* ---------------------------------------------------------------------\n * API pública\n * ------------------------------------------------------------------ */\n\n override focus(options?: FocusOptions): void {\n this.editor?.focus(options ?? { preventScroll: true });\n }\n\n override blur(): void {\n this.editor?.blur();\n }\n\n execute(command: string, value?: string): void {\n if (value !== undefined) {\n this.#restoreSelection();\n nativeExec('styleWithCSS', 'true');\n nativeExec(command, value);\n this.#afterCommand();\n return;\n }\n this.#execCommand(command);\n }\n\n insertHTML(html: string): void {\n const clean = this.#cleanHtml(html);\n const probe = document.createElement('div');\n probe.innerHTML = clean;\n const extra = probe.textContent?.length ?? 0;\n if (!this.#fits(extra)) {\n this.#limitError();\n return;\n }\n this.#restoreSelection();\n insertHtml(this.editor!, clean);\n this.#afterCommand();\n }\n\n /** Mescla as células tocadas pela seleção. */\n mergeCells(): boolean {\n const table = this.#currentTable();\n const editor = this.editor;\n const range = editor ? getRange(editor, this.#lastRange) : null;\n if (!table || !range) return false;\n const merged = mergeSelectedCells(table, range);\n if (!merged) return false;\n placeCaretAtEnd(merged);\n this.#afterCommand();\n return true;\n }\n\n /** Divide a célula mesclada atual. */\n splitCell(): boolean {\n const table = this.#currentTable();\n const editor = this.editor;\n const range = editor ? getRange(editor, this.#lastRange) : null;\n const cell = editor\n ? closestInEditor<HTMLTableCellElement>(editor, range?.startContainer ?? null, 'td,th')\n : null;\n if (!table || !cell) return false;\n const created = splitTableCell(table, cell);\n if (!created.length) return false;\n placeCaretAtEnd(cell);\n this.#afterCommand();\n return true;\n }\n\n getHtml(): string {\n return this.value;\n }\n\n setHtml(html: string): void {\n this.value = html;\n }\n\n getText(): string {\n return this.text;\n }\n\n clear(): void {\n this.value = '';\n this.#dirty = false;\n this.#applyValue('');\n this.updateFormValue();\n this.#emitChange();\n this.focus();\n }\n\n undo(): void {\n this.execute('undo');\n }\n\n redo(): void {\n this.execute('redo');\n }\n\n saveSelection(): void {\n if (this.editor) this.#lastRange = saveRange(this.editor) ?? this.#lastRange;\n }\n\n restoreSelection(): void {\n this.#restoreSelection();\n }\n\n openDialog(kind: 'link' | 'image' | 'video'): void {\n if (kind === 'link') void this.#openLinkDialog();\n else if (kind === 'image') void this.#openImageDialog();\n else void this.#openVideoDialog();\n }\n\n toggleSource(): void {\n this.#toggleSource();\n }\n\n toggleFullscreen(): void {\n this.fullscreen = !this.fullscreen;\n }\n\n\n\n\n\n\n\n\n\n\n\n\n}\n\nexport function defineFxEditor(): typeof FxEditor {\n return defineElement('fx-editor', FxEditor);\n}\n"],"names":["splitTableCell","align"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { FxEditor } from './editor';
2
+ export { FxEditor };
3
+ export type { FxEditorChangeDetail, FxEditorUploadResult, } from './editor';
4
+ export { FX_EDITOR_CONTENT_CSS } from './styles';
5
+ export { sanitizeHtml, sanitizeEmbedUrl, sanitizeLinkUrl, sanitizeMediaUrl } from './sanitize-html';
6
+ export { normalizeHtml, normalizeForEditor, normalizeForStorage } from './normalize-html';
7
+ declare global {
8
+ interface HTMLElementTagNameMap {
9
+ 'fx-editor': FxEditor;
10
+ }
11
+ }
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/editor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAkB,MAAM,UAAU,CAAC;AAGpD,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,YAAY,EACV,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACpG,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAK1F,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,QAAQ,CAAC;KACvB;CACF"}
@@ -0,0 +1,7 @@
1
+ import { defineFxEditor } from "./editor.js";
2
+ import { FxEditor } from "./editor.js";
3
+ defineFxEditor();
4
+ export {
5
+ FxEditor
6
+ };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../src/components/editor/index.ts"],"sourcesContent":["import { FxEditor, defineFxEditor } from './editor';\n\n// Reexporta a classe e os tipos públicos.\nexport { FxEditor };\nexport type {\n FxEditorChangeDetail,\n FxEditorUploadResult,\n} from './editor';\nexport { FX_EDITOR_CONTENT_CSS } from './styles';\nexport { sanitizeHtml, sanitizeEmbedUrl, sanitizeLinkUrl, sanitizeMediaUrl } from './sanitize-html';\nexport { normalizeHtml, normalizeForEditor, normalizeForStorage } from './normalize-html';\n\n// Auto-registro: importar `@wrrdev/fenix-ui/editor` define <fx-editor>.\ndefineFxEditor();\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'fx-editor': FxEditor;\n }\n}\n"],"names":[],"mappings":";;AAaA,eAAA;"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Normalizador de HTML do <fx-editor>.
3
+ *
4
+ * Ele garante um contrato estável para o dado salvo:
5
+ * - apenas blocos no nível raiz (texto/inline é embrulhado em <p>);
6
+ * - tags legadas convertidas (b→strong, i→em, strike→s);
7
+ * - mídia sempre em <figure> atômico;
8
+ * - tabelas com thead/tbody e colgroup;
9
+ * - grid como layout table com role=presentation;
10
+ * - sem spans/parágrafos vazios.
11
+ */
12
+ export interface NormalizeOptions {
13
+ /** Adiciona `contenteditable="false"` nas figuras de mídia (uso no editor). */
14
+ forEditor?: boolean;
15
+ }
16
+ /**
17
+ * Normaliza um `<body>` já parseado/sanitizado e devolve o HTML final.
18
+ * Evita uma segunda parseada quando o chamador já tem o DOM em mãos.
19
+ */
20
+ export declare function normalizeElement(body: Element, options?: NormalizeOptions): string;
21
+ /**
22
+ * Canonicaliza o HTML do editor.
23
+ *
24
+ * @example
25
+ * normalizeHtml('<div>Oi <b>mundo</b></div>')
26
+ * // => '<p>Oi <strong>mundo</strong></p>'
27
+ */
28
+ export declare function normalizeHtml(html: string, options?: NormalizeOptions): string;
29
+ /** Remove atributos exclusivos do editor que não devem ir para o dado salvo. */
30
+ export declare function normalizeForStorage(html: string): string;
31
+ /** Prepara o HTML para entrar no contenteditable (figuras atômicas). */
32
+ export declare function normalizeForEditor(html: string): string;
33
+ //# sourceMappingURL=normalize-html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize-html.d.ts","sourceRoot":"","sources":["../../../src/components/editor/normalize-html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAyTD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAWtF;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CAUlF;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wEAAwE;AACxE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD"}