OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/renderer/browser_plugin/browser_plugin_bindings.h" | |
6 | |
7 #include <cstdlib> | |
8 #include <string> | |
9 | |
10 #include "base/bind.h" | |
11 #include "base/logging.h" | |
12 #include "base/message_loop.h" | |
13 #include "base/string16.h" | |
14 #include "base/string_split.h" | |
15 #include "base/utf_string_conversions.h" | |
16 #include "content/renderer/browser_plugin/browser_plugin.h" | |
17 #include "third_party/npapi/bindings/npapi.h" | |
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" | |
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | |
20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMMessageEvent.h" | |
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" | |
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | |
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" | |
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" | |
25 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSerialize
dScriptValue.h" | |
26 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" | |
27 #include "v8/include/v8.h" | |
28 | |
29 using WebKit::WebBindings; | |
30 using WebKit::WebElement; | |
31 using WebKit::WebDOMEvent; | |
32 using WebKit::WebDOMMessageEvent; | |
33 using WebKit::WebPluginContainer; | |
34 using WebKit::WebSerializedScriptValue; | |
35 using WebKit::WebString; | |
36 | |
37 namespace content { | |
38 | |
39 namespace { | |
40 | |
41 const char kAddEventListener[] = "addEventListener"; | |
42 const char kRemoveEventListener[] = "removeEventListener"; | |
43 const char kSrcAttribute[] = "src"; | |
44 | |
45 BrowserPluginBindings* GetBindings(NPObject* object) { | |
46 return static_cast<BrowserPluginBindings::BrowserPluginNPObject*>(object)-> | |
47 message_channel; | |
48 } | |
49 | |
50 bool IdentifierIsAddEventListener(NPIdentifier identifier) { | |
51 return WebBindings::getStringIdentifier(kAddEventListener) == identifier; | |
52 } | |
53 | |
54 bool IdentifierIsRemoveEventListener(NPIdentifier identifier) { | |
55 return WebBindings::getStringIdentifier(kRemoveEventListener) == identifier; | |
56 } | |
57 | |
58 bool IdentifierIsSrcAttribute(NPIdentifier identifier) { | |
59 return WebBindings::getStringIdentifier(kSrcAttribute) == identifier; | |
60 } | |
61 | |
62 std::string StringFromNPVariant(const NPVariant& variant) { | |
63 if (!NPVARIANT_IS_STRING(variant)) | |
64 return std::string(); | |
65 const NPString& np_string = NPVARIANT_TO_STRING(variant); | |
66 return std::string(np_string.UTF8Characters, np_string.UTF8Length); | |
67 } | |
68 | |
69 string16 String16FromNPVariant(const NPVariant& variant) { | |
70 if (!NPVARIANT_IS_STRING(variant)) | |
71 return string16(); | |
72 const NPString& np_string = NPVARIANT_TO_STRING(variant); | |
73 string16 wstr; | |
74 if (!UTF8ToUTF16(np_string.UTF8Characters, np_string.UTF8Length, &wstr)) | |
75 return string16(); | |
76 return wstr; | |
77 } | |
78 | |
79 bool StringToNPVariant(const std::string &in, NPVariant *variant) { | |
80 size_t length = in.size(); | |
81 NPUTF8 *chars = static_cast<NPUTF8 *>(malloc(length)); | |
82 if (!chars) { | |
83 VOID_TO_NPVARIANT(*variant); | |
84 return false; | |
85 } | |
86 memcpy(chars, in.c_str(), length); | |
87 STRINGN_TO_NPVARIANT(chars, length, *variant); | |
88 return true; | |
89 } | |
90 | |
91 //------------------------------------------------------------------------------ | |
92 // Implementations of NPClass functions. These are here to: | |
93 // - Implement src attribute. | |
94 //------------------------------------------------------------------------------ | |
95 NPObject* BrowserPluginBindingsAllocate(NPP npp, NPClass* the_class) { | |
96 return new BrowserPluginBindings::BrowserPluginNPObject; | |
97 } | |
98 | |
99 void BrowserPluginBindingsDeallocate(NPObject* object) { | |
100 BrowserPluginBindings::BrowserPluginNPObject* instance = | |
101 static_cast<BrowserPluginBindings::BrowserPluginNPObject*>(object); | |
102 delete instance; | |
103 } | |
104 | |
105 bool BrowserPluginBindingsHasMethod(NPObject* np_obj, NPIdentifier name) { | |
106 if (!np_obj) | |
107 return false; | |
108 | |
109 if (IdentifierIsAddEventListener(name)) | |
110 return true; | |
111 | |
112 if (IdentifierIsRemoveEventListener(name)) | |
113 return true; | |
114 | |
115 return false; | |
116 } | |
117 | |
118 bool BrowserPluginBindingsInvoke(NPObject* np_obj, NPIdentifier name, | |
119 const NPVariant* args, uint32 arg_count, | |
120 NPVariant* result) { | |
121 if (!np_obj) | |
122 return false; | |
123 | |
124 BrowserPluginBindings* bindings = GetBindings(np_obj); | |
125 if (!bindings) | |
126 return false; | |
127 | |
128 if (IdentifierIsAddEventListener(name) && (arg_count == 2)) { | |
129 std::string event_name = StringFromNPVariant(args[0]); | |
130 if (event_name.empty()) | |
131 return false; | |
132 | |
133 v8::Local<v8::Value> value = | |
134 v8::Local<v8::Value>::New(WebBindings::toV8Value(&args[1])); | |
135 if (value.IsEmpty() || !value->IsFunction()) | |
136 return false; | |
137 | |
138 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(value); | |
139 return bindings->instance()->AddEventListener(event_name, function); | |
140 } | |
141 | |
142 if (IdentifierIsRemoveEventListener(name) && arg_count == 2) { | |
143 std::string event_name = StringFromNPVariant(args[0]); | |
144 if (event_name.empty()) | |
145 return false; | |
146 | |
147 v8::Local<v8::Value> value = | |
148 v8::Local<v8::Value>::New(WebBindings::toV8Value(&args[1])); | |
149 | |
150 if (value.IsEmpty() || !value->IsFunction()) | |
151 return false; | |
152 | |
153 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(value); | |
154 return bindings->instance()->RemoveEventListener(event_name, function); | |
155 } | |
156 | |
157 return false; | |
158 } | |
159 | |
160 bool BrowserPluginBindingsInvokeDefault(NPObject* np_obj, | |
161 const NPVariant* args, | |
162 uint32 arg_count, | |
163 NPVariant* result) { | |
164 NOTIMPLEMENTED(); | |
165 return false; | |
166 } | |
167 | |
168 bool BrowserPluginBindingsHasProperty(NPObject* np_obj, NPIdentifier name) { | |
169 return IdentifierIsSrcAttribute(name); | |
170 } | |
171 | |
172 bool BrowserPluginBindingsGetProperty(NPObject* np_obj, NPIdentifier name, | |
173 NPVariant* result) { | |
174 if (!np_obj) | |
175 return false; | |
176 | |
177 if (IdentifierIsAddEventListener(name) || | |
178 IdentifierIsRemoveEventListener(name)) | |
179 return false; | |
180 | |
181 if (IdentifierIsSrcAttribute(name)) { | |
182 BrowserPluginBindings* bindings = GetBindings(np_obj); | |
183 if (!bindings) | |
184 return false; | |
185 std::string src = bindings->instance()->GetSrcAttribute(); | |
186 return StringToNPVariant(src, result); | |
187 } | |
188 | |
189 return false; | |
190 } | |
191 | |
192 bool BrowserPluginBindingsSetProperty(NPObject* np_obj, NPIdentifier name, | |
193 const NPVariant* variant) { | |
194 if (!np_obj) | |
195 return false; | |
196 | |
197 if (IdentifierIsSrcAttribute(name)) { | |
198 std::string src = StringFromNPVariant(*variant); | |
199 BrowserPluginBindings* bindings = GetBindings(np_obj); | |
200 if (!bindings) | |
201 return false; | |
202 bindings->instance()->SetSrcAttribute(src); | |
203 return true; | |
204 } | |
205 return false; | |
206 } | |
207 | |
208 bool BrowserPluginBindingsEnumerate(NPObject *np_obj, NPIdentifier **value, | |
209 uint32_t *count) { | |
210 NOTIMPLEMENTED(); | |
211 return true; | |
212 } | |
213 | |
214 NPClass browser_plugin_message_class = { | |
215 NP_CLASS_STRUCT_VERSION, | |
216 &BrowserPluginBindingsAllocate, | |
217 &BrowserPluginBindingsDeallocate, | |
218 NULL, | |
219 &BrowserPluginBindingsHasMethod, | |
220 &BrowserPluginBindingsInvoke, | |
221 &BrowserPluginBindingsInvokeDefault, | |
222 &BrowserPluginBindingsHasProperty, | |
223 &BrowserPluginBindingsGetProperty, | |
224 &BrowserPluginBindingsSetProperty, | |
225 NULL, | |
226 &BrowserPluginBindingsEnumerate, | |
227 }; | |
228 | |
229 } // namespace | |
230 | |
231 // BrowserPluginBindings ------------------------------------------------------ | |
232 | |
233 BrowserPluginBindings::BrowserPluginNPObject::BrowserPluginNPObject() { | |
234 } | |
235 | |
236 BrowserPluginBindings::BrowserPluginNPObject::~BrowserPluginNPObject() { | |
237 } | |
238 | |
239 BrowserPluginBindings::BrowserPluginBindings(BrowserPlugin* instance) | |
240 : instance_(instance), | |
241 np_object_(NULL), | |
242 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | |
243 NPObject* obj = | |
244 WebBindings::createObject(NULL, &browser_plugin_message_class); | |
245 np_object_ = static_cast<BrowserPluginBindings::BrowserPluginNPObject*>(obj); | |
246 np_object_->message_channel = weak_ptr_factory_.GetWeakPtr(); | |
247 } | |
248 | |
249 BrowserPluginBindings::~BrowserPluginBindings() { | |
250 WebBindings::releaseObject(np_object_); | |
251 } | |
252 | |
253 } // namespace content | |
OLD | NEW |