summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-06 19:25:58 +0000
committerjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-06 19:25:58 +0000
commitae5184d682c302981920f45b580b5a306fc957f9 (patch)
tree5374e7d63121d44649ab87f3a1c4571bb0ed33ba
parent7bc551f6363486b7ea6f004d1404304f7f69a7e0 (diff)
downloadchromium_src-ae5184d682c302981920f45b580b5a306fc957f9.zip
chromium_src-ae5184d682c302981920f45b580b5a306fc957f9.tar.gz
chromium_src-ae5184d682c302981920f45b580b5a306fc957f9.tar.bz2
Hook into another code path that lets the renderer request a new tab to be created
BUG=96877 TEST=browser_tests:ExtensionApiTest.WebNavigationRequestOpenTab Review URL: http://codereview.chromium.org/8055011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@104346 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/extension_webnavigation_api.cc29
-rw-r--r--chrome/browser/extensions/extension_webnavigation_api.h6
-rw-r--r--chrome/browser/extensions/extension_webnavigation_apitest.cc34
-rw-r--r--chrome/test/data/extensions/api_test/webnavigation/requestOpenTab/a.html11
-rw-r--r--chrome/test/data/extensions/api_test/webnavigation/requestOpenTab/b.html1
-rw-r--r--chrome/test/data/extensions/api_test/webnavigation/test_requestOpenTab.html5
-rw-r--r--chrome/test/data/extensions/api_test/webnavigation/test_requestOpenTab.js84
-rw-r--r--content/browser/renderer_host/render_view_host.cc6
-rw-r--r--content/browser/renderer_host/render_view_host.h6
-rw-r--r--content/browser/renderer_host/render_view_host_delegate.h3
-rw-r--r--content/browser/tab_contents/tab_contents.cc23
-rw-r--r--content/browser/tab_contents/tab_contents.h6
-rw-r--r--content/browser/tab_contents/tab_contents_observer.cc8
-rw-r--r--content/browser/tab_contents/tab_contents_observer.h7
-rw-r--r--content/common/view_messages.h5
-rw-r--r--content/renderer/render_view.cc20
-rw-r--r--content/renderer/render_view.h4
17 files changed, 236 insertions, 22 deletions
diff --git a/chrome/browser/extensions/extension_webnavigation_api.cc b/chrome/browser/extensions/extension_webnavigation_api.cc
index 66643ee..b675871 100644
--- a/chrome/browser/extensions/extension_webnavigation_api.cc
+++ b/chrome/browser/extensions/extension_webnavigation_api.cc
@@ -576,6 +576,35 @@ void ExtensionWebNavigationTabObserver::DidFinishLoad(
frame_id);
}
+void ExtensionWebNavigationTabObserver::DidOpenRequestedURL(
+ TabContents* new_contents,
+ const GURL& url,
+ const GURL& referrer,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ int64 source_frame_id) {
+ if (!navigation_state_.CanSendEvents(source_frame_id))
+ return;
+
+ // We only send the onCreatedNavigationTarget if we end up creating a new
+ // window.
+ if (disposition != SINGLETON_TAB &&
+ disposition != NEW_FOREGROUND_TAB &&
+ disposition != NEW_BACKGROUND_TAB &&
+ disposition != NEW_POPUP &&
+ disposition != NEW_WINDOW &&
+ disposition != OFF_THE_RECORD)
+ return;
+
+ DispatchOnCreatedNavigationTarget(
+ tab_contents(),
+ new_contents->browser_context(),
+ source_frame_id,
+ navigation_state_.IsMainFrame(source_frame_id),
+ new_contents,
+ url);
+}
+
void ExtensionWebNavigationTabObserver::TabContentsDestroyed(
TabContents* tab) {
g_tab_observer.Get().erase(tab);
diff --git a/chrome/browser/extensions/extension_webnavigation_api.h b/chrome/browser/extensions/extension_webnavigation_api.h
index 92d0985..932734f 100644
--- a/chrome/browser/extensions/extension_webnavigation_api.h
+++ b/chrome/browser/extensions/extension_webnavigation_api.h
@@ -148,6 +148,12 @@ class ExtensionWebNavigationTabObserver : public TabContentsObserver {
int error_code) OVERRIDE;
virtual void DocumentLoadedInFrame(int64 frame_id) OVERRIDE;
virtual void DidFinishLoad(int64 frame_id) OVERRIDE;
+ virtual void DidOpenRequestedURL(TabContents* new_contents,
+ const GURL& url,
+ const GURL& referrer,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ int64 source_frame_id) OVERRIDE;
virtual void TabContentsDestroyed(TabContents* tab) OVERRIDE;
private:
diff --git a/chrome/browser/extensions/extension_webnavigation_apitest.cc b/chrome/browser/extensions/extension_webnavigation_apitest.cc
index 1996e28..22fb035 100644
--- a/chrome/browser/extensions/extension_webnavigation_apitest.cc
+++ b/chrome/browser/extensions/extension_webnavigation_apitest.cc
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/command_line.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h"
@@ -12,9 +11,11 @@
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
+#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "net/base/mock_host_resolver.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
#include "webkit/glue/context_menu.h"
namespace {
@@ -147,3 +148,34 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, WebNavigationUserAction) {
ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
}
+
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, WebNavigationRequestOpenTab) {
+ FrameNavigationState::set_allow_extension_scheme(true);
+
+ // Wait for the extension to set itself up and return control to us.
+ ASSERT_TRUE(RunExtensionSubtest("webnavigation", "test_requestOpenTab.html"))
+ << message_;
+
+ ResultCatcher catcher;
+
+ ExtensionService* service = browser()->profile()->GetExtensionService();
+ const Extension* extension =
+ service->GetExtensionById(last_loaded_extension_id_, false);
+ GURL url = extension->GetResourceURL("requestOpenTab/a.html");
+
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // There's a link on a.html. Middle-click on it to open it in a new tab.
+ WebKit::WebMouseEvent mouse_event;
+ mouse_event.type = WebKit::WebInputEvent::MouseDown;
+ mouse_event.button = WebKit::WebMouseEvent::ButtonMiddle;
+ mouse_event.x = 7;
+ mouse_event.y = 7;
+ mouse_event.clickCount = 1;
+ TabContents* tab = browser()->GetSelectedTabContents();
+ tab->render_view_host()->ForwardMouseEvent(mouse_event);
+ mouse_event.type = WebKit::WebInputEvent::MouseUp;
+ tab->render_view_host()->ForwardMouseEvent(mouse_event);
+
+ ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
+}
diff --git a/chrome/test/data/extensions/api_test/webnavigation/requestOpenTab/a.html b/chrome/test/data/extensions/api_test/webnavigation/requestOpenTab/a.html
new file mode 100644
index 0000000..6473d89
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/webnavigation/requestOpenTab/a.html
@@ -0,0 +1,11 @@
+<html><head>
+<style type="text/css">
+body {
+ margin: 0;
+}
+</style>
+</head>
+<body>
+<a href="b.html">link</a>
+</body>
+</html>
diff --git a/chrome/test/data/extensions/api_test/webnavigation/requestOpenTab/b.html b/chrome/test/data/extensions/api_test/webnavigation/requestOpenTab/b.html
new file mode 100644
index 0000000..18ecdcb
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/webnavigation/requestOpenTab/b.html
@@ -0,0 +1 @@
+<html></html>
diff --git a/chrome/test/data/extensions/api_test/webnavigation/test_requestOpenTab.html b/chrome/test/data/extensions/api_test/webnavigation/test_requestOpenTab.html
new file mode 100644
index 0000000..fadbdba
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/webnavigation/test_requestOpenTab.html
@@ -0,0 +1,5 @@
+<script src="test_requestOpenTab.js"></script>
+<script src="framework.js"></script>
+<script>
+ runTests();
+</script>
diff --git a/chrome/test/data/extensions/api_test/webnavigation/test_requestOpenTab.js b/chrome/test/data/extensions/api_test/webnavigation/test_requestOpenTab.js
new file mode 100644
index 0000000..4301571
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/webnavigation/test_requestOpenTab.js
@@ -0,0 +1,84 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function runTests() {
+ var getURL = chrome.extension.getURL;
+ chrome.tabs.create({"url": "about:blank"}, function(tab) {
+ var tabId = tab.id;
+
+ chrome.test.runTests([
+ // Opens a tab and waits for the user to middle-click on a link in it.
+ function requestOpenTab() {
+ expect([
+ { label: "a-onBeforeNavigate",
+ event: "onBeforeNavigate",
+ details: { frameId: 0,
+ tabId: 0,
+ timeStamp: 0,
+ url: getURL('requestOpenTab/a.html') }},
+ { label: "a-onCommitted",
+ event: "onCommitted",
+ details: { frameId: 0,
+ tabId: 0,
+ timeStamp: 0,
+ transitionQualifiers: [],
+ transitionType: "typed",
+ url: getURL('requestOpenTab/a.html') }},
+ { label: "a-onDOMContentLoaded",
+ event: "onDOMContentLoaded",
+ details: { frameId: 0,
+ tabId: 0,
+ timeStamp: 0,
+ url: getURL('requestOpenTab/a.html') }},
+ { label: "a-onCompleted",
+ event: "onCompleted",
+ details: { frameId: 0,
+ tabId: 0,
+ timeStamp: 0,
+ url: getURL('requestOpenTab/a.html') }},
+ { label: "b-onCreatedNavigationTarget",
+ event: "onCreatedNavigationTarget",
+ details: { sourceFrameId: 0,
+ sourceTabId: 0,
+ tabId: 1,
+ timeStamp: 0,
+ url: getURL('requestOpenTab/b.html') }},
+ { label: "b-onBeforeNavigate",
+ event: "onBeforeNavigate",
+ details: { frameId: 0,
+ tabId: 1,
+ timeStamp: 0,
+ url: getURL('requestOpenTab/b.html') }},
+ { label: "b-onCommitted",
+ event: "onCommitted",
+ details: { frameId: 0,
+ tabId: 1,
+ timeStamp: 0,
+ transitionQualifiers: [],
+ transitionType: "link",
+ url: getURL('requestOpenTab/b.html') }},
+ { label: "b-onDOMContentLoaded",
+ event: "onDOMContentLoaded",
+ details: { frameId: 0,
+ tabId: 1,
+ timeStamp: 0,
+ url: getURL('requestOpenTab/b.html') }},
+ { label: "b-onCompleted",
+ event: "onCompleted",
+ details: { frameId: 0,
+ tabId: 1,
+ timeStamp: 0,
+ url: getURL('requestOpenTab/b.html') }}],
+ [ navigationOrder("a-"),
+ navigationOrder("b-"),
+ [ "a-onDOMContentLoaded",
+ "b-onCreatedNavigationTarget",
+ "b-onBeforeNavigate" ]]);
+
+ // Notify the api test that we're waiting for the user.
+ chrome.test.notifyPass();
+ },
+ ]);
+ });
+}
diff --git a/content/browser/renderer_host/render_view_host.cc b/content/browser/renderer_host/render_view_host.cc
index c797151..f2b1a76 100644
--- a/content/browser/renderer_host/render_view_host.cc
+++ b/content/browser/renderer_host/render_view_host.cc
@@ -951,12 +951,14 @@ void RenderViewHost::OnMsgToggleFullscreen(bool enter_fullscreen) {
void RenderViewHost::OnMsgOpenURL(const GURL& url,
const GURL& referrer,
- WindowOpenDisposition disposition) {
+ WindowOpenDisposition disposition,
+ int64 source_frame_id) {
GURL validated_url(url);
FilterURL(ChildProcessSecurityPolicy::GetInstance(),
process()->id(), &validated_url);
- delegate_->RequestOpenURL(validated_url, referrer, disposition);
+ delegate_->RequestOpenURL(
+ validated_url, referrer, disposition, source_frame_id);
}
void RenderViewHost::OnMsgDidContentsPreferredSizeChange(
diff --git a/content/browser/renderer_host/render_view_host.h b/content/browser/renderer_host/render_view_host.h
index ef541c8..d29b8e4 100644
--- a/content/browser/renderer_host/render_view_host.h
+++ b/content/browser/renderer_host/render_view_host.h
@@ -490,8 +490,10 @@ class CONTENT_EXPORT RenderViewHost : public RenderWidgetHost {
void OnMsgDocumentOnLoadCompletedInMainFrame(int32 page_id);
void OnMsgContextMenu(const ContextMenuParams& params);
void OnMsgToggleFullscreen(bool enter_fullscreen);
- void OnMsgOpenURL(const GURL& url, const GURL& referrer,
- WindowOpenDisposition disposition);
+ void OnMsgOpenURL(const GURL& url,
+ const GURL& referrer,
+ WindowOpenDisposition disposition,
+ int64 source_frame_id);
void OnMsgDidContentsPreferredSizeChange(const gfx::Size& new_size);
void OnMsgDidChangeScrollbarsForMainFrame(bool has_horizontal_scrollbar,
bool has_vertical_scrollbar);
diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h
index 65bb4ac..c86dc34 100644
--- a/content/browser/renderer_host/render_view_host_delegate.h
+++ b/content/browser/renderer_host/render_view_host_delegate.h
@@ -283,7 +283,8 @@ class CONTENT_EXPORT RenderViewHostDelegate : public IPC::Channel::Listener {
// The page wants to open a URL with the specified disposition.
virtual void RequestOpenURL(const GURL& url,
const GURL& referrer,
- WindowOpenDisposition disposition) {}
+ WindowOpenDisposition disposition,
+ int64 source_frame_id) {}
// A javascript message, confirmation or prompt should be shown.
virtual void RunJavaScriptMessage(const RenderViewHost* rvh,
diff --git a/content/browser/tab_contents/tab_contents.cc b/content/browser/tab_contents/tab_contents.cc
index 2d3cf8d..5d809cc 100644
--- a/content/browser/tab_contents/tab_contents.cc
+++ b/content/browser/tab_contents/tab_contents.cc
@@ -1675,8 +1675,12 @@ void TabContents::DocumentOnLoadCompletedInMainFrame(
Details<int>(&page_id));
}
-void TabContents::RequestOpenURL(const GURL& url, const GURL& referrer,
- WindowOpenDisposition disposition) {
+void TabContents::RequestOpenURL(const GURL& url,
+ const GURL& referrer,
+ WindowOpenDisposition disposition,
+ int64 source_frame_id) {
+ TabContents* new_contents = NULL;
+ PageTransition::Type transition_type = PageTransition::LINK;
if (render_manager_.web_ui()) {
// When we're a Web UI, it will provide a page transition type for us (this
// is so the new tab page can specify AUTO_BOOKMARK for automatically
@@ -1686,10 +1690,21 @@ void TabContents::RequestOpenURL(const GURL& url, const GURL& referrer,
// want web sites to see a referrer of "chrome://blah" (and some
// chrome: URLs might have search terms or other stuff we don't want to
// send to the site), so we send no referrer.
- OpenURL(url, GURL(), disposition,
+ new_contents = OpenURL(url, GURL(), disposition,
render_manager_.web_ui()->link_transition_type());
+ transition_type = render_manager_.web_ui()->link_transition_type();
} else {
- OpenURL(url, referrer, disposition, PageTransition::LINK);
+ new_contents = OpenURL(url, referrer, disposition, PageTransition::LINK);
+ }
+ if (new_contents) {
+ // Notify observers.
+ FOR_EACH_OBSERVER(TabContentsObserver, observers_,
+ DidOpenRequestedURL(new_contents,
+ url,
+ referrer,
+ disposition,
+ transition_type,
+ source_frame_id));
}
}
diff --git a/content/browser/tab_contents/tab_contents.h b/content/browser/tab_contents/tab_contents.h
index acdefbc..8262c95 100644
--- a/content/browser/tab_contents/tab_contents.h
+++ b/content/browser/tab_contents/tab_contents.h
@@ -655,8 +655,10 @@ class CONTENT_EXPORT TabContents : public PageNavigator,
virtual void DocumentOnLoadCompletedInMainFrame(
RenderViewHost* render_view_host,
int32 page_id) OVERRIDE;
- virtual void RequestOpenURL(const GURL& url, const GURL& referrer,
- WindowOpenDisposition disposition) OVERRIDE;
+ virtual void RequestOpenURL(const GURL& url,
+ const GURL& referrer,
+ WindowOpenDisposition disposition,
+ int64 source_frame_id) OVERRIDE;
virtual void RunJavaScriptMessage(const RenderViewHost* rvh,
const string16& message,
const string16& default_prompt,
diff --git a/content/browser/tab_contents/tab_contents_observer.cc b/content/browser/tab_contents/tab_contents_observer.cc
index f3b5af5..fa5ff3c 100644
--- a/content/browser/tab_contents/tab_contents_observer.cc
+++ b/content/browser/tab_contents/tab_contents_observer.cc
@@ -85,6 +85,14 @@ void TabContentsObserver::DidOpenURL(const GURL& url,
PageTransition::Type transition) {
}
+void TabContentsObserver::DidOpenRequestedURL(TabContents* new_contents,
+ const GURL& url,
+ const GURL& referrer,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ int64 source_frame_id) {
+}
+
void TabContentsObserver::AppCacheAccessed(const GURL& manifest_url,
bool blocked_by_policy) {
}
diff --git a/content/browser/tab_contents/tab_contents_observer.h b/content/browser/tab_contents/tab_contents_observer.h
index 3d922c1..fdc157d 100644
--- a/content/browser/tab_contents/tab_contents_observer.h
+++ b/content/browser/tab_contents/tab_contents_observer.h
@@ -64,6 +64,13 @@ class CONTENT_EXPORT TabContentsObserver : public IPC::Channel::Listener,
WindowOpenDisposition disposition,
PageTransition::Type transition);
+ virtual void DidOpenRequestedURL(TabContents* new_contents,
+ const GURL& url,
+ const GURL& referrer,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ int64 source_frame_id);
+
virtual void AppCacheAccessed(const GURL& manifest_url,
bool blocked_by_policy);
#if 0
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index e418265..3d439b7c 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -1556,10 +1556,11 @@ IPC_SYNC_MESSAGE_ROUTED4_2(ViewHostMsg_RunJavaScriptMessage,
string16 /* out - user_input field */)
// Requests that the given URL be opened in the specified manner.
-IPC_MESSAGE_ROUTED3(ViewHostMsg_OpenURL,
+IPC_MESSAGE_ROUTED4(ViewHostMsg_OpenURL,
GURL /* url */,
GURL /* referrer */,
- WindowOpenDisposition /* disposition */)
+ WindowOpenDisposition /* disposition */,
+ int64 /* frame id */)
// Notifies that the preferred size of the content changed.
IPC_MESSAGE_ROUTED1(ViewHostMsg_DidContentsPreferredSizeChange,
diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc
index 34551fa..c79c567 100644
--- a/content/renderer/render_view.cc
+++ b/content/renderer/render_view.cc
@@ -1252,10 +1252,16 @@ void RenderView::UpdateSessionHistory(WebFrame* frame) {
routing_id_, page_id_, webkit_glue::HistoryItemToString(item)));
}
-void RenderView::OpenURL(
- const GURL& url, const GURL& referrer, WebNavigationPolicy policy) {
+void RenderView::OpenURL(WebFrame* frame,
+ const GURL& url,
+ const GURL& referrer,
+ WebNavigationPolicy policy) {
Send(new ViewHostMsg_OpenURL(
- routing_id_, url, referrer, NavigationPolicyToDisposition(policy)));
+ routing_id_,
+ url,
+ referrer,
+ NavigationPolicyToDisposition(policy),
+ frame->identifier()));
}
// WebViewDelegate ------------------------------------------------------------
@@ -1972,7 +1978,7 @@ void RenderView::loadURLExternally(
Send(new ViewHostMsg_DownloadUrl(routing_id_, request.url(), referrer,
suggested_name));
} else {
- OpenURL(request.url(), referrer, policy);
+ OpenURL(frame, request.url(), referrer, policy);
}
}
@@ -2006,7 +2012,7 @@ WebNavigationPolicy RenderView::decidePolicyForNavigation(
// navigation.
page_id_ = -1;
last_page_id_sent_to_browser_ = -1;
- OpenURL(url, referrer, default_policy);
+ OpenURL(frame, url, referrer, default_policy);
return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
}
@@ -2050,7 +2056,7 @@ WebNavigationPolicy RenderView::decidePolicyForNavigation(
if (should_fork) {
GURL referrer(request.httpHeaderField(WebString::fromUTF8("Referer")));
- OpenURL(url, send_referrer ? referrer : GURL(), default_policy);
+ OpenURL(frame, url, send_referrer ? referrer : GURL(), default_policy);
return WebKit::WebNavigationPolicyIgnore; // Suppress the load here.
}
}
@@ -2120,7 +2126,7 @@ WebNavigationPolicy RenderView::decidePolicyForNavigation(
if (is_fork || is_noreferrer_and_blank_target) {
// Open the URL via the browser, not via WebKit.
- OpenURL(url, GURL(), default_policy);
+ OpenURL(frame, url, GURL(), default_policy);
return WebKit::WebNavigationPolicyIgnore;
}
diff --git a/content/renderer/render_view.h b/content/renderer/render_view.h
index 536f0ff..2c16ac6 100644
--- a/content/renderer/render_view.h
+++ b/content/renderer/render_view.h
@@ -731,7 +731,9 @@ class RenderView : public RenderWidget,
void UpdateEncoding(WebKit::WebFrame* frame,
const std::string& encoding_name);
- void OpenURL(const GURL& url, const GURL& referrer,
+ void OpenURL(WebKit::WebFrame* frame,
+ const GURL& url,
+ const GURL& referrer,
WebKit::WebNavigationPolicy policy);
bool RunJavaScriptMessage(int type,