/* * Copyright (C) 2004-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import "DOMNodeInternal.h" #import "DOMDocumentInternal.h" #import "DOMElementInternal.h" #import "DOMEventInternal.h" #import "DOMInternal.h" #import "DOMNamedNodeMapInternal.h" #import "DOMNodeListInternal.h" #import "ExceptionHandlers.h" #import "ObjCEventListener.h" #import <WebCore/DOMImplementation.h> #import <WebCore/Element.h> #import <WebCore/JSExecState.h> #import <WebCore/NodeList.h> #import <WebCore/SVGTests.h> #import <WebCore/ThreadCheck.h> #import <WebCore/WebCoreObjCExtras.h> #import <WebCore/WebScriptObjectPrivate.h> using namespace WebCore; static inline Node& unwrap(DOMNode& wrapper) { ASSERT(wrapper._internal); return reinterpret_cast<Node&>(*wrapper._internal); } Node* core(DOMNode *wrapper) { return wrapper ? &unwrap(*wrapper) : nullptr; } DOMNode *kit(Node* value) { WebCoreThreadViolationCheckRoundOne(); if (!value) return nil; if (DOMNode *wrapper = getDOMWrapper(value)) return [[wrapper retain] autorelease]; DOMNode *wrapper = [[kitClass(value) alloc] _init]; if (!wrapper) return nil; wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(value); value->ref(); addDOMWrapper(wrapper, value); return [wrapper autorelease]; } @implementation DOMNode - (void)dealloc { if (WebCoreObjCScheduleDeallocateOnMainThread([DOMNode class], self)) return; if (_internal) unwrap(*self).deref(); [super dealloc]; } - (NSString *)nodeName { JSMainThreadNullState state; return unwrap(*self).nodeName(); } - (NSString *)nodeValue { JSMainThreadNullState state; return unwrap(*self).nodeValue(); } - (void)setNodeValue:(NSString *)newNodeValue { JSMainThreadNullState state; raiseOnDOMError(unwrap(*self).setNodeValue(newNodeValue)); } - (unsigned short)nodeType { JSMainThreadNullState state; return unwrap(*self).nodeType(); } - (DOMNode *)parentNode { JSMainThreadNullState state; return kit(unwrap(*self).parentNode()); } - (DOMNodeList *)childNodes { JSMainThreadNullState state; return kit(unwrap(*self).childNodes().get()); } - (DOMNode *)firstChild { JSMainThreadNullState state; return kit(unwrap(*self).firstChild()); } - (DOMNode *)lastChild { JSMainThreadNullState state; return kit(unwrap(*self).lastChild()); } - (DOMNode *)previousSibling { JSMainThreadNullState state; return kit(unwrap(*self).previousSibling()); } - (DOMNode *)nextSibling { JSMainThreadNullState state; return kit(unwrap(*self).nextSibling()); } - (DOMDocument *)ownerDocument { JSMainThreadNullState state; return kit(&unwrap(*self).document()); } - (NSString *)namespaceURI { JSMainThreadNullState state; return unwrap(*self).namespaceURI(); } - (NSString *)prefix { JSMainThreadNullState state; return unwrap(*self).prefix(); } - (void)setPrefix:(NSString *)newPrefix { JSMainThreadNullState state; raiseOnDOMError(unwrap(*self).setPrefix(newPrefix)); } - (NSString *)localName { JSMainThreadNullState state; return unwrap(*self).localName(); } - (DOMNamedNodeMap *)attributes { JSMainThreadNullState state; return kit(unwrap(*self).attributes()); } - (NSString *)baseURI { JSMainThreadNullState state; return unwrap(*self).baseURI().string(); } - (NSString *)textContent { JSMainThreadNullState state; return unwrap(*self).textContent(); } - (void)setTextContent:(NSString *)newTextContent { JSMainThreadNullState state; raiseOnDOMError(unwrap(*self).setTextContent(newTextContent)); } - (BOOL)isConnected { JSMainThreadNullState state; return unwrap(*self).isConnected(); } - (DOMElement *)parentElement { JSMainThreadNullState state; return kit(unwrap(*self).parentElement()); } - (BOOL)isContentEditable { JSMainThreadNullState state; return unwrap(*self).isContentEditable(); } - (DOMNode *)insertBefore:(DOMNode *)newChild refChild:(DOMNode *)refChild { JSMainThreadNullState state; if (!newChild) raiseTypeErrorException(); raiseOnDOMError(unwrap(*self).insertBefore(*core(newChild), core(refChild))); return newChild; } - (DOMNode *)replaceChild:(DOMNode *)newChild oldChild:(DOMNode *)oldChild { JSMainThreadNullState state; if (!newChild) raiseTypeErrorException(); if (!oldChild) raiseTypeErrorException(); raiseOnDOMError(unwrap(*self).replaceChild(*core(newChild), *core(oldChild))); return oldChild; } - (DOMNode *)removeChild:(DOMNode *)oldChild { JSMainThreadNullState state; if (!oldChild) raiseTypeErrorException(); raiseOnDOMError(unwrap(*self).removeChild(*core(oldChild))); return oldChild; } - (DOMNode *)appendChild:(DOMNode *)newChild { JSMainThreadNullState state; if (!newChild) raiseTypeErrorException(); raiseOnDOMError(unwrap(*self).appendChild(*core(newChild))); return newChild; } - (BOOL)hasChildNodes { JSMainThreadNullState state; return unwrap(*self).hasChildNodes(); } - (DOMNode *)cloneNode:(BOOL)deep { JSMainThreadNullState state; return kit(raiseOnDOMError(unwrap(*self).cloneNodeForBindings(deep)).ptr()); } - (void)normalize { JSMainThreadNullState state; unwrap(*self).normalize(); } - (BOOL)isSupported:(NSString *)feature version:(NSString *)version { return SVGTests::hasFeatureForLegacyBindings(feature, version); } - (BOOL)hasAttributes { JSMainThreadNullState state; return unwrap(*self).hasAttributes(); } - (BOOL)isSameNode:(DOMNode *)other { JSMainThreadNullState state; return unwrap(*self).isSameNode(core(other)); } - (BOOL)isEqualNode:(DOMNode *)other { JSMainThreadNullState state; return unwrap(*self).isEqualNode(core(other)); } - (NSString *)lookupPrefix:(NSString *)inNamespaceURI { JSMainThreadNullState state; return unwrap(*self).lookupPrefix(inNamespaceURI); } - (NSString *)lookupNamespaceURI:(NSString *)inPrefix { JSMainThreadNullState state; return unwrap(*self).lookupNamespaceURI(inPrefix); } - (BOOL)isDefaultNamespace:(NSString *)inNamespaceURI { JSMainThreadNullState state; return unwrap(*self).isDefaultNamespace(inNamespaceURI); } - (unsigned short)compareDocumentPosition:(DOMNode *)other { JSMainThreadNullState state; if (!other) return Node::DOCUMENT_POSITION_DISCONNECTED; return unwrap(*self).compareDocumentPosition(*core(other)); } - (BOOL)contains:(DOMNode *)other { JSMainThreadNullState state; return unwrap(*self).contains(core(other)); } - (void)inspect { JSMainThreadNullState state; unwrap(*self).inspect(); } - (void)addEventListener:(NSString *)type listener:(id <DOMEventListener>)listener useCapture:(BOOL)useCapture { JSMainThreadNullState state; unwrap(*self).addEventListenerForBindings(type, ObjCEventListener::wrap(listener), static_cast<bool>(useCapture)); } - (void)addEventListener:(NSString *)type :(id <DOMEventListener>)listener :(BOOL)useCapture { JSMainThreadNullState state; unwrap(*self).addEventListenerForBindings(type, ObjCEventListener::wrap(listener), static_cast<bool>(useCapture)); } - (void)removeEventListener:(NSString *)type listener:(id <DOMEventListener>)listener useCapture:(BOOL)useCapture { JSMainThreadNullState state; unwrap(*self).removeEventListenerForBindings(type, ObjCEventListener::wrap(listener), static_cast<bool>(useCapture)); } - (void)removeEventListener:(NSString *)type :(id <DOMEventListener>)listener :(BOOL)useCapture { JSMainThreadNullState state; unwrap(*self).removeEventListenerForBindings(type, ObjCEventListener::wrap(listener), static_cast<bool>(useCapture)); } - (BOOL)dispatchEvent:(DOMEvent *)event { JSMainThreadNullState state; if (!event) raiseTypeErrorException(); return raiseOnDOMError(unwrap(*self).dispatchEventForBindings(*core(event))); } @end @implementation DOMNode (DOMNodeDeprecated) - (DOMNode *)insertBefore:(DOMNode *)newChild :(DOMNode *)refChild { return [self insertBefore:newChild refChild:refChild]; } - (DOMNode *)replaceChild:(DOMNode *)newChild :(DOMNode *)oldChild { return [self replaceChild:newChild oldChild:oldChild]; } - (BOOL)isSupported:(NSString *)feature :(NSString *)version { return [self isSupported:feature version:version]; } @end