1/* 2 * Copyright (C) 2007-2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "config.h" 32#include "V8Node.h" 33 34#include "V8Attr.h" 35#include "V8CDATASection.h" 36#include "V8Comment.h" 37#include "V8Document.h" 38#include "V8DocumentFragment.h" 39#include "V8DocumentType.h" 40#include "V8Element.h" 41#include "V8Entity.h" 42#include "V8HTMLElement.h" 43#include "V8Notation.h" 44#include "V8ProcessingInstruction.h" 45#include "V8SVGElement.h" 46#include "V8ShadowRoot.h" 47#include "V8Text.h" 48#include "bindings/v8/ExceptionState.h" 49#include "bindings/v8/V8AbstractEventListener.h" 50#include "bindings/v8/V8Binding.h" 51#include "bindings/v8/V8EventListener.h" 52#include "core/dom/Document.h" 53#include "core/dom/custom/CustomElementCallbackDispatcher.h" 54#include "core/events/EventListener.h" 55#include "core/dom/shadow/ShadowRoot.h" 56#include "wtf/RefPtr.h" 57 58namespace WebCore { 59 60// These functions are custom to prevent a wrapper lookup of the return value which is always 61// part of the arguments. 62void V8Node::insertBeforeMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) 63{ 64 v8::Handle<v8::Object> holder = info.Holder(); 65 Node* imp = V8Node::toNative(holder); 66 67 CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope; 68 69 ExceptionState exceptionState(ExceptionState::ExecutionContext, "insertBefore", "Node", info.Holder(), info.GetIsolate()); 70 Node* newChild = V8Node::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate())) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0; 71 Node* refChild = V8Node::hasInstance(info[1], info.GetIsolate(), worldType(info.GetIsolate())) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(info[1])) : 0; 72 imp->insertBefore(newChild, refChild, exceptionState); 73 if (exceptionState.throwIfNeeded()) 74 return; 75 v8SetReturnValue(info, info[0]); 76} 77 78void V8Node::replaceChildMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) 79{ 80 v8::Handle<v8::Object> holder = info.Holder(); 81 Node* imp = V8Node::toNative(holder); 82 83 CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope; 84 85 ExceptionState exceptionState(ExceptionState::ExecutionContext, "replaceChild", "Node", info.Holder(), info.GetIsolate()); 86 Node* newChild = V8Node::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate())) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0; 87 Node* oldChild = V8Node::hasInstance(info[1], info.GetIsolate(), worldType(info.GetIsolate())) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(info[1])) : 0; 88 imp->replaceChild(newChild, oldChild, exceptionState); 89 if (exceptionState.throwIfNeeded()) 90 return; 91 v8SetReturnValue(info, info[1]); 92} 93 94void V8Node::removeChildMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) 95{ 96 v8::Handle<v8::Object> holder = info.Holder(); 97 Node* imp = V8Node::toNative(holder); 98 99 CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope; 100 101 ExceptionState exceptionState(ExceptionState::ExecutionContext, "removeChild", "Node", info.Holder(), info.GetIsolate()); 102 Node* oldChild = V8Node::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate())) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0; 103 imp->removeChild(oldChild, exceptionState); 104 if (exceptionState.throwIfNeeded()) 105 return; 106 v8SetReturnValue(info, info[0]); 107} 108 109void V8Node::appendChildMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info) 110{ 111 v8::Handle<v8::Object> holder = info.Holder(); 112 Node* imp = V8Node::toNative(holder); 113 114 CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope; 115 116 ExceptionState exceptionState(ExceptionState::ExecutionContext, "appendChild", "Node", info.Holder(), info.GetIsolate()); 117 Node* newChild = V8Node::hasInstance(info[0], info.GetIsolate(), worldType(info.GetIsolate())) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(info[0])) : 0; 118 imp->appendChild(newChild, exceptionState); 119 if (exceptionState.throwIfNeeded()) 120 return; 121 v8SetReturnValue(info, info[0]); 122} 123 124v8::Handle<v8::Object> wrap(Node* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate) 125{ 126 ASSERT(impl); 127 switch (impl->nodeType()) { 128 case Node::ELEMENT_NODE: 129 // For performance reasons, this is inlined from V8Element::wrap and must remain in sync. 130 if (impl->isHTMLElement()) 131 return wrap(toHTMLElement(impl), creationContext, isolate); 132 if (impl->isSVGElement()) 133 return wrap(toSVGElement(impl), creationContext, isolate); 134 return V8Element::createWrapper(toElement(impl), creationContext, isolate); 135 case Node::ATTRIBUTE_NODE: 136 return wrap(toAttr(impl), creationContext, isolate); 137 case Node::TEXT_NODE: 138 return wrap(toText(impl), creationContext, isolate); 139 case Node::CDATA_SECTION_NODE: 140 return wrap(toCDATASection(impl), creationContext, isolate); 141 case Node::PROCESSING_INSTRUCTION_NODE: 142 return wrap(toProcessingInstruction(impl), creationContext, isolate); 143 case Node::COMMENT_NODE: 144 return wrap(toComment(impl), creationContext, isolate); 145 case Node::DOCUMENT_NODE: 146 return wrap(toDocument(impl), creationContext, isolate); 147 case Node::DOCUMENT_TYPE_NODE: 148 return wrap(toDocumentType(impl), creationContext, isolate); 149 case Node::DOCUMENT_FRAGMENT_NODE: 150 if (impl->isShadowRoot()) 151 return wrap(toShadowRoot(impl), creationContext, isolate); 152 return wrap(toDocumentFragment(impl), creationContext, isolate); 153 case Node::ENTITY_NODE: 154 case Node::NOTATION_NODE: 155 // We never create objects of Entity and Notation. 156 ASSERT_NOT_REACHED(); 157 break; 158 default: 159 break; // ENTITY_REFERENCE_NODE or XPATH_NAMESPACE_NODE 160 } 161 return V8Node::createWrapper(impl, creationContext, isolate); 162} 163} // namespace WebCore 164