| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007 Apple Inc. All rights reserved. |
| 3 * (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> | 3 * (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> |
| 4 * | 4 * |
| 5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
| 6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
| 7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
| 8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
| 9 * | 9 * |
| 10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 { | 274 { |
| 275 if (node->inDocument()) { | 275 if (node->inDocument()) { |
| 276 notifyNodeRemovedFromDocument(node); | 276 notifyNodeRemovedFromDocument(node); |
| 277 node->document()->notifyRemovePendingSheetIfNeeded(); | 277 node->document()->notifyRemovePendingSheetIfNeeded(); |
| 278 } else if (node->isContainerNode()) | 278 } else if (node->isContainerNode()) |
| 279 notifyNodeRemovedFromTree(toContainerNode(node)); | 279 notifyNodeRemovedFromTree(toContainerNode(node)); |
| 280 } | 280 } |
| 281 | 281 |
| 282 class ChildFrameDisconnector { | 282 class ChildFrameDisconnector { |
| 283 public: | 283 public: |
| 284 explicit ChildFrameDisconnector(Node* root); | 284 enum ShouldIncludeRoot { |
| 285 DoNotIncludeRoot, |
| 286 IncludeRoot |
| 287 }; |
| 288 |
| 289 explicit ChildFrameDisconnector(Node* root, ShouldIncludeRoot shouldIncludeR
oot = IncludeRoot) |
| 290 : m_root(root) |
| 291 { |
| 292 collectDescendant(m_root, shouldIncludeRoot); |
| 293 rootNodes().add(m_root); |
| 294 } |
| 295 |
| 296 ~ChildFrameDisconnector() |
| 297 { |
| 298 rootNodes().remove(m_root); |
| 299 } |
| 300 |
| 285 void disconnect(); | 301 void disconnect(); |
| 286 | 302 |
| 303 static bool nodeHasDisconnector(Node*); |
| 304 |
| 287 private: | 305 private: |
| 288 void collectDescendant(Node* root); | 306 void collectDescendant(Node* root, ShouldIncludeRoot); |
| 289 void collectDescendant(ElementShadow*); | 307 void collectDescendant(ElementShadow*); |
| 290 | 308 |
| 309 static HashSet<Node*>& rootNodes() |
| 310 { |
| 311 DEFINE_STATIC_LOCAL(HashSet<Node*>, nodes, ()); |
| 312 return nodes; |
| 313 } |
| 314 |
| 291 class Target { | 315 class Target { |
| 292 public: | 316 public: |
| 293 Target(HTMLFrameOwnerElement* element) | 317 Target(HTMLFrameOwnerElement* element) |
| 294 : m_owner(element) | 318 : m_owner(element) |
| 295 , m_ownerParent(element->parentNode()) | 319 , m_ownerParent(element->parentNode()) |
| 296 { | 320 { |
| 297 } | 321 } |
| 298 | 322 |
| 299 bool isValid() const { return m_owner->parentNode() == m_ownerParent; } | 323 bool isValid() const { return m_owner->parentNode() == m_ownerParent; } |
| 300 void disconnect(); | 324 void disconnect(); |
| 301 | 325 |
| 302 private: | 326 private: |
| 303 RefPtr<HTMLFrameOwnerElement> m_owner; | 327 RefPtr<HTMLFrameOwnerElement> m_owner; |
| 304 ContainerNode* m_ownerParent; | 328 ContainerNode* m_ownerParent; |
| 305 }; | 329 }; |
| 306 | 330 |
| 307 Vector<Target, 10> m_list; | 331 Vector<Target, 10> m_list; |
| 332 Node* m_root; |
| 308 }; | 333 }; |
| 309 | 334 |
| 310 inline ChildFrameDisconnector::ChildFrameDisconnector(Node* root) | 335 inline void ChildFrameDisconnector::collectDescendant(Node* root, ShouldIncludeR
oot shouldIncludeRoot) |
| 311 { | 336 { |
| 312 collectDescendant(root); | 337 for (Node* node = shouldIncludeRoot == IncludeRoot ? root : root->firstChild
(); node; |
| 313 } | 338 node = node->traverseNextNode(root)) { |
| 314 | |
| 315 inline void ChildFrameDisconnector::collectDescendant(Node* root) | |
| 316 { | |
| 317 for (Node* node = root; node; node = node->traverseNextNode(root)) { | |
| 318 if (!node->isElementNode()) | 339 if (!node->isElementNode()) |
| 319 continue; | 340 continue; |
| 320 Element* element = toElement(node); | 341 Element* element = toElement(node); |
| 321 if (element->hasCustomCallbacks() && element->isFrameOwnerElement()) | 342 if (element->hasCustomCallbacks() && element->isFrameOwnerElement()) |
| 322 m_list.append(toFrameOwnerElement(element)); | 343 m_list.append(toFrameOwnerElement(element)); |
| 323 if (ElementShadow* shadow = element->shadow()) | 344 if (ElementShadow* shadow = element->shadow()) |
| 324 collectDescendant(shadow); | 345 collectDescendant(shadow); |
| 325 } | 346 } |
| 326 } | 347 } |
| 327 | 348 |
| 328 inline void ChildFrameDisconnector::disconnect() | 349 inline void ChildFrameDisconnector::disconnect() |
| 329 { | 350 { |
| 330 unsigned size = m_list.size(); | 351 unsigned size = m_list.size(); |
| 331 for (unsigned i = 0; i < size; ++i) { | 352 for (unsigned i = 0; i < size; ++i) { |
| 332 Target& target = m_list[i]; | 353 Target& target = m_list[i]; |
| 333 if (target.isValid()) | 354 if (target.isValid()) |
| 334 target.disconnect(); | 355 target.disconnect(); |
| 335 } | 356 } |
| 336 } | 357 } |
| 337 | 358 |
| 359 inline bool ChildFrameDisconnector::nodeHasDisconnector(Node* node) |
| 360 { |
| 361 HashSet<Node*>& nodes = rootNodes(); |
| 362 |
| 363 if (nodes.isEmpty()) |
| 364 return false; |
| 365 |
| 366 for (; node; node = node->parentNode()) |
| 367 if (nodes.contains(node)) |
| 368 return true; |
| 369 |
| 370 return false; |
| 371 } |
| 372 |
| 338 } // namespace WebCore | 373 } // namespace WebCore |
| 339 | 374 |
| 340 #endif // ContainerNodeAlgorithms_h | 375 #endif // ContainerNodeAlgorithms_h |
| OLD | NEW |