Changeset 158530 in webkit


Ignore:
Timestamp:
Nov 3, 2013 3:13:53 AM (10 years ago)
Author:
Antti Koivisto
Message:

Add helpers for partial descendant traversal to element iterators
https://bugs.webkit.org/show_bug.cgi?id=123703

Reviewed by Andreas Kling.

  • dom/ElementAncestorIterator.h:

(WebCore::lineageOfType):

lineageOfType definition didn't match the declaration.

  • dom/ElementDescendantIterator.h:

(WebCore::::find):
(WebCore::::from):

Add find and from for getting begin iterator for partial traversals.

  • editing/FrameSelection.cpp:

(WebCore::scanForForm):
(WebCore::FrameSelection::currentForm):

  • html/HTMLFormElement.cpp:

(WebCore::HTMLFormElement::formElementIndex):
(WebCore::HTMLFormElement::findClosestFormAncestor):

Use them in a few places.

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r158529 r158530  
     12013-11-03  Antti Koivisto  <antti@apple.com>
     2
     3        Add helpers for partial descendant traversal to element iterators
     4        https://bugs.webkit.org/show_bug.cgi?id=123703
     5
     6        Reviewed by Andreas Kling.
     7
     8        * dom/ElementAncestorIterator.h:
     9        (WebCore::lineageOfType):
     10       
     11            lineageOfType definition didn't match the declaration.
     12
     13        * dom/ElementDescendantIterator.h:
     14        (WebCore::::find):
     15        (WebCore::::from):
     16       
     17            Add find and from for getting begin iterator for partial traversals.
     18
     19        * editing/FrameSelection.cpp:
     20        (WebCore::scanForForm):
     21        (WebCore::FrameSelection::currentForm):
     22        * html/HTMLFormElement.cpp:
     23        (WebCore::HTMLFormElement::formElementIndex):
     24        (WebCore::HTMLFormElement::findClosestFormAncestor):
     25       
     26            Use them in a few places.
     27
    1282013-11-03  Andreas Kling  <akling@apple.com>
    229
  • trunk/Source/WebCore/dom/ElementAncestorIterator.h

    r157924 r158530  
    183183
    184184template <typename ElementType>
    185 inline ElementAncestorIteratorAdapter<ElementType> lineageOfType(ElementType& first)
    186 {
    187     return ElementAncestorIteratorAdapter<ElementType>(&first);
    188 }
    189 
    190 template <typename ElementType>
    191 inline ElementAncestorConstIteratorAdapter<ElementType> lineageOfType(const ElementType& first)
    192 {
    193     return ElementAncestorConstIteratorAdapter<ElementType>(&first);
     185inline ElementAncestorIteratorAdapter<ElementType> lineageOfType(Element& first)
     186{
     187    if (isElementOfType<const ElementType>(first))
     188        return ElementAncestorIteratorAdapter<ElementType>(static_cast<ElementType*>(&first));
     189    return ancestorsOfType<ElementType>(first);
     190}
     191
     192template <typename ElementType>
     193inline ElementAncestorConstIteratorAdapter<ElementType> lineageOfType(const Element& first)
     194{
     195    if (isElementOfType<const ElementType>(first))
     196        return ElementAncestorConstIteratorAdapter<ElementType>(static_cast<const ElementType*>(&first));
     197    return ancestorsOfType<ElementType>(first);
    194198}
    195199
  • trunk/Source/WebCore/dom/ElementDescendantIterator.h

    r157924 r158530  
    5353    ElementDescendantIterator<ElementType> begin();
    5454    ElementDescendantIterator<ElementType> end();
     55    ElementDescendantIterator<ElementType> find(Element&);
     56    ElementDescendantIterator<ElementType> from(Element&);
     57
    5558    ElementType* first();
    5659    ElementType* last();
     
    6669    ElementDescendantConstIterator<ElementType> begin() const;
    6770    ElementDescendantConstIterator<ElementType> end() const;
     71    ElementDescendantConstIterator<ElementType> find(const Element&) const;
     72    ElementDescendantConstIterator<ElementType> from(const Element&) const;
     73
    6874    const ElementType* first() const;
    6975    const ElementType* last() const;
     
    138144    return ElementDescendantIterator<ElementType>(m_root);
    139145}
     146   
     147template <typename ElementType>
     148inline ElementDescendantIterator<ElementType> ElementDescendantIteratorAdapter<ElementType>::find(Element& descendant)
     149{
     150    if (!isElementOfType<const ElementType>(descendant))
     151        return end();
     152    if (!descendant.isDescendantOf(&m_root))
     153        return end();
     154    return ElementDescendantIterator<ElementType>(m_root, static_cast<ElementType*>(&descendant));
     155}
     156
     157template <typename ElementType>
     158inline ElementDescendantIterator<ElementType> ElementDescendantIteratorAdapter<ElementType>::from(Element& descendant)
     159{
     160    ASSERT(descendant.isDescendantOf(&m_root));
     161    if (isElementOfType<const ElementType>(descendant))
     162        return ElementDescendantIterator<ElementType>(m_root, static_cast<ElementType*>(&descendant));
     163    ElementType* next = Traversal<ElementType>::next(&m_root, &descendant);
     164    return ElementDescendantIterator<ElementType>(m_root, next);
     165}
    140166
    141167template <typename ElementType>
     
    172198
    173199template <typename ElementType>
     200inline ElementDescendantConstIterator<ElementType> ElementDescendantConstIteratorAdapter<ElementType>::find(const Element& descendant) const
     201{
     202    if (!isElementOfType<const ElementType>(descendant))
     203        return end();
     204    if (!descendant.isDescendantOf(&m_root))
     205        return end();
     206    return ElementDescendantConstIterator<ElementType>(m_root, static_cast<const ElementType*>(&descendant));
     207}
     208
     209template <typename ElementType>
     210inline ElementDescendantConstIterator<ElementType> ElementDescendantConstIteratorAdapter<ElementType>::from(const Element& descendant) const
     211{
     212    ASSERT(descendant.isDescendantOf(&m_root));
     213    if (isElementOfType<const ElementType>(descendant))
     214        return ElementDescendantConstIterator<ElementType>(m_root, static_cast<const ElementType*>(&descendant));
     215    const ElementType* next = Traversal<ElementType>::next(&m_root, &descendant);
     216    return ElementDescendantConstIterator<ElementType>(m_root, next);
     217}
     218
     219template <typename ElementType>
    174220inline const ElementType* ElementDescendantConstIteratorAdapter<ElementType>::first() const
    175221{
  • trunk/Source/WebCore/editing/FrameSelection.cpp

    r158350 r158530  
    3333#include "EditorClient.h"
    3434#include "Element.h"
    35 #include "ElementTraversal.h"
     35#include "ElementIterator.h"
    3636#include "EventHandler.h"
    3737#include "ExceptionCode.h"
     
    19501950
    19511951// Scans logically forward from "start", including any child frames.
    1952 static HTMLFormElement* scanForForm(Node* start)
     1952static HTMLFormElement* scanForForm(Element* start)
    19531953{
    19541954    if (!start)
    1955         return 0;
    1956     HTMLElement* element = start->isHTMLElement() ? toHTMLElement(start) : Traversal<HTMLElement>::next(start);
    1957     for (; element; element = Traversal<HTMLElement>::next(element)) {
    1958         if (isHTMLFormElement(element))
    1959             return toHTMLFormElement(element);
    1960         if (element->isFormControlElement())
    1961             return static_cast<HTMLFormControlElement*>(element)->form();
    1962         if (element->hasTagName(frameTag) || element->hasTagName(iframeTag))
    1963             if (HTMLFormElement* frameResult = scanForForm(toHTMLFrameElementBase(element)->contentDocument()))
     1955        return nullptr;
     1956
     1957    auto descendants = descendantsOfType<HTMLElement>(start->document());
     1958    for (auto it = descendants.from(*start), end = descendants.end(); it != end; ++it) {
     1959        HTMLElement& element = *it;
     1960        if (isHTMLFormElement(&element))
     1961            return toHTMLFormElement(&element);
     1962        if (element.isFormControlElement())
     1963            return static_cast<HTMLFormControlElement&>(element).form();
     1964        if (element.hasTagName(frameTag) || element.hasTagName(iframeTag)) {
     1965            if (HTMLFormElement* frameResult = scanForForm(toHTMLFrameElementBase(element).contentDocument()->documentElement()))
    19641966                return frameResult;
    1965     }
    1966     return 0;
     1967        }
     1968    }
     1969    return nullptr;
    19671970}
    19681971
     
    19711974{
    19721975    // Start looking either at the active (first responder) node, or where the selection is.
    1973     Node* start = m_frame->document()->focusedElement();
     1976    Element* start = m_frame->document()->focusedElement();
    19741977    if (!start)
    1975         start = this->start().deprecatedNode();
    1976 
    1977     // Try walking up the node tree to find a form element.
    1978     Node* node;
    1979     for (node = start; node; node = node->parentNode()) {
    1980         if (isHTMLFormElement(node))
    1981             return toHTMLFormElement(node);
    1982         if (node->isHTMLElement() && toHTMLElement(node)->isFormControlElement())
    1983             return static_cast<HTMLFormControlElement*>(node)->form();
    1984     }
     1978        start = this->start().element();
     1979    if (!start)
     1980        return nullptr;
     1981
     1982    if (auto form = lineageOfType<HTMLFormElement>(*start).first())
     1983        return form;
     1984    if (auto formControl = lineageOfType<HTMLFormControlElement>(*start).first())
     1985        return formControl->form();
    19851986
    19861987    // Try walking forward in the node tree to find a form element.
  • trunk/Source/WebCore/html/HTMLFormElement.cpp

    r157971 r158530  
    2828#include "Attribute.h"
    2929#include "Document.h"
    30 #include "ElementTraversal.h"
     30#include "ElementIterator.h"
    3131#include "Event.h"
    3232#include "EventNames.h"
     
    463463    }
    464464
     465    unsigned currentAssociatedElementsAfterIndex = m_associatedElementsAfterIndex;
     466    ++m_associatedElementsAfterIndex;
     467
    465468    // Check for the special case where this element is the very last thing in
    466469    // the form's tree of children; we don't want to walk the entire tree in that
    467470    // common case that occurs during parsing; instead we'll just return a value
    468471    // that says "add this form element to the end of the array".
    469     if (ElementTraversal::next(&associatedHTMLElement, this)) {
    470         unsigned i = m_associatedElementsBeforeIndex;
    471         for (Element* element = this; element; element = ElementTraversal::next(element, this)) {
    472             if (element == &associatedHTMLElement) {
    473                 ++m_associatedElementsAfterIndex;
    474                 return i;
    475             }
    476             if (!element->isFormControlElement() && !element->hasTagName(objectTag))
    477                 continue;
    478             if (!element->isHTMLElement() || toHTMLElement(element)->form() != this)
    479                 continue;
    480             ++i;
    481         }
    482     }
    483     return m_associatedElementsAfterIndex++;
     472    auto descendants = descendantsOfType<HTMLElement>(*this);
     473    auto it = descendants.find(associatedHTMLElement);
     474    auto end = descendants.end();
     475    if (it == end || ++it == end)
     476        return currentAssociatedElementsAfterIndex;
     477
     478    unsigned i = m_associatedElementsBeforeIndex;
     479    for (auto it = descendants.begin(); it != end; ++it) {
     480        HTMLElement& element = *it;
     481        if (&element == &associatedHTMLElement)
     482            return i;
     483        if (!element.isFormControlElement() && !element.hasTagName(objectTag))
     484            continue;
     485        if (element.form() != this)
     486            continue;
     487        ++i;
     488    }
     489    return currentAssociatedElementsAfterIndex;
    484490}
    485491
     
    728734HTMLFormElement* HTMLFormElement::findClosestFormAncestor(const Element& startElement)
    729735{
    730     for (Element* element = startElement.parentElement(); element; element = element->parentElement()) {
    731         if (isHTMLFormElement(element))
    732             return toHTMLFormElement(element);
    733     }
    734     return 0;
     736    return const_cast<HTMLFormElement*>(ancestorsOfType<HTMLFormElement>(startElement).first());
    735737}
    736738
Note: See TracChangeset for help on using the changeset viewer.