Title: [122660] trunk
Revision
122660
Author
[email protected]
Date
2012-07-14 00:08:55 -0700 (Sat, 14 Jul 2012)

Log Message

Iterating backwards over HTMLCollection is O(n^2)
https://bugs.webkit.org/show_bug.cgi?id=91306

Reviewed by Anders Carlsson.

Source/WebCore: 

Fixed the bug by introducing itemBefore that iterates nodes backwards to complement itemAfter.
Unfortunately, some HTML collections such as HTMLFormCollection and HTMLTableRowsCollection have
its own itemAfter function and writing an equivalent itemBefore is somewhat tricky. For now,
added a new boolean flag indicating whether a given HTML collection supports itemBefore or not,
and left those HTML collections that override itemAfter alone.

This also paves our way to share more code between DynamicNodeList and HTMLCollection.

Test: perf/htmlcollection-backwards-iteration.html

* dom/DynamicNodeList.h:
(WebCore::DynamicNodeListCacheBase::DynamicNodeListCacheBase): Takes ItemBeforeSupportType.
(WebCore::DynamicNodeListCacheBase::supportsItemBefore): Added.
(DynamicNodeListCacheBase):
(WebCore::DynamicNodeListCacheBase::setItemCache): Replaced a FIXME by an assertion now that
we can.
* html/HTMLAllCollection.cpp:
(WebCore::HTMLAllCollection::HTMLAllCollection): Supports itemBefore since it doesn't override
itemAfter.
* html/HTMLCollection.cpp:
(WebCore::HTMLCollection::HTMLCollection):
(WebCore::HTMLCollection::create):
(WebCore::isAcceptableElement): Made it a static local function instead of a static member.
(WebCore::nextNode): Templatized.
(WebCore::itemBeforeOrAfter): Extracted from itemAfter and templatized.
(WebCore::HTMLCollection::itemBefore): Added.
(WebCore::HTMLCollection::itemAfter):
(WebCore::HTMLCollection::shouldSearchFromFirstItem): Added. Determines whether we should reset
the item cache to the first item. We obviously do if the cache is invalid. If the target offset
is after the cached offset, then we shouldn't go back regardless of availability of itemBefore.
Otherwise, we go back to the first item iff itemBefore is not available or the distance from
the cached offset to the target offset is greater than the target offset itself.
(WebCore::HTMLCollection::length):
(WebCore::HTMLCollection::item): Use the term "offset" to match the terminology elsewhere.
(WebCore::HTMLCollection::itemBeforeOrAfterCachedItem): Ditto. Also added the logic to iterate
nodes backwards using itemBefore. Once we're in this branch, we should always find a matching
item since the target offset was less than the cached offset, and offsets are non-negative.
If we had ever reached the end of the loop without finding an item, it indicates that the cache
has been invalid and we have some serious bug elsewhere.
* html/HTMLCollection.h:
(WebCore::HTMLCollectionCacheBase::HTMLCollectionCacheBase):
(HTMLCollection):
* html/HTMLOptionsCollection.cpp:
(WebCore::HTMLOptionsCollection::HTMLOptionsCollection): Supports itemBefore since it doesn't
override itemAfter.
* html/HTMLFormCollection.cpp:
(WebCore::HTMLFormCollection::HTMLFormCollection): Doesn't support itemBefore as it overrides
itemAfter.
* html/HTMLNameCollection.cpp:
(WebCore::HTMLNameCollection::HTMLNameCollection): Ditto.
* html/HTMLPropertiesCollection.cpp:
(WebCore::HTMLPropertiesCollection::HTMLPropertiesCollection):
* html/HTMLTableRowsCollection.cpp:
(WebCore::HTMLTableRowsCollection::HTMLTableRowsCollection):

LayoutTests: 

Add an asymptotic time complexity test.

* perf/htmlcollection-backwards-iteration-expected.txt: Added.
* perf/htmlcollection-backwards-iteration.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (122659 => 122660)


--- trunk/LayoutTests/ChangeLog	2012-07-14 03:45:48 UTC (rev 122659)
+++ trunk/LayoutTests/ChangeLog	2012-07-14 07:08:55 UTC (rev 122660)
@@ -1,3 +1,15 @@
+2012-07-13  Ryosuke Niwa  <[email protected]>
+
+        Iterating backwards over HTMLCollection is O(n^2)
+        https://bugs.webkit.org/show_bug.cgi?id=91306
+
+        Reviewed by Anders Carlsson.
+
+        Add an asymptotic time complexity test.
+
+        * perf/htmlcollection-backwards-iteration-expected.txt: Added.
+        * perf/htmlcollection-backwards-iteration.html: Added.
+
 2012-07-13  Kent Tamura  <[email protected]>
 
         Internals: Clean up the mock PagePopupDriver correctly.

Added: trunk/LayoutTests/perf/htmlcollection-backwards-iteration-expected.txt (0 => 122660)


--- trunk/LayoutTests/perf/htmlcollection-backwards-iteration-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/perf/htmlcollection-backwards-iteration-expected.txt	2012-07-14 07:08:55 UTC (rev 122660)
@@ -0,0 +1,3 @@
+Tests that iterating over HTMLCollection backwards is linear.
+PASS
+

Added: trunk/LayoutTests/perf/htmlcollection-backwards-iteration.html (0 => 122660)


--- trunk/LayoutTests/perf/htmlcollection-backwards-iteration.html	                        (rev 0)
+++ trunk/LayoutTests/perf/htmlcollection-backwards-iteration.html	2012-07-14 07:08:55 UTC (rev 122660)
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<body>
+<div id="container" style="display: none;"></div>
+<script src=""
+<script>
+
+var container = document.getElementById('container');
+
+function setupFunction(magnitude)
+{
+    container.innerHTML = '';
+    for (var i = 0; i < magnitude; i++)
+        container.appendChild(document.createElement('div'));
+}
+
+function test(magnitude)
+{
+    var children = container.children;
+    for (var i = children.length; i > 0;i--)
+        children[i - 1].class = 'hi';
+}
+
+Magnitude.description("Tests that iterating over HTMLCollection backwards is linear.");
+Magnitude.run(setupFunction, test, Magnitude.LINEAR);
+
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (122659 => 122660)


--- trunk/Source/WebCore/ChangeLog	2012-07-14 03:45:48 UTC (rev 122659)
+++ trunk/Source/WebCore/ChangeLog	2012-07-14 07:08:55 UTC (rev 122660)
@@ -1,3 +1,65 @@
+2012-07-13  Ryosuke Niwa  <[email protected]>
+
+        Iterating backwards over HTMLCollection is O(n^2)
+        https://bugs.webkit.org/show_bug.cgi?id=91306
+
+        Reviewed by Anders Carlsson.
+
+        Fixed the bug by introducing itemBefore that iterates nodes backwards to complement itemAfter.
+        Unfortunately, some HTML collections such as HTMLFormCollection and HTMLTableRowsCollection have
+        its own itemAfter function and writing an equivalent itemBefore is somewhat tricky. For now,
+        added a new boolean flag indicating whether a given HTML collection supports itemBefore or not,
+        and left those HTML collections that override itemAfter alone.
+
+        This also paves our way to share more code between DynamicNodeList and HTMLCollection.
+
+        Test: perf/htmlcollection-backwards-iteration.html
+
+        * dom/DynamicNodeList.h:
+        (WebCore::DynamicNodeListCacheBase::DynamicNodeListCacheBase): Takes ItemBeforeSupportType.
+        (WebCore::DynamicNodeListCacheBase::supportsItemBefore): Added.
+        (DynamicNodeListCacheBase):
+        (WebCore::DynamicNodeListCacheBase::setItemCache): Replaced a FIXME by an assertion now that
+        we can.
+        * html/HTMLAllCollection.cpp:
+        (WebCore::HTMLAllCollection::HTMLAllCollection): Supports itemBefore since it doesn't override
+        itemAfter.
+        * html/HTMLCollection.cpp:
+        (WebCore::HTMLCollection::HTMLCollection):
+        (WebCore::HTMLCollection::create):
+        (WebCore::isAcceptableElement): Made it a static local function instead of a static member.
+        (WebCore::nextNode): Templatized.
+        (WebCore::itemBeforeOrAfter): Extracted from itemAfter and templatized.
+        (WebCore::HTMLCollection::itemBefore): Added.
+        (WebCore::HTMLCollection::itemAfter):
+        (WebCore::HTMLCollection::shouldSearchFromFirstItem): Added. Determines whether we should reset
+        the item cache to the first item. We obviously do if the cache is invalid. If the target offset
+        is after the cached offset, then we shouldn't go back regardless of availability of itemBefore.
+        Otherwise, we go back to the first item iff itemBefore is not available or the distance from
+        the cached offset to the target offset is greater than the target offset itself.
+        (WebCore::HTMLCollection::length):
+        (WebCore::HTMLCollection::item): Use the term "offset" to match the terminology elsewhere.
+        (WebCore::HTMLCollection::itemBeforeOrAfterCachedItem): Ditto. Also added the logic to iterate
+        nodes backwards using itemBefore. Once we're in this branch, we should always find a matching
+        item since the target offset was less than the cached offset, and offsets are non-negative.
+        If we had ever reached the end of the loop without finding an item, it indicates that the cache
+        has been invalid and we have some serious bug elsewhere.
+        * html/HTMLCollection.h:
+        (WebCore::HTMLCollectionCacheBase::HTMLCollectionCacheBase):
+        (HTMLCollection):
+        * html/HTMLOptionsCollection.cpp:
+        (WebCore::HTMLOptionsCollection::HTMLOptionsCollection): Supports itemBefore since it doesn't
+        override itemAfter.
+        * html/HTMLFormCollection.cpp:
+        (WebCore::HTMLFormCollection::HTMLFormCollection): Doesn't support itemBefore as it overrides
+        itemAfter.
+        * html/HTMLNameCollection.cpp:
+        (WebCore::HTMLNameCollection::HTMLNameCollection): Ditto.
+        * html/HTMLPropertiesCollection.cpp:
+        (WebCore::HTMLPropertiesCollection::HTMLPropertiesCollection):
+        * html/HTMLTableRowsCollection.cpp:
+        (WebCore::HTMLTableRowsCollection::HTMLTableRowsCollection):
+
 2012-07-13  Eric Penner  <[email protected]>
 
         [chromium] Add 'self-managed' option to CCPrioritizedTexture to enable render-surface and canvas use cases.

Modified: trunk/Source/WebCore/dom/DynamicNodeList.h (122659 => 122660)


--- trunk/Source/WebCore/dom/DynamicNodeList.h	2012-07-14 03:45:48 UTC (rev 122659)
+++ trunk/Source/WebCore/dom/DynamicNodeList.h	2012-07-14 07:08:55 UTC (rev 122660)
@@ -43,7 +43,13 @@
 
 class DynamicNodeListCacheBase {
 public:
-    DynamicNodeListCacheBase(NodeListRootType rootType, NodeListInvalidationType invalidationType, CollectionType collectionType = InvalidCollectionType)
+    enum ItemBeforeSupportType {
+        DoNotSupportItemBefore,
+        SupportItemBefore,
+    };
+
+    DynamicNodeListCacheBase(NodeListRootType rootType, NodeListInvalidationType invalidationType,
+        CollectionType collectionType = InvalidCollectionType, ItemBeforeSupportType itemBeforeSupportType = DoNotSupportItemBefore)
         : m_cachedItem(0)
         , m_isLengthCacheValid(false)
         , m_isItemCacheValid(false)
@@ -51,6 +57,7 @@
         , m_invalidationType(invalidationType)
         , m_isNameCacheValid(false)
         , m_collectionType(collectionType)
+        , m_supportsItemBefore(itemBeforeSupportType == SupportItemBefore)
     {
         ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType));
         ASSERT(m_collectionType == static_cast<unsigned>(collectionType));
@@ -66,6 +73,8 @@
     static bool shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType, const QualifiedName&);
 
 protected:
+    bool supportsItemBefore() const { return m_supportsItemBefore; }
+
     ALWAYS_INLINE bool isItemCacheValid() const { return m_isItemCacheValid; }
     ALWAYS_INLINE Node* cachedItem() const { return m_cachedItem; }
     ALWAYS_INLINE unsigned cachedItemOffset() const { return m_cachedItemOffset; }
@@ -79,7 +88,7 @@
     }
     ALWAYS_INLINE void setItemCache(Node* item, unsigned offset) const
     {
-        // FIXME: Assert that item is not null once we've updated DynamicNodeList.
+        ASSERT(item);
         m_cachedItem = item;
         m_cachedItemOffset = offset;
         m_isItemCacheValid = true;
@@ -100,6 +109,7 @@
     // From HTMLCollection
     mutable unsigned m_isNameCacheValid : 1;
     const unsigned m_collectionType : 5;
+    const unsigned m_supportsItemBefore : 1;
 };
 
 ALWAYS_INLINE bool DynamicNodeListCacheBase::shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType type, const QualifiedName& attrName)

Modified: trunk/Source/WebCore/html/HTMLAllCollection.cpp (122659 => 122660)


--- trunk/Source/WebCore/html/HTMLAllCollection.cpp	2012-07-14 03:45:48 UTC (rev 122659)
+++ trunk/Source/WebCore/html/HTMLAllCollection.cpp	2012-07-14 07:08:55 UTC (rev 122660)
@@ -36,7 +36,7 @@
 }
 
 HTMLAllCollection::HTMLAllCollection(Document* document)
-    : HTMLCollection(document, DocAll)
+    : HTMLCollection(document, DocAll, SupportItemBefore)
 {
 }
 

Modified: trunk/Source/WebCore/html/HTMLCollection.cpp (122659 => 122660)


--- trunk/Source/WebCore/html/HTMLCollection.cpp	2012-07-14 03:45:48 UTC (rev 122659)
+++ trunk/Source/WebCore/html/HTMLCollection.cpp	2012-07-14 07:08:55 UTC (rev 122660)
@@ -152,8 +152,8 @@
 }
     
 
-HTMLCollection::HTMLCollection(Node* base, CollectionType type)
-    : HTMLCollectionCacheBase(rootTypeFromCollectionType(type), invalidationTypeExcludingIdAndNameAttributes(type), type)
+HTMLCollection::HTMLCollection(Node* base, CollectionType type, ItemBeforeSupportType itemBeforeSupportType)
+    : HTMLCollectionCacheBase(rootTypeFromCollectionType(type), invalidationTypeExcludingIdAndNameAttributes(type), type, itemBeforeSupportType)
     , m_base(base)
 {
     ASSERT(m_base);
@@ -162,7 +162,7 @@
 
 PassRefPtr<HTMLCollection> HTMLCollection::create(Node* base, CollectionType type)
 {
-    return adoptRef(new HTMLCollection(base, type));
+    return adoptRef(new HTMLCollection(base, type, SupportItemBefore));
 }
 
 HTMLCollection::~HTMLCollection()
@@ -179,12 +179,12 @@
     m_base->document()->unregisterNodeListCache(this);
 }
 
-inline bool HTMLCollection::isAcceptableElement(Element* element) const
+static inline bool isAcceptableElement(CollectionType type, Element* element)
 {
-    if (!element->isHTMLElement() && !(type() == DocAll || type() == NodeChildren))
+    if (!element->isHTMLElement() && !(type == DocAll || type == NodeChildren))
         return false;
 
-    switch (type()) {
+    switch (type) {
     case DocImages:
         return element->hasLocalName(imgTag);
     case DocScripts:
@@ -237,26 +237,54 @@
     return false;
 }
 
-static ALWAYS_INLINE Node* nextNode(Node* base, Node* previous, bool onlyIncludeDirectChildren)
+template<bool forward>
+static Node* nextNode(Node* base, Node* previous, bool onlyIncludeDirectChildren)
 {
-    return onlyIncludeDirectChildren ? previous->traverseNextSibling(base) : previous->traverseNextNode(base);
+    if (forward)
+        return onlyIncludeDirectChildren ? previous->nextSibling() : previous->traverseNextNode(base);
+    else
+        return onlyIncludeDirectChildren ? previous->previousSibling() : previous->traversePreviousNode(base);
 }
 
-Element* HTMLCollection::itemAfter(unsigned& offsetInArray, Element* previous) const
+template<bool forward>
+static Element* itemBeforeOrAfter(CollectionType type, Node* base, unsigned& offsetInArray, Node* previous)
 {
     ASSERT_UNUSED(offsetInArray, !offsetInArray);
-    bool _onlyIncludeDirectChildren_ = shouldOnlyIncludeDirectChildren(type());
-    Node* rootNode = base();
-    Node* current = previous ? nextNode(rootNode, previous, onlyIncludeDirectChildren) : m_base->firstChild();
+    bool _onlyIncludeDirectChildren_ = shouldOnlyIncludeDirectChildren(type);
+    Node* rootNode = base;
+    Node* current = previous ? nextNode<forward>(rootNode, previous, onlyIncludeDirectChildren) : (forward ? base->firstChild() : base->lastChild());
 
-    for (; current; current = nextNode(rootNode, current, onlyIncludeDirectChildren)) {
-        if (current->isElementNode() && isAcceptableElement(toElement(current)))
+    for (; current; current = nextNode<forward>(rootNode, current, onlyIncludeDirectChildren)) {
+        if (current->isElementNode() && isAcceptableElement(type, toElement(current)))
             return toElement(current);
     }
 
     return 0;
 }
 
+Element* HTMLCollection::itemBefore(unsigned& offsetInArray, Element* previous) const
+{
+    return itemBeforeOrAfter<false>(type(), base(), offsetInArray, previous);
+}
+
+Element* HTMLCollection::itemAfter(unsigned& offsetInArray, Element* previous) const
+{
+    return itemBeforeOrAfter<true>(type(), base(), offsetInArray, previous);
+}
+    
+bool ALWAYS_INLINE HTMLCollection::shouldSearchFromFirstItem(unsigned offset) const
+{
+    if (!isItemCacheValid())
+        return true;
+
+    ASSERT(offset != cachedItemOffset());
+    if (offset > cachedItemOffset())
+        return false;
+
+    unsigned distanceFromCachedItem = cachedItemOffset() - offset;
+    return !supportsItemBefore() || offset < distanceFromCachedItem;
+}
+
 unsigned HTMLCollection::length() const
 {
     if (isLengthCacheValid())
@@ -272,18 +300,18 @@
     unsigned offset = cachedItemOffset();
     do {
         offset++;
-    } while (itemAfterCachedItem(offset));
+    } while (itemBeforeOrAfterCachedItem(offset));
 
     setLengthCache(offset);
     return offset;
 }
 
-Node* HTMLCollection::item(unsigned index) const
+Node* HTMLCollection::item(unsigned offset) const
 {
-    if (isItemCacheValid() && cachedItemOffset() == index)
+    if (isItemCacheValid() && cachedItemOffset() == offset)
         return cachedItem();
 
-    if (isLengthCacheValid() && cachedLength() <= index)
+    if (isLengthCacheValid() && cachedLength() <= offset)
         return 0;
 
 #if ENABLE(MICRODATA)
@@ -291,7 +319,7 @@
         static_cast<const HTMLPropertiesCollection*>(this)->updateRefElements();
 #endif
 
-    if (!isItemCacheValid() || cachedItemOffset() > index) {
+    if (shouldSearchFromFirstItem(offset)) {
         unsigned offsetInArray = 0;
         Node* firstItem = itemAfter(offsetInArray, 0);
         if (!firstItem) {
@@ -300,30 +328,45 @@
         }
         setItemCache(firstItem, 0, offsetInArray);
         ASSERT(!cachedItemOffset());
-        if (!index)
+        if (!offset)
             return cachedItem();
     }
 
-    return itemAfterCachedItem(index);
+    return itemBeforeOrAfterCachedItem(offset);
 }
 
-Element* HTMLCollection::itemAfterCachedItem(unsigned index) const
+Element* HTMLCollection::itemBeforeOrAfterCachedItem(unsigned offset) const
 {
-    unsigned currentIndex = cachedItemOffset();
+    unsigned currentOffset = cachedItemOffset();
     ASSERT(cachedItem()->isElementNode());
     Element* currentItem = toElement(cachedItem());
-    ASSERT(currentIndex < index);
+    ASSERT(currentOffset != offset);
 
     unsigned offsetInArray = cachedElementsArrayOffset();
+
+    if (offset < cachedItemOffset()) {
+        ASSERT(supportsItemBefore());
+        while ((currentItem = itemBefore(offsetInArray, currentItem))) {
+            ASSERT(currentOffset);
+            currentOffset--;
+            if (currentOffset == offset) {
+                setItemCache(currentItem, currentOffset, offsetInArray);
+                return currentItem;
+            }
+        }
+        ASSERT_NOT_REACHED();
+        return 0;
+    }
+
     while ((currentItem = itemAfter(offsetInArray, currentItem))) {
-        currentIndex++;
-        if (currentIndex == index) {
-            setItemCache(currentItem, currentIndex, offsetInArray);
+        currentOffset++;
+        if (currentOffset == offset) {
+            setItemCache(currentItem, currentOffset, offsetInArray);
             return currentItem;
         }
     }
 
-    setLengthCache(currentIndex);
+    setLengthCache(currentOffset);
 
     return 0;
 }

Modified: trunk/Source/WebCore/html/HTMLCollection.h (122659 => 122660)


--- trunk/Source/WebCore/html/HTMLCollection.h	2012-07-14 03:45:48 UTC (rev 122659)
+++ trunk/Source/WebCore/html/HTMLCollection.h	2012-07-14 07:08:55 UTC (rev 122660)
@@ -39,8 +39,8 @@
 
 class HTMLCollectionCacheBase : public DynamicNodeListCacheBase {
 public:
-    HTMLCollectionCacheBase(NodeListRootType rootType, NodeListInvalidationType invalidationType, CollectionType collectionType)
-        : DynamicNodeListCacheBase(rootType, invalidationType, collectionType)
+    HTMLCollectionCacheBase(NodeListRootType rootType, NodeListInvalidationType invalidationType, CollectionType collectionType, ItemBeforeSupportType itemBeforeSupportType)
+        : DynamicNodeListCacheBase(rootType, invalidationType, collectionType, itemBeforeSupportType)
         , m_cachedElementsArrayOffset(0)
     {
     }
@@ -106,7 +106,7 @@
     Node* base() const { return m_base.get(); }
 
 protected:
-    HTMLCollection(Node* base, CollectionType);
+    HTMLCollection(Node* base, CollectionType, ItemBeforeSupportType);
 
     virtual void updateNameCache() const;
     virtual Element* itemAfter(unsigned& offsetInArray, Element*) const;
@@ -114,8 +114,9 @@
 private:
     bool checkForNameMatch(Element*, bool checkName, const AtomicString& name) const;
 
-    Element* itemAfterCachedItem(unsigned) const;
-    bool isAcceptableElement(Element*) const;
+    Element* itemBefore(unsigned& offsetInArray, Element*) const;
+    bool shouldSearchFromFirstItem(unsigned offset) const;
+    Element* itemBeforeOrAfterCachedItem(unsigned offset) const;
 
     RefPtr<Node> m_base;
 };

Modified: trunk/Source/WebCore/html/HTMLFormCollection.cpp (122659 => 122660)


--- trunk/Source/WebCore/html/HTMLFormCollection.cpp	2012-07-14 03:45:48 UTC (rev 122659)
+++ trunk/Source/WebCore/html/HTMLFormCollection.cpp	2012-07-14 07:08:55 UTC (rev 122660)
@@ -37,7 +37,7 @@
 // calculation every time if anything has changed.
 
 HTMLFormCollection::HTMLFormCollection(Element* base)
-    : HTMLCollection(base, FormControls)
+    : HTMLCollection(base, FormControls, DoNotSupportItemBefore)
 {
     ASSERT(base->hasTagName(formTag) || base->hasTagName(fieldsetTag));
 }

Modified: trunk/Source/WebCore/html/HTMLNameCollection.cpp (122659 => 122660)


--- trunk/Source/WebCore/html/HTMLNameCollection.cpp	2012-07-14 03:45:48 UTC (rev 122659)
+++ trunk/Source/WebCore/html/HTMLNameCollection.cpp	2012-07-14 07:08:55 UTC (rev 122660)
@@ -33,7 +33,7 @@
 using namespace HTMLNames;
 
 HTMLNameCollection::HTMLNameCollection(Document* document, CollectionType type, const AtomicString& name)
-    : HTMLCollection(document, type)
+    : HTMLCollection(document, type, DoNotSupportItemBefore)
     , m_name(name)
 {
 }

Modified: trunk/Source/WebCore/html/HTMLOptionsCollection.cpp (122659 => 122660)


--- trunk/Source/WebCore/html/HTMLOptionsCollection.cpp	2012-07-14 03:45:48 UTC (rev 122659)
+++ trunk/Source/WebCore/html/HTMLOptionsCollection.cpp	2012-07-14 07:08:55 UTC (rev 122660)
@@ -28,7 +28,7 @@
 namespace WebCore {
 
 HTMLOptionsCollection::HTMLOptionsCollection(Element* select)
-    : HTMLCollection(select, SelectOptions)
+    : HTMLCollection(select, SelectOptions, SupportItemBefore)
 {
     ASSERT(select->hasTagName(HTMLNames::selectTag));
 }

Modified: trunk/Source/WebCore/html/HTMLPropertiesCollection.cpp (122659 => 122660)


--- trunk/Source/WebCore/html/HTMLPropertiesCollection.cpp	2012-07-14 03:45:48 UTC (rev 122659)
+++ trunk/Source/WebCore/html/HTMLPropertiesCollection.cpp	2012-07-14 07:08:55 UTC (rev 122660)
@@ -51,7 +51,7 @@
 }
 
 HTMLPropertiesCollection::HTMLPropertiesCollection(Node* itemNode)
-    : HTMLCollection(itemNode, ItemProperties)
+    : HTMLCollection(itemNode, ItemProperties, DoNotSupportItemBefore)
     , m_hasPropertyNameCache(false)
     , m_hasItemRefElements(false)
 {

Modified: trunk/Source/WebCore/html/HTMLTableRowsCollection.cpp (122659 => 122660)


--- trunk/Source/WebCore/html/HTMLTableRowsCollection.cpp	2012-07-14 03:45:48 UTC (rev 122659)
+++ trunk/Source/WebCore/html/HTMLTableRowsCollection.cpp	2012-07-14 07:08:55 UTC (rev 122660)
@@ -152,7 +152,7 @@
 // table to get at the collection cache. Order of argument evaluation is undefined and can
 // differ between compilers.
 HTMLTableRowsCollection::HTMLTableRowsCollection(Element* table)
-    : HTMLCollection(table, TableRows)
+    : HTMLCollection(table, TableRows, DoNotSupportItemBefore)
 {
     ASSERT(table->hasTagName(tableTag));
 }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to