2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2008, 2012 Apple Inc. All rights reserved.
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.
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.
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.
21 #ifndef StylePropertySet_h
22 #define StylePropertySet_h
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"
36 class CSSStyleDeclaration;
38 class ImmutableStylePropertySet;
40 class MutableStylePropertySet;
41 class StylePropertyShorthand;
42 class StyleSheetContents;
44 class StylePropertySet : public RefCountedWillBeRefCountedGarbageCollected<StylePropertySet> {
45 friend class PropertyReference;
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
52 void finalizeGarbageCollectedObject();
54 // Override RefCounted's deref() to ensure operator delete is called on
55 // the appropriate subclass type.
59 class PropertyReference {
61 PropertyReference(const StylePropertySet& propertySet, unsigned index)
62 : m_propertySet(propertySet)
67 CSSPropertyID id() const { return static_cast<CSSPropertyID>(propertyMetadata().m_propertyID); }
68 CSSPropertyID shorthandID() const { return propertyMetadata().shorthandID(); }
70 bool isImportant() const { return propertyMetadata().m_important; }
71 bool isInherited() const { return propertyMetadata().m_inherited; }
72 bool isImplicit() const { return propertyMetadata().m_implicit; }
74 String cssName() const;
75 String cssText() const;
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()); }
81 // FIXME: Remove this.
82 CSSProperty toCSSProperty() const { return CSSProperty(propertyMetadata(), const_cast<CSSValue*>(propertyValue())); }
84 const StylePropertyMetadata& propertyMetadata() const;
87 const CSSValue* propertyValue() const;
89 const StylePropertySet& m_propertySet;
93 unsigned propertyCount() const;
95 PropertyReference propertyAt(unsigned index) const { return PropertyReference(*this, index); }
96 int findPropertyIndex(CSSPropertyID) const;
98 PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
99 String getPropertyValue(CSSPropertyID) const;
101 bool propertyIsImportant(CSSPropertyID) const;
102 CSSPropertyID getPropertyShorthand(CSSPropertyID) const;
103 bool isPropertyImplicit(CSSPropertyID) const;
105 PassRefPtrWillBeRawPtr<MutableStylePropertySet> copyBlockProperties() const;
107 CSSParserMode cssParserMode() const { return static_cast<CSSParserMode>(m_cssParserMode); }
109 PassRefPtrWillBeRawPtr<MutableStylePropertySet> mutableCopy() const;
110 PassRefPtr<ImmutableStylePropertySet> immutableCopyIfNeeded() const;
112 PassRefPtrWillBeRawPtr<MutableStylePropertySet> copyPropertiesInSet(const Vector<CSSPropertyID>&) const;
114 String asText() const;
116 bool isMutable() const { return m_isMutable; }
118 bool hasFailedOrCanceledSubresources() const;
120 static unsigned averageSizeInBytes();
126 bool propertyMatches(CSSPropertyID, const CSSValue*) const;
128 void trace(Visitor*);
129 void traceAfterDispatch(Visitor*) { }
133 enum { MaxArraySize = (1 << 28) - 1 };
135 StylePropertySet(CSSParserMode cssParserMode)
136 : m_cssParserMode(cssParserMode)
141 StylePropertySet(CSSParserMode cssParserMode, unsigned immutableArraySize)
142 : m_cssParserMode(cssParserMode)
144 , m_arraySize(std::min(immutableArraySize, unsigned(MaxArraySize)))
147 unsigned m_cssParserMode : 3;
148 mutable unsigned m_isMutable : 1;
149 unsigned m_arraySize : 28;
151 friend class PropertySetCSSStyleDeclaration;
154 class ImmutableStylePropertySet : public StylePropertySet {
156 ~ImmutableStylePropertySet();
157 static PassRefPtr<ImmutableStylePropertySet> create(const CSSProperty* properties, unsigned count, CSSParserMode);
159 unsigned propertyCount() const { return m_arraySize; }
161 const RawPtrWillBeMember<CSSValue>* valueArray() const;
162 const StylePropertyMetadata* metadataArray() const;
163 int findPropertyIndex(CSSPropertyID) const;
165 void traceAfterDispatch(Visitor*);
167 void* operator new(std::size_t, void* location)
175 ImmutableStylePropertySet(const CSSProperty*, unsigned count, CSSParserMode);
178 inline const RawPtrWillBeMember<CSSValue>* ImmutableStylePropertySet::valueArray() const
180 return reinterpret_cast<const RawPtrWillBeMember<CSSValue>*>(const_cast<const void**>(&(this->m_storage)));
183 inline const StylePropertyMetadata* ImmutableStylePropertySet::metadataArray() const
185 return reinterpret_cast<const StylePropertyMetadata*>(&reinterpret_cast<const char*>(&(this->m_storage))[m_arraySize * sizeof(RawPtrWillBeMember<CSSValue>)]);
188 DEFINE_TYPE_CASTS(ImmutableStylePropertySet, StylePropertySet, set, !set->isMutable(), !set.isMutable());
190 inline ImmutableStylePropertySet* toImmutableStylePropertySet(const RefPtr<StylePropertySet>& set)
192 return toImmutableStylePropertySet(set.get());
195 class MutableStylePropertySet : public StylePropertySet {
197 ~MutableStylePropertySet() { }
198 static PassRefPtrWillBeRawPtr<MutableStylePropertySet> create(CSSParserMode = HTMLQuirksMode);
199 static PassRefPtrWillBeRawPtr<MutableStylePropertySet> create(const CSSProperty* properties, unsigned count);
201 unsigned propertyCount() const { return m_propertyVector.size(); }
203 void addParsedProperties(const WillBeHeapVector<CSSProperty, 256>&);
204 void addParsedProperty(const CSSProperty&);
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);
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);
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*);
224 void mergeAndOverrideOnConflict(const StylePropertySet*);
227 void parseDeclaration(const String& styleDeclaration, StyleSheetContents* contextStyleSheet);
229 CSSStyleDeclaration* ensureCSSStyleDeclaration();
230 int findPropertyIndex(CSSPropertyID) const;
232 void traceAfterDispatch(Visitor*);
235 explicit MutableStylePropertySet(CSSParserMode);
236 explicit MutableStylePropertySet(const StylePropertySet&);
237 MutableStylePropertySet(const CSSProperty* properties, unsigned count);
239 bool removeShorthandProperty(CSSPropertyID);
240 CSSProperty* findCSSPropertyWithID(CSSPropertyID);
241 OwnPtrWillBeMember<PropertySetCSSStyleDeclaration> m_cssomWrapper;
243 friend class StylePropertySet;
245 WillBeHeapVector<CSSProperty, 4> m_propertyVector;
248 DEFINE_TYPE_CASTS(MutableStylePropertySet, StylePropertySet, set, set->isMutable(), set.isMutable());
250 inline MutableStylePropertySet* toMutableStylePropertySet(const RefPtr<StylePropertySet>& set)
252 return toMutableStylePropertySet(set.get());
255 inline const StylePropertyMetadata& StylePropertySet::PropertyReference::propertyMetadata() const
257 if (m_propertySet.isMutable())
258 return toMutableStylePropertySet(m_propertySet).m_propertyVector.at(m_index).metadata();
259 return toImmutableStylePropertySet(m_propertySet).metadataArray()[m_index];
262 inline const CSSValue* StylePropertySet::PropertyReference::propertyValue() const
264 if (m_propertySet.isMutable())
265 return toMutableStylePropertySet(m_propertySet).m_propertyVector.at(m_index).value();
266 return toImmutableStylePropertySet(m_propertySet).valueArray()[m_index];
269 inline unsigned StylePropertySet::propertyCount() const
272 return toMutableStylePropertySet(this)->m_propertyVector.size();
276 inline bool StylePropertySet::isEmpty() const
278 return !propertyCount();
282 inline void StylePropertySet::deref()
288 delete toMutableStylePropertySet(this);
290 delete toImmutableStylePropertySet(this);
292 #endif // !ENABLE(OILPAN)
294 inline int StylePropertySet::findPropertyIndex(CSSPropertyID propertyID) const
297 return toMutableStylePropertySet(this)->findPropertyIndex(propertyID);
298 return toImmutableStylePropertySet(this)->findPropertyIndex(propertyID);
301 } // namespace WebCore
303 #endif // StylePropertySet_h