| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "core/dom/SubframeTracker.h" |
| 6 |
| 7 #include "core/dom/Node.h" |
| 8 #include "core/html/HTMLFrameOwnerElement.h" |
| 9 |
| 10 namespace blink { |
| 11 |
| 12 SubframeTracker::SubframeTracker() = default; |
| 13 |
| 14 bool SubframeTracker::hasConnectedSubframes(Node& node) const |
| 15 { |
| 16 return m_connectedSubframeNodes.contains(&node); |
| 17 } |
| 18 |
| 19 void SubframeTracker::disconnectSubframesAt(Node& root, DisconnectPolicy policy) |
| 20 { |
| 21 auto it = m_connectedSubframeNodes.find(&root); |
| 22 if (it == m_connectedSubframeNodes.end()) |
| 23 return; |
| 24 |
| 25 if (policy == DescendantsOnly) |
| 26 ++it; |
| 27 |
| 28 WillBeHeapVector<RefPtrWillBeMember<HTMLFrameOwnerElement>, 10> frameOwners; |
| 29 for (; it != m_connectedSubframeNodes.end() && root.containsIncludingShadowD
OM(*it); ++it) { |
| 30 if ((*it)->isFrameOwnerElement()) |
| 31 frameOwners.append(toHTMLFrameOwnerElement(*it)); |
| 32 } |
| 33 |
| 34 for (size_t i = 0; i < frameOwners.size(); ++i) { |
| 35 HTMLFrameOwnerElement* owner = frameOwners[i].get(); |
| 36 // Don't need to traverse up the tree for the first owner since no |
| 37 // script could have moved it. |
| 38 if (!i || root.containsIncludingShadowDOM(owner)) |
| 39 owner->disconnectContentFrame(); |
| 40 } |
| 41 } |
| 42 |
| 43 DEFINE_TRACE(SubframeTracker) |
| 44 { |
| 45 #if ENABLE(OILPAN) |
| 46 visitor->trace(m_connectedSubframeNodes); |
| 47 #endif // ENABLE(OILPAN) |
| 48 } |
| 49 |
| 50 void SubframeTracker::connectSubframe(HTMLFrameOwnerElement& owner) |
| 51 { |
| 52 WillBeHeapVector<RawPtrWillBeMember<Node>> pathToOwner; |
| 53 for (ContainerNode* node = &owner; node; node = node->parentOrShadowHostNode
()) |
| 54 pathToOwner.append(node); |
| 55 |
| 56 // Find the lowest node in the ancestor chain that's not already tracked in |
| 57 // the set of connected subframe nodes. |
| 58 SubframeNodeSet::iterator insertionLocation = m_connectedSubframeNodes.end()
; |
| 59 auto node = pathToOwner.rbegin(); |
| 60 for (; node != pathToOwner.rend(); ++node) { |
| 61 auto it = m_connectedSubframeNodes.find(*node); |
| 62 if (it == m_connectedSubframeNodes.end()) |
| 63 break; |
| 64 insertionLocation = it; |
| 65 } |
| 66 |
| 67 // Insert the remainder of the chain immediately after the last found node. |
| 68 if (insertionLocation != m_connectedSubframeNodes.end()) { |
| 69 // LinkedHashSet only exposes insertBefore(), so increment the iterator. |
| 70 ++insertionLocation; |
| 71 } |
| 72 |
| 73 for (; node != pathToOwner.rend(); ++node) |
| 74 m_connectedSubframeNodes.insertBefore(insertionLocation, *node); |
| 75 } |
| 76 |
| 77 void SubframeTracker::disconnectSubframe(HTMLFrameOwnerElement& owner) |
| 78 { |
| 79 for (ContainerNode* node = &owner; node; node = node->parentOrShadowHostNode
()) { |
| 80 ASSERT(!m_connectedSubframeNodes.isEmpty()); |
| 81 auto it = m_connectedSubframeNodes.find(node); |
| 82 ASSERT(it != m_connectedSubframeNodes.end()); |
| 83 auto nextNode = it; |
| 84 // If the next node in |m_connectedSubframeNodes| is a child of this |
| 85 // node, it can't be removed since there are still connected subframes. |
| 86 if (*nextNode != m_connectedSubframeNodes.last() && (*++nextNode)->paren
tOrShadowHostNode() == node) |
| 87 return; |
| 88 m_connectedSubframeNodes.remove(it); |
| 89 } |
| 90 } |
| 91 |
| 92 } // namespace blink |
| OLD | NEW |