1/* 2 * Copyright (C) 2012 Apple 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 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#import "config.h" 27#import "WKDOMInternals.h" 28 29#if WK_API_ENABLED 30 31#import <WebCore/Document.h> 32#import <WebCore/Element.h> 33#import <WebCore/Node.h> 34#import <WebCore/Range.h> 35#import <WebCore/Text.h> 36#import <wtf/NeverDestroyed.h> 37 38// Classes to instantiate. 39#import "WKDOMElement.h" 40#import "WKDOMDocument.h" 41#import "WKDOMText.h" 42 43namespace WebKit { 44 45template<typename WebCoreType, typename WKDOMType> 46static WKDOMType toWKDOMType(WebCoreType impl, DOMCache<WebCoreType, WKDOMType>& cache); 47 48// -- Caches -- 49 50DOMCache<WebCore::Node*, WKDOMNode *>& WKDOMNodeCache() 51{ 52 static NeverDestroyed<DOMCache<WebCore::Node*, WKDOMNode *>> cache; 53 return cache; 54} 55 56DOMCache<WebCore::Range*, WKDOMRange *>& WKDOMRangeCache() 57{ 58 static NeverDestroyed<DOMCache<WebCore::Range*, WKDOMRange *>> cache; 59 return cache; 60} 61 62// -- Node and classes derived from Node. -- 63 64static Class WKDOMNodeClass(WebCore::Node* impl) 65{ 66 switch (impl->nodeType()) { 67 case WebCore::Node::ELEMENT_NODE: 68 return [WKDOMElement class]; 69 case WebCore::Node::DOCUMENT_NODE: 70 return [WKDOMDocument class]; 71 case WebCore::Node::TEXT_NODE: 72 return [WKDOMText class]; 73 case WebCore::Node::ATTRIBUTE_NODE: 74 case WebCore::Node::CDATA_SECTION_NODE: 75 case WebCore::Node::ENTITY_REFERENCE_NODE: 76 case WebCore::Node::ENTITY_NODE: 77 case WebCore::Node::PROCESSING_INSTRUCTION_NODE: 78 case WebCore::Node::COMMENT_NODE: 79 case WebCore::Node::DOCUMENT_TYPE_NODE: 80 case WebCore::Node::DOCUMENT_FRAGMENT_NODE: 81 case WebCore::Node::NOTATION_NODE: 82 case WebCore::Node::XPATH_NAMESPACE_NODE: 83 return [WKDOMNode class]; 84 } 85 ASSERT_NOT_REACHED(); 86 return nil; 87} 88 89static WKDOMNode *initWithImpl(WebCore::Node* impl) 90{ 91 return [[WKDOMNodeClass(impl) alloc] _initWithImpl:impl]; 92} 93 94WebCore::Node* toWebCoreNode(WKDOMNode *wrapper) 95{ 96 return wrapper ? wrapper->_impl.get() : 0; 97} 98 99WKDOMNode *toWKDOMNode(WebCore::Node* impl) 100{ 101 return toWKDOMType<WebCore::Node*, WKDOMNode *>(impl, WKDOMNodeCache()); 102} 103 104WebCore::Element* toWebCoreElement(WKDOMElement *wrapper) 105{ 106 return wrapper ? reinterpret_cast<WebCore::Element*>(wrapper->_impl.get()) : 0; 107} 108 109WKDOMElement *toWKDOMElement(WebCore::Element* impl) 110{ 111 return static_cast<WKDOMElement*>(toWKDOMNode(static_cast<WebCore::Node*>(impl))); 112} 113 114WebCore::Document* toWebCoreDocument(WKDOMDocument *wrapper) 115{ 116 return wrapper ? reinterpret_cast<WebCore::Document*>(wrapper->_impl.get()) : 0; 117} 118 119WKDOMDocument *toWKDOMDocument(WebCore::Document* impl) 120{ 121 return static_cast<WKDOMDocument*>(toWKDOMNode(static_cast<WebCore::Node*>(impl))); 122} 123 124WebCore::Text* toWebCoreText(WKDOMText *wrapper) 125{ 126 return wrapper ? reinterpret_cast<WebCore::Text*>(wrapper->_impl.get()) : 0; 127} 128 129WKDOMText *toWKDOMText(WebCore::Text* impl) 130{ 131 return static_cast<WKDOMText*>(toWKDOMNode(static_cast<WebCore::Node*>(impl))); 132} 133 134// -- Range. -- 135 136static WKDOMRange *initWithImpl(WebCore::Range* impl) 137{ 138 return [[WKDOMRange alloc] _initWithImpl:impl]; 139} 140 141WebCore::Range* toWebCoreRange(WKDOMRange * wrapper) 142{ 143 return wrapper ? wrapper->_impl.get() : 0; 144} 145 146WKDOMRange *toWKDOMRange(WebCore::Range* impl) 147{ 148 return toWKDOMType<WebCore::Range*, WKDOMRange *>(impl, WKDOMRangeCache()); 149} 150 151// -- Helpers -- 152 153template<typename WebCoreType, typename WKDOMType> 154static WKDOMType toWKDOMType(WebCoreType impl, DOMCache<WebCoreType, WKDOMType>& cache) 155{ 156 if (!impl) 157 return nil; 158 if (WKDOMType wrapper = cache.get(impl)) 159 return [[wrapper retain] autorelease]; 160 WKDOMType wrapper = initWithImpl(impl); 161 if (!wrapper) 162 return nil; 163 return [wrapper autorelease]; 164} 165 166NSArray *toNSArray(const Vector<WebCore::IntRect>& rects) 167{ 168 size_t size = rects.size(); 169 NSMutableArray *array = [NSMutableArray arrayWithCapacity:size]; 170 for (size_t i = 0; i < size; ++i) 171 [array addObject:[NSValue valueWithRect:rects[i]]]; 172 return array; 173} 174 175} // namespace WebKit 176 177#endif // WK_API_ENABLED 178