【VC++开源代码栏目提醒】:网学会员--在 VC++开源代码编辑为广大网友搜集整理了:webkit开发学习笔记第一版 - 企业软件开发绩等信息,祝愿广大网友取得需要的信息,参考学习。
由于
工作需要,最近在准备一个介绍 webkit 的 PPT 文档, 我个人断断续续
学习 webkit的
代码也有一年多了,其间也阅读了网上的一些 webkit 相关技术文章,但中文的资料很少,大部分都是 english 的,有些 E 文资料还需要翻墙。
平常由于自已记性不好,去年看过的一些模块今年再去翻时,竟然没一点印象了,悲剧。
。
。
所以,借此机会,把自已对 webkit 的理解先做下笔记,以便于以后需要时可以方便查阅。
需要说明的是,笔记记录的有我个人的理解,也有网上摘录的片段和图片,不一定正确,也会比较凌乱,希望看到的朋友及时指正,共同进步。
一. Webkit 的由来1. 十几年前的故事 1994 年,Netscape 浏览器曾占据整个浏览器市场的 90,风头无二(也很嚣张) 。
但随 把 着微软推出 win95 后, IE1.0 做为 win95 的插件发布, 开始挑战 Netscape 的霸主地位, 到发布 IE4.x,短短三年时间,打败 Netscape。
这里面虽然说有与 windows 集成的原因, 但从本身的功能上来讲, IE 从速度和对标准的支持上来讲,已真正打败了 Netscape。
此阶段的浏览器可称为第一代浏览器。
它的主要特点是单窗口型式。
竞争的最主要是访 问速度、兼容性。
原因:90 年代都大多是用 modem 拨号上网,56K/S。
2.Webkit 出生 Apple 公司在它的 MacOSX 里,集成了基于 KHTML 改进型的 WebKit 引擎的浏览器,命名为:Safari,当年苹果比较了 Gecko 和 KHTML 后,之所以选择了后者,就因为它拥有清晰的源码结构、极快的渲染速度。
(K
HTML 是由 KDE 小组开发的)随后, apple 将它
开源。
至此,第二代浏览器,基本上是三分天下: Trident: IE 系列, 以 Trident 作为内核引擎 Gecko: Firefox 是基于 Gecko 开发 WebKit: Safari Google Chrome 搜狗双核浏览器集成 IE 和 chrome QQ 浏览器 5。
WebKit 内核在手机上的应用也十分广泛, 例如 Google 的手机 Gphone、 Apple 的 iPhoneNokia’sSeries60browser 等所使用的 Browser 内核引擎,都是基于 WebKit。
总结:webkit 是什么?答:Webkit 是一套浏览器排版
代码, 已
开源,主要由 apple 公司在维护。
强调: webkit仅仅是一套排版引擎,举个例子说明下: google 的 chrome 是一个浏览器对吧, 那 chrome 主要包含以下模块: 外壳 UI(多标签,菜单,状态栏,网址输入栏等) ,读取网络数据的模块,排版解析模块,JS 解析引擎。
外壳 UI 是 google 自已写的,js 引擎是 google 写的 V8 读取网络数据模块用的 winhttp,只有排版引擎用的 webkit。
不知道我说清楚了没,呵呵。
WebKit is an open source Web content engine for browsers and other applications. We valuereal‐world web compatibility standards compliance stability performance security portabilityusabilityandrelativeeaseofunderstandingandmodifyingthecodehackability.二. Webkit 编译环境Webkit 的官网:http://www.webkit.org/说明:下面的几种编译方法,越往下面看越简单噢。
1. Webkit 提供以下几种主要的编译环境 1.MaxosXXcodeToolspackage 2.WindowsVisualStudio 最为常用,毕竟用 winxp 系统的还是多数 3.QT 4.GTK 具体的环境搭建见:http://www.webkit.org/building/tools.html2. WebKitwinxp 下编译小结 网上很多人抱怨 webkit 总是编译不过,确实, webkit 没有提供一个下载
代码后, 在 直接可以用 VS 工具编译的方法, 因为它用到了 gcc 编译环境, windows 下编译的话, 需要安装 cygwin 才行,由于它的编译脚本用的 perl,又需要安装 perl 的环境。
总之比 较麻烦。
这也是因为网上的文章,有介绍 QT 安装环境的,有的是介绍官方 webkit 的安装环 境的,还有的是介绍 safari 的, 所以在网上查阅
文档时一定要找到你相对应的才行。
重点要注意的地方: 1. 下载 Cygwin,一定要下载 webkit 提供的版本。
2. 用 vs2005 的话,一定要打 SP1. 3. QuickTimeSDK 和 directXSDK 必不可少。
4.启动 Cygwin ,安装官网方法,执行./WebkitTools/Scripts/build‐webkit 脚本。
3. 较简单的编译安装 QTwebkit 直接在 QT 的官网下载如:qt‐sdk‐win‐opensource‐2009.04.exe该版本是我 09 年下半年使 用的,官网上应该早有新版本了不需要 cygwin 不需要 quickTime,只需要执行下面几个步骤:1、下载安装 Visual.Studio.net.2005,或 2008;2、将 qt‐sdk‐win‐opensource‐2009.04.exe 解压到某个目录下;以 D:qt4.5.0 为例3、配置环境变量:在“我的电脑”—“属性”‐‐‐“高级”‐‐‐环境变量‐‐‐的用户变量‐‐‐新建,添加一个变量名为 QTDIR 变量值为 D:qt4.5.0qt‐win‐opensource‐src‐4.5.0PATH 变量值为 D:qt4.5.0qt‐win‐opensource‐src‐4.5.0bin添加新的环境变量名字为quotQMAKESPECquot值为quotwin32‐msvc2005quot.4、编译源
代码通过quot开始quot菜单 ‐gtquotMicrosoftVisualStudio2005quot‐gtquotVisualStudioToolsquot 运行命令行....到 qt 源码的目录下运行命令:gtconfigure.exe‐
webkit编译过程中会问一个问题:是否接受 GPL 协议选y.经过一段时间以后qmake 被编译出来了.接着编译一大堆
代码简单的敲入 nmake 即可.5、编译应用程序gtqmakegtnmake就会在该应用
程序下,就会在 debug 目录下生成可以执行文件。
不过我个人不太喜欢 QT,只是安装了跑一跑,QT 的安装环境包含了 webkit 的源
代码, 同时它自带了一个简单的 Browser 项目如下:编译运行。
在 Visual Studio 中设置 browser 工程为主工程,然后编译。
可以顺利编译完成,下面是运行后的效果图。
4. 最最简单的 webkit 学习环境‐ISee5. Isee 是一位中国人移植的 webkit, 在 winxp 下用 vs2008 直接编译即可调试,用于学习 最好,强烈支持,也是一位同事推荐给我的,后面的
代码走读主要基于该环境。
6. Isee 还可以直接移植到 wince 平台运行噢。
7. 官网:http://code.google.com/p/iseebrowser/ 备注:原作者已经不再维护了。
所以 webkit 内核的版本号有点老。
8. webkit 在 vs2008 中编译 见 :http://xjchilli.blog.163.com/blog/static/45347739200910/三. Webkit 整体介绍 1. Webkit 的结构图以 ISee 架构举例: cairo 一个 2D 绘图库 casqt Unicode 处理用的库,从 QT 中抽取部分
代码形成的 expat 一个 XMLSAX 解析器的库 freetype 矢量字库接口库,用于存取 ttf 矢量字体文件 libcurl 一个
开源的 url 库,支持 HTTP、FTP 等协议 Libjpeglibpng 图像解码库 lib
xml 基于 DOM 树的 XML 解析器 libxslt XMLtransformengine pthread Pthread 库, portofthePOSIXthreadlibrary sqlite3 一个小型的数据库,据称在型入式平台是存取速度最快的数据 库。
开源, 编译后就一个 400K 的
sqlite.dll。
移植非常方便,纯 C 写的。
wceshunt 一个用于 WindowsCE 平台下的 C
常用函数封装库 Zlib Zlib 库。
用于解
压缩。
2. Webkit 源
代码由三大模块组成: 1.WebCore, 2.WebKit, 3.JavaScriptCore。
WebCore:排版引擎核心,WebCore 包含主要以下模块:Loader ParserDOMRender LayoutPaint。
WebKit:移植层,主要包含: GUI,FileSystemThread,Text,图片编解码等与平台相 关的函数。
JavaScriptCore:JS 虚拟机,相对独立,主要用于操作 DOM, DOM 是 W3C 定义的规范, 主要用于定义外部可以操作的浏览器内核的接口,而 webcore 必须实现 DOM 规范。
具体的 DOM 规范可以查 w3c. 3. WebKit 分模块介绍这里简单列出,后面再具体介绍 Webkit 平台相关 1 CURL 网络库 2 libPngLibJpeg 图形处理相关 3 sqlite 小型关系数据库 WebCore 核心 1 Loader 加载资源及 Cache 实现Curl 2 DOM:HTML 词法分析与语法分析 3 DOM:DOM 节点与 Render 节点创建,形成 DOM 树 4 Render:Render 树介绍,RenderBox 5 Layout:排版介绍 6 CssParser 模块 7 Binding‐DOM 与
JavascriptCore 绑定的功能 JavascriptCore‐javascript 引擎 1 API‐基本 javascript 功能 2 Binding 与其它功能绑定的功能如:DOMCJNI 3 DerviedSource 自动产生的
代码 4 PCRE‐Perl‐CompatibleRegularExpressions 5 KJS‐JavascriptKernel4. 页面的整个处理流程—简单介绍,详细流程在后面笔记中 1. 用户输入网址后,FrameLoader::load 函数会接收到 URL。
2. 把 URL 请求传给 CURL 库。
3. CURL 发出 http 请求,得到数据后,传给 Loader,开始解析。
4. 通过 DomBuilder 按 W3C 的 html 规范生成 Dom 树 5. 如果有 javascript,JSEngine 就通过 ECMA‐262 标准完善 Dom 树 6. 在生成 DOM 树的同时, 同步生成 Render 树。
7. 解析完后, 调用 Layout 排版 8. Paint 出来Webkit‐libCurl 库介绍 前面有说道 webkit 仅仅是一个页面排版的引擎, 对 所以, webkit 来说,网页数据(html文件,图片,.css.js 文件)的请求与接收都是通过第三方的库:libCurl 来处理。
打开 webkit 开发工程.sln即可以看到,libcurl 可以被静态或动态链接到主工程中。
Libcurl 就是指的 curl只是在 webkit 工程中,不作为单独的进程存在,而是被编译成动态库。
webkit 主要用到 curl 的以下功能: 1 Http 协议。
包含:GetputPostCookie 管理。
2 https 协议。
3 本地文件缓存。
前进,后退管理Webkit 具体调用了哪些 curl 接口,详见后面 Loader 模块介绍章节。
这里简单列举: 1 curl_global_initCURL_GLOBAL_ALL 2 curl_multi_init 3 curl_share_init 4 curl_share_setopt 5 curl_easy_getinfo 6 curl_multi_fdset 7 curl_multi_perform 8 curl_multi_info_read 9 curl_multi_cleanup 10 curl_share_cleanup 11 curl_global_cleanup可以看到,由于 webkit 要支持同时请求多个 http 数据,所以用到的是 curl 的 multi 接口。
在介绍 Loader 之前,先介绍一下 libcurl,打下基础。
以下附一篇 libcurl 的介绍:一、 概念1. 为什么要使用 libcurl1 作为 http 的客户端,可以直接用 socket 连接服务器,然后对到的数据进行 http解析,但要分析协议头,实现代理…这样太麻烦了。
2 libcurl 是一个
开源的客户端 url 传输库,支持 FTP,FTPS,TFTP,HTTP,HTTPS,GOPHER,TEL
NET,DICT,FILE 和 LDAP,支持 Windows,Unix,Linux 等平台,简单易用,且库文件占用空间不到 200K2. get 和 post 方式客户端在 http 连接时向服务提交数据的方式分为 get 和 post 两种1 Get 方式将所要传输的数据附在网址后面,然后一起送达服务器,它的优点是效率比较高;缺点是安全性差、数据不超过 1024 个字符、必须是 7 位的 ASCII 编码;
查询时经常用此方法。
2 Post 通过 Http post 处理发送数据,它的优点是安全性较强、支持数据量大、支持字符多;缺点是效率相对低;编辑修改时多使用此方法。
3. cookie 与 session1 cookiecookie 是发送到客户浏览器的文本串句柄,并保存在客户机硬盘上,可以用来在某个 Web站点会话之间持久地保持数据。
cookie 在客户端。
2 sessionsession 是访问者从到达某个特定主页到离开为止的那段时间。
每一访问者都会单独获得一个 session,实现站点多个用户之间在所有页面中共享信息。
session 在服务器上。
3 libcurl 中使用 cookie保存 cookie 使之后的链接与此链接使用相同的 cookiea 在关闭链接的时候把 cookie 写入指定的文件curl_easy_setoptcurlCURLOPT_COOKIEJARquot/tmp/cookie.txtquotb 取用现在有的 cookie,而不重新得到 cookiecurl_easy_setoptcurlCURLOPT_COOKIEFILEquot/tmp/cookie.txtquotb http 与 https 的区别1 Http 是明文发送,任何人都可以拦截并读取内容2 Https 是加密传输协议,用它传输的内容都是加密过的,https 是 http 的扩展,其安全基础是 SSL 协议c base64 编码1 为什么要使用 base64 编码如果要传一段包含特殊字符比较多的数据, 直接上传就需要处理转意符之类的很多
问题, 用base64 编码,它可以把数据转成可读的字串,base64 由 a‐zA‐Z/总计 64 个字符组成。
2 传送 base64 编码的注意事项由于 base64 的组成部分有加号, 而加号是 url 中的转意字符,所以无论是 get 方式还是 post,传到服务器的过程中,都会把加号转成空格,所以在传 base64 之前需要把 base64 编码后的加号替换成”2B” ,这样就可以正常发送了。
二、 例程d
代码includeltstdio.hgtincludeltcurl/curl.hgtboolgetUrlcharfilename CURLcurl CURLcoderes FILEfp iffpfopenfilenamequotwquotNULL // 返回结果用文件存储 returnfalse structcurl_slistheadersNULL headerscurl_slist_appendheadersquotAccept:Agent‐007quot curlcurl_easy_init // 初始化 ifcurl curl_easy_setoptcurlCURLOPT_PROXYquot10.99.60.201:8080quot// 代理 curl_easy_setoptcurlCURLOPT_HTTPHEADERheaders// 改协议头 curl_easy_setoptcurl CURLOPT_URLquothttp://www.google.com/searchhlenampqxieyan0811ampbtnGGoogleSearchampaqfampoqxieyan081quot curl_easy_setoptcurlCURLOPT_WRITEDATAfp rescurl_easy_performcurl // 执行 curl_slist_free_allheaders curl_easy_cleanupcurl fclosefp returntrueboolpostUrlcharfilename CURLcurl CURLcoderes FILEfp iffpfopenfilenamequotwquotNULL returnfalse curlcurl_easy_init ifcurl curl_easy_setoptcurlCURLOPT_COOKIEFILEquot/tmp/cookie.txtquot// 指定 cookie 文件 //curl_easy_setoptcurlCURLOPT_COOKIEJARquot/tmp/cookie.txtquot curl_easy_setoptcurl CURLOPT_POSTFIELDSquotamplogintypeuidampuxieyanamppswxxx86quot // 指定 post 内容 curl_easy_setoptcurlCURLOPT_PROXYquot10.99.60.201:8080quot curl_easy_setoptcurl CURLOPT_URL quothttp://mail.sina.com.cn/cgi‐bin/login.cgiquot// 指定 url curl_easy_setoptcurlCURLOPT_WRITEDATAfp rescurl_easy_performcurl curl_easy_cleanupcurl fclosefp returntrueintmainvoid getUrlquot/tmp/get.htmlquot postUrlquot/tmp/post.htmlquote 编译 gmain.cpp‐omain‐lcurlWebkitLoader 模块介绍 前面说过, webkit 只是一个排版引擎,在 Webkit 排版/渲染一个网页之前, 它肯定需要从
网络上、或者本地文件
系统中读到网页的 http 数据,对吧,对 webkit 来讲,他要的就是数据,不管你是从网络读的还是本地文件读的。
Loader 就是这样一个模块,它承上启下,不仅负责为 webkit 引擎提供数据,还控制着webkit 的绘制。
另外,它同时还与提供数据的“来源”打交道。
先简单举例说明: 用户输入一个 url,这时是 Loader 接收 url 请求,它把 url 传递给 curl,设置 curl 的回调函数,当 curl 读到数据,loader 把数据传递给 Parser,开始生成 DOM。
一.下面重点介绍一下与 Loader 相关的数据结构和模块。
Frame:可以看做是浏览器外壳调用 Loader 的总入口,它就像我们印象中的一个网页,它关注的是页面的显示 FrameView 、页面数据的加载FrameLoader 、页面内的各种控制器EditorEventHandlerScriptControlleretc. 等等,它包含以下模块(只列出重点):DocumentPageFrameViewRenderViewFrameLoaderDOMWindow下面分别介绍PS: 必须要了解这些概念,不然后面的东东都无法理解:1Document:这个类的爷爷类是 Node , 它是 DOM 树各元素的基类; Document 有个子类是 HTMLDocument ,它是整个
文档 DOM 树的根结点,这样就明白了:原来 Document 就是描述具体文档的
代码,看一下它的头文件,就更明白了,它的属性与方法就是围绕着各种各样的结点: Text , Comment , CDATASection , Element……2Page: 我的理解是, Page 与 Frame严格说是 FrameView是一一对应的, Frame 关注 UI,Page关注数据。
现在的浏览器一般都提供同时打开多个窗口,每一个窗口对应的数据就是这个Page 在管理了。
在 page.cpp 文件里, 还有个重要的全局指针变量: staticHashSetltPagegtallPages 这个变量包含了所有的 page 实例。
3FrameView: 可以理解为为一个网页的 ViewPort 它提供一个显示区域,同时包含的有Render 根节点、layout 排版相关接口、Scroll 相关等。
FrameView 是 Layout 排版的总入口。
4RenderView: 与 FrameView 差不多,只是分工不同,它管理与 Render 树相关的东东。
5 FrameLoader:重点,FrameLoader 类将 Documents 加载到 Frames。
当点击一个链接时,FrameLoader 创建一个新的处于“policy”状态的 DocumentLoader 对象,一旦 webkit 指示FrameLoader 将本次加载视为一个
导航navigation,FrameLoader 就推动 DocumentLoader 进入“provisional”状态,(在该状态,DocumentLoader 发调用 CURL 发起一个网络请求,并等待是 html 还是下载文件。
)同时DocumentLoader 会创建一个 MainResourceLoader 对象(该对象在后面单独介绍) 。
6)。
DOMWindow: 实现了 Dom 的一些接口,如 CreateNode 等。
后面可以详细讲讲。
上面介绍的概念比较多,我也不晓得好不好理解,没理解也不怕,多去看看
代码,这是必须的。
另外看看下面的图,就会清晰很多的.