Home | History | Annotate | Download | only in web
      1 /*
      2  * Copyright (C) 2009 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "public/web/WebBindings.h"
     33 
     34 #include "V8Element.h"
     35 #include "V8Range.h"
     36 #include "bindings/v8/NPV8Object.h"  // for PrivateIdentifier
     37 #include "bindings/v8/ScriptController.h"
     38 #include "bindings/v8/V8DOMWrapper.h"
     39 #include "bindings/v8/V8NPObject.h"
     40 #include "bindings/v8/V8NPUtils.h"
     41 #include "bindings/v8/custom/V8ArrayBufferCustom.h"
     42 #include "bindings/v8/custom/V8ArrayBufferViewCustom.h"
     43 #include "bindings/v8/npruntime_impl.h"
     44 #include "bindings/v8/npruntime_priv.h"
     45 #include "core/dom/Range.h"
     46 #include "core/frame/LocalDOMWindow.h"
     47 #include "core/frame/LocalFrame.h"
     48 #include "public/platform/WebArrayBuffer.h"
     49 #include "public/web/WebArrayBufferView.h"
     50 #include "public/web/WebElement.h"
     51 #include "public/web/WebRange.h"
     52 #include "wtf/ArrayBufferView.h"
     53 
     54 using namespace WebCore;
     55 
     56 namespace blink {
     57 
     58 bool WebBindings::construct(NPP npp, NPObject* object, const NPVariant* args, uint32_t argCount, NPVariant* result)
     59 {
     60     return _NPN_Construct(npp, object, args, argCount, result);
     61 }
     62 
     63 NPObject* WebBindings::createObject(NPP npp, NPClass* npClass)
     64 {
     65     return _NPN_CreateObject(npp, npClass);
     66 }
     67 
     68 bool WebBindings::enumerate(NPP npp, NPObject* object, NPIdentifier** identifier, uint32_t* identifierCount)
     69 {
     70     return _NPN_Enumerate(npp, object, identifier, identifierCount);
     71 }
     72 
     73 bool WebBindings::evaluate(NPP npp, NPObject* object, NPString* script, NPVariant* result)
     74 {
     75     return _NPN_Evaluate(npp, object, script, result);
     76 }
     77 
     78 bool WebBindings::evaluateHelper(NPP npp, bool popupsAllowed, NPObject* object, NPString* script, NPVariant* result)
     79 {
     80     return _NPN_EvaluateHelper(npp, popupsAllowed, object, script, result);
     81 }
     82 
     83 NPIdentifier WebBindings::getIntIdentifier(int32_t number)
     84 {
     85     return _NPN_GetIntIdentifier(number);
     86 }
     87 
     88 bool WebBindings::getProperty(NPP npp, NPObject* object, NPIdentifier property, NPVariant* result)
     89 {
     90     return _NPN_GetProperty(npp, object, property, result);
     91 }
     92 
     93 NPIdentifier WebBindings::getStringIdentifier(const NPUTF8* string)
     94 {
     95     return _NPN_GetStringIdentifier(string);
     96 }
     97 
     98 void WebBindings::getStringIdentifiers(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers)
     99 {
    100     _NPN_GetStringIdentifiers(names, nameCount, identifiers);
    101 }
    102 
    103 bool WebBindings::hasMethod(NPP npp, NPObject* object, NPIdentifier method)
    104 {
    105     return _NPN_HasMethod(npp, object, method);
    106 }
    107 
    108 bool WebBindings::hasProperty(NPP npp, NPObject* object, NPIdentifier property)
    109 {
    110     return _NPN_HasProperty(npp, object, property);
    111 }
    112 
    113 bool WebBindings::identifierIsString(NPIdentifier identifier)
    114 {
    115     return _NPN_IdentifierIsString(identifier);
    116 }
    117 
    118 int32_t WebBindings::intFromIdentifier(NPIdentifier identifier)
    119 {
    120     return _NPN_IntFromIdentifier(identifier);
    121 }
    122 
    123 void WebBindings::initializeVariantWithStringCopy(NPVariant* variant, const NPString* value)
    124 {
    125     _NPN_InitializeVariantWithStringCopy(variant, value);
    126 }
    127 
    128 bool WebBindings::invoke(NPP npp, NPObject* object, NPIdentifier method, const NPVariant* args, uint32_t argCount, NPVariant* result)
    129 {
    130     return _NPN_Invoke(npp, object, method, args, argCount, result);
    131 }
    132 
    133 bool WebBindings::invokeDefault(NPP npp, NPObject* object, const NPVariant* args, uint32_t argCount, NPVariant* result)
    134 {
    135     return _NPN_InvokeDefault(npp, object, args, argCount, result);
    136 }
    137 
    138 void WebBindings::releaseObject(NPObject* object)
    139 {
    140     return _NPN_ReleaseObject(object);
    141 }
    142 
    143 void WebBindings::releaseVariantValue(NPVariant* variant)
    144 {
    145     _NPN_ReleaseVariantValue(variant);
    146 }
    147 
    148 bool WebBindings::removeProperty(NPP npp, NPObject* object, NPIdentifier identifier)
    149 {
    150     return _NPN_RemoveProperty(npp, object, identifier);
    151 }
    152 
    153 NPObject* WebBindings::retainObject(NPObject* object)
    154 {
    155     return _NPN_RetainObject(object);
    156 }
    157 
    158 void WebBindings::setException(NPObject* object, const NPUTF8* message)
    159 {
    160     _NPN_SetException(object, message);
    161 }
    162 
    163 bool WebBindings::setProperty(NPP npp, NPObject* object, NPIdentifier identifier, const NPVariant* value)
    164 {
    165     return _NPN_SetProperty(npp, object, identifier, value);
    166 }
    167 
    168 void WebBindings::registerObjectOwner(NPP)
    169 {
    170 }
    171 
    172 void WebBindings::unregisterObjectOwner(NPP)
    173 {
    174 }
    175 
    176 NPP WebBindings::getObjectOwner(NPObject*)
    177 {
    178     return 0;
    179 }
    180 
    181 void WebBindings::unregisterObject(NPObject* object)
    182 {
    183     _NPN_UnregisterObject(object);
    184 }
    185 
    186 void WebBindings::dropV8WrapperForObject(NPObject* object)
    187 {
    188     WebCore::forgetV8ObjectForNPObject(object);
    189 }
    190 
    191 NPUTF8* WebBindings::utf8FromIdentifier(NPIdentifier identifier)
    192 {
    193     return _NPN_UTF8FromIdentifier(identifier);
    194 }
    195 
    196 void WebBindings::extractIdentifierData(const NPIdentifier& identifier, const NPUTF8*& string, int32_t& number, bool& isString)
    197 {
    198     PrivateIdentifier* data = static_cast<PrivateIdentifier*>(identifier);
    199     if (!data) {
    200         isString = false;
    201         number = 0;
    202         return;
    203     }
    204 
    205     isString = data->isString;
    206     if (isString)
    207         string = data->value.string;
    208     else
    209         number = data->value.number;
    210 }
    211 
    212 static bool getRangeImpl(NPObject* object, WebRange* webRange, v8::Isolate* isolate)
    213 {
    214     if (!object)
    215         return false;
    216 
    217     V8NPObject* v8NPObject = npObjectToV8NPObject(object);
    218     if (!v8NPObject)
    219         return false;
    220 
    221     v8::HandleScope handleScope(isolate);
    222     v8::Handle<v8::Object> v8Object = v8::Local<v8::Object>::New(isolate, v8NPObject->v8Object);
    223     if (v8Object.IsEmpty())
    224         return false;
    225     if (!V8Range::wrapperTypeInfo.equals(toWrapperTypeInfo(v8Object)))
    226         return false;
    227 
    228     Range* native = V8Range::hasInstance(v8Object, isolate) ? V8Range::toNative(v8Object) : 0;
    229     if (!native)
    230         return false;
    231 
    232     *webRange = WebRange(native);
    233     return true;
    234 }
    235 
    236 static bool getNodeImpl(NPObject* object, WebNode* webNode, v8::Isolate* isolate)
    237 {
    238     if (!object)
    239         return false;
    240 
    241     V8NPObject* v8NPObject = npObjectToV8NPObject(object);
    242     if (!v8NPObject)
    243         return false;
    244 
    245     v8::HandleScope handleScope(isolate);
    246     v8::Handle<v8::Object> v8Object = v8::Local<v8::Object>::New(isolate, v8NPObject->v8Object);
    247     if (v8Object.IsEmpty())
    248         return false;
    249     Node* native = V8Node::hasInstance(v8Object, isolate) ? V8Node::toNative(v8Object) : 0;
    250     if (!native)
    251         return false;
    252 
    253     *webNode = WebNode(native);
    254     return true;
    255 }
    256 
    257 static bool getElementImpl(NPObject* object, WebElement* webElement, v8::Isolate* isolate)
    258 {
    259     if (!object)
    260         return false;
    261 
    262     V8NPObject* v8NPObject = npObjectToV8NPObject(object);
    263     if (!v8NPObject)
    264         return false;
    265 
    266     v8::HandleScope handleScope(isolate);
    267     v8::Handle<v8::Object> v8Object = v8::Local<v8::Object>::New(isolate, v8NPObject->v8Object);
    268     if (v8Object.IsEmpty())
    269         return false;
    270     Element* native = V8Element::hasInstance(v8Object, isolate) ? V8Element::toNative(v8Object) : 0;
    271     if (!native)
    272         return false;
    273 
    274     *webElement = WebElement(native);
    275     return true;
    276 }
    277 
    278 static bool getArrayBufferImpl(NPObject* object, WebArrayBuffer* arrayBuffer, v8::Isolate* isolate)
    279 {
    280     if (!object)
    281         return false;
    282 
    283     V8NPObject* v8NPObject = npObjectToV8NPObject(object);
    284     if (!v8NPObject)
    285         return false;
    286 
    287     v8::HandleScope handleScope(isolate);
    288     v8::Handle<v8::Object> v8Object = v8::Local<v8::Object>::New(isolate, v8NPObject->v8Object);
    289     if (v8Object.IsEmpty())
    290         return false;
    291     ArrayBuffer* native = V8ArrayBuffer::hasInstance(v8Object, isolate) ? V8ArrayBuffer::toNative(v8Object) : 0;
    292     if (!native)
    293         return false;
    294 
    295     *arrayBuffer = WebArrayBuffer(native);
    296     return true;
    297 }
    298 
    299 static bool getArrayBufferViewImpl(NPObject* object, WebArrayBufferView* arrayBufferView, v8::Isolate* isolate)
    300 {
    301     if (!object)
    302         return false;
    303 
    304     V8NPObject* v8NPObject = npObjectToV8NPObject(object);
    305     if (!v8NPObject)
    306         return false;
    307 
    308     v8::HandleScope handleScope(isolate);
    309     v8::Handle<v8::Object> v8Object = v8::Local<v8::Object>::New(isolate, v8NPObject->v8Object);
    310     if (v8Object.IsEmpty())
    311         return false;
    312     ArrayBufferView* native = V8ArrayBufferView::hasInstance(v8Object, isolate) ? V8ArrayBufferView::toNative(v8Object) : 0;
    313     if (!native)
    314         return false;
    315 
    316     *arrayBufferView = WebArrayBufferView(native);
    317     return true;
    318 }
    319 
    320 static NPObject* makeIntArrayImpl(const WebVector<int>& data, v8::Isolate* isolate)
    321 {
    322     v8::HandleScope handleScope(isolate);
    323     v8::Handle<v8::Array> result = v8::Array::New(isolate, data.size());
    324     for (size_t i = 0; i < data.size(); ++i)
    325         result->Set(i, v8::Number::New(isolate, data[i]));
    326 
    327     LocalDOMWindow* window = currentDOMWindow(isolate);
    328     return npCreateV8ScriptObject(0, result, window, isolate);
    329 }
    330 
    331 static NPObject* makeStringArrayImpl(const WebVector<WebString>& data, v8::Isolate* isolate)
    332 {
    333     v8::HandleScope handleScope(isolate);
    334     v8::Handle<v8::Array> result = v8::Array::New(isolate, data.size());
    335     for (size_t i = 0; i < data.size(); ++i)
    336         result->Set(i, v8String(isolate, data[i]));
    337 
    338     LocalDOMWindow* window = currentDOMWindow(isolate);
    339     return npCreateV8ScriptObject(0, result, window, isolate);
    340 }
    341 
    342 bool WebBindings::getRange(NPObject* range, WebRange* webRange)
    343 {
    344     return getRangeImpl(range, webRange, v8::Isolate::GetCurrent());
    345 }
    346 
    347 bool WebBindings::getArrayBuffer(NPObject* arrayBuffer, WebArrayBuffer* webArrayBuffer)
    348 {
    349     return getArrayBufferImpl(arrayBuffer, webArrayBuffer, v8::Isolate::GetCurrent());
    350 }
    351 
    352 bool WebBindings::getArrayBufferView(NPObject* arrayBufferView, WebArrayBufferView* webArrayBufferView)
    353 {
    354     return getArrayBufferViewImpl(arrayBufferView, webArrayBufferView, v8::Isolate::GetCurrent());
    355 }
    356 
    357 bool WebBindings::getNode(NPObject* node, WebNode* webNode)
    358 {
    359     return getNodeImpl(node, webNode, v8::Isolate::GetCurrent());
    360 }
    361 
    362 bool WebBindings::getElement(NPObject* element, WebElement* webElement)
    363 {
    364     return getElementImpl(element, webElement, v8::Isolate::GetCurrent());
    365 }
    366 
    367 NPObject* WebBindings::makeIntArray(const WebVector<int>& data)
    368 {
    369     return makeIntArrayImpl(data, v8::Isolate::GetCurrent());
    370 }
    371 
    372 NPObject* WebBindings::makeStringArray(const WebVector<WebString>& data)
    373 {
    374     return makeStringArrayImpl(data, v8::Isolate::GetCurrent());
    375 }
    376 
    377 void WebBindings::pushExceptionHandler(ExceptionHandler handler, void* data)
    378 {
    379     WebCore::pushExceptionHandler(handler, data);
    380 }
    381 
    382 void WebBindings::popExceptionHandler()
    383 {
    384     WebCore::popExceptionHandler();
    385 }
    386 
    387 void WebBindings::toNPVariant(v8::Local<v8::Value> object, NPObject* root, NPVariant* result)
    388 {
    389     WebCore::convertV8ObjectToNPVariant(object, root, result, v8::Isolate::GetCurrent());
    390 }
    391 
    392 v8::Handle<v8::Value> WebBindings::toV8Value(const NPVariant* variant)
    393 {
    394     v8::Isolate* isolate = v8::Isolate::GetCurrent();
    395     if (variant->type == NPVariantType_Object) {
    396         NPObject* object = NPVARIANT_TO_OBJECT(*variant);
    397         V8NPObject* v8Object = npObjectToV8NPObject(object);
    398         if (!v8Object)
    399             return v8::Undefined(isolate);
    400         return convertNPVariantToV8Object(variant, v8Object->rootObject->frame()->script().windowScriptNPObject(), isolate);
    401     }
    402     // Safe to pass 0 since we have checked the script object class to make sure the
    403     // argument is a primitive v8 type.
    404     return convertNPVariantToV8Object(variant, 0, isolate);
    405 }
    406 
    407 } // namespace blink
    408