OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/css/ActiveStyleSheets.h" | 5 #include "core/css/ActiveStyleSheets.h" |
6 | 6 |
7 #include "core/css/CSSStyleSheet.h" | 7 #include "core/css/CSSStyleSheet.h" |
8 #include "core/css/RuleSet.h" | 8 #include "core/css/RuleSet.h" |
9 #include "core/css/resolver/ScopedStyleResolver.h" | 9 #include "core/css/resolver/ScopedStyleResolver.h" |
10 #include "core/dom/ContainerNode.h" | 10 #include "core/dom/ContainerNode.h" |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 // Active rules for the given stylesheet changed. | 96 // Active rules for the given stylesheet changed. |
97 // DOM, CSSOM, or media query changes. | 97 // DOM, CSSOM, or media query changes. |
98 if (sheet1.second) | 98 if (sheet1.second) |
99 changedRuleSets.append(sheet1.second); | 99 changedRuleSets.append(sheet1.second); |
100 if (sheet2.second) | 100 if (sheet2.second) |
101 changedRuleSets.append(sheet2.second); | 101 changedRuleSets.append(sheet2.second); |
102 } | 102 } |
103 return changedRuleSets.size() ? ActiveSheetsChanged : NoActiveSheetsChanged; | 103 return changedRuleSets.size() ? ActiveSheetsChanged : NoActiveSheetsChanged; |
104 } | 104 } |
105 | 105 |
106 namespace { | |
107 | |
108 enum RuleSetFlags { | |
109 FontFaceRules = 1 << 0, | |
110 KeyframesRules = 1 << 1, | |
111 FullRecalcRules = 1 << 2 | |
112 }; | |
113 | |
114 unsigned getRuleSetFlags(const HeapVector<Member<RuleSet>> ruleSets) { | |
115 unsigned flags = 0; | |
116 for (auto& ruleSet : ruleSets) { | |
117 ruleSet->compactRulesIfNeeded(); | |
118 if (!ruleSet->keyframesRules().isEmpty()) | |
119 flags |= KeyframesRules; | |
120 if (!ruleSet->fontFaceRules().isEmpty()) | |
121 flags |= FontFaceRules; | |
122 if (ruleSet->needsFullRecalcForRuleSetInvalidation()) | |
123 flags |= FullRecalcRules; | |
124 } | |
125 return flags; | |
126 } | |
127 | |
128 } // namespace | |
129 | |
130 void applyRuleSetChanges(StyleEngine& engine, | |
131 TreeScope& treeScope, | |
132 const ActiveStyleSheetVector& oldStyleSheets, | |
133 const ActiveStyleSheetVector& newStyleSheets) { | |
134 HeapVector<Member<RuleSet>> changedRuleSets; | |
135 | |
136 ActiveSheetsChange change = | |
137 compareActiveStyleSheets(oldStyleSheets, newStyleSheets, changedRuleSets); | |
138 if (change == NoActiveSheetsChanged) | |
139 return; | |
140 | |
141 // TODO(rune@opera.com): engine.setNeedsGlobalRuleSetUpdate(); | |
142 | |
143 unsigned changedRuleFlags = getRuleSetFlags(changedRuleSets); | |
144 bool fontsChanged = treeScope.rootNode().isDocumentNode() && | |
145 (changedRuleFlags & FontFaceRules); | |
146 unsigned appendStartIndex = 0; | |
147 | |
148 // We don't need to clear the font cache if new sheets are appended. | |
149 if (fontsChanged && change == ActiveSheetsChanged) | |
150 engine.clearFontCache(); | |
151 | |
152 // - If all sheets were removed, we remove the ScopedStyleResolver. | |
153 // - If new sheets were appended to existing ones, start appending after the | |
154 // common prefix. | |
155 // - For other diffs, reset author style and re-add all sheets for the | |
156 // TreeScope. | |
157 if (treeScope.scopedStyleResolver()) { | |
158 if (newStyleSheets.isEmpty()) | |
159 engine.resetAuthorStyle(treeScope); | |
160 else if (change == ActiveSheetsAppended) | |
161 appendStartIndex = oldStyleSheets.size(); | |
162 else | |
163 treeScope.scopedStyleResolver()->resetAuthorStyle(); | |
164 } | |
165 | |
166 if (!newStyleSheets.isEmpty()) { | |
167 treeScope.ensureScopedStyleResolver().appendActiveStyleSheets( | |
168 appendStartIndex, newStyleSheets); | |
169 } | |
170 | |
171 if (treeScope.document().hasPendingForcedStyleRecalc()) | |
172 return; | |
173 | |
174 if (!treeScope.document().body() || | |
175 treeScope.document().hasNodesWithPlaceholderStyle()) { | |
176 treeScope.document().setNeedsStyleRecalc( | |
177 SubtreeStyleChange, StyleChangeReasonForTracing::create( | |
178 StyleChangeReason::CleanupPlaceholderStyles)); | |
179 return; | |
180 } | |
181 | |
182 if (changedRuleFlags & KeyframesRules) | |
183 ScopedStyleResolver::keyframesRulesAdded(treeScope); | |
184 | |
185 if (fontsChanged || (changedRuleFlags & FullRecalcRules)) { | |
186 ScopedStyleResolver::invalidationRootForTreeScope(treeScope) | |
187 .setNeedsStyleRecalc(SubtreeStyleChange, | |
188 StyleChangeReasonForTracing::create( | |
189 StyleChangeReason::ActiveStylesheetsUpdate)); | |
190 return; | |
191 } | |
192 | |
193 engine.scheduleInvalidationsForRuleSets(treeScope, changedRuleSets); | |
194 } | |
195 | |
196 } // namespace blink | 106 } // namespace blink |
OLD | NEW |