Index: third_party/WebKit/Source/core/dom/StyleEngine.cpp |
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.cpp b/third_party/WebKit/Source/core/dom/StyleEngine.cpp |
index fb1be1e4cc2949ffd99343fe1d90da385d0afb91..8d868c52e1c9660e1a8905c097418758c8f61d8a 100644 |
--- a/third_party/WebKit/Source/core/dom/StyleEngine.cpp |
+++ b/third_party/WebKit/Source/core/dom/StyleEngine.cpp |
@@ -140,7 +140,6 @@ void StyleEngine::injectAuthorSheet(StyleSheetContents* authorSheet) { |
m_injectedAuthorStyleSheets.append(TraceWrapperMember<CSSStyleSheet>( |
this, CSSStyleSheet::create(authorSheet, *m_document))); |
markDocumentDirty(); |
- resolverChanged(AnalyzedStyleUpdate); |
} |
CSSStyleSheet& StyleEngine::ensureInspectorStyleSheet() { |
@@ -151,7 +150,10 @@ CSSStyleSheet& StyleEngine::ensureInspectorStyleSheet() { |
StyleSheetContents::create(CSSParserContext(*m_document, nullptr)); |
m_inspectorStyleSheet = CSSStyleSheet::create(contents, *m_document); |
markDocumentDirty(); |
- resolverChanged(AnalyzedStyleUpdate); |
+ // TODO(rune@opera.com): Making the active stylesheets up-to-date here is |
+ // required by some inspector tests, at least. I theory this should not be |
+ // necessary. Need to investigate to figure out if/why. |
+ updateActiveStyle(); |
return *m_inspectorStyleSheet; |
} |
@@ -185,23 +187,10 @@ void StyleEngine::removePendingSheet(Node& styleSheetCandidateNode, |
document().didRemoveAllPendingStylesheet(); |
} |
-void StyleEngine::setNeedsActiveStyleUpdate( |
- StyleSheet* sheet, |
- StyleResolverUpdateMode updateMode) { |
- // resolverChanged() is called for inactive non-master documents because |
- // import documents are inactive documents. resolverChanged() for imports |
- // will call resolverChanged() for the master document and update the active |
- // stylesheets including the ones from the import. |
+void StyleEngine::setNeedsActiveStyleUpdate(TreeScope& treeScope) { |
if (!document().isActive() && isMaster()) |
return; |
- |
- if (sheet && document().isActive()) { |
- Node* node = sheet->ownerNode(); |
- if (node && node->isConnected()) |
- markTreeScopeDirty(node->treeScope()); |
- } |
- |
- resolverChanged(updateMode); |
+ markTreeScopeDirty(treeScope); |
} |
void StyleEngine::addStyleSheetCandidateNode(Node& node) { |
@@ -240,11 +229,15 @@ void StyleEngine::removeStyleSheetCandidateNode(Node& node, |
} |
void StyleEngine::modifiedStyleSheetCandidateNode(Node& node) { |
- if (!node.isConnected()) |
- return; |
+ if (node.isConnected()) |
+ markTreeScopeDirty(node.treeScope()); |
+} |
- markTreeScopeDirty(node.treeScope()); |
- resolverChanged(AnalyzedStyleUpdate); |
+void StyleEngine::mediaQueriesChangedInScope(TreeScope& treeScope) { |
+ if (ScopedStyleResolver* resolver = treeScope.scopedStyleResolver()) { |
+ resolver->setNeedsAppendAllSheets(); |
+ setNeedsActiveStyleUpdate(treeScope); |
+ } |
} |
void StyleEngine::watchedSelectorsChanged() { |
@@ -270,13 +263,14 @@ void StyleEngine::mediaQueryAffectingValueChanged( |
ShadowTreeStyleSheetCollection* collection = |
toShadowTreeStyleSheetCollection(styleSheetCollectionFor(*treeScope)); |
DCHECK(collection); |
- collection->clearMediaQueryRuleSetStyleSheets(); |
+ if (collection->mediaQueryAffectingValueChanged()) |
+ setNeedsActiveStyleUpdate(*treeScope); |
} |
} |
void StyleEngine::mediaQueryAffectingValueChanged() { |
- resolverChanged(FullStyleUpdate); |
- documentStyleSheetCollection().clearMediaQueryRuleSetStyleSheets(); |
+ if (documentStyleSheetCollection().mediaQueryAffectingValueChanged()) |
+ setNeedsActiveStyleUpdate(document()); |
mediaQueryAffectingValueChanged(m_activeTreeScopes); |
if (m_resolver) |
m_resolver->updateMediaType(); |
@@ -288,19 +282,18 @@ void StyleEngine::updateStyleSheetsInImport( |
HeapVector<Member<StyleSheet>> sheetsForList; |
ImportedDocumentStyleSheetCollector subcollector(parentCollector, |
sheetsForList); |
- documentStyleSheetCollection().collectStyleSheets(*this, subcollector); |
+ documentStyleSheetCollection().collectStyleSheets(subcollector); |
documentStyleSheetCollection().swapSheetsForSheetList(sheetsForList); |
} |
void StyleEngine::updateActiveStyleSheetsInShadow( |
- StyleResolverUpdateMode updateMode, |
TreeScope* treeScope, |
UnorderedTreeScopeSet& treeScopesRemoved) { |
DCHECK_NE(treeScope, m_document); |
ShadowTreeStyleSheetCollection* collection = |
toShadowTreeStyleSheetCollection(styleSheetCollectionFor(*treeScope)); |
DCHECK(collection); |
- collection->updateActiveStyleSheets(*this, updateMode); |
+ collection->updateActiveStyleSheets(); |
if (!collection->hasStyleSheetCandidateNodes()) { |
treeScopesRemoved.add(treeScope); |
// When removing TreeScope from ActiveTreeScopes, |
@@ -309,29 +302,28 @@ void StyleEngine::updateActiveStyleSheetsInShadow( |
} |
} |
-void StyleEngine::updateActiveStyleSheets(StyleResolverUpdateMode updateMode) { |
+void StyleEngine::updateActiveStyleSheets() { |
+ if (!needsActiveStyleSheetUpdate()) |
+ return; |
+ |
DCHECK(isMaster()); |
DCHECK(!document().inStyleRecalc()); |
- |
- if (!document().isActive()) |
- return; |
+ DCHECK(document().isActive()); |
TRACE_EVENT0("blink,blink_style", "StyleEngine::updateActiveStyleSheets"); |
if (shouldUpdateDocumentStyleSheetCollection()) |
- documentStyleSheetCollection().updateActiveStyleSheets(*this, updateMode); |
+ documentStyleSheetCollection().updateActiveStyleSheets(); |
if (shouldUpdateShadowTreeStyleSheetCollection()) { |
UnorderedTreeScopeSet treeScopesRemoved; |
if (m_allTreeScopesDirty) { |
for (TreeScope* treeScope : m_activeTreeScopes) |
- updateActiveStyleSheetsInShadow(updateMode, treeScope, |
- treeScopesRemoved); |
+ updateActiveStyleSheetsInShadow(treeScope, treeScopesRemoved); |
} else { |
for (TreeScope* treeScope : m_dirtyTreeScopes) |
- updateActiveStyleSheetsInShadow(updateMode, treeScope, |
- treeScopesRemoved); |
+ updateActiveStyleSheetsInShadow(treeScope, treeScopesRemoved); |
} |
for (TreeScope* treeScope : treeScopesRemoved) |
m_activeTreeScopes.remove(treeScope); |
@@ -344,31 +336,31 @@ void StyleEngine::updateActiveStyleSheets(StyleResolverUpdateMode updateMode) { |
m_allTreeScopesDirty = false; |
} |
-void StyleEngine::updateActiveStyleSheets() { |
- // TODO(rune@opera.com): collect ActiveStyleSheets here. |
-} |
- |
void StyleEngine::updateViewport() { |
if (m_viewportResolver) |
m_viewportResolver->updateViewport(documentStyleSheetCollection()); |
} |
bool StyleEngine::needsActiveStyleUpdate() const { |
- return m_viewportResolver && m_viewportResolver->needsUpdate(); |
+ return (m_viewportResolver && m_viewportResolver->needsUpdate()) || |
+ needsActiveStyleSheetUpdate() || m_globalRuleSet.isDirty(); |
} |
void StyleEngine::updateActiveStyle() { |
+ DCHECK(document().isActive()); |
updateViewport(); |
updateActiveStyleSheets(); |
m_globalRuleSet.update(document()); |
} |
-const HeapVector<Member<CSSStyleSheet>> |
-StyleEngine::activeStyleSheetsForInspector() const { |
+const ActiveStyleSheetVector StyleEngine::activeStyleSheetsForInspector() { |
+ if (document().isActive()) |
+ updateActiveStyle(); |
+ |
if (m_activeTreeScopes.isEmpty()) |
return documentStyleSheetCollection().activeAuthorStyleSheets(); |
- HeapVector<Member<CSSStyleSheet>> activeStyleSheets; |
+ ActiveStyleSheetVector activeStyleSheets; |
activeStyleSheets.appendVector( |
documentStyleSheetCollection().activeAuthorStyleSheets()); |
@@ -385,12 +377,6 @@ StyleEngine::activeStyleSheetsForInspector() const { |
} |
void StyleEngine::shadowRootRemovedFromDocument(ShadowRoot* shadowRoot) { |
- if (StyleResolver* styleResolver = resolver()) { |
- if (TreeScopeStyleSheetCollection* collection = |
- styleSheetCollectionFor(*shadowRoot)) |
- styleResolver->removePendingAuthorStyleSheets( |
- collection->activeAuthorStyleSheets()); |
- } |
m_styleSheetCollectionMap.remove(shadowRoot); |
m_activeTreeScopes.remove(shadowRoot); |
m_dirtyTreeScopes.remove(shadowRoot); |
@@ -417,28 +403,6 @@ void StyleEngine::resetAuthorStyle(TreeScope& treeScope) { |
treeScope.clearScopedStyleResolver(); |
} |
-void StyleEngine::finishAppendAuthorStyleSheets() { |
- m_globalRuleSet.markDirty(); |
- m_globalRuleSet.update(document()); |
- |
- if (!document().layoutViewItem().isNull() && |
- document().layoutViewItem().style()) |
- document().layoutViewItem().style()->font().update(fontSelector()); |
-} |
- |
-void StyleEngine::appendActiveAuthorStyleSheets() { |
- DCHECK(isMaster()); |
- |
- m_resolver->appendAuthorStyleSheets( |
- documentStyleSheetCollection().activeAuthorStyleSheets()); |
- for (TreeScope* treeScope : m_activeTreeScopes) { |
- if (TreeScopeStyleSheetCollection* collection = |
- m_styleSheetCollectionMap.get(treeScope)) |
- m_resolver->appendAuthorStyleSheets( |
- collection->activeAuthorStyleSheets()); |
- } |
-} |
- |
void StyleEngine::setRuleUsageTracker(StyleRuleUsageTracker* tracker) { |
m_tracker = tracker; |
@@ -458,13 +422,7 @@ RuleSet* StyleEngine::ruleSetForSheet(CSSStyleSheet& sheet) { |
void StyleEngine::createResolver() { |
m_resolver = StyleResolver::create(*m_document); |
- |
m_resolver->setRuleUsageTracker(m_tracker); |
- |
- // A scoped style resolver for document will be created during |
- // appendActiveAuthorStyleSheets if needed. |
- appendActiveAuthorStyleSheets(); |
- finishAppendAuthorStyleSheets(); |
} |
void StyleEngine::clearResolver() { |
@@ -497,41 +455,12 @@ void StyleEngine::clearResolver() { |
} |
} |
-void StyleEngine::clearMasterResolver() { |
- if (Document* master = this->master()) |
- master->styleEngine().clearResolver(); |
-} |
- |
void StyleEngine::didDetach() { |
clearResolver(); |
m_viewportResolver = nullptr; |
m_mediaQueryEvaluator = nullptr; |
} |
-bool StyleEngine::shouldClearResolver() const { |
- return !m_didCalculateResolver && !haveScriptBlockingStylesheetsLoaded(); |
-} |
- |
-void StyleEngine::resolverChanged(StyleResolverUpdateMode mode) { |
- if (!isMaster()) { |
- if (Document* master = this->master()) |
- master->styleEngine().resolverChanged(mode); |
- return; |
- } |
- |
- // Don't bother updating, since we haven't loaded all our style info yet |
- // and haven't calculated the style selector for the first time. |
- if (!document().isActive() || shouldClearResolver()) { |
- clearResolver(); |
- return; |
- } |
- |
- if (mode == FullStyleUpdate) |
- markAllTreeScopesDirty(); |
- m_didCalculateResolver = true; |
- updateActiveStyleSheets(mode); |
-} |
- |
void StyleEngine::clearFontCache() { |
if (m_fontSelector) |
m_fontSelector->fontFaceCache()->clearCSSConnected(); |
@@ -573,6 +502,7 @@ void StyleEngine::markTreeScopeDirty(TreeScope& scope) { |
DCHECK(m_styleSheetCollectionMap.contains(&scope)); |
m_dirtyTreeScopes.add(&scope); |
+ document().scheduleLayoutTreeUpdateIfNeeded(); |
} |
void StyleEngine::markDocumentDirty() { |
@@ -581,6 +511,8 @@ void StyleEngine::markDocumentDirty() { |
viewportRulesChanged(); |
if (document().importLoader()) |
document().importsController()->master()->styleEngine().markDocumentDirty(); |
+ else |
+ document().scheduleLayoutTreeUpdateIfNeeded(); |
} |
CSSStyleSheet* StyleEngine::createSheet(Element& element, |
@@ -615,8 +547,7 @@ CSSStyleSheet* StyleEngine::createSheet(Element& element, |
DCHECK(styleSheet); |
if (!element.isInShadowTree()) { |
styleSheet->setTitle(element.title()); |
- setPreferredStylesheetSetNameIfNotSet(element.title(), |
- DontUpdateActiveSheets); |
+ setPreferredStylesheetSetNameIfNotSet(element.title()); |
} |
return styleSheet; |
} |
@@ -691,9 +622,6 @@ void StyleEngine::classChangedForElement(const SpaceSplitString& changedClasses, |
return; |
InvalidationLists invalidationLists; |
unsigned changedSize = changedClasses.size(); |
- // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
- // updates are async. https://crbug.com/567021 |
- ensureResolver(); |
const RuleFeatureSet& features = ruleFeatureSet(); |
for (unsigned i = 0; i < changedSize; ++i) { |
features.collectInvalidationSetsForClass(invalidationLists, element, |
@@ -720,9 +648,6 @@ void StyleEngine::classChangedForElement(const SpaceSplitString& oldClasses, |
remainingClassBits.ensureSize(oldClasses.size()); |
InvalidationLists invalidationLists; |
- // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
- // updates are async. https://crbug.com/567021 |
- ensureResolver(); |
const RuleFeatureSet& features = ruleFeatureSet(); |
for (unsigned i = 0; i < newClasses.size(); ++i) { |
@@ -761,9 +686,6 @@ void StyleEngine::attributeChangedForElement(const QualifiedName& attributeName, |
return; |
InvalidationLists invalidationLists; |
- // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
- // updates are async. https://crbug.com/567021 |
- ensureResolver(); |
ruleFeatureSet().collectInvalidationSetsForAttribute(invalidationLists, |
element, attributeName); |
m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
@@ -777,9 +699,6 @@ void StyleEngine::idChangedForElement(const AtomicString& oldId, |
return; |
InvalidationLists invalidationLists; |
- // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
- // updates are async. https://crbug.com/567021 |
- ensureResolver(); |
const RuleFeatureSet& features = ruleFeatureSet(); |
if (!oldId.isEmpty()) |
features.collectInvalidationSetsForId(invalidationLists, element, oldId); |
@@ -796,9 +715,6 @@ void StyleEngine::pseudoStateChangedForElement( |
return; |
InvalidationLists invalidationLists; |
- // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
- // updates are async. https://crbug.com/567021 |
- ensureResolver(); |
ruleFeatureSet().collectInvalidationSetsForPseudoClass(invalidationLists, |
element, pseudoType); |
m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
@@ -813,9 +729,6 @@ void StyleEngine::scheduleSiblingInvalidationsForElement( |
InvalidationLists invalidationLists; |
- // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
- // updates are async. https://crbug.com/567021 |
- ensureResolver(); |
const RuleFeatureSet& features = ruleFeatureSet(); |
if (element.hasID()) { |
@@ -885,9 +798,6 @@ void StyleEngine::scheduleInvalidationsForRemovedSibling( |
void StyleEngine::scheduleNthPseudoInvalidations(ContainerNode& nthParent) { |
InvalidationLists invalidationLists; |
- // TODO(rune@opera.com): ensureResolver() can be removed once stylesheet |
- // updates are async. https://crbug.com/567021 |
- ensureResolver(); |
ruleFeatureSet().collectNthInvalidationSet(invalidationLists); |
m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, |
nthParent); |
@@ -985,9 +895,7 @@ void StyleEngine::setStatsEnabled(bool enabled) { |
m_styleResolverStats->reset(); |
} |
-void StyleEngine::setPreferredStylesheetSetNameIfNotSet( |
- const String& name, |
- ActiveSheetsUpdate activeSheetsUpdate) { |
+void StyleEngine::setPreferredStylesheetSetNameIfNotSet(const String& name) { |
if (!m_preferredStylesheetSetName.isEmpty()) |
return; |
m_preferredStylesheetSetName = name; |
@@ -997,14 +905,7 @@ void StyleEngine::setPreferredStylesheetSetNameIfNotSet( |
// and either only collects persistent style, or additionally preferred |
// style when present. |
m_selectedStylesheetSetName = name; |
- |
- // TODO(rune@opera.com): For async stylesheet update, we should always mark |
- // the TreeScope dirty here, and the synchronous active stylesheet update |
- // (resolverChanged) should go away. |
- if (activeSheetsUpdate == UpdateActiveSheets) { |
- markDocumentDirty(); |
- resolverChanged(AnalyzedStyleUpdate); |
- } |
+ markDocumentDirty(); |
} |
void StyleEngine::setSelectedStylesheetSetName(const String& name) { |
@@ -1017,7 +918,7 @@ void StyleEngine::setSelectedStylesheetSetName(const String& name) { |
} |
void StyleEngine::setHttpDefaultStyle(const String& content) { |
- setPreferredStylesheetSetNameIfNotSet(content, UpdateActiveSheets); |
+ setPreferredStylesheetSetNameIfNotSet(content); |
} |
void StyleEngine::ensureUAStyleForFullscreen() { |
@@ -1050,9 +951,13 @@ void StyleEngine::viewportRulesChanged() { |
m_viewportResolver->setNeedsCollectRules(); |
} |
-void StyleEngine::importRemoved() { |
+void StyleEngine::importAddedOrRemoved() { |
if (document().importLoader()) { |
- document().importsController()->master()->styleEngine().importRemoved(); |
+ document() |
+ .importsController() |
+ ->master() |
+ ->styleEngine() |
+ .importAddedOrRemoved(); |
return; |
} |
@@ -1066,6 +971,7 @@ void StyleEngine::importRemoved() { |
// into the document. The assumption is that removing html imports is very |
// rare. |
if (ScopedStyleResolver* resolver = document().scopedStyleResolver()) { |
+ markDocumentDirty(); |
resolver->setNeedsAppendAllSheets(); |
document().setNeedsStyleRecalc( |
SubtreeStyleChange, StyleChangeReasonForTracing::create( |