Reviewed by John
[WebKit-https.git] / WebCore / khtml / css / css_valueimpl.h
1 /*
2  * This file is part of the DOM implementation for KDE.
3  *
4  * (C) 1999-2003 Lars Knoll (knoll@kde.org)
5  * Copyright (C) 2004 Apple Computer, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #ifndef _CSS_css_valueimpl_h_
24 #define _CSS_css_valueimpl_h_
25
26 #include "dom/css_value.h"
27 #include "css/css_base.h"
28 #include "misc/loader_client.h"
29 #include <qvaluelist.h>
30
31 namespace khtml {
32     class RenderStyle;
33     class CachedImage;
34     class DocLoader;
35 }
36
37 namespace DOM {
38
39 class CSSMutableStyleDeclarationImpl;
40 class CounterImpl;
41
42 extern const int inheritableProperties[];
43 extern const unsigned numInheritableProperties;
44
45 class CSSStyleDeclarationImpl : public StyleBaseImpl
46 {
47 public:
48     virtual bool isStyleDeclaration();
49
50     CSSRuleImpl *parentRule() const;
51
52     virtual DOMString cssText() const = 0;
53     virtual void setCssText(const DOMString &, int &exceptionCode) = 0;
54
55     virtual unsigned long length() const = 0;
56     virtual DOMString item(unsigned long index) const = 0;
57
58     virtual CSSValueImpl *getPropertyCSSValue(int propertyID) const = 0;
59     virtual DOMString getPropertyValue(int propertyID) const = 0;
60     virtual bool getPropertyPriority(int propertyID) const = 0;
61
62     virtual void setProperty(int propertyId, const DOMString &value, bool important, int &exceptionCode) = 0;
63     virtual DOMString removeProperty(int propertyID, int &exceptionCode) = 0;
64
65     virtual CSSMutableStyleDeclarationImpl *copy() const = 0;
66     virtual CSSMutableStyleDeclarationImpl *makeMutable() = 0;
67  
68     void diff(CSSMutableStyleDeclarationImpl *) const;
69
70     CSSMutableStyleDeclarationImpl *copyPropertiesInSet(const int *set, unsigned length) const;
71
72 protected:
73     CSSStyleDeclarationImpl(CSSRuleImpl *parentRule = 0);
74
75
76 private:
77     CSSStyleDeclarationImpl(const CSSStyleDeclarationImpl &);
78     CSSStyleDeclarationImpl& operator=(const CSSStyleDeclarationImpl &);
79 };
80
81 class CSSValueImpl : public StyleBaseImpl
82 {
83 public:
84     virtual unsigned short cssValueType() const = 0;
85     virtual DOMString cssText() const = 0;
86
87     virtual bool isValue() { return true; }
88     virtual bool isFontValue() { return false; }
89 };
90
91 class CSSInheritedValueImpl : public CSSValueImpl
92 {
93 public:
94     virtual unsigned short cssValueType() const;
95     virtual DOMString cssText() const;
96 };
97
98 class CSSInitialValueImpl : public CSSValueImpl
99 {
100 public:
101     virtual unsigned short cssValueType() const;
102     virtual DOMString cssText() const;
103 };
104
105 class CSSValueListImpl : public CSSValueImpl
106 {
107 public:
108     CSSValueListImpl();
109
110     virtual ~CSSValueListImpl();
111
112     unsigned long length() const { return m_values.count(); }
113     CSSValueImpl *item ( unsigned long index ) { return m_values.at(index); }
114
115     virtual bool isValueList() { return true; }
116
117     virtual unsigned short cssValueType() const;
118
119     void append(CSSValueImpl *val);
120     virtual DOMString cssText() const;
121
122 protected:
123     QPtrList<CSSValueImpl> m_values;
124 };
125
126
127 class Counter;
128 class RGBColor;
129 class Rect;
130 class DashboardRegionImpl;
131
132 class CSSPrimitiveValueImpl : public CSSValueImpl
133 {
134 public:
135     CSSPrimitiveValueImpl();
136     CSSPrimitiveValueImpl(int ident);
137     CSSPrimitiveValueImpl(double num, CSSPrimitiveValue::UnitTypes type);
138     CSSPrimitiveValueImpl(const DOMString &str, CSSPrimitiveValue::UnitTypes type);
139     CSSPrimitiveValueImpl(const Counter &c);
140     CSSPrimitiveValueImpl(RectImpl *r);
141     CSSPrimitiveValueImpl(DashboardRegionImpl *r);
142     CSSPrimitiveValueImpl(QRgb color);
143
144     virtual ~CSSPrimitiveValueImpl();
145
146     void cleanup();
147
148     unsigned short primitiveType() const {
149             return m_type;
150     }
151
152     /*
153      * computes a length in pixels out of the given CSSValue. Need the RenderStyle to get
154      * the fontinfo in case val is defined in em or ex.
155      *
156      * The metrics have to be a bit different for screen and printer output.
157      * For screen output we assume 1 inch == 72 px, for printer we assume 300 dpi
158      *
159      * this is screen/printer dependent, so we probably need a config option for this,
160      * and some tool to calibrate.
161      */
162     int computeLength( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics );
163     int computeLength( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics, double multiplier );
164     double computeLengthFloat( khtml::RenderStyle *style, QPaintDeviceMetrics *devMetrics,
165                                bool applyZoomFactor = true );
166
167     // use with care!!!
168     void setPrimitiveType(unsigned short type) { m_type = type; }
169     void setFloatValue ( unsigned short unitType, double floatValue, int &exceptioncode );
170     double getFloatValue ( unsigned short/* unitType */) const {
171         return m_value.num;
172     }
173
174     void setStringValue ( unsigned short stringType, const DOM::DOMString &stringValue, int &exceptioncode );
175     DOM::DOMString getStringValue() const;
176     
177     CounterImpl *getCounterValue () const {
178         return ( m_type != CSSPrimitiveValue::CSS_COUNTER ? 0 : m_value.counter );
179     }
180
181     RectImpl *getRectValue () const {
182         return ( m_type != CSSPrimitiveValue::CSS_RECT ? 0 : m_value.rect );
183     }
184
185     QRgb getRGBColorValue () const {
186         return ( m_type != CSSPrimitiveValue::CSS_RGBCOLOR ? 0 : m_value.rgbcolor );
187     }
188
189 #if APPLE_CHANGES
190     DashboardRegionImpl *getDashboardRegionValue () const {
191         return ( m_type != CSSPrimitiveValue::CSS_DASHBOARD_REGION ? 0 : m_value.region );
192     }
193 #endif
194
195     virtual bool isPrimitiveValue() const { return true; }
196     virtual unsigned short cssValueType() const;
197
198     int getIdent();
199
200     virtual bool parseString( const DOMString &string, bool = false);
201     virtual DOMString cssText() const;
202
203     virtual bool isQuirkValue() { return false; }
204
205 protected:
206     int m_type;
207     union {
208         int ident;
209         double num;
210         DOMStringImpl *string;
211         CounterImpl *counter;
212         RectImpl *rect;
213         QRgb rgbcolor;
214         DashboardRegionImpl *region;
215     } m_value;
216 };
217
218 // This value is used to handle quirky margins in reflow roots (body, td, and th) like WinIE.
219 // The basic idea is that a stylesheet can use the value __qem (for quirky em) instead of em
220 // in a stylesheet.  When the quirky value is used, if you're in quirks mode, the margin will
221 // collapse away inside a table cell.
222 class CSSQuirkPrimitiveValueImpl : public CSSPrimitiveValueImpl
223 {
224 public:
225     CSSQuirkPrimitiveValueImpl(double num, CSSPrimitiveValue::UnitTypes type)
226       :CSSPrimitiveValueImpl(num, type) {}
227
228     virtual bool isQuirkValue() { return true; }
229 };
230
231 class CounterImpl : public khtml::Shared<CounterImpl> {
232 public:
233     DOMString identifier() const { return m_identifier; }
234     DOMString listStyle() const { return m_listStyle; }
235     DOMString separator() const { return m_separator; }
236
237     DOMString m_identifier;
238     DOMString m_listStyle;
239     DOMString m_separator;
240 };
241
242 class RectImpl : public khtml::Shared<RectImpl> {
243 public:
244     RectImpl();
245     virtual ~RectImpl();
246
247     CSSPrimitiveValueImpl *top() { return m_top; }
248     CSSPrimitiveValueImpl *right() { return m_right; }
249     CSSPrimitiveValueImpl *bottom() { return m_bottom; }
250     CSSPrimitiveValueImpl *left() { return m_left; }
251
252     void setTop( CSSPrimitiveValueImpl *top );
253     void setRight( CSSPrimitiveValueImpl *right );
254     void setBottom( CSSPrimitiveValueImpl *bottom );
255     void setLeft( CSSPrimitiveValueImpl *left );
256 protected:
257     CSSPrimitiveValueImpl *m_top;
258     CSSPrimitiveValueImpl *m_right;
259     CSSPrimitiveValueImpl *m_bottom;
260     CSSPrimitiveValueImpl *m_left;
261 };
262
263 #if APPLE_CHANGES
264
265 class DashboardRegionImpl : public RectImpl {
266 public:
267     DashboardRegionImpl() : m_next(0), m_isCircle(0), m_isRectangle(0) { }
268     ~DashboardRegionImpl() {
269         if (m_next)
270             m_next->deref();
271     }
272
273     void setNext (DashboardRegionImpl *next)
274     {
275         if (next) next->ref();
276         if (m_next) m_next->deref();
277         m_next = next;
278     }
279     
280 public:
281     DashboardRegionImpl *m_next;
282     QString m_label;
283     QString m_geometryType;
284     unsigned int m_isCircle:1;
285     unsigned int m_isRectangle:1;
286 };
287
288 #endif
289
290 class CSSImageValueImpl : public CSSPrimitiveValueImpl, public khtml::CachedObjectClient
291 {
292 public:
293     CSSImageValueImpl();
294     CSSImageValueImpl(const DOMString &url, StyleBaseImpl *style);
295     virtual ~CSSImageValueImpl();
296
297     khtml::CachedImage *image(khtml::DocLoader* loader);
298
299 protected:
300     khtml::CachedImage* m_image;
301     bool m_accessedImage;
302 };
303
304 class FontFamilyValueImpl : public CSSPrimitiveValueImpl
305 {
306 public:
307     FontFamilyValueImpl( const QString &string);
308     const QString &fontName() const { return parsedFontName; }
309     int genericFamilyType() const { return _genericFamilyType; }
310
311     virtual DOMString cssText() const;
312
313     QString parsedFontName;
314 private:
315     int _genericFamilyType;
316 };
317
318 class FontValueImpl : public CSSValueImpl
319 {
320 public:
321     FontValueImpl();
322     virtual ~FontValueImpl();
323
324     virtual unsigned short cssValueType() const { return CSSValue::CSS_CUSTOM; }
325     
326     virtual DOMString cssText() const;
327     
328     virtual bool isFontValue() { return true; }
329
330     CSSPrimitiveValueImpl *style;
331     CSSPrimitiveValueImpl *variant;
332     CSSPrimitiveValueImpl *weight;
333     CSSPrimitiveValueImpl *size;
334     CSSPrimitiveValueImpl *lineHeight;
335     CSSValueListImpl *family;
336 };
337
338 // Used for text-shadow and box-shadow
339 class ShadowValueImpl : public CSSValueImpl
340 {
341 public:
342     ShadowValueImpl(CSSPrimitiveValueImpl* _x, CSSPrimitiveValueImpl* _y,
343                     CSSPrimitiveValueImpl* _blur, CSSPrimitiveValueImpl* _color);
344     virtual ~ShadowValueImpl();
345
346     virtual unsigned short cssValueType() const { return CSSValue::CSS_CUSTOM; }
347
348     virtual DOMString cssText() const;
349
350     CSSPrimitiveValueImpl* x;
351     CSSPrimitiveValueImpl* y;
352     CSSPrimitiveValueImpl* blur;
353     CSSPrimitiveValueImpl* color;
354 };
355
356 // Used by box-flex-group-transition
357 class FlexGroupTransitionValueImpl : public CSSValueImpl
358 {
359 public:
360     FlexGroupTransitionValueImpl();
361     FlexGroupTransitionValueImpl(unsigned int _group1, 
362                                  unsigned int _group2,
363                                  CSSPrimitiveValueImpl* _length);
364     virtual ~FlexGroupTransitionValueImpl();
365     
366     virtual unsigned short cssValueType() const { return CSSValue::CSS_CUSTOM; }
367     
368     virtual DOMString cssText() const;
369     
370     bool isAuto() const { return autoValue; }
371
372     bool autoValue;
373     unsigned int group1;
374     unsigned int group2;
375     CSSPrimitiveValueImpl* length;
376 };
377
378 // ------------------------------------------------------------------------------
379
380 // another helper class
381 class CSSProperty
382 {
383 public:
384     CSSProperty() : m_id(-1), m_bImportant(false), m_value(0)
385     {
386     }
387     CSSProperty(int propID, CSSValueImpl *value, bool important = false)
388         : m_id(propID), m_bImportant(important), m_value(value)
389     {
390         if (value) value->ref();
391     }
392     CSSProperty(const CSSProperty& o)
393     {
394         m_id = o.m_id;
395         m_bImportant = o.m_bImportant;
396         m_value = o.m_value;
397         if (m_value) m_value->ref();
398     }
399     CSSProperty &operator=(const CSSProperty& o)
400     {
401         if (o.m_value) o.m_value->ref();
402         if (m_value) m_value->deref();
403         m_id = o.m_id;
404         m_bImportant = o.m_bImportant;
405         m_value = o.m_value;
406         return *this;
407     }
408     ~CSSProperty() {
409         if(m_value) m_value->deref();
410     }
411
412     void setValue(CSSValueImpl *val) {
413         if (val) val->ref();
414         if (m_value) m_value->deref();
415         m_value = val;
416     }
417
418     int id() const { return m_id; }
419     bool isImportant() const { return m_bImportant; }
420     CSSValueImpl *value() const { return m_value; }
421     
422     DOMString cssText() const;
423
424     // make sure the following fits in 4 bytes.
425     int  m_id;
426     bool m_bImportant;
427
428     friend bool operator==(const CSSProperty &, const CSSProperty &);
429
430 protected:
431     CSSValueImpl *m_value;
432 };
433
434 class CSSMutableStyleDeclarationImpl : public CSSStyleDeclarationImpl
435 {
436 public:
437     CSSMutableStyleDeclarationImpl();
438     CSSMutableStyleDeclarationImpl(CSSRuleImpl *parentRule);
439     CSSMutableStyleDeclarationImpl(CSSRuleImpl *parentRule, const QValueList<CSSProperty> &);
440     CSSMutableStyleDeclarationImpl(CSSRuleImpl *parentRule, const CSSProperty * const *, int numProperties);
441     virtual ~CSSMutableStyleDeclarationImpl();
442
443     CSSMutableStyleDeclarationImpl &operator=(const CSSMutableStyleDeclarationImpl &);
444
445     void setNode(NodeImpl *node) { m_node = node; }
446
447     virtual DOMString cssText() const;
448     virtual void setCssText(const DOMString &, int &exceptionCode);
449
450     virtual unsigned long length() const;
451     virtual DOMString item(unsigned long index) const;
452
453     virtual CSSValueImpl *getPropertyCSSValue(int propertyID) const;
454     virtual DOMString getPropertyValue(int propertyID) const;
455     virtual bool getPropertyPriority(int propertyID) const;
456
457     virtual void setProperty(int propertyId, const DOMString &value, bool important, int &exceptionCode);
458     virtual DOMString removeProperty(int propertyID, int &exceptionCode);
459
460     virtual CSSMutableStyleDeclarationImpl *copy() const;
461     virtual CSSMutableStyleDeclarationImpl *makeMutable();
462
463     QValueListConstIterator<CSSProperty> valuesIterator() const { return m_values.begin(); }
464
465     bool setProperty(int propertyID, int value, bool important = false, bool notifyChanged = true);
466     bool setProperty(int propertyID, const DOMString &value, bool important, bool notifyChanged, int &exceptionCode);
467     bool setProperty(int propertyId, const DOMString &value, bool important = false, bool notifyChanged = true)
468         { int exceptionCode; return setProperty(propertyId, value, important, notifyChanged, exceptionCode); }
469
470     DOMString removeProperty(int propertyID, bool notifyChanged, int &exceptionCode);
471     DOMString removeProperty(int propertyID, bool notifyChanged = true)
472         { int exceptionCode; return removeProperty(propertyID, notifyChanged, exceptionCode); }
473
474     void clear();
475
476     void setChanged();
477  
478     // setLengthProperty treats integers as pixels! (Needed for conversion of HTML attributes.)
479     void setLengthProperty(int propertyId, const DOMString &value, bool important, bool multiLength = false);
480     void setStringProperty(int propertyId, const DOMString &value, CSSPrimitiveValue::UnitTypes, bool important = false); // parsed string value
481     void setImageProperty(int propertyId, const DOMString &URL, bool important = false);
482  
483     // The following parses an entire new style declaration.
484     void parseDeclaration(const DOMString &styleDeclaration);
485
486     // Besides adding the properties, this also removes any existing properties with these IDs.
487     // It does no notification since it's called by the parser.
488     void addParsedProperties(const CSSProperty * const *, int numProperties);
489  
490     CSSMutableStyleDeclarationImpl *copyBlockProperties() const;
491     void removeBlockProperties();
492     void removeInheritableProperties();
493     void removePropertiesInSet(const int *set, unsigned length);
494
495     void merge(CSSMutableStyleDeclarationImpl *, bool argOverridesOnConflict = true);
496  
497 private:
498     DOMString getShortHandValue(const int* properties, int number) const;
499     DOMString get4Values(const int* properties) const;
500  
501     QValueList<CSSProperty> m_values;
502     NodeImpl *m_node;
503 };
504
505 } // namespace
506
507 #endif