這兩天在分析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
,不在安裝目錄下,所以找了老半天。
主要參考文章:
按照文中編譯環境要求搭建好,進行編譯就可以了,用 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] 举报,一经查实,本站将立刻删除。