OLD | NEW |
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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 const SpaceSplitString& classNames() const { return m_classNames; } | 95 const SpaceSplitString& classNames() const { return m_classNames; } |
96 | 96 |
97 const AtomicString& idForStyleResolution() const { return m_idForStyleResolu
tion; } | 97 const AtomicString& idForStyleResolution() const { return m_idForStyleResolu
tion; } |
98 void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyle
Resolution = newId; } | 98 void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyle
Resolution = newId; } |
99 | 99 |
100 const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); } | 100 const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); } |
101 | 101 |
102 const StylePropertySet* presentationAttributeStyle() const; | 102 const StylePropertySet* presentationAttributeStyle() const; |
103 | 103 |
104 // This is not a trivial getter and its return value should be cached for pe
rformance. | 104 // This is not a trivial getter and its return value should be cached for pe
rformance. |
105 size_t length() const; | 105 size_t attributeCount() const; |
106 bool isEmpty() const { return !length(); } | 106 bool hasAttributes() const { return !!attributeCount(); } |
107 | 107 |
108 AttributeIteratorAccessor attributesIterator() const; | 108 AttributeIteratorAccessor attributesIterator() const; |
109 | 109 |
110 const Attribute& attributeItem(unsigned index) const; | 110 const Attribute& attributeAt(unsigned index) const; |
111 const Attribute* getAttributeItem(const QualifiedName&) const; | 111 const Attribute* findAttributeByName(const QualifiedName&) const; |
112 size_t getAttributeItemIndex(const QualifiedName&, bool shouldIgnoreCase = f
alse) const; | 112 size_t findAttributeIndexByName(const QualifiedName&, bool shouldIgnoreCase
= false) const; |
113 size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttr
ibuteCase) const; | 113 size_t findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreA
ttributeCase) const; |
114 size_t getAttrIndex(Attr*) const; | 114 size_t findAttrNodeIndex(Attr*) const; |
115 | 115 |
116 bool hasID() const { return !m_idForStyleResolution.isNull(); } | 116 bool hasID() const { return !m_idForStyleResolution.isNull(); } |
117 bool hasClass() const { return !m_classNames.isNull(); } | 117 bool hasClass() const { return !m_classNames.isNull(); } |
118 | 118 |
119 bool isEquivalent(const ElementData* other) const; | 119 bool isEquivalent(const ElementData* other) const; |
120 | 120 |
121 bool isUnique() const { return m_isUnique; } | 121 bool isUnique() const { return m_isUnique; } |
122 | 122 |
123 protected: | 123 protected: |
124 ElementData(); | 124 ElementData(); |
(...skipping 13 matching lines...) Expand all Loading... |
138 | 138 |
139 private: | 139 private: |
140 friend class Element; | 140 friend class Element; |
141 friend class ShareableElementData; | 141 friend class ShareableElementData; |
142 friend class UniqueElementData; | 142 friend class UniqueElementData; |
143 friend class SVGElement; | 143 friend class SVGElement; |
144 | 144 |
145 void destroy(); | 145 void destroy(); |
146 | 146 |
147 const Attribute* attributeBase() const; | 147 const Attribute* attributeBase() const; |
148 const Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnor
eAttributeCase) const; | 148 const Attribute* findAttributeByName(const AtomicString& name, bool shouldIg
noreAttributeCase) const; |
149 size_t getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIg
noreAttributeCase) const; | 149 size_t findAttributeIndexByNameSlowCase(const AtomicString& name, bool shoul
dIgnoreAttributeCase) const; |
150 | 150 |
151 PassRefPtr<UniqueElementData> makeUniqueCopy() const; | 151 PassRefPtr<UniqueElementData> makeUniqueCopy() const; |
152 }; | 152 }; |
153 | 153 |
154 #if COMPILER(MSVC) | 154 #if COMPILER(MSVC) |
155 #pragma warning(push) | 155 #pragma warning(push) |
156 #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" war
ning | 156 #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" war
ning |
157 #endif | 157 #endif |
158 | 158 |
159 // SharableElementData is managed by ElementDataCache and is produced by | 159 // SharableElementData is managed by ElementDataCache and is produced by |
(...skipping 20 matching lines...) Expand all Loading... |
180 // be created to fill in values in the ElementData that are derived from | 180 // be created to fill in values in the ElementData that are derived from |
181 // attributes. For example populating the m_inlineStyle from the style attribute | 181 // attributes. For example populating the m_inlineStyle from the style attribute |
182 // doesn't require a UniqueElementData as all elements with the same style | 182 // doesn't require a UniqueElementData as all elements with the same style |
183 // attribute will have the same inline style. | 183 // attribute will have the same inline style. |
184 class UniqueElementData FINAL : public ElementData { | 184 class UniqueElementData FINAL : public ElementData { |
185 public: | 185 public: |
186 static PassRefPtr<UniqueElementData> create(); | 186 static PassRefPtr<UniqueElementData> create(); |
187 PassRefPtr<ShareableElementData> makeShareableCopy() const; | 187 PassRefPtr<ShareableElementData> makeShareableCopy() const; |
188 | 188 |
189 // These functions do no error/duplicate checking. | 189 // These functions do no error/duplicate checking. |
190 void addAttribute(const QualifiedName&, const AtomicString&); | 190 void appendAttribute(const QualifiedName&, const AtomicString&); |
191 void removeAttribute(size_t index); | 191 void removeAttributeAt(size_t index); |
192 | 192 |
193 Attribute& attributeItem(unsigned index); | 193 Attribute& attributeAt(unsigned index); |
194 Attribute* getAttributeItem(const QualifiedName&); | 194 Attribute* findAttributeByName(const QualifiedName&); |
195 | 195 |
196 UniqueElementData(); | 196 UniqueElementData(); |
197 explicit UniqueElementData(const ShareableElementData&); | 197 explicit UniqueElementData(const ShareableElementData&); |
198 explicit UniqueElementData(const UniqueElementData&); | 198 explicit UniqueElementData(const UniqueElementData&); |
199 | 199 |
200 // FIXME: We might want to support sharing element data for elements with | 200 // FIXME: We might want to support sharing element data for elements with |
201 // presentation attribute style. Lots of table cells likely have the same | 201 // presentation attribute style. Lots of table cells likely have the same |
202 // attributes. Most modern pages don't use presentation attributes though | 202 // attributes. Most modern pages don't use presentation attributes though |
203 // so this might not make sense. | 203 // so this might not make sense. |
204 mutable RefPtr<StylePropertySet> m_presentationAttributeStyle; | 204 mutable RefPtr<StylePropertySet> m_presentationAttributeStyle; |
205 Vector<Attribute, 4> m_attributeVector; | 205 Vector<Attribute, 4> m_attributeVector; |
206 }; | 206 }; |
207 | 207 |
208 inline void ElementData::deref() | 208 inline void ElementData::deref() |
209 { | 209 { |
210 if (!derefBase()) | 210 if (!derefBase()) |
211 return; | 211 return; |
212 destroy(); | 212 destroy(); |
213 } | 213 } |
214 | 214 |
215 inline size_t ElementData::length() const | 215 inline size_t ElementData::attributeCount() const |
216 { | 216 { |
217 if (isUnique()) | 217 if (isUnique()) |
218 return static_cast<const UniqueElementData*>(this)->m_attributeVector.si
ze(); | 218 return static_cast<const UniqueElementData*>(this)->m_attributeVector.si
ze(); |
219 return m_arraySize; | 219 return m_arraySize; |
220 } | 220 } |
221 | 221 |
222 inline const StylePropertySet* ElementData::presentationAttributeStyle() const | 222 inline const StylePropertySet* ElementData::presentationAttributeStyle() const |
223 { | 223 { |
224 if (!m_isUnique) | 224 if (!m_isUnique) |
225 return 0; | 225 return 0; |
226 return static_cast<const UniqueElementData*>(this)->m_presentationAttributeS
tyle.get(); | 226 return static_cast<const UniqueElementData*>(this)->m_presentationAttributeS
tyle.get(); |
227 } | 227 } |
228 | 228 |
229 inline const Attribute* ElementData::getAttributeItem(const AtomicString& name,
bool shouldIgnoreAttributeCase) const | 229 inline const Attribute* ElementData::findAttributeByName(const AtomicString& nam
e, bool shouldIgnoreAttributeCase) const |
230 { | 230 { |
231 size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase); | 231 size_t index = findAttributeIndexByName(name, shouldIgnoreAttributeCase); |
232 if (index != kNotFound) | 232 if (index != kNotFound) |
233 return &attributeItem(index); | 233 return &attributeAt(index); |
234 return 0; | 234 return 0; |
235 } | 235 } |
236 | 236 |
237 inline const Attribute* ElementData::attributeBase() const | 237 inline const Attribute* ElementData::attributeBase() const |
238 { | 238 { |
239 if (m_isUnique) | 239 if (m_isUnique) |
240 return static_cast<const UniqueElementData*>(this)->m_attributeVector.be
gin(); | 240 return static_cast<const UniqueElementData*>(this)->m_attributeVector.be
gin(); |
241 return static_cast<const ShareableElementData*>(this)->m_attributeArray; | 241 return static_cast<const ShareableElementData*>(this)->m_attributeArray; |
242 } | 242 } |
243 | 243 |
244 inline size_t ElementData::getAttributeItemIndex(const QualifiedName& name, bool
shouldIgnoreCase) const | 244 inline size_t ElementData::findAttributeIndexByName(const QualifiedName& name, b
ool shouldIgnoreCase) const |
245 { | 245 { |
246 AttributeIteratorAccessor attributes = attributesIterator(); | 246 AttributeIteratorAccessor attributes = attributesIterator(); |
247 AttributeConstIterator end = attributes.end(); | 247 AttributeConstIterator end = attributes.end(); |
248 for (AttributeConstIterator it = attributes.begin(); it != end; ++it) { | 248 for (AttributeConstIterator it = attributes.begin(); it != end; ++it) { |
249 if (it->name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase)) | 249 if (it->name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase)) |
250 return it.index(); | 250 return it.index(); |
251 } | 251 } |
252 return kNotFound; | 252 return kNotFound; |
253 } | 253 } |
254 | 254 |
255 // We use a boolean parameter instead of calling shouldIgnoreAttributeCase so th
at the caller | 255 // We use a boolean parameter instead of calling shouldIgnoreAttributeCase so th
at the caller |
256 // can tune the behavior (hasAttribute is case sensitive whereas getAttribute is
not). | 256 // can tune the behavior (hasAttribute is case sensitive whereas getAttribute is
not). |
257 inline size_t ElementData::getAttributeItemIndex(const AtomicString& name, bool
shouldIgnoreAttributeCase) const | 257 inline size_t ElementData::findAttributeIndexByName(const AtomicString& name, bo
ol shouldIgnoreAttributeCase) const |
258 { | 258 { |
259 bool doSlowCheck = shouldIgnoreAttributeCase; | 259 bool doSlowCheck = shouldIgnoreAttributeCase; |
260 | 260 |
261 // Optimize for the case where the attribute exists and its name exactly mat
ches. | 261 // Optimize for the case where the attribute exists and its name exactly mat
ches. |
262 AttributeIteratorAccessor attributes = attributesIterator(); | 262 AttributeIteratorAccessor attributes = attributesIterator(); |
263 AttributeConstIterator end = attributes.end(); | 263 AttributeConstIterator end = attributes.end(); |
264 for (AttributeConstIterator it = attributes.begin(); it != end; ++it) { | 264 for (AttributeConstIterator it = attributes.begin(); it != end; ++it) { |
265 // FIXME: Why check the prefix? Namespaces should be all that matter. | 265 // FIXME: Why check the prefix? Namespaces should be all that matter. |
266 // Most attributes (all of HTML and CSS) have no namespace. | 266 // Most attributes (all of HTML and CSS) have no namespace. |
267 if (!it->name().hasPrefix()) { | 267 if (!it->name().hasPrefix()) { |
268 if (name == it->localName()) | 268 if (name == it->localName()) |
269 return it.index(); | 269 return it.index(); |
270 } else { | 270 } else { |
271 doSlowCheck = true; | 271 doSlowCheck = true; |
272 } | 272 } |
273 } | 273 } |
274 | 274 |
275 if (doSlowCheck) | 275 if (doSlowCheck) |
276 return getAttributeItemIndexSlowCase(name, shouldIgnoreAttributeCase); | 276 return findAttributeIndexByNameSlowCase(name, shouldIgnoreAttributeCase)
; |
277 return kNotFound; | 277 return kNotFound; |
278 } | 278 } |
279 | 279 |
280 inline AttributeIteratorAccessor ElementData::attributesIterator() const | 280 inline AttributeIteratorAccessor ElementData::attributesIterator() const |
281 { | 281 { |
282 if (isUnique()) { | 282 if (isUnique()) { |
283 const Vector<Attribute, 4>& attributeVector = static_cast<const UniqueEl
ementData*>(this)->m_attributeVector; | 283 const Vector<Attribute, 4>& attributeVector = static_cast<const UniqueEl
ementData*>(this)->m_attributeVector; |
284 return AttributeIteratorAccessor(attributeVector.data(), attributeVector
.size()); | 284 return AttributeIteratorAccessor(attributeVector.data(), attributeVector
.size()); |
285 } | 285 } |
286 return AttributeIteratorAccessor(static_cast<const ShareableElementData*>(th
is)->m_attributeArray, m_arraySize); | 286 return AttributeIteratorAccessor(static_cast<const ShareableElementData*>(th
is)->m_attributeArray, m_arraySize); |
287 } | 287 } |
288 | 288 |
289 inline const Attribute* ElementData::getAttributeItem(const QualifiedName& name)
const | 289 inline const Attribute* ElementData::findAttributeByName(const QualifiedName& na
me) const |
290 { | 290 { |
291 AttributeIteratorAccessor attributes = attributesIterator(); | 291 AttributeIteratorAccessor attributes = attributesIterator(); |
292 AttributeConstIterator end = attributes.end(); | 292 AttributeConstIterator end = attributes.end(); |
293 for (AttributeConstIterator it = attributes.begin(); it != end; ++it) { | 293 for (AttributeConstIterator it = attributes.begin(); it != end; ++it) { |
294 if (it->name().matches(name)) | 294 if (it->name().matches(name)) |
295 return *it; | 295 return *it; |
296 } | 296 } |
297 return 0; | 297 return 0; |
298 } | 298 } |
299 | 299 |
300 inline const Attribute& ElementData::attributeItem(unsigned index) const | 300 inline const Attribute& ElementData::attributeAt(unsigned index) const |
301 { | 301 { |
302 RELEASE_ASSERT(index < length()); | 302 RELEASE_ASSERT(index < attributeCount()); |
303 ASSERT(attributeBase() + index); | 303 ASSERT(attributeBase() + index); |
304 return *(attributeBase() + index); | 304 return *(attributeBase() + index); |
305 } | 305 } |
306 | 306 |
307 inline void UniqueElementData::addAttribute(const QualifiedName& attributeName,
const AtomicString& value) | 307 inline void UniqueElementData::appendAttribute(const QualifiedName& attributeNam
e, const AtomicString& value) |
308 { | 308 { |
309 m_attributeVector.append(Attribute(attributeName, value)); | 309 m_attributeVector.append(Attribute(attributeName, value)); |
310 } | 310 } |
311 | 311 |
312 inline void UniqueElementData::removeAttribute(size_t index) | 312 inline void UniqueElementData::removeAttributeAt(size_t index) |
313 { | 313 { |
314 m_attributeVector.remove(index); | 314 m_attributeVector.remove(index); |
315 } | 315 } |
316 | 316 |
317 inline Attribute& UniqueElementData::attributeItem(unsigned index) | 317 inline Attribute& UniqueElementData::attributeAt(unsigned index) |
318 { | 318 { |
319 return m_attributeVector.at(index); | 319 return m_attributeVector.at(index); |
320 } | 320 } |
321 | 321 |
322 } // namespace WebCore | 322 } // namespace WebCore |
323 | 323 |
324 #endif // ElementData_h | 324 #endif // ElementData_h |
OLD | NEW |