OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. | 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. |
3 * Copyright (C) 2011 Apple Inc. All rights reserved. | 3 * Copyright (C) 2011 Apple Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 23 matching lines...) Expand all Loading... |
34 #include "wtf/PassRefPtr.h" | 34 #include "wtf/PassRefPtr.h" |
35 #include "wtf/RefPtr.h" | 35 #include "wtf/RefPtr.h" |
36 #include "wtf/Vector.h" | 36 #include "wtf/Vector.h" |
37 #include "wtf/text/StringBuilder.h" | 37 #include "wtf/text/StringBuilder.h" |
38 | 38 |
39 namespace WebCore { | 39 namespace WebCore { |
40 | 40 |
41 struct HTMLConstructionSiteTask { | 41 struct HTMLConstructionSiteTask { |
42 enum Operation { | 42 enum Operation { |
43 Insert, | 43 Insert, |
| 44 InsertText, // Handles possible merging of text nodes. |
44 InsertAlreadyParsedChild, // Insert w/o calling begin/end parsing. | 45 InsertAlreadyParsedChild, // Insert w/o calling begin/end parsing. |
45 Reparent, | 46 Reparent, |
46 TakeAllChildren, | 47 TakeAllChildren, |
47 }; | 48 }; |
48 | 49 |
49 explicit HTMLConstructionSiteTask(Operation op) | 50 explicit HTMLConstructionSiteTask(Operation op) |
50 : operation(op) | 51 : operation(op) |
51 , selfClosing(false) | 52 , selfClosing(false) |
52 { | 53 { |
53 } | 54 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 class HTMLFormElement; | 90 class HTMLFormElement; |
90 | 91 |
91 class HTMLConstructionSite { | 92 class HTMLConstructionSite { |
92 WTF_MAKE_NONCOPYABLE(HTMLConstructionSite); | 93 WTF_MAKE_NONCOPYABLE(HTMLConstructionSite); |
93 public: | 94 public: |
94 HTMLConstructionSite(Document*, ParserContentPolicy); | 95 HTMLConstructionSite(Document*, ParserContentPolicy); |
95 HTMLConstructionSite(DocumentFragment*, ParserContentPolicy); | 96 HTMLConstructionSite(DocumentFragment*, ParserContentPolicy); |
96 ~HTMLConstructionSite(); | 97 ~HTMLConstructionSite(); |
97 | 98 |
98 void detach(); | 99 void detach(); |
| 100 |
| 101 // executeQueuedTasks empties the queue but does not flush pending text. |
| 102 // NOTE: Possible reentrancy via JavaScript execution. |
99 void executeQueuedTasks(); | 103 void executeQueuedTasks(); |
100 | 104 |
| 105 // flushPendingText turns pending text into queued Text insertions, but does
not execute them. |
| 106 void flushPendingText(); |
| 107 |
| 108 // flush calls both flushPendingText and executeQueuedTasks. |
| 109 // NOTE: Possible reentrancy via JavaScript execution. |
| 110 void flush(); |
| 111 |
101 void setDefaultCompatibilityMode(); | 112 void setDefaultCompatibilityMode(); |
102 void processEndOfFile(); | 113 void processEndOfFile(); |
103 void finishedParsing(); | 114 void finishedParsing(); |
104 | 115 |
105 void insertDoctype(AtomicHTMLToken*); | 116 void insertDoctype(AtomicHTMLToken*); |
106 void insertComment(AtomicHTMLToken*); | 117 void insertComment(AtomicHTMLToken*); |
107 void insertCommentOnDocument(AtomicHTMLToken*); | 118 void insertCommentOnDocument(AtomicHTMLToken*); |
108 void insertCommentOnHTMLHtmlElement(AtomicHTMLToken*); | 119 void insertCommentOnHTMLHtmlElement(AtomicHTMLToken*); |
109 void insertHTMLElement(AtomicHTMLToken*); | 120 void insertHTMLElement(AtomicHTMLToken*); |
110 void insertSelfClosingHTMLElement(AtomicHTMLToken*); | 121 void insertSelfClosingHTMLElement(AtomicHTMLToken*); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 // and a Document in all other cases. | 220 // and a Document in all other cases. |
210 ContainerNode* m_attachmentRoot; | 221 ContainerNode* m_attachmentRoot; |
211 | 222 |
212 RefPtr<HTMLStackItem> m_head; | 223 RefPtr<HTMLStackItem> m_head; |
213 RefPtr<HTMLFormElement> m_form; | 224 RefPtr<HTMLFormElement> m_form; |
214 mutable HTMLElementStack m_openElements; | 225 mutable HTMLElementStack m_openElements; |
215 mutable HTMLFormattingElementList m_activeFormattingElements; | 226 mutable HTMLFormattingElementList m_activeFormattingElements; |
216 | 227 |
217 TaskQueue m_taskQueue; | 228 TaskQueue m_taskQueue; |
218 | 229 |
| 230 struct PendingText { |
| 231 PendingText() |
| 232 : whitespaceMode(WhitespaceUnknown) |
| 233 { |
| 234 } |
| 235 |
| 236 void append(PassRefPtr<ContainerNode> newParent, PassRefPtr<Node> newNex
tChild, const String& newString, WhitespaceMode newWhitespaceMode) |
| 237 { |
| 238 ASSERT(!parent || parent == newParent); |
| 239 parent = newParent; |
| 240 ASSERT(!nextChild || nextChild == newNextChild); |
| 241 nextChild = newNextChild; |
| 242 stringBuilder.append(newString); |
| 243 whitespaceMode = std::min(whitespaceMode, newWhitespaceMode); |
| 244 } |
| 245 |
| 246 void swap(PendingText& other) |
| 247 { |
| 248 std::swap(whitespaceMode, other.whitespaceMode); |
| 249 parent.swap(other.parent); |
| 250 nextChild.swap(other.nextChild); |
| 251 stringBuilder.swap(other.stringBuilder); |
| 252 } |
| 253 |
| 254 bool isEmpty() |
| 255 { |
| 256 // When the stringbuilder is empty, the parent and whitespace should
also be "empty". |
| 257 ASSERT(stringBuilder.isEmpty() == !parent); |
| 258 ASSERT(!stringBuilder.isEmpty() || !nextChild); |
| 259 ASSERT(!stringBuilder.isEmpty() || (whitespaceMode == WhitespaceUnkn
own)); |
| 260 return stringBuilder.isEmpty(); |
| 261 } |
| 262 |
| 263 RefPtr<ContainerNode> parent; |
| 264 RefPtr<Node> nextChild; |
| 265 StringBuilder stringBuilder; |
| 266 WhitespaceMode whitespaceMode; |
| 267 }; |
| 268 |
| 269 PendingText m_pendingText; |
| 270 |
219 ParserContentPolicy m_parserContentPolicy; | 271 ParserContentPolicy m_parserContentPolicy; |
220 bool m_isParsingFragment; | 272 bool m_isParsingFragment; |
221 | 273 |
222 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.
html#parsing-main-intable | 274 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.
html#parsing-main-intable |
223 // In the "in table" insertion mode, we sometimes get into a state where | 275 // In the "in table" insertion mode, we sometimes get into a state where |
224 // "whenever a node would be inserted into the current node, it must instead | 276 // "whenever a node would be inserted into the current node, it must instead |
225 // be foster parented." This flag tracks whether we're in that state. | 277 // be foster parented." This flag tracks whether we're in that state. |
226 bool m_redirectAttachToFosterParent; | 278 bool m_redirectAttachToFosterParent; |
227 | 279 |
228 bool m_inQuirksMode; | 280 bool m_inQuirksMode; |
229 }; | 281 }; |
230 | 282 |
231 } // namespace WebCore | 283 } // namespace WebCore |
232 | 284 |
233 #endif | 285 #endif |
OLD | NEW |