Este documento especifica os requisitos para solucionar problemas de renderização e persistência de widgets com caracteres especiais (como ->), garantir suporte a AJAX e scripts controladores de widgets na pré-visualização, e refatorar as funções específicas de módulo no Editor HTML.
1. Mapeamento de IDs e Correção de Caracteres Especiais (->, ", {, etc.) nos Widgets
1.1 Problema
Ao persistir ou converter widgets no Editor HTML Visual, caracteres especiais presentes nas assinaturas (como o operador -> ou aspas e chaves do JSON) são convertidos pelo navegador em entidades HTML (>, ", &), resultando em valores corrompidos (ex: menus->render(...) ou menus->render(...)). Isso quebra a validação regex do backend (html_editor_ajax_widget_render()) e impede que os widgets sejam renderizados. Além disso, ao retornar para o editor de código (previsualizarVoltar), o formato de variável original ([[widgets#...]]) é permanentemente substituído por blocos de comentários corrompidos.
1.2 Solução no Editor Visual (html-editor.js)
-
Instanciação do Mapa de Widgets:
-
No construtor/inicialização do
HtmlEditor, inicializar um contadorthis.widgetCounter = 0;e um objeto de memóriathis.widgetsMap = {};.
-
-
Diferenciação de Tipos e Descarregamento de Entidades (Unescape):
-
Na função
convertWidgetCommentsToWrappers(): -
Antes de varrer os comentários, converter as ocorrências de variáveis inline
[[widgets#...]]em comentários temporários rotulados como<!-- widgets-var#signature < --><!-- widgets-var#signature > -->. -
Realizar unescape da assinatura (converter
>→->,"→",&→&) antes de processá-la. -
No loop TreeWalker de comentários, verificar o prefixo correspondente:
-
Se for
widgets-var#, marcarisVariable = true. -
Se for
widgets#, marcarisVariable = false.
-
-
Gerar um identificador de widget único (ex:
widget-0,widget-1, etc.). -
Armazenar o objeto de metadados correspondente em
this.widgetsMap:this.widgetsMap[widgetId] = { signature: signature, isVariable: isVariable, type: type, slug: slug }; -
Criar o wrapper passando este ID e o status
isVariable.
-
-
Estruturação de Atributos do Wrapper:
-
Na função
createWrapperEl(opts): -
Definir
data-widget-idcom o ID único correspondente. -
Definir
data-widget-variablecom o valor'true'ou'false'(correspondendo aisVariable). -
Definir
data-widget-typeedata-widget-slugcomo valores limpos e puramente alfanuméricos. -
NÃO persistir o atributo
data-widget-signaturecontendo caracteres especiais no elemento DOM final (ou, se mantiver, usá-lo apenas como fallback sem caracteres especiais).
-
-
Manipulação de Edições e Clonagem:
-
Na função
editWidgetWrapper(wrapper): -
Ao alterar as configurações/slug de um widget existente, gerar um novo ID exclusivo para o widget editado. Copiar os metadados anteriores do mapa, atualizar a assinatura e o slug, e atualizar o atributo
data-widget-idno DOM. Isso evita conflito caso o widget seja um clone de outro na tela.
-
-
Exportação Limpa de HTML:
-
Na função
extractUserHtml(widgetsToComments): -
Se
widgetsToCommentsfortrue, ler odata-widget-iddo wrapper e buscar as propriedades correspondentes emthis.widgetsMap. -
Se
isVariablefortrue, substituir o wrapper de volta pela variável original em formato de texto puro:[[widgets#+ signature +]]. -
Se
isVariableforfalse, substituir o wrapper pelo bloco de comentários correspondente<!-- widgets#+ signature +< -->...<!-- widgets#+ signature +> -->contendo o mockup original.
-
2. Unescape e AJAX no Pré-visualizador (html-editor-interface.js)
2.1 Unescape no Previewer Script
-
Na função interna
widgetPreviewBootstrap():-
Ao converter variáveis inline em comentários temporários, aplicar o unescape das entidades HTML (
>,",&) do termo capturado. -
No loop de comentários, aplicar o mesmo unescape na assinatura antes de realizar a chamada AJAX para
html-editor-widget-render.
-
3. Inclusão Automática de widget.js no Pré-visualizador
3.1 Requisitos
-
Na função
previewHtmlConteudo(htmlDoUsuario, cssDoUsuario, framework, extraParams):-
Analisar o
htmlDoUsuariovia Regex para extrair todas as assinaturas de widgets presentes na página (tanto em formato de comentárioswidgets#...quanto de variáveis[[widgets#...]]). -
Para cada assinatura de widget identificada:
-
Extrair o nome do módulo correspondente (a parte que antecede o
->). -
Verificar se o módulo correspondente possui um script controlador de widget (mapeado:
galleries→galleries.widget.js,publisher-index→publisher-index.widget.js,menus→menus.widget.js). -
Coletar as tags de inclusão de script correspondentes de forma desduplicada (não incluir o mesmo arquivo de widget mais de uma vez na página).
-
Injetar os scripts de widget mapeados no cabeçalho (
<head>) do HTML do iframe de pré-visualização.
-
4. Suporte a AJAX no Pré-visualizador (widgetsToAjax)
4.1 Requisitos e Funcionamento On-The-Fly
-
Os scripts controladores de widget (como
publisher-index.widget.js) executam chamadas AJAX que dependem do parâmetroajaxWidgetscontendo as assinaturas dos widgets presentes para que o roteador de widgets do gestor (gestor.php) processe a rota corretamente. -
Como o iframe de preview é gerado via
srcdocestaticamente pelo JavaScript do editor, a variávelgestor.widgetsToAjaxnão é criada automaticamente pelo PHP e não está presente por padrão em seu contexto de execução. -
Por isso, a lógica do PHP que detecta widgets e gera essa variável deve ser totalmente replicada no lado do cliente:
-
Na função
previewHtmlConteudo(htmlDoUsuario, cssDoUsuario, framework, extraParams), a cada renderização/atualização de código do preview, o JavaScript deve analisar ohtmlDoUsuariovia Regex para identificar todos os widgets presentes (tanto comentários quanto variáveis inline). -
Obter as assinaturas únicas (desduplicadas) dos widgets e concatená-las utilizando o divisor
<#;>. -
Injetar dinamicamente no cabeçalho (
<head>) do iframe de pré-visualização um bloco<script>que declara essa variável com a lista de assinaturas construída em tempo de execução:<script> window.gestor = Object.assign({}, window.parent.gestor || {}); window.gestor.widgetsToAjax = "SIG1<#;>SIG2..."; </script>Isso assegura que qualquer AJAX disparado pelos scripts controladores de widget de dentro do preview funcione de forma transparente e encontre a variável preenchida com as assinaturas da tela corrente.
-
5. Refatoração de Funções Específicas de Módulos (html-editor-modules.js)
5.1 Requisitos
-
Mover as constantes, variáveis e funções específicas de simulação de módulos do
html-editor-interface.jspara um novo arquivo:gestor/assets/interface/html-editor-modules.js -
Elementos a serem movidos:
-
Módulo
menus:MENUS_SIM_FALLBACK,menusGetSimulationTree,menusExtrairBlocos,menusResolverItemVars,menusAplicarVars,menusInjetarChildren,menusRenderLevel,menusMontarBase,menusPublicadorMockPaginas,menusExpandirPublicadores,menusSimularPreview. -
Módulo
galleries:galleriesGetSimulationList,galleriesExtrairBlocos,galleriesAplicarVars,galleriesMontarBase,galleriesGetControls,galleriesRenderDots,galleriesProcessarControles,galleriesResolverGlobais,galleriesSimularPreview. -
Módulo
publisher:publisherVariablesOrSimulation,publisherVariablesOrValues,publisherValuesUpdate,publisherGetAllVariables,publisherVariablesSearch,publisherTableVariables.
-
-
Todas as funções acima deverão ser anexadas ao escopo global (
window) emhtml-editor-modules.jspara que possam ser chamadas a partir dehtml-editor-interface.js.
5.2 Exposição de Escopo no Interface JS
-
No início do callback
readydohtml-editor-interface.js(onde as instâncias do CodeMirror e metadados locais são criados), expor esses objetos no escopo global para que as funções emhtml-editor-modules.jspossam acessá-los:window.CodeMirrorHtml = CodeMirrorHtml; window.CodeMirrorHtmlExtraHead = CodeMirrorHtmlExtraHead; window.publisher_fields_schema = publisher_fields_schema;
5.3 Registro Dinâmico na Biblioteca PHP
-
No arquivo
gestor/bibliotecas/html-editor.php, incluir dinamicamente o novo scripthtml-editor-modulesna funçãohtml_editor_renderutilizando:gestor_pagina_javascript_incluir('biblioteca',[ 'caminho' => 'html-editor-modules', 'biblioteca' => 'html-editor', ]);O script deve ser carregado antes de
html-editor-interface.