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