| 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 |