1 /*
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2008 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 CSSMutableStyleDeclaration_h
22 #define CSSMutableStyleDeclaration_h
23
24 #include "CSSStyleDeclaration.h"
25 #include "CSSPrimitiveValue.h"
26 #include "CSSProperty.h"
27 #include "KURLHash.h"
28 #include "PlatformString.h"
29 #include <wtf/ListHashSet.h>
30 #include <wtf/Vector.h>
31
32 namespace WebCore {
33
34 class Node;
35
36 class CSSMutableStyleDeclarationConstIterator {
37 public:
38 CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclaration* decl, CSSProperty* current);
39 CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclarationConstIterator& o);
40 ~CSSMutableStyleDeclarationConstIterator();
41
42 const CSSProperty& operator*() const { return *m_current; }
43 const CSSProperty* operator->() const { return m_current; }
44
45 bool operator!=(const CSSMutableStyleDeclarationConstIterator& o) { ASSERT(m_decl == o.m_decl); return m_current != o.m_current; }
46 bool operator==(const CSSMutableStyleDeclarationConstIterator& o) { ASSERT(m_decl == o.m_decl); return m_current == o.m_current; }
47
48 CSSMutableStyleDeclarationConstIterator& operator=(const CSSMutableStyleDeclarationConstIterator& o);
49
50 CSSMutableStyleDeclarationConstIterator& operator++();
51 CSSMutableStyleDeclarationConstIterator& operator--();
52
53 private:
54 const CSSMutableStyleDeclaration* m_decl;
55 CSSProperty* m_current;
56 };
57
58 class CSSMutableStyleDeclaration : public CSSStyleDeclaration {
59 public:
create()60 static PassRefPtr<CSSMutableStyleDeclaration> create()
61 {
62 return adoptRef(new CSSMutableStyleDeclaration);
63 }
create(CSSRule * parentRule)64 static PassRefPtr<CSSMutableStyleDeclaration> create(CSSRule* parentRule)
65 {
66 return adoptRef(new CSSMutableStyleDeclaration(parentRule));
67 }
create(CSSRule * parentRule,const CSSProperty * const * properties,int numProperties)68 static PassRefPtr<CSSMutableStyleDeclaration> create(CSSRule* parentRule, const CSSProperty* const* properties, int numProperties)
69 {
70 return adoptRef(new CSSMutableStyleDeclaration(parentRule, properties, numProperties));
71 }
create(const Vector<CSSProperty> & properties)72 static PassRefPtr<CSSMutableStyleDeclaration> create(const Vector<CSSProperty>& properties)
73 {
74 return adoptRef(new CSSMutableStyleDeclaration(0, properties));
75 }
76
77 CSSMutableStyleDeclaration& operator=(const CSSMutableStyleDeclaration&);
78
79 typedef CSSMutableStyleDeclarationConstIterator const_iterator;
80
begin()81 const_iterator begin() { return const_iterator(this, m_properties.begin()); }
end()82 const_iterator end() { return const_iterator(this, m_properties.end()); }
83
setNode(Node * node)84 void setNode(Node* node) { m_node = node; }
85
node()86 Node* node() const { return m_node; }
87
isMutableStyleDeclaration()88 virtual bool isMutableStyleDeclaration() const { return true; }
89
90 virtual String cssText() const;
91 virtual void setCssText(const String&, ExceptionCode&);
92
93 virtual unsigned virtualLength() const;
length()94 unsigned length() const { return m_properties.size(); }
95
96 virtual String item(unsigned index) const;
97
98 virtual PassRefPtr<CSSValue> getPropertyCSSValue(int propertyID) const;
99 virtual String getPropertyValue(int propertyID) const;
100 virtual bool getPropertyPriority(int propertyID) const;
101 virtual int getPropertyShorthand(int propertyID) const;
102 virtual bool isPropertyImplicit(int propertyID) const;
103
104 virtual void setProperty(int propertyId, const String& value, bool important, ExceptionCode&);
105 virtual String removeProperty(int propertyID, ExceptionCode&);
106
107 virtual PassRefPtr<CSSMutableStyleDeclaration> copy() const;
108
109 bool setProperty(int propertyID, int value, bool important = false, bool notifyChanged = true);
110 bool setProperty(int propertyId, double value, CSSPrimitiveValue::UnitTypes, bool important = false, bool notifyChanged = true);
111 bool setProperty(int propertyID, const String& value, bool important = false, bool notifyChanged = true);
112
113 String removeProperty(int propertyID, bool notifyChanged = true, bool returnText = false);
114
115 // setLengthProperty treats integers as pixels! (Needed for conversion of HTML attributes.)
116 void setLengthProperty(int propertyId, const String& value, bool important, bool multiLength = false);
117 void setStringProperty(int propertyId, const String& value, CSSPrimitiveValue::UnitTypes, bool important = false); // parsed string value
118 void setImageProperty(int propertyId, const String& url, bool important = false);
119
120 // The following parses an entire new style declaration.
121 void parseDeclaration(const String& styleDeclaration);
122
123 // Besides adding the properties, this also removes any existing properties with these IDs.
124 // It does no notification since it's called by the parser.
125 void addParsedProperties(const CSSProperty* const *, int numProperties);
126 // This does no change notifications since it's only called by createMarkup.
127 void addParsedProperty(const CSSProperty&);
128
129 PassRefPtr<CSSMutableStyleDeclaration> copyBlockProperties() const;
130 void removeBlockProperties();
131 void removePropertiesInSet(const int* set, unsigned length, bool notifyChanged = true);
132
133 void merge(const CSSMutableStyleDeclaration*, bool argOverridesOnConflict = true);
134
setStrictParsing(bool b)135 void setStrictParsing(bool b) { m_strictParsing = b; }
useStrictParsing()136 bool useStrictParsing() const { return m_strictParsing; }
137
138 void addSubresourceStyleURLs(ListHashSet<KURL>&);
139
propertiesEqual(const CSSMutableStyleDeclaration * o)140 bool propertiesEqual(const CSSMutableStyleDeclaration* o) const { return m_properties == o->m_properties; }
141
142 bool isInlineStyleDeclaration();
143
144 protected:
145 CSSMutableStyleDeclaration(CSSRule* parentRule);
146
147 private:
148 CSSMutableStyleDeclaration();
149 CSSMutableStyleDeclaration(CSSRule* parentRule, const Vector<CSSProperty>&);
150 CSSMutableStyleDeclaration(CSSRule* parentRule, const CSSProperty* const *, int numProperties);
151
152 virtual PassRefPtr<CSSMutableStyleDeclaration> makeMutable();
153
154 void setNeedsStyleRecalc();
155
156 String getShorthandValue(const int* properties, size_t) const;
157 String getCommonValue(const int* properties, size_t) const;
158 String getLayeredShorthandValue(const int* properties, size_t) const;
159 String get4Values(const int* properties) const;
160 String borderSpacingValue(const int properties[2]) const;
161
getShorthandValue(const int (& properties)[size])162 template<size_t size> String getShorthandValue(const int (&properties)[size]) const { return getShorthandValue(properties, size); }
getCommonValue(const int (& properties)[size])163 template<size_t size> String getCommonValue(const int (&properties)[size]) const { return getCommonValue(properties, size); }
getLayeredShorthandValue(const int (& properties)[size])164 template<size_t size> String getLayeredShorthandValue(const int (&properties)[size]) const { return getLayeredShorthandValue(properties, size); }
165
166 void setPropertyInternal(const CSSProperty&, CSSProperty* slot = 0);
167 bool removeShorthandProperty(int propertyID, bool notifyChanged);
168
169 Vector<CSSProperty>::const_iterator findPropertyWithId(int propertyId) const;
170 Vector<CSSProperty>::iterator findPropertyWithId(int propertyId);
171
172 Vector<CSSProperty, 4> m_properties;
173
174 Node* m_node;
175 bool m_strictParsing : 1;
176 #ifndef NDEBUG
177 unsigned m_iteratorCount : 4;
178 #endif
179
180 friend class CSSMutableStyleDeclarationConstIterator;
181 };
182
CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclaration * decl,CSSProperty * current)183 inline CSSMutableStyleDeclarationConstIterator::CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclaration* decl, CSSProperty* current)
184 : m_decl(decl)
185 , m_current(current)
186 {
187 #ifndef NDEBUG
188 const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount++;
189 #endif
190 }
191
CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclarationConstIterator & o)192 inline CSSMutableStyleDeclarationConstIterator::CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclarationConstIterator& o)
193 : m_decl(o.m_decl)
194 , m_current(o.m_current)
195 {
196 #ifndef NDEBUG
197 const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount++;
198 #endif
199 }
200
~CSSMutableStyleDeclarationConstIterator()201 inline CSSMutableStyleDeclarationConstIterator::~CSSMutableStyleDeclarationConstIterator()
202 {
203 #ifndef NDEBUG
204 const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount--;
205 #endif
206 }
207
208 inline CSSMutableStyleDeclarationConstIterator& CSSMutableStyleDeclarationConstIterator::operator=(const CSSMutableStyleDeclarationConstIterator& o)
209 {
210 m_decl = o.m_decl;
211 m_current = o.m_current;
212 #ifndef NDEBUG
213 const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount++;
214 #endif
215 return *this;
216 }
217
218 inline CSSMutableStyleDeclarationConstIterator& CSSMutableStyleDeclarationConstIterator::operator++()
219 {
220 ASSERT(m_current != const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_properties.end());
221 ++m_current;
222 return *this;
223 }
224
225 inline CSSMutableStyleDeclarationConstIterator& CSSMutableStyleDeclarationConstIterator::operator--()
226 {
227 --m_current;
228 return *this;
229 }
230
231 } // namespace WebCore
232
233 #endif // CSSMutableStyleDeclaration_h
234