summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qcssparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text/qcssparser.cpp')
-rw-r--r--src/gui/text/qcssparser.cpp93
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);
}