diff options
author | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-05-30 12:48:17 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-05-30 12:48:17 +0200 |
commit | 881da28418d380042aa95a97f0cbd42560a64f7c (patch) | |
tree | a794dff3274695e99c651902dde93d934ea7a5af /Source/WebCore/html/HTMLTableRowsCollection.cpp | |
parent | 7e104c57a70fdf551bb3d22a5d637cdcbc69dbea (diff) | |
parent | 0fcedcd17cc00d3dd44c718b3cb36c1033319671 (diff) | |
download | qtwebkit-881da28418d380042aa95a97f0cbd42560a64f7c.tar.gz |
Merge 'wip/next' into dev
Change-Id: Iff9ee5e23bb326c4371ec8ed81d56f2f05d680e9
Diffstat (limited to 'Source/WebCore/html/HTMLTableRowsCollection.cpp')
-rw-r--r-- | Source/WebCore/html/HTMLTableRowsCollection.cpp | 159 |
1 files changed, 77 insertions, 82 deletions
diff --git a/Source/WebCore/html/HTMLTableRowsCollection.cpp b/Source/WebCore/html/HTMLTableRowsCollection.cpp index 5e6d7c732..2d91d9d48 100644 --- a/Source/WebCore/html/HTMLTableRowsCollection.cpp +++ b/Source/WebCore/html/HTMLTableRowsCollection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2011, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2011, 2012, 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 @@ -10,7 +10,7 @@ * 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -29,6 +29,7 @@ #include "config.h" #include "HTMLTableRowsCollection.h" +#include "ElementIterator.h" #include "HTMLNames.h" #include "HTMLTableElement.h" #include "HTMLTableRowElement.h" @@ -37,136 +38,130 @@ namespace WebCore { using namespace HTMLNames; -static bool isInHead(Element* row) +static inline void assertRowIsInTable(HTMLTableElement& table, HTMLTableRowElement* row) { - return row->parentNode() && toElement(row->parentNode())->hasLocalName(theadTag); +#if !ASSERT_DISABLED + UNUSED_PARAM(table); + UNUSED_PARAM(row); +#else + if (!row) + return; + if (row->parentNode() == &table) + return; + ASSERT(row->parentNode()); + ASSERT(row->parentNode()->hasTagName(theadTag) || row->parentNode()->hasTagName(tbodyTag) || row->parentNode()->hasTagName(tfootTag)); + ASSERT(row->parentNode()->parentNode() == &table); +#endif } -static bool isInBody(Element* row) +static inline bool isInSection(HTMLTableRowElement& row, const HTMLQualifiedName& sectionTag) { - return row->parentNode() && toElement(row->parentNode())->hasLocalName(tbodyTag); + // Because we know that the parent is a table or a section, it's safe to cast it to an HTMLElement + // giving us access to the faster hasTagName overload from that class. + return downcast<HTMLElement>(*row.parentNode()).hasTagName(sectionTag); } -static bool isInFoot(Element* row) +HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement& table, HTMLTableRowElement* previous) { - return row->parentNode() && toElement(row->parentNode())->hasLocalName(tfootTag); -} - -HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement* table, HTMLTableRowElement* previous) -{ - Node* child = 0; - - // Start by looking for the next row in this section. - // Continue only if there is none. - if (previous && previous->parentNode() != table) { - for (child = previous->nextSibling(); child; child = child->nextSibling()) { - if (child->hasTagName(trTag)) - return static_cast<HTMLTableRowElement*>(child); - } + // The HTMLCollection caching mechanism, along with the code in this class, will guarantee that the previous row + // is an immediate child of either the table, or a table section that is itself an immediate child of the table. + assertRowIsInTable(table, previous); + + // Start by looking for the next row in this section. Continue only if there is none. + if (previous && previous->parentNode() != &table) { + auto childRows = childrenOfType<HTMLTableRowElement>(*previous->parentNode()); + auto row = childRows.beginAt(*previous); + if (++row != childRows.end()) + return &*row; } + Element* child = nullptr; + // If still looking at head sections, find the first row in the next head section. if (!previous) - child = table->firstChild(); - else if (isInHead(previous)) - child = previous->parentNode()->nextSibling(); - for (; child; child = child->nextSibling()) { + child = ElementTraversal::firstChild(table); + else if (isInSection(*previous, theadTag)) + child = ElementTraversal::nextSibling(*previous->parentNode()); + for (; child; child = ElementTraversal::nextSibling(*child)) { if (child->hasTagName(theadTag)) { - for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) { - if (grandchild->hasTagName(trTag)) - return static_cast<HTMLTableRowElement*>(grandchild); - } + if (auto row = childrenOfType<HTMLTableRowElement>(*child).first()) + return row; } } // If still looking at top level and bodies, find the next row in top level or the first in the next body section. - if (!previous || isInHead(previous)) - child = table->firstChild(); - else if (previous->parentNode() == table) - child = previous->nextSibling(); - else if (isInBody(previous)) - child = previous->parentNode()->nextSibling(); - for (; child; child = child->nextSibling()) { - if (child->hasTagName(trTag)) - return static_cast<HTMLTableRowElement*>(child); + if (!previous || isInSection(*previous, theadTag)) + child = ElementTraversal::firstChild(table); + else if (previous->parentNode() == &table) + child = ElementTraversal::nextSibling(*previous); + else if (isInSection(*previous, tbodyTag)) + child = ElementTraversal::nextSibling(*previous->parentNode()); + for (; child; child = ElementTraversal::nextSibling(*child)) { + if (is<HTMLTableRowElement>(*child)) + return downcast<HTMLTableRowElement>(child); if (child->hasTagName(tbodyTag)) { - for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) { - if (grandchild->hasTagName(trTag)) - return static_cast<HTMLTableRowElement*>(grandchild); - } + if (auto row = childrenOfType<HTMLTableRowElement>(*child).first()) + return row; } } // Find the first row in the next foot section. - if (!previous || !isInFoot(previous)) - child = table->firstChild(); + if (!previous || !isInSection(*previous, tfootTag)) + child = ElementTraversal::firstChild(table); else - child = previous->parentNode()->nextSibling(); - for (; child; child = child->nextSibling()) { + child = ElementTraversal::nextSibling(*previous->parentNode()); + for (; child; child = ElementTraversal::nextSibling(*child)) { if (child->hasTagName(tfootTag)) { - for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) { - if (grandchild->hasTagName(trTag)) - return static_cast<HTMLTableRowElement*>(grandchild); - } + if (auto row = childrenOfType<HTMLTableRowElement>(*child).first()) + return row; } } - return 0; + return nullptr; } -HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table) +HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement& table) { - for (Node* child = table->lastChild(); child; child = child->previousSibling()) { + for (auto* child = ElementTraversal::lastChild(table); child; child = ElementTraversal::previousSibling(*child)) { if (child->hasTagName(tfootTag)) { - for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) { - if (grandchild->hasTagName(trTag)) - return static_cast<HTMLTableRowElement*>(grandchild); - } + if (auto* row = childrenOfType<HTMLTableRowElement>(*child).last()) + return row; } } - for (Node* child = table->lastChild(); child; child = child->previousSibling()) { - if (child->hasTagName(trTag)) - return static_cast<HTMLTableRowElement*>(child); + for (auto* child = ElementTraversal::lastChild(table); child; child = ElementTraversal::previousSibling(*child)) { + if (is<HTMLTableRowElement>(*child)) + return downcast<HTMLTableRowElement>(child); if (child->hasTagName(tbodyTag)) { - for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) { - if (grandchild->hasTagName(trTag)) - return static_cast<HTMLTableRowElement*>(grandchild); - } + if (auto* row = childrenOfType<HTMLTableRowElement>(*child).last()) + return row; } } - for (Node* child = table->lastChild(); child; child = child->previousSibling()) { + for (auto* child = ElementTraversal::lastChild(table); child; child = ElementTraversal::previousSibling(*child)) { if (child->hasTagName(theadTag)) { - for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) { - if (grandchild->hasTagName(trTag)) - return static_cast<HTMLTableRowElement*>(grandchild); - } + if (auto* row = childrenOfType<HTMLTableRowElement>(*child).last()) + return row; } } - return 0; + return nullptr; } -// Must call get() on the table in case that argument is compiled before dereferencing the -// table to get at the collection cache. Order of argument evaluation is undefined and can -// differ between compilers. -HTMLTableRowsCollection::HTMLTableRowsCollection(Node* table) - : HTMLCollection(table, TableRows, OverridesItemAfter) +HTMLTableRowsCollection::HTMLTableRowsCollection(HTMLTableElement& table) + : CachedHTMLCollection<HTMLTableRowsCollection, CollectionTypeTraits<TableRows>::traversalType>(table, TableRows) { - ASSERT(isHTMLTableElement(table)); } -PassRefPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(Node* table, CollectionType) +Ref<HTMLTableRowsCollection> HTMLTableRowsCollection::create(HTMLTableElement& table, CollectionType type) { - return adoptRef(new HTMLTableRowsCollection(table)); + ASSERT_UNUSED(type, type == TableRows); + return adoptRef(*new HTMLTableRowsCollection(table)); } -Element* HTMLTableRowsCollection::virtualItemAfter(unsigned& offsetInArray, Element* previous) const +Element* HTMLTableRowsCollection::customElementAfter(Element* previous) const { - ASSERT_UNUSED(offsetInArray, !offsetInArray); - ASSERT(!previous || (previous->isHTMLElement() && toHTMLElement(previous)->hasLocalName(trTag))); - return rowAfter(toHTMLTableElement(ownerNode()), static_cast<HTMLTableRowElement*>(previous)); + return rowAfter(const_cast<HTMLTableElement&>(tableElement()), downcast<HTMLTableRowElement>(previous)); } } |