diff options
Diffstat (limited to 'src/gui/text/qcssparser.cpp')
-rw-r--r-- | src/gui/text/qcssparser.cpp | 93 |
1 files changed, 65 insertions, 28 deletions
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index a7a8918703..31d832a9ce 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -403,8 +403,8 @@ ValueExtractor::ValueExtractor(const QVector<Declaration> &decls, const QPalette LengthData ValueExtractor::lengthValue(const Value& v) { - QString s = v.variant.toString(); - s.reserve(s.length()); + const QString str = v.variant.toString(); + QStringRef s(&str); LengthData data; data.unit = LengthData::None; if (s.endsWith(QLatin1String("px"), Qt::CaseInsensitive)) @@ -905,7 +905,7 @@ static QBrush brushFromData(const BrushData& c, const QPalette &pal) } } -static BorderStyle parseStyleValue(QCss::Value v) +static BorderStyle parseStyleValue(const QCss::Value &v) { if (v.type == Value::KnownIdentifier) { switch (v.variant.toInt()) { @@ -1447,11 +1447,13 @@ bool Declaration::realValue(qreal *real, const char *unit) const const Value &v = d->values.at(0); if (unit && v.type != Value::Length) return false; - QString s = v.variant.toString(); + const QString str = v.variant.toString(); + QStringRef s(&str); if (unit) { - if (!s.endsWith(QLatin1String(unit), Qt::CaseInsensitive)) + const QLatin1String unitStr(unit); + if (!s.endsWith(unitStr, Qt::CaseInsensitive)) return false; - s.chop(qstrlen(unit)); + s.chop(unitStr.size()); } bool ok = false; qreal val = s.toDouble(&ok); @@ -1464,11 +1466,13 @@ static bool intValueHelper(const QCss::Value &v, int *i, const char *unit) { if (unit && v.type != Value::Length) return false; - QString s = v.variant.toString(); + const QString str = v.variant.toString(); + QStringRef s(&str); if (unit) { - if (!s.endsWith(QLatin1String(unit), Qt::CaseInsensitive)) + const QLatin1String unitStr(unit); + if (!s.endsWith(unitStr, Qt::CaseInsensitive)) return false; - s.chop(qstrlen(unit)); + s.chop(unitStr.size()); } bool ok = false; int val = s.toInt(&ok); @@ -1872,12 +1876,15 @@ bool StyleSelector::selectorMatches(const Selector &selector, NodePtr node) do { match = basicSelectorMatches(sel, node); if (!match) { - if (sel.relationToNext == BasicSelector::MatchNextSelectorIfParent - || i == selector.basicSelectors.count() - 1) // first element must always match! + if (i == selector.basicSelectors.count() - 1) // first element must always match! + break; + if (sel.relationToNext != BasicSelector::MatchNextSelectorIfAncestor && + sel.relationToNext != BasicSelector::MatchNextSelectorIfIndirectAdjecent) break; } - if (match || sel.relationToNext != BasicSelector::MatchNextSelectorIfAncestor) + if (match || (sel.relationToNext != BasicSelector::MatchNextSelectorIfAncestor && + sel.relationToNext != BasicSelector::MatchNextSelectorIfIndirectAdjecent)) --i; if (i < 0) @@ -1890,16 +1897,18 @@ bool StyleSelector::selectorMatches(const Selector &selector, NodePtr node) NodePtr nextParent = parentNode(node); freeNode(node); node = nextParent; - } else if (sel.relationToNext == BasicSelector::MatchNextSelectorIfPreceeds) { + } else if (sel.relationToNext == BasicSelector::MatchNextSelectorIfDirectAdjecent + || sel.relationToNext == BasicSelector::MatchNextSelectorIfIndirectAdjecent) { NodePtr previousSibling = previousSiblingNode(node); freeNode(node); node = previousSibling; - } + } if (isNullNode(node)) { match = false; break; } - } while (i >= 0 && (match || sel.relationToNext == BasicSelector::MatchNextSelectorIfAncestor)); + } while (i >= 0 && (match || sel.relationToNext == BasicSelector::MatchNextSelectorIfAncestor + || sel.relationToNext == BasicSelector::MatchNextSelectorIfIndirectAdjecent)); freeNode(node); @@ -1919,18 +1928,38 @@ bool StyleSelector::basicSelectorMatches(const BasicSelector &sel, NodePtr node) if (attrValue.isNull()) return false; - if (a.valueMatchCriterium == QCss::AttributeSelector::MatchContains) { + switch (a.valueMatchCriterium) { + case QCss::AttributeSelector::NoMatch: + break; + case QCss::AttributeSelector::MatchEqual: + if (attrValue != a.value) + return false; + break; + case QCss::AttributeSelector::MatchIncludes: { const auto lst = attrValue.splitRef(QLatin1Char(' ')); if (!lst.contains(QStringRef(&a.value))) return false; - } else if ( - (a.valueMatchCriterium == QCss::AttributeSelector::MatchEqual - && attrValue != a.value) - || - (a.valueMatchCriterium == QCss::AttributeSelector::MatchBeginsWith - && !attrValue.startsWith(a.value)) - ) - return false; + break; + } + case QCss::AttributeSelector::MatchDashMatch: { + const QString dashPrefix = a.value + QLatin1Char('-'); + if (attrValue != a.value && !attrValue.startsWith(dashPrefix)) + return false; + break; + } + case QCss::AttributeSelector::MatchBeginsWith: + if (!attrValue.startsWith(a.value)) + return false; + break; + case QCss::AttributeSelector::MatchEndsWith: + if (!attrValue.endsWith(a.value)) + return false; + break; + case QCss::AttributeSelector::MatchContains: + if (!attrValue.contains(a.value)) + return false; + break; + } } } @@ -2087,7 +2116,7 @@ QString Scanner::preprocess(const QString &input, bool *hasEscapeSequences) hexCount = qMin(hexCount, 6); bool ok = false; - ushort code = output.mid(hexStart, hexCount).toUShort(&ok, 16); + ushort code = output.midRef(hexStart, hexCount).toUShort(&ok, 16); if (ok) { output.replace(hexStart - 1, hexCount + 1, QChar(code)); i = hexStart; @@ -2341,9 +2370,11 @@ bool Parser::parseCombinator(BasicSelector::Relation *relation) prev(); } if (test(PLUS)) { - *relation = BasicSelector::MatchNextSelectorIfPreceeds; + *relation = BasicSelector::MatchNextSelectorIfDirectAdjecent; } else if (test(GREATER)) { *relation = BasicSelector::MatchNextSelectorIfParent; + } else if (test(TILDE)) { + *relation = BasicSelector::MatchNextSelectorIfIndirectAdjecent; } skipSpace(); return true; @@ -2444,7 +2475,7 @@ bool Parser::parseSimpleSelector(BasicSelector *basicSel) onceMore = true; AttributeSelector a; a.name = QLatin1String("class"); - a.valueMatchCriterium = AttributeSelector::MatchContains; + a.valueMatchCriterium = AttributeSelector::MatchIncludes; if (!parseClass(&a.value)) return false; basicSel->attributeSelectors.append(a); } else if (testAttrib()) { @@ -2490,9 +2521,15 @@ bool Parser::parseAttrib(AttributeSelector *attr) if (test(EQUAL)) { attr->valueMatchCriterium = AttributeSelector::MatchEqual; } else if (test(INCLUDES)) { - attr->valueMatchCriterium = AttributeSelector::MatchContains; + attr->valueMatchCriterium = AttributeSelector::MatchIncludes; } else if (test(DASHMATCH)) { + attr->valueMatchCriterium = AttributeSelector::MatchDashMatch; + } else if (test(BEGINSWITH)) { attr->valueMatchCriterium = AttributeSelector::MatchBeginsWith; + } else if (test(ENDSWITH)) { + attr->valueMatchCriterium = AttributeSelector::MatchEndsWith; + } else if (test(CONTAINS)) { + attr->valueMatchCriterium = AttributeSelector::MatchContains; } else { return next(RBRACKET); } |