日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

WebKit內(nèi)核源代碼分析(五)

 My鏡像站 2011-12-26

摘要:本文分析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解析中,最常見的是Document,Element,Text三類。

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

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

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

以一個(gè)簡單的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輪廓?是的,最簡化的情況就是這樣,根據(jù)輸入的token,創(chuàng)建出相應(yīng)的Element派生類,然后添加到DOM樹中合適的位置,這就是Tree Construction干的事情。當(dāng)然,添加到合適的位置,這個(gè)需要一系列復(fù)雜的規(guī)則,另外,WebKitRender樹的創(chuàng)建也放到了Tree Construction階段中來,再加上CSS,Javascript,所以,這就是你看到的復(fù)雜的代碼。

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

  1. PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken& token);  
  2.   
  3. 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./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./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。

  1. 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::attach,Element類的attach主要是attachRender樹上,它會(huì)創(chuàng)建對(duì)應(yīng)該ElementRendrObject。

除了m_openElements,HTMLConstructionSite同時(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./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./wiki/GDB。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多