Chromium Code Reviews| Index: chrome/renderer/chrome_content_renderer_client.cc |
| diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc |
| index ef9c3fc04d9a306ee5b4af59a4784042814afd79..40bd1b9794335a7061ba89d1b3cf73825bc89433 100644 |
| --- a/chrome/renderer/chrome_content_renderer_client.cc |
| +++ b/chrome/renderer/chrome_content_renderer_client.cc |
| @@ -17,10 +17,12 @@ |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/content_settings_pattern.h" |
| +#include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h" |
| #include "chrome/common/extensions/chrome_extensions_client.h" |
| #include "chrome/common/extensions/extension.h" |
| #include "chrome/common/extensions/extension_constants.h" |
| #include "chrome/common/extensions/extension_manifest_constants.h" |
| +#include "chrome/common/extensions/extension_messages.h" |
| #include "chrome/common/extensions/extension_process_policy.h" |
| #include "chrome/common/extensions/extension_set.h" |
| #include "chrome/common/external_ipc_fuzzer.h" |
| @@ -72,6 +74,7 @@ |
| #include "content/public/renderer/render_view_visitor.h" |
| #include "extensions/common/constants.h" |
| #include "extensions/common/extension_urls.h" |
| +#include "extensions/common/switches.h" |
| #include "grit/generated_resources.h" |
| #include "grit/locale_settings.h" |
| #include "grit/renderer_resources.h" |
| @@ -92,6 +95,7 @@ |
| #include "third_party/WebKit/public/platform/WebURL.h" |
| #include "third_party/WebKit/public/platform/WebURLError.h" |
| #include "third_party/WebKit/public/platform/WebURLRequest.h" |
| +#include "third_party/WebKit/public/web/WebUserGestureIndicator.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/layout.h" |
| #include "ui/base/resource/resource_bundle.h" |
| @@ -924,6 +928,66 @@ bool ChromeContentRendererClient::AllowPopup() { |
| extensions::Feature::CONTENT_SCRIPT_CONTEXT); |
| } |
| +// For top-level navigations, tries to find a platform app that has registered |
| +// a URL handler matching the URL. If found, delegates further URL processing |
| +// to the browser (the browser is supposed to launch the app), and returns true |
| +// to cancel navigation on the renderer side. Otherwise, returns false. |
| +bool ChromeContentRendererClient::HandleNavigation( |
| + WebKit::WebFrame* frame, |
| + const WebKit::WebURLRequest& request, |
| + WebKit::WebNavigationType type, |
| + WebKit::WebNavigationPolicy default_policy, |
| + bool is_redirect) { |
| + // TODO(sergeygs): Remove this and update includes once url_handlers are |
| + // moved out of experimental. |
| + if (!CommandLine::ForCurrentProcess()->HasSwitch( |
| + extensions::switches::kEnableExperimentalExtensionApis)) |
|
not at google - send to devlin
2013/09/03 18:28:04
this seems unnecessary. Firstly you're gating this
sergeygs
2013/09/04 03:29:17
This switch was only temporary (for debugging). Re
|
| + return false; |
| + |
| + // Limit redirection to top-level frames only. |
| + if (frame != frame->top()) |
| + return false; |
| + |
| + // Exclude reloads (shouldn't happen anyway) and back/forward. |
| + bool navigation_type_ok = |
| + WebKit::WebUserGestureIndicator::isProcessingUserGesture() || |
| + (type == WebKit::WebNavigationTypeLinkClicked) || |
| + (((type == WebKit::WebNavigationTypeFormSubmitted) || |
| + (type == WebKit::WebNavigationTypeFormResubmitted) || |
| + (type == WebKit::WebNavigationTypeOther) |
| + ) && frame->opener() |
| + ); |
| + |
| + if (!navigation_type_ok) |
| + return false; |
| + |
| + // Get the top-level RenderView (tab or extension window) so that we can send |
| + // a routed IPC message to the correct observer. |
| + content::RenderView* render_view = frame->opener() ? |
| + content::RenderView::FromWebView(frame->opener()->view()) : |
| + content::RenderView::FromWebView(frame->view()); |
| + if (!render_view) |
| + return false; |
| + |
| + // Find out if there is an extension that can handle the URL, and if there is, |
| + // send an IPC to the render view to launch it. |
| + const GURL url(request.url()); |
| + const ExtensionSet* exts = extension_dispatcher_->extensions(); |
| + for (ExtensionSet::const_iterator iter = exts->begin(); |
| + iter != exts->end(); |
| + ++iter) { |
| + if (extensions::UrlHandlers::CanExtensionHandleUrl(*iter, url)) { |
| + const GURL referrer_url( |
| + request.httpHeaderField(WebString::fromUTF8("Referer"))); |
| + return RenderThread::Get()->Send( |
| + new ExtensionHostMsg_RedirectUrl( |
| + render_view->GetRoutingID(), url, referrer_url)); |
| + } |
| + } |
| + |
| + return false; |
| +} |
| + |
| bool ChromeContentRendererClient::ShouldFork(WebFrame* frame, |
| const GURL& url, |
| const std::string& http_method, |