- Revision
- 253949
- Author
- [email protected]
- Date
- 2019-12-30 12:16:54 -0800 (Mon, 30 Dec 2019)
Log Message
Style invalidation cleanups
https://bugs.webkit.org/show_bug.cgi?id=205644
Reviewed by Zalan Bujtas.
Move more of the invalidation code from Style::Scope to Style::Invalidator.
* style/StyleInvalidator.cpp:
(WebCore::Style::Invalidator::invalidateStyle):
(WebCore::Style::Invalidator::invalidateAllStyle):
(WebCore::Style::Invalidator::invalidateHostAndSlottedStyleIfNeeded):
* style/StyleInvalidator.h:
* style/StyleScope.cpp:
(WebCore::Style::Scope::analyzeStyleSheetChange):
Return StyleSheetChange struct.
(WebCore::Style::Scope::updateActiveStyleSheets):
(WebCore::Style::Scope::invalidateStyleAfterStyleSheetChange):
Use StyleSheetChange to invalidate the style.
(WebCore::Style::Scope::updateResolver):
(WebCore::Style::Scope::scheduleUpdate):
(WebCore::Style::Scope::evaluateMediaQueries):
(WebCore::Style::invalidateHostAndSlottedStyleIfNeeded): Deleted.
* style/StyleScope.h:
(WebCore::Style::Scope::document):
(WebCore::Style::Scope::shadowRoot const):
(WebCore::Style::Scope::shadowRoot):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (253948 => 253949)
--- trunk/Source/WebCore/ChangeLog 2019-12-30 18:25:36 UTC (rev 253948)
+++ trunk/Source/WebCore/ChangeLog 2019-12-30 20:16:54 UTC (rev 253949)
@@ -1,3 +1,36 @@
+2019-12-30 Antti Koivisto <[email protected]>
+
+ Style invalidation cleanups
+ https://bugs.webkit.org/show_bug.cgi?id=205644
+
+ Reviewed by Zalan Bujtas.
+
+ Move more of the invalidation code from Style::Scope to Style::Invalidator.
+
+ * style/StyleInvalidator.cpp:
+ (WebCore::Style::Invalidator::invalidateStyle):
+ (WebCore::Style::Invalidator::invalidateAllStyle):
+ (WebCore::Style::Invalidator::invalidateHostAndSlottedStyleIfNeeded):
+ * style/StyleInvalidator.h:
+ * style/StyleScope.cpp:
+ (WebCore::Style::Scope::analyzeStyleSheetChange):
+
+ Return StyleSheetChange struct.
+
+ (WebCore::Style::Scope::updateActiveStyleSheets):
+ (WebCore::Style::Scope::invalidateStyleAfterStyleSheetChange):
+
+ Use StyleSheetChange to invalidate the style.
+
+ (WebCore::Style::Scope::updateResolver):
+ (WebCore::Style::Scope::scheduleUpdate):
+ (WebCore::Style::Scope::evaluateMediaQueries):
+ (WebCore::Style::invalidateHostAndSlottedStyleIfNeeded): Deleted.
+ * style/StyleScope.h:
+ (WebCore::Style::Scope::document):
+ (WebCore::Style::Scope::shadowRoot const):
+ (WebCore::Style::Scope::shadowRoot):
+
2019-12-30 Zalan Bujtas <[email protected]>
[LFC][IFC] Fix imported/w3c/web-platform-tests/css/css-text/white-space/white-space-wrap-after-nowrap-001.html
Modified: trunk/Source/WebCore/style/StyleInvalidator.cpp (253948 => 253949)
--- trunk/Source/WebCore/style/StyleInvalidator.cpp 2019-12-30 18:25:36 UTC (rev 253948)
+++ trunk/Source/WebCore/style/StyleInvalidator.cpp 2019-12-30 20:16:54 UTC (rev 253949)
@@ -37,6 +37,7 @@
#include "ShadowRoot.h"
#include "StyleResolver.h"
#include "StyleRuleImport.h"
+#include "StyleScope.h"
#include "StyleScopeRuleSets.h"
#include "StyleSheetContents.h"
#include <wtf/SetForScope.h>
@@ -212,6 +213,21 @@
invalidateStyleForTree(*documentElement, &filter);
}
+void Invalidator::invalidateStyle(Scope& scope)
+{
+ if (m_dirtiesAllStyle) {
+ invalidateAllStyle(scope);
+ return;
+ }
+
+ if (auto* shadowRoot = scope.shadowRoot()) {
+ invalidateStyle(*shadowRoot);
+ return;
+ }
+
+ invalidateStyle(scope.document());
+}
+
void Invalidator::invalidateStyle(ShadowRoot& shadowRoot)
{
ASSERT(!m_dirtiesAllStyle);
@@ -337,5 +353,34 @@
}
}
+void Invalidator::invalidateAllStyle(Scope& scope)
+{
+ if (auto* shadowRoot = scope.shadowRoot()) {
+ for (auto& shadowChild : childrenOfType<Element>(*shadowRoot))
+ shadowChild.invalidateStyleForSubtreeInternal();
+ invalidateHostAndSlottedStyleIfNeeded(*shadowRoot);
+ return;
+ }
+
+ scope.document().scheduleFullStyleRebuild();
}
+
+void Invalidator::invalidateHostAndSlottedStyleIfNeeded(ShadowRoot& shadowRoot)
+{
+ auto& host = *shadowRoot.host();
+ auto* resolver = shadowRoot.styleScope().resolverIfExists();
+ if (!resolver)
+ return;
+ auto& authorStyle = resolver->ruleSets().authorStyle();
+
+ if (!authorStyle.hostPseudoClassRules().isEmpty())
+ host.invalidateStyleInternal();
+
+ if (!authorStyle.slottedPseudoElementRules().isEmpty()) {
+ for (auto& shadowChild : childrenOfType<Element>(host))
+ shadowChild.invalidateStyleInternal();
+ }
}
+
+}
+}
Modified: trunk/Source/WebCore/style/StyleInvalidator.h (253948 => 253949)
--- trunk/Source/WebCore/style/StyleInvalidator.h 2019-12-30 18:25:36 UTC (rev 253948)
+++ trunk/Source/WebCore/style/StyleInvalidator.h 2019-12-30 20:16:54 UTC (rev 253949)
@@ -35,6 +35,7 @@
class Document;
class Element;
class MediaQueryEvaluator;
+class Scope;
class SelectorFilter;
class ShadowRoot;
class StyleSheetContents;
@@ -52,6 +53,7 @@
bool dirtiesAllStyle() const { return m_dirtiesAllStyle; }
void invalidateStyle(Document&);
+ void invalidateStyle(Scope&);
void invalidateStyle(ShadowRoot&);
void invalidateStyle(Element&);
@@ -60,6 +62,8 @@
using MatchElementRuleSets = HashMap<MatchElement, InvalidationRuleSetVector, WTF::IntHash<MatchElement>, WTF::StrongEnumHashTraits<MatchElement>>;
static void addToMatchElementRuleSets(Invalidator::MatchElementRuleSets&, const InvalidationRuleSet&);
static void invalidateWithMatchElementRuleSets(Element&, const MatchElementRuleSets&);
+ static void invalidateAllStyle(Scope&);
+ static void invalidateHostAndSlottedStyleIfNeeded(ShadowRoot&);
private:
enum class CheckDescendants { Yes, No };
Modified: trunk/Source/WebCore/style/StyleScope.cpp (253948 => 253949)
--- trunk/Source/WebCore/style/StyleScope.cpp 2019-12-30 18:25:36 UTC (rev 253948)
+++ trunk/Source/WebCore/style/StyleScope.cpp 2019-12-30 20:16:54 UTC (rev 253949)
@@ -381,32 +381,29 @@
}
}
-Scope::ResolverUpdateType Scope::analyzeStyleSheetChange(const Vector<RefPtr<CSSStyleSheet>>& newStylesheets, bool& requiresFullStyleRecalc)
+Scope::StyleSheetChange Scope::analyzeStyleSheetChange(const Vector<RefPtr<CSSStyleSheet>>& newStylesheets)
{
- requiresFullStyleRecalc = true;
-
unsigned newStylesheetCount = newStylesheets.size();
if (!resolverIfExists())
- return Reconstruct;
+ return { ResolverUpdateType::Reconstruct };
- auto& styleResolver = *resolverIfExists();
-
// Find out which stylesheets are new.
unsigned oldStylesheetCount = m_activeStyleSheets.size();
if (newStylesheetCount < oldStylesheetCount)
- return Reconstruct;
+ return { ResolverUpdateType::Reconstruct };
Vector<StyleSheetContents*> addedSheets;
unsigned newIndex = 0;
for (unsigned oldIndex = 0; oldIndex < oldStylesheetCount; ++oldIndex) {
if (newIndex >= newStylesheetCount)
- return Reconstruct;
+ return { ResolverUpdateType::Reconstruct };
+
while (m_activeStyleSheets[oldIndex] != newStylesheets[newIndex]) {
addedSheets.append(&newStylesheets[newIndex]->contents());
++newIndex;
if (newIndex == newStylesheetCount)
- return Reconstruct;
+ return { ResolverUpdateType::Reconstruct };
}
++newIndex;
}
@@ -415,26 +412,10 @@
addedSheets.append(&newStylesheets[newIndex]->contents());
++newIndex;
}
+
// If all new sheets were added at the end of the list we can just add them to existing Resolver.
// If there were insertions we need to re-add all the stylesheets so rules are ordered correctly.
- auto ResolverUpdateType = hasInsertions ? Reset : Additive;
-
- // If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
- if (!m_document.bodyOrFrameset() || m_document.hasNodesWithNonFinalStyle() || m_document.hasNodesWithMissingStyle())
- return ResolverUpdateType;
-
- Invalidator invalidator(addedSheets, styleResolver.mediaQueryEvaluator());
- if (invalidator.dirtiesAllStyle())
- return ResolverUpdateType;
-
- if (m_shadowRoot)
- invalidator.invalidateStyle(*m_shadowRoot);
- else
- invalidator.invalidateStyle(m_document);
-
- requiresFullStyleRecalc = false;
-
- return ResolverUpdateType;
+ return { hasInsertions ? ResolverUpdateType::Reset : ResolverUpdateType::Additive, WTFMove(addedSheets) };
}
static void filterEnabledNonemptyCSSStyleSheets(Vector<RefPtr<CSSStyleSheet>>& result, const Vector<RefPtr<StyleSheet>>& sheets)
@@ -453,18 +434,6 @@
}
}
-static void invalidateHostAndSlottedStyleIfNeeded(ShadowRoot& shadowRoot, Resolver& resolver)
-{
- auto& host = *shadowRoot.host();
- if (!resolver.ruleSets().authorStyle().hostPseudoClassRules().isEmpty())
- host.invalidateStyle();
-
- if (!resolver.ruleSets().authorStyle().slottedPseudoElementRules().isEmpty()) {
- for (auto& shadowChild : childrenOfType<Element>(host))
- shadowChild.invalidateStyle();
- }
-}
-
void Scope::updateActiveStyleSheets(UpdateType updateType)
{
ASSERT(!m_pendingUpdate);
@@ -489,12 +458,11 @@
activeCSSStyleSheets.appendVector(m_document.extensionStyleSheets().authorStyleSheetsForTesting());
filterEnabledNonemptyCSSStyleSheets(activeCSSStyleSheets, activeStyleSheets);
- bool requiresFullStyleRecalc = true;
- ResolverUpdateType ResolverUpdateType = Reconstruct;
+ auto styleSheetChange = StyleSheetChange { ResolverUpdateType::Reconstruct };
if (updateType == UpdateType::ActiveSet)
- ResolverUpdateType = analyzeStyleSheetChange(activeCSSStyleSheets, requiresFullStyleRecalc);
+ styleSheetChange = analyzeStyleSheetChange(activeCSSStyleSheets);
- updateResolver(activeCSSStyleSheets, ResolverUpdateType);
+ updateResolver(activeCSSStyleSheets, styleSheetChange.resolverUpdateType);
m_weakCopyOfActiveStyleSheetListForFastLookup = nullptr;
m_activeStyleSheets.swap(activeCSSStyleSheets);
@@ -507,20 +475,26 @@
m_usesStyleBasedEditability = true;
}
- // FIXME: Move this code somewhere else.
- if (requiresFullStyleRecalc) {
- if (m_shadowRoot) {
- for (auto& shadowChild : childrenOfType<Element>(*m_shadowRoot))
- shadowChild.invalidateStyleForSubtree();
- invalidateHostAndSlottedStyleIfNeeded(*m_shadowRoot, resolver());
- } else
- m_document.scheduleFullStyleRebuild();
+ invalidateStyleAfterStyleSheetChange(styleSheetChange);
+}
+
+void Scope::invalidateStyleAfterStyleSheetChange(const StyleSheetChange& styleSheetChange)
+{
+ // If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
+ bool invalidateAll = !m_document.bodyOrFrameset() || m_document.hasNodesWithNonFinalStyle() || m_document.hasNodesWithMissingStyle();
+
+ if (styleSheetChange.resolverUpdateType == ResolverUpdateType::Reconstruct || invalidateAll) {
+ Invalidator::invalidateAllStyle(*this);
+ return;
}
+
+ Invalidator invalidator(styleSheetChange.addedSheets, m_resolver->mediaQueryEvaluator());
+ invalidator.invalidateStyle(*this);
}
void Scope::updateResolver(Vector<RefPtr<CSSStyleSheet>>& activeStyleSheets, ResolverUpdateType updateType)
{
- if (updateType == Reconstruct) {
+ if (updateType == ResolverUpdateType::Reconstruct) {
clearResolver();
return;
}
@@ -527,11 +501,11 @@
auto& styleResolver = resolver();
SetForScope<bool> isUpdatingStyleResolver { m_isUpdatingStyleResolver, true };
- if (updateType == Reset) {
+ if (updateType == ResolverUpdateType::Reset) {
styleResolver.ruleSets().resetAuthorStyle();
styleResolver.appendAuthorStyleSheets(activeStyleSheets);
} else {
- ASSERT(updateType == Additive);
+ ASSERT(updateType == ResolverUpdateType::Additive);
unsigned firstNewIndex = m_activeStyleSheets.size();
Vector<RefPtr<CSSStyleSheet>> newStyleSheets;
newStyleSheets.appendRange(activeStyleSheets.begin() + firstNewIndex, activeStyleSheets.end());
@@ -599,8 +573,8 @@
{
if (update == UpdateType::ContentsOrInterpretation) {
// :host and ::slotted rules might go away.
- if (m_shadowRoot && m_resolver)
- invalidateHostAndSlottedStyleIfNeeded(*m_shadowRoot, *m_resolver);
+ if (m_shadowRoot)
+ Invalidator::invalidateHostAndSlottedStyleIfNeeded(*m_shadowRoot);
// FIXME: Animation code may trigger resource load in middle of style recalc and that can add a rule to a content extension stylesheet.
// Fix and remove isResolvingTreeStyle() test below, see https://bugs.webkit.org/show_bug.cgi?id=194335
// FIXME: The m_isUpdatingStyleResolver test is here because extension stylesheets can get us here from Resolver::appendAuthorStyleSheets.
@@ -652,10 +626,7 @@
switch (evaluationChanges->type) {
case DynamicMediaQueryEvaluationChanges::Type::InvalidateStyle: {
Invalidator invalidator(evaluationChanges->invalidationRuleSets);
- if (m_shadowRoot)
- invalidator.invalidateStyle(*m_shadowRoot);
- else
- invalidator.invalidateStyle(m_document);
+ invalidator.invalidateStyle(*this);
break;
}
case DynamicMediaQueryEvaluationChanges::Type::ResetStyle:
Modified: trunk/Source/WebCore/style/StyleScope.h (253948 => 253949)
--- trunk/Source/WebCore/style/StyleScope.h 2019-12-30 18:25:36 UTC (rev 253948)
+++ trunk/Source/WebCore/style/StyleScope.h 2019-12-30 20:16:54 UTC (rev 253949)
@@ -123,6 +123,9 @@
void releaseMemory();
const Document& document() const { return m_document; }
+ Document& document() { return m_document; }
+ const ShadowRoot* shadowRoot() const { return m_shadowRoot; }
+ ShadowRoot* shadowRoot() { return m_shadowRoot; }
static Scope& forNode(Node&);
static Scope* forOrdinal(Element&, ScopeOrdinal);
@@ -143,12 +146,18 @@
void collectActiveStyleSheets(Vector<RefPtr<StyleSheet>>&);
- enum ResolverUpdateType {
+ enum class ResolverUpdateType {
Reconstruct,
Reset,
Additive
};
- ResolverUpdateType analyzeStyleSheetChange(const Vector<RefPtr<CSSStyleSheet>>& newStylesheets, bool& requiresFullStyleRecalc);
+ struct StyleSheetChange {
+ ResolverUpdateType resolverUpdateType;
+ Vector<StyleSheetContents*> addedSheets { };
+ };
+ StyleSheetChange analyzeStyleSheetChange(const Vector<RefPtr<CSSStyleSheet>>& newStylesheets);
+ void invalidateStyleAfterStyleSheetChange(const StyleSheetChange&);
+
void updateResolver(Vector<RefPtr<CSSStyleSheet>>&, ResolverUpdateType);
void pendingUpdateTimerFired();