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