Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / html / HTMLCollection.h
1 /*
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.
6  *
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.
11  *
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.
16  *
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.
21  *
22  */
23
24 #ifndef HTMLCollection_h
25 #define HTMLCollection_h
26
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"
33
34 namespace WebCore {
35
36 class HTMLCollection : public ScriptWrappable, public RefCounted<HTMLCollection>, public LiveNodeListBase {
37 public:
38     enum ItemAfterOverrideType {
39         OverridesItemAfter,
40         DoesNotOverrideItemAfter,
41     };
42
43     static PassRefPtr<HTMLCollection> create(ContainerNode& base, CollectionType);
44     virtual ~HTMLCollection();
45     virtual void invalidateCache(Document* oldDocument = 0) const OVERRIDE;
46
47     // DOM API
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&);
53
54     // Non-DOM API
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); }
58
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;
64
65 protected:
66     HTMLCollection(ContainerNode& base, CollectionType, ItemAfterOverrideType);
67
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);
72
73     virtual void updateIdNameCache() const;
74     bool hasValidIdNameCache() const { return m_hasValidIdNameCache; }
75     void setHasValidIdNameCache() const
76     {
77         ASSERT(!m_hasValidIdNameCache);
78         m_hasValidIdNameCache = true;
79         document().incrementNodeListWithIdNameCacheCount();
80     }
81
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); }
87
88 private:
89     Element* traverseNextElement(Element& previous, const ContainerNode& root) const;
90
91     static void append(NodeCacheMap&, const AtomicString&, Element*);
92     void invalidateIdNameCacheMaps(Document* oldDocument = 0) const
93     {
94         if (!m_hasValidIdNameCache)
95             return;
96
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());
101
102         m_idCache.clear();
103         m_nameCache.clear();
104         m_hasValidIdNameCache = false;
105     }
106
107     void unregisterIdNameCacheFromDocument(Document& document) const
108     {
109         ASSERT(m_hasValidIdNameCache);
110         document.decrementNodeListWithIdNameCacheCount();
111     }
112
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;
119
120     friend class LiveNodeListBase;
121 };
122
123 } // namespace
124
125 #endif