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.
5 #include "content/renderer/browser_plugin/browser_plugin_bindings.h"
10 #include "base/bind.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/strings/string16.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_split.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "content/common/browser_plugin/browser_plugin_constants.h"
17 #include "content/public/renderer/v8_value_converter.h"
18 #include "content/renderer/browser_plugin/browser_plugin.h"
19 #include "third_party/WebKit/public/platform/WebString.h"
20 #include "third_party/WebKit/public/web/WebBindings.h"
21 #include "third_party/WebKit/public/web/WebDOMMessageEvent.h"
22 #include "third_party/WebKit/public/web/WebDocument.h"
23 #include "third_party/WebKit/public/web/WebElement.h"
24 #include "third_party/WebKit/public/web/WebFrame.h"
25 #include "third_party/WebKit/public/web/WebNode.h"
26 #include "third_party/WebKit/public/web/WebPluginContainer.h"
27 #include "third_party/WebKit/public/web/WebView.h"
28 #include "third_party/npapi/bindings/npapi.h"
29 #include "v8/include/v8.h"
31 using blink::WebBindings
;
32 using blink::WebElement
;
33 using blink::WebDOMEvent
;
34 using blink::WebDOMMessageEvent
;
35 using blink::WebPluginContainer
;
36 using blink::WebString
;
42 BrowserPluginBindings
* GetBindings(NPObject
* object
) {
43 return static_cast<BrowserPluginBindings::BrowserPluginNPObject
*>(object
)->
44 message_channel
.get();
47 std::string
StringFromNPVariant(const NPVariant
& variant
) {
48 if (!NPVARIANT_IS_STRING(variant
))
50 const NPString
& np_string
= NPVARIANT_TO_STRING(variant
);
51 return std::string(np_string
.UTF8Characters
, np_string
.UTF8Length
);
54 //------------------------------------------------------------------------------
55 // Implementations of NPClass functions. These are here to:
56 // - Implement src attribute.
57 //------------------------------------------------------------------------------
58 NPObject
* BrowserPluginBindingsAllocate(NPP npp
, NPClass
* the_class
) {
59 return new BrowserPluginBindings::BrowserPluginNPObject
;
62 void BrowserPluginBindingsDeallocate(NPObject
* object
) {
63 BrowserPluginBindings::BrowserPluginNPObject
* instance
=
64 static_cast<BrowserPluginBindings::BrowserPluginNPObject
*>(object
);
68 bool BrowserPluginBindingsHasMethod(NPObject
* np_obj
, NPIdentifier name
) {
72 bool BrowserPluginBindingsInvokeDefault(NPObject
* np_obj
,
73 const NPVariant
* args
,
80 bool BrowserPluginBindingsHasProperty(NPObject
* np_obj
, NPIdentifier name
) {
84 BrowserPluginBindings
* bindings
= GetBindings(np_obj
);
88 return bindings
->HasProperty(name
);
91 bool BrowserPluginBindingsGetProperty(NPObject
* np_obj
, NPIdentifier name
,
99 // All attributes from here on rely on the bindings, so retrieve it once and
100 // return on failure.
101 BrowserPluginBindings
* bindings
= GetBindings(np_obj
);
105 return bindings
->GetProperty(name
, result
);
108 bool BrowserPluginBindingsSetProperty(NPObject
* np_obj
, NPIdentifier name
,
109 const NPVariant
* variant
) {
115 // All attributes from here on rely on the bindings, so retrieve it once and
116 // return on failure.
117 BrowserPluginBindings
* bindings
= GetBindings(np_obj
);
121 if (variant
->type
== NPVariantType_Null
)
122 return bindings
->RemoveProperty(np_obj
, name
);
124 return bindings
->SetProperty(np_obj
, name
, variant
);
127 bool BrowserPluginBindingsEnumerate(NPObject
*np_obj
, NPIdentifier
**value
,
133 NPClass browser_plugin_message_class
= {
134 NP_CLASS_STRUCT_VERSION
,
135 &BrowserPluginBindingsAllocate
,
136 &BrowserPluginBindingsDeallocate
,
138 &BrowserPluginBindingsHasMethod
,
140 &BrowserPluginBindingsInvokeDefault
,
141 &BrowserPluginBindingsHasProperty
,
142 &BrowserPluginBindingsGetProperty
,
143 &BrowserPluginBindingsSetProperty
,
145 &BrowserPluginBindingsEnumerate
,
150 // BrowserPluginPropertyBinding ------------------------------------------------
152 class BrowserPluginPropertyBinding
{
154 explicit BrowserPluginPropertyBinding(const char name
[]) : name_(name
) {}
155 virtual ~BrowserPluginPropertyBinding() {}
156 const std::string
& name() const { return name_
; }
157 bool MatchesName(NPIdentifier name
) const {
158 return WebBindings::getStringIdentifier(name_
.c_str()) == name
;
160 virtual bool GetProperty(BrowserPluginBindings
* bindings
,
161 NPVariant
* result
) = 0;
162 virtual bool SetProperty(BrowserPluginBindings
* bindings
,
164 const NPVariant
* variant
) = 0;
165 virtual void RemoveProperty(BrowserPluginBindings
* bindings
,
166 NPObject
* np_obj
) = 0;
167 // Updates the DOM Attribute value with the current property value.
168 void UpdateDOMAttribute(BrowserPluginBindings
* bindings
,
169 std::string new_value
) {
170 bindings
->instance()->UpdateDOMAttribute(name(), new_value
);
175 DISALLOW_COPY_AND_ASSIGN(BrowserPluginPropertyBinding
);
178 class BrowserPluginPropertyBindingAllowTransparency
179 : public BrowserPluginPropertyBinding
{
181 BrowserPluginPropertyBindingAllowTransparency()
182 : BrowserPluginPropertyBinding(
183 browser_plugin::kAttributeAllowTransparency
) {
185 virtual bool GetProperty(BrowserPluginBindings
* bindings
,
186 NPVariant
* result
) OVERRIDE
{
187 bool allow_transparency
=
188 bindings
->instance()->GetAllowTransparencyAttribute();
189 BOOLEAN_TO_NPVARIANT(allow_transparency
, *result
);
192 virtual bool SetProperty(BrowserPluginBindings
* bindings
,
194 const NPVariant
* variant
) OVERRIDE
{
195 std::string value
= StringFromNPVariant(*variant
);
196 if (!bindings
->instance()->HasDOMAttribute(name())) {
197 UpdateDOMAttribute(bindings
, value
);
198 bindings
->instance()->ParseAllowTransparencyAttribute();
200 UpdateDOMAttribute(bindings
, value
);
204 virtual void RemoveProperty(BrowserPluginBindings
* bindings
,
205 NPObject
* np_obj
) OVERRIDE
{
206 bindings
->instance()->RemoveDOMAttribute(name());
207 bindings
->instance()->ParseAllowTransparencyAttribute();
210 DISALLOW_COPY_AND_ASSIGN(BrowserPluginPropertyBindingAllowTransparency
);
213 class BrowserPluginPropertyBindingContentWindow
214 : public BrowserPluginPropertyBinding
{
216 BrowserPluginPropertyBindingContentWindow()
217 : BrowserPluginPropertyBinding(browser_plugin::kAttributeContentWindow
) {
219 virtual bool GetProperty(BrowserPluginBindings
* bindings
,
220 NPVariant
* result
) OVERRIDE
{
221 NPObject
* obj
= bindings
->instance()->GetContentWindow();
223 result
->type
= NPVariantType_Object
;
224 result
->value
.objectValue
= WebBindings::retainObject(obj
);
228 virtual bool SetProperty(BrowserPluginBindings
* bindings
,
230 const NPVariant
* variant
) OVERRIDE
{
233 virtual void RemoveProperty(BrowserPluginBindings
* bindings
,
234 NPObject
* np_obj
) OVERRIDE
{}
236 DISALLOW_COPY_AND_ASSIGN(BrowserPluginPropertyBindingContentWindow
);
240 // BrowserPluginBindings ------------------------------------------------------
242 BrowserPluginBindings::BrowserPluginNPObject::BrowserPluginNPObject() {
245 BrowserPluginBindings::BrowserPluginNPObject::~BrowserPluginNPObject() {
248 BrowserPluginBindings::BrowserPluginBindings(BrowserPlugin
* instance
)
249 : instance_(instance
),
251 weak_ptr_factory_(this) {
253 WebBindings::createObject(instance
->pluginNPP(),
254 &browser_plugin_message_class
);
255 np_object_
= static_cast<BrowserPluginBindings::BrowserPluginNPObject
*>(obj
);
256 np_object_
->message_channel
= weak_ptr_factory_
.GetWeakPtr();
258 property_bindings_
.push_back(
259 new BrowserPluginPropertyBindingAllowTransparency
);
260 property_bindings_
.push_back(new BrowserPluginPropertyBindingContentWindow
);
263 BrowserPluginBindings::~BrowserPluginBindings() {
264 WebBindings::releaseObject(np_object_
);
267 bool BrowserPluginBindings::HasProperty(NPIdentifier name
) const {
268 for (PropertyBindingList::const_iterator iter
= property_bindings_
.begin();
269 iter
!= property_bindings_
.end();
271 if ((*iter
)->MatchesName(name
))
277 bool BrowserPluginBindings::SetProperty(NPObject
* np_obj
,
279 const NPVariant
* variant
) {
280 for (PropertyBindingList::iterator iter
= property_bindings_
.begin();
281 iter
!= property_bindings_
.end();
283 if ((*iter
)->MatchesName(name
)) {
284 if ((*iter
)->SetProperty(this, np_obj
, variant
)) {
293 bool BrowserPluginBindings::RemoveProperty(NPObject
* np_obj
,
295 for (PropertyBindingList::iterator iter
= property_bindings_
.begin();
296 iter
!= property_bindings_
.end();
298 if ((*iter
)->MatchesName(name
)) {
299 (*iter
)->RemoveProperty(this, np_obj
);
306 bool BrowserPluginBindings::GetProperty(NPIdentifier name
, NPVariant
* result
) {
307 for (PropertyBindingList::iterator iter
= property_bindings_
.begin();
308 iter
!= property_bindings_
.end();
310 if ((*iter
)->MatchesName(name
))
311 return (*iter
)->GetProperty(this, result
);
316 } // namespace content