#ifndef SiblingTraversalStrategies_h
#define SiblingTraversalStrategies_h
#include "core/dom/Element.h"
#include "core/dom/ElementTraversal.h"
#include "core/rendering/style/RenderStyle.h"
namespace WebCore {
struct DOMSiblingTraversalStrategy {
bool isFirstChild(Element&) const;
bool isLastChild(Element&) const;
bool isFirstOfType(Element&, const QualifiedName&) const;
bool isLastOfType(Element&, const QualifiedName&) const;
int countElementsBefore(Element&) const;
int countElementsAfter(Element&) const;
int countElementsOfTypeBefore(Element&, const QualifiedName&) const;
int countElementsOfTypeAfter(Element&, const QualifiedName&) const;
};
inline bool DOMSiblingTraversalStrategy::isFirstChild(Element& element) const
{
return !ElementTraversal::previousSibling(element);
}
inline bool DOMSiblingTraversalStrategy::isLastChild(Element& element) const
{
return !ElementTraversal::nextSibling(element);
}
inline bool DOMSiblingTraversalStrategy::isFirstOfType(Element& element, const QualifiedName& type) const
{
for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
if (sibling->hasTagName(type))
return false;
}
return true;
}
inline bool DOMSiblingTraversalStrategy::isLastOfType(Element& element, const QualifiedName& type) const
{
for (const Element* sibling = ElementTraversal::nextSibling(element); sibling; sibling = ElementTraversal::nextSibling(*sibling)) {
if (sibling->hasTagName(type))
return false;
}
return true;
}
inline int DOMSiblingTraversalStrategy::countElementsBefore(Element& element) const
{
int count = 0;
for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling))
count++;
return count;
}
inline int DOMSiblingTraversalStrategy::countElementsOfTypeBefore(Element& element, const QualifiedName& type) const
{
int count = 0;
for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
if (sibling->hasTagName(type))
++count;
}
return count;
}
inline int DOMSiblingTraversalStrategy::countElementsAfter(Element& element) const
{
int count = 0;
for (const Element* sibling = ElementTraversal::nextSibling(element); sibling; sibling = ElementTraversal::nextSibling(*sibling))
++count;
return count;
}
inline int DOMSiblingTraversalStrategy::countElementsOfTypeAfter(Element& element, const QualifiedName& type) const
{
int count = 0;
for (const Element* sibling = ElementTraversal::nextSibling(element); sibling; sibling = ElementTraversal::nextSibling(*sibling)) {
if (sibling->hasTagName(type))
++count;
}
return count;
}
struct ShadowDOMSiblingTraversalStrategy {
ShadowDOMSiblingTraversalStrategy(const Vector<Node*, 32>& siblings, int nth)
: m_siblings(siblings)
, m_nth(nth)
{
}
bool isFirstChild(Element&) const;
bool isLastChild(Element&) const;
bool isFirstOfType(Element&, const QualifiedName&) const;
bool isLastOfType(Element&, const QualifiedName&) const;
int countElementsBefore(Element&) const;
int countElementsAfter(Element&) const;
int countElementsOfTypeBefore(Element&, const QualifiedName&) const;
int countElementsOfTypeAfter(Element&, const QualifiedName&) const;
private:
const Vector<Node*, 32>& m_siblings;
int m_nth;
};
inline bool ShadowDOMSiblingTraversalStrategy::isFirstChild(Element& element) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
for (int i = m_nth - 1; i >= 0; --i) {
if (m_siblings[i]->isElementNode())
return false;
}
return true;
}
inline bool ShadowDOMSiblingTraversalStrategy::isLastChild(Element& element) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
for (size_t i = m_nth + 1; i < m_siblings.size(); ++i) {
if (m_siblings[i]->isElementNode())
return false;
}
return true;
}
inline bool ShadowDOMSiblingTraversalStrategy::isFirstOfType(Element& element, const QualifiedName& type) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
for (int i = m_nth - 1; i >= 0; --i) {
if (m_siblings[i]->hasTagName(type))
return false;
}
return true;
}
inline bool ShadowDOMSiblingTraversalStrategy::isLastOfType(Element& element, const QualifiedName& type) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
for (size_t i = m_nth + 1; i < m_siblings.size(); ++i) {
if (m_siblings[i]->hasTagName(type))
return false;
}
return true;
}
inline int ShadowDOMSiblingTraversalStrategy::countElementsBefore(Element& element) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
int count = 0;
for (int i = m_nth - 1; i >= 0; --i) {
if (m_siblings[i]->isElementNode())
++count;
}
return count;
}
inline int ShadowDOMSiblingTraversalStrategy::countElementsAfter(Element& element) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
int count = 0;
for (size_t i = m_nth + 1; i < m_siblings.size(); ++i) {
if (m_siblings[i]->isElementNode())
return ++count;
}
return count;
}
inline int ShadowDOMSiblingTraversalStrategy::countElementsOfTypeBefore(Element& element, const QualifiedName& type) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
int count = 0;
for (int i = m_nth - 1; i >= 0; --i) {
if (m_siblings[i]->hasTagName(type))
++count;
}
return count;
}
inline int ShadowDOMSiblingTraversalStrategy::countElementsOfTypeAfter(Element& element, const QualifiedName& type) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
int count = 0;
for (size_t i = m_nth + 1; i < m_siblings.size(); ++i) {
if (m_siblings[i]->hasTagName(type))
return ++count;
}
return count;
}
}
#endif