Intégration du moteur HTML dans une application Windows native - choix et architecture

Comment nous avons traduit le travail avec HTML dans 1C: Enterprise d'Internet Explorer vers WebKit

La possibilité d'afficher du HTML dans des formulaires 1C est apparue dans la plate-forme 1C: Enterprise en 2003, version 8.0. Pour travailler avec HTML, la plate-forme a utilisé le moteur de navigation Internet Explorer (1C: Enterprise fonctionnait à l'époque uniquement sous Windows). Le moteur de navigation a été utilisé par la plateforme à des fins utilitaires. Par exemple, pour écrire à partir de zéro un élément à part entière pour éditer du texte à la Word - avec la possibilité de différentes solutions de couleurs et de polices, insérer des images, etc. - une tâche très difficile. Et si vous utilisez HTML à ces fins et utilisez le moteur de navigateur Internet comme outil d'affichage, la tâche est grandement simplifiée. En outre, avec l'aide du moteur, un certain nombre d'autres mécanismes (par exemple, l'affichage des informations d'aide ) et des éléments (par exemple, Scheduler ) ont été mis en œuvre.

Eh bien, la possibilité pour les développeurs d'applications d'afficher en utilisant la conception personnalisée HTML selon les normes du monde des systèmes comptables a parfois permis d'apporter une variété de points forts agréables à l'interface des applications commerciales.

Au fil du temps, la plate-forme a commencé à prendre en charge d'abord Linux, puis macOS. Internet Explorer n'était pas adapté pour travailler avec HTML dans ces systèmes d'exploitation pour des raisons évidentes; sous Linux, nous avons utilisé WebKitGTK + , et sur macOs, une bibliothèque basée sur Cocoa . Ainsi, l'unité de la base de code pour les différents systèmes d'exploitation (que nous essayons de maintenir pour le code client au niveau de 95%) a été violée dans ce domaine. Eh bien, le moteur IE à ce stade est devenu la source d'un certain nombre de problèmes.
image

Les problèmes:

  • Le moteur IE a un code source fermé - cela signifie:
    • Un ajustement flexible du moteur aux besoins de la plate-forme n'est pas possible
    • Débogage et compréhension des processus à l'intérieur
    • Impossible de corriger les bogues et les erreurs en mettant à jour la version du moteur
  • Le moteur n'est pas adapté à la mise en œuvre de tâches de programmation Web modernes
  • Problèmes de performances sur les machines faibles

Ainsi, la traduction de travailler avec HTML dans la version 1C: Enterprise pour Windows du moteur IE à quelque chose d'autre était évidente. Que choisir?

Pour commencer, nous avons formulé les exigences pour le moteur:

  • Prise en charge des technologies de programmation Web modernes
  • Open source pour une personnalisation flexible du moteur et la compréhension de sa logique
  • Haute performance sur les ordinateurs plus lents
  • Il est souhaitable que le moteur nécessite un petit nombre de bibliothèques tierces pour fonctionner

Sélection du moteur


De quoi choisir? Nous avons bien sûr commencé avec WebKit , avec lequel nous travaillions déjà dans des versions de la plateforme pour Linux et macOS.

WebKit a été développé chez Apple au début des années 2000 sur la base des moteurs open source KHTML et KJS . Basé sur WebKit, le navigateur Safari a été créé, plus tard - Chrome (encore plus tard, Chrome est passé de WebKit à Blink , qui est à nouveau basé sur le code WebCore de WebKit).

Le code source de WebKit est open source et sous licence LGPL . WebKit est écrit pour macOS, il existe plusieurs ports pour Windows:

WebKit AppleWin


Il s'agit du port que les développeurs WebKit suggèrent de créer sous Windows par défaut. Il a été fabriqué par des employés d'Apple du milieu à la fin des années 2000. Il utilise la bibliothèque graphique CoreGraphics , qui est une version simplifiée de la bibliothèque pour macOS, portée sur Windows. Pour exécuter JavaScript, le port utilise la bibliothèque JavaScriptCore avec la même API que celle utilisée dans l'implémentation de la plate-forme pour Linux. Cela en fait un candidat de choix pour l'utilisation.

WebKit WinCairo


Ce port utilise la bibliothèque Cairo pour les graphiques. Depuis un certain temps, Apple développe activement ce port en tant qu'analogue du port principal AppleWin. L'avantage de ce port est qu'il dépend moins des bibliothèques spécifiques à macOS dont CoreGraphics a besoin. De plus, le port utilise la même bibliothèque de graphiques ( Cairo ) que le moteur WebKitGTK +, que nous utilisons dans l'implémentation Linux de la plate-forme, ce qui est bon pour standardiser le comportement de notre code.

QtWebKit


Une autre implémentation du moteur WebKit pour Windows, désormais indépendante des développeurs du moteur lui-même. Qt est une bibliothèque multiplateforme populaire avec sa propre bibliothèque graphique QtGui. Ce port utilise également la bibliothèque JavaScriptCore pour gérer JavaScript, mais il présente des inconvénients:

  • Forte dépendance à l'égard des principaux composants de Qt, qui, s'ils sont utilisés dans des logiciels tiers, devront être livrés avec lui
  • Un ensemble d'interfaces différent pour travailler avec des composants pour le rendu HTML par rapport à WebKitGTK et sa propre logique pour travailler avec eux.

WebKitGtk + pour Windows


Nous avons déjà utilisé WebKitGtk + dans la version Linux de la plateforme. Mais l'option de l'utiliser dans Windows a été exclue en raison de la complexité de l'assemblage, de la mauvaise documentation de ce processus et du manque de prise en charge constante de cette zone de développement par les développeurs de WebKitGTK +.

Chrome (Clignotement)


Le premier et le seul moteur non WebKit, qui a été considéré comme un candidat pour résoudre le problème. Il a été rejeté en raison de grandes différences dans la logique des composants de rendu HTML par rapport à WebKitGTK + et à une autre bibliothèque pour travailler avec JavaScript ( V8 ).

Que choisir?


Après des recherches, AppleWin et WinCairo ont atteint la finale.
Pour faire le choix final, nous avons étudié le fonctionnement de WebKit.

Structure du moteur WebKit


En règle générale, différents ports WebKit diffèrent de deux manières. Le premier est directement l'implémentation d'un système d'exploitation particulier à l'aide de composants spécifiques au système d'exploitation. Le second est une bibliothèque graphique. La figure ci-dessous décrit les différences en ce sens entre les ports WebKit. Pour Windows, les développeurs WebKit ont écrit des ports sur la bibliothèque CoreGraphics et Cairo adaptée.

image

Un modèle simplifié du moteur: trois mécanismes traditionnels de formatage d'une page Web - HTML, JavaScript et CSS - sont alimentés par le moteur, et il forme et affiche la page à partir d'eux:

image

Le moteur lui-même se compose de plusieurs composants:

  • WTF (Web Template Framework, pas ce que vous auriez pu penser ): vous trouverez ici vos propres implémentations de structures de données pour le fonctionnement du moteur, ainsi que le travail avec des flux
  • JavaScriptCore: un composant, comme son nom l'indique, pour travailler avec le langage JavaScript
  • WebCore: tout le travail avec DOM, les styles, l'analyse HTML et XML est écrit ici. Toute la «magie» principale du moteur se fait ici.
  • Plateforme: effectue des actions techniques pour interagir avec le réseau, placer des données dans une base de données, décoder des images, travailler avec des médias
  • API WebKit et WebKit2 - reliant tous les composants et leur donnant accès

image
La relation entre les composants WebKit et les fonctionnalités spécifiques au système d'exploitation est illustrée dans la figure ci-dessous. Comme vous pouvez le voir, il existe un certain nombre de points spécifiques qui doivent être mis en œuvre séparément pour chaque système d'exploitation. Bien que JavaScriptCore vous permette de vous utiliser dans chaque port sans implémentations distinctes.

image

Comment une page Web est formée


Depuis le réseau, une réponse vient à une requête au serveur avec des données à télécharger. Le chargeur transmet les données à l'analyseur qui, en interagissant avec le composant pour JavaScript, forme le DOM et la feuille de style. Ensuite, les données générées sont transférées dans l'arborescence de rendu et affichées dans un contexte graphique.
image
La page elle-même comprend également des composants individuels. Le composant WebCore implémente la classe Page, qui permet d'accéder à la page entière. La page a un cadre principal - MainFrame, un cadre a toujours un document. Le cadre principal peut avoir un nombre quelconque d'autres cadres, avec également des documents à l'intérieur. Pour chaque image, certains événements sont formés séparément, ainsi que des contextes graphiques et JavaScript spécifiques.

image

L'analyseur HTML simplifié fonctionne comme ceci. À partir de l'ensemble d'octets reçus du serveur, le décodeur génère un ensemble de caractères pour l'analyse. Les symboles sont convertis en jetons ou jetons, qui sont généralement des éléments élémentaires de code avec des méta-informations sur le type de texte qu'il est, qu'il fasse partie de la syntaxe ou du contenu du langage. Ensuite, les nœuds sont formés à partir de jetons pour construire une arborescence DOM. Un constructeur d'arborescence à partir d'un ensemble de nœuds forme un modèle d'objet complet pour un document de page Web.

image

Choix final


  • Applewin
    • Avantages:
      • Implémenté sur une bibliothèque graphique qui s'exécute sur macOS - la principale plate-forme cible pour les développeurs WebKit
    • Inconvénients:
      • Absence de mise en œuvre du mécanisme d'impression
      • Un grand nombre de dépendances
  • Wincairo
    • Avantages:
      • La même bibliothèque graphique (Le Caire), utilisée dans le port Linux de la plate-forme 1C
    • Inconvénients:
      • Essentiel pour nos tâches introuvable

Vaincu WinCairo. Pour le développement, la dernière version de WebKit disponible à l'époque a été prise - 605.1.11.

Implémentation


Bien que le moteur soit assez bien couvert par les tests unitaires (environ 30 000 pour tous les composants du moteur, écrits par les auteurs du moteur), il existe des erreurs et des lacunes dans les implémentations pour les OS «non principaux» (c'est-à-dire pour tout ce qui n'est pas macOS). Ces lacunes d'implémentation ont été progressivement découvertes au fur et à mesure que le moteur était développé et testé dans le cadre de la plateforme 1C: Enterprise.

Télécharger HTML via Drag & Drop


Lors du glissement du texte dans la fenêtre, il a été constaté que si le texte glissé contient des caractères non ASCII, des hiéroglyphes sont insérés dans le document final. L'erreur est apparue uniquement dans l'implémentation Windows du moteur, car elle fonctionnait avec un mécanisme spécifique au système d'exploitation pour faire glisser et déposer des éléments. Il s'avère que le texte n'a pas été décodé d'UNICODE en UTF-16 avant d'être transmis au gestionnaire d'événement d'insertion.

Modifier Maj + Entrer le comportement du clavier


Dans la plupart des éditeurs de texte (y compris Microsoft Word), cette combinaison insère un saut de ligne. Le comportement standard de WebKit consiste à insérer un nouveau paragraphe (comme si vous appuyiez simplement sur Entrée). Nous avons changé le moteur, rendant le comportement plus familier aux utilisateurs.

Organisation du mécanisme d'annulation et de rétablissement.


WebKit fournit une API pour implémenter son propre mécanisme d'annulation et de répétition des actions utilisateur. Son schéma est le suivant: lorsque l'utilisateur effectue une certaine action discrète du point de vue du moteur (par exemple, basculement vers un nouveau paragraphe, mise en forme en italique, collage), WebKit en informe le développeur à l'aide de l'API afin qu'il puisse enregistrer cette action.

Lors du test du mécanisme implémenté, une chose désagréable a été découverte: le moteur ne signale pas de changements dans la structure des tables. Des commandes d'ajout et de suppression de cellules et de modification de l'attribut colSpan ont été ajoutées, qui sont devenues partie intégrante des actions composites, telles que, par exemple, l'ajout / la suppression d'une colonne ou d'une ligne dans un tableau. Ces commandes composites sont enregistrées dans la même pile d'annulation et de rétablissement et, conjointement avec les commandes du moteur, assurent le bon fonctionnement du mécanisme.

Coller depuis Excel


Ceux qui ont travaillé avec le presse-papiers Windows et Excel peuvent savoir que, premièrement, lors de la copie d'Excel vers HTML, le format du presse-papiers dans le fragment copié contient uniquement les balises des cellules et des lignes, mais pas la balise du tableau lui-même, et deuxièmement, les styles d'un document Excel ne sont pas transférés vers les cellules. Pour cette raison, l'insertion, par exemple, d'une table des couleurs dans un élément modifiable dans Chrome ressemble à ceci:

Original:

image

Dans Chrome:

image

Ces deux facteurs n'ont pas été pris en compte par les développeurs de WebKit. L'ouverture du code moteur nous a permis d'affiner le mécanisme d'insertion, et maintenant le fragment du tableau inséré dans le champ HTML du Document est proche de l'original:

image

Génération de polices italiques


Si Windows n'a pas de version italique d'une police non standard, la plupart des éditeurs de texte peuvent générer une telle police à l'aide de sa version standard. Cependant, WebKit n'a pas pu le faire et a induit les développeurs en erreur à plusieurs reprises: comment se fait-il que dans le code HTML du document, nous ayons mis le texte dans la balise <i>, mais malgré cela, le texte est resté droit. La raison en est que le moteur WebKit sélectionne la police souhaitée dans le port WinCairo que nous utilisons - s'il n'y a pas de version italique, le moteur utilise la version régulière. Ce comportement a été remplacé par l'utilisation de la police italique générée par la bibliothèque graphique Cairo.

Erreurs de décodage d'images et d'animations


Des erreurs dans le comportement du moteur lors de l'utilisation d'éléments graphiques ont été trouvées. Lors du chargement de certaines images au format PNG, une distorsion de l'image a été observée, et parfois son absence du tout. Il n'a pas été possible de trouver la raison de ce comportement, car une erreur se produit lors du décodage des images dans les entrailles de la bibliothèque libpng.

Empiriquement, il a été constaté que lors de la liaison de la bibliothèque libpng de manière dynamique au lieu d'une bibliothèque statique, le problème est résolu. Par ailleurs, dans la version actuelle du moteur, la liaison est effectuée de cette manière. Il a été décidé de faire de même.

Un autre problème était le moteur lors du chargement des animations au format GIF. L'erreur a été périodiquement reproduite lors du chargement de la page avec de telles animations et a conduit au crash du programme. L'erreur a été causée par le manque de synchronisation lors de l'utilisation du tampon dans lequel la prochaine image de l'animation est placée. Le problème a été résolu à l'aide des outils de synchronisation WebKit internes.

Support orthographique


Dans l'assembly avec Internet Explorer, dans Windows version 8 et versions ultérieures, la vérification orthographique peut être activée pour le champ HTML modifiable. Pour ce faire, il suffisait d'attribuer "vérification orthographique" égal à "vrai". WebKit avait différentes solutions pour différents ports: sous Linux c'est la bibliothèque Enchant , sur macOS il a son propre mécanisme, familier à tous les utilisateurs des produits Apple. Mais pour Windows, il n'y a pas d'implémentation, mais une API est fournie pour sa propre solution. Nous avons utilisé l' API de vérification orthographique de Windows , disponible à partir de Windows 8, et mis en œuvre un mécanisme similaire à la génération avec Internet Explorer. Soit dit en passant, maintenant dans un document formaté dans les clients natifs 1C: Enterprise, cette fonctionnalité fonctionne également. Avant la version 8.3.14, il était désactivé en raison des performances médiocres d'Internet Explorer.

Prise en charge de Windows XP


Certains de nos clients fonctionnent toujours sous Windows XP et ne mettront pas à niveau le système d'exploitation dans un avenir proche. Triste pour nous en tant que développeurs, mais vrai. Donc - nous devons les soutenir. Et ici, nous avons eu une surprise désagréable: les développeurs de WebKit depuis environ un an n'ont pas pris en charge le moteur dans WinXP. Une tentative de génération d'une version du moteur avec un ensemble d'outils de génération pour WinXP a échoué - les développeurs WebKit utilisent des bibliothèques disponibles uniquement avec les versions de Windows Vista et versions ultérieures.

Que faire Les options étaient les suivantes:

  1. Quittez l'implémentation de WinXP avec le moteur Internet Explorer et utilisez WebKit dans les anciennes versions de Windows
  2. Prenez pour le développement une version antérieure du moteur WebKit, qui fonctionne dans WinXP, et utilisez cette version dans tous les OS
  3. Utilisez la version appropriée de WebKit dans WinXP et utilisez le dernier moteur dans les anciennes versions de Windows
  4. Portez vous-même la version actuelle du moteur sur WinXP et utilisez-la partout

La question n'était pas simple. La première option vous permettait d'utiliser la dernière version du moteur WebKit, mais vous obligerait à renvoyer l'ancienne implémentation avec Internet Explorer. Dans une telle solution, il serait difficile d'assurer un fonctionnement sans erreur du programme et le code lui-même serait très compliqué. La deuxième option a fourni le même comportement sur tous les systèmes d'exploitation Windows, cependant, elle ne nous laisserait pas la possibilité de développement - la mise à jour du moteur pour corriger les erreurs et obtenir de nouvelles fonctionnalités des développeurs du moteur dans les versions ultérieures. La troisième option vous permettait d'utiliser la version actuelle du moteur dans les anciennes versions de Windows, mais compliquait considérablement la logique d'installation et garantissait le même comportement de version dans tous les systèmes d'exploitation. La quatrième option semble préférable à toutes les autres, mais il est impossible de prévoir la complexité et, en général, la possibilité d'une telle solution.

Néanmoins, nous avons décidé de tenter notre chance et de mettre en œuvre la quatrième option, la plus correcte d'un point de vue architectural (en utilisant un code source de moteur unique sur toutes les versions de Windows). La version portée de WebKit fonctionne différemment dans WinXP et les versions plus récentes de Windows:

  • J'ai dû abandonner les outils du nouveau DirectX (d3d11) au profit de l'ancien DirectX9 (d3d9) et adapter ses fichiers d'en-tête à la version plus récente du SDK.
  • Les fonctions du nouveau SDK, lorsqu'elles sont exécutées sur de nouvelles versions de Windows, sont appelées à l'adresse (obtenue via GetProcAddress ).
  • Pour transférer des données entre les flux du moteur, WinXP utilise le stockage local Thread, dans les nouvelles versions - le stockage local Fibre.

Résumé


Donc, maintenant dans notre plateforme 1C: Enterprise à partir de la version 8.3.14 (version - fin 2018), le HTML sera pris en charge au plus haut niveau - HTML5, OpenGL, etc. Tant la quantité que la qualité des raisins secs pouvant être amenés à prendre des décisions sur notre plateforme ne sont limitées que par l'imagination du développeur. Et pourtant, bien sûr, le système d'exploitation du client - sur WinXP, de nombreux petits pains HTML5 savoureux ne fonctionneront pas, pour des raisons évidentes.

Désormais, sur les applications Windows, la plateforme 1C: Enterprise pourra montrer ceci:



Mais, en utilisant les «goodies» du HTML dans les solutions d'application, n'oubliez pas le bon sens. L'utilisation de HTML est appropriée et recommandée pour des tâches spécialisées (affichage d'aide, techniques, descriptions de produits, ...), mais pas pour la mise en œuvre de tâches de logique métier (entrée / sortie d'informations structurées). Pour ce faire, vous devez utiliser les mécanismes d'interface 1C: Enterprise standard qui fournissent une prise en charge automatique des droits d'accès, la gestion des fonctionnalités, l'adaptation au facteur de forme de l'appareil, la prise en charge des paramètres utilisateur et le travail de nombreux autres mécanismes, sans lesquels le fonctionnement à part entière d'une application métier devient presque impossible.

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


All Articles