diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-17 21:47:16 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-17 21:47:16 +0000 |
commit | d9d8f0c234ea70e6c5121c038c3c6ab33699f903 (patch) | |
tree | b755aee455afacf4bb88950ab74e6876ad85dd39 /chrome/browser/external_tab_container_win.cc | |
parent | 1b8a1b648148a058b2c03d89398a65038992732f (diff) | |
download | chromium_src-d9d8f0c234ea70e6c5121c038c3c6ab33699f903.zip chromium_src-d9d8f0c234ea70e6c5121c038c3c6ab33699f903.tar.gz chromium_src-d9d8f0c234ea70e6c5121c038c3c6ab33699f903.tar.bz2 |
Added full support for invoking before unload and unload handlers on ChromeFrame rendered
pages. This allows a webpage to put up a confirmation dialog in its beforeunload handler
and potentially cancel the operation. We only support invoking unload handlers on the page
for IE full tab mode. To achieve this the active document handles the OLECMDID_ONUNLOAD
exec command which is passed by the DOCHOST to the object which allows us to potentially
cancel the operation.
Thanks to Stoyan for his help in authoring parts of this CL.
The AutomationMsg_RunUnloadHandlers message which is used only by ChromeFrame is now a sync
message which returns back a bool indicating whether the unload operation can be continued
or not. The ExternalTabContainer now implements the BeforeUnloadFired method in the
TabContentsDelegate and aborts the unload operation if the user chose to not proceed with
the unload.
Fixes bug http://code.google.com/p/chromium/issues/detail?id=33200
Bug=33200
Test=Covered by existing unload event test. Will add a test which validates whether a page
can cancel the unload operation in a subsequent CL.
Review URL: http://codereview.chromium.org/3450014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59854 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/external_tab_container_win.cc')
-rw-r--r-- | chrome/browser/external_tab_container_win.cc | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/chrome/browser/external_tab_container_win.cc b/chrome/browser/external_tab_container_win.cc index 24d7f60..012a966 100644 --- a/chrome/browser/external_tab_container_win.cc +++ b/chrome/browser/external_tab_container_win.cc @@ -57,13 +57,11 @@ ExternalTabContainer::ExternalTabContainer( handle_top_level_requests_(false), external_method_factory_(this), enabled_extension_automation_(false), - waiting_for_unload_event_(false), pending_(false), infobars_enabled_(true), focus_manager_(NULL), external_tab_view_(NULL), - notification_window_(NULL), - notification_message_(NULL) { + unload_reply_message_(NULL) { } ExternalTabContainer::~ExternalTabContainer() { @@ -417,15 +415,16 @@ void ExternalTabContainer::LoadingStateChanged(TabContents* source) { } void ExternalTabContainer::CloseContents(TabContents* source) { - static const int kExternalTabCloseContentsDelayMS = 100; + if (!automation_) + return; - if (waiting_for_unload_event_) { - PostMessage(notification_window_, notification_message_, 0, 0); - waiting_for_unload_event_ = false; + if (unload_reply_message_) { + AutomationMsg_RunUnloadHandlers::WriteReplyParams(unload_reply_message_, + true); + automation_->Send(unload_reply_message_); + unload_reply_message_ = NULL; } else { - if (automation_) { - automation_->Send(new AutomationMsg_CloseExternalTab(0, tab_handle_)); - } + automation_->Send(new AutomationMsg_CloseExternalTab(0, tab_handle_)); } } @@ -612,6 +611,27 @@ void ExternalTabContainer::ShowHtmlDialog(HtmlDialogUIDelegate* delegate, browser_->window()->ShowHTMLDialog(delegate, parent); } +void ExternalTabContainer::BeforeUnloadFired(TabContents* tab, + bool proceed, + bool* proceed_to_fire_unload) { + DCHECK(unload_reply_message_); + *proceed_to_fire_unload = true; + + if (!automation_) { + delete unload_reply_message_; + unload_reply_message_ = NULL; + return; + } + + if (!proceed) { + AutomationMsg_RunUnloadHandlers::WriteReplyParams(unload_reply_message_, + false); + automation_->Send(unload_reply_message_); + unload_reply_message_ = NULL; + *proceed_to_fire_unload = false; + } +} + //////////////////////////////////////////////////////////////////////////////// // ExternalTabContainer, NotificationObserver implementation: @@ -717,20 +737,24 @@ void ExternalTabContainer::OnFinalMessage(HWND window) { Release(); } -void ExternalTabContainer::RunUnloadHandlers( - gfx::NativeWindow notification_window, - int notification_message) { - DCHECK(::IsWindow(notification_window)); - if (tab_contents_) { - notification_window_ = notification_window; - notification_message_ = notification_message; +void ExternalTabContainer::RunUnloadHandlers(IPC::Message* reply_message) { + if (!automation_) { + delete reply_message; + return; + } - if (Browser::RunUnloadEventsHelper(tab_contents_)) { - waiting_for_unload_event_ = true; - } + // If we have a pending unload message, then just respond back to this + // request and continue processing the previous unload message. + if (unload_reply_message_) { + AutomationMsg_RunUnloadHandlers::WriteReplyParams(reply_message, true); + automation_->Send(reply_message); + return; } - if (!waiting_for_unload_event_) { - PostMessage(notification_window, notification_message, 0, 0); + if (tab_contents_ && Browser::RunUnloadEventsHelper(tab_contents_)) { + unload_reply_message_ = reply_message; + } else { + AutomationMsg_RunUnloadHandlers::WriteReplyParams(reply_message, true); + automation_->Send(reply_message); } } |