Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1069)

Side by Side Diff: Source/core/css/resolver/StyleResolver.cpp

Issue 1134173002: Get rid of TreeBoundaryCrossingRules. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Missing resolver decrement and adjusted test. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 } 117 }
118 118
119 static StylePropertySet* rightToLeftDeclaration() 119 static StylePropertySet* rightToLeftDeclaration()
120 { 120 {
121 DEFINE_STATIC_REF_WILL_BE_PERSISTENT(MutableStylePropertySet, rightToLeftDec l, (MutableStylePropertySet::create())); 121 DEFINE_STATIC_REF_WILL_BE_PERSISTENT(MutableStylePropertySet, rightToLeftDec l, (MutableStylePropertySet::create()));
122 if (rightToLeftDecl->isEmpty()) 122 if (rightToLeftDecl->isEmpty())
123 rightToLeftDecl->setProperty(CSSPropertyDirection, CSSValueRtl); 123 rightToLeftDecl->setProperty(CSSPropertyDirection, CSSValueRtl);
124 return rightToLeftDecl; 124 return rightToLeftDecl;
125 } 125 }
126 126
127 static void collectScopedResolversForHostedShadowTrees(const Element* element, W illBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers) 127 static void collectScopedResolversForHostedShadowTrees(const Element& element, W illBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers)
128 { 128 {
129 ElementShadow* shadow = element->shadow(); 129 ElementShadow* shadow = element.shadow();
130 if (!shadow) 130 if (!shadow)
131 return; 131 return;
132 132
133 // Adding scoped resolver for active shadow roots for shadow host styling. 133 // Adding scoped resolver for active shadow roots for shadow host styling.
134 for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shad owRoot = shadowRoot->olderShadowRoot()) { 134 for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shad owRoot = shadowRoot->olderShadowRoot()) {
135 if (shadowRoot->numberOfStyles() > 0) { 135 if (shadowRoot->numberOfStyles() > 0) {
136 if (ScopedStyleResolver* resolver = shadowRoot->scopedStyleResolver( )) 136 if (ScopedStyleResolver* resolver = shadowRoot->scopedStyleResolver( ))
137 resolvers.append(resolver); 137 resolvers.append(resolver);
138 } 138 }
139 } 139 }
140 } 140 }
141 141
142 static void collectScopedResolversForTreeBoundaryCrossingRules(const Element& el ement, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolversIn OuterScopes, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resol versInDistributedScopes)
143 {
144 // TODO(rune@opera.com): TreeScope::treeScopeInComposedTree can potentially be expensive as its doing
145 // composed tree traversal to find the closest tree-scope for the element in the composed tree. Getting the
146 // ancestor tree-scopes are much cheaper as we do the composed tree traversa l for each TreeScope once and then cache
147 // its composed tree parent scope as a member.
148 for (TreeScope* scope = TreeScope::treeScopeInComposedTree(element); scope; scope = scope->composedParent()) {
149 if (scope == element.treeScope())
150 continue;
151 ScopedStyleResolver* resolver = scope->scopedStyleResolver();
152 if (!resolver || !resolver->hasTreeBoundaryCrossingRules())
153 continue;
154 if (element.treeScope().isInclusiveAncestorOf(resolver->treeScope()))
155 resolversInDistributedScopes.append(resolver);
156 else
157 resolversInOuterScopes.append(resolver);
158 }
159 }
160
142 StyleResolver::StyleResolver(Document& document) 161 StyleResolver::StyleResolver(Document& document)
143 : m_document(document) 162 : m_document(document)
144 , m_viewportStyleResolver(ViewportStyleResolver::create(&document)) 163 , m_viewportStyleResolver(ViewportStyleResolver::create(&document))
145 , m_needCollectFeatures(false) 164 , m_needCollectFeatures(false)
146 , m_printMediaType(false) 165 , m_printMediaType(false)
147 , m_styleResourceLoader(&document) 166 , m_styleResourceLoader(&document)
148 , m_styleSharingDepth(0) 167 , m_styleSharingDepth(0)
149 , m_styleResolverStatsSequence(0) 168 , m_styleResolverStatsSequence(0)
150 , m_accessCount(0) 169 , m_accessCount(0)
151 { 170 {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 245
227 void StyleResolver::resetRuleFeatures() 246 void StyleResolver::resetRuleFeatures()
228 { 247 {
229 // Need to recreate RuleFeatureSet. 248 // Need to recreate RuleFeatureSet.
230 m_features.clear(); 249 m_features.clear();
231 m_siblingRuleSet.clear(); 250 m_siblingRuleSet.clear();
232 m_uncommonAttributeRuleSet.clear(); 251 m_uncommonAttributeRuleSet.clear();
233 m_needCollectFeatures = true; 252 m_needCollectFeatures = true;
234 } 253 }
235 254
236 void StyleResolver::addTreeBoundaryCrossingScope(ContainerNode& scope)
237 {
238 m_treeBoundaryCrossingRules.addScope(scope);
239 }
240
241 void StyleResolver::resetAuthorStyle(TreeScope& treeScope) 255 void StyleResolver::resetAuthorStyle(TreeScope& treeScope)
242 { 256 {
243 m_treeBoundaryCrossingRules.removeScope(treeScope.rootNode());
244 resetRuleFeatures(); 257 resetRuleFeatures();
245 258
246 ScopedStyleResolver* resolver = treeScope.scopedStyleResolver(); 259 ScopedStyleResolver* resolver = treeScope.scopedStyleResolver();
247 if (!resolver) 260 if (!resolver)
248 return; 261 return;
249 262
250 if (treeScope.rootNode().isDocumentNode()) { 263 if (treeScope.rootNode().isDocumentNode()) {
251 resolver->resetAuthorStyle(); 264 resolver->resetAuthorStyle();
252 return; 265 return;
253 } 266 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 } 365 }
353 366
354 StyleResolver::~StyleResolver() 367 StyleResolver::~StyleResolver()
355 { 368 {
356 } 369 }
357 370
358 static inline ScopedStyleResolver* scopedResolverFor(const Element* element) 371 static inline ScopedStyleResolver* scopedResolverFor(const Element* element)
359 { 372 {
360 // Ideally, returning element->treeScope().scopedStyleResolver() should be 373 // Ideally, returning element->treeScope().scopedStyleResolver() should be
361 // enough, but ::cue and custom pseudo elements like ::-webkit-meter-bar pie rce 374 // enough, but ::cue and custom pseudo elements like ::-webkit-meter-bar pie rce
362 // through a shadow dom boundary, yet they are not part of m_treeBoundaryCro ssingRules. 375 // through a shadow dom boundary, yet they are not part of treeBoundaryCross ingRules.
363 // The assumption here is that these rules only pierce through one boundary and 376 // The assumption here is that these rules only pierce through one boundary and
364 // that the scope of these elements do not have a style resolver due to the fact 377 // that the scope of these elements do not have a style resolver due to the fact
365 // that VTT scopes and UA shadow trees don't have <style> elements. This is 378 // that VTT scopes and UA shadow trees don't have <style> elements. This is
366 // backed up by the ASSERTs below. 379 // backed up by the ASSERTs below.
367 // 380 //
368 // FIXME: Make ::cue and custom pseudo elements part of boundary crossing ru les 381 // FIXME: Make ::cue and custom pseudo elements part of boundary crossing ru les
369 // when moving those rules to ScopedStyleResolver as part of issue 401359. 382 // when moving those rules to ScopedStyleResolver as part of issue 401359.
370 383
371 TreeScope* treeScope = &element->treeScope(); 384 TreeScope* treeScope = &element->treeScope();
372 if (ScopedStyleResolver* resolver = treeScope->scopedStyleResolver()) { 385 if (ScopedStyleResolver* resolver = treeScope->scopedStyleResolver()) {
373 ASSERT(element->shadowPseudoId().isEmpty()); 386 ASSERT(element->shadowPseudoId().isEmpty());
374 ASSERT(!element->isVTTElement()); 387 ASSERT(!element->isVTTElement());
375 return resolver; 388 return resolver;
376 } 389 }
377 390
378 treeScope = treeScope->parentTreeScope(); 391 treeScope = treeScope->parentTreeScope();
379 if (!treeScope) 392 if (!treeScope)
380 return nullptr; 393 return nullptr;
381 if (element->shadowPseudoId().isEmpty() && !element->isVTTElement()) 394 if (element->shadowPseudoId().isEmpty() && !element->isVTTElement())
382 return nullptr; 395 return nullptr;
383 return treeScope->scopedStyleResolver(); 396 return treeScope->scopedStyleResolver();
384 } 397 }
385 398
386 void StyleResolver::matchAuthorRules(Element* element, ElementRuleCollector& col lector, bool includeEmptyRules) 399 void StyleResolver::matchAuthorRules(Element* element, ElementRuleCollector& col lector, bool includeEmptyRules)
387 { 400 {
388 collector.clearMatchedRules();
389 collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult(). matchedProperties.size() - 1; 401 collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult(). matchedProperties.size() - 1;
390 402
391 CascadeOrder cascadeOrder = 0;
392 WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolversInShad owTree; 403 WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolversInShad owTree;
393 collectScopedResolversForHostedShadowTrees(element, resolversInShadowTree); 404 WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolversInOute rScopes;
405 WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolversInDist ributedScopes;
406
407 collectScopedResolversForHostedShadowTrees(*element, resolversInShadowTree);
408 if (document().styleEngine().hasTreeBoundaryCrossingRules())
409 collectScopedResolversForTreeBoundaryCrossingRules(*element, resolversIn OuterScopes, resolversInDistributedScopes);
410
411 // According to the CSS Scoping spec, cascading of rules from inner vs outer scopes happens
412 // such that outer scope rules wins regardless of specificity. For rules fro m tree-scopes
413 // that do not have an ascendant/descendant relationship in the tree-of-tree s (typical for
414 // ::content rules from different scopes during re-distribution), tree-of-tr ees order of
415 // appearance applies, hence specificity wins although last rule in order of appearance wins
416 // if the specificity is the same.
417 //
418 // The code below uses CascadeOrder which is an order-of-appearance value, a nd should give
419 // the correct cascading order when order-of-appearance applies.
420 // The "outer scope wins" rule is ensured by calls to sortAndTransferMatched Rules().
421 //
422 // TODO(rune@opera.com): The current implementation does not handle cascadin g order as
423 // spec'ed for !important rules or multiple shadow trees per host.
394 424
395 // Apply :host and :host-context rules from inner scopes. 425 // Apply :host and :host-context rules from inner scopes.
396 for (int j = resolversInShadowTree.size() - 1; j >= 0; --j) 426 if (resolversInShadowTree.size()) {
397 resolversInShadowTree.at(j)->collectMatchingShadowHostRules(collector, i ncludeEmptyRules, ++cascadeOrder); 427 collector.clearMatchedRules();
428 CascadeOrder cascadeOrder = 0;
429 for (int i = resolversInShadowTree.size() - 1; i >= 0; --i)
430 resolversInShadowTree.at(i)->collectMatchingShadowHostRules(collecto r, includeEmptyRules, ++cascadeOrder);
431 collector.sortAndTransferMatchedRules();
432 }
398 433
399 // Apply normal rules from element scope. 434 // Apply ::content rules from distributed scopes
400 if (ScopedStyleResolver* resolver = scopedResolverFor(element)) 435 if (resolversInDistributedScopes.size()) {
401 resolver->collectMatchingAuthorRules(collector, includeEmptyRules, ++cas cadeOrder); 436 collector.clearMatchedRules();
437 CascadeOrder cascadeOrder = 0;
438 for (int j = resolversInDistributedScopes.size() - 1; j >= 0; --j)
439 resolversInDistributedScopes.at(j)->collectMatchingTreeBoundaryCross ingRules(collector, includeEmptyRules, ++cascadeOrder);
440 collector.sortAndTransferMatchedRules();
441 }
402 442
403 // Apply /deep/ and ::shadow rules from outer scopes, and ::content from inn er. 443 // Apply rules from the element's scope.
404 m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collec tor, includeEmptyRules); 444 if (ScopedStyleResolver* resolver = scopedResolverFor(element)) {
405 collector.sortAndTransferMatchedRules(); 445 collector.clearMatchedRules();
446 resolver->collectMatchingAuthorRules(collector, includeEmptyRules, ignor eCascadeOrder);
447
448 // TODO(rune@opera.com): Only piercing rules, of the boundary crossing r ules,
449 // can match elements in the same scope as the rules, thus we can drop t he code
450 // below if piercing combinators are removed.
451 if (resolver->hasTreeBoundaryCrossingRules())
452 resolver->collectMatchingTreeBoundaryCrossingRules(collector, includ eEmptyRules, ignoreCascadeOrder);
453
454 collector.sortAndTransferMatchedRules();
455 }
456
457 // Apply /deep/ and ::shadow rules from outer scopes.
458 // TODO(rune@opera.com): The code below can be removed if we remove support for shadow piercing selectors.
459 for (unsigned k = 0; k < resolversInOuterScopes.size(); k++) {
460 collector.clearMatchedRules();
461 resolversInOuterScopes.at(k)->collectMatchingTreeBoundaryCrossingRules(c ollector, includeEmptyRules, ignoreCascadeOrder);
462 collector.sortAndTransferMatchedRules();
463 }
406 } 464 }
407 465
408 void StyleResolver::matchUARules(ElementRuleCollector& collector) 466 void StyleResolver::matchUARules(ElementRuleCollector& collector)
409 { 467 {
410 collector.setMatchingUARules(true); 468 collector.setMatchingUARules(true);
411 469
412 CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance( ); 470 CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance( );
413 RuleSet* userAgentStyleSheet = m_printMediaType ? defaultStyleSheets.default PrintStyle() : defaultStyleSheets.defaultStyle(); 471 RuleSet* userAgentStyleSheet = m_printMediaType ? defaultStyleSheets.default PrintStyle() : defaultStyleSheets.defaultStyle();
414 matchRuleSet(collector, userAgentStyleSheet); 472 matchRuleSet(collector, userAgentStyleSheet);
415 473
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 loadPendingResources(state); 1045 loadPendingResources(state);
988 1046
989 ASSERT(!state.fontBuilder().fontDirty()); 1047 ASSERT(!state.fontBuilder().fontDirty());
990 1048
991 return true; 1049 return true;
992 } 1050 }
993 1051
994 StyleRuleKeyframes* StyleResolver::findKeyframesRule(const Element* element, con st AtomicString& animationName) 1052 StyleRuleKeyframes* StyleResolver::findKeyframesRule(const Element* element, con st AtomicString& animationName)
995 { 1053 {
996 WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolvers; 1054 WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolvers;
997 collectScopedResolversForHostedShadowTrees(element, resolvers); 1055 collectScopedResolversForHostedShadowTrees(*element, resolvers);
998 if (ScopedStyleResolver* scopedResolver = element->treeScope().scopedStyleRe solver()) 1056 if (ScopedStyleResolver* scopedResolver = element->treeScope().scopedStyleRe solver())
999 resolvers.append(scopedResolver); 1057 resolvers.append(scopedResolver);
1000 1058
1001 for (size_t i = 0; i < resolvers.size(); ++i) { 1059 for (size_t i = 0; i < resolvers.size(); ++i) {
1002 if (StyleRuleKeyframes* keyframesRule = resolvers[i]->keyframeStylesForA nimation(animationName.impl())) 1060 if (StyleRuleKeyframes* keyframesRule = resolvers[i]->keyframeStylesForA nimation(animationName.impl()))
1003 return keyframesRule; 1061 return keyframesRule;
1004 } 1062 }
1005 return nullptr; 1063 return nullptr;
1006 } 1064 }
1007 1065
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 { 1554 {
1497 #if ENABLE(OILPAN) 1555 #if ENABLE(OILPAN)
1498 visitor->trace(m_matchedPropertiesCache); 1556 visitor->trace(m_matchedPropertiesCache);
1499 visitor->trace(m_viewportDependentMediaQueryResults); 1557 visitor->trace(m_viewportDependentMediaQueryResults);
1500 visitor->trace(m_selectorFilter); 1558 visitor->trace(m_selectorFilter);
1501 visitor->trace(m_viewportStyleResolver); 1559 visitor->trace(m_viewportStyleResolver);
1502 visitor->trace(m_features); 1560 visitor->trace(m_features);
1503 visitor->trace(m_siblingRuleSet); 1561 visitor->trace(m_siblingRuleSet);
1504 visitor->trace(m_uncommonAttributeRuleSet); 1562 visitor->trace(m_uncommonAttributeRuleSet);
1505 visitor->trace(m_watchedSelectorsRules); 1563 visitor->trace(m_watchedSelectorsRules);
1506 visitor->trace(m_treeBoundaryCrossingRules);
1507 visitor->trace(m_styleResourceLoader); 1564 visitor->trace(m_styleResourceLoader);
1508 visitor->trace(m_styleSharingLists); 1565 visitor->trace(m_styleSharingLists);
1509 visitor->trace(m_pendingStyleSheets); 1566 visitor->trace(m_pendingStyleSheets);
1510 visitor->trace(m_document); 1567 visitor->trace(m_document);
1511 #endif 1568 #endif
1512 } 1569 }
1513 1570
1514 } // namespace blink 1571 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698