Home | History | Annotate | Download | only in src
      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 "WebBindings.h"
     33 
     34 #include "npruntime_impl.h"
     35 #include "npruntime_priv.h"
     36 
     37 #include "../public/WebDragData.h"
     38 #include "../public/WebRange.h"
     39 
     40 #if USE(V8)
     41 #include "ChromiumDataObject.h"
     42 #include "ClipboardChromium.h"
     43 #include "EventNames.h"
     44 #include "MouseEvent.h"
     45 #include "NPV8Object.h"  // for PrivateIdentifier
     46 #include "Range.h"
     47 #include "V8BindingState.h"
     48 #include "V8DOMWrapper.h"
     49 #include "V8Event.h"
     50 #include "V8Helpers.h"
     51 #include "V8Proxy.h"
     52 #include "V8Range.h"
     53 #elif USE(JSC)
     54 #include "bridge/c/c_utility.h"
     55 #endif
     56 
     57 #if USE(JAVASCRIPTCORE_BINDINGS)
     58 using JSC::Bindings::PrivateIdentifier;
     59 #endif
     60 
     61 using namespace WebCore;
     62 
     63 namespace WebKit {
     64 
     65 bool WebBindings::construct(NPP npp, NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant* result)
     66 {
     67     return _NPN_Construct(npp, npobj, args, argCount, result);
     68 }
     69 
     70 NPObject* WebBindings::createObject(NPP npp, NPClass* npClass)
     71 {
     72     return _NPN_CreateObject(npp, npClass);
     73 }
     74 
     75 bool WebBindings::enumerate(NPP id, NPObject* obj, NPIdentifier** identifier, uint32_t* val)
     76 {
     77     return _NPN_Enumerate(id, obj, identifier, val);
     78 }
     79 
     80 bool WebBindings::evaluate(NPP npp, NPObject* npObject, NPString* npScript, NPVariant* result)
     81 {
     82     return _NPN_Evaluate(npp, npObject, npScript, result);
     83 }
     84 
     85 bool WebBindings::evaluateHelper(NPP npp, bool popups_allowed, NPObject* npobj, NPString* npscript, NPVariant* result)
     86 {
     87     return _NPN_EvaluateHelper(npp, popups_allowed, npobj, npscript, result);
     88 }
     89 
     90 NPIdentifier WebBindings::getIntIdentifier(int32_t number)
     91 {
     92     return _NPN_GetIntIdentifier(number);
     93 }
     94 
     95 bool WebBindings::getProperty(NPP npp, NPObject* obj, NPIdentifier propertyName, NPVariant *result)
     96 {
     97     return _NPN_GetProperty(npp, obj, propertyName, result);
     98 }
     99 
    100 NPIdentifier WebBindings::getStringIdentifier(const NPUTF8* string)
    101 {
    102     return _NPN_GetStringIdentifier(string);
    103 }
    104 
    105 void WebBindings::getStringIdentifiers(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers)
    106 {
    107     _NPN_GetStringIdentifiers(names, nameCount, identifiers);
    108 }
    109 
    110 bool WebBindings::hasMethod(NPP npp, NPObject* npObject, NPIdentifier methodName)
    111 {
    112     return _NPN_HasMethod(npp, npObject, methodName);
    113 }
    114 
    115 bool WebBindings::hasProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName)
    116 {
    117     return _NPN_HasProperty(npp, npObject, propertyName);
    118 }
    119 
    120 bool WebBindings::identifierIsString(NPIdentifier identifier)
    121 {
    122     return _NPN_IdentifierIsString(identifier);
    123 }
    124 
    125 int32_t WebBindings::intFromIdentifier(NPIdentifier identifier)
    126 {
    127     return _NPN_IntFromIdentifier(identifier);
    128 }
    129 
    130 void WebBindings::initializeVariantWithStringCopy(NPVariant* variant, const NPString* value)
    131 {
    132 #if USE(V8)
    133     _NPN_InitializeVariantWithStringCopy(variant, value);
    134 #else
    135     NPN_InitializeVariantWithStringCopy(variant, value);
    136 #endif
    137 }
    138 
    139 bool WebBindings::invoke(NPP npp, NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
    140 {
    141     return _NPN_Invoke(npp, npObject, methodName, arguments, argumentCount, result);
    142 }
    143 
    144 bool WebBindings::invokeDefault(NPP id, NPObject* obj, const NPVariant* args, uint32_t count, NPVariant* result)
    145 {
    146     return _NPN_InvokeDefault(id, obj, args, count, result);
    147 }
    148 
    149 void WebBindings::releaseObject(NPObject* npObject)
    150 {
    151     return _NPN_ReleaseObject(npObject);
    152 }
    153 
    154 void WebBindings::releaseVariantValue(NPVariant* variant)
    155 {
    156     _NPN_ReleaseVariantValue(variant);
    157 }
    158 
    159 bool WebBindings::removeProperty(NPP id, NPObject* object, NPIdentifier identifier)
    160 {
    161     return  _NPN_RemoveProperty(id, object, identifier);
    162 }
    163 
    164 NPObject* WebBindings::retainObject(NPObject* npObject)
    165 {
    166     return _NPN_RetainObject(npObject);
    167 }
    168 
    169 void WebBindings::setException(NPObject* obj, const NPUTF8* message)
    170 {
    171     _NPN_SetException(obj, message);
    172 }
    173 
    174 bool WebBindings::setProperty(NPP id, NPObject* obj, NPIdentifier identifier, const NPVariant* variant)
    175 {
    176     return _NPN_SetProperty(id, obj, identifier, variant);
    177 }
    178 
    179 void WebBindings::unregisterObject(NPObject* npObject)
    180 {
    181 #if USE(V8)
    182     _NPN_UnregisterObject(npObject);
    183 #endif
    184 }
    185 
    186 NPUTF8* WebBindings::utf8FromIdentifier(NPIdentifier identifier)
    187 {
    188     return _NPN_UTF8FromIdentifier(identifier);
    189 }
    190 
    191 void WebBindings::extractIdentifierData(const NPIdentifier& identifier, const NPUTF8*& string, int32_t& number, bool& isString)
    192 {
    193     PrivateIdentifier* priv = static_cast<PrivateIdentifier*>(identifier);
    194     if (!priv) {
    195         isString = false;
    196         number = 0;
    197         return;
    198     }
    199 
    200     isString = priv->isString;
    201     if (isString)
    202         string = priv->value.string;
    203     else
    204         number = priv->value.number;
    205 }
    206 
    207 #if USE(V8)
    208 
    209 static v8::Local<v8::Value> getEvent(const v8::Handle<v8::Context>& context)
    210 {
    211     static v8::Persistent<v8::String> eventSymbol(v8::Persistent<v8::String>::New(v8::String::NewSymbol("event")));
    212     return context->Global()->GetHiddenValue(eventSymbol);
    213 }
    214 
    215 static bool getDragDataImpl(NPObject* npobj, int* eventId, WebDragData* data)
    216 {
    217     if (!npobj)
    218         return false;
    219     if (npobj->_class != npScriptObjectClass)
    220         return false;
    221 
    222     v8::HandleScope handleScope;
    223     v8::Handle<v8::Context> context = v8::Context::GetEntered();
    224     if (context.IsEmpty())
    225         return false;
    226 
    227     // Get the current WebCore event.
    228     v8::Handle<v8::Value> currentEvent(getEvent(context));
    229     Event* event = V8Event::toNative(v8::Handle<v8::Object>::Cast(currentEvent));
    230     if (!event)
    231         return false;
    232 
    233     // Check that the given npobj is that event.
    234     V8NPObject* object = reinterpret_cast<V8NPObject*>(npobj);
    235     Event* given = V8Event::toNative(object->v8Object);
    236     if (given != event)
    237         return false;
    238 
    239     // Check the execution frames are same origin.
    240     V8Proxy* current = V8Proxy::retrieve(V8Proxy::retrieveFrameForCurrentContext());
    241     Frame* frame = V8Proxy::retrieveFrame(context);
    242     if (!current || !V8BindingSecurity::canAccessFrame(V8BindingState::Only(), frame, false))
    243         return false;
    244 
    245     const EventNames& names(eventNames());
    246     const AtomicString& eventType(event->type());
    247 
    248     enum DragTargetMouseEventId {
    249         DragEnterId = 1, DragOverId = 2, DragLeaveId = 3, DropId = 4
    250     };
    251 
    252     // The event type should be a drag event.
    253     if (eventType == names.dragenterEvent)
    254         *eventId = DragEnterId;
    255     else if (eventType == names.dragoverEvent)
    256         *eventId = DragOverId;
    257     else if (eventType == names.dragleaveEvent)
    258         *eventId = DragLeaveId;
    259     else if (eventType == names.dropEvent)
    260         *eventId = DropId;
    261     else
    262         return false;
    263 
    264     // Drag events are mouse events and should have a clipboard.
    265     MouseEvent* me = static_cast<MouseEvent*>(event);
    266     Clipboard* clipboard = me->clipboard();
    267     if (!clipboard)
    268         return false;
    269 
    270     // And that clipboard should be accessible by WebKit policy.
    271     ClipboardChromium* chrome = static_cast<ClipboardChromium*>(clipboard);
    272     HashSet<String> accessible(chrome->types());
    273     if (accessible.isEmpty())
    274         return false;
    275 
    276     RefPtr<ChromiumDataObject> dataObject(chrome->dataObject());
    277     if (dataObject && data)
    278         *data = WebDragData(dataObject);
    279 
    280     return dataObject;
    281 }
    282 
    283 static bool getRangeImpl(NPObject* npobj, WebRange* range)
    284 {
    285     V8NPObject* v8npobject = reinterpret_cast<V8NPObject*>(npobj);
    286     v8::Handle<v8::Object> v8object(v8npobject->v8Object);
    287     if (V8ClassIndex::RANGE != V8DOMWrapper::domWrapperType(v8object))
    288         return false;
    289 
    290     Range* native = V8Range::toNative(v8object);
    291     if (!native)
    292         return false;
    293 
    294     *range = WebRange(native);
    295     return true;
    296 }
    297 
    298 #endif
    299 
    300 bool WebBindings::getDragData(NPObject* event, int* eventId, WebDragData* data)
    301 {
    302 #if USE(V8)
    303     return getDragDataImpl(event, eventId, data);
    304 #else
    305     // Not supported on other ports (JSC, etc).
    306     return false;
    307 #endif
    308 }
    309 
    310 bool WebBindings::isDragEvent(NPObject* event)
    311 {
    312     int eventId;
    313     return getDragData(event, &eventId, 0);
    314 }
    315 
    316 bool WebBindings::getRange(NPObject* range, WebRange* webrange)
    317 {
    318 #if USE(V8)
    319     return getRangeImpl(range, webrange);
    320 #else
    321     // Not supported on other ports (JSC, etc).
    322     return false;
    323 #endif
    324 }
    325 
    326 } // namespace WebKit
    327