Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 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 // Implements the Chrome Extensions WebNavigation API. | 5 // Implements the Chrome Extensions WebNavigation API. |
| 6 | 6 |
| 7 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h" | 7 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h" |
| 8 | 8 |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "chrome/browser/chrome_notification_types.h" | 10 #include "chrome/browser/chrome_notification_types.h" |
| 11 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_consta nts.h" | 11 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_consta nts.h" |
| 12 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helper s.h" | 12 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helper s.h" |
| 13 #include "chrome/browser/extensions/extension_tab_util.h" | 13 #include "chrome/browser/extensions/extension_tab_util.h" |
| 14 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
| 15 #include "chrome/browser/tab_contents/retargeting_details.h" | 15 #include "chrome/browser/tab_contents/retargeting_details.h" |
| 16 #include "chrome/browser/ui/browser.h" | 16 #include "chrome/browser/ui/browser.h" |
| 17 #include "chrome/browser/ui/browser_list.h" | 17 #include "chrome/browser/ui/browser_list.h" |
| 18 #include "chrome/common/extensions/api/web_navigation.h" | 18 #include "chrome/common/extensions/api/web_navigation.h" |
| 19 #include "content/public/browser/navigation_details.h" | 19 #include "content/public/browser/navigation_details.h" |
| 20 #include "content/public/browser/navigation_handle.h" | |
| 20 #include "content/public/browser/notification_service.h" | 21 #include "content/public/browser/notification_service.h" |
| 21 #include "content/public/browser/notification_types.h" | 22 #include "content/public/browser/notification_types.h" |
| 22 #include "content/public/browser/render_frame_host.h" | 23 #include "content/public/browser/render_frame_host.h" |
| 23 #include "content/public/browser/render_process_host.h" | 24 #include "content/public/browser/render_process_host.h" |
| 24 #include "content/public/browser/resource_request_details.h" | 25 #include "content/public/browser/resource_request_details.h" |
| 25 #include "content/public/browser/web_contents.h" | 26 #include "content/public/browser/web_contents.h" |
| 26 #include "content/public/common/url_constants.h" | 27 #include "content/public/common/url_constants.h" |
| 27 #include "extensions/browser/event_router.h" | 28 #include "extensions/browser/event_router.h" |
| 28 #include "extensions/browser/extension_api_frame_id_map.h" | 29 #include "extensions/browser/extension_api_frame_id_map.h" |
| 29 #include "extensions/browser/view_type_utils.h" | 30 #include "extensions/browser/view_type_utils.h" |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 content::RenderFrameHost* old_host, | 260 content::RenderFrameHost* old_host, |
| 260 content::RenderFrameHost* new_host) { | 261 content::RenderFrameHost* new_host) { |
| 261 if (old_host) { | 262 if (old_host) { |
| 262 RenderFrameDeleted(old_host); | 263 RenderFrameDeleted(old_host); |
| 263 navigation_state_.FrameHostDeleted(old_host); | 264 navigation_state_.FrameHostDeleted(old_host); |
| 264 } | 265 } |
| 265 | 266 |
| 266 navigation_state_.FrameHostCreated(new_host); | 267 navigation_state_.FrameHostCreated(new_host); |
| 267 } | 268 } |
| 268 | 269 |
| 269 void WebNavigationTabObserver::DidStartProvisionalLoadForFrame( | 270 void WebNavigationTabObserver::DidStartNavigation( |
| 270 content::RenderFrameHost* render_frame_host, | 271 content::NavigationHandle* navigation_handle) { |
| 271 const GURL& validated_url, | 272 if (navigation_handle->IsSynchronousNavigation()) |
| 272 bool is_error_page, | |
| 273 bool is_iframe_srcdoc) { | |
| 274 DVLOG(2) << "DidStartProvisionalLoad(" | |
| 275 << "render_frame_host=" << render_frame_host | |
| 276 << ", frame_num=" << render_frame_host->GetRoutingID() | |
| 277 << ", url=" << validated_url << ")"; | |
| 278 navigation_state_.StartTrackingNavigation(render_frame_host, validated_url, | |
| 279 is_error_page, is_iframe_srcdoc); | |
| 280 | |
| 281 if (!navigation_state_.CanSendEvents(render_frame_host)) | |
| 282 return; | 273 return; |
| 283 | 274 |
| 284 helpers::DispatchOnBeforeNavigate( | 275 if (!FrameNavigationState::IsValidUrl(navigation_handle->GetURL())) |
| 285 web_contents(), | 276 return; |
| 286 render_frame_host, | 277 |
| 287 navigation_state_.GetUrl(render_frame_host)); | 278 helpers::DispatchOnBeforeNavigate(navigation_handle); |
| 288 } | 279 } |
| 289 | 280 |
| 290 void WebNavigationTabObserver::DidCommitProvisionalLoadForFrame( | 281 void WebNavigationTabObserver::DidFinishNavigation( |
|
Devlin
2016/02/05 18:30:28
I'm sure it's just that I'm not as familiar with a
nasko
2016/02/05 23:41:22
I rephrased the comment on is_loading, which I mis
| |
| 291 content::RenderFrameHost* render_frame_host, | 282 content::NavigationHandle* navigation_handle) { |
| 292 const GURL& url, | 283 if (navigation_handle->HasCommitted()) { |
| 293 ui::PageTransition transition_type) { | 284 if (navigation_handle->IsErrorPage()) { |
| 294 DVLOG(2) << "DidCommitProvisionalLoad(" | 285 HandleError(navigation_handle); |
|
Devlin
2016/02/05 18:30:28
HandleError vs DispatchOnErrorOccurred is a little
nasko
2016/02/05 23:41:22
Done.
| |
| 295 << "render_frame_host=" << render_frame_host | 286 } else { |
| 296 << ", frame_num=" << render_frame_host->GetRoutingID() | 287 HandleCommit(navigation_handle); |
| 297 << ", url=" << url << ")"; | 288 } |
| 298 bool is_reference_fragment_navigation = | |
| 299 IsReferenceFragmentNavigation(render_frame_host, url); | |
| 300 bool is_history_state_modification = | |
| 301 navigation_state_.GetNavigationCommitted(render_frame_host); | |
| 302 | |
| 303 // Update the URL as it might have changed. | |
| 304 navigation_state_.UpdateFrame(render_frame_host, url); | |
| 305 navigation_state_.SetNavigationCommitted(render_frame_host); | |
| 306 | |
| 307 if (!navigation_state_.CanSendEvents(render_frame_host)) | |
| 308 return; | |
| 309 | |
| 310 events::HistogramValue histogram_value = events::UNKNOWN; | |
| 311 std::string event_name; | |
| 312 if (is_reference_fragment_navigation) { | |
| 313 histogram_value = events::WEB_NAVIGATION_ON_REFERENCE_FRAGMENT_UPDATED; | |
| 314 event_name = web_navigation::OnReferenceFragmentUpdated::kEventName; | |
| 315 } else if (is_history_state_modification) { | |
| 316 histogram_value = events::WEB_NAVIGATION_ON_HISTORY_STATE_UPDATED; | |
| 317 event_name = web_navigation::OnHistoryStateUpdated::kEventName; | |
| 318 } else { | 289 } else { |
| 319 if (navigation_state_.GetIsServerRedirected(render_frame_host)) { | 290 helpers::DispatchOnErrorOccurred(navigation_handle); |
| 320 transition_type = ui::PageTransitionFromInt( | |
| 321 transition_type | ui::PAGE_TRANSITION_SERVER_REDIRECT); | |
| 322 } | |
| 323 histogram_value = events::WEB_NAVIGATION_ON_COMMITTED; | |
| 324 event_name = web_navigation::OnCommitted::kEventName; | |
| 325 } | 291 } |
| 326 helpers::DispatchOnCommitted( | |
| 327 histogram_value, event_name, web_contents(), render_frame_host, | |
| 328 navigation_state_.GetUrl(render_frame_host), transition_type); | |
| 329 } | |
| 330 | |
| 331 void WebNavigationTabObserver::DidFailProvisionalLoad( | |
| 332 content::RenderFrameHost* render_frame_host, | |
| 333 const GURL& validated_url, | |
| 334 int error_code, | |
| 335 const base::string16& error_description, | |
| 336 bool was_ignored_by_handler) { | |
| 337 DVLOG(2) << "DidFailProvisionalLoad(" | |
| 338 << "render_frame_host=" << render_frame_host | |
| 339 << ", frame_num=" << render_frame_host->GetRoutingID() | |
| 340 << ", url=" << validated_url << ")"; | |
| 341 if (navigation_state_.CanSendEvents(render_frame_host)) { | |
| 342 helpers::DispatchOnErrorOccurred( | |
| 343 web_contents(), | |
| 344 render_frame_host, | |
| 345 navigation_state_.GetUrl(render_frame_host), | |
| 346 error_code); | |
| 347 } | |
| 348 navigation_state_.SetErrorOccurredInFrame(render_frame_host); | |
| 349 } | 292 } |
| 350 | 293 |
| 351 void WebNavigationTabObserver::DocumentLoadedInFrame( | 294 void WebNavigationTabObserver::DocumentLoadedInFrame( |
| 352 content::RenderFrameHost* render_frame_host) { | 295 content::RenderFrameHost* render_frame_host) { |
| 353 DVLOG(2) << "DocumentLoadedInFrame(" | |
| 354 << "render_frame_host=" << render_frame_host | |
| 355 << ", frame_num=" << render_frame_host->GetRoutingID() << ")"; | |
| 356 if (!navigation_state_.CanSendEvents(render_frame_host)) | 296 if (!navigation_state_.CanSendEvents(render_frame_host)) |
| 357 return; | 297 return; |
| 298 | |
| 358 navigation_state_.SetParsingFinished(render_frame_host); | 299 navigation_state_.SetParsingFinished(render_frame_host); |
| 359 helpers::DispatchOnDOMContentLoaded( | 300 helpers::DispatchOnDOMContentLoaded( |
| 360 web_contents(), | 301 web_contents(), |
| 361 render_frame_host, | 302 render_frame_host, |
| 362 navigation_state_.GetUrl(render_frame_host)); | 303 navigation_state_.GetUrl(render_frame_host)); |
| 363 | 304 |
| 364 if (!navigation_state_.GetNavigationCompleted(render_frame_host)) | 305 if (!navigation_state_.GetNavigationCompleted(render_frame_host)) |
| 365 return; | 306 return; |
| 366 | 307 |
| 367 // The load might already have finished by the time we finished parsing. For | 308 // The load might already have finished by the time we finished parsing. For |
| 368 // compatibility reasons, we artifically delay the load completed signal until | 309 // compatibility reasons, we artifically delay the load completed signal until |
| 369 // after parsing was completed. | 310 // after parsing was completed. |
| 370 helpers::DispatchOnCompleted(web_contents(), | 311 helpers::DispatchOnCompleted(web_contents(), |
| 371 render_frame_host, | 312 render_frame_host, |
| 372 navigation_state_.GetUrl(render_frame_host)); | 313 navigation_state_.GetUrl(render_frame_host)); |
| 373 } | 314 } |
| 374 | 315 |
| 375 void WebNavigationTabObserver::DidFinishLoad( | 316 void WebNavigationTabObserver::DidFinishLoad( |
| 376 content::RenderFrameHost* render_frame_host, | 317 content::RenderFrameHost* render_frame_host, |
| 377 const GURL& validated_url) { | 318 const GURL& validated_url) { |
| 378 DVLOG(2) << "DidFinishLoad(" | |
| 379 << "render_frame_host=" << render_frame_host | |
| 380 << ", frame_num=" << render_frame_host->GetRoutingID() | |
| 381 << ", url=" << validated_url << ")"; | |
| 382 // When showing replacement content, we might get load signals for frames | 319 // When showing replacement content, we might get load signals for frames |
| 383 // that weren't reguarly loaded. | 320 // that weren't reguarly loaded. |
| 384 if (!navigation_state_.IsValidFrame(render_frame_host)) | 321 if (!navigation_state_.IsValidFrame(render_frame_host)) |
| 385 return; | 322 return; |
| 323 | |
| 386 navigation_state_.SetNavigationCompleted(render_frame_host); | 324 navigation_state_.SetNavigationCompleted(render_frame_host); |
| 387 if (!navigation_state_.CanSendEvents(render_frame_host)) | 325 if (!navigation_state_.CanSendEvents(render_frame_host)) |
| 388 return; | 326 return; |
| 389 | 327 |
| 390 // A new navigation might have started before the old one completed. | 328 // A new navigation might have started before the old one completed. |
| 391 // Ignore the old navigation completion in that case. | 329 // Ignore the old navigation completion in that case. |
| 392 // srcdoc iframes will report a url of about:blank, still let it through. | 330 // srcdoc iframes will report a url of about:blank, still let it through. |
| 393 if (navigation_state_.GetUrl(render_frame_host) != validated_url && | 331 if (navigation_state_.GetUrl(render_frame_host) != validated_url && |
| 394 (navigation_state_.GetUrl(render_frame_host) != | 332 (navigation_state_.GetUrl(render_frame_host) != |
| 395 GURL(content::kAboutSrcDocURL) || | 333 GURL(content::kAboutSrcDocURL) || |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 406 render_frame_host, | 344 render_frame_host, |
| 407 navigation_state_.GetUrl(render_frame_host)); | 345 navigation_state_.GetUrl(render_frame_host)); |
| 408 } | 346 } |
| 409 | 347 |
| 410 void WebNavigationTabObserver::DidFailLoad( | 348 void WebNavigationTabObserver::DidFailLoad( |
| 411 content::RenderFrameHost* render_frame_host, | 349 content::RenderFrameHost* render_frame_host, |
| 412 const GURL& validated_url, | 350 const GURL& validated_url, |
| 413 int error_code, | 351 int error_code, |
| 414 const base::string16& error_description, | 352 const base::string16& error_description, |
| 415 bool was_ignored_by_handler) { | 353 bool was_ignored_by_handler) { |
| 416 DVLOG(2) << "DidFailLoad(" | |
| 417 << "render_frame_host=" << render_frame_host | |
| 418 << ", frame_num=" << render_frame_host->GetRoutingID() | |
| 419 << ", url=" << validated_url << ")"; | |
| 420 // When showing replacement content, we might get load signals for frames | 354 // When showing replacement content, we might get load signals for frames |
| 421 // that weren't reguarly loaded. | 355 // that weren't reguarly loaded. |
| 422 if (!navigation_state_.IsValidFrame(render_frame_host)) | 356 if (!navigation_state_.IsValidFrame(render_frame_host)) |
| 423 return; | 357 return; |
| 358 | |
| 424 if (navigation_state_.CanSendEvents(render_frame_host)) { | 359 if (navigation_state_.CanSendEvents(render_frame_host)) { |
| 425 helpers::DispatchOnErrorOccurred( | 360 helpers::DispatchOnErrorOccurred( |
| 426 web_contents(), | 361 web_contents(), |
| 427 render_frame_host, | 362 render_frame_host, |
| 428 navigation_state_.GetUrl(render_frame_host), | 363 navigation_state_.GetUrl(render_frame_host), |
| 429 error_code); | 364 error_code); |
| 430 } | 365 } |
| 431 navigation_state_.SetErrorOccurredInFrame(render_frame_host); | 366 navigation_state_.SetErrorOccurredInFrame(render_frame_host); |
| 432 } | 367 } |
| 433 | 368 |
| 434 void WebNavigationTabObserver::DidGetRedirectForResourceRequest( | |
| 435 content::RenderFrameHost* render_frame_host, | |
| 436 const content::ResourceRedirectDetails& details) { | |
| 437 if (details.resource_type != content::RESOURCE_TYPE_MAIN_FRAME && | |
| 438 details.resource_type != content::RESOURCE_TYPE_SUB_FRAME) { | |
| 439 return; | |
| 440 } | |
| 441 navigation_state_.SetIsServerRedirected(render_frame_host); | |
| 442 } | |
| 443 | |
| 444 void WebNavigationTabObserver::DidOpenRequestedURL( | 369 void WebNavigationTabObserver::DidOpenRequestedURL( |
| 445 content::WebContents* new_contents, | 370 content::WebContents* new_contents, |
| 446 content::RenderFrameHost* source_render_frame_host, | 371 content::RenderFrameHost* source_render_frame_host, |
| 447 const GURL& url, | 372 const GURL& url, |
| 448 const content::Referrer& referrer, | 373 const content::Referrer& referrer, |
| 449 WindowOpenDisposition disposition, | 374 WindowOpenDisposition disposition, |
| 450 ui::PageTransition transition) { | 375 ui::PageTransition transition) { |
| 451 if (!navigation_state_.CanSendEvents(source_render_frame_host)) | 376 if (!navigation_state_.CanSendEvents(source_render_frame_host)) |
| 452 return; | 377 return; |
| 453 | 378 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 466 source_render_frame_host, | 391 source_render_frame_host, |
| 467 new_contents, | 392 new_contents, |
| 468 url); | 393 url); |
| 469 } | 394 } |
| 470 | 395 |
| 471 void WebNavigationTabObserver::WebContentsDestroyed() { | 396 void WebNavigationTabObserver::WebContentsDestroyed() { |
| 472 g_tab_observer.Get().erase(web_contents()); | 397 g_tab_observer.Get().erase(web_contents()); |
| 473 registrar_.RemoveAll(); | 398 registrar_.RemoveAll(); |
| 474 } | 399 } |
| 475 | 400 |
| 401 void WebNavigationTabObserver::HandleCommit( | |
| 402 content::NavigationHandle* navigation_handle) { | |
| 403 bool is_reference_fragment_navigation = IsReferenceFragmentNavigation( | |
| 404 navigation_handle->GetRenderFrameHost(), navigation_handle->GetURL()); | |
| 405 | |
| 406 navigation_state_.StartTrackingDocumentLoad( | |
| 407 navigation_handle->GetRenderFrameHost(), navigation_handle->GetURL(), | |
| 408 navigation_handle->IsSamePage(), | |
| 409 false, // is_error_page | |
| 410 navigation_handle->IsSrcdoc()); | |
| 411 | |
| 412 events::HistogramValue histogram_value = events::UNKNOWN; | |
| 413 std::string event_name; | |
| 414 if (is_reference_fragment_navigation) { | |
| 415 histogram_value = events::WEB_NAVIGATION_ON_REFERENCE_FRAGMENT_UPDATED; | |
| 416 event_name = web_navigation::OnReferenceFragmentUpdated::kEventName; | |
| 417 } else if (navigation_handle->IsSamePage()) { | |
| 418 histogram_value = events::WEB_NAVIGATION_ON_HISTORY_STATE_UPDATED; | |
| 419 event_name = web_navigation::OnHistoryStateUpdated::kEventName; | |
| 420 } else { | |
| 421 histogram_value = events::WEB_NAVIGATION_ON_COMMITTED; | |
| 422 event_name = web_navigation::OnCommitted::kEventName; | |
| 423 } | |
| 424 helpers::DispatchOnCommitted(histogram_value, event_name, navigation_handle); | |
| 425 } | |
| 426 | |
| 427 void WebNavigationTabObserver::HandleError( | |
| 428 content::NavigationHandle* navigation_handle) { | |
| 429 navigation_state_.StartTrackingDocumentLoad( | |
| 430 navigation_handle->GetRenderFrameHost(), navigation_handle->GetURL(), | |
| 431 navigation_handle->IsSamePage(), | |
| 432 true, // is_error_page | |
| 433 navigation_handle->IsSrcdoc()); | |
| 434 | |
| 435 helpers::DispatchOnErrorOccurred(navigation_handle); | |
| 436 } | |
| 437 | |
| 476 // See also NavigationController::IsURLInPageNavigation. | 438 // See also NavigationController::IsURLInPageNavigation. |
| 477 bool WebNavigationTabObserver::IsReferenceFragmentNavigation( | 439 bool WebNavigationTabObserver::IsReferenceFragmentNavigation( |
| 478 content::RenderFrameHost* render_frame_host, | 440 content::RenderFrameHost* render_frame_host, |
| 479 const GURL& url) { | 441 const GURL& url) { |
| 480 GURL existing_url = navigation_state_.GetUrl(render_frame_host); | 442 GURL existing_url = navigation_state_.GetUrl(render_frame_host); |
| 481 if (existing_url == url) | 443 if (existing_url == url) |
| 482 return false; | 444 return false; |
| 483 | 445 |
| 484 url::Replacements<char> replacements; | 446 url::Replacements<char> replacements; |
| 485 replacements.ClearRef(); | 447 replacements.ClearRef(); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 616 return g_factory.Pointer(); | 578 return g_factory.Pointer(); |
| 617 } | 579 } |
| 618 | 580 |
| 619 void WebNavigationAPI::OnListenerAdded(const EventListenerInfo& details) { | 581 void WebNavigationAPI::OnListenerAdded(const EventListenerInfo& details) { |
| 620 web_navigation_event_router_.reset(new WebNavigationEventRouter( | 582 web_navigation_event_router_.reset(new WebNavigationEventRouter( |
| 621 Profile::FromBrowserContext(browser_context_))); | 583 Profile::FromBrowserContext(browser_context_))); |
| 622 EventRouter::Get(browser_context_)->UnregisterObserver(this); | 584 EventRouter::Get(browser_context_)->UnregisterObserver(this); |
| 623 } | 585 } |
| 624 | 586 |
| 625 } // namespace extensions | 587 } // namespace extensions |
| OLD | NEW |