介紹下webkit對於html元素的解析流程.
DocumentLoader收到html後通過DocumentWriter調用HTMLDocumentParser::appendBytes,然後通過DocumentWriter解碼後,調用HTMLDocumentParser::append添加到HTMLInputStream中,如果當前有js在執行,就調用HTMLPreloadScanner預先下載一些img和css資源,如果有被suspend,就等待HTMLParserScheduler來resume,調用HTMLTokenizer來獲取一個HTMLToken,並且調用HTMLTreeBuilder來建立DOM
Tree,如果有Script需要運行,就把HTMLTreeBuilder給pause,然後在下次獲取Token前,通過HTMLScriptRunner來執行相應的Script。
解析過程中主要涉HTMLTreeBuilder.cpp,HTMLTokenizer.cpp,HTMLDocumentParser.cpp.其中setInsertionMode主要是記錄解析的狀態。
HTMLTokenizer提供了nextToken的方法用來解析HTMLInputStream,每次調用解析出一個token(包含tagname和其他的屬性名和屬性值)交給HTMLTreeBuilder的processToken方法進行處理。如下是具體的解析過程:
假設有下列HTML文件:
<html>
<head>
<link rel="prefetch" type="text/html" href="http://127.0.0.1/index.html" />
</head>
<body>
test
</body>
</html>
1. 解析到token的tagname爲html,類型爲StartTag,交給HTMLTreeBuilder的processToken的方法處理,processStartTag---->defaultForInitial--->setInsertionMode(BeforeHTMLMode)---> m_tree.insertHTMLHtmlStartTagBeforeHTML(token)--->創建html元素(HTMLHtmlElement類)的對象並m_openElements.pushHTMLHtmlElement--->Node.attach()
2. 解析到token的類型爲character,交給HTMLTreeBuilder的processToken的方法處理,processCharacter(token)
3. 解析到token的tagname爲head,類型爲StartTag,交給HTMLTreeBuilder的processToken的方法處理,processStartTag----> m_tree.insertHTMLHeadElement(token)--->創建head元素(HTMLHeadElement類)的對象並m_openElements.pushHTMLHeadElement--->Node.attach()
4. 解析到token的類型爲character,交給HTMLTreeBuilder的processToken的方法處理,processCharacter(token)
5. 解析到token的tagname爲link,類型爲StartTag,交給HTMLTreeBuilder的processToken的方法處理,processStartTag---> processStartTagForInHead(token)---> m_tree.insertSelfClosingHTMLElement(token)--->創建link元素(HTMLLinkElement類)的對象,進入HTMLLinkElement類進行一些實際的操作,比如檢查屬性,根據存在的屬性進行相關操作。--->Node.attach()
6. 解析到token的類型爲character,交給HTMLTreeBuilder的processToken的方法處理,processCharacter(token)
7. 解析到token的tagname爲head,類型爲EndTag,交給HTMLTreeBuilder的processToken的方法處理,processEndTag(token)---> m_tree.openElements()->popHTMLHeadElement()--->setInsertionMode(AfterHeadMode) --->Node.attach()
8. 解析到token的類型爲character,交給HTMLTreeBuilder的processToken的方法處理,processCharacter(token)
9. 解析到token的tagname爲body,類型爲StartTag,交給HTMLTreeBuilder的processToken的方法處理, processStartTag(token)---> m_framesetOk = false--->創建body元素(HTMLBodyElement類)的對象並pushHTMLBodyElement(attachToCurrent(body元素的對象))---> attach(currentNode(), body對象)--->Node.attach()
10. 解析到token的類型爲character,交給HTMLTreeBuilder的processToken的方法處理,processCharacter(token)---> processCharacterBuffer(buffer)--->獲取到characters值爲test--->m_tree.insertTextNode(characters)--->attachAtSite--->Text::attach()--->Node::createRendererIfNeeded()--->Node.attach()
11. 解析到token的tagname爲body,類型爲EndTag,交給HTMLTreeBuilder的processToken的方法處理, processEndTag(token)---> processEndTagForInBody(token)---> processBodyEndTagForInBody(token)---> setInsertionMode(AfterBodyMode)
12. 解析到token的類型爲character,交給HTMLTreeBuilder的processToken的方法處理,processCharacter(token)---> processCharacterBuffer---> m_tree.insertTextNode(characters)
13. 解析到token的tagname爲html,類型爲EndTag,交給HTMLTreeBuilder的processToken的方法處理, processEndTag(token)---> processEndTagForInBody(token)---> setInsertionMode(AfterAfterBodyMode)
14. 解析到token的類型爲EndOfFile,交給HTMLTreeBuilder的processToken的方法處理, processEndOfFile(token)---> m_tree.openElements()->popAll()將HTMLElementStack清空。
希望對大家有用,現在搞webkit的人真少~~~.
附有HTML5 a標籤
屬性 | 值 | 描述 |
---|---|---|
charset | char_encoding | HTML 5 中不支持。 |
coords | coordinates | HTML 5 中不支持。 |
href | URL | 鏈接的目標 URL。 |
hreflang | language_code | 規定目標 URL 的基準語言。僅在 href 屬性存在時使用。 |
media | media query |
規定目標 URL 的媒介類型。 默認值:all。僅在 href 屬性存在時使用。 |
name | section_name | HTML 5 中不支持。 |
rel |
|
規定當前文檔與目標 URL 之間的關係。 僅在 href 屬性存在時使用。 |
rev | text | HTML 5 中不支持。 |
shape |
|
HTML 5 中不支持。 |
target |
|
在何處打開目標 URL。僅在 href 屬性存在時使用。 |
type | mime_type |
規定目標 URL 的 MIME 類型。僅在 href 屬性存在時使用。 注:MIME = Multipurpose Internet Mail Extensions。 |