| 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 |