Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(336)

Side by Side Diff: Source/core/dom/AttributeCollection.h

Issue 354363002: Move attributes-related API from UniqueElementData to AttributeCollection (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/dom/Attr.cpp ('k') | Source/core/dom/AttributeCollection.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * Copyright (C) 2014 Apple Inc. All rights reserved. 3 * Copyright (C) 2014 Apple Inc. All rights reserved.
4 * Copyright (C) 2014 Samsung Electronics. All rights reserved. 4 * Copyright (C) 2014 Samsung Electronics. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are 7 * modification, are permitted provided that the following conditions are
8 * met: 8 * met:
9 * 9 *
10 * * Redistributions of source code must retain the above copyright 10 * * Redistributions of source code must retain the above copyright
(...skipping 15 matching lines...) Expand all
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33 #ifndef AttributeCollection_h 33 #ifndef AttributeCollection_h
34 #define AttributeCollection_h 34 #define AttributeCollection_h
35 35
36 #include "core/dom/Attr.h"
36 #include "core/dom/Attribute.h" 37 #include "core/dom/Attribute.h"
38 #include "wtf/Vector.h"
37 39
38 namespace blink { 40 namespace blink {
39 41
40 class Attr; 42 template <typename Container, typename ContainerMemberType = Container>
43 class AttributeCollectionGeneric {
44 public:
45 typedef typename Container::ValueType ValueType;
46 typedef ValueType* iterator;
41 47
42 class AttributeCollection { 48 AttributeCollectionGeneric(Container& attributes)
49 : m_attributes(attributes)
50 { }
51
52 ValueType& operator[](unsigned index) const { return at(index); }
53 ValueType& at(unsigned index) const
54 {
55 RELEASE_ASSERT(index < size());
56 return begin()[index];
57 }
58
59 iterator begin() const { return m_attributes.data(); }
60 iterator end() const { return begin() + size(); }
61
62 unsigned size() const { return m_attributes.size(); }
63 bool isEmpty() const { return !size(); }
64
65 iterator find(const QualifiedName&) const;
66 iterator find(const AtomicString& name, bool shouldIgnoreCase) const;
67 size_t findIndex(const QualifiedName&, bool shouldIgnoreCase = false) const;
68 size_t findIndex(const AtomicString& name, bool shouldIgnoreCase) const;
69 size_t findIndex(Attr*) const;
70
71 protected:
72 size_t findSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase ) const;
73
74 ContainerMemberType m_attributes;
75 };
76
77 class AttributeArray {
43 public: 78 public:
44 typedef const Attribute* const_iterator; 79 typedef const Attribute ValueType;
45 80
46 AttributeCollection(const Attribute* array, unsigned size) 81 AttributeArray(const Attribute* array, unsigned size)
47 : m_array(array) 82 : m_array(array)
48 , m_size(size) 83 , m_size(size)
49 { } 84 { }
50 85
51 const Attribute& operator[](unsigned index) const { return at(index); } 86 const Attribute* data() const { return m_array; }
52 const Attribute& at(unsigned index) const
53 {
54 RELEASE_ASSERT(index < m_size);
55 return m_array[index];
56 }
57
58 const Attribute* find(const QualifiedName&) const;
59 const Attribute* find(const AtomicString& name, bool shouldIgnoreCase) const ;
60 size_t findIndex(const QualifiedName&, bool shouldIgnoreCase = false) const;
61 size_t findIndex(const AtomicString& name, bool shouldIgnoreCase) const;
62 size_t findIndex(Attr*) const;
63
64 const_iterator begin() const { return m_array; }
65 const_iterator end() const { return m_array + m_size; }
66
67 unsigned size() const { return m_size; } 87 unsigned size() const { return m_size; }
68 bool isEmpty() const { return !m_size; }
69 88
70 private: 89 private:
71 size_t findSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase ) const;
72
73 const Attribute* m_array; 90 const Attribute* m_array;
74 unsigned m_size; 91 unsigned m_size;
75 }; 92 };
76 93
77 inline const Attribute* AttributeCollection::find(const AtomicString& name, bool shouldIgnoreCase) const 94 class AttributeCollection : public AttributeCollectionGeneric<const AttributeArr ay> {
95 public:
96 typedef iterator const_iterator;
97
98 AttributeCollection(const Attribute* array, unsigned size)
99 : AttributeCollectionGeneric<const AttributeArray>(AttributeArray(array, size))
100 { }
101 };
102
103 typedef Vector<Attribute, 4> AttributeVector;
104 class MutableAttributeCollection : public AttributeCollectionGeneric<AttributeVe ctor, AttributeVector&> {
105 public:
106 explicit MutableAttributeCollection(AttributeVector& attributes)
107 : AttributeCollectionGeneric<AttributeVector, AttributeVector&>(attribut es)
108 { }
109
110 // These functions do no error/duplicate checking.
111 void append(const QualifiedName&, const AtomicString& value);
112 void remove(unsigned index);
113 };
114
115 inline void MutableAttributeCollection::append(const QualifiedName& name, const AtomicString& value)
116 {
117 m_attributes.append(Attribute(name, value));
118 }
119
120 inline void MutableAttributeCollection::remove(unsigned index)
121 {
122 m_attributes.remove(index);
123 }
124
125 template <typename Container, typename ContainerMemberType>
126 inline typename AttributeCollectionGeneric<Container, ContainerMemberType>::iter ator AttributeCollectionGeneric<Container, ContainerMemberType>::find(const Atom icString& name, bool shouldIgnoreCase) const
78 { 127 {
79 size_t index = findIndex(name, shouldIgnoreCase); 128 size_t index = findIndex(name, shouldIgnoreCase);
80 return index != kNotFound ? &at(index) : 0; 129 return index != kNotFound ? &at(index) : 0;
81 } 130 }
82 131
83 inline size_t AttributeCollection::findIndex(const QualifiedName& name, bool sho uldIgnoreCase) const 132 template <typename Container, typename ContainerMemberType>
133 inline size_t AttributeCollectionGeneric<Container, ContainerMemberType>::findIn dex(const QualifiedName& name, bool shouldIgnoreCase) const
84 { 134 {
85 const_iterator end = this->end(); 135 iterator end = this->end();
86 unsigned index = 0; 136 unsigned index = 0;
87 for (const_iterator it = begin(); it != end; ++it, ++index) { 137 for (iterator it = begin(); it != end; ++it, ++index) {
88 if (it->name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase)) 138 if (it->name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase))
89 return index; 139 return index;
90 } 140 }
91 return kNotFound; 141 return kNotFound;
92 } 142 }
93 143
94 // We use a boolean parameter instead of calling shouldIgnoreAttributeCase so th at the caller 144 // We use a boolean parameter instead of calling shouldIgnoreAttributeCase so th at the caller
95 // can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not). 145 // can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not).
96 inline size_t AttributeCollection::findIndex(const AtomicString& name, bool shou ldIgnoreCase) const 146 template <typename Container, typename ContainerMemberType>
147 inline size_t AttributeCollectionGeneric<Container, ContainerMemberType>::findIn dex(const AtomicString& name, bool shouldIgnoreCase) const
97 { 148 {
98 bool doSlowCheck = shouldIgnoreCase; 149 bool doSlowCheck = shouldIgnoreCase;
99 150
100 // Optimize for the case where the attribute exists and its name exactly mat ches. 151 // Optimize for the case where the attribute exists and its name exactly mat ches.
101 const_iterator end = this->end(); 152 iterator end = this->end();
102 unsigned index = 0; 153 unsigned index = 0;
103 for (const_iterator it = begin(); it != end; ++it, ++index) { 154 for (iterator it = begin(); it != end; ++it, ++index) {
104 // FIXME: Why check the prefix? Namespaces should be all that matter. 155 // FIXME: Why check the prefix? Namespaces should be all that matter.
105 // Most attributes (all of HTML and CSS) have no namespace. 156 // Most attributes (all of HTML and CSS) have no namespace.
106 if (!it->name().hasPrefix()) { 157 if (!it->name().hasPrefix()) {
107 if (name == it->localName()) 158 if (name == it->localName())
108 return index; 159 return index;
109 } else { 160 } else {
110 doSlowCheck = true; 161 doSlowCheck = true;
111 } 162 }
112 } 163 }
113 164
114 if (doSlowCheck) 165 if (doSlowCheck)
115 return findSlowCase(name, shouldIgnoreCase); 166 return findSlowCase(name, shouldIgnoreCase);
116 return kNotFound; 167 return kNotFound;
117 } 168 }
118 169
119 inline const Attribute* AttributeCollection::find(const QualifiedName& name) con st 170 template <typename Container, typename ContainerMemberType>
171 inline typename AttributeCollectionGeneric<Container, ContainerMemberType>::iter ator AttributeCollectionGeneric<Container, ContainerMemberType>::find(const Qual ifiedName& name) const
120 { 172 {
121 const_iterator end = this->end(); 173 iterator end = this->end();
122 for (const_iterator it = begin(); it != end; ++it) { 174 for (iterator it = begin(); it != end; ++it) {
123 if (it->name().matches(name)) 175 if (it->name().matches(name))
124 return it; 176 return it;
125 } 177 }
126 return 0; 178 return 0;
127 } 179 }
128 180
181 template <typename Container, typename ContainerMemberType>
182 size_t AttributeCollectionGeneric<Container, ContainerMemberType>::findIndex(Att r* attr) const
183 {
184 // This relies on the fact that Attr's QualifiedName == the Attribute's name .
185 iterator end = this->end();
186 unsigned index = 0;
187 for (iterator it = begin(); it != end; ++it, ++index) {
188 if (it->name() == attr->qualifiedName())
189 return index;
190 }
191 return kNotFound;
192 }
193
194 template <typename Container, typename ContainerMemberType>
195 size_t AttributeCollectionGeneric<Container, ContainerMemberType>::findSlowCase( const AtomicString& name, bool shouldIgnoreAttributeCase) const
196 {
197 // Continue to checking case-insensitively and/or full namespaced names if n ecessary:
198 iterator end = this->end();
199 unsigned index = 0;
200 for (iterator it = begin(); it != end; ++it, ++index) {
201 // FIXME: Why check the prefix? Namespace is all that should matter
202 // and all HTML/SVG attributes have a null namespace!
203 if (!it->name().hasPrefix()) {
204 if (shouldIgnoreAttributeCase && equalIgnoringCase(name, it->localNa me()))
205 return index;
206 } else {
207 // FIXME: Would be faster to do this comparison without calling toSt ring, which
208 // generates a temporary string by concatenation. But this branch is only reached
209 // if the attribute name has a prefix, which is rare in HTML.
210 if (equalPossiblyIgnoringCase(name, it->name().toString(), shouldIgn oreAttributeCase))
211 return index;
212 }
213 }
214 return kNotFound;
215 }
216
129 } // namespace blink 217 } // namespace blink
130 218
131 #endif // AttributeCollection_h 219 #endif // AttributeCollection_h
OLDNEW
« no previous file with comments | « Source/core/dom/Attr.cpp ('k') | Source/core/dom/AttributeCollection.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698