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 RenderIterator_h 27#define RenderIterator_h 28 29#include "RenderElement.h" 30 31namespace WebCore { 32 33template <typename T> 34class RenderIterator { 35public: 36 RenderIterator(const RenderElement* root); 37 RenderIterator(const RenderElement* root, T* current); 38 39 T& operator*(); 40 T* operator->(); 41 42 bool operator==(const RenderIterator& other) const; 43 bool operator!=(const RenderIterator& other) const; 44 45 RenderIterator& traverseNextSibling(); 46 RenderIterator& traversePreviousSibling(); 47 RenderIterator& traverseAncestor(); 48 49private: 50 const RenderElement* m_root; 51 T* m_current; 52}; 53 54template <typename T> 55class RenderConstIterator { 56public: 57 RenderConstIterator(const RenderElement* root); 58 RenderConstIterator(const RenderElement* root, const T* current); 59 60 const T& operator*() const; 61 const T* operator->() const; 62 63 bool operator==(const RenderConstIterator& other) const; 64 bool operator!=(const RenderConstIterator& other) const; 65 66 RenderConstIterator& traverseNextSibling(); 67 RenderConstIterator& traversePreviousSibling(); 68 RenderConstIterator& traverseAncestor(); 69 70private: 71 const RenderElement* m_root; 72 const T* m_current; 73}; 74 75// Traversal helpers 76 77namespace RenderTraversal { 78 79template <typename T, typename U> 80inline T* firstChild(U& current) 81{ 82 RenderObject* object = current.firstChild(); 83 while (object && !isRendererOfType<const T>(*object)) 84 object = object->nextSibling(); 85 return static_cast<T*>(object); 86} 87 88template <typename T, typename U> 89inline T* lastChild(U& current) 90{ 91 RenderObject* object = current.lastChild(); 92 while (object && !isRendererOfType<const T>(*object)) 93 object = object->previousSibling(); 94 return static_cast<T*>(object); 95} 96 97template <typename T, typename U> 98inline T* nextSibling(U& current) 99{ 100 RenderObject* object = current.nextSibling(); 101 while (object && !isRendererOfType<const T>(*object)) 102 object = object->nextSibling(); 103 return static_cast<T*>(object); 104} 105 106template <typename T, typename U> 107inline T* previousSibling(U& current) 108{ 109 RenderObject* object = current.previousSibling(); 110 while (object && !isRendererOfType<const T>(*object)) 111 object = object->previousSibling(); 112 return static_cast<T*>(object); 113} 114 115template <typename T> 116inline T* findAncestorOfType(const RenderObject& current) 117{ 118 for (auto ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) { 119 if (isRendererOfType<const T>(*ancestor)) 120 return static_cast<T*>(ancestor); 121 } 122 return nullptr; 123} 124 125} // namespace WebCore::RenderTraversal 126 127// RenderIterator 128 129template <typename T> 130inline RenderIterator<T>::RenderIterator(const RenderElement* root) 131 : m_root(root) 132 , m_current(nullptr) 133{ 134} 135 136template <typename T> 137inline RenderIterator<T>::RenderIterator(const RenderElement* root, T* current) 138 : m_root(root) 139 , m_current(current) 140{ 141} 142 143template <typename T> 144inline RenderIterator<T>& RenderIterator<T>::traverseNextSibling() 145{ 146 ASSERT(m_current); 147 m_current = RenderTraversal::nextSibling<T>(*m_current); 148 return *this; 149} 150 151template <typename T> 152inline RenderIterator<T>& RenderIterator<T>::traversePreviousSibling() 153{ 154 ASSERT(m_current); 155 m_current = RenderTraversal::previousSibling<T>(*m_current); 156 return *this; 157} 158 159template <typename T> 160inline RenderIterator<T>& RenderIterator<T>::traverseAncestor() 161{ 162 ASSERT(m_current); 163 ASSERT(m_current != m_root); 164 m_current = RenderTraversal::findAncestorOfType<T>(*m_current); 165 return *this; 166} 167 168template <typename T> 169inline T& RenderIterator<T>::operator*() 170{ 171 ASSERT(m_current); 172 return *m_current; 173} 174 175template <typename T> 176inline T* RenderIterator<T>::operator->() 177{ 178 ASSERT(m_current); 179 return m_current; 180} 181 182template <typename T> 183inline bool RenderIterator<T>::operator==(const RenderIterator& other) const 184{ 185 ASSERT(m_root == other.m_root); 186 return m_current == other.m_current; 187} 188 189template <typename T> 190inline bool RenderIterator<T>::operator!=(const RenderIterator& other) const 191{ 192 return !(*this == other); 193} 194 195// RenderConstIterator 196 197template <typename T> 198inline RenderConstIterator<T>::RenderConstIterator(const RenderElement* root) 199 : m_root(root) 200 , m_current(nullptr) 201{ 202} 203 204template <typename T> 205inline RenderConstIterator<T>::RenderConstIterator(const RenderElement* root, const T* current) 206 : m_root(root) 207 , m_current(current) 208{ 209} 210 211template <typename T> 212inline RenderConstIterator<T>& RenderConstIterator<T>::traverseNextSibling() 213{ 214 ASSERT(m_current); 215 m_current = RenderTraversal::nextSibling<T>(*m_current); 216 return *this; 217} 218 219template <typename T> 220inline RenderConstIterator<T>& RenderConstIterator<T>::traversePreviousSibling() 221{ 222 ASSERT(m_current); 223 m_current = RenderTraversal::previousSibling<T>(m_current); 224 return *this; 225} 226 227 228template <typename T> 229inline RenderConstIterator<T>& RenderConstIterator<T>::traverseAncestor() 230{ 231 ASSERT(m_current); 232 ASSERT(m_current != m_root); 233 m_current = RenderTraversal::findAncestorOfType<const T>(*m_current); 234 return *this; 235} 236 237template <typename T> 238inline const T& RenderConstIterator<T>::operator*() const 239{ 240 ASSERT(m_current); 241 return *m_current; 242} 243 244template <typename T> 245inline const T* RenderConstIterator<T>::operator->() const 246{ 247 ASSERT(m_current); 248 return m_current; 249} 250 251template <typename T> 252inline bool RenderConstIterator<T>::operator==(const RenderConstIterator& other) const 253{ 254 ASSERT(m_root == other.m_root); 255 return m_current == other.m_current; 256} 257 258template <typename T> 259inline bool RenderConstIterator<T>::operator!=(const RenderConstIterator& other) const 260{ 261 return !(*this == other); 262} 263 264} 265 266#include "RenderAncestorIterator.h" 267#include "RenderChildIterator.h" 268 269#endif 270