diff options
Diffstat (limited to 'Source/WebCore/dom/ElementData.h')
-rw-r--r-- | Source/WebCore/dom/ElementData.h | 114 |
1 files changed, 66 insertions, 48 deletions
diff --git a/Source/WebCore/dom/ElementData.h b/Source/WebCore/dom/ElementData.h index 296b37c49..f6d1eafd7 100644 --- a/Source/WebCore/dom/ElementData.h +++ b/Source/WebCore/dom/ElementData.h @@ -23,12 +23,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ElementData_h -#define ElementData_h +#pragma once #include "Attribute.h" #include "SpaceSplitString.h" #include <wtf/RefCounted.h> +#include <wtf/TypeCasts.h> namespace WebCore { @@ -67,6 +67,9 @@ public: AttributeConstIterator begin() const { return AttributeConstIterator(m_array, 0); } AttributeConstIterator end() const { return AttributeConstIterator(m_array, m_size); } + + unsigned attributeCount() const { return m_size; } + private: const Attribute* m_array; unsigned m_size; @@ -81,8 +84,7 @@ public: static const unsigned attributeNotFound = static_cast<unsigned>(-1); - void clearClass() const { m_classNames.clear(); } - void setClass(const AtomicString& className, bool shouldFoldCase) const { m_classNames.set(className, shouldFoldCase); } + void setClassNames(const SpaceSplitString& classNames) const { m_classNames = classNames; } const SpaceSplitString& classNames() const { return m_classNames; } static ptrdiff_t classNamesMemoryOffset() { return OBJECT_OFFSETOF(ElementData, m_classNames); } @@ -101,7 +103,7 @@ public: const Attribute* findAttributeByName(const QualifiedName&) const; unsigned findAttributeIndexByName(const QualifiedName&) const; unsigned findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const; - unsigned findAttributeIndexByNameForAttributeNode(const Attr*, bool shouldIgnoreAttributeCase = false) const; + const Attribute* findLanguageAttribute() const; bool hasID() const { return !m_idForStyleResolution.isNull(); } bool hasClass() const { return !m_classNames.isEmpty(); } @@ -110,6 +112,13 @@ public: bool isEquivalent(const ElementData* other) const; bool isUnique() const { return m_arraySizeAndFlags & s_flagIsUnique; } + static uint32_t isUniqueFlag() { return s_flagIsUnique; } + + static ptrdiff_t arraySizeAndFlagsMemoryOffset() { return OBJECT_OFFSETOF(ElementData, m_arraySizeAndFlags); } + static inline uint32_t styleAttributeIsDirtyFlag() { return s_flagStyleAttributeIsDirty; } + static uint32_t animatedSVGAttributesAreDirtyFlag() { return s_flagAnimatedSVGAttributesAreDirty; } + + static uint32_t arraySizeOffset() { return s_flagCount; } private: mutable uint32_t m_arraySizeAndFlags; @@ -120,9 +129,7 @@ private: static const uint32_t s_flagHasNameAttribute = 1 << 1; static const uint32_t s_flagPresentationAttributeStyleIsDirty = 1 << 2; static const uint32_t s_flagStyleAttributeIsDirty = 1 << 3; -#if ENABLE(SVG) static const uint32_t s_flagAnimatedSVGAttributesAreDirty = 1 << 4; -#endif static const uint32_t s_flagsMask = (1 << s_flagCount) - 1; inline void updateFlag(uint32_t flag, bool set) const @@ -149,10 +156,8 @@ protected: bool presentationAttributeStyleIsDirty() const { return m_arraySizeAndFlags & s_flagPresentationAttributeStyleIsDirty; } void setPresentationAttributeStyleIsDirty(bool isDirty) const { updateFlag(s_flagPresentationAttributeStyleIsDirty, isDirty); } -#if ENABLE(SVG) bool animatedSVGAttributesAreDirty() const { return m_arraySizeAndFlags & s_flagAnimatedSVGAttributesAreDirty; } void setAnimatedSVGAttributesAreDirty(bool dirty) const { updateFlag(s_flagAnimatedSVGAttributesAreDirty, dirty); } -#endif mutable RefPtr<StyleProperties> m_inlineStyle; mutable SpaceSplitString m_classNames; @@ -163,17 +168,14 @@ private: friend class StyledElement; friend class ShareableElementData; friend class UniqueElementData; -#if ENABLE(SVG) friend class SVGElement; -#endif void destroy(); const Attribute* attributeBase() const; const Attribute* findAttributeByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const; - unsigned findAttributeIndexByNameSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const; - PassRef<UniqueElementData> makeUniqueCopy() const; + Ref<UniqueElementData> makeUniqueCopy() const; }; #if COMPILER(MSVC) @@ -183,12 +185,14 @@ private: class ShareableElementData : public ElementData { public: - static PassRef<ShareableElementData> createWithAttributes(const Vector<Attribute>&); + static Ref<ShareableElementData> createWithAttributes(const Vector<Attribute>&); explicit ShareableElementData(const Vector<Attribute>&); explicit ShareableElementData(const UniqueElementData&); ~ShareableElementData(); + static ptrdiff_t attributeArrayMemoryOffset() { return OBJECT_OFFSETOF(ShareableElementData, m_attributeArray); } + Attribute m_attributeArray[0]; }; @@ -198,8 +202,8 @@ public: class UniqueElementData : public ElementData { public: - static PassRef<UniqueElementData> create(); - PassRef<ShareableElementData> makeShareableCopy() const; + static Ref<UniqueElementData> create(); + Ref<ShareableElementData> makeShareableCopy() const; // These functions do no error/duplicate checking. void addAttribute(const QualifiedName&, const AtomicString&); @@ -212,8 +216,11 @@ public: explicit UniqueElementData(const ShareableElementData&); explicit UniqueElementData(const UniqueElementData&); + static ptrdiff_t attributeVectorMemoryOffset() { return OBJECT_OFFSETOF(UniqueElementData, m_attributeVector); } + mutable RefPtr<StyleProperties> m_presentationAttributeStyle; - Vector<Attribute, 4> m_attributeVector; + typedef Vector<Attribute, 4> AttributeVector; + AttributeVector m_attributeVector; }; inline void ElementData::deref() @@ -225,43 +232,43 @@ inline void ElementData::deref() inline unsigned ElementData::length() const { - if (isUnique()) - return static_cast<const UniqueElementData*>(this)->m_attributeVector.size(); + if (is<UniqueElementData>(*this)) + return downcast<UniqueElementData>(*this).m_attributeVector.size(); return arraySize(); } inline const Attribute* ElementData::attributeBase() const { - if (isUnique()) - return static_cast<const UniqueElementData*>(this)->m_attributeVector.data(); - return static_cast<const ShareableElementData*>(this)->m_attributeArray; + if (is<UniqueElementData>(*this)) + return downcast<UniqueElementData>(*this).m_attributeVector.data(); + return downcast<ShareableElementData>(*this).m_attributeArray; } inline const StyleProperties* ElementData::presentationAttributeStyle() const { - if (!isUnique()) - return 0; - return static_cast<const UniqueElementData*>(this)->m_presentationAttributeStyle.get(); + if (!is<UniqueElementData>(*this)) + return nullptr; + return downcast<UniqueElementData>(*this).m_presentationAttributeStyle.get(); } inline AttributeIteratorAccessor ElementData::attributesIterator() const { - if (isUnique()) { - const Vector<Attribute, 4>& attributeVector = static_cast<const UniqueElementData*>(this)->m_attributeVector; + if (is<UniqueElementData>(*this)) { + const Vector<Attribute, 4>& attributeVector = downcast<UniqueElementData>(*this).m_attributeVector; return AttributeIteratorAccessor(attributeVector.data(), attributeVector.size()); } - return AttributeIteratorAccessor(static_cast<const ShareableElementData*>(this)->m_attributeArray, arraySize()); + return AttributeIteratorAccessor(downcast<ShareableElementData>(*this).m_attributeArray, arraySize()); } -inline const Attribute* ElementData::findAttributeByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const +ALWAYS_INLINE const Attribute* ElementData::findAttributeByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const { unsigned index = findAttributeIndexByName(name, shouldIgnoreAttributeCase); if (index != attributeNotFound) return &attributeAt(index); - return 0; + return nullptr; } -inline unsigned ElementData::findAttributeIndexByName(const QualifiedName& name) const +ALWAYS_INLINE unsigned ElementData::findAttributeIndexByName(const QualifiedName& name) const { const Attribute* attributes = attributeBase(); for (unsigned i = 0, count = length(); i < count; ++i) { @@ -273,27 +280,33 @@ inline unsigned ElementData::findAttributeIndexByName(const QualifiedName& name) // We use a boolean parameter instead of calling shouldIgnoreAttributeCase so that the caller // can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not). -inline unsigned ElementData::findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const +ALWAYS_INLINE unsigned ElementData::findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const { - const Attribute* attributes = attributeBase(); - bool doSlowCheck = shouldIgnoreAttributeCase; - const AtomicString& caseAdjustedName = shouldIgnoreAttributeCase ? name.lower() : name; + unsigned attributeCount = length(); + if (!attributeCount) + return attributeNotFound; - // Optimize for the case where the attribute exists and its name exactly matches. - for (unsigned i = 0, count = length(); i < count; ++i) { - if (!attributes[i].name().hasPrefix()) { - if (caseAdjustedName == attributes[i].localName()) - return i; - } else - doSlowCheck = true; - } + const Attribute* attributes = attributeBase(); + const AtomicString& caseAdjustedName = shouldIgnoreAttributeCase ? name.convertToASCIILowercase() : name; + + unsigned attributeIndex = 0; + do { + const Attribute& attribute = attributes[attributeIndex]; + if (!attribute.name().hasPrefix()) { + if (attribute.localName() == caseAdjustedName) + return attributeIndex; + } else { + if (attribute.name().toString() == caseAdjustedName) + return attributeIndex; + } + + ++attributeIndex; + } while (attributeIndex < attributeCount); - if (doSlowCheck) - return findAttributeIndexByNameSlowCase(name, shouldIgnoreAttributeCase); return attributeNotFound; } -inline const Attribute* ElementData::findAttributeByName(const QualifiedName& name) const +ALWAYS_INLINE const Attribute* ElementData::findAttributeByName(const QualifiedName& name) const { const Attribute* attributes = attributeBase(); for (unsigned i = 0, count = length(); i < count; ++i) { @@ -324,7 +337,12 @@ inline Attribute& UniqueElementData::attributeAt(unsigned index) return m_attributeVector.at(index); } -} +} // namespace WebCore -#endif +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ShareableElementData) + static bool isType(const WebCore::ElementData& elementData) { return !elementData.isUnique(); } +SPECIALIZE_TYPE_TRAITS_END() +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::UniqueElementData) + static bool isType(const WebCore::ElementData& elementData) { return elementData.isUnique(); } +SPECIALIZE_TYPE_TRAITS_END() |