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

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

Issue 354023008: Move attributes-related methods from ElementData to AttributeCollection (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Take feedback into consideration Created 6 years, 6 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/Element.cpp ('k') | Source/core/dom/ElementData.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 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 15 matching lines...) Expand all
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32 #ifndef ElementData_h 32 #ifndef ElementData_h
33 #define ElementData_h 33 #define ElementData_h
34 34
35 #include "core/dom/Attribute.h" 35 #include "core/dom/Attribute.h"
36 #include "core/dom/AttributeCollection.h"
36 #include "core/dom/SpaceSplitString.h" 37 #include "core/dom/SpaceSplitString.h"
37 #include "platform/heap/Handle.h" 38 #include "platform/heap/Handle.h"
38 #include "wtf/text/AtomicString.h" 39 #include "wtf/text/AtomicString.h"
39 40
40 namespace WebCore { 41 namespace WebCore {
41 42
42 class Attr;
43 class ShareableElementData; 43 class ShareableElementData;
44 class StylePropertySet; 44 class StylePropertySet;
45 class UniqueElementData; 45 class UniqueElementData;
46 46
47 class AttributeCollection {
48 public:
49 typedef const Attribute* const_iterator;
50
51 AttributeCollection(const Attribute* array, unsigned size)
52 : m_array(array)
53 , m_size(size)
54 { }
55
56 const_iterator begin() const { return m_array; }
57 const_iterator end() const { return m_array + m_size; }
58
59 unsigned size() const { return m_size; }
60
61 private:
62 const Attribute* m_array;
63 unsigned m_size;
64 };
65
66 // ElementData represents very common, but not necessarily unique to an element, 47 // ElementData represents very common, but not necessarily unique to an element,
67 // data such as attributes, inline style, and parsed class names and ids. 48 // data such as attributes, inline style, and parsed class names and ids.
68 class ElementData : public RefCountedWillBeGarbageCollectedFinalized<ElementData > { 49 class ElementData : public RefCountedWillBeGarbageCollectedFinalized<ElementData > {
69 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; 50 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
70 public: 51 public:
71 #if ENABLE(OILPAN) 52 #if ENABLE(OILPAN)
72 // Override GarbageCollectedFinalized's finalizeGarbageCollectedObject to 53 // Override GarbageCollectedFinalized's finalizeGarbageCollectedObject to
73 // dispatch to the correct subclass destructor. 54 // dispatch to the correct subclass destructor.
74 void finalizeGarbageCollectedObject(); 55 void finalizeGarbageCollectedObject();
75 #else 56 #else
76 // Override RefCounted's deref() to ensure operator delete is called on 57 // Override RefCounted's deref() to ensure operator delete is called on
77 // the appropriate subclass type. 58 // the appropriate subclass type.
78 void deref(); 59 void deref();
79 #endif 60 #endif
80 61
81 void clearClass() const { m_classNames.clear(); } 62 void clearClass() const { m_classNames.clear(); }
82 void setClass(const AtomicString& className, bool shouldFoldCase) const { m_ classNames.set(className, shouldFoldCase); } 63 void setClass(const AtomicString& className, bool shouldFoldCase) const { m_ classNames.set(className, shouldFoldCase); }
83 const SpaceSplitString& classNames() const { return m_classNames; } 64 const SpaceSplitString& classNames() const { return m_classNames; }
84 65
85 const AtomicString& idForStyleResolution() const { return m_idForStyleResolu tion; } 66 const AtomicString& idForStyleResolution() const { return m_idForStyleResolu tion; }
86 void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyle Resolution = newId; } 67 void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyle Resolution = newId; }
87 68
88 const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); } 69 const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); }
89 70
90 const StylePropertySet* presentationAttributeStyle() const; 71 const StylePropertySet* presentationAttributeStyle() const;
91 72
92 // This is not a trivial getter and its return value should be cached for pe rformance.
93 size_t attributeCount() const;
94 bool hasAttributes() const { return !!attributeCount(); }
95
96 AttributeCollection attributes() const; 73 AttributeCollection attributes() const;
97 74
98 const Attribute& attributeAt(unsigned index) const;
99 const Attribute* findAttributeByName(const QualifiedName&) const;
100 size_t findAttributeIndexByName(const QualifiedName&, bool shouldIgnoreCase = false) const;
101 size_t findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreA ttributeCase) const;
102 size_t findAttrNodeIndex(Attr*) const;
103
104 bool hasID() const { return !m_idForStyleResolution.isNull(); } 75 bool hasID() const { return !m_idForStyleResolution.isNull(); }
105 bool hasClass() const { return !m_classNames.isNull(); } 76 bool hasClass() const { return !m_classNames.isNull(); }
106 77
107 bool isEquivalent(const ElementData* other) const; 78 bool isEquivalent(const ElementData* other) const;
108 79
109 bool isUnique() const { return m_isUnique; } 80 bool isUnique() const { return m_isUnique; }
110 81
111 void traceAfterDispatch(Visitor*); 82 void traceAfterDispatch(Visitor*);
112 void trace(Visitor*); 83 void trace(Visitor*);
113 84
(...skipping 16 matching lines...) Expand all
130 private: 101 private:
131 friend class Element; 102 friend class Element;
132 friend class ShareableElementData; 103 friend class ShareableElementData;
133 friend class UniqueElementData; 104 friend class UniqueElementData;
134 friend class SVGElement; 105 friend class SVGElement;
135 106
136 #if !ENABLE(OILPAN) 107 #if !ENABLE(OILPAN)
137 void destroy(); 108 void destroy();
138 #endif 109 #endif
139 110
140 const Attribute* attributeBase() const;
141 const Attribute* findAttributeByName(const AtomicString& name, bool shouldIg noreAttributeCase) const;
142 size_t findAttributeIndexByNameSlowCase(const AtomicString& name, bool shoul dIgnoreAttributeCase) const;
143
144 PassRefPtrWillBeRawPtr<UniqueElementData> makeUniqueCopy() const; 111 PassRefPtrWillBeRawPtr<UniqueElementData> makeUniqueCopy() const;
145 }; 112 };
146 113
147 #if COMPILER(MSVC) 114 #if COMPILER(MSVC)
148 #pragma warning(push) 115 #pragma warning(push)
149 #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" war ning 116 #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" war ning
150 #endif 117 #endif
151 118
152 // SharableElementData is managed by ElementDataCache and is produced by 119 // SharableElementData is managed by ElementDataCache and is produced by
153 // the parser during page load for elements that have identical attributes. This 120 // the parser during page load for elements that have identical attributes. This
(...skipping 12 matching lines...) Expand all
166 // Add support for placement new as ShareableElementData is not allocated 133 // Add support for placement new as ShareableElementData is not allocated
167 // with a fixed size. Instead the allocated memory size is computed based on 134 // with a fixed size. Instead the allocated memory size is computed based on
168 // the number of attributes. This requires us to use Heap::allocate directly 135 // the number of attributes. This requires us to use Heap::allocate directly
169 // with the computed size and subsequently call placement new with the 136 // with the computed size and subsequently call placement new with the
170 // allocated memory address. 137 // allocated memory address.
171 void* operator new(std::size_t, void* location) 138 void* operator new(std::size_t, void* location)
172 { 139 {
173 return location; 140 return location;
174 } 141 }
175 142
143 AttributeCollection attributes() const;
144
176 Attribute m_attributeArray[0]; 145 Attribute m_attributeArray[0];
177 }; 146 };
178 147
179 #if COMPILER(MSVC) 148 #if COMPILER(MSVC)
180 #pragma warning(pop) 149 #pragma warning(pop)
181 #endif 150 #endif
182 151
183 // UniqueElementData is created when an element needs to mutate its attributes 152 // UniqueElementData is created when an element needs to mutate its attributes
184 // or gains presentation attribute style (ex. width="10"). It does not need to 153 // or gains presentation attribute style (ex. width="10"). It does not need to
185 // be created to fill in values in the ElementData that are derived from 154 // be created to fill in values in the ElementData that are derived from
186 // attributes. For example populating the m_inlineStyle from the style attribute 155 // attributes. For example populating the m_inlineStyle from the style attribute
187 // doesn't require a UniqueElementData as all elements with the same style 156 // doesn't require a UniqueElementData as all elements with the same style
188 // attribute will have the same inline style. 157 // attribute will have the same inline style.
189 class UniqueElementData FINAL : public ElementData { 158 class UniqueElementData FINAL : public ElementData {
190 public: 159 public:
191 static PassRefPtrWillBeRawPtr<UniqueElementData> create(); 160 static PassRefPtrWillBeRawPtr<UniqueElementData> create();
192 PassRefPtrWillBeRawPtr<ShareableElementData> makeShareableCopy() const; 161 PassRefPtrWillBeRawPtr<ShareableElementData> makeShareableCopy() const;
193 162
194 // These functions do no error/duplicate checking. 163 // These functions do no error/duplicate checking.
195 void appendAttribute(const QualifiedName&, const AtomicString&); 164 void appendAttribute(const QualifiedName&, const AtomicString&);
196 void removeAttributeAt(size_t index); 165 void removeAttributeAt(size_t index);
197 166
167 AttributeCollection attributes() const;
168
198 Attribute& attributeAt(unsigned index); 169 Attribute& attributeAt(unsigned index);
199 Attribute* findAttributeByName(const QualifiedName&); 170 Attribute* findAttributeByName(const QualifiedName&);
200 171
201 UniqueElementData(); 172 UniqueElementData();
202 explicit UniqueElementData(const ShareableElementData&); 173 explicit UniqueElementData(const ShareableElementData&);
203 explicit UniqueElementData(const UniqueElementData&); 174 explicit UniqueElementData(const UniqueElementData&);
204 175
205 void traceAfterDispatch(Visitor*); 176 void traceAfterDispatch(Visitor*);
206 177
207 // FIXME: We might want to support sharing element data for elements with 178 // FIXME: We might want to support sharing element data for elements with
208 // presentation attribute style. Lots of table cells likely have the same 179 // presentation attribute style. Lots of table cells likely have the same
209 // attributes. Most modern pages don't use presentation attributes though 180 // attributes. Most modern pages don't use presentation attributes though
210 // so this might not make sense. 181 // so this might not make sense.
211 mutable RefPtrWillBeMember<StylePropertySet> m_presentationAttributeStyle; 182 mutable RefPtrWillBeMember<StylePropertySet> m_presentationAttributeStyle;
212 Vector<Attribute, 4> m_attributeVector; 183 Vector<Attribute, 4> m_attributeVector;
213 }; 184 };
214 185
215 #if !ENABLE(OILPAN) 186 #if !ENABLE(OILPAN)
216 inline void ElementData::deref() 187 inline void ElementData::deref()
217 { 188 {
218 if (!derefBase()) 189 if (!derefBase())
219 return; 190 return;
220 destroy(); 191 destroy();
221 } 192 }
222 #endif 193 #endif
223 194
224 inline size_t ElementData::attributeCount() const
225 {
226 if (isUnique())
227 return static_cast<const UniqueElementData*>(this)->m_attributeVector.si ze();
228 return m_arraySize;
229 }
230
231 inline const StylePropertySet* ElementData::presentationAttributeStyle() const 195 inline const StylePropertySet* ElementData::presentationAttributeStyle() const
232 { 196 {
233 if (!m_isUnique) 197 if (!m_isUnique)
234 return 0; 198 return 0;
235 return static_cast<const UniqueElementData*>(this)->m_presentationAttributeS tyle.get(); 199 return static_cast<const UniqueElementData*>(this)->m_presentationAttributeS tyle.get();
236 } 200 }
237 201
238 inline const Attribute* ElementData::findAttributeByName(const AtomicString& nam e, bool shouldIgnoreAttributeCase) const
239 {
240 size_t index = findAttributeIndexByName(name, shouldIgnoreAttributeCase);
241 if (index != kNotFound)
242 return &attributeAt(index);
243 return 0;
244 }
245
246 inline const Attribute* ElementData::attributeBase() const
247 {
248 if (m_isUnique)
249 return static_cast<const UniqueElementData*>(this)->m_attributeVector.be gin();
250 return static_cast<const ShareableElementData*>(this)->m_attributeArray;
251 }
252
253 inline size_t ElementData::findAttributeIndexByName(const QualifiedName& name, b ool shouldIgnoreCase) const
254 {
255 AttributeCollection attributes = this->attributes();
256 AttributeCollection::const_iterator end = attributes.end();
257 unsigned index = 0;
258 for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it, ++index) {
259 if (it->name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase))
260 return index;
261 }
262 return kNotFound;
263 }
264
265 // We use a boolean parameter instead of calling shouldIgnoreAttributeCase so th at the caller
266 // can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not).
267 inline size_t ElementData::findAttributeIndexByName(const AtomicString& name, bo ol shouldIgnoreAttributeCase) const
268 {
269 bool doSlowCheck = shouldIgnoreAttributeCase;
270
271 // Optimize for the case where the attribute exists and its name exactly mat ches.
272 AttributeCollection attributes = this->attributes();
273 AttributeCollection::const_iterator end = attributes.end();
274 unsigned index = 0;
275 for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it, ++index) {
276 // FIXME: Why check the prefix? Namespaces should be all that matter.
277 // Most attributes (all of HTML and CSS) have no namespace.
278 if (!it->name().hasPrefix()) {
279 if (name == it->localName())
280 return index;
281 } else {
282 doSlowCheck = true;
283 }
284 }
285
286 if (doSlowCheck)
287 return findAttributeIndexByNameSlowCase(name, shouldIgnoreAttributeCase) ;
288 return kNotFound;
289 }
290
291 inline AttributeCollection ElementData::attributes() const 202 inline AttributeCollection ElementData::attributes() const
292 { 203 {
293 if (isUnique()) { 204 if (isUnique())
294 const Vector<Attribute, 4>& attributeVector = static_cast<const UniqueEl ementData*>(this)->m_attributeVector; 205 return static_cast<const UniqueElementData*>(this)->attributes();
295 return AttributeCollection(attributeVector.data(), attributeVector.size( )); 206 return static_cast<const ShareableElementData*>(this)->attributes();
296 }
297 return AttributeCollection(static_cast<const ShareableElementData*>(this)->m _attributeArray, m_arraySize);
298 } 207 }
299 208
300 inline const Attribute* ElementData::findAttributeByName(const QualifiedName& na me) const 209 inline AttributeCollection ShareableElementData::attributes() const
301 { 210 {
302 AttributeCollection attributes = this->attributes(); 211 return AttributeCollection(m_attributeArray, m_arraySize);
303 AttributeCollection::const_iterator end = attributes.end();
304 for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
305 if (it->name().matches(name))
306 return it;
307 }
308 return 0;
309 } 212 }
310 213
311 inline const Attribute& ElementData::attributeAt(unsigned index) const 214 inline AttributeCollection UniqueElementData::attributes() const
312 { 215 {
313 RELEASE_ASSERT(index < attributeCount()); 216 return AttributeCollection(m_attributeVector.data(), m_attributeVector.size( ));
314 ASSERT(attributeBase() + index);
315 return *(attributeBase() + index);
316 } 217 }
317 218
318 inline void UniqueElementData::appendAttribute(const QualifiedName& attributeNam e, const AtomicString& value) 219 inline void UniqueElementData::appendAttribute(const QualifiedName& attributeNam e, const AtomicString& value)
319 { 220 {
320 m_attributeVector.append(Attribute(attributeName, value)); 221 m_attributeVector.append(Attribute(attributeName, value));
321 } 222 }
322 223
323 inline void UniqueElementData::removeAttributeAt(size_t index) 224 inline void UniqueElementData::removeAttributeAt(size_t index)
324 { 225 {
325 m_attributeVector.remove(index); 226 m_attributeVector.remove(index);
326 } 227 }
327 228
328 inline Attribute& UniqueElementData::attributeAt(unsigned index) 229 inline Attribute& UniqueElementData::attributeAt(unsigned index)
329 { 230 {
330 return m_attributeVector.at(index); 231 return m_attributeVector.at(index);
331 } 232 }
332 233
333 } // namespace WebCore 234 } // namespace WebCore
334 235
335 #endif // ElementData_h 236 #endif // ElementData_h
OLDNEW
« no previous file with comments | « Source/core/dom/Element.cpp ('k') | Source/core/dom/ElementData.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698