2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
5 * Copyright (C) 2014 Samsung Electronics. All rights reserved.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
24 #ifndef HTMLCollection_h
25 #define HTMLCollection_h
27 #include "core/dom/LiveNodeListBase.h"
28 #include "core/html/CollectionIndexCache.h"
29 #include "core/html/CollectionType.h"
30 #include "wtf/Forward.h"
31 #include "wtf/HashMap.h"
32 #include "wtf/Vector.h"
36 class HTMLCollection : public ScriptWrappable, public RefCounted<HTMLCollection>, public LiveNodeListBase {
38 enum ItemAfterOverrideType {
40 DoesNotOverrideItemAfter,
43 static PassRefPtr<HTMLCollection> create(ContainerNode& base, CollectionType);
44 virtual ~HTMLCollection();
45 virtual void invalidateCache(Document* oldDocument = 0) const OVERRIDE;
48 unsigned length() const { return m_collectionIndexCache.nodeCount(*this); }
49 Element* item(unsigned offset) const { return m_collectionIndexCache.nodeAt(*this, offset); }
50 virtual Element* namedItem(const AtomicString& name) const;
51 bool namedPropertyQuery(const AtomicString&, ExceptionState&);
52 void namedPropertyEnumerator(Vector<String>& names, ExceptionState&);
55 void namedItems(const AtomicString& name, Vector<RefPtr<Element> >&) const;
56 bool isEmpty() const { return m_collectionIndexCache.isEmpty(*this); }
57 bool hasExactlyOneItem() const { return m_collectionIndexCache.hasExactlyOneNode(*this); }
59 // CollectionIndexCache API.
60 bool canTraverseBackward() const { return !overridesItemAfter(); }
61 Element* itemBefore(const Element* previousItem) const;
62 Element* traverseToFirstElement(const ContainerNode& root) const;
63 Element* traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset, const ContainerNode& root) const;
66 HTMLCollection(ContainerNode& base, CollectionType, ItemAfterOverrideType);
68 bool overridesItemAfter() const { return m_overridesItemAfter; }
69 virtual Element* virtualItemAfter(Element*) const;
70 bool shouldOnlyIncludeDirectChildren() const { return m_shouldOnlyIncludeDirectChildren; }
71 virtual void supportedPropertyNames(Vector<String>& names);
73 virtual void updateIdNameCache() const;
74 bool hasValidIdNameCache() const { return m_hasValidIdNameCache; }
75 void setHasValidIdNameCache() const
77 ASSERT(!m_hasValidIdNameCache);
78 m_hasValidIdNameCache = true;
79 document().incrementNodeListWithIdNameCacheCount();
82 typedef HashMap<StringImpl*, OwnPtr<Vector<Element*> > > NodeCacheMap;
83 Vector<Element*>* idCache(const AtomicString& name) const { return m_idCache.get(name.impl()); }
84 Vector<Element*>* nameCache(const AtomicString& name) const { return m_nameCache.get(name.impl()); }
85 void appendIdCache(const AtomicString& name, Element* element) const { append(m_idCache, name, element); }
86 void appendNameCache(const AtomicString& name, Element* element) const { append(m_nameCache, name, element); }
89 Element* traverseNextElement(Element& previous, const ContainerNode& root) const;
91 static void append(NodeCacheMap&, const AtomicString&, Element*);
92 void invalidateIdNameCacheMaps(Document* oldDocument = 0) const
94 if (!m_hasValidIdNameCache)
97 // Make sure we decrement the NodeListWithIdNameCache count from
98 // the old document instead of the new one in the case the collection
99 // is moved to a new document.
100 unregisterIdNameCacheFromDocument(oldDocument ? *oldDocument : document());
104 m_hasValidIdNameCache = false;
107 void unregisterIdNameCacheFromDocument(Document& document) const
109 ASSERT(m_hasValidIdNameCache);
110 document.decrementNodeListWithIdNameCacheCount();
113 const unsigned m_overridesItemAfter : 1;
114 const unsigned m_shouldOnlyIncludeDirectChildren : 1;
115 mutable unsigned m_hasValidIdNameCache : 1;
116 mutable NodeCacheMap m_idCache;
117 mutable NodeCacheMap m_nameCache;
118 mutable CollectionIndexCache<HTMLCollection, Element> m_collectionIndexCache;
120 friend class LiveNodeListBase;