summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/HTMLTableRowsCollection.cpp
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-05-30 12:48:17 +0200
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-05-30 12:48:17 +0200
commit881da28418d380042aa95a97f0cbd42560a64f7c (patch)
treea794dff3274695e99c651902dde93d934ea7a5af /Source/WebCore/html/HTMLTableRowsCollection.cpp
parent7e104c57a70fdf551bb3d22a5d637cdcbc69dbea (diff)
parent0fcedcd17cc00d3dd44c718b3cb36c1033319671 (diff)
downloadqtwebkit-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.cpp159
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));
}
}