summaryrefslogtreecommitdiff
path: root/Source/WebCore/dom/ElementData.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/dom/ElementData.h')
-rw-r--r--Source/WebCore/dom/ElementData.h114
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()