Don't include CSSParser.h from other headers
[WebKit-https.git] / Source / WebCore / css / StyleProperties.h
1 /*
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.
5  *
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.
10  *
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.
15  *
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.
20  */
21
22 #ifndef StyleProperties_h
23 #define StyleProperties_h
24
25 #include "CSSParserMode.h"
26 #include "CSSPrimitiveValue.h"
27 #include "CSSProperty.h"
28 #include "CSSPropertyNames.h"
29 #include "CSSValueKeywords.h"
30 #include <memory>
31 #include <wtf/ListHashSet.h>
32 #include <wtf/TypeCasts.h>
33 #include <wtf/Vector.h>
34 #include <wtf/text/WTFString.h>
35
36 namespace WebCore {
37
38 class CSSStyleDeclaration;
39 class CachedResource;
40 class ImmutableStyleProperties;
41 class URL;
42 class MutableStyleProperties;
43 class PropertySetCSSStyleDeclaration;
44 class StyledElement;
45 class StylePropertyShorthand;
46 class StyleSheetContents;
47
48 class StyleProperties : public RefCounted<StyleProperties> {
49     friend class PropertyReference;
50 public:
51     // Override RefCounted's deref() to ensure operator delete is called on
52     // the appropriate subclass type.
53     void deref();
54
55     class PropertyReference {
56     public:
57         PropertyReference(const StylePropertyMetadata& metadata, const CSSValue* value)
58             : m_metadata(metadata)
59             , m_value(value)
60         { }
61
62         CSSPropertyID id() const { return static_cast<CSSPropertyID>(m_metadata.m_propertyID); }
63         CSSPropertyID shorthandID() const { return m_metadata.shorthandID(); }
64
65         bool isImportant() const { return m_metadata.m_important; }
66         bool isInherited() const { return m_metadata.m_inherited; }
67         bool isImplicit() const { return m_metadata.m_implicit; }
68
69         String cssName() const;
70         String cssText() const;
71
72         const CSSValue* value() const { return m_value; }
73         // FIXME: We should try to remove this mutable overload.
74         CSSValue* value() { return const_cast<CSSValue*>(m_value); }
75
76         // FIXME: Remove this.
77         CSSProperty toCSSProperty() const { return CSSProperty(id(), const_cast<CSSValue*>(m_value), isImportant(), m_metadata.m_isSetFromShorthand, m_metadata.m_indexInShorthandsVector, isImplicit()); }
78
79     private:
80         const StylePropertyMetadata& m_metadata;
81         const CSSValue* m_value;
82     };
83
84     unsigned propertyCount() const;
85     bool isEmpty() const { return !propertyCount(); }
86     PropertyReference propertyAt(unsigned) const;
87
88     WEBCORE_EXPORT PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
89     WEBCORE_EXPORT String getPropertyValue(CSSPropertyID) const;
90     bool propertyIsImportant(CSSPropertyID) const;
91     String getPropertyShorthand(CSSPropertyID) const;
92     bool isPropertyImplicit(CSSPropertyID) const;
93
94     RefPtr<CSSValue> getCustomPropertyCSSValue(const String& propertyName) const;
95     String getCustomPropertyValue(const String& propertyName) const;
96     bool customPropertyIsImportant(const String& propertyName) const;
97
98     Ref<MutableStyleProperties> copyBlockProperties() const;
99
100     CSSParserMode cssParserMode() const { return static_cast<CSSParserMode>(m_cssParserMode); }
101
102     void addSubresourceStyleURLs(ListHashSet<URL>&, StyleSheetContents* contextStyleSheet) const;
103
104     WEBCORE_EXPORT Ref<MutableStyleProperties> mutableCopy() const;
105     Ref<ImmutableStyleProperties> immutableCopyIfNeeded() const;
106
107     Ref<MutableStyleProperties> copyPropertiesInSet(const CSSPropertyID* set, unsigned length) const;
108     
109     String asText() const;
110
111     bool isMutable() const { return m_isMutable; }
112     bool hasCSSOMWrapper() const;
113
114     bool traverseSubresources(const std::function<bool (const CachedResource&)>& handler) const;
115
116     static unsigned averageSizeInBytes();
117
118 #ifndef NDEBUG
119     void showStyle();
120 #endif
121
122     bool propertyMatches(CSSPropertyID, const CSSValue*) const;
123
124 protected:
125     StyleProperties(CSSParserMode cssParserMode)
126         : m_cssParserMode(cssParserMode)
127         , m_isMutable(true)
128         , m_arraySize(0)
129     { }
130
131     StyleProperties(CSSParserMode cssParserMode, unsigned immutableArraySize)
132         : m_cssParserMode(cssParserMode)
133         , m_isMutable(false)
134         , m_arraySize(immutableArraySize)
135     { }
136
137     int findPropertyIndex(CSSPropertyID) const;
138     int findCustomPropertyIndex(const String& propertyName) const;
139     
140     unsigned m_cssParserMode : 2;
141     mutable unsigned m_isMutable : 1;
142     unsigned m_arraySize : 29;
143     
144 private:
145     String getShorthandValue(const StylePropertyShorthand&) const;
146     String getCommonValue(const StylePropertyShorthand&) const;
147     enum CommonValueMode { OmitUncommonValues, ReturnNullOnUncommonValues };
148     String borderPropertyValue(CommonValueMode) const;
149     String getLayeredShorthandValue(const StylePropertyShorthand&) const;
150     String get4Values(const StylePropertyShorthand&) const;
151     String borderSpacingValue(const StylePropertyShorthand&) const;
152     String fontValue() const;
153     void appendFontLonghandValueIfExplicit(CSSPropertyID, StringBuilder& result, String& value) const;
154     
155     PassRefPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) const;
156     
157     friend class PropertySetCSSStyleDeclaration;
158 };
159
160 class ImmutableStyleProperties : public StyleProperties {
161 public:
162     WEBCORE_EXPORT ~ImmutableStyleProperties();
163     static Ref<ImmutableStyleProperties> create(const CSSProperty* properties, unsigned count, CSSParserMode);
164
165     unsigned propertyCount() const { return m_arraySize; }
166     bool isEmpty() const { return !propertyCount(); }
167     PropertyReference propertyAt(unsigned index) const;
168
169     const CSSValue** valueArray() const;
170     const StylePropertyMetadata* metadataArray() const;
171     int findPropertyIndex(CSSPropertyID) const;
172     int findCustomPropertyIndex(const String& propertyName) const;
173     
174     void* m_storage;
175
176 private:
177     ImmutableStyleProperties(const CSSProperty*, unsigned count, CSSParserMode);
178 };
179
180 inline const CSSValue** ImmutableStyleProperties::valueArray() const
181 {
182     return reinterpret_cast<const CSSValue**>(const_cast<const void**>((&(this->m_storage))));
183 }
184
185 inline const StylePropertyMetadata* ImmutableStyleProperties::metadataArray() const
186 {
187     return reinterpret_cast_ptr<const StylePropertyMetadata*>(&reinterpret_cast_ptr<const char*>(&(this->m_storage))[m_arraySize * sizeof(CSSValue*)]);
188 }
189
190 class MutableStyleProperties : public StyleProperties {
191 public:
192     WEBCORE_EXPORT static Ref<MutableStyleProperties> create(CSSParserMode = CSSQuirksMode);
193     static Ref<MutableStyleProperties> create(const CSSProperty* properties, unsigned count);
194
195     WEBCORE_EXPORT ~MutableStyleProperties();
196
197     unsigned propertyCount() const { return m_propertyVector.size(); }
198     bool isEmpty() const { return !propertyCount(); }
199     PropertyReference propertyAt(unsigned index) const;
200
201     PropertySetCSSStyleDeclaration* cssStyleDeclaration();
202
203     bool addParsedProperties(const ParsedPropertyVector&);
204     bool addParsedProperty(const CSSProperty&);
205
206     // These expand shorthand properties into multiple properties.
207     bool setProperty(CSSPropertyID, const String& value, bool important = false, StyleSheetContents* contextStyleSheet = 0);
208     void setProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important = false);
209
210     // These do not. FIXME: This is too messy, we can do better.
211     bool setProperty(CSSPropertyID, CSSValueID identifier, bool important = false);
212     bool setProperty(CSSPropertyID, CSSPropertyID identifier, bool important = false);
213     bool setProperty(const CSSProperty&, CSSProperty* slot = nullptr);
214
215     bool removeProperty(CSSPropertyID, String* returnText = nullptr);
216     void removeBlockProperties();
217     bool removePropertiesInSet(const CSSPropertyID* set, unsigned length);
218
219     void mergeAndOverrideOnConflict(const StyleProperties&);
220
221     void clear();
222     bool parseDeclaration(const String& styleDeclaration, StyleSheetContents* contextStyleSheet);
223
224     WEBCORE_EXPORT CSSStyleDeclaration* ensureCSSStyleDeclaration();
225     CSSStyleDeclaration* ensureInlineCSSStyleDeclaration(StyledElement* parentElement);
226
227     int findPropertyIndex(CSSPropertyID) const;
228     int findCustomPropertyIndex(const String& propertyName) const;
229     
230     Vector<CSSProperty, 4> m_propertyVector;
231
232     // Methods for querying and altering CSS custom properties.
233     bool setCustomProperty(const String& propertyName, const String& value, bool important = false, StyleSheetContents* contextStyleSheet = 0);
234     bool removeCustomProperty(const String& propertyName, String* returnText = nullptr);
235
236 private:
237     explicit MutableStyleProperties(CSSParserMode);
238     explicit MutableStyleProperties(const StyleProperties&);
239     MutableStyleProperties(const CSSProperty* properties, unsigned count);
240
241     bool removeShorthandProperty(CSSPropertyID);
242     CSSProperty* findCSSPropertyWithID(CSSPropertyID);
243     CSSProperty* findCustomCSSPropertyWithName(const String&);
244     std::unique_ptr<PropertySetCSSStyleDeclaration> m_cssomWrapper;
245
246     friend class StyleProperties;
247 };
248
249 inline ImmutableStyleProperties::PropertyReference ImmutableStyleProperties::propertyAt(unsigned index) const
250 {
251     return PropertyReference(metadataArray()[index], valueArray()[index]);
252 }
253
254 inline MutableStyleProperties::PropertyReference MutableStyleProperties::propertyAt(unsigned index) const
255 {
256     const CSSProperty& property = m_propertyVector[index];
257     return PropertyReference(property.metadata(), property.value());
258 }
259
260 inline StyleProperties::PropertyReference StyleProperties::propertyAt(unsigned index) const
261 {
262     if (is<MutableStyleProperties>(*this))
263         return downcast<MutableStyleProperties>(*this).propertyAt(index);
264     return downcast<ImmutableStyleProperties>(*this).propertyAt(index);
265 }
266
267 inline unsigned StyleProperties::propertyCount() const
268 {
269     if (is<MutableStyleProperties>(*this))
270         return downcast<MutableStyleProperties>(*this).propertyCount();
271     return downcast<ImmutableStyleProperties>(*this).propertyCount();
272 }
273
274 inline void StyleProperties::deref()
275 {
276     if (!derefBase())
277         return;
278
279     if (is<MutableStyleProperties>(*this))
280         delete downcast<MutableStyleProperties>(this);
281     else
282         delete downcast<ImmutableStyleProperties>(this);
283 }
284
285 inline int StyleProperties::findPropertyIndex(CSSPropertyID propertyID) const
286 {
287     if (is<MutableStyleProperties>(*this))
288         return downcast<MutableStyleProperties>(*this).findPropertyIndex(propertyID);
289     return downcast<ImmutableStyleProperties>(*this).findPropertyIndex(propertyID);
290 }
291
292 inline int StyleProperties::findCustomPropertyIndex(const String& propertyName) const
293 {
294     if (is<MutableStyleProperties>(*this))
295         return downcast<MutableStyleProperties>(*this).findCustomPropertyIndex(propertyName);
296     return downcast<ImmutableStyleProperties>(*this).findCustomPropertyIndex(propertyName);
297 }
298
299 } // namespace WebCore
300
301 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::MutableStyleProperties)
302     static bool isType(const WebCore::StyleProperties& set) { return set.isMutable(); }
303 SPECIALIZE_TYPE_TRAITS_END()
304
305 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ImmutableStyleProperties)
306     static bool isType(const WebCore::StyleProperties& set) { return !set.isMutable(); }
307 SPECIALIZE_TYPE_TRAITS_END()
308
309 #endif // StyleProperties_h