1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
// 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 "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/string_util.h"
#include "content/common/view_messages.h"
DomAutomationController::DomAutomationController()
: sender_(NULL),
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,
CppVariant* result) {
if (args.size() != 1) {
result->SetNull();
return;
}
if (automation_id_ == MSG_ROUTING_NONE) {
result->SetNull();
return;
}
if (!sender_) {
NOTREACHED();
result->SetNull();
return;
}
std::string json;
JSONStringValueSerializer serializer(&json);
scoped_ptr<Value> value;
// Warning: note that JSON officially requires the root-level object to be
// an object (e.g. {foo:3}) or an array, while here we're serializing
// strings, bools, etc. to "JSON". This only works because (a) the JSON
// 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
// grabbing the 0th element to get the value out.
switch (args[0].type) {
case NPVariantType_String: {
value.reset(Value::CreateStringValue(args[0].ToString()));
break;
}
case NPVariantType_Bool: {
value.reset(Value::CreateBooleanValue(args[0].ToBoolean()));
break;
}
case NPVariantType_Int32: {
value.reset(Value::CreateIntegerValue(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(Value::CreateIntegerValue(args[0].ToInt32()));
break;
}
default: {
result->SetNull();
return;
}
}
if (!serializer.Serialize(*value)) {
result->SetNull();
return;
}
bool succeeded = sender_->Send(
new ViewHostMsg_DomOperationResponse(routing_id_, json, automation_id_));
result->Set(succeeded);
automation_id_ = MSG_ROUTING_NONE;
}
void DomAutomationController::SendJSON(const CppArgumentList& args,
CppVariant* result) {
if (args.size() != 1) {
result->SetNull();
return;
}
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;
}
void DomAutomationController::SendWithId(const CppArgumentList& args,
CppVariant* result) {
if (args.size() != 2) {
result->SetNull();
return;
}
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(
const CppArgumentList& args, CppVariant* result) {
if (args.size() != 1) {
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);
}
|