| 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 |