Descrição do Problema / Contexto
Após os testes e refinamentos do BATCH-078, foram levantadas 6 novas demandas de melhorias funcionais e correções para o Live Editor e para o Dashboard Site Toolbar:
-
Mapeamento de Widgets com Múltiplos Elementos Irmãos (No Elemento Pai):
-
Problema: Quando um widget renderiza múltiplos elementos irmãos (ex: uma sequência de tags
<a>que formam um menu), o sistema atualmente marca individualmente cada irmão. O primeiro irmão ganha os atributos de raiz (data-c2f-widget-root="1",data-c2f-marker, etc.). Isso faz com que a caixa tracejada e o label fiquem restritos apenas ao primeiro link, deixando o resto do menu sem destaque ou com marcações fragmentadas. -
Solução: Se o widget possui múltiplos elementos-raiz na sua expansão (ou se o contêiner pai, como
<nav>ou<ul>, encapsula essencialmente os elementos do widget), o editor deve marcar o elemento pai (liveParent, ex: o<nav>) como a raiz do widget (recebendo os atributosdata-c2f-widget-id,data-c2f-widget-root="1",data-c2f-marker,data-widget-typeedata-widget-slug). Na reconstrução (reconstructOriginal), ao detectar que o elemento marcado é o pai, o sistema substitui o seuinnerHTML(e não o elemento em si) pelo marcador original decodificado.
-
-
Substituição dos Ícones Fomantic Restantes por SVG:
-
Problema: Em
html-editor.js, ainda restam alguns ícones do Fomantic UI utilizando a tag<i class="... icon">(como o botão de abrir pastas/selecionar arquivos, etc.). Como o live editor roda na página pública do site (que não possui as fontes e estilos da Fomantic UI carregados), esses ícones não renderizam ou aparecem quebrados. -
Solução: Localizar todas as tags
<i>de ícone restantes nohtml-editor.jse substituí-las por representações correspondentes em SVG inline (comstroke="currentColor"e dimensões fixas), assegurando total independência do motor visual.
-
-
Selecionador de Imagens (Image Picker) Funcional no Modal de Edição:
-
Problema: No painel clássico do
admin-paginas, ao editar um elemento de imagem, o modal de edição oferece o botão_html-editor-imagepick-btnao lado do input de URL (element-src). Este botão abre o gerenciador de arquivos em um iframe para seleção da imagem do servidor. No live editor, o modal apenas oferece um campo de entrada de texto comum, sem botão de busca. -
Solução: Integrar o botão do selecionador de imagens ao lado do input de URL no modal de edição (
html-editor-modal). Ao ser clicado, deve exibir um modal com iframe apontando para o selecionador doadmin-arquivos, atualizando o campoelement-srccom o caminho da imagem selecionada (espelhando a funcionalidade do componentehtml-editor-modal.htmlda administração).
-
-
Modal de Edição Redimensionável com Mouse (Drag):
-
Problema: O modal
html-editor-modalpossui tamanho estático, dificultando a edição de campos de texto longos ou a visualização do conteúdo. -
Comportamento Esperado: O modal de edição deve ser redimensionável. O usuário deve ser capaz de ajustar a largura e altura da caixa arrastando o canto inferior direito (utilizando CSS
resize: both; overflow: auto;ou captura de mouse com listener de drag).
-
-
Filtro de Módulos com Autocomplete na Toolbar:
-
Problema: A listagem de módulos na toolbar do site é longa e estática.
-
Comportamento Esperado: Adicionar um campo de entrada de texto no topo do dropdown de módulos com o placeholder
"Filtre os módulos...". Ao digitar, a lista deve filtrar os itens em tempo real, ocultando os módulos cujos títulos não coincidem com o termo de busca.
-
-
Agrupamento de Módulos por Categoria/Grupo:
-
Problema: O menu de módulos da toolbar lista todos os itens em ordem alfabética plana. O painel clássico administrativo (
gestor.php, na funçãogestor_pagina_menu) agrupa os módulos por grupos correspondentes (ex: Configurações, Conteúdo, etc.). -
Comportamento Esperado: Reorganizar a estrutura e renderização do menu da toolbar para exibir os módulos agrupados por suas categorias. O nome da categoria deve figurar como cabeçalho não-clicável e com distinção visual (ex: texto em caixa alta, tamanho menor e cor atenuada). A filtragem por autocomplete (Item 5) deve ser sensível a esses grupos, ocultando cabeçalhos de grupos que fiquem vazios.
-
-
Isolamento de Widgets Duplicados/Consecutivos (Alinhamento por Cauda):
-
Problema: Ao duplicar um widget ou quando existem dois widgets idênticos consecutivos no raw HTML, a lógica do alinhador de âncoras (
mapTree) se confunde. Como ele varre o DOM vivo para a âncoraafterSiga partir do início do widget (wrapStart), ele encontra a assinatura (como uma tag<a>idêntica) dentro do próprio primeiro widget, gerando um mapeamento vazio do primeiro e agrupando indevidamente todos os elementos do primeiro e segundo widgets sob um único ID de widget. -
Solução: Implementar o alinhamento pela cauda (tail alignment). Ao resolver a âncora
afterIdxno cru, calcula-se a contagem de nós estruturais restantes dali até o fim do contêiner cru. No DOM vivo, a âncora correspondente é o nó com a mesma assinaturaafterSigque apresenta exatamente o mesmo número de nós estruturais restantes até o final do contêiner vivo.
-
-
Divisão e Restauração Independente de Backups (Página e Layout):
-
Problema: O dropdown de restauração de backups (
c2f-backups-btn) do live editor exibe apenas os backups do HTML da página (paginas.html). No entanto, o usuário também pode editar o layout da página (registro emlayouts). Se houver modificações no layout, o usuário precisa ser capaz de visualizar e restaurar versões anteriores tanto do conteúdo quanto do layout. -
Comportamento Esperado: A caixa de backups deve ser dividida em duas colunas claramente identificadas: Backups da Página (lista o histórico de backups do campo HTML da página) e Backups do Layout (lista o histórico de backups do campo HTML do layout). Ao clicar em um backup da página, apenas a página (
#c2f-page-content) é restaurada; ao clicar em um backup de layout, apenas o layout é restaurado no editor, de forma independente e antes de salvar a versão final.
-
Proposta de Alterações Detalhada
1. Mapeamento de Widgets no Elemento Pai
-
Detecção em
mapTree:-
Ao alinhar e mapear um widget, se a expansão renderizada resultar em múltiplos elementos filhos (
rootEls.length > 1), ou se o pai (liveParent) for um contêiner estrutural direto (ex:<nav>,<ul>), o editor deve definir os atributos do widget (data-c2f-widget-id,data-c2f-widget-root="1",data-c2f-marker,data-widget-type,data-widget-slug) noliveParent(o pai) ao invés do primeiro irmão.
-
-
Reconstrução em
reconstructOriginal:-
Quando o elemento com
data-c2f-widget-root="1"edata-c2f-markerfor detectado, o sistema checa se ele é um contêiner pai marcado. -
Se for o pai, em vez de substituir o elemento na árvore (com
replaceChild), o sistema decodifica o marcador e substitui oinnerHTMLdo elemento pelo marcador original, preservando a tag externa (<nav>,<ul>, etc.) intacta no HTML salvo.
-
2. Substituição de Ícones Fomantic Restantes
-
Analisar em
html-editor.jse localizar strings/templates contendo<i class="... icon">(ex:folder open,image, etc.). -
Substituir por strings de tags
<svg viewBox="0 0 24 24" ...>correspondentes.
3. Selecionador de Imagens no Modal
-
Adicionar o botão
_html-editor-imagepick-btnao lado do input de origem do elemento no modal do live editor. -
Ao clicar no botão, disparar a abertura do modal de iframe apontando para o gerenciador de arquivos do sistema (
admin-arquivos). Ao escolher o arquivo no gerenciador, capturar a mensagem/evento de seleção para preencher o inputelement-srce disparar a atualização de preview da imagem.
4. Redimensionamento do Modal
-
Adicionar estilo CSS de
resize: both; overflow: auto;ao contêiner#html-editor-modal(ou implementar handlers de evento de mouse down/move/up no canto do modal para ajustarwidth/heightvia Javascript) e certificar-se de que os campos internos se adaptam fluidamente ao novo tamanho da caixa.
5 e 6. Agrupamento e Filtro no Menu da Toolbar
-
Backend (
dashboard.php/dashboard_site_toolbar):-
Estruturar os módulos recuperados em formato aninhado (agrupados por grupo/categoria), reusando a lógica de
gestor_pagina_menudegestor.php.
-
-
Frontend (
dashboard-site-toolbar.html/dashboard.iframe-toolbar.js):-
Renderizar o menu com títulos de grupos e subitens.
-
Inserir o campo de texto
<input id="c2f-modules-filter" placeholder="Filtre os módulos...">no topo do menu. -
Implementar no JS o listener de teclado (
input/keyup) que varre as opções.c2f-menu-item, realizando busca case-insensitive e ocultando os cabeçalhos de grupos.c2f-group-headercaso nenhum item daquele grupo esteja visível.
-
7. Alinhamento de Âncoras por Cauda em Widgets Consecutivos
-
Ajuste em
mapTree:-
Ao buscar o
wrapEndpara o widget atual no DOM vivo, contar quantos nós comstructSig(node) !== nullexistem a partir derClose + 1até o final do contêiner original (raw.length). Chamaremos essa contagem deremNodes. -
Na busca por
foundno DOM vivo, varrer os nós a partir dewrapStarte selecionar como âncora o nó que atende a dois critérios:-
Possui o mesmo
structSig(node) === afterSig; -
Possui exatamente
remNodesnós comstructSig !== nullrestantes até o fim do contêiner vivo (live.length).
-
-
Esse alinhamento por cauda elimina ambiguidades em estruturas repetitivas ou widgets duplicados consecutivos.
-
8. Divisão e Restauração Independente de Backups (Página e Layout)
-
Backend (
dashboard.php):-
Ajustar a API AJAX de busca de backups para que ela retorne duas listas separadas: backups da página (
page_backups) e backups do layout associado (layout_backups), baseando-se nolayout_idcorrespondente. -
Ajustar a API AJAX de recuperação de backup individual para suportar a busca tanto de backups de página quanto de layout.
-
-
Frontend (
dashboard.toolbar.js):-
No painel de backups (
buildBackupPanel/openBackupPanel), estruturar o modal para renderizar duas colunas lado a lado (ex: flexbox ou grid com títulos "Backups da Página" e "Backups do Layout"). -
Mapear o clique nos backups do layout para que eles façam a requisição do backup e injetem o layout original reconstruído (preservando o slot
#c2f-page-contentda página ativa para que o conteúdo atual do usuário não seja perdido durante a restauração do layout). -
Mapear o clique nos backups da página para atualizar somente o
#c2f-page-contentcom o HTML correspondente da versão.
-
Validação e Testes
-
Validação de Sintaxe e Suíte:
-
Garantir que
composer testcontinue 100% verde (76/76 testes) e quenode --check/php -lnos arquivos modificados não apresentem erros de compilação.
-
-
Smoke Test
_smoke_batch078_r2.mjs:-
O smoke test deve ser expandido/adaptado para validar:
-
O mapeamento de widget de múltiplos elementos no elemento pai, garantindo que o save reconstrua a marcação no
innerHTMLdo pai; -
Cenário com dois widgets idênticos e consecutivos, confirmando que cada um é mapeado como um widget separado e independente na tela (sem mesclá-los).
-
-
-
Validação Visual:
-
Abrir uma página com dois widgets de menus idênticos seguidos. Confirmar que cada um recebe seu outline amarelo tracejado independente e seu respectivo label de controle (não ficando agrupados como se fossem um único widget).
-
Abrir uma página com menu de links públicos (widget). Confirmar que ao pairar o cursor no menu, o outline amarelo envolve todo o contêiner do menu (o pai
<nav>) e exibe o label do widget apenas uma vez, travando a edição dos links filhos. -
Testar a filtragem por texto digitando no input da toolbar de módulos e atestar que a lista e as categorias são filtradas em tempo real.
-
Clicar para editar uma imagem no editor, clicar no botão de busca de imagem, selecionar um arquivo pelo gerenciador e ver a URL ser preenchida no campo. Redimensionar o modal arrastando o canto da caixa.
-
Clicar no botão de backups da toolbar e certificar-se de que a caixa exibe as duas colunas (Página e Layout) com seus respectivos históricos de versões.
-
Testar a restauração de um backup de layout e confirmar que o layout visual é restaurado mantendo o conteúdo da página inalterado na tela, e vice-versa.
-