Changeset 142855 in webkit
- Timestamp:
- Feb 13, 2013 11:51:43 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 22 added
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r142854 r142855 1 2013-02-13 Hayato Ito <hayato@chromium.org> 2 3 [Shadow DOM] Implements a '::distributed()' pseudo element. 4 https://bugs.webkit.org/show_bug.cgi?id=82169 5 6 Reviewed by Dimitri Glazkov. 7 8 * fast/dom/shadow/distributed-pseudo-element-expected.html: Added. 9 * fast/dom/shadow/distributed-pseudo-element-for-shadow-element-expected.html: Added. 10 * fast/dom/shadow/distributed-pseudo-element-for-shadow-element.html: Added. 11 * fast/dom/shadow/distributed-pseudo-element-match-all-expected.html: Added. 12 * fast/dom/shadow/distributed-pseudo-element-match-all.html: Added. 13 * fast/dom/shadow/distributed-pseudo-element-match-descendant-expected.html: Added. 14 * fast/dom/shadow/distributed-pseudo-element-match-descendant.html: Added. 15 * fast/dom/shadow/distributed-pseudo-element-nested-expected.html: Added. 16 * fast/dom/shadow/distributed-pseudo-element-nested.html: Added. 17 * fast/dom/shadow/distributed-pseudo-element-no-match-expected.html: Added. 18 * fast/dom/shadow/distributed-pseudo-element-no-match.html: Added. 19 * fast/dom/shadow/distributed-pseudo-element-reprojection-expected.html: Added. 20 * fast/dom/shadow/distributed-pseudo-element-reprojection.html: Added. 21 * fast/dom/shadow/distributed-pseudo-element-scoped-expected.html: Added. 22 * fast/dom/shadow/distributed-pseudo-element-scoped.html: Added. 23 * fast/dom/shadow/distributed-pseudo-element-support-selector-expected.html: Added. 24 * fast/dom/shadow/distributed-pseudo-element-support-selector.html: Added. 25 * fast/dom/shadow/distributed-pseudo-element-used-in-selector-list-expected.html: Added. 26 * fast/dom/shadow/distributed-pseudo-element-used-in-selector-list.html: Added. 27 * fast/dom/shadow/distributed-pseudo-element-with-any-expected.html: Added. 28 * fast/dom/shadow/distributed-pseudo-element-with-any.html: Added. 29 * fast/dom/shadow/distributed-pseudo-element.html: Added. 30 1 31 2013-02-06 Gregg Tavares <gman@chromium.org> 2 32 -
trunk/Source/WebCore/ChangeLog
r142849 r142855 1 2013-02-13 Hayato Ito <hayato@chromium.org> 2 3 [Shadow DOM] Implements a '::distributed()' pseudo element. 4 https://bugs.webkit.org/show_bug.cgi?id=82169 5 6 Reviewed by Dimitri Glazkov. 7 8 Implements a '::distributed()' pseudo element. 9 See the Shadow DOM specification and the filed bug for the detail. 10 11 - http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#selecting-nodes-distributed-to-insertion-points 12 - https://www.w3.org/Bugs/Public/show_bug.cgi?id=19684 13 14 For example, suppose we are given the following DOM tree and shadow tree: 15 16 - <A> 17 - <B> 18 - <C> 19 20 [A's ShadowRoot] 21 <D> 22 - <style> 23 E content::distributed(B C) { color: green; } 24 - <E> 25 - <content> (Node B is distributed to this insertion point.) 26 27 In this case, the style rule defined in the shadow tree matches node 'C'. 28 29 A '::distributed()' pseudo element can not be a pseudo class since 30 an intersection between matched_elements(some_selector) and 31 matched_elements(some_selector::distributed(...)) is always an 32 empty set. A '::distributed()' pseudo element is the first-ever 33 *functional* pseudo element which takes a parameter, which can be 34 a selector. 35 36 This rule crosses the shadow boundary from a shadow tree to the 37 tree of its shadow host. That means a rule which includes 38 '::distributed()' pseudo element is defined in shadow tree, but 39 the node which is matched in the rule, the subject of the 40 selector, is outside of the shadow tree. Therefore, we cannot 41 predict where the subject of the selector will be beforehand. 42 Current CSS implementation assumes the subject of the selector 43 must exist in the current scope. 44 45 To overcome this issue, DocumentRuleSets now has a instance of 46 ShadowDistributedRules class. A style rule will be stored in this 47 instance if the rule includes a '::distributed()' pseudo element. 48 This class also keeps track of each RuleSet by mapping it with a 49 scope where the rule was originally defined. In the example, the 50 scope is A's ShadowRoot. The scope is used to check whether the 51 left-most matched element (in the example, it's a node 'E') exists 52 in the scope. 53 54 Internally, a '::distributed' pseudo element is represented by a 55 newly introduced 'ShadowDistributed' relation. That makes an 56 implementation of SelectorChecker::checkSelector() much simpler. 57 A transformation from a distributed pseudo element to a 58 ShadowDistributed is done in parsing stage of CSS. 59 60 Since '::distributed()' is an experimental feature, it's actually 61 prefixed with '-webkit-' and guarded by SHADOW_DOM flag. 62 63 Tests: fast/dom/shadow/distributed-pseudo-element-for-shadow-element.html 64 fast/dom/shadow/distributed-pseudo-element-match-all.html 65 fast/dom/shadow/distributed-pseudo-element-match-descendant.html 66 fast/dom/shadow/distributed-pseudo-element-nested.html 67 fast/dom/shadow/distributed-pseudo-element-no-match.html 68 fast/dom/shadow/distributed-pseudo-element-reprojection.html 69 fast/dom/shadow/distributed-pseudo-element-scoped.html 70 fast/dom/shadow/distributed-pseudo-element-support-selector.html 71 fast/dom/shadow/distributed-pseudo-element-used-in-selector-list.html 72 fast/dom/shadow/distributed-pseudo-element-with-any.html 73 fast/dom/shadow/distributed-pseudo-element.html 74 75 * css/CSSGrammar.y.in: 76 CSS Grammar was updated to support '::distrbuted(selector)'. 77 This pseudo element is the first pseudo element which can take a selector as a parameter. 78 * css/CSSParser.cpp: 79 (WebCore::CSSParser::detectDashToken): 80 (WebCore::CSSParser::rewriteSpecifiersWithNamespaceIfNeeded): 81 (WebCore::CSSParser::rewriteSpecifiersWithElementName): 82 Here we are converting a '::distributed' pseudo element into a 83 ShadowDistributed relation internally. To support the conversion, 84 these rewriteSpecifiersXXX functions (formally called 85 updateSpecifiersXXX) now return the specifiers which may be 86 converted. 87 (WebCore::CSSParser::rewriteSpecifiers): 88 * css/CSSParser.h: 89 * css/CSSParserValues.cpp: 90 (WebCore::CSSParserSelector::CSSParserSelector): 91 * css/CSSParserValues.h: 92 (CSSParserSelector): 93 (WebCore::CSSParserSelector::functionArgumentSelector): 94 To hold an intermediate selector which appears at the position of an argument in 95 functional pseudo element when parsing CSS. 96 (WebCore::CSSParserSelector::setFunctionArgumentSelector): 97 (WebCore::CSSParserSelector::isDistributedPseudoElement): 98 * css/CSSSelector.cpp: 99 Add new pseudo element, PseudoDistributed, and its internal representation, ShadowDistributed relation. 100 (WebCore::CSSSelector::pseudoId): 101 (WebCore::nameToPseudoTypeMap): 102 (WebCore::CSSSelector::extractPseudoType): 103 (WebCore::CSSSelector::selectorText): 104 * css/CSSSelector.h: 105 (CSSSelector): 106 (WebCore): 107 (WebCore::CSSSelector::isDistributedPseudoElement): 108 (WebCore::CSSSelector::isShadowDistributed): 109 * css/CSSSelectorList.cpp: 110 (WebCore): 111 (SelectorHasShadowDistributed): 112 (WebCore::SelectorHasShadowDistributed::operator()): 113 (WebCore::CSSSelectorList::hasShadowDistributedAt): 114 * css/CSSSelectorList.h: 115 (CSSSelectorList): 116 * css/DocumentRuleSets.cpp: 117 (WebCore): 118 (WebCore::ShadowDistributedRules::addRule): 119 Every CSS rule which includes '::distributed(...)' should be managed by calling this function. 120 (WebCore::ShadowDistributedRules::collectMatchRequests): 121 (WebCore::DocumentRuleSets::resetAuthorStyle): 122 * css/DocumentRuleSets.h: 123 (WebCore): 124 (ShadowDistributedRules): 125 (WebCore::ShadowDistributedRules::clear): 126 (DocumentRuleSets): 127 (WebCore::DocumentRuleSets::shadowDistributedRules) 128 DocumentRuleSets owns an instance of ShadowDistributedRules. 129 * css/RuleSet.cpp: 130 (WebCore::RuleSet::addChildRules): 131 Updated to check whether the rule contains '::distributed()' or not. 132 * css/SelectorChecker.cpp: 133 (WebCore::SelectorChecker::match): 134 Support ShadowDistributed relation. Check all possible insertion points where a node is distributed. 135 * css/SelectorChecker.h: 136 (WebCore::SelectorChecker::SelectorCheckingContext::SelectorCheckingContext): 137 Adds enum of BehaviorAtBoundary. '::distributed()' is the only 138 rule which uses 'CrossedBoundary' since it is the only rule which 139 crosses shadow boundaries. 140 (SelectorCheckingContext): 141 * css/SelectorFilter.cpp: 142 (WebCore::SelectorFilter::collectIdentifierHashes): 143 * css/StyleResolver.cpp: 144 (WebCore::StyleResolver::collectMatchingRules): 145 (WebCore::StyleResolver::matchAuthorRules): 146 (WebCore::StyleResolver::collectMatchingRulesForList): 147 (WebCore::StyleResolver::ruleMatches): 148 * css/StyleResolver.h: 149 (MatchRequest): 150 (WebCore::MatchRequest::MatchRequest): Add behaviorAtBoundary field. 151 (WebCore): 152 (StyleResolver): 153 * html/shadow/InsertionPoint.cpp: 154 (WebCore::collectInsertionPointsWhereNodeIsDistributed): 155 (WebCore): 156 * html/shadow/InsertionPoint.h: 157 (WebCore): 158 1 159 2013-02-13 Kentaro Hara <haraken@chromium.org> 2 160 -
trunk/Source/WebCore/css/CSSGrammar.y.in
r142739 r142855 62 62 %} 63 63 64 #if ENABLE_SHADOW_DOM 65 %expect 67 66 #else 64 67 %expect 66 68 #endif 65 69 66 70 %nonassoc LOWEST_PREC … … 185 189 #endif 186 190 %token <string> NOTFUNCTION 191 %token <string> DISTRIBUTEDFUNCTION 187 192 %token <string> CALCFUNCTION 188 193 %token <string> MINFUNCTION … … 1204 1209 $$ = $2; 1205 1210 if ($$) 1206 parser->updateSpecifiersWithElementName(nullAtom, $1, $$);1211 $$ = parser->rewriteSpecifiersWithElementName(nullAtom, $1, $$); 1207 1212 } 1208 1213 | specifier_list { 1209 1214 $$ = $1; 1210 1215 if ($$) 1211 parser->updateSpecifiersWithNamespaceIfNeeded($$);1216 $$ = parser->rewriteSpecifiersWithNamespaceIfNeeded($$); 1212 1217 } 1213 1218 | namespace_selector element_name { … … 1217 1222 $$ = $3; 1218 1223 if ($$) 1219 parser->updateSpecifiersWithElementName($1, $2, $$);1224 $$ = parser->rewriteSpecifiersWithElementName($1, $2, $$); 1220 1225 } 1221 1226 | namespace_selector specifier_list { 1222 1227 $$ = $2; 1223 1228 if ($$) 1224 parser->updateSpecifiersWithElementName($1, starAtom, $$);1229 $$ = parser->rewriteSpecifiersWithElementName($1, starAtom, $$); 1225 1230 } 1226 1231 ; … … 1267 1272 $$ = 0; 1268 1273 else if ($1) 1269 $$ = parser-> updateSpecifiers($1, $2);1274 $$ = parser->rewriteSpecifiers($1, $2); 1270 1275 } 1271 1276 | specifier_list error { … … 1412 1417 } else 1413 1418 $$ = 0; 1419 } 1420 #endif 1421 #if ENABLE_SHADOW_DOM 1422 | ':' ':' DISTRIBUTEDFUNCTION maybe_space selector maybe_space ')' { 1423 if (!$5) 1424 $$ = 0; 1425 else { 1426 $$ = parser->createFloatingSelector(); 1427 $$->setMatch(CSSSelector::PseudoElement); 1428 $$->setFunctionArgumentSelector($5); 1429 $3.lower(); 1430 $$->setValue($3); 1431 } 1414 1432 } 1415 1433 #endif -
trunk/Source/WebCore/css/CSSParser.cpp
r142739 r142855 10044 10044 } else if (length == 12 && isEqualToCSSIdentifier(name + 1, "webkit-calc")) 10045 10045 m_token = CALCFUNCTION; 10046 #if ENABLE(SHADOW_DOM) 10047 else if (length == 19 && isEqualToCSSIdentifier(name + 1, "webkit-distributed")) 10048 m_token = DISTRIBUTEDFUNCTION; 10049 #endif 10046 10050 } 10047 10051 … … 11075 11079 } 11076 11080 11077 void CSSParser::updateSpecifiersWithNamespaceIfNeeded(CSSParserSelector* specifiers)11081 CSSParserSelector* CSSParser::rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector* specifiers) 11078 11082 { 11079 11083 if (m_defaultNamespace != starAtom || specifiers->isCustomPseudoElement()) 11080 updateSpecifiersWithElementName(nullAtom, starAtom, specifiers, /*tagIsForNamespaceRule*/true); 11081 } 11082 11083 void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule) 11084 return rewriteSpecifiersWithElementName(nullAtom, starAtom, specifiers, /*tagIsForNamespaceRule*/true); 11085 return specifiers; 11086 } 11087 11088 CSSParserSelector* CSSParser::rewriteSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule) 11084 11089 { 11085 11090 AtomicString determinedNamespace = namespacePrefix != nullAtom && m_styleSheet ? m_styleSheet->determineNamespace(namespacePrefix) : m_defaultNamespace; 11086 11091 QualifiedName tag(namespacePrefix, elementName, determinedNamespace); 11087 11092 11093 #if ENABLE(SHADOW_DOM) 11094 if (specifiers->isDistributedPseudoElement()) { 11095 CSSParserSelector* argumentSelector = specifiers->functionArgumentSelector(); 11096 ASSERT(argumentSelector); 11097 CSSParserSelector* end = argumentSelector; 11098 while (end->tagHistory()) 11099 end = end->tagHistory(); 11100 OwnPtr<CSSParserSelector> elementNameSelector = adoptPtr(new CSSParserSelector(tag)); 11101 end->setTagHistory(elementNameSelector.release()); 11102 end->setRelation(CSSSelector::ShadowDistributed); 11103 return argumentSelector; 11104 } 11105 #endif 11106 11088 11107 if (!specifiers->isCustomPseudoElement()) { 11089 11108 if (tag == anyQName()) 11090 return ;11109 return specifiers; 11091 11110 #if ENABLE(VIDEO_TRACK) 11092 11111 if (!(specifiers->pseudoType() == CSSSelector::PseudoCue)) 11093 11112 #endif 11094 11113 specifiers->prependTagSelector(tag, tagIsForNamespaceRule); 11095 return ;11114 return specifiers; 11096 11115 } 11097 11116 … … 11107 11126 if (tag != anyQName()) 11108 11127 lastShadowDescendant->tagHistory()->prependTagSelector(tag, tagIsForNamespaceRule); 11109 return ;11128 return specifiers; 11110 11129 } 11111 11130 … … 11115 11134 lastShadowDescendant->setTagHistory(elementNameSelector.release()); 11116 11135 lastShadowDescendant->setRelation(CSSSelector::ShadowDescendant); 11117 } 11118 11119 CSSParserSelector* CSSParser::updateSpecifiers(CSSParserSelector* specifiers, CSSParserSelector* newSpecifier) 11136 return specifiers; 11137 } 11138 11139 CSSParserSelector* CSSParser::rewriteSpecifiers(CSSParserSelector* specifiers, CSSParserSelector* newSpecifier) 11120 11140 { 11121 11141 #if ENABLE(VIDEO_TRACK) -
trunk/Source/WebCore/css/CSSParser.h
r142739 r142855 329 329 void addNamespace(const AtomicString& prefix, const AtomicString& uri); 330 330 QualifiedName determineNameInNamespace(const AtomicString& prefix, const AtomicString& localName); 331 void updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector*, bool isNamespacePlaceholder = false); 332 void updateSpecifiersWithNamespaceIfNeeded(CSSParserSelector*); 333 CSSParserSelector* updateSpecifiers(CSSParserSelector*, CSSParserSelector*); 331 332 CSSParserSelector* rewriteSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector*, bool isNamespacePlaceholder = false); 333 CSSParserSelector* rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector*); 334 CSSParserSelector* rewriteSpecifiers(CSSParserSelector*, CSSParserSelector*); 334 335 335 336 void invalidBlockHit(); -
trunk/Source/WebCore/css/CSSParserValues.cpp
r142021 r142855 148 148 CSSParserSelector::CSSParserSelector() 149 149 : m_selector(adoptPtr(fastNew<CSSSelector>())) 150 #if ENABLE(SHADOW_DOM) 151 , m_functionArgumentSelector(0) 152 #endif 150 153 { 151 154 } -
trunk/Source/WebCore/css/CSSParserValues.h
r141816 r142855 187 187 void adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectorVector); 188 188 189 #if ENABLE(SHADOW_DOM) 190 CSSParserSelector* functionArgumentSelector() const { return m_functionArgumentSelector; } 191 void setFunctionArgumentSelector(CSSParserSelector* selector) { m_functionArgumentSelector = selector; } 192 bool isDistributedPseudoElement() const { return m_selector->isDistributedPseudoElement(); } 193 #endif 194 189 195 CSSSelector::PseudoType pseudoType() const { return m_selector->pseudoType(); } 190 196 bool isCustomPseudoElement() const { return m_selector->isCustomPseudoElement(); } … … 202 208 OwnPtr<CSSSelector> m_selector; 203 209 OwnPtr<CSSParserSelector> m_tagHistory; 210 #if ENABLE(SHADOW_DOM) 211 CSSParserSelector* m_functionArgumentSelector; 212 #endif 204 213 }; 205 214 -
trunk/Source/WebCore/css/CSSSelector.cpp
r140707 r142855 243 243 #if ENABLE(IFRAME_SEAMLESS) 244 244 case PseudoSeamlessDocument: 245 #endif 246 #if ENABLE(SHADOW_DOM) 247 case PseudoDistributed: 245 248 #endif 246 249 return NOPSEUDO; … … 333 336 #if ENABLE(IFRAME_SEAMLESS) 334 337 DEFINE_STATIC_LOCAL(AtomicString, seamlessDocument, ("-webkit-seamless-document", AtomicString::ConstructFromLiteral)); 338 #endif 339 #if ENABLE(SHADOW_DOM) 340 DEFINE_STATIC_LOCAL(AtomicString, distributed, ("-webkit-distributed(", AtomicString::ConstructFromLiteral)); 335 341 #endif 336 342 DEFINE_STATIC_LOCAL(AtomicString, inRange, ("in-range", AtomicString::ConstructFromLiteral)); … … 417 423 nameToPseudoType->set(seamlessDocument.impl(), CSSSelector::PseudoSeamlessDocument); 418 424 #endif 425 #if ENABLE(SHADOW_DOM) 426 nameToPseudoType->set(distributed.impl(), CSSSelector::PseudoDistributed); 427 #endif 419 428 nameToPseudoType->set(inRange.impl(), CSSSelector::PseudoInRange); 420 429 nameToPseudoType->set(outOfRange.impl(), CSSSelector::PseudoOutOfRange); … … 467 476 case PseudoFirstLine: 468 477 compat = true; 478 #if ENABLE(SHADOW_DOM) 479 case PseudoDistributed: 480 #endif 469 481 case PseudoResizer: 470 482 case PseudoScrollbar: … … 708 720 case CSSSelector::ShadowDescendant: 709 721 return tagHistoryText + str.toString(); 722 #if ENABLE(SHADOW_DOM) 723 case CSSSelector::ShadowDistributed: 724 return tagHistoryText + "::-webkit-distributed(" + str.toString() + ")"; 725 #endif 710 726 } 711 727 } -
trunk/Source/WebCore/css/CSSSelector.h
r140707 r142855 78 78 IndirectAdjacent, 79 79 SubSelector, 80 ShadowDescendant 80 ShadowDescendant, 81 #if ENABLE(SHADOW_DOM) 82 ShadowDistributed 83 #endif 81 84 }; 82 85 … … 164 167 #endif 165 168 #if ENABLE(IFRAME_SEAMLESS) 166 PseudoSeamlessDocument 169 PseudoSeamlessDocument, 170 #endif 171 #if ENABLE(SHADOW_DOM) 172 PseudoDistributed 167 173 #endif 168 174 }; … … 221 227 bool isSiblingSelector() const; 222 228 bool isAttributeSelector() const; 229 #if ENABLE(SHADOW_DOM) 230 bool isDistributedPseudoElement() const; 231 bool isShadowDistributed() const; 232 #endif 223 233 224 234 Relation relation() const { return static_cast<Relation>(m_relation); } … … 333 343 } 334 344 345 #if ENABLE(SHADOW_DOM) 346 inline bool CSSSelector::isDistributedPseudoElement() const 347 { 348 return m_match == PseudoElement && pseudoType() == PseudoDistributed; 349 } 350 351 inline bool CSSSelector::isShadowDistributed() const 352 { 353 return m_relation == CSSSelector::ShadowDistributed; 354 } 355 #endif 356 335 357 inline void CSSSelector::setValue(const AtomicString& value) 336 358 { -
trunk/Source/WebCore/css/CSSSelectorList.cpp
r141570 r142855 212 212 } 213 213 214 214 #if ENABLE(SHADOW_DOM) 215 class SelectorHasShadowDistributed { 216 public: 217 bool operator()(const CSSSelector* selector) 218 { 219 return selector->isShadowDistributed(); 220 } 221 }; 222 223 bool CSSSelectorList::hasShadowDistributedAt(size_t index) const 224 { 225 SelectorHasShadowDistributed functor; 226 return forEachTagSelector(functor, selectorAt(index)); 227 } 228 #endif 215 229 216 230 } // namespace WebCore -
trunk/Source/WebCore/css/CSSSelectorList.h
r140677 r142855 62 62 bool hasInvalidSelector() const; 63 63 64 #if ENABLE(SHADOW_DOM) 65 bool hasShadowDistributedAt(size_t index) const; 66 #endif 67 64 68 String selectorsText() const; 65 69 -
trunk/Source/WebCore/css/DocumentRuleSets.cpp
r142573 r142855 38 38 39 39 namespace WebCore { 40 41 #if ENABLE(SHADOW_DOM) 42 void ShadowDistributedRules::addRule(StyleRule* rule, size_t selectorIndex, ContainerNode* scope, AddRuleFlags addRuleFlags) 43 { 44 if (m_shadowDistributedRuleSetMap.contains(scope)) 45 m_shadowDistributedRuleSetMap.get(scope)->addRule(rule, selectorIndex, addRuleFlags); 46 else { 47 OwnPtr<RuleSet> ruleSetForScope = adoptPtr(new RuleSet()); 48 ruleSetForScope->addRule(rule, selectorIndex, addRuleFlags); 49 m_shadowDistributedRuleSetMap.add(scope, ruleSetForScope.release()); 50 } 51 } 52 53 void ShadowDistributedRules::collectMatchRequests(bool includeEmptyRules, Vector<MatchRequest>& matchRequests) 54 { 55 for (ShadowDistributedRuleSetMap::iterator it = m_shadowDistributedRuleSetMap.begin(); it != m_shadowDistributedRuleSetMap.end(); ++it) 56 matchRequests.append(MatchRequest(it->value.get(), includeEmptyRules, it->key, SelectorChecker::CrossesBoundary)); 57 } 58 #endif 40 59 41 60 DocumentRuleSets::DocumentRuleSets() … … 82 101 m_authorStyle = RuleSet::create(); 83 102 m_authorStyle->disableAutoShrinkToFit(); 103 #if ENABLE(SHADOW_DOM) 104 m_shadowDistributedRules.clear(); 105 #endif 84 106 } 85 107 -
trunk/Source/WebCore/css/DocumentRuleSets.h
r142573 r142855 25 25 26 26 #include "RuleFeature.h" 27 #include "RuleSet.h" 27 28 28 29 #include <wtf/OwnPtr.h> … … 36 37 class DocumentStyleSheetCollection; 37 38 class InspectorCSSOMWrappers; 39 class MatchRequest; 38 40 class MediaQueryEvaluator; 39 41 class RuleSet; 40 class StyleResolver;41 42 class StyleScopeResolver; 43 44 #if ENABLE(SHADOW_DOM) 45 class ShadowDistributedRules { 46 public: 47 void addRule(StyleRule*, size_t selectorIndex, ContainerNode* scope, AddRuleFlags); 48 void collectMatchRequests(bool includeEmptyRules, Vector<MatchRequest>&); 49 void clear() { m_shadowDistributedRuleSetMap.clear(); } 50 private: 51 typedef HashMap<const ContainerNode*, OwnPtr<RuleSet> > ShadowDistributedRuleSetMap; 52 ShadowDistributedRuleSetMap m_shadowDistributedRuleSetMap; 53 }; 54 #endif 42 55 43 56 class DocumentRuleSets { … … 58 71 void collectFeatures(bool isViewSource, StyleScopeResolver*); 59 72 void reportMemoryUsage(MemoryObjectInfo*) const; 73 #if ENABLE(SHADOW_DOM) 74 ShadowDistributedRules& shadowDistributedRules() { return m_shadowDistributedRules; } 75 #endif 60 76 61 77 private: … … 66 82 OwnPtr<RuleSet> m_siblingRuleSet; 67 83 OwnPtr<RuleSet> m_uncommonAttributeRuleSet; 84 #if ENABLE(SHADOW_DOM) 85 ShadowDistributedRules m_shadowDistributedRules; 86 #endif 68 87 }; 69 88 -
trunk/Source/WebCore/css/RuleSet.cpp
r141806 r142855 308 308 StyleRuleBase* rule = rules[i].get(); 309 309 310 if (rule->isStyleRule()) 311 addStyleRule(static_cast<StyleRule*>(rule), addRuleFlags); 312 else if (rule->isPageRule()) 310 if (rule->isStyleRule()) { 311 StyleRule* styleRule = static_cast<StyleRule*>(rule); 312 #if ENABLE(SHADOW_DOM) 313 if (!scope) 314 addStyleRule(styleRule, addRuleFlags); 315 else { 316 const CSSSelectorList& selectorList = styleRule->selectorList(); 317 for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = selectorList.indexOfNextSelectorAfter(selectorIndex)) { 318 if (selectorList.hasShadowDistributedAt(selectorIndex)) 319 resolver->ruleSets().shadowDistributedRules().addRule(styleRule, selectorIndex, const_cast<ContainerNode*>(scope), addRuleFlags); 320 else 321 addRule(styleRule, selectorIndex, addRuleFlags); 322 } 323 } 324 #else 325 addStyleRule(styleRule, addRuleFlags); 326 #endif 327 328 } else if (rule->isPageRule()) 313 329 addPageRule(static_cast<StyleRulePage*>(rule)); 314 330 else if (rule->isMediaRule()) { -
trunk/Source/WebCore/css/SelectorChecker.cpp
r142717 r142855 42 42 #include "HTMLProgressElement.h" 43 43 #include "HTMLStyleElement.h" 44 #include "InsertionPoint.h" 44 45 #include "InspectorInstrumentation.h" 45 46 #include "NodeRenderStyle.h" … … 282 283 // Prepare next selector 283 284 const CSSSelector* historySelector = context.selector->tagHistory(); 284 if (!historySelector) 285 if (!historySelector) { 286 if (context.behaviorAtBoundary == CrossesBoundary) { 287 ASSERT(context.scope); 288 return context.scope->contains(context.element) ? SelectorMatches : SelectorFailsLocally; 289 } 285 290 return SelectorMatches; 291 } 286 292 287 293 SelectorCheckingContext nextContext(context); … … 380 386 return match(nextContext, ignoreDynamicPseudo, siblingTraversalStrategy); 381 387 } 388 #if ENABLE(SHADOW_DOM) 389 case CSSSelector::ShadowDistributed: 390 { 391 Vector<InsertionPoint*, 8> insertionPoints; 392 for (Element* element = context.element; element; element = element->parentElement()) { 393 insertionPoints.clear(); 394 collectInsertionPointsWhereNodeIsDistributed(element, insertionPoints); 395 for (size_t i = 0; i < insertionPoints.size(); ++i) { 396 nextContext.element = insertionPoints[i]; 397 nextContext.isSubSelector = false; 398 nextContext.elementStyle = 0; 399 if (match(nextContext, ignoreDynamicPseudo, siblingTraversalStrategy) == SelectorMatches) 400 return SelectorMatches; 401 } 402 } 403 return SelectorFailsCompletely; 404 } 405 #endif 382 406 } 383 407 -
trunk/Source/WebCore/css/SelectorChecker.h
r142717 r142855 49 49 enum Mode { ResolvingStyle = 0, CollectingRules, QueryingRules, SharingRules }; 50 50 explicit SelectorChecker(Document*, Mode); 51 enum BehaviorAtBoundary { DoesNotCrossBoundary, CrossesBoundary }; 51 52 52 53 struct SelectorCheckingContext { … … 62 63 , hasScrollbarPseudo(false) 63 64 , hasSelectionPseudo(false) 65 , behaviorAtBoundary(DoesNotCrossBoundary) 64 66 { } 65 67 … … 73 75 bool hasScrollbarPseudo; 74 76 bool hasSelectionPseudo; 77 BehaviorAtBoundary behaviorAtBoundary; 75 78 }; 76 79 -
trunk/Source/WebCore/css/SelectorFilter.cpp
r141524 r142855 148 148 case CSSSelector::IndirectAdjacent: 149 149 case CSSSelector::ShadowDescendant: 150 #if ENABLE(SHADOW_DOM) 151 case CSSSelector::ShadowDistributed: 152 #endif 150 153 skipOverSubselectors = true; 151 154 break; -
trunk/Source/WebCore/css/StyleResolver.cpp
r142791 r142855 479 479 if (!MatchingUARulesScope::isMatchingUARules() 480 480 && !treeScope->applyAuthorStyles() 481 && (!matchRequest.scope || matchRequest.scope->treeScope() != treeScope)) 481 && (!matchRequest.scope || matchRequest.scope->treeScope() != treeScope) 482 && matchRequest.behaviorAtBoundary == SelectorChecker::DoesNotCrossBoundary) 482 483 return; 483 484 … … 624 625 collectMatchingRules(matchRequest, ruleRange); 625 626 collectMatchingRulesForRegion(matchRequest, ruleRange); 627 #if ENABLE(SHADOW_DOM) 628 Vector<MatchRequest> matchRequests; 629 m_ruleSets.shadowDistributedRules().collectMatchRequests(includeEmptyRules, matchRequests); 630 for (size_t i = 0; i < matchRequests.size(); ++i) 631 collectMatchingRules(matchRequests[i], ruleRange); 632 #endif 633 626 634 sortAndTransferMatchedRules(result); 627 635 … … 664 672 // In some cases we may end up looking up style for random elements in the middle of a recursive tree resolve. 665 673 // Ancestor identifier filter won't be up-to-date in that case and we can't use the fast path. 666 bool canUseFastReject = m_selectorFilter.parentStackIsConsistent(state.parentNode()) ;674 bool canUseFastReject = m_selectorFilter.parentStackIsConsistent(state.parentNode()) && matchRequest.behaviorAtBoundary == SelectorChecker::DoesNotCrossBoundary; 667 675 668 676 unsigned size = rules->size(); … … 675 683 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willMatchRule(document(), rule, this); 676 684 PseudoId dynamicPseudo = NOPSEUDO; 677 if (ruleMatches(ruleData, matchRequest.scope, dynamicPseudo )) {685 if (ruleMatches(ruleData, matchRequest.scope, dynamicPseudo, matchRequest.behaviorAtBoundary)) { 678 686 // If the rule has no properties to apply, then ignore it in the non-debug mode. 679 687 const StylePropertySet* properties = rule->properties(); … … 2076 2084 } 2077 2085 2078 inline bool StyleResolver::ruleMatches(const RuleData& ruleData, const ContainerNode* scope, PseudoId& dynamicPseudo )2086 inline bool StyleResolver::ruleMatches(const RuleData& ruleData, const ContainerNode* scope, PseudoId& dynamicPseudo, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary) 2079 2087 { 2080 2088 State& state = m_state; … … 2104 2112 context.scope = scope; 2105 2113 context.pseudoStyle = state.pseudoStyle(); 2114 context.behaviorAtBoundary = behaviorAtBoundary; 2106 2115 SelectorChecker::Match match = selectorChecker.match(context, dynamicPseudo, DOMSiblingTraversalStrategy()); 2107 2116 if (match != SelectorChecker::SelectorMatches) -
trunk/Source/WebCore/css/StyleResolver.h
r142757 r142855 137 137 }; 138 138 139 class MatchRequest { 140 public: 141 MatchRequest(RuleSet* ruleSet, bool includeEmptyRules = false, const ContainerNode* scope = 0, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary = SelectorChecker::DoesNotCrossBoundary) 142 : ruleSet(ruleSet) 143 , includeEmptyRules(includeEmptyRules) 144 , scope(scope) 145 , behaviorAtBoundary(behaviorAtBoundary) { } 146 const RuleSet* ruleSet; 147 const bool includeEmptyRules; 148 const ContainerNode* scope; 149 const SelectorChecker::BehaviorAtBoundary behaviorAtBoundary; 150 }; 151 139 152 // This class selects a RenderStyle for a given element based on a collection of stylesheets. 140 153 class StyleResolver { … … 348 361 }; 349 362 350 struct MatchRequest {351 MatchRequest(RuleSet* ruleSet, bool includeEmptyRules = false, const ContainerNode* scope = 0)352 : ruleSet(ruleSet)353 , includeEmptyRules(includeEmptyRules)354 , scope(scope) { }355 const RuleSet* ruleSet;356 const bool includeEmptyRules;357 const ContainerNode* scope;358 };359 360 363 static void addMatchedProperties(MatchResult&, const StylePropertySet* properties, StyleRule* = 0, unsigned linkMatchType = SelectorChecker::MatchAll, PropertyWhitelistType = PropertyWhitelistNone); 361 364 void addElementStyleProperties(MatchResult&, const StylePropertySet*, bool isCacheable = true); … … 377 380 void sortAndTransferMatchedRules(MatchResult&); 378 381 379 bool ruleMatches(const RuleData&, const ContainerNode* scope, PseudoId& );382 bool ruleMatches(const RuleData&, const ContainerNode* scope, PseudoId&, SelectorChecker::BehaviorAtBoundary = SelectorChecker::DoesNotCrossBoundary); 380 383 bool checkRegionSelector(const CSSSelector* regionSelector, Element* regionElement); 381 384 void applyMatchedProperties(const MatchResult&, const Element*); -
trunk/Source/WebCore/html/shadow/InsertionPoint.cpp
r140299 r142855 230 230 } 231 231 232 void collectInsertionPointsWhereNodeIsDistributed(const Node* node, Vector<InsertionPoint*, 8>& results) 233 { 234 const Node* current = node; 235 while (true) { 236 if (ElementShadow* shadow = shadowOfParentForDistribution(current)) { 237 if (ShadowRoot* root = current->containingShadowRoot()) 238 ContentDistributor::ensureDistribution(root); 239 if (InsertionPoint* insertedTo = shadow->distributor().findInsertionPointFor(node)) { 240 current = insertedTo; 241 results.append(insertedTo); 242 continue; 243 } 244 } 245 if (Node* parent = parentNodeForDistribution(current)) { 246 if (InsertionPoint* insertedTo = parent->isShadowRoot() ? ScopeContentDistribution::assignedTo(toShadowRoot(parent)) : 0) { 247 current = insertedTo; 248 results.append(insertedTo); 249 continue; 250 } 251 } 252 return; 253 } 254 } 255 232 256 } // namespace WebCore -
trunk/Source/WebCore/html/shadow/InsertionPoint.h
r141516 r142855 162 162 InsertionPoint* resolveReprojection(const Node*); 163 163 164 void collectInsertionPointsWhereNodeIsDistributed(const Node*, Vector<InsertionPoint*, 8>& results); 165 164 166 } // namespace WebCore 165 167
Note: See TracChangeset
for help on using the changeset viewer.