Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(352)

Side by Side Diff: chrome/browser/ui/cocoa/web_dialog_window_controller.mm

Issue 1640043002: Mac (cleanup): Remove WebDialogs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 #import "chrome/browser/ui/cocoa/web_dialog_window_controller.h"
6
7 #include "base/logging.h"
8 #include "base/mac/scoped_nsobject.h"
9 #include "base/macros.h"
10 #include "base/strings/sys_string_conversions.h"
11 #import "chrome/browser/ui/browser_dialogs.h"
12 #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
13 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
14 #include "content/public/browser/native_web_keyboard_event.h"
15 #include "content/public/browser/web_contents.h"
16 #include "content/public/browser/web_ui_message_handler.h"
17 #include "ui/events/keycodes/keyboard_codes.h"
18 #include "ui/gfx/geometry/size.h"
19 #include "ui/web_dialogs/web_dialog_delegate.h"
20 #include "ui/web_dialogs/web_dialog_web_contents_delegate.h"
21
22 using content::NativeWebKeyboardEvent;
23 using content::WebContents;
24 using content::WebUIMessageHandler;
25 using ui::WebDialogDelegate;
26 using ui::WebDialogUI;
27 using ui::WebDialogWebContentsDelegate;
28
29 // Thin bridge that routes notifications to
30 // WebDialogWindowController's member variables.
31 class WebDialogWindowDelegateBridge
32 : public WebDialogDelegate,
33 public WebDialogWebContentsDelegate {
34 public:
35 // All parameters must be non-NULL/non-nil.
36 WebDialogWindowDelegateBridge(WebDialogWindowController* controller,
37 content::BrowserContext* context,
38 WebDialogDelegate* delegate);
39
40 ~WebDialogWindowDelegateBridge() override;
41
42 // Called when the window is directly closed, e.g. from the close
43 // button or from an accelerator.
44 void WindowControllerClosed();
45
46 // WebDialogDelegate declarations.
47 ui::ModalType GetDialogModalType() const override;
48 base::string16 GetDialogTitle() const override;
49 GURL GetDialogContentURL() const override;
50 void GetWebUIMessageHandlers(
51 std::vector<WebUIMessageHandler*>* handlers) const override;
52 void GetDialogSize(gfx::Size* size) const override;
53 void GetMinimumDialogSize(gfx::Size* size) const override;
54 std::string GetDialogArgs() const override;
55 void OnDialogClosed(const std::string& json_retval) override;
56 void OnCloseContents(WebContents* source, bool* out_close_dialog) override;
57 bool ShouldShowDialogTitle() const override { return true; }
58
59 // WebDialogWebContentsDelegate declarations.
60 void MoveContents(WebContents* source, const gfx::Rect& pos) override;
61 void HandleKeyboardEvent(content::WebContents* source,
62 const NativeWebKeyboardEvent& event) override;
63 void CloseContents(WebContents* source) override;
64 content::WebContents* OpenURLFromTab(
65 content::WebContents* source,
66 const content::OpenURLParams& params) override;
67 void AddNewContents(content::WebContents* source,
68 content::WebContents* new_contents,
69 WindowOpenDisposition disposition,
70 const gfx::Rect& initial_rect,
71 bool user_gesture,
72 bool* was_blocked) override;
73 void LoadingStateChanged(content::WebContents* source,
74 bool to_different_document) override;
75
76 private:
77 WebDialogWindowController* controller_; // weak
78 WebDialogDelegate* delegate_; // weak, owned by controller_
79
80 // Calls delegate_'s OnDialogClosed() exactly once, nulling it out afterwards
81 // so that no other WebDialogDelegate calls are sent to it. Returns whether or
82 // not the OnDialogClosed() was actually called on the delegate.
83 bool DelegateOnDialogClosed(const std::string& json_retval);
84
85 DISALLOW_COPY_AND_ASSIGN(WebDialogWindowDelegateBridge);
86 };
87
88 namespace chrome {
89
90 gfx::NativeWindow ShowWebDialog(gfx::NativeView parent,
91 content::BrowserContext* context,
92 WebDialogDelegate* delegate) {
93 return [WebDialogWindowController showWebDialog:delegate
94 context:context];
95 }
96
97 } // namespace chrome
98
99 WebDialogWindowDelegateBridge::WebDialogWindowDelegateBridge(
100 WebDialogWindowController* controller,
101 content::BrowserContext* context,
102 WebDialogDelegate* delegate)
103 : WebDialogWebContentsDelegate(context, new ChromeWebContentsHandler),
104 controller_(controller),
105 delegate_(delegate) {
106 DCHECK(controller_);
107 DCHECK(delegate_);
108 }
109
110 WebDialogWindowDelegateBridge::~WebDialogWindowDelegateBridge() {}
111
112 void WebDialogWindowDelegateBridge::WindowControllerClosed() {
113 Detach();
114 controller_ = nil;
115 DelegateOnDialogClosed("");
116 }
117
118 bool WebDialogWindowDelegateBridge::DelegateOnDialogClosed(
119 const std::string& json_retval) {
120 if (delegate_) {
121 WebDialogDelegate* real_delegate = delegate_;
122 delegate_ = NULL;
123 real_delegate->OnDialogClosed(json_retval);
124 return true;
125 }
126 return false;
127 }
128
129 // WebDialogDelegate definitions.
130
131 // All of these functions check for NULL first since delegate_ is set
132 // to NULL when the window is closed.
133
134 ui::ModalType WebDialogWindowDelegateBridge::GetDialogModalType() const {
135 // TODO(akalin): Support modal dialog boxes.
136 if (delegate_ && delegate_->GetDialogModalType() != ui::MODAL_TYPE_NONE) {
137 LOG(WARNING) << "Modal Web dialogs are not supported yet";
138 }
139 return ui::MODAL_TYPE_NONE;
140 }
141
142 base::string16 WebDialogWindowDelegateBridge::GetDialogTitle() const {
143 return delegate_ ? delegate_->GetDialogTitle() : base::string16();
144 }
145
146 GURL WebDialogWindowDelegateBridge::GetDialogContentURL() const {
147 return delegate_ ? delegate_->GetDialogContentURL() : GURL();
148 }
149
150 void WebDialogWindowDelegateBridge::GetWebUIMessageHandlers(
151 std::vector<WebUIMessageHandler*>* handlers) const {
152 if (delegate_) {
153 delegate_->GetWebUIMessageHandlers(handlers);
154 } else {
155 // TODO(akalin): Add this clause in the windows version. Also
156 // make sure that everything expects handlers to be non-NULL and
157 // document it.
158 handlers->clear();
159 }
160 }
161
162 void WebDialogWindowDelegateBridge::GetDialogSize(gfx::Size* size) const {
163 if (delegate_)
164 delegate_->GetDialogSize(size);
165 else
166 *size = gfx::Size();
167 }
168
169 void WebDialogWindowDelegateBridge::GetMinimumDialogSize(
170 gfx::Size* size) const {
171 if (delegate_)
172 delegate_->GetMinimumDialogSize(size);
173 else
174 *size = gfx::Size();
175 }
176
177 std::string WebDialogWindowDelegateBridge::GetDialogArgs() const {
178 return delegate_ ? delegate_->GetDialogArgs() : "";
179 }
180
181 void WebDialogWindowDelegateBridge::OnDialogClosed(
182 const std::string& json_retval) {
183 Detach();
184 // [controller_ close] should be called at most once, too.
185 if (DelegateOnDialogClosed(json_retval)) {
186 [controller_ close];
187 }
188 controller_ = nil;
189 }
190
191 void WebDialogWindowDelegateBridge::OnCloseContents(WebContents* source,
192 bool* out_close_dialog) {
193 *out_close_dialog = true;
194 }
195
196 void WebDialogWindowDelegateBridge::CloseContents(WebContents* source) {
197 bool close_dialog = false;
198 OnCloseContents(source, &close_dialog);
199 if (close_dialog)
200 OnDialogClosed(std::string());
201 }
202
203 content::WebContents* WebDialogWindowDelegateBridge::OpenURLFromTab(
204 content::WebContents* source,
205 const content::OpenURLParams& params) {
206 content::WebContents* new_contents = NULL;
207 if (delegate_ &&
208 delegate_->HandleOpenURLFromTab(source, params, &new_contents)) {
209 return new_contents;
210 }
211 return WebDialogWebContentsDelegate::OpenURLFromTab(source, params);
212 }
213
214 void WebDialogWindowDelegateBridge::AddNewContents(
215 content::WebContents* source,
216 content::WebContents* new_contents,
217 WindowOpenDisposition disposition,
218 const gfx::Rect& initial_rect,
219 bool user_gesture,
220 bool* was_blocked) {
221 if (delegate_ && delegate_->HandleAddNewContents(
222 source, new_contents, disposition, initial_rect, user_gesture)) {
223 return;
224 }
225 WebDialogWebContentsDelegate::AddNewContents(
226 source, new_contents, disposition, initial_rect, user_gesture,
227 was_blocked);
228 }
229
230 void WebDialogWindowDelegateBridge::LoadingStateChanged(
231 content::WebContents* source, bool to_different_document) {
232 if (delegate_)
233 delegate_->OnLoadingStateChanged(source);
234 }
235
236 void WebDialogWindowDelegateBridge::MoveContents(WebContents* source,
237 const gfx::Rect& pos) {
238 // TODO(akalin): Actually set the window bounds.
239 }
240
241 // A simplified version of BrowserWindowCocoa::HandleKeyboardEvent().
242 // We don't handle global keyboard shortcuts here, but that's fine since
243 // they're all browser-specific. (This may change in the future.)
244 void WebDialogWindowDelegateBridge::HandleKeyboardEvent(
245 content::WebContents* source,
246 const NativeWebKeyboardEvent& event) {
247 if (event.skip_in_browser || event.type == NativeWebKeyboardEvent::Char)
248 return;
249
250 // Close ourselves if the user hits Esc or Command-. . The normal
251 // way to do this is to implement (void)cancel:(int)sender, but
252 // since we handle keyboard events ourselves we can't do that.
253 //
254 // According to experiments, hitting Esc works regardless of the
255 // presence of other modifiers (as long as it's not an app-level
256 // shortcut, e.g. Commmand-Esc for Front Row) but no other modifiers
257 // can be present for Command-. to work.
258 //
259 // TODO(thakis): It would be nice to get cancel: to work somehow.
260 // Bug: http://code.google.com/p/chromium/issues/detail?id=32828 .
261 if (event.type == NativeWebKeyboardEvent::RawKeyDown &&
262 ((event.windowsKeyCode == ui::VKEY_ESCAPE) ||
263 (event.windowsKeyCode == ui::VKEY_OEM_PERIOD &&
264 event.modifiers == NativeWebKeyboardEvent::MetaKey))) {
265 [controller_ close];
266 return;
267 }
268
269 ChromeEventProcessingWindow* event_window =
270 static_cast<ChromeEventProcessingWindow*>([controller_ window]);
271 DCHECK([event_window isKindOfClass:[ChromeEventProcessingWindow class]]);
272 [event_window redispatchKeyEvent:event.os_event];
273 }
274
275 @implementation WebDialogWindowController
276
277 // NOTE(akalin): We'll probably have to add the parentWindow parameter back
278 // in once we implement modal dialogs.
279
280 + (NSWindow*)showWebDialog:(WebDialogDelegate*)delegate
281 context:(content::BrowserContext*)context {
282 WebDialogWindowController* webDialogWindowController =
283 [[WebDialogWindowController alloc] initWithDelegate:delegate
284 context:context];
285 [webDialogWindowController loadDialogContents];
286 [webDialogWindowController showWindow:nil];
287 return [webDialogWindowController window];
288 }
289
290 - (id)initWithDelegate:(WebDialogDelegate*)delegate
291 context:(content::BrowserContext*)context {
292 DCHECK(delegate);
293 DCHECK(context);
294
295 gfx::Size dialogSize;
296 delegate->GetDialogSize(&dialogSize);
297 NSRect dialogRect = NSMakeRect(0, 0, dialogSize.width(), dialogSize.height());
298 NSUInteger style = NSTitledWindowMask | NSClosableWindowMask |
299 NSResizableWindowMask;
300 base::scoped_nsobject<ChromeEventProcessingWindow> window(
301 [[ChromeEventProcessingWindow alloc]
302 initWithContentRect:dialogRect
303 styleMask:style
304 backing:NSBackingStoreBuffered
305 defer:NO]);
306 if (!window.get()) {
307 return nil;
308 }
309 self = [super initWithWindow:window];
310 if (!self) {
311 return nil;
312 }
313 [window setWindowController:self];
314 [window setDelegate:self];
315 [window setTitle:base::SysUTF16ToNSString(delegate->GetDialogTitle())];
316 [window setMinSize:dialogRect.size];
317 [window center];
318 delegate_.reset(
319 new WebDialogWindowDelegateBridge(self, context, delegate));
320 return self;
321 }
322
323 - (void)loadDialogContents {
324 webContents_.reset(WebContents::Create(
325 WebContents::CreateParams(delegate_->browser_context())));
326 [[self window] setContentView:webContents_->GetNativeView()];
327 webContents_->SetDelegate(delegate_.get());
328
329 // This must be done before loading the page; see the comments in
330 // WebDialogUI.
331 WebDialogUI::SetDelegate(webContents_.get(), delegate_.get());
332
333 webContents_->GetController().LoadURL(
334 delegate_->GetDialogContentURL(),
335 content::Referrer(),
336 ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
337 std::string());
338
339 // TODO(akalin): add accelerator for ESC to close the dialog box.
340 //
341 // TODO(akalin): Figure out why implementing (void)cancel:(id)sender
342 // to do the above doesn't work.
343 }
344
345 - (void)windowWillClose:(NSNotification*)notification {
346 delegate_->WindowControllerClosed();
347 [self autorelease];
348 }
349
350 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698