| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "content/browser/tab_contents/tab_contents.h" | 5 #include "content/browser/tab_contents/tab_contents.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 11 #include "base/metrics/stats_counters.h" | 11 #include "base/metrics/stats_counters.h" |
| 12 #include "base/string16.h" | 12 #include "base/string16.h" |
| 13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 14 #include "base/time.h" | 14 #include "base/time.h" |
| 15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
| 16 #include "chrome/browser/debugger/devtools_manager.h" | 16 #include "chrome/browser/debugger/devtools_manager.h" |
| 17 #include "chrome/browser/load_from_memory_cache_details.h" | 17 #include "chrome/browser/load_from_memory_cache_details.h" |
| 18 #include "chrome/browser/notifications/desktop_notification_service.h" | 18 #include "chrome/browser/notifications/desktop_notification_service.h" |
| 19 #include "chrome/browser/notifications/desktop_notification_service_factory.h" | 19 #include "chrome/browser/notifications/desktop_notification_service_factory.h" |
| 20 #include "chrome/browser/profiles/profile.h" | 20 #include "chrome/browser/profiles/profile.h" |
| 21 #include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h" | |
| 22 #include "chrome/common/chrome_constants.h" | |
| 23 #include "content/browser/child_process_security_policy.h" | 21 #include "content/browser/child_process_security_policy.h" |
| 24 #include "content/browser/content_browser_client.h" | 22 #include "content/browser/content_browser_client.h" |
| 25 #include "content/browser/host_zoom_map.h" | 23 #include "content/browser/host_zoom_map.h" |
| 26 #include "content/browser/in_process_webkit/session_storage_namespace.h" | 24 #include "content/browser/in_process_webkit/session_storage_namespace.h" |
| 27 #include "content/browser/load_notification_details.h" | 25 #include "content/browser/load_notification_details.h" |
| 28 #include "content/browser/renderer_host/render_process_host.h" | 26 #include "content/browser/renderer_host/render_process_host.h" |
| 29 #include "content/browser/renderer_host/render_view_host.h" | 27 #include "content/browser/renderer_host/render_view_host.h" |
| 30 #include "content/browser/renderer_host/render_widget_host_view.h" | 28 #include "content/browser/renderer_host/render_widget_host_view.h" |
| 31 #include "content/browser/renderer_host/resource_request_details.h" | 29 #include "content/browser/renderer_host/resource_request_details.h" |
| 32 #include "content/browser/site_instance.h" | 30 #include "content/browser/site_instance.h" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 load_state_(net::LOAD_STATE_IDLE), | 179 load_state_(net::LOAD_STATE_IDLE), |
| 182 upload_size_(0), | 180 upload_size_(0), |
| 183 upload_position_(0), | 181 upload_position_(0), |
| 184 displayed_insecure_content_(false), | 182 displayed_insecure_content_(false), |
| 185 capturing_contents_(false), | 183 capturing_contents_(false), |
| 186 is_being_destroyed_(false), | 184 is_being_destroyed_(false), |
| 187 notify_disconnection_(false), | 185 notify_disconnection_(false), |
| 188 #if defined(OS_WIN) | 186 #if defined(OS_WIN) |
| 189 message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)), | 187 message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)), |
| 190 #endif | 188 #endif |
| 191 suppress_javascript_messages_(false), | |
| 192 is_showing_before_unload_dialog_(false), | 189 is_showing_before_unload_dialog_(false), |
| 193 opener_web_ui_type_(WebUI::kNoWebUI), | 190 opener_web_ui_type_(WebUI::kNoWebUI), |
| 194 closed_by_user_gesture_(false), | 191 closed_by_user_gesture_(false), |
| 195 minimum_zoom_percent_( | 192 minimum_zoom_percent_( |
| 196 static_cast<int>(WebKit::WebView::minTextSizeMultiplier * 100)), | 193 static_cast<int>(WebKit::WebView::minTextSizeMultiplier * 100)), |
| 197 maximum_zoom_percent_( | 194 maximum_zoom_percent_( |
| 198 static_cast<int>(WebKit::WebView::maxTextSizeMultiplier * 100)), | 195 static_cast<int>(WebKit::WebView::maxTextSizeMultiplier * 100)), |
| 199 temporary_zoom_settings_(false), | 196 temporary_zoom_settings_(false), |
| 200 content_restrictions_(0) { | 197 content_restrictions_(0) { |
| 201 | 198 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 214 // uses to get the routing_id. | 211 // uses to get the routing_id. |
| 215 AddObservers(); | 212 AddObservers(); |
| 216 } | 213 } |
| 217 | 214 |
| 218 TabContents::~TabContents() { | 215 TabContents::~TabContents() { |
| 219 is_being_destroyed_ = true; | 216 is_being_destroyed_ = true; |
| 220 | 217 |
| 221 // We don't want any notifications while we're running our destructor. | 218 // We don't want any notifications while we're running our destructor. |
| 222 registrar_.RemoveAll(); | 219 registrar_.RemoveAll(); |
| 223 | 220 |
| 221 // Clear out any JavaScript state. |
| 222 if (delegate_) |
| 223 delegate_->GetJavaScriptDialogCreator()->ResetJavaScriptState(this); |
| 224 |
| 224 NotifyDisconnected(); | 225 NotifyDisconnected(); |
| 225 | 226 |
| 226 // First cleanly close all child windows. | 227 // First cleanly close all child windows. |
| 227 // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked | 228 // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked |
| 228 // some of these to close. CloseWindows is async, so it might get called | 229 // some of these to close. CloseWindows is async, so it might get called |
| 229 // twice before it runs. | 230 // twice before it runs. |
| 230 CloseConstrainedWindows(); | 231 CloseConstrainedWindows(); |
| 231 | 232 |
| 232 // Notify any observer that have a reference on this tab contents. | 233 // Notify any observer that have a reference on this tab contents. |
| 233 NotificationService::current()->Notify( | 234 NotificationService::current()->Notify( |
| (...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1082 | 1083 |
| 1083 // Notify observers about navigation. | 1084 // Notify observers about navigation. |
| 1084 FOR_EACH_OBSERVER(TabContentsObserver, observers_, | 1085 FOR_EACH_OBSERVER(TabContentsObserver, observers_, |
| 1085 DidNavigateMainFramePostCommit(details, params)); | 1086 DidNavigateMainFramePostCommit(details, params)); |
| 1086 } | 1087 } |
| 1087 | 1088 |
| 1088 void TabContents::DidNavigateAnyFramePostCommit( | 1089 void TabContents::DidNavigateAnyFramePostCommit( |
| 1089 RenderViewHost* render_view_host, | 1090 RenderViewHost* render_view_host, |
| 1090 const content::LoadCommittedDetails& details, | 1091 const content::LoadCommittedDetails& details, |
| 1091 const ViewHostMsg_FrameNavigate_Params& params) { | 1092 const ViewHostMsg_FrameNavigate_Params& params) { |
| 1092 // If we navigate, start showing messages again. This does nothing to prevent | 1093 // If we navigate, reset JavaScript state. This does nothing to prevent |
| 1093 // a malicious script from spamming messages, since the script could just | 1094 // a malicious script from spamming messages, since the script could just |
| 1094 // reload the page to stop blocking. | 1095 // reload the page to stop blocking. |
| 1095 suppress_javascript_messages_ = false; | 1096 if (delegate_) |
| 1097 delegate_->GetJavaScriptDialogCreator()->ResetJavaScriptState(this); |
| 1096 | 1098 |
| 1097 // Notify observers about navigation. | 1099 // Notify observers about navigation. |
| 1098 FOR_EACH_OBSERVER(TabContentsObserver, observers_, | 1100 FOR_EACH_OBSERVER(TabContentsObserver, observers_, |
| 1099 DidNavigateAnyFramePostCommit(details, params)); | 1101 DidNavigateAnyFramePostCommit(details, params)); |
| 1100 } | 1102 } |
| 1101 | 1103 |
| 1102 void TabContents::CloseConstrainedWindows() { | 1104 void TabContents::CloseConstrainedWindows() { |
| 1103 // Clear out any constrained windows since we are leaving this page entirely. | 1105 // Clear out any constrained windows since we are leaving this page entirely. |
| 1104 // To ensure that we iterate over every element in child_windows_ we | 1106 // To ensure that we iterate over every element in child_windows_ we |
| 1105 // need to use a copy of child_windows_. Otherwise if | 1107 // need to use a copy of child_windows_. Otherwise if |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1552 } | 1554 } |
| 1553 | 1555 |
| 1554 void TabContents::RunJavaScriptMessage( | 1556 void TabContents::RunJavaScriptMessage( |
| 1555 const RenderViewHost* rvh, | 1557 const RenderViewHost* rvh, |
| 1556 const string16& message, | 1558 const string16& message, |
| 1557 const string16& default_prompt, | 1559 const string16& default_prompt, |
| 1558 const GURL& frame_url, | 1560 const GURL& frame_url, |
| 1559 const int flags, | 1561 const int flags, |
| 1560 IPC::Message* reply_msg, | 1562 IPC::Message* reply_msg, |
| 1561 bool* did_suppress_message) { | 1563 bool* did_suppress_message) { |
| 1562 // Suppress javascript messages when requested and when inside a constrained | 1564 // Suppress JavaScript dialogs when requested. Also suppress messages when |
| 1563 // popup window (because that activates them and breaks them out of the | 1565 // showing an interstitial as it's shown over the previous page and we don't |
| 1564 // constrained window jail). | 1566 // want the hidden page's dialogs to interfere with the interstitial. |
| 1565 // Also suppress messages when showing an interstitial. The interstitial is | |
| 1566 // shown over the previous page, we don't want the hidden page dialogs to | |
| 1567 // interfere with the interstitial. | |
| 1568 bool suppress_this_message = | 1567 bool suppress_this_message = |
| 1569 rvh->is_swapped_out() || | 1568 rvh->is_swapped_out() || |
| 1570 suppress_javascript_messages_ || | |
| 1571 showing_interstitial_page() || | 1569 showing_interstitial_page() || |
| 1572 (delegate() && delegate()->ShouldSuppressDialogs()); | 1570 !delegate_ || |
| 1573 if (delegate()) | 1571 delegate_->ShouldSuppressDialogs(); |
| 1574 suppress_this_message |= | 1572 |
| 1575 (delegate()->GetConstrainingContents(this) != this); | 1573 if (!suppress_this_message) { |
| 1574 delegate_->GetJavaScriptDialogCreator()->RunJavaScriptDialog( |
| 1575 this, |
| 1576 frame_url, |
| 1577 flags, |
| 1578 message, |
| 1579 default_prompt, |
| 1580 reply_msg, |
| 1581 &suppress_this_message, |
| 1582 profile()); |
| 1583 } |
| 1584 |
| 1585 if (suppress_this_message) { |
| 1586 // If we are suppressing messages, just reply as if the user immediately |
| 1587 // pressed "Cancel". |
| 1588 OnDialogClosed(reply_msg, false, string16()); |
| 1589 } |
| 1576 | 1590 |
| 1577 *did_suppress_message = suppress_this_message; | 1591 *did_suppress_message = suppress_this_message; |
| 1578 | |
| 1579 if (!suppress_this_message) { | |
| 1580 base::TimeDelta time_since_last_message( | |
| 1581 base::TimeTicks::Now() - last_javascript_message_dismissal_); | |
| 1582 bool show_suppress_checkbox = false; | |
| 1583 // Show a checkbox offering to suppress further messages if this message is | |
| 1584 // being displayed within kJavascriptMessageExpectedDelay of the last one. | |
| 1585 if (time_since_last_message < | |
| 1586 base::TimeDelta::FromMilliseconds( | |
| 1587 chrome::kJavascriptMessageExpectedDelay)) | |
| 1588 show_suppress_checkbox = true; | |
| 1589 | |
| 1590 RunJavascriptMessageBox(profile(), | |
| 1591 this, | |
| 1592 frame_url, | |
| 1593 flags, | |
| 1594 UTF16ToWideHack(message), | |
| 1595 UTF16ToWideHack(default_prompt), | |
| 1596 show_suppress_checkbox, | |
| 1597 reply_msg); | |
| 1598 } else { | |
| 1599 // If we are suppressing messages, just reply as is if the user immediately | |
| 1600 // pressed "Cancel". | |
| 1601 OnMessageBoxClosed(reply_msg, false, std::wstring()); | |
| 1602 } | |
| 1603 } | 1592 } |
| 1604 | 1593 |
| 1605 void TabContents::RunBeforeUnloadConfirm(const RenderViewHost* rvh, | 1594 void TabContents::RunBeforeUnloadConfirm(const RenderViewHost* rvh, |
| 1606 const string16& message, | 1595 const string16& message, |
| 1607 IPC::Message* reply_msg) { | 1596 IPC::Message* reply_msg) { |
| 1608 if (delegate()) | 1597 if (delegate()) |
| 1609 delegate()->WillRunBeforeUnloadConfirm(); | 1598 delegate()->WillRunBeforeUnloadConfirm(); |
| 1610 bool suppress_this_message = rvh->is_swapped_out() || | 1599 |
| 1611 (delegate() && delegate()->ShouldSuppressDialogs()); | 1600 bool suppress_this_message = |
| 1601 rvh->is_swapped_out() || |
| 1602 !delegate_ || |
| 1603 delegate_->ShouldSuppressDialogs(); |
| 1612 if (suppress_this_message) { | 1604 if (suppress_this_message) { |
| 1613 render_view_host()->JavaScriptDialogClosed(reply_msg, true, string16()); | 1605 render_view_host()->JavaScriptDialogClosed(reply_msg, true, string16()); |
| 1614 return; | 1606 return; |
| 1615 } | 1607 } |
| 1608 |
| 1616 is_showing_before_unload_dialog_ = true; | 1609 is_showing_before_unload_dialog_ = true; |
| 1617 RunBeforeUnloadDialog(this, UTF16ToWideHack(message), reply_msg); | 1610 delegate_->GetJavaScriptDialogCreator()->RunBeforeUnloadDialog( |
| 1611 this, |
| 1612 message, |
| 1613 reply_msg); |
| 1618 } | 1614 } |
| 1619 | 1615 |
| 1620 WebPreferences TabContents::GetWebkitPrefs() { | 1616 WebPreferences TabContents::GetWebkitPrefs() { |
| 1621 Profile* profile = render_view_host()->process()->profile(); | 1617 Profile* profile = render_view_host()->process()->profile(); |
| 1622 bool is_web_ui = false; | 1618 bool is_web_ui = false; |
| 1623 WebPreferences web_prefs = | 1619 WebPreferences web_prefs = |
| 1624 RenderViewHostDelegateHelper::GetWebkitPrefs(profile, is_web_ui); | 1620 RenderViewHostDelegateHelper::GetWebkitPrefs(profile, is_web_ui); |
| 1625 | 1621 |
| 1626 // Force accelerated compositing and 2d canvas off for chrome: and | 1622 // Force accelerated compositing and 2d canvas off for chrome: and |
| 1627 // chrome-extension: pages. | 1623 // chrome-extension: pages. |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1805 const NotificationDetails& details) { | 1801 const NotificationDetails& details) { |
| 1806 switch (type.value) { | 1802 switch (type.value) { |
| 1807 case NotificationType::RENDER_WIDGET_HOST_DESTROYED: | 1803 case NotificationType::RENDER_WIDGET_HOST_DESTROYED: |
| 1808 view_->RenderWidgetHostDestroyed(Source<RenderWidgetHost>(source).ptr()); | 1804 view_->RenderWidgetHostDestroyed(Source<RenderWidgetHost>(source).ptr()); |
| 1809 break; | 1805 break; |
| 1810 default: | 1806 default: |
| 1811 NOTREACHED(); | 1807 NOTREACHED(); |
| 1812 } | 1808 } |
| 1813 } | 1809 } |
| 1814 | 1810 |
| 1815 gfx::NativeWindow TabContents::GetMessageBoxRootWindow() { | 1811 // Overridden from JavaScriptDialogDelegate |
| 1816 return view_->GetTopLevelNativeWindow(); | |
| 1817 } | |
| 1818 | 1812 |
| 1819 void TabContents::OnMessageBoxClosed(IPC::Message* reply_msg, | 1813 void TabContents::OnDialogClosed(IPC::Message* reply_msg, |
| 1820 bool success, | 1814 bool success, |
| 1821 const std::wstring& user_input) { | 1815 const string16& user_input) { |
| 1822 last_javascript_message_dismissal_ = base::TimeTicks::Now(); | |
| 1823 if (is_showing_before_unload_dialog_ && !success) { | 1816 if (is_showing_before_unload_dialog_ && !success) { |
| 1824 // If a beforeunload dialog is canceled, we need to stop the throbber from | 1817 // If a beforeunload dialog is canceled, we need to stop the throbber from |
| 1825 // spinning, since we forced it to start spinning in Navigate. | 1818 // spinning, since we forced it to start spinning in Navigate. |
| 1826 DidStopLoading(); | 1819 DidStopLoading(); |
| 1827 | 1820 |
| 1828 tab_close_start_time_ = base::TimeTicks(); | 1821 tab_close_start_time_ = base::TimeTicks(); |
| 1829 } | 1822 } |
| 1830 is_showing_before_unload_dialog_ = false; | 1823 is_showing_before_unload_dialog_ = false; |
| 1831 render_view_host()->JavaScriptDialogClosed(reply_msg, | 1824 render_view_host()->JavaScriptDialogClosed(reply_msg, |
| 1832 success, | 1825 success, |
| 1833 WideToUTF16Hack(user_input)); | 1826 user_input); |
| 1834 } | 1827 } |
| 1835 | 1828 |
| 1836 void TabContents::SetSuppressMessageBoxes(bool suppress_message_boxes) { | 1829 gfx::NativeWindow TabContents::GetDialogRootWindow() { |
| 1837 set_suppress_javascript_messages(suppress_message_boxes); | 1830 return view_->GetTopLevelNativeWindow(); |
| 1838 } | 1831 } |
| 1839 | 1832 |
| 1840 TabContents* TabContents::AsTabContents() { | 1833 TabContents* TabContents::AsTabContents() { |
| 1841 return this; | 1834 return this; |
| 1842 } | 1835 } |
| 1843 | 1836 |
| 1844 ExtensionHost* TabContents::AsExtensionHost() { | 1837 ExtensionHost* TabContents::AsExtensionHost() { |
| 1845 return NULL; | 1838 return NULL; |
| 1846 } | 1839 } |
| 1847 | 1840 |
| 1848 void TabContents::set_encoding(const std::string& encoding) { | 1841 void TabContents::set_encoding(const std::string& encoding) { |
| 1849 encoding_ = content::GetContentClient()->browser()-> | 1842 encoding_ = content::GetContentClient()->browser()-> |
| 1850 GetCanonicalEncodingNameByAliasName(encoding); | 1843 GetCanonicalEncodingNameByAliasName(encoding); |
| 1851 } | 1844 } |
| 1852 | 1845 |
| 1853 void TabContents::SwapInRenderViewHost(RenderViewHost* rvh) { | 1846 void TabContents::SwapInRenderViewHost(RenderViewHost* rvh) { |
| 1854 render_manager_.SwapInRenderViewHost(rvh); | 1847 render_manager_.SwapInRenderViewHost(rvh); |
| 1855 } | 1848 } |
| 1856 | 1849 |
| 1857 void TabContents::CreateViewAndSetSizeForRVH(RenderViewHost* rvh) { | 1850 void TabContents::CreateViewAndSetSizeForRVH(RenderViewHost* rvh) { |
| 1858 RenderWidgetHostView* rwh_view = view()->CreateViewForWidget(rvh); | 1851 RenderWidgetHostView* rwh_view = view()->CreateViewForWidget(rvh); |
| 1859 rwh_view->SetSize(view()->GetContainerSize()); | 1852 rwh_view->SetSize(view()->GetContainerSize()); |
| 1860 } | 1853 } |
| 1861 | 1854 |
| 1862 void TabContents::OnOnlineStateChanged(bool online) { | 1855 void TabContents::OnOnlineStateChanged(bool online) { |
| 1863 render_view_host()->Send(new ViewMsg_NetworkStateChanged( | 1856 render_view_host()->Send(new ViewMsg_NetworkStateChanged( |
| 1864 render_view_host()->routing_id(), online)); | 1857 render_view_host()->routing_id(), online)); |
| 1865 } | 1858 } |
| OLD | NEW |