1、WebKit 介绍及总结一 . WebKit 简介Webkit 是一个开放源代码的浏览器引擎 (web browser engine) ,最初的代码来自 KDE 的 KHTML 和 KJS( 均开放源代码 ) 。苹果公司在 Webkit 的基础上做了大量优化改进工作 ,此时的 Apple Webkit 已经和 Webkit 有了不少差别,最后开发出了著名的 Safari ,可以说 Safari 是一个相当成功的产品,但是 Safari 却不是开放源代码的。基于 WebKit 的浏览器产品有:苹果的 Safari 和 iPhone , Google 的 Chrome 和 Android , No
2、kia 的 S60 ,傲游 3(Maxthon3) ;WebKit 目前支持 HTML4/5 , CSS1/2 , DOM1/2 , HTTP/FILE , GIF/JPEG/PNG , XML , SVG , RSS2.0等;同类的浏览器引擎有: Trident ( IE 内核) , Gechko ( Netscape, Mozilla 和 Firefox 内核) , Presto ( Opera 内核,不免费) , Tasman ( IE for MAC 内核) ,等等,而 WebKit 因为其功能强大、速度快而且免费备受欢迎。二 . 用到的库: 除了平台相关的库, WebKit 需要用到
3、的一些主要的后台库有:ICU : International Components for Unicode , 一个成熟,广泛使用的一套为 C / C + + 和 Java 库提供 Unicode 的 全球化支持软件;XSLT : eXtensible Stylesheet Language Transformation, W3C 定义的用于 XML 文档转换的规范;Curl : 一个利用 URL 语法的命令行数据传输工具,基于 libcurl 。Sqlite : SQLite 是实现了 SQL92 标准的 SQL 数据库引擎,它能在一个库里组合数据库引擎和接口 , 将所有数据存储于单个文件
4、;Gperf :一个很完美的哈希函数生成器;Flex : Fast Lex, 快速词法分析生成器;Bison :语法分析生成器,可以将一段带注释的上下文无关语法转化成 LALR 或 GLR 语法;Enchant :一个拼写检查库,提供单词的拼写检查、纠错等功能;三 . 代码目录结构WebKitTools一些测试 WebKit 实现功能的程序;WebKitLibrariesWebKit 用到的库以及系统调用接口定义;WebKitExamplePlugins一些来自 Netscape 的插件,比如输入法、动画和 Cocoa 环境等;WebKitSite: 保存了 www.webkit.org 网站
5、的WebKit此目录位于 WebKit 的最上层,定义了与应用相关的一些接口,因此它是平台相关的,每个子目录都是对应平台的完整实现:cf : Core Foundation, MAC OS X 上的系统级 C 语言 API 接口;win : Windows ;mac : MAC OS X ;qt : Q Toolkit ,其公司已被 Nokia 收购;gtk : Gimp Toolkit ;scripts :一些脚本,目前只有一个关于 WebKit 版本的脚本程序;chromium : Google Chrome 开发平台;wx : wxWindows ,一种可移植的 C+ 和 Python
6、GUI 工具箱, by Julian Smart ;haiku :一种开源 OS ,从 BeOS 而来, 2001 开始, 2009 发布首版;efl: Enlightenment Foundation Libraries, Enlightenment 平台;WebCore WebKit 的核心部分,定义了浏览相关的数据 IO 、页面加载、脚本分析、 UI 组织、事件处理、网络分析、平台相关的具体实现等内容。xml :提供 xml 相关的内容;html :提供 html 相关的内容;其下的 Canvas 目录定义了 3D 画布以及 WebGL 库相关的内容;wml: Wireless Mark
7、up Language ;css :提供 css 相关的内容;dom :提供 dom 相关的内容;editing :编辑相关的功能;page :浏览相关内容,并非是我们看到的一个页面,在一次浏览会话中,它只有一个实例;rendering :页面渲染相关的内容,在对页面脚本进行 DOM 树分析之后,需要对这些元素进行渲染和显示;notification :内部模块间的事件通信;history :页面浏览历史记录相关的内容;svg :矢量图形功能,有选项, -svg ;mathml : W3C 为网页中的数学表达式制定的规范;有编译选项, -mathml ;loader : 加载资源及 Cache
8、 ;workers :“ Web Workers 为 WEB 前端网页上的脚本提供了一种能在后台进程中运行的方法。一旦它被创建, Web Workers 就可以通过 postMessage() 向任务池发送任务请求,执行完之后再通过 postMessage() 返回消息给创建者指定的事件处理 程序 ( 通过 onmessage 进行捕获 ) 。 Web Workers 进程能够在不影响用户界面的情况下处理任务,并且,它还可以使用 XMLHttpRequest 来处理 I/O ,无论 responseXML 和 channel 属性是否为 null 。 ”storage : Web Storag
9、e 相关的内容,保存页面的数据,可以看成是 Cookie 的升级;websockets :与网络连接相关的内容;bridge: 主要包含 NPPlugin(Netscape Plugin) 方面的接口访问等内容;binding : Dom 与 JavaScriptCore 绑定的功能;accessibility :提供控件的可用性相关的内容, accessibility 常用来形容对一些特殊人群的功能支持,比如残障者、老人等;icu :里面放了专门为 Mac OS X 10.4 编译的 icu 相关头文件 ;platform :提供了平台相关的具体实现,如事件响应、本地化、网络连接等;plug
10、ins :插件相关内容;ForwardingHeaders :头文件;inspector : Inspector 是 WebKit 提供的查看网页源代码,DOM 树,以及调试脚本的工具,本目录包含了实现此功能的内容;Configurations : X Code 环境相关的配置文件;English.lproj :本地化文件;manual-tests :测试用的 html 文件;Resources :资源,图标;WebCore.gyp :工程文件。 GYP ( Generate Youre Project )是 google 自己开发了一个脚本工具,这个工具也 是采用 python 编写的。它采
11、用了自定义的一套规则,用于生成各种工程文件;WebCore.vcproj : VC 工程文件;WebCore.xcodeproj : X Code 工程文件;WTF : Apple 的 C+ 库,可以看作精简的 STL ; SunSpider一个 JavaScript 的检测程序,它不检测 DOM 或者浏览器其他的 API ,只用来检测 Javascript 。JavaScriptGlueJavaScriptCore :有关 JavaScript 的相关内容,包括了脚本解释器、分析器以及执行程序;PlanetWebkit: 一个比较灵活的 RSS 阅读器; Webkit 网站上的 Planet
12、 :一站式的 Webkit 开发与动态信息;四 . 体系结构WebKit 主要包括三部分: WebKit , WebCore ,以及 JavaScriptCore ,加上所使用的库,依托的平台,其基本的体系结构 (Architecture) 如下所示:注意有的模块相对于下面的模块有突出,这是因为此模块与下面几个模块直接相关,比如 WebCore 模块就与 JavaScriptCore 、 Libraries 和 Platforms 模块直接相关。五 . 调用过程知道了 WebKit 的大体结构,我们就可以深究下去,看看这个浏览器引擎具体是怎么工作的。首先介绍几个基本且重要的类:Page :打开
13、 page.h 头文件,我们似乎看不到我们概念中的“页面”相关的东西,没错,这里的 Page 并非就是我们印象中的简单网页,在头文件中我们发现很多关于 history 的东西, goBack(),goForward(), 等等,关于主题的设定,关于 Frame 的描述等等,因此,这里的 Page 更像是我们见到的浏览器,抽象起来,应该算是我们访问网站的一次浏览会话;在 page.cpp 文件里,还有个重要的全局指针变量: static HashSetPage* allPages; 这个变量包含了所有的page 实例,没错!就像 FireFox 一样,我们可以启动几个浏览器,而且就是在一个进程里
14、;allPages 在 Page 的构造函数里将每次新产生的 Page 对象加入;每次启动新的 window ,才会新建一个 Page 对象,并触发 PageGroup:addPage() ;Frame :与 Page 相比, Frame 更像我们印象中的一个网页,它关注的是页面的显示 (FrameView) 、页面数据的加载(FrameLoader) 、页面内的各种控制器 (Editor, EventHandler, ScriptController, etc.) 等等,可以说,这个结构表示浏览器开始从外部控制转向关注一个页面的具体描述了;Document :这个类的爷爷类是 Node ,它
15、是 DOM 树各元素的基类; Document 有个子类是 HTMLDocument ,它是整个文档 DOM 树的根结点,这样就明白了:原来 Document 就是描述具体文档的代码,看一下它的头文件,就更明白了,它的属性与方法就是围绕着各种各样的结点:Text , Comment , CDATASection , Element当然, Document 不止描述了 HTML 相关的结点,还有 XHTML 、 SVG 、 WML 等等其他类型的页面;另外, Node 的父类之一是 EventTarget ,也就是所有元素都有事件响应的能力,由于 Document 类作为 DOM 根结点的位置,因此在窗口事件发生时,它第一个接收到事件,并寻找到事件发生的目标元素,然后从目标元素开始以树的路径向上依次处理事件。RenderObject :在形成 DOM 树结点的时候, Node 会根据需要调用 RenderObject 的方法,生成 Render 结点并最终形成 Render 树,因此此类是 Render 树各种结点类的基类,它的一个孙子类 RenderView ,就是整个 Render 树的根结点。对于调用过程,这里有一段话,我认为比较明确地描述了一个场景: