Commit 643be00f authored by jochen@chromium.org's avatar jochen@chromium.org

Convert DomAutomationController from CppBoundClass to gin::Wrappable

BUG=297480
R=jam@chromium.org

Review URL: https://codereview.chromium.org/131573003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244394 0039d316-1c4b-4281-b951-d872f2087c98
parent 982325f6
...@@ -98,6 +98,7 @@ IN_PROC_BROWSER_TEST_F(CommandsApiTest, Basic) { ...@@ -98,6 +98,7 @@ IN_PROC_BROWSER_TEST_F(CommandsApiTest, Basic) {
tab, tab,
"setInterval(function(){" "setInterval(function(){"
" if(document.body.bgColor == 'red'){" " if(document.body.bgColor == 'red'){"
" window.domAutomationController.setAutomationId(0);"
" window.domAutomationController.send(true)}}, 100)", " window.domAutomationController.send(true)}}, 100)",
&result)); &result));
ASSERT_TRUE(result); ASSERT_TRUE(result);
...@@ -111,6 +112,7 @@ IN_PROC_BROWSER_TEST_F(CommandsApiTest, Basic) { ...@@ -111,6 +112,7 @@ IN_PROC_BROWSER_TEST_F(CommandsApiTest, Basic) {
tab, tab,
"setInterval(function(){" "setInterval(function(){"
" if(document.body.bgColor == 'blue'){" " if(document.body.bgColor == 'blue'){"
" window.domAutomationController.setAutomationId(0);"
" window.domAutomationController.send(true)}}, 100)", " window.domAutomationController.send(true)}}, 100)",
&result)); &result));
ASSERT_TRUE(result); ASSERT_TRUE(result);
...@@ -158,6 +160,7 @@ IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_PageAction) { ...@@ -158,6 +160,7 @@ IN_PROC_BROWSER_TEST_F(CommandsApiTest, MAYBE_PageAction) {
tab, tab,
"setInterval(function(){" "setInterval(function(){"
" if(document.body.bgColor == 'red'){" " if(document.body.bgColor == 'red'){"
" window.domAutomationController.setAutomationId(0);"
" window.domAutomationController.send(true)}}, 100)", " window.domAutomationController.send(true)}}, 100)",
&result)); &result));
ASSERT_TRUE(result); ASSERT_TRUE(result);
...@@ -229,6 +232,7 @@ IN_PROC_BROWSER_TEST_F(CommandsApiTest, DontOverwriteSystemShortcuts) { ...@@ -229,6 +232,7 @@ IN_PROC_BROWSER_TEST_F(CommandsApiTest, DontOverwriteSystemShortcuts) {
tab, tab,
"setInterval(function() {" "setInterval(function() {"
" if (document.body.bgColor == 'blue') {" " if (document.body.bgColor == 'blue') {"
" window.domAutomationController.setAutomationId(0);"
" window.domAutomationController.send(true)}}, 100)", " window.domAutomationController.send(true)}}, 100)",
&result)); &result));
ASSERT_TRUE(result); ASSERT_TRUE(result);
......
...@@ -4,52 +4,57 @@ ...@@ -4,52 +4,57 @@
#include "content/renderer/dom_automation_controller.h" #include "content/renderer/dom_automation_controller.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/json/json_string_value_serializer.h" #include "base/json/json_string_value_serializer.h"
#include "base/metrics/histogram.h"
#include "base/metrics/statistics_recorder.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "content/common/child_process_messages.h" #include "content/common/child_process_messages.h"
#include "content/common/view_messages.h" #include "content/common/view_messages.h"
#include "content/renderer/render_view_impl.h"
using webkit_glue::CppArgumentList; #include "content/renderer/v8_value_converter_impl.h"
using webkit_glue::CppVariant; #include "gin/handle.h"
#include "gin/object_template_builder.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebKit.h"
namespace content { namespace content {
DomAutomationController::DomAutomationController() gin::WrapperInfo DomAutomationController::kWrapperInfo = {
: sender_(NULL), gin::kEmbedderNativeGin};
routing_id_(MSG_ROUTING_NONE),
automation_id_(MSG_ROUTING_NONE) {
BindCallback("send", base::Bind(&DomAutomationController::Send,
base::Unretained(this)));
BindCallback("setAutomationId",
base::Bind(&DomAutomationController::SetAutomationId,
base::Unretained(this)));
BindCallback("sendJSON", base::Bind(&DomAutomationController::SendJSON,
base::Unretained(this)));
BindCallback("sendWithId", base::Bind(&DomAutomationController::SendWithId,
base::Unretained(this)));
}
void DomAutomationController::Send(const CppArgumentList& args, // static
CppVariant* result) { void DomAutomationController::Install(blink::WebFrame* frame) {
if (args.size() != 1) { v8::Isolate* isolate = blink::mainThreadIsolate();
result->SetNull(); v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
if (context.IsEmpty())
return; return;
}
if (automation_id_ == MSG_ROUTING_NONE) { v8::Context::Scope context_scope(context);
result->SetNull();
return;
}
if (!sender_) { gin::Handle<DomAutomationController> controller =
NOTREACHED(); gin::CreateHandle(isolate, new DomAutomationController(frame));
result->SetNull(); v8::Handle<v8::Object> global = context->Global();
return; global->Set(gin::StringToV8(isolate, "domAutomationController"),
} controller.ToV8());
}
DomAutomationController::DomAutomationController(blink::WebFrame* frame)
: frame_(frame), automation_id_(MSG_ROUTING_NONE) {}
DomAutomationController::~DomAutomationController() {}
gin::ObjectTemplateBuilder DomAutomationController::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return gin::Wrappable<DomAutomationController>::GetObjectTemplateBuilder(
isolate)
.SetMethod("send", &DomAutomationController::Send)
.SetMethod("setAutomationId", &DomAutomationController::SetAutomationId)
.SetMethod("sendJSON", &DomAutomationController::SendJSON)
.SetMethod("sendWithId", &DomAutomationController::SendWithId);
}
bool DomAutomationController::Send(const gin::Arguments& args) {
if (automation_id_ == MSG_ROUTING_NONE)
return false;
std::string json; std::string json;
JSONStringValueSerializer serializer(&json); JSONStringValueSerializer serializer(&json);
...@@ -61,114 +66,47 @@ void DomAutomationController::Send(const CppArgumentList& args, ...@@ -61,114 +66,47 @@ void DomAutomationController::Send(const CppArgumentList& args,
// writer is lenient, and (b) on the receiving side we wrap the JSON string // writer is lenient, and (b) on the receiving side we wrap the JSON string
// in square brackets, converting it to an array, then parsing it and // in square brackets, converting it to an array, then parsing it and
// grabbing the 0th element to get the value out. // grabbing the 0th element to get the value out.
switch (args[0].type) { if (args.PeekNext()->IsString() || args.PeekNext()->IsBoolean() ||
case NPVariantType_String: { args.PeekNext()->IsNumber()) {
value.reset(new base::StringValue(args[0].ToString())); V8ValueConverterImpl conv;
break; value.reset(
} conv.FromV8Value(args.PeekNext(), args.isolate()->GetCurrentContext()));
case NPVariantType_Bool: { } else {
value.reset(new base::FundamentalValue(args[0].ToBoolean())); return false;
break;
}
case NPVariantType_Int32: {
value.reset(new base::FundamentalValue(args[0].ToInt32()));
break;
}
case NPVariantType_Double: {
// The value that is sent back is an integer while it is treated
// as a double in this binding. The reason being that KJS treats
// any number value as a double. Refer for more details,
// chrome/third_party/webkit/src/JavaScriptCore/bindings/c/c_utility.cpp
value.reset(new base::FundamentalValue(args[0].ToInt32()));
break;
}
default: {
result->SetNull();
return;
}
} }
if (!serializer.Serialize(*value)) { if (!serializer.Serialize(*value))
result->SetNull(); return false;
return;
}
bool succeeded = sender_->Send( RenderViewImpl* render_view = RenderViewImpl::FromWebView(frame_->view());
new ViewHostMsg_DomOperationResponse(routing_id_, json, automation_id_)); bool succeeded = render_view->Send(new ViewHostMsg_DomOperationResponse(
result->Set(succeeded); render_view->GetRoutingID(), json, automation_id_));
automation_id_ = MSG_ROUTING_NONE; automation_id_ = MSG_ROUTING_NONE;
return succeeded;
} }
void DomAutomationController::SendJSON(const CppArgumentList& args, bool DomAutomationController::SendJSON(const std::string& json) {
CppVariant* result) { if (automation_id_ == MSG_ROUTING_NONE)
if (args.size() != 1) { return false;
result->SetNull(); RenderViewImpl* render_view = RenderViewImpl::FromWebView(frame_->view());
return; bool result = render_view->Send(new ViewHostMsg_DomOperationResponse(
} render_view->GetRoutingID(), json, automation_id_));
if (automation_id_ == MSG_ROUTING_NONE) {
result->SetNull();
return;
}
if (!sender_) {
NOTREACHED();
result->SetNull();
return;
}
if (args[0].type != NPVariantType_String) {
result->SetNull();
return;
}
std::string json = args[0].ToString();
result->Set(sender_->Send(
new ViewHostMsg_DomOperationResponse(routing_id_, json, automation_id_)));
automation_id_ = MSG_ROUTING_NONE; automation_id_ = MSG_ROUTING_NONE;
return result;
} }
void DomAutomationController::SendWithId(const CppArgumentList& args, bool DomAutomationController::SendWithId(int automation_id,
CppVariant* result) { const std::string& str) {
if (args.size() != 2) { RenderViewImpl* render_view = RenderViewImpl::FromWebView(frame_->view());
result->SetNull(); return render_view->Send(new ViewHostMsg_DomOperationResponse(
return; render_view->GetRoutingID(), str, automation_id));
}
if (!sender_) {
NOTREACHED();
result->SetNull();
return;
}
if (!args[0].isNumber() || args[1].type != NPVariantType_String) {
result->SetNull();
return;
}
result->Set(sender_->Send(
new ViewHostMsg_DomOperationResponse(routing_id_, args[1].ToString(),
args[0].ToInt32())));
} }
void DomAutomationController::SetAutomationId( bool DomAutomationController::SetAutomationId(int automation_id) {
const CppArgumentList& args, CppVariant* result) { automation_id_ = automation_id;
if (args.size() != 1) { return true;
result->SetNull();
return;
}
// The check here is for NumberType and not Int32 as
// KJS::JSType only defines a NumberType (no Int32)
if (!args[0].isNumber()) {
result->SetNull();
return;
}
automation_id_ = args[0].ToInt32();
result->Set(true);
} }
} // namespace content } // namespace content
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
#ifndef CONTENT_RENDERER_DOM_AUTOMATION_CONTROLLER_H_ #ifndef CONTENT_RENDERER_DOM_AUTOMATION_CONTROLLER_H_
#define CONTENT_RENDERER_DOM_AUTOMATION_CONTROLLER_H_ #define CONTENT_RENDERER_DOM_AUTOMATION_CONTROLLER_H_
#include "ipc/ipc_sender.h" #include "base/basictypes.h"
#include "webkit/renderer/cpp_bound_class.h" #include "gin/wrappable.h"
/* DomAutomationController class: /* DomAutomationController class:
Bound to Javascript window.domAutomationController object. Bound to Javascript window.domAutomationController object.
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
(0) Initialization step where DAController is bound to the renderer (0) Initialization step where DAController is bound to the renderer
and the view_id of the renderer is supplied to the DAController for and the view_id of the renderer is supplied to the DAController for
routing message in (5). (routing_id_) routing message in (5).
(1) A 'javascript:' url is sent from the test process to master as an IPC (1) A 'javascript:' url is sent from the test process to master as an IPC
message. A unique routing id is generated at this stage (automation_id_) message. A unique routing id is generated at this stage (automation_id_)
(2) The automation_id_ of step (1) is supplied to DAController by calling (2) The automation_id_ of step (1) is supplied to DAController by calling
...@@ -61,8 +61,8 @@ ...@@ -61,8 +61,8 @@
(4) A callback is generated as a result of domAutomationController.send() (4) A callback is generated as a result of domAutomationController.send()
into Cpp. The supplied value is received as a result of this callback. into Cpp. The supplied value is received as a result of this callback.
(5) The value received in (4) is sent to the master along with the (5) The value received in (4) is sent to the master along with the
stored automation_id_ as an IPC message. routing_id_ is used to route stored automation_id_ as an IPC message. The frame_'s RenderFrameImpl is
the message. (IPC messages, ViewHostMsg_*DomAutomation* ) used to route the message. (IPC messages, ViewHostMsg_*DomAutomation* )
(6) The value and the automation_id_ is extracted out of the message received (6) The value and the automation_id_ is extracted out of the message received
in (5). This value is relayed to AProxy using another IPC message. in (5). This value is relayed to AProxy using another IPC message.
automation_id_ is used to route the message. automation_id_ is used to route the message.
...@@ -70,57 +70,50 @@ ...@@ -70,57 +70,50 @@
*/ */
namespace blink {
class WebFrame;
}
namespace gin {
class Arguments;
}
namespace content { namespace content {
// TODO(vibhor): Add another method-pair like sendLater() and sendNow() class DomAutomationController : public gin::Wrappable<DomAutomationController> {
// sendLater() should keep building a json serializer
// sendNow() should send the above serializer as a string.
class DomAutomationController : public webkit_glue::CppBoundClass {
public: public:
DomAutomationController(); static gin::WrapperInfo kWrapperInfo;
static void Install(blink::WebFrame* frame);
// Makes the renderer send a javascript value to the app. // Makes the renderer send a javascript value to the app.
// The value to be sent can be either of type NPString, // The value to be sent can be either of type String,
// Number (double casted to int32) or boolean. // Number (double casted to int32) or Boolean. Any other type or no
// The function returns true/false based on the result of actual send over // argument at all is ignored.
// IPC. It sets the return value to null on unexpected errors or arguments. bool Send(const gin::Arguments& args);
void Send(const webkit_glue::CppArgumentList& args,
webkit_glue::CppVariant* result);
// Makes the renderer send a javascript value to the app. // Makes the renderer send a javascript value to the app.
// The value must be a NPString and should be properly formed JSON. // The value should be properly formed JSON.
// This function does not modify/escape the returned string in any way. bool SendJSON(const std::string& json);
void SendJSON(const webkit_glue::CppArgumentList& args,
webkit_glue::CppVariant* result);
// Sends a string with a provided Automation Id. // Sends a string with a provided Automation Id.
// Expects two javascript values; the first must be a number type and will be bool SendWithId(int automation_id, const std::string& str);
// used as the Automation Id, the second must be of type NPString.
// The function returns true/false to the javascript based on the success
// of the send over IPC. It sets the javascript return value to null on
// unexpected errors or arguments.
void SendWithId(const webkit_glue::CppArgumentList& args,
webkit_glue::CppVariant* result);
void SetAutomationId(const webkit_glue::CppArgumentList& args,
webkit_glue::CppVariant* result);
// TODO(vibhor): Implement later bool SetAutomationId(int automation_id);
// static CppBindingObjectMethod sendLater;
// static CppBindingObjectMethod sendNow;
void set_routing_id(int routing_id) { routing_id_ = routing_id; } private:
explicit DomAutomationController(blink::WebFrame* frame);
virtual ~DomAutomationController();
void set_message_sender(IPC::Sender* sender) { // gin::WrappableBase
sender_ = sender; virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
} v8::Isolate* isolate) OVERRIDE;
private: blink::WebFrame* frame_;
IPC::Sender* sender_;
// Refer to the comments at the top of the file for more details.
int routing_id_; // routing id to be used by first channel.
int automation_id_; // routing id to be used by the next channel. int automation_id_; // routing id to be used by the next channel.
DISALLOW_COPY_AND_ASSIGN(DomAutomationController);
}; };
} // namespace content } // namespace content
......
...@@ -3654,18 +3654,11 @@ void RenderViewImpl::didClearWindowObject(WebFrame* frame) { ...@@ -3654,18 +3654,11 @@ void RenderViewImpl::didClearWindowObject(WebFrame* frame) {
FOR_EACH_OBSERVER(RenderViewObserver, observers_, FOR_EACH_OBSERVER(RenderViewObserver, observers_,
DidClearWindowObject(frame)); DidClearWindowObject(frame));
if (enabled_bindings_ & BINDINGS_POLICY_DOM_AUTOMATION) { if (enabled_bindings_ & BINDINGS_POLICY_DOM_AUTOMATION)
if (!dom_automation_controller_) DomAutomationController::Install(frame);
dom_automation_controller_.reset(new DomAutomationController());
dom_automation_controller_->set_message_sender( if (enabled_bindings_ & BINDINGS_POLICY_STATS_COLLECTION)
static_cast<RenderView*>(this)); StatsCollectionController::Install(frame);
dom_automation_controller_->set_routing_id(routing_id());
dom_automation_controller_->BindToJavascript(frame,
"domAutomationController");
}
if (enabled_bindings_ & BINDINGS_POLICY_STATS_COLLECTION)
StatsCollectionController::Install(frame);
} }
void RenderViewImpl::didCreateDocumentElement(WebFrame* frame) { void RenderViewImpl::didCreateDocumentElement(WebFrame* frame) {
......
...@@ -133,7 +133,6 @@ class BrowserPluginManager; ...@@ -133,7 +133,6 @@ class BrowserPluginManager;
class DeviceOrientationDispatcher; class DeviceOrientationDispatcher;
class DevToolsAgent; class DevToolsAgent;
class DocumentState; class DocumentState;
class DomAutomationController;
class ExternalPopupMenu; class ExternalPopupMenu;
class FaviconHelper; class FaviconHelper;
class GeolocationDispatcher; class GeolocationDispatcher;
...@@ -1497,10 +1496,6 @@ class CONTENT_EXPORT RenderViewImpl ...@@ -1497,10 +1496,6 @@ class CONTENT_EXPORT RenderViewImpl
// compositor. // compositor.
bool allow_partial_swap_; bool allow_partial_swap_;
// Allows JS to access DOM automation. The JS object is only exposed when the
// DOM automation bindings are enabled.
scoped_ptr<DomAutomationController> dom_automation_controller_;
// This field stores drag/drop related info for the event that is currently // This field stores drag/drop related info for the event that is currently
// being handled. If the current event results in starting a drag/drop // being handled. If the current event results in starting a drag/drop
// session, this info is sent to the browser along with other drag/drop info. // session, this info is sent to the browser along with other drag/drop info.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment