| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/browser/web_contents.h" | 5 #include "chrome/browser/web_contents.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/compiler_specific.h" |
| 8 #include "base/file_version_info.h" | 9 #include "base/file_version_info.h" |
| 9 #include "chrome/app/locales/locale_settings.h" | 10 #include "chrome/app/locales/locale_settings.h" |
| 10 #include "chrome/browser/bookmarks/bookmark_model.h" | 11 #include "chrome/browser/bookmarks/bookmark_model.h" |
| 11 #include "chrome/browser/browser.h" | 12 #include "chrome/browser/browser.h" |
| 12 #include "chrome/browser/cache_manager_host.h" | 13 #include "chrome/browser/cache_manager_host.h" |
| 13 #include "chrome/browser/character_encoding.h" | 14 #include "chrome/browser/character_encoding.h" |
| 14 #include "chrome/browser/dom_operation_notification_details.h" | 15 #include "chrome/browser/dom_operation_notification_details.h" |
| 15 #include "chrome/browser/download/download_manager.h" | 16 #include "chrome/browser/download/download_manager.h" |
| 16 #include "chrome/browser/find_in_page_controller.h" | 17 #include "chrome/browser/find_in_page_controller.h" |
| 17 #include "chrome/browser/find_notification_details.h" | 18 #include "chrome/browser/find_notification_details.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 43 #include "chrome/common/pref_names.h" | 44 #include "chrome/common/pref_names.h" |
| 44 #include "chrome/common/pref_service.h" | 45 #include "chrome/common/pref_service.h" |
| 45 #include "chrome/common/resource_bundle.h" | 46 #include "chrome/common/resource_bundle.h" |
| 46 #include "net/base/mime_util.h" | 47 #include "net/base/mime_util.h" |
| 47 #include "net/base/registry_controlled_domain.h" | 48 #include "net/base/registry_controlled_domain.h" |
| 48 #include "webkit/glue/webkit_glue.h" | 49 #include "webkit/glue/webkit_glue.h" |
| 49 #include "webkit/glue/plugins/webplugin_delegate_impl.h" | 50 #include "webkit/glue/plugins/webplugin_delegate_impl.h" |
| 50 | 51 |
| 51 #include "generated_resources.h" | 52 #include "generated_resources.h" |
| 52 | 53 |
| 54 // Cross-Site Navigations |
| 55 // |
| 56 // If a WebContents is told to navigate to a different web site (as determined |
| 57 // by SiteInstance), it will replace its current RenderViewHost with a new |
| 58 // RenderViewHost dedicated to the new SiteInstance. This works as follows: |
| 59 // |
| 60 // - Navigate determines whether the destination is cross-site, and if so, |
| 61 // it creates a pending_render_view_host_ and moves into the PENDING |
| 62 // RendererState. |
| 63 // - The pending RVH is "suspended," so that no navigation messages are sent to |
| 64 // its renderer until the onbeforeunload JavaScript handler has a chance to |
| 65 // run in the current RVH. |
| 66 // - The pending RVH tells CrossSiteRequestManager (a thread-safe singleton) |
| 67 // that it has a pending cross-site request. ResourceDispatcherHost will |
| 68 // check for this when the response arrives. |
| 69 // - The current RVH runs its onbeforeunload handler. If it returns false, we |
| 70 // cancel all the pending logic and go back to NORMAL. Otherwise we allow |
| 71 // the pending RVH to send the navigation request to its renderer. |
| 72 // - ResourceDispatcherHost receives a ResourceRequest on the IO thread. It |
| 73 // checks CrossSiteRequestManager to see that the RVH responsible has a |
| 74 // pending cross-site request, and then installs a CrossSiteEventHandler. |
| 75 // - When RDH receives a response, the BufferedEventHandler determines whether |
| 76 // it is a download. If so, it sends a message to the new renderer causing |
| 77 // it to cancel the request, and the download proceeds in the download |
| 78 // thread. For now, we stay in a PENDING state (with a pending RVH) until |
| 79 // the next DidNavigate event for this WebContents. This isn't ideal, but it |
| 80 // doesn't affect any functionality. |
| 81 // - After RDH receives a response and determines that it is safe and not a |
| 82 // download, it pauses the response to first run the old page's onunload |
| 83 // handler. It does this by asynchronously calling the OnCrossSiteResponse |
| 84 // method of WebContents on the UI thread, which sends a ClosePage message |
| 85 // to the current RVH. |
| 86 // - Once the onunload handler is finished, a ClosePage_ACK message is sent to |
| 87 // the ResourceDispatcherHost, who unpauses the response. Data is then sent |
| 88 // to the pending RVH. |
| 89 // - The pending renderer sends a FrameNavigate message that invokes the |
| 90 // DidNavigate method. This replaces the current RVH with the |
| 91 // pending RVH and goes back to the NORMAL RendererState. |
| 92 |
| 53 namespace { | 93 namespace { |
| 54 | 94 |
| 55 // Amount of time we wait between when a key event is received and the renderer | 95 // Amount of time we wait between when a key event is received and the renderer |
| 56 // is queried for its state and pushed to the NavigationEntry. | 96 // is queried for its state and pushed to the NavigationEntry. |
| 57 const int kQueryStateDelay = 5000; | 97 const int kQueryStateDelay = 5000; |
| 58 | 98 |
| 59 const int kSyncWaitDelay = 40; | 99 const int kSyncWaitDelay = 40; |
| 60 | 100 |
| 61 // If another javascript message box is displayed within | 101 // If another javascript message box is displayed within |
| 62 // kJavascriptMessageExpectedDelay of a previous javascript message box being | 102 // kJavascriptMessageExpectedDelay of a previous javascript message box being |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 const int kPrefsToObserveLength = arraysize(kPrefsToObserve); | 137 const int kPrefsToObserveLength = arraysize(kPrefsToObserve); |
| 98 | 138 |
| 99 void InitWebContentsClass() { | 139 void InitWebContentsClass() { |
| 100 static bool web_contents_class_initialized = false; | 140 static bool web_contents_class_initialized = false; |
| 101 if (!web_contents_class_initialized) { | 141 if (!web_contents_class_initialized) { |
| 102 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 142 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 103 web_contents_class_initialized = true; | 143 web_contents_class_initialized = true; |
| 104 } | 144 } |
| 105 } | 145 } |
| 106 | 146 |
| 147 // Returns true if the entry's transition type is FORM_SUBMIT. |
| 148 bool IsFormSubmit(const NavigationEntry* entry) { |
| 149 return (PageTransition::StripQualifier(entry->transition_type()) == |
| 150 PageTransition::FORM_SUBMIT); |
| 151 } |
| 152 |
| 107 } // namespace | 153 } // namespace |
| 108 | 154 |
| 109 /////////////////////////////////////////////////////////////////////////////// | |
| 110 // WebContents | |
| 111 | |
| 112 class WebContents::GearsCreateShortcutCallbackFunctor { | 155 class WebContents::GearsCreateShortcutCallbackFunctor { |
| 113 public: | 156 public: |
| 114 explicit GearsCreateShortcutCallbackFunctor(WebContents* contents) | 157 explicit GearsCreateShortcutCallbackFunctor(WebContents* contents) |
| 115 : contents_(contents) {} | 158 : contents_(contents) {} |
| 116 | 159 |
| 117 void Run(const GearsShortcutData& shortcut_data, bool success) { | 160 void Run(const GearsShortcutData& shortcut_data, bool success) { |
| 118 if (contents_) | 161 if (contents_) |
| 119 contents_->OnGearsCreateShortcutDone(shortcut_data, success); | 162 contents_->OnGearsCreateShortcutDone(shortcut_data, success); |
| 120 delete this; | 163 delete this; |
| 121 } | 164 } |
| 122 void Cancel() { | 165 void Cancel() { |
| 123 contents_ = NULL; | 166 contents_ = NULL; |
| 124 } | 167 } |
| 125 | 168 |
| 126 private: | 169 private: |
| 127 WebContents* contents_; | 170 WebContents* contents_; |
| 128 }; | 171 }; |
| 129 | 172 |
| 173 WebContents::WebContents(Profile* profile, |
| 174 SiteInstance* site_instance, |
| 175 RenderViewHostFactory* render_view_factory, |
| 176 int routing_id, |
| 177 HANDLE modal_dialog_event) |
| 178 : TabContents(TAB_CONTENTS_WEB), |
| 179 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 180 render_manager_(render_view_factory, this, this)), |
| 181 render_view_factory_(render_view_factory), |
| 182 has_page_title_(false), |
| 183 info_bar_visible_(false), |
| 184 is_starred_(false), |
| 185 printing_(*this), |
| 186 notify_disconnection_(false), |
| 187 message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)), |
| 188 ALLOW_THIS_IN_INITIALIZER_LIST(fav_icon_helper_(this)), |
| 189 crashed_plugin_info_bar_(NULL), |
| 190 suppress_javascript_messages_(false), |
| 191 load_state_(net::LOAD_STATE_IDLE) { |
| 192 InitWebContentsClass(); |
| 193 |
| 194 pending_install_.page_id = 0; |
| 195 pending_install_.callback_functor = NULL; |
| 196 |
| 197 render_manager_.Init(profile, site_instance, routing_id, modal_dialog_event); |
| 198 |
| 199 // Register for notifications about all interested prefs change. |
| 200 PrefService* prefs = profile->GetPrefs(); |
| 201 if (prefs) |
| 202 for (int i = 0; i < kPrefsToObserveLength; ++i) |
| 203 prefs->AddPrefObserver(kPrefsToObserve[i], this); |
| 204 |
| 205 // Register for notifications about URL starredness changing on any profile. |
| 206 NotificationService::current()-> |
| 207 AddObserver(this, NOTIFY_URLS_STARRED, NotificationService::AllSources()); |
| 208 NotificationService::current()-> |
| 209 AddObserver(this, NOTIFY_BOOKMARK_MODEL_LOADED, |
| 210 NotificationService::AllSources()); |
| 211 } |
| 212 |
| 213 WebContents::~WebContents() { |
| 214 if (web_app_.get()) |
| 215 web_app_->RemoveObserver(this); |
| 216 if (pending_install_.callback_functor) |
| 217 pending_install_.callback_functor->Cancel(); |
| 218 } |
| 219 |
| 130 // static | 220 // static |
| 131 void WebContents::RegisterUserPrefs(PrefService* prefs) { | 221 void WebContents::RegisterUserPrefs(PrefService* prefs) { |
| 132 prefs->RegisterBooleanPref(prefs::kAlternateErrorPagesEnabled, true); | 222 prefs->RegisterBooleanPref(prefs::kAlternateErrorPagesEnabled, true); |
| 133 | 223 |
| 134 WebPreferences pref_defaults; | 224 WebPreferences pref_defaults; |
| 135 prefs->RegisterBooleanPref(prefs::kWebKitJavascriptEnabled, | 225 prefs->RegisterBooleanPref(prefs::kWebKitJavascriptEnabled, |
| 136 pref_defaults.javascript_enabled); | 226 pref_defaults.javascript_enabled); |
| 137 prefs->RegisterBooleanPref( | 227 prefs->RegisterBooleanPref( |
| 138 prefs::kWebKitJavascriptCanOpenWindowsAutomatically, true); | 228 prefs::kWebKitJavascriptCanOpenWindowsAutomatically, true); |
| 139 prefs->RegisterBooleanPref(prefs::kWebKitLoadsImagesAutomatically, | 229 prefs->RegisterBooleanPref(prefs::kWebKitLoadsImagesAutomatically, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 prefs->RegisterLocalizedIntegerPref(prefs::kWebKitMinimumFontSize, | 264 prefs->RegisterLocalizedIntegerPref(prefs::kWebKitMinimumFontSize, |
| 175 IDS_MINIMUM_FONT_SIZE); | 265 IDS_MINIMUM_FONT_SIZE); |
| 176 prefs->RegisterLocalizedIntegerPref(prefs::kWebKitMinimumLogicalFontSize, | 266 prefs->RegisterLocalizedIntegerPref(prefs::kWebKitMinimumLogicalFontSize, |
| 177 IDS_MINIMUM_LOGICAL_FONT_SIZE); | 267 IDS_MINIMUM_LOGICAL_FONT_SIZE); |
| 178 prefs->RegisterLocalizedBooleanPref(prefs::kWebKitUsesUniversalDetector, | 268 prefs->RegisterLocalizedBooleanPref(prefs::kWebKitUsesUniversalDetector, |
| 179 IDS_USES_UNIVERSAL_DETECTOR); | 269 IDS_USES_UNIVERSAL_DETECTOR); |
| 180 prefs->RegisterLocalizedStringPref(prefs::kStaticEncodings, | 270 prefs->RegisterLocalizedStringPref(prefs::kStaticEncodings, |
| 181 IDS_STATIC_ENCODING_LIST); | 271 IDS_STATIC_ENCODING_LIST); |
| 182 } | 272 } |
| 183 | 273 |
| 184 WebContents::WebContents(Profile* profile, | 274 PasswordManager* WebContents::GetPasswordManager() { |
| 185 SiteInstance* site_instance, | 275 if (password_manager_.get() == NULL) |
| 186 RenderViewHostFactory* render_view_factory, | 276 password_manager_.reset(new PasswordManager(this)); |
| 187 int routing_id, | 277 return password_manager_.get(); |
| 188 HANDLE modal_dialog_event) | |
| 189 : TabContents(TAB_CONTENTS_WEB), | |
| 190 #pragma warning(suppress: 4355) // Okay to pass "this" here. | |
| 191 render_manager_(render_view_factory, this, this), | |
| 192 render_view_factory_(render_view_factory), | |
| 193 has_page_title_(false), | |
| 194 info_bar_visible_(false), | |
| 195 is_starred_(false), | |
| 196 printing_(*this), | |
| 197 notify_disconnection_(false), | |
| 198 message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)), | |
| 199 capturing_contents_(false), | |
| 200 #pragma warning(suppress: 4355) // Okay to pass "this" here. | |
| 201 fav_icon_helper_(this), | |
| 202 crashed_plugin_info_bar_(NULL), | |
| 203 suppress_javascript_messages_(false), | |
| 204 load_state_(net::LOAD_STATE_IDLE) { | |
| 205 InitWebContentsClass(); | |
| 206 | |
| 207 pending_install_.page_id = 0; | |
| 208 pending_install_.callback_functor = NULL; | |
| 209 | |
| 210 render_manager_.Init(profile, site_instance, routing_id, modal_dialog_event); | |
| 211 | |
| 212 // Register for notifications about all interested prefs change. | |
| 213 PrefService* prefs = profile->GetPrefs(); | |
| 214 if (prefs) | |
| 215 for (int i = 0; i < kPrefsToObserveLength; ++i) | |
| 216 prefs->AddPrefObserver(kPrefsToObserve[i], this); | |
| 217 | |
| 218 // Register for notifications about URL starredness changing on any profile. | |
| 219 NotificationService::current()-> | |
| 220 AddObserver(this, NOTIFY_URLS_STARRED, NotificationService::AllSources()); | |
| 221 NotificationService::current()-> | |
| 222 AddObserver(this, NOTIFY_BOOKMARK_MODEL_LOADED, | |
| 223 NotificationService::AllSources()); | |
| 224 } | 278 } |
| 225 | 279 |
| 226 WebContents::~WebContents() { | 280 PluginInstaller* WebContents::GetPluginInstaller() { |
| 227 if (web_app_.get()) | 281 if (plugin_installer_.get() == NULL) |
| 228 web_app_->RemoveObserver(this); | 282 plugin_installer_.reset(new PluginInstaller(this)); |
| 229 if (pending_install_.callback_functor) | 283 return plugin_installer_.get(); |
| 230 pending_install_.callback_functor->Cancel(); | |
| 231 } | |
| 232 | |
| 233 void WebContents::CreateView(HWND parent_hwnd, | |
| 234 const gfx::Rect& initial_bounds) { | |
| 235 set_delete_on_destroy(false); | |
| 236 HWNDViewContainer::Init(parent_hwnd, initial_bounds, false); | |
| 237 | |
| 238 // Remove the root view drop target so we can register our own. | |
| 239 RevokeDragDrop(GetHWND()); | |
| 240 drop_target_ = new WebDropTarget(GetHWND(), this); | |
| 241 } | |
| 242 | |
| 243 void WebContents::GetContainerBounds(gfx::Rect *out) const { | |
| 244 CRect r; | |
| 245 GetBounds(&r, false); | |
| 246 *out = r; | |
| 247 } | |
| 248 | |
| 249 void WebContents::ShowContents() { | |
| 250 if (view()) | |
| 251 view()->DidBecomeSelected(); | |
| 252 | |
| 253 // Loop through children and send DidBecomeSelected to them, too. | |
| 254 int count = static_cast<int>(child_windows_.size()); | |
| 255 for (int i = count - 1; i >= 0; --i) { | |
| 256 ConstrainedWindow* window = child_windows_.at(i); | |
| 257 window->DidBecomeSelected(); | |
| 258 } | |
| 259 | |
| 260 // If we have a FindInPage dialog, notify it that its tab was selected. | |
| 261 if (find_in_page_controller_.get()) | |
| 262 find_in_page_controller_->DidBecomeSelected(); | |
| 263 } | |
| 264 | |
| 265 void WebContents::HideContents() { | |
| 266 // TODO(pkasting): http://b/1239839 Right now we purposefully don't call | |
| 267 // our superclass HideContents(), because some callers want to be very picky | |
| 268 // about the order in which these get called. In addition to making the code | |
| 269 // here practically impossible to understand, this also means we end up | |
| 270 // calling TabContents::WasHidden() twice if callers call both versions of | |
| 271 // HideContents() on a WebContents. | |
| 272 | |
| 273 WasHidden(); | |
| 274 } | |
| 275 | |
| 276 void WebContents::SizeContents(const gfx::Size& size) { | |
| 277 if (view()) | |
| 278 view()->SetSize(size); | |
| 279 if (find_in_page_controller_.get()) | |
| 280 find_in_page_controller_->RespondToResize(size); | |
| 281 RepositionSupressedPopupsToFit(size); | |
| 282 } | 284 } |
| 283 | 285 |
| 284 void WebContents::Destroy() { | 286 void WebContents::Destroy() { |
| 285 // Tell the notification service we no longer want notifications. | 287 // Tell the notification service we no longer want notifications. |
| 286 NotificationService::current()-> | 288 NotificationService::current()-> |
| 287 RemoveObserver(this, NOTIFY_URLS_STARRED, | 289 RemoveObserver(this, NOTIFY_URLS_STARRED, |
| 288 NotificationService::AllSources()); | 290 NotificationService::AllSources()); |
| 289 NotificationService::current()-> | 291 NotificationService::current()-> |
| 290 RemoveObserver(this, NOTIFY_BOOKMARK_MODEL_LOADED, | 292 RemoveObserver(this, NOTIFY_BOOKMARK_MODEL_LOADED, |
| 291 NotificationService::AllSources()); | 293 NotificationService::AllSources()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 309 // Detach plugin windows so that they are not destroyed automatically. | 311 // Detach plugin windows so that they are not destroyed automatically. |
| 310 // They will be cleaned up properly in plugin process. | 312 // They will be cleaned up properly in plugin process. |
| 311 DetachPluginWindows(); | 313 DetachPluginWindows(); |
| 312 | 314 |
| 313 NotifyDisconnected(); | 315 NotifyDisconnected(); |
| 314 HungRendererWarning::HideForWebContents(this); | 316 HungRendererWarning::HideForWebContents(this); |
| 315 render_manager_.Shutdown(); | 317 render_manager_.Shutdown(); |
| 316 TabContents::Destroy(); | 318 TabContents::Destroy(); |
| 317 } | 319 } |
| 318 | 320 |
| 319 /////////////////////////////////////////////////////////////////////////////// | 321 SiteInstance* WebContents::GetSiteInstance() const { |
| 320 // Event Handlers | 322 return render_manager_.current_host()->site_instance(); |
| 321 | |
| 322 void WebContents::OnDestroy() { | |
| 323 if (drop_target_.get()) { | |
| 324 RevokeDragDrop(GetHWND()); | |
| 325 drop_target_ = NULL; | |
| 326 } | |
| 327 } | 323 } |
| 328 | 324 |
| 329 void WebContents::OnWindowPosChanged(WINDOWPOS* window_pos) { | 325 SkBitmap WebContents::GetFavIcon() { |
| 330 if (window_pos->flags & SWP_HIDEWINDOW) { | 326 if (web_app_.get() && IsWebApplicationActive()) { |
| 331 HideContents(); | 327 SkBitmap app_icon = web_app_->GetFavIcon(); |
| 332 } else { | 328 if (!app_icon.isNull()) |
| 333 // The WebContents was shown by a means other than the user selecting a | 329 return app_icon; |
| 334 // Tab, e.g. the window was minimized then restored. | |
| 335 if (window_pos->flags & SWP_SHOWWINDOW) | |
| 336 ShowContents(); | |
| 337 // Unless we were specifically told not to size, cause the renderer to be | |
| 338 // sized to the new bounds, which forces a repaint. Not required for the | |
| 339 // simple minimize-restore case described above, for example, since the | |
| 340 // size hasn't changed. | |
| 341 if (!(window_pos->flags & SWP_NOSIZE)) { | |
| 342 gfx::Size size(window_pos->cx, window_pos->cy); | |
| 343 SizeContents(size); | |
| 344 } | |
| 345 | |
| 346 // If we have a FindInPage dialog, notify it that the window changed. | |
| 347 if (find_in_page_controller_.get() && find_in_page_controller_->IsVisible()) | |
| 348 find_in_page_controller_->MoveWindowIfNecessary(gfx::Rect()); | |
| 349 } | 330 } |
| 331 return TabContents::GetFavIcon(); |
| 350 } | 332 } |
| 351 | 333 |
| 352 void WebContents::OnPaint(HDC junk_dc) { | 334 std::wstring WebContents::GetStatusText() const { |
| 353 if (render_view_host() && !render_view_host()->IsRenderViewLive()) { | 335 if (!is_loading() || load_state_ == net::LOAD_STATE_IDLE) |
| 354 if (!sad_tab_.get()) | 336 return std::wstring(); |
| 355 sad_tab_.reset(new SadTabView); | 337 |
| 356 CRect cr; | 338 switch (load_state_) { |
| 357 GetClientRect(&cr); | 339 case net::LOAD_STATE_WAITING_FOR_CACHE: |
| 358 sad_tab_->SetBounds(cr); | 340 return l10n_util::GetString(IDS_LOAD_STATE_WAITING_FOR_CACHE); |
| 359 ChromeCanvasPaint canvas(GetHWND(), true); | 341 case net::LOAD_STATE_RESOLVING_PROXY_FOR_URL: |
| 360 sad_tab_->ProcessPaint(&canvas); | 342 return l10n_util::GetString(IDS_LOAD_STATE_RESOLVING_PROXY_FOR_URL); |
| 361 return; | 343 case net::LOAD_STATE_RESOLVING_HOST: |
| 344 return l10n_util::GetString(IDS_LOAD_STATE_RESOLVING_HOST); |
| 345 case net::LOAD_STATE_CONNECTING: |
| 346 return l10n_util::GetString(IDS_LOAD_STATE_CONNECTING); |
| 347 case net::LOAD_STATE_SENDING_REQUEST: |
| 348 return l10n_util::GetString(IDS_LOAD_STATE_SENDING_REQUEST); |
| 349 case net::LOAD_STATE_WAITING_FOR_RESPONSE: |
| 350 return l10n_util::GetStringF(IDS_LOAD_STATE_WAITING_FOR_RESPONSE, |
| 351 load_state_host_); |
| 352 // Ignore net::LOAD_STATE_READING_RESPONSE and net::LOAD_STATE_IDLE |
| 362 } | 353 } |
| 363 | 354 |
| 364 // We need to do this to validate the dirty area so we don't end up in a | 355 return std::wstring(); |
| 365 // WM_PAINTstorm that causes other mysterious bugs (such as WM_TIMERs not | |
| 366 // firing etc). It doesn't matter that we don't have any non-clipped area. | |
| 367 CPaintDC dc(GetHWND()); | |
| 368 SetMsgHandled(FALSE); | |
| 369 } | 356 } |
| 370 | 357 |
| 371 LRESULT WebContents::OnMouseRange(UINT msg, WPARAM w_param, LPARAM l_param) { | |
| 372 switch (msg) { | |
| 373 case WM_LBUTTONDOWN: | |
| 374 case WM_MBUTTONDOWN: | |
| 375 case WM_RBUTTONDOWN: | |
| 376 // Make sure this TabContents is activated when it is clicked on. | |
| 377 if (delegate()) | |
| 378 delegate()->ActivateContents(this); | |
| 379 break; | |
| 380 case WM_MOUSEMOVE: | |
| 381 // Let our delegate know that the mouse moved (useful for resetting status | |
| 382 // bubble state). | |
| 383 if (delegate()) | |
| 384 delegate()->ContentsMouseEvent(this, WM_MOUSEMOVE); | |
| 385 break; | |
| 386 default: | |
| 387 break; | |
| 388 } | |
| 389 | |
| 390 return 0; | |
| 391 } | |
| 392 | |
| 393 void WebContents::OnMouseLeave() { | |
| 394 // Let our delegate know that the mouse moved (useful for resetting status | |
| 395 // bubble state). | |
| 396 if (delegate()) | |
| 397 delegate()->ContentsMouseEvent(this, WM_MOUSELEAVE); | |
| 398 SetMsgHandled(FALSE); | |
| 399 } | |
| 400 | |
| 401 // A message is reflected here from view(). | |
| 402 // Return non-zero to indicate that it is handled here. | |
| 403 // Return 0 to allow view() to further process it. | |
| 404 LRESULT WebContents::OnReflectedMessage(UINT msg, WPARAM w_param, | |
| 405 LPARAM l_param) { | |
| 406 MSG* message = reinterpret_cast<MSG*>(l_param); | |
| 407 switch (message->message) { | |
| 408 case WM_MOUSEWHEEL: | |
| 409 // This message is reflected from the view() to this window. | |
| 410 if (GET_KEYSTATE_WPARAM(message->wParam) & MK_CONTROL) { | |
| 411 WheelZoom(GET_WHEEL_DELTA_WPARAM(message->wParam)); | |
| 412 return 1; | |
| 413 } | |
| 414 break; | |
| 415 case WM_HSCROLL: | |
| 416 case WM_VSCROLL: | |
| 417 if (ScrollZoom(LOWORD(message->wParam))) | |
| 418 return 1; | |
| 419 default: | |
| 420 break; | |
| 421 } | |
| 422 | |
| 423 return 0; | |
| 424 } | |
| 425 | |
| 426 void WebContents::OnSize(UINT param, const CSize& size) { | |
| 427 HWNDViewContainer::OnSize(param, size); | |
| 428 | |
| 429 // Hack for thinkpad touchpad driver. | |
| 430 // Set fake scrollbars so that we can get scroll messages, | |
| 431 SCROLLINFO si = {0}; | |
| 432 si.cbSize = sizeof(si); | |
| 433 si.fMask = SIF_ALL; | |
| 434 | |
| 435 si.nMin = 1; | |
| 436 si.nMax = 100; | |
| 437 si.nPage = 10; | |
| 438 si.nTrackPos = 50; | |
| 439 | |
| 440 ::SetScrollInfo(GetHWND(), SB_HORZ, &si, FALSE); | |
| 441 ::SetScrollInfo(GetHWND(), SB_VERT, &si, FALSE); | |
| 442 } | |
| 443 | |
| 444 LRESULT WebContents::OnNCCalcSize(BOOL w_param, LPARAM l_param) { | |
| 445 // Hack for thinkpad mouse wheel driver. We have set the fake scroll bars | |
| 446 // to receive scroll messages from thinkpad touchpad driver. Suppress | |
| 447 // painting of scrollbars by returning 0 size for them. | |
| 448 return 0; | |
| 449 } | |
| 450 | |
| 451 void WebContents::OnNCPaint(HRGN rgn) { | |
| 452 // Suppress default WM_NCPAINT handling. We don't need to do anything | |
| 453 // here since the view will draw everything correctly. | |
| 454 } | |
| 455 | |
| 456 void WebContents::OnHScroll(int scroll_type, short position, HWND scrollbar) { | |
| 457 ScrollCommon(WM_HSCROLL, scroll_type, position, scrollbar); | |
| 458 } | |
| 459 | |
| 460 void WebContents::OnVScroll(int scroll_type, short position, HWND scrollbar) { | |
| 461 ScrollCommon(WM_VSCROLL, scroll_type, position, scrollbar); | |
| 462 } | |
| 463 | |
| 464 void WebContents::ScrollCommon(UINT message, int scroll_type, short position, | |
| 465 HWND scrollbar) { | |
| 466 // This window can receive scroll events as a result of the ThinkPad's | |
| 467 // Trackpad scroll wheel emulation. | |
| 468 if (!ScrollZoom(scroll_type)) { | |
| 469 // Reflect scroll message to the view() to give it a chance | |
| 470 // to process scrolling. | |
| 471 SendMessage(GetContentHWND(), message, MAKELONG(scroll_type, position), | |
| 472 (LPARAM) scrollbar); | |
| 473 } | |
| 474 } | |
| 475 | |
| 476 bool WebContents::ScrollZoom(int scroll_type) { | |
| 477 // If ctrl is held, zoom the UI. There are three issues with this: | |
| 478 // 1) Should the event be eaten or forwarded to content? We eat the event, | |
| 479 // which is like Firefox and unlike IE. | |
| 480 // 2) Should wheel up zoom in or out? We zoom in (increase font size), which | |
| 481 // is like IE and Google maps, but unlike Firefox. | |
| 482 // 3) Should the mouse have to be over the content area? We zoom as long as | |
| 483 // content has focus, although FF and IE require that the mouse is over | |
| 484 // content. This is because all events get forwarded when content has | |
| 485 // focus. | |
| 486 if (GetAsyncKeyState(VK_CONTROL) & 0x8000) { | |
| 487 int distance = 0; | |
| 488 switch (scroll_type) { | |
| 489 case SB_LINEUP: | |
| 490 distance = WHEEL_DELTA; | |
| 491 break; | |
| 492 case SB_LINEDOWN: | |
| 493 distance = -WHEEL_DELTA; | |
| 494 break; | |
| 495 // TODO(joshia): Handle SB_PAGEUP, SB_PAGEDOWN, SB_THUMBPOSITION, | |
| 496 // and SB_THUMBTRACK for completeness | |
| 497 default: | |
| 498 break; | |
| 499 } | |
| 500 | |
| 501 WheelZoom(distance); | |
| 502 return true; | |
| 503 } | |
| 504 return false; | |
| 505 } | |
| 506 | |
| 507 void WebContents::WheelZoom(int distance) { | |
| 508 if (delegate()) { | |
| 509 bool zoom_in = distance > 0; | |
| 510 delegate()->ContentsZoomChange(zoom_in); | |
| 511 } | |
| 512 } | |
| 513 | |
| 514 void WebContents::OnSetFocus(HWND window) { | |
| 515 // TODO(jcampan): figure out why removing this prevents tabs opened in the | |
| 516 // background from properly taking focus. | |
| 517 // We NULL-check the render_view_host_ here because Windows can send us | |
| 518 // messages during the destruction process after it has been destroyed. | |
| 519 if (view()) { | |
| 520 HWND inner_hwnd = view()->GetPluginHWND(); | |
| 521 if (::IsWindow(inner_hwnd)) | |
| 522 ::SetFocus(inner_hwnd); | |
| 523 } | |
| 524 } | |
| 525 | |
| 526 void WebContents::OnSavePage() { | |
| 527 // If we can not save the page, try to download it. | |
| 528 if (!SavePackage::IsSavableContents(contents_mime_type())) { | |
| 529 DownloadManager* dlm = profile()->GetDownloadManager(); | |
| 530 const GURL& current_page_url = GetURL(); | |
| 531 if (dlm && current_page_url.is_valid()) | |
| 532 dlm->DownloadUrl(current_page_url, GURL(), this); | |
| 533 return; | |
| 534 } | |
| 535 | |
| 536 // Get our user preference state. | |
| 537 PrefService* prefs = profile()->GetPrefs(); | |
| 538 DCHECK(prefs); | |
| 539 | |
| 540 std::wstring suggest_name = | |
| 541 SavePackage::GetSuggestNameForSaveAs(prefs, GetTitle()); | |
| 542 | |
| 543 SavePackage::SavePackageParam param(contents_mime_type()); | |
| 544 param.prefs = prefs; | |
| 545 | |
| 546 // TODO(rocking): Use new asynchronous dialog boxes to prevent the SaveAs | |
| 547 // dialog blocking the UI thread. See bug: http://b/issue?id=1129694. | |
| 548 if (SavePackage::GetSaveInfo(suggest_name, GetContainerHWND(), ¶m)) | |
| 549 SavePage(param.saved_main_file_path, param.dir, param.save_type); | |
| 550 } | |
| 551 | |
| 552 void WebContents::SavePage(const std::wstring& main_file, | |
| 553 const std::wstring& dir_path, | |
| 554 SavePackage::SavePackageType save_type) { | |
| 555 // Stop the page from navigating. | |
| 556 Stop(); | |
| 557 | |
| 558 save_package_ = new SavePackage(this, save_type, main_file, dir_path); | |
| 559 save_package_->Init(); | |
| 560 } | |
| 561 | |
| 562 /////////////////////////////////////////////////////////////////////////////// | |
| 563 | |
| 564 // Cross-Site Navigations | |
| 565 // | |
| 566 // If a WebContents is told to navigate to a different web site (as determined | |
| 567 // by SiteInstance), it will replace its current RenderViewHost with a new | |
| 568 // RenderViewHost dedicated to the new SiteInstance. This works as follows: | |
| 569 // | |
| 570 // - Navigate determines whether the destination is cross-site, and if so, | |
| 571 // it creates a pending_render_view_host_ and moves into the PENDING | |
| 572 // RendererState. | |
| 573 // - The pending RVH is "suspended," so that no navigation messages are sent to | |
| 574 // its renderer until the onbeforeunload JavaScript handler has a chance to | |
| 575 // run in the current RVH. | |
| 576 // - The pending RVH tells CrossSiteRequestManager (a thread-safe singleton) | |
| 577 // that it has a pending cross-site request. ResourceDispatcherHost will | |
| 578 // check for this when the response arrives. | |
| 579 // - The current RVH runs its onbeforeunload handler. If it returns false, we | |
| 580 // cancel all the pending logic and go back to NORMAL. Otherwise we allow | |
| 581 // the pending RVH to send the navigation request to its renderer. | |
| 582 // - ResourceDispatcherHost receives a ResourceRequest on the IO thread. It | |
| 583 // checks CrossSiteRequestManager to see that the RVH responsible has a | |
| 584 // pending cross-site request, and then installs a CrossSiteEventHandler. | |
| 585 // - When RDH receives a response, the BufferedEventHandler determines whether | |
| 586 // it is a download. If so, it sends a message to the new renderer causing | |
| 587 // it to cancel the request, and the download proceeds in the download | |
| 588 // thread. For now, we stay in a PENDING state (with a pending RVH) until | |
| 589 // the next DidNavigate event for this WebContents. This isn't ideal, but it | |
| 590 // doesn't affect any functionality. | |
| 591 // - After RDH receives a response and determines that it is safe and not a | |
| 592 // download, it pauses the response to first run the old page's onunload | |
| 593 // handler. It does this by asynchronously calling the OnCrossSiteResponse | |
| 594 // method of WebContents on the UI thread, which sends a ClosePage message | |
| 595 // to the current RVH. | |
| 596 // - Once the onunload handler is finished, a ClosePage_ACK message is sent to | |
| 597 // the ResourceDispatcherHost, who unpauses the response. Data is then sent | |
| 598 // to the pending RVH. | |
| 599 // - The pending renderer sends a FrameNavigate message that invokes the | |
| 600 // DidNavigate method. This replaces the current RVH with the | |
| 601 // pending RVH and goes back to the NORMAL RendererState. | |
| 602 | |
| 603 bool WebContents::NavigateToPendingEntry(bool reload) { | 358 bool WebContents::NavigateToPendingEntry(bool reload) { |
| 604 NavigationEntry* entry = controller()->GetPendingEntry(); | 359 NavigationEntry* entry = controller()->GetPendingEntry(); |
| 605 RenderViewHost* dest_render_view_host = render_manager_.Navigate(*entry); | 360 RenderViewHost* dest_render_view_host = render_manager_.Navigate(*entry); |
| 606 if (!dest_render_view_host) | 361 if (!dest_render_view_host) |
| 607 return false; // Unable to create the desired render view host. | 362 return false; // Unable to create the desired render view host. |
| 608 | 363 |
| 609 // Used for page load time metrics. | 364 // Used for page load time metrics. |
| 610 current_load_start_ = TimeTicks::Now(); | 365 current_load_start_ = TimeTicks::Now(); |
| 611 | 366 |
| 612 // Navigate in the desired RenderViewHost. | 367 // Navigate in the desired RenderViewHost. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 630 } | 385 } |
| 631 | 386 |
| 632 return true; | 387 return true; |
| 633 } | 388 } |
| 634 | 389 |
| 635 void WebContents::Stop() { | 390 void WebContents::Stop() { |
| 636 render_manager_.Stop(); | 391 render_manager_.Stop(); |
| 637 printing_.Stop(); | 392 printing_.Stop(); |
| 638 } | 393 } |
| 639 | 394 |
| 395 void WebContents::StartFinding(int request_id, |
| 396 const std::wstring& search_string, |
| 397 bool forward, |
| 398 bool match_case, |
| 399 bool find_next) { |
| 400 render_view_host()->StartFinding(request_id, search_string, forward, |
| 401 match_case, find_next); |
| 402 } |
| 403 |
| 404 void WebContents::StopFinding(bool clear_selection) { |
| 405 render_view_host()->StopFinding(clear_selection); |
| 406 } |
| 407 |
| 408 void WebContents::Cut() { |
| 409 render_view_host()->Cut(); |
| 410 } |
| 411 |
| 412 void WebContents::Copy() { |
| 413 render_view_host()->Copy(); |
| 414 } |
| 415 |
| 416 void WebContents::Paste() { |
| 417 render_view_host()->Paste(); |
| 418 } |
| 419 |
| 640 void WebContents::DidBecomeSelected() { | 420 void WebContents::DidBecomeSelected() { |
| 641 TabContents::DidBecomeSelected(); | 421 TabContents::DidBecomeSelected(); |
| 642 | 422 |
| 643 if (view()) | 423 if (view()) |
| 644 view()->DidBecomeSelected(); | 424 view()->DidBecomeSelected(); |
| 645 | 425 |
| 646 CacheManagerHost::GetInstance()->ObserveActivity(process()->host_id()); | 426 CacheManagerHost::GetInstance()->ObserveActivity(process()->host_id()); |
| 647 } | 427 } |
| 648 | 428 |
| 649 void WebContents::WasHidden() { | 429 void WebContents::WasHidden() { |
| 650 if (!capturing_contents_) { | 430 if (!capturing_contents()) { |
| 651 // |render_view_host()| can be NULL if the user middle clicks a link to open | 431 // |render_view_host()| can be NULL if the user middle clicks a link to open |
| 652 // a tab in then background, then closes the tab before selecting it. This | 432 // a tab in then background, then closes the tab before selecting it. This |
| 653 // is because closing the tab calls WebContents::Destroy(), which removes | 433 // is because closing the tab calls WebContents::Destroy(), which removes |
| 654 // the |render_view_host()|; then when we actually destroy the window, | 434 // the |render_view_host()|; then when we actually destroy the window, |
| 655 // OnWindowPosChanged() notices and calls HideContents() (which calls us). | 435 // OnWindowPosChanged() notices and calls HideContents() (which calls us). |
| 656 if (view()) | 436 if (view()) |
| 657 view()->WasHidden(); | 437 view()->WasHidden(); |
| 658 | 438 |
| 659 // Loop through children and send WasHidden to them, too. | 439 // Loop through children and send WasHidden to them, too. |
| 660 int count = static_cast<int>(child_windows_.size()); | 440 int count = static_cast<int>(child_windows_.size()); |
| 661 for (int i = count - 1; i >= 0; --i) { | 441 for (int i = count - 1; i >= 0; --i) { |
| 662 ConstrainedWindow* window = child_windows_.at(i); | 442 ConstrainedWindow* window = child_windows_.at(i); |
| 663 window->WasHidden(); | 443 window->WasHidden(); |
| 664 } | 444 } |
| 665 } | 445 } |
| 666 | 446 |
| 667 // If we have a FindInPage dialog, notify it that its tab was hidden. | 447 // If we have a FindInPage dialog, notify it that its tab was hidden. |
| 668 if (find_in_page_controller_.get()) | 448 if (find_in_page_controller_.get()) |
| 669 find_in_page_controller_->DidBecomeUnselected(); | 449 find_in_page_controller_->DidBecomeUnselected(); |
| 670 | 450 |
| 671 TabContents::WasHidden(); | 451 TabContents::WasHidden(); |
| 672 } | 452 } |
| 673 | 453 |
| 674 void WebContents::StartFinding(int request_id, | 454 void WebContents::ShowContents() { |
| 675 const std::wstring& search_string, | 455 if (view()) |
| 676 bool forward, | 456 view()->DidBecomeSelected(); |
| 677 bool match_case, | 457 |
| 678 bool find_next) { | 458 // Loop through children and send DidBecomeSelected to them, too. |
| 679 render_view_host()->StartFinding(request_id, search_string, forward, | 459 int count = static_cast<int>(child_windows_.size()); |
| 680 match_case, find_next); | 460 for (int i = count - 1; i >= 0; --i) { |
| 461 ConstrainedWindow* window = child_windows_.at(i); |
| 462 window->DidBecomeSelected(); |
| 463 } |
| 464 |
| 465 // If we have a FindInPage dialog, notify it that its tab was selected. |
| 466 if (find_in_page_controller_.get()) |
| 467 find_in_page_controller_->DidBecomeSelected(); |
| 681 } | 468 } |
| 682 | 469 |
| 683 void WebContents::StopFinding(bool clear_selection) { | 470 void WebContents::HideContents() { |
| 684 render_view_host()->StopFinding(clear_selection); | 471 // TODO(pkasting): http://b/1239839 Right now we purposefully don't call |
| 472 // our superclass HideContents(), because some callers want to be very picky |
| 473 // about the order in which these get called. In addition to making the code |
| 474 // here practically impossible to understand, this also means we end up |
| 475 // calling TabContents::WasHidden() twice if callers call both versions of |
| 476 // HideContents() on a WebContents. |
| 477 WasHidden(); |
| 478 } |
| 479 |
| 480 void WebContents::SizeContents(const gfx::Size& size) { |
| 481 if (view()) |
| 482 view()->SetSize(size); |
| 483 if (find_in_page_controller_.get()) |
| 484 find_in_page_controller_->RespondToResize(size); |
| 485 RepositionSupressedPopupsToFit(size); |
| 486 } |
| 487 |
| 488 HWND WebContents::GetContentHWND() { |
| 489 if (!view()) |
| 490 return NULL; |
| 491 return view()->GetPluginHWND(); |
| 492 } |
| 493 |
| 494 void WebContents::CreateView(HWND parent_hwnd, |
| 495 const gfx::Rect& initial_bounds) { |
| 496 set_delete_on_destroy(false); |
| 497 HWNDViewContainer::Init(parent_hwnd, initial_bounds, false); |
| 498 |
| 499 // Remove the root view drop target so we can register our own. |
| 500 RevokeDragDrop(GetHWND()); |
| 501 drop_target_ = new WebDropTarget(GetHWND(), this); |
| 502 } |
| 503 |
| 504 void WebContents::GetContainerBounds(gfx::Rect *out) const { |
| 505 CRect r; |
| 506 GetBounds(&r, false); |
| 507 *out = r; |
| 508 } |
| 509 |
| 510 InfoBarView* WebContents::GetInfoBarView() { |
| 511 if (info_bar_view_.get() == NULL) { |
| 512 info_bar_view_.reset(new InfoBarView(this)); |
| 513 // The WebContents owns the info-bar. |
| 514 info_bar_view_->SetParentOwned(false); |
| 515 } |
| 516 return info_bar_view_.get(); |
| 517 } |
| 518 |
| 519 void WebContents::SetDownloadShelfVisible(bool visible) { |
| 520 TabContents::SetDownloadShelfVisible(visible); |
| 521 if (visible) { |
| 522 // Always set this value as it reflects the last time the download shelf |
| 523 // was made visible (even if it was already visible). |
| 524 last_download_shelf_show_ = TimeTicks::Now(); |
| 525 } |
| 685 } | 526 } |
| 686 | 527 |
| 687 void WebContents::OpenFindInPageWindow(const Browser& browser) { | 528 void WebContents::OpenFindInPageWindow(const Browser& browser) { |
| 688 if (!find_in_page_controller_.get()) { | 529 if (!find_in_page_controller_.get()) { |
| 689 // Get the Chrome top-level (Frame) window. | 530 // Get the Chrome top-level (Frame) window. |
| 690 HWND hwnd = browser.GetTopLevelHWND(); | 531 HWND hwnd = browser.GetTopLevelHWND(); |
| 691 find_in_page_controller_.reset(new FindInPageController(this, hwnd)); | 532 find_in_page_controller_.reset(new FindInPageController(this, hwnd)); |
| 692 } else { | 533 } else { |
| 693 find_in_page_controller_->Show(); | 534 find_in_page_controller_->Show(); |
| 694 } | 535 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 if (IsFindWindowFullyVisible() && | 570 if (IsFindWindowFullyVisible() && |
| 730 ::IsWindow(find_wnd) && | 571 ::IsWindow(find_wnd) && |
| 731 ::GetWindowRect(find_wnd, &window_rect)) { | 572 ::GetWindowRect(find_wnd, &window_rect)) { |
| 732 *x = window_rect.TopLeft().x; | 573 *x = window_rect.TopLeft().x; |
| 733 *y = window_rect.TopLeft().y; | 574 *y = window_rect.TopLeft().y; |
| 734 return true; | 575 return true; |
| 735 } | 576 } |
| 736 | 577 |
| 737 return false; | 578 return false; |
| 738 } | 579 } |
| 739 void WebContents::OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg, | |
| 740 bool success, | |
| 741 const std::wstring& prompt) { | |
| 742 last_javascript_message_dismissal_ = TimeTicks::Now(); | |
| 743 render_manager_.OnJavaScriptMessageBoxClosed(reply_msg, success, prompt); | |
| 744 } | |
| 745 | |
| 746 // Generic NotificationObserver callback. | |
| 747 void WebContents::Observe(NotificationType type, | |
| 748 const NotificationSource& source, | |
| 749 const NotificationDetails& details) { | |
| 750 TabContents::Observe(type, source, details); | |
| 751 switch (type) { | |
| 752 case NOTIFY_BOOKMARK_MODEL_LOADED: // BookmarkModel finished loading, fall | |
| 753 // through to update starred state. | |
| 754 case NOTIFY_URLS_STARRED: { // Somewhere, a URL has been starred. | |
| 755 // Ignore notifications for profiles other than our current one. | |
| 756 Profile* source_profile = Source<Profile>(source).ptr(); | |
| 757 if (!source_profile->IsSameProfile(profile())) | |
| 758 return; | |
| 759 | |
| 760 UpdateStarredStateForCurrentURL(); | |
| 761 break; | |
| 762 } | |
| 763 case NOTIFY_PREF_CHANGED: { | |
| 764 std::wstring* pref_name_in = Details<std::wstring>(details).ptr(); | |
| 765 DCHECK(Source<PrefService>(source).ptr() == profile()->GetPrefs()); | |
| 766 if (*pref_name_in == prefs::kAlternateErrorPagesEnabled) { | |
| 767 UpdateAlternateErrorPageURL(); | |
| 768 } else if (*pref_name_in == prefs::kDefaultCharset || | |
| 769 StartsWithASCII(WideToUTF8(*pref_name_in), "webkit.webprefs.", true) | |
| 770 ) { | |
| 771 UpdateWebPreferences(); | |
| 772 } else { | |
| 773 NOTREACHED() << "unexpected pref change notification" << *pref_name_in; | |
| 774 } | |
| 775 break; | |
| 776 } | |
| 777 default: { | |
| 778 NOTREACHED(); | |
| 779 break; | |
| 780 } | |
| 781 } | |
| 782 } | |
| 783 | |
| 784 void WebContents::NotifySwapped() { | |
| 785 // After sending out a swap notification, we need to send a disconnect | |
| 786 // notification so that clients that pick up a pointer to |this| can NULL the | |
| 787 // pointer. See Bug 1230284. | |
| 788 notify_disconnection_ = true; | |
| 789 NotificationService::current()-> | |
| 790 Notify(NOTIFY_WEB_CONTENTS_SWAPPED, | |
| 791 Source<WebContents>(this), | |
| 792 NotificationService::NoDetails()); | |
| 793 } | |
| 794 | |
| 795 void WebContents::NotifyConnected() { | |
| 796 notify_disconnection_ = true; | |
| 797 NotificationService::current()-> | |
| 798 Notify(NOTIFY_WEB_CONTENTS_CONNECTED, | |
| 799 Source<WebContents>(this), | |
| 800 NotificationService::NoDetails()); | |
| 801 } | |
| 802 | |
| 803 void WebContents::NotifyDisconnected() { | |
| 804 if (!notify_disconnection_) | |
| 805 return; | |
| 806 | |
| 807 notify_disconnection_ = false; | |
| 808 NotificationService::current()-> | |
| 809 Notify(NOTIFY_WEB_CONTENTS_DISCONNECTED, | |
| 810 Source<WebContents>(this), | |
| 811 NotificationService::NoDetails()); | |
| 812 } | |
| 813 | |
| 814 void WebContents::UpdateHistoryForNavigation(const GURL& display_url, | |
| 815 const ViewHostMsg_FrameNavigate_Params& params) { | |
| 816 if (profile()->IsOffTheRecord()) | |
| 817 return; | |
| 818 | |
| 819 // Add to history service. | |
| 820 HistoryService* hs = profile()->GetHistoryService(Profile::IMPLICIT_ACCESS); | |
| 821 if (hs) { | |
| 822 if (PageTransition::IsMainFrame(params.transition) && | |
| 823 display_url != params.url) { | |
| 824 // Hack on the "display" URL so that it will appear in history. For some | |
| 825 // types of URLs, we will display a magic URL that is different from where | |
| 826 // the page is actually navigated. We want the user to see in history | |
| 827 // what they saw in the URL bar, so we add the display URL as a redirect. | |
| 828 // This only applies to the main frame, as the display URL doesn't apply | |
| 829 // to sub-frames. | |
| 830 std::vector<GURL> redirects = params.redirects; | |
| 831 if (!redirects.empty()) | |
| 832 redirects.back() = display_url; | |
| 833 hs->AddPage(display_url, this, params.page_id, params.referrer, | |
| 834 params.transition, redirects); | |
| 835 } else { | |
| 836 hs->AddPage(params.url, this, params.page_id, params.referrer, | |
| 837 params.transition, params.redirects); | |
| 838 } | |
| 839 } | |
| 840 } | |
| 841 | |
| 842 void WebContents::MaybeCloseChildWindows( | |
| 843 const ViewHostMsg_FrameNavigate_Params& params) { | |
| 844 if (net::RegistryControlledDomainService::SameDomainOrHost( | |
| 845 last_url_, params.url)) | |
| 846 return; | |
| 847 last_url_ = params.url; | |
| 848 | |
| 849 // Clear out any child windows since we are leaving this page entirely. | |
| 850 // We use indices instead of iterators in case CloseWindow does something | |
| 851 // that may invalidate an iterator. | |
| 852 int size = static_cast<int>(child_windows_.size()); | |
| 853 for (int i = size - 1; i >= 0; --i) { | |
| 854 ConstrainedWindow* window = child_windows_[i]; | |
| 855 if (window) | |
| 856 window->CloseConstrainedWindow(); | |
| 857 } | |
| 858 } | |
| 859 | |
| 860 void WebContents::SetDownloadShelfVisible(bool visible) { | |
| 861 TabContents::SetDownloadShelfVisible(visible); | |
| 862 if (visible) { | |
| 863 // Always set this value as it reflects the last time the download shelf | |
| 864 // was made visible (even if it was already visible). | |
| 865 last_download_shelf_show_ = TimeTicks::Now(); | |
| 866 } | |
| 867 } | |
| 868 | |
| 869 void WebContents::SetInfoBarVisible(bool visible) { | |
| 870 if (info_bar_visible_ != visible) { | |
| 871 info_bar_visible_ = visible; | |
| 872 if (info_bar_visible_) { | |
| 873 // Invoke GetInfoBarView to force the info bar to be created. | |
| 874 GetInfoBarView(); | |
| 875 } | |
| 876 ToolbarSizeChanged(false); | |
| 877 } | |
| 878 } | |
| 879 | 580 |
| 880 void WebContents::SetFindInPageVisible(bool visible) { | 581 void WebContents::SetFindInPageVisible(bool visible) { |
| 881 if (find_in_page_controller_.get()) { | 582 if (find_in_page_controller_.get()) { |
| 882 if (visible) | 583 if (visible) |
| 883 find_in_page_controller_->Show(); | 584 find_in_page_controller_->Show(); |
| 884 else | 585 else |
| 885 find_in_page_controller_->EndFindSession(); | 586 find_in_page_controller_->EndFindSession(); |
| 886 } | 587 } |
| 887 } | 588 } |
| 888 | 589 |
| 889 InfoBarView* WebContents::GetInfoBarView() { | |
| 890 if (info_bar_view_.get() == NULL) { | |
| 891 info_bar_view_.reset(new InfoBarView(this)); | |
| 892 // The WebContents owns the info-bar. | |
| 893 info_bar_view_->SetParentOwned(false); | |
| 894 } | |
| 895 return info_bar_view_.get(); | |
| 896 } | |
| 897 | |
| 898 void WebContents::SetWebApp(WebApp* web_app) { | 590 void WebContents::SetWebApp(WebApp* web_app) { |
| 899 if (web_app_.get()) { | 591 if (web_app_.get()) { |
| 900 web_app_->RemoveObserver(this); | 592 web_app_->RemoveObserver(this); |
| 901 web_app_->SetWebContents(NULL); | 593 web_app_->SetWebContents(NULL); |
| 902 } | 594 } |
| 903 | 595 |
| 904 web_app_ = web_app; | 596 web_app_ = web_app; |
| 905 if (web_app) { | 597 if (web_app) { |
| 906 web_app->AddObserver(this); | 598 web_app->AddObserver(this); |
| 907 web_app_->SetWebContents(this); | 599 web_app_->SetWebContents(this); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 929 } | 621 } |
| 930 DCHECK(!pending_install_.icon.isNull()) << "Menu item should be disabled."; | 622 DCHECK(!pending_install_.icon.isNull()) << "Menu item should be disabled."; |
| 931 if (pending_install_.title.empty()) | 623 if (pending_install_.title.empty()) |
| 932 pending_install_.title = UTF8ToWide(GetURL().spec()); | 624 pending_install_.title = UTF8ToWide(GetURL().spec()); |
| 933 | 625 |
| 934 // Request the application info. When done OnDidGetApplicationInfo is invoked | 626 // Request the application info. When done OnDidGetApplicationInfo is invoked |
| 935 // and we'll create the shortcut. | 627 // and we'll create the shortcut. |
| 936 render_view_host()->GetApplicationInfo(pending_install_.page_id); | 628 render_view_host()->GetApplicationInfo(pending_install_.page_id); |
| 937 } | 629 } |
| 938 | 630 |
| 939 PasswordManager* WebContents::GetPasswordManager() { | 631 void WebContents::OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg, |
| 940 if (password_manager_.get() == NULL) | 632 bool success, |
| 941 password_manager_.reset(new PasswordManager(this)); | 633 const std::wstring& prompt) { |
| 942 return password_manager_.get(); | 634 last_javascript_message_dismissal_ = TimeTicks::Now(); |
| 635 render_manager_.OnJavaScriptMessageBoxClosed(reply_msg, success, prompt); |
| 943 } | 636 } |
| 944 | 637 |
| 945 PluginInstaller* WebContents::GetPluginInstaller() { | 638 void WebContents::SetInfoBarVisible(bool visible) { |
| 946 if (plugin_installer_.get() == NULL) | 639 if (info_bar_visible_ != visible) { |
| 947 plugin_installer_.reset(new PluginInstaller(this)); | 640 info_bar_visible_ = visible; |
| 948 return plugin_installer_.get(); | 641 if (info_bar_visible_) { |
| 642 // Invoke GetInfoBarView to force the info bar to be created. |
| 643 GetInfoBarView(); |
| 644 } |
| 645 ToolbarSizeChanged(false); |
| 646 } |
| 647 } |
| 648 |
| 649 void WebContents::OnSavePage() { |
| 650 // If we can not save the page, try to download it. |
| 651 if (!SavePackage::IsSavableContents(contents_mime_type())) { |
| 652 DownloadManager* dlm = profile()->GetDownloadManager(); |
| 653 const GURL& current_page_url = GetURL(); |
| 654 if (dlm && current_page_url.is_valid()) |
| 655 dlm->DownloadUrl(current_page_url, GURL(), this); |
| 656 return; |
| 657 } |
| 658 |
| 659 // Get our user preference state. |
| 660 PrefService* prefs = profile()->GetPrefs(); |
| 661 DCHECK(prefs); |
| 662 |
| 663 std::wstring suggest_name = |
| 664 SavePackage::GetSuggestNameForSaveAs(prefs, GetTitle()); |
| 665 |
| 666 SavePackage::SavePackageParam param(contents_mime_type()); |
| 667 param.prefs = prefs; |
| 668 |
| 669 // TODO(rocking): Use new asynchronous dialog boxes to prevent the SaveAs |
| 670 // dialog blocking the UI thread. See bug: http://b/issue?id=1129694. |
| 671 if (SavePackage::GetSaveInfo(suggest_name, GetContainerHWND(), ¶m)) |
| 672 SavePage(param.saved_main_file_path, param.dir, param.save_type); |
| 673 } |
| 674 |
| 675 void WebContents::SavePage(const std::wstring& main_file, |
| 676 const std::wstring& dir_path, |
| 677 SavePackage::SavePackageType save_type) { |
| 678 // Stop the page from navigating. |
| 679 Stop(); |
| 680 |
| 681 save_package_ = new SavePackage(this, save_type, main_file, dir_path); |
| 682 save_package_->Init(); |
| 683 } |
| 684 |
| 685 void WebContents::PrintPreview() { |
| 686 // We can't print interstitial page for now. |
| 687 if (render_manager_.showing_interstitial_page()) |
| 688 return; |
| 689 |
| 690 // If we have a FindInPage dialog, notify it that its tab was hidden. |
| 691 if (find_in_page_controller_.get()) |
| 692 find_in_page_controller_->DidBecomeUnselected(); |
| 693 |
| 694 // We don't show the print preview for the beta, only the print dialog. |
| 695 printing_.ShowPrintDialog(); |
| 696 } |
| 697 |
| 698 bool WebContents::PrintNow() { |
| 699 // We can't print interstitial page for now. |
| 700 if (render_manager_.showing_interstitial_page()) |
| 701 return false; |
| 702 |
| 703 // If we have a FindInPage dialog, notify it that its tab was hidden. |
| 704 if (find_in_page_controller_.get()) |
| 705 find_in_page_controller_->DidBecomeUnselected(); |
| 706 |
| 707 return printing_.PrintNow(); |
| 949 } | 708 } |
| 950 | 709 |
| 951 bool WebContents::IsActiveEntry(int32 page_id) { | 710 bool WebContents::IsActiveEntry(int32 page_id) { |
| 952 NavigationEntry* active_entry = controller()->GetActiveEntry(); | 711 NavigationEntry* active_entry = controller()->GetActiveEntry(); |
| 953 return (active_entry != NULL && | 712 return (active_entry != NULL && |
| 954 active_entry->site_instance() == GetSiteInstance() && | 713 active_entry->site_instance() == GetSiteInstance() && |
| 955 active_entry->page_id() == page_id); | 714 active_entry->page_id() == page_id); |
| 956 } | 715 } |
| 957 | 716 |
| 958 /////////////////////////////////////////////////////////////////////////////// | 717 void WebContents::SetInitialFocus(bool reverse) { |
| 959 // RenderViewHostDelegate implementation: | 718 render_view_host()->SetInitialFocus(reverse); |
| 719 } |
| 720 |
| 721 // Notifies the RenderWidgetHost instance about the fact that the page is |
| 722 // loading, or done loading and calls the base implementation. |
| 723 void WebContents::SetIsLoading(bool is_loading, |
| 724 LoadNotificationDetails* details) { |
| 725 if (!is_loading) { |
| 726 load_state_ = net::LOAD_STATE_IDLE; |
| 727 load_state_host_.clear(); |
| 728 } |
| 729 |
| 730 TabContents::SetIsLoading(is_loading, details); |
| 731 render_manager_.SetIsLoading(is_loading); |
| 732 } |
| 960 | 733 |
| 961 RenderViewHostDelegate::FindInPage* WebContents::GetFindInPageDelegate() const { | 734 RenderViewHostDelegate::FindInPage* WebContents::GetFindInPageDelegate() const { |
| 962 // The find in page controller implements this interface for us. Our return | 735 // The find in page controller implements this interface for us. Our return |
| 963 // value can be NULL, so it's fine if the find in controller doesn't exist. | 736 // value can be NULL, so it's fine if the find in controller doesn't exist. |
| 964 return find_in_page_controller_.get(); | 737 return find_in_page_controller_.get(); |
| 965 } | 738 } |
| 966 | 739 |
| 967 RenderViewHostDelegate::Save* WebContents::GetSaveDelegate() const { | 740 RenderViewHostDelegate::Save* WebContents::GetSaveDelegate() const { |
| 968 return save_package_.get(); // May be NULL, but we can return NULL. | 741 return save_package_.get(); // May be NULL, but we can return NULL. |
| 969 } | 742 } |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1115 | 888 |
| 1116 // In the case of interstitial, we don't mess with the navigation entries. | 889 // In the case of interstitial, we don't mess with the navigation entries. |
| 1117 // TODO(brettw) this seems like a bug. What happens if the page goes and | 890 // TODO(brettw) this seems like a bug. What happens if the page goes and |
| 1118 // does something on its own (or something that just got delayed), then | 891 // does something on its own (or something that just got delayed), then |
| 1119 // we won't have a navigation entry for that stuff when the interstitial | 892 // we won't have a navigation entry for that stuff when the interstitial |
| 1120 // is hidden. | 893 // is hidden. |
| 1121 if (render_manager_.showing_interstitial_page()) | 894 if (render_manager_.showing_interstitial_page()) |
| 1122 return; | 895 return; |
| 1123 | 896 |
| 1124 // We can't do anything about navigations when we're inactive. | 897 // We can't do anything about navigations when we're inactive. |
| 1125 if (!controller() || !is_active_) | 898 if (!controller() || !is_active()) |
| 1126 return; | 899 return; |
| 1127 | 900 |
| 1128 // Update the site of the SiteInstance if it doesn't have one yet, unless we | 901 // Update the site of the SiteInstance if it doesn't have one yet, unless we |
| 1129 // are showing an interstitial page. If we are, we should wait until the | 902 // are showing an interstitial page. If we are, we should wait until the |
| 1130 // real page commits. | 903 // real page commits. |
| 1131 // | 904 // |
| 1132 // TODO(brettw) the old code only checked for INTERSTIAL, this new code also | 905 // TODO(brettw) the old code only checked for INTERSTIAL, this new code also |
| 1133 // checks for LEAVING_INTERSTITIAL mode in the manager. Is this difference | 906 // checks for LEAVING_INTERSTITIAL mode in the manager. Is this difference |
| 1134 // important? | 907 // important? |
| 1135 if (!GetSiteInstance()->has_site() && | 908 if (!GetSiteInstance()->has_site() && |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1147 // for the appropriate notification (best) or you can add it to | 920 // for the appropriate notification (best) or you can add it to |
| 1148 // DidNavigateMainFramePostCommit / DidNavigateAnyFramePostCommit (only if | 921 // DidNavigateMainFramePostCommit / DidNavigateAnyFramePostCommit (only if |
| 1149 // necessary, please). | 922 // necessary, please). |
| 1150 | 923 |
| 1151 // Run post-commit tasks. | 924 // Run post-commit tasks. |
| 1152 if (details.is_main_frame) | 925 if (details.is_main_frame) |
| 1153 DidNavigateMainFramePostCommit(details, params); | 926 DidNavigateMainFramePostCommit(details, params); |
| 1154 DidNavigateAnyFramePostCommit(rvh, details, params); | 927 DidNavigateAnyFramePostCommit(rvh, details, params); |
| 1155 } | 928 } |
| 1156 | 929 |
| 1157 void WebContents::DidNavigateMainFramePostCommit( | |
| 1158 const NavigationController::LoadCommittedDetails& details, | |
| 1159 const ViewHostMsg_FrameNavigate_Params& params) { | |
| 1160 // Hide the download shelf if all the following conditions are true: | |
| 1161 // - there are no active downloads. | |
| 1162 // - this is a navigation to a different TLD. | |
| 1163 // - at least 5 seconds have elapsed since the download shelf was shown. | |
| 1164 // TODO(jcampan): bug 1156075 when user gestures are reliable, they should | |
| 1165 // be used to ensure we are hiding only on user initiated | |
| 1166 // navigations. | |
| 1167 DownloadManager* download_manager = profile()->GetDownloadManager(); | |
| 1168 // download_manager can be NULL in unit test context. | |
| 1169 if (download_manager && download_manager->in_progress_count() == 0 && | |
| 1170 !details.previous_url.is_empty() && | |
| 1171 !net::RegistryControlledDomainService::SameDomainOrHost( | |
| 1172 details.previous_url, details.entry->url())) { | |
| 1173 TimeDelta time_delta( | |
| 1174 TimeTicks::Now() - last_download_shelf_show_); | |
| 1175 if (time_delta > | |
| 1176 TimeDelta::FromMilliseconds(kDownloadShelfHideDelay)) { | |
| 1177 SetDownloadShelfVisible(false); | |
| 1178 } | |
| 1179 } | |
| 1180 | |
| 1181 if (details.is_user_initiated_main_frame_load()) { | |
| 1182 // Clear the status bubble. This is a workaround for a bug where WebKit | |
| 1183 // doesn't let us know that the cursor left an element during a | |
| 1184 // transition (this is also why the mouse cursor remains as a hand after | |
| 1185 // clicking on a link); see bugs 1184641 and 980803. We don't want to | |
| 1186 // clear the bubble when a user navigates to a named anchor in the same | |
| 1187 // page. | |
| 1188 UpdateTargetURL(details.entry->page_id(), GURL()); | |
| 1189 | |
| 1190 // UpdateHelpersForDidNavigate will handle the case where the password_form | |
| 1191 // origin is valid. | |
| 1192 // TODO(brettw) bug 1343111: Password manager stuff in here needs to be | |
| 1193 // cleaned up and covered by tests. | |
| 1194 if (!params.password_form.origin.is_valid()) | |
| 1195 GetPasswordManager()->DidNavigate(); | |
| 1196 } | |
| 1197 | |
| 1198 // The keyword generator uses the navigation entries, so must be called after | |
| 1199 // the commit. | |
| 1200 GenerateKeywordIfNecessary(params); | |
| 1201 | |
| 1202 // We no longer know the title after this navigation. | |
| 1203 has_page_title_ = false; | |
| 1204 | |
| 1205 // Update contents MIME type of the main webframe. | |
| 1206 contents_mime_type_ = params.contents_mime_type; | |
| 1207 | |
| 1208 // Get the favicon, either from history or request it from the net. | |
| 1209 fav_icon_helper_.FetchFavIcon(details.entry->url()); | |
| 1210 | |
| 1211 // Close constrained popups if necessary. | |
| 1212 MaybeCloseChildWindows(params); | |
| 1213 | |
| 1214 // We hide the FindInPage window when the user navigates away, except on | |
| 1215 // reload. | |
| 1216 if (PageTransition::StripQualifier(params.transition) != | |
| 1217 PageTransition::RELOAD) | |
| 1218 SetFindInPageVisible(false); | |
| 1219 | |
| 1220 // Update the starred state. | |
| 1221 UpdateStarredStateForCurrentURL(); | |
| 1222 } | |
| 1223 | |
| 1224 void WebContents::DidNavigateAnyFramePostCommit( | |
| 1225 RenderViewHost* render_view_host, | |
| 1226 const NavigationController::LoadCommittedDetails& details, | |
| 1227 const ViewHostMsg_FrameNavigate_Params& params) { | |
| 1228 // If we navigate, start showing messages again. This does nothing to prevent | |
| 1229 // a malicious script from spamming messages, since the script could just | |
| 1230 // reload the page to stop blocking. | |
| 1231 suppress_javascript_messages_ = false; | |
| 1232 | |
| 1233 // Update history. Note that this needs to happen after the entry is complete, | |
| 1234 // which WillNavigate[Main,Sub]Frame will do before this function is called. | |
| 1235 if (params.should_update_history) { | |
| 1236 // Most of the time, the displayURL matches the loaded URL, but for about: | |
| 1237 // URLs, we use a data: URL as the real value. We actually want to save | |
| 1238 // the about: URL to the history db and keep the data: URL hidden. This is | |
| 1239 // what the TabContents' URL getter does. | |
| 1240 UpdateHistoryForNavigation(GetURL(), params); | |
| 1241 } | |
| 1242 | |
| 1243 // Notify the password manager of the navigation or form submit. | |
| 1244 // TODO(brettw) bug 1343111: Password manager stuff in here needs to be | |
| 1245 // cleaned up and covered by tests. | |
| 1246 if (params.password_form.origin.is_valid()) | |
| 1247 GetPasswordManager()->ProvisionallySavePassword(params.password_form); | |
| 1248 } | |
| 1249 | |
| 1250 bool WebContents::IsWebApplicationActive() const { | |
| 1251 if (!web_app_.get()) | |
| 1252 return false; | |
| 1253 | |
| 1254 // If we are inside an application, the application is always active. For | |
| 1255 // example, this allows us to display the GMail icon even when we are bounced | |
| 1256 // the login page. | |
| 1257 if (delegate() && delegate()->IsApplication()) | |
| 1258 return true; | |
| 1259 | |
| 1260 return (GetURL() == web_app_->url()); | |
| 1261 } | |
| 1262 | |
| 1263 void WebContents::WebAppImagesChanged(WebApp* web_app) { | |
| 1264 DCHECK(web_app == web_app_.get()); | |
| 1265 if (delegate() && IsWebApplicationActive()) | |
| 1266 delegate()->NavigationStateChanged(this, TabContents::INVALIDATE_FAVICON); | |
| 1267 } | |
| 1268 | |
| 1269 void WebContents::UpdateStarredStateForCurrentURL() { | |
| 1270 BookmarkModel* model = profile()->GetBookmarkModel(); | |
| 1271 const bool old_state = is_starred_; | |
| 1272 is_starred_ = (model && model->IsBookmarked(GetURL())); | |
| 1273 | |
| 1274 if (is_starred_ != old_state && delegate()) | |
| 1275 delegate()->URLStarredChanged(this, is_starred_); | |
| 1276 } | |
| 1277 | |
| 1278 void WebContents::UpdateAlternateErrorPageURL() { | |
| 1279 GURL url = GetAlternateErrorPageURL(); | |
| 1280 render_view_host()->SetAlternateErrorPageURL(url); | |
| 1281 } | |
| 1282 | |
| 1283 void WebContents::UpdateWebPreferences() { | |
| 1284 render_view_host()->UpdateWebPreferences(GetWebkitPrefs()); | |
| 1285 } | |
| 1286 | |
| 1287 void WebContents::UpdateRenderViewSize() { | |
| 1288 // Using same technique as OnPaint, which sets size of SadTab. | |
| 1289 CRect cr; | |
| 1290 GetClientRect(&cr); | |
| 1291 gfx::Size new_size(cr.Width(), cr.Height()); | |
| 1292 SizeContents(new_size); | |
| 1293 } | |
| 1294 | |
| 1295 void WebContents::UpdateState(RenderViewHost* rvh, | 930 void WebContents::UpdateState(RenderViewHost* rvh, |
| 1296 int32 page_id, | 931 int32 page_id, |
| 1297 const GURL& url, | 932 const GURL& url, |
| 1298 const std::wstring& title, | 933 const std::wstring& title, |
| 1299 const std::string& state) { | 934 const std::string& state) { |
| 1300 if (rvh != render_view_host() || | 935 if (rvh != render_view_host() || |
| 1301 render_manager_.showing_interstitial_page()) { | 936 render_manager_.showing_interstitial_page()) { |
| 1302 // This UpdateState is either: | 937 // This UpdateState is either: |
| 1303 // - targeted not at the current RenderViewHost. This could be that we are | 938 // - targeted not at the current RenderViewHost. This could be that we are |
| 1304 // showing the interstitial page and getting an update for the regular page, | 939 // showing the interstitial page and getting an update for the regular page, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1368 controller()->NotifyEntryChanged(entry, entry_index); | 1003 controller()->NotifyEntryChanged(entry, entry_index); |
| 1369 } | 1004 } |
| 1370 | 1005 |
| 1371 void WebContents::UpdateTitle(RenderViewHost* rvh, | 1006 void WebContents::UpdateTitle(RenderViewHost* rvh, |
| 1372 int32 page_id, const std::wstring& title) { | 1007 int32 page_id, const std::wstring& title) { |
| 1373 if (!controller()) | 1008 if (!controller()) |
| 1374 return; | 1009 return; |
| 1375 | 1010 |
| 1376 // If we have a title, that's a pretty good indication that we've started | 1011 // If we have a title, that's a pretty good indication that we've started |
| 1377 // getting useful data. | 1012 // getting useful data. |
| 1378 response_started_ = false; | 1013 SetNotWaitingForResponse(); |
| 1379 | 1014 |
| 1380 NavigationEntry* entry; | 1015 NavigationEntry* entry; |
| 1381 if (render_manager_.showing_interstitial_page() && | 1016 if (render_manager_.showing_interstitial_page() && |
| 1382 (rvh == render_view_host())) { | 1017 (rvh == render_view_host())) { |
| 1383 // We are showing an interstitial page in a different RenderViewHost, so | 1018 // We are showing an interstitial page in a different RenderViewHost, so |
| 1384 // the page_id is not sufficient to find the entry from the controller. | 1019 // the page_id is not sufficient to find the entry from the controller. |
| 1385 // (both RenderViewHost page_ids overlap). We know it is the last entry, | 1020 // (both RenderViewHost page_ids overlap). We know it is the last entry, |
| 1386 // so just use that. | 1021 // so just use that. |
| 1387 entry = controller()->GetLastCommittedEntry(); | 1022 entry = controller()->GetLastCommittedEntry(); |
| 1388 } else { | 1023 } else { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1411 HistoryService* hs = profile()->GetHistoryService(Profile::IMPLICIT_ACCESS); | 1046 HistoryService* hs = profile()->GetHistoryService(Profile::IMPLICIT_ACCESS); |
| 1412 if (hs && !has_page_title_ && !trimmed_title.empty()) { | 1047 if (hs && !has_page_title_ && !trimmed_title.empty()) { |
| 1413 hs->SetPageTitle(entry->display_url(), trimmed_title); | 1048 hs->SetPageTitle(entry->display_url(), trimmed_title); |
| 1414 has_page_title_ = true; | 1049 has_page_title_ = true; |
| 1415 } | 1050 } |
| 1416 } | 1051 } |
| 1417 | 1052 |
| 1418 | 1053 |
| 1419 void WebContents::UpdateEncoding(RenderViewHost* render_view_host, | 1054 void WebContents::UpdateEncoding(RenderViewHost* render_view_host, |
| 1420 const std::wstring& encoding_name) { | 1055 const std::wstring& encoding_name) { |
| 1421 SetEncoding(encoding_name); | 1056 set_encoding(encoding_name); |
| 1422 } | 1057 } |
| 1423 | 1058 |
| 1424 void WebContents::UpdateTargetURL(int32 page_id, const GURL& url) { | 1059 void WebContents::UpdateTargetURL(int32 page_id, const GURL& url) { |
| 1425 if (delegate()) | 1060 if (delegate()) |
| 1426 delegate()->UpdateTargetURL(this, url); | 1061 delegate()->UpdateTargetURL(this, url); |
| 1427 } | 1062 } |
| 1428 | 1063 |
| 1429 void WebContents::UpdateThumbnail(const GURL& url, | 1064 void WebContents::UpdateThumbnail(const GURL& url, |
| 1430 const SkBitmap& bitmap, | 1065 const SkBitmap& bitmap, |
| 1431 const ThumbnailScore& score) { | 1066 const ThumbnailScore& score) { |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1762 ChromeViews::FocusManager* focus_manager = | 1397 ChromeViews::FocusManager* focus_manager = |
| 1763 ChromeViews::FocusManager::GetFocusManager(GetHWND()); | 1398 ChromeViews::FocusManager::GetFocusManager(GetHWND()); |
| 1764 | 1399 |
| 1765 // We may not have a focus manager if the tab has been switched before this | 1400 // We may not have a focus manager if the tab has been switched before this |
| 1766 // message arrived. | 1401 // message arrived. |
| 1767 if (focus_manager) { | 1402 if (focus_manager) { |
| 1768 focus_manager->AdvanceFocus(reverse); | 1403 focus_manager->AdvanceFocus(reverse); |
| 1769 } | 1404 } |
| 1770 } | 1405 } |
| 1771 | 1406 |
| 1407 // Checks to see if we should generate a keyword based on the OSDD, and if |
| 1408 // necessary uses TemplateURLFetcher to download the OSDD and create a keyword. |
| 1409 void WebContents::PageHasOSDD(RenderViewHost* render_view_host, |
| 1410 int32 page_id, const GURL& url, |
| 1411 bool autodetected) { |
| 1412 // Make sure page_id is the current page, and the TemplateURLModel is loaded. |
| 1413 DCHECK(url.is_valid()); |
| 1414 if (!controller() || !IsActiveEntry(page_id)) |
| 1415 return; |
| 1416 TemplateURLModel* url_model = profile()->GetTemplateURLModel(); |
| 1417 if (!url_model) |
| 1418 return; |
| 1419 if (!url_model->loaded()) { |
| 1420 url_model->Load(); |
| 1421 return; |
| 1422 } |
| 1423 if (!profile()->GetTemplateURLFetcher()) |
| 1424 return; |
| 1425 |
| 1426 if (profile()->IsOffTheRecord()) |
| 1427 return; |
| 1428 |
| 1429 const NavigationEntry* entry = controller()->GetLastCommittedEntry(); |
| 1430 DCHECK(entry); |
| 1431 |
| 1432 const NavigationEntry* base_entry = entry; |
| 1433 if (IsFormSubmit(base_entry)) { |
| 1434 // If the current page is a form submit, find the last page that was not |
| 1435 // a form submit and use its url to generate the keyword from. |
| 1436 int index = controller()->GetLastCommittedEntryIndex() - 1; |
| 1437 while (index >= 0 && IsFormSubmit(controller()->GetEntryAtIndex(index))) |
| 1438 index--; |
| 1439 if (index >= 0) |
| 1440 base_entry = controller()->GetEntryAtIndex(index); |
| 1441 else |
| 1442 base_entry = NULL; |
| 1443 } |
| 1444 |
| 1445 // We want to use the user typed URL if available since that represents what |
| 1446 // the user typed to get here, and fall back on the regular URL if not. |
| 1447 if (!base_entry) |
| 1448 return; |
| 1449 GURL keyword_url = base_entry->user_typed_url().is_valid() ? |
| 1450 base_entry->user_typed_url() : base_entry->url(); |
| 1451 if (!keyword_url.is_valid()) |
| 1452 return; |
| 1453 std::wstring keyword = TemplateURLModel::GenerateKeyword(keyword_url, |
| 1454 autodetected); |
| 1455 if (keyword.empty()) |
| 1456 return; |
| 1457 const TemplateURL* template_url = |
| 1458 url_model->GetTemplateURLForKeyword(keyword); |
| 1459 if (template_url && (!template_url->safe_for_autoreplace() || |
| 1460 template_url->originating_url() == url)) { |
| 1461 // Either there is a user created TemplateURL for this keyword, or the |
| 1462 // keyword has the same OSDD url and we've parsed it. |
| 1463 return; |
| 1464 } |
| 1465 |
| 1466 // Download the OpenSearch description document. If this is successful a |
| 1467 // new keyword will be created when done. |
| 1468 profile()->GetTemplateURLFetcher()->ScheduleDownload( |
| 1469 keyword, |
| 1470 url, |
| 1471 base_entry->favicon().url(), |
| 1472 GetAncestor(GetHWND(), GA_ROOT), |
| 1473 autodetected); |
| 1474 } |
| 1475 |
| 1476 void WebContents::InspectElementReply(int num_resources) { |
| 1477 // We have received reply from inspect element request. Notify the |
| 1478 // automation provider in case we need to notify automation client. |
| 1479 NotificationService::current()-> |
| 1480 Notify(NOTIFY_DOM_INSPECT_ELEMENT_RESPONSE, Source<WebContents>(this), |
| 1481 Details<int>(&num_resources)); |
| 1482 } |
| 1483 |
| 1484 void WebContents::DidGetPrintedPagesCount(int cookie, int number_pages) { |
| 1485 printing_.DidGetPrintedPagesCount(cookie, number_pages); |
| 1486 } |
| 1487 |
| 1488 void WebContents::DidPrintPage(const ViewHostMsg_DidPrintPage_Params& params) { |
| 1489 printing_.DidPrintPage(params); |
| 1490 } |
| 1491 |
| 1492 // The renderer sends back to the browser the key events it did not process. |
| 1493 void WebContents::HandleKeyboardEvent(const WebKeyboardEvent& event) { |
| 1494 // The renderer returned a keyboard event it did not process. This may be |
| 1495 // a keyboard shortcut that we have to process. |
| 1496 if (event.type == WebInputEvent::KEY_DOWN) { |
| 1497 ChromeViews::FocusManager* focus_manager = |
| 1498 ChromeViews::FocusManager::GetFocusManager(GetHWND()); |
| 1499 // We may not have a focus_manager at this point (if the tab has been |
| 1500 // switched by the time this message returned). |
| 1501 if (focus_manager) { |
| 1502 ChromeViews::Accelerator accelerator(event.key_code, |
| 1503 (event.modifiers & WebInputEvent::SHIFT_KEY) == |
| 1504 WebInputEvent::SHIFT_KEY, |
| 1505 (event.modifiers & WebInputEvent::CTRL_KEY) == |
| 1506 WebInputEvent::CTRL_KEY, |
| 1507 (event.modifiers & WebInputEvent::ALT_KEY) == |
| 1508 WebInputEvent::ALT_KEY); |
| 1509 if (focus_manager->ProcessAccelerator(accelerator, false)) |
| 1510 return; |
| 1511 } |
| 1512 } |
| 1513 |
| 1514 // Any unhandled keyboard/character messages should be defproced. |
| 1515 // This allows stuff like Alt+F4, etc to work correctly. |
| 1516 DefWindowProc(event.actual_message.hwnd, |
| 1517 event.actual_message.message, |
| 1518 event.actual_message.wParam, |
| 1519 event.actual_message.lParam); |
| 1520 } |
| 1521 |
| 1772 GURL WebContents::GetAlternateErrorPageURL() const { | 1522 GURL WebContents::GetAlternateErrorPageURL() const { |
| 1773 GURL url; | 1523 GURL url; |
| 1774 PrefService* prefs = profile()->GetPrefs(); | 1524 PrefService* prefs = profile()->GetPrefs(); |
| 1775 DCHECK(prefs); | 1525 DCHECK(prefs); |
| 1776 if (prefs->GetBoolean(prefs::kAlternateErrorPagesEnabled)) { | 1526 if (prefs->GetBoolean(prefs::kAlternateErrorPagesEnabled)) { |
| 1777 url = google_util::AppendGoogleLocaleParam(GURL(kLinkDoctorBaseURL)); | 1527 url = google_util::AppendGoogleLocaleParam(GURL(kLinkDoctorBaseURL)); |
| 1778 url = google_util::AppendGoogleTLDParam(url); | 1528 url = google_util::AppendGoogleTLDParam(url); |
| 1779 } | 1529 } |
| 1780 return url; | 1530 return url; |
| 1781 } | 1531 } |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1892 | 1642 |
| 1893 InfoBarView* view = GetInfoBarView(); | 1643 InfoBarView* view = GetInfoBarView(); |
| 1894 if (-1 == view->GetChildIndex(crashed_plugin_info_bar_)) { | 1644 if (-1 == view->GetChildIndex(crashed_plugin_info_bar_)) { |
| 1895 crashed_plugin_info_bar_ = new InfoBarMessageView(info_bar_message); | 1645 crashed_plugin_info_bar_ = new InfoBarMessageView(info_bar_message); |
| 1896 view->AddChildView(crashed_plugin_info_bar_); | 1646 view->AddChildView(crashed_plugin_info_bar_); |
| 1897 } else { | 1647 } else { |
| 1898 crashed_plugin_info_bar_->SetMessageText(info_bar_message); | 1648 crashed_plugin_info_bar_->SetMessageText(info_bar_message); |
| 1899 } | 1649 } |
| 1900 } | 1650 } |
| 1901 | 1651 |
| 1902 // Returns true if the entry's transition type is FORM_SUBMIT. | 1652 bool WebContents::CanBlur() const { |
| 1903 static bool IsFormSubmit(const NavigationEntry* entry) { | 1653 return delegate() ? delegate()->CanBlur() : true; |
| 1904 DCHECK(entry); | |
| 1905 return (PageTransition::StripQualifier(entry->transition_type()) == | |
| 1906 PageTransition::FORM_SUBMIT); | |
| 1907 } | 1654 } |
| 1908 | 1655 |
| 1909 void WebContents::PageHasOSDD(RenderViewHost* render_view_host, | 1656 void WebContents::RendererUnresponsive(RenderViewHost* rvh) { |
| 1910 int32 page_id, const GURL& url, | 1657 if (render_view_host() && render_view_host()->IsRenderViewLive()) |
| 1911 bool autodetected) { | 1658 HungRendererWarning::ShowForWebContents(this); |
| 1912 // Make sure page_id is the current page, and the TemplateURLModel is loaded. | 1659 } |
| 1913 DCHECK(url.is_valid()); | |
| 1914 if (!controller() || !IsActiveEntry(page_id)) | |
| 1915 return; | |
| 1916 TemplateURLModel* url_model = profile()->GetTemplateURLModel(); | |
| 1917 if (!url_model) | |
| 1918 return; | |
| 1919 if (!url_model->loaded()) { | |
| 1920 url_model->Load(); | |
| 1921 return; | |
| 1922 } | |
| 1923 if (!profile()->GetTemplateURLFetcher()) | |
| 1924 return; | |
| 1925 | 1660 |
| 1926 if (profile()->IsOffTheRecord()) | 1661 void WebContents::RendererResponsive(RenderViewHost* render_view_host) { |
| 1927 return; | 1662 HungRendererWarning::HideForWebContents(this); |
| 1663 } |
| 1928 | 1664 |
| 1929 const NavigationEntry* entry = controller()->GetLastCommittedEntry(); | 1665 void WebContents::LoadStateChanged(const GURL& url, |
| 1930 DCHECK(entry); | 1666 net::LoadState load_state) { |
| 1931 | 1667 load_state_ = load_state; |
| 1932 const NavigationEntry* base_entry = entry; | 1668 load_state_host_ = UTF8ToWide(url.host()); |
| 1933 if (IsFormSubmit(base_entry)) { | 1669 if (load_state_ == net::LOAD_STATE_READING_RESPONSE) |
| 1934 // If the current page is a form submit, find the last page that was not | 1670 SetNotWaitingForResponse(); |
| 1935 // a form submit and use its url to generate the keyword from. | 1671 if (is_loading()) |
| 1936 int index = controller()->GetLastCommittedEntryIndex() - 1; | 1672 NotifyNavigationStateChanged(INVALIDATE_LOAD); |
| 1937 while (index >= 0 && IsFormSubmit(controller()->GetEntryAtIndex(index))) | |
| 1938 index--; | |
| 1939 if (index >= 0) | |
| 1940 base_entry = controller()->GetEntryAtIndex(index); | |
| 1941 else | |
| 1942 base_entry = NULL; | |
| 1943 } | |
| 1944 | |
| 1945 // We want to use the user typed URL if available since that represents what | |
| 1946 // the user typed to get here, and fall back on the regular URL if not. | |
| 1947 if (!base_entry) | |
| 1948 return; | |
| 1949 GURL keyword_url = base_entry->user_typed_url().is_valid() ? | |
| 1950 base_entry->user_typed_url() : base_entry->url(); | |
| 1951 if (!keyword_url.is_valid()) | |
| 1952 return; | |
| 1953 std::wstring keyword = TemplateURLModel::GenerateKeyword(keyword_url, | |
| 1954 autodetected); | |
| 1955 if (keyword.empty()) | |
| 1956 return; | |
| 1957 const TemplateURL* template_url = | |
| 1958 url_model->GetTemplateURLForKeyword(keyword); | |
| 1959 if (template_url && (!template_url->safe_for_autoreplace() || | |
| 1960 template_url->originating_url() == url)) { | |
| 1961 // Either there is a user created TemplateURL for this keyword, or the | |
| 1962 // keyword has the same OSDD url and we've parsed it. | |
| 1963 return; | |
| 1964 } | |
| 1965 | |
| 1966 // Download the OpenSearch description document. If this is successful a | |
| 1967 // new keyword will be created when done. | |
| 1968 profile()->GetTemplateURLFetcher()->ScheduleDownload( | |
| 1969 keyword, | |
| 1970 url, | |
| 1971 base_entry->favicon().url(), | |
| 1972 GetAncestor(GetHWND(), GA_ROOT), | |
| 1973 autodetected); | |
| 1974 } | 1673 } |
| 1975 | 1674 |
| 1976 void WebContents::OnDidGetApplicationInfo( | 1675 void WebContents::OnDidGetApplicationInfo( |
| 1977 int32 page_id, | 1676 int32 page_id, |
| 1978 const webkit_glue::WebApplicationInfo& info) { | 1677 const webkit_glue::WebApplicationInfo& info) { |
| 1979 if (pending_install_.page_id != page_id) | 1678 if (pending_install_.page_id != page_id) |
| 1980 return; // The user clicked create on a separate page. Ignore this. | 1679 return; // The user clicked create on a separate page. Ignore this. |
| 1981 | 1680 |
| 1982 pending_install_.callback_functor = | 1681 pending_install_.callback_functor = |
| 1983 new GearsCreateShortcutCallbackFunctor(this); | 1682 new GearsCreateShortcutCallbackFunctor(this); |
| 1984 GearsCreateShortcut( | 1683 GearsCreateShortcut( |
| 1985 info, pending_install_.title, pending_install_.url, pending_install_.icon, | 1684 info, pending_install_.title, pending_install_.url, pending_install_.icon, |
| 1986 NewCallback(pending_install_.callback_functor, | 1685 NewCallback(pending_install_.callback_functor, |
| 1987 &GearsCreateShortcutCallbackFunctor::Run)); | 1686 &GearsCreateShortcutCallbackFunctor::Run)); |
| 1988 } | 1687 } |
| 1989 | 1688 |
| 1689 void WebContents::FileSelected(const std::wstring& path, void* params) { |
| 1690 render_view_host()->FileSelected(path); |
| 1691 } |
| 1692 |
| 1693 void WebContents::FileSelectionCanceled(void* params) { |
| 1694 // If the user cancels choosing a file to upload we need to pass back the |
| 1695 // empty string. |
| 1696 render_view_host()->FileSelected(std::wstring()); |
| 1697 } |
| 1698 |
| 1699 void WebContents::BeforeUnloadFiredFromRenderManager( |
| 1700 bool proceed, |
| 1701 bool* proceed_to_fire_unload) { |
| 1702 delegate()->BeforeUnloadFired(this, proceed, proceed_to_fire_unload); |
| 1703 } |
| 1704 |
| 1705 void WebContents::UpdateRenderViewSizeForRenderManager() { |
| 1706 // Using same technique as OnPaint, which sets size of SadTab. |
| 1707 CRect cr; |
| 1708 GetClientRect(&cr); |
| 1709 gfx::Size new_size(cr.Width(), cr.Height()); |
| 1710 SizeContents(new_size); |
| 1711 } |
| 1712 |
| 1713 bool WebContents::CreateRenderViewForRenderManager( |
| 1714 RenderViewHost* render_view_host) { |
| 1715 RenderWidgetHostHWND* view = CreatePageView(render_view_host); |
| 1716 |
| 1717 bool ok = render_view_host->CreateRenderView(); |
| 1718 if (ok) { |
| 1719 CRect client_rect; |
| 1720 ::GetClientRect(GetHWND(), &client_rect); |
| 1721 view->SetSize(gfx::Size(client_rect.Width(), client_rect.Height())); |
| 1722 UpdateMaxPageIDIfNecessary(render_view_host->site_instance(), |
| 1723 render_view_host); |
| 1724 } |
| 1725 return ok; |
| 1726 } |
| 1727 |
| 1728 void WebContents::Observe(NotificationType type, |
| 1729 const NotificationSource& source, |
| 1730 const NotificationDetails& details) { |
| 1731 switch (type) { |
| 1732 case NOTIFY_BOOKMARK_MODEL_LOADED: // BookmarkModel finished loading, fall |
| 1733 // through to update starred state. |
| 1734 case NOTIFY_URLS_STARRED: { // Somewhere, a URL has been starred. |
| 1735 // Ignore notifications for profiles other than our current one. |
| 1736 Profile* source_profile = Source<Profile>(source).ptr(); |
| 1737 if (!source_profile->IsSameProfile(profile())) |
| 1738 return; |
| 1739 |
| 1740 UpdateStarredStateForCurrentURL(); |
| 1741 break; |
| 1742 } |
| 1743 case NOTIFY_PREF_CHANGED: { |
| 1744 std::wstring* pref_name_in = Details<std::wstring>(details).ptr(); |
| 1745 DCHECK(Source<PrefService>(source).ptr() == profile()->GetPrefs()); |
| 1746 if (*pref_name_in == prefs::kAlternateErrorPagesEnabled) { |
| 1747 UpdateAlternateErrorPageURL(); |
| 1748 } else if (*pref_name_in == prefs::kDefaultCharset || |
| 1749 StartsWithASCII(WideToUTF8(*pref_name_in), "webkit.webprefs.", true) |
| 1750 ) { |
| 1751 UpdateWebPreferences(); |
| 1752 } else { |
| 1753 NOTREACHED() << "unexpected pref change notification" << *pref_name_in; |
| 1754 } |
| 1755 break; |
| 1756 } |
| 1757 default: { |
| 1758 NOTREACHED(); |
| 1759 break; |
| 1760 } |
| 1761 } |
| 1762 } |
| 1763 |
| 1764 void WebContents::OnDestroy() { |
| 1765 if (drop_target_.get()) { |
| 1766 RevokeDragDrop(GetHWND()); |
| 1767 drop_target_ = NULL; |
| 1768 } |
| 1769 } |
| 1770 |
| 1771 void WebContents::OnHScroll(int scroll_type, short position, HWND scrollbar) { |
| 1772 ScrollCommon(WM_HSCROLL, scroll_type, position, scrollbar); |
| 1773 } |
| 1774 |
| 1775 void WebContents::OnMouseLeave() { |
| 1776 // Let our delegate know that the mouse moved (useful for resetting status |
| 1777 // bubble state). |
| 1778 if (delegate()) |
| 1779 delegate()->ContentsMouseEvent(this, WM_MOUSELEAVE); |
| 1780 SetMsgHandled(FALSE); |
| 1781 } |
| 1782 |
| 1783 LRESULT WebContents::OnMouseRange(UINT msg, WPARAM w_param, LPARAM l_param) { |
| 1784 switch (msg) { |
| 1785 case WM_LBUTTONDOWN: |
| 1786 case WM_MBUTTONDOWN: |
| 1787 case WM_RBUTTONDOWN: |
| 1788 // Make sure this TabContents is activated when it is clicked on. |
| 1789 if (delegate()) |
| 1790 delegate()->ActivateContents(this); |
| 1791 break; |
| 1792 case WM_MOUSEMOVE: |
| 1793 // Let our delegate know that the mouse moved (useful for resetting status |
| 1794 // bubble state). |
| 1795 if (delegate()) |
| 1796 delegate()->ContentsMouseEvent(this, WM_MOUSEMOVE); |
| 1797 break; |
| 1798 default: |
| 1799 break; |
| 1800 } |
| 1801 |
| 1802 return 0; |
| 1803 } |
| 1804 |
| 1805 void WebContents::OnPaint(HDC junk_dc) { |
| 1806 if (render_view_host() && !render_view_host()->IsRenderViewLive()) { |
| 1807 if (!sad_tab_.get()) |
| 1808 sad_tab_.reset(new SadTabView); |
| 1809 CRect cr; |
| 1810 GetClientRect(&cr); |
| 1811 sad_tab_->SetBounds(cr); |
| 1812 ChromeCanvasPaint canvas(GetHWND(), true); |
| 1813 sad_tab_->ProcessPaint(&canvas); |
| 1814 return; |
| 1815 } |
| 1816 |
| 1817 // We need to do this to validate the dirty area so we don't end up in a |
| 1818 // WM_PAINTstorm that causes other mysterious bugs (such as WM_TIMERs not |
| 1819 // firing etc). It doesn't matter that we don't have any non-clipped area. |
| 1820 CPaintDC dc(GetHWND()); |
| 1821 SetMsgHandled(FALSE); |
| 1822 } |
| 1823 |
| 1824 // A message is reflected here from view(). |
| 1825 // Return non-zero to indicate that it is handled here. |
| 1826 // Return 0 to allow view() to further process it. |
| 1827 LRESULT WebContents::OnReflectedMessage(UINT msg, WPARAM w_param, |
| 1828 LPARAM l_param) { |
| 1829 MSG* message = reinterpret_cast<MSG*>(l_param); |
| 1830 switch (message->message) { |
| 1831 case WM_MOUSEWHEEL: |
| 1832 // This message is reflected from the view() to this window. |
| 1833 if (GET_KEYSTATE_WPARAM(message->wParam) & MK_CONTROL) { |
| 1834 WheelZoom(GET_WHEEL_DELTA_WPARAM(message->wParam)); |
| 1835 return 1; |
| 1836 } |
| 1837 break; |
| 1838 case WM_HSCROLL: |
| 1839 case WM_VSCROLL: |
| 1840 if (ScrollZoom(LOWORD(message->wParam))) |
| 1841 return 1; |
| 1842 default: |
| 1843 break; |
| 1844 } |
| 1845 |
| 1846 return 0; |
| 1847 } |
| 1848 |
| 1849 void WebContents::OnSetFocus(HWND window) { |
| 1850 // TODO(jcampan): figure out why removing this prevents tabs opened in the |
| 1851 // background from properly taking focus. |
| 1852 // We NULL-check the render_view_host_ here because Windows can send us |
| 1853 // messages during the destruction process after it has been destroyed. |
| 1854 if (view()) { |
| 1855 HWND inner_hwnd = view()->GetPluginHWND(); |
| 1856 if (::IsWindow(inner_hwnd)) |
| 1857 ::SetFocus(inner_hwnd); |
| 1858 } |
| 1859 } |
| 1860 |
| 1861 void WebContents::OnVScroll(int scroll_type, short position, HWND scrollbar) { |
| 1862 ScrollCommon(WM_VSCROLL, scroll_type, position, scrollbar); |
| 1863 } |
| 1864 |
| 1865 void WebContents::OnWindowPosChanged(WINDOWPOS* window_pos) { |
| 1866 if (window_pos->flags & SWP_HIDEWINDOW) { |
| 1867 HideContents(); |
| 1868 } else { |
| 1869 // The WebContents was shown by a means other than the user selecting a |
| 1870 // Tab, e.g. the window was minimized then restored. |
| 1871 if (window_pos->flags & SWP_SHOWWINDOW) |
| 1872 ShowContents(); |
| 1873 // Unless we were specifically told not to size, cause the renderer to be |
| 1874 // sized to the new bounds, which forces a repaint. Not required for the |
| 1875 // simple minimize-restore case described above, for example, since the |
| 1876 // size hasn't changed. |
| 1877 if (!(window_pos->flags & SWP_NOSIZE)) { |
| 1878 gfx::Size size(window_pos->cx, window_pos->cy); |
| 1879 SizeContents(size); |
| 1880 } |
| 1881 |
| 1882 // If we have a FindInPage dialog, notify it that the window changed. |
| 1883 if (find_in_page_controller_.get() && find_in_page_controller_->IsVisible()) |
| 1884 find_in_page_controller_->MoveWindowIfNecessary(gfx::Rect()); |
| 1885 } |
| 1886 } |
| 1887 |
| 1888 void WebContents::OnSize(UINT param, const CSize& size) { |
| 1889 HWNDViewContainer::OnSize(param, size); |
| 1890 |
| 1891 // Hack for thinkpad touchpad driver. |
| 1892 // Set fake scrollbars so that we can get scroll messages, |
| 1893 SCROLLINFO si = {0}; |
| 1894 si.cbSize = sizeof(si); |
| 1895 si.fMask = SIF_ALL; |
| 1896 |
| 1897 si.nMin = 1; |
| 1898 si.nMax = 100; |
| 1899 si.nPage = 10; |
| 1900 si.nTrackPos = 50; |
| 1901 |
| 1902 ::SetScrollInfo(GetHWND(), SB_HORZ, &si, FALSE); |
| 1903 ::SetScrollInfo(GetHWND(), SB_VERT, &si, FALSE); |
| 1904 } |
| 1905 |
| 1906 LRESULT WebContents::OnNCCalcSize(BOOL w_param, LPARAM l_param) { |
| 1907 // Hack for thinkpad mouse wheel driver. We have set the fake scroll bars |
| 1908 // to receive scroll messages from thinkpad touchpad driver. Suppress |
| 1909 // painting of scrollbars by returning 0 size for them. |
| 1910 return 0; |
| 1911 } |
| 1912 |
| 1913 void WebContents::OnNCPaint(HRGN rgn) { |
| 1914 // Suppress default WM_NCPAINT handling. We don't need to do anything |
| 1915 // here since the view will draw everything correctly. |
| 1916 } |
| 1917 |
| 1918 void WebContents::ScrollCommon(UINT message, int scroll_type, short position, |
| 1919 HWND scrollbar) { |
| 1920 // This window can receive scroll events as a result of the ThinkPad's |
| 1921 // Trackpad scroll wheel emulation. |
| 1922 if (!ScrollZoom(scroll_type)) { |
| 1923 // Reflect scroll message to the view() to give it a chance |
| 1924 // to process scrolling. |
| 1925 SendMessage(GetContentHWND(), message, MAKELONG(scroll_type, position), |
| 1926 (LPARAM) scrollbar); |
| 1927 } |
| 1928 } |
| 1929 |
| 1930 bool WebContents::ScrollZoom(int scroll_type) { |
| 1931 // If ctrl is held, zoom the UI. There are three issues with this: |
| 1932 // 1) Should the event be eaten or forwarded to content? We eat the event, |
| 1933 // which is like Firefox and unlike IE. |
| 1934 // 2) Should wheel up zoom in or out? We zoom in (increase font size), which |
| 1935 // is like IE and Google maps, but unlike Firefox. |
| 1936 // 3) Should the mouse have to be over the content area? We zoom as long as |
| 1937 // content has focus, although FF and IE require that the mouse is over |
| 1938 // content. This is because all events get forwarded when content has |
| 1939 // focus. |
| 1940 if (GetAsyncKeyState(VK_CONTROL) & 0x8000) { |
| 1941 int distance = 0; |
| 1942 switch (scroll_type) { |
| 1943 case SB_LINEUP: |
| 1944 distance = WHEEL_DELTA; |
| 1945 break; |
| 1946 case SB_LINEDOWN: |
| 1947 distance = -WHEEL_DELTA; |
| 1948 break; |
| 1949 // TODO(joshia): Handle SB_PAGEUP, SB_PAGEDOWN, SB_THUMBPOSITION, |
| 1950 // and SB_THUMBTRACK for completeness |
| 1951 default: |
| 1952 break; |
| 1953 } |
| 1954 |
| 1955 WheelZoom(distance); |
| 1956 return true; |
| 1957 } |
| 1958 return false; |
| 1959 } |
| 1960 |
| 1961 void WebContents::WheelZoom(int distance) { |
| 1962 if (delegate()) { |
| 1963 bool zoom_in = distance > 0; |
| 1964 delegate()->ContentsZoomChange(zoom_in); |
| 1965 } |
| 1966 } |
| 1967 |
| 1968 void WebContents::DidNavigateMainFramePostCommit( |
| 1969 const NavigationController::LoadCommittedDetails& details, |
| 1970 const ViewHostMsg_FrameNavigate_Params& params) { |
| 1971 // Hide the download shelf if all the following conditions are true: |
| 1972 // - there are no active downloads. |
| 1973 // - this is a navigation to a different TLD. |
| 1974 // - at least 5 seconds have elapsed since the download shelf was shown. |
| 1975 // TODO(jcampan): bug 1156075 when user gestures are reliable, they should |
| 1976 // be used to ensure we are hiding only on user initiated |
| 1977 // navigations. |
| 1978 DownloadManager* download_manager = profile()->GetDownloadManager(); |
| 1979 // download_manager can be NULL in unit test context. |
| 1980 if (download_manager && download_manager->in_progress_count() == 0 && |
| 1981 !details.previous_url.is_empty() && |
| 1982 !net::RegistryControlledDomainService::SameDomainOrHost( |
| 1983 details.previous_url, details.entry->url())) { |
| 1984 TimeDelta time_delta( |
| 1985 TimeTicks::Now() - last_download_shelf_show_); |
| 1986 if (time_delta > |
| 1987 TimeDelta::FromMilliseconds(kDownloadShelfHideDelay)) { |
| 1988 SetDownloadShelfVisible(false); |
| 1989 } |
| 1990 } |
| 1991 |
| 1992 if (details.is_user_initiated_main_frame_load()) { |
| 1993 // Clear the status bubble. This is a workaround for a bug where WebKit |
| 1994 // doesn't let us know that the cursor left an element during a |
| 1995 // transition (this is also why the mouse cursor remains as a hand after |
| 1996 // clicking on a link); see bugs 1184641 and 980803. We don't want to |
| 1997 // clear the bubble when a user navigates to a named anchor in the same |
| 1998 // page. |
| 1999 UpdateTargetURL(details.entry->page_id(), GURL()); |
| 2000 |
| 2001 // UpdateHelpersForDidNavigate will handle the case where the password_form |
| 2002 // origin is valid. |
| 2003 // TODO(brettw) bug 1343111: Password manager stuff in here needs to be |
| 2004 // cleaned up and covered by tests. |
| 2005 if (!params.password_form.origin.is_valid()) |
| 2006 GetPasswordManager()->DidNavigate(); |
| 2007 } |
| 2008 |
| 2009 // The keyword generator uses the navigation entries, so must be called after |
| 2010 // the commit. |
| 2011 GenerateKeywordIfNecessary(params); |
| 2012 |
| 2013 // We no longer know the title after this navigation. |
| 2014 has_page_title_ = false; |
| 2015 |
| 2016 // Update contents MIME type of the main webframe. |
| 2017 contents_mime_type_ = params.contents_mime_type; |
| 2018 |
| 2019 // Get the favicon, either from history or request it from the net. |
| 2020 fav_icon_helper_.FetchFavIcon(details.entry->url()); |
| 2021 |
| 2022 // Close constrained popups if necessary. |
| 2023 MaybeCloseChildWindows(params); |
| 2024 |
| 2025 // We hide the FindInPage window when the user navigates away, except on |
| 2026 // reload. |
| 2027 if (PageTransition::StripQualifier(params.transition) != |
| 2028 PageTransition::RELOAD) |
| 2029 SetFindInPageVisible(false); |
| 2030 |
| 2031 // Update the starred state. |
| 2032 UpdateStarredStateForCurrentURL(); |
| 2033 } |
| 2034 |
| 2035 void WebContents::DidNavigateAnyFramePostCommit( |
| 2036 RenderViewHost* render_view_host, |
| 2037 const NavigationController::LoadCommittedDetails& details, |
| 2038 const ViewHostMsg_FrameNavigate_Params& params) { |
| 2039 // If we navigate, start showing messages again. This does nothing to prevent |
| 2040 // a malicious script from spamming messages, since the script could just |
| 2041 // reload the page to stop blocking. |
| 2042 suppress_javascript_messages_ = false; |
| 2043 |
| 2044 // Update history. Note that this needs to happen after the entry is complete, |
| 2045 // which WillNavigate[Main,Sub]Frame will do before this function is called. |
| 2046 if (params.should_update_history) { |
| 2047 // Most of the time, the displayURL matches the loaded URL, but for about: |
| 2048 // URLs, we use a data: URL as the real value. We actually want to save |
| 2049 // the about: URL to the history db and keep the data: URL hidden. This is |
| 2050 // what the TabContents' URL getter does. |
| 2051 UpdateHistoryForNavigation(GetURL(), params); |
| 2052 } |
| 2053 |
| 2054 // Notify the password manager of the navigation or form submit. |
| 2055 // TODO(brettw) bug 1343111: Password manager stuff in here needs to be |
| 2056 // cleaned up and covered by tests. |
| 2057 if (params.password_form.origin.is_valid()) |
| 2058 GetPasswordManager()->ProvisionallySavePassword(params.password_form); |
| 2059 } |
| 2060 |
| 2061 void WebContents::MaybeCloseChildWindows( |
| 2062 const ViewHostMsg_FrameNavigate_Params& params) { |
| 2063 if (net::RegistryControlledDomainService::SameDomainOrHost( |
| 2064 last_url_, params.url)) |
| 2065 return; |
| 2066 last_url_ = params.url; |
| 2067 |
| 2068 // Clear out any child windows since we are leaving this page entirely. |
| 2069 // We use indices instead of iterators in case CloseWindow does something |
| 2070 // that may invalidate an iterator. |
| 2071 int size = static_cast<int>(child_windows_.size()); |
| 2072 for (int i = size - 1; i >= 0; --i) { |
| 2073 ConstrainedWindow* window = child_windows_[i]; |
| 2074 if (window) |
| 2075 window->CloseConstrainedWindow(); |
| 2076 } |
| 2077 } |
| 2078 |
| 2079 void WebContents::UpdateStarredStateForCurrentURL() { |
| 2080 BookmarkModel* model = profile()->GetBookmarkModel(); |
| 2081 const bool old_state = is_starred_; |
| 2082 is_starred_ = (model && model->IsBookmarked(GetURL())); |
| 2083 |
| 2084 if (is_starred_ != old_state && delegate()) |
| 2085 delegate()->URLStarredChanged(this, is_starred_); |
| 2086 } |
| 2087 |
| 2088 void WebContents::UpdateAlternateErrorPageURL() { |
| 2089 GURL url = GetAlternateErrorPageURL(); |
| 2090 render_view_host()->SetAlternateErrorPageURL(url); |
| 2091 } |
| 2092 |
| 2093 void WebContents::UpdateWebPreferences() { |
| 2094 render_view_host()->UpdateWebPreferences(GetWebkitPrefs()); |
| 2095 } |
| 2096 |
| 2097 bool WebContents::IsWebApplicationActive() const { |
| 2098 if (!web_app_.get()) |
| 2099 return false; |
| 2100 |
| 2101 // If we are inside an application, the application is always active. For |
| 2102 // example, this allows us to display the GMail icon even when we are bounced |
| 2103 // the login page. |
| 2104 if (delegate() && delegate()->IsApplication()) |
| 2105 return true; |
| 2106 |
| 2107 return (GetURL() == web_app_->url()); |
| 2108 } |
| 2109 |
| 2110 void WebContents::WebAppImagesChanged(WebApp* web_app) { |
| 2111 DCHECK(web_app == web_app_.get()); |
| 2112 if (delegate() && IsWebApplicationActive()) |
| 2113 delegate()->NavigationStateChanged(this, TabContents::INVALIDATE_FAVICON); |
| 2114 } |
| 2115 |
| 1990 void WebContents::OnGearsCreateShortcutDone( | 2116 void WebContents::OnGearsCreateShortcutDone( |
| 1991 const GearsShortcutData& shortcut_data, bool success) { | 2117 const GearsShortcutData& shortcut_data, bool success) { |
| 1992 NavigationEntry* current_entry = controller()->GetLastCommittedEntry(); | 2118 NavigationEntry* current_entry = controller()->GetLastCommittedEntry(); |
| 1993 bool same_page = | 2119 bool same_page = |
| 1994 current_entry && pending_install_.page_id == current_entry->page_id(); | 2120 current_entry && pending_install_.page_id == current_entry->page_id(); |
| 1995 | 2121 |
| 1996 if (success && same_page) { | 2122 if (success && same_page) { |
| 1997 // Only switch to app mode if the user chose to create a shortcut and | 2123 // Only switch to app mode if the user chose to create a shortcut and |
| 1998 // we're still on the same page that it corresponded to. | 2124 // we're still on the same page that it corresponded to. |
| 1999 SetWebApp(new WebApp(profile(), shortcut_data)); | 2125 SetWebApp(new WebApp(profile(), shortcut_data)); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2024 // Also tell the renderer to update its internal representation. We | 2150 // Also tell the renderer to update its internal representation. We |
| 2025 // need to reserve enough IDs to make all restored page IDs less than | 2151 // need to reserve enough IDs to make all restored page IDs less than |
| 2026 // the max. | 2152 // the max. |
| 2027 if (curr_max_page_id < 0) | 2153 if (curr_max_page_id < 0) |
| 2028 curr_max_page_id = 0; | 2154 curr_max_page_id = 0; |
| 2029 rvh->ReservePageIDRange(max_restored_page_id - curr_max_page_id); | 2155 rvh->ReservePageIDRange(max_restored_page_id - curr_max_page_id); |
| 2030 } | 2156 } |
| 2031 } | 2157 } |
| 2032 } | 2158 } |
| 2033 | 2159 |
| 2034 void WebContents::BeforeUnloadFiredFromRenderManager( | 2160 void WebContents::UpdateHistoryForNavigation(const GURL& display_url, |
| 2035 bool proceed, | 2161 const ViewHostMsg_FrameNavigate_Params& params) { |
| 2036 bool* proceed_to_fire_unload) { | 2162 if (profile()->IsOffTheRecord()) |
| 2037 delegate()->BeforeUnloadFired(this, proceed, proceed_to_fire_unload); | 2163 return; |
| 2164 |
| 2165 // Add to history service. |
| 2166 HistoryService* hs = profile()->GetHistoryService(Profile::IMPLICIT_ACCESS); |
| 2167 if (hs) { |
| 2168 if (PageTransition::IsMainFrame(params.transition) && |
| 2169 display_url != params.url) { |
| 2170 // Hack on the "display" URL so that it will appear in history. For some |
| 2171 // types of URLs, we will display a magic URL that is different from where |
| 2172 // the page is actually navigated. We want the user to see in history |
| 2173 // what they saw in the URL bar, so we add the display URL as a redirect. |
| 2174 // This only applies to the main frame, as the display URL doesn't apply |
| 2175 // to sub-frames. |
| 2176 std::vector<GURL> redirects = params.redirects; |
| 2177 if (!redirects.empty()) |
| 2178 redirects.back() = display_url; |
| 2179 hs->AddPage(display_url, this, params.page_id, params.referrer, |
| 2180 params.transition, redirects); |
| 2181 } else { |
| 2182 hs->AddPage(params.url, this, params.page_id, params.referrer, |
| 2183 params.transition, params.redirects); |
| 2184 } |
| 2185 } |
| 2038 } | 2186 } |
| 2039 | 2187 |
| 2040 | 2188 RenderWidgetHostHWND* WebContents::CreatePageView( |
| 2041 HWND WebContents::GetContentHWND() { | 2189 RenderViewHost* render_view_host) { |
| 2042 if (!view()) | 2190 // Create the View as well. Its lifetime matches the child process'. |
| 2043 return NULL; | 2191 DCHECK(!render_view_host->view()); |
| 2044 return view()->GetPluginHWND(); | 2192 RenderWidgetHostHWND* view = new RenderWidgetHostHWND(render_view_host); |
| 2193 render_view_host->set_view(view); |
| 2194 view->Create(GetHWND()); |
| 2195 view->ShowWindow(SW_SHOW); |
| 2196 return view; |
| 2045 } | 2197 } |
| 2046 | 2198 |
| 2047 bool WebContents::CanDisplayFile(const std::wstring& full_path) { | 2199 void WebContents::DetachPluginWindows() { |
| 2048 bool allow_wildcard = false; | 2200 EnumChildWindows(GetHWND(), WebContents::EnumPluginWindowsCallback, NULL); |
| 2049 std::string mime_type; | |
| 2050 net::GetMimeTypeFromFile(full_path, &mime_type); | |
| 2051 if (net::IsSupportedMimeType(mime_type) || | |
| 2052 (PluginService::GetInstance() && | |
| 2053 PluginService::GetInstance()->HavePluginFor(mime_type, allow_wildcard))) | |
| 2054 return true; | |
| 2055 return false; | |
| 2056 } | 2201 } |
| 2057 | 2202 |
| 2058 void WebContents::PrintPreview() { | 2203 BOOL WebContents::EnumPluginWindowsCallback(HWND window, LPARAM) { |
| 2059 // We can't print interstitial page for now. | 2204 if (WebPluginDelegateImpl::IsPluginDelegateWindow(window)) { |
| 2060 if (render_manager_.showing_interstitial_page()) | 2205 ::ShowWindow(window, SW_HIDE); |
| 2206 SetParent(window, NULL); |
| 2207 } |
| 2208 |
| 2209 return TRUE; |
| 2210 } |
| 2211 |
| 2212 void WebContents::NotifySwapped() { |
| 2213 // After sending out a swap notification, we need to send a disconnect |
| 2214 // notification so that clients that pick up a pointer to |this| can NULL the |
| 2215 // pointer. See Bug 1230284. |
| 2216 notify_disconnection_ = true; |
| 2217 NotificationService::current()-> |
| 2218 Notify(NOTIFY_WEB_CONTENTS_SWAPPED, |
| 2219 Source<WebContents>(this), |
| 2220 NotificationService::NoDetails()); |
| 2221 } |
| 2222 |
| 2223 void WebContents::NotifyConnected() { |
| 2224 notify_disconnection_ = true; |
| 2225 NotificationService::current()-> |
| 2226 Notify(NOTIFY_WEB_CONTENTS_CONNECTED, |
| 2227 Source<WebContents>(this), |
| 2228 NotificationService::NoDetails()); |
| 2229 } |
| 2230 |
| 2231 void WebContents::NotifyDisconnected() { |
| 2232 if (!notify_disconnection_) |
| 2061 return; | 2233 return; |
| 2062 | 2234 |
| 2063 // If we have a FindInPage dialog, notify it that its tab was hidden. | 2235 notify_disconnection_ = false; |
| 2064 if (find_in_page_controller_.get()) | 2236 NotificationService::current()-> |
| 2065 find_in_page_controller_->DidBecomeUnselected(); | 2237 Notify(NOTIFY_WEB_CONTENTS_DISCONNECTED, |
| 2066 | 2238 Source<WebContents>(this), |
| 2067 // We don't show the print preview for the beta, only the print dialog. | 2239 NotificationService::NoDetails()); |
| 2068 printing_.ShowPrintDialog(); | |
| 2069 } | |
| 2070 | |
| 2071 bool WebContents::PrintNow() { | |
| 2072 // We can't print interstitial page for now. | |
| 2073 if (render_manager_.showing_interstitial_page()) | |
| 2074 return false; | |
| 2075 | |
| 2076 // If we have a FindInPage dialog, notify it that its tab was hidden. | |
| 2077 if (find_in_page_controller_.get()) | |
| 2078 find_in_page_controller_->DidBecomeUnselected(); | |
| 2079 | |
| 2080 return printing_.PrintNow(); | |
| 2081 } | |
| 2082 | |
| 2083 void WebContents::WillCaptureContents() { | |
| 2084 capturing_contents_ = true; | |
| 2085 } | |
| 2086 | |
| 2087 void WebContents::DidCaptureContents() { | |
| 2088 capturing_contents_ = false; | |
| 2089 } | |
| 2090 | |
| 2091 void WebContents::Cut() { | |
| 2092 render_view_host()->Cut(); | |
| 2093 } | |
| 2094 | |
| 2095 void WebContents::Copy() { | |
| 2096 render_view_host()->Copy(); | |
| 2097 } | |
| 2098 | |
| 2099 void WebContents::Paste() { | |
| 2100 render_view_host()->Paste(); | |
| 2101 } | |
| 2102 | |
| 2103 void WebContents::SetInitialFocus(bool reverse) { | |
| 2104 render_view_host()->SetInitialFocus(reverse); | |
| 2105 } | 2240 } |
| 2106 | 2241 |
| 2107 void WebContents::GenerateKeywordIfNecessary( | 2242 void WebContents::GenerateKeywordIfNecessary( |
| 2108 const ViewHostMsg_FrameNavigate_Params& params) { | 2243 const ViewHostMsg_FrameNavigate_Params& params) { |
| 2109 DCHECK(controller()); | 2244 DCHECK(controller()); |
| 2110 if (!params.searchable_form_url.is_valid()) | 2245 if (!params.searchable_form_url.is_valid()) |
| 2111 return; | 2246 return; |
| 2112 | 2247 |
| 2113 if (profile()->IsOffTheRecord()) | 2248 if (profile()->IsOffTheRecord()) |
| 2114 return; | 2249 return; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2171 // The favicon url isn't valid. This means there really isn't a favicon, | 2306 // The favicon url isn't valid. This means there really isn't a favicon, |
| 2172 // or the favicon url wasn't obtained before the load started. This assumes | 2307 // or the favicon url wasn't obtained before the load started. This assumes |
| 2173 // the later. | 2308 // the later. |
| 2174 // TODO(sky): Need a way to set the favicon that doesn't involve generating | 2309 // TODO(sky): Need a way to set the favicon that doesn't involve generating |
| 2175 // its url. | 2310 // its url. |
| 2176 new_url->SetFavIconURL(TemplateURL::GenerateFaviconURL(params.referrer)); | 2311 new_url->SetFavIconURL(TemplateURL::GenerateFaviconURL(params.referrer)); |
| 2177 } | 2312 } |
| 2178 new_url->set_safe_for_autoreplace(true); | 2313 new_url->set_safe_for_autoreplace(true); |
| 2179 url_model->Add(new_url); | 2314 url_model->Add(new_url); |
| 2180 } | 2315 } |
| 2181 | |
| 2182 void WebContents::InspectElementReply(int num_resources) { | |
| 2183 // We have received reply from inspect element request. Notify the | |
| 2184 // automation provider in case we need to notify automation client. | |
| 2185 NotificationService::current()-> | |
| 2186 Notify(NOTIFY_DOM_INSPECT_ELEMENT_RESPONSE, Source<WebContents>(this), | |
| 2187 Details<int>(&num_resources)); | |
| 2188 } | |
| 2189 | |
| 2190 // The renderer sends back to the browser the key events it did not process. | |
| 2191 void WebContents::HandleKeyboardEvent(const WebKeyboardEvent& event) { | |
| 2192 // The renderer returned a keyboard event it did not process. This may be | |
| 2193 // a keyboard shortcut that we have to process. | |
| 2194 if (event.type == WebInputEvent::KEY_DOWN) { | |
| 2195 ChromeViews::FocusManager* focus_manager = | |
| 2196 ChromeViews::FocusManager::GetFocusManager(GetHWND()); | |
| 2197 // We may not have a focus_manager at this point (if the tab has been | |
| 2198 // switched by the time this message returned). | |
| 2199 if (focus_manager) { | |
| 2200 ChromeViews::Accelerator accelerator(event.key_code, | |
| 2201 (event.modifiers & WebInputEvent::SHIFT_KEY) == | |
| 2202 WebInputEvent::SHIFT_KEY, | |
| 2203 (event.modifiers & WebInputEvent::CTRL_KEY) == | |
| 2204 WebInputEvent::CTRL_KEY, | |
| 2205 (event.modifiers & WebInputEvent::ALT_KEY) == | |
| 2206 WebInputEvent::ALT_KEY); | |
| 2207 if (focus_manager->ProcessAccelerator(accelerator, false)) | |
| 2208 return; | |
| 2209 } | |
| 2210 } | |
| 2211 | |
| 2212 // Any unhandled keyboard/character messages should be defproced. | |
| 2213 // This allows stuff like Alt+F4, etc to work correctly. | |
| 2214 DefWindowProc(event.actual_message.hwnd, | |
| 2215 event.actual_message.message, | |
| 2216 event.actual_message.wParam, | |
| 2217 event.actual_message.lParam); | |
| 2218 } | |
| 2219 | |
| 2220 bool WebContents::CreateRenderViewForRenderManager( | |
| 2221 RenderViewHost* render_view_host) { | |
| 2222 RenderWidgetHostHWND* view = CreatePageView(render_view_host); | |
| 2223 | |
| 2224 bool ok = render_view_host->CreateRenderView(); | |
| 2225 if (ok) { | |
| 2226 CRect client_rect; | |
| 2227 ::GetClientRect(GetHWND(), &client_rect); | |
| 2228 view->SetSize(gfx::Size(client_rect.Width(), client_rect.Height())); | |
| 2229 UpdateMaxPageIDIfNecessary(render_view_host->site_instance(), | |
| 2230 render_view_host); | |
| 2231 } | |
| 2232 return ok; | |
| 2233 } | |
| 2234 | |
| 2235 RenderWidgetHostHWND* WebContents::CreatePageView( | |
| 2236 RenderViewHost* render_view_host) { | |
| 2237 // Create the View as well. Its lifetime matches the child process'. | |
| 2238 DCHECK(!render_view_host->view()); | |
| 2239 RenderWidgetHostHWND* view = new RenderWidgetHostHWND(render_view_host); | |
| 2240 render_view_host->set_view(view); | |
| 2241 view->Create(GetHWND()); | |
| 2242 view->ShowWindow(SW_SHOW); | |
| 2243 return view; | |
| 2244 } | |
| 2245 | |
| 2246 void WebContents::DidGetPrintedPagesCount(int cookie, int number_pages) { | |
| 2247 printing_.DidGetPrintedPagesCount(cookie, number_pages); | |
| 2248 } | |
| 2249 | |
| 2250 void WebContents::DidPrintPage(const ViewHostMsg_DidPrintPage_Params& params) { | |
| 2251 printing_.DidPrintPage(params); | |
| 2252 } | |
| 2253 | |
| 2254 void WebContents::SetIsLoading(bool is_loading, | |
| 2255 LoadNotificationDetails* details) { | |
| 2256 if (!is_loading) { | |
| 2257 load_state_ = net::LOAD_STATE_IDLE; | |
| 2258 load_state_host_.clear(); | |
| 2259 } | |
| 2260 | |
| 2261 TabContents::SetIsLoading(is_loading, details); | |
| 2262 render_manager_.SetIsLoading(is_loading); | |
| 2263 } | |
| 2264 | |
| 2265 void WebContents::FileSelected(const std::wstring& path, void* params) { | |
| 2266 render_view_host()->FileSelected(path); | |
| 2267 } | |
| 2268 | |
| 2269 void WebContents::FileSelectionCanceled(void* params) { | |
| 2270 // If the user cancels choosing a file to upload we need to pass back the | |
| 2271 // empty string. | |
| 2272 render_view_host()->FileSelected(std::wstring()); | |
| 2273 } | |
| 2274 | |
| 2275 /////////////////////////////////////////////////////////////////////////////// | |
| 2276 | |
| 2277 SkBitmap WebContents::GetFavIcon() { | |
| 2278 if (web_app_.get() && IsWebApplicationActive()) { | |
| 2279 SkBitmap app_icon = web_app_->GetFavIcon(); | |
| 2280 if (!app_icon.isNull()) | |
| 2281 return app_icon; | |
| 2282 } | |
| 2283 return TabContents::GetFavIcon(); | |
| 2284 } | |
| 2285 | |
| 2286 std::wstring WebContents::GetStatusText() const { | |
| 2287 if (!is_loading() || load_state_ == net::LOAD_STATE_IDLE) | |
| 2288 return std::wstring(); | |
| 2289 | |
| 2290 switch (load_state_) { | |
| 2291 case net::LOAD_STATE_WAITING_FOR_CACHE: | |
| 2292 return l10n_util::GetString(IDS_LOAD_STATE_WAITING_FOR_CACHE); | |
| 2293 case net::LOAD_STATE_RESOLVING_PROXY_FOR_URL: | |
| 2294 return l10n_util::GetString(IDS_LOAD_STATE_RESOLVING_PROXY_FOR_URL); | |
| 2295 case net::LOAD_STATE_RESOLVING_HOST: | |
| 2296 return l10n_util::GetString(IDS_LOAD_STATE_RESOLVING_HOST); | |
| 2297 case net::LOAD_STATE_CONNECTING: | |
| 2298 return l10n_util::GetString(IDS_LOAD_STATE_CONNECTING); | |
| 2299 case net::LOAD_STATE_SENDING_REQUEST: | |
| 2300 return l10n_util::GetString(IDS_LOAD_STATE_SENDING_REQUEST); | |
| 2301 case net::LOAD_STATE_WAITING_FOR_RESPONSE: | |
| 2302 return l10n_util::GetStringF(IDS_LOAD_STATE_WAITING_FOR_RESPONSE, | |
| 2303 load_state_host_); | |
| 2304 // Ignore net::LOAD_STATE_READING_RESPONSE and net::LOAD_STATE_IDLE | |
| 2305 } | |
| 2306 | |
| 2307 return std::wstring(); | |
| 2308 } | |
| 2309 | |
| 2310 bool WebContents::CanBlur() const { | |
| 2311 return delegate() ? delegate()->CanBlur() : true; | |
| 2312 } | |
| 2313 | |
| 2314 void WebContents::RendererUnresponsive(RenderViewHost* rvh) { | |
| 2315 if (render_view_host() && render_view_host()->IsRenderViewLive()) | |
| 2316 HungRendererWarning::ShowForWebContents(this); | |
| 2317 } | |
| 2318 | |
| 2319 void WebContents::RendererResponsive(RenderViewHost* render_view_host) { | |
| 2320 HungRendererWarning::HideForWebContents(this); | |
| 2321 } | |
| 2322 | |
| 2323 void WebContents::LoadStateChanged(const GURL& url, | |
| 2324 net::LoadState load_state) { | |
| 2325 load_state_ = load_state; | |
| 2326 load_state_host_ = UTF8ToWide(url.host()); | |
| 2327 if (load_state_ == net::LOAD_STATE_READING_RESPONSE) | |
| 2328 response_started_ = false; | |
| 2329 if (is_loading()) | |
| 2330 NotifyNavigationStateChanged(INVALIDATE_LOAD); | |
| 2331 } | |
| 2332 | |
| 2333 void WebContents::DetachPluginWindows() { | |
| 2334 EnumChildWindows(GetHWND(), WebContents::EnumPluginWindowsCallback, NULL); | |
| 2335 } | |
| 2336 | |
| 2337 BOOL WebContents::EnumPluginWindowsCallback(HWND window, LPARAM) { | |
| 2338 if (WebPluginDelegateImpl::IsPluginDelegateWindow(window)) { | |
| 2339 ::ShowWindow(window, SW_HIDE); | |
| 2340 SetParent(window, NULL); | |
| 2341 } | |
| 2342 | |
| 2343 return TRUE; | |
| 2344 } | |
| OLD | NEW |