|
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 #if USE(V8) |
|
38 #include "ChromiumDataObject.h" |
|
39 #include "ClipboardChromium.h" |
|
40 #include "EventNames.h" |
|
41 #include "MouseEvent.h" |
|
42 #include "NPV8Object.h" // for PrivateIdentifier |
|
43 #include "Range.h" |
|
44 #include "V8BindingState.h" |
|
45 #include "V8DOMWrapper.h" |
|
46 #include "V8Event.h" |
|
47 #include "V8Helpers.h" |
|
48 #include "V8HiddenPropertyName.h" |
|
49 #include "V8NPUtils.h" |
|
50 #include "V8Proxy.h" |
|
51 #include "V8Range.h" |
|
52 #elif USE(JSC) |
|
53 #include "bridge/c/c_utility.h" |
|
54 #endif |
|
55 #include "WebDragData.h" |
|
56 #include "WebRange.h" |
|
57 |
|
58 #if USE(JAVASCRIPTCORE_BINDINGS) |
|
59 using JSC::Bindings::PrivateIdentifier; |
|
60 #endif |
|
61 |
|
62 using namespace WebCore; |
|
63 |
|
64 namespace WebKit { |
|
65 |
|
66 bool WebBindings::construct(NPP npp, NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant* result) |
|
67 { |
|
68 return _NPN_Construct(npp, npobj, args, argCount, result); |
|
69 } |
|
70 |
|
71 NPObject* WebBindings::createObject(NPP npp, NPClass* npClass) |
|
72 { |
|
73 return _NPN_CreateObject(npp, npClass); |
|
74 } |
|
75 |
|
76 bool WebBindings::enumerate(NPP id, NPObject* obj, NPIdentifier** identifier, uint32_t* val) |
|
77 { |
|
78 return _NPN_Enumerate(id, obj, identifier, val); |
|
79 } |
|
80 |
|
81 bool WebBindings::evaluate(NPP npp, NPObject* npObject, NPString* npScript, NPVariant* result) |
|
82 { |
|
83 return _NPN_Evaluate(npp, npObject, npScript, result); |
|
84 } |
|
85 |
|
86 bool WebBindings::evaluateHelper(NPP npp, bool popups_allowed, NPObject* npobj, NPString* npscript, NPVariant* result) |
|
87 { |
|
88 return _NPN_EvaluateHelper(npp, popups_allowed, npobj, npscript, result); |
|
89 } |
|
90 |
|
91 NPIdentifier WebBindings::getIntIdentifier(int32_t number) |
|
92 { |
|
93 return _NPN_GetIntIdentifier(number); |
|
94 } |
|
95 |
|
96 bool WebBindings::getProperty(NPP npp, NPObject* obj, NPIdentifier propertyName, NPVariant *result) |
|
97 { |
|
98 return _NPN_GetProperty(npp, obj, propertyName, result); |
|
99 } |
|
100 |
|
101 NPIdentifier WebBindings::getStringIdentifier(const NPUTF8* string) |
|
102 { |
|
103 return _NPN_GetStringIdentifier(string); |
|
104 } |
|
105 |
|
106 void WebBindings::getStringIdentifiers(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers) |
|
107 { |
|
108 _NPN_GetStringIdentifiers(names, nameCount, identifiers); |
|
109 } |
|
110 |
|
111 bool WebBindings::hasMethod(NPP npp, NPObject* npObject, NPIdentifier methodName) |
|
112 { |
|
113 return _NPN_HasMethod(npp, npObject, methodName); |
|
114 } |
|
115 |
|
116 bool WebBindings::hasProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName) |
|
117 { |
|
118 return _NPN_HasProperty(npp, npObject, propertyName); |
|
119 } |
|
120 |
|
121 bool WebBindings::identifierIsString(NPIdentifier identifier) |
|
122 { |
|
123 return _NPN_IdentifierIsString(identifier); |
|
124 } |
|
125 |
|
126 int32_t WebBindings::intFromIdentifier(NPIdentifier identifier) |
|
127 { |
|
128 return _NPN_IntFromIdentifier(identifier); |
|
129 } |
|
130 |
|
131 void WebBindings::initializeVariantWithStringCopy(NPVariant* variant, const NPString* value) |
|
132 { |
|
133 #if USE(V8) |
|
134 _NPN_InitializeVariantWithStringCopy(variant, value); |
|
135 #else |
|
136 NPN_InitializeVariantWithStringCopy(variant, value); |
|
137 #endif |
|
138 } |
|
139 |
|
140 bool WebBindings::invoke(NPP npp, NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) |
|
141 { |
|
142 return _NPN_Invoke(npp, npObject, methodName, arguments, argumentCount, result); |
|
143 } |
|
144 |
|
145 bool WebBindings::invokeDefault(NPP id, NPObject* obj, const NPVariant* args, uint32_t count, NPVariant* result) |
|
146 { |
|
147 return _NPN_InvokeDefault(id, obj, args, count, result); |
|
148 } |
|
149 |
|
150 void WebBindings::releaseObject(NPObject* npObject) |
|
151 { |
|
152 return _NPN_ReleaseObject(npObject); |
|
153 } |
|
154 |
|
155 void WebBindings::releaseVariantValue(NPVariant* variant) |
|
156 { |
|
157 _NPN_ReleaseVariantValue(variant); |
|
158 } |
|
159 |
|
160 bool WebBindings::removeProperty(NPP id, NPObject* object, NPIdentifier identifier) |
|
161 { |
|
162 return _NPN_RemoveProperty(id, object, identifier); |
|
163 } |
|
164 |
|
165 NPObject* WebBindings::retainObject(NPObject* npObject) |
|
166 { |
|
167 return _NPN_RetainObject(npObject); |
|
168 } |
|
169 |
|
170 void WebBindings::setException(NPObject* obj, const NPUTF8* message) |
|
171 { |
|
172 _NPN_SetException(obj, message); |
|
173 } |
|
174 |
|
175 bool WebBindings::setProperty(NPP id, NPObject* obj, NPIdentifier identifier, const NPVariant* variant) |
|
176 { |
|
177 return _NPN_SetProperty(id, obj, identifier, variant); |
|
178 } |
|
179 |
|
180 void WebBindings::unregisterObject(NPObject* npObject) |
|
181 { |
|
182 #if USE(V8) |
|
183 _NPN_UnregisterObject(npObject); |
|
184 #endif |
|
185 } |
|
186 |
|
187 NPUTF8* WebBindings::utf8FromIdentifier(NPIdentifier identifier) |
|
188 { |
|
189 return _NPN_UTF8FromIdentifier(identifier); |
|
190 } |
|
191 |
|
192 void WebBindings::extractIdentifierData(const NPIdentifier& identifier, const NPUTF8*& string, int32_t& number, bool& isString) |
|
193 { |
|
194 PrivateIdentifier* priv = static_cast<PrivateIdentifier*>(identifier); |
|
195 if (!priv) { |
|
196 isString = false; |
|
197 number = 0; |
|
198 return; |
|
199 } |
|
200 |
|
201 isString = priv->isString; |
|
202 if (isString) |
|
203 string = priv->value.string; |
|
204 else |
|
205 number = priv->value.number; |
|
206 } |
|
207 |
|
208 #if USE(V8) |
|
209 |
|
210 static v8::Local<v8::Value> getEvent(const v8::Handle<v8::Context>& context) |
|
211 { |
|
212 return context->Global()->GetHiddenValue(V8HiddenPropertyName::event()); |
|
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 (!V8Range::info.equals(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 void WebBindings::pushExceptionHandler(ExceptionHandler handler, void* data) |
|
327 { |
|
328 WebCore::pushExceptionHandler(handler, data); |
|
329 } |
|
330 |
|
331 void WebBindings::popExceptionHandler() |
|
332 { |
|
333 WebCore::popExceptionHandler(); |
|
334 } |
|
335 |
|
336 } // namespace WebKit |