diff -r 000000000000 -r 4f2f89ce4247 WebCore/html/HTMLCollection.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebCore/html/HTMLCollection.cpp Fri Sep 17 09:02:29 2010 +0300
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "HTMLCollection.h"
+
+#include "HTMLDocument.h"
+#include "HTMLElement.h"
+#include "HTMLNames.h"
+#include "HTMLObjectElement.h"
+#include "HTMLOptionElement.h"
+#include "NodeList.h"
+
+#include
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLCollection::HTMLCollection(PassRefPtr base, CollectionType type)
+ : m_idsDone(false)
+ , m_base(base)
+ , m_type(type)
+ , m_info(m_base->isDocumentNode() ? static_cast(m_base.get())->collectionInfo(type) : 0)
+ , m_ownsInfo(false)
+{
+}
+
+HTMLCollection::HTMLCollection(PassRefPtr base, CollectionType type, CollectionCache* info)
+ : m_idsDone(false)
+ , m_base(base)
+ , m_type(type)
+ , m_info(info)
+ , m_ownsInfo(false)
+{
+}
+
+PassRefPtr HTMLCollection::create(PassRefPtr base, CollectionType type)
+{
+ return adoptRef(new HTMLCollection(base, type));
+}
+
+HTMLCollection::~HTMLCollection()
+{
+ if (m_ownsInfo)
+ delete m_info;
+}
+
+void HTMLCollection::resetCollectionInfo() const
+{
+ unsigned docversion = static_cast(m_base->document())->domTreeVersion();
+
+ if (!m_info) {
+ m_info = new CollectionCache;
+ m_ownsInfo = true;
+ m_info->version = docversion;
+ return;
+ }
+
+ if (m_info->version != docversion) {
+ m_info->reset();
+ m_info->version = docversion;
+ }
+}
+
+static Node* nextNodeOrSibling(Node* base, Node* node, bool includeChildren)
+{
+ return includeChildren ? node->traverseNextNode(base) : node->traverseNextSibling(base);
+}
+
+Element* HTMLCollection::itemAfter(Element* previous) const
+{
+ bool deep = true;
+
+ switch (m_type) {
+ case DocAll:
+ case DocAnchors:
+ case DocApplets:
+ case DocEmbeds:
+ case DocForms:
+ case DocImages:
+ case DocLinks:
+ case DocObjects:
+ case DocScripts:
+ case DocumentNamedItems:
+ case MapAreas:
+ case OtherCollection:
+ case SelectOptions:
+ case DataListOptions:
+ case WindowNamedItems:
+ break;
+ case NodeChildren:
+ case TRCells:
+ case TSectionRows:
+ case TableTBodies:
+ deep = false;
+ break;
+ }
+
+ Node* current;
+ if (!previous)
+ current = m_base->firstChild();
+ else
+ current = nextNodeOrSibling(m_base.get(), previous, deep);
+
+ for (; current; current = nextNodeOrSibling(m_base.get(), current, deep)) {
+ if (!current->isElementNode())
+ continue;
+ Element* e = static_cast(current);
+ switch (m_type) {
+ case DocImages:
+ if (e->hasLocalName(imgTag))
+ return e;
+ break;
+ case DocScripts:
+ if (e->hasLocalName(scriptTag))
+ return e;
+ break;
+ case DocForms:
+ if (e->hasLocalName(formTag))
+ return e;
+ break;
+ case TableTBodies:
+ if (e->hasLocalName(tbodyTag))
+ return e;
+ break;
+ case TRCells:
+ if (e->hasLocalName(tdTag) || e->hasLocalName(thTag))
+ return e;
+ break;
+ case TSectionRows:
+ if (e->hasLocalName(trTag))
+ return e;
+ break;
+ case SelectOptions:
+ if (e->hasLocalName(optionTag))
+ return e;
+ break;
+ case DataListOptions:
+ if (e->hasLocalName(optionTag)) {
+ HTMLOptionElement* option = static_cast(e);
+ if (!option->disabled() && !option->value().isEmpty())
+ return e;
+ }
+ break;
+ case MapAreas:
+ if (e->hasLocalName(areaTag))
+ return e;
+ break;
+ case DocApplets: // all