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 |