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

📄 cssstyleselector.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        while (n) {
            if (canShareStyleWithElement(n))
                return n->renderer()->style();
            if (count++ == siblingThreshold)
                return 0;
            for (n = n->previousSibling(); n && !n->isElementNode(); n = n->previousSibling());
        }
    }
    return 0;
}


RenderStyle* CSSStyleSelector::styleForElement(ElementImpl* e, RenderStyle* defaultParent, bool allowSharing)
{
#if NOKIA_CHANGES
    if (!e->getDocument()->haveStylesheetsLoaded() && !e->getDocument()->fastDisplayMode()) {
#else
    if (!e->getDocument()->haveStylesheetsLoaded()) {
#endif
        if (!styleNotYetAvailable) {
            styleNotYetAvailable = ::new RenderStyle();
            styleNotYetAvailable->setDisplay(NONE);
            styleNotYetAvailable->ref();
        }
        return styleNotYetAvailable;
    }

    initElementAndPseudoState(e);
    if (allowSharing) {
        style = locateSharedStyle();
#ifdef STYLE_SHARING_STATS
        fraction += style != 0;
        total++;
        printf("Sharing %d out of %d\n", fraction, total);
#endif
        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.
        CSSMutableStyleDeclarationImpl* attributeDecl = htmlElement->additionalAttributeStyleDecl();
        if (attributeDecl) {
            if (firstAuthorRule == -1) firstAuthorRule = m_matchedDeclCount;
            lastAuthorRule = m_matchedDeclCount;
            addMatchedDeclaration(attributeDecl);
        }
    }

    // 6. Check the rules in author sheets next.
    matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);

    // 7. Now check our inline style attribute.
    if (htmlElement) {
        CSSMutableStyleDeclarationImpl* inlineDecl = htmlElement->inlineStyleDecl();
        if (inlineDecl) {
            if (firstAuthorRule == -1) firstAuthorRule = m_matchedDeclCount;
            lastAuthorRule = m_matchedDeclCount;
            addMatchedDeclaration(inlineDecl);
        }
    }

    // Now we have all of the matched rules in the appropriate order.  Walk the rules and apply
    // high-priority properties first, i.e., those properties that other properties depend on.
    // The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
    // and (4) normal important.
    applyDeclarations(true, false, 0, m_matchedDeclCount-1);
    applyDeclarations(true, true, firstAuthorRule, lastAuthorRule);
    applyDeclarations(true, true, firstUserRule, lastUserRule);
    applyDeclarations(true, true, firstUARule, lastUARule);

    // If our font got dirtied, go ahead and update it now.
    if (fontDirty) {
        checkForTextSizeAdjust();
        checkForGenericFamilyChange(style, parentStyle);
        style->htmlFont().update(paintDeviceMetrics);
        fontDirty = false;
    }

    // Now do the normal priority properties.
    applyDeclarations(false, false, 0, m_matchedDeclCount-1);
    applyDeclarations(false, true, firstAuthorRule, lastAuthorRule);
    applyDeclarations(false, true, firstUserRule, lastUserRule);
    applyDeclarations(false, true, firstUARule, lastUARule);

    // If our font got dirtied by one of the non-essential font props,
    // go ahead and update it a second time.
    if (fontDirty) {
        checkForTextSizeAdjust();
        checkForGenericFamilyChange(style, parentStyle);
        style->htmlFont().update(paintDeviceMetrics);
        fontDirty = false;
    }

    // Clean up our style object's display and text decorations (among other fixups).
    adjustRenderStyle(style, e);

    // If we are a link, cache the determined pseudo-state.
    if (e->hasAnchor())
        style->setPseudoState(pseudoState);

    // Now return the style.
    return style;
}

RenderStyle* CSSStyleSelector::pseudoStyleForElement(RenderStyle::PseudoId pseudo,
                                                     ElementImpl* e, RenderStyle* parentStyle)
{
    if (!e)
        return 0;

    initElementAndPseudoState(e);
    initForStyleResolve(e, parentStyle);
    pseudoStyle = pseudo;

    // Since we don't use pseudo-elements in any of our quirk/print user agent rules, don't waste time walking
    // those rules.

    // Check UA, user and author rules.
    int firstUARule = -1, lastUARule = -1, firstUserRule = -1, lastUserRule = -1, firstAuthorRule = -1, lastAuthorRule = -1;
    matchRules(defaultStyle, firstUARule, lastUARule);
    matchRules(m_userStyle, firstUserRule, lastUserRule);
    matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);

    if (m_matchedDeclCount == 0)
        return 0;

    style = new (e->getDocument()->renderArena()) RenderStyle();
    if (parentStyle)
        style->inheritFrom(parentStyle);
    else
        parentStyle = style;
    style->noninherited_flags._styleType = pseudoStyle;

    // High-priority properties.
    applyDeclarations(true, false, 0, m_matchedDeclCount-1);
    applyDeclarations(true, true, firstAuthorRule, lastAuthorRule);
    applyDeclarations(true, true, firstUserRule, lastUserRule);
    applyDeclarations(true, true, firstUARule, lastUARule);

    // If our font got dirtied, go ahead and update it now.
    if (fontDirty) {
        checkForTextSizeAdjust();
        checkForGenericFamilyChange(style, parentStyle);
        style->htmlFont().update(paintDeviceMetrics);
        fontDirty = false;
    }

    // Now do the normal priority properties.
    applyDeclarations(false, false, 0, m_matchedDeclCount-1);
    applyDeclarations(false, true, firstAuthorRule, lastAuthorRule);
    applyDeclarations(false, true, firstUserRule, lastUserRule);
    applyDeclarations(false, true, firstUARule, lastUARule);

    // If our font got dirtied by one of the non-essential font props,
    // go ahead and update it a second time.
    if (fontDirty) {
        checkForTextSizeAdjust();
        checkForGenericFamilyChange(style, parentStyle);
        style->htmlFont().update(paintDeviceMetrics);
        fontDirty = false;
    }

    // Clean up our style object's display and text decorations (among other fixups).
    adjustRenderStyle(style, 0);

    // Now return the style.
    return style;
}

void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, DOM::ElementImpl *e)
{
    // Cache our original display.
    style->setOriginalDisplay(style->display());

    if (style->display() != NONE) {
        // If we have a <td> that specifies a float property, in quirks mode we just drop the float
        // property.
        // Sites also commonly use display:inline/block on <td>s and <table>s.  In quirks mode we force
        // these tags to retain their display types.
        if (!strictParsing && e) {
            if (e->id() == ID_TD) {
                style->setDisplay(TABLE_CELL);
                style->setFloating(FNONE);
            }
            else if (e->id() == ID_TABLE)
                style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE);
        }

        // Frames and framesets never honor position:relative or position:absolute.  This is necessary to
        // fix a crash where a site tries to position these objects.  They also never honor display.
        if (e && (e->id() == ID_FRAME || e->id() == ID_FRAMESET)) {
            style->setPosition(STATIC);
            style->setDisplay(BLOCK);
        }

        // Table headers with a text-align of auto will change the text-align to center.
        if (e && e->id() == ID_TH && style->textAlign() == TAAUTO)
            style->setTextAlign(CENTER);

        // Mutate the display to BLOCK or TABLE for certain cases, e.g., if someone attempts to
        // position or float an inline, compact, or run-in.  Cache the original display, since it
        // may be needed for positioned elements that have to compute their static normal flow
        // positions.  We also force inline-level roots to be block-level.
        if (style->display() != BLOCK && style->display() != TABLE && style->display() != BOX &&
            (style->position() == ABSOLUTE || style->position() == FIXED || style->floating() != FNONE ||
             (e && e->getDocument()->documentElement() == e))) {
            if (style->display() == INLINE_TABLE)
                style->setDisplay(TABLE);
            else if (style->display() == INLINE_BOX)
                style->setDisplay(BOX);
            else if (style->display() == LIST_ITEM) {
                // It is a WinIE bug that floated list items lose their bullets, so we'll emulate the quirk,
                // but only in quirks mode.
                if (!strictParsing && style->floating() != FNONE)
                    style->setDisplay(BLOCK);
            }
            else
                style->setDisplay(BLOCK);
        }

        // After performing the display mutation, check table rows.  We do not honor position:relative on
        // table rows.  This has been established in CSS2.1 (and caused a crash in containingBlock() on
        // some sites).
        if (style->display() == TABLE_ROW && style->position() == RELATIVE)
            style->setPosition(STATIC);
    }

    // Make sure our z-index value is only applied if the object is positioned,
    // relatively positioned, or transparent.
    if (style->position() == STATIC && style->opacity() == 1.0f) {
        if (e && e->getDocument()->documentElement() == e)
            style->setZIndex(0); // The root has a z-index of 0 if not positioned or transparent.
        else
            style->setHasAutoZIndex(); // Everyone else gets an auto z-index.
    }

    // Auto z-index becomes 0 for transparent objects.  This prevents cases where
    // objects that should be blended as a single unit end up with a non-transparent object
    // wedged in between them.
    if (style->opacity() < 1.0f && style->hasAutoZIndex())
        style->setZIndex(0);

    // Finally update our text decorations in effect, but don't allow text-decoration to percolate through
    // tables, inline blocks, inline tables, or run-ins.
    if (style->display() == TABLE || style->display() == INLINE_TABLE || style->display() == RUN_IN
        || style->display() == INLINE_BLOCK || style->display() == INLINE_BOX)
        style->setTextDecorationsInEffect(style->textDecoration());
    else
        style->addToTextDecorationsInEffect(style->textDecoration());

    // Cull out any useless layers and also repeat patterns into additional layers.
    style->adjustBackgroundLayers();

    // Only use slow repaints if we actually have a background image.
    // FIXME: We only need to invalidate the fixed regions when scrolling.  It's total overkill to
    // prevent the entire view from blitting on a scroll.
    if (style->hasFixedBackgroundImage() && view)
        view->useSlowRepaints();
}

static bool subject;

bool CSSStyleSelector::checkSelector(CSSSelector* sel, ElementImpl *e)
{
    dynamicPseudo = RenderStyle::NOPSEUDO;

    NodeImpl *n = e;

    // we have the subject part of the selector
    subject = true;

    // We track whether or not the rule contains only :hover and :active in a simple selector. If
    // so, we can't allow that to apply to every element on the page.  We assume the author intended
    // to apply the rules only to links.
    bool onlyHoverActive = (sel->tag == anyQName &&
                            (sel->match == CSSSelector::Pseudo &&
                              (sel->pseudoType() == CSSSelector::PseudoHover ||
                               sel->pseudoType() == CSSSelector::PseudoActive)));
    bool affectedByHover = style ? style->affectedByHoverRules() : false;
    bool affectedByActive = style ? style->affectedByActiveRules() : false;
    bool havePseudo = pseudoStyle != RenderStyle::NOPSEUDO;

    // first selector has to match
    if (!checkOneSelector(sel, e)) return false;

    // check the subselectors
    CSSSelector::Relation relation = sel->relation;
    while((sel = sel->tagHistory))
    {
        if (!n->isElementNode()) return false;
        if (relation != CSSSelector::SubSelector) {
            subject = false;
            if (havePseudo && dynamicPseudo != pseudoStyle)
                return false;
        }

        switch(relation)
        {
        case CSSSelector::Descendant:

⌨️ 快捷键说明

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