File indexing completed on 2024-04-28 15:22:43

0001 /*
0002  * This file is part of the DOM implementation for KDE.
0003  *
0004  * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
0005  *           (C) 2004, 2005, 2006 Apple Computer, Inc.
0006  *           (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
0007  *
0008  * This library is free software; you can redistribute it and/or
0009  * modify it under the terms of the GNU Library General Public
0010  * License as published by the Free Software Foundation; either
0011  * version 2 of the License, or (at your option) any later version.
0012  *
0013  * This library is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * Library General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU Library General Public License
0019  * along with this library; see the file COPYING.LIB.  If not, write to
0020  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021  * Boston, MA 02110-1301, USA.
0022  *
0023  */
0024 #ifndef _CSS_css_valueimpl_h_
0025 #define _CSS_css_valueimpl_h_
0026 
0027 #include "dom/css_value.h"
0028 #include "dom/dom_string.h"
0029 #include "css/css_base.h"
0030 #include "misc/loader_client.h"
0031 #include "misc/shared.h"
0032 #include "misc/enum.h"
0033 
0034 namespace khtml
0035 {
0036 class RenderStyle;
0037 class CachedImage;
0038 }
0039 
0040 namespace DOM
0041 {
0042 
0043 class CSSRuleImpl;
0044 class CSSValueImpl;
0045 class NodeImpl;
0046 class CounterImpl;
0047 class PairImpl;
0048 
0049 class CSSStyleDeclarationImpl : public StyleBaseImpl
0050 {
0051 public:
0052     CSSStyleDeclarationImpl(CSSRuleImpl *parentRule);
0053     CSSStyleDeclarationImpl(CSSRuleImpl *parentRule, QList<CSSProperty *> *lstValues);
0054     virtual ~CSSStyleDeclarationImpl();
0055 
0056     CSSStyleDeclarationImpl &operator=(const CSSStyleDeclarationImpl &);
0057 
0058     virtual unsigned long length() const;
0059     CSSRuleImpl *parentRule() const;
0060     virtual void removeProperty(int propertyID, DOM::DOMString *old = nullptr);
0061     virtual bool removePropertiesInSet(const int *set, unsigned length);
0062     virtual bool setProperty(int propertyId, const DOM::DOMString &value, bool important, int &ec);
0063     virtual bool setProperty(int propertyId, const DOM::DOMString &value, bool important = false);
0064     virtual void setProperty(int propertyId, int value, bool important = false);
0065     virtual void clear();
0066     // this treats integers as pixels!
0067     // needed for conversion of html attributes
0068     virtual void setLengthProperty(int id, const DOM::DOMString &value, bool important, bool multiLength = false);
0069 
0070     void setProperty(const DOMString &propertyName, const DOMString &value, const DOMString &priority);
0071     DOMString removeProperty(const DOMString &propertyName);
0072 
0073     // add a whole, unparsed property
0074     virtual void setProperty(const DOMString &propertyString);
0075     virtual DOM::DOMString item(unsigned long index) const;
0076 
0077     DOM::DOMString cssText() const;
0078     void setCssText(const DOM::DOMString &str);
0079 
0080     bool isStyleDeclaration() const override
0081     {
0082         return true;
0083     }
0084     virtual bool isPropertyImplicit(int propertyID) const;
0085     bool parseString(const DOMString &string, bool = false) override;
0086 
0087     CSSValueImpl *getPropertyCSSValue(const DOMString &propertyName) const;
0088     DOMString getPropertyValue(const DOMString &propertyName) const;
0089     DOMString getPropertyPriority(const DOMString &propertyName) const;
0090 
0091     virtual CSSValueImpl *getPropertyCSSValue(int propertyID) const;
0092     virtual DOMString getPropertyValue(int propertyID) const;
0093     virtual bool getPropertyPriority(int propertyID) const;
0094 
0095     QList<CSSProperty *> *values() const
0096     {
0097         return m_lstValues;
0098     }
0099     void setNode(NodeImpl *_node)
0100     {
0101         m_node = _node;
0102     }
0103 
0104     virtual void setChanged();
0105 
0106 protected:
0107     DOMString getShortHandValue(const int *properties, int number) const;
0108     DOMString getCommonValue(const int *properties, int number) const;
0109     DOMString getLayeredShortHandValue(const int *properties, unsigned number) const;
0110     DOMString get4Values(const int *properties) const;
0111 
0112     QList<CSSProperty *> *m_lstValues;
0113     NodeImpl *m_node;
0114 
0115 private:
0116     // currently not needed - make sure it is not used
0117     CSSStyleDeclarationImpl(const CSSStyleDeclarationImpl &o);
0118 };
0119 
0120 class CSSInlineStyleDeclarationImpl : public CSSStyleDeclarationImpl
0121 {
0122 public:
0123     CSSInlineStyleDeclarationImpl(CSSRuleImpl *parentRule): CSSStyleDeclarationImpl(parentRule) {}
0124     void setChanged() override;
0125     void updateFromAttribute(const DOMString &value);
0126 };
0127 
0128 class CSSValueImpl : public StyleBaseImpl
0129 {
0130 public:
0131     CSSValueImpl() : StyleBaseImpl() {}
0132 
0133     virtual unsigned short cssValueType() const = 0;
0134 
0135     virtual DOM::DOMString cssText() const = 0;
0136     void setCssText(const DOM::DOMString &) { } // FIXME: Not implemented.
0137 
0138     bool isValue() const override
0139     {
0140         return true;
0141     }
0142     virtual bool isFontValue() const
0143     {
0144         return false;
0145     }
0146     virtual bool isImplicitInitialValue() const
0147     {
0148         return false;
0149     }
0150 };
0151 
0152 class CSSInheritedValueImpl : public CSSValueImpl
0153 {
0154 public:
0155     CSSInheritedValueImpl() : CSSValueImpl() {}
0156     virtual ~CSSInheritedValueImpl() {}
0157 
0158     unsigned short cssValueType() const override;
0159     DOM::DOMString cssText() const override;
0160 };
0161 
0162 class CSSInitialValueImpl : public CSSValueImpl
0163 {
0164 public:
0165     CSSInitialValueImpl(bool implicit)
0166         : m_implicit(implicit)
0167     {}
0168     unsigned short cssValueType() const override;
0169     DOM::DOMString cssText() const override;
0170 
0171     bool isImplicitInitialValue() const override
0172     {
0173         return m_implicit;
0174     }
0175 private:
0176     bool m_implicit; // whether this property has been created implicitly to fill undeclared properties
0177     // of a shorthand (e.g. 'border-top-width: medium' set from the 'border: solid red' declaration)
0178 };
0179 
0180 class CSSValueListImpl : public CSSValueImpl
0181 {
0182 public:
0183     enum Separator {
0184         Space,
0185         Comma
0186     };
0187 
0188     CSSValueListImpl() : CSSValueImpl(), m_separator(Space) {}
0189     CSSValueListImpl(Separator sep) : CSSValueImpl(), m_separator(sep) {}
0190 
0191     virtual ~CSSValueListImpl();
0192 
0193     unsigned long length() const
0194     {
0195         return m_values.count();
0196     }
0197     CSSValueImpl *item(unsigned long index)
0198     {
0199         return  index < length() ? m_values.at(index) : nullptr;
0200     }
0201 
0202     bool isValueList() const override
0203     {
0204         return true;
0205     }
0206 
0207     unsigned short cssValueType() const override;
0208 
0209     void append(CSSValueImpl *val);
0210     DOM::DOMString cssText() const override;
0211 
0212 protected:
0213     KDE_BF_ENUM(Separator) m_separator: 1;
0214     QList<CSSValueImpl *> m_values;
0215 };
0216 
0217 class Counter;
0218 class RGBColor;
0219 class Rect;
0220 
0221 class CSSPrimitiveValueImpl : public CSSValueImpl
0222 {
0223 public:
0224     CSSPrimitiveValueImpl();
0225     CSSPrimitiveValueImpl(int ident);
0226     CSSPrimitiveValueImpl(double num, CSSPrimitiveValue::UnitTypes type);
0227     CSSPrimitiveValueImpl(const DOMString &str, CSSPrimitiveValue::UnitTypes type);
0228     CSSPrimitiveValueImpl(CounterImpl *c);
0229     CSSPrimitiveValueImpl(RectImpl *r);
0230     CSSPrimitiveValueImpl(QRgb color);
0231     CSSPrimitiveValueImpl(PairImpl *p);
0232 
0233     virtual ~CSSPrimitiveValueImpl();
0234 
0235     void cleanup();
0236 
0237     unsigned short primitiveType() const
0238     {
0239         return m_type;
0240     }
0241 
0242     /*
0243      * computes a length in pixels out of the given CSSValue. Need the RenderStyle to get
0244      * the fontinfo in case val is defined in em or ex.
0245      *
0246      * The metrics have to be a bit different for screen and printer output.
0247      * For screen output we assume 1 inch == 72 px, for printer we assume 300 dpi
0248      *
0249      * this is screen/printer dependent, so we probably need a config option for this,
0250      * and some tool to calibrate.
0251      */
0252     int computeLength(khtml::RenderStyle *style, khtml::RenderStyle *rootStyle, int logicalDpiY);
0253 
0254     double computeLengthFloat(khtml::RenderStyle *style, khtml::RenderStyle *rootStyle, int logicalDpiY);
0255 
0256     /*
0257      * rounds a computer value into integer as appropriate. This takes
0258      * care of the various 4.9999999999 type cases
0259      */
0260     static int snapValue(double result)
0261     {
0262         // Conversions are imprecise, often resulting in values of, e.g., 44.99998.  We
0263         // need to go ahead and round if we're really close to the next integer value.
0264         return (int)(result + (result < 0 ? -0.01 : +0.01));
0265     }
0266 
0267     // Retrieves an explicit resolution from the CSSValue if it contains one.
0268     // This is specific to the CSS3 Media Queries module's resolution feature.
0269     int getDPIResolution() const;
0270 
0271     // use with care!!!
0272     void setPrimitiveType(unsigned short type)
0273     {
0274         m_type = type;
0275     }
0276     void setFloatValue(unsigned short unitType, double floatValue, int &exceptioncode);
0277     double floatValue(unsigned short unitType = CSSPrimitiveValue::CSS_UNKNOWN) const
0278     {
0279         (void)unitType;
0280         return m_value.num;
0281     }
0282 
0283     void setStringValue(unsigned short stringType, const DOM::DOMString &stringValue, int &exceptioncode);
0284     DOM::DOMStringImpl *getStringValue() const
0285     {
0286         return ((m_type < CSSPrimitiveValue::CSS_STRING ||
0287                  m_type > CSSPrimitiveValue::CSS_ATTR ||
0288                  m_type == CSSPrimitiveValue::CSS_IDENT) ?  // fix IDENT
0289                 nullptr : m_value.string);
0290     }
0291     CounterImpl *getCounterValue() const
0292     {
0293         return (m_type != CSSPrimitiveValue::CSS_COUNTER ? nullptr : m_value.counter);
0294     }
0295 
0296     RectImpl *getRectValue() const
0297     {
0298         return (m_type != CSSPrimitiveValue::CSS_RECT ? nullptr : m_value.rect);
0299     }
0300 
0301     QRgb getRGBColorValue() const
0302     {
0303         return (m_type != CSSPrimitiveValue::CSS_RGBCOLOR ? 0 : m_value.rgbcolor);
0304     }
0305 
0306     PairImpl *getPairValue() const
0307     {
0308         return (m_type != CSSPrimitiveValue::CSS_PAIR ? nullptr : m_value.pair);
0309     }
0310 
0311     bool isPrimitiveValue() const override
0312     {
0313         return true;
0314     }
0315     unsigned short cssValueType() const override;
0316 
0317     int getIdent();
0318 
0319     bool parseString(const DOMString &string, bool = false) override;
0320     DOM::DOMString cssText() const override;
0321 
0322     virtual bool isQuirkValue() const
0323     {
0324         return false;
0325     }
0326 
0327 protected:
0328     int m_type;
0329     union {
0330         int ident;
0331         double num;
0332         DOM::DOMStringImpl *string;
0333         CounterImpl *counter;
0334         RectImpl *rect;
0335         QRgb rgbcolor;
0336         PairImpl *pair;
0337     } m_value;
0338 };
0339 
0340 // This value is used to handle quirky margins in reflow roots (body, td, and th) like WinIE.
0341 // The basic idea is that a stylesheet can use the value __qem (for quirky em) instead of em
0342 // in a stylesheet.  When the quirky value is used, if you're in quirks mode, the margin will
0343 // collapse away inside a table cell.
0344 class CSSQuirkPrimitiveValueImpl : public CSSPrimitiveValueImpl
0345 {
0346 public:
0347     CSSQuirkPrimitiveValueImpl(double num, CSSPrimitiveValue::UnitTypes type)
0348         : CSSPrimitiveValueImpl(num, type) {}
0349 
0350     virtual ~CSSQuirkPrimitiveValueImpl() {}
0351 
0352     bool isQuirkValue() const override
0353     {
0354         return true;
0355     }
0356 };
0357 
0358 class CounterImpl : public khtml::Shared<CounterImpl>
0359 {
0360 public:
0361     CounterImpl() : m_listStyle(0) { }
0362     DOMString identifier() const
0363     {
0364         return m_identifier;
0365     }
0366     unsigned int listStyle() const
0367     {
0368         return m_listStyle;
0369     }
0370     DOMString separator() const
0371     {
0372         return m_separator;
0373     }
0374 
0375     DOMString m_identifier;
0376     unsigned int m_listStyle;
0377     DOMString m_separator;
0378 };
0379 
0380 class RectImpl : public khtml::Shared<RectImpl>
0381 {
0382 public:
0383     RectImpl();
0384     ~RectImpl();
0385 
0386     CSSPrimitiveValueImpl *top() const
0387     {
0388         return m_top;
0389     }
0390     CSSPrimitiveValueImpl *right() const
0391     {
0392         return m_right;
0393     }
0394     CSSPrimitiveValueImpl *bottom() const
0395     {
0396         return m_bottom;
0397     }
0398     CSSPrimitiveValueImpl *left() const
0399     {
0400         return m_left;
0401     }
0402 
0403     void setTop(CSSPrimitiveValueImpl *top);
0404     void setRight(CSSPrimitiveValueImpl *right);
0405     void setBottom(CSSPrimitiveValueImpl *bottom);
0406     void setLeft(CSSPrimitiveValueImpl *left);
0407 protected:
0408     CSSPrimitiveValueImpl *m_top;
0409     CSSPrimitiveValueImpl *m_right;
0410     CSSPrimitiveValueImpl *m_bottom;
0411     CSSPrimitiveValueImpl *m_left;
0412 };
0413 
0414 // A primitive value representing a pair.  This is useful for properties like border-radius, background-size/position,
0415 // and border-spacing (all of which are space-separated sets of two values).  At the moment we are only using it for
0416 // border-radius and background-size, but (FIXME) border-spacing and background-position could be converted over to use
0417 // it (eliminating some extra -webkit- internal properties).
0418 class PairImpl : public khtml::Shared<PairImpl>
0419 {
0420 public:
0421     PairImpl() : m_first(nullptr), m_second(nullptr) { }
0422     PairImpl(CSSPrimitiveValueImpl *first, CSSPrimitiveValueImpl *second)
0423         : m_first(first), m_second(second)
0424     {
0425         if (first) {
0426             first->ref();
0427         } if (second) {
0428             second->ref();
0429         }
0430     }
0431     virtual ~PairImpl();
0432 
0433     CSSPrimitiveValueImpl *first() const
0434     {
0435         return m_first;
0436     }
0437     CSSPrimitiveValueImpl *second() const
0438     {
0439         return m_second;
0440     }
0441 
0442     void setFirst(CSSPrimitiveValueImpl *first);
0443     void setSecond(CSSPrimitiveValueImpl *second);
0444 
0445 protected:
0446     CSSPrimitiveValueImpl *m_first;
0447     CSSPrimitiveValueImpl *m_second;
0448 };
0449 
0450 class CSSImageValueImpl : public CSSPrimitiveValueImpl, public khtml::CachedObjectClient
0451 {
0452 public:
0453     CSSImageValueImpl(const DOMString &url, StyleBaseImpl *style);
0454     CSSImageValueImpl();
0455     virtual ~CSSImageValueImpl();
0456 
0457     khtml::CachedImage *requestCssImage(DocumentImpl *doc);
0458 protected:
0459     khtml::CachedImage *m_image;
0460     QString m_fullImageUrl;
0461 };
0462 
0463 class FontFamilyValueImpl : public CSSPrimitiveValueImpl
0464 {
0465 public:
0466     FontFamilyValueImpl(const QString &string);
0467     const QString &fontName() const
0468     {
0469         return parsedFontName;
0470     }
0471     int genericFamilyType() const
0472     {
0473         return _genericFamilyType;
0474     }
0475 protected:
0476     QString parsedFontName;
0477 private:
0478     int _genericFamilyType;
0479 };
0480 
0481 class FontValueImpl : public CSSValueImpl
0482 {
0483 public:
0484     FontValueImpl();
0485     virtual ~FontValueImpl();
0486 
0487     unsigned short cssValueType() const override
0488     {
0489         return CSSValue::CSS_CUSTOM;
0490     }
0491 
0492     DOM::DOMString cssText() const override;
0493 
0494     bool isFontValue() const override
0495     {
0496         return true;
0497     }
0498 
0499     CSSPrimitiveValueImpl *style;
0500     CSSPrimitiveValueImpl *variant;
0501     CSSPrimitiveValueImpl *weight;
0502     CSSPrimitiveValueImpl *size;
0503     CSSPrimitiveValueImpl *lineHeight;
0504     CSSValueListImpl *family;
0505 };
0506 
0507 // Used for quotes
0508 class QuotesValueImpl : public CSSValueImpl
0509 {
0510 public:
0511     QuotesValueImpl();
0512 //    virtual ~QuotesValueImpl();
0513 
0514     unsigned short cssValueType() const override
0515     {
0516         return CSSValue::CSS_CUSTOM;
0517     }
0518     DOM::DOMString cssText() const override;
0519 
0520     void addLevel(const QString &open, const QString &close);
0521     QString openQuote(int level) const;
0522     QString closeQuote(int level) const;
0523 
0524     unsigned int levels;
0525     QStringList data;
0526 };
0527 
0528 // Used for text-shadow and box-shadow
0529 class ShadowValueImpl : public CSSValueImpl
0530 {
0531 public:
0532     ShadowValueImpl(CSSPrimitiveValueImpl *_x, CSSPrimitiveValueImpl *_y,
0533                     CSSPrimitiveValueImpl *_blur, CSSPrimitiveValueImpl *_color);
0534     virtual ~ShadowValueImpl();
0535 
0536     unsigned short cssValueType() const override
0537     {
0538         return CSSValue::CSS_CUSTOM;
0539     }
0540 
0541     DOM::DOMString cssText() const override;
0542 
0543     CSSPrimitiveValueImpl *x;
0544     CSSPrimitiveValueImpl *y;
0545     CSSPrimitiveValueImpl *blur;
0546     CSSPrimitiveValueImpl *color;
0547 };
0548 
0549 // Used for counter-reset and counter-increment
0550 class CounterActImpl : public CSSValueImpl
0551 {
0552 public:
0553     CounterActImpl(const DOMString &c, short v) : m_counter(c), m_value(v) { }
0554     virtual ~CounterActImpl() {}
0555 
0556     unsigned short cssValueType() const override
0557     {
0558         return CSSValue::CSS_CUSTOM;
0559     }
0560     DOM::DOMString cssText() const override;
0561 
0562     const DOMString &counter() const
0563     {
0564         return m_counter;
0565     }
0566     short value() const
0567     {
0568         return m_value;
0569     }
0570     void setValue(const short v)
0571     {
0572         m_value = v;
0573     }
0574 
0575     DOM::DOMString m_counter;
0576     short m_value;
0577 };
0578 
0579 class CSSFontFaceSrcValueImpl : public CSSValueImpl
0580 {
0581 public:
0582     CSSFontFaceSrcValueImpl(const DOMString &resource, bool local)
0583         : m_resource(resource)
0584         , m_isLocal(local)
0585 #if 0
0586         //ENABLE(SVG_FONTS)
0587         , m_svgFontFaceElement(0)
0588 #endif
0589     {
0590     }
0591     virtual ~CSSFontFaceSrcValueImpl() { }
0592 
0593     unsigned short cssValueType() const override
0594     {
0595         return CSSValue::CSS_CUSTOM;
0596     }
0597 
0598     const DOMString &resource() const
0599     {
0600         return m_resource;
0601     }
0602     const DOMString &format() const
0603     {
0604         return m_format;
0605     }
0606     bool isLocal() const
0607     {
0608         return m_isLocal;
0609     }
0610 
0611     void setFormat(const DOMString &format)
0612     {
0613         m_format = format;
0614     }
0615 
0616     bool isSupportedFormat() const;
0617 
0618 #if 0
0619     //ENABLE(SVG_FONTS)
0620     bool isSVGFontFaceSrc() const;
0621 
0622     SVGFontFaceElement *svgFontFaceElement() const
0623     {
0624         return m_svgFontFaceElement;
0625     }
0626     void setSVGFontFaceElement(SVGFontFaceElement *element)
0627     {
0628         m_svgFontFaceElement = element;
0629     }
0630 #endif
0631 
0632     DOMString cssText() const override;
0633 
0634 private:
0635 
0636     DOMString m_resource;
0637     DOMString m_format;
0638     bool m_isLocal;
0639 
0640 #if 0
0641     //ENABLE(SVG_FONTS)
0642     SVGFontFaceElement *m_svgFontFaceElement;
0643 #endif
0644 };
0645 
0646 // ------------------------------------------------------------------------------
0647 
0648 // another helper class
0649 class CSSProperty
0650 {
0651 public:
0652     CSSProperty()
0653     {
0654         m_id = -1;
0655         m_important = false;
0656         m_value = nullptr;
0657     }
0658     CSSProperty(const CSSProperty &o)
0659     {
0660         m_id = o.m_id;
0661         m_important = o.m_important;
0662         m_value = o.m_value;
0663         if (m_value) {
0664             m_value->ref();
0665         }
0666     }
0667     ~CSSProperty()
0668     {
0669         if (m_value) {
0670             m_value->deref();
0671         }
0672     }
0673 
0674     void setValue(CSSValueImpl *val)
0675     {
0676         if (val != m_value) {
0677             if (m_value) {
0678                 m_value->deref();
0679             }
0680             m_value = val;
0681             if (m_value) {
0682                 m_value->ref();
0683             }
0684         }
0685     }
0686 
0687     int id() const
0688     {
0689         return m_id;
0690     }
0691 
0692     bool isImportant() const
0693     {
0694         return m_important;
0695     }
0696     bool isImplicit() const
0697     {
0698         return m_implicit;
0699     }
0700 
0701     CSSValueImpl *value() const
0702     {
0703         return m_value;
0704     }
0705 
0706     DOM::DOMString cssText() const;
0707 
0708     // make sure the following fits in 4 bytes.
0709     signed int  m_id   : 28;
0710     bool m_important   : 1;
0711     bool m_implicit    : 1; // whether this property has been set implicitly as part of a shorthand
0712     // (e.g. 'margin-left: 10px' set from the 'margin: 10px' declaration)
0713 protected:
0714     CSSValueImpl *m_value;
0715 };
0716 
0717 } // namespace
0718 
0719 #endif