| 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))
|
| + 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,
|
|
|