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

0001 /*
0002  * This file is part of the DOM implementation for KDE.
0003  *
0004  * Copyright 2003 Lars Knoll (knoll@kde.org)
0005  * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
0006  *
0007  * This library is free software; you can redistribute it and/or
0008  * modify it under the terms of the GNU Library General Public
0009  * License as published by the Free Software Foundation; either
0010  * version 2 of the License, or (at your option) any later version.
0011  *
0012  * This library is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  * Library General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Library General Public License
0018  * along with this library; see the file COPYING.LIB.  If not, write to
0019  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020  * Boston, MA 02110-1301, USA.
0021  */
0022 #ifndef _CSS_cssparser_h_
0023 #define _CSS_cssparser_h_
0024 
0025 #include <QString>
0026 #include <QColor>
0027 #include <QVector>
0028 #include <dom/dom_string.h>
0029 #include <misc/htmlnames.h>
0030 #include <wtf/Vector.h>
0031 #include <xml/dom_docimpl.h>
0032 
0033 namespace khtml
0034 {
0035 class MediaQuery;
0036 }
0037 
0038 namespace DOM
0039 {
0040 class StyleListImpl;
0041 class CSSStyleSheetImpl;
0042 class CSSRuleImpl;
0043 class CSSStyleRuleImpl;
0044 class DocumentImpl;
0045 class CSSValueImpl;
0046 class CSSValueListImpl;
0047 class CSSPrimitiveValueImpl;
0048 class CSSStyleDeclarationImpl;
0049 class CSSFontFaceRuleImpl;
0050 class CSSProperty;
0051 class MediaListImpl;
0052 class CSSSelector;
0053 
0054 struct ParseString {
0055     unsigned short *string;
0056     int length;
0057 };
0058 
0059 struct Value;
0060 class ValueList;
0061 
0062 struct Function {
0063     ParseString name;
0064     ValueList *args;
0065 };
0066 
0067 struct Value {
0068     int id;
0069     bool isInt;
0070     union {
0071         double fValue;
0072         int iValue;
0073         ParseString string;
0074         struct Function *function;
0075     };
0076     enum {
0077         Operator = 0x100000,
0078         Function = 0x100001,
0079         Q_EMS     = 0x100002
0080     };
0081 
0082     int unit;
0083 };
0084 
0085 static inline QString qString(const ParseString &ps)
0086 {
0087     return QString((QChar *)ps.string, ps.length);
0088 }
0089 static inline DOMString domString(const ParseString &ps)
0090 {
0091     return DOMString((QChar *)ps.string, ps.length);
0092 }
0093 
0094 class ValueList
0095 {
0096 public:
0097     ValueList() : m_current(0) { }
0098     ~ValueList();
0099     void addValue(const Value &v)
0100     {
0101         m_values.append(v);
0102     }
0103     int size() const
0104     {
0105         return m_values.size();
0106     }
0107     Value *current()
0108     {
0109         return m_current < m_values.size() ? &m_values[m_current] : nullptr;
0110     }
0111     Value *next()
0112     {
0113         ++m_current;
0114         return current();
0115     }
0116 private:
0117     QVector<Value> m_values;
0118     int m_current;
0119 };
0120 
0121 class CSSParser
0122 {
0123 public:
0124     CSSParser(bool strictParsing = true);
0125     ~CSSParser();
0126 
0127     void parseSheet(DOM::CSSStyleSheetImpl *sheet, const DOM::DOMString &string);
0128     DOM::CSSRuleImpl *parseRule(DOM::CSSStyleSheetImpl *sheet, const DOM::DOMString &string);
0129     bool parseValue(DOM::CSSStyleDeclarationImpl *decls, int id, const DOM::DOMString &string,
0130                     bool _important);
0131     bool parseDeclaration(DOM::CSSStyleDeclarationImpl *decls, const DOM::DOMString &string);
0132     bool parseMediaQuery(DOM::MediaListImpl *queries, const DOM::DOMString &string);
0133     QList<DOM::CSSSelector *> parseSelectorList(DOM::DocumentImpl *doc, const DOM::DOMString &string);
0134     // Returns an empty list on parse error.
0135 
0136     static CSSParser *current()
0137     {
0138         return currentParser;
0139     }
0140 
0141     unsigned int getLocalNameId(const DOMString &str)
0142     {
0143         LocalName localname;
0144         DOM::DocumentImpl *doc = document();
0145         if (doc && doc->isHTMLDocument()) {
0146             localname = LocalName::fromString(str, khtml::IDS_NormalizeLower);
0147         } else {
0148             localname = LocalName::fromString(str);
0149         }
0150         boundLocalNames.append(localname);
0151         return localname.id();
0152     }
0153 
0154     DOM::DocumentImpl *document() const;
0155 
0156     unsigned int defaultNamespace();
0157 
0158     void addProperty(int propId, CSSValueImpl *value, bool important);
0159     void rollbackParsedProperties(int toNumParsedProperties);
0160     bool hasProperties() const
0161     {
0162         return numParsedProperties > 0;
0163     }
0164     CSSStyleDeclarationImpl *createStyleDeclaration(CSSStyleRuleImpl *rule);
0165     CSSStyleDeclarationImpl *createFontFaceStyleDeclaration(CSSFontFaceRuleImpl *rule);
0166     void clearProperties();
0167 
0168     bool parseValue(int propId, bool important);
0169     bool parseSVGValue(int propId, bool important);
0170     bool parseShortHand(int propId, const int *properties, const int numProperties, bool important);
0171     bool parse4Values(int propId, const int *properties, bool important);
0172     bool parseContent(int propId, bool important);
0173 
0174     CSSValueImpl *parseBackgroundColor();
0175     CSSValueImpl *parseBackgroundImage(bool &didParse);
0176 
0177     enum BackgroundPosKind {
0178         BgPos_X,
0179         BgPos_Y,
0180         BgPos_NonKW,
0181         BgPos_Center
0182     };
0183 
0184     CSSValueImpl *parseBackgroundPositionXY(BackgroundPosKind &kindOut);
0185     void parseBackgroundPosition(CSSValueImpl *&value1, CSSValueImpl *&value2);
0186     CSSValueImpl *parseBackgroundSize();
0187 
0188     bool parseBackgroundProperty(int propId, int &propId1, int &propId2, CSSValueImpl *&retValue1, CSSValueImpl *&retValue2);
0189     bool parseBackgroundShorthand(bool important);
0190 
0191     void addBackgroundValue(CSSValueImpl *&lval, CSSValueImpl *rval);
0192 
0193     bool parseShape(int propId, bool important);
0194     bool parseFontShorthand(bool important);
0195     bool parseFontFaceSrc();
0196     bool parseCounter(int propId, bool increment, bool important);
0197     bool parseListStyleShorthand(bool important);
0198 
0199     // returns parsed font-weight's css value id if valid, otherwise 0 (CSS_VAL_INVALID)
0200     int parseFontWeight(Value *val, bool strict);
0201 
0202     bool parseColorParameters(Value *, int *colorValues, bool parseAlpha);
0203     bool parseHSLParameters(Value *, double *colorValues, bool parseAlpha);
0204 
0205     // returns the found property
0206     // 0 if nothing found (or ok == false)
0207     // @param forward if true, it parses the next in the list
0208     CSSValueListImpl *parseFontFamily();
0209     CSSPrimitiveValueImpl *parseColor();
0210     CSSPrimitiveValueImpl *parseColorFromValue(Value *val);
0211     CSSValueImpl *parseCounterContent(ValueList *args, bool counters);
0212 
0213     // CSS3 Parsing Routines (for properties specific to CSS3)
0214     bool parseShadow(int propId, bool important);
0215 
0216     // SVG parsing:
0217     CSSValueImpl *parseSVGStrokeDasharray();
0218     CSSValueImpl *parseSVGPaint();
0219     CSSValueImpl *parseSVGColor();
0220 private:
0221     // defines units allowed for a certain property, used in parseUnit
0222     enum Units {
0223         FUnknown   = 0x0000,
0224         FInteger   = 0x0001,
0225         FNumber    = 0x0002,  // Real Numbers
0226         FPercent   = 0x0004,
0227         FLength    = 0x0008,
0228         FAngle     = 0x0010,
0229         FTime      = 0x0020,
0230         FFrequency = 0x0040,
0231         FRelative  = 0x0100,
0232         FNonNeg    = 0x0200
0233     };
0234 
0235     bool parseBorderImage(int propId, bool important);
0236     bool parseBorderRadius(bool important);
0237 
0238     static bool validUnit(Value *value, int unitflags, bool strict);
0239 
0240 public:
0241     bool strict;
0242     bool important;
0243     unsigned int id;
0244     DOM::StyleListImpl *styleElement;
0245     mutable DOM::DocumentImpl  *styleDocument; // cached document for styleElement,
0246     // or manually set one for special parses
0247 
0248     // Outputs for specialized parses.
0249     DOM::CSSRuleImpl *rule;
0250     khtml::MediaQuery *mediaQuery;
0251     QList<DOM::CSSSelector *> selectors;
0252 
0253     ValueList *valueList;
0254     CSSProperty **parsedProperties;
0255     int numParsedProperties;
0256     int maxParsedProperties;
0257 
0258     int m_inParseShorthand;
0259     int m_currentShorthand;
0260     bool m_implicitShorthand;
0261 
0262     static CSSParser *currentParser;
0263 
0264     // tokenizer methods and data
0265 public:
0266     int lex(void *yylval);
0267     int token()
0268     {
0269         return yyTok;
0270     }
0271     unsigned short *text(int *length);
0272     int lex();
0273 private:
0274     int yyparse();
0275     void runParser();
0276     void setupParser(const char *prefix, const DOMString &string, const char *suffix);
0277 
0278     bool inShorthand() const
0279     {
0280         return m_inParseShorthand;
0281     }
0282 
0283     unsigned short *data;
0284     unsigned short *yytext;
0285     unsigned short *yy_c_buf_p;
0286     unsigned short yy_hold_char;
0287     int yy_last_accepting_state;
0288     unsigned short *yy_last_accepting_cpos;
0289     int block_nesting;
0290     int yyleng;
0291     int yyTok;
0292     int yy_start;
0293     WTF::Vector<LocalName> boundLocalNames;
0294 };
0295 
0296 } // namespace
0297 #endif
0298