summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/debugger/debugger_remote_service.cc6
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc27
-rw-r--r--chrome/browser/renderer_host/render_view_host.h6
-rw-r--r--chrome/browser/renderer_host/test/render_view_host_browsertest.cc93
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/common/notification_type.h8
-rw-r--r--chrome/common/render_messages_internal.h20
-rw-r--r--chrome/renderer/render_view.cc29
-rw-r--r--chrome/renderer/render_view.h12
9 files changed, 179 insertions, 23 deletions
diff --git a/chrome/browser/debugger/debugger_remote_service.cc b/chrome/browser/debugger/debugger_remote_service.cc
index 4c3341b..3d102d5 100644
--- a/chrome/browser/debugger/debugger_remote_service.cc
+++ b/chrome/browser/debugger/debugger_remote_service.cc
@@ -331,9 +331,7 @@ bool DebuggerRemoteService::DispatchEvaluateJavascript(
}
std::string javascript;
content->GetString(kDataKey, &javascript);
- render_view_host->Send(
- new ViewMsg_ScriptEvalRequest(render_view_host->routing_id(),
- L"",
- UTF8ToWide(javascript)));
+ render_view_host->ExecuteJavascriptInWebFrame(std::wstring(),
+ UTF8ToWide(javascript));
return false;
}
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index de32b0c..a702b08 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -14,6 +14,7 @@
#include "base/stats_counters.h"
#include "base/string_util.h"
#include "base/time.h"
+#include "base/values.h"
#include "chrome/browser/blocked_plugin_manager.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/child_process_security_policy.h"
@@ -490,8 +491,20 @@ void RenderViewHost::ReservePageIDRange(int size) {
}
void RenderViewHost::ExecuteJavascriptInWebFrame(
- const std::wstring& frame_xpath, const std::wstring& jscript) {
- Send(new ViewMsg_ScriptEvalRequest(routing_id(), frame_xpath, jscript));
+ const std::wstring& frame_xpath,
+ const std::wstring& jscript) {
+ Send(new ViewMsg_ScriptEvalRequest(routing_id(), WideToUTF16(frame_xpath),
+ WideToUTF16(jscript),
+ 0, false));
+}
+
+int RenderViewHost::ExecuteJavascriptInWebFrameNotifyResult(
+ const string16& frame_xpath,
+ const string16& jscript) {
+ static int next_id = 1;
+ Send(new ViewMsg_ScriptEvalRequest(routing_id(), frame_xpath, jscript,
+ next_id, true));
+ return next_id++;
}
void RenderViewHost::InsertCSSInWebFrame(
@@ -871,6 +884,7 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_SetSuggestResult, OnSetSuggestResult)
IPC_MESSAGE_HANDLER(ViewHostMsg_DetectedPhishingSite,
OnDetectedPhishingSite)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_ScriptEvalResponse, OnScriptEvalResponse)
// Have the super handle all other messages.
IPC_MESSAGE_UNHANDLED(RenderWidgetHost::OnMessageReceived(msg))
IPC_END_MESSAGE_MAP_EX()
@@ -2102,3 +2116,12 @@ void RenderViewHost::OnDetectedPhishingSite(const GURL& phishing_url,
// TODO(noelutz): send an HTTP request to the client-side detection frontends
// to confirm that the URL is really phishing.
}
+
+void RenderViewHost::OnScriptEvalResponse(int id, bool result) {
+ scoped_ptr<Value> result_value(Value::CreateBooleanValue(result));
+ std::pair<int, Value*> details(id, result_value.get());
+ NotificationService::current()->Notify(
+ NotificationType::EXECUTE_JAVASCRIPT_RESULT,
+ Source<RenderViewHost>(this),
+ Details<std::pair<int, Value*> >(&details));
+}
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index e5f09ff..b9bf703 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -252,6 +252,11 @@ class RenderViewHost : public RenderWidgetHost {
void ExecuteJavascriptInWebFrame(const std::wstring& frame_xpath,
const std::wstring& jscript);
+ // Runs some javascript within the context of a frame in the page. The result
+ // is sent back via the notification EXECUTE_JAVASCRIPT_RESULT.
+ int ExecuteJavascriptInWebFrameNotifyResult(const string16& frame_xpath,
+ const string16& jscript);
+
// Insert some css into a frame in the page. |id| is optional, and specifies
// the element id given when inserting/replacing the style element.
void InsertCSSInWebFrame(const std::wstring& frame_xpath,
@@ -688,6 +693,7 @@ class RenderViewHost : public RenderWidgetHost {
void OnDetectedPhishingSite(const GURL& phishing_url,
double phishing_score,
const SkBitmap& thumbnail);
+ void OnScriptEvalResponse(int id, bool result);
private:
friend class TestRenderViewHost;
diff --git a/chrome/browser/renderer_host/test/render_view_host_browsertest.cc b/chrome/browser/renderer_host/test/render_view_host_browsertest.cc
new file mode 100644
index 0000000..b75c09b
--- /dev/null
+++ b/chrome/browser/renderer_host/test/render_view_host_browsertest.cc
@@ -0,0 +1,93 @@
+// Copyright (c) 2010 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 "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/test/in_process_browser_test.h"
+#include "chrome/test/ui_test_utils.h"
+#include "net/test/test_server.h"
+
+typedef InProcessBrowserTest RenderViewHostTest;
+
+typedef std::pair<int, Value*> ExecuteDetailType;
+
+namespace {
+
+// NotificationObserver used to listen for EXECUTE_JAVASCRIPT_RESULT
+// notifications.
+class ExecuteNotificationObserver : public NotificationObserver {
+ public:
+ ExecuteNotificationObserver() : id_(0) {}
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ id_ = (static_cast<Details<ExecuteDetailType > >(details))->first;
+ Value* value = (static_cast<Details<ExecuteDetailType > >(details))->second;
+ if (value)
+ value_.reset(value->DeepCopy());
+ MessageLoopForUI::current()->Quit();
+ }
+
+ int id() const { return id_; }
+
+ Value* value() const { return value_.get(); }
+
+ private:
+ int id_;
+ scoped_ptr<Value> value_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExecuteNotificationObserver);
+};
+
+} // namespace
+
+// Makes sure ExecuteJavascriptInWebFrameNotifyResult works.
+IN_PROC_BROWSER_TEST_F(RenderViewHostTest,
+ ExecuteJavascriptInWebFrameNotifyResult) {
+ ASSERT_TRUE(test_server()->Start());
+ GURL empty_url(test_server()->GetURL("files/empty.html"));
+ ui_test_utils::NavigateToURL(browser(), empty_url);
+ RenderViewHost* rvh = browser()->GetSelectedTabContents()->render_view_host();
+ ASSERT_TRUE(rvh);
+
+ // Execute the script 'true' and make sure we get back true.
+ int execute_id = rvh->ExecuteJavascriptInWebFrameNotifyResult(
+ string16(),
+ ASCIIToUTF16("true;"));
+ {
+ ExecuteNotificationObserver observer;
+ ui_test_utils::RegisterAndWait(
+ &observer,
+ NotificationType::EXECUTE_JAVASCRIPT_RESULT,
+ Source<RenderViewHost>(rvh));
+ EXPECT_EQ(execute_id, observer.id());
+ ASSERT_TRUE(observer.value());
+ bool bool_value;
+ ASSERT_TRUE(observer.value()->GetAsBoolean(&bool_value));
+ EXPECT_TRUE(bool_value);
+ }
+
+ // Execute the script 'false' and make sure we get back false.
+ int execute_id2 = rvh->ExecuteJavascriptInWebFrameNotifyResult(
+ string16(),
+ ASCIIToUTF16("false;"));
+ // The ids should change.
+ EXPECT_NE(execute_id, execute_id2);
+ {
+ ExecuteNotificationObserver observer;
+ ui_test_utils::RegisterAndWait(
+ &observer,
+ NotificationType::EXECUTE_JAVASCRIPT_RESULT,
+ Source<RenderViewHost>(rvh));
+ EXPECT_EQ(execute_id2, observer.id());
+ ASSERT_TRUE(observer.value());
+ bool bool_value;
+ ASSERT_TRUE(observer.value()->GetAsBoolean(&bool_value));
+ EXPECT_FALSE(bool_value);
+ }
+}
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 70cea2d..9040353 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1970,6 +1970,7 @@
'browser/popup_blocker_browsertest.cc',
'browser/printing/print_dialog_cloud_uitest.cc',
'browser/renderer_host/test/render_process_host_browsertest.cc',
+ 'browser/renderer_host/test/render_view_host_browsertest.cc',
'browser/renderer_host/test/render_view_host_manager_browsertest.cc',
'browser/renderer_host/test/renderer_accessibility_browsertest.cc',
'browser/renderer_host/test/web_cache_manager_browsertest.cc',
diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h
index bd3ebcd..5febed7 100644
--- a/chrome/common/notification_type.h
+++ b/chrome/common/notification_type.h
@@ -494,6 +494,14 @@ class NotificationType {
// view host for the page, there are no details.
FOCUS_CHANGED_IN_PAGE,
+ // Notification posted from ExecuteJavascriptInWebFrameNotifyResult. The
+ // source is the RenderViewHost ExecuteJavascriptInWebFrameNotifyResult was
+ // invoked on. The details are a std::pair<int, Value*> with the int giving
+ // the id returned from ExecuteJavascriptInWebFrameNotifyResult and the
+ // Value the results of the javascript expression. The Value is owned by
+ // RenderViewHost.
+ EXECUTE_JAVASCRIPT_RESULT,
+
// BackgroundContents ------------------------------------------------------
// A new background contents was opened by script. The source is the parent
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 349c423..b2cb0bf 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -370,9 +370,16 @@ IPC_BEGIN_MESSAGES(View)
// jscript_url is the string containing the javascript: url to be executed
// in the target frame's context. The string should start with "javascript:"
// and continue with a valid JS text.
- IPC_MESSAGE_ROUTED2(ViewMsg_ScriptEvalRequest,
- std::wstring, /* frame_xpath */
- std::wstring /* jscript_url */)
+ //
+ // If the fourth parameter is true the result is sent back to the renderer
+ // using the message ViewHostMsg_ScriptEvalResponse.
+ // ViewHostMsg_ScriptEvalResponse is passed the ID parameter so that the
+ // client can uniquely identify the request.
+ IPC_MESSAGE_ROUTED4(ViewMsg_ScriptEvalRequest,
+ string16, /* frame_xpath */
+ string16, /* jscript_url */
+ int, /* ID */
+ bool /* If true, result is sent back. */)
// Request for the renderer to evaluate an xpath to a frame and insert css
// into that frame's document. See ViewMsg_ScriptEvalRequest for details on
@@ -2925,4 +2932,11 @@ IPC_BEGIN_MESSAGES(ViewHost)
double /* phishing_score */,
SkBitmap /* thumbnail */)
+ // Response from ViewMsg_ScriptEvalRequest. The ID is the parameter supplied
+ // to ViewMsg_ScriptEvalRequest. The result is true if the script evaluated
+ // to the boolean result true, false otherwise.
+ IPC_MESSAGE_ROUTED2(ViewHostMsg_ScriptEvalResponse,
+ int /* id */,
+ bool /* result */)
+
IPC_END_MESSAGES(ViewHost)
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index ab4336a..38a44f3 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -143,6 +143,7 @@
#include "third_party/WebKit/WebKit/chromium/public/WebVector.h"
#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
#include "third_party/WebKit/WebKit/chromium/public/WebWindowFeatures.h"
+#include "v8/include/v8.h"
#include "webkit/appcache/web_application_cache_host_impl.h"
#include "webkit/glue/context_menu.h"
#include "webkit/glue/dom_operations.h"
@@ -4151,13 +4152,19 @@ void RenderView::SetSuggestResult(const std::string& suggest) {
Send(new ViewHostMsg_SetSuggestResult(routing_id_, page_id_, suggest));
}
-void RenderView::EvaluateScript(const std::wstring& frame_xpath,
- const std::wstring& script) {
- WebFrame* web_frame = GetChildFrame(frame_xpath);
- if (!web_frame)
- return;
-
- web_frame->executeScript(WebScriptSource(WideToUTF16Hack(script)));
+void RenderView::EvaluateScript(const string16& frame_xpath,
+ const string16& script,
+ int id,
+ bool notify_result) {
+ v8::Handle<v8::Value> result;
+ WebFrame* web_frame = GetChildFrame(UTF16ToWideHack(frame_xpath));
+ if (web_frame)
+ result = web_frame->executeScriptAndReturnValue(WebScriptSource(script));
+ if (notify_result) {
+ bool bool_result = !result.IsEmpty() && result->IsBoolean() ?
+ result->BooleanValue() : false;
+ Send(new ViewHostMsg_ScriptEvalResponse(routing_id_, id, bool_result));
+ }
}
void RenderView::InsertCSS(const std::wstring& frame_xpath,
@@ -4199,9 +4206,11 @@ void RenderView::OnPepperPluginDestroy(
}
}
-void RenderView::OnScriptEvalRequest(const std::wstring& frame_xpath,
- const std::wstring& jscript) {
- EvaluateScript(frame_xpath, jscript);
+void RenderView::OnScriptEvalRequest(const string16& frame_xpath,
+ const string16& jscript,
+ int id,
+ bool notify_result) {
+ EvaluateScript(frame_xpath, jscript, id, notify_result);
}
void RenderView::OnCSSInsertRequest(const std::wstring& frame_xpath,
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 2292a3c..2fb488c 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -232,8 +232,10 @@ class RenderView : public RenderWidget,
void SetSuggestResult(const std::string& suggest);
// Evaluates a string of JavaScript in a particular frame.
- void EvaluateScript(const std::wstring& frame_xpath,
- const std::wstring& jscript);
+ void EvaluateScript(const string16& frame_xpath,
+ const string16& jscript,
+ int id,
+ bool notify_result);
// Adds the given file chooser request to the file_chooser_completion_ queue
// (see that var for more) and requests the chooser be displayed if there are
@@ -828,8 +830,10 @@ class RenderView : public RenderWidget,
void OnReservePageIDRange(int size_of_range);
void OnResetPageEncodingToDefault();
void OnRevertTranslation(int page_id);
- void OnScriptEvalRequest(const std::wstring& frame_xpath,
- const std::wstring& jscript);
+ void OnScriptEvalRequest(const string16& frame_xpath,
+ const string16& jscript,
+ int id,
+ bool notify_result);
void OnSelectAll();
void OnSetAccessibilityFocus(int acc_obj_id);
void OnSetActive(bool active);