OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All |
7 * rights reserved. | 7 * rights reserved. |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
9 * (http://www.torchmobile.com/) | 9 * (http://www.torchmobile.com/) |
10 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. | 10 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include "core/dom/StyleEngine.h" | 30 #include "core/dom/StyleEngine.h" |
31 | 31 |
32 #include "core/HTMLNames.h" | 32 #include "core/HTMLNames.h" |
33 #include "core/css/CSSDefaultStyleSheets.h" | 33 #include "core/css/CSSDefaultStyleSheets.h" |
34 #include "core/css/CSSFontSelector.h" | 34 #include "core/css/CSSFontSelector.h" |
35 #include "core/css/CSSStyleSheet.h" | 35 #include "core/css/CSSStyleSheet.h" |
36 #include "core/css/FontFaceCache.h" | 36 #include "core/css/FontFaceCache.h" |
37 #include "core/css/StyleSheetContents.h" | 37 #include "core/css/StyleSheetContents.h" |
38 #include "core/css/invalidation/InvalidationSet.h" | 38 #include "core/css/invalidation/InvalidationSet.h" |
39 #include "core/css/resolver/ScopedStyleResolver.h" | 39 #include "core/css/resolver/ScopedStyleResolver.h" |
| 40 #include "core/css/resolver/SharedStyleFinder.h" |
40 #include "core/css/resolver/ViewportStyleResolver.h" | 41 #include "core/css/resolver/ViewportStyleResolver.h" |
41 #include "core/dom/DocumentStyleSheetCollector.h" | 42 #include "core/dom/DocumentStyleSheetCollector.h" |
42 #include "core/dom/Element.h" | 43 #include "core/dom/Element.h" |
43 #include "core/dom/ElementTraversal.h" | 44 #include "core/dom/ElementTraversal.h" |
44 #include "core/dom/ProcessingInstruction.h" | 45 #include "core/dom/ProcessingInstruction.h" |
45 #include "core/dom/ShadowTreeStyleSheetCollection.h" | 46 #include "core/dom/ShadowTreeStyleSheetCollection.h" |
46 #include "core/dom/StyleChangeReason.h" | 47 #include "core/dom/StyleChangeReason.h" |
47 #include "core/dom/shadow/ShadowRoot.h" | 48 #include "core/dom/shadow/ShadowRoot.h" |
48 #include "core/frame/Settings.h" | 49 #include "core/frame/Settings.h" |
49 #include "core/html/HTMLIFrameElement.h" | 50 #include "core/html/HTMLIFrameElement.h" |
50 #include "core/html/HTMLLinkElement.h" | 51 #include "core/html/HTMLLinkElement.h" |
51 #include "core/html/HTMLSlotElement.h" | 52 #include "core/html/HTMLSlotElement.h" |
52 #include "core/html/imports/HTMLImportsController.h" | 53 #include "core/html/imports/HTMLImportsController.h" |
53 #include "core/inspector/InspectorInstrumentation.h" | 54 #include "core/inspector/InspectorInstrumentation.h" |
| 55 #include "core/layout/api/LayoutViewItem.h" |
54 #include "core/page/Page.h" | 56 #include "core/page/Page.h" |
55 #include "core/svg/SVGStyleElement.h" | 57 #include "core/svg/SVGStyleElement.h" |
56 #include "platform/fonts/FontCache.h" | 58 #include "platform/fonts/FontCache.h" |
57 #include "platform/tracing/TraceEvent.h" | 59 #include "platform/tracing/TraceEvent.h" |
58 | 60 |
59 namespace blink { | 61 namespace blink { |
60 | 62 |
61 using namespace HTMLNames; | 63 using namespace HTMLNames; |
62 | 64 |
63 StyleEngine::StyleEngine(Document& document) | 65 StyleEngine::StyleEngine(Document& document) |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 | 121 |
120 const HeapVector<TraceWrapperMember<StyleSheet>>& | 122 const HeapVector<TraceWrapperMember<StyleSheet>>& |
121 StyleEngine::styleSheetsForStyleSheetList(TreeScope& treeScope) { | 123 StyleEngine::styleSheetsForStyleSheetList(TreeScope& treeScope) { |
122 if (treeScope == m_document) | 124 if (treeScope == m_document) |
123 return documentStyleSheetCollection().styleSheetsForStyleSheetList(); | 125 return documentStyleSheetCollection().styleSheetsForStyleSheetList(); |
124 | 126 |
125 return ensureStyleSheetCollectionFor(treeScope) | 127 return ensureStyleSheetCollectionFor(treeScope) |
126 ->styleSheetsForStyleSheetList(); | 128 ->styleSheetsForStyleSheetList(); |
127 } | 129 } |
128 | 130 |
129 void StyleEngine::resetCSSFeatureFlags(const RuleFeatureSet& features) { | |
130 m_usesSiblingRules = features.usesSiblingRules(); | |
131 m_usesFirstLineRules = features.usesFirstLineRules(); | |
132 m_usesWindowInactiveSelector = features.usesWindowInactiveSelector(); | |
133 m_maxDirectAdjacentSelectors = features.maxDirectAdjacentSelectors(); | |
134 } | |
135 | |
136 void StyleEngine::injectAuthorSheet(StyleSheetContents* authorSheet) { | 131 void StyleEngine::injectAuthorSheet(StyleSheetContents* authorSheet) { |
137 m_injectedAuthorStyleSheets.append( | 132 m_injectedAuthorStyleSheets.append( |
138 CSSStyleSheet::create(authorSheet, *m_document)); | 133 CSSStyleSheet::create(authorSheet, *m_document)); |
139 markDocumentDirty(); | 134 markDocumentDirty(); |
140 resolverChanged(AnalyzedStyleUpdate); | 135 resolverChanged(AnalyzedStyleUpdate); |
141 } | 136 } |
142 | 137 |
143 CSSStyleSheet& StyleEngine::ensureInspectorStyleSheet() { | 138 CSSStyleSheet& StyleEngine::ensureInspectorStyleSheet() { |
144 if (m_inspectorStyleSheet) | 139 if (m_inspectorStyleSheet) |
145 return *m_inspectorStyleSheet; | 140 return *m_inspectorStyleSheet; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 if (!node.isConnected()) | 243 if (!node.isConnected()) |
249 return; | 244 return; |
250 | 245 |
251 TreeScope& treeScope = isStyleElement(node) ? node.treeScope() : *m_document; | 246 TreeScope& treeScope = isStyleElement(node) ? node.treeScope() : *m_document; |
252 DCHECK(isStyleElement(node) || treeScope == m_document); | 247 DCHECK(isStyleElement(node) || treeScope == m_document); |
253 markTreeScopeDirty(treeScope); | 248 markTreeScopeDirty(treeScope); |
254 resolverChanged(AnalyzedStyleUpdate); | 249 resolverChanged(AnalyzedStyleUpdate); |
255 } | 250 } |
256 | 251 |
257 void StyleEngine::watchedSelectorsChanged() { | 252 void StyleEngine::watchedSelectorsChanged() { |
258 if (m_resolver) { | 253 m_globalRuleSet.initWatchedSelectorsRuleSet(document()); |
259 m_resolver->initWatchedSelectorRules(); | 254 // TODO(rune@opera.com): Should be able to use RuleSetInvalidation here. |
260 m_resolver->resetRuleFeatures(); | |
261 } | |
262 document().setNeedsStyleRecalc(SubtreeStyleChange, | 255 document().setNeedsStyleRecalc(SubtreeStyleChange, |
263 StyleChangeReasonForTracing::create( | 256 StyleChangeReasonForTracing::create( |
264 StyleChangeReason::DeclarativeContent)); | 257 StyleChangeReason::DeclarativeContent)); |
265 } | 258 } |
266 | 259 |
267 bool StyleEngine::shouldUpdateDocumentStyleSheetCollection( | 260 bool StyleEngine::shouldUpdateDocumentStyleSheetCollection( |
268 StyleResolverUpdateMode updateMode) const { | 261 StyleResolverUpdateMode updateMode) const { |
269 return m_documentScopeDirty || updateMode == FullStyleUpdate; | 262 return m_documentScopeDirty || updateMode == FullStyleUpdate; |
270 } | 263 } |
271 | 264 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 m_treeBoundaryCrossingScopes.add(&treeScope.rootNode()); | 383 m_treeBoundaryCrossingScopes.add(&treeScope.rootNode()); |
391 } | 384 } |
392 | 385 |
393 void StyleEngine::resetAuthorStyle(TreeScope& treeScope) { | 386 void StyleEngine::resetAuthorStyle(TreeScope& treeScope) { |
394 m_treeBoundaryCrossingScopes.remove(&treeScope.rootNode()); | 387 m_treeBoundaryCrossingScopes.remove(&treeScope.rootNode()); |
395 | 388 |
396 ScopedStyleResolver* scopedResolver = treeScope.scopedStyleResolver(); | 389 ScopedStyleResolver* scopedResolver = treeScope.scopedStyleResolver(); |
397 if (!scopedResolver) | 390 if (!scopedResolver) |
398 return; | 391 return; |
399 | 392 |
400 DCHECK(m_resolver); | 393 m_globalRuleSet.markDirty(); |
401 m_resolver->resetRuleFeatures(); | |
402 if (treeScope.rootNode().isDocumentNode()) { | 394 if (treeScope.rootNode().isDocumentNode()) { |
403 scopedResolver->resetAuthorStyle(); | 395 scopedResolver->resetAuthorStyle(); |
404 return; | 396 return; |
405 } | 397 } |
406 | 398 |
407 treeScope.clearScopedStyleResolver(); | 399 treeScope.clearScopedStyleResolver(); |
408 } | 400 } |
409 | 401 |
| 402 void StyleEngine::finishAppendAuthorStyleSheets() { |
| 403 m_globalRuleSet.markDirty(); |
| 404 m_globalRuleSet.update(document()); |
| 405 |
| 406 if (!document().layoutViewItem().isNull() && |
| 407 document().layoutViewItem().style()) |
| 408 document().layoutViewItem().style()->font().update(fontSelector()); |
| 409 } |
| 410 |
410 void StyleEngine::appendActiveAuthorStyleSheets() { | 411 void StyleEngine::appendActiveAuthorStyleSheets() { |
411 DCHECK(isMaster()); | 412 DCHECK(isMaster()); |
412 | 413 |
413 viewportRulesChanged(); | 414 viewportRulesChanged(); |
414 | 415 |
415 m_resolver->appendAuthorStyleSheets( | 416 m_resolver->appendAuthorStyleSheets( |
416 documentStyleSheetCollection().activeAuthorStyleSheets()); | 417 documentStyleSheetCollection().activeAuthorStyleSheets()); |
417 for (TreeScope* treeScope : m_activeTreeScopes) { | 418 for (TreeScope* treeScope : m_activeTreeScopes) { |
418 if (TreeScopeStyleSheetCollection* collection = | 419 if (TreeScopeStyleSheetCollection* collection = |
419 m_styleSheetCollectionMap.get(treeScope)) | 420 m_styleSheetCollectionMap.get(treeScope)) |
420 m_resolver->appendAuthorStyleSheets( | 421 m_resolver->appendAuthorStyleSheets( |
421 collection->activeAuthorStyleSheets()); | 422 collection->activeAuthorStyleSheets()); |
422 } | 423 } |
423 m_resolver->finishAppendAuthorStyleSheets(); | |
424 } | 424 } |
425 | 425 |
426 void StyleEngine::createResolver() { | 426 void StyleEngine::createResolver() { |
427 m_resolver = StyleResolver::create(*m_document); | 427 m_resolver = StyleResolver::create(*m_document); |
428 | 428 |
429 // A scoped style resolver for document will be created during | 429 // A scoped style resolver for document will be created during |
430 // appendActiveAuthorStyleSheets if needed. | 430 // appendActiveAuthorStyleSheets if needed. |
431 appendActiveAuthorStyleSheets(); | 431 appendActiveAuthorStyleSheets(); |
| 432 finishAppendAuthorStyleSheets(); |
432 } | 433 } |
433 | 434 |
434 void StyleEngine::clearResolver() { | 435 void StyleEngine::clearResolver() { |
435 DCHECK(!document().inStyleRecalc()); | 436 DCHECK(!document().inStyleRecalc()); |
436 DCHECK(isMaster() || !m_resolver); | 437 DCHECK(isMaster() || !m_resolver); |
437 | 438 |
438 document().clearScopedStyleResolver(); | 439 document().clearScopedStyleResolver(); |
439 // TODO(rune@opera.com): The clearing of all shadow tree scoped style | 440 // TODO(rune@opera.com): The clearing of all shadow tree scoped style |
440 // resolvers below should not be necessary. It was introduced to fix a crash | 441 // resolvers below should not be necessary. It was introduced to fix a crash |
441 // bug (https://crbug.com/447976) when clearResolver is called from didDetach | 442 // bug (https://crbug.com/447976) when clearResolver is called from didDetach |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 return true; | 644 return true; |
644 return element.parentNode()->getStyleChangeType() >= SubtreeStyleChange; | 645 return element.parentNode()->getStyleChangeType() >= SubtreeStyleChange; |
645 } | 646 } |
646 | 647 |
647 void StyleEngine::classChangedForElement(const SpaceSplitString& changedClasses, | 648 void StyleEngine::classChangedForElement(const SpaceSplitString& changedClasses, |
648 Element& element) { | 649 Element& element) { |
649 if (shouldSkipInvalidationFor(element)) | 650 if (shouldSkipInvalidationFor(element)) |
650 return; | 651 return; |
651 InvalidationLists invalidationLists; | 652 InvalidationLists invalidationLists; |
652 unsigned changedSize = changedClasses.size(); | 653 unsigned changedSize = changedClasses.size(); |
653 RuleFeatureSet& ruleFeatureSet = | 654 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
654 ensureResolver().ensureUpdatedRuleFeatureSet(); | 655 // updates are async. https://crbug.com/567021 |
655 for (unsigned i = 0; i < changedSize; ++i) | 656 ensureResolver(); |
656 ruleFeatureSet.collectInvalidationSetsForClass(invalidationLists, element, | 657 const RuleFeatureSet& features = ruleFeatureSet(); |
657 changedClasses[i]); | 658 for (unsigned i = 0; i < changedSize; ++i) { |
| 659 features.collectInvalidationSetsForClass(invalidationLists, element, |
| 660 changedClasses[i]); |
| 661 } |
658 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, | 662 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
659 element); | 663 element); |
660 } | 664 } |
661 | 665 |
662 void StyleEngine::classChangedForElement(const SpaceSplitString& oldClasses, | 666 void StyleEngine::classChangedForElement(const SpaceSplitString& oldClasses, |
663 const SpaceSplitString& newClasses, | 667 const SpaceSplitString& newClasses, |
664 Element& element) { | 668 Element& element) { |
665 if (shouldSkipInvalidationFor(element)) | 669 if (shouldSkipInvalidationFor(element)) |
666 return; | 670 return; |
667 | 671 |
668 if (!oldClasses.size()) { | 672 if (!oldClasses.size()) { |
669 classChangedForElement(newClasses, element); | 673 classChangedForElement(newClasses, element); |
670 return; | 674 return; |
671 } | 675 } |
672 | 676 |
673 // Class vectors tend to be very short. This is faster than using a hash | 677 // Class vectors tend to be very short. This is faster than using a hash |
674 // table. | 678 // table. |
675 BitVector remainingClassBits; | 679 BitVector remainingClassBits; |
676 remainingClassBits.ensureSize(oldClasses.size()); | 680 remainingClassBits.ensureSize(oldClasses.size()); |
677 | 681 |
678 InvalidationLists invalidationLists; | 682 InvalidationLists invalidationLists; |
679 RuleFeatureSet& ruleFeatureSet = | 683 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
680 ensureResolver().ensureUpdatedRuleFeatureSet(); | 684 // updates are async. https://crbug.com/567021 |
| 685 ensureResolver(); |
| 686 const RuleFeatureSet& features = ruleFeatureSet(); |
681 | 687 |
682 for (unsigned i = 0; i < newClasses.size(); ++i) { | 688 for (unsigned i = 0; i < newClasses.size(); ++i) { |
683 bool found = false; | 689 bool found = false; |
684 for (unsigned j = 0; j < oldClasses.size(); ++j) { | 690 for (unsigned j = 0; j < oldClasses.size(); ++j) { |
685 if (newClasses[i] == oldClasses[j]) { | 691 if (newClasses[i] == oldClasses[j]) { |
686 // Mark each class that is still in the newClasses so we can skip doing | 692 // Mark each class that is still in the newClasses so we can skip doing |
687 // an n^2 search below when looking for removals. We can't break from | 693 // an n^2 search below when looking for removals. We can't break from |
688 // this loop early since a class can appear more than once. | 694 // this loop early since a class can appear more than once. |
689 remainingClassBits.quickSet(j); | 695 remainingClassBits.quickSet(j); |
690 found = true; | 696 found = true; |
691 } | 697 } |
692 } | 698 } |
693 // Class was added. | 699 // Class was added. |
694 if (!found) | 700 if (!found) { |
695 ruleFeatureSet.collectInvalidationSetsForClass(invalidationLists, element, | 701 features.collectInvalidationSetsForClass(invalidationLists, element, |
696 newClasses[i]); | 702 newClasses[i]); |
| 703 } |
697 } | 704 } |
698 | 705 |
699 for (unsigned i = 0; i < oldClasses.size(); ++i) { | 706 for (unsigned i = 0; i < oldClasses.size(); ++i) { |
700 if (remainingClassBits.quickGet(i)) | 707 if (remainingClassBits.quickGet(i)) |
701 continue; | 708 continue; |
702 // Class was removed. | 709 // Class was removed. |
703 ruleFeatureSet.collectInvalidationSetsForClass(invalidationLists, element, | 710 features.collectInvalidationSetsForClass(invalidationLists, element, |
704 oldClasses[i]); | 711 oldClasses[i]); |
705 } | 712 } |
706 | 713 |
707 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, | 714 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
708 element); | 715 element); |
709 } | 716 } |
710 | 717 |
711 void StyleEngine::attributeChangedForElement(const QualifiedName& attributeName, | 718 void StyleEngine::attributeChangedForElement(const QualifiedName& attributeName, |
712 Element& element) { | 719 Element& element) { |
713 if (shouldSkipInvalidationFor(element)) | 720 if (shouldSkipInvalidationFor(element)) |
714 return; | 721 return; |
715 | 722 |
716 InvalidationLists invalidationLists; | 723 InvalidationLists invalidationLists; |
717 ensureResolver() | 724 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
718 .ensureUpdatedRuleFeatureSet() | 725 // updates are async. https://crbug.com/567021 |
719 .collectInvalidationSetsForAttribute(invalidationLists, element, | 726 ensureResolver(); |
720 attributeName); | 727 ruleFeatureSet().collectInvalidationSetsForAttribute(invalidationLists, |
| 728 element, attributeName); |
721 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, | 729 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
722 element); | 730 element); |
723 } | 731 } |
724 | 732 |
725 void StyleEngine::idChangedForElement(const AtomicString& oldId, | 733 void StyleEngine::idChangedForElement(const AtomicString& oldId, |
726 const AtomicString& newId, | 734 const AtomicString& newId, |
727 Element& element) { | 735 Element& element) { |
728 if (shouldSkipInvalidationFor(element)) | 736 if (shouldSkipInvalidationFor(element)) |
729 return; | 737 return; |
730 | 738 |
731 InvalidationLists invalidationLists; | 739 InvalidationLists invalidationLists; |
732 RuleFeatureSet& ruleFeatureSet = | 740 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
733 ensureResolver().ensureUpdatedRuleFeatureSet(); | 741 // updates are async. https://crbug.com/567021 |
| 742 ensureResolver(); |
| 743 const RuleFeatureSet& features = ruleFeatureSet(); |
734 if (!oldId.isEmpty()) | 744 if (!oldId.isEmpty()) |
735 ruleFeatureSet.collectInvalidationSetsForId(invalidationLists, element, | 745 features.collectInvalidationSetsForId(invalidationLists, element, oldId); |
736 oldId); | |
737 if (!newId.isEmpty()) | 746 if (!newId.isEmpty()) |
738 ruleFeatureSet.collectInvalidationSetsForId(invalidationLists, element, | 747 features.collectInvalidationSetsForId(invalidationLists, element, newId); |
739 newId); | |
740 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, | 748 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
741 element); | 749 element); |
742 } | 750 } |
743 | 751 |
744 void StyleEngine::pseudoStateChangedForElement( | 752 void StyleEngine::pseudoStateChangedForElement( |
745 CSSSelector::PseudoType pseudoType, | 753 CSSSelector::PseudoType pseudoType, |
746 Element& element) { | 754 Element& element) { |
747 if (shouldSkipInvalidationFor(element)) | 755 if (shouldSkipInvalidationFor(element)) |
748 return; | 756 return; |
749 | 757 |
750 InvalidationLists invalidationLists; | 758 InvalidationLists invalidationLists; |
751 ensureResolver() | 759 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
752 .ensureUpdatedRuleFeatureSet() | 760 // updates are async. https://crbug.com/567021 |
753 .collectInvalidationSetsForPseudoClass(invalidationLists, element, | 761 ensureResolver(); |
754 pseudoType); | 762 ruleFeatureSet().collectInvalidationSetsForPseudoClass(invalidationLists, |
| 763 element, pseudoType); |
755 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, | 764 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
756 element); | 765 element); |
757 } | 766 } |
758 | 767 |
759 void StyleEngine::scheduleSiblingInvalidationsForElement( | 768 void StyleEngine::scheduleSiblingInvalidationsForElement( |
760 Element& element, | 769 Element& element, |
761 ContainerNode& schedulingParent, | 770 ContainerNode& schedulingParent, |
762 unsigned minDirectAdjacent) { | 771 unsigned minDirectAdjacent) { |
763 DCHECK(minDirectAdjacent); | 772 DCHECK(minDirectAdjacent); |
764 | 773 |
765 InvalidationLists invalidationLists; | 774 InvalidationLists invalidationLists; |
766 | 775 |
767 RuleFeatureSet& ruleFeatureSet = | 776 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
768 ensureResolver().ensureUpdatedRuleFeatureSet(); | 777 // updates are async. https://crbug.com/567021 |
| 778 ensureResolver(); |
| 779 const RuleFeatureSet& features = ruleFeatureSet(); |
769 | 780 |
770 if (element.hasID()) | 781 if (element.hasID()) { |
771 ruleFeatureSet.collectSiblingInvalidationSetForId( | 782 features.collectSiblingInvalidationSetForId(invalidationLists, element, |
772 invalidationLists, element, element.idForStyleResolution(), | 783 element.idForStyleResolution(), |
773 minDirectAdjacent); | 784 minDirectAdjacent); |
| 785 } |
774 | 786 |
775 if (element.hasClass()) { | 787 if (element.hasClass()) { |
776 const SpaceSplitString& classNames = element.classNames(); | 788 const SpaceSplitString& classNames = element.classNames(); |
777 for (size_t i = 0; i < classNames.size(); i++) | 789 for (size_t i = 0; i < classNames.size(); i++) |
778 ruleFeatureSet.collectSiblingInvalidationSetForClass( | 790 features.collectSiblingInvalidationSetForClass( |
779 invalidationLists, element, classNames[i], minDirectAdjacent); | 791 invalidationLists, element, classNames[i], minDirectAdjacent); |
780 } | 792 } |
781 | 793 |
782 for (const Attribute& attribute : element.attributes()) | 794 for (const Attribute& attribute : element.attributes()) |
783 ruleFeatureSet.collectSiblingInvalidationSetForAttribute( | 795 features.collectSiblingInvalidationSetForAttribute( |
784 invalidationLists, element, attribute.name(), minDirectAdjacent); | 796 invalidationLists, element, attribute.name(), minDirectAdjacent); |
785 | 797 |
786 ruleFeatureSet.collectUniversalSiblingInvalidationSet(invalidationLists, | 798 features.collectUniversalSiblingInvalidationSet(invalidationLists, |
787 minDirectAdjacent); | 799 minDirectAdjacent); |
788 | 800 |
789 m_styleInvalidator.scheduleSiblingInvalidationsAsDescendants( | 801 m_styleInvalidator.scheduleSiblingInvalidationsAsDescendants( |
790 invalidationLists, schedulingParent); | 802 invalidationLists, schedulingParent); |
791 } | 803 } |
792 | 804 |
793 void StyleEngine::scheduleInvalidationsForInsertedSibling( | 805 void StyleEngine::scheduleInvalidationsForInsertedSibling( |
794 Element* beforeElement, | 806 Element* beforeElement, |
795 Element& insertedElement) { | 807 Element& insertedElement) { |
796 unsigned affectedSiblings = | 808 unsigned affectedSiblings = |
797 insertedElement.parentNode()->childrenAffectedByIndirectAdjacentRules() | 809 insertedElement.parentNode()->childrenAffectedByIndirectAdjacentRules() |
798 ? UINT_MAX | 810 ? UINT_MAX |
799 : m_maxDirectAdjacentSelectors; | 811 : maxDirectAdjacentSelectors(); |
800 | 812 |
801 ContainerNode* schedulingParent = insertedElement.parentElementOrShadowRoot(); | 813 ContainerNode* schedulingParent = insertedElement.parentElementOrShadowRoot(); |
802 if (!schedulingParent) | 814 if (!schedulingParent) |
803 return; | 815 return; |
804 | 816 |
805 scheduleSiblingInvalidationsForElement(insertedElement, *schedulingParent, 1); | 817 scheduleSiblingInvalidationsForElement(insertedElement, *schedulingParent, 1); |
806 | 818 |
807 for (unsigned i = 1; beforeElement && i <= affectedSiblings; | 819 for (unsigned i = 1; beforeElement && i <= affectedSiblings; |
808 i++, beforeElement = ElementTraversal::previousSibling(*beforeElement)) | 820 i++, beforeElement = ElementTraversal::previousSibling(*beforeElement)) |
809 scheduleSiblingInvalidationsForElement(*beforeElement, *schedulingParent, | 821 scheduleSiblingInvalidationsForElement(*beforeElement, *schedulingParent, |
810 i); | 822 i); |
811 } | 823 } |
812 | 824 |
813 void StyleEngine::scheduleInvalidationsForRemovedSibling( | 825 void StyleEngine::scheduleInvalidationsForRemovedSibling( |
814 Element* beforeElement, | 826 Element* beforeElement, |
815 Element& removedElement, | 827 Element& removedElement, |
816 Element& afterElement) { | 828 Element& afterElement) { |
817 unsigned affectedSiblings = | 829 unsigned affectedSiblings = |
818 afterElement.parentNode()->childrenAffectedByIndirectAdjacentRules() | 830 afterElement.parentNode()->childrenAffectedByIndirectAdjacentRules() |
819 ? UINT_MAX | 831 ? UINT_MAX |
820 : m_maxDirectAdjacentSelectors; | 832 : maxDirectAdjacentSelectors(); |
821 | 833 |
822 ContainerNode* schedulingParent = afterElement.parentElementOrShadowRoot(); | 834 ContainerNode* schedulingParent = afterElement.parentElementOrShadowRoot(); |
823 if (!schedulingParent) | 835 if (!schedulingParent) |
824 return; | 836 return; |
825 | 837 |
826 scheduleSiblingInvalidationsForElement(removedElement, *schedulingParent, 1); | 838 scheduleSiblingInvalidationsForElement(removedElement, *schedulingParent, 1); |
827 | 839 |
828 for (unsigned i = 1; beforeElement && i <= affectedSiblings; | 840 for (unsigned i = 1; beforeElement && i <= affectedSiblings; |
829 i++, beforeElement = ElementTraversal::previousSibling(*beforeElement)) | 841 i++, beforeElement = ElementTraversal::previousSibling(*beforeElement)) |
830 scheduleSiblingInvalidationsForElement(*beforeElement, *schedulingParent, | 842 scheduleSiblingInvalidationsForElement(*beforeElement, *schedulingParent, |
831 i); | 843 i); |
832 } | 844 } |
833 | 845 |
834 void StyleEngine::scheduleNthPseudoInvalidations(ContainerNode& nthParent) { | 846 void StyleEngine::scheduleNthPseudoInvalidations(ContainerNode& nthParent) { |
835 InvalidationLists invalidationLists; | 847 InvalidationLists invalidationLists; |
836 ensureResolver().ensureUpdatedRuleFeatureSet().collectNthInvalidationSet( | 848 // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
837 invalidationLists); | 849 // updates are async. https://crbug.com/567021 |
| 850 ensureResolver(); |
| 851 ruleFeatureSet().collectNthInvalidationSet(invalidationLists); |
838 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, | 852 m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
839 nthParent); | 853 nthParent); |
840 } | 854 } |
841 | 855 |
842 void StyleEngine::scheduleRuleSetInvalidationsForElement( | 856 void StyleEngine::scheduleRuleSetInvalidationsForElement( |
843 Element& element, | 857 Element& element, |
844 const HeapVector<Member<RuleSet>>& ruleSets) { | 858 const HeapVector<Member<RuleSet>>& ruleSets) { |
845 AtomicString id; | 859 AtomicString id; |
846 const SpaceSplitString* classNames = nullptr; | 860 const SpaceSplitString* classNames = nullptr; |
847 | 861 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 // has no other effect than the ability to read back the set value using | 973 // has no other effect than the ability to read back the set value using |
960 // the same api. If it did have an effect, we should have marked the | 974 // the same api. If it did have an effect, we should have marked the |
961 // document scope dirty and triggered an update of the active stylesheets | 975 // document scope dirty and triggered an update of the active stylesheets |
962 // from here. | 976 // from here. |
963 } | 977 } |
964 | 978 |
965 void StyleEngine::setHttpDefaultStyle(const String& content) { | 979 void StyleEngine::setHttpDefaultStyle(const String& content) { |
966 setPreferredStylesheetSetNameIfNotSet(content, UpdateActiveSheets); | 980 setPreferredStylesheetSetNameIfNotSet(content, UpdateActiveSheets); |
967 } | 981 } |
968 | 982 |
969 void StyleEngine::ensureFullscreenUAStyle() { | 983 void StyleEngine::ensureUAStyleForFullscreen() { |
| 984 if (m_globalRuleSet.hasFullscreenUAStyle()) |
| 985 return; |
970 CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetForFullscreen(); | 986 CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetForFullscreen(); |
971 if (!m_resolver) | 987 m_globalRuleSet.markDirty(); |
972 return; | 988 m_globalRuleSet.update(document()); |
973 if (!m_resolver->hasFullscreenUAStyle()) | 989 } |
974 m_resolver->resetRuleFeatures(); | 990 |
| 991 void StyleEngine::ensureUAStyleForElement(const Element& element) { |
| 992 if (CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetsForElement( |
| 993 element)) { |
| 994 m_globalRuleSet.markDirty(); |
| 995 m_globalRuleSet.update(document()); |
| 996 } |
| 997 } |
| 998 |
| 999 bool StyleEngine::hasRulesForId(const AtomicString& id) const { |
| 1000 return m_globalRuleSet.ruleFeatureSet().hasSelectorForId(id); |
975 } | 1001 } |
976 | 1002 |
977 void StyleEngine::initialViewportChanged() { | 1003 void StyleEngine::initialViewportChanged() { |
978 if (!m_viewportResolver) | 1004 if (!m_viewportResolver) |
979 return; | 1005 return; |
980 | 1006 |
981 m_viewportResolver->initialViewportChanged(); | 1007 m_viewportResolver->initialViewportChanged(); |
982 | 1008 |
983 // TODO(rune@opera.com): for async stylesheet update, updateViewport() should | 1009 // TODO(rune@opera.com): for async stylesheet update, updateViewport() should |
984 // be called as part of the lifecycle update for active style. Synchronous for | 1010 // be called as part of the lifecycle update for active style. Synchronous for |
985 // now. | 1011 // now. |
986 m_viewportResolver->updateViewport(documentStyleSheetCollection()); | 1012 m_viewportResolver->updateViewport(documentStyleSheetCollection()); |
987 } | 1013 } |
988 | 1014 |
989 void StyleEngine::viewportRulesChanged() { | 1015 void StyleEngine::viewportRulesChanged() { |
990 if (!m_viewportResolver) | 1016 if (!m_viewportResolver) |
991 return; | 1017 return; |
992 m_viewportResolver->setNeedsCollectRules(); | 1018 m_viewportResolver->setNeedsCollectRules(); |
993 | 1019 |
994 // TODO(rune@opera.com): for async stylesheet update, updateViewport() should | 1020 // TODO(rune@opera.com): for async stylesheet update, updateViewport() should |
995 // be called as part of the lifecycle update for active style. Synchronous for | 1021 // be called as part of the lifecycle update for active style. Synchronous for |
996 // now. | 1022 // now. |
997 m_viewportResolver->updateViewport(documentStyleSheetCollection()); | 1023 m_viewportResolver->updateViewport(documentStyleSheetCollection()); |
998 } | 1024 } |
999 | 1025 |
| 1026 PassRefPtr<ComputedStyle> StyleEngine::findSharedStyle( |
| 1027 const ElementResolveContext& elementResolveContext) { |
| 1028 DCHECK(m_resolver); |
| 1029 return SharedStyleFinder( |
| 1030 elementResolveContext, m_globalRuleSet.ruleFeatureSet(), |
| 1031 m_globalRuleSet.siblingRuleSet(), |
| 1032 m_globalRuleSet.uncommonAttributeRuleSet(), *m_resolver) |
| 1033 .findSharedStyle(); |
| 1034 } |
| 1035 |
1000 DEFINE_TRACE(StyleEngine) { | 1036 DEFINE_TRACE(StyleEngine) { |
1001 visitor->trace(m_document); | 1037 visitor->trace(m_document); |
1002 visitor->trace(m_injectedAuthorStyleSheets); | 1038 visitor->trace(m_injectedAuthorStyleSheets); |
1003 visitor->trace(m_inspectorStyleSheet); | 1039 visitor->trace(m_inspectorStyleSheet); |
1004 visitor->trace(m_documentStyleSheetCollection); | 1040 visitor->trace(m_documentStyleSheetCollection); |
1005 visitor->trace(m_styleSheetCollectionMap); | 1041 visitor->trace(m_styleSheetCollectionMap); |
| 1042 visitor->trace(m_dirtyTreeScopes); |
| 1043 visitor->trace(m_activeTreeScopes); |
| 1044 visitor->trace(m_treeBoundaryCrossingScopes); |
| 1045 visitor->trace(m_globalRuleSet); |
1006 visitor->trace(m_resolver); | 1046 visitor->trace(m_resolver); |
1007 visitor->trace(m_viewportResolver); | 1047 visitor->trace(m_viewportResolver); |
1008 visitor->trace(m_styleInvalidator); | 1048 visitor->trace(m_styleInvalidator); |
1009 visitor->trace(m_dirtyTreeScopes); | |
1010 visitor->trace(m_activeTreeScopes); | |
1011 visitor->trace(m_treeBoundaryCrossingScopes); | |
1012 visitor->trace(m_fontSelector); | 1049 visitor->trace(m_fontSelector); |
1013 visitor->trace(m_textToSheetCache); | 1050 visitor->trace(m_textToSheetCache); |
1014 visitor->trace(m_sheetToTextCache); | 1051 visitor->trace(m_sheetToTextCache); |
1015 CSSFontSelectorClient::trace(visitor); | 1052 CSSFontSelectorClient::trace(visitor); |
1016 } | 1053 } |
1017 | 1054 |
1018 DEFINE_TRACE_WRAPPERS(StyleEngine) { | 1055 DEFINE_TRACE_WRAPPERS(StyleEngine) { |
1019 for (auto sheet : m_injectedAuthorStyleSheets) { | 1056 for (auto sheet : m_injectedAuthorStyleSheets) { |
1020 visitor->traceWrappers(sheet); | 1057 visitor->traceWrappers(sheet); |
1021 } | 1058 } |
1022 visitor->traceWrappers(m_documentStyleSheetCollection); | 1059 visitor->traceWrappers(m_documentStyleSheetCollection); |
1023 } | 1060 } |
1024 | 1061 |
1025 } // namespace blink | 1062 } // namespace blink |
OLD | NEW |