diff options
Diffstat (limited to 'Source/WebCore/css/StyleProperties.h')
-rw-r--r-- | Source/WebCore/css/StyleProperties.h | 259 |
1 files changed, 151 insertions, 108 deletions
diff --git a/Source/WebCore/css/StyleProperties.h b/Source/WebCore/css/StyleProperties.h index f958c8427..8195c6759 100644 --- a/Source/WebCore/css/StyleProperties.h +++ b/Source/WebCore/css/StyleProperties.h @@ -19,24 +19,23 @@ * Boston, MA 02110-1301, USA. */ -#ifndef StyleProperties_h -#define StyleProperties_h +#pragma once #include "CSSParserMode.h" -#include "CSSPrimitiveValue.h" +#include "CSSParserTokenRange.h" #include "CSSProperty.h" -#include "CSSPropertyNames.h" #include "CSSValueKeywords.h" #include <memory> #include <wtf/ListHashSet.h> +#include <wtf/TypeCasts.h> #include <wtf/Vector.h> #include <wtf/text/WTFString.h> namespace WebCore { -class CSSRule; +class CSSDeferredParser; class CSSStyleDeclaration; -class ComputedStyleExtractor; +class CachedResource; class ImmutableStyleProperties; class URL; class MutableStyleProperties; @@ -45,73 +44,95 @@ class StyledElement; class StylePropertyShorthand; class StyleSheetContents; -class StyleProperties : public RefCounted<StyleProperties> { - friend class PropertyReference; +enum StylePropertiesType { ImmutablePropertiesType, MutablePropertiesType, DeferredPropertiesType }; + +class StylePropertiesBase : public RefCounted<StylePropertiesBase> { public: // Override RefCounted's deref() to ensure operator delete is called on // the appropriate subclass type. void deref(); + + StylePropertiesType type() const { return static_cast<StylePropertiesType>(m_type); } + + CSSParserMode cssParserMode() const { return static_cast<CSSParserMode>(m_cssParserMode); } + +protected: + StylePropertiesBase(CSSParserMode cssParserMode, StylePropertiesType type) + : m_cssParserMode(cssParserMode) + , m_type(type) + , m_arraySize(0) + { } + + StylePropertiesBase(CSSParserMode cssParserMode, unsigned immutableArraySize) + : m_cssParserMode(cssParserMode) + , m_type(ImmutablePropertiesType) + , m_arraySize(immutableArraySize) + { } + + unsigned m_cssParserMode : 3; + mutable unsigned m_type : 2; + unsigned m_arraySize : 27; +}; +class StyleProperties : public StylePropertiesBase { + friend class PropertyReference; +public: class PropertyReference { public: - PropertyReference(const StyleProperties& propertySet, unsigned index) - : m_propertySet(propertySet) - , m_index(index) - { - } + PropertyReference(const StylePropertyMetadata& metadata, const CSSValue* value) + : m_metadata(metadata) + , m_value(value) + { } - CSSPropertyID id() const { return static_cast<CSSPropertyID>(propertyMetadata().m_propertyID); } - CSSPropertyID shorthandID() const { return propertyMetadata().shorthandID(); } + CSSPropertyID id() const { return static_cast<CSSPropertyID>(m_metadata.m_propertyID); } + CSSPropertyID shorthandID() const { return m_metadata.shorthandID(); } - bool isImportant() const { return propertyMetadata().m_important; } - bool isInherited() const { return propertyMetadata().m_inherited; } - bool isImplicit() const { return propertyMetadata().m_implicit; } + bool isImportant() const { return m_metadata.m_important; } + bool isInherited() const { return m_metadata.m_inherited; } + bool isImplicit() const { return m_metadata.m_implicit; } String cssName() const; String cssText() const; - const CSSValue* value() const { return propertyValue(); } + const CSSValue* value() const { return m_value; } // FIXME: We should try to remove this mutable overload. - CSSValue* value() { return const_cast<CSSValue*>(propertyValue()); } + CSSValue* value() { return const_cast<CSSValue*>(m_value); } // FIXME: Remove this. - CSSProperty toCSSProperty() const { return CSSProperty(propertyMetadata(), const_cast<CSSValue*>(propertyValue())); } - const StylePropertyMetadata& propertyMetadata() const; + CSSProperty toCSSProperty() const { return CSSProperty(id(), const_cast<CSSValue*>(m_value), isImportant(), m_metadata.m_isSetFromShorthand, m_metadata.m_indexInShorthandsVector, isImplicit()); } private: - const CSSValue* propertyValue() const; - - const StyleProperties& m_propertySet; - unsigned m_index; + const StylePropertyMetadata& m_metadata; + const CSSValue* m_value; }; unsigned propertyCount() const; - bool isEmpty() const; - PropertyReference propertyAt(unsigned index) const { return PropertyReference(*this, index); } + bool isEmpty() const { return !propertyCount(); } + PropertyReference propertyAt(unsigned) const; - PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const; - String getPropertyValue(CSSPropertyID) const; + WEBCORE_EXPORT RefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const; + WEBCORE_EXPORT String getPropertyValue(CSSPropertyID) const; bool propertyIsImportant(CSSPropertyID) const; String getPropertyShorthand(CSSPropertyID) const; bool isPropertyImplicit(CSSPropertyID) const; - PassRef<MutableStyleProperties> copyBlockProperties() const; + RefPtr<CSSValue> getCustomPropertyCSSValue(const String& propertyName) const; + String getCustomPropertyValue(const String& propertyName) const; + bool customPropertyIsImportant(const String& propertyName) const; - CSSParserMode cssParserMode() const { return static_cast<CSSParserMode>(m_cssParserMode); } + Ref<MutableStyleProperties> copyBlockProperties() const; - void addSubresourceStyleURLs(ListHashSet<URL>&, StyleSheetContents* contextStyleSheet) const; + WEBCORE_EXPORT Ref<MutableStyleProperties> mutableCopy() const; + Ref<ImmutableStyleProperties> immutableCopyIfNeeded() const; - PassRef<MutableStyleProperties> mutableCopy() const; - PassRef<ImmutableStyleProperties> immutableCopyIfNeeded() const; - - PassRef<MutableStyleProperties> copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const; + Ref<MutableStyleProperties> copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const; String asText() const; - bool isMutable() const { return m_isMutable; } bool hasCSSOMWrapper() const; + bool isMutable() const { return type() == MutablePropertiesType; } - bool hasFailedOrCanceledSubresources() const; + bool traverseSubresources(const std::function<bool (const CachedResource&)>& handler) const; static unsigned averageSizeInBytes(); @@ -122,24 +143,17 @@ public: bool propertyMatches(CSSPropertyID, const CSSValue*) const; protected: - StyleProperties(CSSParserMode cssParserMode) - : m_cssParserMode(cssParserMode) - , m_isMutable(true) - , m_arraySize(0) + StyleProperties(CSSParserMode cssParserMode, StylePropertiesType type) + : StylePropertiesBase(cssParserMode, type) { } StyleProperties(CSSParserMode cssParserMode, unsigned immutableArraySize) - : m_cssParserMode(cssParserMode) - , m_isMutable(false) - , m_arraySize(immutableArraySize) + : StylePropertiesBase(cssParserMode, immutableArraySize) { } int findPropertyIndex(CSSPropertyID) const; + int findCustomPropertyIndex(const String& propertyName) const; - unsigned m_cssParserMode : 2; - mutable unsigned m_isMutable : 1; - unsigned m_arraySize : 29; - private: String getShorthandValue(const StylePropertyShorthand&) const; String getCommonValue(const StylePropertyShorthand&) const; @@ -150,21 +164,26 @@ private: String borderSpacingValue(const StylePropertyShorthand&) const; String fontValue() const; void appendFontLonghandValueIfExplicit(CSSPropertyID, StringBuilder& result, String& value) const; - + + RefPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) const; + friend class PropertySetCSSStyleDeclaration; }; -class ImmutableStyleProperties : public StyleProperties { +class ImmutableStyleProperties final : public StyleProperties { public: - ~ImmutableStyleProperties(); - static PassRef<ImmutableStyleProperties> create(const CSSProperty* properties, unsigned count, CSSParserMode); + WEBCORE_EXPORT ~ImmutableStyleProperties(); + static Ref<ImmutableStyleProperties> create(const CSSProperty* properties, unsigned count, CSSParserMode); unsigned propertyCount() const { return m_arraySize; } + bool isEmpty() const { return !propertyCount(); } + PropertyReference propertyAt(unsigned index) const; const CSSValue** valueArray() const; const StylePropertyMetadata* metadataArray() const; int findPropertyIndex(CSSPropertyID) const; - + int findCustomPropertyIndex(const String& propertyName) const; + void* m_storage; private: @@ -181,52 +200,53 @@ inline const StylePropertyMetadata* ImmutableStyleProperties::metadataArray() co return reinterpret_cast_ptr<const StylePropertyMetadata*>(&reinterpret_cast_ptr<const char*>(&(this->m_storage))[m_arraySize * sizeof(CSSValue*)]); } -class MutableStyleProperties : public StyleProperties { +class MutableStyleProperties final : public StyleProperties { public: - static PassRef<MutableStyleProperties> create(CSSParserMode = CSSQuirksMode); - static PassRef<MutableStyleProperties> create(const CSSProperty* properties, unsigned count); + WEBCORE_EXPORT static Ref<MutableStyleProperties> create(CSSParserMode = HTMLQuirksMode); + static Ref<MutableStyleProperties> create(const CSSProperty* properties, unsigned count); - ~MutableStyleProperties(); + WEBCORE_EXPORT ~MutableStyleProperties(); unsigned propertyCount() const { return m_propertyVector.size(); } + bool isEmpty() const { return !propertyCount(); } + PropertyReference propertyAt(unsigned index) const; PropertySetCSSStyleDeclaration* cssStyleDeclaration(); - void addParsedProperties(const Vector<CSSProperty>&); - void addParsedProperty(const CSSProperty&); + bool addParsedProperties(const ParsedPropertyVector&); + bool addParsedProperty(const CSSProperty&); // These expand shorthand properties into multiple properties. - bool setProperty(CSSPropertyID, const String& value, bool important = false, StyleSheetContents* contextStyleSheet = 0); - void setProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important = false); + bool setProperty(CSSPropertyID, const String& value, bool important, CSSParserContext); + bool setProperty(CSSPropertyID, const String& value, bool important = false); + void setProperty(CSSPropertyID, RefPtr<CSSValue>&&, bool important = false); // These do not. FIXME: This is too messy, we can do better. bool setProperty(CSSPropertyID, CSSValueID identifier, bool important = false); bool setProperty(CSSPropertyID, CSSPropertyID identifier, bool important = false); - void appendPrefixingVariantProperty(const CSSProperty&); - void setPrefixingVariantProperty(const CSSProperty&); - void setProperty(const CSSProperty&, CSSProperty* slot = 0); + bool setProperty(const CSSProperty&, CSSProperty* slot = nullptr); - bool removeProperty(CSSPropertyID, String* returnText = 0); - void removePrefixedOrUnprefixedProperty(CSSPropertyID); + bool removeProperty(CSSPropertyID, String* returnText = nullptr); void removeBlockProperties(); bool removePropertiesInSet(const CSSPropertyID* set, unsigned length); - // FIXME: These two can be moved to EditingStyle.cpp - void removeEquivalentProperties(const StyleProperties*); - void removeEquivalentProperties(const ComputedStyleExtractor*); - void mergeAndOverrideOnConflict(const StyleProperties&); void clear(); - void parseDeclaration(const String& styleDeclaration, StyleSheetContents* contextStyleSheet); + bool parseDeclaration(const String& styleDeclaration, CSSParserContext); - CSSStyleDeclaration* ensureCSSStyleDeclaration(); + WEBCORE_EXPORT CSSStyleDeclaration* ensureCSSStyleDeclaration(); CSSStyleDeclaration* ensureInlineCSSStyleDeclaration(StyledElement* parentElement); int findPropertyIndex(CSSPropertyID) const; - + int findCustomPropertyIndex(const String& propertyName) const; + Vector<CSSProperty, 4> m_propertyVector; + // Methods for querying and altering CSS custom properties. + bool setCustomProperty(const String& propertyName, const String& value, bool important, CSSParserContext); + bool removeCustomProperty(const String& propertyName, String* returnText = nullptr); + private: explicit MutableStyleProperties(CSSParserMode); explicit MutableStyleProperties(const StyleProperties&); @@ -234,69 +254,92 @@ private: bool removeShorthandProperty(CSSPropertyID); CSSProperty* findCSSPropertyWithID(CSSPropertyID); + CSSProperty* findCustomCSSPropertyWithName(const String&); std::unique_ptr<PropertySetCSSStyleDeclaration> m_cssomWrapper; friend class StyleProperties; }; -TYPE_CASTS_BASE(MutableStyleProperties, StyleProperties, set, set->isMutable(), set.isMutable()); - -inline MutableStyleProperties* toMutableStyleProperties(const RefPtr<StyleProperties>& set) -{ - return toMutableStyleProperties(set.get()); -} +class DeferredStyleProperties final : public StylePropertiesBase { +public: + WEBCORE_EXPORT ~DeferredStyleProperties(); + static Ref<DeferredStyleProperties> create(const CSSParserTokenRange&, CSSDeferredParser&); -TYPE_CASTS_BASE(ImmutableStyleProperties, StyleProperties, set, !set->isMutable(), !set.isMutable()); + Ref<ImmutableStyleProperties> parseDeferredProperties(); + +private: + DeferredStyleProperties(const CSSParserTokenRange&, CSSDeferredParser&); + + Vector<CSSParserToken> m_tokens; + Ref<CSSDeferredParser> m_parser; +}; -inline ImmutableStyleProperties* toImmutableStyleProperties(const RefPtr<StyleProperties>& set) +inline ImmutableStyleProperties::PropertyReference ImmutableStyleProperties::propertyAt(unsigned index) const { - return toImmutableStyleProperties(set.get()); + return PropertyReference(metadataArray()[index], valueArray()[index]); } -inline const StylePropertyMetadata& StyleProperties::PropertyReference::propertyMetadata() const +inline MutableStyleProperties::PropertyReference MutableStyleProperties::propertyAt(unsigned index) const { - if (m_propertySet.isMutable()) - return static_cast<const MutableStyleProperties&>(m_propertySet).m_propertyVector.at(m_index).metadata(); - return static_cast<const ImmutableStyleProperties&>(m_propertySet).metadataArray()[m_index]; + const CSSProperty& property = m_propertyVector[index]; + return PropertyReference(property.metadata(), property.value()); } -inline const CSSValue* StyleProperties::PropertyReference::propertyValue() const +inline StyleProperties::PropertyReference StyleProperties::propertyAt(unsigned index) const { - if (m_propertySet.isMutable()) - return static_cast<const MutableStyleProperties&>(m_propertySet).m_propertyVector.at(m_index).value(); - return static_cast<const ImmutableStyleProperties&>(m_propertySet).valueArray()[m_index]; + if (is<MutableStyleProperties>(*this)) + return downcast<MutableStyleProperties>(*this).propertyAt(index); + return downcast<ImmutableStyleProperties>(*this).propertyAt(index); } inline unsigned StyleProperties::propertyCount() const { - if (m_isMutable) - return static_cast<const MutableStyleProperties*>(this)->m_propertyVector.size(); - return m_arraySize; -} - -inline bool StyleProperties::isEmpty() const -{ - return !propertyCount(); + if (is<MutableStyleProperties>(*this)) + return downcast<MutableStyleProperties>(*this).propertyCount(); + return downcast<ImmutableStyleProperties>(*this).propertyCount(); } -inline void StyleProperties::deref() +inline void StylePropertiesBase::deref() { if (!derefBase()) return; - if (m_isMutable) - delete static_cast<MutableStyleProperties*>(this); + if (is<MutableStyleProperties>(*this)) + delete downcast<MutableStyleProperties>(this); + else if (is<ImmutableStyleProperties>(*this)) + delete downcast<ImmutableStyleProperties>(this); else - delete static_cast<ImmutableStyleProperties*>(this); + delete downcast<DeferredStyleProperties>(this); } inline int StyleProperties::findPropertyIndex(CSSPropertyID propertyID) const { - if (m_isMutable) - return toMutableStyleProperties(this)->findPropertyIndex(propertyID); - return toImmutableStyleProperties(this)->findPropertyIndex(propertyID); + if (is<MutableStyleProperties>(*this)) + return downcast<MutableStyleProperties>(*this).findPropertyIndex(propertyID); + return downcast<ImmutableStyleProperties>(*this).findPropertyIndex(propertyID); +} + +inline int StyleProperties::findCustomPropertyIndex(const String& propertyName) const +{ + if (is<MutableStyleProperties>(*this)) + return downcast<MutableStyleProperties>(*this).findCustomPropertyIndex(propertyName); + return downcast<ImmutableStyleProperties>(*this).findCustomPropertyIndex(propertyName); } } // namespace WebCore -#endif // StyleProperties_h +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleProperties) + static bool isType(const WebCore::StylePropertiesBase& set) { return set.type() != WebCore::DeferredPropertiesType; } +SPECIALIZE_TYPE_TRAITS_END() + +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::MutableStyleProperties) + static bool isType(const WebCore::StylePropertiesBase& set) { return set.type() == WebCore::MutablePropertiesType; } +SPECIALIZE_TYPE_TRAITS_END() + +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ImmutableStyleProperties) + static bool isType(const WebCore::StylePropertiesBase& set) { return set.type() == WebCore::ImmutablePropertiesType; } +SPECIALIZE_TYPE_TRAITS_END() + +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::DeferredStyleProperties) + static bool isType(const WebCore::StylePropertiesBase& set) { return set.type() == WebCore::DeferredPropertiesType; } +SPECIALIZE_TYPE_TRAITS_END() |