Changeset 107911 in webkit
- Timestamp:
- Feb 16, 2012 1:31:17 AM (12 years ago)
- Location:
- trunk
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r107910 r107911 1 2012-02-16 Roland Steiner <rolandsteiner@chromium.org> 2 3 <style scoped>: Implement scoped selector matching in the slow path 4 https://bugs.webkit.org/show_bug.cgi?id=77528 5 6 Extended existing <style scoped> tests to also verify that selector matching doesn't exceed the scoping element. 7 8 Reviewed by Antti Koivisto. 9 10 * fast/css/style-scoped/style-scoped-basic-expected.txt: 11 * fast/css/style-scoped/style-scoped-basic.html: 12 * fast/css/style-scoped/style-scoped-remove-scoped-expected.txt: 13 * fast/css/style-scoped/style-scoped-remove-scoped.html: 14 * fast/css/style-scoped/style-scoped-set-scoped-expected.txt: 15 * fast/css/style-scoped/style-scoped-set-scoped.html: 16 1 17 2012-02-16 Noel Gordon <noel.gordon@gmail.com> 2 18 -
trunk/LayoutTests/fast/css/style-scoped/style-scoped-basic-expected.txt
r106331 r107911 9 9 Text 10 10 11 Text 11 12 Text 12 13 Text … … 29 30 P2: rgb(0, 128, 0) 30 31 R2: rgb(0, 0, 255) 32 E2: rgb(255, 0, 0) 31 33 32 34 S3: rgb(0, 0, 0) -
trunk/LayoutTests/fast/css/style-scoped/style-scoped-basic.html
r106331 r107911 29 29 test('P2'); 30 30 test('R2'); 31 test('E2'); 31 32 log(''); 32 33 test('S3'); … … 52 53 <span id="S1">Text</span> 53 54 <p id="P1">Text</p> 54 <pre id ="R1" class="bar">Text</pre>55 <pre id="R1" class="bar">Text</pre> 55 56 <pre id="E1" class="baz">Text</pre> 56 57 </div> 57 <div> 58 <div id="foo"> 59 <div id="sib"></div> 58 60 <div> 59 61 <style type="text/css" scoped> … … 61 63 p { color: green; } 62 64 div .bar { color: blue; } 65 #foo .baz { color: rgb(10, 10, 10); } /* should NOT apply! */ 66 sib + * { color: rgb(20, 20, 20); } /* should NOT apply! */ 67 sib ~ * { color: rgb(30, 30, 30); } /* should NOT apply! */ 68 div div { color: rgb(40, 40, 40); } /* should NOT apply! */ 63 69 </style> 64 70 <span id="S2">Text</span> 65 71 <p id="P2">Text</p> 66 72 <pre id="R2" class="bar">Text</pre> 73 <pre id="E2" class="baz">Text</pre> 67 74 </div> 68 75 <span id="S3">Text</span> 69 76 <p id="P3">Text</p> 70 <pre id ="R3" class="bar">Text</pre>77 <pre id="R3" class="bar">Text</pre> 71 78 <pre id="E3" class="baz">Text</pre> 72 79 </div> … … 74 81 <span id="S4">Text</span> 75 82 <p id="P4">Text</p> 76 <pre id ="R4" class="bar">Text</pre>83 <pre id="R4" class="bar">Text</pre> 77 84 <pre id="E4" class="baz">Text</pre> 78 85 </div> -
trunk/LayoutTests/fast/css/style-scoped/style-scoped-remove-scoped-expected.txt
r106331 r107911 5 5 6 6 Text 7 8 9 Text 7 10 Text 8 11 9 12 Text 13 14 15 Text 10 16 Text 11 17 18 Text 19 20 12 21 --- ORIGINAL --- 13 22 S1: rgb(0, 0, 0) 14 23 P1: rgb(0, 0, 0) 24 R1: rgb(0, 0, 0) 15 25 S2: rgb(255, 0, 0) 16 26 P2: rgb(0, 128, 0) 27 R2: rgb(255, 0, 0) 17 28 S3: rgb(0, 0, 0) 18 29 P3: rgb(0, 0, 0) 30 R3: rgb(0, 0, 0) 19 31 --- AFTER UN-SETTING @SCOPED --- 20 32 S1: rgb(255, 0, 0) 21 33 P1: rgb(0, 128, 0) 34 R1: rgb(0, 0, 255) 22 35 S2: rgb(255, 0, 0) 23 36 P2: rgb(0, 128, 0) 37 R2: rgb(0, 0, 255) 24 38 S3: rgb(255, 0, 0) 25 39 P3: rgb(0, 128, 0) 40 R3: rgb(0, 0, 255) 26 41 --- FINISHED --- 27 42 -
trunk/LayoutTests/fast/css/style-scoped/style-scoped-remove-scoped.html
r106331 r107911 18 18 test('S1'); 19 19 test('P1'); 20 test('R1'); 20 21 test('S2'); 21 22 test('P2'); 23 test('R2'); 22 24 test('S3'); 23 25 test('P3'); 26 test('R3'); 24 27 } 25 28 … … 53 56 <span id="S1">Text</span> 54 57 <p id="P1">Text</p> 58 <pre id="R1">Text</p> 55 59 </div> 56 60 <div> … … 58 62 div { color: red; } 59 63 p { color: green; } 64 p ~ div pre { color: blue; } /* should NOT apply while scoped! */ 60 65 </style> 61 66 <span id="S2">Text</span> 62 67 <p id="P2">Text</p> 68 <pre id="R2">Text</p> 63 69 </div> 64 70 <div> 65 71 <span id="S3">Text</span> 66 72 <p id="P3">Text</p> 73 <pre id="R3">Text</p> 67 74 </div> 68 75 <pre id="console"></pre> -
trunk/LayoutTests/fast/css/style-scoped/style-scoped-set-scoped-expected.txt
r106331 r107911 5 5 6 6 Text 7 8 9 Text 7 10 Text 8 11 9 12 Text 13 14 15 Text 10 16 Text 11 17 18 Text 19 20 12 21 --- ORIGINAL --- 13 22 S1: rgb(255, 0, 0) 14 23 P1: rgb(0, 128, 0) 24 R1: rgb(0, 0, 255) 15 25 S2: rgb(255, 0, 0) 16 26 P2: rgb(0, 128, 0) 27 R2: rgb(0, 0, 255) 17 28 S3: rgb(255, 0, 0) 18 29 P3: rgb(0, 128, 0) 30 R3: rgb(0, 0, 255) 19 31 --- AFTER SETTING @SCOPED --- 20 32 S1: rgb(0, 0, 0) 21 33 P1: rgb(0, 0, 0) 34 R1: rgb(0, 0, 0) 22 35 S2: rgb(255, 0, 0) 23 36 P2: rgb(0, 128, 0) 37 R2: rgb(255, 0, 0) 24 38 S3: rgb(0, 0, 0) 25 39 P3: rgb(0, 0, 0) 40 R3: rgb(0, 0, 0) 26 41 --- FINISHED --- 27 42 -
trunk/LayoutTests/fast/css/style-scoped/style-scoped-set-scoped.html
r106331 r107911 18 18 test('S1'); 19 19 test('P1'); 20 test('R1'); 20 21 test('S2'); 21 22 test('P2'); 23 test('R2'); 22 24 test('S3'); 23 25 test('P3'); 26 test('R3'); 24 27 } 25 28 … … 53 56 <span id="S1">Text</span> 54 57 <p id="P1">Text</p> 58 <pre id="R1">Text</p> 55 59 </div> 56 60 <div> … … 58 62 div { color: red; } 59 63 p { color: green; } 64 p ~ div pre { color: blue; } /* should NOT apply while scoped! */ 60 65 </style> 61 66 <span id="S2">Text</span> 62 67 <p id="P2">Text</p> 68 <pre id="R2">Text</p> 63 69 </div> 64 70 <div> 65 71 <span id="S3">Text</span> 66 72 <p id="P3">Text</p> 73 <pre id="R3">Text</p> 67 74 </div> 68 75 <pre id="console"></pre> -
trunk/Source/WebCore/ChangeLog
r107900 r107911 1 2012-02-16 Roland Steiner <rolandsteiner@chromium.org> 2 3 <style scoped>: Implement scoped selector matching in the slow path 4 https://bugs.webkit.org/show_bug.cgi?id=77528 5 6 Added scope information to SelectorCheckingContext, SelectorChecker methods and CSSStyleSelector methods. 7 Added matchOptions struct to CSSStyleSelector similar to SelectorCheckingContext in SelectorChecker. 8 Adapted the calling sites. 9 10 Reviewed by Antti Koivisto. 11 12 No new tests. (extended existing tests) 13 14 * css/CSSStyleSelector.cpp: 15 (RuleData): 16 (RuleSet): 17 (WebCore::CSSStyleSelector::determineScopingElement): 18 (WebCore::CSSStyleSelector::collectMatchingRules): 19 (WebCore::CSSStyleSelector::collectMatchingRulesForRegion): 20 (WebCore::CSSStyleSelector::matchScopedAuthorRules): 21 (WebCore::CSSStyleSelector::matchAuthorRules): 22 (WebCore::CSSStyleSelector::collectMatchingRulesForList): 23 * css/CSSStyleSelector.h: 24 (CSSStyleSelector): 25 (MatchOptions): 26 (WebCore::CSSStyleSelector::MatchOptions::MatchOptions): 27 * css/SelectorChecker.cpp: 28 (WebCore::SelectorChecker::checkSelector): 29 * css/SelectorChecker.h: 30 (WebCore::SelectorChecker::SelectorCheckingContext::SelectorCheckingContext): 31 (SelectorCheckingContext): 32 (SelectorChecker): 33 1 34 2012-02-15 Patrick Gansterer <paroga@webkit.org> 2 35 -
trunk/Source/WebCore/css/CSSStyleSelector.cpp
r107881 r107911 174 174 class RuleData { 175 175 public: 176 RuleData(CSSStyleRule*, CSSSelector*, unsigned position );176 RuleData(CSSStyleRule*, CSSSelector*, unsigned position, bool canUseFastCheckSelector = true); 177 177 178 178 unsigned position() const { return m_position; } … … 226 226 void addRulesFromSheet(CSSStyleSheet*, const MediaQueryEvaluator&, CSSStyleSelector* = 0, const Element* = 0); 227 227 228 void addStyleRule(CSSStyleRule* );229 void addRule(CSSStyleRule*, CSSSelector* );228 void addStyleRule(CSSStyleRule*, bool canUseFastCheckSelector = true); 229 void addRule(CSSStyleRule*, CSSSelector*, bool canUseFastCheckSelector = true); 230 230 void addPageRule(CSSPageRule*); 231 231 void addToRuleSet(AtomicStringImpl* key, AtomRuleMap&, const RuleData&); … … 444 444 445 445 #if ENABLE(STYLE_SCOPED) 446 Element* CSSStyleSelector::determineScopingElement(const CSSStyleSheet* sheet)446 const Element* CSSStyleSelector::determineScopingElement(const CSSStyleSheet* sheet) 447 447 { 448 448 ASSERT(sheet); … … 757 757 } 758 758 759 void CSSStyleSelector::collectMatchingRules(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)759 void CSSStyleSelector::collectMatchingRules(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions& options) 760 760 { 761 761 ASSERT(rules); … … 765 765 // then sort the buffer. 766 766 if (m_element->hasID()) 767 collectMatchingRulesForList(rules->idRules(m_element->idForStyleResolution().impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);767 collectMatchingRulesForList(rules->idRules(m_element->idForStyleResolution().impl()), firstRuleIndex, lastRuleIndex, options); 768 768 if (m_element->hasClass()) { 769 769 ASSERT(m_styledElement); … … 771 771 size_t size = classNames.size(); 772 772 for (size_t i = 0; i < size; ++i) 773 collectMatchingRulesForList(rules->classRules(classNames[i].impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);773 collectMatchingRulesForList(rules->classRules(classNames[i].impl()), firstRuleIndex, lastRuleIndex, options); 774 774 } 775 775 const AtomicString& pseudoId = m_element->shadowPseudoId(); 776 776 if (!pseudoId.isEmpty()) { 777 777 ASSERT(m_styledElement); 778 collectMatchingRulesForList(rules->shadowPseudoElementRules(pseudoId.impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);778 collectMatchingRulesForList(rules->shadowPseudoElementRules(pseudoId.impl()), firstRuleIndex, lastRuleIndex, options); 779 779 } 780 780 if (m_element->isLink()) 781 collectMatchingRulesForList(rules->linkPseudoClassRules(), firstRuleIndex, lastRuleIndex, includeEmptyRules);781 collectMatchingRulesForList(rules->linkPseudoClassRules(), firstRuleIndex, lastRuleIndex, options); 782 782 if (m_checker.matchesFocusPseudoClass(m_element)) 783 collectMatchingRulesForList(rules->focusPseudoClassRules(), firstRuleIndex, lastRuleIndex, includeEmptyRules);784 collectMatchingRulesForList(rules->tagRules(m_element->localName().impl()), firstRuleIndex, lastRuleIndex, includeEmptyRules);785 collectMatchingRulesForList(rules->universalRules(), firstRuleIndex, lastRuleIndex, includeEmptyRules);786 } 787 788 void CSSStyleSelector::collectMatchingRulesForRegion(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules)783 collectMatchingRulesForList(rules->focusPseudoClassRules(), firstRuleIndex, lastRuleIndex, options); 784 collectMatchingRulesForList(rules->tagRules(m_element->localName().impl()), firstRuleIndex, lastRuleIndex, options); 785 collectMatchingRulesForList(rules->universalRules(), firstRuleIndex, lastRuleIndex, options); 786 } 787 788 void CSSStyleSelector::collectMatchingRulesForRegion(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions& options) 789 789 { 790 790 if (!m_regionForStyling) … … 797 797 RuleSet* regionRules = rules->m_regionSelectorsAndRuleSets.at(i).ruleSet.get(); 798 798 ASSERT(regionRules); 799 collectMatchingRules(regionRules, firstRuleIndex, lastRuleIndex, includeEmptyRules);799 collectMatchingRules(regionRules, firstRuleIndex, lastRuleIndex, options); 800 800 } 801 801 } … … 836 836 return; 837 837 838 MatchOptions options(includeEmptyRules); 839 838 840 // Match scoped author rules by traversing the scoped element stack (rebuild it if it got inconsistent). 839 841 const Element* parent = m_element->parentOrHostElement(); … … 841 843 setupScopingElementStack(parent); 842 844 for (size_t i = m_scopingElementStack.size(); i; --i) { 843 collectMatchingRules(m_scopingElementStack[i - 1].m_ruleSet, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, includeEmptyRules); 844 collectMatchingRulesForRegion(m_scopingElementStack[i - 1].m_ruleSet, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, includeEmptyRules); 845 const ScopeStackFrame& frame = m_scopingElementStack[i - 1]; 846 options.scope = frame.m_element; 847 collectMatchingRules(frame.m_ruleSet, result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options); 848 collectMatchingRulesForRegion(frame.m_ruleSet, result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options); 845 849 } 846 850 // Also include the current element. 847 851 RuleSet* ruleSet = scopedRuleSetForElement(m_element); 848 852 if (ruleSet) { 849 collectMatchingRules(ruleSet, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, includeEmptyRules); 850 collectMatchingRulesForRegion(ruleSet, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, includeEmptyRules); 853 options.scope = m_element; 854 collectMatchingRules(ruleSet, result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options); 855 collectMatchingRulesForRegion(ruleSet, result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options); 851 856 } 852 857 #else … … 859 864 { 860 865 m_matchedRules.clear(); 861 862 866 result.ranges.lastAuthorRule = result.matchedProperties.size() - 1; 863 collectMatchingRules(m_authorStyle.get(), result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, includeEmptyRules); 864 collectMatchingRulesForRegion(m_authorStyle.get(), result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, includeEmptyRules); 867 868 if (!m_element) 869 return; 870 871 // Match global author rules. 872 MatchOptions options(includeEmptyRules); 873 collectMatchingRules(m_authorStyle.get(), result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options); 874 collectMatchingRulesForRegion(m_authorStyle.get(), result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options); 865 875 866 876 matchScopedAuthorRules(result, includeEmptyRules); … … 922 932 bool MatchingUARulesScope::m_matchingUARules = false; 923 933 924 inline static bool matchesInTreeScope(TreeScope* treeScope, bool ruleReachesIntoShadowDOM) 925 { 926 return MatchingUARulesScope::isMatchingUARules() || treeScope->applyAuthorSheets() || ruleReachesIntoShadowDOM; 927 } 928 929 void CSSStyleSelector::collectMatchingRulesForList(const Vector<RuleData>* rules, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules) 934 void CSSStyleSelector::collectMatchingRulesForList(const Vector<RuleData>* rules, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions& options) 930 935 { 931 936 if (!rules) … … 943 948 CSSStyleRule* rule = ruleData.rule(); 944 949 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willMatchRule(document(), rule); 950 #if ENABLE(STYLE_SCOPED) 951 if (checkSelector(ruleData, options.scope)) { 952 #else 945 953 if (checkSelector(ruleData)) { 946 if (!matchesInTreeScope(m_element->treeScope(), m_checker.hasUnknownPseudoElements())) { 954 #endif 955 // Check whether the rule is applicable in the current tree scope. Criteria for this: 956 // a) it's a UA rule 957 // b) the tree scope allows author rules 958 // c) the rules comes from a scoped style sheet within the same tree scope 959 // d) the rule contains shadow-ID pseudo elements 960 TreeScope* treeScope = m_element->treeScope(); 961 if (!MatchingUARulesScope::isMatchingUARules() 962 && !treeScope->applyAuthorSheets() 963 #if ENABLE(STYLE_SCOPED) 964 && (!options.scope || options.scope->treeScope() != treeScope) 965 #endif 966 && !m_checker.hasUnknownPseudoElements()) { 967 947 968 InspectorInstrumentation::didMatchRule(cookie, false); 948 969 continue; … … 950 971 // If the rule has no properties to apply, then ignore it in the non-debug mode. 951 972 StylePropertySet* decl = rule->declaration(); 952 if (!decl || (decl->isEmpty() && ! includeEmptyRules)) {973 if (!decl || (decl->isEmpty() && !options.includeEmptyRules)) { 953 974 InspectorInstrumentation::didMatchRule(cookie, false); 954 975 continue; … … 2082 2103 } 2083 2104 2084 inline bool CSSStyleSelector::checkSelector(const RuleData& ruleData )2105 inline bool CSSStyleSelector::checkSelector(const RuleData& ruleData, const Element* scope) 2085 2106 { 2086 2107 m_dynamicPseudo = NOPSEUDO; … … 2105 2126 2106 2127 // Slow path. 2107 SelectorChecker::SelectorCheckingContext context(ruleData.selector(), m_element, SelectorChecker::VisitedMatchEnabled, style(), m_parentNode ? m_parentNode->renderStyle() : 0); 2128 SelectorChecker::SelectorCheckingContext context(ruleData.selector(), m_element, SelectorChecker::VisitedMatchEnabled); 2129 context.elementStyle = style(); 2130 context.elementParentStyle = m_parentNode ? m_parentNode->renderStyle() : 0; 2131 context.scope = scope; 2108 2132 SelectorChecker::SelectorMatch match = m_checker.checkSelector(context, m_dynamicPseudo); 2109 2133 if (match != SelectorChecker::SelectorMatches) … … 2212 2236 } 2213 2237 2214 RuleData::RuleData(CSSStyleRule* rule, CSSSelector* selector, unsigned position )2238 RuleData::RuleData(CSSStyleRule* rule, CSSSelector* selector, unsigned position, bool canUseFastCheckSelector) 2215 2239 : m_rule(rule) 2216 2240 , m_selector(selector) 2217 2241 , m_specificity(selector->specificity()) 2218 2242 , m_position(position) 2219 , m_hasFastCheckableSelector( SelectorChecker::isFastCheckableSelector(selector))2243 , m_hasFastCheckableSelector(canUseFastCheckSelector && SelectorChecker::isFastCheckableSelector(selector)) 2220 2244 , m_hasMultipartSelector(!!selector->tagHistory()) 2221 2245 , m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash(isSelectorMatchingHTMLBasedOnRuleHash(selector)) … … 2286 2310 } 2287 2311 2288 void RuleSet::addRule(CSSStyleRule* rule, CSSSelector* selector )2289 { 2290 RuleData ruleData(rule, selector, m_ruleCount++ );2312 void RuleSet::addRule(CSSStyleRule* rule, CSSSelector* selector, bool canUseFastCheckSelector) 2313 { 2314 RuleData ruleData(rule, selector, m_ruleCount++, canUseFastCheckSelector); 2291 2315 collectFeaturesFromRuleData(m_features, ruleData); 2292 2316 … … 2365 2389 CSSRule* rule = sheet->item(i); 2366 2390 if (rule->isStyleRule()) 2367 addStyleRule(static_cast<CSSStyleRule*>(rule) );2391 addStyleRule(static_cast<CSSStyleRule*>(rule), !scope); 2368 2392 else if (rule->isPageRule()) 2369 2393 addPageRule(static_cast<CSSPageRule*>(rule)); … … 2382 2406 CSSRule *childItem = rules->item(j); 2383 2407 if (childItem->isStyleRule()) 2384 addStyleRule(static_cast<CSSStyleRule*>(childItem) );2408 addStyleRule(static_cast<CSSStyleRule*>(childItem), !scope); 2385 2409 else if (childItem->isPageRule()) 2386 2410 addPageRule(static_cast<CSSPageRule*>(childItem)); … … 2426 2450 } 2427 2451 2428 void RuleSet::addStyleRule(CSSStyleRule* rule )2452 void RuleSet::addStyleRule(CSSStyleRule* rule, bool canUseFastCheckSelector) 2429 2453 { 2430 2454 for (CSSSelector* s = rule->selectorList().first(); s; s = CSSSelectorList::next(s)) 2431 addRule(rule, s );2455 addRule(rule, s, canUseFastCheckSelector); 2432 2456 } 2433 2457 -
trunk/Source/WebCore/css/CSSStyleSelector.h
r107783 r107911 107 107 ~CSSStyleSelector(); 108 108 109 #if ENABLE(STYLE_SCOPED)110 static Element* determineScopingElement(const CSSStyleSheet*);111 #endif112 113 109 // Using these during tree walk will allow style selector to optimize child and descendant selector lookups. 114 110 void pushParent(Element* parent); … … 289 285 bool isCacheable; 290 286 }; 287 288 struct MatchOptions { 289 MatchOptions(bool includeEmptyRules, const Element* scope = 0) : scope(scope), includeEmptyRules(includeEmptyRules) { } 290 const Element* scope; 291 bool includeEmptyRules; 292 }; 293 291 294 static void addMatchedProperties(MatchResult& matchResult, StylePropertySet* properties, CSSStyleRule* rule = 0, unsigned linkMatchType = SelectorChecker::MatchAll); 292 295 … … 297 300 void matchUserRules(MatchResult&, bool includeEmptyRules); 298 301 void matchScopedAuthorRules(MatchResult&, bool includeEmptyRules); 299 void collectMatchingRules(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);300 void collectMatchingRulesForRegion(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);301 void collectMatchingRulesForList(const Vector<RuleData>*, int& firstRuleIndex, int& lastRuleIndex, bool includeEmptyRules);302 void collectMatchingRules(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions&); 303 void collectMatchingRulesForRegion(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions&); 304 void collectMatchingRulesForList(const Vector<RuleData>*, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions&); 302 305 bool fastRejectSelector(const RuleData&) const; 303 306 void sortMatchedRules(); 304 307 void sortAndTransferMatchedRules(MatchResult&); 305 308 306 bool checkSelector(const RuleData& );309 bool checkSelector(const RuleData&, const Element* scope = 0); 307 310 bool checkRegionSelector(CSSSelector* regionSelector, Element* regionElement); 308 311 void applyMatchedProperties(const MatchResult&); … … 447 450 448 451 #if ENABLE(STYLE_SCOPED) 452 static const Element* determineScopingElement(const CSSStyleSheet*); 453 449 454 typedef HashMap<const Element*, OwnPtr<RuleSet> > ScopedRuleSetMap; 450 455 -
trunk/Source/WebCore/css/SelectorChecker.cpp
r107509 r107911 469 469 470 470 if (relation != CSSSelector::SubSelector) { 471 // Abort if the next selector would exceed the scope. 472 if (context.element == context.scope) 473 return SelectorFailsCompletely; 474 471 475 // Bail-out if this selector is irrelevant for the pseudoStyle 472 476 if (m_pseudoStyle != NOPSEUDO && m_pseudoStyle != dynamicPseudo) … … 488 492 if (match == SelectorMatches || match == SelectorFailsCompletely) 489 493 return match; 494 if (nextContext.element == nextContext.scope) 495 return SelectorFailsCompletely; 490 496 } 491 497 return SelectorFailsCompletely; … … 543 549 case CSSSelector::ShadowDescendant: 544 550 { 551 // If we're in the same tree-scope as the scoping element, then following a shadow descendant combinator would escape that and thus the scope. 552 if (context.scope && context.scope->treeScope() == context.element->treeScope()) 553 return SelectorFailsCompletely; 545 554 Node* shadowHostNode = context.element->shadowAncestorNode(); 546 555 if (shadowHostNode == context.element || !shadowHostNode->isElementNode()) -
trunk/Source/WebCore/css/SelectorChecker.h
r107212 r107911 55 55 struct SelectorCheckingContext { 56 56 // Initial selector constructor 57 SelectorCheckingContext(CSSSelector* selector, Element* element, VisitedMatchType visitedMatchType , RenderStyle* elementStyle = 0, RenderStyle* elementParentStyle = 0)57 SelectorCheckingContext(CSSSelector* selector, Element* element, VisitedMatchType visitedMatchType) 58 58 : selector(selector) 59 59 , element(element) 60 , scope(0) 60 61 , visitedMatchType(visitedMatchType) 61 , elementStyle( elementStyle)62 , elementParentStyle( elementParentStyle)62 , elementStyle(0) 63 , elementParentStyle(0) 63 64 , isSubSelector(false) 64 65 { } … … 66 67 CSSSelector* selector; 67 68 Element* element; 69 const Element* scope; 68 70 VisitedMatchType visitedMatchType; 69 71 RenderStyle* elementStyle; … … 144 146 }; 145 147 Vector<ParentStackFrame> m_parentStack; 146 148 147 149 // With 100 unique strings in the filter, 2^12 slot table has false positive rate of ~0.2%. 148 150 static const unsigned bloomFilterKeyBits = 12;
Note: See TracChangeset
for help on using the changeset viewer.