Integración del motor HTML en la aplicación nativa de Windows: elección y arquitectura

Cómo tradujimos el trabajo con HTML en 1C: Enterprise de Internet Explorer a WebKit

La capacidad de mostrar HTML en formularios 1C apareció en la plataforma 1C: Enterprise en 2003, versión 8.0. Para trabajar con HTML, la plataforma utilizó el motor de navegador Internet Explorer (1C: Enterprise en ese momento solo funcionaba bajo Windows). El motor del navegador fue utilizado por la plataforma con fines utilitarios. Por ejemplo, para escribir desde cero un elemento completo para editar texto a la Palabra, con la posibilidad de varias soluciones de color y fuente, insertar imágenes, etc. - Una tarea muy difícil. Y si utiliza HTML para estos fines y utiliza el motor del navegador de Internet como herramienta de visualización, la tarea se simplifica enormemente. Además, con la ayuda del motor, se implementaron otros mecanismos (por ejemplo, mostrar información de ayuda ) y elementos (por ejemplo, Scheduler ).

Bueno, la capacidad de los desarrolladores de aplicaciones de mostrar usando un diseño HTML personalizado según los estándares del mundo de los sistemas de contabilidad a veces hizo posible traer una variedad de aspectos agradables a la interfaz de las aplicaciones comerciales.

Con el paso del tiempo, la plataforma comenzó a admitir Linux primero, y luego macOS. Internet Explorer no era adecuado para trabajar con HTML en estos sistemas operativos por razones obvias; en Linux, utilizamos WebKitGTK + , y en macOs, una biblioteca basada en Cocoa . Por lo tanto, la unidad de la base del código para diferentes sistemas operativos (que tratamos de mantener para el código del cliente al nivel del 95%) se violó en esta área. Bueno, el motor IE en este momento se convirtió en la fuente de una serie de problemas.
imagen

Los problemas:

  • El motor IE ha cerrado el código fuente; significa:
    • No es posible un ajuste flexible del motor a las necesidades de la plataforma.
    • Depuración y comprensión de los procesos internos.
    • No se pueden corregir errores y errores al actualizar la versión del motor
  • El motor no es adecuado para la implementación de tareas modernas de programación web.
  • Problemas de rendimiento en máquinas débiles

Entonces, la traducción de trabajar con HTML en la versión 1C: Enterprise para Windows del motor de IE a otra cosa fue obvia. Que elegir

Para empezar, formulamos los requisitos para el motor:

  • Soporte para tecnologías modernas de programación web.
  • Código abierto para una personalización flexible del motor y la comprensión de su lógica.
  • Alto rendimiento en computadoras más lentas
  • Es deseable que el motor requiera una pequeña cantidad de bibliotecas de terceros para funcionar

Selección del motor


¿De qué elegir? Comenzamos, por supuesto, con WebKit , con el que ya trabajamos en versiones de la plataforma para Linux y macOS.

WebKit fue desarrollado en Apple a principios de la década de 2000 basado en los motores de código abierto KHTML y KJS . Basado en WebKit, se creó el navegador Safari, más tarde, Chrome (incluso más tarde Chrome cambió de WebKit a Blink , que nuevamente se basa en el código WebCore de WebKit).

El código fuente de WebKit es de código abierto y tiene licencia bajo la LGPL . WebKit está escrito para macOS, hay varios puertos para Windows:

WebKit AppleWin


Este es el puerto que los desarrolladores de WebKit sugieren construir en Windows de forma predeterminada. Fue hecho por empleados de Apple a mediados y finales de la década de 2000. Utiliza la biblioteca de gráficos CoreGraphics , que es una versión simplificada de la biblioteca para macOS, portada a Windows. Para ejecutar JavaScript, el puerto usa la biblioteca JavaScriptCore con la misma API que se usa en la implementación de la plataforma para Linux. Esto lo convierte en un candidato ideal para su uso.

WebKit WinCairo


Este puerto utiliza la biblioteca de El Cairo para gráficos. Durante algún tiempo, Apple ha estado desarrollando activamente este puerto como un análogo al puerto principal AppleWin. La ventaja de este puerto es que depende menos de las bibliotecas específicas de macOS que requiere CoreGraphics. Además, el puerto utiliza la misma biblioteca para gráficos ( Cairo ) que el motor WebKitGTK +, que utilizamos en la implementación de Linux de la plataforma, lo cual es bueno para estandarizar el comportamiento de nuestro código.

QtWebKit


Otra implementación del motor WebKit para Windows, ahora independiente de los desarrolladores del propio motor. Qt es una biblioteca multiplataforma popular con su propia biblioteca de gráficos QtGui. Este puerto también usa la biblioteca JavaScriptCore para manejar JavaScript, sin embargo tiene desventajas:

  • Fuerte dependencia de los componentes principales de Qt, que, si se usan en software de terceros, deberán entregarse con él
  • Un conjunto diferente de interfaces para trabajar con componentes para renderizar HTML en comparación con WebKitGTK y su propia lógica para trabajar con ellos.

WebKitGtk + para Windows


Ya hemos usado WebKitGtk + en la versión de Linux de la plataforma. Pero la opción de usarlo en Windows se descartó debido a la complejidad del ensamblaje, la documentación deficiente de este proceso y la falta de soporte constante para esta área de desarrollo por parte de los desarrolladores de WebKitGTK +.

Cromo (parpadeo)


El primer y único motor no similar a WebKit, que se consideró como un candidato para resolver el problema. Fue rechazado debido a las grandes diferencias en la lógica de los componentes para renderizar HTML en comparación con WebKitGTK + y otra biblioteca para trabajar con JavaScript ( V8 ).

Que elegir


Después de la investigación, AppleWin y WinCairo llegaron a la final.
Para tomar la decisión final, estudiamos cómo funciona WebKit.

Estructura del motor de WebKit


Por lo general, los diferentes puertos de WebKit difieren de dos maneras. El primero es directamente la implementación de un sistema operativo particular utilizando componentes específicos del sistema operativo. El segundo es una biblioteca de gráficos. La siguiente figura describe las diferencias en este sentido entre los puertos WebKit. Para Windows, los desarrolladores de WebKit escribieron puertos en la biblioteca CoreGraphics y Cairo adaptadas.

imagen

Un modelo simplificado del motor: tres mecanismos tradicionales para formatear una página web (HTML, JavaScript y CSS) se alimentan al motor, y forma y muestra la página desde ellos:

imagen

El motor en sí consta de varios componentes:

  • WTF (Web Template Framework, no lo que podría haber pensado ): aquí encontrará sus propias implementaciones de estructuras de datos para el funcionamiento del motor, así como trabajar con flujos
  • JavaScriptCore: un componente, como su nombre lo indica, para trabajar con el lenguaje JavaScript
  • WebCore: todo el trabajo con DOM, estilos, análisis HTML y XML está escrito aquí. Aquí se hace toda la "magia" principal del motor.
  • Plataforma: realiza acciones técnicas para interactuar con la red, colocar datos en una base de datos, decodificar imágenes, trabajar con medios
  • WebKit y WebKit2 API: vinculan todos los componentes y proporcionan acceso a ellos

imagen
La relación entre los componentes de WebKit y las características específicas del sistema operativo se muestra en la figura a continuación. Como puede ver, hay bastantes puntos específicos que deben implementarse para cada sistema operativo por separado. Aunque JavaScriptCore le permite usar usted mismo en cada puerto sin implementaciones separadas.

imagen

Cómo se forma una página web


Desde la red, una respuesta llega a una solicitud al servidor con datos para descargar. El cargador pasa los datos al analizador, que, al interactuar con el componente de JavaScript, forma el DOM y la hoja de estilo. A continuación, los datos generados se transfieren al árbol de representación y se muestran en un contexto gráfico.
imagen
La página en sí también consta de componentes individuales. El componente WebCore implementa la clase Page, que permite el acceso a toda la página. La página tiene un marco principal: MainFrame, un marco siempre tiene un documento. El marco principal puede tener cualquier número de otros marcos, también con documentos dentro. Para cada marco, algunos eventos se forman por separado, así como contextos gráficos y JavaScript específicos.

imagen

El analizador HTML simplificado funciona así. Del conjunto de bytes recibidos del servidor, el decodificador genera un conjunto de caracteres para el análisis. Los símbolos se convierten en tokens o tokens, que generalmente son piezas elementales de código con metainformación sobre qué tipo de texto es, ya sea que forme parte de la sintaxis o el contenido del lenguaje. Luego, los nodos se forman a partir de tokens para construir un árbol DOM. Un generador de árboles a partir de un conjunto de nodos forma un modelo de objeto completo para un documento de página web.

imagen

Elección final


  • Applewin
    • Pros:
      • Implementado en una biblioteca de gráficos que se ejecuta en macOS, la plataforma de destino principal para los desarrolladores de WebKit
    • Contras:
      • Falta de implementación del mecanismo de impresión.
      • Un gran número de dependencias.
  • Wincairo
    • Pros:
      • La misma biblioteca de gráficos (Cairo), utilizada en el puerto Linux de la plataforma 1C.
    • Contras:
      • Esencial para nuestras tareas no encontradas

Derrotado WinCairo. Para el desarrollo, se tomó la última versión de WebKit disponible en ese momento: 605.1.11.

Implementación


Aunque el motor está bastante bien cubierto por las pruebas unitarias (alrededor de 30,000 para todos los componentes del motor, escritos por los autores del motor), existen errores y deficiencias en las implementaciones para sistemas operativos "no básicos" (es decir, para todo lo que no es macOS). Estas brechas de implementación se descubrieron gradualmente a medida que el motor se desarrolló y probó como parte de la plataforma 1C: Enterprise.

Descargar HTML a través de arrastrar y soltar


Al arrastrar texto a la ventana, se descubrió que si el texto que se arrastra contiene caracteres que no son ASCII, los jeroglíficos se insertan en el documento final. El error apareció solo en la implementación de Windows del motor, porque funcionaba con un mecanismo específico del sistema operativo para arrastrar y soltar elementos. Resulta que el texto no se decodificó de UNICODE a UTF-16 antes de pasarlo al controlador de eventos de inserción.

Cambiar Shift + Enter Comportamiento del teclado


En la mayoría de los editores de texto (incluido Microsoft Word), esta combinación inserta un salto de línea. El comportamiento estándar de WebKit es insertar un nuevo párrafo (como si simplemente presionara Enter). Cambiamos el motor, haciendo que el comportamiento sea más familiar para los usuarios.

Organización del mecanismo de deshacer y rehacer.


WebKit proporciona una API para implementar su propio mecanismo para cancelar y repetir acciones del usuario. Su esquema es el siguiente: cuando el usuario realiza una determinada acción discreta desde el punto de vista del motor (por ejemplo, cambiar a un nuevo párrafo, formatear en cursiva, pegar), WebKit informa al desarrollador acerca de esto utilizando la API para que pueda registrar esta acción.

En el proceso de probar el mecanismo implementado, se descubrió algo desagradable: el motor no informa cambios en la estructura de las tablas. Se agregaron comandos para agregar y eliminar celdas y cambiar el atributo colSpan, que se convirtió en parte de acciones compuestas, como, por ejemplo, agregar / eliminar una columna o una fila en una tabla. Dichos comandos compuestos se registran en la misma pila de deshacer y rehacer, y junto con los comandos del motor aseguran el funcionamiento correcto del mecanismo.

Pegar desde Excel


Aquellos que trabajaron con el portapapeles de Windows y Excel pueden saber que, en primer lugar, al copiar de Excel a HTML, el formato del portapapeles en el fragmento copiado contiene solo las etiquetas de las celdas y filas, pero no la etiqueta de la tabla en sí, y en segundo lugar, Los estilos de un documento de Excel no se transfieren a las celdas. Debido a esto, insertar, por ejemplo, una tabla de colores en un elemento editable en Chrome tiene este aspecto:

Original:

imagen

En cromo:

imagen

Los desarrolladores de WebKit no tuvieron en cuenta estos dos factores. La apertura del código del motor nos permitió refinar el mecanismo de inserción, y ahora el fragmento de la tabla insertada en el campo HTML del documento está cerca del original:

imagen

Generación de letra cursiva


Si Windows no tiene una versión en cursiva de una fuente no estándar, la mayoría de los editores de texto pueden generar dicha fuente utilizando su versión normal. Sin embargo, WebKit no pudo hacer esto y engañó a los desarrolladores un par de veces: cómo es que en el código HTML del documento colocamos el texto en la etiqueta <i>, pero a pesar de esto, el texto se mantuvo recto. La razón es que el motor WebKit selecciona la fuente deseada en el puerto WinCairo que usamos; si no hay una versión en cursiva, el motor usa la versión normal. Este comportamiento ha sido reemplazado por el uso de la fuente en cursiva generada por la biblioteca de gráficos Cairo.

Errores en la decodificación de imágenes y animaciones


Se encontraron errores en el comportamiento del motor al trabajar con elementos gráficos. Al cargar algunas imágenes en formato PNG, se observó distorsión de la imagen y, a veces, su ausencia. No fue posible averiguar la razón de este comportamiento, ya que se produce un error al decodificar imágenes en los intestinos de la biblioteca libpng.

Empíricamente, se encontró que al vincular la biblioteca libpng de forma dinámica en lugar de una estática, el problema se soluciona. Por cierto, en la versión actual del motor, el enlace se realiza de esta manera. Se decidió hacer lo mismo.

Otro problema era el motor al cargar animaciones en formato GIF. El error se reprodujo periódicamente al cargar la página con tales animaciones y provocó el bloqueo del programa. El error fue causado por la falta de sincronización al trabajar con el búfer en el que se coloca el siguiente cuadro de la animación. El problema se resolvió utilizando herramientas de sincronización internas de WebKit.

Soporte ortográfico


En el ensamblaje con Internet Explorer, en Windows versión 8 y posterior, la corrección ortográfica podría habilitarse para el campo editable HTML. Para hacer esto, fue suficiente para atribuir "corrector ortográfico" igual a "verdadero". WebKit tenía diferentes soluciones para diferentes puertos: en Linux es la biblioteca Enchant , en macOS tiene su propio mecanismo, familiar para todos los usuarios de productos Apple. Pero para Windows no hay implementación, pero se proporciona una API para su propia solución. Utilizamos la API de corrección ortográfica de Windows , disponible a partir de Windows 8, e implementamos un mecanismo similar a la compilación con Internet Explorer. Por cierto, ahora en un documento formateado en clientes nativos de 1C: Enterprise, esta funcionalidad también funciona. Antes de la versión 8.3.14, estaba deshabilitado debido al bajo rendimiento de Internet Explorer.

Soporte de Windows XP


Algunos de nuestros clientes aún trabajan en Windows XP y no van a actualizar el sistema operativo en un futuro próximo. Triste para nosotros como desarrolladores, pero cierto. Entonces, necesitamos apoyarlos. Y aquí tuvimos una sorpresa desagradable: los desarrolladores de WebKit durante aproximadamente un año no han admitido el motor en WinXP. El intento de compilar una versión del motor con un conjunto de herramientas de compilación para WinXP no tuvo éxito: los desarrolladores de WebKit usan bibliotecas que solo están disponibles desde Windows Vista y versiones posteriores.

Que hacer Las opciones fueron las siguientes:

  1. Deje la implementación de WinXP con el motor de Internet Explorer y use WebKit en versiones anteriores de Windows
  2. Tome para el desarrollo una versión anterior del motor WebKit, que funciona en WinXP, y use esta versión en todos los SO
  3. Use la versión adecuada de WebKit en WinXP y use el último motor en versiones anteriores de Windows
  4. Transfiera la versión actual del motor a WinXP y úselo en todas partes

La pregunta no fue simple. La primera opción le permitía usar la última versión del motor WebKit, pero lo obligaría a devolver la implementación anterior con Internet Explorer. En tal solución, sería difícil garantizar un funcionamiento sin errores del programa, y ​​el código en sí sería muy complicado. La segunda opción proporcionó el mismo comportamiento en todos los sistemas operativos Windows, sin embargo, no nos dejaría la oportunidad de desarrollar: actualizar el motor para corregir errores y obtener nuevas características de los desarrolladores del motor en versiones posteriores. La tercera opción le permitía usar la versión actual del motor en versiones anteriores de Windows, pero complicaba enormemente la lógica de instalación y garantizaba el mismo comportamiento de versión en todos los sistemas operativos. La cuarta opción parecía preferible a todas las demás, pero era imposible predecir la complejidad y, en general, la posibilidad de tal solución.

Sin embargo, decidimos arriesgarnos e implementar la cuarta opción, la más correcta desde el punto de vista arquitectónico (usando un único código fuente del motor en todas las versiones de Windows). La versión portada de WebKit funciona de manera diferente en WinXP y en las versiones más recientes de Windows:

  • Tuve que abandonar las herramientas del nuevo DirectX (d3d11) en favor del antiguo DirectX9 (d3d9) y adaptar sus archivos de encabezado a la versión más joven del SDK.
  • Las funciones del nuevo SDK, cuando se ejecutan en nuevas versiones de Windows, se invocan en la dirección (obtenida a través de GetProcAddress ).
  • Para transferir datos entre flujos en el motor, WinXP utiliza el almacenamiento local de subprocesos, en nuevas versiones: almacenamiento local de fibra.

Resumen


Entonces, ahora en nuestra plataforma 1C: Enterprise a partir de la versión 8.3.14 (lanzamiento - finales de 2018) HTML será compatible al más alto nivel: HTML5, OpenGL, etc. Tanto la cantidad como la calidad de las pasas que se pueden incorporar a las decisiones en nuestra plataforma están limitadas solo por la imaginación del desarrollador. Y, sin embargo, por supuesto, el sistema operativo del cliente: en WinXP, muchos sabrosos bollos HTML5 no funcionarán, por razones obvias.

Ahora en aplicaciones de Windows en la plataforma 1C: Enterprise podrá mostrar esto:



Pero, usando las "ventajas" de HTML en soluciones de aplicación, no olvide el sentido común. El uso de HTML es apropiado y recomendado para tareas especializadas (mostrar ayuda, técnicas, descripciones de productos, ...), pero no para implementar tareas de lógica de negocios (entrada / salida de información estructurada). Para hacer esto, debe usar los mecanismos de interfaz estándar 1C: Enterprise que brindan soporte automático para los derechos de acceso, administración de funcionalidad, adaptación al factor de forma del dispositivo, soporte para la configuración del usuario y el trabajo de muchos otros mecanismos, sin los cuales el funcionamiento completo de una aplicación comercial se vuelve casi imposible.

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


All Articles