| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |