Diff
Modified: trunk/Source/WebCore/CMakeLists.txt (154248 => 154249)
--- trunk/Source/WebCore/CMakeLists.txt 2013-08-18 14:39:43 UTC (rev 154248)
+++ trunk/Source/WebCore/CMakeLists.txt 2013-08-18 16:01:28 UTC (rev 154249)
@@ -1154,6 +1154,7 @@
dom/DocumentStyleSheetCollection.cpp
dom/DocumentType.cpp
dom/Element.cpp
+ dom/ElementData.cpp
dom/ElementRareData.cpp
dom/EntityReference.cpp
dom/ErrorEvent.cpp
Modified: trunk/Source/WebCore/ChangeLog (154248 => 154249)
--- trunk/Source/WebCore/ChangeLog 2013-08-18 14:39:43 UTC (rev 154248)
+++ trunk/Source/WebCore/ChangeLog 2013-08-18 16:01:28 UTC (rev 154249)
@@ -1,3 +1,11 @@
+2013-08-18 Andreas Kling <[email protected]>
+
+ <https://webkit.org/b/119981> Move ElementData & co to their own files.
+
+ Reviewed by Antti Koivisto.
+
+ I like to move it move it.
+
2013-08-18 David Kilzer <[email protected]>
BUILD FIX (r153990): Add UNUSED_PARAM for heightChanged when CSS_SHAPES is disabled
Modified: trunk/Source/WebCore/GNUmakefile.list.am (154248 => 154249)
--- trunk/Source/WebCore/GNUmakefile.list.am 2013-08-18 14:39:43 UTC (rev 154248)
+++ trunk/Source/WebCore/GNUmakefile.list.am 2013-08-18 16:01:28 UTC (rev 154249)
@@ -2868,6 +2868,8 @@
Source/WebCore/dom/DOMTimeStamp.h \
Source/WebCore/dom/Element.cpp \
Source/WebCore/dom/Element.h \
+ Source/WebCore/dom/ElementData.cpp \
+ Source/WebCore/dom/ElementData.h \
Source/WebCore/dom/ElementRareData.cpp \
Source/WebCore/dom/ElementRareData.h \
Source/WebCore/dom/ElementTraversal.h \
Modified: trunk/Source/WebCore/Target.pri (154248 => 154249)
--- trunk/Source/WebCore/Target.pri 2013-08-18 14:39:43 UTC (rev 154248)
+++ trunk/Source/WebCore/Target.pri 2013-08-18 16:01:28 UTC (rev 154249)
@@ -400,6 +400,7 @@
dom/DOMStringMap.cpp \
dom/DatasetDOMStringMap.cpp \
dom/Element.cpp \
+ dom/ElementData.cpp \
dom/ElementRareData.cpp \
dom/EntityReference.cpp \
dom/ErrorEvent.cpp \
@@ -1610,6 +1611,7 @@
dom/DOMTimeStamp.h \
dom/DatasetDOMStringMap.h \
dom/Element.h \
+ dom/ElementData.h \
dom/ElementTravesal.h \
dom/Entity.h \
dom/EntityReference.h \
Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (154248 => 154249)
--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj 2013-08-18 14:39:43 UTC (rev 154248)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj 2013-08-18 16:01:28 UTC (rev 154249)
@@ -12500,6 +12500,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
</ClCompile>
+ <ClCompile Include="..\dom\ElementData.cpp" />
<ClCompile Include="..\dom\ElementRareData.cpp" />
<ClCompile Include="..\dom\EntityReference.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@@ -20244,6 +20245,7 @@
<ClInclude Include="..\dom\DOMStringMap.h" />
<ClInclude Include="..\dom\DOMTimeStamp.h" />
<ClInclude Include="..\dom\Element.h" />
+ <ClInclude Include="..\dom\ElementData.h" />
<ClInclude Include="..\dom\ElementTraversal.h" />
<ClInclude Include="..\dom\Entity.h" />
<ClInclude Include="..\dom\EntityReference.h" />
@@ -21373,4 +21375,4 @@
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (154248 => 154249)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2013-08-18 14:39:43 UTC (rev 154248)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2013-08-18 16:01:28 UTC (rev 154249)
@@ -4524,6 +4524,8 @@
B59DD6AA11902A71007E9684 /* JSSQLStatementErrorCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B59DD6A811902A71007E9684 /* JSSQLStatementErrorCallback.cpp */; };
B5A684220FFABE9800D24689 /* SQLiteFileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = B5A684210FFABE9800D24689 /* SQLiteFileSystem.h */; };
B5A684240FFABEAA00D24689 /* SQLiteFileSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5A684230FFABEAA00D24689 /* SQLiteFileSystem.cpp */; };
+ B5B7A17017C10AA800E4AA0A /* ElementData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5B7A16F17C1080600E4AA0A /* ElementData.cpp */; };
+ B5B7A17117C10AC000E4AA0A /* ElementData.h in Headers */ = {isa = PBXBuildFile; fileRef = B5B7A16E17C1048000E4AA0A /* ElementData.h */; settings = {ATTRIBUTES = (Private, ); }; };
B5D31DFA11CF610B009F22B4 /* ActiveDOMCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5D31DF811CF610B009F22B4 /* ActiveDOMCallback.cpp */; };
B5D31DFB11CF610B009F22B4 /* ActiveDOMCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B5D31DF911CF610B009F22B4 /* ActiveDOMCallback.h */; };
B6566270120B1227006EA85C /* JSIDBTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = B656626E120B1227006EA85C /* JSIDBTransaction.h */; };
@@ -11172,6 +11174,8 @@
B59DD6A811902A71007E9684 /* JSSQLStatementErrorCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSQLStatementErrorCallback.cpp; sourceTree = "<group>"; };
B5A684210FFABE9800D24689 /* SQLiteFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLiteFileSystem.h; path = sql/SQLiteFileSystem.h; sourceTree = "<group>"; };
B5A684230FFABEAA00D24689 /* SQLiteFileSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SQLiteFileSystem.cpp; path = sql/SQLiteFileSystem.cpp; sourceTree = "<group>"; };
+ B5B7A16E17C1048000E4AA0A /* ElementData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ElementData.h; sourceTree = "<group>"; };
+ B5B7A16F17C1080600E4AA0A /* ElementData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ElementData.cpp; sourceTree = "<group>"; };
B5D31DF811CF610B009F22B4 /* ActiveDOMCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ActiveDOMCallback.cpp; path = generic/ActiveDOMCallback.cpp; sourceTree = "<group>"; };
B5D31DF911CF610B009F22B4 /* ActiveDOMCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ActiveDOMCallback.h; path = generic/ActiveDOMCallback.h; sourceTree = "<group>"; };
B656626E120B1227006EA85C /* JSIDBTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSIDBTransaction.h; sourceTree = "<group>"; };
@@ -20222,6 +20226,8 @@
A8C4A7F609D563270003AC8D /* Element.cpp */,
A8C4A7F509D563270003AC8D /* Element.h */,
93EEC1EA09C2877700C515D1 /* Element.idl */,
+ B5B7A16F17C1080600E4AA0A /* ElementData.cpp */,
+ B5B7A16E17C1048000E4AA0A /* ElementData.h */,
4FAB48641643A66D00F70C07 /* ElementRareData.cpp */,
637B7ADE0E8767B800E32194 /* ElementRareData.h */,
E4D58EBA17B8F12800CBDCA8 /* ElementTraversal.h */,
@@ -23472,6 +23478,7 @@
B22279A80D00BF220071B782 /* SVGCursorElement.h in Headers */,
B22279AE0D00BF220071B782 /* SVGDefsElement.h in Headers */,
B22279B10D00BF220071B782 /* SVGDescElement.h in Headers */,
+ B5B7A17117C10AC000E4AA0A /* ElementData.h in Headers */,
B22279B40D00BF220071B782 /* SVGDocument.h in Headers */,
B28C6A280D00C44800334AA4 /* SVGDocumentExtensions.h in Headers */,
B22279B70D00BF220071B782 /* SVGElement.h in Headers */,
@@ -26224,6 +26231,7 @@
A871DED00A1530C700B12A68 /* RenderPart.cpp in Sources */,
A43BF59C1149292800C643CA /* RenderProgress.cpp in Sources */,
5A574F24131DB93900471B88 /* RenderQuote.cpp in Sources */,
+ B5B7A17017C10AA800E4AA0A /* ElementData.cpp in Sources */,
D70AD65713E1342B005B50B4 /* RenderRegion.cpp in Sources */,
BCE93F471517C6D5008CCF74 /* RenderRegionSet.cpp in Sources */,
A871DFE20A15376B00B12A68 /* RenderReplaced.cpp in Sources */,
Modified: trunk/Source/WebCore/dom/Element.cpp (154248 => 154249)
--- trunk/Source/WebCore/dom/Element.cpp 2013-08-18 14:39:43 UTC (rev 154248)
+++ trunk/Source/WebCore/dom/Element.cpp 2013-08-18 16:01:28 UTC (rev 154249)
@@ -3193,218 +3193,4 @@
}
#endif
-void ElementData::deref()
-{
- if (!derefBase())
- return;
-
- if (m_isUnique)
- delete static_cast<UniqueElementData*>(this);
- else
- delete static_cast<ShareableElementData*>(this);
-}
-
-ElementData::ElementData()
- : m_isUnique(true)
- , m_arraySize(0)
- , m_hasNameAttribute(false)
- , m_presentationAttributeStyleIsDirty(false)
- , m_styleAttributeIsDirty(false)
-#if ENABLE(SVG)
- , m_animatedSVGAttributesAreDirty(false)
-#endif
-{
-}
-
-ElementData::ElementData(unsigned arraySize)
- : m_isUnique(false)
- , m_arraySize(arraySize)
- , m_hasNameAttribute(false)
- , m_presentationAttributeStyleIsDirty(false)
- , m_styleAttributeIsDirty(false)
-#if ENABLE(SVG)
- , m_animatedSVGAttributesAreDirty(false)
-#endif
-{
-}
-
-struct SameSizeAsElementData : public RefCounted<SameSizeAsElementData> {
- unsigned bitfield;
- void* refPtrs[3];
-};
-
-COMPILE_ASSERT(sizeof(ElementData) == sizeof(SameSizeAsElementData), element_attribute_data_should_stay_small);
-
-static size_t sizeForShareableElementDataWithAttributeCount(unsigned count)
-{
- return sizeof(ShareableElementData) + sizeof(Attribute) * count;
-}
-
-PassRefPtr<ShareableElementData> ShareableElementData::createWithAttributes(const Vector<Attribute>& attributes)
-{
- void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(attributes.size()));
- return adoptRef(new (NotNull, slot) ShareableElementData(attributes));
-}
-
-PassRefPtr<UniqueElementData> UniqueElementData::create()
-{
- return adoptRef(new UniqueElementData);
-}
-
-ShareableElementData::ShareableElementData(const Vector<Attribute>& attributes)
- : ElementData(attributes.size())
-{
- for (unsigned i = 0; i < m_arraySize; ++i)
- new (NotNull, &m_attributeArray[i]) Attribute(attributes[i]);
-}
-
-ShareableElementData::~ShareableElementData()
-{
- for (unsigned i = 0; i < m_arraySize; ++i)
- m_attributeArray[i].~Attribute();
-}
-
-ShareableElementData::ShareableElementData(const UniqueElementData& other)
- : ElementData(other, false)
-{
- ASSERT(!other.m_presentationAttributeStyle);
-
- if (other.m_inlineStyle) {
- ASSERT(!other.m_inlineStyle->hasCSSOMWrapper());
- m_inlineStyle = other.m_inlineStyle->immutableCopyIfNeeded();
- }
-
- for (unsigned i = 0; i < m_arraySize; ++i)
- new (NotNull, &m_attributeArray[i]) Attribute(other.m_attributeVector.at(i));
-}
-
-ElementData::ElementData(const ElementData& other, bool isUnique)
- : m_isUnique(isUnique)
- , m_arraySize(isUnique ? 0 : other.length())
- , m_hasNameAttribute(other.m_hasNameAttribute)
- , m_presentationAttributeStyleIsDirty(other.m_presentationAttributeStyleIsDirty)
- , m_styleAttributeIsDirty(other.m_styleAttributeIsDirty)
-#if ENABLE(SVG)
- , m_animatedSVGAttributesAreDirty(other.m_animatedSVGAttributesAreDirty)
-#endif
- , m_classNames(other.m_classNames)
- , m_idForStyleResolution(other.m_idForStyleResolution)
-{
- // NOTE: The inline style is copied by the subclass copy constructor since we don't know what to do with it here.
-}
-
-UniqueElementData::UniqueElementData()
-{
-}
-
-UniqueElementData::UniqueElementData(const UniqueElementData& other)
- : ElementData(other, true)
- , m_presentationAttributeStyle(other.m_presentationAttributeStyle)
- , m_attributeVector(other.m_attributeVector)
-{
- m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->mutableCopy() : 0;
-}
-
-UniqueElementData::UniqueElementData(const ShareableElementData& other)
- : ElementData(other, true)
-{
- // An ShareableElementData should never have a mutable inline StylePropertySet attached.
- ASSERT(!other.m_inlineStyle || !other.m_inlineStyle->isMutable());
- m_inlineStyle = other.m_inlineStyle;
-
- m_attributeVector.reserveCapacity(other.length());
- for (unsigned i = 0; i < other.length(); ++i)
- m_attributeVector.uncheckedAppend(other.m_attributeArray[i]);
-}
-
-PassRefPtr<UniqueElementData> ElementData::makeUniqueCopy() const
-{
- if (isUnique())
- return adoptRef(new UniqueElementData(static_cast<const UniqueElementData&>(*this)));
- return adoptRef(new UniqueElementData(static_cast<const ShareableElementData&>(*this)));
-}
-
-PassRefPtr<ShareableElementData> UniqueElementData::makeShareableCopy() const
-{
- void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(m_attributeVector.size()));
- return adoptRef(new (NotNull, slot) ShareableElementData(*this));
-}
-
-void UniqueElementData::addAttribute(const QualifiedName& attributeName, const AtomicString& value)
-{
- m_attributeVector.append(Attribute(attributeName, value));
-}
-
-void UniqueElementData::removeAttribute(unsigned index)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(index < length());
- m_attributeVector.remove(index);
-}
-
-bool ElementData::isEquivalent(const ElementData* other) const
-{
- if (!other)
- return isEmpty();
-
- unsigned len = length();
- if (len != other->length())
- return false;
-
- for (unsigned i = 0; i < len; i++) {
- const Attribute& attribute = attributeAt(i);
- const Attribute* otherAttr = other->findAttributeByName(attribute.name());
- if (!otherAttr || attribute.value() != otherAttr->value())
- return false;
- }
-
- return true;
-}
-
-unsigned ElementData::findAttributeIndexByNameSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const
-{
- // Continue to checking case-insensitively and/or full namespaced names if necessary:
- for (unsigned i = 0; i < length(); ++i) {
- const Attribute& attribute = attributeAt(i);
- if (!attribute.name().hasPrefix()) {
- if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attribute.localName()))
- return i;
- } else {
- // FIXME: Would be faster to do this comparison without calling toString, which
- // generates a temporary string by concatenation. But this branch is only reached
- // if the attribute name has a prefix, which is rare in HTML.
- if (equalPossiblyIgnoringCase(name, attribute.name().toString(), shouldIgnoreAttributeCase))
- return i;
- }
- }
- return attributeNotFound;
-}
-
-unsigned ElementData::findAttributeIndexByNameForAttributeNode(const Attr* attr, bool shouldIgnoreAttributeCase) const
-{
- ASSERT(attr);
- const Attribute* attributes = attributeBase();
- unsigned count = length();
- for (unsigned i = 0; i < count; ++i) {
- if (attributes[i].name().matchesIgnoringCaseForLocalName(attr->qualifiedName(), shouldIgnoreAttributeCase))
- return i;
- }
- return attributeNotFound;
-}
-
-Attribute* UniqueElementData::findAttributeByName(const QualifiedName& name)
-{
- unsigned count = length();
- for (unsigned i = 0; i < count; ++i) {
- if (m_attributeVector.at(i).name().matches(name))
- return &m_attributeVector.at(i);
- }
- return 0;
-}
-
-Attribute& UniqueElementData::attributeAt(unsigned index)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(index < length());
- return m_attributeVector.at(index);
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/Element.h (154248 => 154249)
--- trunk/Source/WebCore/dom/Element.h 2013-08-18 14:39:43 UTC (rev 154248)
+++ trunk/Source/WebCore/dom/Element.h 2013-08-18 16:01:28 UTC (rev 154249)
@@ -25,145 +25,28 @@
#ifndef Element_h
#define Element_h
-#include "Attribute.h"
#include "CollectionType.h"
#include "Document.h"
+#include "ElementData.h"
#include "HTMLNames.h"
#include "RegionOversetState.h"
#include "ScrollTypes.h"
-#include "SpaceSplitString.h"
#include "StyleResolveTree.h"
namespace WebCore {
-class Attr;
class ClientRect;
class ClientRectList;
class DOMStringMap;
class DOMTokenList;
-class Element;
class ElementRareData;
class HTMLDocument;
-class ShareableElementData;
class IntSize;
class Locale;
-class UniqueElementData;
class PseudoElement;
class RenderRegion;
class ShadowRoot;
-class StylePropertySet;
-class ElementData : public RefCounted<ElementData> {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- // Override RefCounted's deref() to ensure operator delete is called on
- // the appropriate subclass type.
- void deref();
-
- 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); }
- const SpaceSplitString& classNames() const { return m_classNames; }
-
- const AtomicString& idForStyleResolution() const { return m_idForStyleResolution; }
- void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyleResolution = newId; }
-
- const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); }
-
- const StylePropertySet* presentationAttributeStyle() const;
-
- unsigned length() const;
- bool isEmpty() const { return !length(); }
-
- const Attribute& attributeAt(unsigned index) const;
- 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;
-
- bool hasID() const { return !m_idForStyleResolution.isNull(); }
- bool hasClass() const { return !m_classNames.isNull(); }
- bool hasName() const { return m_hasNameAttribute; }
-
- bool isEquivalent(const ElementData* other) const;
-
- bool isUnique() const { return m_isUnique; }
-
-protected:
- ElementData();
- ElementData(unsigned arraySize);
- ElementData(const ElementData&, bool isUnique);
-
- unsigned m_isUnique : 1;
- unsigned m_arraySize : 27;
- mutable unsigned m_hasNameAttribute : 1;
- mutable unsigned m_presentationAttributeStyleIsDirty : 1;
- mutable unsigned m_styleAttributeIsDirty : 1;
-#if ENABLE(SVG)
- mutable unsigned m_animatedSVGAttributesAreDirty : 1;
-#endif
-
- mutable RefPtr<StylePropertySet> m_inlineStyle;
- mutable SpaceSplitString m_classNames;
- mutable AtomicString m_idForStyleResolution;
-
-private:
- friend class Element;
- friend class StyledElement;
- friend class ShareableElementData;
- friend class UniqueElementData;
-#if ENABLE(SVG)
- friend class SVGElement;
-#endif
-
- const Attribute* attributeBase() const;
- const Attribute* findAttributeByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
- unsigned findAttributeIndexByNameSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
-
- PassRefPtr<UniqueElementData> makeUniqueCopy() const;
-};
-
-#if COMPILER(MSVC)
-#pragma warning(push)
-#pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
-#endif
-
-class ShareableElementData : public ElementData {
-public:
- static PassRefPtr<ShareableElementData> createWithAttributes(const Vector<Attribute>&);
-
- explicit ShareableElementData(const Vector<Attribute>&);
- explicit ShareableElementData(const UniqueElementData&);
- ~ShareableElementData();
-
- Attribute m_attributeArray[0];
-};
-
-#if COMPILER(MSVC)
-#pragma warning(pop)
-#endif
-
-class UniqueElementData : public ElementData {
-public:
- static PassRefPtr<UniqueElementData> create();
- PassRefPtr<ShareableElementData> makeShareableCopy() const;
-
- // These functions do no error/duplicate checking.
- void addAttribute(const QualifiedName&, const AtomicString&);
- void removeAttribute(unsigned index);
-
- Attribute& attributeAt(unsigned index);
- Attribute* findAttributeByName(const QualifiedName&);
-
- UniqueElementData();
- explicit UniqueElementData(const ShareableElementData&);
- explicit UniqueElementData(const UniqueElementData&);
-
- mutable RefPtr<StylePropertySet> m_presentationAttributeStyle;
- Vector<Attribute, 4> m_attributeVector;
-};
-
enum AffectedSelectorType {
AffectedSelectorChecked = 1,
AffectedSelectorEnabled = 1 << 1,
@@ -947,83 +830,6 @@
return node && node->isElementNode() && toElement(node)->shadowRoot();
}
-inline unsigned ElementData::length() const
-{
- if (isUnique())
- return static_cast<const UniqueElementData*>(this)->m_attributeVector.size();
- return m_arraySize;
-}
-
-inline const Attribute* ElementData::attributeBase() const
-{
- if (m_isUnique)
- return static_cast<const UniqueElementData*>(this)->m_attributeVector.data();
- return static_cast<const ShareableElementData*>(this)->m_attributeArray;
-}
-
-inline const StylePropertySet* ElementData::presentationAttributeStyle() const
-{
- if (!m_isUnique)
- return 0;
- return static_cast<const UniqueElementData*>(this)->m_presentationAttributeStyle.get();
-}
-
-inline const Attribute* ElementData::findAttributeByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const
-{
- unsigned index = findAttributeIndexByName(name, shouldIgnoreAttributeCase);
- if (index != attributeNotFound)
- return &attributeAt(index);
- return 0;
-}
-
-inline unsigned ElementData::findAttributeIndexByName(const QualifiedName& name) const
-{
- const Attribute* attributes = attributeBase();
- for (unsigned i = 0, count = length(); i < count; ++i) {
- if (attributes[i].name().matches(name))
- return i;
- }
- return attributeNotFound;
-}
-
-// 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
-{
- const Attribute* attributes = attributeBase();
- bool doSlowCheck = shouldIgnoreAttributeCase;
- const AtomicString& caseAdjustedName = shouldIgnoreAttributeCase ? name.lower() : name;
-
- // 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;
- }
-
- if (doSlowCheck)
- return findAttributeIndexByNameSlowCase(name, shouldIgnoreAttributeCase);
- return attributeNotFound;
-}
-
-inline const Attribute* ElementData::findAttributeByName(const QualifiedName& name) const
-{
- const Attribute* attributes = attributeBase();
- for (unsigned i = 0, count = length(); i < count; ++i) {
- if (attributes[i].name().matches(name))
- return &attributes[i];
- }
- return 0;
-}
-
-inline const Attribute& ElementData::attributeAt(unsigned index) const
-{
- RELEASE_ASSERT(index < length());
- return attributeBase()[index];
-}
-
} // namespace
#endif
Added: trunk/Source/WebCore/dom/ElementData.cpp (0 => 154249)
--- trunk/Source/WebCore/dom/ElementData.cpp (rev 0)
+++ trunk/Source/WebCore/dom/ElementData.cpp 2013-08-18 16:01:28 UTC (rev 154249)
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ElementData.h"
+
+#include "Attr.h"
+#include "StylePropertySet.h"
+
+namespace WebCore {
+
+void ElementData::deref()
+{
+ if (!derefBase())
+ return;
+
+ if (m_isUnique)
+ delete static_cast<UniqueElementData*>(this);
+ else
+ delete static_cast<ShareableElementData*>(this);
+}
+
+ElementData::ElementData()
+ : m_isUnique(true)
+ , m_arraySize(0)
+ , m_hasNameAttribute(false)
+ , m_presentationAttributeStyleIsDirty(false)
+ , m_styleAttributeIsDirty(false)
+#if ENABLE(SVG)
+ , m_animatedSVGAttributesAreDirty(false)
+#endif
+{
+}
+
+ElementData::ElementData(unsigned arraySize)
+ : m_isUnique(false)
+ , m_arraySize(arraySize)
+ , m_hasNameAttribute(false)
+ , m_presentationAttributeStyleIsDirty(false)
+ , m_styleAttributeIsDirty(false)
+#if ENABLE(SVG)
+ , m_animatedSVGAttributesAreDirty(false)
+#endif
+{
+}
+
+struct SameSizeAsElementData : public RefCounted<SameSizeAsElementData> {
+ unsigned bitfield;
+ void* refPtrs[3];
+};
+
+COMPILE_ASSERT(sizeof(ElementData) == sizeof(SameSizeAsElementData), element_attribute_data_should_stay_small);
+
+static size_t sizeForShareableElementDataWithAttributeCount(unsigned count)
+{
+ return sizeof(ShareableElementData) + sizeof(Attribute) * count;
+}
+
+PassRefPtr<ShareableElementData> ShareableElementData::createWithAttributes(const Vector<Attribute>& attributes)
+{
+ void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(attributes.size()));
+ return adoptRef(new (NotNull, slot) ShareableElementData(attributes));
+}
+
+PassRefPtr<UniqueElementData> UniqueElementData::create()
+{
+ return adoptRef(new UniqueElementData);
+}
+
+ShareableElementData::ShareableElementData(const Vector<Attribute>& attributes)
+ : ElementData(attributes.size())
+{
+ for (unsigned i = 0; i < m_arraySize; ++i)
+ new (NotNull, &m_attributeArray[i]) Attribute(attributes[i]);
+}
+
+ShareableElementData::~ShareableElementData()
+{
+ for (unsigned i = 0; i < m_arraySize; ++i)
+ m_attributeArray[i].~Attribute();
+}
+
+ShareableElementData::ShareableElementData(const UniqueElementData& other)
+ : ElementData(other, false)
+{
+ ASSERT(!other.m_presentationAttributeStyle);
+
+ if (other.m_inlineStyle) {
+ ASSERT(!other.m_inlineStyle->hasCSSOMWrapper());
+ m_inlineStyle = other.m_inlineStyle->immutableCopyIfNeeded();
+ }
+
+ for (unsigned i = 0; i < m_arraySize; ++i)
+ new (NotNull, &m_attributeArray[i]) Attribute(other.m_attributeVector.at(i));
+}
+
+ElementData::ElementData(const ElementData& other, bool isUnique)
+ : m_isUnique(isUnique)
+ , m_arraySize(isUnique ? 0 : other.length())
+ , m_hasNameAttribute(other.m_hasNameAttribute)
+ , m_presentationAttributeStyleIsDirty(other.m_presentationAttributeStyleIsDirty)
+ , m_styleAttributeIsDirty(other.m_styleAttributeIsDirty)
+#if ENABLE(SVG)
+ , m_animatedSVGAttributesAreDirty(other.m_animatedSVGAttributesAreDirty)
+#endif
+ , m_classNames(other.m_classNames)
+ , m_idForStyleResolution(other.m_idForStyleResolution)
+{
+ // NOTE: The inline style is copied by the subclass copy constructor since we don't know what to do with it here.
+}
+
+UniqueElementData::UniqueElementData()
+{
+}
+
+UniqueElementData::UniqueElementData(const UniqueElementData& other)
+ : ElementData(other, true)
+ , m_presentationAttributeStyle(other.m_presentationAttributeStyle)
+ , m_attributeVector(other.m_attributeVector)
+{
+ m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->mutableCopy() : 0;
+}
+
+UniqueElementData::UniqueElementData(const ShareableElementData& other)
+ : ElementData(other, true)
+{
+ // An ShareableElementData should never have a mutable inline StylePropertySet attached.
+ ASSERT(!other.m_inlineStyle || !other.m_inlineStyle->isMutable());
+ m_inlineStyle = other.m_inlineStyle;
+
+ m_attributeVector.reserveCapacity(other.length());
+ for (unsigned i = 0; i < other.length(); ++i)
+ m_attributeVector.uncheckedAppend(other.m_attributeArray[i]);
+}
+
+PassRefPtr<UniqueElementData> ElementData::makeUniqueCopy() const
+{
+ if (isUnique())
+ return adoptRef(new UniqueElementData(static_cast<const UniqueElementData&>(*this)));
+ return adoptRef(new UniqueElementData(static_cast<const ShareableElementData&>(*this)));
+}
+
+PassRefPtr<ShareableElementData> UniqueElementData::makeShareableCopy() const
+{
+ void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(m_attributeVector.size()));
+ return adoptRef(new (NotNull, slot) ShareableElementData(*this));
+}
+
+void UniqueElementData::addAttribute(const QualifiedName& attributeName, const AtomicString& value)
+{
+ m_attributeVector.append(Attribute(attributeName, value));
+}
+
+void UniqueElementData::removeAttribute(unsigned index)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(index < length());
+ m_attributeVector.remove(index);
+}
+
+bool ElementData::isEquivalent(const ElementData* other) const
+{
+ if (!other)
+ return isEmpty();
+
+ unsigned len = length();
+ if (len != other->length())
+ return false;
+
+ for (unsigned i = 0; i < len; i++) {
+ const Attribute& attribute = attributeAt(i);
+ const Attribute* otherAttr = other->findAttributeByName(attribute.name());
+ if (!otherAttr || attribute.value() != otherAttr->value())
+ return false;
+ }
+
+ return true;
+}
+
+unsigned ElementData::findAttributeIndexByNameSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const
+{
+ // Continue to checking case-insensitively and/or full namespaced names if necessary:
+ for (unsigned i = 0; i < length(); ++i) {
+ const Attribute& attribute = attributeAt(i);
+ if (!attribute.name().hasPrefix()) {
+ if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attribute.localName()))
+ return i;
+ } else {
+ // FIXME: Would be faster to do this comparison without calling toString, which
+ // generates a temporary string by concatenation. But this branch is only reached
+ // if the attribute name has a prefix, which is rare in HTML.
+ if (equalPossiblyIgnoringCase(name, attribute.name().toString(), shouldIgnoreAttributeCase))
+ return i;
+ }
+ }
+ return attributeNotFound;
+}
+
+unsigned ElementData::findAttributeIndexByNameForAttributeNode(const Attr* attr, bool shouldIgnoreAttributeCase) const
+{
+ ASSERT(attr);
+ const Attribute* attributes = attributeBase();
+ unsigned count = length();
+ for (unsigned i = 0; i < count; ++i) {
+ if (attributes[i].name().matchesIgnoringCaseForLocalName(attr->qualifiedName(), shouldIgnoreAttributeCase))
+ return i;
+ }
+ return attributeNotFound;
+}
+
+Attribute* UniqueElementData::findAttributeByName(const QualifiedName& name)
+{
+ unsigned count = length();
+ for (unsigned i = 0; i < count; ++i) {
+ if (m_attributeVector.at(i).name().matches(name))
+ return &m_attributeVector.at(i);
+ }
+ return 0;
+}
+
+Attribute& UniqueElementData::attributeAt(unsigned index)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(index < length());
+ return m_attributeVector.at(index);
+}
+
+}
+
Added: trunk/Source/WebCore/dom/ElementData.h (0 => 154249)
--- trunk/Source/WebCore/dom/ElementData.h (rev 0)
+++ trunk/Source/WebCore/dom/ElementData.h 2013-08-18 16:01:28 UTC (rev 154249)
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ElementData_h
+#define ElementData_h
+
+#include "Attribute.h"
+#include "SpaceSplitString.h"
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class Attr;
+class ShareableElementData;
+class StylePropertySet;
+class UniqueElementData;
+
+class ElementData : public RefCounted<ElementData> {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ // Override RefCounted's deref() to ensure operator delete is called on
+ // the appropriate subclass type.
+ void deref();
+
+ 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); }
+ const SpaceSplitString& classNames() const { return m_classNames; }
+
+ const AtomicString& idForStyleResolution() const { return m_idForStyleResolution; }
+ void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyleResolution = newId; }
+
+ const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); }
+ const StylePropertySet* presentationAttributeStyle() const;
+
+ unsigned length() const;
+ bool isEmpty() const { return !length(); }
+
+ const Attribute& attributeAt(unsigned index) const;
+ 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;
+
+ bool hasID() const { return !m_idForStyleResolution.isNull(); }
+ bool hasClass() const { return !m_classNames.isNull(); }
+ bool hasName() const { return m_hasNameAttribute; }
+
+ bool isEquivalent(const ElementData* other) const;
+
+ bool isUnique() const { return m_isUnique; }
+
+protected:
+ ElementData();
+ ElementData(unsigned arraySize);
+ ElementData(const ElementData&, bool isUnique);
+
+ unsigned m_isUnique : 1;
+ unsigned m_arraySize : 27;
+ mutable unsigned m_hasNameAttribute : 1;
+ mutable unsigned m_presentationAttributeStyleIsDirty : 1;
+ mutable unsigned m_styleAttributeIsDirty : 1;
+#if ENABLE(SVG)
+ mutable unsigned m_animatedSVGAttributesAreDirty : 1;
+#endif
+
+ mutable RefPtr<StylePropertySet> m_inlineStyle;
+ mutable SpaceSplitString m_classNames;
+ mutable AtomicString m_idForStyleResolution;
+
+private:
+ friend class Element;
+ friend class StyledElement;
+ friend class ShareableElementData;
+ friend class UniqueElementData;
+#if ENABLE(SVG)
+ friend class SVGElement;
+#endif
+
+ const Attribute* attributeBase() const;
+ const Attribute* findAttributeByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+ unsigned findAttributeIndexByNameSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+
+ PassRefPtr<UniqueElementData> makeUniqueCopy() const;
+};
+
+#if COMPILER(MSVC)
+#pragma warning(push)
+#pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
+#endif
+
+class ShareableElementData : public ElementData {
+public:
+ static PassRefPtr<ShareableElementData> createWithAttributes(const Vector<Attribute>&);
+
+ explicit ShareableElementData(const Vector<Attribute>&);
+ explicit ShareableElementData(const UniqueElementData&);
+ ~ShareableElementData();
+
+ Attribute m_attributeArray[0];
+};
+
+#if COMPILER(MSVC)
+#pragma warning(pop)
+#endif
+
+class UniqueElementData : public ElementData {
+public:
+ static PassRefPtr<UniqueElementData> create();
+ PassRefPtr<ShareableElementData> makeShareableCopy() const;
+
+ // These functions do no error/duplicate checking.
+ void addAttribute(const QualifiedName&, const AtomicString&);
+ void removeAttribute(unsigned index);
+
+ Attribute& attributeAt(unsigned index);
+ Attribute* findAttributeByName(const QualifiedName&);
+
+ UniqueElementData();
+ explicit UniqueElementData(const ShareableElementData&);
+ explicit UniqueElementData(const UniqueElementData&);
+
+ mutable RefPtr<StylePropertySet> m_presentationAttributeStyle;
+ Vector<Attribute, 4> m_attributeVector;
+};
+
+inline unsigned ElementData::length() const
+{
+ if (isUnique())
+ return static_cast<const UniqueElementData*>(this)->m_attributeVector.size();
+ return m_arraySize;
+}
+
+inline const Attribute* ElementData::attributeBase() const
+{
+ if (m_isUnique)
+ return static_cast<const UniqueElementData*>(this)->m_attributeVector.data();
+ return static_cast<const ShareableElementData*>(this)->m_attributeArray;
+}
+
+inline const StylePropertySet* ElementData::presentationAttributeStyle() const
+{
+ if (!m_isUnique)
+ return 0;
+ return static_cast<const UniqueElementData*>(this)->m_presentationAttributeStyle.get();
+}
+
+inline const Attribute* ElementData::findAttributeByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const
+{
+ unsigned index = findAttributeIndexByName(name, shouldIgnoreAttributeCase);
+ if (index != attributeNotFound)
+ return &attributeAt(index);
+ return 0;
+}
+
+inline unsigned ElementData::findAttributeIndexByName(const QualifiedName& name) const
+{
+ const Attribute* attributes = attributeBase();
+ for (unsigned i = 0, count = length(); i < count; ++i) {
+ if (attributes[i].name().matches(name))
+ return i;
+ }
+ return attributeNotFound;
+}
+
+// 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
+{
+ const Attribute* attributes = attributeBase();
+ bool doSlowCheck = shouldIgnoreAttributeCase;
+ const AtomicString& caseAdjustedName = shouldIgnoreAttributeCase ? name.lower() : name;
+
+ // 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;
+ }
+
+ if (doSlowCheck)
+ return findAttributeIndexByNameSlowCase(name, shouldIgnoreAttributeCase);
+ return attributeNotFound;
+}
+
+inline const Attribute* ElementData::findAttributeByName(const QualifiedName& name) const
+{
+ const Attribute* attributes = attributeBase();
+ for (unsigned i = 0, count = length(); i < count; ++i) {
+ if (attributes[i].name().matches(name))
+ return &attributes[i];
+ }
+ return 0;
+}
+
+inline const Attribute& ElementData::attributeAt(unsigned index) const
+{
+ RELEASE_ASSERT(index < length());
+ return attributeBase()[index];
+}
+
+}
+
+#endif
+