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