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,unsigned variableDependentValueCount)72 static PassRefPtr<CSSMutableStyleDeclaration> create(const Vector<CSSProperty>& properties, unsigned variableDependentValueCount)
73 {
74 return adoptRef(new CSSMutableStyleDeclaration(0, properties, variableDependentValueCount));
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
isMutableStyleDeclaration()86 virtual bool isMutableStyleDeclaration() const { return true; }
87
88 virtual String cssText() const;
89 virtual void setCssText(const String&, ExceptionCode&);
90
91 virtual unsigned length() const;
92 virtual String item(unsigned index) const;
93
94 virtual PassRefPtr<CSSValue> getPropertyCSSValue(int propertyID) const;
95 virtual String getPropertyValue(int propertyID) const;
96 virtual bool getPropertyPriority(int propertyID) const;
97 virtual int getPropertyShorthand(int propertyID) const;
98 virtual bool isPropertyImplicit(int propertyID) const;
99
100 virtual void setProperty(int propertyId, const String& value, bool important, ExceptionCode&);
101 virtual String removeProperty(int propertyID, ExceptionCode&);
102
103 virtual PassRefPtr<CSSMutableStyleDeclaration> copy() const;
104
105 bool setProperty(int propertyID, int value, bool important = false, bool notifyChanged = true);
106 bool setProperty(int propertyID, const String& value, bool important = false, bool notifyChanged = true);
107
108 String removeProperty(int propertyID, bool notifyChanged = true, bool returnText = false);
109
110 // setLengthProperty treats integers as pixels! (Needed for conversion of HTML attributes.)
111 void setLengthProperty(int propertyId, const String& value, bool important, bool multiLength = false);
112 void setStringProperty(int propertyId, const String& value, CSSPrimitiveValue::UnitTypes, bool important = false); // parsed string value
113 void setImageProperty(int propertyId, const String& url, bool important = false);
114
115 // The following parses an entire new style declaration.
116 void parseDeclaration(const String& styleDeclaration);
117
118 // Besides adding the properties, this also removes any existing properties with these IDs.
119 // It does no notification since it's called by the parser.
120 void addParsedProperties(const CSSProperty* const *, int numProperties);
121 // This does no change notifications since it's only called by createMarkup.
122 void addParsedProperty(const CSSProperty&);
123
124 PassRefPtr<CSSMutableStyleDeclaration> copyBlockProperties() const;
125 void removeBlockProperties();
126 void removePropertiesInSet(const int* set, unsigned length, bool notifyChanged = true);
127
128 void merge(CSSMutableStyleDeclaration*, bool argOverridesOnConflict = true);
129
hasVariableDependentValue()130 bool hasVariableDependentValue() const { return m_variableDependentValueCount > 0; }
131
setStrictParsing(bool b)132 void setStrictParsing(bool b) { m_strictParsing = b; }
useStrictParsing()133 bool useStrictParsing() const { return m_strictParsing; }
134
135 void addSubresourceStyleURLs(ListHashSet<KURL>&);
136
137 protected:
138 CSSMutableStyleDeclaration(CSSRule* parentRule);
139
140 private:
141 CSSMutableStyleDeclaration();
142 CSSMutableStyleDeclaration(CSSRule* parentRule, const Vector<CSSProperty>&, unsigned variableDependentValueCount);
143 CSSMutableStyleDeclaration(CSSRule* parentRule, const CSSProperty* const *, int numProperties);
144
145 virtual PassRefPtr<CSSMutableStyleDeclaration> makeMutable();
146
147 void setNeedsStyleRecalc();
148
149 String getShorthandValue(const int* properties, int number) const;
150 String getCommonValue(const int* properties, int number) const;
151 String getLayeredShorthandValue(const int* properties, unsigned number) const;
152 String get4Values(const int* properties) const;
153
154 void setPropertyInternal(const CSSProperty&, CSSProperty* slot = 0);
155 bool removeShorthandProperty(int propertyID, bool notifyChanged);
156
157 Vector<CSSProperty>::const_iterator findPropertyWithId(int propertyId) const;
158 Vector<CSSProperty>::iterator findPropertyWithId(int propertyId);
159
160 Vector<CSSProperty, 4> m_properties;
161
162 Node* m_node;
163 unsigned m_variableDependentValueCount : 24;
164 bool m_strictParsing : 1;
165 #ifndef NDEBUG
166 unsigned m_iteratorCount : 4;
167 #endif
168
169 friend class CSSMutableStyleDeclarationConstIterator;
170 };
171
CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclaration * decl,CSSProperty * current)172 inline CSSMutableStyleDeclarationConstIterator::CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclaration* decl, CSSProperty* current)
173 : m_decl(decl)
174 , m_current(current)
175 {
176 #ifndef NDEBUG
177 const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount++;
178 #endif
179 }
180
CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclarationConstIterator & o)181 inline CSSMutableStyleDeclarationConstIterator::CSSMutableStyleDeclarationConstIterator(const CSSMutableStyleDeclarationConstIterator& o)
182 : m_decl(o.m_decl)
183 , m_current(o.m_current)
184 {
185 #ifndef NDEBUG
186 const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount++;
187 #endif
188 }
189
~CSSMutableStyleDeclarationConstIterator()190 inline CSSMutableStyleDeclarationConstIterator::~CSSMutableStyleDeclarationConstIterator()
191 {
192 #ifndef NDEBUG
193 const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount--;
194 #endif
195 }
196
197 inline CSSMutableStyleDeclarationConstIterator& CSSMutableStyleDeclarationConstIterator::operator=(const CSSMutableStyleDeclarationConstIterator& o)
198 {
199 m_decl = o.m_decl;
200 m_current = o.m_current;
201 #ifndef NDEBUG
202 const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_iteratorCount++;
203 #endif
204 return *this;
205 }
206
207 inline CSSMutableStyleDeclarationConstIterator& CSSMutableStyleDeclarationConstIterator::operator++()
208 {
209 ASSERT(m_current != const_cast<CSSMutableStyleDeclaration*>(m_decl)->m_properties.end());
210 ++m_current;
211 return *this;
212 }
213
214 inline CSSMutableStyleDeclarationConstIterator& CSSMutableStyleDeclarationConstIterator::operator--()
215 {
216 --m_current;
217 return *this;
218 }
219
220 } // namespace WebCore
221
222 #endif // CSSMutableStyleDeclaration_h
223