1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QCSSPARSER_P_H
43 #define QCSSPARSER_P_H
44 
45 //
46 //  W A R N I N G
47 //  -------------
48 //
49 // This file is not part of the Qt API.  It exists for the convenience
50 // of the QLibrary class.  This header file may change from
51 // version to version without notice, or even be removed.
52 //
53 // We mean it.
54 //
55 
56 #include <QtCore/QStringList>
57 #include <QtCore/QVector>
58 #include <QtCore/QVariant>
59 #include <QtCore/QPair>
60 #include <QtCore/QSize>
61 #include <QtCore/QMultiHash>
62 #include <QtGui/QFont>
63 #include <QtGui/QPalette>
64 #include <QtGui/QIcon>
65 #include <QtCore/QSharedData>
66 
67 
68 #ifndef QT_NO_CSSPARSER
69 
70 // VxWorks defines NONE as (-1) "for times when NULL won't do"
71 #if defined(Q_OS_VXWORKS) && defined(NONE)
72 #  undef NONE
73 #endif
74 #if defined(Q_OS_INTEGRITY)
75 #  undef Value
76 #endif
77 
78 QT_BEGIN_NAMESPACE
79 
80 namespace QCss
81 {
82 
83 enum Property {
84     UnknownProperty,
85     BackgroundColor,
86     Color,
87     Float,
88     Font,
89     FontFamily,
90     FontSize,
91     FontStyle,
92     FontWeight,
93     Margin,
94     MarginBottom,
95     MarginLeft,
96     MarginRight,
97     MarginTop,
98     QtBlockIndent,
99     QtListIndent,
100     QtParagraphType,
101     QtTableType,
102     QtUserState,
103     TextDecoration,
104     TextIndent,
105     TextUnderlineStyle,
106     VerticalAlignment,
107     Whitespace,
108     QtSelectionForeground,
109     QtSelectionBackground,
110     Border,
111     BorderLeft,
112     BorderRight,
113     BorderTop,
114     BorderBottom,
115     Padding,
116     PaddingLeft,
117     PaddingRight,
118     PaddingTop,
119     PaddingBottom,
120     PageBreakBefore,
121     PageBreakAfter,
122     QtAlternateBackground,
123     BorderLeftStyle,
124     BorderRightStyle,
125     BorderTopStyle,
126     BorderBottomStyle,
127     BorderStyles,
128     BorderLeftColor,
129     BorderRightColor,
130     BorderTopColor,
131     BorderBottomColor,
132     BorderColor,
133     BorderLeftWidth,
134     BorderRightWidth,
135     BorderTopWidth,
136     BorderBottomWidth,
137     BorderWidth,
138     BorderTopLeftRadius,
139     BorderTopRightRadius,
140     BorderBottomLeftRadius,
141     BorderBottomRightRadius,
142     BorderRadius,
143     Background,
144     BackgroundOrigin,
145     BackgroundClip,
146     BackgroundRepeat,
147     BackgroundPosition,
148     BackgroundAttachment,
149     BackgroundImage,
150     BorderImage,
151     QtSpacing,
152     Width,
153     Height,
154     MinimumWidth,
155     MinimumHeight,
156     MaximumWidth,
157     MaximumHeight,
158     QtImage,
159     Left,
160     Right,
161     Top,
162     Bottom,
163     QtOrigin,
164     QtPosition,
165     Position,
166     QtStyleFeatures,
167     QtBackgroundRole,
168     ListStyleType,
169     ListStyle,
170     QtImageAlignment,
171     TextAlignment,
172     Outline,
173     OutlineOffset,
174     OutlineWidth,
175     OutlineColor,
176     OutlineStyle,
177     OutlineRadius,
178     OutlineTopLeftRadius,
179     OutlineTopRightRadius,
180     OutlineBottomLeftRadius,
181     OutlineBottomRightRadius,
182     FontVariant,
183     TextTransform,
184     QtListNumberPrefix,
185     QtListNumberSuffix,
186     LineHeight,
187     NumProperties
188 };
189 
190 enum KnownValue {
191     UnknownValue,
192     Value_Normal,
193     Value_Pre,
194     Value_NoWrap,
195     Value_PreWrap,
196     Value_Small,
197     Value_Medium,
198     Value_Large,
199     Value_XLarge,
200     Value_XXLarge,
201     Value_Italic,
202     Value_Oblique,
203     Value_Bold,
204     Value_Underline,
205     Value_Overline,
206     Value_LineThrough,
207     Value_Sub,
208     Value_Super,
209     Value_Left,
210     Value_Right,
211     Value_Top,
212     Value_Bottom,
213     Value_Center,
214     Value_Native,
215     Value_Solid,
216     Value_Dotted,
217     Value_Dashed,
218     Value_DotDash,
219     Value_DotDotDash,
220     Value_Double,
221     Value_Groove,
222     Value_Ridge,
223     Value_Inset,
224     Value_Outset,
225     Value_Wave,
226     Value_Middle,
227     Value_Auto,
228     Value_Always,
229     Value_None,
230     Value_Transparent,
231     Value_Disc,
232     Value_Circle,
233     Value_Square,
234     Value_Decimal,
235     Value_LowerAlpha,
236     Value_UpperAlpha,
237     Value_LowerRoman,
238     Value_UpperRoman,
239     Value_SmallCaps,
240     Value_Uppercase,
241     Value_Lowercase,
242 
243     /* keep these in same order as QPalette::ColorRole */
244     Value_FirstColorRole,
245     Value_WindowText = Value_FirstColorRole,
246     Value_Button,
247     Value_Light,
248     Value_Midlight,
249     Value_Dark,
250     Value_Mid,
251     Value_Text,
252     Value_BrightText,
253     Value_ButtonText,
254     Value_Base,
255     Value_Window,
256     Value_Shadow,
257     Value_Highlight,
258     Value_HighlightedText,
259     Value_Link,
260     Value_LinkVisited,
261     Value_AlternateBase,
262     Value_LastColorRole = Value_AlternateBase,
263 
264     Value_Disabled,
265     Value_Active,
266     Value_Selected,
267     Value_On,
268     Value_Off,
269 
270     NumKnownValues
271 };
272 
273 enum BorderStyle {
274     BorderStyle_Unknown,
275     BorderStyle_None,
276     BorderStyle_Dotted,
277     BorderStyle_Dashed,
278     BorderStyle_Solid,
279     BorderStyle_Double,
280     BorderStyle_DotDash,
281     BorderStyle_DotDotDash,
282     BorderStyle_Groove,
283     BorderStyle_Ridge,
284     BorderStyle_Inset,
285     BorderStyle_Outset,
286     BorderStyle_Native,
287     NumKnownBorderStyles
288 };
289 
290 enum Edge {
291     TopEdge,
292     RightEdge,
293     BottomEdge,
294     LeftEdge,
295     NumEdges
296 };
297 
298 enum Corner {
299     TopLeftCorner,
300     TopRightCorner,
301     BottomLeftCorner,
302     BottomRightCorner
303 };
304 
305 enum TileMode {
306     TileMode_Unknown,
307     TileMode_Round,
308     TileMode_Stretch,
309     TileMode_Repeat,
310     NumKnownTileModes
311 };
312 
313 enum Repeat {
314     Repeat_Unknown,
315     Repeat_None,
316     Repeat_X,
317     Repeat_Y,
318     Repeat_XY,
319     NumKnownRepeats
320 };
321 
322 enum Origin {
323     Origin_Unknown,
324     Origin_Padding,
325     Origin_Border,
326     Origin_Content,
327     Origin_Margin,
328     NumKnownOrigins
329 };
330 
331 enum PositionMode {
332     PositionMode_Unknown,
333     PositionMode_Static,
334     PositionMode_Relative,
335     PositionMode_Absolute,
336     PositionMode_Fixed,
337     NumKnownPositionModes
338 };
339 
340 enum Attachment {
341     Attachment_Unknown,
342     Attachment_Fixed,
343     Attachment_Scroll,
344     NumKnownAttachments
345 };
346 
347 enum StyleFeature {
348     StyleFeature_None = 0,
349     StyleFeature_BackgroundColor = 1,
350     StyleFeature_BackgroundGradient = 2,
351     NumKnownStyleFeatures = 4
352 };
353 
354 struct Q_GUI_EXPORT Value
355 {
356     enum Type {
357         Unknown,
358         Number,
359         Percentage,
360         Length,
361         String,
362         Identifier,
363         KnownIdentifier,
364         Uri,
365         Color,
366         Function,
367         TermOperatorSlash,
368         TermOperatorComma
369     };
ValueValue370     inline Value() : type(Unknown) { }
371     Type type;
372     QVariant variant;
373     QString toString() const;
374 };
375 
376 struct ColorData {
ColorDataColorData377     ColorData() : role(QPalette::NoRole), type(Invalid) {}
ColorDataColorData378     ColorData(const QColor &col) : color(col), role(QPalette::NoRole), type(Color) {}
ColorDataColorData379     ColorData(QPalette::ColorRole r) : role(r), type(Role) {}
380     QColor color;
381     QPalette::ColorRole role;
382     enum { Invalid, Color, Role} type;
383 };
384 
385 struct BrushData {
BrushDataBrushData386     BrushData() : role(QPalette::NoRole), type(Invalid) {}
BrushDataBrushData387     BrushData(const QBrush &br) : brush(br), role(QPalette::NoRole), type(Brush) {}
BrushDataBrushData388     BrushData(QPalette::ColorRole r) : role(r), type(Role) {}
389     QBrush brush;
390     QPalette::ColorRole role;
391     enum { Invalid, Brush, Role, DependsOnThePalette } type;
392 };
393 
394 struct BackgroundData {
395     BrushData brush;
396     QString image;
397     Repeat repeat;
398     Qt::Alignment alignment;
399 };
400 
401 struct LengthData {
402     qreal number;
403     enum { None, Px, Ex, Em } unit;
404 };
405 
406 struct BorderData {
407     LengthData width;
408     BorderStyle style;
409     BrushData color;
410 };
411 
412 
413 // 1. StyleRule - x:hover, y:clicked > z:checked { prop1: value1; prop2: value2; }
414 // 2. QVector<Selector> - x:hover, y:clicked z:checked
415 // 3. QVector<BasicSelector> - y:clicked z:checked
416 // 4. QVector<Declaration> - { prop1: value1; prop2: value2; }
417 // 5. Declaration - prop1: value1;
418 
419 struct Q_AUTOTEST_EXPORT Declaration
420 {
421     struct DeclarationData : public QSharedData
422     {
DeclarationDataDeclaration::DeclarationData423         inline DeclarationData() : propertyId(UnknownProperty), important(false) {}
424         QString property;
425         Property propertyId;
426         QVector<Value> values;
427         QVariant parsed;
428         bool important;
429     };
430     QExplicitlySharedDataPointer<DeclarationData> d;
DeclarationDeclaration431     inline Declaration() : d(new DeclarationData()) {}
isEmptyDeclaration432     inline bool isEmpty() const { return d->property.isEmpty() && d->propertyId == UnknownProperty; }
433 
434     // helper functions
435     QColor colorValue(const QPalette & = QPalette()) const;
436     void colorValues(QColor *c, const QPalette & = QPalette()) const;
437     QBrush brushValue(const QPalette & = QPalette()) const;
438     void brushValues(QBrush *c, const QPalette & = QPalette()) const;
439 
440     BorderStyle styleValue() const;
441     void styleValues(BorderStyle *s) const;
442 
443     Origin originValue() const;
444     Repeat repeatValue() const;
445     Qt::Alignment alignmentValue() const;
446     PositionMode positionValue() const;
447     Attachment attachmentValue() const;
448     int  styleFeaturesValue() const;
449 
450     bool intValue(int *i, const char *unit = 0) const;
451     bool realValue(qreal *r, const char *unit = 0) const;
452 
453     QSize sizeValue() const;
454     QRect rectValue() const;
455     QString uriValue() const;
456     QIcon iconValue() const;
457 
458     void borderImageValue(QString *image, int *cuts, TileMode *h, TileMode *v) const;
459 };
460 
461 const quint64 PseudoClass_Unknown          = Q_UINT64_C(0x0000000000000000);
462 const quint64 PseudoClass_Enabled          = Q_UINT64_C(0x0000000000000001);
463 const quint64 PseudoClass_Disabled         = Q_UINT64_C(0x0000000000000002);
464 const quint64 PseudoClass_Pressed          = Q_UINT64_C(0x0000000000000004);
465 const quint64 PseudoClass_Focus            = Q_UINT64_C(0x0000000000000008);
466 const quint64 PseudoClass_Hover            = Q_UINT64_C(0x0000000000000010);
467 const quint64 PseudoClass_Checked          = Q_UINT64_C(0x0000000000000020);
468 const quint64 PseudoClass_Unchecked        = Q_UINT64_C(0x0000000000000040);
469 const quint64 PseudoClass_Indeterminate    = Q_UINT64_C(0x0000000000000080);
470 const quint64 PseudoClass_Unspecified      = Q_UINT64_C(0x0000000000000100);
471 const quint64 PseudoClass_Selected         = Q_UINT64_C(0x0000000000000200);
472 const quint64 PseudoClass_Horizontal       = Q_UINT64_C(0x0000000000000400);
473 const quint64 PseudoClass_Vertical         = Q_UINT64_C(0x0000000000000800);
474 const quint64 PseudoClass_Window           = Q_UINT64_C(0x0000000000001000);
475 const quint64 PseudoClass_Children         = Q_UINT64_C(0x0000000000002000);
476 const quint64 PseudoClass_Sibling          = Q_UINT64_C(0x0000000000004000);
477 const quint64 PseudoClass_Default          = Q_UINT64_C(0x0000000000008000);
478 const quint64 PseudoClass_First            = Q_UINT64_C(0x0000000000010000);
479 const quint64 PseudoClass_Last             = Q_UINT64_C(0x0000000000020000);
480 const quint64 PseudoClass_Middle           = Q_UINT64_C(0x0000000000040000);
481 const quint64 PseudoClass_OnlyOne          = Q_UINT64_C(0x0000000000080000);
482 const quint64 PseudoClass_PreviousSelected = Q_UINT64_C(0x0000000000100000);
483 const quint64 PseudoClass_NextSelected     = Q_UINT64_C(0x0000000000200000);
484 const quint64 PseudoClass_Flat             = Q_UINT64_C(0x0000000000400000);
485 const quint64 PseudoClass_Left             = Q_UINT64_C(0x0000000000800000);
486 const quint64 PseudoClass_Right            = Q_UINT64_C(0x0000000001000000);
487 const quint64 PseudoClass_Top              = Q_UINT64_C(0x0000000002000000);
488 const quint64 PseudoClass_Bottom           = Q_UINT64_C(0x0000000004000000);
489 const quint64 PseudoClass_Exclusive        = Q_UINT64_C(0x0000000008000000);
490 const quint64 PseudoClass_NonExclusive     = Q_UINT64_C(0x0000000010000000);
491 const quint64 PseudoClass_Frameless        = Q_UINT64_C(0x0000000020000000);
492 const quint64 PseudoClass_ReadOnly         = Q_UINT64_C(0x0000000040000000);
493 const quint64 PseudoClass_Active           = Q_UINT64_C(0x0000000080000000);
494 const quint64 PseudoClass_Closable         = Q_UINT64_C(0x0000000100000000);
495 const quint64 PseudoClass_Movable          = Q_UINT64_C(0x0000000200000000);
496 const quint64 PseudoClass_Floatable        = Q_UINT64_C(0x0000000400000000);
497 const quint64 PseudoClass_Minimized        = Q_UINT64_C(0x0000000800000000);
498 const quint64 PseudoClass_Maximized        = Q_UINT64_C(0x0000001000000000);
499 const quint64 PseudoClass_On               = Q_UINT64_C(0x0000002000000000);
500 const quint64 PseudoClass_Off              = Q_UINT64_C(0x0000004000000000);
501 const quint64 PseudoClass_Editable         = Q_UINT64_C(0x0000008000000000);
502 const quint64 PseudoClass_Item             = Q_UINT64_C(0x0000010000000000);
503 const quint64 PseudoClass_Closed           = Q_UINT64_C(0x0000020000000000);
504 const quint64 PseudoClass_Open             = Q_UINT64_C(0x0000040000000000);
505 const quint64 PseudoClass_EditFocus        = Q_UINT64_C(0x0000080000000000);
506 const quint64 PseudoClass_Alternate        = Q_UINT64_C(0x0000100000000000);
507 // The Any specifier is never generated, but can be used as a wildcard in searches.
508 const quint64 PseudoClass_Any              = Q_UINT64_C(0x0000ffffffffffff);
509 const int NumPseudos = 46;
510 
511 struct Pseudo
512 {
PseudoPseudo513     Pseudo() : type(0), negated(false) { }
514     quint64 type;
515     QString name;
516     QString function;
517     bool negated;
518 };
519 
520 struct AttributeSelector
521 {
522     enum ValueMatchType {
523         NoMatch,
524         MatchEqual,
525         MatchContains,
526         MatchBeginsWith
527     };
AttributeSelectorAttributeSelector528     inline AttributeSelector() : valueMatchCriterium(NoMatch) {}
529 
530     QString name;
531     QString value;
532     ValueMatchType valueMatchCriterium;
533 };
534 
535 struct BasicSelector
536 {
BasicSelectorBasicSelector537     inline BasicSelector() : relationToNext(NoRelation) {}
538 
539     enum Relation {
540         NoRelation,
541         MatchNextSelectorIfAncestor,
542         MatchNextSelectorIfParent,
543         MatchNextSelectorIfPreceeds
544     };
545 
546     QString elementName;
547 
548     QStringList ids;
549     QVector<Pseudo> pseudos;
550     QVector<AttributeSelector> attributeSelectors;
551 
552     Relation relationToNext;
553 };
554 
555 struct Q_AUTOTEST_EXPORT Selector
556 {
557     QVector<BasicSelector> basicSelectors;
558     int specificity() const;
559     quint64 pseudoClass(quint64 *negated = 0) const;
560     QString pseudoElement() const;
561 };
562 
563 struct StyleRule;
564 struct MediaRule;
565 struct PageRule;
566 struct ImportRule;
567 
568 struct Q_AUTOTEST_EXPORT ValueExtractor
569 {
570     ValueExtractor(const QVector<Declaration> &declarations, const QPalette & = QPalette());
571 
572     bool extractFont(QFont *font, int *fontSizeAdjustment);
573     bool extractBackground(QBrush *, QString *, Repeat *, Qt::Alignment *, QCss::Origin *, QCss::Attachment *,
574                            QCss::Origin *);
575     bool extractGeometry(int *w, int *h, int *minw, int *minh, int *maxw, int *maxh);
576     bool extractPosition(int *l, int *t, int *r, int *b, QCss::Origin *, Qt::Alignment *,
577                          QCss::PositionMode *, Qt::Alignment *);
578     bool extractBox(int *margins, int *paddings, int *spacing = 0);
579     bool extractBorder(int *borders, QBrush *colors, BorderStyle *Styles, QSize *radii);
580     bool extractOutline(int *borders, QBrush *colors, BorderStyle *Styles, QSize *radii, int *offsets);
581     bool extractPalette(QBrush *fg, QBrush *sfg, QBrush *sbg, QBrush *abg);
582     int  extractStyleFeatures();
583     bool extractImage(QIcon *icon, Qt::Alignment *a, QSize *size);
584 
585     int lengthValue(const Declaration &decl);
586 
587 private:
588     void extractFont();
589     void borderValue(const Declaration &decl, int *width, QCss::BorderStyle *style, QBrush *color);
590     LengthData lengthValue(const Value& v);
591     void lengthValues(const Declaration &decl, int *m);
592     QSize sizeValue(const Declaration &decl);
593     void sizeValues(const Declaration &decl, QSize *radii);
594 
595     QVector<Declaration> declarations;
596     QFont f;
597     int adjustment;
598     int fontExtracted;
599     QPalette pal;
600 };
601 
602 struct StyleRule
603 {
StyleRuleStyleRule604     StyleRule() : order(0) { }
605     QVector<Selector> selectors;
606     QVector<Declaration> declarations;
607     int order;
608 };
609 
610 struct MediaRule
611 {
612     QStringList media;
613     QVector<StyleRule> styleRules;
614 };
615 
616 struct PageRule
617 {
618     QString selector;
619     QVector<Declaration> declarations;
620 };
621 
622 struct ImportRule
623 {
624     QString href;
625     QStringList media;
626 };
627 
628 enum StyleSheetOrigin {
629     StyleSheetOrigin_Unspecified,
630     StyleSheetOrigin_UserAgent,
631     StyleSheetOrigin_User,
632     StyleSheetOrigin_Author,
633     StyleSheetOrigin_Inline
634 };
635 
636 struct StyleSheet
637 {
StyleSheetStyleSheet638     StyleSheet() : origin(StyleSheetOrigin_Unspecified), depth(0) { }
639     QVector<StyleRule> styleRules;  //only contains rules that are not indexed
640     QVector<MediaRule> mediaRules;
641     QVector<PageRule> pageRules;
642     QVector<ImportRule> importRules;
643     StyleSheetOrigin origin;
644     int depth; // applicable only for inline style sheets
645     QMultiHash<QString, StyleRule> nameIndex;
646     QMultiHash<QString, StyleRule> idIndex;
647     void buildIndexes(Qt::CaseSensitivity nameCaseSensitivity = Qt::CaseSensitive);
648 };
649 
650 class Q_GUI_EXPORT StyleSelector
651 {
652 public:
StyleSelector()653     StyleSelector() : nameCaseSensitivity(Qt::CaseSensitive)  {}
654     virtual ~StyleSelector();
655 
656     union NodePtr {
657         void *ptr;
658         int id;
659     };
660 
661     QVector<StyleRule> styleRulesForNode(NodePtr node);
662     QVector<Declaration> declarationsForNode(NodePtr node, const char *extraPseudo = 0);
663 
664     virtual bool nodeNameEquals(NodePtr node, const QString& nodeName) const;
665     virtual QString attribute(NodePtr node, const QString &name) const = 0;
666     virtual bool hasAttributes(NodePtr node) const = 0;
667     virtual QStringList nodeIds(NodePtr node) const;
668     virtual QStringList nodeNames(NodePtr node) const = 0;
669     virtual bool isNullNode(NodePtr node) const = 0;
670     virtual NodePtr parentNode(NodePtr node) const = 0;
671     virtual NodePtr previousSiblingNode(NodePtr node) const = 0;
672     virtual NodePtr duplicateNode(NodePtr node) const = 0;
673     virtual void freeNode(NodePtr node) const = 0;
674 
675     QVector<StyleSheet> styleSheets;
676     QString medium;
677     Qt::CaseSensitivity nameCaseSensitivity;
678 private:
679     void matchRule(NodePtr node, const StyleRule &rules, StyleSheetOrigin origin,
680                     int depth, QMap<uint, StyleRule> *weightedRules);
681     bool selectorMatches(const Selector &rule, NodePtr node);
682     bool basicSelectorMatches(const BasicSelector &rule, NodePtr node);
683 };
684 
685 enum TokenType {
686     NONE,
687 
688     S,
689 
690     CDO,
691     CDC,
692     INCLUDES,
693     DASHMATCH,
694 
695     LBRACE,
696     PLUS,
697     GREATER,
698     COMMA,
699 
700     STRING,
701     INVALID,
702 
703     IDENT,
704 
705     HASH,
706 
707     ATKEYWORD_SYM,
708 
709     EXCLAMATION_SYM,
710 
711     LENGTH,
712 
713     PERCENTAGE,
714     NUMBER,
715 
716     FUNCTION,
717 
718     COLON,
719     SEMICOLON,
720     RBRACE,
721     SLASH,
722     MINUS,
723     DOT,
724     STAR,
725     LBRACKET,
726     RBRACKET,
727     EQUAL,
728     LPAREN,
729     RPAREN,
730     OR
731 };
732 
733 struct Q_GUI_EXPORT Symbol
734 {
SymbolSymbol735     inline Symbol() : token(NONE), start(0), len(-1) {}
736     TokenType token;
737     QString text;
738     int start, len;
739     QString lexem() const;
740 };
741 
742 class Q_AUTOTEST_EXPORT Scanner
743 {
744 public:
745     static QString preprocess(const QString &input, bool *hasEscapeSequences = 0);
746     static void scan(const QString &preprocessedInput, QVector<Symbol> *symbols);
747 };
748 
749 class Q_GUI_EXPORT Parser
750 {
751 public:
752     Parser();
753     Parser(const QString &css, bool file = false);
754 
755     void init(const QString &css, bool file = false);
756     bool parse(StyleSheet *styleSheet, Qt::CaseSensitivity nameCaseSensitivity = Qt::CaseSensitive);
757     Symbol errorSymbol();
758 
759     bool parseImport(ImportRule *importRule);
760     bool parseMedia(MediaRule *mediaRule);
761     bool parseMedium(QStringList *media);
762     bool parsePage(PageRule *pageRule);
763     bool parsePseudoPage(QString *selector);
764     bool parseNextOperator(Value *value);
765     bool parseCombinator(BasicSelector::Relation *relation);
766     bool parseProperty(Declaration *decl);
767     bool parseRuleset(StyleRule *styleRule);
768     bool parseSelector(Selector *sel);
769     bool parseSimpleSelector(BasicSelector *basicSel);
770     bool parseClass(QString *name);
771     bool parseElementName(QString *name);
772     bool parseAttrib(AttributeSelector *attr);
773     bool parsePseudo(Pseudo *pseudo);
774     bool parseNextDeclaration(Declaration *declaration);
775     bool parsePrio(Declaration *declaration);
776     bool parseExpr(QVector<Value> *values);
777     bool parseTerm(Value *value);
778     bool parseFunction(QString *name, QString *args);
779     bool parseHexColor(QColor *col);
780     bool testAndParseUri(QString *uri);
781 
testRuleset()782     inline bool testRuleset() { return testSelector(); }
testSelector()783     inline bool testSelector() { return testSimpleSelector(); }
parseNextSelector(Selector * sel)784     inline bool parseNextSelector(Selector *sel) { if (!testSelector()) return recordError(); return parseSelector(sel); }
785     bool testSimpleSelector();
parseNextSimpleSelector(BasicSelector * basicSel)786     inline bool parseNextSimpleSelector(BasicSelector *basicSel) { if (!testSimpleSelector()) return recordError(); return parseSimpleSelector(basicSel); }
testElementName()787     inline bool testElementName() { return test(IDENT) || test(STAR); }
testClass()788     inline bool testClass() { return test(DOT); }
testAttrib()789     inline bool testAttrib() { return test(LBRACKET); }
testPseudo()790     inline bool testPseudo() { return test(COLON); }
testMedium()791     inline bool testMedium() { return test(IDENT); }
parseNextMedium(QStringList * media)792     inline bool parseNextMedium(QStringList *media) { if (!testMedium()) return recordError(); return parseMedium(media); }
testPseudoPage()793     inline bool testPseudoPage() { return test(COLON); }
testImport()794     inline bool testImport() { return testTokenAndEndsWith(ATKEYWORD_SYM, QLatin1String("import")); }
testMedia()795     inline bool testMedia() { return testTokenAndEndsWith(ATKEYWORD_SYM, QLatin1String("media")); }
testPage()796     inline bool testPage() { return testTokenAndEndsWith(ATKEYWORD_SYM, QLatin1String("page")); }
testCombinator()797     inline bool testCombinator() { return test(PLUS) || test(GREATER) || test(S); }
testProperty()798     inline bool testProperty() { return test(IDENT); }
799     bool testTerm();
testExpr()800     inline bool testExpr() { return testTerm(); }
parseNextExpr(QVector<Value> * values)801     inline bool parseNextExpr(QVector<Value> *values) { if (!testExpr()) return recordError(); return parseExpr(values); }
802     bool testPrio();
testHexColor()803     inline bool testHexColor() { return test(HASH); }
testFunction()804     inline bool testFunction() { return test(FUNCTION); }
parseNextFunction(QString * name,QString * args)805     inline bool parseNextFunction(QString *name, QString *args) { if (!testFunction()) return recordError(); return parseFunction(name, args); }
806 
lookupElementName()807     inline bool lookupElementName() const { return lookup() == IDENT || lookup() == STAR; }
808 
skipSpace()809     inline void skipSpace() { while (test(S)) {}; }
810 
hasNext()811     inline bool hasNext() const { return index < symbols.count(); }
next()812     inline TokenType next() { return symbols.at(index++).token; }
813     bool next(TokenType t);
814     bool test(TokenType t);
prev()815     inline void prev() { index--; }
symbol()816     inline const Symbol &symbol() const { return symbols.at(index - 1); }
lexem()817     inline QString lexem() const { return symbol().lexem(); }
818     QString unquotedLexem() const;
819     QString lexemUntil(TokenType t);
820     bool until(TokenType target, TokenType target2 = NONE);
lookup()821     inline TokenType lookup() const {
822         return (index - 1) < symbols.count() ? symbols.at(index - 1).token : NONE;
823     }
824 
825     bool testTokenAndEndsWith(TokenType t, const QLatin1String &str);
826 
recordError()827     inline bool recordError() { errorIndex = index; return false; }
828 
829     QVector<Symbol> symbols;
830     int index;
831     int errorIndex;
832     bool hasEscapeSequences;
833     QString sourcePath;
834 };
835 
836 } // namespace QCss
837 
838 QT_END_NAMESPACE
839 
840 Q_DECLARE_METATYPE( QCss::BackgroundData )
841 Q_DECLARE_METATYPE( QCss::LengthData )
842 Q_DECLARE_METATYPE( QCss::BorderData )
843 
844 
845 #endif // QT_NO_CSSPARSER
846 
847 #endif
848