Index: components/bubble/bubble_manager.cc |
diff --git a/components/bubble/bubble_manager.cc b/components/bubble/bubble_manager.cc |
index 36902a37d4f398d224f138b6cb2c33ea6a5123f3..ad2e9c0c738bc83a1d639799c95d5d462d52e6fc 100644 |
--- a/components/bubble/bubble_manager.cc |
+++ b/components/bubble/bubble_manager.cc |
@@ -47,7 +47,7 @@ bool BubbleManager::CloseBubble(BubbleReference bubble, |
BubbleCloseReason reason) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK_NE(manager_state_, ITERATING_BUBBLES); |
- return CloseAllMatchingBubbles(bubble.get(), reason); |
+ return CloseAllMatchingBubbles(bubble.get(), nullptr, reason); |
} |
void BubbleManager::CloseAllBubbles(BubbleCloseReason reason) { |
@@ -56,7 +56,7 @@ void BubbleManager::CloseAllBubbles(BubbleCloseReason reason) { |
DCHECK_NE(reason, BUBBLE_CLOSE_CANCELED); |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK_NE(manager_state_, ITERATING_BUBBLES); |
- CloseAllMatchingBubbles(nullptr, reason); |
+ CloseAllMatchingBubbles(nullptr, nullptr, reason); |
} |
void BubbleManager::UpdateAllBubbleAnchors() { |
@@ -89,19 +89,34 @@ void BubbleManager::FinalizePendingRequests() { |
CloseAllBubbles(BUBBLE_CLOSE_FORCED); |
} |
-bool BubbleManager::CloseAllMatchingBubbles(BubbleController* match, |
- BubbleCloseReason reason) { |
+void BubbleManager::CloseBubblesOwnedBy(const content::RenderFrameHost* frame) { |
+ CloseAllMatchingBubbles(nullptr, frame, BUBBLE_CLOSE_FRAME_DESTROYED); |
+} |
+ |
+bool BubbleManager::CloseAllMatchingBubbles( |
+ BubbleController* bubble, |
+ const content::RenderFrameHost* owner, |
+ BubbleCloseReason reason) { |
+ // Specifying both an owning frame and a particular bubble to close doesn't |
+ // make sense. If we have a frame, all bubbles owned by that frame need to |
+ // have the opportunity to close. If we want to close a specific bubble, then |
+ // it should get the close event regardless of which frame owns it. On the |
+ // other hand, OR'ing the conditions needs a special case in order to be able |
+ // to close all bubbles, so we disallow passing both until a need appears. |
+ DCHECK(!bubble || !owner); |
+ |
ScopedVector<BubbleController> close_queue; |
// Guard against bubbles being added or removed while iterating the bubbles. |
ManagerState original_state = manager_state_; |
manager_state_ = ITERATING_BUBBLES; |
- for (auto iter = controllers_.begin(); iter != controllers_.end();) { |
- if ((!match || match == *iter) && (*iter)->ShouldClose(reason)) { |
- close_queue.push_back(*iter); |
- iter = controllers_.weak_erase(iter); |
+ for (auto i = controllers_.begin(); i != controllers_.end();) { |
+ if ((!bubble || bubble == *i) && (!owner || (*i)->OwningFrameIs(owner)) && |
+ (*i)->ShouldClose(reason)) { |
+ close_queue.push_back(*i); |
+ i = controllers_.weak_erase(i); |
} else { |
- ++iter; |
+ ++i; |
} |
} |
manager_state_ = original_state; |