| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
| 5 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights
reserved. | 5 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights
reserved. |
| 6 * | 6 * |
| 7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 #endif | 73 #endif |
| 74 | 74 |
| 75 private: | 75 private: |
| 76 #ifndef NDEBUG | 76 #ifndef NDEBUG |
| 77 static unsigned s_count; | 77 static unsigned s_count; |
| 78 #endif | 78 #endif |
| 79 }; | 79 }; |
| 80 | 80 |
| 81 class ContainerNode : public Node { | 81 class ContainerNode : public Node { |
| 82 friend class PostAttachCallbackDisabler; | 82 friend class PostAttachCallbackDisabler; |
| 83 friend class InsertionCallbackDeferer; |
| 83 public: | 84 public: |
| 84 virtual ~ContainerNode(); | 85 virtual ~ContainerNode(); |
| 85 | 86 |
| 86 Node* firstChild() const { return m_firstChild; } | 87 Node* firstChild() const { return m_firstChild; } |
| 87 Node* lastChild() const { return m_lastChild; } | 88 Node* lastChild() const { return m_lastChild; } |
| 88 bool hasChildNodes() const { return m_firstChild; } | 89 bool hasChildNodes() const { return m_firstChild; } |
| 89 | 90 |
| 90 // ParentNode interface API | 91 // ParentNode interface API |
| 91 PassRefPtr<HTMLCollection> children(); | 92 PassRefPtr<HTMLCollection> children(); |
| 92 Element* firstElementChild() const; | 93 Element* firstElementChild() const; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 | 134 |
| 134 void disconnectDescendantFrames(); | 135 void disconnectDescendantFrames(); |
| 135 | 136 |
| 136 virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const {
return true; } | 137 virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const {
return true; } |
| 137 | 138 |
| 138 virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE; | 139 virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE; |
| 139 | 140 |
| 140 protected: | 141 protected: |
| 141 ContainerNode(TreeScope*, ConstructionType = CreateContainer); | 142 ContainerNode(TreeScope*, ConstructionType = CreateContainer); |
| 142 | 143 |
| 144 static void queueInsertionCallback(NodeCallback, Node*); |
| 145 static bool insertionCallbacksAreSuspended(); |
| 143 static void queuePostAttachCallback(NodeCallback, Node*); | 146 static void queuePostAttachCallback(NodeCallback, Node*); |
| 144 static bool postAttachCallbacksAreSuspended(); | 147 static bool postAttachCallbacksAreSuspended(); |
| 145 | 148 |
| 146 template<class GenericNode, class GenericNodeContainer> | 149 template<class GenericNode, class GenericNodeContainer> |
| 147 friend void appendChildToContainer(GenericNode* child, GenericNodeContainer*
); | 150 friend void appendChildToContainer(GenericNode* child, GenericNodeContainer*
); |
| 148 | 151 |
| 149 template<class GenericNode, class GenericNodeContainer> | 152 template<class GenericNode, class GenericNodeContainer> |
| 150 friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, Generi
cNode*& tail, GenericNodeContainer*); | 153 friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, Generi
cNode*& tail, GenericNodeContainer*); |
| 151 | 154 |
| 152 void removeDetachedChildren(); | 155 void removeDetachedChildren(); |
| 153 void setFirstChild(Node* child) { m_firstChild = child; } | 156 void setFirstChild(Node* child) { m_firstChild = child; } |
| 154 void setLastChild(Node* child) { m_lastChild = child; } | 157 void setLastChild(Node* child) { m_lastChild = child; } |
| 155 | 158 |
| 156 private: | 159 private: |
| 157 void removeBetween(Node* previousChild, Node* nextChild, Node* oldChild); | 160 void removeBetween(Node* previousChild, Node* nextChild, Node* oldChild); |
| 158 void insertBeforeCommon(Node* nextChild, Node* oldChild); | 161 void insertBeforeCommon(Node* nextChild, Node* oldChild); |
| 159 | 162 |
| 160 static void dispatchPostAttachCallbacks(); | 163 static void dispatchPostAttachCallbacks(); |
| 164 |
| 161 void suspendPostAttachCallbacks(); | 165 void suspendPostAttachCallbacks(); |
| 162 void resumePostAttachCallbacks(); | 166 void resumePostAttachCallbacks(); |
| 163 | 167 |
| 168 static void dispatchInsertionCallbacks(); |
| 169 |
| 170 static void suspendInsertionCallbacks(); |
| 171 static void resumeInsertionCallbacks(); |
| 172 |
| 164 Node* m_firstChild; | 173 Node* m_firstChild; |
| 165 Node* m_lastChild; | 174 Node* m_lastChild; |
| 166 }; | 175 }; |
| 167 | 176 |
| 168 #ifndef NDEBUG | 177 #ifndef NDEBUG |
| 169 bool childAttachedAllowedWhenAttachingChildren(ContainerNode*); | 178 bool childAttachedAllowedWhenAttachingChildren(ContainerNode*); |
| 170 #endif | 179 #endif |
| 171 | 180 |
| 172 inline ContainerNode* toContainerNode(Node* node) | 181 inline ContainerNode* toContainerNode(Node* node) |
| 173 { | 182 { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 ASSERT(!nodes.size()); | 286 ASSERT(!nodes.size()); |
| 278 for (Node* child = node->firstChild(); child; child = child->nextSibling()) | 287 for (Node* child = node->firstChild(); child; child = child->nextSibling()) |
| 279 nodes.append(child); | 288 nodes.append(child); |
| 280 } | 289 } |
| 281 | 290 |
| 282 class ChildNodesLazySnapshot { | 291 class ChildNodesLazySnapshot { |
| 283 WTF_MAKE_NONCOPYABLE(ChildNodesLazySnapshot); | 292 WTF_MAKE_NONCOPYABLE(ChildNodesLazySnapshot); |
| 284 WTF_MAKE_FAST_ALLOCATED; | 293 WTF_MAKE_FAST_ALLOCATED; |
| 285 public: | 294 public: |
| 286 explicit ChildNodesLazySnapshot(Node* parentNode) | 295 explicit ChildNodesLazySnapshot(Node* parentNode) |
| 287 : m_currentNode(parentNode->firstChild()) | 296 : m_currentNode(parentNode->lastChild()) |
| 288 , m_currentIndex(0) | 297 , m_currentIndex(0) |
| 289 { | 298 { |
| 290 m_nextSnapshot = latestSnapshot; | 299 m_nextSnapshot = latestSnapshot; |
| 291 latestSnapshot = this; | 300 latestSnapshot = this; |
| 292 } | 301 } |
| 293 | 302 |
| 294 ~ChildNodesLazySnapshot() | 303 ~ChildNodesLazySnapshot() |
| 295 { | 304 { |
| 296 latestSnapshot = m_nextSnapshot; | 305 latestSnapshot = m_nextSnapshot; |
| 297 } | 306 } |
| 298 | 307 |
| 299 // Returns 0 if there is no next Node. | 308 // Returns 0 if there is no previous Node. |
| 300 PassRefPtr<Node> nextNode() | 309 PassRefPtr<Node> previousNode() |
| 301 { | 310 { |
| 302 if (LIKELY(!hasSnapshot())) { | 311 if (LIKELY(!hasSnapshot())) { |
| 303 RefPtr<Node> node = m_currentNode; | 312 RefPtr<Node> node = m_currentNode; |
| 304 if (node) | 313 if (node) |
| 305 m_currentNode = node->nextSibling(); | 314 m_currentNode = node->previousSibling(); |
| 306 return node.release(); | 315 return node.release(); |
| 307 } | 316 } |
| 308 Vector<RefPtr<Node> >& nodeVector = *m_childNodes; | 317 Vector<RefPtr<Node> >& nodeVector = *m_childNodes; |
| 309 if (m_currentIndex >= nodeVector.size()) | 318 if (m_currentIndex >= nodeVector.size()) |
| 310 return 0; | 319 return 0; |
| 311 return nodeVector[m_currentIndex++]; | 320 return nodeVector[m_currentIndex++]; |
| 312 } | 321 } |
| 313 | 322 |
| 314 void takeSnapshot() | 323 void takeSnapshot() |
| 315 { | 324 { |
| 316 if (hasSnapshot()) | 325 if (hasSnapshot()) |
| 317 return; | 326 return; |
| 318 m_childNodes = adoptPtr(new Vector<RefPtr<Node> >()); | 327 m_childNodes = adoptPtr(new Vector<RefPtr<Node> >()); |
| 319 Node* node = m_currentNode.get(); | 328 Node* node = m_currentNode.get(); |
| 320 while (node) { | 329 while (node) { |
| 321 m_childNodes->append(node); | 330 m_childNodes->append(node); |
| 322 node = node->nextSibling(); | 331 node = node->previousSibling(); |
| 323 } | 332 } |
| 324 } | 333 } |
| 325 | 334 |
| 326 ChildNodesLazySnapshot* nextSnapshot() { return m_nextSnapshot; } | 335 ChildNodesLazySnapshot* nextSnapshot() { return m_nextSnapshot; } |
| 327 bool hasSnapshot() { return !!m_childNodes.get(); } | 336 bool hasSnapshot() { return !!m_childNodes.get(); } |
| 328 | 337 |
| 329 static void takeChildNodesLazySnapshot() | 338 static void takeChildNodesLazySnapshot() |
| 330 { | 339 { |
| 331 ChildNodesLazySnapshot* snapshot = latestSnapshot; | 340 ChildNodesLazySnapshot* snapshot = latestSnapshot; |
| 332 while (snapshot && !snapshot->hasSnapshot()) { | 341 while (snapshot && !snapshot->hasSnapshot()) { |
| 333 snapshot->takeSnapshot(); | 342 snapshot->takeSnapshot(); |
| 334 snapshot = snapshot->nextSnapshot(); | 343 snapshot = snapshot->nextSnapshot(); |
| 335 } | 344 } |
| 336 } | 345 } |
| 337 | 346 |
| 338 private: | 347 private: |
| 339 static ChildNodesLazySnapshot* latestSnapshot; | 348 static ChildNodesLazySnapshot* latestSnapshot; |
| 340 | 349 |
| 341 RefPtr<Node> m_currentNode; | 350 RefPtr<Node> m_currentNode; |
| 342 unsigned m_currentIndex; | 351 unsigned m_currentIndex; |
| 343 OwnPtr<Vector<RefPtr<Node> > > m_childNodes; // Lazily instantiated. | 352 OwnPtr<Vector<RefPtr<Node> > > m_childNodes; // Lazily instantiated. |
| 344 ChildNodesLazySnapshot* m_nextSnapshot; | 353 ChildNodesLazySnapshot* m_nextSnapshot; |
| 345 }; | 354 }; |
| 346 | 355 |
| 356 // Used to ensure Radio Buttons resolve their checked state in document |
| 357 // order when a subtree of them is inserted. This is necessary because |
| 358 // we resolve style in reverse document order. |
| 359 class InsertionCallbackDeferer { |
| 360 public: |
| 361 InsertionCallbackDeferer() |
| 362 { |
| 363 ContainerNode::suspendInsertionCallbacks(); |
| 364 } |
| 365 |
| 366 ~InsertionCallbackDeferer() |
| 367 { |
| 368 ContainerNode::resumeInsertionCallbacks(); |
| 369 } |
| 370 }; |
| 371 |
| 347 class PostAttachCallbackDisabler { | 372 class PostAttachCallbackDisabler { |
| 348 public: | 373 public: |
| 349 PostAttachCallbackDisabler(ContainerNode* node) | 374 PostAttachCallbackDisabler(ContainerNode* node) |
| 350 : m_node(node) | 375 : m_node(node) |
| 351 { | 376 { |
| 352 ASSERT(m_node); | 377 ASSERT(m_node); |
| 353 m_node->suspendPostAttachCallbacks(); | 378 m_node->suspendPostAttachCallbacks(); |
| 354 } | 379 } |
| 355 | 380 |
| 356 ~PostAttachCallbackDisabler() | 381 ~PostAttachCallbackDisabler() |
| 357 { | 382 { |
| 358 m_node->resumePostAttachCallbacks(); | 383 m_node->resumePostAttachCallbacks(); |
| 359 } | 384 } |
| 360 | 385 |
| 361 private: | 386 private: |
| 362 ContainerNode* m_node; | 387 ContainerNode* m_node; |
| 363 }; | 388 }; |
| 364 | 389 |
| 365 } // namespace WebCore | 390 } // namespace WebCore |
| 366 | 391 |
| 367 #endif // ContainerNode_h | 392 #endif // ContainerNode_h |
| OLD | NEW |