/* * Copyright (C) 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef ElementAncestorIterator_h #define ElementAncestorIterator_h #include "ElementIterator.h" namespace WebCore { template class ElementAncestorIterator : public ElementIterator { public: ElementAncestorIterator(); explicit ElementAncestorIterator(ElementType* current); ElementAncestorIterator& operator++(); }; template class ElementAncestorConstIterator : public ElementConstIterator { public: ElementAncestorConstIterator(); explicit ElementAncestorConstIterator(const ElementType* current); ElementAncestorConstIterator& operator++(); }; template class ElementAncestorIteratorAdapter { public: explicit ElementAncestorIteratorAdapter(ElementType* first); ElementAncestorIterator begin(); ElementAncestorIterator end(); ElementType* first() { return m_first; } private: ElementType* m_first; }; template class ElementAncestorConstIteratorAdapter { public: explicit ElementAncestorConstIteratorAdapter(const ElementType* first); ElementAncestorConstIterator begin() const; ElementAncestorConstIterator end() const; const ElementType* first() const { return m_first; } private: const ElementType* m_first; }; ElementAncestorIteratorAdapter elementLineage(Element* first); ElementAncestorConstIteratorAdapter elementLineage(const Element* first); ElementAncestorIteratorAdapter elementAncestors(Element* descendant); ElementAncestorConstIteratorAdapter elementAncestors(const Element* descendant); template ElementAncestorIteratorAdapter lineageOfType(Element& first); template ElementAncestorConstIteratorAdapter lineageOfType(const Element& first); template ElementAncestorIteratorAdapter ancestorsOfType(Element& descendant); template ElementAncestorConstIteratorAdapter ancestorsOfType(const Element& descendant); // ElementAncestorIterator template inline ElementAncestorIterator::ElementAncestorIterator() : ElementIterator(nullptr) { } template inline ElementAncestorIterator::ElementAncestorIterator(ElementType* current) : ElementIterator(nullptr, current) { } template inline ElementAncestorIterator& ElementAncestorIterator::operator++() { return static_cast&>(ElementIterator::traverseAncestor()); } // ElementAncestorConstIterator template inline ElementAncestorConstIterator::ElementAncestorConstIterator() : ElementConstIterator(nullptr) { } template inline ElementAncestorConstIterator::ElementAncestorConstIterator(const ElementType* current) : ElementConstIterator(nullptr, current) { } template inline ElementAncestorConstIterator& ElementAncestorConstIterator::operator++() { return static_cast&>(ElementConstIterator::traverseAncestor()); } // ElementAncestorIteratorAdapter template inline ElementAncestorIteratorAdapter::ElementAncestorIteratorAdapter(ElementType* first) : m_first(first) { } template inline ElementAncestorIterator ElementAncestorIteratorAdapter::begin() { return ElementAncestorIterator(m_first); } template inline ElementAncestorIterator ElementAncestorIteratorAdapter::end() { return ElementAncestorIterator(); } // ElementAncestorConstIteratorAdapter template inline ElementAncestorConstIteratorAdapter::ElementAncestorConstIteratorAdapter(const ElementType* first) : m_first(first) { } template inline ElementAncestorConstIterator ElementAncestorConstIteratorAdapter::begin() const { return ElementAncestorConstIterator(m_first); } template inline ElementAncestorConstIterator ElementAncestorConstIteratorAdapter::end() const { return ElementAncestorConstIterator(); } // Standalone functions inline ElementAncestorIteratorAdapter elementLineage(Element* first) { return ElementAncestorIteratorAdapter(first); } inline ElementAncestorConstIteratorAdapter elementLineage(const Element* first) { return ElementAncestorConstIteratorAdapter(first); } inline ElementAncestorIteratorAdapter elementAncestors(Element* descendant) { return ElementAncestorIteratorAdapter(descendant->parentElement()); } inline ElementAncestorConstIteratorAdapter elementAncestors(const Element* descendant) { return ElementAncestorConstIteratorAdapter(descendant->parentElement()); } template inline ElementAncestorIteratorAdapter lineageOfType(Element& first) { if (is(first)) return ElementAncestorIteratorAdapter(static_cast(&first)); return ancestorsOfType(first); } template inline ElementAncestorConstIteratorAdapter lineageOfType(const Element& first) { if (is(first)) return ElementAncestorConstIteratorAdapter(static_cast(&first)); return ancestorsOfType(first); } template inline ElementAncestorIteratorAdapter ancestorsOfType(Element& descendant) { ElementType* first = findElementAncestorOfType(descendant); return ElementAncestorIteratorAdapter(first); } template inline ElementAncestorConstIteratorAdapter ancestorsOfType(const Element& descendant) { const ElementType* first = findElementAncestorOfType(descendant); return ElementAncestorConstIteratorAdapter(first); } } #endif