Upstream version 7.36.149.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 RefCountedWillBeRefCountedGarbageCollected<StylePropertySet> {
45     friend class PropertyReference;
46 public:
47
48 #if ENABLE(OILPAN)
49     // When oilpan is enabled override the finalize method to dispatch to the subclasses'
50     // destructor. This can be removed once the MutableStylePropertySet's OwnPtr is moved
51     // to the heap.
52     void finalizeGarbageCollectedObject();
53 #else
54     // Override RefCounted's deref() to ensure operator delete is called on
55     // the appropriate subclass type.
56     void deref();
57 #endif
58
59     class PropertyReference {
60     public:
61         PropertyReference(const StylePropertySet& propertySet, unsigned index)
62             : m_propertySet(propertySet)
63             , m_index(index)
64         {
65         }
66
67         CSSPropertyID id() const { return static_cast<CSSPropertyID>(propertyMetadata().m_propertyID); }
68         CSSPropertyID shorthandID() const { return propertyMetadata().shorthandID(); }
69
70         bool isImportant() const { return propertyMetadata().m_important; }
71         bool isInherited() const { return propertyMetadata().m_inherited; }
72         bool isImplicit() const { return propertyMetadata().m_implicit; }
73
74         String cssName() const;
75         String cssText() const;
76
77         const CSSValue* value() const { return propertyValue(); }
78         // FIXME: We should try to remove this mutable overload.
79         CSSValue* value() { return const_cast<CSSValue*>(propertyValue()); }
80
81         // FIXME: Remove this.
82         CSSProperty toCSSProperty() const { return CSSProperty(propertyMetadata(), const_cast<CSSValue*>(propertyValue())); }
83
84         const StylePropertyMetadata& propertyMetadata() const;
85
86     private:
87         const CSSValue* propertyValue() const;
88
89         const StylePropertySet& m_propertySet;
90         unsigned m_index;
91     };
92
93     unsigned propertyCount() const;
94     bool isEmpty() const;
95     PropertyReference propertyAt(unsigned index) const { return PropertyReference(*this, index); }
96     int findPropertyIndex(CSSPropertyID) const;
97
98     PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
99     String getPropertyValue(CSSPropertyID) const;
100
101     bool propertyIsImportant(CSSPropertyID) const;
102     CSSPropertyID getPropertyShorthand(CSSPropertyID) const;
103     bool isPropertyImplicit(CSSPropertyID) const;
104
105     PassRefPtrWillBeRawPtr<MutableStylePropertySet> copyBlockProperties() const;
106
107     CSSParserMode cssParserMode() const { return static_cast<CSSParserMode>(m_cssParserMode); }
108
109     PassRefPtrWillBeRawPtr<MutableStylePropertySet> mutableCopy() const;
110     PassRefPtr<ImmutableStylePropertySet> immutableCopyIfNeeded() const;
111
112     PassRefPtrWillBeRawPtr<MutableStylePropertySet> copyPropertiesInSet(const Vector<CSSPropertyID>&) const;
113
114     String asText() const;
115
116     bool isMutable() const { return m_isMutable; }
117
118     bool hasFailedOrCanceledSubresources() const;
119
120     static unsigned averageSizeInBytes();
121
122 #ifndef NDEBUG
123     void showStyle();
124 #endif
125
126     bool propertyMatches(CSSPropertyID, const CSSValue*) const;
127
128     void trace(Visitor*);
129     void traceAfterDispatch(Visitor*) { }
130
131 protected:
132
133     enum { MaxArraySize = (1 << 28) - 1 };
134
135     StylePropertySet(CSSParserMode cssParserMode)
136         : m_cssParserMode(cssParserMode)
137         , m_isMutable(true)
138         , m_arraySize(0)
139     { }
140
141     StylePropertySet(CSSParserMode cssParserMode, unsigned immutableArraySize)
142         : m_cssParserMode(cssParserMode)
143         , m_isMutable(false)
144         , m_arraySize(std::min(immutableArraySize, unsigned(MaxArraySize)))
145     { }
146
147     unsigned m_cssParserMode : 3;
148     mutable unsigned m_isMutable : 1;
149     unsigned m_arraySize : 28;
150
151     friend class PropertySetCSSStyleDeclaration;
152 };
153
154 class ImmutableStylePropertySet : public StylePropertySet {
155 public:
156     ~ImmutableStylePropertySet();
157     static PassRefPtr<ImmutableStylePropertySet> create(const CSSProperty* properties, unsigned count, CSSParserMode);
158
159     unsigned propertyCount() const { return m_arraySize; }
160
161     const RawPtrWillBeMember<CSSValue>* valueArray() const;
162     const StylePropertyMetadata* metadataArray() const;
163     int findPropertyIndex(CSSPropertyID) const;
164
165     void traceAfterDispatch(Visitor*);
166
167     void* operator new(std::size_t, void* location)
168     {
169         return location;
170     }
171
172     void* m_storage;
173
174 private:
175     ImmutableStylePropertySet(const CSSProperty*, unsigned count, CSSParserMode);
176 };
177
178 inline const RawPtrWillBeMember<CSSValue>* ImmutableStylePropertySet::valueArray() const
179 {
180     return reinterpret_cast<const RawPtrWillBeMember<CSSValue>*>(const_cast<const void**>(&(this->m_storage)));
181 }
182
183 inline const StylePropertyMetadata* ImmutableStylePropertySet::metadataArray() const
184 {
185     return reinterpret_cast<const StylePropertyMetadata*>(&reinterpret_cast<const char*>(&(this->m_storage))[m_arraySize * sizeof(RawPtrWillBeMember<CSSValue>)]);
186 }
187
188 DEFINE_TYPE_CASTS(ImmutableStylePropertySet, StylePropertySet, set, !set->isMutable(), !set.isMutable());
189
190 inline ImmutableStylePropertySet* toImmutableStylePropertySet(const RefPtr<StylePropertySet>& set)
191 {
192     return toImmutableStylePropertySet(set.get());
193 }
194
195 class MutableStylePropertySet : public StylePropertySet {
196 public:
197     ~MutableStylePropertySet() { }
198     static PassRefPtrWillBeRawPtr<MutableStylePropertySet> create(CSSParserMode = HTMLQuirksMode);
199     static PassRefPtrWillBeRawPtr<MutableStylePropertySet> create(const CSSProperty* properties, unsigned count);
200
201     unsigned propertyCount() const { return m_propertyVector.size(); }
202
203     void addParsedProperties(const WillBeHeapVector<CSSProperty, 256>&);
204     void 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, PassRefPtrWillBeRawPtr<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     void appendPrefixingVariantProperty(const CSSProperty&);
214     void setPrefixingVariantProperty(const CSSProperty&);
215     void setProperty(const CSSProperty&, CSSProperty* slot = 0);
216
217     bool removeProperty(CSSPropertyID, String* returnText = 0);
218     void removePrefixedOrUnprefixedProperty(CSSPropertyID);
219     void removeBlockProperties();
220     bool removePropertiesInSet(const CSSPropertyID* set, unsigned length);
221     void removeEquivalentProperties(const StylePropertySet*);
222     void removeEquivalentProperties(const CSSStyleDeclaration*);
223
224     void mergeAndOverrideOnConflict(const StylePropertySet*);
225
226     void clear();
227     void parseDeclaration(const String& styleDeclaration, StyleSheetContents* contextStyleSheet);
228
229     CSSStyleDeclaration* ensureCSSStyleDeclaration();
230     int findPropertyIndex(CSSPropertyID) const;
231
232     void traceAfterDispatch(Visitor*);
233
234 private:
235     explicit MutableStylePropertySet(CSSParserMode);
236     explicit MutableStylePropertySet(const StylePropertySet&);
237     MutableStylePropertySet(const CSSProperty* properties, unsigned count);
238
239     bool removeShorthandProperty(CSSPropertyID);
240     CSSProperty* findCSSPropertyWithID(CSSPropertyID);
241     OwnPtrWillBeMember<PropertySetCSSStyleDeclaration> m_cssomWrapper;
242
243     friend class StylePropertySet;
244
245     WillBeHeapVector<CSSProperty, 4> m_propertyVector;
246 };
247
248 DEFINE_TYPE_CASTS(MutableStylePropertySet, StylePropertySet, set, set->isMutable(), set.isMutable());
249
250 inline MutableStylePropertySet* toMutableStylePropertySet(const RefPtr<StylePropertySet>& set)
251 {
252     return toMutableStylePropertySet(set.get());
253 }
254
255 inline const StylePropertyMetadata& StylePropertySet::PropertyReference::propertyMetadata() const
256 {
257     if (m_propertySet.isMutable())
258         return toMutableStylePropertySet(m_propertySet).m_propertyVector.at(m_index).metadata();
259     return toImmutableStylePropertySet(m_propertySet).metadataArray()[m_index];
260 }
261
262 inline const CSSValue* StylePropertySet::PropertyReference::propertyValue() const
263 {
264     if (m_propertySet.isMutable())
265         return toMutableStylePropertySet(m_propertySet).m_propertyVector.at(m_index).value();
266     return toImmutableStylePropertySet(m_propertySet).valueArray()[m_index];
267 }
268
269 inline unsigned StylePropertySet::propertyCount() const
270 {
271     if (m_isMutable)
272         return toMutableStylePropertySet(this)->m_propertyVector.size();
273     return m_arraySize;
274 }
275
276 inline bool StylePropertySet::isEmpty() const
277 {
278     return !propertyCount();
279 }
280
281 #if !ENABLE(OILPAN)
282 inline void StylePropertySet::deref()
283 {
284     if (!derefBase())
285         return;
286
287     if (m_isMutable)
288         delete toMutableStylePropertySet(this);
289     else
290         delete toImmutableStylePropertySet(this);
291 }
292 #endif // !ENABLE(OILPAN)
293
294 inline int StylePropertySet::findPropertyIndex(CSSPropertyID propertyID) const
295 {
296     if (m_isMutable)
297         return toMutableStylePropertySet(this)->findPropertyIndex(propertyID);
298     return toImmutableStylePropertySet(this)->findPropertyIndex(propertyID);
299 }
300
301 } // namespace WebCore
302
303 #endif // StylePropertySet_h