dom/DocumentStyleSheetCollection.cpp
dom/DocumentType.cpp
dom/Element.cpp
- dom/ElementAttributeData.cpp
dom/ElementRareData.cpp
dom/ElementShadow.cpp
dom/EntityReference.cpp
+2013-02-12 Andreas Kling <akling@apple.com>
+
+ Move ElementAttributeData into Element.cpp/h
+ <http://webkit.org/b/109610>
+
+ Reviewed by Anders Carlsson.
+
+ Removed ElementAttributeData.cpp/h and moved the class itself into Element headquarters.
+ In the near future, Element should be the only client of this class, and thus it won't
+ be necessary for other classes to know anything about it.
+
+ * dom/ElementAttributeData.cpp: Removed.
+ * dom/ElementAttributeData.h: Removed.
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * Target.pri:
+ * WebCore.gypi:
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/DOMAllInOne.cpp:
+ * dom/DocumentSharedObjectPool.cpp:
+ * dom/Element.cpp:
+ * dom/Element.h:
+ * workers/SharedWorker.cpp:
+ * Modules/webdatabase/DatabaseManager.cpp: Add ExceptionCode.h since Element.h doesn't pull it in anymore.
+
2013-02-12 Simon Fraser <simon.fraser@apple.com>
Crash when scrolling soon after page starts loading
Source/WebCore/dom/DOMTimeStamp.h \
Source/WebCore/dom/Element.cpp \
Source/WebCore/dom/Element.h \
- Source/WebCore/dom/ElementAttributeData.cpp \
- Source/WebCore/dom/ElementAttributeData.h \
Source/WebCore/dom/ElementRareData.cpp \
Source/WebCore/dom/ElementRareData.h \
Source/WebCore/dom/ElementShadow.cpp \
#include "DatabaseContext.h"
#include "DatabaseSync.h"
#include "DatabaseTask.h"
+#include "ExceptionCode.h"
#include "InspectorDatabaseInstrumentation.h"
#include "Logging.h"
#include "ScriptController.h"
dom/DOMStringMap.cpp \
dom/DatasetDOMStringMap.cpp \
dom/Element.cpp \
- dom/ElementAttributeData.cpp \
dom/ElementRareData.cpp \
dom/ElementShadow.cpp \
dom/EntityReference.cpp \
dom/DatasetDOMStringMap.h \
dom/Element.h \
dom/ElementShadow.h \
- dom/ElementAttributeData.h \
dom/Entity.h \
dom/EntityReference.h \
dom/Event.h \
'dom/DocumentType.cpp',
'dom/ElementShadow.cpp',
'dom/Element.cpp',
- 'dom/ElementAttributeData.cpp',
'dom/ElementRareData.cpp',
'dom/ElementRareData.h',
'dom/Entity.h',
2B365C841525119E0091D27B /* RenderSVGEllipse.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B4235A015250F6000DBBCD8 /* RenderSVGEllipse.h */; };
2BE8E2C712A589EC00FAD550 /* HTMLMetaCharsetParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BE8E2C612A589EC00FAD550 /* HTMLMetaCharsetParser.h */; };
2BE8E2C912A58A0100FAD550 /* HTMLMetaCharsetParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BE8E2C812A58A0100FAD550 /* HTMLMetaCharsetParser.cpp */; };
- 2CF6878814D32EB500340F39 /* ElementAttributeData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2CF6878714D32EB500340F39 /* ElementAttributeData.cpp */; };
- 2CF6878A14D32EFF00340F39 /* ElementAttributeData.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CF6878914D32EFF00340F39 /* ElementAttributeData.h */; settings = {ATTRIBUTES = (Private, ); }; };
2D3A0E3613A7D76100E85AF0 /* SVGParsingError.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D3A0E3513A7D76100E85AF0 /* SVGParsingError.h */; settings = {ATTRIBUTES = (Private, ); }; };
2D481F00146B5C4C00AA7834 /* CrossfadeGeneratedImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D2FC0541460CD6F00263633 /* CrossfadeGeneratedImage.cpp */; };
2D481F02146B5C5500AA7834 /* CrossfadeGeneratedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D2FC0551460CD6F00263633 /* CrossfadeGeneratedImage.h */; };
2B4235A015250F6000DBBCD8 /* RenderSVGEllipse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGEllipse.h; sourceTree = "<group>"; };
2BE8E2C612A589EC00FAD550 /* HTMLMetaCharsetParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTMLMetaCharsetParser.h; path = parser/HTMLMetaCharsetParser.h; sourceTree = "<group>"; };
2BE8E2C812A58A0100FAD550 /* HTMLMetaCharsetParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HTMLMetaCharsetParser.cpp; path = parser/HTMLMetaCharsetParser.cpp; sourceTree = "<group>"; };
- 2CF6878714D32EB500340F39 /* ElementAttributeData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ElementAttributeData.cpp; sourceTree = "<group>"; };
- 2CF6878914D32EFF00340F39 /* ElementAttributeData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementAttributeData.h; sourceTree = "<group>"; };
2D2FC0541460CD6F00263633 /* CrossfadeGeneratedImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CrossfadeGeneratedImage.cpp; sourceTree = "<group>"; };
2D2FC0551460CD6F00263633 /* CrossfadeGeneratedImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossfadeGeneratedImage.h; sourceTree = "<group>"; };
2D2FC0561460CD6F00263633 /* GeneratorGeneratedImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GeneratorGeneratedImage.cpp; sourceTree = "<group>"; };
A8C4A7F609D563270003AC8D /* Element.cpp */,
A8C4A7F509D563270003AC8D /* Element.h */,
93EEC1EA09C2877700C515D1 /* Element.idl */,
- 2CF6878714D32EB500340F39 /* ElementAttributeData.cpp */,
- 2CF6878914D32EFF00340F39 /* ElementAttributeData.h */,
4FAB48641643A66D00F70C07 /* ElementRareData.cpp */,
637B7ADE0E8767B800E32194 /* ElementRareData.h */,
57CF4C8414F7597A00ECFF14 /* ElementShadow.cpp */,
4BAE95B10B2FA9CE00AED8A0 /* EditorDeleteAction.h in Headers */,
93FDAFCA0B11307400E2746F /* EditorInsertAction.h in Headers */,
A8C4A80709D563270003AC8D /* Element.h in Headers */,
- 2CF6878A14D32EFF00340F39 /* ElementAttributeData.h in Headers */,
63F5D4F70E8C4B7100C0BD04 /* ElementRareData.h in Headers */,
57CF4C8714F7597A00ECFF14 /* ElementShadow.h in Headers */,
E415F1840D9A1A830033CE97 /* ElementTimeControl.h in Headers */,
93A38B4B0D0E5808006872C2 /* EditorCommand.cpp in Sources */,
ED501DC60B249F2900AE18D9 /* EditorMac.mm in Sources */,
A8C4A80809D563270003AC8D /* Element.cpp in Sources */,
- 2CF6878814D32EB500340F39 /* ElementAttributeData.cpp in Sources */,
4FFC022D1643B726004E1638 /* ElementRareData.cpp in Sources */,
57CF4C8614F7597A00ECFF14 /* ElementShadow.cpp in Sources */,
A8CFF6CB0A1561CD000A4234 /* EllipsisBox.cpp in Sources */,
#include "DocumentSharedObjectPool.cpp"
#include "DocumentType.cpp"
#include "Element.cpp"
-#include "ElementAttributeData.cpp"
#include "ElementShadow.cpp"
#include "EntityReference.cpp"
#include "ErrorEvent.cpp"
#include "config.h"
#include "DocumentSharedObjectPool.h"
-#include "Attribute.h"
-#include "ElementAttributeData.h"
+#include "Element.h"
namespace WebCore {
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* (C) 2007 David Smith (catfish.man@gmail.com)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
* (C) 2007 Eric Seidel (eric@webkit.org)
*
* This library is free software; you can redistribute it and/or
#include "XMLNames.h"
#include "htmlediting.h"
#include <wtf/BitVector.h>
+#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/text/CString.h>
#if ENABLE(SVG)
}
#endif
+void ElementAttributeData::deref()
+{
+ if (!derefBase())
+ return;
+
+ if (m_isMutable)
+ delete static_cast<MutableElementAttributeData*>(this);
+ else
+ delete static_cast<ImmutableElementAttributeData*>(this);
+}
+
+ElementAttributeData::ElementAttributeData()
+ : m_isMutable(true)
+ , m_arraySize(0)
+ , m_presentationAttributeStyleIsDirty(false)
+ , m_styleAttributeIsDirty(false)
+#if ENABLE(SVG)
+ , m_animatedSVGAttributesAreDirty(false)
+#endif
+{
+}
+
+ElementAttributeData::ElementAttributeData(unsigned arraySize)
+ : m_isMutable(false)
+ , m_arraySize(arraySize)
+ , m_presentationAttributeStyleIsDirty(false)
+ , m_styleAttributeIsDirty(false)
+#if ENABLE(SVG)
+ , m_animatedSVGAttributesAreDirty(false)
+#endif
+{
+}
+
+struct SameSizeAsElementAttributeData : public RefCounted<SameSizeAsElementAttributeData> {
+ unsigned bitfield;
+ void* refPtrs[3];
+};
+
+COMPILE_ASSERT(sizeof(ElementAttributeData) == sizeof(SameSizeAsElementAttributeData), element_attribute_data_should_stay_small);
+
+static size_t sizeForImmutableElementAttributeDataWithAttributeCount(unsigned count)
+{
+ return sizeof(ImmutableElementAttributeData) - sizeof(void*) + sizeof(Attribute) * count;
+}
+
+PassRefPtr<ElementAttributeData> ElementAttributeData::createImmutable(const Vector<Attribute>& attributes)
+{
+ void* slot = WTF::fastMalloc(sizeForImmutableElementAttributeDataWithAttributeCount(attributes.size()));
+ return adoptRef(new (slot) ImmutableElementAttributeData(attributes));
+}
+
+PassRefPtr<ElementAttributeData> ElementAttributeData::create()
+{
+ return adoptRef(new MutableElementAttributeData);
+}
+
+ImmutableElementAttributeData::ImmutableElementAttributeData(const Vector<Attribute>& attributes)
+ : ElementAttributeData(attributes.size())
+{
+ for (unsigned i = 0; i < m_arraySize; ++i)
+ new (&reinterpret_cast<Attribute*>(&m_attributeArray)[i]) Attribute(attributes[i]);
+}
+
+ImmutableElementAttributeData::~ImmutableElementAttributeData()
+{
+ for (unsigned i = 0; i < m_arraySize; ++i)
+ (reinterpret_cast<Attribute*>(&m_attributeArray)[i]).~Attribute();
+}
+
+ImmutableElementAttributeData::ImmutableElementAttributeData(const MutableElementAttributeData& other)
+ : ElementAttributeData(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 (&reinterpret_cast<Attribute*>(&m_attributeArray)[i]) Attribute(*other.attributeItem(i));
+}
+
+ElementAttributeData::ElementAttributeData(const ElementAttributeData& other, bool isMutable)
+ : m_isMutable(isMutable)
+ , m_arraySize(isMutable ? 0 : other.length())
+ , 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.
+}
+
+MutableElementAttributeData::MutableElementAttributeData()
+{
+}
+
+MutableElementAttributeData::MutableElementAttributeData(const MutableElementAttributeData& other)
+ : ElementAttributeData(other, true)
+ , m_presentationAttributeStyle(other.m_presentationAttributeStyle)
+ , m_attributeVector(other.m_attributeVector)
+{
+ m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->copy() : 0;
+}
+
+MutableElementAttributeData::MutableElementAttributeData(const ImmutableElementAttributeData& other)
+ : ElementAttributeData(other, true)
+{
+ // An ImmutableElementAttributeData 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.immutableAttributeArray()[i]);
+}
+
+PassRefPtr<ElementAttributeData> ElementAttributeData::makeMutableCopy() const
+{
+ if (isMutable())
+ return adoptRef(new MutableElementAttributeData(static_cast<const MutableElementAttributeData&>(*this)));
+ return adoptRef(new MutableElementAttributeData(static_cast<const ImmutableElementAttributeData&>(*this)));
+}
+
+PassRefPtr<ElementAttributeData> ElementAttributeData::makeImmutableCopy() const
+{
+ ASSERT(isMutable());
+ void* slot = WTF::fastMalloc(sizeForImmutableElementAttributeDataWithAttributeCount(mutableAttributeVector().size()));
+ return adoptRef(new (slot) ImmutableElementAttributeData(static_cast<const MutableElementAttributeData&>(*this)));
+}
+
+void ElementAttributeData::setPresentationAttributeStyle(PassRefPtr<StylePropertySet> style) const
+{
+ ASSERT(m_isMutable);
+ static_cast<const MutableElementAttributeData*>(this)->m_presentationAttributeStyle = style;
+}
+
+void ElementAttributeData::addAttribute(const Attribute& attribute)
+{
+ ASSERT(isMutable());
+ mutableAttributeVector().append(attribute);
+}
+
+void ElementAttributeData::removeAttribute(size_t index)
+{
+ ASSERT(isMutable());
+ ASSERT_WITH_SECURITY_IMPLICATION(index < length());
+ mutableAttributeVector().remove(index);
+}
+
+bool ElementAttributeData::isEquivalent(const ElementAttributeData* 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 = attributeItem(i);
+ const Attribute* otherAttr = other->getAttributeItem(attribute->name());
+ if (!otherAttr || attribute->value() != otherAttr->value())
+ return false;
+ }
+
+ return true;
+}
+
+void ElementAttributeData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+{
+ size_t actualSize = m_isMutable ? sizeof(ElementAttributeData) : sizeForImmutableElementAttributeDataWithAttributeCount(m_arraySize);
+ MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM, actualSize);
+ info.addMember(m_inlineStyle, "inlineStyle");
+ info.addMember(m_classNames, "classNames");
+ info.addMember(m_idForStyleResolution, "idForStyleResolution");
+ if (m_isMutable) {
+ info.addMember(presentationAttributeStyle(), "presentationAttributeStyle()");
+ info.addMember(mutableAttributeVector(), "mutableAttributeVector");
+ }
+ for (unsigned i = 0, len = length(); i < len; i++)
+ info.addMember(*attributeItem(i), "*attributeItem");
+}
+
+size_t ElementAttributeData::getAttributeItemIndexSlowCase(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 = attributeItem(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 notFound;
+}
+
} // namespace WebCore
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
#ifndef Element_h
#define Element_h
+#include "Attribute.h"
#include "CollectionType.h"
#include "Document.h"
-#include "ElementAttributeData.h"
#include "FragmentScriptingPermission.h"
#include "HTMLNames.h"
#include "ScrollTypes.h"
+#include "SpaceSplitString.h"
namespace WebCore {
class Attr;
-class Attribute;
class ClientRect;
class ClientRectList;
class DOMStringMap;
class DOMTokenList;
+class Element;
class ElementRareData;
class ElementShadow;
+class ImmutableElementAttributeData;
class IntSize;
class Locale;
+class MutableElementAttributeData;
class PseudoElement;
class RenderRegion;
class ShadowRoot;
+class StylePropertySet;
+
+class ElementAttributeData : public RefCounted<ElementAttributeData> {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ static PassRefPtr<ElementAttributeData> create();
+ static PassRefPtr<ElementAttributeData> createImmutable(const Vector<Attribute>&);
+
+ // Override RefCounted's deref() to ensure operator delete is called on
+ // the appropriate subclass type.
+ void deref();
+
+ 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;
+ void setPresentationAttributeStyle(PassRefPtr<StylePropertySet>) const;
+
+ size_t length() const;
+ bool isEmpty() const { return !length(); }
+
+ const Attribute* attributeItem(unsigned index) const;
+ const Attribute* getAttributeItem(const QualifiedName&) const;
+ Attribute* attributeItem(unsigned index);
+ Attribute* getAttributeItem(const QualifiedName&);
+ size_t getAttributeItemIndex(const QualifiedName&) const;
+ size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+
+ // These functions do no error checking.
+ void addAttribute(const Attribute&);
+ void removeAttribute(size_t index);
+
+ bool hasID() const { return !m_idForStyleResolution.isNull(); }
+ bool hasClass() const { return !m_classNames.isNull(); }
+
+ bool isEquivalent(const ElementAttributeData* other) const;
+
+ void reportMemoryUsage(MemoryObjectInfo*) const;
+
+ bool isMutable() const { return m_isMutable; }
+ const Attribute* immutableAttributeArray() const;
+
+protected:
+ ElementAttributeData();
+ ElementAttributeData(unsigned arraySize);
+ ElementAttributeData(const ElementAttributeData&, bool isMutable);
+
+ unsigned m_isMutable : 1;
+ unsigned m_arraySize : 28;
+ 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 ImmutableElementAttributeData;
+ friend class MutableElementAttributeData;
+#if ENABLE(SVG)
+ friend class SVGElement;
+#endif
+
+ Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase);
+ const Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+ size_t getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+
+ PassRefPtr<ElementAttributeData> makeMutableCopy() const;
+ PassRefPtr<ElementAttributeData> makeImmutableCopy() const;
+
+ Vector<Attribute, 4>& mutableAttributeVector();
+ const Vector<Attribute, 4>& mutableAttributeVector() const;
+};
+
+class ImmutableElementAttributeData : public ElementAttributeData {
+public:
+ ImmutableElementAttributeData(const Vector<Attribute>&);
+ ImmutableElementAttributeData(const MutableElementAttributeData&);
+ ~ImmutableElementAttributeData();
+
+ void* m_attributeArray;
+};
+
+class MutableElementAttributeData : public ElementAttributeData {
+public:
+ MutableElementAttributeData();
+ MutableElementAttributeData(const ImmutableElementAttributeData&);
+ MutableElementAttributeData(const MutableElementAttributeData&);
+
+ mutable RefPtr<StylePropertySet> m_presentationAttributeStyle;
+ Vector<Attribute, 4> m_attributeVector;
+};
enum AffectedSelectorType {
AffectedSelectorChecked = 1,
{
return node && node->isElementNode() && toElement(node)->shadow();
}
+inline Vector<Attribute, 4>& ElementAttributeData::mutableAttributeVector()
+{
+ ASSERT(m_isMutable);
+ return static_cast<MutableElementAttributeData*>(this)->m_attributeVector;
+}
+
+inline const Vector<Attribute, 4>& ElementAttributeData::mutableAttributeVector() const
+{
+ ASSERT(m_isMutable);
+ return static_cast<const MutableElementAttributeData*>(this)->m_attributeVector;
+}
+
+inline const Attribute* ElementAttributeData::immutableAttributeArray() const
+{
+ ASSERT(!m_isMutable);
+ return reinterpret_cast<const Attribute*>(&static_cast<const ImmutableElementAttributeData*>(this)->m_attributeArray);
+}
+
+inline size_t ElementAttributeData::length() const
+{
+ if (isMutable())
+ return mutableAttributeVector().size();
+ return m_arraySize;
+}
+
+inline const StylePropertySet* ElementAttributeData::presentationAttributeStyle() const
+{
+ if (!m_isMutable)
+ return 0;
+ return static_cast<const MutableElementAttributeData*>(this)->m_presentationAttributeStyle.get();
+}
+
+inline Attribute* ElementAttributeData::getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase)
+{
+ size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);
+ if (index != notFound)
+ return attributeItem(index);
+ return 0;
+}
+
+inline const Attribute* ElementAttributeData::getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const
+{
+ size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);
+ if (index != notFound)
+ return attributeItem(index);
+ return 0;
+}
+
+inline size_t ElementAttributeData::getAttributeItemIndex(const QualifiedName& name) const
+{
+ for (unsigned i = 0; i < length(); ++i) {
+ if (attributeItem(i)->name().matches(name))
+ return i;
+ }
+ return notFound;
+}
+
+// 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 size_t ElementAttributeData::getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const
+{
+ unsigned len = length();
+ bool doSlowCheck = shouldIgnoreAttributeCase;
+
+ // Optimize for the case where the attribute exists and its name exactly matches.
+ for (unsigned i = 0; i < len; ++i) {
+ const Attribute* attribute = attributeItem(i);
+ if (!attribute->name().hasPrefix()) {
+ if (name == attribute->localName())
+ return i;
+ } else
+ doSlowCheck = true;
+ }
+
+ if (doSlowCheck)
+ return getAttributeItemIndexSlowCase(name, shouldIgnoreAttributeCase);
+ return notFound;
+}
+
+inline const Attribute* ElementAttributeData::getAttributeItem(const QualifiedName& name) const
+{
+ for (unsigned i = 0; i < length(); ++i) {
+ if (attributeItem(i)->name().matches(name))
+ return attributeItem(i);
+ }
+ return 0;
+}
+
+inline Attribute* ElementAttributeData::getAttributeItem(const QualifiedName& name)
+{
+ for (unsigned i = 0; i < length(); ++i) {
+ if (attributeItem(i)->name().matches(name))
+ return attributeItem(i);
+ }
+ return 0;
+}
+
+inline const Attribute* ElementAttributeData::attributeItem(unsigned index) const
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(index < length());
+ if (m_isMutable)
+ return &mutableAttributeVector().at(index);
+ return &immutableAttributeArray()[index];
+}
+
+inline Attribute* ElementAttributeData::attributeItem(unsigned index)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(index < length());
+ return &mutableAttributeVector().at(index);
+}
} // namespace
+++ /dev/null
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Peter Kelly (pmk@post.com)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2010, 2012 Apple Inc. All rights reserved.
- * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "ElementAttributeData.h"
-
-#include "WebCoreMemoryInstrumentation.h"
-#include <wtf/MemoryInstrumentationVector.h>
-
-namespace WebCore {
-
-struct SameSizeAsElementAttributeData : public RefCounted<SameSizeAsElementAttributeData> {
- unsigned bitfield;
- void* refPtrs[3];
-};
-
-COMPILE_ASSERT(sizeof(ElementAttributeData) == sizeof(SameSizeAsElementAttributeData), element_attribute_data_should_stay_small);
-
-static size_t sizeForImmutableElementAttributeDataWithAttributeCount(unsigned count)
-{
- return sizeof(ImmutableElementAttributeData) - sizeof(void*) + sizeof(Attribute) * count;
-}
-
-PassRefPtr<ElementAttributeData> ElementAttributeData::createImmutable(const Vector<Attribute>& attributes)
-{
- void* slot = WTF::fastMalloc(sizeForImmutableElementAttributeDataWithAttributeCount(attributes.size()));
- return adoptRef(new (slot) ImmutableElementAttributeData(attributes));
-}
-
-PassRefPtr<ElementAttributeData> ElementAttributeData::create()
-{
- return adoptRef(new MutableElementAttributeData);
-}
-
-ImmutableElementAttributeData::ImmutableElementAttributeData(const Vector<Attribute>& attributes)
- : ElementAttributeData(attributes.size())
-{
- for (unsigned i = 0; i < m_arraySize; ++i)
- new (&reinterpret_cast<Attribute*>(&m_attributeArray)[i]) Attribute(attributes[i]);
-}
-
-ImmutableElementAttributeData::~ImmutableElementAttributeData()
-{
- for (unsigned i = 0; i < m_arraySize; ++i)
- (reinterpret_cast<Attribute*>(&m_attributeArray)[i]).~Attribute();
-}
-
-ImmutableElementAttributeData::ImmutableElementAttributeData(const MutableElementAttributeData& other)
- : ElementAttributeData(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 (&reinterpret_cast<Attribute*>(&m_attributeArray)[i]) Attribute(*other.attributeItem(i));
-}
-
-ElementAttributeData::ElementAttributeData(const ElementAttributeData& other, bool isMutable)
- : m_isMutable(isMutable)
- , m_arraySize(isMutable ? 0 : other.length())
- , 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.
-}
-
-MutableElementAttributeData::MutableElementAttributeData(const MutableElementAttributeData& other)
- : ElementAttributeData(other, true)
- , m_presentationAttributeStyle(other.m_presentationAttributeStyle)
- , m_attributeVector(other.m_attributeVector)
-{
- m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->copy() : 0;
-}
-
-MutableElementAttributeData::MutableElementAttributeData(const ImmutableElementAttributeData& other)
- : ElementAttributeData(other, true)
-{
- // An ImmutableElementAttributeData 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.immutableAttributeArray()[i]);
-}
-
-PassRefPtr<ElementAttributeData> ElementAttributeData::makeMutableCopy() const
-{
- if (isMutable())
- return adoptRef(new MutableElementAttributeData(static_cast<const MutableElementAttributeData&>(*this)));
- return adoptRef(new MutableElementAttributeData(static_cast<const ImmutableElementAttributeData&>(*this)));
-}
-
-PassRefPtr<ElementAttributeData> ElementAttributeData::makeImmutableCopy() const
-{
- ASSERT(isMutable());
- void* slot = WTF::fastMalloc(sizeForImmutableElementAttributeDataWithAttributeCount(mutableAttributeVector().size()));
- return adoptRef(new (slot) ImmutableElementAttributeData(static_cast<const MutableElementAttributeData&>(*this)));
-}
-
-void ElementAttributeData::addAttribute(const Attribute& attribute)
-{
- ASSERT(isMutable());
- mutableAttributeVector().append(attribute);
-}
-
-void ElementAttributeData::removeAttribute(size_t index)
-{
- ASSERT(isMutable());
- ASSERT_WITH_SECURITY_IMPLICATION(index < length());
- mutableAttributeVector().remove(index);
-}
-
-bool ElementAttributeData::isEquivalent(const ElementAttributeData* 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 = attributeItem(i);
- const Attribute* otherAttr = other->getAttributeItem(attribute->name());
- if (!otherAttr || attribute->value() != otherAttr->value())
- return false;
- }
-
- return true;
-}
-
-void ElementAttributeData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
-{
- size_t actualSize = m_isMutable ? sizeof(ElementAttributeData) : sizeForImmutableElementAttributeDataWithAttributeCount(m_arraySize);
- MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM, actualSize);
- info.addMember(m_inlineStyle, "inlineStyle");
- info.addMember(m_classNames, "classNames");
- info.addMember(m_idForStyleResolution, "idForStyleResolution");
- if (m_isMutable) {
- info.addMember(presentationAttributeStyle(), "presentationAttributeStyle()");
- info.addMember(mutableAttributeVector(), "mutableAttributeVector");
- }
- for (unsigned i = 0, len = length(); i < len; i++)
- info.addMember(*attributeItem(i), "*attributeItem");
-}
-
-size_t ElementAttributeData::getAttributeItemIndexSlowCase(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 = attributeItem(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 notFound;
-}
-
-}
+++ /dev/null
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Peter Kelly (pmk@post.com)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2010, 2012 Apple Inc. All rights reserved.
- * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ElementAttributeData_h
-#define ElementAttributeData_h
-
-#include "Attribute.h"
-#include "SpaceSplitString.h"
-#include "StylePropertySet.h"
-#include <wtf/NotFound.h>
-
-namespace WebCore {
-
-class Element;
-class ImmutableElementAttributeData;
-class MutableElementAttributeData;
-
-class ElementAttributeData : public RefCounted<ElementAttributeData> {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- static PassRefPtr<ElementAttributeData> create();
- static PassRefPtr<ElementAttributeData> createImmutable(const Vector<Attribute>&);
-
- // Override RefCounted's deref() to ensure operator delete is called on
- // the appropriate subclass type.
- void deref();
-
- 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;
- void setPresentationAttributeStyle(PassRefPtr<StylePropertySet>) const;
-
- size_t length() const;
- bool isEmpty() const { return !length(); }
-
- // Internal interface.
- const Attribute* attributeItem(unsigned index) const;
- const Attribute* getAttributeItem(const QualifiedName&) const;
- Attribute* attributeItem(unsigned index);
- Attribute* getAttributeItem(const QualifiedName&);
- size_t getAttributeItemIndex(const QualifiedName&) const;
- size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
-
- // These functions do no error checking.
- void addAttribute(const Attribute&);
- void removeAttribute(size_t index);
-
- bool hasID() const { return !m_idForStyleResolution.isNull(); }
- bool hasClass() const { return !m_classNames.isNull(); }
-
- bool isEquivalent(const ElementAttributeData* other) const;
-
- void reportMemoryUsage(MemoryObjectInfo*) const;
-
- bool isMutable() const { return m_isMutable; }
- const Attribute* immutableAttributeArray() const;
-
-protected:
- ElementAttributeData()
- : m_isMutable(true)
- , m_arraySize(0)
- , m_presentationAttributeStyleIsDirty(false)
- , m_styleAttributeIsDirty(false)
-#if ENABLE(SVG)
- , m_animatedSVGAttributesAreDirty(false)
-#endif
- { }
-
- ElementAttributeData(unsigned arraySize)
- : m_isMutable(false)
- , m_arraySize(arraySize)
- , m_presentationAttributeStyleIsDirty(false)
- , m_styleAttributeIsDirty(false)
-#if ENABLE(SVG)
- , m_animatedSVGAttributesAreDirty(false)
-#endif
- { }
-
- ElementAttributeData(const ElementAttributeData&, bool isMutable);
-
- unsigned m_isMutable : 1;
- unsigned m_arraySize : 28;
- 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 ImmutableElementAttributeData;
- friend class MutableElementAttributeData;
-#if ENABLE(SVG)
- friend class SVGElement;
-#endif
-
- Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase);
- const Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
- size_t getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
-
- PassRefPtr<ElementAttributeData> makeMutableCopy() const;
- PassRefPtr<ElementAttributeData> makeImmutableCopy() const;
-
- Vector<Attribute, 4>& mutableAttributeVector();
- const Vector<Attribute, 4>& mutableAttributeVector() const;
-};
-
-class ImmutableElementAttributeData : public ElementAttributeData {
-public:
- ImmutableElementAttributeData(const Vector<Attribute>&);
- ImmutableElementAttributeData(const MutableElementAttributeData&);
- ~ImmutableElementAttributeData();
-
- void* m_attributeArray;
-};
-
-class MutableElementAttributeData : public ElementAttributeData {
-public:
- MutableElementAttributeData() { }
- MutableElementAttributeData(const ImmutableElementAttributeData&);
- MutableElementAttributeData(const MutableElementAttributeData&);
-
- mutable RefPtr<StylePropertySet> m_presentationAttributeStyle;
- Vector<Attribute, 4> m_attributeVector;
-};
-
-inline Vector<Attribute, 4>& ElementAttributeData::mutableAttributeVector()
-{
- ASSERT(m_isMutable);
- return static_cast<MutableElementAttributeData*>(this)->m_attributeVector;
-}
-
-inline const Vector<Attribute, 4>& ElementAttributeData::mutableAttributeVector() const
-{
- ASSERT(m_isMutable);
- return static_cast<const MutableElementAttributeData*>(this)->m_attributeVector;
-}
-
-inline const Attribute* ElementAttributeData::immutableAttributeArray() const
-{
- ASSERT(!m_isMutable);
- return reinterpret_cast<const Attribute*>(&static_cast<const ImmutableElementAttributeData*>(this)->m_attributeArray);
-}
-
-inline size_t ElementAttributeData::length() const
-{
- if (isMutable())
- return mutableAttributeVector().size();
- return m_arraySize;
-}
-
-inline const StylePropertySet* ElementAttributeData::presentationAttributeStyle() const
-{
- if (!m_isMutable)
- return 0;
- return static_cast<const MutableElementAttributeData*>(this)->m_presentationAttributeStyle.get();
-}
-
-inline void ElementAttributeData::setPresentationAttributeStyle(PassRefPtr<StylePropertySet> style) const
-{
- ASSERT(m_isMutable);
- static_cast<const MutableElementAttributeData*>(this)->m_presentationAttributeStyle = style;
-}
-
-inline Attribute* ElementAttributeData::getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase)
-{
- size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);
- if (index != notFound)
- return attributeItem(index);
- return 0;
-}
-
-inline const Attribute* ElementAttributeData::getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const
-{
- size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);
- if (index != notFound)
- return attributeItem(index);
- return 0;
-}
-
-inline size_t ElementAttributeData::getAttributeItemIndex(const QualifiedName& name) const
-{
- for (unsigned i = 0; i < length(); ++i) {
- if (attributeItem(i)->name().matches(name))
- return i;
- }
- return notFound;
-}
-
-// 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 size_t ElementAttributeData::getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const
-{
- unsigned len = length();
- bool doSlowCheck = shouldIgnoreAttributeCase;
-
- // Optimize for the case where the attribute exists and its name exactly matches.
- for (unsigned i = 0; i < len; ++i) {
- const Attribute* attribute = attributeItem(i);
- if (!attribute->name().hasPrefix()) {
- if (name == attribute->localName())
- return i;
- } else
- doSlowCheck = true;
- }
-
- if (doSlowCheck)
- return getAttributeItemIndexSlowCase(name, shouldIgnoreAttributeCase);
- return notFound;
-}
-
-inline const Attribute* ElementAttributeData::getAttributeItem(const QualifiedName& name) const
-{
- for (unsigned i = 0; i < length(); ++i) {
- if (attributeItem(i)->name().matches(name))
- return attributeItem(i);
- }
- return 0;
-}
-
-inline Attribute* ElementAttributeData::getAttributeItem(const QualifiedName& name)
-{
- for (unsigned i = 0; i < length(); ++i) {
- if (attributeItem(i)->name().matches(name))
- return attributeItem(i);
- }
- return 0;
-}
-
-inline const Attribute* ElementAttributeData::attributeItem(unsigned index) const
-{
- ASSERT_WITH_SECURITY_IMPLICATION(index < length());
- if (m_isMutable)
- return &mutableAttributeVector().at(index);
- return &immutableAttributeArray()[index];
-}
-
-inline Attribute* ElementAttributeData::attributeItem(unsigned index)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(index < length());
- return &mutableAttributeVector().at(index);
-}
-
-inline void ElementAttributeData::deref()
-{
- if (!derefBase())
- return;
-
- if (m_isMutable)
- delete static_cast<MutableElementAttributeData*>(this);
- else
- delete static_cast<ImmutableElementAttributeData*>(this);
-}
-
-}
-
-#endif // ElementAttributeData_h
#include "SharedWorker.h"
+#include "ExceptionCode.h"
#include "FeatureObserver.h"
#include "InspectorInstrumentation.h"
#include "KURL.h"