• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "core/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:
PropertyReference(const StylePropertySet & propertySet,unsigned index)61         PropertyReference(const StylePropertySet& propertySet, unsigned index)
62             : m_propertySet(propertySet)
63             , m_index(index)
64         {
65         }
66 
id()67         CSSPropertyID id() const { return static_cast<CSSPropertyID>(propertyMetadata().m_propertyID); }
shorthandID()68         CSSPropertyID shorthandID() const { return propertyMetadata().shorthandID(); }
69 
isImportant()70         bool isImportant() const { return propertyMetadata().m_important; }
isInherited()71         bool isInherited() const { return propertyMetadata().m_inherited; }
isImplicit()72         bool isImplicit() const { return propertyMetadata().m_implicit; }
73 
74         String cssName() const;
75         String cssText() const;
76 
value()77         const CSSValue* value() const { return propertyValue(); }
78         // FIXME: We should try to remove this mutable overload.
value()79         CSSValue* value() { return const_cast<CSSValue*>(propertyValue()); }
80 
81         // FIXME: Remove this.
toCSSProperty()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;
propertyAt(unsigned index)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 
cssParserMode()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 
isMutable()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*);
traceAfterDispatch(Visitor *)129     void traceAfterDispatch(Visitor*) { }
130 
131 protected:
132 
133     enum { MaxArraySize = (1 << 28) - 1 };
134 
StylePropertySet(CSSParserMode cssParserMode)135     StylePropertySet(CSSParserMode cssParserMode)
136         : m_cssParserMode(cssParserMode)
137         , m_isMutable(true)
138         , m_arraySize(0)
139     { }
140 
StylePropertySet(CSSParserMode cssParserMode,unsigned immutableArraySize)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 
propertyCount()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 
new(std::size_t,void * location)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 
valueArray()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 
metadataArray()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 
toImmutableStylePropertySet(const RefPtr<StylePropertySet> & set)190 inline ImmutableStylePropertySet* toImmutableStylePropertySet(const RefPtr<StylePropertySet>& set)
191 {
192     return toImmutableStylePropertySet(set.get());
193 }
194 
195 class MutableStylePropertySet : public StylePropertySet {
196 public:
~MutableStylePropertySet()197     ~MutableStylePropertySet() { }
198     static PassRefPtrWillBeRawPtr<MutableStylePropertySet> create(CSSParserMode = HTMLQuirksMode);
199     static PassRefPtrWillBeRawPtr<MutableStylePropertySet> create(const CSSProperty* properties, unsigned count);
200 
propertyCount()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 
toMutableStylePropertySet(const RefPtr<StylePropertySet> & set)250 inline MutableStylePropertySet* toMutableStylePropertySet(const RefPtr<StylePropertySet>& set)
251 {
252     return toMutableStylePropertySet(set.get());
253 }
254 
propertyMetadata()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 
propertyValue()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 
propertyCount()269 inline unsigned StylePropertySet::propertyCount() const
270 {
271     if (m_isMutable)
272         return toMutableStylePropertySet(this)->m_propertyVector.size();
273     return m_arraySize;
274 }
275 
isEmpty()276 inline bool StylePropertySet::isEmpty() const
277 {
278     return !propertyCount();
279 }
280 
281 #if !ENABLE(OILPAN)
deref()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 
findPropertyIndex(CSSPropertyID propertyID)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
304