summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstritar@chromium.org <jstritar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-30 17:59:16 +0000
committerjstritar@chromium.org <jstritar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-30 17:59:16 +0000
commitc107d49794a5ccf7c5cc8f8e27604782de57279b (patch)
tree7e5993a8f7371fab5ac6ac61f570658392e68e72
parent11713fd37bfee13bbc698190d939259ecff636f8 (diff)
downloadchromium_src-c107d49794a5ccf7c5cc8f8e27604782de57279b.zip
chromium_src-c107d49794a5ccf7c5cc8f8e27604782de57279b.tar.gz
chromium_src-c107d49794a5ccf7c5cc8f8e27604782de57279b.tar.bz2
Fix callback for chrome.tabs.update with javascript URLs.
UpdateTabFunction is asynchronous when updating a tab with a javascript URL. In this situation, the method was returning early before generating the callback result. This fixes the ExecuteScriptApiTest.NavigationRaceJavaScriptUrl test. BUG=89731 TEST=ExecuteScriptApiTest.NavigationRaceJavaScriptUrl Review URL: http://codereview.chromium.org/9225010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@119690 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/execute_script_apitest.cc13
-rw-r--r--chrome/browser/extensions/extension_javascript_url_apitest.cc6
-rw-r--r--chrome/browser/extensions/extension_tabs_module.cc58
-rw-r--r--chrome/browser/extensions/extension_tabs_module.h11
-rw-r--r--chrome/test/data/extensions/api_test/tabs/javascript_url_permissions/test.js16
5 files changed, 62 insertions, 42 deletions
diff --git a/chrome/browser/extensions/execute_script_apitest.cc b/chrome/browser/extensions/execute_script_apitest.cc
index ee8db03..3a5e92a 100644
--- a/chrome/browser/extensions/execute_script_apitest.cc
+++ b/chrome/browser/extensions/execute_script_apitest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -77,16 +77,7 @@ IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, NavigationRaceExecuteScript) {
"execute_script.html")) << message_;
}
-
-#if defined(OS_LINUX)
-// Fails on Linux. http://crbug.com/89731
-#define MAYBE_NavigationRaceJavaScriptUrl DISABLED_NavigationRaceJavaScriptUrl
-#else
-#define MAYBE_NavigationRaceJavaScriptUrl NavigationRaceJavaScriptUrl
-#endif
-
-IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest,
- MAYBE_NavigationRaceJavaScriptUrl) {
+IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, NavigationRaceJavaScriptURL) {
host_resolver()->AddRule("a.com", "127.0.0.1");
host_resolver()->AddRule("b.com", "127.0.0.1");
ASSERT_TRUE(StartTestServer());
diff --git a/chrome/browser/extensions/extension_javascript_url_apitest.cc b/chrome/browser/extensions/extension_javascript_url_apitest.cc
index d7ea29e..8a845e3 100644
--- a/chrome/browser/extensions/extension_javascript_url_apitest.cc
+++ b/chrome/browser/extensions/extension_javascript_url_apitest.cc
@@ -1,12 +1,12 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
#include "chrome/browser/extensions/extension_apitest.h"
#include "net/base/mock_host_resolver.h"
-// Disabled, http://crbug.com/63589.
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_JavaScriptURLPermissions) {
+// If crashing, mark disabled and update http://crbug.com/63589.
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, JavaScriptURLPermissions) {
host_resolver()->AddRule("a.com", "127.0.0.1");
host_resolver()->AddRule("b.com", "127.0.0.1");
ASSERT_TRUE(StartTestServer());
diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc
index f4eb3ad..f737d37 100644
--- a/chrome/browser/extensions/extension_tabs_module.cc
+++ b/chrome/browser/extensions/extension_tabs_module.cc
@@ -1058,7 +1058,7 @@ bool HighlightTabsFunction::RunImpl() {
return true;
}
-UpdateTabFunction::UpdateTabFunction() {
+UpdateTabFunction::UpdateTabFunction() : web_contents_(NULL) {
}
bool UpdateTabFunction::RunImpl() {
@@ -1094,12 +1094,17 @@ bool UpdateTabFunction::RunImpl() {
NULL, &tab_strip, &contents, &tab_index, &error_)) {
return false;
}
- NavigationController& controller = contents->web_contents()->GetController();
+
+ web_contents_ = contents->web_contents();
+ NavigationController& controller = web_contents_->GetController();
// TODO(rafaelw): handle setting remaining tab properties:
// -title
// -favIconUrl
+ // We wait to fire the callback when executing 'javascript:' URLs in tabs.
+ bool is_async = false;
+
// Navigate the tab to a new location if the url is different.
std::string url_string;
if (update_props->HasKey(keys::kUrlKey)) {
@@ -1123,7 +1128,7 @@ bool UpdateTabFunction::RunImpl() {
// we need to check host permissions before allowing them.
if (url.SchemeIs(chrome::kJavaScriptScheme)) {
if (!GetExtension()->CanExecuteScriptOnPage(
- contents->web_contents()->GetURL(), NULL, &error_)) {
+ web_contents_->GetURL(), NULL, &error_)) {
return false;
}
@@ -1135,16 +1140,15 @@ bool UpdateTabFunction::RunImpl() {
params.all_frames = false;
params.in_main_world = true;
- RenderViewHost* render_view_host =
- contents->web_contents()->GetRenderViewHost();
+ RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
render_view_host->Send(
new ExtensionMsg_ExecuteCode(render_view_host->routing_id(),
params));
- Observe(contents->web_contents());
- AddRef(); // balanced in Observe()
+ Observe(web_contents_);
+ AddRef(); // Balanced in OnExecuteCodeFinished().
- return true;
+ is_async = true;
}
controller.LoadURL(
@@ -1153,7 +1157,7 @@ bool UpdateTabFunction::RunImpl() {
// The URL of a tab contents never actually changes to a JavaScript URL, so
// this check only makes sense in other cases.
if (!url.SchemeIs(chrome::kJavaScriptScheme))
- DCHECK_EQ(url.spec(), contents->web_contents()->GetURL().spec());
+ DCHECK_EQ(url.spec(), web_contents_->GetURL().spec());
}
bool active = false;
@@ -1173,7 +1177,7 @@ bool UpdateTabFunction::RunImpl() {
tab_strip->ActivateTabAt(tab_index, false);
DCHECK_EQ(contents, tab_strip->GetActiveTabContents());
}
- contents->web_contents()->Focus();
+ web_contents_->Focus();
}
if (update_props->HasKey(keys::kHighlightedKey)) {
@@ -1209,20 +1213,30 @@ bool UpdateTabFunction::RunImpl() {
tab_index, &opener_contents->web_contents()->GetController());
}
- if (has_callback()) {
- if (GetExtension()->HasAPIPermission(ExtensionAPIPermission::kTab)) {
- result_.reset(ExtensionTabUtil::CreateTabValue(contents->web_contents(),
- tab_strip,
- tab_index));
- } else {
- result_.reset(Value::CreateNullValue());
- }
+ if (!is_async) {
+ PopulateResult();
+ SendResponse(true);
}
-
- SendResponse(true);
return true;
}
+void UpdateTabFunction::PopulateResult() {
+ if (!has_callback())
+ return;
+
+ if (GetExtension()->HasAPIPermission(ExtensionAPIPermission::kTab) &&
+ web_contents_ != NULL) {
+ result_.reset(ExtensionTabUtil::CreateTabValue(web_contents_));
+ } else {
+ result_.reset(Value::CreateNullValue());
+ }
+}
+
+void UpdateTabFunction::WebContentsDestroyed(WebContents* tab) {
+ CHECK_EQ(tab, web_contents_);
+ web_contents_ = NULL;
+}
+
bool UpdateTabFunction::OnMessageReceived(const IPC::Message& message) {
if (message.type() != ExtensionHostMsg_ExecuteCodeFinished::ID)
return false;
@@ -1252,10 +1266,12 @@ void UpdateTabFunction::OnExecuteCodeFinished(int request_id,
error_ = error;
}
+ if (success)
+ PopulateResult();
SendResponse(success);
Observe(NULL);
- Release(); // balanced in Execute()
+ Release(); // Balanced in RunImpl().
}
bool MoveTabsFunction::RunImpl() {
diff --git a/chrome/browser/extensions/extension_tabs_module.h b/chrome/browser/extensions/extension_tabs_module.h
index 944de1c..61f2c39 100644
--- a/chrome/browser/extensions/extension_tabs_module.h
+++ b/chrome/browser/extensions/extension_tabs_module.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -18,11 +18,12 @@
class BackingStore;
class SkBitmap;
-
namespace base {
class DictionaryValue;
} // namespace base
-
+namespace content {
+class WebContents;
+} // namespace content
// Windows
class GetWindowFunction : public SyncExtensionFunction {
virtual ~GetWindowFunction() {}
@@ -112,10 +113,14 @@ class UpdateTabFunction : public AsyncExtensionFunction,
private:
virtual ~UpdateTabFunction() {}
virtual bool RunImpl() OVERRIDE;
+ virtual void WebContentsDestroyed(content::WebContents* tab) OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
void OnExecuteCodeFinished(int request_id,
bool success,
const std::string& error);
+ void PopulateResult();
+
+ content::WebContents* web_contents_;
DECLARE_EXTENSION_FUNCTION_NAME("tabs.update")
};
class MoveTabsFunction : public SyncExtensionFunction {
diff --git a/chrome/test/data/extensions/api_test/tabs/javascript_url_permissions/test.js b/chrome/test/data/extensions/api_test/tabs/javascript_url_permissions/test.js
index d35d1b1..104dc2b 100644
--- a/chrome/test/data/extensions/api_test/tabs/javascript_url_permissions/test.js
+++ b/chrome/test/data/extensions/api_test/tabs/javascript_url_permissions/test.js
@@ -1,9 +1,12 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
+var assertEq = chrome.test.assertEq;
+var pass = chrome.test.callbackPass;
+
chrome.test.getConfig(function(config) {
- var javaScriptURL = "javascript:void(document.body.bgColor='red')";
+ var javaScriptURL = "javascript:void(document.title='js-url-success')";
var fixPort = function(url) {
return url.replace(/PORT/, config.testServer.port);
@@ -26,8 +29,13 @@ chrome.test.getConfig(function(config) {
},
function javaScriptURLShouldSucceed() {
- chrome.tabs.update(secondTabId, {url: javaScriptURL},
- chrome.test.callbackPass());
+ chrome.tabs.update(
+ secondTabId,
+ {url: javaScriptURL},
+ pass(function(tab) {
+ assertEq(secondTabId, tab.id);
+ assertEq('js-url-success', tab.title);
+ }));
}
]);
});