Changeset 195293 in webkit
- Timestamp:
- Jan 19, 2016 9:39:20 AM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r195291 r195293 1 2016-01-18 Antti Koivisto <antti@apple.com> 2 3 Selector checker should not mutate document and style 4 https://bugs.webkit.org/show_bug.cgi?id=153205 5 6 Reviewed by Darin Adler. 7 8 Selector checker currently writes affected-by bits and similar directly to the document and style during selector 9 matching. This is confusing, complicated and wrong. 10 11 This patch changes SelectorChecker and SelectorCompiler to collect style relatationship metadata to a separate 12 data structure (currently part of SelectorChecker::CheckingContext) instead of changing the document and style 13 directly. The mutations are performed later outside selector checker. 14 15 * css/ElementRuleCollector.cpp: 16 (WebCore::ElementRuleCollector::ruleMatches): 17 (WebCore::ElementRuleCollector::commitStyleRelations): 18 19 Apply the relationship bit to elements and style. 20 21 (WebCore::ElementRuleCollector::collectMatchingRulesForList): 22 * css/ElementRuleCollector.h: 23 * css/SelectorChecker.cpp: 24 (WebCore::SelectorChecker::LocalContext::LocalContext): 25 26 LocalContext is now a separate data structure. 27 28 (WebCore::addStyleRelation): 29 30 Helper for recording new style relations. This is used where code mutated elements or style directly before. 31 32 (WebCore::isFirstChildElement): 33 (WebCore::isLastChildElement): 34 (WebCore::isFirstOfType): 35 (WebCore::isLastOfType): 36 (WebCore::countElementsBefore): 37 (WebCore::countElementsOfTypeBefore): 38 (WebCore::SelectorChecker::SelectorChecker): 39 (WebCore::SelectorChecker::match): 40 (WebCore::hasScrollbarPseudoElement): 41 (WebCore::localContextForParent): 42 (WebCore::SelectorChecker::matchRecursively): 43 (WebCore::attributeValueMatches): 44 (WebCore::anyAttributeMatches): 45 (WebCore::canMatchHoverOrActiveInQuirksMode): 46 (WebCore::tagMatches): 47 (WebCore::SelectorChecker::checkOne): 48 (WebCore::SelectorChecker::matchSelectorList): 49 (WebCore::SelectorChecker::checkScrollbarPseudoClass): 50 (WebCore::SelectorChecker::CheckingContextWithStatus::CheckingContextWithStatus): Deleted. 51 (WebCore::checkingContextForParent): Deleted. 52 * css/SelectorChecker.h: 53 (WebCore::SelectorChecker::CheckingContext::CheckingContext): 54 * css/SelectorCheckerTestFunctions.h: 55 (WebCore::isEnabled): 56 (WebCore::isMediaDocument): 57 (WebCore::isChecked): 58 (WebCore::isInRange): 59 (WebCore::isOutOfRange): 60 * css/StyleResolver.h: 61 (WebCore::checkRegionSelector): 62 * cssjit/SelectorCompiler.cpp: 63 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateAddStyleRelationIfResolvingStyle): 64 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateAddStyleRelation): 65 66 Helpers for generating code for recording new style relations. This is used where code mutated elements or style directly before. 67 68 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorCheckerExcludingPseudoElements): 69 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateDirectAdjacentTreeWalker): 70 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateIndirectAdjacentTreeWalker): 71 (WebCore::SelectorCompiler::addStyleRelationElementFunction): 72 (WebCore::SelectorCompiler::SelectorCodeGenerator::jumpIfNoPreviousAdjacentElement): 73 (WebCore::SelectorCompiler::SelectorCodeGenerator::moduloIsZero): 74 (WebCore::SelectorCompiler::SelectorCodeGenerator::linkFailures): 75 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatching): 76 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateContextFunctionCallTest): 77 (WebCore::SelectorCompiler::elementIsActive): 78 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsActive): 79 (WebCore::SelectorCompiler::jumpIfElementIsNotEmpty): 80 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsEmpty): 81 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsFirstChild): 82 (WebCore::SelectorCompiler::elementIsHovered): 83 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsHovered): 84 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsInLanguage): 85 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsLastChild): 86 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsOnlyChild): 87 (WebCore::SelectorCompiler::makeContextStyleUniqueIfNecessaryAndTestIsPlaceholderShown): 88 (WebCore::SelectorCompiler::isPlaceholderShown): 89 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementHasPlaceholderShown): 90 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsLink): 91 (WebCore::SelectorCompiler::nthFilterIsAlwaysSatisified): 92 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild): 93 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChildOf): 94 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthLastChild): 95 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthLastChildOf): 96 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateMarkPseudoStyleForPseudoElement): 97 (WebCore::SelectorCompiler::SelectorCodeGenerator::addFlagsToElementStyleFromContext): Deleted. 98 (WebCore::SelectorCompiler::setNodeFlag): Deleted. 99 (WebCore::SelectorCompiler::SelectorCodeGenerator::markElementIfResolvingStyle): Deleted. 100 (WebCore::SelectorCompiler::setFirstChildState): Deleted. 101 (WebCore::SelectorCompiler::elementIsActiveForStyleResolution): Deleted. 102 (WebCore::SelectorCompiler::setElementStyleIsAffectedByEmpty): Deleted. 103 (WebCore::SelectorCompiler::setElementStyleFromContextIsAffectedByEmptyAndUpdateRenderStyleIfNecessary): Deleted. 104 (WebCore::SelectorCompiler::elementIsHoveredForStyleResolution): Deleted. 105 (WebCore::SelectorCompiler::setLastChildState): Deleted. 106 (WebCore::SelectorCompiler::setOnlyChildState): Deleted. 107 (WebCore::SelectorCompiler::makeElementStyleUniqueIfNecessaryAndTestIsPlaceholderShown): Deleted. 108 (WebCore::SelectorCompiler::setElementChildIndex): Deleted. 109 (WebCore::SelectorCompiler::setChildrenAffectedByBackwardPositionalRules): Deleted. 110 (WebCore::SelectorCompiler::setParentAffectedByLastChildOf): Deleted. 111 * dom/SelectorQuery.cpp: 112 (WebCore::SelectorDataList::selectorMatches): 113 (WebCore::SelectorDataList::selectorClosest): 114 (WebCore::SelectorDataList::matches): 115 * inspector/InspectorCSSAgent.cpp: 116 (WebCore::InspectorCSSAgent::buildArrayForMatchedRuleList): 117 * inspector/InspectorStyleSheet.cpp: 118 (WebCore::buildObjectForSelectorHelper): 119 1 120 2016-01-19 Carlos Garcia Campos <cgarcia@igalia.com> 2 121 -
trunk/Source/WebCore/css/ElementRuleCollector.cpp
r194762 r195293 38 38 #include "HTMLElement.h" 39 39 #include "InspectorInstrumentation.h" 40 #include "NodeRenderStyle.h" 40 41 #include "RenderRegion.h" 41 42 #include "SVGElement.h" … … 329 330 330 331 SelectorChecker::CheckingContext context(m_mode); 331 context.elementStyle = m_style;332 332 context.pseudoId = m_pseudoStyleRequest.pseudoId; 333 333 context.scrollbar = m_pseudoStyleRequest.scrollbar; 334 334 context.scrollbarPart = m_pseudoStyleRequest.scrollbarPart; 335 335 336 bool selectorMatches; 336 337 #if ENABLE(CSS_SELECTOR_JIT) 337 338 if (compiledSelectorChecker) { … … 343 344 ruleData.compiledSelectorUsed(); 344 345 #endif 345 returnselectorChecker(&m_element, &context, &specificity);346 } 346 selectorMatches = selectorChecker(&m_element, &context, &specificity); 347 } else 347 348 #endif // ENABLE(CSS_SELECTOR_JIT) 348 349 // Slow path. 350 SelectorChecker selectorChecker(m_element.document()); 351 return selectorChecker.match(ruleData.selector(), &m_element, context, specificity); 349 { 350 // Slow path. 351 SelectorChecker selectorChecker(m_element.document()); 352 selectorMatches = selectorChecker.match(*ruleData.selector(), m_element, context, specificity); 353 } 354 355 commitStyleRelations(context.styleRelations); 356 357 if (context.pseudoIDSet) 358 m_style->setHasPseudoStyles(context.pseudoIDSet); 359 360 return selectorMatches; 361 } 362 363 // FIXME: Rule collector should not be doing mutations. Move this somewhere else. 364 void ElementRuleCollector::commitStyleRelations(const SelectorChecker::StyleRelations& styleRelations) 365 { 366 for (auto& relation : styleRelations) { 367 switch (relation.type) { 368 case SelectorChecker::StyleRelation::AffectedByActive: 369 if (&relation.element == &m_element) 370 m_style->setAffectedByActive(); 371 else 372 relation.element.setChildrenAffectedByActive(); 373 break; 374 case SelectorChecker::StyleRelation::AffectedByDrag: 375 if (&relation.element == &m_element) 376 m_style->setAffectedByDrag(); 377 else 378 relation.element.setChildrenAffectedByDrag(); 379 break; 380 case SelectorChecker::StyleRelation::AffectedByEmpty: 381 relation.element.setStyleAffectedByEmpty(); 382 if (&relation.element == &m_element) 383 m_style->setEmptyState(relation.value); 384 break; 385 case SelectorChecker::StyleRelation::AffectedByHover: 386 if (&relation.element == &m_element) 387 m_style->setAffectedByHover(); 388 else 389 relation.element.setChildrenAffectedByHover(); 390 break; 391 case SelectorChecker::StyleRelation::AffectedByPreviousSibling: 392 relation.element.setStyleIsAffectedByPreviousSibling(); 393 break; 394 case SelectorChecker::StyleRelation::AffectsNextSibling: 395 relation.element.setAffectsNextSiblingElementStyle(); 396 break; 397 case SelectorChecker::StyleRelation::ChildrenAffectedByBackwardPositionalRules: 398 relation.element.setChildrenAffectedByBackwardPositionalRules(); 399 break; 400 case SelectorChecker::StyleRelation::ChildrenAffectedByFirstChildRules: 401 relation.element.setChildrenAffectedByFirstChildRules(); 402 break; 403 case SelectorChecker::StyleRelation::ChildrenAffectedByPropertyBasedBackwardPositionalRules: 404 relation.element.setChildrenAffectedByBackwardPositionalRules(); 405 relation.element.setChildrenAffectedByPropertyBasedBackwardPositionalRules(); 406 break; 407 case SelectorChecker::StyleRelation::ChildrenAffectedByLastChildRules: 408 relation.element.setChildrenAffectedByLastChildRules(); 409 break; 410 case SelectorChecker::StyleRelation::FirstChild: 411 if (&relation.element == &m_element) 412 m_style->setFirstChildState(); 413 else if (auto* style = relation.element.renderStyle()) 414 style->setFirstChildState(); 415 break; 416 case SelectorChecker::StyleRelation::LastChild: 417 if (&relation.element == &m_element) 418 m_style->setLastChildState(); 419 else if (auto* style = relation.element.renderStyle()) 420 style->setLastChildState(); 421 break; 422 case SelectorChecker::StyleRelation::NthChildIndex: 423 relation.element.setChildIndex(relation.value); 424 break; 425 case SelectorChecker::StyleRelation::Unique: 426 if (&relation.element == &m_element) 427 m_style->setUnique(); 428 else if (auto* style = relation.element.renderStyle()) 429 style->setUnique(); 430 break; 431 } 432 } 352 433 } 353 434 -
trunk/Source/WebCore/css/ElementRuleCollector.h
r194762 r195293 85 85 void addMatchedRule(const MatchedRule&); 86 86 87 void commitStyleRelations(const SelectorChecker::StyleRelations&); 88 87 89 Element& m_element; 88 90 RenderStyle* m_style; -
trunk/Source/WebCore/css/SelectorChecker.cpp
r191327 r195293 3 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) 4 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) 5 * Copyright (C) 2005 , 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014Apple Inc. All rights reserved.5 * Copyright (C) 2005-2016 Apple Inc. All rights reserved. 6 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> 7 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> … … 47 47 #include "HTMLStyleElement.h" 48 48 #include "InspectorInstrumentation.h" 49 #include "NodeRenderStyle.h"50 49 #include "Page.h" 51 50 #include "RenderElement.h" 52 #include "RenderStyle.h"53 51 #include "SelectorCheckerTestFunctions.h" 54 52 #include "ShadowRoot.h" … … 64 62 }; 65 63 66 struct SelectorChecker::CheckingContextWithStatus : public SelectorChecker::CheckingContext { 67 CheckingContextWithStatus(const SelectorChecker::CheckingContext& checkingContext, const CSSSelector* selector, Element* element) 68 : SelectorChecker::CheckingContext(checkingContext) 69 , selector(selector) 70 , element(element) 71 , visitedMatchType(resolvingMode == SelectorChecker::Mode::QueryingRules ? VisitedMatchType::Disabled : VisitedMatchType::Enabled) 72 , firstSelectorOfTheFragment(selector) 73 , inFunctionalPseudoClass(false) 74 , pseudoElementEffective(true) 75 , hasScrollbarPseudo(false) 76 , hasSelectionPseudo(false) 64 struct SelectorChecker::LocalContext { 65 LocalContext(const CSSSelector& selector, const Element& element, VisitedMatchType visitedMatchType, PseudoId pseudoId) 66 : selector(&selector) 67 , element(&element) 68 , visitedMatchType(visitedMatchType) 69 , firstSelectorOfTheFragment(&selector) 70 , pseudoId(pseudoId) 77 71 { } 78 72 79 73 const CSSSelector* selector; 80 Element* element;74 const Element* element; 81 75 VisitedMatchType visitedMatchType; 82 76 const CSSSelector* firstSelectorOfTheFragment; 83 bool inFunctionalPseudoClass; 84 bool pseudoElementEffective; 85 bool hasScrollbarPseudo; 86 bool hasSelectionPseudo; 77 PseudoId pseudoId; 78 bool isMatchElement { true }; 79 bool inFunctionalPseudoClass { false }; 80 bool pseudoElementEffective { true }; 81 bool hasScrollbarPseudo { false }; 82 bool hasSelectionPseudo { false }; 83 87 84 }; 88 85 86 static inline void addStyleRelation(SelectorChecker::CheckingContext& checkingContext, const Element& element, SelectorChecker::StyleRelation::Type type, unsigned value = 1) 87 { 88 ASSERT(value == 1 || type == SelectorChecker::StyleRelation::NthChildIndex || type == SelectorChecker::StyleRelation::AffectedByEmpty); 89 if (checkingContext.resolvingMode != SelectorChecker::Mode::ResolvingStyle) 90 return; 91 checkingContext.styleRelations.append({ const_cast<Element&>(element), type, value }); 92 } 93 89 94 static inline bool isFirstChildElement(const Element& element) 90 95 { … … 97 102 } 98 103 99 static inline bool isFirstOfType( Element& element, const QualifiedName& type, bool isResolvingStyle)100 { 101 for ( Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {102 if (isResolvingStyle)103 sibling->setAffectsNextSiblingElementStyle(); 104 static inline bool isFirstOfType(SelectorChecker::CheckingContext& checkingContext, const Element& element, const QualifiedName& type) 105 { 106 for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) { 107 addStyleRelation(checkingContext, *sibling, SelectorChecker::StyleRelation::AffectsNextSibling); 108 104 109 if (sibling->hasTagName(type)) 105 110 return false; … … 117 122 } 118 123 119 static inline int countElementsBefore( Element& element, bool isResolvingStyle)124 static inline int countElementsBefore(SelectorChecker::CheckingContext& checkingContext, const Element& element) 120 125 { 121 126 int count = 0; 122 for ( Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {123 if (isResolvingStyle) 124 sibling->setAffectsNextSiblingElementStyle();127 for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) { 128 129 addStyleRelation(checkingContext, *sibling, SelectorChecker::StyleRelation::AffectsNextSibling); 125 130 126 131 unsigned index = sibling->childIndex(); … … 134 139 } 135 140 136 static inline int countElementsOfTypeBefore( Element& element, const QualifiedName& type, bool isResolvingStyle)141 static inline int countElementsOfTypeBefore(SelectorChecker::CheckingContext& checkingContext, const Element& element, const QualifiedName& type) 137 142 { 138 143 int count = 0; 139 for (Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) { 140 if (isResolvingStyle) 141 sibling->setAffectsNextSiblingElementStyle(); 144 for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) { 145 addStyleRelation(checkingContext, *sibling, SelectorChecker::StyleRelation::AffectsNextSibling); 142 146 143 147 if (sibling->hasTagName(type)) … … 171 175 } 172 176 173 bool SelectorChecker::match(const CSSSelector * selector, Element* element, const CheckingContext& providedContext, unsigned& specificity) const177 bool SelectorChecker::match(const CSSSelector& selector, const Element& element, CheckingContext& checkingContext, unsigned& specificity) const 174 178 { 175 179 specificity = 0; 176 180 177 CheckingContextWithStatus context(providedContext, selector, element);181 LocalContext context(selector, element, checkingContext.resolvingMode == SelectorChecker::Mode::QueryingRules ? VisitedMatchType::Disabled : VisitedMatchType::Enabled, checkingContext.pseudoId); 178 182 PseudoIdSet pseudoIdSet; 179 MatchResult result = matchRecursively(c ontext, pseudoIdSet, specificity);183 MatchResult result = matchRecursively(checkingContext, context, pseudoIdSet, specificity); 180 184 if (result.match != Match::SelectorMatches) 181 185 return false; 182 if (c ontext.pseudoId != NOPSEUDO && !pseudoIdSet.has(context.pseudoId))186 if (checkingContext.pseudoId != NOPSEUDO && !pseudoIdSet.has(checkingContext.pseudoId)) 183 187 return false; 184 188 185 if (c ontext.pseudoId == NOPSEUDO && pseudoIdSet) {189 if (checkingContext.pseudoId == NOPSEUDO && pseudoIdSet) { 186 190 PseudoIdSet publicPseudoIdSet = pseudoIdSet & PseudoIdSet::fromMask(PUBLIC_PSEUDOID_MASK); 187 if (c ontext.resolvingMode == Mode::ResolvingStyle && publicPseudoIdSet)188 c ontext.elementStyle->setHasPseudoStyles(publicPseudoIdSet);191 if (checkingContext.resolvingMode == Mode::ResolvingStyle && publicPseudoIdSet) 192 checkingContext.pseudoIDSet = publicPseudoIdSet; 189 193 190 194 // When ignoring virtual pseudo elements, the context's pseudo should also be NOPSEUDO but that does 191 195 // not cause a failure. 192 return c ontext.resolvingMode == Mode::CollectingRulesIgnoringVirtualPseudoElements || result.matchType == MatchType::Element;196 return checkingContext.resolvingMode == Mode::CollectingRulesIgnoringVirtualPseudoElements || result.matchType == MatchType::Element; 193 197 } 194 198 return true; … … 206 210 } 207 211 208 static SelectorChecker:: CheckingContextWithStatus checkingContextForParent(const SelectorChecker::CheckingContextWithStatus& context)209 { 210 SelectorChecker:: CheckingContextWithStatusupdatedContext(context);212 static SelectorChecker::LocalContext localContextForParent(const SelectorChecker::LocalContext& context) 213 { 214 SelectorChecker::LocalContext updatedContext(context); 211 215 // Disable :visited matching when we see the first link. 212 216 if (context.element->isLink()) 213 217 updatedContext.visitedMatchType = VisitedMatchType::Disabled; 214 218 updatedContext.element = context.element->parentElement(); 219 updatedContext.isMatchElement = false; 215 220 return updatedContext; 216 221 } … … 222 227 // * SelectorFailsAllSiblings - the selector fails for e and any sibling of e 223 228 // * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e 224 SelectorChecker::MatchResult SelectorChecker::matchRecursively( const CheckingContextWithStatus& context, PseudoIdSet& dynamicPseudoIdSet, unsigned& specificity) const229 SelectorChecker::MatchResult SelectorChecker::matchRecursively(CheckingContext& checkingContext, const LocalContext& context, PseudoIdSet& dynamicPseudoIdSet, unsigned& specificity) const 225 230 { 226 231 MatchType matchType = MatchType::Element; 227 232 228 233 // The first selector has to match. 229 if (!checkOne(c ontext, dynamicPseudoIdSet, matchType, specificity))234 if (!checkOne(checkingContext, context, dynamicPseudoIdSet, matchType, specificity)) 230 235 return MatchResult::fails(Match::SelectorFailsLocally); 231 236 … … 248 253 return MatchResult::fails(Match::SelectorFailsCompletely); 249 254 250 if (c ontext.resolvingMode == Mode::QueryingRules)255 if (checkingContext.resolvingMode == Mode::QueryingRules) 251 256 return MatchResult::fails(Match::SelectorFailsCompletely); 252 257 … … 266 271 return MatchResult::matches(matchType); 267 272 268 CheckingContextWithStatusnextContext(context);273 LocalContext nextContext(context); 269 274 nextContext.selector = historySelector; 270 275 … … 281 286 // Virtual pseudo element is only effective in the rightmost fragment. 282 287 nextContext.pseudoElementEffective = false; 288 nextContext.isMatchElement = false; 283 289 } 284 290 285 291 switch (relation) { 286 292 case CSSSelector::Descendant: 287 nextContext = checkingContextForParent(nextContext);293 nextContext = localContextForParent(nextContext); 288 294 nextContext.firstSelectorOfTheFragment = nextContext.selector; 289 nextContext.elementStyle = nullptr; 290 for (; nextContext.element; nextContext = checkingContextForParent(nextContext)) { 295 for (; nextContext.element; nextContext = localContextForParent(nextContext)) { 291 296 PseudoIdSet ignoreDynamicPseudo; 292 297 unsigned descendantsSpecificity = 0; 293 MatchResult result = matchRecursively( nextContext, ignoreDynamicPseudo, descendantsSpecificity);298 MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo, descendantsSpecificity); 294 299 ASSERT(!nextContext.pseudoElementEffective && !ignoreDynamicPseudo); 295 300 … … 304 309 case CSSSelector::Child: 305 310 { 306 nextContext = checkingContextForParent(nextContext);311 nextContext = localContextForParent(nextContext); 307 312 if (!nextContext.element) 308 313 return MatchResult::fails(Match::SelectorFailsCompletely); 309 314 nextContext.firstSelectorOfTheFragment = nextContext.selector; 310 nextContext.elementStyle = nullptr;311 315 PseudoIdSet ignoreDynamicPseudo; 312 316 unsigned childSpecificity = 0; 313 MatchResult result = matchRecursively( nextContext, ignoreDynamicPseudo, childSpecificity);317 MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo, childSpecificity); 314 318 ASSERT(!nextContext.pseudoElementEffective && !ignoreDynamicPseudo); 315 319 … … 324 328 case CSSSelector::DirectAdjacent: 325 329 { 326 if (context.resolvingMode == Mode::ResolvingStyle) 327 context.element->setStyleIsAffectedByPreviousSibling(); 330 addStyleRelation(checkingContext, *context.element, StyleRelation::AffectedByPreviousSibling); 328 331 329 332 Element* previousElement = context.element->previousElementSibling(); 330 333 if (!previousElement) 331 334 return MatchResult::fails(Match::SelectorFailsAllSiblings); 332 if (context.resolvingMode == Mode::ResolvingStyle) 333 previousElement->setAffectsNextSiblingElementStyle(); 335 336 addStyleRelation(checkingContext, *previousElement, StyleRelation::AffectsNextSibling); 337 334 338 nextContext.element = previousElement; 335 339 nextContext.firstSelectorOfTheFragment = nextContext.selector; 336 nextContext.elementStyle = nullptr;337 340 PseudoIdSet ignoreDynamicPseudo; 338 341 unsigned adjacentSpecificity = 0; 339 MatchResult result = matchRecursively( nextContext, ignoreDynamicPseudo, adjacentSpecificity);342 MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo, adjacentSpecificity); 340 343 ASSERT(!nextContext.pseudoElementEffective && !ignoreDynamicPseudo); 341 344 … … 346 349 } 347 350 case CSSSelector::IndirectAdjacent: 348 if (context.resolvingMode == Mode::ResolvingStyle)349 context.element->setStyleIsAffectedByPreviousSibling(); 351 addStyleRelation(checkingContext, *context.element, StyleRelation::AffectedByPreviousSibling); 352 350 353 nextContext.element = context.element->previousElementSibling(); 351 354 nextContext.firstSelectorOfTheFragment = nextContext.selector; 352 nextContext.elementStyle = nullptr;353 355 for (; nextContext.element; nextContext.element = nextContext.element->previousElementSibling()) { 354 if (context.resolvingMode == Mode::ResolvingStyle) 355 nextContext.element->setAffectsNextSiblingElementStyle(); 356 addStyleRelation(checkingContext, *nextContext.element, StyleRelation::AffectsNextSibling); 356 357 357 358 PseudoIdSet ignoreDynamicPseudo; 358 359 unsigned indirectAdjacentSpecificity = 0; 359 MatchResult result = matchRecursively( nextContext, ignoreDynamicPseudo, indirectAdjacentSpecificity);360 MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo, indirectAdjacentSpecificity); 360 361 ASSERT(!nextContext.pseudoElementEffective && !ignoreDynamicPseudo); 361 362 … … 375 376 nextContext.hasScrollbarPseudo = hasScrollbarPseudoElement(dynamicPseudoIdSet); 376 377 nextContext.hasSelectionPseudo = dynamicPseudoIdSet.has(SELECTION); 377 if ((context. elementStyle || context.resolvingMode == Mode::CollectingRules) && dynamicPseudoIdSet378 if ((context.isMatchElement || checkingContext.resolvingMode == Mode::CollectingRules) && dynamicPseudoIdSet 378 379 && !nextContext.hasSelectionPseudo 379 380 && !(nextContext.hasScrollbarPseudo && nextContext.selector->match() == CSSSelector::PseudoClass)) … … 381 382 382 383 unsigned subselectorSpecificity = 0; 383 MatchResult result = matchRecursively( nextContext, dynamicPseudoIdSet, subselectorSpecificity);384 MatchResult result = matchRecursively(checkingContext, nextContext, dynamicPseudoIdSet, subselectorSpecificity); 384 385 385 386 if (result.match == Match::SelectorMatches) … … 395 396 nextContext.element = shadowHostNode; 396 397 nextContext.firstSelectorOfTheFragment = nextContext.selector; 397 nextContext.elementStyle = nullptr;398 398 PseudoIdSet ignoreDynamicPseudo; 399 399 unsigned shadowDescendantSpecificity = 0; 400 MatchResult result = matchRecursively( nextContext, ignoreDynamicPseudo, shadowDescendantSpecificity);400 MatchResult result = matchRecursively(checkingContext, nextContext, ignoreDynamicPseudo, shadowDescendantSpecificity); 401 401 402 402 if (result.match == Match::SelectorMatches) … … 505 505 } 506 506 507 static bool anyAttributeMatches( Element* element, const CSSSelector* selector, const QualifiedName& selectorAttr, bool caseSensitive)507 static bool anyAttributeMatches(const Element* element, const CSSSelector* selector, const QualifiedName& selectorAttr, bool caseSensitive) 508 508 { 509 509 ASSERT(element->hasAttributesWithoutUpdate()); … … 519 519 } 520 520 521 static bool canMatchHoverOrActiveInQuirksMode(const SelectorChecker:: CheckingContextWithStatus& context)521 static bool canMatchHoverOrActiveInQuirksMode(const SelectorChecker::LocalContext& context) 522 522 { 523 523 // For quirks mode, follow this: http://quirks.spec.whatwg.org/#the-:active-and-:hover-quirk … … 589 589 } 590 590 591 bool SelectorChecker::checkOne( const CheckingContextWithStatus& context, PseudoIdSet& dynamicPseudoIdSet, MatchType& matchType, unsigned& specificity) const592 { 593 Element* const &element = context.element;591 bool SelectorChecker::checkOne(CheckingContext& checkingContext, const LocalContext& context, PseudoIdSet& dynamicPseudoIdSet, MatchType& matchType, unsigned& specificity) const 592 { 593 const Element* element = context.element; 594 594 const CSSSelector* const & selector = context.selector; 595 595 ASSERT(element); … … 627 627 628 628 for (const CSSSelector* subselector = selectorList->first(); subselector; subselector = CSSSelectorList::next(subselector)) { 629 CheckingContextWithStatussubcontext(context);629 LocalContext subcontext(context); 630 630 subcontext.inFunctionalPseudoClass = true; 631 631 subcontext.pseudoElementEffective = false; … … 635 635 636 636 unsigned ignoredSpecificity; 637 if (matchRecursively( subcontext, ignoreDynamicPseudo, ignoredSpecificity).match == Match::SelectorMatches) {637 if (matchRecursively(checkingContext, subcontext, ignoreDynamicPseudo, ignoredSpecificity).match == Match::SelectorMatches) { 638 638 ASSERT(!ignoreDynamicPseudo); 639 639 return false; … … 644 644 // CSS scrollbars match a specific subset of pseudo classes, and they have specialized rules for each 645 645 // (since there are no elements involved except with window-inactive). 646 return checkScrollbarPseudoClass(c ontext, selector);646 return checkScrollbarPseudoClass(checkingContext, *context.element, selector); 647 647 } 648 648 … … 668 668 } 669 669 } 670 if (context.resolvingMode == Mode::ResolvingStyle) { 671 element->setStyleAffectedByEmpty(); 672 if (context.elementStyle) 673 context.elementStyle->setEmptyState(result); 674 } 670 addStyleRelation(checkingContext, *context.element, StyleRelation::AffectedByEmpty, result); 671 675 672 return result; 676 673 } 677 674 case CSSSelector::PseudoClassFirstChild: 678 675 // first-child matches the first child that is an element 679 if (Element* parentElement = element->parentElement()) { 680 bool result = isFirstChildElement(*element); 681 if (context.resolvingMode == Mode::ResolvingStyle) { 682 RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element->renderStyle(); 683 parentElement->setChildrenAffectedByFirstChildRules(); 684 if (result && childStyle) 685 childStyle->setFirstChildState(); 686 } 687 return result; 676 if (const Element* parentElement = element->parentElement()) { 677 bool isFirstChild = isFirstChildElement(*element); 678 if (isFirstChild) 679 addStyleRelation(checkingContext, *element, StyleRelation::FirstChild); 680 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByFirstChildRules); 681 return isFirstChild; 688 682 } 689 683 break; … … 691 685 // first-of-type matches the first element of its type 692 686 if (element->parentElement()) { 693 if (context.resolvingMode == Mode::ResolvingStyle) 694 element->setStyleIsAffectedByPreviousSibling(); 695 696 return isFirstOfType(*element, element->tagQName(), context.resolvingMode == Mode::ResolvingStyle); 687 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByPreviousSibling); 688 return isFirstOfType(checkingContext, *element, element->tagQName()); 697 689 } 698 690 break; 699 691 case CSSSelector::PseudoClassLastChild: 700 692 // last-child matches the last child that is an element 701 if (Element* parentElement = element->parentElement()) { 702 bool result = parentElement->isFinishedParsingChildren() && isLastChildElement(*element); 703 if (context.resolvingMode == Mode::ResolvingStyle) { 704 RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element->renderStyle(); 705 parentElement->setChildrenAffectedByLastChildRules(); 706 if (result && childStyle) 707 childStyle->setLastChildState(); 708 } 709 return result; 693 if (const Element* parentElement = element->parentElement()) { 694 bool isLastChild = parentElement->isFinishedParsingChildren() && isLastChildElement(*element); 695 if (isLastChild) 696 addStyleRelation(checkingContext, *element, StyleRelation::LastChild); 697 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByLastChildRules); 698 return isLastChild; 710 699 } 711 700 break; … … 713 702 // last-of-type matches the last element of its type 714 703 if (Element* parentElement = element->parentElement()) { 715 if (context.resolvingMode == Mode::ResolvingStyle) 716 parentElement->setChildrenAffectedByBackwardPositionalRules(); 704 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByBackwardPositionalRules); 717 705 if (!parentElement->isFinishedParsingChildren()) 718 706 return false; … … 724 712 bool firstChild = isFirstChildElement(*element); 725 713 bool onlyChild = firstChild && parentElement->isFinishedParsingChildren() && isLastChildElement(*element); 726 if (context.resolvingMode == Mode::ResolvingStyle) { 727 RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element->renderStyle(); 728 parentElement->setChildrenAffectedByFirstChildRules(); 729 parentElement->setChildrenAffectedByLastChildRules(); 730 if (firstChild && childStyle) 731 childStyle->setFirstChildState(); 732 if (onlyChild && childStyle) 733 childStyle->setLastChildState(); 734 } 714 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByFirstChildRules); 715 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByLastChildRules); 716 if (firstChild) 717 addStyleRelation(checkingContext, *element, StyleRelation::FirstChild); 718 if (onlyChild) 719 addStyleRelation(checkingContext, *element, StyleRelation::LastChild); 735 720 return onlyChild; 736 721 } … … 739 724 // FIXME: This selector is very slow. 740 725 if (Element* parentElement = element->parentElement()) { 741 if (context.resolvingMode == Mode::ResolvingStyle) { 742 element->setStyleIsAffectedByPreviousSibling(); 743 parentElement->setChildrenAffectedByBackwardPositionalRules(); 744 } 726 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByPreviousSibling); 727 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByBackwardPositionalRules); 745 728 if (!parentElement->isFinishedParsingChildren()) 746 729 return false; 747 return isFirstOfType( *element, element->tagQName(), context.resolvingMode == Mode::ResolvingStyle) && isLastOfType(*element, element->tagQName());730 return isFirstOfType(checkingContext, *element, element->tagQName()) && isLastOfType(*element, element->tagQName()); 748 731 } 749 732 break; … … 755 738 MatchType localMatchType = MatchType::VirtualPseudoElementOnly; 756 739 for (const CSSSelector* subselector = selector->selectorList()->first(); subselector; subselector = CSSSelectorList::next(subselector)) { 757 CheckingContextWithStatussubcontext(context);740 LocalContext subcontext(context); 758 741 subcontext.inFunctionalPseudoClass = true; 759 742 subcontext.pseudoElementEffective = context.pseudoElementEffective; … … 762 745 PseudoIdSet localDynamicPseudoIdSet; 763 746 unsigned localSpecificity = 0; 764 MatchResult result = matchRecursively( subcontext, localDynamicPseudoIdSet, localSpecificity);747 MatchResult result = matchRecursively(checkingContext, subcontext, localDynamicPseudoIdSet, localSpecificity); 765 748 if (result.match == Match::SelectorMatches) { 766 749 maxSpecificity = std::max(maxSpecificity, localSpecificity); … … 781 764 case CSSSelector::PseudoClassPlaceholderShown: 782 765 if (is<HTMLTextFormControlElement>(*element)) { 783 if (context.resolvingMode == Mode::ResolvingStyle) { 784 if (RenderStyle* style = context.elementStyle ? context.elementStyle : element->renderStyle()) 785 style->setUnique(); 786 } 766 addStyleRelation(checkingContext, *element, StyleRelation::Unique); 787 767 return downcast<HTMLTextFormControlElement>(*element).isPlaceholderVisible(); 788 768 } … … 794 774 if (const CSSSelectorList* selectorList = selector->selectorList()) { 795 775 unsigned selectorListSpecificity; 796 if (matchSelectorList(c ontext, *element, *selectorList, selectorListSpecificity))776 if (matchSelectorList(checkingContext, context, *element, *selectorList, selectorListSpecificity)) 797 777 specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity); 798 778 else … … 800 780 } 801 781 802 if (context.resolvingMode == Mode::ResolvingStyle) 803 element->setStyleIsAffectedByPreviousSibling(); 782 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByPreviousSibling); 804 783 805 784 int count = 1; 806 785 if (const CSSSelectorList* selectorList = selector->selectorList()) { 807 786 for (Element* sibling = ElementTraversal::previousSibling(*element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) { 808 if (context.resolvingMode == Mode::ResolvingStyle) 809 sibling->setAffectsNextSiblingElementStyle(); 787 addStyleRelation(checkingContext, *sibling, StyleRelation::AffectsNextSibling); 810 788 811 789 unsigned ignoredSpecificity; 812 if (matchSelectorList(c ontext, *sibling, *selectorList, ignoredSpecificity))790 if (matchSelectorList(checkingContext, context, *sibling, *selectorList, ignoredSpecificity)) 813 791 ++count; 814 792 } 815 793 } else { 816 count += countElementsBefore(*element, context.resolvingMode == Mode::ResolvingStyle); 817 if (context.resolvingMode == Mode::ResolvingStyle) 818 element->setChildIndex(count); 794 count += countElementsBefore(checkingContext, *element); 795 addStyleRelation(checkingContext, *element, StyleRelation::NthChildIndex, count); 819 796 } 820 797 … … 828 805 829 806 if (element->parentElement()) { 830 if (context.resolvingMode == Mode::ResolvingStyle) 831 element->setStyleIsAffectedByPreviousSibling(); 832 833 int count = 1 + countElementsOfTypeBefore(*element, element->tagQName(), context.resolvingMode == Mode::ResolvingStyle); 807 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByPreviousSibling); 808 809 int count = 1 + countElementsOfTypeBefore(checkingContext, *element, element->tagQName()); 834 810 if (selector->matchNth(count)) 835 811 return true; … … 842 818 if (const CSSSelectorList* selectorList = selector->selectorList()) { 843 819 unsigned selectorListSpecificity; 844 if (matchSelectorList(c ontext, *element, *selectorList, selectorListSpecificity))820 if (matchSelectorList(checkingContext, context, *element, *selectorList, selectorListSpecificity)) 845 821 specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity); 846 822 else 847 823 return false; 848 824 849 if (context.resolvingMode == Mode::ResolvingStyle) { 850 parentElement->setChildrenAffectedByPropertyBasedBackwardPositionalRules(); 851 parentElement->setChildrenAffectedByBackwardPositionalRules(); 852 } 853 } else if (context.resolvingMode == Mode::ResolvingStyle) 854 parentElement->setChildrenAffectedByBackwardPositionalRules(); 825 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByPropertyBasedBackwardPositionalRules); 826 } else 827 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByBackwardPositionalRules); 855 828 856 829 if (!parentElement->isFinishedParsingChildren()) … … 861 834 for (Element* sibling = ElementTraversal::nextSibling(*element); sibling; sibling = ElementTraversal::nextSibling(*sibling)) { 862 835 unsigned ignoredSpecificity; 863 if (matchSelectorList(c ontext, *sibling, *selectorList, ignoredSpecificity))836 if (matchSelectorList(checkingContext, context, *sibling, *selectorList, ignoredSpecificity)) 864 837 ++count; 865 838 } … … 875 848 break; 876 849 if (Element* parentElement = element->parentElement()) { 877 if (context.resolvingMode == Mode::ResolvingStyle)878 parentElement->setChildrenAffectedByBackwardPositionalRules(); 850 addStyleRelation(checkingContext, *parentElement, StyleRelation::ChildrenAffectedByBackwardPositionalRules); 851 879 852 if (!parentElement->isFinishedParsingChildren()) 880 853 return false; … … 891 864 case CSSSelector::PseudoClassAny: 892 865 { 893 CheckingContextWithStatus subContext(context);894 sub Context.inFunctionalPseudoClass = true;895 sub Context.pseudoElementEffective = false;896 for (sub Context.selector = selector->selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(subContext.selector)) {897 sub Context.firstSelectorOfTheFragment = subContext.selector;866 LocalContext subcontext(context); 867 subcontext.inFunctionalPseudoClass = true; 868 subcontext.pseudoElementEffective = false; 869 for (subcontext.selector = selector->selectorList()->first(); subcontext.selector; subcontext.selector = CSSSelectorList::next(subcontext.selector)) { 870 subcontext.firstSelectorOfTheFragment = subcontext.selector; 898 871 PseudoIdSet ignoreDynamicPseudo; 899 872 unsigned ingoredSpecificity = 0; 900 if (matchRecursively( subContext, ignoreDynamicPseudo, ingoredSpecificity).match == Match::SelectorMatches)873 if (matchRecursively(checkingContext, subcontext, ignoreDynamicPseudo, ingoredSpecificity).match == Match::SelectorMatches) 901 874 return true; 902 875 } … … 917 890 return element->isLink() && context.visitedMatchType == VisitedMatchType::Enabled; 918 891 case CSSSelector::PseudoClassDrag: 919 if (context.resolvingMode == Mode::ResolvingStyle) { 920 if (context.elementStyle) 921 context.elementStyle->setAffectedByDrag(); 922 else 923 element->setChildrenAffectedByDrag(); 924 } 892 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByDrag); 893 925 894 if (element->renderer() && element->renderer()->isDragging()) 926 895 return true; … … 930 899 case CSSSelector::PseudoClassHover: 931 900 if (m_strictParsing || element->isLink() || canMatchHoverOrActiveInQuirksMode(context)) { 932 if (context.resolvingMode == Mode::ResolvingStyle) { 933 if (context.elementStyle) 934 context.elementStyle->setAffectedByHover(); 935 else 936 element->setChildrenAffectedByHover(); 937 } 938 if (element->hovered() || InspectorInstrumentation::forcePseudoState(*element, CSSSelector::PseudoClassHover)) 901 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByHover); 902 903 if (element->hovered() || InspectorInstrumentation::forcePseudoState(const_cast<Element&>(*element), CSSSelector::PseudoClassHover)) 939 904 return true; 940 905 } … … 942 907 case CSSSelector::PseudoClassActive: 943 908 if (m_strictParsing || element->isLink() || canMatchHoverOrActiveInQuirksMode(context)) { 944 if (context.resolvingMode == Mode::ResolvingStyle) { 945 if (context.elementStyle) 946 context.elementStyle->setAffectedByActive(); 947 else 948 element->setChildrenAffectedByActive(); 949 } 950 if (element->active() || InspectorInstrumentation::forcePseudoState(*element, CSSSelector::PseudoClassActive)) 909 addStyleRelation(checkingContext, *element, StyleRelation::AffectedByActive); 910 911 if (element->active() || InspectorInstrumentation::forcePseudoState(const_cast<Element&>(*element), CSSSelector::PseudoClassActive)) 951 912 return true; 952 913 } … … 1008 969 case CSSSelector::PseudoClassScope: 1009 970 { 1010 const Node* contextualReferenceNode = !c ontext.scope ? element->document().documentElement() : context.scope;971 const Node* contextualReferenceNode = !checkingContext.scope ? element->document().documentElement() : checkingContext.scope; 1011 972 if (element == contextualReferenceNode) 1012 973 return true; … … 1051 1012 #if ENABLE(VIDEO_TRACK) 1052 1013 if (selector->match() == CSSSelector::PseudoElement && selector->pseudoElementType() == CSSSelector::PseudoElementCue) { 1053 CheckingContextWithStatus subContext(context);1014 LocalContext subcontext(context); 1054 1015 1055 1016 const CSSSelector* const & selector = context.selector; 1056 for (sub Context.selector = selector->selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(subContext.selector)) {1057 sub Context.firstSelectorOfTheFragment = subContext.selector;1058 sub Context.inFunctionalPseudoClass = true;1059 sub Context.pseudoElementEffective = false;1017 for (subcontext.selector = selector->selectorList()->first(); subcontext.selector; subcontext.selector = CSSSelectorList::next(subcontext.selector)) { 1018 subcontext.firstSelectorOfTheFragment = subcontext.selector; 1019 subcontext.inFunctionalPseudoClass = true; 1020 subcontext.pseudoElementEffective = false; 1060 1021 PseudoIdSet ignoredDynamicPseudo; 1061 1022 unsigned ignoredSpecificity = 0; 1062 if (matchRecursively( subContext, ignoredDynamicPseudo, ignoredSpecificity).match == Match::SelectorMatches)1023 if (matchRecursively(checkingContext, subcontext, ignoredDynamicPseudo, ignoredSpecificity).match == Match::SelectorMatches) 1063 1024 return true; 1064 1025 } … … 1070 1031 } 1071 1032 1072 bool SelectorChecker::matchSelectorList( const CheckingContextWithStatus& baseContext,Element& element, const CSSSelectorList& selectorList, unsigned& specificity) const1033 bool SelectorChecker::matchSelectorList(CheckingContext& checkingContext, const LocalContext& context, const Element& element, const CSSSelectorList& selectorList, unsigned& specificity) const 1073 1034 { 1074 1035 specificity = 0; … … 1076 1037 1077 1038 for (const CSSSelector* subselector = selectorList.first(); subselector; subselector = CSSSelectorList::next(subselector)) { 1078 CheckingContextWithStatus subcontext(baseContext);1039 LocalContext subcontext(context); 1079 1040 subcontext.element = &element; 1080 1041 subcontext.selector = subselector; … … 1084 1045 PseudoIdSet ignoreDynamicPseudo; 1085 1046 unsigned localSpecificity = 0; 1086 if (matchRecursively( subcontext, ignoreDynamicPseudo, localSpecificity).match == Match::SelectorMatches) {1047 if (matchRecursively(checkingContext, subcontext, ignoreDynamicPseudo, localSpecificity).match == Match::SelectorMatches) { 1087 1048 ASSERT(!ignoreDynamicPseudo); 1088 1049 … … 1094 1055 } 1095 1056 1096 bool SelectorChecker::checkScrollbarPseudoClass(const CheckingContext WithStatus& context, const CSSSelector* selector) const1057 bool SelectorChecker::checkScrollbarPseudoClass(const CheckingContext& checkingContext, const Element& element, const CSSSelector* selector) const 1097 1058 { 1098 1059 ASSERT(selector->match() == CSSSelector::PseudoClass); … … 1100 1061 switch (selector->pseudoClassType()) { 1101 1062 case CSSSelector::PseudoClassWindowInactive: 1102 return isWindowInactive( context.element);1063 return isWindowInactive(&element); 1103 1064 case CSSSelector::PseudoClassEnabled: 1104 return scrollbarMatchesEnabledPseudoClass(c ontext);1065 return scrollbarMatchesEnabledPseudoClass(checkingContext); 1105 1066 case CSSSelector::PseudoClassDisabled: 1106 return scrollbarMatchesDisabledPseudoClass(c ontext);1067 return scrollbarMatchesDisabledPseudoClass(checkingContext); 1107 1068 case CSSSelector::PseudoClassHover: 1108 return scrollbarMatchesHoverPseudoClass(c ontext);1069 return scrollbarMatchesHoverPseudoClass(checkingContext); 1109 1070 case CSSSelector::PseudoClassActive: 1110 return scrollbarMatchesActivePseudoClass(c ontext);1071 return scrollbarMatchesActivePseudoClass(checkingContext); 1111 1072 case CSSSelector::PseudoClassHorizontal: 1112 return scrollbarMatchesHorizontalPseudoClass(c ontext);1073 return scrollbarMatchesHorizontalPseudoClass(checkingContext); 1113 1074 case CSSSelector::PseudoClassVertical: 1114 return scrollbarMatchesVerticalPseudoClass(c ontext);1075 return scrollbarMatchesVerticalPseudoClass(checkingContext); 1115 1076 case CSSSelector::PseudoClassDecrement: 1116 return scrollbarMatchesDecrementPseudoClass(c ontext);1077 return scrollbarMatchesDecrementPseudoClass(checkingContext); 1117 1078 case CSSSelector::PseudoClassIncrement: 1118 return scrollbarMatchesIncrementPseudoClass(c ontext);1079 return scrollbarMatchesIncrementPseudoClass(checkingContext); 1119 1080 case CSSSelector::PseudoClassStart: 1120 return scrollbarMatchesStartPseudoClass(c ontext);1081 return scrollbarMatchesStartPseudoClass(checkingContext); 1121 1082 case CSSSelector::PseudoClassEnd: 1122 return scrollbarMatchesEndPseudoClass(c ontext);1083 return scrollbarMatchesEndPseudoClass(checkingContext); 1123 1084 case CSSSelector::PseudoClassDoubleButton: 1124 return scrollbarMatchesDoubleButtonPseudoClass(c ontext);1085 return scrollbarMatchesDoubleButtonPseudoClass(checkingContext); 1125 1086 case CSSSelector::PseudoClassSingleButton: 1126 return scrollbarMatchesSingleButtonPseudoClass(c ontext);1087 return scrollbarMatchesSingleButtonPseudoClass(checkingContext); 1127 1088 case CSSSelector::PseudoClassNoButton: 1128 return scrollbarMatchesNoButtonPseudoClass(c ontext);1089 return scrollbarMatchesNoButtonPseudoClass(checkingContext); 1129 1090 case CSSSelector::PseudoClassCornerPresent: 1130 return scrollbarMatchesCornerPresentPseudoClass(c ontext);1091 return scrollbarMatchesCornerPresentPseudoClass(checkingContext); 1131 1092 default: 1132 1093 return false; -
trunk/Source/WebCore/css/SelectorChecker.h
r191252 r195293 3 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) 4 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) 5 * Copyright (C) 2005 , 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014Apple Inc. All rights reserved.5 * Copyright (C) 2005-2016 Apple Inc. All rights reserved. 6 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> 7 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> … … 77 77 SelectorChecker(Document&); 78 78 79 struct StyleRelation { 80 enum Type { 81 AffectedByActive, 82 AffectedByDrag, 83 AffectedByEmpty, 84 AffectedByHover, 85 AffectedByPreviousSibling, 86 AffectsNextSibling, 87 ChildrenAffectedByBackwardPositionalRules, 88 ChildrenAffectedByFirstChildRules, 89 ChildrenAffectedByPropertyBasedBackwardPositionalRules, 90 ChildrenAffectedByLastChildRules, 91 FirstChild, 92 LastChild, 93 NthChildIndex, 94 Unique, 95 }; 96 Element& element; 97 Type type; 98 unsigned value; 99 }; 100 using StyleRelations = Vector<StyleRelation, 8>; 101 79 102 struct CheckingContext { 80 103 CheckingContext(SelectorChecker::Mode resolvingMode) 81 104 : resolvingMode(resolvingMode) 82 , elementStyle(nullptr)83 , pseudoId(NOPSEUDO)84 , scrollbar(nullptr)85 , scrollbarPart(NoPart)86 , scope(nullptr)87 105 { } 88 106 89 SelectorChecker::Mode resolvingMode; 90 RenderStyle* elementStyle; 91 PseudoId pseudoId; 92 RenderScrollbar* scrollbar; 93 ScrollbarPart scrollbarPart; 94 const ContainerNode* scope; 107 const SelectorChecker::Mode resolvingMode; 108 PseudoId pseudoId { NOPSEUDO }; 109 RenderScrollbar* scrollbar { nullptr }; 110 ScrollbarPart scrollbarPart { NoPart }; 111 const ContainerNode* scope { nullptr }; 112 113 // FIXME: It would be nicer to have a separate object for return values. This requires some more work in the selector compiler. 114 StyleRelations styleRelations; 115 PseudoIdSet pseudoIDSet; 95 116 }; 96 117 97 struct CheckingContextWithStatus; 98 99 bool match(const CSSSelector*, Element*, const CheckingContext&, unsigned& specificity) const; 118 bool match(const CSSSelector&, const Element&, CheckingContext&, unsigned& specificity) const; 100 119 101 120 static bool isCommonPseudoClassSelector(const CSSSelector*); … … 106 125 static unsigned determineLinkMatchType(const CSSSelector*); 107 126 127 struct LocalContext; 128 108 129 private: 109 MatchResult matchRecursively( const CheckingContextWithStatus&, PseudoIdSet&, unsigned& specificity) const;110 bool checkOne( const CheckingContextWithStatus&, PseudoIdSet&, MatchType&, unsigned& specificity) const;111 bool matchSelectorList( const CheckingContextWithStatus&,Element&, const CSSSelectorList&, unsigned& specificity) const;130 MatchResult matchRecursively(CheckingContext&, const LocalContext&, PseudoIdSet&, unsigned& specificity) const; 131 bool checkOne(CheckingContext&, const LocalContext&, PseudoIdSet&, MatchType&, unsigned& specificity) const; 132 bool matchSelectorList(CheckingContext&, const LocalContext&, const Element&, const CSSSelectorList&, unsigned& specificity) const; 112 133 113 bool checkScrollbarPseudoClass(const CheckingContext WithStatus&, const CSSSelector*) const;134 bool checkScrollbarPseudoClass(const CheckingContext&, const Element&, const CSSSelector*) const; 114 135 115 136 bool m_strictParsing; -
trunk/Source/WebCore/css/SelectorCheckerTestFunctions.h
r191327 r195293 64 64 } 65 65 66 ALWAYS_INLINE bool isMediaDocument( Element* element)66 ALWAYS_INLINE bool isMediaDocument(const Element* element) 67 67 { 68 68 return element->document().isMediaDocument(); 69 69 } 70 70 71 ALWAYS_INLINE bool isChecked( Element& element)71 ALWAYS_INLINE bool isChecked(const Element& element) 72 72 { 73 73 // Even though WinIE allows checked and indeterminate to co-exist, the CSS selector spec says that … … 79 79 } 80 80 if (is<HTMLOptionElement>(element)) 81 return downcast<HTMLOptionElement>(element).selected();82 83 return false; 84 } 85 86 ALWAYS_INLINE bool isInRange( Element* element)81 return const_cast<HTMLOptionElement&>(downcast<HTMLOptionElement>(element)).selected(); 82 83 return false; 84 } 85 86 ALWAYS_INLINE bool isInRange(const Element* element) 87 87 { 88 88 return element->isInRange(); 89 89 } 90 90 91 ALWAYS_INLINE bool isOutOfRange( Element* element)91 ALWAYS_INLINE bool isOutOfRange(const Element* element) 92 92 { 93 93 return element->isOutOfRange(); -
trunk/Source/WebCore/css/StyleResolver.h
r194762 r195293 611 611 SelectorChecker::CheckingContext selectorCheckingContext(SelectorChecker::Mode::QueryingRules); 612 612 unsigned ignoredSpecificity; 613 if (selectorChecker.match( s,regionElement, selectorCheckingContext, ignoredSpecificity))613 if (selectorChecker.match(*s, *regionElement, selectorCheckingContext, ignoredSpecificity)) 614 614 return true; 615 615 } -
trunk/Source/WebCore/cssjit/SelectorCompiler.cpp
r194496 r195293 1 1 /* 2 * Copyright (C) 2013-201 5Apple Inc. All rights reserved.2 * Copyright (C) 2013-2016 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2014 Yusuke Suzuki <utatane.tea@gmail.com> 4 4 * … … 292 292 void generateContextFunctionCallTest(Assembler::JumpList& failureCases, JSC::FunctionPtr); 293 293 void generateElementIsActive(Assembler::JumpList& failureCases, const SelectorFragment&); 294 void generateElementIsEmpty(Assembler::JumpList& failureCases , const SelectorFragment&);295 void generateElementIsFirstChild(Assembler::JumpList& failureCases , const SelectorFragment&);294 void generateElementIsEmpty(Assembler::JumpList& failureCases); 295 void generateElementIsFirstChild(Assembler::JumpList& failureCases); 296 296 void generateElementIsHovered(Assembler::JumpList& failureCases, const SelectorFragment&); 297 297 void generateElementIsInLanguage(Assembler::JumpList& failureCases, const SelectorFragment&); 298 298 void generateElementIsInLanguage(Assembler::JumpList& failureCases, const Vector<AtomicString>*); 299 void generateElementIsLastChild(Assembler::JumpList& failureCases , const SelectorFragment&);300 void generateElementIsOnlyChild(Assembler::JumpList& failureCases , const SelectorFragment&);301 void generateElementHasPlaceholderShown(Assembler::JumpList& failureCases , const SelectorFragment&);299 void generateElementIsLastChild(Assembler::JumpList& failureCases); 300 void generateElementIsOnlyChild(Assembler::JumpList& failureCases); 301 void generateElementHasPlaceholderShown(Assembler::JumpList& failureCases); 302 302 void generateSynchronizeStyleAttribute(Assembler::RegisterID elementDataArraySizeAndFlags); 303 303 void generateSynchronizeAllAnimatedSVGAttribute(Assembler::RegisterID elementDataArraySizeAndFlags); … … 324 324 325 325 // Helpers. 326 void addFlagsToElementStyleFromContext(Assembler::RegisterID checkingContext, int64_t); 326 void generateAddStyleRelationIfResolvingStyle(Assembler::RegisterID element, SelectorChecker::StyleRelation::Type, Optional<Assembler::RegisterID> value = { }); 327 void generateAddStyleRelation(Assembler::RegisterID checkingContext, Assembler::RegisterID element, SelectorChecker::StyleRelation::Type, Optional<Assembler::RegisterID> value = { }); 327 328 Assembler::Jump branchOnResolvingModeWithCheckingContext(Assembler::RelationalCondition, SelectorChecker::Mode, Assembler::RegisterID checkingContext); 328 329 Assembler::Jump branchOnResolvingMode(Assembler::RelationalCondition, SelectorChecker::Mode, Assembler::RegisterID checkingContext); … … 333 334 void generateRequestedPseudoElementEqualsToSelectorPseudoElement(Assembler::JumpList& failureCases, const SelectorFragment&, Assembler::RegisterID checkingContext); 334 335 void generateSpecialFailureInQuirksModeForActiveAndHoverIfNeeded(Assembler::JumpList& failureCases, const SelectorFragment&); 335 void markElementIfResolvingStyle(Assembler::RegisterID, int32_t);336 336 Assembler::JumpList jumpIfNoPreviousAdjacentElement(); 337 337 Assembler::JumpList jumpIfNoNextAdjacentElement(); … … 1892 1892 } 1893 1893 if (shouldMarkStyleIsAffectedByPreviousSibling(fragment)) 1894 markElementIfResolvingStyle(elementAddressRegister, Node::flagStyleIsAffectedByPreviousSibling());1894 generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectedByPreviousSibling); 1895 1895 generateBacktrackingTailsIfNeeded(failureCases, fragment); 1896 1896 } … … 2136 2136 { 2137 2137 generateWalkToPreviousAdjacent(failureCases, fragment); 2138 markElementIfResolvingStyle(elementAddressRegister, Node::flagAffectsNextSiblingElementStyle());2138 generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectsNextSibling); 2139 2139 2140 2140 Assembler::JumpList matchingTagNameFailureCases; … … 2161 2161 2162 2162 generateWalkToPreviousAdjacent(failureCases, fragment); 2163 markElementIfResolvingStyle(elementAddressRegister, Node::flagAffectsNextSiblingElementStyle());2163 generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectsNextSibling); 2164 2164 2165 2165 if (fragment.backtrackingFlags & BacktrackingFlag::IndirectAdjacentEntryPoint) … … 2171 2171 } 2172 2172 2173 2174 void SelectorCodeGenerator::addFlagsToElementStyleFromContext(Assembler::RegisterID checkingContext, int64_t newFlag) 2173 void SelectorCodeGenerator::generateAddStyleRelationIfResolvingStyle(Assembler::RegisterID element, SelectorChecker::StyleRelation::Type relationType, Optional<Assembler::RegisterID> value) 2174 { 2175 if (m_selectorContext == SelectorContext::QuerySelector) 2176 return; 2177 2178 LocalRegister checkingContext(m_registerAllocator); 2179 Assembler::Jump notResolvingStyle = jumpIfNotResolvingStyle(checkingContext); 2180 2181 generateAddStyleRelation(checkingContext, element, relationType, value); 2182 2183 notResolvingStyle.link(&m_assembler); 2184 } 2185 2186 static void addStyleRelationFunction(SelectorChecker::CheckingContext* checkingContext, Element* element) 2187 { 2188 checkingContext->styleRelations.append({ *element, SelectorChecker::StyleRelation::AffectedByActive, 1 }); 2189 } 2190 2191 void SelectorCodeGenerator::generateAddStyleRelation(Assembler::RegisterID checkingContext, Assembler::RegisterID element, SelectorChecker::StyleRelation::Type relationType, Optional<Assembler::RegisterID> value) 2175 2192 { 2176 2193 ASSERT(m_selectorContext != SelectorContext::QuerySelector); 2177 2194 2178 LocalRegister childStyle(m_registerAllocator); 2179 m_assembler.loadPtr(Assembler::Address(checkingContext, OBJECT_OFFSETOF(SelectorChecker::CheckingContext, elementStyle)), childStyle); 2180 2181 // FIXME: We should look into doing something smart in MacroAssembler instead. 2182 Assembler::Address flagAddress(childStyle, RenderStyle::noninheritedFlagsMemoryOffset() + RenderStyle::NonInheritedFlags::flagsMemoryOffset()); 2183 #if CPU(ARM_THUMB2) 2184 int32_t flagLowBits = newFlag & 0xffffffff; 2185 int32_t flagHighBits = newFlag >> 32; 2186 if (flagLowBits) 2187 m_assembler.or32(Assembler::TrustedImm32(flagLowBits), flagAddress); 2188 if (flagHighBits) { 2189 Assembler::Address flagHighAddress = flagAddress.withOffset(4); 2190 m_assembler.or32(Assembler::TrustedImm32(flagHighBits), flagHighAddress); 2191 } 2192 #elif CPU(X86_64) || CPU(ARM64) 2193 LocalRegister flags(m_registerAllocator); 2194 m_assembler.load64(flagAddress, flags); 2195 LocalRegister isFirstChildStateFlagImmediate(m_registerAllocator); 2196 m_assembler.move(Assembler::TrustedImm64(newFlag), isFirstChildStateFlagImmediate); 2197 m_assembler.or64(isFirstChildStateFlagImmediate, flags); 2198 m_assembler.store64(flags, flagAddress); 2199 #else 2200 #error SelectorCodeGenerator::addFlagsToElementStyleFromContext not implemented for this architecture. 2201 #endif 2195 // FIXME: Append to vector without a function call at least when there is sufficient capacity. 2196 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 2197 functionCall.setFunctionAddress(addStyleRelationFunction); 2198 functionCall.setTwoArguments(checkingContext, element); 2199 functionCall.call(); 2200 2201 Assembler::Address vectorAddress(checkingContext, OBJECT_OFFSETOF(SelectorChecker::CheckingContext, styleRelations)); 2202 auto dataAddress = vectorAddress.withOffset(SelectorChecker::StyleRelations::dataMemoryOffset()); 2203 auto sizeAddress = vectorAddress.withOffset(SelectorChecker::StyleRelations::sizeMemoryOffset()); 2204 2205 LocalRegister relationPointer(m_registerAllocator); 2206 m_assembler.load32(sizeAddress, relationPointer); 2207 m_assembler.sub32(Assembler::TrustedImm32(1), relationPointer); 2208 m_assembler.mul32(Assembler::TrustedImm32(sizeof(SelectorChecker::StyleRelation)), relationPointer, relationPointer); 2209 m_assembler.addPtr(dataAddress, relationPointer); 2210 2211 Assembler::Address typeAddress(relationPointer, OBJECT_OFFSETOF(SelectorChecker::StyleRelation, type)); 2212 m_assembler.store32(Assembler::TrustedImm32(relationType), typeAddress); 2213 2214 if (value) { 2215 Assembler::Address valueAddress(relationPointer, OBJECT_OFFSETOF(SelectorChecker::StyleRelation, value)); 2216 m_assembler.store32(*value, valueAddress); 2217 } 2202 2218 } 2203 2219 … … 2419 2435 2420 2436 failureCases.append(modulo(Assembler::NonZero, inputDividend, divisor)); 2421 }2422 2423 static void setNodeFlag(Assembler& assembler, Assembler::RegisterID elementAddress, int32_t flag)2424 {2425 assembler.or32(Assembler::TrustedImm32(flag), Assembler::Address(elementAddress, Node::nodeFlagsMemoryOffset()));2426 }2427 2428 void SelectorCodeGenerator::markElementIfResolvingStyle(Assembler::RegisterID element, int32_t nodeFlag)2429 {2430 if (m_selectorContext == SelectorContext::QuerySelector)2431 return;2432 2433 Assembler::JumpList skipMarking;2434 {2435 LocalRegister checkingContext(m_registerAllocator);2436 skipMarking.append(jumpIfNotResolvingStyle(checkingContext));2437 }2438 2439 setNodeFlag(m_assembler, element, nodeFlag);2440 2441 skipMarking.link(&m_assembler);2442 2437 } 2443 2438 … … 2548 2543 generateElementIsActive(matchingPostTagNameFailureCases, fragment); 2549 2544 if (fragment.pseudoClasses.contains(CSSSelector::PseudoClassEmpty)) 2550 generateElementIsEmpty(matchingPostTagNameFailureCases , fragment);2545 generateElementIsEmpty(matchingPostTagNameFailureCases); 2551 2546 if (fragment.pseudoClasses.contains(CSSSelector::PseudoClassHover)) 2552 2547 generateElementIsHovered(matchingPostTagNameFailureCases, fragment); 2553 2548 if (fragment.pseudoClasses.contains(CSSSelector::PseudoClassOnlyChild)) 2554 generateElementIsOnlyChild(matchingPostTagNameFailureCases , fragment);2549 generateElementIsOnlyChild(matchingPostTagNameFailureCases); 2555 2550 if (fragment.pseudoClasses.contains(CSSSelector::PseudoClassPlaceholderShown)) 2556 generateElementHasPlaceholderShown(matchingPostTagNameFailureCases , fragment);2551 generateElementHasPlaceholderShown(matchingPostTagNameFailureCases); 2557 2552 if (fragment.pseudoClasses.contains(CSSSelector::PseudoClassFirstChild)) 2558 generateElementIsFirstChild(matchingPostTagNameFailureCases , fragment);2553 generateElementIsFirstChild(matchingPostTagNameFailureCases); 2559 2554 if (fragment.pseudoClasses.contains(CSSSelector::PseudoClassLastChild)) 2560 generateElementIsLastChild(matchingPostTagNameFailureCases , fragment);2555 generateElementIsLastChild(matchingPostTagNameFailureCases); 2561 2556 if (!fragment.nthChildFilters.isEmpty()) 2562 2557 generateElementIsNthChild(matchingPostTagNameFailureCases, fragment); … … 3053 3048 } 3054 3049 3055 static void setFirstChildState(Element* element)3056 {3057 if (RenderStyle* style = element->renderStyle())3058 style->setFirstChildState();3059 }3060 3061 3050 static bool elementIsActive(Element* element) 3062 3051 { … … 3064 3053 } 3065 3054 3066 static bool elementIsActiveForStyleResolution(Element* element, const SelectorChecker::CheckingContext* checkingContext)3067 {3068 if (checkingContext->resolvingMode == SelectorChecker::Mode::ResolvingStyle)3069 element->setChildrenAffectedByActive();3070 return element->active() || InspectorInstrumentation::forcePseudoState(*element, CSSSelector::PseudoClassActive);3071 }3072 3073 3055 void SelectorCodeGenerator::generateElementIsActive(Assembler::JumpList& failureCases, const SelectorFragment& fragment) 3074 3056 { 3075 3057 generateSpecialFailureInQuirksModeForActiveAndHoverIfNeeded(failureCases, fragment); 3076 if (m_selectorContext == SelectorContext::QuerySelector) { 3077 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3078 functionCall.setFunctionAddress(elementIsActive); 3079 functionCall.setOneArgument(elementAddressRegister); 3080 failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero)); 3081 return; 3082 } 3083 3084 if (fragmentMatchesTheRightmostElement(m_selectorContext, fragment)) { 3085 LocalRegister checkingContext(m_registerAllocator); 3086 Assembler::Jump notResolvingStyle = jumpIfNotResolvingStyle(checkingContext); 3087 addFlagsToElementStyleFromContext(checkingContext, RenderStyle::NonInheritedFlags::flagIsaffectedByActive()); 3088 notResolvingStyle.link(&m_assembler); 3089 3090 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3091 functionCall.setFunctionAddress(elementIsActive); 3092 functionCall.setOneArgument(elementAddressRegister); 3093 failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero)); 3094 } else { 3095 Assembler::RegisterID checkingContext = m_registerAllocator.allocateRegisterWithPreference(JSC::GPRInfo::argumentGPR1); 3096 loadCheckingContext(checkingContext); 3097 m_registerAllocator.deallocateRegister(checkingContext); 3098 3099 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3100 functionCall.setFunctionAddress(elementIsActiveForStyleResolution); 3101 functionCall.setTwoArguments(elementAddressRegister, checkingContext); 3102 failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero)); 3103 } 3058 3059 generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectedByActive); 3060 3061 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3062 functionCall.setFunctionAddress(elementIsActive); 3063 functionCall.setOneArgument(elementAddressRegister); 3064 failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero)); 3104 3065 } 3105 3066 … … 3130 3091 } 3131 3092 3132 static void setElementStyleIsAffectedByEmpty(Element* element) 3133 { 3134 element->setStyleAffectedByEmpty(); 3135 } 3136 3137 static void setElementStyleFromContextIsAffectedByEmptyAndUpdateRenderStyleIfNecessary(SelectorChecker::CheckingContext* context, bool isEmpty) 3138 { 3139 ASSERT(context->elementStyle); 3140 context->elementStyle->setEmptyState(isEmpty); 3141 } 3142 3143 void SelectorCodeGenerator::generateElementIsEmpty(Assembler::JumpList& failureCases, const SelectorFragment& fragment) 3093 void SelectorCodeGenerator::generateElementIsEmpty(Assembler::JumpList& failureCases) 3144 3094 { 3145 3095 if (m_selectorContext == SelectorContext::QuerySelector) { … … 3156 3106 notEmpty.link(&m_assembler); 3157 3107 3158 Assembler::Jump skipMarking; 3159 if (fragmentMatchesTheRightmostElement(m_selectorContext, fragment)) { 3160 { 3161 LocalRegister checkingContext(m_registerAllocator); 3162 skipMarking = jumpIfNotResolvingStyle(checkingContext); 3163 3164 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3165 functionCall.setFunctionAddress(setElementStyleFromContextIsAffectedByEmptyAndUpdateRenderStyleIfNecessary); 3166 functionCall.setTwoArguments(checkingContext, isEmptyResults); 3167 functionCall.call(); 3168 } 3169 3170 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3171 functionCall.setFunctionAddress(setElementStyleIsAffectedByEmpty); 3172 functionCall.setOneArgument(elementAddressRegister); 3173 functionCall.call(); 3174 } else { 3175 { 3176 LocalRegister checkingContext(m_registerAllocator); 3177 skipMarking = jumpIfNotResolvingStyle(checkingContext); 3178 } 3179 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3180 functionCall.setFunctionAddress(setElementStyleIsAffectedByEmpty); 3181 functionCall.setOneArgument(elementAddressRegister); 3182 functionCall.call(); 3183 } 3184 skipMarking.link(&m_assembler); 3108 generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectedByEmpty, Assembler::RegisterID(isEmptyResults)); 3185 3109 3186 3110 failureCases.append(m_assembler.branchTest32(Assembler::Zero, isEmptyResults)); 3187 3111 } 3188 3112 3189 void SelectorCodeGenerator::generateElementIsFirstChild(Assembler::JumpList& failureCases , const SelectorFragment& fragment)3113 void SelectorCodeGenerator::generateElementIsFirstChild(Assembler::JumpList& failureCases) 3190 3114 { 3191 3115 if (m_selectorContext == SelectorContext::QuerySelector) { … … 3217 3141 Assembler::Jump notResolvingStyle = jumpIfNotResolvingStyle(checkingContext); 3218 3142 3219 setNodeFlag(m_assembler, parentElement, Node::flagChildrenAffectedByFirstChildRulesFlag());3143 generateAddStyleRelation(checkingContext, parentElement, SelectorChecker::StyleRelation::ChildrenAffectedByFirstChildRules); 3220 3144 m_registerAllocator.deallocateRegister(parentElement); 3221 3145 … … 3224 3148 failureCases.append(m_assembler.branchTest32(Assembler::NonZero, isFirstChildRegister)); 3225 3149 3226 if (fragmentMatchesTheRightmostElement(m_selectorContext, fragment)) 3227 addFlagsToElementStyleFromContext(checkingContext, RenderStyle::NonInheritedFlags::setFirstChildStateFlags()); 3228 else { 3229 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3230 functionCall.setFunctionAddress(setFirstChildState); 3231 Assembler::RegisterID elementAddress = elementAddressRegister; 3232 functionCall.setOneArgument(elementAddress); 3233 functionCall.call(); 3234 } 3150 generateAddStyleRelation(checkingContext, elementAddressRegister, SelectorChecker::StyleRelation::FirstChild); 3235 3151 3236 3152 notResolvingStyle.link(&m_assembler); … … 3243 3159 } 3244 3160 3245 static bool elementIsHoveredForStyleResolution(Element* element, const SelectorChecker::CheckingContext* checkingContext)3246 {3247 if (checkingContext->resolvingMode == SelectorChecker::Mode::ResolvingStyle)3248 element->setChildrenAffectedByHover();3249 return element->hovered() || InspectorInstrumentation::forcePseudoState(*element, CSSSelector::PseudoClassHover);3250 }3251 3252 3161 void SelectorCodeGenerator::generateElementIsHovered(Assembler::JumpList& failureCases, const SelectorFragment& fragment) 3253 3162 { 3254 3163 generateSpecialFailureInQuirksModeForActiveAndHoverIfNeeded(failureCases, fragment); 3255 if (m_selectorContext == SelectorContext::QuerySelector) { 3256 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3257 functionCall.setFunctionAddress(elementIsHovered); 3258 functionCall.setOneArgument(elementAddressRegister); 3259 failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero)); 3260 return; 3261 } 3262 3263 if (fragmentMatchesTheRightmostElement(m_selectorContext, fragment)) { 3264 LocalRegisterWithPreference checkingContext(m_registerAllocator, JSC::GPRInfo::argumentGPR1); 3265 Assembler::Jump notResolvingStyle = jumpIfNotResolvingStyle(checkingContext); 3266 addFlagsToElementStyleFromContext(checkingContext, RenderStyle::NonInheritedFlags::flagIsaffectedByHover()); 3267 notResolvingStyle.link(&m_assembler); 3268 3269 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3270 functionCall.setFunctionAddress(elementIsHovered); 3271 functionCall.setOneArgument(elementAddressRegister); 3272 failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero)); 3273 } else { 3274 Assembler::RegisterID checkingContext = m_registerAllocator.allocateRegisterWithPreference(JSC::GPRInfo::argumentGPR1); 3275 loadCheckingContext(checkingContext); 3276 m_registerAllocator.deallocateRegister(checkingContext); 3277 3278 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3279 functionCall.setFunctionAddress(elementIsHoveredForStyleResolution); 3280 functionCall.setTwoArguments(elementAddressRegister, checkingContext); 3281 failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero)); 3282 } 3164 3165 generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectedByHover); 3166 3167 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3168 functionCall.setFunctionAddress(elementIsHovered); 3169 functionCall.setOneArgument(elementAddressRegister); 3170 failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero)); 3283 3171 } 3284 3172 … … 3301 3189 } 3302 3190 3303 static void setLastChildState(Element* element) 3304 { 3305 if (RenderStyle* style = element->renderStyle()) 3306 style->setLastChildState(); 3307 } 3308 3309 void SelectorCodeGenerator::generateElementIsLastChild(Assembler::JumpList& failureCases, const SelectorFragment& fragment) 3191 void SelectorCodeGenerator::generateElementIsLastChild(Assembler::JumpList& failureCases) 3310 3192 { 3311 3193 if (m_selectorContext == SelectorContext::QuerySelector) { … … 3343 3225 Assembler::Jump notResolvingStyle = jumpIfNotResolvingStyle(checkingContext); 3344 3226 3345 setNodeFlag(m_assembler, parentElement, Node::flagChildrenAffectedByLastChildRulesFlag());3227 generateAddStyleRelation(checkingContext, parentElement, SelectorChecker::StyleRelation::ChildrenAffectedByLastChildRules); 3346 3228 m_registerAllocator.deallocateRegister(parentElement); 3347 3229 … … 3350 3232 failureCases.append(m_assembler.branchTest32(Assembler::NonZero, isLastChildRegister)); 3351 3233 3352 if (fragmentMatchesTheRightmostElement(m_selectorContext, fragment)) 3353 addFlagsToElementStyleFromContext(checkingContext, RenderStyle::NonInheritedFlags::setLastChildStateFlags()); 3354 else { 3355 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3356 functionCall.setFunctionAddress(setLastChildState); 3357 Assembler::RegisterID elementAddress = elementAddressRegister; 3358 functionCall.setOneArgument(elementAddress); 3359 functionCall.call(); 3360 } 3234 generateAddStyleRelation(checkingContext, elementAddressRegister, SelectorChecker::StyleRelation::LastChild); 3361 3235 3362 3236 notResolvingStyle.link(&m_assembler); … … 3364 3238 } 3365 3239 3366 static void setOnlyChildState(Element* element) 3367 { 3368 if (RenderStyle* style = element->renderStyle()) { 3369 style->setFirstChildState(); 3370 style->setLastChildState(); 3371 } 3372 } 3373 3374 void SelectorCodeGenerator::generateElementIsOnlyChild(Assembler::JumpList& failureCases, const SelectorFragment& fragment) 3240 void SelectorCodeGenerator::generateElementIsOnlyChild(Assembler::JumpList& failureCases) 3375 3241 { 3376 3242 // Is Only child is pretty much a combination of isFirstChild + isLastChild. The main difference is that tree marking is combined. … … 3418 3284 Assembler::Jump notResolvingStyle = jumpIfNotResolvingStyle(checkingContext); 3419 3285 3420 setNodeFlag(m_assembler, parentElement, Node::flagChildrenAffectedByFirstChildRulesFlag() | Node::flagChildrenAffectedByLastChildRulesFlag()); 3286 generateAddStyleRelation(checkingContext, parentElement, SelectorChecker::StyleRelation::ChildrenAffectedByFirstChildRules); 3287 generateAddStyleRelation(checkingContext, parentElement, SelectorChecker::StyleRelation::ChildrenAffectedByLastChildRules); 3288 3421 3289 m_registerAllocator.deallocateRegister(parentElement); 3422 3290 … … 3425 3293 failureCases.append(m_assembler.branchTest32(Assembler::NonZero, isOnlyChildRegister)); 3426 3294 3427 if (fragmentMatchesTheRightmostElement(m_selectorContext, fragment)) 3428 addFlagsToElementStyleFromContext(checkingContext, RenderStyle::NonInheritedFlags::setFirstChildStateFlags() | RenderStyle::NonInheritedFlags::setLastChildStateFlags()); 3429 else { 3430 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3431 functionCall.setFunctionAddress(setOnlyChildState); 3432 Assembler::RegisterID elementAddress = elementAddressRegister; 3433 functionCall.setOneArgument(elementAddress); 3434 functionCall.call(); 3435 } 3295 generateAddStyleRelation(checkingContext, elementAddressRegister, SelectorChecker::StyleRelation::FirstChild); 3296 generateAddStyleRelation(checkingContext, elementAddressRegister, SelectorChecker::StyleRelation::LastChild); 3436 3297 3437 3298 notResolvingStyle.link(&m_assembler); … … 3439 3300 } 3440 3301 3441 static bool makeContextStyleUniqueIfNecessaryAndTestIsPlaceholderShown(Element* element, constSelectorChecker::CheckingContext* checkingContext)3302 static bool makeContextStyleUniqueIfNecessaryAndTestIsPlaceholderShown(Element* element, SelectorChecker::CheckingContext* checkingContext) 3442 3303 { 3443 3304 if (is<HTMLTextFormControlElement>(*element)) { 3444 3305 if (checkingContext->resolvingMode == SelectorChecker::Mode::ResolvingStyle) 3445 checkingContext-> elementStyle->setUnique();3306 checkingContext->styleRelations.append({ *element, SelectorChecker::StyleRelation::Unique, 1 }); 3446 3307 return downcast<HTMLTextFormControlElement>(*element).isPlaceholderVisible(); 3447 3308 } … … 3449 3310 } 3450 3311 3451 static bool makeElementStyleUniqueIfNecessaryAndTestIsPlaceholderShown(Element* element, const SelectorChecker::CheckingContext* checkingContext)3452 {3453 if (is<HTMLTextFormControlElement>(*element)) {3454 if (checkingContext->resolvingMode == SelectorChecker::Mode::ResolvingStyle) {3455 if (RenderStyle* style = element->renderStyle())3456 style->setUnique();3457 }3458 return downcast<HTMLTextFormControlElement>(*element).isPlaceholderVisible();3459 }3460 return false;3461 }3462 3463 3312 static bool isPlaceholderShown(Element* element) 3464 3313 { … … 3466 3315 } 3467 3316 3468 void SelectorCodeGenerator::generateElementHasPlaceholderShown(Assembler::JumpList& failureCases , const SelectorFragment& fragment)3317 void SelectorCodeGenerator::generateElementHasPlaceholderShown(Assembler::JumpList& failureCases) 3469 3318 { 3470 3319 if (m_selectorContext == SelectorContext::QuerySelector) { … … 3481 3330 3482 3331 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3483 if (fragmentMatchesTheRightmostElement(m_selectorContext, fragment)) 3484 functionCall.setFunctionAddress(makeContextStyleUniqueIfNecessaryAndTestIsPlaceholderShown); 3485 else 3486 functionCall.setFunctionAddress(makeElementStyleUniqueIfNecessaryAndTestIsPlaceholderShown); 3332 functionCall.setFunctionAddress(makeContextStyleUniqueIfNecessaryAndTestIsPlaceholderShown); 3487 3333 functionCall.setTwoArguments(elementAddressRegister, checkingContext); 3488 3334 failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero)); … … 3586 3432 } 3587 3433 3588 static void setElementChildIndex(Element* element, int index)3589 {3590 element->setChildIndex(index);3591 }3592 3593 3434 static bool nthFilterIsAlwaysSatisified(int a, int b) 3594 3435 { … … 3617 3458 3618 3459 if (!isAdjacentRelation(fragment.relationToRightFragment)) 3619 markElementIfResolvingStyle(elementAddressRegister, Node::flagStyleIsAffectedByPreviousSibling());3460 generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectedByPreviousSibling); 3620 3461 3621 3462 // Setup the counter at 1. … … 3635 3476 Assembler::JumpList noCachedChildIndexCases; 3636 3477 generateWalkToPreviousAdjacentElement(noMoreSiblingsCases, previousSibling); 3637 markElementIfResolvingStyle(previousSibling, Node::flagAffectsNextSiblingElementStyle());3478 generateAddStyleRelationIfResolvingStyle(previousSibling, SelectorChecker::StyleRelation::AffectsNextSibling); 3638 3479 noCachedChildIndexCases.append(m_assembler.branchTest32(Assembler::Zero, Assembler::Address(previousSibling, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagHasRareData()))); 3639 3480 { … … 3651 3492 Assembler::Label loopStart = m_assembler.label(); 3652 3493 generateWalkToPreviousAdjacentElement(noMoreSiblingsCases, previousSibling); 3653 markElementIfResolvingStyle(previousSibling, Node::flagAffectsNextSiblingElementStyle());3494 generateAddStyleRelationIfResolvingStyle(previousSibling, SelectorChecker::StyleRelation::AffectsNextSibling); 3654 3495 m_assembler.add32(Assembler::TrustedImm32(1), elementCounter); 3655 3496 m_assembler.jump().linkTo(loopStart, &m_assembler); … … 3657 3498 } 3658 3499 3659 // Tree marking when doing style resolution. 3660 if (m_selectorContext != SelectorContext::QuerySelector) { 3661 LocalRegister checkingContext(m_registerAllocator); 3662 Assembler::Jump notResolvingStyle = jumpIfNotResolvingStyle(checkingContext); 3663 3664 Assembler::RegisterID elementAddress = elementAddressRegister; 3665 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3666 functionCall.setFunctionAddress(setElementChildIndex); 3667 functionCall.setTwoArguments(elementAddress, elementCounter); 3668 functionCall.call(); 3669 3670 notResolvingStyle.link(&m_assembler); 3671 } 3500 generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::NthChildIndex, Assembler::RegisterID(elementCounter)); 3672 3501 3673 3502 for (const auto& slot : validSubsetFilters) … … 3696 3525 3697 3526 if (!isAdjacentRelation(fragment.relationToRightFragment)) 3698 markElementIfResolvingStyle(elementAddressRegister, Node::flagStyleIsAffectedByPreviousSibling());3527 generateAddStyleRelationIfResolvingStyle(elementAddressRegister, SelectorChecker::StyleRelation::AffectedByPreviousSibling); 3699 3528 3700 3529 for (const NthChildOfSelectorInfo* nthChildOfSelectorInfo : validSubsetFilters) { … … 3713 3542 3714 3543 generateWalkToPreviousAdjacentElement(noMoreSiblingsCases, previousSibling); 3715 markElementIfResolvingStyle(previousSibling, Node::flagAffectsNextSiblingElementStyle());3544 generateAddStyleRelationIfResolvingStyle(previousSibling, SelectorChecker::StyleRelation::AffectsNextSibling); 3716 3545 3717 3546 Assembler::JumpList localFailureCases; … … 3728 3557 } 3729 3558 3730 static void setChildrenAffectedByBackwardPositionalRules(Element* element)3731 {3732 element->setChildrenAffectedByBackwardPositionalRules();3733 }3734 3735 3559 void SelectorCodeGenerator::generateElementIsNthLastChild(Assembler::JumpList& failureCases, const SelectorFragment& fragment) 3736 3560 { … … 3741 3565 generateWalkToParentElement(failureCases, parentElement); 3742 3566 3743 if (m_selectorContext != SelectorContext::QuerySelector) { 3744 Assembler::Jump skipMarking; 3745 { 3746 LocalRegister checkingContext(m_registerAllocator); 3747 skipMarking = jumpIfNotResolvingStyle(checkingContext); 3748 } 3749 3750 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3751 functionCall.setFunctionAddress(setChildrenAffectedByBackwardPositionalRules); 3752 functionCall.setOneArgument(parentElement); 3753 functionCall.call(); 3754 3755 skipMarking.link(&m_assembler); 3756 } 3567 generateAddStyleRelationIfResolvingStyle(parentElement, SelectorChecker::StyleRelation::ChildrenAffectedByBackwardPositionalRules); 3757 3568 3758 3569 failureCases.append(m_assembler.branchTest32(Assembler::Zero, Assembler::Address(parentElement, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagIsParsingChildrenFinished()))); … … 3789 3600 } 3790 3601 3791 static void setParentAffectedByLastChildOf(Element* parentElement)3792 {3793 ASSERT(parentElement);3794 parentElement->setChildrenAffectedByPropertyBasedBackwardPositionalRules();3795 parentElement->setChildrenAffectedByBackwardPositionalRules();3796 }3797 3798 3602 void SelectorCodeGenerator::generateElementIsNthLastChildOf(Assembler::JumpList& failureCases, const SelectorFragment& fragment) 3799 3603 { … … 3804 3608 generateWalkToParentElement(failureCases, parentElement); 3805 3609 3806 if (m_selectorContext != SelectorContext::QuerySelector) { 3807 Assembler::Jump skipMarking; 3808 { 3809 LocalRegister checkingContext(m_registerAllocator); 3810 skipMarking = jumpIfNotResolvingStyle(checkingContext); 3811 } 3812 3813 FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls); 3814 functionCall.setFunctionAddress(setParentAffectedByLastChildOf); 3815 functionCall.setOneArgument(parentElement); 3816 functionCall.call(); 3817 3818 skipMarking.link(&m_assembler); 3819 } 3610 generateAddStyleRelationIfResolvingStyle(parentElement, SelectorChecker::StyleRelation::ChildrenAffectedByPropertyBasedBackwardPositionalRules); 3820 3611 3821 3612 failureCases.append(m_assembler.branchTest32(Assembler::Zero, Assembler::Address(parentElement, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagIsParsingChildrenFinished()))); … … 4004 3795 if (dynamicPseudo < FIRST_INTERNAL_PSEUDOID) { 4005 3796 failureCases.append(branchOnResolvingModeWithCheckingContext(Assembler::NotEqual, SelectorChecker::Mode::ResolvingStyle, checkingContext)); 4006 addFlagsToElementStyleFromContext(checkingContext, RenderStyle::NonInheritedFlags::flagPseudoStyle(dynamicPseudo)); 3797 3798 Assembler::Address pseudoIDSetAddress(checkingContext, OBJECT_OFFSETOF(SelectorChecker::CheckingContext, pseudoIDSet)); 3799 auto pseudoIDSetDataAddress = pseudoIDSetAddress.withOffset(PseudoIdSet::dataMemoryOffset()); 3800 PseudoIdSet value { dynamicPseudo }; 3801 m_assembler.store32(Assembler::TrustedImm32(value.data()), pseudoIDSetDataAddress); 4007 3802 } 4008 3803 -
trunk/Source/WebCore/dom/SelectorQuery.cpp
r195141 r195293 119 119 selectorCheckingContext.scope = rootNode.isDocumentNode() ? nullptr : &rootNode; 120 120 unsigned ignoredSpecificity; 121 return selectorChecker.match( selectorData.selector, &element, selectorCheckingContext, ignoredSpecificity);121 return selectorChecker.match(*selectorData.selector, element, selectorCheckingContext, ignoredSpecificity); 122 122 } 123 123 … … 127 127 SelectorChecker::CheckingContext selectorCheckingContext(SelectorChecker::Mode::QueryingRules); 128 128 selectorCheckingContext.scope = rootNode.isDocumentNode() ? nullptr : &rootNode; 129 Element* currentNode = &element;130 129 unsigned ignoredSpecificity; 131 if (!selectorChecker.match( selectorData.selector, currentNode, selectorCheckingContext, ignoredSpecificity))130 if (!selectorChecker.match(*selectorData.selector, element, selectorCheckingContext, ignoredSpecificity)) 132 131 return nullptr; 133 return currentNode;132 return &element; 134 133 } 135 134 -
trunk/Source/WebCore/inspector/InspectorCSSAgent.cpp
r194819 r195293 1051 1051 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) { 1052 1052 unsigned ignoredSpecificity; 1053 bool matched = selectorChecker.match( selector,element, context, ignoredSpecificity);1053 bool matched = selectorChecker.match(*selector, *element, context, ignoredSpecificity); 1054 1054 if (matched) 1055 1055 matchingSelectors->addItem(index); -
trunk/Source/WebCore/inspector/InspectorStyleSheet.cpp
r194819 r195293 863 863 864 864 unsigned specificity; 865 bool okay = selectorChecker.match( &selector,element, context, specificity);865 bool okay = selectorChecker.match(selector, *element, context, specificity); 866 866 if (!okay) 867 867 specificity = selector.staticSpecificity(okay); -
trunk/Source/WebCore/rendering/style/RenderStyleConstants.h
r194104 r195293 140 140 141 141 unsigned data() const { return m_data; } 142 143 static ptrdiff_t dataMemoryOffset() { return OBJECT_OFFSETOF(PseudoIdSet, m_data); } 144 142 145 private: 143 146 explicit PseudoIdSet(unsigned rawPseudoIdSet)
Note: See TracChangeset
for help on using the changeset viewer.