OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2000 Harri Porten (porten@kde.org) | 2 * Copyright (C) 2000 Harri Porten (porten@kde.org) |
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com) | 3 * Copyright (C) 2001 Peter Kelly (pmk@post.com) |
4 * Copyright (C) 2004-2006 Apple Computer, Inc. | 4 * Copyright (C) 2004-2006 Apple Computer, Inc. |
5 * Copyright (C) 2006 James G. Speth (speth@end.com) | 5 * Copyright (C) 2006 James G. Speth (speth@end.com) |
6 * Copyright (C) 2006 Samuel Weinig (sam@webkit.org) | 6 * Copyright (C) 2006 Samuel Weinig (sam@webkit.org) |
7 * Copyright 2007, 2008 Google Inc. All Rights Reserved. | 7 * Copyright 2007, 2008 Google Inc. All Rights Reserved. |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Lesser General Public | 10 * modify it under the terms of the GNU Lesser General Public |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 #include "V8SVGPODTypeWrapper.h" | 113 #include "V8SVGPODTypeWrapper.h" |
114 #include "SVGElementInstance.h" | 114 #include "SVGElementInstance.h" |
115 #include "SVGException.h" | 115 #include "SVGException.h" |
116 #include "SVGPathSeg.h" | 116 #include "SVGPathSeg.h" |
117 #endif | 117 #endif |
118 | 118 |
119 #include "Navigator.h" | 119 #include "Navigator.h" |
120 | 120 |
121 namespace WebCore { | 121 namespace WebCore { |
122 | 122 |
123 class V8ScheduledAction : public ScheduledAction { | |
124 public: | |
125 V8ScheduledAction(v8::Handle<v8::Function> func, int argc, | |
126 v8::Handle<v8::Value> argv[]); | |
127 explicit V8ScheduledAction(const WebCore::String& code) : m_argc(0), | |
128 m_argv(0), m_code(code) { } | |
129 virtual ~V8ScheduledAction(); | |
130 virtual void execute(ScriptExecutionContext* window); | |
131 | |
132 private: | |
133 v8::Persistent<v8::Function> m_func; | |
134 int m_argc; | |
135 v8::Persistent<v8::Value>* m_argv; | |
136 | |
137 ScriptSourceCode m_code; | |
138 }; | |
139 | |
140 V8ScheduledAction::V8ScheduledAction(v8::Handle<v8::Function> func, int argc, | |
141 v8::Handle<v8::Value> argv[]) | |
142 : m_code(String(), KURL(), 0) { | |
143 m_func = v8::Persistent<v8::Function>::New(func); | |
144 | |
145 #ifndef NDEBUG | |
146 V8Proxy::RegisterGlobalHandle(SCHEDULED_ACTION, this, m_func); | |
147 #endif | |
148 | |
149 m_argc = argc; | |
150 if (argc > 0) { | |
151 m_argv = new v8::Persistent<v8::Value>[argc]; | |
152 for (int i = 0; i < argc; i++) { | |
153 m_argv[i] = v8::Persistent<v8::Value>::New(argv[i]); | |
154 | |
155 #ifndef NDEBUG | |
156 V8Proxy::RegisterGlobalHandle(SCHEDULED_ACTION, this, m_argv[i]); | |
157 #endif | |
158 } | |
159 } else { | |
160 m_argv = NULL; | |
161 } | |
162 } | |
163 | |
164 | |
165 V8ScheduledAction::~V8ScheduledAction() { | |
166 if (!m_func.IsEmpty()) { | |
167 #ifndef NDEBUG | |
168 V8Proxy::UnregisterGlobalHandle(this, m_func); | |
169 #endif | |
170 m_func.Dispose(); | |
171 | |
172 for (int i = 0; i < m_argc; i++) { | |
173 #ifndef NDEBUG | |
174 V8Proxy::UnregisterGlobalHandle(this, m_argv[i]); | |
175 #endif | |
176 m_argv[i].Dispose(); | |
177 } | |
178 if (m_argc > 0) { | |
179 delete[] m_argv; | |
180 } | |
181 } | |
182 } | |
183 | |
184 | |
185 void V8ScheduledAction::execute(ScriptExecutionContext* script_context) { | |
186 // TODO(ager): Timeouts for running the javascript code are not set. | |
187 V8Proxy* proxy = V8Proxy::retrieve(script_context); | |
188 if (!proxy) return; | |
189 | |
190 v8::HandleScope handle_scope; | |
191 v8::Local<v8::Context> context = proxy->GetContext(); | |
192 if (context.IsEmpty()) return; // JS may not be enabled. | |
193 | |
194 v8::Context::Scope scope(context); | |
195 | |
196 proxy->setTimerCallback(true); | |
197 | |
198 if (!m_func.IsEmpty() && m_func->IsFunction()) { | |
199 proxy->CallFunction(v8::Persistent<v8::Function>::Cast(m_func), | |
200 context->Global(), m_argc, m_argv); | |
201 } else { | |
202 proxy->Evaluate(m_code.url(), m_code.startLine() - 1, m_code.source(), 0); | |
203 } | |
204 | |
205 if (script_context->isDocument()) { | |
206 Document* doc = static_cast<Document*>(script_context); | |
207 doc->updateRendering(); | |
208 } | |
209 | |
210 proxy->setTimerCallback(false); | |
211 } | |
212 | |
213 | |
214 CALLBACK_FUNC_DECL(DOMParserConstructor) { | |
215 INC_STATS("DOM.DOMParser.Contructor"); | |
216 return V8Proxy::ConstructDOMObject<V8ClassIndex::DOMPARSER, | |
217 DOMParser>(args); | |
218 } | |
219 | |
220 CALLBACK_FUNC_DECL(MessageChannelConstructor) { | |
221 INC_STATS("DOM.MessageChannel.Constructor"); | |
222 if (!args.IsConstructCall()) { | |
223 V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, | |
224 "DOM object constructor cannot be called as a function."); | |
225 return v8::Undefined(); | |
226 } | |
227 | |
228 // Get the document. | |
229 Frame* frame = V8Proxy::retrieveFrame(); | |
230 if (!frame) | |
231 return v8::Undefined(); | |
232 Document* document = frame->document(); | |
233 | |
234 // Note: it's OK to let this RefPtr go out of scope because we also call | |
235 // SetDOMWrapper(), which effectively holds a reference to obj. | |
236 RefPtr<MessageChannel> obj = MessageChannel::create(document); | |
237 | |
238 // Create wrappers for the two associated MessagePorts. | |
239 v8::Handle<v8::Value> port1_wrapper = | |
240 V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, obj->port1()); | |
241 v8::Handle<v8::Value> port2_wrapper = | |
242 V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, obj->port2()); | |
243 | |
244 v8::Handle<v8::Object> wrapper_object = args.Holder(); | |
245 | |
246 // Setup the standard wrapper object internal fields. | |
247 V8Proxy::SetDOMWrapper( | |
248 wrapper_object, V8ClassIndex::MESSAGECHANNEL, obj.get()); | |
249 | |
250 obj->ref(); | |
251 V8Proxy::SetJSWrapperForDOMObject( | |
252 obj.get(), v8::Persistent<v8::Object>::New(wrapper_object)); | |
253 | |
254 // Create references from the MessageChannel wrapper to the two | |
255 // MessagePort wrappers to make sure that the MessagePort wrappers | |
256 // stay alive as long as the MessageChannel wrapper is around. | |
257 wrapper_object->SetInternalField(kMessageChannelPort1Index, port1_wrapper); | |
258 wrapper_object->SetInternalField(kMessageChannelPort2Index, port2_wrapper); | |
259 | |
260 // Return the wrapper object which will be the result of the call to | |
261 // new. | |
262 return wrapper_object; | |
263 } | |
264 | |
265 | |
266 CALLBACK_FUNC_DECL(WebKitCSSMatrixConstructor) { | |
267 INC_STATS("DOM.WebKitCSSMatrix.Constructor"); | |
268 String s; | |
269 if (args.Length() >= 1) | |
270 s = ToWebCoreString(args[0]); | |
271 | |
272 // Create the matrix. | |
273 ExceptionCode ec = 0; | |
274 RefPtr<WebKitCSSMatrix> matrix = WebKitCSSMatrix::create(s, ec); | |
275 if (ec != 0) { | |
276 V8Proxy::SetDOMException(ec); | |
277 return v8::Undefined(); | |
278 } | |
279 | |
280 // Transform the holder into a wrapper object for the matrix. | |
281 V8Proxy::SetDOMWrapper(args.Holder(), | |
282 V8ClassIndex::ToInt(V8ClassIndex::WEBKITCSSMATRIX), | |
283 matrix.get()); | |
284 // Add the wrapper to the DOM object map. | |
285 matrix->ref(); | |
286 V8Proxy::SetJSWrapperForDOMObject( | |
287 matrix.get(), | |
288 v8::Persistent<v8::Object>::New(args.Holder())); | |
289 return args.Holder(); | |
290 } | |
291 | |
292 CALLBACK_FUNC_DECL(WebKitPointConstructor) { | 123 CALLBACK_FUNC_DECL(WebKitPointConstructor) { |
293 INC_STATS("DOM.WebKitPoint.Constructor"); | 124 INC_STATS("DOM.WebKitPoint.Constructor"); |
294 return V8Proxy::ConstructDOMObject<V8ClassIndex::WEBKITPOINT, | 125 return V8Proxy::ConstructDOMObject<V8ClassIndex::WEBKITPOINT, |
295 WebKitPoint>(args); | 126 WebKitPoint>(args); |
296 } | 127 } |
297 | 128 |
298 CALLBACK_FUNC_DECL(XMLSerializerConstructor) { | |
299 INC_STATS("DOM.XMLSerializer.Constructor"); | |
300 return V8Proxy::ConstructDOMObject<V8ClassIndex::XMLSERIALIZER, | |
301 XMLSerializer>(args); | |
302 } | |
303 | |
304 | |
305 CALLBACK_FUNC_DECL(XPathEvaluatorConstructor) { | |
306 INC_STATS("DOM.XPathEvaluator.Constructor"); | |
307 return V8Proxy::ConstructDOMObject<V8ClassIndex::XPATHEVALUATOR, | |
308 XPathEvaluator>(args); | |
309 } | |
310 | |
311 | |
312 CALLBACK_FUNC_DECL(XSLTProcessorConstructor) { | |
313 INC_STATS("DOM.XSLTProcessor.Constructor"); | |
314 return V8Proxy::ConstructDOMObject<V8ClassIndex::XSLTPROCESSOR, | |
315 XSLTProcessor>(args); | |
316 } | |
317 | |
318 | |
319 CALLBACK_FUNC_DECL(XSLTProcessorImportStylesheet) { | |
320 INC_STATS("DOM.XSLTProcessor.importStylesheet"); | |
321 // Return undefined if argument does not have the correct type. | |
322 if (!V8Node::HasInstance(args[0])) | |
323 return v8::Undefined(); | |
324 | |
325 XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>( | |
326 V8ClassIndex::XSLTPROCESSOR, args.Holder()); | |
327 | |
328 Node* node = V8Proxy::DOMWrapperToNode<Node>(args[0]); | |
329 imp->importStylesheet(node); | |
330 return v8::Undefined(); | |
331 } | |
332 | |
333 | |
334 CALLBACK_FUNC_DECL(XSLTProcessorTransformToFragment) { | |
335 INC_STATS("DOM.XSLTProcessor.transformToFragment"); | |
336 // Return undefined if arguments do not have correct types. | |
337 if (!V8Node::HasInstance(args[0]) || !V8Document::HasInstance(args[1])) | |
338 return v8::Undefined(); | |
339 | |
340 XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>( | |
341 V8ClassIndex::XSLTPROCESSOR, args.Holder()); | |
342 | |
343 Node* source = V8Proxy::DOMWrapperToNode<Node>(args[0]); | |
344 Document* owner = | |
345 V8Proxy::DOMWrapperToNode<Document>(args[1]); | |
346 RefPtr<DocumentFragment> result = imp->transformToFragment(source, owner); | |
347 return V8Proxy::NodeToV8Object(result.get()); | |
348 } | |
349 | |
350 | |
351 CALLBACK_FUNC_DECL(XSLTProcessorTransformToDocument) { | |
352 INC_STATS("DOM.XSLTProcessor.transformToDocument"); | |
353 // Return undefined if argument does not have the correct type. | |
354 if (!V8Node::HasInstance(args[0])) | |
355 return v8::Undefined(); | |
356 | |
357 XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>( | |
358 V8ClassIndex::XSLTPROCESSOR, args.Holder()); | |
359 | |
360 Node* source = V8Proxy::DOMWrapperToNode<Node>(args[0]); | |
361 if (!source) | |
362 return v8::Undefined(); | |
363 RefPtr<Document> result = imp->transformToDocument(source); | |
364 // Return undefined if no result was found. | |
365 if (!result) | |
366 return v8::Undefined(); | |
367 return V8Proxy::NodeToV8Object(result.get()); | |
368 } | |
369 | |
370 | |
371 CALLBACK_FUNC_DECL(XSLTProcessorSetParameter) { | |
372 INC_STATS("DOM.XSLTProcessor.setParameter"); | |
373 // Bail out if localName or value is null or undefined. | |
374 if (args[1]->IsNull() || args[1]->IsUndefined() || | |
375 args[2]->IsNull() || args[2]->IsUndefined()) { | |
376 return v8::Undefined(); | |
377 } | |
378 | |
379 XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>( | |
380 V8ClassIndex::XSLTPROCESSOR, args.Holder()); | |
381 | |
382 String namespaceURI = ToWebCoreString(args[0]); | |
383 String localName = ToWebCoreString(args[1]); | |
384 String value = ToWebCoreString(args[2]); | |
385 imp->setParameter(namespaceURI, localName, value); | |
386 return v8::Undefined(); | |
387 } | |
388 | |
389 | |
390 CALLBACK_FUNC_DECL(XSLTProcessorGetParameter) { | |
391 INC_STATS("DOM.XSLTProcessor.getParameter"); | |
392 // Bail out if localName is null or undefined. | |
393 if (args[1]->IsNull() || args[1]->IsUndefined()) { | |
394 return v8::Undefined(); | |
395 } | |
396 | |
397 XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>( | |
398 V8ClassIndex::XSLTPROCESSOR, args.Holder()); | |
399 | |
400 String namespaceURI = ToWebCoreString(args[0]); | |
401 String localName = ToWebCoreString(args[1]); | |
402 String result = imp->getParameter(namespaceURI, localName); | |
403 // Return undefined if the string is null. | |
404 if (result.isNull()) return v8::Undefined(); | |
405 return v8String(result); | |
406 } | |
407 | |
408 | |
409 CALLBACK_FUNC_DECL(XSLTProcessorRemoveParameter) { | |
410 INC_STATS("DOM.XSLTProcessor.removeParameter"); | |
411 // Bail out if localName is null or undefined. | |
412 if (args[1]->IsNull() || args[1]->IsUndefined()) | |
413 return v8::Undefined(); | |
414 | |
415 XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>( | |
416 V8ClassIndex::XSLTPROCESSOR, args.Holder()); | |
417 | |
418 String namespaceURI = ToWebCoreString(args[0]); | |
419 String localName = ToWebCoreString(args[1]); | |
420 imp->removeParameter(namespaceURI, localName); | |
421 return v8::Undefined(); | |
422 } | |
423 | |
424 | |
425 // ---- Canvas support ---- | |
426 static v8::Handle<v8::Value> CanvasStyleToV8Object(CanvasStyle* style) { | |
427 if (style->canvasGradient()) { | |
428 return V8Proxy::ToV8Object(V8ClassIndex::CANVASGRADIENT, | |
429 style->canvasGradient()); | |
430 } | |
431 if (style->canvasPattern()) { | |
432 return V8Proxy::ToV8Object(V8ClassIndex::CANVASPATTERN, | |
433 style->canvasPattern()); | |
434 } | |
435 return v8String(style->color()); | |
436 } | |
437 | |
438 static PassRefPtr<CanvasStyle> V8ObjectToCanvasStyle(v8::Handle<v8::Value> value
) | |
439 { | |
440 if (value->IsString()) | |
441 return CanvasStyle::create(ToWebCoreString(value)); | |
442 | |
443 if (V8CanvasGradient::HasInstance(value)) { | |
444 CanvasGradient* gradient = | |
445 V8Proxy::DOMWrapperToNative<CanvasGradient>(value); | |
446 return CanvasStyle::create(gradient); | |
447 } | |
448 | |
449 if (V8CanvasPattern::HasInstance(value)) { | |
450 CanvasPattern* pattern = | |
451 V8Proxy::DOMWrapperToNative<CanvasPattern>(value); | |
452 return CanvasStyle::create(pattern); | |
453 } | |
454 | |
455 return 0; | |
456 } | |
457 | |
458 | |
459 ACCESSOR_GETTER(CanvasRenderingContext2DStrokeStyle) { | |
460 CanvasRenderingContext2D* impl = | |
461 V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder()); | |
462 CanvasStyle* strokeStyle = impl->strokeStyle(); | |
463 return CanvasStyleToV8Object(strokeStyle); | |
464 } | |
465 | |
466 | |
467 ACCESSOR_SETTER(CanvasRenderingContext2DStrokeStyle) { | |
468 CanvasRenderingContext2D* impl = | |
469 V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder()); | |
470 impl->setStrokeStyle(V8ObjectToCanvasStyle(value)); | |
471 } | |
472 | |
473 ACCESSOR_GETTER(CanvasRenderingContext2DFillStyle) { | |
474 CanvasRenderingContext2D* impl = | |
475 V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder()); | |
476 CanvasStyle* fillStyle = impl->fillStyle(); | |
477 return CanvasStyleToV8Object(fillStyle); | |
478 } | |
479 | |
480 | |
481 ACCESSOR_SETTER(CanvasRenderingContext2DFillStyle) { | |
482 CanvasRenderingContext2D* impl = | |
483 V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder()); | |
484 impl->setFillStyle(V8ObjectToCanvasStyle(value)); | |
485 } | |
486 | |
487 | |
488 // DOMImplementation is a singleton in WebCore. If we use our normal | 129 // DOMImplementation is a singleton in WebCore. If we use our normal |
489 // mapping from DOM objects to V8 wrappers, the same wrapper will be | 130 // mapping from DOM objects to V8 wrappers, the same wrapper will be |
490 // shared for all frames in the same process. This is a major | 131 // shared for all frames in the same process. This is a major |
491 // security problem. Therefore, we generate a DOMImplementation | 132 // security problem. Therefore, we generate a DOMImplementation |
492 // wrapper per document and store it in an internal field of the | 133 // wrapper per document and store it in an internal field of the |
493 // document. Since the DOMImplementation object is a singleton, we do | 134 // document. Since the DOMImplementation object is a singleton, we do |
494 // not have to do anything to keep the DOMImplementation object alive | 135 // not have to do anything to keep the DOMImplementation object alive |
495 // for the lifetime of the wrapper. | 136 // for the lifetime of the wrapper. |
496 ACCESSOR_GETTER(DocumentImplementation) { | 137 ACCESSOR_GETTER(DocumentImplementation) { |
497 ASSERT(info.Holder()->InternalFieldCount() >= | 138 ASSERT(info.Holder()->InternalFieldCount() >= |
(...skipping 29 matching lines...) Expand all Loading... |
527 Document* imp = V8Proxy::DOMWrapperToNative<Document>(info.Holder()); | 168 Document* imp = V8Proxy::DOMWrapperToNative<Document>(info.Holder()); |
528 if (!imp->frame()) | 169 if (!imp->frame()) |
529 return; | 170 return; |
530 | 171 |
531 DOMWindow* window = imp->frame()->domWindow(); | 172 DOMWindow* window = imp->frame()->domWindow(); |
532 // WindowSetLocation does security checks. // XXXMB- verify! | 173 // WindowSetLocation does security checks. // XXXMB- verify! |
533 WindowSetLocation(window, ToWebCoreString(value)); | 174 WindowSetLocation(window, ToWebCoreString(value)); |
534 } | 175 } |
535 | 176 |
536 | 177 |
537 ACCESSOR_GETTER(EventSrcElement) { | |
538 Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder()); | |
539 EventTarget* target = event->target(); | |
540 return V8Proxy::EventTargetToV8Object(target); | |
541 } | |
542 | |
543 | |
544 ACCESSOR_GETTER(EventReturnValue) { | |
545 Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder()); | |
546 return event->defaultPrevented() ? v8::False() : v8::True(); | |
547 } | |
548 | |
549 | |
550 ACCESSOR_SETTER(EventReturnValue) { | |
551 Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder()); | |
552 bool v = value->BooleanValue(); | |
553 event->setDefaultPrevented(!v); | |
554 } | |
555 | |
556 | |
557 ACCESSOR_GETTER(EventDataTransfer) { | |
558 Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder()); | |
559 | |
560 if (event->isDragEvent()) { | |
561 MouseEvent* impl = static_cast<MouseEvent*>(event); | |
562 Clipboard* clipboard = impl->clipboard(); | |
563 return V8Proxy::ToV8Object(V8ClassIndex::CLIPBOARD, clipboard); | |
564 } | |
565 | |
566 return v8::Undefined(); | |
567 } | |
568 | |
569 | |
570 ACCESSOR_GETTER(EventClipboardData) { | |
571 Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder()); | |
572 | |
573 if (event->isClipboardEvent()) { | |
574 ClipboardEvent* impl = static_cast<ClipboardEvent*>(event); | |
575 Clipboard* clipboard = impl->clipboard(); | |
576 return V8Proxy::ToV8Object(V8ClassIndex::CLIPBOARD, clipboard); | |
577 } | |
578 | |
579 return v8::Undefined(); | |
580 } | |
581 | |
582 | |
583 INDEXED_PROPERTY_GETTER(DOMStringList) { | |
584 INC_STATS("DOM.DOMStringList.IndexedPropertyGetter"); | |
585 DOMStringList* imp = | |
586 V8Proxy::DOMWrapperToNative<DOMStringList>(info.Holder()); | |
587 return v8String(imp->item(index)); | |
588 } | |
589 | |
590 | |
591 CALLBACK_FUNC_DECL(DOMStringListItem) { | |
592 INC_STATS("DOM.DOMStringListItem()"); | |
593 if (args.Length() == 0) | |
594 return v8::Null(); | |
595 uint32_t index = args[0]->Uint32Value(); | |
596 | |
597 DOMStringList* imp = | |
598 V8Proxy::DOMWrapperToNative<DOMStringList>(args.Holder()); | |
599 if (index >= imp->length()) | |
600 return v8::Null(); | |
601 | |
602 return v8String(imp->item(index)); | |
603 } | |
604 | |
605 | |
606 NAMED_PROPERTY_DELETER(HTMLDocument) { | |
607 // Only handle document.all. Insert the marker object into the | |
608 // shadow internal field to signal that document.all is no longer | |
609 // shadowed. | |
610 String key = ToWebCoreString(name); | |
611 if (key == "all") { | |
612 ASSERT(info.Holder()->InternalFieldCount() == | |
613 kHTMLDocumentInternalFieldCount); | |
614 v8::Local<v8::Value> marker = | |
615 info.Holder()->GetInternalField(kHTMLDocumentMarkerIndex); | |
616 info.Holder()->SetInternalField(kHTMLDocumentShadowIndex, marker); | |
617 return v8::True(); | |
618 } | |
619 return v8::Handle<v8::Boolean>(); | |
620 } | |
621 | |
622 | |
623 NAMED_PROPERTY_SETTER(HTMLDocument) | |
624 { | |
625 INC_STATS("DOM.HTMLDocument.NamedPropertySetter"); | |
626 // Only handle document.all. We insert the value into the shadow | |
627 // internal field from which the getter will retrieve it. | |
628 String key = ToWebCoreString(name); | |
629 if (key == "all") { | |
630 ASSERT(info.Holder()->InternalFieldCount() == | |
631 kHTMLDocumentInternalFieldCount); | |
632 info.Holder()->SetInternalField(kHTMLDocumentShadowIndex, value); | |
633 } | |
634 return v8::Handle<v8::Value>(); | |
635 } | |
636 | |
637 | |
638 NAMED_PROPERTY_GETTER(HTMLDocument) | |
639 { | |
640 INC_STATS("DOM.HTMLDocument.NamedPropertyGetter"); | |
641 AtomicString key = ToWebCoreString(name); | |
642 | |
643 // Special case for document.all. If the value in the shadow | |
644 // internal field is not the marker object, then document.all has | |
645 // been temporarily shadowed and we return the value. | |
646 if (key == "all") { | |
647 ASSERT(info.Holder()->InternalFieldCount() == kHTMLDocumentInternalField
Count); | |
648 v8::Local<v8::Value> marker = info.Holder()->GetInternalField(kHTMLDocum
entMarkerIndex); | |
649 v8::Local<v8::Value> value = info.Holder()->GetInternalField(kHTMLDocume
ntShadowIndex); | |
650 if (marker != value) | |
651 return value; | |
652 } | |
653 | |
654 HTMLDocument* imp = V8Proxy::DOMWrapperToNode<HTMLDocument>(info.Holder()); | |
655 | |
656 // Fast case for named elements that are not there. | |
657 if (!imp->hasNamedItem(key.impl()) && !imp->hasExtraNamedItem(key.impl())) | |
658 return v8::Handle<v8::Value>(); | |
659 | |
660 RefPtr<HTMLCollection> items = imp->documentNamedItems(key); | |
661 if (items->length() == 0) | |
662 return v8::Handle<v8::Value>(); | |
663 if (items->length() == 1) { | |
664 Node* node = items->firstItem(); | |
665 Frame* frame = 0; | |
666 if (node->hasTagName(HTMLNames::iframeTag) && | |
667 (frame = static_cast<HTMLIFrameElement*>(node)->contentFrame())) | |
668 return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow
()); | |
669 return V8Proxy::NodeToV8Object(node); | |
670 } | |
671 return V8Proxy::ToV8Object(V8ClassIndex::HTMLCOLLECTION, items.get()); | |
672 } | |
673 | |
674 | |
675 NAMED_PROPERTY_GETTER(HTMLFrameSetElement) | |
676 { | |
677 INC_STATS("DOM.HTMLFrameSetElement.NamedPropertyGetter"); | |
678 HTMLFrameSetElement* imp = | |
679 V8Proxy::DOMWrapperToNode<HTMLFrameSetElement>(info.Holder()); | |
680 String key = ToWebCoreString(name); | |
681 Node* frame = imp->children()->namedItem(key); | |
682 if (frame && frame->hasTagName(HTMLNames::frameTag)) { | |
683 Document* doc = static_cast<HTMLFrameElement*>(frame)->contentDocument(); | |
684 if (doc) { | |
685 Frame* content_frame = doc->frame(); | |
686 if (content_frame) | |
687 return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, content_frame->domWi
ndow()); | |
688 } | |
689 return v8::Undefined(); | |
690 } | |
691 return v8::Handle<v8::Value>(); | |
692 } | |
693 | |
694 | |
695 INDEXED_PROPERTY_GETTER(NamedNodeMap) { | |
696 INC_STATS("DOM.NamedNodeMap.IndexedPropertyGetter"); | |
697 NamedNodeMap* imp = V8Proxy::ToNativeObject<NamedNodeMap>( | |
698 V8ClassIndex::NAMEDNODEMAP, info.Holder()); | |
699 RefPtr<Node> result = imp->item(index); | |
700 if (!result) return v8::Handle<v8::Value>(); | |
701 | |
702 return V8Proxy::NodeToV8Object(result.get()); | |
703 } | |
704 | |
705 NAMED_PROPERTY_GETTER(NamedNodeMap) { | |
706 INC_STATS("DOM.NamedNodeMap.NamedPropertyGetter"); | |
707 // Search the prototype chain first. | |
708 v8::Handle<v8::Value> value = | |
709 info.Holder()->GetRealNamedPropertyInPrototypeChain(name); | |
710 if (!value.IsEmpty()) | |
711 return value; | |
712 | |
713 // Then look for IDL defined properties on the object itself. | |
714 if (info.Holder()->HasRealNamedCallbackProperty(name)) | |
715 return v8::Handle<v8::Value>(); | |
716 | |
717 // Finally, search the DOM. | |
718 NamedNodeMap* imp = V8Proxy::ToNativeObject<NamedNodeMap>( | |
719 V8ClassIndex::NAMEDNODEMAP, info.Holder()); | |
720 String prop_name = ToWebCoreString(name); | |
721 RefPtr<Node> result = imp->getNamedItem(prop_name); | |
722 if (!result) return v8::Handle<v8::Value>(); | |
723 | |
724 return V8Proxy::NodeToV8Object(result.get()); | |
725 } | |
726 | |
727 | |
728 NAMED_PROPERTY_GETTER(NodeList) { | |
729 INC_STATS("DOM.NodeList.NamedPropertyGetter"); | |
730 NodeList* list = V8Proxy::ToNativeObject<NodeList>( | |
731 V8ClassIndex::NODELIST, info.Holder()); | |
732 String prop_name = ToWebCoreString(name); | |
733 | |
734 // Length property cannot be overridden. | |
735 if (prop_name == "length") | |
736 return v8::Number::New(list->length()); | |
737 | |
738 RefPtr<Node> result = list->itemWithName(prop_name); | |
739 if (result) | |
740 return V8Proxy::NodeToV8Object(result.get()); | |
741 | |
742 return v8::Handle<v8::Value>(); | |
743 } | |
744 | |
745 | |
746 INDEXED_PROPERTY_GETTER(HTMLFormElement) { | 178 INDEXED_PROPERTY_GETTER(HTMLFormElement) { |
747 INC_STATS("DOM.HTMLFormElement.IndexedPropertyGetter"); | 179 INC_STATS("DOM.HTMLFormElement.IndexedPropertyGetter"); |
748 HTMLFormElement* form = | 180 HTMLFormElement* form = |
749 V8Proxy::DOMWrapperToNode<HTMLFormElement>(info.Holder()); | 181 V8Proxy::DOMWrapperToNode<HTMLFormElement>(info.Holder()); |
750 | 182 |
751 RefPtr<Node> result = form->elements()->item(index); | 183 RefPtr<Node> result = form->elements()->item(index); |
752 if (!result) return v8::Handle<v8::Value>(); | 184 if (!result) return v8::Handle<v8::Value>(); |
753 return V8Proxy::NodeToV8Object(result.get()); | 185 return V8Proxy::NodeToV8Object(result.get()); |
754 } | 186 } |
755 | 187 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 } | 234 } |
803 | 235 |
804 | 236 |
805 INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection) { | 237 INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection) { |
806 INC_STATS("DOM.HTMLSelectElementCollection.IndexedPropertySetter"); | 238 INC_STATS("DOM.HTMLSelectElementCollection.IndexedPropertySetter"); |
807 HTMLSelectElement* select = | 239 HTMLSelectElement* select = |
808 V8Proxy::DOMWrapperToNode<HTMLSelectElement>(info.Holder()); | 240 V8Proxy::DOMWrapperToNode<HTMLSelectElement>(info.Holder()); |
809 return OptionsCollectionSetter(index, value, select); | 241 return OptionsCollectionSetter(index, value, select); |
810 } | 242 } |
811 | 243 |
812 // Check for a CSS prefix. | |
813 // Passed prefix is all lowercase. | |
814 // First character of the prefix within the property name may be upper or lowerc
ase. | |
815 // Other characters in the prefix within the property name must be lowercase. | |
816 // The prefix within the property name must be followed by a capital letter. | |
817 static bool hasCSSPropertyNamePrefix(const String& propertyName, const char* pre
fix) | |
818 { | |
819 #ifndef NDEBUG | |
820 ASSERT(*prefix); | |
821 for (const char* p = prefix; *p; ++p) | |
822 ASSERT(WTF::isASCIILower(*p)); | |
823 ASSERT(propertyName.length()); | |
824 #endif | |
825 | |
826 if (WTF::toASCIILower(propertyName[0]) != prefix[0]) | |
827 return false; | |
828 | |
829 unsigned length = propertyName.length(); | |
830 for (unsigned i = 1; i < length; ++i) { | |
831 if (!prefix[i]) | |
832 return WTF::isASCIIUpper(propertyName[i]); | |
833 if (propertyName[i] != prefix[i]) | |
834 return false; | |
835 } | |
836 return false; | |
837 } | |
838 | |
839 // When getting properties on CSSStyleDeclarations, the name used from | |
840 // Javascript and the actual name of the property are not the same, so | |
841 // we have to do the following translation. The translation turns upper | |
842 // case characters into lower case characters and inserts dashes to | |
843 // separate words. | |
844 // | |
845 // Example: 'backgroundPositionY' -> 'background-position-y' | |
846 // | |
847 // Also, certain prefixes such as 'pos', 'css-' and 'pixel-' are stripped | |
848 // and the pixel_or_pos_prefix out parameter is used to indicate whether or | |
849 // not the property name was prefixed with 'pos-' or 'pixel-'. | |
850 static String cssPropertyName(const String& propertyName, bool* hadPixelOrPosPre
fix = 0) | |
851 { | |
852 if (hadPixelOrPosPrefix) | |
853 *hadPixelOrPosPrefix = false; | |
854 | |
855 unsigned length = propertyName.length(); | |
856 if (!length) | |
857 return String(); | |
858 | |
859 Vector<UChar> name; | |
860 name.reserveCapacity(length); | |
861 | |
862 unsigned i = 0; | |
863 | |
864 if (hasCSSPropertyNamePrefix(propertyName, "css")) | |
865 i += 3; | |
866 else if (hasCSSPropertyNamePrefix(propertyName, "pixel")) { | |
867 i += 5; | |
868 if (hadPixelOrPosPrefix) | |
869 *hadPixelOrPosPrefix = true; | |
870 } else if (hasCSSPropertyNamePrefix(propertyName, "pos")) { | |
871 i += 3; | |
872 if (hadPixelOrPosPrefix) | |
873 *hadPixelOrPosPrefix = true; | |
874 } else if (hasCSSPropertyNamePrefix(propertyName, "webkit") | |
875 || hasCSSPropertyNamePrefix(propertyName, "khtml") | |
876 || hasCSSPropertyNamePrefix(propertyName, "apple")) | |
877 name.append('-'); | |
878 else { | |
879 if (WTF::isASCIIUpper(propertyName[0])) | |
880 return String(); | |
881 } | |
882 | |
883 name.append(WTF::toASCIILower(propertyName[i++])); | |
884 | |
885 for (; i < length; ++i) { | |
886 UChar c = propertyName[i]; | |
887 if (!WTF::isASCIIUpper(c)) | |
888 name.append(c); | |
889 else { | |
890 name.append('-'); | |
891 name.append(WTF::toASCIILower(c)); | |
892 } | |
893 } | |
894 | |
895 return String::adopt(name); | |
896 } | |
897 | |
898 NAMED_PROPERTY_GETTER(CSSStyleDeclaration) { | |
899 INC_STATS("DOM.CSSStyleDeclaration.NamedPropertyGetter"); | |
900 // First look for API defined attributes on the style declaration | |
901 // object. | |
902 if (info.Holder()->HasRealNamedCallbackProperty(name)) | |
903 return v8::Handle<v8::Value>(); | |
904 | |
905 // Search the style declaration. | |
906 CSSStyleDeclaration* imp = V8Proxy::ToNativeObject<CSSStyleDeclaration>( | |
907 V8ClassIndex::CSSSTYLEDECLARATION, info.Holder()); | |
908 | |
909 bool pixel_or_pos; | |
910 String p = ToWebCoreString(name); | |
911 String prop = cssPropertyName(p, &pixel_or_pos); | |
912 | |
913 // Do not handle non-property names. | |
914 if (!CSSStyleDeclaration::isPropertyName(prop)) { | |
915 return v8::Handle<v8::Value>(); | |
916 } | |
917 | |
918 RefPtr<CSSValue> v = imp->getPropertyCSSValue(prop); | |
919 if (v) { | |
920 if (pixel_or_pos && v->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) { | |
921 RefPtr<CSSPrimitiveValue> primitive_value = | |
922 static_pointer_cast<CSSPrimitiveValue>(v); | |
923 return v8::Number::New( | |
924 primitive_value->getFloatValue(CSSPrimitiveValue::CSS_PX)); | |
925 } | |
926 return v8StringOrNull(v->cssText()); | |
927 } | |
928 | |
929 String result = imp->getPropertyValue(prop); | |
930 if (result.isNull()) | |
931 result = ""; // convert null to empty string. | |
932 | |
933 // The 'filter' attribute is made undetectable in KJS/WebKit | |
934 // to avoid confusion with IE's filter extension. | |
935 if (prop == "filter") { | |
936 return v8UndetectableString(result); | |
937 } | |
938 return v8String(result); | |
939 } | |
940 | |
941 | |
942 NAMED_PROPERTY_SETTER(CSSStyleDeclaration) { | |
943 INC_STATS("DOM.CSSStyleDeclaration.NamedPropertySetter"); | |
944 CSSStyleDeclaration* imp = V8Proxy::ToNativeObject<CSSStyleDeclaration>( | |
945 V8ClassIndex::CSSSTYLEDECLARATION, info.Holder()); | |
946 String property_name = ToWebCoreString(name); | |
947 int ec = 0; | |
948 | |
949 bool pixel_or_pos; | |
950 String prop = cssPropertyName(property_name, &pixel_or_pos); | |
951 if (!CSSStyleDeclaration::isPropertyName(prop)) { | |
952 return v8::Handle<v8::Value>(); // do not block the call | |
953 } | |
954 | |
955 String prop_value = valueToStringWithNullCheck(value); | |
956 if (pixel_or_pos) prop_value += "px"; | |
957 imp->setProperty(prop, prop_value, ec); | |
958 | |
959 V8Proxy::SetDOMException(ec); | |
960 return value; | |
961 } | |
962 | |
963 | |
964 NAMED_PROPERTY_GETTER(StyleSheetList) { | |
965 INC_STATS("DOM.StyleSheetList.NamedPropertyGetter"); | |
966 // Look for local properties first. | |
967 if (info.Holder()->HasRealNamedProperty(name)) { | |
968 return v8::Handle<v8::Value>(); | |
969 } | |
970 | |
971 // Search style sheet. | |
972 StyleSheetList* imp = V8Proxy::ToNativeObject<StyleSheetList>( | |
973 V8ClassIndex::STYLESHEETLIST, info.Holder()); | |
974 String key = ToWebCoreString(name); | |
975 HTMLStyleElement* item = imp->getNamedItem(key); | |
976 if (item) { | |
977 return V8Proxy::ToV8Object(V8ClassIndex::HTMLSTYLEELEMENT, item); | |
978 } | |
979 return v8::Handle<v8::Value>(); | |
980 } | |
981 | |
982 | |
983 // CanvasRenderingContext2D ---------------------------------------------------- | 244 // CanvasRenderingContext2D ---------------------------------------------------- |
984 | 245 |
985 // Helper macro for converting v8 values into floats (expected by many of the | 246 // Helper macro for converting v8 values into floats (expected by many of the |
986 // canvas functions). | 247 // canvas functions). |
987 #define TO_FLOAT(a) static_cast<float>((a)->NumberValue()) | 248 #define TO_FLOAT(a) static_cast<float>((a)->NumberValue()) |
988 | 249 |
989 // TODO: SetStrokeColor and SetFillColor are similar except function names, | 250 // TODO: SetStrokeColor and SetFillColor are similar except function names, |
990 // consolidate them into one. | 251 // consolidate them into one. |
991 CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetStrokeColor) { | 252 CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetStrokeColor) { |
992 INC_STATS("DOM.CanvasRenderingContext2D.setStrokeColor()"); | 253 INC_STATS("DOM.CanvasRenderingContext2D.setStrokeColor()"); |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1389 } | 650 } |
1390 | 651 |
1391 if (ec != 0) { | 652 if (ec != 0) { |
1392 V8Proxy::SetDOMException(ec); | 653 V8Proxy::SetDOMException(ec); |
1393 return v8::Handle<v8::Value>(); | 654 return v8::Handle<v8::Value>(); |
1394 } | 655 } |
1395 | 656 |
1396 return v8::Undefined(); | 657 return v8::Undefined(); |
1397 } | 658 } |
1398 | 659 |
1399 | |
1400 // Clipboard ------------------------------------------------------------------- | |
1401 | |
1402 | |
1403 ACCESSOR_GETTER(ClipboardTypes) { | |
1404 INC_STATS("DOM.Clipboard.types()"); | |
1405 Clipboard* imp = | |
1406 V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, | |
1407 info.Holder()); | |
1408 | |
1409 HashSet<String> types = imp->types(); | |
1410 if (types.isEmpty()) | |
1411 return v8::Null(); | |
1412 | |
1413 v8::Local<v8::Array> result = v8::Array::New(types.size()); | |
1414 HashSet<String>::const_iterator end = types.end(); | |
1415 int index = 0; | |
1416 for (HashSet<String>::const_iterator it = types.begin(); | |
1417 it != end; | |
1418 ++it, ++index) { | |
1419 result->Set(v8::Integer::New(index), v8String(*it)); | |
1420 } | |
1421 return result; | |
1422 } | |
1423 | |
1424 | |
1425 CALLBACK_FUNC_DECL(ClipboardClearData) { | |
1426 INC_STATS("DOM.Clipboard.clearData()"); | |
1427 Clipboard* imp = V8Proxy::ToNativeObject<Clipboard>( | |
1428 V8ClassIndex::CLIPBOARD, args.Holder()); | |
1429 | |
1430 if (args.Length() == 0) { | |
1431 imp->clearAllData(); | |
1432 return v8::Undefined(); | |
1433 } | |
1434 | |
1435 if (args.Length() == 1) { | |
1436 String v = ToWebCoreString(args[0]); | |
1437 imp->clearData(v); | |
1438 return v8::Undefined(); | |
1439 } | |
1440 | |
1441 V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, | |
1442 "clearData: Invalid number of arguments"); | |
1443 return v8::Undefined(); | |
1444 } | |
1445 | |
1446 | |
1447 CALLBACK_FUNC_DECL(ClipboardGetData) { | |
1448 INC_STATS("DOM.Clipboard.getData()"); | |
1449 Clipboard* imp = V8Proxy::ToNativeObject<Clipboard>( | |
1450 V8ClassIndex::CLIPBOARD, args.Holder()); | |
1451 | |
1452 if (args.Length() != 1) { | |
1453 V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, | |
1454 "getData: Invalid number of arguments"); | |
1455 return v8::Undefined(); | |
1456 } | |
1457 | |
1458 bool success; | |
1459 String v = ToWebCoreString(args[0]); | |
1460 String result = imp->getData(v, success); | |
1461 if (success) return v8String(result); | |
1462 return v8::Undefined(); | |
1463 } | |
1464 | |
1465 CALLBACK_FUNC_DECL(ClipboardSetData) { | |
1466 INC_STATS("DOM.Clipboard.setData()"); | |
1467 Clipboard* imp = V8Proxy::ToNativeObject<Clipboard>( | |
1468 V8ClassIndex::CLIPBOARD, args.Holder()); | |
1469 | |
1470 if (args.Length() != 2) { | |
1471 V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, | |
1472 "setData: Invalid number of arguments"); | |
1473 return v8::Undefined(); | |
1474 } | |
1475 | |
1476 String type = ToWebCoreString(args[0]); | |
1477 String data = ToWebCoreString(args[1]); | |
1478 bool result = imp->setData(type, data); | |
1479 return result ? v8::True() : v8::False(); | |
1480 } | |
1481 | |
1482 | |
1483 CALLBACK_FUNC_DECL(ClipboardSetDragImage) { | |
1484 INC_STATS("DOM.Clipboard.setDragImage()"); | |
1485 Clipboard* imp = V8Proxy::ToNativeObject<Clipboard>( | |
1486 V8ClassIndex::CLIPBOARD, args.Holder()); | |
1487 | |
1488 if (!imp->isForDragging()) | |
1489 return v8::Undefined(); | |
1490 | |
1491 if (args.Length() != 3) { | |
1492 V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, | |
1493 "setDragImage: Invalid number of arguments"); | |
1494 return v8::Undefined(); | |
1495 } | |
1496 | |
1497 int x = ToInt32(args[1]); | |
1498 int y = ToInt32(args[2]); | |
1499 | |
1500 Node* node = 0; | |
1501 if (V8Node::HasInstance(args[0])) | |
1502 node = V8Proxy::DOMWrapperToNode<Node>(args[0]); | |
1503 if (!node) { | |
1504 V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, | |
1505 "setDragImageFromElement: Invalid first argument"); | |
1506 return v8::Undefined(); | |
1507 } | |
1508 | |
1509 if (!node->isElementNode()) { | |
1510 V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, | |
1511 "setDragImageFromElement: Invalid first argument"); | |
1512 return v8::Undefined(); | |
1513 } | |
1514 | |
1515 if (static_cast<Element*>(node)->hasLocalName(HTMLNames::imgTag) && | |
1516 !node->inDocument()) | |
1517 imp->setDragImage(static_cast<HTMLImageElement*>(node)->cachedImage(), | |
1518 IntPoint(x, y)); | |
1519 else | |
1520 imp->setDragImageElement(node, IntPoint(x, y)); | |
1521 | |
1522 return v8::Undefined(); | |
1523 } | |
1524 | |
1525 | |
1526 static bool AllowSettingSrcToJavascriptURL(Element* element, String name, | 660 static bool AllowSettingSrcToJavascriptURL(Element* element, String name, |
1527 String value) { | 661 String value) { |
1528 // Need to parse value as URL first in order to check its protocol. | 662 // Need to parse value as URL first in order to check its protocol. |
1529 // " javascript:", "java\0script:", "javascript\t:", "javascript\1:" | 663 // " javascript:", "java\0script:", "javascript\t:", "javascript\1:" |
1530 // are all parsed as "javascript:" url. | 664 // are all parsed as "javascript:" url. |
1531 // When changing location in HTMLFrameElement, value is parsed as url. | 665 // When changing location in HTMLFrameElement, value is parsed as url. |
1532 // We must match the behavior there. | 666 // We must match the behavior there. |
1533 // See issue 804099. | 667 // See issue 804099. |
1534 // | 668 // |
1535 // parseURL is defined in CSSHelper.cpp. | 669 // parseURL is defined in CSSHelper.cpp. |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1729 | 863 |
1730 int id; | 864 int id; |
1731 if (function->IsString()) { | 865 if (function->IsString()) { |
1732 // Don't allow setting timeouts to run empty functions! | 866 // Don't allow setting timeouts to run empty functions! |
1733 // (Bug 1009597) | 867 // (Bug 1009597) |
1734 WebCore::String string_function = ToWebCoreString(function); | 868 WebCore::String string_function = ToWebCoreString(function); |
1735 if (string_function.length() == 0) | 869 if (string_function.length() == 0) |
1736 return v8::Undefined(); | 870 return v8::Undefined(); |
1737 | 871 |
1738 id = DOMTimer::install(script_context, | 872 id = DOMTimer::install(script_context, |
1739 new V8ScheduledAction(string_function), timeout, | 873 new ScheduledAction(string_function), timeout, |
1740 single_shot); | 874 single_shot); |
1741 } else if (function->IsFunction()) { | 875 } else if (function->IsFunction()) { |
1742 int param_count = num_arguments >= 2 ? num_arguments - 2 : 0; | 876 int param_count = num_arguments >= 2 ? num_arguments - 2 : 0; |
1743 v8::Local<v8::Value>* params = 0; | 877 v8::Local<v8::Value>* params = 0; |
1744 if (param_count > 0) { | 878 if (param_count > 0) { |
1745 params = new v8::Local<v8::Value>[param_count]; | 879 params = new v8::Local<v8::Value>[param_count]; |
1746 for (int i = 0; i < param_count; i++) | 880 for (int i = 0; i < param_count; i++) |
1747 // parameters must be globalized | 881 // parameters must be globalized |
1748 params[i] = args[i+2]; | 882 params[i] = args[i+2]; |
1749 } | 883 } |
1750 | 884 |
1751 // params is passed to action, and released in action's destructor | 885 // params is passed to action, and released in action's destructor |
1752 ScheduledAction* action = new V8ScheduledAction( | 886 ScheduledAction* action = new ScheduledAction( |
1753 v8::Handle<v8::Function>::Cast(function), param_count, params); | 887 v8::Handle<v8::Function>::Cast(function), param_count, params); |
1754 | 888 |
1755 delete[] params; | 889 delete[] params; |
1756 | 890 |
1757 id = DOMTimer::install(script_context, action, timeout, single_shot); | 891 id = DOMTimer::install(script_context, action, timeout, single_shot); |
1758 } else { | 892 } else { |
1759 // TODO(fqian): what's the right return value if failed. | 893 // TODO(fqian): what's the right return value if failed. |
1760 return v8::Undefined(); | 894 return v8::Undefined(); |
1761 } | 895 } |
1762 return v8::Integer::New(id); | 896 return v8::Integer::New(id); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1960 return args.This()->ObjectProtoToString(); | 1094 return args.This()->ObjectProtoToString(); |
1961 } | 1095 } |
1962 | 1096 |
1963 CALLBACK_FUNC_DECL(DOMWindowNOP) | 1097 CALLBACK_FUNC_DECL(DOMWindowNOP) |
1964 { | 1098 { |
1965 INC_STATS("DOM.DOMWindow.nop()"); | 1099 INC_STATS("DOM.DOMWindow.nop()"); |
1966 return v8::Undefined(); | 1100 return v8::Undefined(); |
1967 } | 1101 } |
1968 | 1102 |
1969 | 1103 |
1970 // Node ------------------------------------------------------------- | |
1971 | |
1972 CALLBACK_FUNC_DECL(NodeAddEventListener) { | |
1973 INC_STATS("DOM.Node.addEventListener()"); | |
1974 Node* node = V8Proxy::DOMWrapperToNode<Node>(args.Holder()); | |
1975 | |
1976 V8Proxy* proxy = V8Proxy::retrieve(node->document()->frame()); | |
1977 if (!proxy) | |
1978 return v8::Undefined(); | |
1979 | |
1980 RefPtr<EventListener> listener = | |
1981 proxy->FindOrCreateV8EventListener(args[1], false); | |
1982 if (listener) { | |
1983 String type = ToWebCoreString(args[0]); | |
1984 bool useCapture = args[2]->BooleanValue(); | |
1985 node->addEventListener(type, listener, useCapture); | |
1986 } | |
1987 return v8::Undefined(); | |
1988 } | |
1989 | |
1990 CALLBACK_FUNC_DECL(NodeRemoveEventListener) { | |
1991 INC_STATS("DOM.Node.removeEventListener()"); | |
1992 Node* node = V8Proxy::DOMWrapperToNode<Node>(args.Holder()); | |
1993 | |
1994 V8Proxy* proxy = V8Proxy::retrieve(node->document()->frame()); | |
1995 // It is possbile that the owner document of the node is detached | |
1996 // from the frame, return immediately in this case. | |
1997 // See issue 878909 | |
1998 if (!proxy) | |
1999 return v8::Undefined(); | |
2000 | |
2001 RefPtr<EventListener> listener = | |
2002 proxy->FindV8EventListener(args[1], false); | |
2003 if (listener) { | |
2004 String type = ToWebCoreString(args[0]); | |
2005 bool useCapture = args[2]->BooleanValue(); | |
2006 node->removeEventListener(type, listener.get(), useCapture); | |
2007 } | |
2008 | |
2009 return v8::Undefined(); | |
2010 } | |
2011 | |
2012 | |
2013 // Navigator ------------------------------------------------------------------ | |
2014 ACCESSOR_GETTER(NavigatorAppVersion) { | |
2015 INC_STATS("DOM.Navigator.appVersion"); | |
2016 v8::Handle<v8::Object> holder = info.Holder(); | |
2017 Navigator* imp = V8Proxy::ToNativeObject<Navigator>(V8ClassIndex::NAVIGATOR, | |
2018 holder); | |
2019 String v = ToString(imp->appVersion()); | |
2020 return v8StringOrUndefined(v); | |
2021 } | |
2022 | |
2023 | |
2024 // TreeWalker ------------------------------------------------------------------ | |
2025 | |
2026 CALLBACK_FUNC_DECL(TreeWalkerParentNode) { | |
2027 INC_STATS("DOM.TreeWalker.parentNode()"); | |
2028 TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( | |
2029 V8ClassIndex::TREEWALKER, args.Holder()); | |
2030 | |
2031 ScriptState state; | |
2032 RefPtr<Node> result = treeWalker->parentNode(&state); | |
2033 if (state.hadException()) { | |
2034 v8::ThrowException(state.exception()); | |
2035 return v8::Undefined(); | |
2036 } | |
2037 if (!result) return v8::Null(); | |
2038 return V8Proxy::NodeToV8Object(result.get()); | |
2039 } | |
2040 | |
2041 CALLBACK_FUNC_DECL(TreeWalkerFirstChild) { | |
2042 INC_STATS("DOM.TreeWalker.firstChild()"); | |
2043 TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( | |
2044 V8ClassIndex::TREEWALKER, args.Holder()); | |
2045 | |
2046 ScriptState state; | |
2047 RefPtr<Node> result = treeWalker->firstChild(&state); | |
2048 if (state.hadException()) { | |
2049 v8::ThrowException(state.exception()); | |
2050 return v8::Undefined(); | |
2051 } | |
2052 if (!result) return v8::Null(); | |
2053 return V8Proxy::NodeToV8Object(result.get()); | |
2054 } | |
2055 | |
2056 CALLBACK_FUNC_DECL(TreeWalkerLastChild) { | |
2057 INC_STATS("DOM.TreeWalker.lastChild()"); | |
2058 TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( | |
2059 V8ClassIndex::TREEWALKER, args.Holder()); | |
2060 | |
2061 ScriptState state; | |
2062 RefPtr<Node> result = treeWalker->lastChild(&state); | |
2063 if (state.hadException()) { | |
2064 v8::ThrowException(state.exception()); | |
2065 return v8::Undefined(); | |
2066 } | |
2067 if (!result) return v8::Null(); | |
2068 return V8Proxy::NodeToV8Object(result.get()); | |
2069 } | |
2070 | |
2071 CALLBACK_FUNC_DECL(TreeWalkerNextNode) { | |
2072 INC_STATS("DOM.TreeWalker.nextNode()"); | |
2073 TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( | |
2074 V8ClassIndex::TREEWALKER, args.Holder()); | |
2075 | |
2076 ScriptState state; | |
2077 RefPtr<Node> result = treeWalker->nextNode(&state); | |
2078 if (state.hadException()) { | |
2079 v8::ThrowException(state.exception()); | |
2080 return v8::Undefined(); | |
2081 } | |
2082 if (!result) return v8::Null(); | |
2083 return V8Proxy::NodeToV8Object(result.get()); | |
2084 } | |
2085 | |
2086 CALLBACK_FUNC_DECL(TreeWalkerPreviousNode) { | |
2087 INC_STATS("DOM.TreeWalker.previousNode()"); | |
2088 TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( | |
2089 V8ClassIndex::TREEWALKER, args.Holder()); | |
2090 | |
2091 ScriptState state; | |
2092 RefPtr<Node> result = treeWalker->previousNode(&state); | |
2093 if (state.hadException()) { | |
2094 v8::ThrowException(state.exception()); | |
2095 return v8::Undefined(); | |
2096 } | |
2097 if (!result) return v8::Null(); | |
2098 return V8Proxy::NodeToV8Object(result.get()); | |
2099 } | |
2100 | |
2101 CALLBACK_FUNC_DECL(TreeWalkerNextSibling) { | |
2102 INC_STATS("DOM.TreeWalker.nextSibling()"); | |
2103 TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( | |
2104 V8ClassIndex::TREEWALKER, args.Holder()); | |
2105 | |
2106 ScriptState state; | |
2107 RefPtr<Node> result = treeWalker->nextSibling(&state); | |
2108 if (state.hadException()) { | |
2109 v8::ThrowException(state.exception()); | |
2110 return v8::Undefined(); | |
2111 } | |
2112 if (!result) return v8::Null(); | |
2113 return V8Proxy::NodeToV8Object(result.get()); | |
2114 } | |
2115 | |
2116 CALLBACK_FUNC_DECL(TreeWalkerPreviousSibling) { | |
2117 INC_STATS("DOM.TreeWalker.previousSibling()"); | |
2118 TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( | |
2119 V8ClassIndex::TREEWALKER, args.Holder()); | |
2120 | |
2121 ScriptState state; | |
2122 RefPtr<Node> result = treeWalker->previousSibling(&state); | |
2123 if (state.hadException()) { | |
2124 v8::ThrowException(state.exception()); | |
2125 return v8::Undefined(); | |
2126 } | |
2127 if (!result) return v8::Null(); | |
2128 return V8Proxy::NodeToV8Object(result.get()); | |
2129 } | |
2130 | |
2131 CALLBACK_FUNC_DECL(NodeIteratorNextNode) { | |
2132 INC_STATS("DOM.NodeIterator.nextNode()"); | |
2133 NodeIterator* nodeIterator = V8Proxy::ToNativeObject<NodeIterator>( | |
2134 V8ClassIndex::NODEITERATOR, args.Holder()); | |
2135 | |
2136 ExceptionCode ec = 0; | |
2137 ScriptState state; | |
2138 RefPtr<Node> result = nodeIterator->nextNode(&state, ec); | |
2139 if (ec != 0) { | |
2140 V8Proxy::SetDOMException(ec); | |
2141 return v8::Null(); | |
2142 } | |
2143 if (state.hadException()) { | |
2144 v8::ThrowException(state.exception()); | |
2145 return v8::Undefined(); | |
2146 } | |
2147 if (!result) return v8::Null(); | |
2148 return V8Proxy::NodeToV8Object(result.get()); | |
2149 } | |
2150 | |
2151 CALLBACK_FUNC_DECL(NodeIteratorPreviousNode) { | |
2152 INC_STATS("DOM.NodeIterator.previousNode()"); | |
2153 NodeIterator* nodeIterator = V8Proxy::ToNativeObject<NodeIterator>( | |
2154 V8ClassIndex::NODEITERATOR, args.Holder()); | |
2155 | |
2156 ExceptionCode ec = 0; | |
2157 ScriptState state; | |
2158 RefPtr<Node> result = nodeIterator->previousNode(&state, ec); | |
2159 if (ec != 0) { | |
2160 V8Proxy::SetDOMException(ec); | |
2161 return v8::Null(); | |
2162 } | |
2163 if (state.hadException()) { | |
2164 v8::ThrowException(state.exception()); | |
2165 return v8::Undefined(); | |
2166 } | |
2167 if (!result) return v8::Null(); | |
2168 return V8Proxy::NodeToV8Object(result.get()); | |
2169 } | |
2170 | |
2171 CALLBACK_FUNC_DECL(NodeFilterAcceptNode) { | |
2172 INC_STATS("DOM.NodeFilter.acceptNode()"); | |
2173 V8Proxy::SetDOMException(NOT_SUPPORTED_ERR); | |
2174 return v8::Undefined(); | |
2175 } | |
2176 | |
2177 CALLBACK_FUNC_DECL(HTMLFormElementSubmit) { | 1104 CALLBACK_FUNC_DECL(HTMLFormElementSubmit) { |
2178 INC_STATS("DOM.HTMLFormElement.submit()"); | 1105 INC_STATS("DOM.HTMLFormElement.submit()"); |
2179 | 1106 |
2180 HTMLFormElement* form = | 1107 HTMLFormElement* form = |
2181 V8Proxy::DOMWrapperToNative<HTMLFormElement>(args.Holder()); | 1108 V8Proxy::DOMWrapperToNative<HTMLFormElement>(args.Holder()); |
2182 | 1109 |
2183 form->submit(0, false, false); | 1110 form->submit(0, false, false); |
2184 return v8::Undefined(); | 1111 return v8::Undefined(); |
2185 } | 1112 } |
2186 | 1113 |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2461 #undef MAKE_CASE | 1388 #undef MAKE_CASE |
2462 | 1389 |
2463 default: | 1390 default: |
2464 return V8ClassIndex::INVALID_CLASS_INDEX; | 1391 return V8ClassIndex::INVALID_CLASS_INDEX; |
2465 } | 1392 } |
2466 } | 1393 } |
2467 | 1394 |
2468 #endif // ENABLE(SVG) | 1395 #endif // ENABLE(SVG) |
2469 | 1396 |
2470 } // namespace WebCore | 1397 } // namespace WebCore |
OLD | NEW |