| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/cocoa/html_dialog_window_controller.h" | 5 #import "chrome/browser/cocoa/html_dialog_window_controller.h" |
| 6 | 6 |
| 7 #include "base/gfx/size.h" | 7 #include "base/gfx/size.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/scoped_nsobject.h" | 9 #include "base/scoped_nsobject.h" |
| 10 #include "base/sys_string_conversions.h" | 10 #include "base/sys_string_conversions.h" |
| 11 #include "chrome/browser/browser.h" | |
| 12 #include "chrome/browser/browser_window.h" | |
| 13 #import "chrome/browser/cocoa/browser_command_executor.h" | 11 #import "chrome/browser/cocoa/browser_command_executor.h" |
| 14 #import "chrome/browser/cocoa/chrome_event_processing_window.h" | 12 #import "chrome/browser/cocoa/chrome_event_processing_window.h" |
| 15 #include "chrome/browser/dom_ui/html_dialog_ui.h" | 13 #include "chrome/browser/dom_ui/html_dialog_ui.h" |
| 14 #include "chrome/browser/dom_ui/html_dialog_tab_contents_delegate.h" |
| 16 #include "chrome/browser/profile.h" | 15 #include "chrome/browser/profile.h" |
| 17 #include "chrome/browser/tab_contents/tab_contents.h" | 16 #include "chrome/browser/tab_contents/tab_contents.h" |
| 18 #include "chrome/browser/tab_contents/tab_contents_delegate.h" | |
| 19 #include "googleurl/src/gurl.h" | |
| 20 | 17 |
| 21 // Thin bridge that routes notifications to | 18 // Thin bridge that routes notifications to |
| 22 // HtmlDialogWindowController's member variables. | 19 // HtmlDialogWindowController's member variables. |
| 23 class HtmlDialogWindowDelegateBridge : public HtmlDialogUIDelegate, | 20 class HtmlDialogWindowDelegateBridge : public HtmlDialogUIDelegate, |
| 24 public TabContentsDelegate { | 21 public HtmlDialogTabContentsDelegate { |
| 25 public: | 22 public: |
| 26 // All parameters must be non-NULL/non-nil. | 23 // All parameters must be non-NULL/non-nil. |
| 27 HtmlDialogWindowDelegateBridge(HtmlDialogWindowController* controller, | 24 HtmlDialogWindowDelegateBridge(HtmlDialogWindowController* controller, |
| 25 Profile* profile, |
| 28 HtmlDialogUIDelegate* delegate); | 26 HtmlDialogUIDelegate* delegate); |
| 29 | 27 |
| 30 virtual ~HtmlDialogWindowDelegateBridge(); | 28 virtual ~HtmlDialogWindowDelegateBridge(); |
| 31 | 29 |
| 32 // Called when the window is directly closed, e.g. from the close | 30 // Called when the window is directly closed, e.g. from the close |
| 33 // button or from an accelerator. | 31 // button or from an accelerator. |
| 34 void WindowControllerClosed(); | 32 void WindowControllerClosed(); |
| 35 | 33 |
| 36 // HtmlDialogUIDelegate declarations. | 34 // HtmlDialogUIDelegate declarations. |
| 37 virtual bool IsDialogModal() const; | 35 virtual bool IsDialogModal() const; |
| 38 virtual std::wstring GetDialogTitle() const; | 36 virtual std::wstring GetDialogTitle() const; |
| 39 virtual GURL GetDialogContentURL() const; | 37 virtual GURL GetDialogContentURL() const; |
| 40 virtual void GetDOMMessageHandlers( | 38 virtual void GetDOMMessageHandlers( |
| 41 std::vector<DOMMessageHandler*>* handlers) const; | 39 std::vector<DOMMessageHandler*>* handlers) const; |
| 42 virtual void GetDialogSize(gfx::Size* size) const; | 40 virtual void GetDialogSize(gfx::Size* size) const; |
| 43 virtual std::string GetDialogArgs() const; | 41 virtual std::string GetDialogArgs() const; |
| 44 virtual void OnDialogClosed(const std::string& json_retval); | 42 virtual void OnDialogClosed(const std::string& json_retval); |
| 45 | 43 |
| 46 // TabContentsDelegate declarations. | 44 // HtmlDialogTabContentsDelegate declarations. |
| 47 // | |
| 48 // TODO(akalin): decomp this out into a separate platform-independent class | |
| 49 // so they don't diverge in behavior. In particular, | |
| 50 // ShouldAddNavigationToHistory() should return false on all platforms but | |
| 51 // currently does so only on OS X. This is tracked in | |
| 52 // http://code.google.com/p/chromium/issues/detail?id=28609 . | |
| 53 virtual void OpenURLFromTab(TabContents* source, | |
| 54 const GURL& url, const GURL& referrer, | |
| 55 WindowOpenDisposition disposition, | |
| 56 PageTransition::Type transition); | |
| 57 virtual void NavigationStateChanged(const TabContents* source, | |
| 58 unsigned changed_flags); | |
| 59 virtual void AddNewContents(TabContents* source, | |
| 60 TabContents* new_contents, | |
| 61 WindowOpenDisposition disposition, | |
| 62 const gfx::Rect& initial_pos, | |
| 63 bool user_gesture); | |
| 64 virtual void ActivateContents(TabContents* contents); | |
| 65 virtual void LoadingStateChanged(TabContents* source); | |
| 66 virtual void CloseContents(TabContents* source); | |
| 67 virtual void MoveContents(TabContents* source, const gfx::Rect& pos); | 45 virtual void MoveContents(TabContents* source, const gfx::Rect& pos); |
| 68 virtual bool IsPopup(TabContents* source); | |
| 69 virtual void ToolbarSizeChanged(TabContents* source, bool is_animating); | 46 virtual void ToolbarSizeChanged(TabContents* source, bool is_animating); |
| 70 virtual void URLStarredChanged(TabContents* source, bool starred); | |
| 71 virtual void UpdateTargetURL(TabContents* source, const GURL& url); | |
| 72 virtual bool ShouldAddNavigationToHistory() const; | |
| 73 | 47 |
| 74 private: | 48 private: |
| 75 HtmlDialogWindowController* controller_; // weak | 49 HtmlDialogWindowController* controller_; // weak |
| 76 HtmlDialogUIDelegate* delegate_; // weak, owned by controller_ | 50 HtmlDialogUIDelegate* delegate_; // weak, owned by controller_ |
| 77 | 51 |
| 78 // Calls delegate_'s OnDialogClosed() exactly once, nulling it out | 52 // Calls delegate_'s OnDialogClosed() exactly once, nulling it out |
| 79 // afterwards so that no other HtmlDialogUIDelegate calls are sent | 53 // afterwards so that no other HtmlDialogUIDelegate calls are sent |
| 80 // to it. Returns whether or not the OnDialogClosed() was actually | 54 // to it. Returns whether or not the OnDialogClosed() was actually |
| 81 // called on the delegate. | 55 // called on the delegate. |
| 82 bool DelegateOnDialogClosed(const std::string& json_retval); | 56 bool DelegateOnDialogClosed(const std::string& json_retval); |
| 83 | 57 |
| 84 DISALLOW_COPY_AND_ASSIGN(HtmlDialogWindowDelegateBridge); | 58 DISALLOW_COPY_AND_ASSIGN(HtmlDialogWindowDelegateBridge); |
| 85 }; | 59 }; |
| 86 | 60 |
| 87 // ChromeEventProcessingWindow expects its controller to implement the | 61 // ChromeEventProcessingWindow expects its controller to implement the |
| 88 // BrowserCommandExecutor protocol. | 62 // BrowserCommandExecutor protocol. |
| 89 @interface HtmlDialogWindowController (InternalAPI) <BrowserCommandExecutor> | 63 @interface HtmlDialogWindowController (InternalAPI) <BrowserCommandExecutor> |
| 90 | 64 |
| 91 - (Profile*)profile; | |
| 92 | |
| 93 // BrowserCommandExecutor methods. | 65 // BrowserCommandExecutor methods. |
| 94 - (void)executeCommand:(int)command; | 66 - (void)executeCommand:(int)command; |
| 95 | 67 |
| 96 @end | 68 @end |
| 97 | 69 |
| 98 namespace html_dialog_window_controller { | 70 namespace html_dialog_window_controller { |
| 99 | 71 |
| 100 void ShowHtmlDialog(HtmlDialogUIDelegate* delegate, Profile* profile) { | 72 void ShowHtmlDialog(HtmlDialogUIDelegate* delegate, Profile* profile) { |
| 101 [HtmlDialogWindowController showHtmlDialog:delegate profile:profile]; | 73 [HtmlDialogWindowController showHtmlDialog:delegate profile:profile]; |
| 102 } | 74 } |
| 103 | 75 |
| 104 } // namespace html_dialog_window_controller | 76 } // namespace html_dialog_window_controller |
| 105 | 77 |
| 106 HtmlDialogWindowDelegateBridge::HtmlDialogWindowDelegateBridge( | 78 HtmlDialogWindowDelegateBridge::HtmlDialogWindowDelegateBridge( |
| 107 HtmlDialogWindowController* controller, HtmlDialogUIDelegate* delegate) | 79 HtmlDialogWindowController* controller, Profile* profile, |
| 108 : controller_(controller), delegate_(delegate) { | 80 HtmlDialogUIDelegate* delegate) |
| 81 : HtmlDialogTabContentsDelegate(profile), |
| 82 controller_(controller), delegate_(delegate) { |
| 109 DCHECK(controller_); | 83 DCHECK(controller_); |
| 110 DCHECK(delegate_); | 84 DCHECK(delegate_); |
| 111 } | 85 } |
| 112 | 86 |
| 113 HtmlDialogWindowDelegateBridge::~HtmlDialogWindowDelegateBridge() {} | 87 HtmlDialogWindowDelegateBridge::~HtmlDialogWindowDelegateBridge() {} |
| 114 | 88 |
| 115 void HtmlDialogWindowDelegateBridge::WindowControllerClosed() { | 89 void HtmlDialogWindowDelegateBridge::WindowControllerClosed() { |
| 90 Detach(); |
| 91 controller_ = nil; |
| 116 DelegateOnDialogClosed(""); | 92 DelegateOnDialogClosed(""); |
| 117 controller_ = nil; | |
| 118 } | 93 } |
| 119 | 94 |
| 120 bool HtmlDialogWindowDelegateBridge::DelegateOnDialogClosed( | 95 bool HtmlDialogWindowDelegateBridge::DelegateOnDialogClosed( |
| 121 const std::string& json_retval) { | 96 const std::string& json_retval) { |
| 122 if (delegate_) { | 97 if (delegate_) { |
| 123 HtmlDialogUIDelegate* real_delegate = delegate_; | 98 HtmlDialogUIDelegate* real_delegate = delegate_; |
| 124 delegate_ = NULL; | 99 delegate_ = NULL; |
| 125 real_delegate->OnDialogClosed(json_retval); | 100 real_delegate->OnDialogClosed(json_retval); |
| 126 return true; | 101 return true; |
| 127 } | 102 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 *size = gfx::Size(); | 143 *size = gfx::Size(); |
| 169 } | 144 } |
| 170 } | 145 } |
| 171 | 146 |
| 172 std::string HtmlDialogWindowDelegateBridge::GetDialogArgs() const { | 147 std::string HtmlDialogWindowDelegateBridge::GetDialogArgs() const { |
| 173 return delegate_ ? delegate_->GetDialogArgs() : ""; | 148 return delegate_ ? delegate_->GetDialogArgs() : ""; |
| 174 } | 149 } |
| 175 | 150 |
| 176 void HtmlDialogWindowDelegateBridge::OnDialogClosed( | 151 void HtmlDialogWindowDelegateBridge::OnDialogClosed( |
| 177 const std::string& json_retval) { | 152 const std::string& json_retval) { |
| 153 Detach(); |
| 178 // [controller_ close] should be called at most once, too. | 154 // [controller_ close] should be called at most once, too. |
| 179 if (DelegateOnDialogClosed(json_retval)) { | 155 if (DelegateOnDialogClosed(json_retval)) { |
| 180 [controller_ close]; | 156 [controller_ close]; |
| 181 } | 157 } |
| 182 controller_ = nil; | 158 controller_ = nil; |
| 183 } | 159 } |
| 184 | 160 |
| 185 // TabContentsDelegate definitions. Most of this logic is copied from | |
| 186 // chrome/browser/views/html_dialog_view.cc . All functions with empty | |
| 187 // bodies are notifications we don't care about. | |
| 188 | |
| 189 void HtmlDialogWindowDelegateBridge::OpenURLFromTab( | |
| 190 TabContents* source, const GURL& url, const GURL& referrer, | |
| 191 WindowOpenDisposition disposition, PageTransition::Type transition) { | |
| 192 if (controller_) { | |
| 193 // Force all links to open in a new window. Code adapted from | |
| 194 // Browser::OpenURLFromTab() with disposition == NEW_WINDOW. | |
| 195 Browser* browser = Browser::Create([controller_ profile]); | |
| 196 TabContents* new_contents = | |
| 197 browser->AddTabWithURL(url, referrer, transition, true, -1, false, NULL); | |
| 198 new_contents->Focus(); | |
| 199 } | |
| 200 } | |
| 201 | |
| 202 void HtmlDialogWindowDelegateBridge::NavigationStateChanged( | |
| 203 const TabContents* source, unsigned changed_flags) { | |
| 204 } | |
| 205 | |
| 206 void HtmlDialogWindowDelegateBridge::AddNewContents( | |
| 207 TabContents* source, TabContents* new_contents, | |
| 208 WindowOpenDisposition disposition, const gfx::Rect& initial_pos, | |
| 209 bool user_gesture) { | |
| 210 if (controller_) { | |
| 211 // Force this to open in a new window, too. Code adapted from | |
| 212 // Browser::AddNewContents() with disposition == NEW_WINDOW. | |
| 213 Browser* browser = Browser::Create([controller_ profile]); | |
| 214 static_cast<TabContentsDelegate*>(browser)-> | |
| 215 AddNewContents(source, new_contents, NEW_FOREGROUND_TAB, | |
| 216 initial_pos, user_gesture); | |
| 217 browser->window()->Show(); | |
| 218 } | |
| 219 } | |
| 220 | |
| 221 void HtmlDialogWindowDelegateBridge::ActivateContents(TabContents* contents) {} | |
| 222 | |
| 223 void HtmlDialogWindowDelegateBridge::LoadingStateChanged(TabContents* source) {} | |
| 224 | |
| 225 void HtmlDialogWindowDelegateBridge::CloseContents(TabContents* source) {} | |
| 226 | |
| 227 void HtmlDialogWindowDelegateBridge::MoveContents(TabContents* source, | 161 void HtmlDialogWindowDelegateBridge::MoveContents(TabContents* source, |
| 228 const gfx::Rect& pos) { | 162 const gfx::Rect& pos) { |
| 229 // TODO(akalin): Actually set the window bounds. | 163 // TODO(akalin): Actually set the window bounds. |
| 230 } | 164 } |
| 231 | 165 |
| 232 bool HtmlDialogWindowDelegateBridge::IsPopup(TabContents* source) { | |
| 233 // This needs to return true so that we are allowed to be resized by | |
| 234 // our contents. | |
| 235 return true; | |
| 236 } | |
| 237 | |
| 238 void HtmlDialogWindowDelegateBridge::ToolbarSizeChanged( | 166 void HtmlDialogWindowDelegateBridge::ToolbarSizeChanged( |
| 239 TabContents* source, bool is_animating) { | 167 TabContents* source, bool is_animating) { |
| 240 // TODO(akalin): Figure out what to do here. | 168 // TODO(akalin): Figure out what to do here. |
| 241 } | 169 } |
| 242 | 170 |
| 243 void HtmlDialogWindowDelegateBridge::URLStarredChanged( | |
| 244 TabContents* source, bool starred) { | |
| 245 // We don't have a visible star to click in the window. | |
| 246 NOTREACHED(); | |
| 247 } | |
| 248 | |
| 249 void HtmlDialogWindowDelegateBridge::UpdateTargetURL( | |
| 250 TabContents* source, const GURL& url) {} | |
| 251 | |
| 252 bool HtmlDialogWindowDelegateBridge::ShouldAddNavigationToHistory() const { | |
| 253 return false; | |
| 254 } | |
| 255 | |
| 256 @implementation HtmlDialogWindowController (InternalAPI) | 171 @implementation HtmlDialogWindowController (InternalAPI) |
| 257 | 172 |
| 258 - (Profile*)profile { | |
| 259 return profile_; | |
| 260 } | |
| 261 | |
| 262 // This gets called whenever a chrome-specific keyboard shortcut is performed | 173 // This gets called whenever a chrome-specific keyboard shortcut is performed |
| 263 // in the HTML dialog window. We simply swallow all those events. | 174 // in the HTML dialog window. We simply swallow all those events. |
| 264 - (void)executeCommand:(int)command {} | 175 - (void)executeCommand:(int)command {} |
| 265 | 176 |
| 266 @end | 177 @end |
| 267 | 178 |
| 268 @implementation HtmlDialogWindowController | 179 @implementation HtmlDialogWindowController |
| 269 | 180 |
| 270 // NOTE(akalin): We'll probably have to add the parentWindow parameter back | 181 // NOTE(akalin): We'll probably have to add the parentWindow parameter back |
| 271 // in once we implement modal dialogs. | 182 // in once we implement modal dialogs. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 302 return nil; | 213 return nil; |
| 303 } | 214 } |
| 304 self = [super initWithWindow:window]; | 215 self = [super initWithWindow:window]; |
| 305 if (!self) { | 216 if (!self) { |
| 306 return nil; | 217 return nil; |
| 307 } | 218 } |
| 308 [window setWindowController:self]; | 219 [window setWindowController:self]; |
| 309 [window setDelegate:self]; | 220 [window setDelegate:self]; |
| 310 [window setTitle:base::SysWideToNSString(delegate->GetDialogTitle())]; | 221 [window setTitle:base::SysWideToNSString(delegate->GetDialogTitle())]; |
| 311 [window center]; | 222 [window center]; |
| 312 delegate_.reset(new HtmlDialogWindowDelegateBridge(self, delegate)); | 223 delegate_.reset(new HtmlDialogWindowDelegateBridge(self, profile, delegate)); |
| 313 // Incognito profiles are not long-lived, so we always want to store a | |
| 314 // non-incognito profile. | |
| 315 // | |
| 316 // TODO(akalin): Should we make it so that we have a default incognito | |
| 317 // profile that's long-lived? Of course, we'd still have to clear it out | |
| 318 // when all incognito browsers close. | |
| 319 profile_ = profile->GetOriginalProfile(); | |
| 320 return self; | 224 return self; |
| 321 } | 225 } |
| 322 | 226 |
| 323 - (void)loadDialogContents { | 227 - (void)loadDialogContents { |
| 324 tabContents_.reset(new TabContents(profile_, NULL, MSG_ROUTING_NONE, NULL)); | 228 tabContents_.reset( |
| 229 new TabContents(delegate_->profile(), NULL, MSG_ROUTING_NONE, NULL)); |
| 325 [[self window] setContentView:tabContents_->GetNativeView()]; | 230 [[self window] setContentView:tabContents_->GetNativeView()]; |
| 326 tabContents_->set_delegate(delegate_.get()); | 231 tabContents_->set_delegate(delegate_.get()); |
| 327 | 232 |
| 328 // This must be done before loading the page; see the comments in | 233 // This must be done before loading the page; see the comments in |
| 329 // HtmlDialogUI. | 234 // HtmlDialogUI. |
| 330 HtmlDialogUI::GetPropertyAccessor().SetProperty(tabContents_->property_bag(), | 235 HtmlDialogUI::GetPropertyAccessor().SetProperty(tabContents_->property_bag(), |
| 331 delegate_.get()); | 236 delegate_.get()); |
| 332 | 237 |
| 333 tabContents_->controller().LoadURL(delegate_->GetDialogContentURL(), | 238 tabContents_->controller().LoadURL(delegate_->GetDialogContentURL(), |
| 334 GURL(), PageTransition::START_PAGE); | 239 GURL(), PageTransition::START_PAGE); |
| 335 | 240 |
| 336 // TODO(akalin): add accelerator for ESC to close the dialog box. | 241 // TODO(akalin): add accelerator for ESC to close the dialog box. |
| 337 // | 242 // |
| 338 // TODO(akalin): Figure out why implementing (void)cancel:(id)sender | 243 // TODO(akalin): Figure out why implementing (void)cancel:(id)sender |
| 339 // to do the above doesn't work. | 244 // to do the above doesn't work. |
| 340 } | 245 } |
| 341 | 246 |
| 342 - (void)windowWillClose:(NSNotification*)notification { | 247 - (void)windowWillClose:(NSNotification*)notification { |
| 343 delegate_->WindowControllerClosed(); | 248 delegate_->WindowControllerClosed(); |
| 344 [self autorelease]; | 249 [self autorelease]; |
| 345 } | 250 } |
| 346 | 251 |
| 347 @end | 252 @end |
| 348 | 253 |
| OLD | NEW |