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. |
| 6 * All rights reserved. |
6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 7 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> | 8 * 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/) | 9 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
| 10 * (http://www.torchmobile.com/) |
9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | 11 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. |
10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 12 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
11 * Copyright (C) 2012 Google Inc. All rights reserved. | 13 * Copyright (C) 2012 Google Inc. All rights reserved. |
12 * | 14 * |
13 * This library is free software; you can redistribute it and/or | 15 * This library is free software; you can redistribute it and/or |
14 * modify it under the terms of the GNU Library General Public | 16 * modify it under the terms of the GNU Library General Public |
15 * License as published by the Free Software Foundation; either | 17 * License as published by the Free Software Foundation; either |
16 * version 2 of the License, or (at your option) any later version. | 18 * version 2 of the License, or (at your option) any later version. |
17 * | 19 * |
18 * This library is distributed in the hope that it will be useful, | 20 * This library is distributed in the hope that it will be useful, |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 #include "core/svg/SVGDocumentExtensions.h" | 93 #include "core/svg/SVGDocumentExtensions.h" |
92 #include "core/svg/SVGElement.h" | 94 #include "core/svg/SVGElement.h" |
93 #include "platform/RuntimeEnabledFeatures.h" | 95 #include "platform/RuntimeEnabledFeatures.h" |
94 #include "wtf/StdLibExtras.h" | 96 #include "wtf/StdLibExtras.h" |
95 | 97 |
96 namespace { | 98 namespace { |
97 | 99 |
98 using namespace blink; | 100 using namespace blink; |
99 | 101 |
100 void setAnimationUpdateIfNeeded(StyleResolverState& state, Element& element) { | 102 void setAnimationUpdateIfNeeded(StyleResolverState& state, Element& element) { |
101 // If any changes to CSS Animations were detected, stash the update away for a
pplication after the | 103 // If any changes to CSS Animations were detected, stash the update away for |
102 // layout object is updated if we're in the appropriate scope. | 104 // application after the layout object is updated if we're in the appropriate |
| 105 // scope. |
103 if (!state.animationUpdate().isEmpty()) | 106 if (!state.animationUpdate().isEmpty()) |
104 element.ensureElementAnimations().cssAnimations().setPendingUpdate( | 107 element.ensureElementAnimations().cssAnimations().setPendingUpdate( |
105 state.animationUpdate()); | 108 state.animationUpdate()); |
106 } | 109 } |
107 | 110 |
108 // Returns whether any @apply rule sets a custom property | 111 // Returns whether any @apply rule sets a custom property |
109 bool cacheCustomPropertiesForApplyAtRules(StyleResolverState& state, | 112 bool cacheCustomPropertiesForApplyAtRules(StyleResolverState& state, |
110 const MatchedPropertiesRange& range) { | 113 const MatchedPropertiesRange& range) { |
111 bool ruleSetsCustomProperty = false; | 114 bool ruleSetsCustomProperty = false; |
112 // TODO(timloh): @apply should also work with properties registered as non-inh
erited. | 115 // TODO(timloh): @apply should also work with properties registered as |
| 116 // non-inherited. |
113 if (!state.style()->inheritedVariables()) | 117 if (!state.style()->inheritedVariables()) |
114 return false; | 118 return false; |
115 for (const auto& matchedProperties : range) { | 119 for (const auto& matchedProperties : range) { |
116 const StylePropertySet& properties = *matchedProperties.properties; | 120 const StylePropertySet& properties = *matchedProperties.properties; |
117 unsigned propertyCount = properties.propertyCount(); | 121 unsigned propertyCount = properties.propertyCount(); |
118 for (unsigned i = 0; i < propertyCount; ++i) { | 122 for (unsigned i = 0; i < propertyCount; ++i) { |
119 StylePropertySet::PropertyReference current = properties.propertyAt(i); | 123 StylePropertySet::PropertyReference current = properties.propertyAt(i); |
120 if (current.id() != CSSPropertyApplyAtRule) | 124 if (current.id() != CSSPropertyApplyAtRule) |
121 continue; | 125 continue; |
122 AtomicString name(toCSSCustomIdentValue(current.value()).value()); | 126 AtomicString name(toCSSCustomIdentValue(current.value()).value()); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 void StyleResolver::appendPendingAuthorStyleSheets() { | 269 void StyleResolver::appendPendingAuthorStyleSheets() { |
266 for (const auto& styleSheet : m_pendingStyleSheets) | 270 for (const auto& styleSheet : m_pendingStyleSheets) |
267 appendCSSStyleSheet(*styleSheet); | 271 appendCSSStyleSheet(*styleSheet); |
268 | 272 |
269 m_pendingStyleSheets.clear(); | 273 m_pendingStyleSheets.clear(); |
270 finishAppendAuthorStyleSheets(); | 274 finishAppendAuthorStyleSheets(); |
271 } | 275 } |
272 | 276 |
273 void StyleResolver::appendAuthorStyleSheets( | 277 void StyleResolver::appendAuthorStyleSheets( |
274 const HeapVector<Member<CSSStyleSheet>>& styleSheets) { | 278 const HeapVector<Member<CSSStyleSheet>>& styleSheets) { |
275 // This handles sheets added to the end of the stylesheet list only. In other
cases the style resolver | 279 // This handles sheets added to the end of the stylesheet list only. In other |
276 // needs to be reconstructed. To handle insertions too the rule order numbers
would need to be updated. | 280 // cases the style resolver needs to be reconstructed. To handle insertions |
| 281 // too the rule order numbers would need to be updated. |
277 for (const auto& styleSheet : styleSheets) | 282 for (const auto& styleSheet : styleSheets) |
278 appendCSSStyleSheet(*styleSheet); | 283 appendCSSStyleSheet(*styleSheet); |
279 } | 284 } |
280 | 285 |
281 void StyleResolver::finishAppendAuthorStyleSheets() { | 286 void StyleResolver::finishAppendAuthorStyleSheets() { |
282 collectFeatures(); | 287 collectFeatures(); |
283 | 288 |
284 if (!document().layoutViewItem().isNull() && | 289 if (!document().layoutViewItem().isNull() && |
285 document().layoutViewItem().style()) | 290 document().layoutViewItem().style()) |
286 document().layoutViewItem().style()->font().update( | 291 document().layoutViewItem().style()->font().update( |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 for (size_t i = 0; i < size; ++i) | 334 for (size_t i = 0; i < size; ++i) |
330 ruleSet->addRule(rules[i].rule, rules[i].selectorIndex, | 335 ruleSet->addRule(rules[i].rule, rules[i].selectorIndex, |
331 rules[i].hasDocumentSecurityOrigin | 336 rules[i].hasDocumentSecurityOrigin |
332 ? RuleHasDocumentSecurityOrigin | 337 ? RuleHasDocumentSecurityOrigin |
333 : RuleHasNoSpecialState); | 338 : RuleHasNoSpecialState); |
334 return ruleSet; | 339 return ruleSet; |
335 } | 340 } |
336 | 341 |
337 void StyleResolver::collectFeatures() { | 342 void StyleResolver::collectFeatures() { |
338 m_features.clear(); | 343 m_features.clear(); |
339 // Collect all ids and rules using sibling selectors (:first-child and similar
) | 344 // Collect all ids and rules using sibling selectors (:first-child and |
340 // in the current set of stylesheets. Style sharing code uses this information
to reject | 345 // similar) in the current set of stylesheets. Style sharing code uses this |
341 // sharing candidates. | 346 // information to reject sharing candidates. |
342 CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance(); | 347 CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance(); |
343 if (defaultStyleSheets.defaultStyle()) { | 348 if (defaultStyleSheets.defaultStyle()) { |
344 m_features.add(defaultStyleSheets.defaultStyle()->features()); | 349 m_features.add(defaultStyleSheets.defaultStyle()->features()); |
345 m_hasFullscreenUAStyle = defaultStyleSheets.fullscreenStyleSheet(); | 350 m_hasFullscreenUAStyle = defaultStyleSheets.fullscreenStyleSheet(); |
346 } | 351 } |
347 | 352 |
348 if (document().isViewSource()) | 353 if (document().isViewSource()) |
349 m_features.add(defaultStyleSheets.defaultViewSourceStyle()->features()); | 354 m_features.add(defaultStyleSheets.defaultViewSourceStyle()->features()); |
350 | 355 |
351 if (m_watchedSelectorsRules) | 356 if (m_watchedSelectorsRules) |
(...skipping 20 matching lines...) Expand all Loading... |
372 1); | 377 1); |
373 StyleSharingList& list = styleSharingList(); | 378 StyleSharingList& list = styleSharingList(); |
374 if (list.size() >= styleSharingListSize) | 379 if (list.size() >= styleSharingListSize) |
375 list.removeLast(); | 380 list.removeLast(); |
376 list.prepend(&element); | 381 list.prepend(&element); |
377 } | 382 } |
378 | 383 |
379 StyleSharingList& StyleResolver::styleSharingList() { | 384 StyleSharingList& StyleResolver::styleSharingList() { |
380 m_styleSharingLists.resize(styleSharingMaxDepth); | 385 m_styleSharingLists.resize(styleSharingMaxDepth); |
381 | 386 |
382 // We never put things at depth 0 into the list since that's only the <html> e
lement | 387 // We never put things at depth 0 into the list since that's only the <html> |
383 // and it has no siblings or cousins to share with. | 388 // element and it has no siblings or cousins to share with. |
384 unsigned depth = | 389 unsigned depth = |
385 std::max(std::min(m_styleSharingDepth, styleSharingMaxDepth), 1u) - 1u; | 390 std::max(std::min(m_styleSharingDepth, styleSharingMaxDepth), 1u) - 1u; |
386 | 391 |
387 if (!m_styleSharingLists[depth]) | 392 if (!m_styleSharingLists[depth]) |
388 m_styleSharingLists[depth] = new StyleSharingList; | 393 m_styleSharingLists[depth] = new StyleSharingList; |
389 return *m_styleSharingLists[depth]; | 394 return *m_styleSharingLists[depth]; |
390 } | 395 } |
391 | 396 |
392 void StyleResolver::clearStyleSharingList() { | 397 void StyleResolver::clearStyleSharingList() { |
393 m_styleSharingLists.resize(0); | 398 m_styleSharingLists.resize(0); |
394 } | 399 } |
395 | 400 |
396 static inline ScopedStyleResolver* scopedResolverFor(const Element& element) { | 401 static inline ScopedStyleResolver* scopedResolverFor(const Element& element) { |
397 // Ideally, returning element->treeScope().scopedStyleResolver() should be | 402 // Ideally, returning element->treeScope().scopedStyleResolver() should be |
398 // enough, but ::cue and custom pseudo elements like ::-webkit-meter-bar pierc
e | 403 // enough, but ::cue and custom pseudo elements like ::-webkit-meter-bar |
399 // through a shadow dom boundary, yet they are not part of m_treeBoundaryCross
ingScopes. | 404 // pierce through a shadow dom boundary, yet they are not part of |
400 // The assumption here is that these rules only pierce through one boundary an
d | 405 // m_treeBoundaryCrossingScopes. The assumption here is that these rules only |
401 // that the scope of these elements do not have a style resolver due to the fa
ct | 406 // pierce through one boundary and that the scope of these elements do not |
402 // that VTT scopes and UA shadow trees don't have <style> elements. This is | 407 // have a style resolver due to the fact that VTT scopes and UA shadow trees |
403 // backed up by the ASSERTs below. | 408 // don't have <style> elements. This is backed up by the ASSERTs below. |
404 // | 409 // |
405 // FIXME: Make ::cue and custom pseudo elements part of boundary crossing rule
s | 410 // FIXME: Make ::cue and custom pseudo elements part of boundary crossing |
406 // when moving those rules to ScopedStyleResolver as part of issue 401359. | 411 // rules when moving those rules to ScopedStyleResolver as part of issue |
| 412 // 401359. |
407 | 413 |
408 TreeScope* treeScope = &element.treeScope(); | 414 TreeScope* treeScope = &element.treeScope(); |
409 if (ScopedStyleResolver* resolver = treeScope->scopedStyleResolver()) { | 415 if (ScopedStyleResolver* resolver = treeScope->scopedStyleResolver()) { |
410 ASSERT(element.shadowPseudoId().isEmpty()); | 416 ASSERT(element.shadowPseudoId().isEmpty()); |
411 ASSERT(!element.isVTTElement()); | 417 ASSERT(!element.isVTTElement()); |
412 return resolver; | 418 return resolver; |
413 } | 419 } |
414 | 420 |
415 treeScope = treeScope->parentTreeScope(); | 421 treeScope = treeScope->parentTreeScope(); |
416 if (!treeScope) | 422 if (!treeScope) |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 isInlineStyleCacheable); | 482 isInlineStyleCacheable); |
477 } | 483 } |
478 | 484 |
479 collector.finishAddingAuthorRulesForTreeScope(); | 485 collector.finishAddingAuthorRulesForTreeScope(); |
480 } | 486 } |
481 | 487 |
482 static bool shouldCheckScope(const Element& element, | 488 static bool shouldCheckScope(const Element& element, |
483 const Node& scopingNode, | 489 const Node& scopingNode, |
484 bool isInnerTreeScope) { | 490 bool isInnerTreeScope) { |
485 if (isInnerTreeScope && element.treeScope() != scopingNode.treeScope()) { | 491 if (isInnerTreeScope && element.treeScope() != scopingNode.treeScope()) { |
486 // Check if |element| may be affected by a ::content rule in |scopingNode|'s
style. | 492 // Check if |element| may be affected by a ::content rule in |scopingNode|'s |
487 // If |element| is a descendant of a shadow host which is ancestral to |scop
ingNode|, | 493 // style. If |element| is a descendant of a shadow host which is ancestral |
488 // the |element| should be included for rule collection. | 494 // to |scopingNode|, the |element| should be included for rule collection. |
489 // Skip otherwise. | 495 // Skip otherwise. |
490 const TreeScope* scope = &scopingNode.treeScope(); | 496 const TreeScope* scope = &scopingNode.treeScope(); |
491 while (scope && scope->parentTreeScope() != &element.treeScope()) | 497 while (scope && scope->parentTreeScope() != &element.treeScope()) |
492 scope = scope->parentTreeScope(); | 498 scope = scope->parentTreeScope(); |
493 Element* shadowHost = scope ? scope->rootNode().ownerShadowHost() : nullptr; | 499 Element* shadowHost = scope ? scope->rootNode().ownerShadowHost() : nullptr; |
494 return shadowHost && element.isDescendantOf(shadowHost); | 500 return shadowHost && element.isDescendantOf(shadowHost); |
495 } | 501 } |
496 | 502 |
497 // When |element| can be distributed to |scopingNode| via <shadow>, ::content
rule can match, | 503 // When |element| can be distributed to |scopingNode| via <shadow>, ::content |
498 // thus the case should be included. | 504 // rule can match, thus the case should be included. |
499 if (!isInnerTreeScope && | 505 if (!isInnerTreeScope && |
500 scopingNode.parentOrShadowHostNode() == | 506 scopingNode.parentOrShadowHostNode() == |
501 element.treeScope().rootNode().parentOrShadowHostNode()) | 507 element.treeScope().rootNode().parentOrShadowHostNode()) |
502 return true; | 508 return true; |
503 | 509 |
504 // Obviously cases when ancestor scope has /deep/ or ::shadow rule should be i
ncluded. | 510 // Obviously cases when ancestor scope has /deep/ or ::shadow rule should be |
505 // Skip otherwise. | 511 // included. Skip otherwise. |
506 return scopingNode.treeScope() | 512 return scopingNode.treeScope() |
507 .scopedStyleResolver() | 513 .scopedStyleResolver() |
508 ->hasDeepOrShadowSelector(); | 514 ->hasDeepOrShadowSelector(); |
509 } | 515 } |
510 | 516 |
511 void StyleResolver::matchScopedRules(const Element& element, | 517 void StyleResolver::matchScopedRules(const Element& element, |
512 ElementRuleCollector& collector) { | 518 ElementRuleCollector& collector) { |
513 // Match rules from treeScopes in the reverse tree-of-trees order, since the | 519 // Match rules from treeScopes in the reverse tree-of-trees order, since the |
514 // cascading order for normal rules is such that when comparing rules from | 520 // cascading order for normal rules is such that when comparing rules from |
515 // different shadow trees, the rule from the tree which comes first in the | 521 // different shadow trees, the rule from the tree which comes first in the |
(...skipping 18 matching lines...) Expand all Loading... |
534 | 540 |
535 bool isInnerTreeScope = | 541 bool isInnerTreeScope = |
536 element.containingTreeScope().isInclusiveAncestorOf(scope); | 542 element.containingTreeScope().isInclusiveAncestorOf(scope); |
537 if (!shouldCheckScope(element, **it, isInnerTreeScope)) | 543 if (!shouldCheckScope(element, **it, isInnerTreeScope)) |
538 continue; | 544 continue; |
539 | 545 |
540 if (!matchElementScopeDone && | 546 if (!matchElementScopeDone && |
541 scope.isInclusiveAncestorOf(element.containingTreeScope())) { | 547 scope.isInclusiveAncestorOf(element.containingTreeScope())) { |
542 matchElementScopeDone = true; | 548 matchElementScopeDone = true; |
543 | 549 |
544 // At this point, the iterator has either encountered the scope for the el
ement | 550 // At this point, the iterator has either encountered the scope for the |
545 // itself (if that scope has boundary-crossing rules), or the iterator has
moved | 551 // element itself (if that scope has boundary-crossing rules), or the |
546 // to a scope which appears before the element's scope in the tree-of-tree
s order. | 552 // iterator has moved to a scope which appears before the element's scope |
547 // Try to match all rules from the element's scope. | 553 // in the tree-of-trees order. Try to match all rules from the element's |
| 554 // scope. |
548 | 555 |
549 matchElementScopeRules(element, elementScopeResolver, collector); | 556 matchElementScopeRules(element, elementScopeResolver, collector); |
550 if (resolver == elementScopeResolver) { | 557 if (resolver == elementScopeResolver) { |
551 // Boundary-crossing rules already collected in matchElementScopeRules. | 558 // Boundary-crossing rules already collected in matchElementScopeRules. |
552 continue; | 559 continue; |
553 } | 560 } |
554 } | 561 } |
555 | 562 |
556 collector.clearMatchedRules(); | 563 collector.clearMatchedRules(); |
557 resolver->collectMatchingTreeBoundaryCrossingRules(collector); | 564 resolver->collectMatchingTreeBoundaryCrossingRules(collector); |
(...skipping 27 matching lines...) Expand all Loading... |
585 | 592 |
586 // Apply :host and :host-context rules from inner scopes. | 593 // Apply :host and :host-context rules from inner scopes. |
587 for (int j = resolversInShadowTree.size() - 1; j >= 0; --j) | 594 for (int j = resolversInShadowTree.size() - 1; j >= 0; --j) |
588 resolversInShadowTree.at(j)->collectMatchingShadowHostRules(collector, | 595 resolversInShadowTree.at(j)->collectMatchingShadowHostRules(collector, |
589 ++cascadeOrder); | 596 ++cascadeOrder); |
590 | 597 |
591 // Apply normal rules from element scope. | 598 // Apply normal rules from element scope. |
592 if (ScopedStyleResolver* resolver = scopedResolverFor(element)) | 599 if (ScopedStyleResolver* resolver = scopedResolverFor(element)) |
593 resolver->collectMatchingAuthorRules(collector, ++cascadeOrder); | 600 resolver->collectMatchingAuthorRules(collector, ++cascadeOrder); |
594 | 601 |
595 // Apply /deep/ and ::shadow rules from outer scopes, and ::content from inner
. | 602 // Apply /deep/ and ::shadow rules from outer scopes, and ::content from |
| 603 // inner. |
596 collectTreeBoundaryCrossingRules(element, collector); | 604 collectTreeBoundaryCrossingRules(element, collector); |
597 collector.sortAndTransferMatchedRules(); | 605 collector.sortAndTransferMatchedRules(); |
598 } | 606 } |
599 | 607 |
600 void StyleResolver::matchUARules(ElementRuleCollector& collector) { | 608 void StyleResolver::matchUARules(ElementRuleCollector& collector) { |
601 collector.setMatchingUARules(true); | 609 collector.setMatchingUARules(true); |
602 | 610 |
603 CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance(); | 611 CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance(); |
604 RuleSet* userAgentStyleSheet = m_printMediaType | 612 RuleSet* userAgentStyleSheet = m_printMediaType |
605 ? defaultStyleSheets.defaultPrintStyle() | 613 ? defaultStyleSheets.defaultPrintStyle() |
606 : defaultStyleSheets.defaultStyle(); | 614 : defaultStyleSheets.defaultStyle(); |
607 matchRuleSet(collector, userAgentStyleSheet); | 615 matchRuleSet(collector, userAgentStyleSheet); |
608 | 616 |
609 // In quirks mode, we match rules from the quirks user agent sheet. | 617 // In quirks mode, we match rules from the quirks user agent sheet. |
610 if (document().inQuirksMode()) | 618 if (document().inQuirksMode()) |
611 matchRuleSet(collector, defaultStyleSheets.defaultQuirksStyle()); | 619 matchRuleSet(collector, defaultStyleSheets.defaultQuirksStyle()); |
612 | 620 |
613 // If document uses view source styles (in view source mode or in xml viewer m
ode), then we match rules from the view source style sheet. | 621 // If document uses view source styles (in view source mode or in xml viewer |
| 622 // mode), then we match rules from the view source style sheet. |
614 if (document().isViewSource()) | 623 if (document().isViewSource()) |
615 matchRuleSet(collector, defaultStyleSheets.defaultViewSourceStyle()); | 624 matchRuleSet(collector, defaultStyleSheets.defaultViewSourceStyle()); |
616 | 625 |
617 collector.finishAddingUARules(); | 626 collector.finishAddingUARules(); |
618 collector.setMatchingUARules(false); | 627 collector.setMatchingUARules(false); |
619 } | 628 } |
620 | 629 |
621 void StyleResolver::matchRuleSet(ElementRuleCollector& collector, | 630 void StyleResolver::matchRuleSet(ElementRuleCollector& collector, |
622 RuleSet* rules) { | 631 RuleSet* rules) { |
623 collector.clearMatchedRules(); | 632 collector.clearMatchedRules(); |
624 collector.collectMatchingRules(MatchRequest(rules)); | 633 collector.collectMatchingRules(MatchRequest(rules)); |
625 collector.sortAndTransferMatchedRules(); | 634 collector.sortAndTransferMatchedRules(); |
626 } | 635 } |
627 | 636 |
628 void StyleResolver::matchAllRules(StyleResolverState& state, | 637 void StyleResolver::matchAllRules(StyleResolverState& state, |
629 ElementRuleCollector& collector, | 638 ElementRuleCollector& collector, |
630 bool includeSMILProperties) { | 639 bool includeSMILProperties) { |
631 matchUARules(collector); | 640 matchUARules(collector); |
632 | 641 |
633 // Now check author rules, beginning first with presentational attributes mapp
ed from HTML. | 642 // Now check author rules, beginning first with presentational attributes |
| 643 // mapped from HTML. |
634 if (state.element()->isStyledElement()) { | 644 if (state.element()->isStyledElement()) { |
635 collector.addElementStyleProperties( | 645 collector.addElementStyleProperties( |
636 state.element()->presentationAttributeStyle()); | 646 state.element()->presentationAttributeStyle()); |
637 | 647 |
638 // Now we check additional mapped declarations. | 648 // Now we check additional mapped declarations. |
639 // Tables and table cells share an additional mapped rule that must be appli
ed | 649 // Tables and table cells share an additional mapped rule that must be |
640 // after all attributes, since their mapped style depends on the values of m
ultiple attributes. | 650 // applied after all attributes, since their mapped style depends on the |
| 651 // values of multiple attributes. |
641 collector.addElementStyleProperties( | 652 collector.addElementStyleProperties( |
642 state.element()->additionalPresentationAttributeStyle()); | 653 state.element()->additionalPresentationAttributeStyle()); |
643 | 654 |
644 if (state.element()->isHTMLElement()) { | 655 if (state.element()->isHTMLElement()) { |
645 bool isAuto; | 656 bool isAuto; |
646 TextDirection textDirection = | 657 TextDirection textDirection = |
647 toHTMLElement(state.element()) | 658 toHTMLElement(state.element()) |
648 ->directionalityIfhasDirAutoAttribute(isAuto); | 659 ->directionalityIfhasDirAutoAttribute(isAuto); |
649 if (isAuto) { | 660 if (isAuto) { |
650 state.setHasDirAutoAttribute(true); | 661 state.setHasDirAutoAttribute(true); |
651 collector.addElementStyleProperties(textDirection == LTR | 662 collector.addElementStyleProperties(textDirection == LTR |
652 ? leftToRightDeclaration() | 663 ? leftToRightDeclaration() |
653 : rightToLeftDeclaration()); | 664 : rightToLeftDeclaration()); |
654 } | 665 } |
655 } | 666 } |
656 } | 667 } |
657 | 668 |
658 matchAuthorRules(*state.element(), collector); | 669 matchAuthorRules(*state.element(), collector); |
659 | 670 |
660 if (state.element()->isStyledElement()) { | 671 if (state.element()->isStyledElement()) { |
661 // For Shadow DOM V1, inline style is already collected in matchScopedRules(
). | 672 // For Shadow DOM V1, inline style is already collected in |
| 673 // matchScopedRules(). |
662 if (document().shadowCascadeOrder() != | 674 if (document().shadowCascadeOrder() != |
663 ShadowCascadeOrder::ShadowCascadeV1 && | 675 ShadowCascadeOrder::ShadowCascadeV1 && |
664 state.element()->inlineStyle()) { | 676 state.element()->inlineStyle()) { |
665 // Inline style is immutable as long as there is no CSSOM wrapper. | 677 // Inline style is immutable as long as there is no CSSOM wrapper. |
666 bool isInlineStyleCacheable = | 678 bool isInlineStyleCacheable = |
667 !state.element()->inlineStyle()->isMutable(); | 679 !state.element()->inlineStyle()->isMutable(); |
668 collector.addElementStyleProperties(state.element()->inlineStyle(), | 680 collector.addElementStyleProperties(state.element()->inlineStyle(), |
669 isInlineStyleCacheable); | 681 isInlineStyleCacheable); |
670 } | 682 } |
671 | 683 |
(...skipping 12 matching lines...) Expand all Loading... |
684 ElementRuleCollector& collector) { | 696 ElementRuleCollector& collector) { |
685 if (m_treeBoundaryCrossingScopes.isEmpty()) | 697 if (m_treeBoundaryCrossingScopes.isEmpty()) |
686 return; | 698 return; |
687 | 699 |
688 // When comparing rules declared in outer treescopes, outer's rules win. | 700 // When comparing rules declared in outer treescopes, outer's rules win. |
689 CascadeOrder outerCascadeOrder = m_treeBoundaryCrossingScopes.size() * 2; | 701 CascadeOrder outerCascadeOrder = m_treeBoundaryCrossingScopes.size() * 2; |
690 // When comparing rules declared in inner treescopes, inner's rules win. | 702 // When comparing rules declared in inner treescopes, inner's rules win. |
691 CascadeOrder innerCascadeOrder = m_treeBoundaryCrossingScopes.size(); | 703 CascadeOrder innerCascadeOrder = m_treeBoundaryCrossingScopes.size(); |
692 | 704 |
693 for (const auto& scopingNode : m_treeBoundaryCrossingScopes) { | 705 for (const auto& scopingNode : m_treeBoundaryCrossingScopes) { |
694 // Skip rule collection for element when tree boundary crossing rules of sco
pingNode's | 706 // Skip rule collection for element when tree boundary crossing rules of |
695 // scope can never apply to it. | 707 // scopingNode's scope can never apply to it. |
696 bool isInnerTreeScope = element.containingTreeScope().isInclusiveAncestorOf( | 708 bool isInnerTreeScope = element.containingTreeScope().isInclusiveAncestorOf( |
697 scopingNode->containingTreeScope()); | 709 scopingNode->containingTreeScope()); |
698 if (!shouldCheckScope(element, *scopingNode, isInnerTreeScope)) | 710 if (!shouldCheckScope(element, *scopingNode, isInnerTreeScope)) |
699 continue; | 711 continue; |
700 | 712 |
701 CascadeOrder cascadeOrder = | 713 CascadeOrder cascadeOrder = |
702 isInnerTreeScope ? innerCascadeOrder : outerCascadeOrder; | 714 isInnerTreeScope ? innerCascadeOrder : outerCascadeOrder; |
703 scopingNode->treeScope() | 715 scopingNode->treeScope() |
704 .scopedStyleResolver() | 716 .scopedStyleResolver() |
705 ->collectMatchingTreeBoundaryCrossingRules(collector, cascadeOrder); | 717 ->collectMatchingTreeBoundaryCrossingRules(collector, cascadeOrder); |
(...skipping 12 matching lines...) Expand all Loading... |
718 documentStyle->setZoom(frame && !document.printing() ? frame->pageZoomFactor() | 730 documentStyle->setZoom(frame && !document.printing() ? frame->pageZoomFactor() |
719 : 1); | 731 : 1); |
720 FontDescription documentFontDescription = documentStyle->getFontDescription(); | 732 FontDescription documentFontDescription = documentStyle->getFontDescription(); |
721 documentFontDescription.setLocale( | 733 documentFontDescription.setLocale( |
722 LayoutLocale::get(document.contentLanguage())); | 734 LayoutLocale::get(document.contentLanguage())); |
723 documentStyle->setFontDescription(documentFontDescription); | 735 documentStyle->setFontDescription(documentFontDescription); |
724 documentStyle->setZIndex(0); | 736 documentStyle->setZIndex(0); |
725 documentStyle->setIsStackingContext(true); | 737 documentStyle->setIsStackingContext(true); |
726 documentStyle->setUserModify(document.inDesignMode() ? READ_WRITE | 738 documentStyle->setUserModify(document.inDesignMode() ? READ_WRITE |
727 : READ_ONLY); | 739 : READ_ONLY); |
728 // These are designed to match the user-agent stylesheet values for the docume
nt element | 740 // These are designed to match the user-agent stylesheet values for the |
729 // so that the common case doesn't need to create a new ComputedStyle in | 741 // document element so that the common case doesn't need to create a new |
730 // Document::inheritHtmlAndBodyElementStyles. | 742 // ComputedStyle in Document::inheritHtmlAndBodyElementStyles. |
731 documentStyle->setDisplay(EDisplay::Block); | 743 documentStyle->setDisplay(EDisplay::Block); |
732 documentStyle->setPosition(AbsolutePosition); | 744 documentStyle->setPosition(AbsolutePosition); |
733 | 745 |
734 document.setupFontBuilder(*documentStyle); | 746 document.setupFontBuilder(*documentStyle); |
735 | 747 |
736 return documentStyle.release(); | 748 return documentStyle.release(); |
737 } | 749 } |
738 | 750 |
739 void StyleResolver::adjustComputedStyle(StyleResolverState& state, | 751 void StyleResolver::adjustComputedStyle(StyleResolverState& state, |
740 Element* element) { | 752 Element* element) { |
741 StyleAdjuster::adjustComputedStyle(state.mutableStyleRef(), | 753 StyleAdjuster::adjustComputedStyle(state.mutableStyleRef(), |
742 *state.parentStyle(), element); | 754 *state.parentStyle(), element); |
743 } | 755 } |
744 | 756 |
745 // Start loading resources referenced by this style. | 757 // Start loading resources referenced by this style. |
746 void StyleResolver::loadPendingResources(StyleResolverState& state) { | 758 void StyleResolver::loadPendingResources(StyleResolverState& state) { |
747 state.elementStyleResources().loadPendingResources(state.style()); | 759 state.elementStyleResources().loadPendingResources(state.style()); |
748 } | 760 } |
749 | 761 |
750 PassRefPtr<ComputedStyle> StyleResolver::styleForElement( | 762 PassRefPtr<ComputedStyle> StyleResolver::styleForElement( |
751 Element* element, | 763 Element* element, |
752 const ComputedStyle* defaultParent, | 764 const ComputedStyle* defaultParent, |
753 StyleSharingBehavior sharingBehavior, | 765 StyleSharingBehavior sharingBehavior, |
754 RuleMatchingBehavior matchingBehavior) { | 766 RuleMatchingBehavior matchingBehavior) { |
755 DCHECK(document().frame()); | 767 DCHECK(document().frame()); |
756 ASSERT(document().settings()); | 768 ASSERT(document().settings()); |
757 ASSERT(!hasPendingAuthorStyleSheets()); | 769 ASSERT(!hasPendingAuthorStyleSheets()); |
758 ASSERT(!m_needCollectFeatures); | 770 ASSERT(!m_needCollectFeatures); |
759 | 771 |
760 // Once an element has a layoutObject, we don't try to destroy it, since other
wise the layoutObject | 772 // Once an element has a layoutObject, we don't try to destroy it, since |
761 // will vanish if a style recalc happens during loading. | 773 // otherwise the layoutObject will vanish if a style recalc happens during |
| 774 // loading. |
762 if (sharingBehavior == AllowStyleSharing && !document().isRenderingReady() && | 775 if (sharingBehavior == AllowStyleSharing && !document().isRenderingReady() && |
763 !element->layoutObject()) { | 776 !element->layoutObject()) { |
764 if (!s_styleNotYetAvailable) { | 777 if (!s_styleNotYetAvailable) { |
765 s_styleNotYetAvailable = ComputedStyle::create().leakRef(); | 778 s_styleNotYetAvailable = ComputedStyle::create().leakRef(); |
766 s_styleNotYetAvailable->setDisplay(EDisplay::None); | 779 s_styleNotYetAvailable->setDisplay(EDisplay::None); |
767 s_styleNotYetAvailable->font().update( | 780 s_styleNotYetAvailable->font().update( |
768 document().styleEngine().fontSelector()); | 781 document().styleEngine().fontSelector()); |
769 } | 782 } |
770 | 783 |
771 document().setHasNodesWithPlaceholderStyle(); | 784 document().setHasNodesWithPlaceholderStyle(); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 toCSSIdentifierValue(*value).getValueID() == CSSValueBlock) | 871 toCSSIdentifierValue(*value).getValueID() == CSSValueBlock) |
859 UseCounter::count( | 872 UseCounter::count( |
860 element->document(), | 873 element->document(), |
861 UseCounter::SummaryElementWithDisplayBlockAuthorRule); | 874 UseCounter::SummaryElementWithDisplayBlockAuthorRule); |
862 } | 875 } |
863 } | 876 } |
864 | 877 |
865 if (element->computedStyle() && | 878 if (element->computedStyle() && |
866 element->computedStyle()->textAutosizingMultiplier() != | 879 element->computedStyle()->textAutosizingMultiplier() != |
867 state.style()->textAutosizingMultiplier()) { | 880 state.style()->textAutosizingMultiplier()) { |
868 // Preserve the text autosizing multiplier on style recalc. Autosizer will
update it during layout if needed. | 881 // Preserve the text autosizing multiplier on style recalc. Autosizer will |
869 // NOTE: this must occur before applyMatchedProperties for correct computa
tion of font-relative lengths. | 882 // update it during layout if needed. |
| 883 // NOTE: this must occur before applyMatchedProperties for correct |
| 884 // computation of font-relative lengths. |
870 state.style()->setTextAutosizingMultiplier( | 885 state.style()->setTextAutosizingMultiplier( |
871 element->computedStyle()->textAutosizingMultiplier()); | 886 element->computedStyle()->textAutosizingMultiplier()); |
872 state.style()->setUnique(); | 887 state.style()->setUnique(); |
873 } | 888 } |
874 | 889 |
875 if (state.hasDirAutoAttribute()) | 890 if (state.hasDirAutoAttribute()) |
876 state.style()->setSelfOrAncestorHasDirAutoAttribute(true); | 891 state.style()->setSelfOrAncestorHasDirAutoAttribute(true); |
877 | 892 |
878 applyMatchedProperties(state, collector.matchedResult()); | 893 applyMatchedProperties(state, collector.matchedResult()); |
879 applyCallbackSelectors(state); | 894 applyCallbackSelectors(state); |
880 | 895 |
881 // Cache our original display. | 896 // Cache our original display. |
882 state.style()->setOriginalDisplay(state.style()->display()); | 897 state.style()->setOriginalDisplay(state.style()->display()); |
883 | 898 |
884 adjustComputedStyle(state, element); | 899 adjustComputedStyle(state, element); |
885 | 900 |
886 if (elementAnimations) | 901 if (elementAnimations) |
887 elementAnimations->updateBaseComputedStyle(state.style()); | 902 elementAnimations->updateBaseComputedStyle(state.style()); |
888 } else { | 903 } else { |
889 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), baseStylesUsed, 1); | 904 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), baseStylesUsed, 1); |
890 } | 905 } |
891 | 906 |
892 // FIXME: The CSSWG wants to specify that the effects of animations are applie
d before | 907 // FIXME: The CSSWG wants to specify that the effects of animations are |
893 // important rules, but this currently happens here as we require adjustment t
o have happened | 908 // applied before important rules, but this currently happens here as we |
894 // before deciding which properties to transition. | 909 // require adjustment to have happened before deciding which properties to |
| 910 // transition. |
895 if (applyAnimatedProperties(state, element)) { | 911 if (applyAnimatedProperties(state, element)) { |
896 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), stylesAnimated, 1); | 912 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), stylesAnimated, 1); |
897 adjustComputedStyle(state, element); | 913 adjustComputedStyle(state, element); |
898 } | 914 } |
899 | 915 |
900 if (isHTMLBodyElement(*element)) | 916 if (isHTMLBodyElement(*element)) |
901 document().textLinkColors().setTextColor(state.style()->color()); | 917 document().textLinkColors().setTextColor(state.style()->color()); |
902 | 918 |
903 setAnimationUpdateIfNeeded(state, *element); | 919 setAnimationUpdateIfNeeded(state, *element); |
904 | 920 |
905 if (state.style()->hasViewportUnits()) | 921 if (state.style()->hasViewportUnits()) |
906 document().setHasViewportUnits(); | 922 document().setHasViewportUnits(); |
907 | 923 |
908 if (state.style()->hasRemUnits()) | 924 if (state.style()->hasRemUnits()) |
909 document().styleEngine().setUsesRemUnit(true); | 925 document().styleEngine().setUsesRemUnit(true); |
910 | 926 |
911 // Now return the style. | 927 // Now return the style. |
912 return state.takeStyle(); | 928 return state.takeStyle(); |
913 } | 929 } |
914 | 930 |
915 // TODO(alancutter): Create compositor keyframe values directly instead of inter
mediate AnimatableValues. | 931 // TODO(alancutter): Create compositor keyframe values directly instead of |
| 932 // intermediate AnimatableValues. |
916 PassRefPtr<AnimatableValue> StyleResolver::createAnimatableValueSnapshot( | 933 PassRefPtr<AnimatableValue> StyleResolver::createAnimatableValueSnapshot( |
917 Element& element, | 934 Element& element, |
918 const ComputedStyle& baseStyle, | 935 const ComputedStyle& baseStyle, |
919 const ComputedStyle* parentStyle, | 936 const ComputedStyle* parentStyle, |
920 CSSPropertyID property, | 937 CSSPropertyID property, |
921 const CSSValue* value) { | 938 const CSSValue* value) { |
922 // TODO(alancutter): Avoid creating a StyleResolverState just to apply a singl
e value on a ComputedStyle. | 939 // TODO(alancutter): Avoid creating a StyleResolverState just to apply a |
| 940 // single value on a ComputedStyle. |
923 StyleResolverState state(element.document(), &element, parentStyle); | 941 StyleResolverState state(element.document(), &element, parentStyle); |
924 state.setStyle(ComputedStyle::clone(baseStyle)); | 942 state.setStyle(ComputedStyle::clone(baseStyle)); |
925 if (value) { | 943 if (value) { |
926 StyleBuilder::applyProperty(property, state, *value); | 944 StyleBuilder::applyProperty(property, state, *value); |
927 state.fontBuilder().createFont( | 945 state.fontBuilder().createFont( |
928 state.document().styleEngine().fontSelector(), state.mutableStyleRef()); | 946 state.document().styleEngine().fontSelector(), state.mutableStyleRef()); |
929 } | 947 } |
930 return CSSAnimatableValueFactory::create(property, *state.style()); | 948 return CSSAnimatableValueFactory::create(property, *state.style()); |
931 } | 949 } |
932 | 950 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 state.style()->setOriginalDisplay(state.style()->display()); | 1059 state.style()->setOriginalDisplay(state.style()->display()); |
1042 | 1060 |
1043 // FIXME: Passing 0 as the Element* introduces a lot of complexity | 1061 // FIXME: Passing 0 as the Element* introduces a lot of complexity |
1044 // in the adjustComputedStyle code. | 1062 // in the adjustComputedStyle code. |
1045 adjustComputedStyle(state, 0); | 1063 adjustComputedStyle(state, 0); |
1046 | 1064 |
1047 if (elementAnimations) | 1065 if (elementAnimations) |
1048 elementAnimations->updateBaseComputedStyle(state.style()); | 1066 elementAnimations->updateBaseComputedStyle(state.style()); |
1049 } | 1067 } |
1050 | 1068 |
1051 // FIXME: The CSSWG wants to specify that the effects of animations are applie
d before | 1069 // FIXME: The CSSWG wants to specify that the effects of animations are |
1052 // important rules, but this currently happens here as we require adjustment t
o have happened | 1070 // applied before important rules, but this currently happens here as we |
1053 // before deciding which properties to transition. | 1071 // require adjustment to have happened before deciding which properties to |
| 1072 // transition. |
1054 if (applyAnimatedProperties(state, pseudoElement)) | 1073 if (applyAnimatedProperties(state, pseudoElement)) |
1055 adjustComputedStyle(state, 0); | 1074 adjustComputedStyle(state, 0); |
1056 | 1075 |
1057 document().styleEngine().incStyleForElementCount(); | 1076 document().styleEngine().incStyleForElementCount(); |
1058 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), pseudoElementsStyled, | 1077 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), pseudoElementsStyled, |
1059 1); | 1078 1); |
1060 | 1079 |
1061 if (state.style()->hasViewportUnits()) | 1080 if (state.style()->hasViewportUnits()) |
1062 document().setHasViewportUnits(); | 1081 document().setHasViewportUnits(); |
1063 | 1082 |
(...skipping 19 matching lines...) Expand all Loading... |
1083 if (PseudoElement* pseudoElement = | 1102 if (PseudoElement* pseudoElement = |
1084 element->pseudoElement(pseudoStyleRequest.pseudoId)) | 1103 element->pseudoElement(pseudoStyleRequest.pseudoId)) |
1085 setAnimationUpdateIfNeeded(state, *pseudoElement); | 1104 setAnimationUpdateIfNeeded(state, *pseudoElement); |
1086 | 1105 |
1087 // Now return the style. | 1106 // Now return the style. |
1088 return state.takeStyle(); | 1107 return state.takeStyle(); |
1089 } | 1108 } |
1090 | 1109 |
1091 PassRefPtr<ComputedStyle> StyleResolver::styleForPage(int pageIndex) { | 1110 PassRefPtr<ComputedStyle> StyleResolver::styleForPage(int pageIndex) { |
1092 ASSERT(!hasPendingAuthorStyleSheets()); | 1111 ASSERT(!hasPendingAuthorStyleSheets()); |
1093 StyleResolverState state( | 1112 // m_rootElementStyle will be set to the document style. |
1094 document(), | 1113 StyleResolverState state(document(), document().documentElement()); |
1095 document() | |
1096 .documentElement()); // m_rootElementStyle will be set to the documen
t style. | |
1097 | 1114 |
1098 RefPtr<ComputedStyle> style = ComputedStyle::create(); | 1115 RefPtr<ComputedStyle> style = ComputedStyle::create(); |
1099 const ComputedStyle* rootElementStyle = state.rootElementStyle() | 1116 const ComputedStyle* rootElementStyle = state.rootElementStyle() |
1100 ? state.rootElementStyle() | 1117 ? state.rootElementStyle() |
1101 : document().computedStyle(); | 1118 : document().computedStyle(); |
1102 ASSERT(rootElementStyle); | 1119 ASSERT(rootElementStyle); |
1103 style->inheritFrom(*rootElementStyle); | 1120 style->inheritFrom(*rootElementStyle); |
1104 state.setStyle(style.release()); | 1121 state.setStyle(style.release()); |
1105 | 1122 |
1106 PageRuleCollector collector(rootElementStyle, pageIndex); | 1123 PageRuleCollector collector(rootElementStyle, pageIndex); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1194 matchUARules(collector); | 1211 matchUARules(collector); |
1195 | 1212 |
1196 if (rulesToInclude & AuthorCSSRules) { | 1213 if (rulesToInclude & AuthorCSSRules) { |
1197 collector.setSameOriginOnly(!(rulesToInclude & CrossOriginCSSRules)); | 1214 collector.setSameOriginOnly(!(rulesToInclude & CrossOriginCSSRules)); |
1198 collector.setIncludeEmptyRules(rulesToInclude & EmptyCSSRules); | 1215 collector.setIncludeEmptyRules(rulesToInclude & EmptyCSSRules); |
1199 matchAuthorRules(element, collector); | 1216 matchAuthorRules(element, collector); |
1200 } | 1217 } |
1201 } | 1218 } |
1202 | 1219 |
1203 // -----------------------------------------------------------------------------
-------- | 1220 // -----------------------------------------------------------------------------
-------- |
1204 // this is mostly boring stuff on how to apply a certain rule to the Computedsty
le... | 1221 // this is mostly boring stuff on how to apply a certain rule to the |
| 1222 // Computedstyle... |
1205 | 1223 |
1206 bool StyleResolver::applyAnimatedProperties(StyleResolverState& state, | 1224 bool StyleResolver::applyAnimatedProperties(StyleResolverState& state, |
1207 const Element* animatingElement) { | 1225 const Element* animatingElement) { |
1208 Element* element = state.element(); | 1226 Element* element = state.element(); |
1209 ASSERT(element); | 1227 ASSERT(element); |
1210 | 1228 |
1211 // The animating element may be this element, or its pseudo element. It is | 1229 // The animating element may be this element, or its pseudo element. It is |
1212 // null when calculating the style for a potential pseudo element that has | 1230 // null when calculating the style for a potential pseudo element that has |
1213 // yet to be created. | 1231 // yet to be created. |
1214 ASSERT(animatingElement == element || !animatingElement || | 1232 ASSERT(animatingElement == element || !animatingElement || |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1277 for (auto& resolver : resolvers) | 1295 for (auto& resolver : resolvers) |
1278 resolver->setHasUnresolvedKeyframesRule(); | 1296 resolver->setHasUnresolvedKeyframesRule(); |
1279 return nullptr; | 1297 return nullptr; |
1280 } | 1298 } |
1281 | 1299 |
1282 template <CSSPropertyPriority priority> | 1300 template <CSSPropertyPriority priority> |
1283 void StyleResolver::applyAnimatedProperties( | 1301 void StyleResolver::applyAnimatedProperties( |
1284 StyleResolverState& state, | 1302 StyleResolverState& state, |
1285 const ActiveInterpolationsMap& activeInterpolationsMap) { | 1303 const ActiveInterpolationsMap& activeInterpolationsMap) { |
1286 // TODO(alancutter): Don't apply presentation attribute animations here, | 1304 // TODO(alancutter): Don't apply presentation attribute animations here, |
1287 // they should instead apply in SVGElement::collectStyleForPresentationAttribu
te(). | 1305 // they should instead apply in |
| 1306 // SVGElement::collectStyleForPresentationAttribute(). |
1288 for (const auto& entry : activeInterpolationsMap) { | 1307 for (const auto& entry : activeInterpolationsMap) { |
1289 CSSPropertyID property = entry.key.isCSSProperty() | 1308 CSSPropertyID property = entry.key.isCSSProperty() |
1290 ? entry.key.cssProperty() | 1309 ? entry.key.cssProperty() |
1291 : entry.key.presentationAttribute(); | 1310 : entry.key.presentationAttribute(); |
1292 if (!CSSPropertyPriorityData<priority>::propertyHasPriority(property)) | 1311 if (!CSSPropertyPriorityData<priority>::propertyHasPriority(property)) |
1293 continue; | 1312 continue; |
1294 const Interpolation& interpolation = *entry.value.first(); | 1313 const Interpolation& interpolation = *entry.value.first(); |
1295 if (interpolation.isInvalidatableInterpolation()) { | 1314 if (interpolation.isInvalidatableInterpolation()) { |
1296 InterpolationEnvironment environment(state); | 1315 InterpolationEnvironment environment(state); |
1297 InvalidatableInterpolation::applyStack(entry.value, environment); | 1316 InvalidatableInterpolation::applyStack(entry.value, environment); |
1298 } else { | 1317 } else { |
1299 // TODO(alancutter): Remove this old code path once animations have comple
tely migrated to InterpolationTypes. | 1318 // TODO(alancutter): Remove this old code path once animations have |
| 1319 // completely migrated to InterpolationTypes. |
1300 toStyleInterpolation(interpolation).apply(state); | 1320 toStyleInterpolation(interpolation).apply(state); |
1301 } | 1321 } |
1302 } | 1322 } |
1303 } | 1323 } |
1304 | 1324 |
1305 static inline bool isValidCueStyleProperty(CSSPropertyID id) { | 1325 static inline bool isValidCueStyleProperty(CSSPropertyID id) { |
1306 switch (id) { | 1326 switch (id) { |
1307 case CSSPropertyBackground: | 1327 case CSSPropertyBackground: |
1308 case CSSPropertyBackgroundAttachment: | 1328 case CSSPropertyBackgroundAttachment: |
1309 case CSSPropertyBackgroundClip: | 1329 case CSSPropertyBackgroundClip: |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1467 | 1487 |
1468 default: | 1488 default: |
1469 return false; | 1489 return false; |
1470 } | 1490 } |
1471 } | 1491 } |
1472 | 1492 |
1473 static bool shouldIgnoreTextTrackAuthorStyle(const Document& document) { | 1493 static bool shouldIgnoreTextTrackAuthorStyle(const Document& document) { |
1474 Settings* settings = document.settings(); | 1494 Settings* settings = document.settings(); |
1475 if (!settings) | 1495 if (!settings) |
1476 return false; | 1496 return false; |
1477 // Ignore author specified settings for text tracks when any of the user setti
ngs are present. | 1497 // Ignore author specified settings for text tracks when any of the user |
| 1498 // settings are present. |
1478 if (!settings->textTrackBackgroundColor().isEmpty() || | 1499 if (!settings->textTrackBackgroundColor().isEmpty() || |
1479 !settings->textTrackFontFamily().isEmpty() || | 1500 !settings->textTrackFontFamily().isEmpty() || |
1480 !settings->textTrackFontStyle().isEmpty() || | 1501 !settings->textTrackFontStyle().isEmpty() || |
1481 !settings->textTrackFontVariant().isEmpty() || | 1502 !settings->textTrackFontVariant().isEmpty() || |
1482 !settings->textTrackTextColor().isEmpty() || | 1503 !settings->textTrackTextColor().isEmpty() || |
1483 !settings->textTrackTextShadow().isEmpty() || | 1504 !settings->textTrackTextShadow().isEmpty() || |
1484 !settings->textTrackTextSize().isEmpty()) | 1505 !settings->textTrackTextSize().isEmpty()) |
1485 return true; | 1506 return true; |
1486 return false; | 1507 return false; |
1487 } | 1508 } |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1591 if (property == CSSPropertyAll) { | 1612 if (property == CSSPropertyAll) { |
1592 applyAllProperty<priority>(state, current.value(), inheritedOnly, | 1613 applyAllProperty<priority>(state, current.value(), inheritedOnly, |
1593 propertyWhitelistType); | 1614 propertyWhitelistType); |
1594 continue; | 1615 continue; |
1595 } | 1616 } |
1596 | 1617 |
1597 if (!isPropertyInWhitelist(propertyWhitelistType, property, document())) | 1618 if (!isPropertyInWhitelist(propertyWhitelistType, property, document())) |
1598 continue; | 1619 continue; |
1599 | 1620 |
1600 if (inheritedOnly && !current.isInherited()) { | 1621 if (inheritedOnly && !current.isInherited()) { |
1601 // If the property value is explicitly inherited, we need to apply further
non-inherited properties | 1622 // If the property value is explicitly inherited, we need to apply further |
1602 // as they might override the value inherited here. For this reason we don
't allow declarations with | 1623 // non-inherited properties as they might override the value inherited |
1603 // explicitly inherited properties to be cached. | 1624 // here. For this reason we don't allow declarations with explicitly |
| 1625 // inherited properties to be cached. |
1604 DCHECK(!current.value().isInheritedValue()); | 1626 DCHECK(!current.value().isInheritedValue()); |
1605 continue; | 1627 continue; |
1606 } | 1628 } |
1607 | 1629 |
1608 if (!CSSPropertyPriorityData<priority>::propertyHasPriority(property)) | 1630 if (!CSSPropertyPriorityData<priority>::propertyHasPriority(property)) |
1609 continue; | 1631 continue; |
1610 | 1632 |
1611 StyleBuilder::applyProperty(current.id(), state, current.value()); | 1633 StyleBuilder::applyProperty(current.id(), state, current.value()); |
1612 } | 1634 } |
1613 } | 1635 } |
1614 | 1636 |
1615 template <CSSPropertyPriority priority> | 1637 template <CSSPropertyPriority priority> |
1616 void StyleResolver::applyMatchedProperties(StyleResolverState& state, | 1638 void StyleResolver::applyMatchedProperties(StyleResolverState& state, |
1617 const MatchedPropertiesRange& range, | 1639 const MatchedPropertiesRange& range, |
1618 bool isImportant, | 1640 bool isImportant, |
1619 bool inheritedOnly) { | 1641 bool inheritedOnly) { |
1620 if (range.isEmpty()) | 1642 if (range.isEmpty()) |
1621 return; | 1643 return; |
1622 | 1644 |
1623 if (state.style()->insideLink() != NotInsideLink) { | 1645 if (state.style()->insideLink() != NotInsideLink) { |
1624 for (const auto& matchedProperties : range) { | 1646 for (const auto& matchedProperties : range) { |
1625 unsigned linkMatchType = matchedProperties.m_types.linkMatchType; | 1647 unsigned linkMatchType = matchedProperties.m_types.linkMatchType; |
1626 // FIXME: It would be nicer to pass these as arguments but that requires c
hanges in many places. | 1648 // FIXME: It would be nicer to pass these as arguments but that requires |
| 1649 // changes in many places. |
1627 state.setApplyPropertyToRegularStyle(linkMatchType & | 1650 state.setApplyPropertyToRegularStyle(linkMatchType & |
1628 CSSSelector::MatchLink); | 1651 CSSSelector::MatchLink); |
1629 state.setApplyPropertyToVisitedLinkStyle(linkMatchType & | 1652 state.setApplyPropertyToVisitedLinkStyle(linkMatchType & |
1630 CSSSelector::MatchVisited); | 1653 CSSSelector::MatchVisited); |
1631 | 1654 |
1632 applyProperties<priority>(state, matchedProperties.properties.get(), | 1655 applyProperties<priority>(state, matchedProperties.properties.get(), |
1633 isImportant, inheritedOnly, | 1656 isImportant, inheritedOnly, |
1634 static_cast<PropertyWhitelistType>( | 1657 static_cast<PropertyWhitelistType>( |
1635 matchedProperties.m_types.whitelistType)); | 1658 matchedProperties.m_types.whitelistType)); |
1636 } | 1659 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1677 bool applyInheritedOnly = false; | 1700 bool applyInheritedOnly = false; |
1678 const CachedMatchedProperties* cachedMatchedProperties = | 1701 const CachedMatchedProperties* cachedMatchedProperties = |
1679 cacheHash | 1702 cacheHash |
1680 ? m_matchedPropertiesCache.find(cacheHash, state, | 1703 ? m_matchedPropertiesCache.find(cacheHash, state, |
1681 matchResult.matchedProperties()) | 1704 matchResult.matchedProperties()) |
1682 : nullptr; | 1705 : nullptr; |
1683 | 1706 |
1684 if (cachedMatchedProperties && MatchedPropertiesCache::isCacheable(state)) { | 1707 if (cachedMatchedProperties && MatchedPropertiesCache::isCacheable(state)) { |
1685 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), | 1708 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), |
1686 matchedPropertyCacheHit, 1); | 1709 matchedPropertyCacheHit, 1); |
1687 // We can build up the style by copying non-inherited properties from an ear
lier style object built using the same exact | 1710 // We can build up the style by copying non-inherited properties from an |
1688 // style declarations. We then only need to apply the inherited properties,
if any, as their values can depend on the | 1711 // earlier style object built using the same exact style declarations. We |
1689 // element context. This is fast and saves memory by reusing the style data
structures. | 1712 // then only need to apply the inherited properties, if any, as their values |
| 1713 // can depend on the element context. This is fast and saves memory by |
| 1714 // reusing the style data structures. |
1690 state.style()->copyNonInheritedFromCached( | 1715 state.style()->copyNonInheritedFromCached( |
1691 *cachedMatchedProperties->computedStyle); | 1716 *cachedMatchedProperties->computedStyle); |
1692 if (state.parentStyle()->inheritedDataShared( | 1717 if (state.parentStyle()->inheritedDataShared( |
1693 *cachedMatchedProperties->parentComputedStyle) && | 1718 *cachedMatchedProperties->parentComputedStyle) && |
1694 !isAtShadowBoundary(element) && | 1719 !isAtShadowBoundary(element) && |
1695 (!state.distributedToInsertionPoint() || | 1720 (!state.distributedToInsertionPoint() || |
1696 state.style()->userModify() == READ_ONLY)) { | 1721 state.style()->userModify() == READ_ONLY)) { |
1697 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), | 1722 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), |
1698 matchedPropertyCacheInheritedHit, 1); | 1723 matchedPropertyCacheInheritedHit, 1); |
1699 | 1724 |
1700 EInsideLink linkStatus = state.style()->insideLink(); | 1725 EInsideLink linkStatus = state.style()->insideLink(); |
1701 // If the cache item parent style has identical inherited properties to th
e current parent style then the | 1726 // If the cache item parent style has identical inherited properties to |
1702 // resulting style will be identical too. We copy the inherited properties
over from the cache and are done. | 1727 // the current parent style then the resulting style will be identical |
| 1728 // too. We copy the inherited properties over from the cache and are done. |
1703 state.style()->inheritFrom(*cachedMatchedProperties->computedStyle); | 1729 state.style()->inheritFrom(*cachedMatchedProperties->computedStyle); |
1704 | 1730 |
1705 // Unfortunately the link status is treated like an inherited property. We
need to explicitly restore it. | 1731 // Unfortunately the link status is treated like an inherited property. We |
| 1732 // need to explicitly restore it. |
1706 state.style()->setInsideLink(linkStatus); | 1733 state.style()->setInsideLink(linkStatus); |
1707 | 1734 |
1708 updateFont(state); | 1735 updateFont(state); |
1709 | 1736 |
1710 return; | 1737 return; |
1711 } | 1738 } |
1712 applyInheritedOnly = true; | 1739 applyInheritedOnly = true; |
1713 } | 1740 } |
1714 | 1741 |
1715 // TODO(leviw): We need the proper bit for tracking whether we need to do this
work. | 1742 // TODO(leviw): We need the proper bit for tracking whether we need to do this |
| 1743 // work. |
1716 applyMatchedProperties<ResolveVariables>(state, matchResult.authorRules(), | 1744 applyMatchedProperties<ResolveVariables>(state, matchResult.authorRules(), |
1717 false, applyInheritedOnly); | 1745 false, applyInheritedOnly); |
1718 applyMatchedProperties<ResolveVariables>(state, matchResult.authorRules(), | 1746 applyMatchedProperties<ResolveVariables>(state, matchResult.authorRules(), |
1719 true, applyInheritedOnly); | 1747 true, applyInheritedOnly); |
1720 // TODO(leviw): stop recalculating every time | 1748 // TODO(leviw): stop recalculating every time |
1721 CSSVariableResolver::resolveVariableDefinitions(state); | 1749 CSSVariableResolver::resolveVariableDefinitions(state); |
1722 | 1750 |
1723 if (RuntimeEnabledFeatures::cssApplyAtRulesEnabled()) { | 1751 if (RuntimeEnabledFeatures::cssApplyAtRulesEnabled()) { |
1724 if (cacheCustomPropertiesForApplyAtRules(state, | 1752 if (cacheCustomPropertiesForApplyAtRules(state, |
1725 matchResult.authorRules())) { | 1753 matchResult.authorRules())) { |
1726 applyMatchedProperties<ResolveVariables>(state, matchResult.authorRules(), | 1754 applyMatchedProperties<ResolveVariables>(state, matchResult.authorRules(), |
1727 false, applyInheritedOnly); | 1755 false, applyInheritedOnly); |
1728 applyMatchedProperties<ResolveVariables>(state, matchResult.authorRules(), | 1756 applyMatchedProperties<ResolveVariables>(state, matchResult.authorRules(), |
1729 true, applyInheritedOnly); | 1757 true, applyInheritedOnly); |
1730 CSSVariableResolver::resolveVariableDefinitions(state); | 1758 CSSVariableResolver::resolveVariableDefinitions(state); |
1731 } | 1759 } |
1732 } | 1760 } |
1733 | 1761 |
1734 // Now we have all of the matched rules in the appropriate order. Walk the rul
es and apply | 1762 // Now we have all of the matched rules in the appropriate order. Walk the |
1735 // high-priority properties first, i.e., those properties that other propertie
s depend on. | 1763 // rules and apply high-priority properties first, i.e., those properties that |
1736 // The order is (1) high-priority not important, (2) high-priority important,
(3) normal not important | 1764 // other properties depend on. The order is (1) high-priority not important, |
1737 // and (4) normal important. | 1765 // (2) high-priority important, (3) normal not important and (4) normal |
| 1766 // important. |
1738 applyMatchedProperties<HighPropertyPriority>(state, matchResult.allRules(), | 1767 applyMatchedProperties<HighPropertyPriority>(state, matchResult.allRules(), |
1739 false, applyInheritedOnly); | 1768 false, applyInheritedOnly); |
1740 for (auto range : ImportantAuthorRanges(matchResult)) | 1769 for (auto range : ImportantAuthorRanges(matchResult)) |
1741 applyMatchedProperties<HighPropertyPriority>(state, range, true, | 1770 applyMatchedProperties<HighPropertyPriority>(state, range, true, |
1742 applyInheritedOnly); | 1771 applyInheritedOnly); |
1743 applyMatchedProperties<HighPropertyPriority>(state, matchResult.uaRules(), | 1772 applyMatchedProperties<HighPropertyPriority>(state, matchResult.uaRules(), |
1744 true, applyInheritedOnly); | 1773 true, applyInheritedOnly); |
1745 | 1774 |
1746 if (UNLIKELY(isSVGForeignObjectElement(element))) { | 1775 if (UNLIKELY(isSVGForeignObjectElement(element))) { |
1747 // LayoutSVGRoot handles zooming for the whole SVG subtree, so foreignObject
content should not be scaled again. | 1776 // LayoutSVGRoot handles zooming for the whole SVG subtree, so foreignObject |
| 1777 // content should not be scaled again. |
1748 // | 1778 // |
1749 // FIXME: The following hijacks the zoom property for foreignObject so that
children of foreignObject get the | 1779 // FIXME: The following hijacks the zoom property for foreignObject so that |
1750 // correct font-size in case of zooming. 'zoom' has HighPropertyPriority, al
ong with other font-related | 1780 // children of foreignObject get the correct font-size in case of zooming. |
1751 // properties used as input to the FontBuilder, so resetting it here may cau
se the FontBuilder to recompute the | 1781 // 'zoom' has HighPropertyPriority, along with other font-related properties |
1752 // font used as inheritable font for foreignObject content. If we want to su
pport zoom on foreignObject we'll | 1782 // used as input to the FontBuilder, so resetting it here may cause the |
| 1783 // FontBuilder to recompute the font used as inheritable font for |
| 1784 // foreignObject content. If we want to support zoom on foreignObject we'll |
1753 // need to find another way of handling the SVG zoom model. | 1785 // need to find another way of handling the SVG zoom model. |
1754 state.setEffectiveZoom(ComputedStyle::initialZoom()); | 1786 state.setEffectiveZoom(ComputedStyle::initialZoom()); |
1755 } | 1787 } |
1756 | 1788 |
1757 if (cachedMatchedProperties && | 1789 if (cachedMatchedProperties && |
1758 cachedMatchedProperties->computedStyle->effectiveZoom() != | 1790 cachedMatchedProperties->computedStyle->effectiveZoom() != |
1759 state.style()->effectiveZoom()) { | 1791 state.style()->effectiveZoom()) { |
1760 state.fontBuilder().didChangeEffectiveZoom(); | 1792 state.fontBuilder().didChangeEffectiveZoom(); |
1761 applyInheritedOnly = false; | 1793 applyInheritedOnly = false; |
1762 } | 1794 } |
1763 | 1795 |
1764 // If our font got dirtied, go ahead and update it now. | 1796 // If our font got dirtied, go ahead and update it now. |
1765 updateFont(state); | 1797 updateFont(state); |
1766 | 1798 |
1767 // Many properties depend on the font. If it changes we just apply all propert
ies. | 1799 // Many properties depend on the font. If it changes we just apply all |
| 1800 // properties. |
1768 if (cachedMatchedProperties && | 1801 if (cachedMatchedProperties && |
1769 cachedMatchedProperties->computedStyle->getFontDescription() != | 1802 cachedMatchedProperties->computedStyle->getFontDescription() != |
1770 state.style()->getFontDescription()) | 1803 state.style()->getFontDescription()) |
1771 applyInheritedOnly = false; | 1804 applyInheritedOnly = false; |
1772 | 1805 |
1773 // Now do the normal priority UA properties. | 1806 // Now do the normal priority UA properties. |
1774 applyMatchedProperties<LowPropertyPriority>(state, matchResult.uaRules(), | 1807 applyMatchedProperties<LowPropertyPriority>(state, matchResult.uaRules(), |
1775 false, applyInheritedOnly); | 1808 false, applyInheritedOnly); |
1776 | 1809 |
1777 // Cache the UA properties to pass them to LayoutTheme in adjustComputedStyle. | 1810 // Cache the UA properties to pass them to LayoutTheme in adjustComputedStyle. |
1778 state.cacheUserAgentBorderAndBackground(); | 1811 state.cacheUserAgentBorderAndBackground(); |
1779 | 1812 |
1780 // Now do the author and user normal priority properties and all the !importan
t properties. | 1813 // Now do the author and user normal priority properties and all the |
| 1814 // !important properties. |
1781 applyMatchedProperties<LowPropertyPriority>(state, matchResult.authorRules(), | 1815 applyMatchedProperties<LowPropertyPriority>(state, matchResult.authorRules(), |
1782 false, applyInheritedOnly); | 1816 false, applyInheritedOnly); |
1783 for (auto range : ImportantAuthorRanges(matchResult)) | 1817 for (auto range : ImportantAuthorRanges(matchResult)) |
1784 applyMatchedProperties<LowPropertyPriority>(state, range, true, | 1818 applyMatchedProperties<LowPropertyPriority>(state, range, true, |
1785 applyInheritedOnly); | 1819 applyInheritedOnly); |
1786 applyMatchedProperties<LowPropertyPriority>(state, matchResult.uaRules(), | 1820 applyMatchedProperties<LowPropertyPriority>(state, matchResult.uaRules(), |
1787 true, applyInheritedOnly); | 1821 true, applyInheritedOnly); |
1788 | 1822 |
1789 if (state.style()->hasAppearance() && !applyInheritedOnly) { | 1823 if (state.style()->hasAppearance() && !applyInheritedOnly) { |
1790 // Check whether the final border and background differs from the cached UA
ones. | 1824 // Check whether the final border and background differs from the cached UA |
1791 // When there is a partial match in the MatchedPropertiesCache, these flags
will already be set correctly | 1825 // ones. When there is a partial match in the MatchedPropertiesCache, these |
1792 // and the value stored in cacheUserAgentBorderAndBackground is incorrect, s
o doing this check again | 1826 // flags will already be set correctly and the value stored in |
| 1827 // cacheUserAgentBorderAndBackground is incorrect, so doing this check again |
1793 // would give the wrong answer. | 1828 // would give the wrong answer. |
1794 state.style()->setHasAuthorBackground(hasAuthorBackground(state)); | 1829 state.style()->setHasAuthorBackground(hasAuthorBackground(state)); |
1795 state.style()->setHasAuthorBorder(hasAuthorBorder(state)); | 1830 state.style()->setHasAuthorBorder(hasAuthorBorder(state)); |
1796 } | 1831 } |
1797 | 1832 |
1798 loadPendingResources(state); | 1833 loadPendingResources(state); |
1799 | 1834 |
1800 if (!cachedMatchedProperties && cacheHash && | 1835 if (!cachedMatchedProperties && cacheHash && |
1801 MatchedPropertiesCache::isCacheable(state)) { | 1836 MatchedPropertiesCache::isCacheable(state)) { |
1802 ASSERT(RuntimeEnabledFeatures::styleMatchedPropertiesCacheEnabled()); | 1837 ASSERT(RuntimeEnabledFeatures::styleMatchedPropertiesCacheEnabled()); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1913 visitor->trace(m_siblingRuleSet); | 1948 visitor->trace(m_siblingRuleSet); |
1914 visitor->trace(m_uncommonAttributeRuleSet); | 1949 visitor->trace(m_uncommonAttributeRuleSet); |
1915 visitor->trace(m_watchedSelectorsRules); | 1950 visitor->trace(m_watchedSelectorsRules); |
1916 visitor->trace(m_treeBoundaryCrossingScopes); | 1951 visitor->trace(m_treeBoundaryCrossingScopes); |
1917 visitor->trace(m_styleSharingLists); | 1952 visitor->trace(m_styleSharingLists); |
1918 visitor->trace(m_pendingStyleSheets); | 1953 visitor->trace(m_pendingStyleSheets); |
1919 visitor->trace(m_document); | 1954 visitor->trace(m_document); |
1920 } | 1955 } |
1921 | 1956 |
1922 } // namespace blink | 1957 } // namespace blink |
OLD | NEW |