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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 explicit HTMLConstructionSiteTask(Operation op) | 53 explicit HTMLConstructionSiteTask(Operation op) |
54 : operation(op), selfClosing(false) {} | 54 : operation(op), selfClosing(false) {} |
55 | 55 |
56 DEFINE_INLINE_TRACE() { | 56 DEFINE_INLINE_TRACE() { |
57 visitor->trace(parent); | 57 visitor->trace(parent); |
58 visitor->trace(nextChild); | 58 visitor->trace(nextChild); |
59 visitor->trace(child); | 59 visitor->trace(child); |
60 } | 60 } |
61 | 61 |
62 ContainerNode* oldParent() { | 62 ContainerNode* oldParent() { |
63 // It's sort of ugly, but we store the |oldParent| in the |child| field | 63 // It's sort of ugly, but we store the |oldParent| in the |child| field of |
64 // of the task so that we don't bloat the HTMLConstructionSiteTask | 64 // the task so that we don't bloat the HTMLConstructionSiteTask object in |
65 // object in the common case of the Insert operation. | 65 // the common case of the Insert operation. |
66 return toContainerNode(child.get()); | 66 return toContainerNode(child.get()); |
67 } | 67 } |
68 | 68 |
69 Operation operation; | 69 Operation operation; |
70 Member<ContainerNode> parent; | 70 Member<ContainerNode> parent; |
71 Member<Node> nextChild; | 71 Member<Node> nextChild; |
72 Member<Node> child; | 72 Member<Node> child; |
73 bool selfClosing; | 73 bool selfClosing; |
74 }; | 74 }; |
75 | 75 |
76 } // namespace blink | 76 } // namespace blink |
77 | 77 |
78 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS( | 78 WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS( |
79 blink::HTMLConstructionSiteTask); | 79 blink::HTMLConstructionSiteTask); |
80 | 80 |
81 namespace blink { | 81 namespace blink { |
82 | 82 |
83 // Note: These are intentionally ordered so that when we concatonate | 83 // Note: These are intentionally ordered so that when we concatonate strings and |
84 // strings and whitespaces the resulting whitespace is ws = min(ws1, ws2). | 84 // whitespaces the resulting whitespace is ws = min(ws1, ws2). |
85 enum WhitespaceMode { | 85 enum WhitespaceMode { |
86 WhitespaceUnknown, | 86 WhitespaceUnknown, |
87 NotAllWhitespace, | 87 NotAllWhitespace, |
88 AllWhitespace, | 88 AllWhitespace, |
89 }; | 89 }; |
90 | 90 |
91 enum FlushMode { | 91 enum FlushMode { |
92 // Flush pending text. Flush queued tasks. | 92 // Flush pending text. Flush queued tasks. |
93 FlushAlways, | 93 FlushAlways, |
94 | 94 |
(...skipping 20 matching lines...) Expand all Loading... |
115 DECLARE_TRACE(); | 115 DECLARE_TRACE(); |
116 | 116 |
117 void initFragmentParsing(DocumentFragment*, Element* contextElement); | 117 void initFragmentParsing(DocumentFragment*, Element* contextElement); |
118 | 118 |
119 void detach(); | 119 void detach(); |
120 | 120 |
121 // executeQueuedTasks empties the queue but does not flush pending text. | 121 // executeQueuedTasks empties the queue but does not flush pending text. |
122 // NOTE: Possible reentrancy via JavaScript execution. | 122 // NOTE: Possible reentrancy via JavaScript execution. |
123 void executeQueuedTasks(); | 123 void executeQueuedTasks(); |
124 | 124 |
125 // flushPendingText turns pending text into queued Text insertions, but does n
ot execute them. | 125 // flushPendingText turns pending text into queued Text insertions, but does |
| 126 // not execute them. |
126 void flushPendingText(FlushMode); | 127 void flushPendingText(FlushMode); |
127 | 128 |
128 // Called before every token in HTMLTreeBuilder::processToken, thus inlined: | 129 // Called before every token in HTMLTreeBuilder::processToken, thus inlined: |
129 void flush(FlushMode mode) { | 130 void flush(FlushMode mode) { |
130 if (!hasPendingTasks()) | 131 if (!hasPendingTasks()) |
131 return; | 132 return; |
132 flushPendingText(mode); | 133 flushPendingText(mode); |
133 executeQueuedTasks(); // NOTE: Possible reentrancy via JavaScript execution
. | 134 // NOTE: Possible reentrancy via JavaScript execution. |
| 135 executeQueuedTasks(); |
134 ASSERT(mode == FlushIfAtTextLimit || !hasPendingTasks()); | 136 ASSERT(mode == FlushIfAtTextLimit || !hasPendingTasks()); |
135 } | 137 } |
136 | 138 |
137 bool hasPendingTasks() { | 139 bool hasPendingTasks() { |
138 return !m_pendingText.isEmpty() || !m_taskQueue.isEmpty(); | 140 return !m_pendingText.isEmpty() || !m_taskQueue.isEmpty(); |
139 } | 141 } |
140 | 142 |
141 void setDefaultCompatibilityMode(); | 143 void setDefaultCompatibilityMode(); |
142 void processEndOfFile(); | 144 void processEndOfFile(); |
143 void finishedParsing(); | 145 void finishedParsing(); |
(...skipping 13 matching lines...) Expand all Loading... |
157 void insertForeignElement(AtomicHTMLToken*, const AtomicString& namespaceURI); | 159 void insertForeignElement(AtomicHTMLToken*, const AtomicString& namespaceURI); |
158 | 160 |
159 void insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken*); | 161 void insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken*); |
160 void insertHTMLHtmlStartTagInBody(AtomicHTMLToken*); | 162 void insertHTMLHtmlStartTagInBody(AtomicHTMLToken*); |
161 void insertHTMLBodyStartTagInBody(AtomicHTMLToken*); | 163 void insertHTMLBodyStartTagInBody(AtomicHTMLToken*); |
162 | 164 |
163 void reparent(HTMLElementStack::ElementRecord* newParent, | 165 void reparent(HTMLElementStack::ElementRecord* newParent, |
164 HTMLElementStack::ElementRecord* child); | 166 HTMLElementStack::ElementRecord* child); |
165 void reparent(HTMLElementStack::ElementRecord* newParent, | 167 void reparent(HTMLElementStack::ElementRecord* newParent, |
166 HTMLStackItem* child); | 168 HTMLStackItem* child); |
167 // insertAlreadyParsedChild assumes that |child| has already been parsed (i.e.
, we're just | 169 // insertAlreadyParsedChild assumes that |child| has already been parsed |
168 // moving it around in the tree rather than parsing it for the first time). Th
at means | 170 // (i.e., we're just moving it around in the tree rather than parsing it for |
169 // this function doesn't call beginParsingChildren / finishParsingChildren. | 171 // the first time). That means this function doesn't call beginParsingChildren |
| 172 // / finishParsingChildren. |
170 void insertAlreadyParsedChild(HTMLStackItem* newParent, | 173 void insertAlreadyParsedChild(HTMLStackItem* newParent, |
171 HTMLElementStack::ElementRecord* child); | 174 HTMLElementStack::ElementRecord* child); |
172 void takeAllChildren(HTMLStackItem* newParent, | 175 void takeAllChildren(HTMLStackItem* newParent, |
173 HTMLElementStack::ElementRecord* oldParent); | 176 HTMLElementStack::ElementRecord* oldParent); |
174 | 177 |
175 HTMLStackItem* createElementFromSavedToken(HTMLStackItem*); | 178 HTMLStackItem* createElementFromSavedToken(HTMLStackItem*); |
176 | 179 |
177 bool shouldFosterParent() const; | 180 bool shouldFosterParent() const; |
178 void fosterParent(Node*); | 181 void fosterParent(Node*); |
179 | 182 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 ~RedirectToFosterParentGuard() { | 230 ~RedirectToFosterParentGuard() { |
228 m_tree.m_redirectAttachToFosterParent = m_wasRedirectingBefore; | 231 m_tree.m_redirectAttachToFosterParent = m_wasRedirectingBefore; |
229 } | 232 } |
230 | 233 |
231 private: | 234 private: |
232 HTMLConstructionSite& m_tree; | 235 HTMLConstructionSite& m_tree; |
233 bool m_wasRedirectingBefore; | 236 bool m_wasRedirectingBefore; |
234 }; | 237 }; |
235 | 238 |
236 private: | 239 private: |
237 // In the common case, this queue will have only one task because most | 240 // In the common case, this queue will have only one task because most tokens |
238 // tokens produce only one DOM mutation. | 241 // produce only one DOM mutation. |
239 typedef HeapVector<HTMLConstructionSiteTask, 1> TaskQueue; | 242 typedef HeapVector<HTMLConstructionSiteTask, 1> TaskQueue; |
240 | 243 |
241 void setCompatibilityMode(Document::CompatibilityMode); | 244 void setCompatibilityMode(Document::CompatibilityMode); |
242 void setCompatibilityModeFromDoctype(const String& name, | 245 void setCompatibilityModeFromDoctype(const String& name, |
243 const String& publicId, | 246 const String& publicId, |
244 const String& systemId); | 247 const String& systemId); |
245 | 248 |
246 void attachLater(ContainerNode* parent, | 249 void attachLater(ContainerNode* parent, |
247 Node* child, | 250 Node* child, |
248 bool selfClosing = false); | 251 bool selfClosing = false); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 nextChild.swap(other.nextChild); | 305 nextChild.swap(other.nextChild); |
303 stringBuilder.swap(other.stringBuilder); | 306 stringBuilder.swap(other.stringBuilder); |
304 } | 307 } |
305 | 308 |
306 void discard() { | 309 void discard() { |
307 PendingText discardedText; | 310 PendingText discardedText; |
308 swap(discardedText); | 311 swap(discardedText); |
309 } | 312 } |
310 | 313 |
311 bool isEmpty() { | 314 bool isEmpty() { |
312 // When the stringbuilder is empty, the parent and whitespace should also
be "empty". | 315 // When the stringbuilder is empty, the parent and whitespace should also |
| 316 // be "empty". |
313 ASSERT(stringBuilder.isEmpty() == !parent); | 317 ASSERT(stringBuilder.isEmpty() == !parent); |
314 ASSERT(!stringBuilder.isEmpty() || !nextChild); | 318 ASSERT(!stringBuilder.isEmpty() || !nextChild); |
315 ASSERT(!stringBuilder.isEmpty() || (whitespaceMode == WhitespaceUnknown)); | 319 ASSERT(!stringBuilder.isEmpty() || (whitespaceMode == WhitespaceUnknown)); |
316 return stringBuilder.isEmpty(); | 320 return stringBuilder.isEmpty(); |
317 } | 321 } |
318 | 322 |
319 DECLARE_TRACE(); | 323 DECLARE_TRACE(); |
320 | 324 |
321 Member<ContainerNode> parent; | 325 Member<ContainerNode> parent; |
322 Member<Node> nextChild; | 326 Member<Node> nextChild; |
(...skipping 10 matching lines...) Expand all Loading... |
333 // In the "in table" insertion mode, we sometimes get into a state where | 337 // In the "in table" insertion mode, we sometimes get into a state where |
334 // "whenever a node would be inserted into the current node, it must instead | 338 // "whenever a node would be inserted into the current node, it must instead |
335 // be foster parented." This flag tracks whether we're in that state. | 339 // be foster parented." This flag tracks whether we're in that state. |
336 bool m_redirectAttachToFosterParent; | 340 bool m_redirectAttachToFosterParent; |
337 | 341 |
338 bool m_inQuirksMode; | 342 bool m_inQuirksMode; |
339 }; | 343 }; |
340 | 344 |
341 } // namespace blink | 345 } // namespace blink |
342 | 346 |
343 #endif | 347 #endif // HTMLConstructionSite_h |
OLD | NEW |