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

📄 cssstyleselector.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        {
            // FIXME: This match needs to know how to backtrack and be non-deterministic.
            bool found = false;
            while(!found)
            {
        n = n->parentNode();
                if(!n || !n->isElementNode()) return false;
                ElementImpl *elem = static_cast<ElementImpl *>(n);
                if (checkOneSelector(sel, elem)) found = true;
            }
            break;
        }
        case CSSSelector::Child:
        {
            n = n->parentNode();
            if (!strictParsing)
                while (n && n->implicitNode()) n = n->parentNode();
            if(!n || !n->isElementNode()) return false;
            ElementImpl *elem = static_cast<ElementImpl *>(n);
            if (!checkOneSelector(sel, elem)) return false;
            break;
        }
        case CSSSelector::Sibling:
        {
            n = n->previousSibling();
        while( n && !n->isElementNode() )
        n = n->previousSibling();
            if( !n ) return false;
            ElementImpl *elem = static_cast<ElementImpl *>(n);
            if (!checkOneSelector(sel, elem)) return false;
            break;
        }
        case CSSSelector::SubSelector:
    {
            if (onlyHoverActive)
                onlyHoverActive = (sel->match == CSSSelector::Pseudo &&
                                   (sel->pseudoType() == CSSSelector::PseudoHover ||
                                    sel->pseudoType() == CSSSelector::PseudoActive));

        //kdDebug() << "CSSOrderedRule::checkSelector" << endl;
        ElementImpl *elem = static_cast<ElementImpl *>(n);
        // a selector is invalid if something follows :first-xxx
        if (dynamicPseudo != RenderStyle::NOPSEUDO)
        return false;
        if (!checkOneSelector(sel, elem)) return false;
        //kdDebug() << "CSSOrderedRule::checkSelector: passed" << endl;
        break;
    }
        }
        relation = sel->relation;
    }

    if (subject && havePseudo && dynamicPseudo != pseudoStyle)
        return false;

    // disallow *:hover, *:active, and *:hover:active except for links
    if (onlyHoverActive && subject) {
        if (pseudoState == PseudoUnknown)
            checkPseudoState(e);

        if (pseudoState == PseudoNone) {
            if (!affectedByHover && style->affectedByHoverRules())
                style->setAffectedByHoverRules(false);
            if (!affectedByActive && style->affectedByActiveRules())
                style->setAffectedByActiveRules(false);
            return false;
        }
    }

    return true;
}

bool CSSStyleSelector::checkOneSelector(DOM::CSSSelector *sel, DOM::ElementImpl *e)
{
    if(!e)
        return false;

    if (sel->tag != anyQName) {
        int eltID = e->id();
        Q_UINT16 localName = localNamePart(eltID);
        Q_UINT16 ns = namespacePart(eltID);
        Q_UINT16 selLocalName = localNamePart(sel->tag);
        Q_UINT16 selNS = namespacePart(sel->tag);

        if (localName <= ID_LAST_TAG && e->isHTMLElement())
            ns = xhtmlNamespace; // FIXME: Really want to move away from this complicated hackery and just
                                 // switch tags and attr names over to AtomicStrings.

        if ((selLocalName != anyLocalName && localName != selLocalName) ||
            (selNS != anyNamespace && ns != selNS))
            return false;
    }

    if (sel->attr) {
        if (sel->match == CSSSelector::Class) {
            if (!e->hasClass())
                return false;
            for (const AtomicStringList* c = e->getClassList(); c; c = c->next())
                if (c->string() == sel->value)
                    return true;
            return false;
        }
        else if (sel->match == CSSSelector::Id)
            return e->hasID() && e->getIDAttribute() == sel->value;
        else if (style && (e != element || !htmlElement || !htmlElement->isMappedAttribute(sel->attr)))
            style->setAffectedByAttributeSelectors();

        const AtomicString& value = e->getAttribute(sel->attr);
        if (value.isNull()) return false; // attribute is not set

        switch(sel->match) {
        case CSSSelector::Exact:
        if ((isXMLDoc && sel->value != value) ||
                (!isXMLDoc && !equalsIgnoreCase(sel->value, value)))
                return false;
            break;
        case CSSSelector::List:
        {
            int spacePos = value.find(' ', 0);
            if (spacePos == -1) {
                // There is no list, just a single item.  We can avoid
                // allocing QStrings and just treat this as an exact
                // match check.
                if ((isXMLDoc && sel->value != value) ||
                    (!isXMLDoc && !equalsIgnoreCase(sel->value, value)))
                    return false;
                break;
            }

            // The selector's value can't contain a space, or it's totally bogus.
            spacePos = sel->value.find(' ');
            if (spacePos != -1)
                return false;

            QString str = value.string();
            QString selStr = sel->value.string();
            int startSearchAt = 0;
            while (true) {
                int foundPos = str.find(selStr, startSearchAt, isXMLDoc);
                if (foundPos == -1) return false;
                if (foundPos == 0 || str[foundPos-1] == ' ') {
                    uint endStr = foundPos + selStr.length();
                    if (endStr == str.length() || str[endStr] == ' ')
                        break; // We found a match.
                }

                // No match.  Keep looking.
                startSearchAt = foundPos + 1;
            }

            break;
        }
        case CSSSelector::Contain:
        {
            //kdDebug( 6080 ) << "checking for contains match" << endl;
            QString str = value.string();
            QString selStr = sel->value.string();
            int pos = str.find(selStr, 0, isXMLDoc);
            if(pos == -1) return false;
            break;
        }
        case CSSSelector::Begin:
        {
            //kdDebug( 6080 ) << "checking for beginswith match" << endl;
            QString str = value.string();
            QString selStr = sel->value.string();
            int pos = str.find(selStr, 0, isXMLDoc);
            if(pos != 0) return false;
            break;
        }
        case CSSSelector::End:
        {
            //kdDebug( 6080 ) << "checking for endswith match" << endl;
            QString str = value.string();
            QString selStr = sel->value.string();
        if (isXMLDoc && !str.endsWith(selStr)) return false;
        if (!isXMLDoc) {
            int pos = str.length() - selStr.length();
        if (pos < 0 || pos != str.find(selStr, pos, false) )
            return false;
        }
            break;
        }
        case CSSSelector::Hyphen:
        {
            //kdDebug( 6080 ) << "checking for hyphen match" << endl;
            QString str = value.string();
            QString selStr = sel->value.string();
            if(str.length() < selStr.length()) return false;
            // Check if str begins with selStr:
            if(str.find(selStr, 0, isXMLDoc) != 0) return false;
            // It does. Check for exact match or following '-':
            if(str.length() != selStr.length()
                && str[selStr.length()] != '-') return false;
            break;
        }
        default:
            break;
        }
    }
    if(sel->match == CSSSelector::Pseudo)
    {
        // Pseudo elements. We need to check first child here. No dynamic pseudo
        // elements for the moment
//  kdDebug() << "CSSOrderedRule::pseudo " << value << endl;
    switch (sel->pseudoType()) {
            case CSSSelector::PseudoEmpty:
                if (!e->firstChild())
                    return true;
                break;
            case CSSSelector::PseudoFirstChild: {
                // first-child matches the first child that is an element!
                if (e->parentNode()) {
                    DOM::NodeImpl* n = e->previousSibling();
                    while ( n && !n->isElementNode() )
                        n = n->previousSibling();
                    if ( !n )
                        return true;
                }
                break;
            }
            case CSSSelector::PseudoLastChild: {
                // last-child matches the last child that is an element!
                if (e->parentNode()) {
                    DOM::NodeImpl* n = e->nextSibling();
                    while ( n && !n->isElementNode() )
                        n = n->nextSibling();
                    if ( !n )
                        return true;
                }
                break;
            }
            case CSSSelector::PseudoOnlyChild: {
                // If both first-child and last-child apply, then only-child applies.
                if (e->parentNode()) {
                    DOM::NodeImpl* n = e->previousSibling();
                    while ( n && !n->isElementNode() )
                        n = n->previousSibling();
                    if ( !n ) {
                        n = e->nextSibling();
                        while ( n && !n->isElementNode() )
                            n = n->nextSibling();
                        if ( !n )
                            return true;
                    }
                }
                break;
            }
            case CSSSelector::PseudoFirstLine:
                if ( subject ) {
                    dynamicPseudo=RenderStyle::FIRST_LINE;
                    return true;
                }
                break;
            case CSSSelector::PseudoFirstLetter:
                if ( subject ) {
                    dynamicPseudo=RenderStyle::FIRST_LETTER;
                    return true;
                }
                break;
            case CSSSelector::PseudoTarget:
                if (e == e->getDocument()->getCSSTarget())
                    return true;
                break;
            case CSSSelector::PseudoAnyLink:
                if (pseudoState == PseudoUnknown)
                    checkPseudoState(e, false);
                if (pseudoState == PseudoAnyLink || pseudoState == PseudoLink || pseudoState == PseudoVisited)
                    return true;
                break;
            case CSSSelector::PseudoLink:
                if ( pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink )
                    checkPseudoState( e );
                if ( pseudoState == PseudoLink )
                    return true;
                break;
            case CSSSelector::PseudoVisited:
                if ( pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink )
                    checkPseudoState( e );
                if ( pseudoState == PseudoVisited )
                    return true;
                break;
            case CSSSelector::PseudoHover: {
                // If we're in quirks mode, then hover should never match anchors with no
                // href.  This is important for sites like wsj.com.
                if (strictParsing || e->id() != ID_A || e->hasAnchor()) {
                    if (element == e && style)
                        style->setAffectedByHoverRules(true);
                    if (e->renderer()) {
                        if (element != e)
                            e->renderer()->style()->setAffectedByHoverRules(true);
                        if (e->renderer()->mouseInside())
                            return true;
                    }
                }
                break;
            }
            case CSSSelector::PseudoDrag: {
                if (element == e && style)
                    style->setAffectedByDragRules(true);
                if (e->renderer()) {
                    if (element != e)
                        e->renderer()->style()->setAffectedByDragRules(true);
                    if (e->renderer()->isDragging())
                        return true;
                }
                break;
            }
            case CSSSelector::PseudoFocus:
                if (e && e->focused()) {
                    return true;
                }
                break;
            case CSSSelector::PseudoActive:
                // If we're in quirks mode, then :active should never match anchors with no
                // href.
                if (strictParsing || e->id() != ID_A || e->hasAnchor()) {
                    if (element == e && style)
                        style->setAffectedByActiveRules(true);
                    else if (e->renderer())
                        e->renderer()->style()->setAffectedByActiveRules(true);
                    if (e->active())
                        return true;
                }
                break;
            case CSSSelector::PseudoRoot:
                if (e == e->getDocument()->documentElement())
                    return true;
                break;
            case CSSSelector::PseudoNot: {
                // check the simple selector
                for (CSSSelector* subSel = sel->simpleSelector; subSel;
                     subSel = subSel->tagHistory) {
                    // :not cannot nest.  I don't really know why this is a restriction in CSS3,
                    // but it is, so let's honor it.
                    if (subSel->simpleSelector)
                        break;
                    if (!checkOneSelector(subSel, e))
                        return true;
                }
                break;
            }

⌨️ 快捷键说明

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