Diff
Modified: trunk/Source/WebCore/ChangeLog (154939 => 154940)
--- trunk/Source/WebCore/ChangeLog 2013-09-01 06:26:12 UTC (rev 154939)
+++ trunk/Source/WebCore/ChangeLog 2013-09-01 10:33:08 UTC (rev 154940)
@@ -1,3 +1,76 @@
+2013-08-31 Antti Koivisto <[email protected]>
+
+ Add element ancestor iterator
+ https://bugs.webkit.org/show_bug.cgi?id=120563
+
+ Reviewed by Andreas Kling.
+
+ This patch adds ancestor iterators. They iterate over elements parent chain up to the root.
+
+ To iterate over Element ancestors:
+
+ auto ancestors = elementAncestors(this);
+ for (auto it = ancestors.begin(), end = ancestors.end(); it != end; ++it) {
+ Element& element = *it;
+ ...
+
+ To iterate over Element ancestors including the current element:
+
+ auto lineage = elementLineage(this);
+ for (auto it = lineage.begin(), end = lineage.end(); it != end; ++it) {
+ Element& element = *it;
+ ...
+
+ To iterate over ancestors of a specific Element subclass:
+
+ auto htmlAncestors = ancestorsOfType<HTMLElement>(this);
+ for (auto it = htmlAncestors.begin(), end = htmlAncestors.end(); it != end; ++it) {
+ HTMLElement& htmlElement = *it;
+ ...
+
+ To iterate over ancestors of a specific Element subclass including the current element:
+
+ auto htmlLineage = lineageOfType<HTMLElement>(this);
+ for (auto it = htmlLineage.begin(), end = htmlLineage.end(); it != end; ++it) {
+ HTMLElement& htmlElement = *it;
+ ...
+
+ The patch also uses the new types in a few places.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * accessibility/AccessibilityNodeObject.cpp:
+ (WebCore::AccessibilityNodeObject::mouseButtonListener):
+ (WebCore::AccessibilityNodeObject::labelForElement):
+ * dom/ElementAncestorIterator.h: Added.
+ (WebCore::::ElementAncestorIterator):
+ (WebCore::::operator):
+ (WebCore::::ElementAncestorConstIterator):
+ (WebCore::::ElementAncestorIteratorAdapter):
+ (WebCore::::begin):
+ (WebCore::::end):
+ (WebCore::::ElementAncestorConstIteratorAdapter):
+ (WebCore::elementLineage):
+ (WebCore::elementAncestors):
+ (WebCore::ancestorsOfType):
+ * dom/ElementIterator.h:
+ (WebCore::findElementAncestorOfType):
+ (WebCore::::traverseAncestor):
+ (WebCore::=):
+ * html/HTMLElement.cpp:
+ (WebCore::HTMLElement::adjustDirectionalityIfNeededAfterChildAttributeChanged):
+ * html/HTMLFieldSetElement.h:
+ (WebCore::isHTMLFieldSetElement):
+ (WebCore::HTMLFieldSetElement):
+ * html/HTMLFrameSetElement.cpp:
+ (WebCore::HTMLFrameSetElement::findContaining):
+ * html/HTMLFrameSetElement.h:
+ (WebCore::HTMLFrameSetElement):
+ * html/HTMLInputElement.h:
+ (WebCore::isHTMLInputElement):
+ (WebCore::toHTMLInputElement):
+ * html/HTMLLegendElement.cpp:
+ (WebCore::HTMLLegendElement::associatedControl):
+
2013-08-31 Darin Adler <[email protected]>
Refactor URL and image writing so layer-violating parts are in Editor, not Pasteboard (Mac-only at first)
Modified: trunk/Source/WebCore/GNUmakefile.list.am (154939 => 154940)
--- trunk/Source/WebCore/GNUmakefile.list.am 2013-09-01 06:26:12 UTC (rev 154939)
+++ trunk/Source/WebCore/GNUmakefile.list.am 2013-09-01 10:33:08 UTC (rev 154940)
@@ -2869,6 +2869,7 @@
Source/WebCore/dom/DOMTimeStamp.h \
Source/WebCore/dom/Element.cpp \
Source/WebCore/dom/Element.h \
+ Source/WebCore/dom/ElementAncestorIterator.h \
Source/WebCore/dom/ElementChildIterator.h \
Source/WebCore/dom/ElementData.cpp \
Source/WebCore/dom/ElementData.h \
Modified: trunk/Source/WebCore/Target.pri (154939 => 154940)
--- trunk/Source/WebCore/Target.pri 2013-09-01 06:26:12 UTC (rev 154939)
+++ trunk/Source/WebCore/Target.pri 2013-09-01 10:33:08 UTC (rev 154940)
@@ -1610,6 +1610,7 @@
dom/DOMTimeStamp.h \
dom/DatasetDOMStringMap.h \
dom/Element.h \
+ dom/ElementAncestorIterator.h \
dom/ElementChildIterator.h \
dom/ElementData.h \
dom/ElementDescendantIterator.h \
Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (154939 => 154940)
--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj 2013-09-01 06:26:12 UTC (rev 154939)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj 2013-09-01 10:33:08 UTC (rev 154940)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="DebugSuffix|Win32">
@@ -20262,6 +20262,7 @@
<ClInclude Include="..\dom\DOMStringMap.h" />
<ClInclude Include="..\dom\DOMTimeStamp.h" />
<ClInclude Include="..\dom\Element.h" />
+ <ClInclude Include="..\dom\ElementAncestorIterator.h" />
<ClInclude Include="..\dom\ElementChildIterator.h" />
<ClInclude Include="..\dom\ElementData.h" />
<ClInclude Include="..\dom\ElementDescendantIterator.h" />
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (154939 => 154940)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2013-09-01 06:26:12 UTC (rev 154939)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2013-09-01 10:33:08 UTC (rev 154940)
@@ -5506,6 +5506,7 @@
E49BD9FA131FD2ED003C56F0 /* CSSValuePool.h in Headers */ = {isa = PBXBuildFile; fileRef = E49BD9F9131FD2ED003C56F0 /* CSSValuePool.h */; settings = {ATTRIBUTES = (Private, ); }; };
E49BDA0B131FD3E5003C56F0 /* CSSValuePool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E49BDA0A131FD3E5003C56F0 /* CSSValuePool.cpp */; };
E4AE7C1617D1BB950009FB31 /* ElementIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AE7C1517D1BB950009FB31 /* ElementIterator.h */; };
+ E4AE7C1A17D232350009FB31 /* ElementAncestorIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AE7C1917D232350009FB31 /* ElementAncestorIterator.h */; };
E4AFCFA50DAF29A300F5F55C /* UnitBezier.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AFCFA40DAF29A300F5F55C /* UnitBezier.h */; };
E4AFD00B0DAF335400F5F55C /* SMILTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4AFD0050DAF335400F5F55C /* SMILTime.cpp */; };
E4AFD00C0DAF335400F5F55C /* SMILTime.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AFD0060DAF335400F5F55C /* SMILTime.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -12280,6 +12281,7 @@
E49BD9F9131FD2ED003C56F0 /* CSSValuePool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSValuePool.h; sourceTree = "<group>"; };
E49BDA0A131FD3E5003C56F0 /* CSSValuePool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSValuePool.cpp; sourceTree = "<group>"; };
E4AE7C1517D1BB950009FB31 /* ElementIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementIterator.h; sourceTree = "<group>"; };
+ E4AE7C1917D232350009FB31 /* ElementAncestorIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementAncestorIterator.h; sourceTree = "<group>"; };
E4AFCFA40DAF29A300F5F55C /* UnitBezier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnitBezier.h; sourceTree = "<group>"; };
E4AFD0050DAF335400F5F55C /* SMILTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SMILTime.cpp; sourceTree = "<group>"; };
E4AFD0060DAF335400F5F55C /* SMILTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SMILTime.h; sourceTree = "<group>"; };
@@ -20223,6 +20225,7 @@
A8C4A7F609D563270003AC8D /* Element.cpp */,
A8C4A7F509D563270003AC8D /* Element.h */,
93EEC1EA09C2877700C515D1 /* Element.idl */,
+ E4AE7C1917D232350009FB31 /* ElementAncestorIterator.h */,
E46A2B1D17CA76B1000DBCD8 /* ElementChildIterator.h */,
B5B7A16F17C1080600E4AA0A /* ElementData.cpp */,
B5B7A16E17C1048000E4AA0A /* ElementData.h */,
@@ -22225,6 +22228,7 @@
31FB1A66120A5D3F00DC02A0 /* JSDeviceMotionEvent.h in Headers */,
59A86008119DAFA100DEF1EF /* JSDeviceOrientationEvent.h in Headers */,
BCE4389C140B1BA8005E437E /* JSDictionary.h in Headers */,
+ E4AE7C1A17D232350009FB31 /* ElementAncestorIterator.h in Headers */,
8987858B122CA26A003AABDA /* JSDirectoryEntry.h in Headers */,
893C483312495472002B3D86 /* JSDirectoryEntrySync.h in Headers */,
8987858D122CA26A003AABDA /* JSDirectoryReader.h in Headers */,
Modified: trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp (154939 => 154940)
--- trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp 2013-09-01 06:26:12 UTC (rev 154939)
+++ trunk/Source/WebCore/accessibility/AccessibilityNodeObject.cpp 2013-09-01 10:33:08 UTC (rev 154940)
@@ -977,21 +977,16 @@
return 0;
// check if our parent is a mouse button listener
- while (node && !node->isElementNode())
- node = node->parentNode();
-
- if (!node)
- return 0;
-
// FIXME: Do the continuation search like anchorElement does
- for (Element* element = toElement(node); element; element = element->parentElement()) {
+ auto lineage = elementLineage(node->isElementNode() ? toElement(node) : node->parentElement());
+ for (auto element = lineage.begin(), end = lineage.end(); element != end; ++element) {
// If we've reached the body and this is not a control element, do not expose press action for this element.
// It can cause false positives, where every piece of text is labeled as accepting press actions.
if (element->hasTagName(bodyTag) && isStaticText())
break;
if (element->hasEventListeners(eventNames().clickEvent) || element->hasEventListeners(eventNames().mousedownEvent) || element->hasEventListeners(eventNames().mouseupEvent))
- return element;
+ return &*element;
}
return 0;
@@ -1099,12 +1094,9 @@
return label;
}
- for (Element* parent = element->parentElement(); parent; parent = parent->parentElement()) {
- if (isHTMLLabelElement(parent))
- return toHTMLLabelElement(parent);
- }
-
- return 0;
+ auto labelAncestors = ancestorsOfType<HTMLLabelElement>(element);
+ auto enclosingLabel = labelAncestors.begin();
+ return enclosingLabel != labelAncestors.end() ? &*enclosingLabel : nullptr;
}
String AccessibilityNodeObject::ariaAccessibilityDescription() const
Added: trunk/Source/WebCore/dom/ElementAncestorIterator.h (0 => 154940)
--- trunk/Source/WebCore/dom/ElementAncestorIterator.h (rev 0)
+++ trunk/Source/WebCore/dom/ElementAncestorIterator.h 2013-09-01 10:33:08 UTC (rev 154940)
@@ -0,0 +1,210 @@
+/*
+ * 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 <typename ElementType>
+class ElementAncestorIterator : public ElementIterator<ElementType> {
+public:
+ ElementAncestorIterator();
+ ElementAncestorIterator(ElementType* current);
+ ElementAncestorIterator& operator++();
+};
+
+template <typename ElementType>
+class ElementAncestorConstIterator : public ElementConstIterator<ElementType> {
+public:
+ ElementAncestorConstIterator();
+ ElementAncestorConstIterator(const ElementType* current);
+ ElementAncestorConstIterator& operator++();
+};
+
+template <typename ElementType>
+class ElementAncestorIteratorAdapter {
+public:
+ ElementAncestorIteratorAdapter(ElementType* descendant);
+ ElementAncestorIterator<ElementType> begin();
+ ElementAncestorIterator<ElementType> end();
+
+private:
+ ElementType* m_first;
+};
+
+template <typename ElementType>
+class ElementAncestorConstIteratorAdapter {
+public:
+ ElementAncestorConstIteratorAdapter(const ElementType* descendant);
+ ElementAncestorConstIterator<ElementType> begin() const;
+ ElementAncestorConstIterator<ElementType> end() const;
+
+private:
+ const ElementType* m_first;
+};
+
+ElementAncestorIteratorAdapter<Element> elementLineage(Element* first);
+ElementAncestorConstIteratorAdapter<Element> elementLineage(const Element* first);
+ElementAncestorIteratorAdapter<Element> elementAncestors(Element* descendant);
+ElementAncestorConstIteratorAdapter<Element> elementAncestors(const Element* descendant);
+template <typename ElementType> ElementAncestorIteratorAdapter<ElementType> lineageOfType(Element* first);
+template <typename ElementType> ElementAncestorConstIteratorAdapter<ElementType> lineageOfType(const Element* first);
+template <typename ElementType> ElementAncestorIteratorAdapter<ElementType> ancestorsOfType(Element* descendant);
+template <typename ElementType> ElementAncestorConstIteratorAdapter<ElementType> ancestorsOfType(const Element* descendant);
+
+// ElementAncestorIterator
+
+template <typename ElementType>
+inline ElementAncestorIterator<ElementType>::ElementAncestorIterator()
+ : ElementIterator<ElementType>(nullptr)
+{
+}
+
+template <typename ElementType>
+inline ElementAncestorIterator<ElementType>::ElementAncestorIterator(ElementType* current)
+ : ElementIterator<ElementType>(nullptr, current)
+{
+}
+
+template <typename ElementType>
+inline ElementAncestorIterator<ElementType>& ElementAncestorIterator<ElementType>::operator++()
+{
+ return static_cast<ElementAncestorIterator<ElementType>&>(ElementIterator<ElementType>::traverseAncestor());
+}
+
+// ElementAncestorConstIterator
+
+template <typename ElementType>
+inline ElementAncestorConstIterator<ElementType>::ElementAncestorConstIterator()
+ : ElementConstIterator<ElementType>(nullptr)
+{
+}
+
+template <typename ElementType>
+inline ElementAncestorConstIterator<ElementType>::ElementAncestorConstIterator(const ElementType* current)
+ : ElementConstIterator<ElementType>(nullptr, current)
+{
+}
+
+template <typename ElementType>
+inline ElementAncestorConstIterator<ElementType>& ElementAncestorConstIterator<ElementType>::operator++()
+{
+ return static_cast<ElementAncestorConstIterator<ElementType>&>(ElementConstIterator<ElementType>::traverseAncestor());
+}
+
+// ElementAncestorIteratorAdapter
+
+template <typename ElementType>
+inline ElementAncestorIteratorAdapter<ElementType>::ElementAncestorIteratorAdapter(ElementType* first)
+ : m_first(first)
+{
+}
+
+template <typename ElementType>
+inline ElementAncestorIterator<ElementType> ElementAncestorIteratorAdapter<ElementType>::begin()
+{
+ return ElementAncestorIterator<ElementType>(m_first);
+}
+
+template <typename ElementType>
+inline ElementAncestorIterator<ElementType> ElementAncestorIteratorAdapter<ElementType>::end()
+{
+ return ElementAncestorIterator<ElementType>();
+}
+
+// ElementAncestorConstIteratorAdapter
+
+template <typename ElementType>
+inline ElementAncestorConstIteratorAdapter<ElementType>::ElementAncestorConstIteratorAdapter(const ElementType* first)
+ : m_first(first)
+{
+}
+
+template <typename ElementType>
+inline ElementAncestorConstIterator<ElementType> ElementAncestorConstIteratorAdapter<ElementType>::begin() const
+{
+ return ElementAncestorConstIterator<ElementType>(m_first);
+}
+
+template <typename ElementType>
+inline ElementAncestorConstIterator<ElementType> ElementAncestorConstIteratorAdapter<ElementType>::end() const
+{
+ return ElementAncestorConstIterator<ElementType>();
+}
+
+// Standalone functions
+
+inline ElementAncestorIteratorAdapter<Element> elementLineage(Element* first)
+{
+ return ElementAncestorIteratorAdapter<Element>(first);
+}
+
+inline ElementAncestorConstIteratorAdapter<Element> elementLineage(const Element* first)
+{
+ return ElementAncestorConstIteratorAdapter<Element>(first);
+}
+
+inline ElementAncestorIteratorAdapter<Element> elementAncestors(Element* descendant)
+{
+ return ElementAncestorIteratorAdapter<Element>(descendant->parentElement());
+}
+
+inline ElementAncestorConstIteratorAdapter<Element> elementAncestors(const Element* descendant)
+{
+ return ElementAncestorConstIteratorAdapter<Element>(descendant->parentElement());
+}
+
+template <typename ElementType>
+inline ElementAncestorIteratorAdapter<ElementType> lineageOfType(ElementType* first)
+{
+ return ElementAncestorIteratorAdapter<ElementType>(first);
+}
+
+template <typename ElementType>
+inline ElementAncestorConstIteratorAdapter<ElementType> lineageOfType(const ElementType* first)
+{
+ return ElementAncestorConstIteratorAdapter<ElementType>(first);
+}
+
+template <typename ElementType>
+inline ElementAncestorIteratorAdapter<ElementType> ancestorsOfType(Element* descendant)
+{
+ ElementType* first = findElementAncestorOfType<ElementType>(*descendant);
+ return ElementAncestorIteratorAdapter<ElementType>(first);
+}
+
+template <typename ElementType>
+inline ElementAncestorConstIteratorAdapter<ElementType> ancestorsOfType(const Element* descendant)
+{
+ const ElementType* first = findElementAncestorOfType<const ElementType>(*descendant);
+ return ElementAncestorConstIteratorAdapter<ElementType>(first);
+}
+
+}
+
+#endif
Modified: trunk/Source/WebCore/dom/ElementIterator.h (154939 => 154940)
--- trunk/Source/WebCore/dom/ElementIterator.h 2013-09-01 06:26:12 UTC (rev 154939)
+++ trunk/Source/WebCore/dom/ElementIterator.h 2013-09-01 10:33:08 UTC (rev 154940)
@@ -43,12 +43,14 @@
ElementType& operator*();
ElementType* operator->();
+ bool operator==(const ElementIterator& other) const;
bool operator!=(const ElementIterator& other) const;
ElementIterator& traverseNext();
ElementIterator& traversePrevious();
ElementIterator& traverseNextSibling();
ElementIterator& traversePreviousSibling();
+ ElementIterator& traverseAncestor();
private:
const ContainerNode* m_root;
@@ -68,12 +70,14 @@
const ElementType& operator*() const;
const ElementType* operator->() const;
+ bool operator==(const ElementConstIterator& other) const;
bool operator!=(const ElementConstIterator& other) const;
ElementConstIterator& traverseNext();
ElementConstIterator& traversePrevious();
ElementConstIterator& traverseNextSibling();
ElementConstIterator& traversePreviousSibling();
+ ElementConstIterator& traverseAncestor();
private:
const ContainerNode* m_root;
@@ -159,7 +163,38 @@
return *this;
}
+template <typename ElementTypeWithConst>
+inline ElementTypeWithConst* findElementAncestorOfType(const Element& current)
+{
+ ContainerNode* ancestor = current.parentNode();
+ while (ancestor && ancestor->isElementNode()) {
+ // Non-root containers are always Elements.
+ Element* element = toElement(ancestor);
+ if (isElementOfType<ElementTypeWithConst>(element))
+ return static_cast<ElementTypeWithConst*>(element);
+ ancestor = ancestor->parentNode();
+ }
+ return nullptr;
+}
+
template <typename ElementType>
+inline ElementIterator<ElementType>& ElementIterator<ElementType>::traverseAncestor()
+{
+ ASSERT(m_current);
+ ASSERT(m_current != m_root);
+ ASSERT(!m_assertions.domTreeHasMutated());
+
+ m_current = findElementAncestorOfType<ElementType>(*m_current);
+
+#if !ASSERT_DISABLED
+ // Drop the assertion when the iterator reaches the end.
+ if (!m_current)
+ m_assertions.dropEventDispatchAssertion();
+#endif
+ return *this;
+}
+
+template <typename ElementType>
inline ElementType& ElementIterator<ElementType>::operator*()
{
ASSERT(m_current);
@@ -176,13 +211,19 @@
}
template <typename ElementType>
-inline bool ElementIterator<ElementType>::operator!=(const ElementIterator& other) const
+inline bool ElementIterator<ElementType>::operator==(const ElementIterator& other) const
{
ASSERT(m_root == other.m_root);
ASSERT(!m_assertions.domTreeHasMutated());
- return m_current != other.m_current;
+ return m_current == other.m_current;
}
+template <typename ElementType>
+inline bool ElementIterator<ElementType>::operator!=(const ElementIterator& other) const
+{
+ return !(*this == other);
+}
+
// ElementConstIterator
template <typename ElementType>
@@ -259,6 +300,23 @@
}
template <typename ElementType>
+inline ElementConstIterator<ElementType>& ElementConstIterator<ElementType>::traverseAncestor()
+{
+ ASSERT(m_current);
+ ASSERT(m_current != m_root);
+ ASSERT(!m_assertions.domTreeHasMutated());
+
+ m_current = findElementAncestorOfType<const ElementType>(*m_current);
+
+#if !ASSERT_DISABLED
+ // Drop the assertion when the iterator reaches the end.
+ if (!m_current)
+ m_assertions.dropEventDispatchAssertion();
+#endif
+ return *this;
+}
+
+template <typename ElementType>
inline const ElementType& ElementConstIterator<ElementType>::operator*() const
{
ASSERT(m_current);
@@ -275,15 +333,22 @@
}
template <typename ElementType>
-inline bool ElementConstIterator<ElementType>::operator!=(const ElementConstIterator& other) const
+inline bool ElementConstIterator<ElementType>::operator==(const ElementConstIterator& other) const
{
ASSERT(m_root == other.m_root);
ASSERT(!m_assertions.domTreeHasMutated());
- return m_current != other.m_current;
+ return m_current == other.m_current;
}
+template <typename ElementType>
+inline bool ElementConstIterator<ElementType>::operator!=(const ElementConstIterator& other) const
+{
+ return !(*this == other);
}
+}
+
+#include "ElementAncestorIterator.h"
#include "ElementChildIterator.h"
#include "ElementDescendantIterator.h"
Modified: trunk/Source/WebCore/html/HTMLElement.cpp (154939 => 154940)
--- trunk/Source/WebCore/html/HTMLElement.cpp 2013-09-01 06:26:12 UTC (rev 154939)
+++ trunk/Source/WebCore/html/HTMLElement.cpp 2013-09-01 10:33:08 UTC (rev 154940)
@@ -32,6 +32,7 @@
#include "CSSValuePool.h"
#include "DOMSettableTokenList.h"
#include "DocumentFragment.h"
+#include "ElementIterator.h"
#include "Event.h"
#include "EventListener.h"
#include "EventNames.h"
@@ -889,13 +890,13 @@
Node* strongDirectionalityTextNode;
TextDirection textDirection = directionality(&strongDirectionalityTextNode);
setHasDirAutoFlagRecursively(child, false);
- if (renderer() && renderer()->style() && renderer()->style()->direction() != textDirection) {
- Element* elementToAdjust = this;
- for (; elementToAdjust; elementToAdjust = elementToAdjust->parentElement()) {
- if (elementAffectsDirectionality(elementToAdjust)) {
- elementToAdjust->setNeedsStyleRecalc();
- return;
- }
+ if (!renderer() || !renderer()->style() || renderer()->style()->direction() == textDirection)
+ return;
+ auto lineage = elementLineage(this);
+ for (auto elementToAdjust = lineage.begin(), end = lineage.end(); elementToAdjust != end; ++elementToAdjust) {
+ if (elementAffectsDirectionality(&*elementToAdjust)) {
+ elementToAdjust->setNeedsStyleRecalc();
+ return;
}
}
}
@@ -930,9 +931,10 @@
if (oldMarkedNode)
setHasDirAutoFlagRecursively(oldMarkedNode, false);
- for (Element* elementToAdjust = this; elementToAdjust; elementToAdjust = elementToAdjust->parentElement()) {
- if (elementAffectsDirectionality(elementToAdjust)) {
- toHTMLElement(elementToAdjust)->calculateAndAdjustDirectionality();
+ auto lineage = lineageOfType<HTMLElement>(this);
+ for (auto elementToAdjust = lineage.begin(), end = lineage.end(); elementToAdjust != end; ++elementToAdjust) {
+ if (elementAffectsDirectionality(&*elementToAdjust)) {
+ elementToAdjust->calculateAndAdjustDirectionality();
return;
}
}
Modified: trunk/Source/WebCore/html/HTMLFieldSetElement.h (154939 => 154940)
--- trunk/Source/WebCore/html/HTMLFieldSetElement.h 2013-09-01 06:26:12 UTC (rev 154939)
+++ trunk/Source/WebCore/html/HTMLFieldSetElement.h 2013-09-01 10:33:08 UTC (rev 154940)
@@ -63,6 +63,19 @@
mutable uint64_t m_documentVersion;
};
+inline bool isHTMLFieldSetElement(const Node* node)
+{
+ return node->isElementNode() && toElement(node)->hasTagName(HTMLNames::fieldsetTag);
+}
+
+inline bool isHTMLFieldSetElement(const Element* element)
+{
+ return element->hasTagName(HTMLNames::fieldsetTag);
+}
+
+template <> inline bool isElementOfType<HTMLFieldSetElement>(const Element* element) { return isHTMLFieldSetElement(element); }
+
+
} // namespace
#endif
Modified: trunk/Source/WebCore/html/HTMLFrameSetElement.cpp (154939 => 154940)
--- trunk/Source/WebCore/html/HTMLFrameSetElement.cpp 2013-09-01 06:26:12 UTC (rev 154939)
+++ trunk/Source/WebCore/html/HTMLFrameSetElement.cpp 2013-09-01 10:33:08 UTC (rev 154940)
@@ -27,6 +27,7 @@
#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "Document.h"
+#include "ElementIterator.h"
#include "Event.h"
#include "EventNames.h"
#include "Frame.h"
@@ -163,13 +164,11 @@
return new (arena) RenderFrameSet(this);
}
-HTMLFrameSetElement* HTMLFrameSetElement::findContaining(Node* node)
+HTMLFrameSetElement* HTMLFrameSetElement::findContaining(Element* descendant)
{
- for (Element* parent = node->parentElement(); parent; parent = parent->parentElement()) {
- if (isHTMLFrameSetElement(parent))
- return toHTMLFrameSetElement(parent);
- }
- return 0;
+ auto ancestorFrameSets = ancestorsOfType<HTMLFrameSetElement>(descendant);
+ auto enclosingFrameSet = ancestorFrameSets.begin();
+ return enclosingFrameSet != ancestorFrameSets.end() ? &*enclosingFrameSet : nullptr;
}
void HTMLFrameSetElement::willAttachRenderers()
Modified: trunk/Source/WebCore/html/HTMLFrameSetElement.h (154939 => 154940)
--- trunk/Source/WebCore/html/HTMLFrameSetElement.h 2013-09-01 06:26:12 UTC (rev 154939)
+++ trunk/Source/WebCore/html/HTMLFrameSetElement.h 2013-09-01 10:33:08 UTC (rev 154940)
@@ -45,7 +45,7 @@
const Length* rowLengths() const { return m_rowLengths.get(); }
const Length* colLengths() const { return m_colLengths.get(); }
- static HTMLFrameSetElement* findContaining(Node* descendant);
+ static HTMLFrameSetElement* findContaining(Element* descendant);
// Declared virtual in Element
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur);
@@ -122,6 +122,8 @@
return static_cast<const HTMLFrameSetElement*>(node);
}
+template <> inline bool isElementOfType<HTMLFrameSetElement>(const Element* element) { return isHTMLFrameSetElement(element); }
+
} // namespace WebCore
#endif // HTMLFrameSetElement_h
Modified: trunk/Source/WebCore/html/HTMLInputElement.h (154939 => 154940)
--- trunk/Source/WebCore/html/HTMLInputElement.h 2013-09-01 06:26:12 UTC (rev 154939)
+++ trunk/Source/WebCore/html/HTMLInputElement.h 2013-09-01 10:33:08 UTC (rev 154940)
@@ -443,12 +443,12 @@
#endif
};
-inline bool isHTMLInputElement(Node* node)
+inline bool isHTMLInputElement(const Node* node)
{
return node->hasTagName(HTMLNames::inputTag);
}
-inline bool isHTMLInputElement(Element* element)
+inline bool isHTMLInputElement(const Element* element)
{
return element->hasTagName(HTMLNames::inputTag);
}
@@ -459,5 +459,11 @@
return static_cast<HTMLInputElement*>(node);
}
+inline const HTMLInputElement* toHTMLInputElement(const Node* node)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!node || isHTMLInputElement(node));
+ return static_cast<const HTMLInputElement*>(node);
+}
+
} //namespace
#endif
Modified: trunk/Source/WebCore/html/HTMLLegendElement.cpp (154939 => 154940)
--- trunk/Source/WebCore/html/HTMLLegendElement.cpp 2013-09-01 06:26:12 UTC (rev 154939)
+++ trunk/Source/WebCore/html/HTMLLegendElement.cpp 2013-09-01 10:33:08 UTC (rev 154940)
@@ -25,7 +25,7 @@
#include "config.h"
#include "HTMLLegendElement.h"
-#include "ElementTraversal.h"
+#include "ElementIterator.h"
#include "HTMLFieldSetElement.h"
#include "HTMLFormControlElement.h"
#include "HTMLNames.h"
@@ -49,21 +49,16 @@
HTMLFormControlElement* HTMLLegendElement::associatedControl()
{
// Check if there's a fieldset belonging to this legend.
- Element* fieldset = parentElement();
- while (fieldset && !fieldset->hasTagName(fieldsetTag))
- fieldset = fieldset->parentElement();
- if (!fieldset)
+ auto fieldsetAncestors = ancestorsOfType<HTMLFieldSetElement>(this);
+ auto enclosingFieldset = fieldsetAncestors.begin();
+ if (enclosingFieldset == fieldsetAncestors.end())
return 0;
// Find first form element inside the fieldset that is not a legend element.
// FIXME: Should we consider tabindex?
- Element* element = fieldset;
- while ((element = ElementTraversal::next(element, fieldset))) {
- if (element->isFormControlElement())
- return static_cast<HTMLFormControlElement*>(element);
- }
-
- return 0;
+ auto fieldsetFormControlDescendants = descendantsOfType<HTMLFormControlElement>(&*enclosingFieldset);
+ auto firstFormControl = fieldsetFormControlDescendants.begin();
+ return firstFormControl != fieldsetFormControlDescendants.end() ? &*firstFormControl : nullptr;
}
void HTMLLegendElement::focus(bool, FocusDirection direction)