summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderIterator.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/RenderIterator.h')
-rw-r--r--Source/WebCore/rendering/RenderIterator.h120
1 files changed, 107 insertions, 13 deletions
diff --git a/Source/WebCore/rendering/RenderIterator.h b/Source/WebCore/rendering/RenderIterator.h
index b50a344b9..ba172e72a 100644
--- a/Source/WebCore/rendering/RenderIterator.h
+++ b/Source/WebCore/rendering/RenderIterator.h
@@ -23,10 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RenderIterator_h
-#define RenderIterator_h
+#pragma once
-#include "RenderObject.h"
+#include "RenderElement.h"
namespace WebCore {
@@ -42,6 +41,7 @@ public:
bool operator==(const RenderIterator& other) const;
bool operator!=(const RenderIterator& other) const;
+ RenderIterator& traverseNext();
RenderIterator& traverseNextSibling();
RenderIterator& traversePreviousSibling();
RenderIterator& traverseAncestor();
@@ -63,6 +63,7 @@ public:
bool operator==(const RenderConstIterator& other) const;
bool operator!=(const RenderConstIterator& other) const;
+ RenderConstIterator& traverseNext();
RenderConstIterator& traverseNextSibling();
RenderConstIterator& traversePreviousSibling();
RenderConstIterator& traverseAncestor();
@@ -72,15 +73,76 @@ private:
const T* m_current;
};
+// Similar to WTF::is<>() but without the static_assert() making sure the check is necessary.
+template <typename T, typename U>
+inline bool isRendererOfType(const U& renderer) { return TypeCastTraits<const T, const U>::isOfType(renderer); }
+
// Traversal helpers
+namespace RenderObjectTraversal {
+
+template <typename U>
+inline RenderObject* firstChild(U& object)
+{
+ return object.firstChild();
+}
+
+inline RenderObject* firstChild(RenderObject& object)
+{
+ return object.firstChildSlow();
+}
+
+inline RenderObject* firstChild(RenderText&)
+{
+ return nullptr;
+}
+
+inline RenderObject* nextAncestorSibling(RenderObject& current, const RenderObject* stayWithin)
+{
+ for (auto* ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) {
+ if (ancestor == stayWithin)
+ return nullptr;
+ if (auto* sibling = ancestor->nextSibling())
+ return sibling;
+ }
+ return nullptr;
+}
+
+template <typename U>
+inline RenderObject* next(U& current, const RenderObject* stayWithin)
+{
+ if (auto* child = firstChild(current))
+ return child;
+
+ if (&current == stayWithin)
+ return nullptr;
+
+ if (auto* sibling = current.nextSibling())
+ return sibling;
+
+ return nextAncestorSibling(current, stayWithin);
+}
+
+inline RenderObject* nextSkippingChildren(RenderObject& current, const RenderObject* stayWithin)
+{
+ if (&current == stayWithin)
+ return nullptr;
+
+ if (auto* sibling = current.nextSibling())
+ return sibling;
+
+ return nextAncestorSibling(current, stayWithin);
+}
+
+}
+
namespace RenderTraversal {
template <typename T, typename U>
inline T* firstChild(U& current)
{
- RenderObject* object = current.firstChild();
- while (object && !isRendererOfType<const T>(*object))
+ RenderObject* object = RenderObjectTraversal::firstChild(current);
+ while (object && !isRendererOfType<T>(*object))
object = object->nextSibling();
return static_cast<T*>(object);
}
@@ -89,7 +151,7 @@ template <typename T, typename U>
inline T* lastChild(U& current)
{
RenderObject* object = current.lastChild();
- while (object && !isRendererOfType<const T>(*object))
+ while (object && !isRendererOfType<T>(*object))
object = object->previousSibling();
return static_cast<T*>(object);
}
@@ -98,7 +160,7 @@ template <typename T, typename U>
inline T* nextSibling(U& current)
{
RenderObject* object = current.nextSibling();
- while (object && !isRendererOfType<const T>(*object))
+ while (object && !isRendererOfType<T>(*object))
object = object->nextSibling();
return static_cast<T*>(object);
}
@@ -107,7 +169,7 @@ template <typename T, typename U>
inline T* previousSibling(U& current)
{
RenderObject* object = current.previousSibling();
- while (object && !isRendererOfType<const T>(*object))
+ while (object && !isRendererOfType<T>(*object))
object = object->previousSibling();
return static_cast<T*>(object);
}
@@ -115,13 +177,31 @@ inline T* previousSibling(U& current)
template <typename T>
inline T* findAncestorOfType(const RenderObject& current)
{
- for (auto ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) {
- if (isRendererOfType<const T>(*ancestor))
+ for (auto* ancestor = current.parent(); ancestor; ancestor = ancestor->parent()) {
+ if (isRendererOfType<T>(*ancestor))
return static_cast<T*>(ancestor);
}
return nullptr;
}
+template <typename T, typename U>
+inline T* firstWithin(U& current)
+{
+ auto* descendant = RenderObjectTraversal::firstChild(current);
+ while (descendant && !isRendererOfType<T>(*descendant))
+ descendant = RenderObjectTraversal::next(*descendant, &current);
+ return static_cast<T*>(descendant);
+}
+
+template <typename T, typename U>
+inline T* next(U& current, const RenderObject* stayWithin)
+{
+ auto* descendant = RenderObjectTraversal::next(current, stayWithin);
+ while (descendant && !isRendererOfType<T>(*descendant))
+ descendant = RenderObjectTraversal::next(*descendant, stayWithin);
+ return static_cast<T*>(descendant);
+}
+
} // namespace WebCore::RenderTraversal
// RenderIterator
@@ -149,6 +229,14 @@ inline RenderIterator<T>& RenderIterator<T>::traverseNextSibling()
}
template <typename T>
+inline RenderIterator<T>& RenderIterator<T>::traverseNext()
+{
+ ASSERT(m_current);
+ m_current = RenderTraversal::next<T>(*m_current, m_root);
+ return *this;
+}
+
+template <typename T>
inline RenderIterator<T>& RenderIterator<T>::traversePreviousSibling()
{
ASSERT(m_current);
@@ -217,6 +305,14 @@ inline RenderConstIterator<T>& RenderConstIterator<T>::traverseNextSibling()
}
template <typename T>
+inline RenderConstIterator<T>& RenderConstIterator<T>::traverseNext()
+{
+ ASSERT(m_current);
+ m_current = RenderTraversal::next<T>(*m_current, m_root);
+ return *this;
+}
+
+template <typename T>
inline RenderConstIterator<T>& RenderConstIterator<T>::traversePreviousSibling()
{
ASSERT(m_current);
@@ -261,9 +357,7 @@ inline bool RenderConstIterator<T>::operator!=(const RenderConstIterator& other)
return !(*this == other);
}
-}
+} // namespace WebCore
#include "RenderAncestorIterator.h"
#include "RenderChildIterator.h"
-
-#endif