微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

WebKit移植分析之一

這兩天在分析WebKit的移植,順便也貼出來吧,同道中人有看到也順便探討探討

 

<!-- /* Font DeFinitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:Simsun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:-1610611985 1107304683 0 0 159 0;} @font-face {font-family:Cambria; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:-1610611985 1073741899 0 0 159 0;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-1610611985 1073750139 0 0 159 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:新宋体; panose-1:2 1 6 9 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@新宋体"; panose-1:2 1 6 9 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:3 135135232 16 0 262145 0;} /* Style DeFinitions */ p.Msonormal,li.Msonormal,div.Msonormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-fareast-font-family:宋体; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt;} h1 {mso-style-priority:9; mso-style-unhide:no; mso-style-qformat:yes; mso-style-link:"标题 1 Char"; mso-style-next:正文; margin-top:17.0pt; margin-right:0cm; margin-bottom:16.5pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:240%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:1; font-size:22.0pt; font-family:"Calibri","sans-serif"; mso-font-kerning:22.0pt;} h2 {mso-style-priority:9; mso-style-qformat:yes; mso-style-link:"标题 2 Char"; mso-style-next:正文; margin-top:13.0pt; margin-right:0cm; margin-bottom:13.0pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:173%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:2; font-size:16.0pt; font-family:"Cambria","serif"; mso-font-kerning:1.0pt;} h3 {mso-style-priority:9; mso-style-qformat:yes; mso-style-link:"标题 3 Char"; mso-style-next:正文; margin-top:13.0pt; margin-right:0cm; margin-bottom:13.0pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:173%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:3; font-size:16.0pt; font-family:"Calibri","sans-serif"; mso-font-kerning:1.0pt;} h4 {mso-style-priority:9; mso-style-qformat:yes; mso-style-link:"标题 4 Char"; mso-style-next:正文; margin-top:14.0pt; margin-right:0cm; margin-bottom:14.5pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:156%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:4; font-size:14.0pt; font-family:"Cambria","serif"; mso-font-kerning:1.0pt;} a:link,span.MsoHyperlink {mso-style-priority:99; color:blue; text-decoration:underline; text-underline:single;} a:visited,span.MsoHyperlinkFollowed {mso-style-noshow:yes; mso-style-priority:99; color:purple; mso-themecolor:followedhyperlink; text-decoration:underline; text-underline:single;} span.1Char {mso-style-name:"标题 1 Char"; mso-style-priority:9; mso-style-unhide:no; mso-style-locked:yes; mso-style-link:"标题 1"; mso-ansi-font-size:22.0pt; mso-bidi-font-size:22.0pt; mso-font-kerning:22.0pt; font-weight:bold;} span.2Char {mso-style-name:"标题 2 Char"; mso-style-priority:9; mso-style-unhide:no; mso-style-locked:yes; mso-style-link:"标题 2"; mso-ansi-font-size:16.0pt; mso-bidi-font-size:16.0pt; font-family:"Cambria","serif"; mso-ascii-font-family:Cambria; mso-hansi-font-family:Cambria; mso-font-kerning:1.0pt; font-weight:bold;} span.3Char {mso-style-name:"标题 3 Char"; mso-style-priority:9; mso-style-unhide:no; mso-style-locked:yes; mso-style-link:"标题 3"; mso-ansi-font-size:16.0pt; mso-bidi-font-size:16.0pt; mso-font-kerning:1.0pt; font-weight:bold;} span.4Char {mso-style-name:"标题 4 Char"; mso-style-priority:9; mso-style-unhide:no; mso-style-locked:yes; mso-style-link:"标题 4"; mso-ansi-font-size:14.0pt; mso-bidi-font-size:14.0pt; font-family:"Cambria","serif"; mso-ascii-font-family:Cambria; mso-hansi-font-family:Cambria; mso-font-kerning:1.0pt; font-weight:bold;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; font-size:10.0pt; mso-ansi-font-size:10.0pt; mso-bidi-font-size:10.0pt; mso-ascii-font-family:Calibri; mso-fareast-font-family:宋体; mso-hansi-font-family:Calibri; mso-font-kerning:0pt;} /* Page DeFinitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page WordSection1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.WordSection1 {page:WordSection1;} -->

WebKit 分析

簡介

 

简要的说, WebKit 由三个模块组成: JavaScriptCore WebCore WebKit WebKit 作为了整个项目的名称

 

JavaScriptCore :是 JavaScript 解释器;裏面也包含了一個 WTF 庫,庫里有很多實用函數。這個 JavaScript 引擎是完全跨平臺的,可以獨立應用。

 

WebCore :是整个项目的核心,用来实现 render 引擎、解析 Web 页面生成一个 DOM 树和一个 render 树,并最终 render it with a backend ,還包括 SVG 支持,網絡支持等。

每個平臺在這部份都有他自己的代碼。 WebCore platform 目錄里就是 OS 相關的代碼以及 rendering backends( Skia,CG(Core Graphic),Cairo) 的代碼。

 

WebKit   應用程序使用到的前端層。每一個 GUI 平臺( windows cocoa Gtk+ Qt )都提供了他們自己的實現。它的目標就是作為 WebCore 層的客戶端,作為要使用 WebKit 的平臺的中間隔離層。

 

所以移植的話應該涉及到 WebCore platform 下有關特定 OS 的代碼和 WebKit 目錄下各個對應平臺的實現。

 

 

編譯過程

 

網上剛看到文章都說 WebKit 編譯很折磨人,不如 chrome 簡單。後來經過實踐, WebKit 編譯其實還可以,就是調試的時候因為一個 dll 版本不對,折騰了很久,後來才瞭解到新版的 WebKit 調試需要 4.0.5 版本后的 safari 里帶的 CoreGraphic.dll 支持,而這個 dll 又安裝在公共目錄,如C:/Program Files/Common Files/Apple/Apple Application Support
,不在安裝目錄下,所以找了老半天。

主要參考文章

http://hi.baidu.com/piperworldcup/blog/item/1c54f7af12a4b1f1faed5069.html/cmtid/d4c65b036482077b3912bb17

按照文中編譯環境要求搭建好,進行編譯就可以了,用 cygwin 的命令行進行編譯。

 

 

移植分析:

目前在 windows mac s60 都有相應的版本, wince 的移植正在開發中, s60 作為一個分支在運行,其他都是主幹代碼。要移植的目錄如下

 

要移植的目錄簡介

Webcore

Webcore/platform/win   針對 win 平臺相關的代碼

Webcore/platform/graphic 針對 cairo,cg 等圖形庫的代碼,

Webcore/platform/graphic/win  圖形庫里于 win 平臺相關的部份

WebCore/platform/network :網絡庫的實現 已有 cf,win 等實現

 

Webkit

WebKit/win   webkit 模塊 win 的具體實現

 

分析一個頁面的加載流程:

 

首先是上层调用 loader(***) ,里面就是 URL 或者是本地文件,对参数进行打包后一步一步,

FrameLoader::load

FrameLoader::loadWithDocumentLoader

FrameLoader::setPolicyDocumentLoader

FrameLoaderClient::dispatchDecidePolicyForNavigateionAction  //win =WebFrame

FrameLoader::continueAfterNavigateionPolicy

PolicyCheck::Call

FrameLoader::CallContinusLoadAfterNavigationPolicy

FrameLoader::ContinueLoadAfterWillSubmitForm

DocumentLoader::startLoadingMainResource

MainResourceLoader::load

MainResourceLoader::loadNow

ResourceHandle::start    // 會由網絡庫發起一個 http 請求

 

 

 

 

MainResourceLoader 作為一個 ResourceHandleClient ,提供了 didReceiveData didReceiveResponse 供網絡庫調用,當網絡庫得到數據后就會調用相關接口,如 didReceiveData

 

MainResourceLoader::didReceiveData 的主要調用函數如下:

MainResourceLoader::didReceiveData

ResourceLoader::didReceiveData

FrameLoader::ReceiveData

DocumentLoader::receiveData

DocumentLoader::commitLoader

FrameLoader::committedLoader

FrameLoaderClient::committedLoader  //WebFrameLoaderClient

FrameLoader::addData

FrameLoader::write

Tokenizer::write

Tokenizer::processtoken

HTMLParser::parsetoken

HTMLParser::insertNode

HTMLParser::handleError

    New HTMLHtmlElement

    New HTMLHeadElement

    New HTMLBodyElement

Node::attach

 

 


数据接收完成后会依次调到

didFinishLoading in ResourceHandleCFNet.cpp

ResourceLoader::didFinishLoading

MainResourceLoader::didFinishLoading

FrameLoader::finishedLoading          WebCore/loader

DocumentLoader::finishedLoading

FrameLoader::finishedLoadingDocument

WebFrameLoaderClient::finishedLoading  in WebKit/win/WebCoreSupport

其中就有对于数据分析和刷新 GUI 的工作。

 

 

通過 Node::attach 就會解析生成 document ,同時創建 frameview domwindow

創建的 frameview 會觸發 layoutTimerFired 時間 timer ,然後調用 layout 方法,從而觸發 RenderObject 的創建和佈局,最後也許會 invalidateRect ,而觸發操作系統的 paint 消息

 

程序主消息循環處理 paint 消息,在 paint 消息里會獲得 frame ,獲得 GraphicContext ,然後調用 frame->view->paint(&ctx) ,從而觸發 RenderObjcect 進行重畫,完整的頁面就出來了。

 

 

WebKit 移植要點

WebCore 一般定義一個接口,然後由各自的平臺來實現這個接口

 

比如網絡處理部份 WebCore 定義了 ResourceHandle

在不同的目錄下, cf,curl,win 就有不同網絡庫對 ResourceHandle 的實現

 

對於圖形庫, WebCore 提供了 GraphicsContext 類,在不同的目錄如 cairo,cg,win 下就提供了不同圖形庫對 GraphicsContext 類的實現。

 

WebKit 目錄下的 win gtm mac 分別代表不同平臺的實現,在每個目錄下的 WebCoreSupport 代表外部程序提供給 WebKit 內部使用的接口實現,如

WebCore::ChromeClient

WebCore::ContextMenuClient

WebCore::DragClient

WebCore::EditorClient

WebCore::FrameLoaderClient

WebCore::InspectorClient

這些部份一般由 Port 移植部份實現,由 WebKit 內部根據一定條件來調用

 

例如

Loader 模塊需要的外部支持 ,Loader 主要負責發起 IO 下載網頁,再發起解析和最後的渲染:

EventHandlerWin.cpp,

FrameLoaderWin.cpp,

DocumentLoaderWin.cpp,

WidgetWin.cpp,

KeyEventWin.cpp

 

WebView WebFrame 主要功能是方便外部程序嵌入,不同 Port 移植實現有所不同。

同時初始化時會把特定的接口告訴 WebKit 內部 , 這兩個是比較重要,而且比較大的實現,代碼比較多,重點 .  WebFrame Loader Client FrameLoaderClient

 

所以移植基本就是實現以上提到的這些接口。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐