Escopo do Lote
Este lote implementa melhorias de navegação e visualização no Editor HTML Visual:
-
Nova seção "Fundo" no styler contendo cor de fundo, seleção de imagem (ImagePicker), repetição, tamanho e posição da imagem de fundo.
-
Botão "Deselecionar" na toolbar flutuante e comportamento alternador (toggle) de seleção ao clicar no elemento ativo.
-
Preservação de rolagem vertical (
scrollTopdo iframe) no histórico de Undo/Redo. -
Quebra de linha e prevenção de transbordo (wrapping e clamp horizontal) nos breadcrumbs (ancestrais e filhos).
-
Exibição de elemento fantasma (ghost element) seguindo o cursor no modo de inserção.
-
Destaque do contêiner alvo completo com borda tracejada amarela de 4 lados (append highlight) se nenhuma posição em linha for localizada.
-
Renderização do esqueleto HTML de widgets inseridos/editados no editor visual via endpoint AJAX dedicado.
Progresso por Slice
O lote foi quebrado nos seguintes slices funcionais:
| Slice | Escopo | Status | Validação |
|---|---|---|---|
| 1 | Seção "Fundo" no Styler: cor de fundo, ImagePicker inline, repeat, size e position (html-editor.js, html-editor-interface.js) |
complete | node --check OK |
| 2 | Botão Deselecionar e Toggle de Seleção (html-editor.js) |
complete | node --check OK |
| 3 | Scroll de Undo/Redo e Layout dos Breadcrumbs (html-editor.js) |
complete | node --check OK |
| 4 | Elemento Fantasma, Highlight de Append e Renderização de Widgets (html-editor.js, html-editor.php, html-editor-visual-controls.js) |
complete | node --check / php -l OK |
Checklist de Implementação
1. Seção "Fundo" (Background) no Styler (html-editor.js)
-
[x] Criar a seção "Fundo" no
tailwindHelperConfig(), posicionando-a imediatamente após a seção "Aparência". -
[x] Migrar o grupo
bgColor(cor de fundo) de "Aparência" para "Fundo". -
[x] Implementar controles de imagem de fundo (
bgImage) na nova seção "Fundo":-
Exibir botão "Selecionar Imagem" (com ícone
folder open) e botão "Limpar" (com íconetrashouban). -
Ao clicar em "Selecionar", disparar mensagem
html-editor-imagepick-openpara a janela pai passandohtml_editor.imagepick. -
Escutar o retorno
html-editor-imagepick-selectedno iframe. SeimagePickerTarget === 'background', definir a imagem selecionada como estilo inlinebackground-image: url('...')no elemento ativo. -
Sincronizar o estado: exibir miniatura de preview se houver imagem de fundo ativa e preencher/limpar o estado adequadamente.
-
-
[x] Adicionar grupos mutuamente exclusivos para propriedades de imagem de fundo no Tailwind:
-
Repetição da imagem:
bg-repeat,bg-no-repeat,bg-repeat-x,bg-repeat-y. -
Tamanho da imagem:
bg-auto,bg-cover,bg-contain. -
Posicionamento da imagem:
bg-center,bg-top,bg-bottom,bg-left,bg-right.
-
-
[x] Atualizar
applyHelperClass()esyncHelperButtons()para suportar e limpar os novos grupos.
2. Botão Deselecionar e Toggle de Seleção (html-editor.js)
-
[x] Adicionar o botão "Deselecionar" na barra flutuante
#html-editor-floating-toolbar.-
Classe:
.he-tb-deselect. -
Ícone: Fomantic UI
times circleouban. -
Estilo visual diferenciado (ex: cor vermelha leve, ou borda destacada para indicar cancelamento).
-
Listener: ao clicar, chamar
clearSelection().
-
-
[x] Modificar o listener global de clique no iframe. Se o clique for disparado sobre o elemento atualmente selecionado (
el === this.selectedElement), deselecioná-lo chamandoclearSelection(). -
[x] Garantir que o teclado
Esccontinue chamandoclearSelection()normalmente.
3. Scroll de Undo/Redo e Layout dos Breadcrumbs (html-editor.js)
-
[x] Atualizar a estrutura de snapshots em
undoStackeredoStack. Armazenar objetos no formato{ html: string, scrollTop: number }. -
[x] No
pushUndo(), capturar oscrollTopatual do iframe e inseri-lo no snapshot. -
[x] No
undo()eredo(), após aplicar o HTML do estado viaapplyState(), restaurar a posição do scroll do viewport (window.scrollTo). -
[x] Atualizar CSS de
#html-editor-selection-breadcrumbe#html-editor-selection-childreneminjectStyles()para suportar quebra de linha (display: flex; flex-wrap: wrap; white-space: normal;). -
[x] Em
updateSelectionUI(), calcular se o breadcrumb transborda o limite direito da janela (left + offsetWidth > window.innerWidth). Caso positivo, ajustar a posiçãoleft(clamp horizontal) para manter todo o breadcrumb dentro do viewport.
4. Elemento Fantasma, Highlight de Append e Renderização de Widgets
-
[x] Ghost Element: No
enterInsertMode(), instanciar o elemento fantasmainsertGhost(uma réplica visual com opacidade0.6e borda tracejada roxa/cinza,pointer-events: none).-
No
onInsertMove(), atualizar as coordenadastop/leftdoinsertGhostcom offset (ex: 15px) em relação ao cursor. -
No
exitInsertMode(), destruir oinsertGhostdo DOM.
-
-
[x] Highlight de Append: No DnD/modo de inserção, se não for identificada uma posição física em linha (antes/depois), mas for selecionado um contêiner pai, exibir o overlay
#html-editor-parent-highlight-overlay(borda amarela tracejada de 4 lados) circundando o contêiner alvo completo. -
[x] Renderizador de Widgets (PHP): Em
html-editor.php, registrar a opção AJAXhtml-editor-widget-render.-
Função correspondente:
html_editor_ajax_widget_render(). -
Deve incluir
gestor/bibliotecas/widgets.phpe retornar o HTML do widget viawidgets_get(['id' => $signature])burlado ($_GESTOR['ajax'] = false).
-
-
[x] JS do Widget: Ao injetar ou converter um widget no iframe, realizar chamada AJAX a
html-editor-widget-renderpara recuperar o HTML renderizado do widget e preencher.conn2flow-widget-innerdo wrapper.
Evidência de Validação (BATCH-039) — 2026-06-14
-
Validação estática:
php -l gestor/bibliotecas/html-editor.phpOK;node --checkOK emgestor/assets/interface/html-editor.js,html-editor-interface.jsehtml-editor-visual-controls.js. -
Arquivos alterados:
-
gestor/assets/interface/html-editor.js(todos os slices no iframe): -
Seção "Fundo":
bgColormigrado de "Aparência"; novos gruposbgRepeat/bgSize/bgPosition(cleanList) e controle especialbgImage(kindbgimage) com botão ImagePicker + Limpar + preview; aplicabackground-imageinline;syncBgImagePreview()norenderStyler; respostahtml-editor-imagepick-selectedtratada quandoimagePickerTarget==='background'. -
Deselecionar/Toggle: botão
.he-tb-deselect(íconetimes circle, destaque vermelho) →clearSelection(); clique no elemento já selecionado também deseleciona;Escpreservado. -
Scroll no histórico: snapshots
{html, scrollTop}(captureSnapshot/restoreScroll);undo/redorestauram a rolagem apósapplyState. -
Breadcrumbs:
display:flex; flex-wrap:wrap; white-space:normal+clampLeft()(mantém ancestrais/filhos/styler dentro da largura do iframe). -
Ghost element:
createInsertGhost/moveInsertGhost/removeInsertGhost(segue o cursor com offset 15px, opacidade 0.6, borda tracejada roxa). -
Highlight de contêiner: overlay
#html-editor-parent-highlight-overlay(amarelo tracejado 4 lados) viashowDropIndicator/insertAtTargetquando a posição éinside. -
Render de widgets:
requestWidgetRender/applyWidgetRender; o mockup original é preservado emdata-widget-mockup(usado no save), o.conn2flow-widget-innerrecebe só o preview; re-render em insert/edit/convert e após undo/redo (rerenderVisibleWidgets). -
gestor/bibliotecas/html-editor.php: rota AJAXhtml-editor-widget-render→html_editor_ajax_widget_render()(valida assinaturamodulo->func(...),gestor_incluir_biblioteca('widgets'),widgets_getem modo page-load). -
gestor/assets/interface/html-editor-visual-controls.js: ponte AJAX (c2f-he:widget-render→ AJAX →c2f-he:widget-rendered). -
gestor/assets/interface/html-editor-interface.js:sistemaSeldo save com os novos ids de overlay.
-
-
Decisão: DEC-053.
-
Pendência (operador): deploy
?️ Projects - Update => Core+ validação runtime (seção Fundo + imagem de fundo; deselecionar/toggle; scroll preservado no undo/redo; breadcrumbs quebrando linha; ghost seguindo o cursor; highlight amarelo ao soltar dentro de contêiner; esqueleto de widget renderizado no preview).