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