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) | |
128 { | |
129 ElementShadow* shadow = element->shadow(); | |
130 if (!shadow) | |
131 return; | |
132 | |
133 // Adding scoped resolver for active shadow roots for shadow host styling. | |
134 for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shad
owRoot = shadowRoot->olderShadowRoot()) { | |
135 if (shadowRoot->numberOfStyles() > 0) { | |
136 if (ScopedStyleResolver* resolver = shadowRoot->scopedStyleResolver(
)) | |
137 resolvers.append(resolver); | |
138 } | |
139 } | |
140 } | |
141 | |
142 StyleResolver::StyleResolver(Document& document) | 127 StyleResolver::StyleResolver(Document& document) |
143 : m_document(document) | 128 : m_document(document) |
144 , m_viewportStyleResolver(ViewportStyleResolver::create(&document)) | 129 , m_viewportStyleResolver(ViewportStyleResolver::create(&document)) |
145 , m_needCollectFeatures(false) | 130 , m_needCollectFeatures(false) |
146 , m_printMediaType(false) | 131 , m_printMediaType(false) |
147 , m_styleResourceLoader(&document) | 132 , m_styleResourceLoader(&document) |
148 , m_styleSharingDepth(0) | 133 , m_styleSharingDepth(0) |
149 , m_accessCount(0) | 134 , m_accessCount(0) |
150 { | 135 { |
151 FrameView* view = document.view(); | 136 FrameView* view = document.view(); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 | 210 |
226 void StyleResolver::resetRuleFeatures() | 211 void StyleResolver::resetRuleFeatures() |
227 { | 212 { |
228 // Need to recreate RuleFeatureSet. | 213 // Need to recreate RuleFeatureSet. |
229 m_features.clear(); | 214 m_features.clear(); |
230 m_siblingRuleSet.clear(); | 215 m_siblingRuleSet.clear(); |
231 m_uncommonAttributeRuleSet.clear(); | 216 m_uncommonAttributeRuleSet.clear(); |
232 m_needCollectFeatures = true; | 217 m_needCollectFeatures = true; |
233 } | 218 } |
234 | 219 |
235 void StyleResolver::addTreeBoundaryCrossingScope(ContainerNode& scope) | |
236 { | |
237 m_treeBoundaryCrossingRules.addScope(scope); | |
238 } | |
239 | |
240 void StyleResolver::resetAuthorStyle(TreeScope& treeScope) | 220 void StyleResolver::resetAuthorStyle(TreeScope& treeScope) |
241 { | 221 { |
242 m_treeBoundaryCrossingRules.removeScope(treeScope.rootNode()); | |
243 resetRuleFeatures(); | 222 resetRuleFeatures(); |
244 | 223 |
245 ScopedStyleResolver* resolver = treeScope.scopedStyleResolver(); | 224 ScopedStyleResolver* resolver = treeScope.scopedStyleResolver(); |
246 if (!resolver) | 225 if (!resolver) |
247 return; | 226 return; |
248 | 227 |
249 if (treeScope.rootNode().isDocumentNode()) { | 228 if (treeScope.rootNode().isDocumentNode()) { |
250 resolver->resetAuthorStyle(); | 229 resolver->resetAuthorStyle(); |
251 return; | 230 return; |
252 } | 231 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 | 311 |
333 void StyleResolver::popParentElement(Element& parent) | 312 void StyleResolver::popParentElement(Element& parent) |
334 { | 313 { |
335 m_selectorFilter.popParent(parent); | 314 m_selectorFilter.popParent(parent); |
336 } | 315 } |
337 | 316 |
338 StyleResolver::~StyleResolver() | 317 StyleResolver::~StyleResolver() |
339 { | 318 { |
340 } | 319 } |
341 | 320 |
342 static inline ScopedStyleResolver* scopedResolverFor(const Element* element) | 321 static inline ScopedStyleResolver* scopedResolverFor(const Element& element) |
343 { | 322 { |
344 // Ideally, returning element->treeScope().scopedStyleResolver() should be | 323 // Ideally, returning element->treeScope().scopedStyleResolver() should be |
345 // enough, but ::cue and custom pseudo elements like ::-webkit-meter-bar pie
rce | 324 // enough, but ::cue and custom pseudo elements like ::-webkit-meter-bar pie
rce |
346 // through a shadow dom boundary, yet they are not part of m_treeBoundaryCro
ssingRules. | 325 // through a shadow dom boundary, yet they are not part of treeBoundaryCross
ingRules. |
347 // The assumption here is that these rules only pierce through one boundary
and | 326 // The assumption here is that these rules only pierce through one boundary
and |
348 // that the scope of these elements do not have a style resolver due to the
fact | 327 // that the scope of these elements do not have a style resolver due to the
fact |
349 // that VTT scopes and UA shadow trees don't have <style> elements. This is | 328 // that VTT scopes and UA shadow trees don't have <style> elements. This is |
350 // backed up by the ASSERTs below. | 329 // backed up by the ASSERTs below. |
351 // | 330 // |
352 // FIXME: Make ::cue and custom pseudo elements part of boundary crossing ru
les | 331 // FIXME: Make ::cue and custom pseudo elements part of boundary crossing ru
les |
353 // when moving those rules to ScopedStyleResolver as part of issue 401359. | 332 // when moving those rules to ScopedStyleResolver as part of issue 401359. |
354 | 333 |
355 TreeScope* treeScope = &element->treeScope(); | 334 TreeScope* treeScope = &element.treeScope(); |
356 if (ScopedStyleResolver* resolver = treeScope->scopedStyleResolver()) { | 335 if (ScopedStyleResolver* resolver = treeScope->scopedStyleResolver()) { |
357 ASSERT(element->shadowPseudoId().isEmpty()); | 336 ASSERT(element.shadowPseudoId().isEmpty()); |
358 ASSERT(!element->isVTTElement()); | 337 ASSERT(!element.isVTTElement()); |
359 return resolver; | 338 return resolver; |
360 } | 339 } |
361 | 340 |
362 treeScope = treeScope->parentTreeScope(); | 341 treeScope = treeScope->parentTreeScope(); |
363 if (!treeScope) | 342 if (!treeScope) |
364 return nullptr; | 343 return nullptr; |
365 if (element->shadowPseudoId().isEmpty() && !element->isVTTElement()) | 344 if (element.shadowPseudoId().isEmpty() && !element.isVTTElement()) |
366 return nullptr; | 345 return nullptr; |
367 return treeScope->scopedStyleResolver(); | 346 return treeScope->scopedStyleResolver(); |
368 } | 347 } |
369 | 348 |
370 void StyleResolver::matchAuthorRules(Element* element, ElementRuleCollector& col
lector, bool includeEmptyRules) | 349 void StyleResolver::matchHostRules(const Element& element, ElementRuleCollector&
collector, bool includeEmptyRules) |
371 { | 350 { |
372 collector.clearMatchedRules(); | 351 ElementShadow* shadow = element.shadow(); |
| 352 if (!shadow) |
| 353 return; |
373 | 354 |
374 CascadeOrder cascadeOrder = 0; | 355 // Adding scoped resolvers for active shadow roots for shadow host styling. |
375 WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolversInShad
owTree; | 356 for (ShadowRoot* shadowRoot = shadow->oldestShadowRoot(); shadowRoot; shadow
Root = shadowRoot->youngerShadowRoot()) { |
376 collectScopedResolversForHostedShadowTrees(element, resolversInShadowTree); | 357 if (!shadowRoot->numberOfStyles()) |
| 358 continue; |
| 359 if (ScopedStyleResolver* resolver = shadowRoot->scopedStyleResolver()) { |
| 360 collector.clearMatchedRules(); |
| 361 resolver->collectMatchingShadowHostRules(collector, includeEmptyRule
s); |
| 362 collector.sortAndTransferMatchedRules(); |
| 363 } |
| 364 } |
| 365 } |
377 | 366 |
378 // Apply :host and :host-context rules from inner scopes. | 367 void StyleResolver::matchScopedRules(const Element& element, ElementRuleCollecto
r& collector, bool includeEmptyRules) |
379 for (int j = resolversInShadowTree.size() - 1; j >= 0; --j) | 368 { |
380 resolversInShadowTree.at(j)->collectMatchingShadowHostRules(collector, i
ncludeEmptyRules, ++cascadeOrder); | 369 // TODO(rune@opera.com): TreeScope::treeScopeInComposedTree can potentially
be expensive as its doing |
| 370 // composed tree traversal to find the closest tree-scope for the element in
the composed tree. Getting the |
| 371 // ancestor tree-scopes are much cheaper as we do the composed tree traversa
l for each TreeScope once and then cache |
| 372 // its composed tree parent scope as a member. |
381 | 373 |
382 // Apply normal rules from element scope. | 374 // TODO(rune@opera.com): The current implementation does not handle cascadin
g order as |
383 if (ScopedStyleResolver* resolver = scopedResolverFor(element)) | 375 // spec'ed for !important rules. |
384 resolver->collectMatchingAuthorRules(collector, includeEmptyRules, ++cas
cadeOrder); | |
385 | 376 |
386 // Apply /deep/ and ::shadow rules from outer scopes, and ::content from inn
er. | 377 ScopedStyleResolver* resolverForElementScope = scopedResolverFor(element); |
387 m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collec
tor, includeEmptyRules); | 378 |
388 collector.sortAndTransferMatchedRules(); | 379 if (!document().styleEngine().hasTreeBoundaryCrossingRules()) { |
| 380 if (!resolverForElementScope) |
| 381 return; |
| 382 collector.clearMatchedRules(); |
| 383 resolverForElementScope->collectMatchingAuthorRules(collector, includeEm
ptyRules); |
| 384 collector.sortAndTransferMatchedRules(); |
| 385 return; |
| 386 } |
| 387 |
| 388 for (TreeScope* scope = TreeScope::treeScopeInComposedTree(element); scope;
scope = scope->composedParent()) { |
| 389 if (ScopedStyleResolver* resolver = scope->scopedStyleResolver()) { |
| 390 collector.clearMatchedRules(); |
| 391 if (resolver == resolverForElementScope) |
| 392 resolver->collectMatchingAuthorRules(collector, includeEmptyRule
s); |
| 393 if (resolver->hasTreeBoundaryCrossingRules()) |
| 394 resolver->collectMatchingTreeBoundaryCrossingRules(collector, in
cludeEmptyRules); |
| 395 collector.sortAndTransferMatchedRules(); |
| 396 } |
| 397 } |
| 398 } |
| 399 |
| 400 void StyleResolver::matchAuthorRules(const Element& element, ElementRuleCollecto
r& collector, bool includeEmptyRules) |
| 401 { |
| 402 matchHostRules(element, collector, includeEmptyRules); |
| 403 matchScopedRules(element, collector, includeEmptyRules); |
389 } | 404 } |
390 | 405 |
391 void StyleResolver::matchUARules(ElementRuleCollector& collector) | 406 void StyleResolver::matchUARules(ElementRuleCollector& collector) |
392 { | 407 { |
393 collector.setMatchingUARules(true); | 408 collector.setMatchingUARules(true); |
394 | 409 |
395 CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance(
); | 410 CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance(
); |
396 RuleSet* userAgentStyleSheet = m_printMediaType ? defaultStyleSheets.default
PrintStyle() : defaultStyleSheets.defaultStyle(); | 411 RuleSet* userAgentStyleSheet = m_printMediaType ? defaultStyleSheets.default
PrintStyle() : defaultStyleSheets.defaultStyle(); |
397 matchRuleSet(collector, userAgentStyleSheet); | 412 matchRuleSet(collector, userAgentStyleSheet); |
398 | 413 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 if (state.element()->isHTMLElement()) { | 445 if (state.element()->isHTMLElement()) { |
431 bool isAuto; | 446 bool isAuto; |
432 TextDirection textDirection = toHTMLElement(state.element())->direct
ionalityIfhasDirAutoAttribute(isAuto); | 447 TextDirection textDirection = toHTMLElement(state.element())->direct
ionalityIfhasDirAutoAttribute(isAuto); |
433 if (isAuto) { | 448 if (isAuto) { |
434 state.setHasDirAutoAttribute(true); | 449 state.setHasDirAutoAttribute(true); |
435 collector.addElementStyleProperties(textDirection == LTR ? leftT
oRightDeclaration() : rightToLeftDeclaration()); | 450 collector.addElementStyleProperties(textDirection == LTR ? leftT
oRightDeclaration() : rightToLeftDeclaration()); |
436 } | 451 } |
437 } | 452 } |
438 } | 453 } |
439 | 454 |
440 matchAuthorRules(state.element(), collector, false); | 455 matchAuthorRules(*state.element(), collector, false); |
441 | 456 |
442 if (state.element()->isStyledElement()) { | 457 if (state.element()->isStyledElement()) { |
443 if (state.element()->inlineStyle()) { | 458 if (state.element()->inlineStyle()) { |
444 // Inline style is immutable as long as there is no CSSOM wrapper. | 459 // Inline style is immutable as long as there is no CSSOM wrapper. |
445 bool isInlineStyleCacheable = !state.element()->inlineStyle()->isMut
able(); | 460 bool isInlineStyleCacheable = !state.element()->inlineStyle()->isMut
able(); |
446 collector.addElementStyleProperties(state.element()->inlineStyle(),
isInlineStyleCacheable); | 461 collector.addElementStyleProperties(state.element()->inlineStyle(),
isInlineStyleCacheable); |
447 } | 462 } |
448 | 463 |
449 // Now check SMIL animation override style. | 464 // Now check SMIL animation override style. |
450 if (includeSMILProperties && state.element()->isSVGElement()) | 465 if (includeSMILProperties && state.element()->isSVGElement()) |
451 collector.addElementStyleProperties(toSVGElement(state.element())->a
nimatedSMILStyleProperties(), false /* isCacheable */); | 466 collector.addElementStyleProperties(toSVGElement(state.element())->a
nimatedSMILStyleProperties(), false /* isCacheable */); |
| 467 |
| 468 collector.finishAddInlineStyle(); |
452 } | 469 } |
453 } | 470 } |
454 | 471 |
455 PassRefPtr<ComputedStyle> StyleResolver::styleForDocument(Document& document) | 472 PassRefPtr<ComputedStyle> StyleResolver::styleForDocument(Document& document) |
456 { | 473 { |
457 const LocalFrame* frame = document.frame(); | 474 const LocalFrame* frame = document.frame(); |
458 | 475 |
459 RefPtr<ComputedStyle> documentStyle = ComputedStyle::create(); | 476 RefPtr<ComputedStyle> documentStyle = ComputedStyle::create(); |
460 documentStyle->setRTLOrdering(document.visuallyOrdered() ? VisualOrder : Log
icalOrder); | 477 documentStyle->setRTLOrdering(document.visuallyOrdered() ? VisualOrder : Log
icalOrder); |
461 documentStyle->setZoom(frame && !document.printing() ? frame->pageZoomFactor
() : 1); | 478 documentStyle->setZoom(frame && !document.printing() ? frame->pageZoomFactor
() : 1); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 | 664 |
648 // Create the style | 665 // Create the style |
649 state.setStyle(ComputedStyle::clone(elementStyle)); | 666 state.setStyle(ComputedStyle::clone(elementStyle)); |
650 | 667 |
651 // We don't need to bother with !important. Since there is only ever one | 668 // We don't need to bother with !important. Since there is only ever one |
652 // decl, there's nothing to override. So just add the first properties. | 669 // decl, there's nothing to override. So just add the first properties. |
653 // We also don't need to bother with animation properties since the only | 670 // We also don't need to bother with animation properties since the only |
654 // relevant one is animation-timing-function and we special-case that in | 671 // relevant one is animation-timing-function and we special-case that in |
655 // CSSAnimations.cpp | 672 // CSSAnimations.cpp |
656 bool inheritedOnly = false; | 673 bool inheritedOnly = false; |
657 applyMatchedProperties<HighPropertyPriority>(state, result, false, result.be
gin(), result.end(), inheritedOnly); | 674 applyMatchedProperties<HighPropertyPriority>(state, result.allRules(), false
, inheritedOnly); |
658 | 675 |
659 // If our font got dirtied, go ahead and update it now. | 676 // If our font got dirtied, go ahead and update it now. |
660 updateFont(state); | 677 updateFont(state); |
661 | 678 |
662 // Now do rest of the properties. | 679 // Now do rest of the properties. |
663 applyMatchedProperties<LowPropertyPriority>(state, result, false, result.beg
in(), result.end(), inheritedOnly); | 680 applyMatchedProperties<LowPropertyPriority>(state, result.allRules(), false,
inheritedOnly); |
664 | 681 |
665 loadPendingResources(state); | 682 loadPendingResources(state); |
666 | 683 |
667 didAccess(); | 684 didAccess(); |
668 | 685 |
669 return state.takeStyle(); | 686 return state.takeStyle(); |
670 } | 687 } |
671 | 688 |
672 // This function is used by the WebAnimations JavaScript API method animate(). | 689 // This function is used by the WebAnimations JavaScript API method animate(). |
673 // FIXME: Remove this when animate() switches away from resolution-dependent par
sing. | 690 // FIXME: Remove this when animate() switches away from resolution-dependent par
sing. |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 | 785 |
769 // Since we don't use pseudo-elements in any of our quirk/print | 786 // Since we don't use pseudo-elements in any of our quirk/print |
770 // user agent rules, don't waste time walking those rules. | 787 // user agent rules, don't waste time walking those rules. |
771 | 788 |
772 if (!baseComputedStyle) { | 789 if (!baseComputedStyle) { |
773 // Check UA, user and author rules. | 790 // Check UA, user and author rules. |
774 ElementRuleCollector collector(state.elementContext(), m_selectorFilter,
state.style()); | 791 ElementRuleCollector collector(state.elementContext(), m_selectorFilter,
state.style()); |
775 collector.setPseudoStyleRequest(pseudoStyleRequest); | 792 collector.setPseudoStyleRequest(pseudoStyleRequest); |
776 | 793 |
777 matchUARules(collector); | 794 matchUARules(collector); |
778 matchAuthorRules(state.element(), collector, false); | 795 matchAuthorRules(*state.element(), collector, false); |
779 | 796 |
780 if (collector.matchedResult().matchedProperties.isEmpty()) | 797 if (!collector.matchedResult().hasMatchedProperties()) |
781 return false; | 798 return false; |
782 | 799 |
783 applyMatchedProperties(state, collector.matchedResult()); | 800 applyMatchedProperties(state, collector.matchedResult()); |
784 applyCallbackSelectors(state); | 801 applyCallbackSelectors(state); |
785 | 802 |
786 // Cache our original display. | 803 // Cache our original display. |
787 state.style()->setOriginalDisplay(state.style()->display()); | 804 state.style()->setOriginalDisplay(state.style()->display()); |
788 | 805 |
789 // FIXME: Passing 0 as the Element* introduces a lot of complexity | 806 // FIXME: Passing 0 as the Element* introduces a lot of complexity |
790 // in the adjustComputedStyle code. | 807 // in the adjustComputedStyle code. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 PageRuleCollector collector(rootElementStyle, pageIndex); | 859 PageRuleCollector collector(rootElementStyle, pageIndex); |
843 | 860 |
844 collector.matchPageRules(CSSDefaultStyleSheets::instance().defaultPrintStyle
()); | 861 collector.matchPageRules(CSSDefaultStyleSheets::instance().defaultPrintStyle
()); |
845 | 862 |
846 if (ScopedStyleResolver* scopedResolver = document().scopedStyleResolver()) | 863 if (ScopedStyleResolver* scopedResolver = document().scopedStyleResolver()) |
847 scopedResolver->matchPageRules(collector); | 864 scopedResolver->matchPageRules(collector); |
848 | 865 |
849 bool inheritedOnly = false; | 866 bool inheritedOnly = false; |
850 | 867 |
851 const MatchResult& result = collector.matchedResult(); | 868 const MatchResult& result = collector.matchedResult(); |
852 applyMatchedProperties<HighPropertyPriority>(state, result, false, result.be
gin(), result.end(), inheritedOnly); | 869 applyMatchedProperties<HighPropertyPriority>(state, result.allRules(), false
, inheritedOnly); |
853 | 870 |
854 // If our font got dirtied, go ahead and update it now. | 871 // If our font got dirtied, go ahead and update it now. |
855 updateFont(state); | 872 updateFont(state); |
856 | 873 |
857 applyMatchedProperties<LowPropertyPriority>(state, result, false, result.beg
in(), result.end(), inheritedOnly); | 874 applyMatchedProperties<LowPropertyPriority>(state, result.allRules(), false,
inheritedOnly); |
858 | 875 |
859 loadPendingResources(state); | 876 loadPendingResources(state); |
860 | 877 |
861 didAccess(); | 878 didAccess(); |
862 | 879 |
863 // Now return the style. | 880 // Now return the style. |
864 return state.takeStyle(); | 881 return state.takeStyle(); |
865 } | 882 } |
866 | 883 |
867 PassRefPtr<ComputedStyle> StyleResolver::initialStyleForElement() | 884 PassRefPtr<ComputedStyle> StyleResolver::initialStyleForElement() |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 | 934 |
918 void StyleResolver::collectPseudoRulesForElement(Element* element, ElementRuleCo
llector& collector, PseudoId pseudoId, unsigned rulesToInclude) | 935 void StyleResolver::collectPseudoRulesForElement(Element* element, ElementRuleCo
llector& collector, PseudoId pseudoId, unsigned rulesToInclude) |
919 { | 936 { |
920 collector.setPseudoStyleRequest(PseudoStyleRequest(pseudoId)); | 937 collector.setPseudoStyleRequest(PseudoStyleRequest(pseudoId)); |
921 | 938 |
922 if (rulesToInclude & UAAndUserCSSRules) | 939 if (rulesToInclude & UAAndUserCSSRules) |
923 matchUARules(collector); | 940 matchUARules(collector); |
924 | 941 |
925 if (rulesToInclude & AuthorCSSRules) { | 942 if (rulesToInclude & AuthorCSSRules) { |
926 collector.setSameOriginOnly(!(rulesToInclude & CrossOriginCSSRules)); | 943 collector.setSameOriginOnly(!(rulesToInclude & CrossOriginCSSRules)); |
927 matchAuthorRules(element, collector, rulesToInclude & EmptyCSSRules); | 944 matchAuthorRules(*element, collector, rulesToInclude & EmptyCSSRules); |
928 } | 945 } |
929 } | 946 } |
930 | 947 |
931 // -----------------------------------------------------------------------------
-------- | 948 // -----------------------------------------------------------------------------
-------- |
932 // this is mostly boring stuff on how to apply a certain rule to the Computedsty
le... | 949 // this is mostly boring stuff on how to apply a certain rule to the Computedsty
le... |
933 | 950 |
934 bool StyleResolver::applyAnimatedProperties(StyleResolverState& state, const Ele
ment* animatingElement) | 951 bool StyleResolver::applyAnimatedProperties(StyleResolverState& state, const Ele
ment* animatingElement) |
935 { | 952 { |
936 Element* element = state.element(); | 953 Element* element = state.element(); |
937 ASSERT(element); | 954 ASSERT(element); |
(...skipping 22 matching lines...) Expand all Loading... |
960 applyAnimatedProperties<LowPropertyPriority>(state, activeInterpolationsForT
ransitions); | 977 applyAnimatedProperties<LowPropertyPriority>(state, activeInterpolationsForT
ransitions); |
961 | 978 |
962 // Start loading resources used by animations. | 979 // Start loading resources used by animations. |
963 loadPendingResources(state); | 980 loadPendingResources(state); |
964 | 981 |
965 ASSERT(!state.fontBuilder().fontDirty()); | 982 ASSERT(!state.fontBuilder().fontDirty()); |
966 | 983 |
967 return true; | 984 return true; |
968 } | 985 } |
969 | 986 |
| 987 static void collectScopedResolversForHostedShadowTrees(const Element& element, W
illBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers) |
| 988 { |
| 989 ElementShadow* shadow = element.shadow(); |
| 990 if (!shadow) |
| 991 return; |
| 992 |
| 993 // Adding scoped resolver for active shadow roots for shadow host styling. |
| 994 for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shad
owRoot = shadowRoot->olderShadowRoot()) { |
| 995 if (shadowRoot->numberOfStyles() > 0) { |
| 996 if (ScopedStyleResolver* resolver = shadowRoot->scopedStyleResolver(
)) |
| 997 resolvers.append(resolver); |
| 998 } |
| 999 } |
| 1000 } |
| 1001 |
970 StyleRuleKeyframes* StyleResolver::findKeyframesRule(const Element* element, con
st AtomicString& animationName) | 1002 StyleRuleKeyframes* StyleResolver::findKeyframesRule(const Element* element, con
st AtomicString& animationName) |
971 { | 1003 { |
972 WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolvers; | 1004 WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolvers; |
973 collectScopedResolversForHostedShadowTrees(element, resolvers); | 1005 collectScopedResolversForHostedShadowTrees(*element, resolvers); |
974 if (ScopedStyleResolver* scopedResolver = element->treeScope().scopedStyleRe
solver()) | 1006 if (ScopedStyleResolver* scopedResolver = element->treeScope().scopedStyleRe
solver()) |
975 resolvers.append(scopedResolver); | 1007 resolvers.append(scopedResolver); |
976 | 1008 |
977 for (size_t i = 0; i < resolvers.size(); ++i) { | 1009 for (size_t i = 0; i < resolvers.size(); ++i) { |
978 if (StyleRuleKeyframes* keyframesRule = resolvers[i]->keyframeStylesForA
nimation(animationName.impl())) | 1010 if (StyleRuleKeyframes* keyframesRule = resolvers[i]->keyframeStylesForA
nimation(animationName.impl())) |
979 return keyframesRule; | 1011 return keyframesRule; |
980 } | 1012 } |
981 return nullptr; | 1013 return nullptr; |
982 } | 1014 } |
983 | 1015 |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1245 } | 1277 } |
1246 | 1278 |
1247 if (!CSSPropertyPriorityData<priority>::propertyHasPriority(property)) | 1279 if (!CSSPropertyPriorityData<priority>::propertyHasPriority(property)) |
1248 continue; | 1280 continue; |
1249 | 1281 |
1250 StyleBuilder::applyProperty(current.id(), state, current.value()); | 1282 StyleBuilder::applyProperty(current.id(), state, current.value()); |
1251 } | 1283 } |
1252 } | 1284 } |
1253 | 1285 |
1254 template <CSSPropertyPriority priority> | 1286 template <CSSPropertyPriority priority> |
1255 void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
hResult& matchResult, bool isImportant, unsigned startIndex, unsigned endIndex,
bool inheritedOnly) | 1287 void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
hedPropertiesRange& range, bool isImportant, bool inheritedOnly) |
1256 { | 1288 { |
1257 if (startIndex == endIndex) | 1289 if (range.begin() == range.end()) |
1258 return; | 1290 return; |
1259 | 1291 |
1260 ASSERT_WITH_SECURITY_IMPLICATION(endIndex <= matchResult.matchedProperties.s
ize()); | |
1261 | |
1262 if (state.style()->insideLink() != NotInsideLink) { | 1292 if (state.style()->insideLink() != NotInsideLink) { |
1263 for (unsigned i = startIndex; i < endIndex; ++i) { | 1293 for (const auto& matchedProperties : range) { |
1264 const MatchedProperties& matchedProperties = matchResult.matchedProp
erties[i]; | |
1265 unsigned linkMatchType = matchedProperties.m_types.linkMatchType; | 1294 unsigned linkMatchType = matchedProperties.m_types.linkMatchType; |
1266 // FIXME: It would be nicer to pass these as arguments but that requ
ires changes in many places. | 1295 // FIXME: It would be nicer to pass these as arguments but that requ
ires changes in many places. |
1267 state.setApplyPropertyToRegularStyle(linkMatchType & CSSSelector::Ma
tchLink); | 1296 state.setApplyPropertyToRegularStyle(linkMatchType & CSSSelector::Ma
tchLink); |
1268 state.setApplyPropertyToVisitedLinkStyle(linkMatchType & CSSSelector
::MatchVisited); | 1297 state.setApplyPropertyToVisitedLinkStyle(linkMatchType & CSSSelector
::MatchVisited); |
1269 | 1298 |
1270 applyProperties<priority>(state, matchedProperties.properties.get(),
isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedPropertie
s.m_types.whitelistType)); | 1299 applyProperties<priority>(state, matchedProperties.properties.get(),
isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedPropertie
s.m_types.whitelistType)); |
1271 } | 1300 } |
1272 state.setApplyPropertyToRegularStyle(true); | 1301 state.setApplyPropertyToRegularStyle(true); |
1273 state.setApplyPropertyToVisitedLinkStyle(false); | 1302 state.setApplyPropertyToVisitedLinkStyle(false); |
1274 return; | 1303 return; |
1275 } | 1304 } |
1276 for (unsigned i = startIndex; i < endIndex; ++i) { | 1305 for (const auto& matchedProperties : range) |
1277 const MatchedProperties& matchedProperties = matchResult.matchedProperti
es[i]; | |
1278 applyProperties<priority>(state, matchedProperties.properties.get(), isI
mportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.m_
types.whitelistType)); | 1306 applyProperties<priority>(state, matchedProperties.properties.get(), isI
mportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.m_
types.whitelistType)); |
1279 } | |
1280 } | 1307 } |
1281 | 1308 |
1282 static unsigned computeMatchedPropertiesHash(const MatchedProperties* properties
, unsigned size) | 1309 static unsigned computeMatchedPropertiesHash(const MatchedProperties* properties
, unsigned size) |
1283 { | 1310 { |
1284 return StringHasher::hashMemory(properties, sizeof(MatchedProperties) * size
); | 1311 return StringHasher::hashMemory(properties, sizeof(MatchedProperties) * size
); |
1285 } | 1312 } |
1286 | 1313 |
1287 void StyleResolver::invalidateMatchedPropertiesCache() | 1314 void StyleResolver::invalidateMatchedPropertiesCache() |
1288 { | 1315 { |
1289 m_matchedPropertiesCache.clear(); | 1316 m_matchedPropertiesCache.clear(); |
1290 } | 1317 } |
1291 | 1318 |
1292 void StyleResolver::notifyResizeForViewportUnits() | 1319 void StyleResolver::notifyResizeForViewportUnits() |
1293 { | 1320 { |
1294 m_viewportStyleResolver->collectViewportRules(); | 1321 m_viewportStyleResolver->collectViewportRules(); |
1295 m_matchedPropertiesCache.clearViewportDependent(); | 1322 m_matchedPropertiesCache.clearViewportDependent(); |
1296 } | 1323 } |
1297 | 1324 |
1298 void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
hResult& matchResult) | 1325 void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
hResult& matchResult) |
1299 { | 1326 { |
1300 const Element* element = state.element(); | 1327 const Element* element = state.element(); |
1301 ASSERT(element); | 1328 ASSERT(element); |
1302 | 1329 |
1303 INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyApply, 1); | 1330 INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyApply, 1); |
1304 | 1331 |
1305 unsigned cacheHash = matchResult.isCacheable ? computeMatchedPropertiesHash(
matchResult.matchedProperties.data(), matchResult.matchedProperties.size()) : 0; | 1332 unsigned cacheHash = matchResult.isCacheable() ? computeMatchedPropertiesHas
h(matchResult.matchedProperties().data(), matchResult.matchedProperties().size()
) : 0; |
1306 bool applyInheritedOnly = false; | 1333 bool applyInheritedOnly = false; |
1307 const CachedMatchedProperties* cachedMatchedProperties = cacheHash ? m_match
edPropertiesCache.find(cacheHash, state, matchResult) : 0; | 1334 const CachedMatchedProperties* cachedMatchedProperties = cacheHash ? m_match
edPropertiesCache.find(cacheHash, state, matchResult.matchedProperties()) : 0; |
1308 | 1335 |
1309 if (cachedMatchedProperties && MatchedPropertiesCache::isCacheable(element,
*state.style(), *state.parentStyle())) { | 1336 if (cachedMatchedProperties && MatchedPropertiesCache::isCacheable(element,
*state.style(), *state.parentStyle())) { |
1310 INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheHit, 1); | 1337 INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheHit, 1); |
1311 // We can build up the style by copying non-inherited properties from an
earlier style object built using the same exact | 1338 // We can build up the style by copying non-inherited properties from an
earlier style object built using the same exact |
1312 // style declarations. We then only need to apply the inherited properti
es, if any, as their values can depend on the | 1339 // style declarations. We then only need to apply the inherited properti
es, if any, as their values can depend on the |
1313 // element context. This is fast and saves memory by reusing the style d
ata structures. | 1340 // element context. This is fast and saves memory by reusing the style d
ata structures. |
1314 state.style()->copyNonInheritedFromCached(*cachedMatchedProperties->comp
utedStyle); | 1341 state.style()->copyNonInheritedFromCached(*cachedMatchedProperties->comp
utedStyle); |
1315 if (state.parentStyle()->inheritedDataShared(*cachedMatchedProperties->p
arentComputedStyle) && !isAtShadowBoundary(element) | 1342 if (state.parentStyle()->inheritedDataShared(*cachedMatchedProperties->p
arentComputedStyle) && !isAtShadowBoundary(element) |
1316 && (!state.distributedToInsertionPoint() || state.style()->userModif
y() == READ_ONLY)) { | 1343 && (!state.distributedToInsertionPoint() || state.style()->userModif
y() == READ_ONLY)) { |
1317 INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheInheritedHi
t, 1); | 1344 INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheInheritedHi
t, 1); |
(...skipping 10 matching lines...) Expand all Loading... |
1328 | 1355 |
1329 return; | 1356 return; |
1330 } | 1357 } |
1331 applyInheritedOnly = true; | 1358 applyInheritedOnly = true; |
1332 } | 1359 } |
1333 | 1360 |
1334 // Now we have all of the matched rules in the appropriate order. Walk the r
ules and apply | 1361 // Now we have all of the matched rules in the appropriate order. Walk the r
ules and apply |
1335 // high-priority properties first, i.e., those properties that other propert
ies depend on. | 1362 // high-priority properties first, i.e., those properties that other propert
ies depend on. |
1336 // The order is (1) high-priority not important, (2) high-priority important
, (3) normal not important | 1363 // The order is (1) high-priority not important, (2) high-priority important
, (3) normal not important |
1337 // and (4) normal important. | 1364 // and (4) normal important. |
1338 applyMatchedProperties<HighPropertyPriority>(state, matchResult, false, matc
hResult.begin(), matchResult.end(), applyInheritedOnly); | 1365 applyMatchedProperties<HighPropertyPriority>(state, matchResult.allRules(),
false, applyInheritedOnly); |
1339 applyMatchedProperties<HighPropertyPriority>(state, matchResult, true, match
Result.beginAuthor(), matchResult.endAuthor(), applyInheritedOnly); | 1366 for (auto range : ImportantAuthorRanges(matchResult)) |
1340 applyMatchedProperties<HighPropertyPriority>(state, matchResult, true, match
Result.beginUA(), matchResult.endUA(), applyInheritedOnly); | 1367 applyMatchedProperties<HighPropertyPriority>(state, range, true, applyIn
heritedOnly); |
| 1368 applyMatchedProperties<HighPropertyPriority>(state, matchResult.uaRules(), t
rue, applyInheritedOnly); |
1341 | 1369 |
1342 if (UNLIKELY(isSVGForeignObjectElement(element))) { | 1370 if (UNLIKELY(isSVGForeignObjectElement(element))) { |
1343 // LayoutSVGRoot handles zooming for the whole SVG subtree, so foreignOb
ject content should not be scaled again. | 1371 // LayoutSVGRoot handles zooming for the whole SVG subtree, so foreignOb
ject content should not be scaled again. |
1344 // | 1372 // |
1345 // FIXME: The following hijacks the zoom property for foreignObject so t
hat children of foreignObject get the | 1373 // FIXME: The following hijacks the zoom property for foreignObject so t
hat children of foreignObject get the |
1346 // correct font-size in case of zooming. 'zoom' has HighPropertyPriority
, along with other font-related | 1374 // correct font-size in case of zooming. 'zoom' has HighPropertyPriority
, along with other font-related |
1347 // properties used as input to the FontBuilder, so resetting it here may
cause the FontBuilder to recompute the | 1375 // properties used as input to the FontBuilder, so resetting it here may
cause the FontBuilder to recompute the |
1348 // font used as inheritable font for foreignObject content. If we want t
o support zoom on foreignObject we'll | 1376 // font used as inheritable font for foreignObject content. If we want t
o support zoom on foreignObject we'll |
1349 // need to find another way of handling the SVG zoom model. | 1377 // need to find another way of handling the SVG zoom model. |
1350 state.setEffectiveZoom(ComputedStyle::initialZoom()); | 1378 state.setEffectiveZoom(ComputedStyle::initialZoom()); |
1351 } | 1379 } |
1352 | 1380 |
1353 if (cachedMatchedProperties && cachedMatchedProperties->computedStyle->effec
tiveZoom() != state.style()->effectiveZoom()) { | 1381 if (cachedMatchedProperties && cachedMatchedProperties->computedStyle->effec
tiveZoom() != state.style()->effectiveZoom()) { |
1354 state.fontBuilder().didChangeEffectiveZoom(); | 1382 state.fontBuilder().didChangeEffectiveZoom(); |
1355 applyInheritedOnly = false; | 1383 applyInheritedOnly = false; |
1356 } | 1384 } |
1357 | 1385 |
1358 // If our font got dirtied, go ahead and update it now. | 1386 // If our font got dirtied, go ahead and update it now. |
1359 updateFont(state); | 1387 updateFont(state); |
1360 | 1388 |
1361 // Many properties depend on the font. If it changes we just apply all prope
rties. | 1389 // Many properties depend on the font. If it changes we just apply all prope
rties. |
1362 if (cachedMatchedProperties && cachedMatchedProperties->computedStyle->fontD
escription() != state.style()->fontDescription()) | 1390 if (cachedMatchedProperties && cachedMatchedProperties->computedStyle->fontD
escription() != state.style()->fontDescription()) |
1363 applyInheritedOnly = false; | 1391 applyInheritedOnly = false; |
1364 | 1392 |
1365 // Now do the normal priority UA properties. | 1393 // Now do the normal priority UA properties. |
1366 applyMatchedProperties<LowPropertyPriority>(state, matchResult, false, match
Result.beginUA(), matchResult.endUA(), applyInheritedOnly); | 1394 applyMatchedProperties<LowPropertyPriority>(state, matchResult.uaRules(), fa
lse, applyInheritedOnly); |
1367 | 1395 |
1368 // Cache the UA properties to pass them to LayoutTheme in adjustComputedStyl
e. | 1396 // Cache the UA properties to pass them to LayoutTheme in adjustComputedStyl
e. |
1369 state.cacheUserAgentBorderAndBackground(); | 1397 state.cacheUserAgentBorderAndBackground(); |
1370 | 1398 |
1371 // Now do the author and user normal priority properties and all the !import
ant properties. | 1399 // Now do the author and user normal priority properties and all the !import
ant properties. |
1372 applyMatchedProperties<LowPropertyPriority>(state, matchResult, false, match
Result.beginAuthor(), matchResult.endAuthor(), applyInheritedOnly); | 1400 applyMatchedProperties<LowPropertyPriority>(state, matchResult.authorRules()
, false, applyInheritedOnly); |
1373 applyMatchedProperties<LowPropertyPriority>(state, matchResult, true, matchR
esult.beginAuthor(), matchResult.endAuthor(), applyInheritedOnly); | 1401 for (auto range : ImportantAuthorRanges(matchResult)) |
1374 applyMatchedProperties<LowPropertyPriority>(state, matchResult, true, matchR
esult.beginUA(), matchResult.endUA(), applyInheritedOnly); | 1402 applyMatchedProperties<LowPropertyPriority>(state, range, true, applyInh
eritedOnly); |
| 1403 applyMatchedProperties<LowPropertyPriority>(state, matchResult.uaRules(), tr
ue, applyInheritedOnly); |
1375 | 1404 |
1376 loadPendingResources(state); | 1405 loadPendingResources(state); |
1377 | 1406 |
1378 if (!cachedMatchedProperties && cacheHash && MatchedPropertiesCache::isCache
able(element, *state.style(), *state.parentStyle())) { | 1407 if (!cachedMatchedProperties && cacheHash && MatchedPropertiesCache::isCache
able(element, *state.style(), *state.parentStyle())) { |
1379 INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheAdded, 1); | 1408 INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheAdded, 1); |
1380 m_matchedPropertiesCache.add(*state.style(), *state.parentStyle(), cache
Hash, matchResult); | 1409 m_matchedPropertiesCache.add(*state.style(), *state.parentStyle(), cache
Hash, matchResult.matchedProperties()); |
1381 } | 1410 } |
1382 | 1411 |
1383 ASSERT(!state.fontBuilder().fontDirty()); | 1412 ASSERT(!state.fontBuilder().fontDirty()); |
1384 } | 1413 } |
1385 | 1414 |
1386 void StyleResolver::applyCallbackSelectors(StyleResolverState& state) | 1415 void StyleResolver::applyCallbackSelectors(StyleResolverState& state) |
1387 { | 1416 { |
1388 if (!m_watchedSelectorsRules) | 1417 if (!m_watchedSelectorsRules) |
1389 return; | 1418 return; |
1390 | 1419 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1457 { | 1486 { |
1458 #if ENABLE(OILPAN) | 1487 #if ENABLE(OILPAN) |
1459 visitor->trace(m_matchedPropertiesCache); | 1488 visitor->trace(m_matchedPropertiesCache); |
1460 visitor->trace(m_viewportDependentMediaQueryResults); | 1489 visitor->trace(m_viewportDependentMediaQueryResults); |
1461 visitor->trace(m_selectorFilter); | 1490 visitor->trace(m_selectorFilter); |
1462 visitor->trace(m_viewportStyleResolver); | 1491 visitor->trace(m_viewportStyleResolver); |
1463 visitor->trace(m_features); | 1492 visitor->trace(m_features); |
1464 visitor->trace(m_siblingRuleSet); | 1493 visitor->trace(m_siblingRuleSet); |
1465 visitor->trace(m_uncommonAttributeRuleSet); | 1494 visitor->trace(m_uncommonAttributeRuleSet); |
1466 visitor->trace(m_watchedSelectorsRules); | 1495 visitor->trace(m_watchedSelectorsRules); |
1467 visitor->trace(m_treeBoundaryCrossingRules); | |
1468 visitor->trace(m_styleResourceLoader); | 1496 visitor->trace(m_styleResourceLoader); |
1469 visitor->trace(m_styleSharingLists); | 1497 visitor->trace(m_styleSharingLists); |
1470 visitor->trace(m_pendingStyleSheets); | 1498 visitor->trace(m_pendingStyleSheets); |
1471 visitor->trace(m_document); | 1499 visitor->trace(m_document); |
1472 #endif | 1500 #endif |
1473 } | 1501 } |
1474 | 1502 |
1475 } // namespace blink | 1503 } // namespace blink |
OLD | NEW |