日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

WebKit 内核源码分析 (五)

發(fā)布時(shí)間:2024/4/15 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WebKit 内核源码分析 (五) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文分析WebKithtml的解析過程,DOM節(jié)點(diǎn)樹的建立。

關(guān)鍵詞:WebKithtml解析,html tree construction,WebCore,

DOM節(jié)點(diǎn)樹,dlmu2001

1.????HTML解析模型

???????????????????????????????????????????????????????????????????????????????

1?HTML解析模型圖

上圖是HTML解析模型圖,HTML解析分成TokeniserTree Construction兩個(gè)步驟,在”WebKit中的html詞法分析

(http://blog.csdn.net/dlmu2001/archive/2010/11/09/5998130.aspx)一文中,我們已經(jīng)對(duì)Tokeniser這一步進(jìn)行了分析,本文的目標(biāo)是Tree Construction這一步。

Tree Construction輸入是token流,輸出是DOM節(jié)點(diǎn)樹。

2.????DOM

HTML DOM定義了一套標(biāo)準(zhǔn)來將html文檔結(jié)構(gòu)化,它定義了表示和修改文檔所需的對(duì)象、這些對(duì)象的行為和屬性以及對(duì)象之間的關(guān)系,可以把它理解為頁面上數(shù)據(jù)和結(jié)構(gòu)的一個(gè)樹形表示。

NodeDOM模型中的基礎(chǔ)類,它可以分成13類(見NodeType),在HTML解析中,最常見的是DocumentElementText三類。

l??Document是文檔樹的根節(jié)點(diǎn),在HTML文檔中,他派生為HTMLDocument

l??在文檔中,所有的標(biāo)簽轉(zhuǎn)化為Element類,一般它有標(biāo)簽名,并根據(jù)標(biāo)簽名繼承為特定的子類。

l??Element之間的原始文本轉(zhuǎn)化成Text類。

以一個(gè)簡(jiǎn)單的html頁面為例:

<html>

<head>

<title>test</title>

</head>

<body>

<h1>hl1</h1>

<h2>hl2</h2>

<h3>hl3</h3>

</body>

</html>

經(jīng)過解析后的節(jié)點(diǎn)樹如下(忽略換行符):


2 HTML DOM節(jié)點(diǎn)樹示例

如果沒有忽略換行符,則每個(gè)換行符就是一個(gè)Value”\n”Text節(jié)點(diǎn)。

3.????Tree Construction原理

將圖二中的節(jié)點(diǎn)樹以WebKit中的類具體化(同樣忽略換行符)。

3 Webkit HTML DOM節(jié)點(diǎn)樹示例

看到這里,你是不是覺得仿佛看到了一個(gè)呼之欲出的Tree Construction輪廓?是的,最簡(jiǎn)化的情況就是這樣,根據(jù)輸入的token,創(chuàng)建出相應(yīng)的Element派生類,然后添加到DOM樹中合適的位置,這就是Tree Construction干的事情。當(dāng)然,添加到合適的位置,這個(gè)需要一系列復(fù)雜的規(guī)則,另外,WebKitRender樹的創(chuàng)建也放到了Tree Construction階段中來,再加上CSSJavascript,所以,這就是你看到的復(fù)雜的代碼。

放出兩個(gè)函數(shù)原型,熱熱身,培養(yǎng)培養(yǎng)感情。

[cpp]?view plaincopy
  • PassRefPtr<Element>?HTMLConstructionSite::createHTMLElement(AtomicHTMLToken&?token);??
  • ??
  • void?HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken&?token);<span?style="color:#595959;FONT-SIZE:?12pt">?</span>??
  • Tree Construction流程由一個(gè)狀態(tài)“Insertion Mode”進(jìn)行控制,它影響token的處理以及是否支持CDATA部分,HTML5中給出了詳細(xì)的規(guī)則(http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#the-insertion-mode)。它也控制了在特定狀態(tài)下能夠處理的token,比如在head里面,再出現(xiàn)head標(biāo)簽,顯然是不應(yīng)該處理的。

    4.????開放元素堆棧

    為了維護(hù)即將解析的標(biāo)簽同已解析的標(biāo)簽之間的關(guān)系(此時(shí)即將解析的標(biāo)簽還沒有加入到DOM樹中),引入了開放元素堆棧m_openElements,初始狀態(tài)下,這個(gè)堆棧是空的,它是向下增長的,所以最上面的節(jié)點(diǎn)是最早加入到堆棧中的,在html文檔中,最上面的節(jié)點(diǎn)就是html元素,最底部的節(jié)點(diǎn)就是最新加入到堆棧中的。Tree Builder的時(shí)候,每碰到一個(gè)StartTagtoken,就會(huì)往m_opnElements中壓棧,碰到EndTagtoken,則出棧。像Character這樣的token,則不需要進(jìn)行壓棧出棧的動(dòng)作,只有可以包含子節(jié)點(diǎn)的tag,才做壓棧出棧的動(dòng)作。Html5的文檔中對(duì)開放元素堆棧也有說明,http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#the-stack-of-open-elements

    對(duì)于正在解析的token,除了根節(jié)點(diǎn)html,它必然是堆棧底部元素(m_openElements.top())的子節(jié)點(diǎn),所以在形成DOM樹的時(shí)候,就可以通過ContainerNode::parserAddChild這樣的接口加入到DOM節(jié)點(diǎn)樹中。

    除了正常的堆棧和壓棧,對(duì)于html,head,body元素,棧結(jié)構(gòu)(HTMLElementStack)中有專門的成員m_htmlElement,m_headElement,m_bodyElement記錄,主要是用于檢錯(cuò)糾錯(cuò)處理。

    在本文的html范例中,當(dāng)解析到<h2>hl2</h2>hl2這個(gè)charactertoken的時(shí)候,它的開放元素堆棧如下,HTMLHeadingElement是堆棧的top,所以它是hl2這個(gè)Text節(jié)點(diǎn)的parent

    4?開放元素堆棧示例

    此時(shí)的DOM節(jié)點(diǎn)樹如下:

    5 Webkit DOM節(jié)點(diǎn)數(shù)示例

    5.????元素的創(chuàng)建

    HTMLElementFactory類提供了元素的創(chuàng)建方法createHTMLElement。傳入為對(duì)應(yīng)的標(biāo)簽名,所屬的document,所屬的form(如果屬于form),在parser的時(shí)候,最后一個(gè)參數(shù)為true

    [cpp]?view plaincopy
  • PassRefPtr<HTMLElement>?HTMLElementFactory::createHTMLElement(const?QualifiedName&?qName,?Document*?document,?HTMLFormElement*?formElement,?bool?createdByParser);??
  • HTMLElementFactory中,通過一個(gè)Hash Maptag name和對(duì)應(yīng)的元素構(gòu)造函數(shù)對(duì)應(yīng)起來(gFunctionMap)tag一般對(duì)應(yīng)一個(gè)派生于HTMLElement的類。如下是HTMLHeadingElement的類層次結(jié)構(gòu)圖。

    6 HTMLHeadingElement類層次圖

    6.????其它

    HTMLConstructionSite::attach中的attach一詞,地瓜理解主要是attachDOM節(jié)點(diǎn)數(shù)上,當(dāng)然,它同時(shí)調(diào)用了Element::attachElement類的attach主要是attachRender樹上,它會(huì)創(chuàng)建對(duì)應(yīng)該ElementRendrObject

    除了m_openElementsHTMLConstructionSite同時(shí)維護(hù)了Format?元素列表m_activeFormattingElements,Formating元素就是那些格式化標(biāo)簽,包括a,b,big,code,em,font,I,fot,I,nobr,s,small,strike,strong,tt,u。為了處理這些Formatting元素的嵌套關(guān)系(此時(shí)它們可能不是父子關(guān)系,而是平級(jí),不加入到m_openElements),HTML5引入了這個(gè)列表(http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#list-of-active-formatting-elements)。

    使用gdb調(diào)試的童子,可以運(yùn)行Tools/gdb/webkit.py腳本,在print結(jié)構(gòu)體的時(shí)候得到易于理解的表示,還可以打印出節(jié)點(diǎn)樹,具體參考http://trac.webkit.org/wiki/GDB

    總結(jié)

    以上是生活随笔為你收集整理的WebKit 内核源码分析 (五)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。