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

📄 cssstyleselector.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                CSSRuleData* elt2 = m_matchedRules[j+1];                if (*elt > *elt2) {                    sorted = false;                    m_matchedRules[j] = elt2;                    m_matchedRules[j+1] = elt;                }            }            if (sorted)                return;        }    }    else {        // Peform a merge sort for larger lists.        uint mid = (start+end)/2;        sortMatchedRules(start, mid);        sortMatchedRules(mid, end);                CSSRuleData* elt = m_matchedRules[mid-1];        CSSRuleData* elt2 = m_matchedRules[mid];                // Handle the fast common case (of equal specificity).  The list may already        // be completely sorted.        if (*elt <= *elt2)            return;                // We have to merge sort.  Ensure our merge buffer is big enough to hold        // all the items.        m_tmpRules.resize(end - start);        uint i1 = start;        uint i2 = mid;                elt = m_matchedRules[i1];        elt2 = m_matchedRules[i2];                while (i1 < mid || i2 < end) {            if (i1 < mid && (i2 == end || *elt <= *elt2)) {                m_tmpRules[m_tmpRuleCount++] = elt;                i1++;                if (i1 < mid)                    elt = m_matchedRules[i1];            }            else {                m_tmpRules[m_tmpRuleCount++] = elt2;                i2++;                if (i2 < end)                    elt2 = m_matchedRules[i2];            }        }                for (uint i = start; i < end; i++)            m_matchedRules[i] = m_tmpRules[i-start];                m_tmpRuleCount = 0;    }    }void CSSStyleSelector::initElementAndPseudoState(ElementImpl* e){    element = e;    if (element && element->isHTMLElement())        htmlElement = static_cast<HTMLElementImpl*>(element);    else        htmlElement = 0;    ::encodedurl = &encodedurl;    pseudoState = PseudoUnknown;}void CSSStyleSelector::initForStyleResolve(ElementImpl* e, RenderStyle* defaultParent){    // set some variables we will need    pseudoStyle = RenderStyle::NOPSEUDO;    parentNode = e->parentNode();    if (defaultParent)        parentStyle = defaultParent;    else        parentStyle = (parentNode && parentNode->renderer()) ? parentNode->renderer()->style() : 0;    view = element->getDocument()->view();    isXMLDoc = !element->getDocument()->isHTMLDocument();    part = element->getDocument()->part();    settings = part ? part->settings() : 0;    paintDeviceMetrics = element->getDocument()->paintDeviceMetrics();        style = 0;        m_matchedRuleCount = 0;    m_matchedDeclCount = 0;    m_tmpRuleCount = 0;        fontDirty = false;}// modified version of the one in kurl.cppstatic void cleanpath(QString &path){    int pos;    while ( (pos = path.find( "/../" )) != -1 ) {        int prev = 0;        if ( pos > 0 )            prev = path.findRev( "/", pos -1 );        // don't remove the host, i.e. http://foo.org/../foo.html        if (prev < 0 || (prev > 3 && path.findRev("://", prev-1) == prev-2))            path.remove( pos, 3);        else            // matching directory found ?            path.remove( prev, pos- prev + 3 );    }    pos = 0;        // Don't remove "//" from an anchor identifier. -rjw    // Set refPos to -2 to mean "I haven't looked for the anchor yet".    // We don't want to waste a function call on the search for the the anchor    // in the vast majority of cases where there is no "//" in the path.    int refPos = -2;    while ( (pos = path.find( "//", pos )) != -1) {        if (refPos == -2)            refPos = path.find("#", 0);        if (refPos > 0 && pos >= refPos)            break;                if ( pos == 0 || path[pos-1] != ':' )            path.remove( pos, 1 );        else            pos += 2;    }    while ( (pos = path.find( "/./" )) != -1)        path.remove( pos, 2 );    //kdDebug() << "checkPseudoState " << path << endl;}static void checkPseudoState( DOM::ElementImpl *e, bool checkVisited = true ){    if (!e->hasAnchor()) {        pseudoState = PseudoNone;        return;    }        const AtomicString& attr = e->getAttribute(ATTR_HREF);    if (attr.isNull()) {        pseudoState = PseudoNone;        return;    }        if (!checkVisited) {        pseudoState = PseudoAnyLink;        return;    }        QConstString cu(attr.unicode(), attr.length());    QString u = cu.string();    if ( !u.contains("://") ) {        if ( u[0] == '/' )            u.prepend(encodedurl->host);        else if ( u[0] == '#' )            u.prepend(encodedurl->file);        else            u.prepend(encodedurl->path);        cleanpath( u );    }    //completeURL( attr.string() );    pseudoState = KHTMLFactory::vLinks()->contains( u ) ? PseudoVisited : PseudoLink;}#ifdef STYLE_SHARING_STATSstatic int fraction = 0;static int total = 0;#endifconst int siblingThreshold = 10;NodeImpl* CSSStyleSelector::locateCousinList(ElementImpl* parent){    if (parent && parent->isHTMLElement()) {        HTMLElementImpl* p = static_cast<HTMLElementImpl*>(parent);        if (p->renderer() && !p->inlineStyleDecl() && !p->hasID()) {            DOM::NodeImpl* r = p->previousSibling();            int subcount = 0;            RenderStyle* st = p->renderer()->style();            while (r) {                if (r->renderer() && r->renderer()->style() == st)                    return r->lastChild();                if (subcount++ == siblingThreshold)                    return 0;                r = r->previousSibling();            }            if (!r)                r = locateCousinList(static_cast<ElementImpl*>(parent->parentNode()));            while (r) {                if (r->renderer() && r->renderer()->style() == st)                    return r->lastChild();                if (subcount++ == siblingThreshold)                    return 0;                r = r->previousSibling();            }        }    }    return 0;}bool CSSStyleSelector::canShareStyleWithElement(NodeImpl* n){    if (n->isHTMLElement()) {        bool mouseInside = element->renderer() ? element->renderer()->mouseInside() : false;        HTMLElementImpl* s = static_cast<HTMLElementImpl*>(n);        if (s->renderer() && (s->id() == element->id()) && !s->hasID() &&            (s->hasClass() == element->hasClass()) && !s->inlineStyleDecl() &&            (s->hasMappedAttributes() == htmlElement->hasMappedAttributes()) &&            (s->hasAnchor() == element->hasAnchor()) &&             !s->renderer()->style()->affectedByAttributeSelectors() &&            (s->renderer()->mouseInside() == mouseInside) &&            (s->active() == element->active()) &&            (s->focused() == element->focused())) {            bool classesMatch = true;            if (s->hasClass()) {                const AtomicString& class1 = element->getAttribute(ATTR_CLASS);                const AtomicString& class2 = s->getAttribute(ATTR_CLASS);                classesMatch = (class1 == class2);            }                        if (classesMatch) {                bool mappedAttrsMatch = true;                if (s->hasMappedAttributes())                    mappedAttrsMatch = s->htmlAttributes()->mapsEquivalent(htmlElement->htmlAttributes());                if (mappedAttrsMatch) {                    bool anchorsMatch = true;                    if (s->hasAnchor()) {                        // We need to check to see if the visited state matches.                        QColor linkColor = element->getDocument()->linkColor();                        QColor visitedColor = element->getDocument()->visitedLinkColor();                        if (pseudoState == PseudoUnknown)                            checkPseudoState(element, s->renderer()->style()->pseudoState() != PseudoAnyLink ||                                             linkColor != visitedColor);                        anchorsMatch = (pseudoState == s->renderer()->style()->pseudoState());                    }                                        if (anchorsMatch) {#ifdef STYLE_SHARING_STATS                        fraction++; total++;                        printf("Sharing %d out of %d\n", fraction, total);#endif                        return true;                    }                }            }        }    }    return false;}RenderStyle* CSSStyleSelector::locateSharedStyle(){    //total++;    if (htmlElement && !htmlElement->inlineStyleDecl() && !htmlElement->hasID() &&        !htmlElement->getDocument()->usesSiblingRules()) {        // Check previous siblings.        int count = 0;        DOM::NodeImpl* n;        for (n = element->previousSibling(); n && !n->isElementNode(); n = n->previousSibling());        while (n) {            if (canShareStyleWithElement(n))                return n->renderer()->style();            if (count++ == siblingThreshold)                return 0;            for (n = n->previousSibling(); n && !n->isElementNode(); n = n->previousSibling());        }        if (!n)             n = locateCousinList(static_cast<ElementImpl*>(element->parentNode()));        while (n) {            if (canShareStyleWithElement(n))                return n->renderer()->style();            if (count++ == siblingThreshold)                return 0;            for (n = n->previousSibling(); n && !n->isElementNode(); n = n->previousSibling());        }            }#ifdef STYLE_SHARING_STATS    total++;    printf("Sharing %d out of %d\n", fraction, total);#endif    return 0;}RenderStyle* CSSStyleSelector::styleForElement(ElementImpl* e, RenderStyle* defaultParent){    if (!e->getDocument()->haveStylesheetsLoaded()) {        if (!styleNotYetAvailable) {            styleNotYetAvailable = ::new RenderStyle();            styleNotYetAvailable->setDisplay(NONE);            styleNotYetAvailable->ref();        }        return styleNotYetAvailable;    }        initElementAndPseudoState(e);    style = locateSharedStyle();    if (style)        return style;    initForStyleResolve(e, defaultParent);    style = new (e->getDocument()->renderArena()) RenderStyle();    if (parentStyle)        style->inheritFrom(parentStyle);    else        parentStyle = style;        // 1. First we match rules from the user agent sheet.    int firstUARule = -1, lastUARule = -1;    matchRules(defaultStyle, firstUARule, lastUARule);        // 2. In quirks mode, we match rules from the quirks user agent sheet.    if (!strictParsing)        matchRules(defaultQuirksStyle, firstUARule, lastUARule);        // 3. If our medium is print, then we match rules from the print sheet.    if (m_medium == "print")        matchRules(defaultPrintStyle, firstUARule, lastUARule);        // 4. Now we check user sheet rules.    int firstUserRule = -1, lastUserRule = -1;    matchRules(m_userStyle, firstUserRule, lastUserRule);    // 5. Now check author rules, beginning first with presentational attributes    // mapped from HTML.    int firstAuthorRule = -1, lastAuthorRule = -1;    if (htmlElement) {        // Ask if the HTML element has mapped attributes.        if (htmlElement->hasMappedAttributes()) {            // Walk our attribute list and add in each decl.            const HTMLNamedAttrMapImpl* map = htmlElement->htmlAttributes();            for (uint i = 0; i < map->length(); i++) {                HTMLAttributeImpl* attr = map->attributeItem(i);                if (attr->decl()) {                    if (firstAuthorRule == -1) firstAuthorRule = m_matchedDeclCount;                    lastAuthorRule = m_matchedDeclCount;                    addMatchedDeclaration(attr->decl());                }            }        }        // Now we check additional mapped declarations.        // Tables and table cells share an additional mapped rule that must be applied        // after all attributes, since their mapped style depends on the values of multiple attributes.        CSSStyleDeclarationImpl* attributeDecl = htmlElement->additionalAttributeStyleDecl();        if (attributeDecl) {            if (firstAuthorRule == -1) firstAuthorRule = m_matchedDeclCount;            lastAuthorRule = m_matchedDeclCount;            addMatchedDeclaration(attributeDecl);        }    }    

⌨️ 快捷键说明

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