Changeset 199268 in webkit
- Timestamp:
- Apr 9, 2016 12:38:32 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r199265 r199268 1 2016-04-09 Antti Koivisto <antti@apple.com> 2 3 Implement functional :host() pseudo class 4 https://bugs.webkit.org/show_bug.cgi?id=156397 5 <rdar://problem/25621445> 6 7 Reviewed by Darin Adler. 8 9 Enable, fix and expand the test. 10 11 * fast/shadow-dom/css-scoping-shadow-host-functional-rule.html: 12 * platform/mac/TestExpectations: 13 1 14 2016-04-07 Darin Adler <darin@apple.com> 2 15 -
trunk/LayoutTests/fast/shadow-dom/css-scoping-shadow-host-functional-rule.html
r190098 r199268 9 9 <body> 10 10 <style> 11 my-host, good-host, other-host, other-good-host{11 host1, host2, host3, host4, host5 { 12 12 display: block; 13 13 width: 100px; 14 height: 50px;14 height: 20px; 15 15 background: red; 16 16 } 17 good-host, other-good-host{17 host3, host4, host5 { 18 18 background: green; 19 19 } 20 20 </style> 21 <p>Test passes if you see a single 100px by 100px green box below.</p> 22 < my-host>21 <p>Test passes if you see a single 100px by 100px green box below.</p> 22 <host1> 23 23 <div>FAIL</div> 24 </my-host> 25 <div class="container"> 26 <good-host> 27 <div>FAIL</div> 28 </good-host> 24 </host1> 25 <host2 id="bar" class="foo" name="baz"> 26 <div>FAIL</div> 27 </host2> 28 <div> 29 <host3> 30 FAIL 31 </host3> 29 32 </div> 30 <other-host id="bar" class="foo" name="baz"> 33 <host4> 34 <div class="child">FAIL</div> 35 </host4> 36 <host5> 31 37 <div>FAIL</div> 32 </other-host> 33 <other-good-host> 34 <div class="child">FAIL</div> 35 </other-good-host> 38 </host5> 36 39 <script> 37 40 38 41 try { 39 var shadowHost = document.querySelector(' other-host');42 var shadowHost = document.querySelector('host1'); 40 43 shadowRoot = shadowHost.attachShadow({mode: 'open'}); 41 shadowRoot.innerHTML = '<style> :host( other-host.foo#bar[name=baz]) { background: green; } </style>';44 shadowRoot.innerHTML = '<style> :host(host1) { background: green !important; } </style>'; 42 45 43 shadowHost = document.querySelector(' other-good-host');46 shadowHost = document.querySelector('host2'); 44 47 shadowRoot = shadowHost.attachShadow({mode: 'open'}); 45 shadowRoot.innerHTML = '<style> :host(.child) { background: red; } </style>'; 48 shadowRoot.innerHTML = '<style> :host(host2.foo#bar[name=baz]) { background: green !important; } </style>'; 49 50 shadowHost = document.querySelector('host3'); 51 shadowRoot = shadowHost.attachShadow({mode: 'open'}); 52 shadowRoot.innerHTML = '<style> :host(div host3) { background: red !important; } </style>'; 53 54 shadowHost = document.querySelector('host4'); 55 shadowRoot = shadowHost.attachShadow({mode: 'open'}); 56 shadowRoot.innerHTML = '<style> :host(.child) { background: red !important; } </style>'; 57 58 shadowHost = document.querySelector('host5'); 59 shadowRoot = shadowHost.attachShadow({mode: 'open'}); 60 shadowRoot.innerHTML = '<style> :host(host1) { background: red !important; } </style>'; 46 61 } catch (exception) { 47 62 document.body.appendChild(document.createTextNode(exception)); -
trunk/LayoutTests/platform/mac/TestExpectations
r199206 r199268 1225 1225 1226 1226 webkit.org/b/148695 fast/shadow-dom [ Pass ] 1227 webkit.org/b/149440 fast/shadow-dom/css-scoping-shadow-host-functional-rule.html [ ImageOnlyFailure ]1228 1227 1229 1228 # Touch events is not enabled on Mac -
trunk/Source/WebCore/ChangeLog
r199265 r199268 1 2016-04-09 Antti Koivisto <antti@apple.com> 2 3 Implement functional :host() pseudo class 4 https://bugs.webkit.org/show_bug.cgi?id=156397 5 <rdar://problem/25621445> 6 7 Reviewed by Darin Adler. 8 9 We already support :host. Add functional syntax too. 10 11 * css/CSSGrammar.y.in: 12 13 Parse functional :host(). 14 15 * css/CSSParser.cpp: 16 (WebCore::CSSParser::detectFunctionTypeToken): 17 * css/CSSParserValues.cpp: 18 (WebCore::CSSParserSelector::parsePseudoClassHostFunctionSelector): 19 * css/CSSParserValues.h: 20 * css/ElementRuleCollector.cpp: 21 (WebCore::ElementRuleCollector::matchedRuleList): 22 (WebCore::ElementRuleCollector::addMatchedRule): 23 24 Factor some shared code here. 25 26 (WebCore::ElementRuleCollector::matchHostPseudoClassRules): 27 28 Instead of using the generic paths use a :host specific code path for matching. 29 This makes it easier to avoid :host matching when it shouldn't. 30 31 (WebCore::ElementRuleCollector::collectMatchingRulesForList): 32 * css/ElementRuleCollector.h: 33 * css/RuleSet.cpp: 34 (WebCore::computeMatchBasedOnRuleHash): 35 36 :host is always handled by the special matching path. 37 38 * css/SelectorChecker.cpp: 39 (WebCore::SelectorChecker::match): 40 (WebCore::SelectorChecker::matchHostPseudoClass): 41 42 Add a function specifically for checking :host. In always fails on the normal code paths. 43 Check the argument selector if provided. 44 45 (WebCore::hasScrollbarPseudoElement): 46 * css/SelectorChecker.h: 47 1 48 2016-04-07 Darin Adler <darin@apple.com> 2 49 -
trunk/Source/WebCore/css/CSSGrammar.y.in
r197165 r199268 369 369 370 370 %token <string> SLOTTEDFUNCTION 371 %token <string> HOSTFUNCTION 371 372 372 373 #endif … … 1367 1368 | ':' ':' SLOTTEDFUNCTION maybe_space compound_selector maybe_space ')' { 1368 1369 $$ = CSSParserSelector::parsePseudoElementSlottedFunctionSelector($3, $5); 1370 } 1371 | ':' HOSTFUNCTION maybe_space compound_selector maybe_space ')' { 1372 $$ = CSSParserSelector::parsePseudoClassHostFunctionSelector($2, $4); 1369 1373 } 1370 1374 #endif -
trunk/Source/WebCore/css/CSSParser.cpp
r199154 r199268 11898 11898 } 11899 11899 #endif 11900 #if ENABLE(SHADOW_DOM) 11901 if (isEqualToCSSIdentifier(name, "host")) { 11902 m_token = HOSTFUNCTION; 11903 return true; 11904 } 11905 #endif 11900 11906 return false; 11901 11907 -
trunk/Source/WebCore/css/CSSParserValues.cpp
r197165 r199268 256 256 return selector.release(); 257 257 } 258 259 CSSParserSelector* CSSParserSelector::parsePseudoClassHostFunctionSelector(const CSSParserString& functionIdentifier, CSSParserSelector* parsedSelector) 260 { 261 ASSERT_UNUSED(functionIdentifier, String(functionIdentifier) == "host("); 262 263 if (!parsedSelector) 264 return nullptr; 265 266 std::unique_ptr<CSSParserSelector> ownedParsedSelector(parsedSelector); 267 268 for (auto* component = parsedSelector; component; component = component->tagHistory()) { 269 if (component->matchesPseudoElement()) 270 return nullptr; 271 } 272 273 auto selectorVector = std::make_unique<Vector<std::unique_ptr<CSSParserSelector>>>(); 274 selectorVector->append(WTFMove(ownedParsedSelector)); 275 276 auto selector = std::make_unique<CSSParserSelector>(); 277 selector->m_selector->setMatch(CSSSelector::PseudoClass); 278 selector->m_selector->setPseudoClassType(CSSSelector::PseudoClassHost); 279 selector->adoptSelectorVector(*selectorVector); 280 return selector.release(); 281 } 258 282 #endif 259 283 -
trunk/Source/WebCore/css/CSSParserValues.h
r197165 r199268 207 207 #if ENABLE(SHADOW_DOM) 208 208 static CSSParserSelector* parsePseudoElementSlottedFunctionSelector(const CSSParserString& functionIdentifier, CSSParserSelector*); 209 static CSSParserSelector* parsePseudoClassHostFunctionSelector(const CSSParserString& functionIdentifier, CSSParserSelector*); 209 210 #endif 210 211 static CSSParserSelector* parsePseudoClassAndCompatibilityElementSelector(CSSParserString& pseudoTypeString); -
trunk/Source/WebCore/css/ElementRuleCollector.cpp
r197779 r199268 108 108 } 109 109 110 inline void ElementRuleCollector::addMatchedRule(const MatchedRule& matchedRule) 111 { 112 m_matchedRules.append(matchedRule); 110 inline void ElementRuleCollector::addMatchedRule(const RuleData& ruleData, unsigned specificity, StyleResolver::RuleRange& ruleRange) 111 { 112 // Update our first/last rule indices in the matched rules array. 113 ++ruleRange.lastRuleIndex; 114 if (ruleRange.firstRuleIndex == -1) 115 ruleRange.firstRuleIndex = ruleRange.lastRuleIndex; 116 117 m_matchedRules.append({ &ruleData, specificity }); 113 118 } 114 119 … … 233 238 m_result.ranges.lastAuthorRule = m_result.matchedProperties().size() - 1; 234 239 240 SelectorChecker::CheckingContext context(m_mode); 241 SelectorChecker selectorChecker(m_element.document()); 242 235 243 auto ruleRange = m_result.ranges.authorRuleRange(); 236 MatchRequest matchRequest(&shadowAuthorStyle, includeEmptyRules); 237 collectMatchingRulesForList(&shadowHostRules, matchRequest, ruleRange); 244 for (auto& ruleData : shadowHostRules) { 245 if (ruleData.rule()->properties().isEmpty() && !includeEmptyRules) 246 continue; 247 auto& selector = *ruleData.selector(); 248 unsigned specificity = 0; 249 if (!selectorChecker.matchHostPseudoClass(selector, m_element, context, specificity)) 250 continue; 251 addMatchedRule(ruleData, specificity, ruleRange); 252 } 238 253 239 254 // We just sort the host rules before other author rules. This matches the current vague spec language … … 487 502 488 503 unsigned specificity; 489 if (ruleMatches(ruleData, specificity)) { 490 // Update our first/last rule indices in the matched rules array. 491 ++ruleRange.lastRuleIndex; 492 if (ruleRange.firstRuleIndex == -1) 493 ruleRange.firstRuleIndex = ruleRange.lastRuleIndex; 494 495 // Add this rule to our list of matched rules. 496 addMatchedRule({&ruleData, specificity}); 497 } 504 if (ruleMatches(ruleData, specificity)) 505 addMatchedRule(ruleData, specificity, ruleRange); 498 506 } 499 507 } -
trunk/Source/WebCore/css/ElementRuleCollector.h
r197779 r199268 90 90 void sortAndTransferMatchedRules(); 91 91 92 void addMatchedRule(const MatchedRule&);92 void addMatchedRule(const RuleData&, unsigned specificity, StyleResolver::RuleRange&); 93 93 94 94 const Element& m_element; -
trunk/Source/WebCore/css/RuleSet.cpp
r197165 r199268 71 71 if (SelectorChecker::isCommonPseudoClassSelector(&selector)) 72 72 return MatchBasedOnRuleHash::ClassB; 73 #if ENABLE(SHADOW_DOM)74 if (selector.match() == CSSSelector::PseudoClass && selector.pseudoClassType() == CSSSelector::PseudoClassHost)75 return MatchBasedOnRuleHash::ClassB;76 #endif77 73 if (selector.match() == CSSSelector::Id) 78 74 return MatchBasedOnRuleHash::ClassA; -
trunk/Source/WebCore/css/SelectorChecker.cpp
r197952 r199268 196 196 // not cause a failure. 197 197 return checkingContext.resolvingMode == Mode::CollectingRulesIgnoringVirtualPseudoElements || result.matchType == MatchType::Element; 198 } 199 return true; 200 } 201 202 203 bool SelectorChecker::matchHostPseudoClass(const CSSSelector& selector, const Element& element, CheckingContext& checkingContext, unsigned& specificity) const 204 { 205 ASSERT(element.shadowRoot()); 206 ASSERT(selector.match() == CSSSelector::PseudoClass && selector.pseudoClassType() == CSSSelector::PseudoClassHost); 207 ASSERT(checkingContext.resolvingMode != SelectorChecker::Mode::QueryingRules); 208 // :host doesn't combine with any other selectors. 209 if (selector.tagHistory()) 210 return false; 211 specificity = selector.simpleSelectorSpecificity(); 212 if (auto* selectorList = selector.selectorList()) { 213 LocalContext context(selector, element, VisitedMatchType::Enabled, NOPSEUDO); 214 unsigned ignoredSpecificity; 215 if (!matchSelectorList(checkingContext, context, element, *selectorList, ignoredSpecificity)) 216 return false; 198 217 } 199 218 return true; -
trunk/Source/WebCore/css/SelectorChecker.h
r197764 r199268 96 96 bool match(const CSSSelector&, const Element&, CheckingContext&, unsigned& specificity) const; 97 97 98 bool matchHostPseudoClass(const CSSSelector&, const Element&, CheckingContext&, unsigned& specificity) const; 99 98 100 static bool isCommonPseudoClassSelector(const CSSSelector*); 99 101 static bool matchesFocusPseudoClass(const Element&);
Note: See TracChangeset
for help on using the changeset viewer.