-
Intake: req-082
-
Alvo de validação: VALIDATION-CHECKLIST.md#batch-082
-
Decisão: DEC-084
-
Base: correções de homologação do Live Editor (barra flutuante + editbar do Dashboard Site Toolbar) pós BATCH-080/081.
Escopo
Quatro correções pontuais no Live Editor. Todo recurso novo do motor (html-editor.js)
permanece gated ao Live Editor (this.raiz), sem alterar o editor visual clássico do admin.
As chamadas AJAX seguem nas rotas site-toolbar-* do dashboard.php, que reusam funções da
biblioteca html-editor.php.
1 — Carregamento de widgets dinâmicos (postMessage → AJAX → postMessage)
Sintoma: ao inserir um widget pelo painel "+", o placeholder Carregando widget… fica preso porque
o postMessage c2f-he:widget-render do motor não tinha receptor no Live Editor.
-
Backend (
dashboard.php): nova rotasite-toolbar-widget-render→dashboard_ajax_site_toolbar_widget_render()(checagestor_acesso('editar','admin-paginas'), inclui a libhtml-editore delega ahtml_editor_ajax_widget_render(), que já existe e resolve a assinaturamodulo->func({...})). -
Frontend (
dashboard.toolbar.js): listener dedicado demessageque intercepta a string JSONc2f-he:widget-render(o motor postaJSON.stringify(...)parawindow.parent, que na página hospedeira top é a própriawindow). HandlerhandleEngineWidgetRender(signature, wrapperId): faz POST na rota, e ao receber o HTML posta de voltac2f-he:widget-rendered(string JSON) para a própriawindow→ o motor chamaapplyWidgetRender.
2 — Seleção automática do modelo inserido (insertTemplate)
-
Motor (
html-editor.js):insertTemplatepassa a rastrear o primeiro nó de elemento (nodeType === 1) inserido nas três relações (replace/before/after) e, ao final, o seleciona (this.selectElement(firstInserted)). Antes sóreplaceselecionava.
3 — Restauração de backups com re-mapeamento (marker-based)
Sintoma: ao restaurar backup de página/layout os widgets vinham como .c2f-widget-box (caixa morta,
não interativa) e as anotações (data-c2f-widget-id/data-c2f-variable) se perdiam.
-
Backend (
dashboard.php):-
dashboard_site_toolbar_boxes_widgets: widgets passam a ser embrulhados nos marcadores de comentário<!-- widgets#SIG < -->{render}<!-- widgets#SIG > -->(formato vivo que omapTreeentende), em vez da div.c2f-widget-box. -
Novo helper
dashboard_site_toolbar_resolver_variaveis($html): resolve@[[var]]@para o valor puro (texto e atributo), espelhando a página viva — sem.c2f-var-box(omapTreere-anota). -
dashboard_ajax_site_toolbar_backup_get: retorna tambémraw(o HTML cru salvo, com marcadores intactos) além dohtmlrenderizado. Para layout,raw/htmlalinham o slot vazio#c2f-page-content.
-
-
Frontend (
dashboard.toolbar.js):restorePageBackup(html, raw)/restoreLayoutBackup(html, raw)chamamdeselectAll(), injetam ohtmlno DOM vivo e orawno container oculto de mapeamento, re-rodammapTree()para re-anotar widgets/variáveis e chamamrestoreChrome(). OvarMapnão é zerado (preserva o mapeamento cruzado layout×conteúdo — ver DEC-084 §3).
4 — Isolamento multi-usuário na Editbar (via hook core↔projeto)
A regra de isolamento é específica de projeto e NÃO vive no core. Segue o sistema de hooks do
Conn2Flow (hook_apply_filters).
-
Core (
dashboard.php): helperdashboard_site_toolbar_verificar_permissao_pagina($pagina)só EXPÕE o filtrodashboard/site-toolbar.permissao-pagina(defaulttrue, guardfunction_exists('hook_apply_filters')) — o core não conhecemultiusuario. Aplicado emsite-toolbar-render,site-toolbar-save,site-toolbar-backups(selecionamid_usuarios) esite-toolbar-backup-get(recebepage_iddo contexto e valida a página dona). -
Projeto (
conn2flow-site): handlermultiusuario_dashboard_site_toolbar_permissao_pagina_filteremmultiusuario.hooks.php, registrado nohooks.json(controllers.dashboard+filters.dashboard["site-toolbar.permissao-pagina"]), exige acesso completo (acesso-completo-a-paginas/admin-paginasouacesso-completo-a-paginas-publisher/publisher-pages, conformepublisher_id) OU que oid_usuariosda página seja o do usuário logado.
Arquivos alterados
Core (conn2flow)
-
gestor/modulos/dashboard/dashboard.php(rota widget-render + helper que emite o filtro de permissão + backup_getraw+ widgets marker-based + resolver variáveis). -
gestor/modulos/dashboard/dashboard.toolbar.js(listener widget-render, restore com raw+remap, page_id no backup_get, cache-bust). -
gestor/assets/interface/html-editor.js(seleção automática eminsertTemplate). -
gestor/bibliotecas/html-editor.php(cache-bust da biblioteca). -
tests/Unit/JS/html-editor.live.test.js(seleção de modelo before/after). -
tests/Unit/JS/dashboard.toolbar.test.js(widget-render → widget-rendered; restore re-mapeia).
Projeto (conn2flow-site, repo privado)
-
gestor/project/hooks/controllers/multiusuario.hooks.php(handler do filtrodashboard/site-toolbar.permissao-pagina). -
gestor/project/hooks/hooks.json(registro do controllerdashboard+ filtro).
Validação
-
Estática:
node --check(html-editor.js/dashboard.toolbar.js),php -l(dashboard.php/html-editor.php). -
Vitest:
npm run test(seleção de modelo; ponte widget-render/rendered; re-mapeamento no restore). -
composer testsem regressão. -
Runtime (deploy
Update => Core+ homologação visual + teste de bloqueio multi-usuário): pendente com o operador.