📄 cssstyleselector.cpp
字号:
// 6. Check the rules in author sheets next. matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule); // 7. Now check our inline style attribute. if (htmlElement) { CSSStyleDeclarationImpl* 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; if (!e->getDocument()->haveStylesheetsLoaded()) { if (!styleNotYetAvailable) { styleNotYetAvailable = ::new RenderStyle(); styleNotYetAvailable->setDisplay(NONE); styleNotYetAvailable->ref(); } return styleNotYetAvailable; } 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. if (e && (e->id() == ID_FRAME || e->id() == ID_FRAMESET)) style->setPosition(STATIC); // 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());}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: { // 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 (selNS == xhtmlNamespace && localName < ID_LAST_TAG) selNS = anyNamespace; // Always match HTML elements even when in HTML docs. 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -