Home | History | Annotate | Download | only in custom
      1 /*
      2 * Copyright (C) 2009 Google Inc. All rights reserved.
      3 * Copyright (C) 2014 Opera Software ASA. All rights reserved.
      4 *
      5 * Redistribution and use in source and binary forms, with or without
      6 * modification, are permitted provided that the following conditions are
      7 * met:
      8 *
      9 *     * Redistributions of source code must retain the above copyright
     10 * notice, this list of conditions and the following disclaimer.
     11 *     * Redistributions in binary form must reproduce the above
     12 * copyright notice, this list of conditions and the following disclaimer
     13 * in the documentation and/or other materials provided with the
     14 * distribution.
     15 *     * Neither the name of Google Inc. nor the names of its
     16 * contributors may be used to endorse or promote products derived from
     17 * this software without specific prior written permission.
     18 *
     19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 */
     31 
     32 #include "config.h"
     33 
     34 #include "bindings/core/v8/NPV8Object.h"
     35 #include "bindings/core/v8/SharedPersistent.h"
     36 #include "bindings/core/v8/V8Binding.h"
     37 #include "bindings/core/v8/V8HTMLAppletElement.h"
     38 #include "bindings/core/v8/V8HTMLEmbedElement.h"
     39 #include "bindings/core/v8/V8HTMLObjectElement.h"
     40 #include "bindings/core/v8/V8NPObject.h"
     41 #include "core/frame/UseCounter.h"
     42 #include "wtf/OwnPtr.h"
     43 #include "wtf/PassOwnPtr.h"
     44 
     45 namespace blink {
     46 
     47 namespace {
     48 
     49 template <typename ElementType, typename PropertyType>
     50 void getScriptableObjectProperty(PropertyType property, const v8::PropertyCallbackInfo<v8::Value>& info)
     51 {
     52     HTMLPlugInElement* impl = ElementType::toImpl(info.Holder());
     53     RefPtr<SharedPersistent<v8::Object> > wrapper = impl->pluginWrapper();
     54     if (!wrapper)
     55         return;
     56 
     57     v8::Local<v8::Object> instance = wrapper->newLocal(info.GetIsolate());
     58     if (instance.IsEmpty())
     59         return;
     60 
     61     TONATIVE_VOID(v8::Local<v8::Value>, value, instance->Get(property));
     62 
     63     // We quit here to allow the binding code to look up general HTMLObjectElement properties
     64     // if they are not overriden by plugin.
     65     if (value->IsUndefined())
     66         return;
     67 
     68     v8SetReturnValue(info, value);
     69 }
     70 
     71 namespace {
     72 void callNpObjectSetter(v8::Local<v8::Object> self, v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
     73 {
     74     npObjectSetNamedProperty(self, name, value, info);
     75 }
     76 
     77 void callNpObjectSetter(v8::Local<v8::Object> self, uint32_t index, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
     78 {
     79     npObjectSetIndexedProperty(self, index, value, info);
     80 }
     81 }
     82 
     83 template <typename ElementType, typename PropertyType>
     84 void setScriptableObjectProperty(PropertyType property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
     85 {
     86     HTMLPlugInElement* impl = ElementType::toImpl(info.Holder());
     87     RefPtr<SharedPersistent<v8::Object> > wrapper = impl->pluginWrapper();
     88     if (!wrapper)
     89         return;
     90 
     91     v8::Local<v8::Object> instance = wrapper->newLocal(info.GetIsolate());
     92     if (instance.IsEmpty())
     93         return;
     94 
     95     // We need to directly call setter on NPObject to be able to detect
     96     // situation where NPObject notifies it does not possess the property
     97     // to be able to lookup standard DOM property.
     98     // This information is lost when retrieving it through v8::Object.
     99     if (isWrappedNPObject(instance)) {
    100         callNpObjectSetter(instance, property, value, info);
    101         return;
    102     }
    103 
    104     // FIXME: The gTalk pepper plugin is the only plugin to make use of
    105     // SetProperty and that is being deprecated. This can be removed as soon as
    106     // it goes away.
    107     // Call SetProperty on a pepper plugin's scriptable object. Note that we
    108     // never set the return value here which would indicate that the plugin has
    109     // intercepted the SetProperty call, which means that the property on the
    110     // DOM element will also be set. For plugin's that don't intercept the call
    111     // (all except gTalk) this makes no difference at all. For gTalk the fact
    112     // that the property on the DOM element also gets set is inconsequential.
    113     instance->Set(property, value);
    114 }
    115 } // namespace
    116 
    117 void V8HTMLAppletElement::namedPropertyGetterCustom(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)
    118 {
    119     getScriptableObjectProperty<V8HTMLAppletElement>(name, info);
    120 }
    121 
    122 void V8HTMLEmbedElement::namedPropertyGetterCustom(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)
    123 {
    124     getScriptableObjectProperty<V8HTMLEmbedElement>(name, info);
    125 }
    126 
    127 void V8HTMLObjectElement::namedPropertyGetterCustom(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)
    128 {
    129     getScriptableObjectProperty<V8HTMLObjectElement>(name, info);
    130 }
    131 
    132 void V8HTMLAppletElement::namedPropertySetterCustom(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
    133 {
    134     setScriptableObjectProperty<V8HTMLAppletElement>(name, value, info);
    135 }
    136 
    137 void V8HTMLEmbedElement::namedPropertySetterCustom(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
    138 {
    139     setScriptableObjectProperty<V8HTMLEmbedElement>(name, value, info);
    140 }
    141 
    142 void V8HTMLObjectElement::namedPropertySetterCustom(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
    143 {
    144     setScriptableObjectProperty<V8HTMLObjectElement>(name, value, info);
    145 }
    146 
    147 void V8HTMLAppletElement::indexedPropertyGetterCustom(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
    148 {
    149     getScriptableObjectProperty<V8HTMLAppletElement>(index, info);
    150 }
    151 
    152 void V8HTMLEmbedElement::indexedPropertyGetterCustom(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
    153 {
    154     getScriptableObjectProperty<V8HTMLEmbedElement>(index, info);
    155 }
    156 
    157 void V8HTMLObjectElement::indexedPropertyGetterCustom(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
    158 {
    159     getScriptableObjectProperty<V8HTMLObjectElement>(index, info);
    160 }
    161 
    162 void V8HTMLAppletElement::indexedPropertySetterCustom(uint32_t index, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
    163 {
    164     setScriptableObjectProperty<V8HTMLAppletElement>(index, value, info);
    165 }
    166 
    167 void V8HTMLEmbedElement::indexedPropertySetterCustom(uint32_t index, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
    168 {
    169     setScriptableObjectProperty<V8HTMLEmbedElement>(index, value, info);
    170 }
    171 
    172 void V8HTMLObjectElement::indexedPropertySetterCustom(uint32_t index, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
    173 {
    174     setScriptableObjectProperty<V8HTMLObjectElement>(index, value, info);
    175 }
    176 
    177 namespace {
    178 
    179 template <typename ElementType>
    180 void invokeOnScriptableObject(const v8::FunctionCallbackInfo<v8::Value>& info)
    181 {
    182     HTMLPlugInElement* impl = ElementType::toImpl(info.Holder());
    183     RefPtr<SharedPersistent<v8::Object> > wrapper = impl->pluginWrapper();
    184     if (!wrapper)
    185         return;
    186 
    187     v8::Local<v8::Object> instance = wrapper->newLocal(info.GetIsolate());
    188     if (instance.IsEmpty())
    189         return;
    190 
    191     WTF::OwnPtr<v8::Handle<v8::Value>[] > arguments = adoptArrayPtr(new v8::Handle<v8::Value>[info.Length()]);
    192     for (int i = 0; i < info.Length(); ++i)
    193         arguments[i] = info[i];
    194 
    195     TONATIVE_VOID(v8::Local<v8::Value>, retVal, instance->CallAsFunction(info.This(), info.Length(), arguments.get()));
    196     v8SetReturnValue(info, retVal);
    197 }
    198 
    199 } // namespace
    200 
    201 void V8HTMLAppletElement::legacyCallCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
    202 {
    203     invokeOnScriptableObject<V8HTMLAppletElement>(info);
    204     UseCounter::count(V8HTMLAppletElement::toImpl(info.Holder())->document(), UseCounter::HTMLAppletElementLegacyCall);
    205 }
    206 
    207 void V8HTMLEmbedElement::legacyCallCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
    208 {
    209     invokeOnScriptableObject<V8HTMLEmbedElement>(info);
    210     UseCounter::count(V8HTMLEmbedElement::toImpl(info.Holder())->document(), UseCounter::HTMLEmbedElementLegacyCall);
    211 }
    212 
    213 void V8HTMLObjectElement::legacyCallCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
    214 {
    215     invokeOnScriptableObject<V8HTMLObjectElement>(info);
    216     UseCounter::count(V8HTMLObjectElement::toImpl(info.Holder())->document(), UseCounter::HTMLObjectElementLegacyCall);
    217 }
    218 
    219 } // namespace blink
    220