| 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 |