Lidamos com o WebKit em 1C, por exemplo, a integração do TinyMCE em um formulário gerenciado no UT 11.4

Muitos já sabem que, no lançamento da plataforma 8.3.14.1565, o navegador Internet Explorer foi substituído pelo Web-Kit, este é realmente um grande passo em frente, mas tenho certeza que, como eu, ainda não está claro o que é o quê. Houve uma experiência de usar o kit da web em 1C, chamando JS de 1C e chamando 1C de JS. Vamos tentar entender juntos como um difere do outro e, ao mesmo tempo, fazer algo útil. Sim, e certamente muitos terão que reescrever seus trabalhos semelhantes depois de atualizar para uma nova plataforma, por isso espero que minha experiência seja útil.

Tudo começou com o fato de a tarefa ter surgido: “Queremos, na UT, inserir uma descrição formatada para o produto para depois voar para a loja online”, porque a descrição padrão do produto chega em uma linha sólida sem hifenização e não parece muito boa. Imediatamente houve o desejo de usar um documento formatado, existe um editor simples e você pode enviá-lo para HTML. Mas assim que mostrei o HTML gerado pelo documento formatado aos desenvolvedores da Web, eles imediatamente acenaram com as mãos e disseram que isso não funcionaria. O site já possui seus próprios estilos para exibir os elementos de bloco necessários e o comportamento desse tipo de texto pode se tornar imprevisível.

A função Get HTML de um documento formatado retorna uma página HTML totalmente formada, com toda a estrutura das tags e o que é mais desagradável, com estilos embutidos. Parece assim.

<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <meta name="format-detection" content="telephone=no" /> <style type="text/css"> body{margin:0;padding:8px;} p{line-height:1.15;margin:0;white-space:pre-wrap;} ol,ul{margin-top:0;margin-bottom:0;} img{border:none;} li>p{display:inline;} </style> </head> <body> <p><span style="text-decoration: underline;"></span></p> <p><span style="font-weight: bold;"> </span></p> <p><span style="color: #ff0000;font-weight: normal;"> </span></p> <p><br></p> </body> </html> 

E se obter o conteúdo da tag body é uma tarefa simples, eu não queria analisar e cortar os atributos de estilo das tags.

O TinyMCE traz de volta um bom layout. Permitindo-se estilos inline apenas no caso da cor, que já é muito melhor.

 <p></p> <p><strong></strong></p> <p><span style="color: #ff0000;"></span></p> 

Foi decidido integrar o TinyMCE, um editor de texto de terceiros. Além disso, a experiência de sua integração com a comunidade 1C já é bastante grande.

Talvez tenha sido um erro, então, e você apenas teve que analisar o texto gerado por um documento formatado, mas nós temos o que temos.

1. Recursos da solução


Como o 1C não permite o upload de arquivos locais do sistema de arquivos para a página no campo HTML, para isso você precisa definitivamente de um servidor Web ou pelo menos o endereço desse arquivo no armazenamento temporário, coloque a biblioteca Tiny js ao lado de 1C e carregue-a nos cabeçalhos do documento HTML você não pode - também precisará criar um arquivo com um layout HTML que forme internamente uma janela do editor pronta e já esteja conectada ao documento HTML.

De maneira geral, na verdade, você pode carregar uma biblioteca se obtiver um endereço para ela no repositório, se ele tiver sido compilado em um arquivo, e o Tiny, além da biblioteca principal, também contém plug-in js-files, um gerenciador de estilos e estilos, os próprios arquivos de crack , ícones etc. e, como você entende, isso complica bastante a tarefa. Ao mesmo tempo, houve uma idéia de compilar tudo isso em um arquivo e não conhecer os problemas, mas demorou muito tempo para entender as ferramentas. Em seguida, o TinyMCE Builder foi encontrado no site oficial, que compila todos os js em um arquivo, e seria uma pequena vitória se fizesse o mesmo com o css, mas não, o css ainda fica ao lado de várias pastas.

O TinyMCE cria um iframe para a janela de edição, que é um documento HTML incorporado na página, para que os eventos que ocorrem nesse iframe 1C não possam ser rastreados, mais sobre isso abaixo.

A configuração do UT 11.4 no momento do desenvolvimento tinha um modo de compatibilidade de 8.3.12; portanto, agora ele usava o IE como um navegador interno, mas uma atualização adicional implicava uma transição para novas versões que já usam o web-kit.

2. Primeiros passos


As principais diferenças no trabalho com o kit da web:

O objeto principal dos campos HTML agora tem uma estrutura diferente e, para trabalhar com o conteúdo da página, você precisa usar a propriedade defaultView

 .HTML.Document.DefaultView 

usou anteriormente a propriedade parentWindow para este

 .HTML.Document.parentWindow 

A proibição de usar eval, que costumava ser universalmente usada para invocar o código JS. Algo assim

Elements.FieldHTML.Document.parentWindow.eval ("alert ('Código de chamada de 1C')")
Mas você pode acessar os métodos diretamente do 1C.

Elements.Description HTML.Document.DefaultView.NameMethodJS ();
E rapidamente criei funções de empacotamento para todos os métodos minúsculos necessários.

 function GetText(){ return tinyMCE.activeEditor.getContent({format: "text"}); } function SetText(text){ return tinyMCE.activeEditor.setContent(text); } function GetHTML(){ return tinyMCE.activeEditor.getContent(); } 

Que abordou ainda mais de 1C para

 HTML = .HTML.Document.DefaultView; HTML = HTML.GetHTML();  = HTML.GetText(); 

Embora se possa conviver com chamadas diretas ao objeto editor, por exemplo,

 .HTML..defaultView.tinyMCE.activeEditor.getContent() 

O processamento da publicação foi baixado imediatamente (um respeito separado ao autor), o que me mostrou muitas coisas interessantes. Funcionou mais ou menos no IE, mas copiar e colar não funcionou no webkit, inicialmente causou um estupor, mas depois ficou claro que era por causa do iframe que o campo HTML não era ativado ao clicar dentro dele, pois o clique realmente ocorreu no documento anexo HTML cujos eventos ficaram presos em algum lugar no caminho para 1C. E, portanto, se você pressionar Ctrl + C em um lugar no formulário e tentar colá-lo dentro do campo do editor, o texto será inserido nesse campo de onde foi copiado porque o campo HTML do documento não está ativado. O mesmo acontece no caso oposto, os atalhos de teclado para copiar e colar não funcionam.

imagem

No início, surgiu a idéia de que era um batente minúsculo e bloqueia a pasta direta do buffer, como o CKEditor, que oferece uma janela separada para colar a partir do buffer. Mas, para verificar se era bem fácil, criei um documento vazio com um campo de entrada e tentei copiar e colar

imagem

Como você pode ver, tudo funciona. Portanto, o problema está em algum lugar do Tiny ou em interação com o 1C.

3. Decisão


Para resolver o problema com a interação do navegador e do 1C, o truque usual foi aplicado, criei um botão invisível na página HTML e planejei clicar nele no JS quando os eventos necessários ocorrerem dentro da página que o 1C interceptaria no evento HTML Press. Mas em que evento realizar um programa de imprensa?

O layout é mais ou menos assim:

 <body> <textarea id="editor"></textarea> <button id="button1c" style="display: none"></button> </body> 

E uma função para acionar um evento de clique no botão

 function clickButton() { button1c.click(); } 

Anteriormente, era possível transferir um objeto do formulário 1C no campo HTML como um objeto e, devido ao fato de o IE se conectar ao 1C via COM, o próprio formulário era de alguma forma convertido em um objeto que o IE entendia e era possível chamar funções de exportação do formulário 1C diretamente do código JS . Agora é impossível.

Estudamos a documentação da API minúscula e encontramos uma construção para interceptar manipuladores de eventos e uma combinação adequada de eventos que devem ativar o campo HTML do documento

 tinymce.activeEditor.on('click', function(e){clickButton(e)}); tinymce.activeEditor.on('KeyDown', function(e){clickButton(e)}); 

Você precisa colocar esse código no local em que o Tiny já foi inicializado. Eu fiz isso no manipulador onload do objeto window . Mas você pode fazer isso de maneira mais bonita e colocar o código ao inicializar o Tiny no parâmetro:

 init_instance_callback 

Agora tudo deve estar em ordem. E o formulário deve funcionar como deveria ...

Tornou-se muito melhor, o campo HTML realmente começou a ser ativado, mas nem sempre, por algum motivo, alguns cliques não fizeram com que o foco se movesse para o campo:

imagem

Este registro mostra que, se você clicar na linha em que o cursor está piscando, o foco do campo funcionará como deveria, mas se você clicar abaixo, o campo não será ativado.

Era um artefato irritante, e as tentativas de entender o que estava acontecendo não deram nenhuma solução. Emito alertas para o manipulador e alertas foram exibidos, mas 1C não respondeu ao evento

imagem

De repente, surgiu a ideia: e se a 1C não conseguir processar o evento que está acontecendo no campo, e se você atrasar um pouco a execução do script JS e ver o que acontece. A função de pausa no JS foi rapidamente implementada usando promessas e espera assíncrona. Como você pode ver no JS, ele também não existe por padrão e nada, as pessoas vivem).

 function sleep(ms){ return new Promise(resolve => setTimeout(resolve, ms)); } async function clickButton(e){ await sleep(1); button1c.click(); } 

Aqui, defino o atraso para um milissegundo, antes de clicar no botão. E pronto, funcionou. 1C começou a processar o clique de um botão a tempo.

imagem

4. Terminamos a troca


Como para armazenar a nova descrição no formato HTML, um novo atributo foi adicionado ao diretório, precisamos substituir o valor do campo típico durante o descarregamento. Para fazer isso, no módulo ExchangeSiteRemoveable, adicione a função GetTexts of RequestsCatalog à extensão e escreva lá:

 . = (., ".", ".HTML_HTML"); 

Só isso. Iniciamos a troca e tudo funciona, resta apenas fazer alterações no site, se necessário, para que a descrição do produto seja percebida como layout e não como uma string.

Sumário


Neste exemplo, tentei a interação do JS WebKit e 1C, coletei o rake e encontrei uma solução.

Talvez para resolver esse problema, fosse mais fácil analisar e limpar o texto HTML de um documento formatado, mas não seria tão interessante e poderá ter alguns problemas com algumas opções de formatação complexas.

Obrigado pela leitura.

Source: https://habr.com/ru/post/pt481768/


All Articles