| 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 19 matching lines...) Expand all Loading... |
| 30 #include <wtf/OwnPtr.h> | 30 #include <wtf/OwnPtr.h> |
| 31 #include <wtf/Vector.h> | 31 #include <wtf/Vector.h> |
| 32 | 32 |
| 33 namespace WebCore { | 33 namespace WebCore { |
| 34 | 34 |
| 35 class FloatPoint; | 35 class FloatPoint; |
| 36 class HTMLCollection; | 36 class HTMLCollection; |
| 37 | 37 |
| 38 typedef void (*NodeCallback)(Node*); | 38 typedef void (*NodeCallback)(Node*); |
| 39 | 39 |
| 40 namespace Private { | 40 namespace Private { |
| 41 template<class GenericNode, class GenericNodeContainer> | 41 template<class GenericNode, class GenericNodeContainer> |
| 42 void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, Ge
nericNodeContainer*); | 42 void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, Ge
nericNodeContainer*); |
| 43 }; | 43 }; |
| 44 | 44 |
| 45 class NoEventDispatchAssertion { | 45 class NoEventDispatchAssertion { |
| 46 public: | 46 public: |
| 47 NoEventDispatchAssertion() | 47 NoEventDispatchAssertion() |
| 48 { | 48 { |
| 49 #ifndef NDEBUG | 49 #ifndef NDEBUG |
| 50 if (!isMainThread()) | 50 if (!isMainThread()) |
| (...skipping 22 matching lines...) Expand all 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; | |
| 84 public: | 83 public: |
| 85 virtual ~ContainerNode(); | 84 virtual ~ContainerNode(); |
| 86 | 85 |
| 87 Node* firstChild() const { return m_firstChild; } | 86 Node* firstChild() const { return m_firstChild; } |
| 88 Node* lastChild() const { return m_lastChild; } | 87 Node* lastChild() const { return m_lastChild; } |
| 89 bool hasChildNodes() const { return m_firstChild; } | 88 bool hasChildNodes() const { return m_firstChild; } |
| 90 | 89 |
| 91 // ParentNode interface API | 90 // ParentNode interface API |
| 92 PassRefPtr<HTMLCollection> children(); | 91 PassRefPtr<HTMLCollection> children(); |
| 93 Element* firstElementChild() const; | 92 Element* firstElementChild() const; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 | 134 |
| 136 void disconnectDescendantFrames(); | 135 void disconnectDescendantFrames(); |
| 137 | 136 |
| 138 virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const {
return true; } | 137 virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const {
return true; } |
| 139 | 138 |
| 140 virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE; | 139 virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE; |
| 141 | 140 |
| 142 protected: | 141 protected: |
| 143 ContainerNode(TreeScope*, ConstructionType = CreateContainer); | 142 ContainerNode(TreeScope*, ConstructionType = CreateContainer); |
| 144 | 143 |
| 145 static void queueInsertionCallback(NodeCallback, Node*); | |
| 146 static bool insertionCallbacksAreSuspended(); | |
| 147 static void queuePostAttachCallback(NodeCallback, Node*); | 144 static void queuePostAttachCallback(NodeCallback, Node*); |
| 148 static bool postAttachCallbacksAreSuspended(); | 145 static bool postAttachCallbacksAreSuspended(); |
| 149 | 146 |
| 150 template<class GenericNode, class GenericNodeContainer> | 147 template<class GenericNode, class GenericNodeContainer> |
| 151 friend void appendChildToContainer(GenericNode* child, GenericNodeContainer*
); | 148 friend void appendChildToContainer(GenericNode* child, GenericNodeContainer*
); |
| 152 | 149 |
| 153 template<class GenericNode, class GenericNodeContainer> | 150 template<class GenericNode, class GenericNodeContainer> |
| 154 friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, Generi
cNode*& tail, GenericNodeContainer*); | 151 friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, Generi
cNode*& tail, GenericNodeContainer*); |
| 155 | 152 |
| 156 void removeDetachedChildren(); | 153 void removeDetachedChildren(); |
| 157 void setFirstChild(Node* child) { m_firstChild = child; } | 154 void setFirstChild(Node* child) { m_firstChild = child; } |
| 158 void setLastChild(Node* child) { m_lastChild = child; } | 155 void setLastChild(Node* child) { m_lastChild = child; } |
| 159 | 156 |
| 160 private: | 157 private: |
| 161 void removeBetween(Node* previousChild, Node* nextChild, Node* oldChild); | 158 void removeBetween(Node* previousChild, Node* nextChild, Node* oldChild); |
| 162 void insertBeforeCommon(Node* nextChild, Node* oldChild); | 159 void insertBeforeCommon(Node* nextChild, Node* oldChild); |
| 163 | 160 |
| 164 static void dispatchPostAttachCallbacks(); | 161 static void dispatchPostAttachCallbacks(); |
| 165 | 162 |
| 166 void suspendPostAttachCallbacks(); | 163 void suspendPostAttachCallbacks(); |
| 167 void resumePostAttachCallbacks(); | 164 void resumePostAttachCallbacks(); |
| 168 | 165 |
| 169 static void dispatchInsertionCallbacks(); | |
| 170 | |
| 171 static void suspendInsertionCallbacks(); | |
| 172 static void resumeInsertionCallbacks(); | |
| 173 | |
| 174 bool getUpperLeftCorner(FloatPoint&) const; | 166 bool getUpperLeftCorner(FloatPoint&) const; |
| 175 bool getLowerRightCorner(FloatPoint&) const; | 167 bool getLowerRightCorner(FloatPoint&) const; |
| 176 | 168 |
| 177 Node* m_firstChild; | 169 Node* m_firstChild; |
| 178 Node* m_lastChild; | 170 Node* m_lastChild; |
| 179 }; | 171 }; |
| 180 | 172 |
| 181 #ifndef NDEBUG | 173 #ifndef NDEBUG |
| 182 bool childAttachedAllowedWhenAttachingChildren(ContainerNode*); | 174 bool childAttachedAllowedWhenAttachingChildren(ContainerNode*); |
| 183 #endif | 175 #endif |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 ASSERT(!nodes.size()); | 282 ASSERT(!nodes.size()); |
| 291 for (Node* child = node->firstChild(); child; child = child->nextSibling()) | 283 for (Node* child = node->firstChild(); child; child = child->nextSibling()) |
| 292 nodes.append(child); | 284 nodes.append(child); |
| 293 } | 285 } |
| 294 | 286 |
| 295 class ChildNodesLazySnapshot { | 287 class ChildNodesLazySnapshot { |
| 296 WTF_MAKE_NONCOPYABLE(ChildNodesLazySnapshot); | 288 WTF_MAKE_NONCOPYABLE(ChildNodesLazySnapshot); |
| 297 WTF_MAKE_FAST_ALLOCATED; | 289 WTF_MAKE_FAST_ALLOCATED; |
| 298 public: | 290 public: |
| 299 explicit ChildNodesLazySnapshot(Node* parentNode) | 291 explicit ChildNodesLazySnapshot(Node* parentNode) |
| 300 : m_currentNode(parentNode->lastChild()) | 292 : m_currentNode(parentNode->firstChild()) |
| 301 , m_currentIndex(0) | 293 , m_currentIndex(0) |
| 302 { | 294 { |
| 303 m_nextSnapshot = latestSnapshot; | 295 m_nextSnapshot = latestSnapshot; |
| 304 latestSnapshot = this; | 296 latestSnapshot = this; |
| 305 } | 297 } |
| 306 | 298 |
| 307 ~ChildNodesLazySnapshot() | 299 ~ChildNodesLazySnapshot() |
| 308 { | 300 { |
| 309 latestSnapshot = m_nextSnapshot; | 301 latestSnapshot = m_nextSnapshot; |
| 310 } | 302 } |
| 311 | 303 |
| 312 // Returns 0 if there is no previous Node. | 304 // Returns 0 if there is no next Node. |
| 313 PassRefPtr<Node> previousNode() | 305 PassRefPtr<Node> nextNode() |
| 314 { | 306 { |
| 315 if (LIKELY(!hasSnapshot())) { | 307 if (LIKELY(!hasSnapshot())) { |
| 316 RefPtr<Node> node = m_currentNode; | 308 RefPtr<Node> node = m_currentNode; |
| 317 if (node) | 309 if (node) |
| 318 m_currentNode = node->previousSibling(); | 310 m_currentNode = node->nextSibling(); |
| 319 return node.release(); | 311 return node.release(); |
| 320 } | 312 } |
| 321 Vector<RefPtr<Node> >& nodeVector = *m_childNodes; | 313 Vector<RefPtr<Node> >& nodeVector = *m_childNodes; |
| 322 if (m_currentIndex >= nodeVector.size()) | 314 if (m_currentIndex >= nodeVector.size()) |
| 323 return 0; | 315 return 0; |
| 324 return nodeVector[m_currentIndex++]; | 316 return nodeVector[m_currentIndex++]; |
| 325 } | 317 } |
| 326 | 318 |
| 327 void takeSnapshot() | 319 void takeSnapshot() |
| 328 { | 320 { |
| 329 if (hasSnapshot()) | 321 if (hasSnapshot()) |
| 330 return; | 322 return; |
| 331 m_childNodes = adoptPtr(new Vector<RefPtr<Node> >()); | 323 m_childNodes = adoptPtr(new Vector<RefPtr<Node> >()); |
| 332 Node* node = m_currentNode.get(); | 324 Node* node = m_currentNode.get(); |
| 333 while (node) { | 325 while (node) { |
| 334 m_childNodes->append(node); | 326 m_childNodes->append(node); |
| 335 node = node->previousSibling(); | 327 node = node->nextSibling(); |
| 336 } | 328 } |
| 337 } | 329 } |
| 338 | 330 |
| 339 ChildNodesLazySnapshot* nextSnapshot() { return m_nextSnapshot; } | 331 ChildNodesLazySnapshot* nextSnapshot() { return m_nextSnapshot; } |
| 340 bool hasSnapshot() { return !!m_childNodes.get(); } | 332 bool hasSnapshot() { return !!m_childNodes.get(); } |
| 341 | 333 |
| 342 static void takeChildNodesLazySnapshot() | 334 static void takeChildNodesLazySnapshot() |
| 343 { | 335 { |
| 344 ChildNodesLazySnapshot* snapshot = latestSnapshot; | 336 ChildNodesLazySnapshot* snapshot = latestSnapshot; |
| 345 while (snapshot && !snapshot->hasSnapshot()) { | 337 while (snapshot && !snapshot->hasSnapshot()) { |
| 346 snapshot->takeSnapshot(); | 338 snapshot->takeSnapshot(); |
| 347 snapshot = snapshot->nextSnapshot(); | 339 snapshot = snapshot->nextSnapshot(); |
| 348 } | 340 } |
| 349 } | 341 } |
| 350 | 342 |
| 351 private: | 343 private: |
| 352 static ChildNodesLazySnapshot* latestSnapshot; | 344 static ChildNodesLazySnapshot* latestSnapshot; |
| 353 | 345 |
| 354 RefPtr<Node> m_currentNode; | 346 RefPtr<Node> m_currentNode; |
| 355 unsigned m_currentIndex; | 347 unsigned m_currentIndex; |
| 356 OwnPtr<Vector<RefPtr<Node> > > m_childNodes; // Lazily instantiated. | 348 OwnPtr<Vector<RefPtr<Node> > > m_childNodes; // Lazily instantiated. |
| 357 ChildNodesLazySnapshot* m_nextSnapshot; | 349 ChildNodesLazySnapshot* m_nextSnapshot; |
| 358 }; | 350 }; |
| 359 | 351 |
| 360 // Used to ensure Radio Buttons resolve their checked state in document | |
| 361 // order when a subtree of them is inserted. This is necessary because | |
| 362 // we resolve style in reverse document order. | |
| 363 class InsertionCallbackDeferer { | |
| 364 public: | |
| 365 InsertionCallbackDeferer() | |
| 366 { | |
| 367 ContainerNode::suspendInsertionCallbacks(); | |
| 368 } | |
| 369 | |
| 370 ~InsertionCallbackDeferer() | |
| 371 { | |
| 372 ContainerNode::resumeInsertionCallbacks(); | |
| 373 } | |
| 374 }; | |
| 375 | |
| 376 class PostAttachCallbackDisabler { | 352 class PostAttachCallbackDisabler { |
| 377 public: | 353 public: |
| 378 PostAttachCallbackDisabler(ContainerNode* node) | 354 PostAttachCallbackDisabler(ContainerNode* node) |
| 379 : m_node(node) | 355 : m_node(node) |
| 380 { | 356 { |
| 381 ASSERT(m_node); | 357 ASSERT(m_node); |
| 382 m_node->suspendPostAttachCallbacks(); | 358 m_node->suspendPostAttachCallbacks(); |
| 383 } | 359 } |
| 384 | 360 |
| 385 ~PostAttachCallbackDisabler() | 361 ~PostAttachCallbackDisabler() |
| 386 { | 362 { |
| 387 m_node->resumePostAttachCallbacks(); | 363 m_node->resumePostAttachCallbacks(); |
| 388 } | 364 } |
| 389 | 365 |
| 390 private: | 366 private: |
| 391 ContainerNode* m_node; | 367 ContainerNode* m_node; |
| 392 }; | 368 }; |
| 393 | 369 |
| 394 } // namespace WebCore | 370 } // namespace WebCore |
| 395 | 371 |
| 396 #endif // ContainerNode_h | 372 #endif // ContainerNode_h |
| OLD | NEW |