2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2008, 2012, 2013 Apple Inc. All rights reserved.
4 * Copyright (C) 2013 Intel Corporation. All rights reserved.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
24 #include "CSSParserMode.h"
25 #include "CSSProperty.h"
26 #include "CSSValueKeywords.h"
28 #include <wtf/ListHashSet.h>
29 #include <wtf/TypeCasts.h>
30 #include <wtf/Vector.h>
31 #include <wtf/text/WTFString.h>
35 class CSSStyleDeclaration;
37 class ImmutableStyleProperties;
39 class MutableStyleProperties;
40 class PropertySetCSSStyleDeclaration;
42 class StylePropertyShorthand;
43 class StyleSheetContents;
45 class StyleProperties : public RefCounted<StyleProperties> {
46 friend class PropertyReference;
48 // Override RefCounted's deref() to ensure operator delete is called on
49 // the appropriate subclass type.
52 class PropertyReference {
54 PropertyReference(const StylePropertyMetadata& metadata, const CSSValue* value)
55 : m_metadata(metadata)
59 CSSPropertyID id() const { return static_cast<CSSPropertyID>(m_metadata.m_propertyID); }
60 CSSPropertyID shorthandID() const { return m_metadata.shorthandID(); }
62 bool isImportant() const { return m_metadata.m_important; }
63 bool isInherited() const { return m_metadata.m_inherited; }
64 bool isImplicit() const { return m_metadata.m_implicit; }
66 String cssName() const;
67 String cssText() const;
69 const CSSValue* value() const { return m_value; }
70 // FIXME: We should try to remove this mutable overload.
71 CSSValue* value() { return const_cast<CSSValue*>(m_value); }
73 // FIXME: Remove this.
74 CSSProperty toCSSProperty() const { return CSSProperty(id(), const_cast<CSSValue*>(m_value), isImportant(), m_metadata.m_isSetFromShorthand, m_metadata.m_indexInShorthandsVector, isImplicit()); }
77 const StylePropertyMetadata& m_metadata;
78 const CSSValue* m_value;
81 unsigned propertyCount() const;
82 bool isEmpty() const { return !propertyCount(); }
83 PropertyReference propertyAt(unsigned) const;
85 WEBCORE_EXPORT RefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
86 WEBCORE_EXPORT String getPropertyValue(CSSPropertyID) const;
87 bool propertyIsImportant(CSSPropertyID) const;
88 String getPropertyShorthand(CSSPropertyID) const;
89 bool isPropertyImplicit(CSSPropertyID) const;
91 RefPtr<CSSValue> getCustomPropertyCSSValue(const String& propertyName) const;
92 String getCustomPropertyValue(const String& propertyName) const;
93 bool customPropertyIsImportant(const String& propertyName) const;
95 Ref<MutableStyleProperties> copyBlockProperties() const;
97 CSSParserMode cssParserMode() const { return static_cast<CSSParserMode>(m_cssParserMode); }
99 void addSubresourceStyleURLs(ListHashSet<URL>&, StyleSheetContents* contextStyleSheet) const;
101 WEBCORE_EXPORT Ref<MutableStyleProperties> mutableCopy() const;
102 Ref<ImmutableStyleProperties> immutableCopyIfNeeded() const;
104 Ref<MutableStyleProperties> copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const;
106 String asText() const;
108 bool isMutable() const { return m_isMutable; }
109 bool hasCSSOMWrapper() const;
111 bool traverseSubresources(const std::function<bool (const CachedResource&)>& handler) const;
113 static unsigned averageSizeInBytes();
119 bool propertyMatches(CSSPropertyID, const CSSValue*) const;
122 StyleProperties(CSSParserMode cssParserMode)
123 : m_cssParserMode(cssParserMode)
128 StyleProperties(CSSParserMode cssParserMode, unsigned immutableArraySize)
129 : m_cssParserMode(cssParserMode)
131 , m_arraySize(immutableArraySize)
134 int findPropertyIndex(CSSPropertyID) const;
135 int findCustomPropertyIndex(const String& propertyName) const;
137 unsigned m_cssParserMode : 2;
138 mutable unsigned m_isMutable : 1;
139 unsigned m_arraySize : 29;
142 String getShorthandValue(const StylePropertyShorthand&) const;
143 String getCommonValue(const StylePropertyShorthand&) const;
144 enum CommonValueMode { OmitUncommonValues, ReturnNullOnUncommonValues };
145 String borderPropertyValue(CommonValueMode) const;
146 String getLayeredShorthandValue(const StylePropertyShorthand&) const;
147 String get4Values(const StylePropertyShorthand&) const;
148 String borderSpacingValue(const StylePropertyShorthand&) const;
149 String fontValue() const;
150 void appendFontLonghandValueIfExplicit(CSSPropertyID, StringBuilder& result, String& value) const;
152 RefPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) const;
154 friend class PropertySetCSSStyleDeclaration;
157 class ImmutableStyleProperties : public StyleProperties {
159 WEBCORE_EXPORT ~ImmutableStyleProperties();
160 static Ref<ImmutableStyleProperties> create(const CSSProperty* properties, unsigned count, CSSParserMode);
162 unsigned propertyCount() const { return m_arraySize; }
163 bool isEmpty() const { return !propertyCount(); }
164 PropertyReference propertyAt(unsigned index) const;
166 const CSSValue** valueArray() const;
167 const StylePropertyMetadata* metadataArray() const;
168 int findPropertyIndex(CSSPropertyID) const;
169 int findCustomPropertyIndex(const String& propertyName) const;
174 ImmutableStyleProperties(const CSSProperty*, unsigned count, CSSParserMode);
177 inline const CSSValue** ImmutableStyleProperties::valueArray() const
179 return reinterpret_cast<const CSSValue**>(const_cast<const void**>((&(this->m_storage))));
182 inline const StylePropertyMetadata* ImmutableStyleProperties::metadataArray() const
184 return reinterpret_cast_ptr<const StylePropertyMetadata*>(&reinterpret_cast_ptr<const char*>(&(this->m_storage))[m_arraySize * sizeof(CSSValue*)]);
187 class MutableStyleProperties : public StyleProperties {
189 WEBCORE_EXPORT static Ref<MutableStyleProperties> create(CSSParserMode = CSSQuirksMode);
190 static Ref<MutableStyleProperties> create(const CSSProperty* properties, unsigned count);
192 WEBCORE_EXPORT ~MutableStyleProperties();
194 unsigned propertyCount() const { return m_propertyVector.size(); }
195 bool isEmpty() const { return !propertyCount(); }
196 PropertyReference propertyAt(unsigned index) const;
198 PropertySetCSSStyleDeclaration* cssStyleDeclaration();
200 bool addParsedProperties(const ParsedPropertyVector&);
201 bool addParsedProperty(const CSSProperty&);
203 // These expand shorthand properties into multiple properties.
204 bool setProperty(CSSPropertyID, const String& value, bool important = false, StyleSheetContents* contextStyleSheet = 0);
205 void setProperty(CSSPropertyID, RefPtr<CSSValue>&&, bool important = false);
207 // These do not. FIXME: This is too messy, we can do better.
208 bool setProperty(CSSPropertyID, CSSValueID identifier, bool important = false);
209 bool setProperty(CSSPropertyID, CSSPropertyID identifier, bool important = false);
210 bool setProperty(const CSSProperty&, CSSProperty* slot = nullptr);
212 bool removeProperty(CSSPropertyID, String* returnText = nullptr);
213 void removeBlockProperties();
214 bool removePropertiesInSet(const CSSPropertyID* set, unsigned length);
216 void mergeAndOverrideOnConflict(const StyleProperties&);
219 bool parseDeclaration(const String& styleDeclaration, StyleSheetContents* contextStyleSheet);
221 WEBCORE_EXPORT CSSStyleDeclaration* ensureCSSStyleDeclaration();
222 CSSStyleDeclaration* ensureInlineCSSStyleDeclaration(StyledElement* parentElement);
224 int findPropertyIndex(CSSPropertyID) const;
225 int findCustomPropertyIndex(const String& propertyName) const;
227 Vector<CSSProperty, 4> m_propertyVector;
229 // Methods for querying and altering CSS custom properties.
230 bool setCustomProperty(const String& propertyName, const String& value, bool important = false, StyleSheetContents* contextStyleSheet = 0);
231 bool removeCustomProperty(const String& propertyName, String* returnText = nullptr);
234 explicit MutableStyleProperties(CSSParserMode);
235 explicit MutableStyleProperties(const StyleProperties&);
236 MutableStyleProperties(const CSSProperty* properties, unsigned count);
238 bool removeShorthandProperty(CSSPropertyID);
239 CSSProperty* findCSSPropertyWithID(CSSPropertyID);
240 CSSProperty* findCustomCSSPropertyWithName(const String&);
241 std::unique_ptr<PropertySetCSSStyleDeclaration> m_cssomWrapper;
243 friend class StyleProperties;
246 inline ImmutableStyleProperties::PropertyReference ImmutableStyleProperties::propertyAt(unsigned index) const
248 return PropertyReference(metadataArray()[index], valueArray()[index]);
251 inline MutableStyleProperties::PropertyReference MutableStyleProperties::propertyAt(unsigned index) const
253 const CSSProperty& property = m_propertyVector[index];
254 return PropertyReference(property.metadata(), property.value());
257 inline StyleProperties::PropertyReference StyleProperties::propertyAt(unsigned index) const
259 if (is<MutableStyleProperties>(*this))
260 return downcast<MutableStyleProperties>(*this).propertyAt(index);
261 return downcast<ImmutableStyleProperties>(*this).propertyAt(index);
264 inline unsigned StyleProperties::propertyCount() const
266 if (is<MutableStyleProperties>(*this))
267 return downcast<MutableStyleProperties>(*this).propertyCount();
268 return downcast<ImmutableStyleProperties>(*this).propertyCount();
271 inline void StyleProperties::deref()
276 if (is<MutableStyleProperties>(*this))
277 delete downcast<MutableStyleProperties>(this);
279 delete downcast<ImmutableStyleProperties>(this);
282 inline int StyleProperties::findPropertyIndex(CSSPropertyID propertyID) const
284 if (is<MutableStyleProperties>(*this))
285 return downcast<MutableStyleProperties>(*this).findPropertyIndex(propertyID);
286 return downcast<ImmutableStyleProperties>(*this).findPropertyIndex(propertyID);
289 inline int StyleProperties::findCustomPropertyIndex(const String& propertyName) const
291 if (is<MutableStyleProperties>(*this))
292 return downcast<MutableStyleProperties>(*this).findCustomPropertyIndex(propertyName);
293 return downcast<ImmutableStyleProperties>(*this).findCustomPropertyIndex(propertyName);
296 } // namespace WebCore
298 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::MutableStyleProperties)
299 static bool isType(const WebCore::StyleProperties& set) { return set.isMutable(); }
300 SPECIALIZE_TYPE_TRAITS_END()
302 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ImmutableStyleProperties)
303 static bool isType(const WebCore::StyleProperties& set) { return !set.isMutable(); }
304 SPECIALIZE_TYPE_TRAITS_END()