File indexing completed on 2024-04-28 11:37:29
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