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