📄 cssstyleselector.cpp
字号:
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; } case CSSSelector::PseudoSelection: dynamicPseudo = RenderStyle::SELECTION; return true; case CSSSelector::PseudoBefore: dynamicPseudo = RenderStyle::BEFORE; return true; case CSSSelector::PseudoAfter: dynamicPseudo = RenderStyle::AFTER; return true; case CSSSelector::PseudoNotParsed: assert(false); break; case CSSSelector::PseudoLang: /* not supported for now */ case CSSSelector::PseudoOther: break; } return false; } // ### add the rest of the checks... return true;}// -----------------------------------------------------------------CSSRuleSet::CSSRuleSet(){ m_idRules.setAutoDelete(true); m_classRules.setAutoDelete(true); m_tagRules.setAutoDelete(true); m_universalRules = 0; m_ruleCount = 0;}void CSSRuleSet::addToRuleSet(void* hash, QPtrDict<CSSRuleDataList>& dict, CSSStyleRuleImpl* rule, CSSSelector* sel){ if (!hash) return; CSSRuleDataList* rules = dict.find(hash); if (!rules) { rules = new CSSRuleDataList(m_ruleCount++, rule, sel); dict.insert(hash, rules); } else rules->append(m_ruleCount++, rule, sel);}void CSSRuleSet::addRule(CSSStyleRuleImpl* rule, CSSSelector* sel){ if (sel->match == CSSSelector::Id) { addToRuleSet(sel->value.implementation(), m_idRules, rule, sel); return; } if (sel->match == CSSSelector::Class) { addToRuleSet(sel->value.implementation(), m_classRules, rule, sel); return; } Q_UINT16 localName = localNamePart(sel->tag); if (localName != anyLocalName) { addToRuleSet((void*)(int)localName, m_tagRules, rule, sel); return; } // Just put it in the universal rule set. if (!m_universalRules) m_universalRules = new CSSRuleDataList(m_ruleCount++, rule, sel); else m_universalRules->append(m_ruleCount++, rule, sel);}void CSSRuleSet::addRulesFromSheet(CSSStyleSheetImpl *sheet, const DOMString &medium){ if (!sheet || !sheet->isCSSStyleSheet()) return; // No media implies "all", but if a media list exists it must // contain our current medium if (sheet->media() && !sheet->media()->contains(medium)) return; // the style sheet doesn't apply int len = sheet->length(); for (int i = 0; i < len; i++) { StyleBaseImpl *item = sheet->item(i); if (item->isStyleRule()) { CSSStyleRuleImpl* rule = static_cast<CSSStyleRuleImpl*>(item); for (CSSSelector* s = rule->selector(); s; s = s->next()) addRule(rule, s); } else if(item->isImportRule()) { CSSImportRuleImpl *import = static_cast<CSSImportRuleImpl *>(item); //kdDebug( 6080 ) << "@import: Media: " // << import->media()->mediaText().string() << endl; if (!import->media() || import->media()->contains(medium)) addRulesFromSheet(import->styleSheet(), medium); } else if(item->isMediaRule()) { CSSMediaRuleImpl *r = static_cast<CSSMediaRuleImpl*>(item); CSSRuleListImpl *rules = r->cssRules(); //DOMString mediaText = media->mediaText(); //kdDebug( 6080 ) << "@media: Media: " // << r->media()->mediaText().string() << endl; if ((!r->media() || r->media()->contains(medium)) && rules) { // Traverse child elements of the @media rule. for (unsigned j = 0; j < rules->length(); j++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -