⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qcssparser.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                               origins, NumKnownOrigins));}PositionMode Declaration::positionValue() const{    if (values.count() != 1)        return PositionMode_Unknown;    return static_cast<PositionMode>(findKnownValue(values.first().variant.toString(),                                     positions, NumKnownPositionModes));}Attachment Declaration::attachmentValue() const{    if (values.count() != 1)        return Attachment_Unknown;    return static_cast<Attachment>(findKnownValue(values.first().variant.toString(),                                   attachments, NumKnownAttachments));}int Declaration::styleFeaturesValue() const{    int features = StyleFeature_None;    for (int i = 0; i < values.count(); i++) {        features |= static_cast<int>(findKnownValue(values.value(i).variant.toString(),                                     styleFeatures, NumKnownStyleFeatures));    }    return features;}QString Declaration::uriValue() const{    if (values.isEmpty() || values.first().type != Value::Uri)        return QString();    return values.first().variant.toString();}Qt::Alignment Declaration::alignmentValue() const{    if (values.isEmpty() || values.count() > 2)        return Qt::AlignLeft | Qt::AlignTop;    return parseAlignment(values.constData(), values.count());}void Declaration::borderImageValue(QString *image, int *cuts,                                   TileMode *h, TileMode *v) const{    *image = uriValue();    for (int i = 0; i < 4; i++)        cuts[i] = -1;    *h = *v = TileMode_Stretch;    if (values.count() < 2)        return;    if (values.at(1).type == Value::Number) { // cuts!        int i;        for (i = 0; i < qMin(values.count()-1, 4); i++) {            const Value& v = values.at(i+1);            if (v.type != Value::Number)                break;            cuts[i] = v.variant.toString().toInt();        }        if (i == 0) cuts[0] = cuts[1] = cuts[2] = cuts[3] = 0;        else if (i == 1) cuts[3] = cuts[2] = cuts[1] = cuts[0];        else if (i == 2) cuts[2] = cuts[0], cuts[3] = cuts[1];        else if (i == 3) cuts[3] = cuts[1];    }    if (values.last().type == Value::Identifier) {        *v = static_cast<TileMode>(findKnownValue(values.last().variant.toString(),                                      tileModes, NumKnownTileModes));    }    if (values[values.count() - 2].type == Value::Identifier) {        *h = static_cast<TileMode>                        (findKnownValue(values[values.count()-2].variant.toString(),                                        tileModes, NumKnownTileModes));    } else        *h = *v;}QIcon Declaration::iconValue() const{    QIcon icon;    for (int i = 0; i < values.count(); i++) {        const Value &value = values.at(i);        if (value.type != Value::Uri)            continue;        if (icon.isNull())            icon = QIcon(value.variant.toString());        else            icon.addPixmap(value.variant.toString());    }    return icon;}///////////////////////////////////////////////////////////////////////////////// Selectorint Selector::specificity() const{    int val = 0;    for (int i = 0; i < basicSelectors.count(); ++i) {        const BasicSelector &sel = basicSelectors.at(i);        if (!sel.elementName.isEmpty())            val += 1;        val += (sel.pseudos.count() + sel.attributeSelectors.count()) * 0x10;        val += sel.ids.count() * 0x100;    }    return val;}QString Selector::pseudoElement() const{    const BasicSelector& bs = basicSelectors.last();    if (!bs.pseudos.isEmpty() && bs.pseudos.first().type == PseudoClass_Unknown)        return bs.pseudos.first().name;    return QString();}int Selector::pseudoClass(int *negated) const{    const BasicSelector& bs = basicSelectors.last();    if (bs.pseudos.isEmpty())        return PseudoClass_Unspecified;    int pc = PseudoClass_Unknown;    for (int i = !pseudoElement().isEmpty(); i < bs.pseudos.count(); i++) {        const Pseudo &pseudo = bs.pseudos.at(i);        if (pseudo.type == PseudoClass_Unknown)            return PseudoClass_Unknown;        if (!pseudo.negated)            pc |= pseudo.type;        else if (negated)            *negated |= pseudo.type;    }    return pc;}///////////////////////////////////////////////////////////////////////////////// StyleSelectorStyleSelector::~StyleSelector(){}QStringList StyleSelector::nodeIds(NodePtr node) const{    return QStringList(attribute(node, QLatin1String("id")));}bool StyleSelector::selectorMatches(const Selector &selector, NodePtr node){    if (selector.basicSelectors.isEmpty())        return false;    if (selector.basicSelectors.first().relationToNext == BasicSelector::NoRelation) {        if (selector.basicSelectors.count() != 1)            return false;        return basicSelectorMatches(selector.basicSelectors.first(), node);    }    if (selector.basicSelectors.count() <= 1)        return false;    int i = selector.basicSelectors.count() - 1;    node = duplicateNode(node);    bool match = true;    BasicSelector sel = selector.basicSelectors.at(i);    do {        match = basicSelectorMatches(sel, node);        if (!match) {            if (sel.relationToNext == BasicSelector::MatchNextSelectorIfParent                || i == selector.basicSelectors.count() - 1) // first element must always match!                break;        }        if (match || sel.relationToNext != BasicSelector::MatchNextSelectorIfAncestor)            --i;        if (i < 0)            break;        sel = selector.basicSelectors.at(i);        if (sel.relationToNext == BasicSelector::MatchNextSelectorIfAncestor            || sel.relationToNext == BasicSelector::MatchNextSelectorIfParent) {            NodePtr nextParent = parentNode(node);            freeNode(node);            node = nextParent;       } else if (sel.relationToNext == BasicSelector::MatchNextSelectorIfPreceeds) {            NodePtr previousSibling = previousSiblingNode(node);            freeNode(node);            node = previousSibling;       }        if (isNullNode(node)) {            match = false;            break;        }   } while (i >= 0 && (match || sel.relationToNext == BasicSelector::MatchNextSelectorIfAncestor));    freeNode(node);    return match;}bool StyleSelector::basicSelectorMatches(const BasicSelector &sel, NodePtr node){    if (!sel.attributeSelectors.isEmpty()) {        if (!hasAttributes(node))            return false;        for (int i = 0; i < sel.attributeSelectors.count(); ++i) {            const QCss::AttributeSelector &a = sel.attributeSelectors.at(i);            if (!hasAttribute(node, a.name))                return false;            const QString attrValue = attribute(node, a.name);            if (a.valueMatchCriterium == QCss::AttributeSelector::MatchContains) {                QStringList lst = attrValue.split(QLatin1Char(' '));                if (!lst.contains(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;        }    }    if (!sel.elementName.isEmpty()        && !nodeNameEquals(node, sel.elementName))            return false;    if (!sel.ids.isEmpty()        && sel.ids != nodeIds(node))            return false;    return true;}static inline bool qcss_selectorLessThan(const QPair<int, QCss::StyleRule> &lhs, const QPair<int, QCss::StyleRule> &rhs){    return lhs.first < rhs.first;}void StyleSelector::matchRules(NodePtr node, const QVector<StyleRule> &rules, StyleSheetOrigin origin,                               int depth, QVector<QPair<int, StyleRule> > *weightedRules){    for (int i = 0; i < rules.count(); ++i) {        const StyleRule &rule = rules.at(i);        for (int j = 0; j < rule.selectors.count(); ++j) {            const Selector& selector = rule.selectors.at(j);            if (selectorMatches(selector, node)) {                QPair<int, StyleRule> weightedRule;                weightedRule.first = selector.specificity()                                     + (origin == StyleSheetOrigin_Inline)*0x1000*depth;                weightedRule.second.selectors.append(selector);                weightedRule.second.declarations = rule.declarations;                weightedRules->append(weightedRule);            }        }    }}// Returns style rules that are in ascending order of specificity// Each of the StyleRule returned will contain exactly one SelectorQVector<StyleRule> StyleSelector::styleRulesForNode(NodePtr node){    QVector<StyleRule> rules;    if (styleSheets.isEmpty())        return rules;    QVector<QPair<int, StyleRule> > weightedRules; // (spec, rule) that will be sorted below    for (int sheetIdx = 0; sheetIdx < styleSheets.count(); ++sheetIdx) {        const StyleSheet &styleSheet = styleSheets.at(sheetIdx);        matchRules(node, styleSheet.styleRules, styleSheet.origin, styleSheet.depth, &weightedRules);        if (!medium.isEmpty()) {            for (int i = 0; i < styleSheet.mediaRules.count(); ++i) {                if (styleSheet.mediaRules.at(i).media.contains(medium, Qt::CaseInsensitive)) {                    matchRules(node, styleSheet.mediaRules.at(i).styleRules, styleSheet.origin,                               styleSheet.depth, &weightedRules);                }            }        }    }    qStableSort(weightedRules.begin(), weightedRules.end(), qcss_selectorLessThan);    for (int j = 0; j < weightedRules.count(); j++)        rules += weightedRules.at(j).second;    return rules;}// for qtexthtmlparser which requires just the declarations with Enabled state// and without pseudo elementsQVector<Declaration> StyleSelector::declarationsForNode(NodePtr node, const char *extraPseudo){    QVector<Declaration> decls;    QVector<StyleRule> rules = styleRulesForNode(node);    for (int i = 0; i < rules.count(); i++) {        const Selector& selector = rules.at(i).selectors.at(0);        const QString pseudoElement = selector.pseudoElement();        if (extraPseudo && pseudoElement == QLatin1String(extraPseudo)) {            decls += rules.at(i).declarations;            continue;        }        if (!pseudoElement.isEmpty()) // skip rules with pseudo elements            continue;        int pseudoClass = selector.pseudoClass();        if (pseudoClass == PseudoClass_Enabled || pseudoClass == PseudoClass_Unspecified)            decls += rules.at(i).declarations;    }    return decls;}static inline bool isHexDigit(const char c){    return (c >= '0' && c <= '9')           || (c >= 'a' && c <= 'f')           || (c >= 'A' && c <= 'F')           ;}QString Scanner::preprocess(const QString &input, bool *hasEscapeSequences){    QString output = input;    if (hasEscapeSequences)        *hasEscapeSequences = false;    int i = 0;    while (i < output.size()) {        if (output.at(i) == QLatin1Char('\\')) {            ++i;            // test for unicode hex escape            int hexCount = 0;            const int hexStart = i;            while (i < output.size()                   && isHexDigit(output.at(i).toLatin1())                   && hexCount < 7) {                ++hexCount;                ++i;            }            if (hexCount == 0) {                if (hasEscapeSequences)                    *hasEscapeSequences = true;                continue;            }            hexCount = qMin(hexCount, 6);            bool ok = false;            ushort code = output.mid(hexStart, hexCount).toUShort(&ok, 16);            if (ok) {                output.replace(hexStart - 1, hexCount + 1, QChar(code));                i = hexStart;            } else {                i = hexStart;            }        } else {            ++i;        }    }    return output;}int QCssScanner_Generated::handleCommentStart(){    while (pos < input.size() - 1) {        if (input.at(pos) == QLatin1Char('*')            && input.at(pos + 1) == QLatin1Char('/')) {            pos += 2;            break;        }        ++pos;    }    return S;}void Scanner::scan(const QString &preprocessedInput, QVector<Symbol> *symbols){    QCssScanner_Generated scanner(preprocessedInput);    Symbol sym;    int tok = scanner.lex();    while (tok != -1) {        sym.token = static_cast<TokenType>(tok);        sym.text = scanner.input;        sym.start = scanner.lexemStart;        sym.len = scanner.lexemLength;        symbols->append(sym);        tok = scanner.lex();    }}QString Symbol::lexem() const{    QString result;    if (len > 0)        result.reserve(len);    for (int i = 0; i < len; ++i) {        if (text.at(start + i) == QLatin1Char('\\') && i < len - 1)            ++i;        result.inline_append(text.at(start + i));    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -