将HTML引擎集成到本机Windows应用程序中-选择和体系结构

我们如何在1C中使用HTML转换工作:从Internet Explorer到WebKit的企业版

以1C形式显示HTML的功能出现在2003年的8.0版本的1C:企业平台中。 为了使用HTML,该平台使用了浏览器引擎Internet Explorer(当时的1C:Enterprise仅在Windows下可以使用)。 该平台将浏览器引擎用于功利目的。 例如,从头开始编写一个完整的元素来编辑文本,例如Word-并可能使用各种颜色和字体解决方案,插入图片等。 -一项艰巨的任务。 而且,如果您出于这些目的使用HTML并将Internet浏览器引擎用作显示工具,则该任务将大大简化。 同样,借助引擎,实现了许多其他机制(例如,显示帮助信息 )和元素(例如, Scheduler )。

嗯,应用程序开发人员能够按照会计系统领域的标准使用HTML定制设计进行显示,因此有时可以为业务应用程序的界面带来各种令人愉悦的亮点。

随着时间的流逝,该平台首先开始支持Linux,然后才支持macOS。 由于明显的原因,Internet Explorer不适合在这些OS中使用HTML。 在Linux上,我们使用WebKitGTK + ,在macOs(基于Cocoa的库)上使用。 因此,在此区域中违反了不同操作系统的代码库的统一性(我们尝试将其保持在95%的客户端代码级别)。 好吧,此时的IE引擎已成为许多问题的根源。
图片

问题:

  • IE引擎已关闭源代码-这意味着:
    • 无法根据平台灵活调整引擎
    • 调试和了解内部流程
    • 无法通过更新引擎版本来修复错误和错误
  • 该引擎不适合执行现代Web编程任务
  • 弱机的性能问题

因此,很明显可以将版本1C:Windows企业版中的HTML从IE引擎转换为其他东西。 选择什么?

首先,我们制定了引擎要求:

  • 支持现代Web编程技术
  • 开源,可灵活定制引擎并了解其逻辑
  • 在较慢的计算机上具有高性能
  • 希望引擎需要少量的第三方库才能工作

引擎选择


有什么选择? 当然,我们从WebKit开始,我们已经使用它开发了适用于Linux和macOS的平台版本。

WebKit是在2000年代初期由苹果公司开发的,基于开源引擎KHTMLKJS 。 基于WebKit,随后创建了Safari浏览器-Chrome(甚至后来Chrome从WebKit切换到BlinkBlink再次基于WebKit的WebCore代码)。

WebKit的源代码是开源的,并根据LGPL许可 。 WebKit是为macOS编写的,Windows有多个端口:

WebKit AppleWin


这是WebKit开发人员建议默认在Windows下构建的端口。 它是由Apple员工在2000年代中后期制造的。 它使用CoreGraphics图形库,该库是macOS库的简化版本,已移植到Windows。 为了执行JavaScript,端口使用JavaScriptCore库和用于Linux平台的实现中使用的API相同。 这使其成为首选。

WebKit WinCairo


此端口使用Cairo库进行图形处理。 一段时间以来,Apple一直在积极开发此端口,以与AppleWin主端口类似。 此端口的优点是它较少依赖CoreGraphics所需的macOS特定库。 此外,该端口使用与WebKitGTK +引擎相同的图形库( Cairo ),我们在平台的Linux实现中使用了该库,这对于标准化代码的行为非常有用。

QtWebKit


Windows的WebKit引擎的另一种实现,现在独立于该引擎本身的开发人员。 Qt是一个流行的跨平台库,带有自己的QtGui图形库。 此端口还使用JavaScriptCore库来处理JavaScript,但是它确实有缺点:

  • 强烈依赖Qt的主要组件,如果在第三方软件中使用,则需要随其一起提供
  • 与WebKitGTK相比,与用于呈现HTML的组件一起使用的一组不同的接口以及用于处理它们的自己的逻辑。

适用于Windows的WebKitGtk +


我们已经在平台的Linux版本中使用了WebKitGtk +。 但是,由于程序集的复杂性,该过程的文档不足以及WebKitGTK +开发人员缺乏对该开发区域的持续支持,因此无法在Windows中使用它。

铬(闪烁)


第一个也是唯一一个非WebKit式引擎,被视为解决该问题的候选者。 与WebKitGTK +和另一个用于JavaScript的库( V8 )相比,用于呈现HTML的组件逻辑差异很大,因此被拒绝。

选择什么?


经过研究,AppleWin和WinCairo进入了决赛。
为了做出最终选择,我们研究了WebKit的工作方式。

WebKit引擎结构


通常,不同的WebKit端口在两种方面有所不同。 首先是使用特定于操作系统的组件直接实现特定操作系统的实现。 第二个是图形库。 下图描述了WebKit端口在此意义上的区别。 对于Windows,WebKit开发人员在改编的CoreGraphics和Cairo库上编写了端口。

图片

引擎的简化模型:将用于格式化网页的三种传统机制(HTML,JavaScript和CSS)馈送到引擎,然后由它们形成并显示页面:

图片

引擎本身包含几个组件:

  • WTF(Web模板框架,不是您可能想到的 ):在这里您可以找到自己的数据结构实现,以实现引擎的功能以及使用流
  • JavaScriptCore:顾名思义,用于使用JavaScript语言的组件
  • WebCore:所有与DOM,样式,HTML和XML解析有关的工作都在此处编写。 引擎的所有主要“魔术”都在这里完成。
  • 平台:执行与网络交互,将数据放入数据库,解码图像,使用媒体的技术操作
  • WebKit和WebKit2 API-链接所有组件并提供对它们的访问

图片
WebKit组件和特定于操作系统的功能之间的关系如下图所示。 如您所见,每个OS分别需要实现很多特定要点。 尽管JavaScriptCore允许您在每个端口中使用自己,而无需单独的实现。

图片

网页的形成方式


来自网络的响应是对服务器的请求,其中包含要下载的数据。 加载程序将数据传递到解析器,解析器与JavaScript组件进行交互,形成DOM和样式表。 接下来,将生成的数据传输到渲染树并在图形上下文中显示。
图片
该页面本身也由各个组件组成。 WebCore组件实现Page类,该类允许访问整个页面。 页面有一个主框架-MainFrame,一个框架总是有一个文档。 主框架可以具有任意数量的其他框架,也可以包含文档。 对于每一帧,都会分别形成一些事件,以及特定的图形和JavaScript上下文。

图片

简化的HTML解析器的工作原理如下。 解码器根据从服务器接收到的一组字节,形成一组用于解析的字符。 将符号转换为令牌或令牌,这些令牌通常是基本代码段,具有有关文本类型(无论是语言语法还是内容的一部分)的元信息。 然后由令牌形成节点以构建DOM树。 来自一组节点的树构建器构成了网页文档的完整对象模型。

图片

最终选择


  • Applewin
    • 优点:
      • 在可在macOS上运行的图形库上实现-macOS是WebKit开发人员的主要目标平台
    • 缺点:
      • 缺乏实施印刷机制
      • 大量的依赖
  • 温开罗
    • 优点:
      • 与1C平台的Linux端口中使用的相同的图形库(Cairo)
    • 缺点:
      • 找不到我们的任务必不可少的

击败了WinCairo。 为了进行开发,采用了当时可用的最新版本的WebKit-605.1.11。

实作


尽管该引擎已经很好地被单元测试所覆盖(引擎的所有组件大约30,000,由引擎的作者编写),但是“非核心”操作系统(即,对于所有非macOS的操作系统)的实现都有错误和不足。 随着引擎作为1C:企业平台的一部分进行开发和测试,这些实施方面的差距逐渐被发现。

通过拖放下载HTML


将文本拖到窗口中时,发现如果所拖的文本包含非ASCII字符,则象形文字会插入最终文档中。 该错误仅出现在引擎的Windows实现中,因为它使用特定于操作系统的机制来拖放元素。 事实证明,在将文本传递给插入事件处理程序之前,并没有将其从UNICODE解码为UTF-16。

更改Shift +输入键盘行为


在大多数文本编辑器(包括Microsoft Word)中,此组合会插入换行符。 WebKit的标准行为是插入一个新段落(就像简单按Enter键一样)。 我们更改了引擎,使用户更熟悉该行为。

撤消和重做机制的组织。


WebKit提供了一个API,用于实现其自己的取消和重复用户操作的机制。 它的方案如下:当用户执行从引擎角度出发的某个特定动作(例如,切换到新段落,斜体格式,粘贴)时,WebKit会使用API​​将此通知开发人员,以便他可以注册该动作。

在测试实现的机制的过程中,发现了一个不愉快的事情:引擎没有报告表结构的更改。 添加了添加和删除单元格以及更改colSpan属性的命令,这些命令成为了复合操作的一部分,例如,添加/删除表中的列或行。 这样的复合命令被注册在相同的撤消和重做堆栈中,并且与来自引擎的命令一起确保机制的正确操作。

从Excel粘贴


使用Windows和Excel剪贴板的人可能知道,首先,从Excel复制到HTML时,复制的片段中的剪贴板格式仅包含单元格和行的标签,而不包含表本身的标签,其次, Excel文档中的样式不会传输到单元格。 因此,例如,将颜色表插入Chrome中的可编辑元素,如下所示:

原件:

图片

在Chrome中:

图片

WebKit的开发人员没有考虑这两个因素。 引擎代码的开放性使我们能够完善插入机制,现在插入到Document的HTML字段中的表的片段已接近原始片段:

图片

斜体字体生成


如果Windows没有非标准字体的斜体版本,则大多数文本编辑器可以使用其常规版本生成这种字体。 但是,WebKit无法做到这一点,并误导了开发人员几次:在文档的HTML代码中,如何将文本放在<i>标记中,但是尽管如此,文本仍然保持直线。 原因是WebKit引擎在我们使用的WinCairo端口中选择了所需的字体-如果没有斜体,则引擎将使用常规版本。 此行为已被使用Cairo图形库生成的斜体字体代替。

解码图像和动画时出错


发现了使用图形元素时引擎行为方面的错误。 当以PNG格式加载某些图像时,观察到图像失真,有时甚至根本没有。 无法找到此现象的原因,因为在libpng库的肠子中解码图像时会发生错误。

根据经验,发现以动态方式而非静态方式链接libpng库时,此问题已解决。 顺便说一下,在当前版本的引擎中,链接是通过这种方式完成的。 决定这样做。

另一个问题是在加载GIF格式的动画时的引擎。 加载带有此类动画的页面时,会定期重现该错误,并导致程序崩溃。 该错误是由于在处理动画下一帧所放置的缓冲区时缺少同步而引起的。 使用内部WebKit同步工具已解决该问题。

拼写支持


在带有Internet Explorer的程序集中,在Windows 8和更高版本中,可以为HTML可编辑字段启用拼写检查。 为此,将“ spellcheck”属性等于“ true”就足够了。 WebKit针对不同端口具有不同的解决方案:在Linux上是Enchant库,在macOS上它具有自己的机制,Apple产品的所有用户都熟悉。 但是对于Windows没有实现,但是为自己的解决方案提供了API。 我们使用了Windows Spell Checking API (从Windows 8开始可用),并实现了与Internet Explorer构建类似的机制。 顺便说一下,现在在本机1C:Enterprise客户端的格式化文档中,此功能也可以使用。 在8.3.14版之前,由于Internet Explorer性能不佳而被禁用。

Windows XP支持


我们的某些客户端仍然可以在Windows XP上运行,并且不会在不久的将来升级操作系统。 作为开发人员,我们感到难过,但事实如此。 所以-我们需要支持他们。 这给我们带来了令人不愉快的惊喜:大约一年来,WebKit开发人员都不支持WinXP中的引擎。 尝试使用一套用于WinXP的构建工具构建引擎版本的尝试失败-WebKit开发人员使用的库仅可从Windows Vista和更高版本获得。

怎么办 选项如下:

  1. 将WinXP实施与Internet Explorer引擎一起保留,并在Windows的较早版本中使用WebKit
  2. 开发适用于WinXP的WebKit引擎的早期版本,并在所有OS中使用该版本。
  3. 在WinXP中使用适当版本的WebKit,在较旧版本的Windows中使用最新的引擎
  4. 自己将当前版本的引擎移植到WinXP并在任何地方使用

问题并不简单。 第一个选项允许您使用WebKit引擎的最新版本,但是将迫使您使用Internet Explorer返回旧的实现。 在这样的解决方案中,将难以确保程序的无错误操作,并且代码本身将非常复杂。 第二个选项在所有Windows操作系统上提供相同的行为,但是,这不会给我们留下开发的机会-更新引擎以修复错误,并从更高版本的引擎开发人员那里获得新功能。 第三个选项允许在较旧版本的Windows中使用引擎的当前版本,但极大地简化了安装逻辑,并确保了所有操作系统中的版本行为相同。 第四个选项看起来比其他所有选项都更好,但是无法预测这种解决方案的复杂性和总体可能性。

尽管如此,我们还是决定尝试并实施第四个选项,这从架构的角度来看是最正确的(在所有Windows版本上使用单个引擎源代码)。 WebKit的移植版本在WinXP和Windows的较新版本中的工作方式有所不同:

  • 我不得不放弃新的DirectX(d3d11)的工具,转而使用旧的DirectX9(d3d9),并将其头文件改编为较新版本的SDK。
  • 在新版本的Windows上执行时,新SDK中的函数将在该地址处调用(通过GetProcAddress获得)。
  • 为了在引擎中的流之间传输数据,WinXP使用了新版本的Thread本地存储-光纤本地存储。

总结


因此,现在在我们的1C:Enterprise平台(版本8.3.14(发行-2018年底))中,将在最高级别支持HTML-HTML5,OpenGL等。 可以在我们的平台上做出决定的葡萄干的数量和质量都仅受开发人员的想象力限制。 但是,当然,客户的操作系统-在WinXP上,由于显而易见的原因,许多美味的HTML5包子都无法使用。

现在在1C:Enterprise平台上的Windows应用程序上将能够显示以下内容:



但是,在应用程序解决方案中使用HTML的“好东西”时,请不要忘记常识。 使用HTML是合适的,建议将其用于专门的任务(显示帮助,技术,产品描述等),但不适用于实现业务逻辑任务(结构化信息的输入/输出)。 为此,您需要使用标准1C:企业接口机制,该机制提供对访问权限,功能管理,对设备外形的适应性,对用户设置的支持以及许多其他机制的工作的自动支持,没有这些功能,业务应用程序的全面运行几乎变得不可能。

Source: https://habr.com/ru/post/zh-CN425713/


All Articles