Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / StylePropertySet.h
1 /*
2  * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2004, 2005, 2006, 2008, 2012 Apple Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #ifndef StylePropertySet_h
22 #define StylePropertySet_h
23
24 #include "CSSPropertyNames.h"
25 #include "core/css/CSSParserMode.h"
26 #include "core/css/CSSPrimitiveValue.h"
27 #include "core/css/CSSProperty.h"
28 #include "core/css/PropertySetCSSStyleDeclaration.h"
29 #include "wtf/ListHashSet.h"
30 #include "wtf/Vector.h"
31 #include "wtf/text/WTFString.h"
32
33 namespace WebCore {
34
35 class CSSRule;
36 class CSSStyleDeclaration;
37 class Element;
38 class ImmutableStylePropertySet;
39 class KURL;
40 class MutableStylePropertySet;
41 class StylePropertyShorthand;
42 class StyleSheetContents;
43
44 class StylePropertySet : public RefCounted<StylePropertySet> {
45     friend class PropertyReference;
46 public:
47     // Override RefCounted's deref() to ensure operator delete is called on
48     // the appropriate subclass type.
49     void deref();
50
51     class PropertyReference {
52     public:
53         PropertyReference(const StylePropertySet& propertySet, unsigned index)
54             : m_propertySet(propertySet)
55             , m_index(index)
56         {
57         }
58
59         CSSPropertyID id() const { return static_cast<CSSPropertyID>(propertyMetadata().m_propertyID); }
60         CSSPropertyID shorthandID() const { return propertyMetadata().shorthandID(); }
61
62         bool isImportant() const { return propertyMetadata().m_important; }
63         bool isInherited() const { return propertyMetadata().m_inherited; }
64         bool isImplicit() const { return propertyMetadata().m_implicit; }
65
66         String cssName() const;
67         String cssText() const;
68
69         const CSSValue* value() const { return propertyValue(); }
70         // FIXME: We should try to remove this mutable overload.
71         CSSValue* value() { return const_cast<CSSValue*>(propertyValue()); }
72
73         // FIXME: Remove this.
74         CSSProperty toCSSProperty() const { return CSSProperty(propertyMetadata(), const_cast<CSSValue*>(propertyValue())); }
75
76         const StylePropertyMetadata& propertyMetadata() const;
77
78     private:
79         const CSSValue* propertyValue() const;
80
81         const StylePropertySet& m_propertySet;
82         unsigned m_index;
83     };
84
85     unsigned propertyCount() const;
86     bool isEmpty() const;
87     PropertyReference propertyAt(unsigned index) const { return PropertyReference(*this, index); }
88     int findPropertyIndex(CSSPropertyID) const;
89
90     PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
91     String getPropertyValue(CSSPropertyID) const;
92
93     bool propertyIsImportant(CSSPropertyID) const;
94     CSSPropertyID getPropertyShorthand(CSSPropertyID) const;
95     bool isPropertyImplicit(CSSPropertyID) const;
96
97     PassRefPtr<MutableStylePropertySet> copyBlockProperties() const;
98
99     CSSParserMode cssParserMode() const { return static_cast<CSSParserMode>(m_cssParserMode); }
100
101     PassRefPtr<MutableStylePropertySet> mutableCopy() const;
102     PassRefPtr<ImmutableStylePropertySet> immutableCopyIfNeeded() const;
103
104     PassRefPtr<MutableStylePropertySet> copyPropertiesInSet(const Vector<CSSPropertyID>&) const;
105
106     String asText() const;
107
108     bool isMutable() const { return m_isMutable; }
109
110     bool hasFailedOrCanceledSubresources() const;
111
112     static unsigned averageSizeInBytes();
113
114 #ifndef NDEBUG
115     void showStyle();
116 #endif
117
118     bool propertyMatches(CSSPropertyID, const CSSValue*) const;
119
120 protected:
121
122     enum { MaxArraySize = (1 << 28) - 1 };
123
124     StylePropertySet(CSSParserMode cssParserMode)
125         : m_cssParserMode(cssParserMode)
126         , m_isMutable(true)
127         , m_arraySize(0)
128     { }
129
130     StylePropertySet(CSSParserMode cssParserMode, unsigned immutableArraySize)
131         : m_cssParserMode(cssParserMode)
132         , m_isMutable(false)
133         , m_arraySize(std::min(immutableArraySize, unsigned(MaxArraySize)))
134     { }
135
136     unsigned m_cssParserMode : 3;
137     mutable unsigned m_isMutable : 1;
138     unsigned m_arraySize : 28;
139
140     friend class PropertySetCSSStyleDeclaration;
141 };
142
143 class ImmutableStylePropertySet : public StylePropertySet {
144 public:
145     ~ImmutableStylePropertySet();
146     static PassRefPtr<ImmutableStylePropertySet> create(const CSSProperty* properties, unsigned count, CSSParserMode);
147
148     unsigned propertyCount() const { return m_arraySize; }
149
150     const CSSValue** valueArray() const;
151     const StylePropertyMetadata* metadataArray() const;
152
153     void* m_storage;
154
155 private:
156     ImmutableStylePropertySet(const CSSProperty*, unsigned count, CSSParserMode);
157 };
158
159 inline const CSSValue** ImmutableStylePropertySet::valueArray() const
160 {
161     return reinterpret_cast<const CSSValue**>(const_cast<const void**>(&(this->m_storage)));
162 }
163
164 inline const StylePropertyMetadata* ImmutableStylePropertySet::metadataArray() const
165 {
166     return reinterpret_cast<const StylePropertyMetadata*>(&reinterpret_cast<const char*>(&(this->m_storage))[m_arraySize * sizeof(CSSValue*)]);
167 }
168
169 DEFINE_TYPE_CASTS(ImmutableStylePropertySet, StylePropertySet, set, !set->isMutable(), !set.isMutable());
170
171 inline ImmutableStylePropertySet* toImmutableStylePropertySet(const RefPtr<StylePropertySet>& set)
172 {
173     return toImmutableStylePropertySet(set.get());
174 }
175
176 class MutableStylePropertySet : public StylePropertySet {
177 public:
178     ~MutableStylePropertySet() { }
179     static PassRefPtr<MutableStylePropertySet> create(CSSParserMode = HTMLQuirksMode);
180     static PassRefPtr<MutableStylePropertySet> create(const CSSProperty* properties, unsigned count);
181
182     unsigned propertyCount() const { return m_propertyVector.size(); }
183
184     void addParsedProperties(const Vector<CSSProperty, 256>&);
185     void addParsedProperty(const CSSProperty&);
186
187     // These expand shorthand properties into multiple properties.
188     bool setProperty(CSSPropertyID, const String& value, bool important = false, StyleSheetContents* contextStyleSheet = 0);
189     void setProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important = false);
190
191     // These do not. FIXME: This is too messy, we can do better.
192     bool setProperty(CSSPropertyID, CSSValueID identifier, bool important = false);
193     bool setProperty(CSSPropertyID, CSSPropertyID identifier, bool important = false);
194     void appendPrefixingVariantProperty(const CSSProperty&);
195     void setPrefixingVariantProperty(const CSSProperty&);
196     void setProperty(const CSSProperty&, CSSProperty* slot = 0);
197
198     bool removeProperty(CSSPropertyID, String* returnText = 0);
199     void removePrefixedOrUnprefixedProperty(CSSPropertyID);
200     void removeBlockProperties();
201     bool removePropertiesInSet(const CSSPropertyID* set, unsigned length);
202     void removeEquivalentProperties(const StylePropertySet*);
203     void removeEquivalentProperties(const CSSStyleDeclaration*);
204
205     void mergeAndOverrideOnConflict(const StylePropertySet*);
206
207     void clear();
208     void parseDeclaration(const String& styleDeclaration, StyleSheetContents* contextStyleSheet);
209
210     CSSStyleDeclaration* ensureCSSStyleDeclaration();
211
212     Vector<CSSProperty, 4> m_propertyVector;
213
214 private:
215     explicit MutableStylePropertySet(CSSParserMode);
216     explicit MutableStylePropertySet(const StylePropertySet&);
217     MutableStylePropertySet(const CSSProperty* properties, unsigned count);
218
219     bool removeShorthandProperty(CSSPropertyID);
220     CSSProperty* findCSSPropertyWithID(CSSPropertyID);
221     OwnPtr<PropertySetCSSStyleDeclaration> m_cssomWrapper;
222
223     friend class StylePropertySet;
224 };
225
226 DEFINE_TYPE_CASTS(MutableStylePropertySet, StylePropertySet, set, set->isMutable(), set.isMutable());
227
228 inline MutableStylePropertySet* toMutableStylePropertySet(const RefPtr<StylePropertySet>& set)
229 {
230     return toMutableStylePropertySet(set.get());
231 }
232
233 inline const StylePropertyMetadata& StylePropertySet::PropertyReference::propertyMetadata() const
234 {
235     if (m_propertySet.isMutable())
236         return toMutableStylePropertySet(m_propertySet).m_propertyVector.at(m_index).metadata();
237     return toImmutableStylePropertySet(m_propertySet).metadataArray()[m_index];
238 }
239
240 inline const CSSValue* StylePropertySet::PropertyReference::propertyValue() const
241 {
242     if (m_propertySet.isMutable())
243         return toMutableStylePropertySet(m_propertySet).m_propertyVector.at(m_index).value();
244     return toImmutableStylePropertySet(m_propertySet).valueArray()[m_index];
245 }
246
247 inline unsigned StylePropertySet::propertyCount() const
248 {
249     if (m_isMutable)
250         return toMutableStylePropertySet(this)->m_propertyVector.size();
251     return m_arraySize;
252 }
253
254 inline bool StylePropertySet::isEmpty() const
255 {
256     return !propertyCount();
257 }
258
259 inline void StylePropertySet::deref()
260 {
261     if (!derefBase())
262         return;
263
264     if (m_isMutable)
265         delete toMutableStylePropertySet(this);
266     else
267         delete toImmutableStylePropertySet(this);
268 }
269
270 } // namespace WebCore
271
272 #endif // StylePropertySet_h