1 // Copyright 2014 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.
5 #import "chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_cocoa.h"
7 #include "base/mac/scoped_block.h"
8 #include "chrome/browser/ui/browser_dialogs.h"
9 #include "chrome/browser/ui/browser_finder.h"
10 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
11 #include "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
12 #include "chrome/browser/ui/cocoa/location_bar/manage_passwords_decoration.h"
13 #import "chrome/browser/ui/cocoa/passwords/manage_passwords_bubble_controller.h"
14 #include "chrome/browser/ui/passwords/manage_passwords_icon.h"
15 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
16 #include "content/public/browser/web_contents.h"
18 typedef void (^Callback)(void);
20 @interface ManagePasswordsBubbleCocoaNotificationBridge : NSObject {
21 base::mac::ScopedBlock<Callback> callback_;
23 - (id)initWithCallback:(Callback)callback;
27 @implementation ManagePasswordsBubbleCocoaNotificationBridge
28 - (id)initWithCallback:(Callback)callback {
29 if ((self = [super init])) {
30 callback_.reset(callback, base::scoped_policy::RETAIN);
40 ManagePasswordsBubbleCocoa* ManagePasswordsBubbleCocoa::bubble_ = NULL;
43 void ShowManagePasswordsBubble(content::WebContents* webContents) {
44 ManagePasswordsBubbleCocoa* instance = ManagePasswordsBubbleCocoa::instance();
45 if (instance && (instance->webContents_ != webContents)) {
46 // The bubble is currently shown for some other tab. We should close it now
47 // and open for |webContents|.
51 ManagePasswordsUIController* controller =
52 ManagePasswordsUIController::FromWebContents(webContents);
53 NSWindow* window = webContents->GetTopLevelNativeWindow();
55 // The tab isn't active right now.
58 BrowserWindowController* bwc =
59 [BrowserWindowController browserWindowControllerForWindow:window];
60 ManagePasswordsBubbleCocoa::ShowBubble(
62 password_manager::ui::IsAutomaticDisplayState(controller->state())
63 ? ManagePasswordsBubble::AUTOMATIC
64 : ManagePasswordsBubble::USER_ACTION,
65 [bwc locationBarBridge]->manage_passwords_decoration()->icon());
68 void CloseManagePasswordsBubble(content::WebContents* web_contents) {
69 // The bubble is closed when it loses the focus.
73 ManagePasswordsBubbleCocoa::ManagePasswordsBubbleCocoa(
74 content::WebContents* webContents,
75 DisplayReason displayReason,
76 ManagePasswordsIcon* icon)
77 : ManagePasswordsBubble(webContents, displayReason),
81 webContents_(webContents),
84 icon_->SetActive(true);
87 ManagePasswordsBubbleCocoa::~ManagePasswordsBubbleCocoa() {
88 [[NSNotificationCenter defaultCenter] removeObserver:bridge_];
89 // Clear the global instance pointer.
92 icon_->SetActive(false);
95 void ManagePasswordsBubbleCocoa::Show() {
96 // Create and show the bubble.
97 NSView* browserView = webContents_->GetNativeView();
99 NSWindow* browserWindow = [browserView window];
100 DCHECK(browserWindow);
101 controller_ = [[ManagePasswordsBubbleController alloc]
102 initWithParentWindow:browserWindow
104 [controller_ showWindow:nil];
106 // Listen for close notification to perform cleanup: the window isn't
107 // necessarily closed by calling Close(). Use a block instead of directly
108 // calling OnClose from the bridge so that we don't need to expose OnClose
109 // in the public API of ManagePasswordsBubbleCocoa.
110 bridge_.reset([[ManagePasswordsBubbleCocoaNotificationBridge alloc]
114 [[NSNotificationCenter defaultCenter]
116 selector:@selector(onClose)
117 name:NSWindowWillCloseNotification
118 object:[controller_ window]];
121 void ManagePasswordsBubbleCocoa::Close() {
128 void ManagePasswordsBubbleCocoa::OnClose() {
133 void ManagePasswordsBubbleCocoa::ShowBubble(content::WebContents* webContents,
134 DisplayReason displayReason,
135 ManagePasswordsIcon* icon) {
138 bubble_ = new ManagePasswordsBubbleCocoa(webContents, displayReason, icon);