Changeset 154769 in webkit


Ignore:
Timestamp:
Aug 28, 2013, 12:43:51 PM (12 years ago)
Author:
Antti Koivisto
Message:

Add child and descendant const iterators
https://bugs.webkit.org/show_bug.cgi?id=120430

Reviewed by Andreas Kling

This patch adds const-correct DOM tree traversal iterators. It also uses them in a few places.

Some const_casts have been applied where constness breaks.

  • dom/ChildIterator.h:

(WebCore::::ChildConstIterator):
(WebCore::::operator):
(WebCore::=):
(WebCore::::ChildConstIteratorAdapter):
(WebCore::::begin):
(WebCore::::end):
(WebCore::elementChildren):
(WebCore::childrenOfType):

  • dom/DescendantIterator.h:

(WebCore::::DescendantConstIterator):
(WebCore::::operator):
(WebCore::=):
(WebCore::::DescendantConstIteratorAdapter):
(WebCore::::begin):
(WebCore::::end):
(WebCore::elementDescendants):
(WebCore::descendantsOfType):

  • dom/Node.cpp:

(WebCore::Node::numberOfScopedHTMLStyleChildren):

  • html/HTMLFieldSetElement.cpp:

(WebCore::HTMLFieldSetElement::legend):

  • html/HTMLFieldSetElement.h:
  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::finishParsingChildren):

  • html/HTMLObjectElement.cpp:

(WebCore::HTMLObjectElement::containsJavaApplet):

  • svg/SVGElement.cpp:

(WebCore::SVGElement::title):

  • svg/SVGSVGElement.cpp:

(WebCore::SVGSVGElement::collectIntersectionOrEnclosureList):
(WebCore::SVGSVGElement::checkIntersection):
(WebCore::SVGSVGElement::checkEnclosure):
(WebCore::SVGSVGElement::getElementById):

  • svg/SVGSVGElement.h:
Location:
trunk/Source/WebCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r154767 r154769  
     12013-08-28  Antti Koivisto  <antti@apple.com>
     2
     3        Add child and descendant const iterators
     4        https://bugs.webkit.org/show_bug.cgi?id=120430
     5
     6        Reviewed by Andreas Kling
     7
     8        This patch adds const-correct DOM tree traversal iterators. It also uses them in a few places.
     9       
     10        Some const_casts have been applied where constness breaks.
     11
     12        * dom/ChildIterator.h:
     13        (WebCore::::ChildConstIterator):
     14        (WebCore::::operator):
     15        (WebCore::=):
     16        (WebCore::::ChildConstIteratorAdapter):
     17        (WebCore::::begin):
     18        (WebCore::::end):
     19        (WebCore::elementChildren):
     20        (WebCore::childrenOfType):
     21        * dom/DescendantIterator.h:
     22        (WebCore::::DescendantConstIterator):
     23        (WebCore::::operator):
     24        (WebCore::=):
     25        (WebCore::::DescendantConstIteratorAdapter):
     26        (WebCore::::begin):
     27        (WebCore::::end):
     28        (WebCore::elementDescendants):
     29        (WebCore::descendantsOfType):
     30        * dom/Node.cpp:
     31        (WebCore::Node::numberOfScopedHTMLStyleChildren):
     32        * html/HTMLFieldSetElement.cpp:
     33        (WebCore::HTMLFieldSetElement::legend):
     34        * html/HTMLFieldSetElement.h:
     35        * html/HTMLMediaElement.cpp:
     36        (WebCore::HTMLMediaElement::finishParsingChildren):
     37        * html/HTMLObjectElement.cpp:
     38        (WebCore::HTMLObjectElement::containsJavaApplet):
     39        * svg/SVGElement.cpp:
     40        (WebCore::SVGElement::title):
     41        * svg/SVGSVGElement.cpp:
     42        (WebCore::SVGSVGElement::collectIntersectionOrEnclosureList):
     43        (WebCore::SVGSVGElement::checkIntersection):
     44        (WebCore::SVGSVGElement::checkEnclosure):
     45        (WebCore::SVGSVGElement::getElementById):
     46        * svg/SVGSVGElement.h:
     47
    1482013-08-28  Lukasz Gajowy  <l.gajowy@samsung.com>
    249
  • trunk/Source/WebCore/dom/ChildIterator.h

    r154751 r154769  
    5454
    5555template <typename ElementType>
     56class ChildConstIterator {
     57public:
     58    ChildConstIterator();
     59    ChildConstIterator(const ElementType* current);
     60    ChildConstIterator& operator++();
     61    const ElementType& operator*() const;
     62    const ElementType* operator->() const;
     63    bool operator!=(const ChildConstIterator& other) const;
     64
     65private:
     66    const ElementType* m_current;
     67
     68#if !ASSERT_DISABLED
     69    DescendantIteratorAssertions m_assertions;
     70#endif
     71};
     72
     73template <typename ElementType>
    5674class ChildIteratorAdapter {
    5775public:
     
    6482};
    6583
     84template <typename ElementType>
     85class ChildConstIteratorAdapter {
     86public:
     87    ChildConstIteratorAdapter(const ContainerNode* root);
     88    ChildConstIterator<ElementType> begin() const;
     89    ChildConstIterator<ElementType> end() const;
     90
     91private:
     92    const ContainerNode* m_root;
     93};
     94
    6695ChildIteratorAdapter<Element> elementChildren(ContainerNode* root);
     96ChildConstIteratorAdapter<Element> elementChildren(const ContainerNode* root);
    6797template <typename ElementType> ChildIteratorAdapter<ElementType> childrenOfType(ContainerNode* root);
     98template <typename ElementType> ChildConstIteratorAdapter<ElementType> childrenOfType(const ContainerNode* root);
     99
     100// ChildIterator
    68101
    69102template <typename ElementType>
     
    119152}
    120153
     154// ChildConstIterator
     155
     156template <typename ElementType>
     157inline ChildConstIterator<ElementType>::ChildConstIterator()
     158    : m_current(nullptr)
     159{
     160}
     161
     162template <typename ElementType>
     163inline ChildConstIterator<ElementType>::ChildConstIterator(const ElementType* current)
     164    : m_current(current)
     165#if !ASSERT_DISABLED
     166    , m_assertions(current)
     167#endif
     168{
     169}
     170
     171template <typename ElementType>
     172inline ChildConstIterator<ElementType>& ChildConstIterator<ElementType>::operator++()
     173{
     174    ASSERT(m_current);
     175    ASSERT(!m_assertions.domTreeHasMutated());
     176    m_current = Traversal<ElementType>::nextSibling(m_current);
     177#if !ASSERT_DISABLED
     178    // Drop the assertion when the iterator reaches the end.
     179    if (!m_current)
     180        m_assertions.dropEventDispatchAssertion();
     181#endif
     182    return *this;
     183}
     184
     185template <typename ElementType>
     186inline const ElementType& ChildConstIterator<ElementType>::operator*() const
     187{
     188    ASSERT(m_current);
     189    ASSERT(!m_assertions.domTreeHasMutated());
     190    return *m_current;
     191}
     192
     193template <typename ElementType>
     194inline const ElementType* ChildConstIterator<ElementType>::operator->() const
     195{
     196    ASSERT(m_current);
     197    ASSERT(!m_assertions.domTreeHasMutated());
     198    return m_current;
     199}
     200
     201template <typename ElementType>
     202inline bool ChildConstIterator<ElementType>::operator!=(const ChildConstIterator& other) const
     203{
     204    ASSERT(!m_assertions.domTreeHasMutated());
     205    return m_current != other.m_current;
     206}
     207
     208// ChildIteratorAdapter
     209
    121210template <typename ElementType>
    122211inline ChildIteratorAdapter<ElementType>::ChildIteratorAdapter(ContainerNode* root)
     
    137226}
    138227
     228// ChildConstIteratorAdapter
     229
     230template <typename ElementType>
     231inline ChildConstIteratorAdapter<ElementType>::ChildConstIteratorAdapter(const ContainerNode* root)
     232    : m_root(root)
     233{
     234}
     235
     236template <typename ElementType>
     237inline ChildConstIterator<ElementType> ChildConstIteratorAdapter<ElementType>::begin() const
     238{
     239    return ChildConstIterator<ElementType>(Traversal<ElementType>::firstChild(m_root));
     240}
     241
     242template <typename ElementType>
     243inline ChildConstIterator<ElementType> ChildConstIteratorAdapter<ElementType>::end() const
     244{
     245    return ChildConstIterator<ElementType>();
     246}
     247
     248// Standalone functions
     249
    139250inline ChildIteratorAdapter<Element> elementChildren(ContainerNode* root)
    140251{
     
    148259}
    149260
    150 }
    151 
    152 #endif
     261inline ChildConstIteratorAdapter<Element> elementChildren(const ContainerNode* root)
     262{
     263    return ChildConstIteratorAdapter<Element>(root);
     264}
     265
     266template <typename ElementType>
     267inline ChildConstIteratorAdapter<ElementType> childrenOfType(const ContainerNode* root)
     268{
     269    return ChildConstIteratorAdapter<ElementType>(root);
     270}
     271
     272}
     273
     274#endif
  • trunk/Source/WebCore/dom/DescendantIterator.h

    r154751 r154769  
    5555
    5656template <typename ElementType>
     57class DescendantConstIterator {
     58public:
     59    DescendantConstIterator(const ContainerNode* root);
     60    DescendantConstIterator(const ContainerNode* root, const ElementType* current);
     61    DescendantConstIterator& operator++();
     62    const ElementType& operator*() const;
     63    const ElementType* operator->() const;
     64    bool operator!=(const DescendantConstIterator& other) const;
     65
     66private:
     67    const ContainerNode* m_root;
     68    const ElementType* m_current;
     69
     70#if !ASSERT_DISABLED
     71    DescendantIteratorAssertions m_assertions;
     72#endif
     73};
     74
     75template <typename ElementType>
    5776class DescendantIteratorAdapter {
    5877public:
     
    6584};
    6685
     86template <typename ElementType>
     87class DescendantConstIteratorAdapter {
     88public:
     89    DescendantConstIteratorAdapter(const ContainerNode* root);
     90    DescendantConstIterator<ElementType> begin() const;
     91    DescendantConstIterator<ElementType> end() const;
     92
     93private:
     94    const ContainerNode* m_root;
     95};
     96
    6797DescendantIteratorAdapter<Element> elementDescendants(ContainerNode* root);
     98DescendantConstIteratorAdapter<Element> elementDescendants(const ContainerNode* root);
    6899template <typename ElementType> DescendantIteratorAdapter<ElementType> descendantsOfType(ContainerNode* root);
     100template <typename ElementType> DescendantConstIteratorAdapter<ElementType> descendantsOfType(const ContainerNode* root);
     101
     102// DescendantIterator
    69103
    70104template <typename ElementType>
     
    123157}
    124158
     159// DescendantConstIterator
     160
     161template <typename ElementType>
     162inline DescendantConstIterator<ElementType>::DescendantConstIterator(const ContainerNode* root)
     163    : m_root(root)
     164    , m_current(nullptr)
     165{
     166}
     167
     168template <typename ElementType>
     169inline DescendantConstIterator<ElementType>::DescendantConstIterator(const ContainerNode* root, const ElementType* current)
     170    : m_root(root)
     171    , m_current(current)
     172#if !ASSERT_DISABLED
     173    , m_assertions(current)
     174#endif
     175{
     176}
     177
     178template <typename ElementType>
     179inline DescendantConstIterator<ElementType>& DescendantConstIterator<ElementType>::operator++()
     180{
     181    ASSERT(m_current);
     182    ASSERT(!m_assertions.domTreeHasMutated());
     183    m_current = Traversal<ElementType>::next(m_current, m_root);
     184#if !ASSERT_DISABLED
     185    // Drop the assertion when the iterator reaches the end.
     186    if (!m_current)
     187        m_assertions.dropEventDispatchAssertion();
     188#endif
     189    return *this;
     190}
     191
     192template <typename ElementType>
     193inline const ElementType& DescendantConstIterator<ElementType>::operator*() const
     194{
     195    ASSERT(m_current);
     196    ASSERT(!m_assertions.domTreeHasMutated());
     197    return *m_current;
     198}
     199
     200template <typename ElementType>
     201inline const ElementType* DescendantConstIterator<ElementType>::operator->() const
     202{
     203    ASSERT(m_current);
     204    ASSERT(!m_assertions.domTreeHasMutated());
     205    return m_current;
     206}
     207
     208template <typename ElementType>
     209inline bool DescendantConstIterator<ElementType>::operator!=(const DescendantConstIterator& other) const
     210{
     211    ASSERT(m_root == other.m_root);
     212    ASSERT(!m_assertions.domTreeHasMutated());
     213    return m_current != other.m_current;
     214}
     215
     216// DescendantIteratorAdapter
     217
    125218template <typename ElementType>
    126219inline DescendantIteratorAdapter<ElementType>::DescendantIteratorAdapter(ContainerNode* root)
     
    141234}
    142235
     236// DescendantConstIteratorAdapter
     237
     238template <typename ElementType>
     239inline DescendantConstIteratorAdapter<ElementType>::DescendantConstIteratorAdapter(const ContainerNode* root)
     240    : m_root(root)
     241{
     242}
     243
     244template <typename ElementType>
     245inline DescendantConstIterator<ElementType> DescendantConstIteratorAdapter<ElementType>::begin() const
     246{
     247    return DescendantConstIterator<ElementType>(m_root, Traversal<ElementType>::firstWithin(m_root));
     248}
     249
     250template <typename ElementType>
     251inline DescendantConstIterator<ElementType> DescendantConstIteratorAdapter<ElementType>::end() const
     252{
     253    return DescendantConstIterator<ElementType>(m_root);
     254}
     255
     256// Standalone functions
     257
    143258inline DescendantIteratorAdapter<Element> elementDescendants(ContainerNode* root)
    144259{
     
    152267}
    153268
    154 }
    155 
    156 #endif
     269inline DescendantConstIteratorAdapter<Element> elementDescendants(const ContainerNode* root)
     270{
     271    return DescendantConstIteratorAdapter<Element>(root);
     272}
     273
     274template <typename ElementType>
     275inline DescendantConstIteratorAdapter<ElementType> descendantsOfType(const ContainerNode* root)
     276{
     277    return DescendantConstIteratorAdapter<ElementType>(root);
     278}
     279
     280}
     281
     282#endif
  • trunk/Source/WebCore/dom/Node.cpp

    r154686 r154769  
    4545#include "DOMImplementation.h"
    4646#include "DOMSettableTokenList.h"
     47#include "DescendantIterator.h"
    4748#include "Document.h"
    4849#include "DocumentFragment.h"
     
    5051#include "Element.h"
    5152#include "ElementRareData.h"
    52 #include "ElementTraversal.h"
    5353#include "Event.h"
    5454#include "EventContext.h"
     
    23932393size_t Node::numberOfScopedHTMLStyleChildren() const
    23942394{
     2395    if (!isContainerNode())
     2396        return 0;
    23952397    size_t count = 0;
    2396     for (HTMLStyleElement* style = Traversal<HTMLStyleElement>::firstWithin(this); style; style = Traversal<HTMLStyleElement>::next(style, this)) {
     2398    auto styleDescendants = descendantsOfType<HTMLStyleElement>(toContainerNode(this));
     2399    for (auto style = styleDescendants.begin(), end = styleDescendants.end(); style != end; ++style) {
    23972400        if (style->isRegisteredAsScoped())
    23982401            count++;
  • trunk/Source/WebCore/html/HTMLFieldSetElement.cpp

    r154679 r154769  
    9090}
    9191
    92 HTMLLegendElement* HTMLFieldSetElement::legend() const
     92const HTMLLegendElement* HTMLFieldSetElement::legend() const
    9393{
    94     return Traversal<HTMLLegendElement>::firstWithin(this);
     94    auto legendDescendants = descendantsOfType<HTMLLegendElement>(this);
     95    auto firstLegend = legendDescendants.begin();
     96    if (firstLegend != legendDescendants.end())
     97        return &*firstLegend;
     98    return nullptr;
    9599}
    96100
  • trunk/Source/WebCore/html/HTMLFieldSetElement.h

    r151947 r154769  
    3535public:
    3636    static PassRefPtr<HTMLFieldSetElement> create(const QualifiedName&, Document*, HTMLFormElement*);
    37     HTMLLegendElement* legend() const;
    3837
     38    const HTMLLegendElement* legend() const;
    3939    PassRefPtr<HTMLCollection> elements();
    4040
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r154760 r154769  
    4040#include "CSSPropertyNames.h"
    4141#include "CSSValueKeywords.h"
     42#include "DescendantIterator.h"
    4243#include "DiagnosticLoggingKeys.h"
    4344#include "DocumentLoader.h"
     
    538539        return;
    539540
    540     if (Traversal<HTMLTrackElement>::firstWithin(this))
     541    auto trackDescendants = descendantsOfType<HTMLTrackElement>(this);
     542    if (trackDescendants.begin() != trackDescendants.end())
    541543        scheduleDelayedAction(ConfigureTextTracks);
    542544#endif
  • trunk/Source/WebCore/html/HTMLObjectElement.cpp

    r154679 r154769  
    462462    if (MIMETypeRegistry::isJavaAppletMIMEType(getAttribute(typeAttr)))
    463463        return true;
    464        
    465     for (auto child = ElementTraversal::firstChild(this); child; child = ElementTraversal::nextSibling(child)) {
    466         if (child->hasTagName(paramTag)
    467                 && equalIgnoringCase(child->getNameAttribute(), "type")
    468                 && MIMETypeRegistry::isJavaAppletMIMEType(child->getAttribute(valueAttr).string()))
     464
     465    for (auto child = elementChildren(this).begin(), end = elementChildren(this).end(); child != end; ++child) {
     466        if (child->hasTagName(paramTag) && equalIgnoringCase(child->getNameAttribute(), "type")
     467            && MIMETypeRegistry::isJavaAppletMIMEType(child->getAttribute(valueAttr).string()))
    469468            return true;
    470         if (child->hasTagName(objectTag)
    471                 && static_cast<HTMLObjectElement*>(child)->containsJavaApplet())
     469        if (child->hasTagName(objectTag) && static_cast<const HTMLObjectElement&>(*child).containsJavaApplet())
    472470            return true;
    473471        if (child->hasTagName(appletTag))
  • trunk/Source/WebCore/svg/SVGElement.cpp

    r154713 r154769  
    3232#include "CSSParser.h"
    3333#include "DOMImplementation.h"
     34#include "DescendantIterator.h"
    3435#include "Document.h"
    35 #include "ElementTraversal.h"
    3636#include "Event.h"
    3737#include "EventNames.h"
     
    880880    // <title> child of this element.
    881881    // If a title child was found, return the text contents.
    882     if (SVGTitleElement* titleElement = Traversal<SVGTitleElement>::firstWithin(this))
    883         return titleElement->innerText();
     882    auto titleDescendants = descendantsOfType<SVGTitleElement>(this);
     883    auto firstTitle = titleDescendants.begin();
     884    if (firstTitle != titleDescendants.end())
     885        return const_cast<SVGTitleElement&>(*firstTitle).innerText();
    884886
    885887    // Otherwise return a null/empty string.
  • trunk/Source/WebCore/svg/SVGSVGElement.cpp

    r154676 r154769  
    2828#include "Attribute.h"
    2929#include "CSSHelper.h"
     30#include "DescendantIterator.h"
    3031#include "Document.h"
    31 #include "ElementTraversal.h"
    3232#include "EventListener.h"
    3333#include "EventNames.h"
     
    338338{
    339339    Vector<RefPtr<Node> > nodes;
    340     SVGElement* svgElement = Traversal<SVGElement>::firstWithin(referenceElement ? referenceElement : this);
    341     while (svgElement) {
     340
     341    auto svgDescendants = descendantsOfType<SVGElement>(referenceElement ? referenceElement : this);
     342    for (auto it = svgDescendants.begin(), end = svgDescendants.end(); it != end; ++it) {
     343        const SVGElement* svgElement = &*it;
    342344        if (collect == CollectIntersectionList) {
    343345            if (checkIntersection(svgElement, rect))
    344                 nodes.append(svgElement);
     346                nodes.append(const_cast<SVGElement*>(svgElement));
    345347        } else {
    346348            if (checkEnclosure(svgElement, rect))
    347                 nodes.append(svgElement);
     349                nodes.append(const_cast<SVGElement*>(svgElement));
    348350        }
    349         svgElement = Traversal<SVGElement>::next(svgElement, referenceElement ? referenceElement : this);
    350351    }
    351352    return StaticNodeList::adopt(nodes);
     
    362363}
    363364
    364 bool SVGSVGElement::checkIntersection(SVGElement* element, const FloatRect& rect) const
     365bool SVGSVGElement::checkIntersection(const SVGElement* element, const FloatRect& rect) const
    365366{
    366367    if (!element)
     
    369370}
    370371
    371 bool SVGSVGElement::checkEnclosure(SVGElement* element, const FloatRect& rect) const
     372bool SVGSVGElement::checkEnclosure(const SVGElement* element, const FloatRect& rect) const
    372373{
    373374    if (!element)
     
    769770// getElementById on SVGSVGElement is restricted to only the child subtree defined by the <svg> element.
    770771// See http://www.w3.org/TR/SVG11/struct.html#InterfaceSVGSVGElement
    771 Element* SVGSVGElement::getElementById(const AtomicString& id) const
     772Element* SVGSVGElement::getElementById(const AtomicString& id)
    772773{
    773774    Element* element = treeScope()->getElementById(id);
     
    777778    // Fall back to traversing our subtree. Duplicate ids are allowed, the first found will
    778779    // be returned.
    779     for (Element* element = ElementTraversal::firstWithin(this); element; element = ElementTraversal::next(element, this)) {
     780    for (auto element = elementDescendants(this).begin(), end = elementDescendants(this).end(); element != end; ++element) {
    780781        if (element->getIdAttribute() == id)
    781             return element;
     782            return &*element;
    782783    }
    783784    return 0;
  • trunk/Source/WebCore/svg/SVGSVGElement.h

    r154371 r154769  
    107107    PassRefPtr<NodeList> getIntersectionList(const FloatRect&, SVGElement* referenceElement) const;
    108108    PassRefPtr<NodeList> getEnclosureList(const FloatRect&, SVGElement* referenceElement) const;
    109     bool checkIntersection(SVGElement*, const FloatRect&) const;
    110     bool checkEnclosure(SVGElement*, const FloatRect&) const;
     109    bool checkIntersection(const SVGElement*, const FloatRect&) const;
     110    bool checkEnclosure(const SVGElement*, const FloatRect&) const;
    111111    void deselectAll();
    112112
     
    124124    void setupInitialView(const String& fragmentIdentifier, Element* anchorNode);
    125125
    126     Element* getElementById(const AtomicString&) const;
     126    Element* getElementById(const AtomicString&);
    127127
    128128    bool widthAttributeEstablishesViewport() const;
Note: See TracChangeset for help on using the changeset viewer.