Conn2Flow
Navegação das docs

SDD

req-044: Correção de Caracteres Especiais nos Widgets, Suporte AJAX no Preview e Refatoração de Módulos no Editor HTML

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…

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 contador this.widgetCounter = 0; e um objeto de memória this.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 &gt; → ->, &quot; → ", &amp; → &) antes de processá-la.

    • No loop TreeWalker de comentários, verificar o prefixo correspondente:

      • Se for widgets-var#, marcar isVariable = true.

      • Se for widgets#, marcar isVariable = 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-id com o ID único correspondente.

    • Definir data-widget-variable com o valor 'true' ou 'false' (correspondendo a isVariable).

    • Definir data-widget-type e data-widget-slug como valores limpos e puramente alfanuméricos.

    • NÃO persistir o atributo data-widget-signature contendo 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-id no 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 widgetsToComments for true, ler o data-widget-id do wrapper e buscar as propriedades correspondentes em this.widgetsMap.

    • Se isVariable for true, substituir o wrapper de volta pela variável original em formato de texto puro: [[widgets# + signature + ]].

    • Se isVariable for false, 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 (&gt;, &quot;, &amp;) 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 htmlDoUsuario via Regex para extrair todas as assinaturas de widgets presentes na página (tanto em formato de comentários widgets#... 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âmetro ajaxWidgets contendo 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 srcdoc estaticamente pelo JavaScript do editor, a variável gestor.widgetsToAjax nã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 o htmlDoUsuario via 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.js para 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) em html-editor-modules.js para que possam ser chamadas a partir de html-editor-interface.js.

5.2 Exposição de Escopo no Interface JS

  • No início do callback ready do html-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 em html-editor-modules.js possam 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 script html-editor-modules na função html_editor_render utilizando:

    gestor_pagina_javascript_incluir('biblioteca',[
      'caminho' => 'html-editor-modules',
      'biblioteca' => 'html-editor',
    ]);

    O script deve ser carregado antes de html-editor-interface.

O Futuro é Híbrido: Humano + IA.

O Conn2Flow é a ferramenta. Se você precisa do Arquiteto para desenhar a estratégia da sua empresa usando essa tecnologia...

Contrate Consultoria Especializada