1/* 2 * Copyright (C) 2013 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. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef ElementAncestorIterator_h 27#define ElementAncestorIterator_h 28 29#include "ElementIterator.h" 30 31namespace WebCore { 32 33template <typename ElementType> 34class ElementAncestorIterator : public ElementIterator<ElementType> { 35public: 36 ElementAncestorIterator(); 37 explicit ElementAncestorIterator(ElementType* current); 38 ElementAncestorIterator& operator++(); 39}; 40 41template <typename ElementType> 42class ElementAncestorConstIterator : public ElementConstIterator<ElementType> { 43public: 44 ElementAncestorConstIterator(); 45 explicit ElementAncestorConstIterator(const ElementType* current); 46 ElementAncestorConstIterator& operator++(); 47}; 48 49template <typename ElementType> 50class ElementAncestorIteratorAdapter { 51public: 52 explicit ElementAncestorIteratorAdapter(ElementType* first); 53 ElementAncestorIterator<ElementType> begin(); 54 ElementAncestorIterator<ElementType> end(); 55 ElementType* first() { return m_first; } 56 57private: 58 ElementType* m_first; 59}; 60 61template <typename ElementType> 62class ElementAncestorConstIteratorAdapter { 63public: 64 explicit ElementAncestorConstIteratorAdapter(const ElementType* first); 65 ElementAncestorConstIterator<ElementType> begin() const; 66 ElementAncestorConstIterator<ElementType> end() const; 67 const ElementType* first() const { return m_first; } 68 69private: 70 const ElementType* m_first; 71}; 72 73ElementAncestorIteratorAdapter<Element> elementLineage(Element* first); 74ElementAncestorConstIteratorAdapter<Element> elementLineage(const Element* first); 75ElementAncestorIteratorAdapter<Element> elementAncestors(Element* descendant); 76ElementAncestorConstIteratorAdapter<Element> elementAncestors(const Element* descendant); 77template <typename ElementType> ElementAncestorIteratorAdapter<ElementType> lineageOfType(Element& first); 78template <typename ElementType> ElementAncestorConstIteratorAdapter<ElementType> lineageOfType(const Element& first); 79template <typename ElementType> ElementAncestorIteratorAdapter<ElementType> ancestorsOfType(Element& descendant); 80template <typename ElementType> ElementAncestorConstIteratorAdapter<ElementType> ancestorsOfType(const Element& descendant); 81 82// ElementAncestorIterator 83 84template <typename ElementType> 85inline ElementAncestorIterator<ElementType>::ElementAncestorIterator() 86 : ElementIterator<ElementType>(nullptr) 87{ 88} 89 90template <typename ElementType> 91inline ElementAncestorIterator<ElementType>::ElementAncestorIterator(ElementType* current) 92 : ElementIterator<ElementType>(nullptr, current) 93{ 94} 95 96template <typename ElementType> 97inline ElementAncestorIterator<ElementType>& ElementAncestorIterator<ElementType>::operator++() 98{ 99 return static_cast<ElementAncestorIterator<ElementType>&>(ElementIterator<ElementType>::traverseAncestor()); 100} 101 102// ElementAncestorConstIterator 103 104template <typename ElementType> 105inline ElementAncestorConstIterator<ElementType>::ElementAncestorConstIterator() 106 : ElementConstIterator<ElementType>(nullptr) 107{ 108} 109 110template <typename ElementType> 111inline ElementAncestorConstIterator<ElementType>::ElementAncestorConstIterator(const ElementType* current) 112 : ElementConstIterator<ElementType>(nullptr, current) 113{ 114} 115 116template <typename ElementType> 117inline ElementAncestorConstIterator<ElementType>& ElementAncestorConstIterator<ElementType>::operator++() 118{ 119 return static_cast<ElementAncestorConstIterator<ElementType>&>(ElementConstIterator<ElementType>::traverseAncestor()); 120} 121 122// ElementAncestorIteratorAdapter 123 124template <typename ElementType> 125inline ElementAncestorIteratorAdapter<ElementType>::ElementAncestorIteratorAdapter(ElementType* first) 126 : m_first(first) 127{ 128} 129 130template <typename ElementType> 131inline ElementAncestorIterator<ElementType> ElementAncestorIteratorAdapter<ElementType>::begin() 132{ 133 return ElementAncestorIterator<ElementType>(m_first); 134} 135 136template <typename ElementType> 137inline ElementAncestorIterator<ElementType> ElementAncestorIteratorAdapter<ElementType>::end() 138{ 139 return ElementAncestorIterator<ElementType>(); 140} 141 142// ElementAncestorConstIteratorAdapter 143 144template <typename ElementType> 145inline ElementAncestorConstIteratorAdapter<ElementType>::ElementAncestorConstIteratorAdapter(const ElementType* first) 146 : m_first(first) 147{ 148} 149 150template <typename ElementType> 151inline ElementAncestorConstIterator<ElementType> ElementAncestorConstIteratorAdapter<ElementType>::begin() const 152{ 153 return ElementAncestorConstIterator<ElementType>(m_first); 154} 155 156template <typename ElementType> 157inline ElementAncestorConstIterator<ElementType> ElementAncestorConstIteratorAdapter<ElementType>::end() const 158{ 159 return ElementAncestorConstIterator<ElementType>(); 160} 161 162// Standalone functions 163 164inline ElementAncestorIteratorAdapter<Element> elementLineage(Element* first) 165{ 166 return ElementAncestorIteratorAdapter<Element>(first); 167} 168 169inline ElementAncestorConstIteratorAdapter<Element> elementLineage(const Element* first) 170{ 171 return ElementAncestorConstIteratorAdapter<Element>(first); 172} 173 174inline ElementAncestorIteratorAdapter<Element> elementAncestors(Element* descendant) 175{ 176 return ElementAncestorIteratorAdapter<Element>(descendant->parentElement()); 177} 178 179inline ElementAncestorConstIteratorAdapter<Element> elementAncestors(const Element* descendant) 180{ 181 return ElementAncestorConstIteratorAdapter<Element>(descendant->parentElement()); 182} 183 184template <typename ElementType> 185inline ElementAncestorIteratorAdapter<ElementType> lineageOfType(Element& first) 186{ 187 if (isElementOfType<const ElementType>(first)) 188 return ElementAncestorIteratorAdapter<ElementType>(static_cast<ElementType*>(&first)); 189 return ancestorsOfType<ElementType>(first); 190} 191 192template <typename ElementType> 193inline ElementAncestorConstIteratorAdapter<ElementType> lineageOfType(const Element& first) 194{ 195 if (isElementOfType<const ElementType>(first)) 196 return ElementAncestorConstIteratorAdapter<ElementType>(static_cast<const ElementType*>(&first)); 197 return ancestorsOfType<ElementType>(first); 198} 199 200template <typename ElementType> 201inline ElementAncestorIteratorAdapter<ElementType> ancestorsOfType(Element& descendant) 202{ 203 ElementType* first = findElementAncestorOfType<ElementType>(descendant); 204 return ElementAncestorIteratorAdapter<ElementType>(first); 205} 206 207template <typename ElementType> 208inline ElementAncestorConstIteratorAdapter<ElementType> ancestorsOfType(const Element& descendant) 209{ 210 const ElementType* first = findElementAncestorOfType<const ElementType>(descendant); 211 return ElementAncestorConstIteratorAdapter<ElementType>(first); 212} 213 214} 215 216#endif 217