| Index: third_party/WebKit/Source/core/css/ActiveStyleSheets.cpp
|
| diff --git a/third_party/WebKit/Source/core/css/ActiveStyleSheets.cpp b/third_party/WebKit/Source/core/css/ActiveStyleSheets.cpp
|
| index 262510f80da0b129ddbc5833dd927e46e0edd622..c0ccd2df004ef62c3731a8d4e12dc3984d87b486 100644
|
| --- a/third_party/WebKit/Source/core/css/ActiveStyleSheets.cpp
|
| +++ b/third_party/WebKit/Source/core/css/ActiveStyleSheets.cpp
|
| @@ -6,6 +6,10 @@
|
|
|
| #include "core/css/CSSStyleSheet.h"
|
| #include "core/css/RuleSet.h"
|
| +#include "core/css/resolver/ScopedStyleResolver.h"
|
| +#include "core/dom/ContainerNode.h"
|
| +#include "core/dom/StyleChangeReason.h"
|
| +#include "core/dom/StyleEngine.h"
|
|
|
| namespace blink {
|
|
|
| @@ -99,4 +103,94 @@ ActiveSheetsChange compareActiveStyleSheets(
|
| return changedRuleSets.size() ? ActiveSheetsChanged : NoActiveSheetsChanged;
|
| }
|
|
|
| +namespace {
|
| +
|
| +enum RuleSetFlags {
|
| + FontFaceRules = 1 << 0,
|
| + KeyframesRules = 1 << 1,
|
| + FullRecalcRules = 1 << 2
|
| +};
|
| +
|
| +unsigned getRuleSetFlags(const HeapVector<Member<RuleSet>> ruleSets) {
|
| + unsigned flags = 0;
|
| + for (auto& ruleSet : ruleSets) {
|
| + ruleSet->compactRulesIfNeeded();
|
| + if (!ruleSet->keyframesRules().isEmpty())
|
| + flags |= KeyframesRules;
|
| + if (!ruleSet->fontFaceRules().isEmpty())
|
| + flags |= FontFaceRules;
|
| + if (ruleSet->needsFullRecalcForRuleSetInvalidation())
|
| + flags |= FullRecalcRules;
|
| + }
|
| + return flags;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +void applyRuleSetChanges(StyleEngine& engine,
|
| + TreeScope& treeScope,
|
| + const ActiveStyleSheetVector& oldStyleSheets,
|
| + const ActiveStyleSheetVector& newStyleSheets) {
|
| + HeapVector<Member<RuleSet>> changedRuleSets;
|
| +
|
| + ActiveSheetsChange change =
|
| + compareActiveStyleSheets(oldStyleSheets, newStyleSheets, changedRuleSets);
|
| + if (change == NoActiveSheetsChanged)
|
| + return;
|
| +
|
| + // TODO(rune@opera.com): engine.setNeedsGlobalRuleSetUpdate();
|
| +
|
| + unsigned changedRuleFlags = getRuleSetFlags(changedRuleSets);
|
| + bool fontsChanged = treeScope.rootNode().isDocumentNode() &&
|
| + (changedRuleFlags & FontFaceRules);
|
| + unsigned appendStartIndex = 0;
|
| +
|
| + // We don't need to clear the font cache if new sheets are appended.
|
| + if (fontsChanged && change == ActiveSheetsChanged)
|
| + engine.clearFontCache();
|
| +
|
| + // - If all sheets were removed, we remove the ScopedStyleResolver.
|
| + // - If new sheets were appended to existing ones, start appending after the
|
| + // common prefix.
|
| + // - For other diffs, reset author style and re-add all sheets for the
|
| + // TreeScope.
|
| + if (treeScope.scopedStyleResolver()) {
|
| + if (newStyleSheets.isEmpty())
|
| + treeScope.clearScopedStyleResolver();
|
| + else if (change == ActiveSheetsAppended)
|
| + appendStartIndex = oldStyleSheets.size();
|
| + else
|
| + treeScope.scopedStyleResolver()->resetAuthorStyle();
|
| + }
|
| +
|
| + if (!newStyleSheets.isEmpty()) {
|
| + treeScope.ensureScopedStyleResolver().appendActiveStyleSheets(
|
| + appendStartIndex, newStyleSheets);
|
| + }
|
| +
|
| + if (treeScope.document().hasPendingForcedStyleRecalc())
|
| + return;
|
| +
|
| + if (!treeScope.document().body() ||
|
| + treeScope.document().hasNodesWithPlaceholderStyle()) {
|
| + treeScope.document().setNeedsStyleRecalc(
|
| + SubtreeStyleChange, StyleChangeReasonForTracing::create(
|
| + StyleChangeReason::CleanupPlaceholderStyles));
|
| + return;
|
| + }
|
| +
|
| + if (changedRuleFlags & KeyframesRules)
|
| + ScopedStyleResolver::keyframesRulesAdded(treeScope);
|
| +
|
| + if (fontsChanged || (changedRuleFlags & FullRecalcRules)) {
|
| + ScopedStyleResolver::invalidationRootForTreeScope(treeScope)
|
| + .setNeedsStyleRecalc(SubtreeStyleChange,
|
| + StyleChangeReasonForTracing::create(
|
| + StyleChangeReason::ActiveStylesheetsUpdate));
|
| + return;
|
| + }
|
| +
|
| + engine.scheduleInvalidationsForRuleSets(treeScope, changedRuleSets);
|
| +}
|
| +
|
| } // namespace blink
|
|
|