###第一步:
DocumentLoader類中的startLoadingMainResource函數加載url返回的數據。
###第三步
######(5)開標籤處理
對於處理例如標籤,處理這個標籤的任務是實例化一個HTMLHtmlElement元素,然後吧它的父元素指向document。
實際操作過程:
先創建一個html結點,再將其父結點和當前結點傳入到一個任務隊列。同時,它會被壓入一個用於存放未遇到閉標籤的所有開標籤。
對於上面所說的任務隊列,會有函數去判斷任務的類型,然後進行不同的操作,比如本次執行的是insert任務,它會去執行一個插入的函數。再插入函數中,會先去檢查父元素是否支持子元素,如果不支持,則直接返回(就像video標籤不支持子元素)。接着再去調具體插入。
插入操作的idea:
-
先設置子元素的父結點,也就是說會把html結點的父結點指向document
-
如果沒有lastChild,就會將這個子元素作爲firstChild。
-
但是由於上面已經有一個doctype的子結點了,也就是說已經有lastChild了,就會把這個子元素的previousSibling指向老的lastChild,老的lastChild的nextSibling指向它。
-
最後把子元素設置爲當前containerNode的lastChild。這樣就建立起了html結點的父子兄弟關係。
######(6)閉標籤處理
當遇到一個閉標籤時,會把棧裏的元素一直pop出來,知道pop到第一個和它標籤名字一樣的:
例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"></meta>
</head>
<body>
<div>
<p><b>hello</b></p>
<p>demo</p>
</div>
</body>
</html>
把push和pop打印出來是這樣的:
push "HTML" m_stackDepth = 1
push "HEAD" m_stackDepth = 2
pop "HEAD" m_stackDepth = 1
push "BODY" m_stackDepth = 2
push "DIV" m_stackDepth = 3
push "P" m_stackDepth = 4
push "B" m_stackDepth = 5
pop "B" m_stackDepth = 4
pop "P" m_stackDepth = 3
push "P" m_stackDepth = 4
pop "P" m_stackDepth = 3
pop "DIV" m_stackDepth = 2
"tagName: body |type: EndTag |attr: |text: "
"tagName: html |type: EndTag |attr: |text: "
但是如果有閉標籤忘記寫了,就會這樣:
push "P" m_stackDepth = 4
push "B" m_stackDepth = 5
"tagName: p |type: EndTag |attr: |text: "
pop "B" m_stackDepth = 4
pop "P" m_stackDepth = 3
push "B" m_stackDepth = 4
push "P" m_stackDepth = 5
pop "P" m_stackDepth = 4
pop "B" m_stackDepth = 3
pop "DIV" m_stackDepth = 2
push "B" m_stackDepth = 3
######(7)自定義標籤的處理
可以把這個標籤當作span標籤