Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(292)

Unified Diff: third_party/WebKit/Source/core/dom/StyleEngine.cpp

Issue 1913833002: Current work-in-progress crbug.com/567021 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More assert fixes Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 b7cccd69a0808c85471a3698915ce9c4f613368e..0083e7efae37a2986db3e6871ef1f170faa83a41 100644
--- a/third_party/WebKit/Source/core/dom/StyleEngine.cpp
+++ b/third_party/WebKit/Source/core/dom/StyleEngine.cpp
@@ -35,8 +35,11 @@
#include "core/css/StyleSheetContents.h"
#include "core/css/invalidation/InvalidationSet.h"
#include "core/css/resolver/ScopedStyleResolver.h"
+#include "core/css/resolver/SharedStyleFinder.h"
+#include "core/css/resolver/ViewportStyleResolver.h"
#include "core/dom/DocumentStyleSheetCollector.h"
#include "core/dom/Element.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/ShadowTreeStyleSheetCollection.h"
#include "core/dom/StyleChangeReason.h"
@@ -44,6 +47,7 @@
#include "core/frame/Settings.h"
#include "core/html/HTMLIFrameElement.h"
#include "core/html/HTMLLinkElement.h"
+#include "core/html/HTMLSlotElement.h"
#include "core/html/imports/HTMLImportsController.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/page/Page.h"
@@ -59,12 +63,13 @@ StyleEngine::StyleEngine(Document& document)
: m_document(&document)
, m_isMaster(!document.importsController() || document.importsController()->master() == &document)
, m_documentStyleSheetCollection(DocumentStyleSheetCollection::create(document))
- // We don't need to create CSSFontSelector for imported document or
- // HTMLTemplateElement's document, because those documents have no frame.
- , m_fontSelector(document.frame() ? CSSFontSelector::create(&document) : nullptr)
{
- if (m_fontSelector)
+ if (document.frame()) {
+ // We don't need to create CSSFontSelector for imported document or
+ // HTMLTemplateElement's document, because those documents have no frame.
+ m_fontSelector = CSSFontSelector::create(&document);
m_fontSelector->registerForInvalidationCallbacks(this);
+ }
}
StyleEngine::~StyleEngine()
@@ -110,25 +115,26 @@ TreeScopeStyleSheetCollection* StyleEngine::styleSheetCollectionFor(TreeScope& t
const HeapVector<Member<StyleSheet>>& StyleEngine::styleSheetsForStyleSheetList(TreeScope& treeScope)
{
+ // TODO(rune@opera.com): we could split styleSheets and active stylesheet
+ // update to have a lighter update while accessing the styleSheets list.
+ DCHECK(master());
+ if (master()->isActive()) {
+ if (isMaster())
+ updateActiveStyle();
+ else
+ master()->styleEngine().updateActiveStyle();
+ }
+
if (treeScope == m_document)
return documentStyleSheetCollection()->styleSheetsForStyleSheetList();
return ensureStyleSheetCollectionFor(treeScope)->styleSheetsForStyleSheetList();
}
-void StyleEngine::resetCSSFeatureFlags(const RuleFeatureSet& features)
-{
- m_usesSiblingRules = features.usesSiblingRules();
- m_usesFirstLineRules = features.usesFirstLineRules();
- m_usesWindowInactiveSelector = features.usesWindowInactiveSelector();
- m_maxDirectAdjacentSelectors = features.maxDirectAdjacentSelectors();
-}
-
void StyleEngine::injectAuthorSheet(StyleSheetContents* authorSheet)
{
m_injectedAuthorStyleSheets.append(CSSStyleSheet::create(authorSheet, m_document));
markDocumentDirty();
- resolverChanged(AnalyzedStyleUpdate);
}
void StyleEngine::addPendingSheet(StyleEngineContext &context)
@@ -149,12 +155,12 @@ void StyleEngine::removePendingSheet(Node* styleSheetCandidateNode, const StyleE
markTreeScopeDirty(*treeScope);
if (context.addedPendingSheetBeforeBody()) {
- DCHECK_GT(m_pendingRenderBlockingStylesheets, 0);
+ DCHECK(m_pendingRenderBlockingStylesheets);
m_pendingRenderBlockingStylesheets--;
}
// Make sure we knew this sheet was pending, and that our count isn't out of sync.
- DCHECK_GT(m_pendingScriptBlockingStylesheets, 0);
+ DCHECK(m_pendingScriptBlockingStylesheets);
m_pendingScriptBlockingStylesheets--;
if (m_pendingScriptBlockingStylesheets)
@@ -163,25 +169,24 @@ void StyleEngine::removePendingSheet(Node* styleSheetCandidateNode, const StyleE
document().didRemoveAllPendingStylesheet();
}
-void StyleEngine::setNeedsActiveStyleUpdate(StyleSheet* sheet, StyleResolverUpdateMode updateMode)
+void StyleEngine::setNeedsActiveStyleUpdate(TreeScope& treeScope)
{
- // 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.
if (!document().isActive() && isMaster())
return;
+ markTreeScopeDirty(treeScope);
+}
+
+void StyleEngine::updateActiveStyle()
+{
+ DCHECK(document().isActive());
+
+ if (!needsActiveStyleUpdate())
+ return;
- if (sheet && document().isActive()) {
- Node* node = sheet->ownerNode();
- if (node && node->inShadowIncludingDocument()) {
- TreeScope& treeScope = isStyleElement(*node) ? node->treeScope() : *m_document;
- DCHECK(isStyleElement(*node) || node->treeScope() == m_document);
- markTreeScopeDirty(treeScope);
- }
- }
+ updateActiveStyleSheets();
+ updateGlobalRuleSet();
- resolverChanged(updateMode);
+ DCHECK(!needsActiveStyleUpdate());
}
void StyleEngine::addStyleSheetCandidateNode(Node* node)
@@ -229,43 +234,47 @@ void StyleEngine::modifiedStyleSheetCandidateNode(Node* node)
TreeScope& treeScope = isStyleElement(*node) ? node->treeScope() : *m_document;
DCHECK(isStyleElement(*node) || treeScope == m_document);
markTreeScopeDirty(treeScope);
- resolverChanged(FullStyleUpdate);
}
void StyleEngine::watchedSelectorsChanged()
{
- if (m_resolver) {
- m_resolver->initWatchedSelectorRules();
- m_resolver->resetRuleFeatures();
- }
+ m_globalRuleSet.initWatchedSelectorsRuleSet(document());
+ m_needsGlobalRuleSetUpdate = true;
document().setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::DeclarativeContent));
}
-bool StyleEngine::shouldUpdateDocumentStyleSheetCollection(StyleResolverUpdateMode updateMode) const
+bool StyleEngine::shouldUpdateDocumentStyleSheetCollection() const
{
- return m_documentScopeDirty || updateMode == FullStyleUpdate;
+ return m_allTreeScopesDirty || m_documentScopeDirty;
}
-bool StyleEngine::shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode updateMode) const
+bool StyleEngine::shouldUpdateShadowTreeStyleSheetCollection() const
{
- return !m_dirtyTreeScopes.isEmpty() || updateMode == FullStyleUpdate;
+ return m_allTreeScopesDirty || !m_dirtyTreeScopes.isEmpty();
}
-void StyleEngine::clearMediaQueryRuleSetOnTreeScopeStyleSheets(UnorderedTreeScopeSet& treeScopes)
+void StyleEngine::mediaQueryAffectingValueChanged(UnorderedTreeScopeSet& treeScopes)
{
for (TreeScope* treeScope : treeScopes) {
DCHECK(treeScope != m_document);
ShadowTreeStyleSheetCollection* collection = toShadowTreeStyleSheetCollection(styleSheetCollectionFor(*treeScope));
DCHECK(collection);
- collection->clearMediaQueryRuleSetStyleSheets();
+ if (collection->mediaQueryAffectingValueChanged())
+ setNeedsActiveStyleUpdate(*treeScope);
}
}
-void StyleEngine::clearMediaQueryRuleSetStyleSheets()
+void StyleEngine::mediaQueryAffectingValueChanged()
{
- resolverChanged(FullStyleUpdate);
- documentStyleSheetCollection()->clearMediaQueryRuleSetStyleSheets();
- clearMediaQueryRuleSetOnTreeScopeStyleSheets(m_activeTreeScopes);
+ if (documentStyleSheetCollection()->mediaQueryAffectingValueChanged())
+ setNeedsActiveStyleUpdate(document());
+ mediaQueryAffectingValueChanged(m_activeTreeScopes);
+
+ if (!document().frame())
+ return;
+
+ if (document().wasPrinting() != document().printing() && document().frame()->pageZoomFactor() != 1)
+ document().setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleSheetChange));
}
void StyleEngine::updateStyleSheetsInImport(DocumentStyleSheetCollector& parentCollector)
@@ -273,16 +282,16 @@ void StyleEngine::updateStyleSheetsInImport(DocumentStyleSheetCollector& parentC
DCHECK(!isMaster());
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)
+void StyleEngine::updateActiveStyleSheetsInShadow(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,
@@ -291,29 +300,27 @@ void StyleEngine::updateActiveStyleSheetsInShadow(StyleResolverUpdateMode update
}
}
-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(updateMode))
- documentStyleSheetCollection()->updateActiveStyleSheets(*this, updateMode);
+ if (shouldUpdateDocumentStyleSheetCollection()) {
+ documentStyleSheetCollection()->updateViewport();
+ documentStyleSheetCollection()->updateActiveStyleSheets();
+ }
- if (shouldUpdateShadowTreeStyleSheetCollection(updateMode)) {
+ if (shouldUpdateShadowTreeStyleSheetCollection()) {
UnorderedTreeScopeSet treeScopesRemoved;
- if (updateMode == FullStyleUpdate) {
- for (TreeScope* treeScope : m_activeTreeScopes)
- updateActiveStyleSheetsInShadow(updateMode, treeScope, treeScopesRemoved);
- } else {
- for (TreeScope* treeScope : m_dirtyTreeScopes)
- updateActiveStyleSheetsInShadow(updateMode, treeScope, treeScopesRemoved);
- }
+ for (TreeScope* treeScope : m_dirtyTreeScopes)
+ updateActiveStyleSheetsInShadow(treeScope, treeScopesRemoved);
for (TreeScope* treeScope : treeScopesRemoved)
m_activeTreeScopes.remove(treeScope);
}
@@ -322,14 +329,18 @@ void StyleEngine::updateActiveStyleSheets(StyleResolverUpdateMode updateMode)
m_dirtyTreeScopes.clear();
m_documentScopeDirty = false;
+ m_allTreeScopesDirty = false;
}
-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());
for (TreeScope* treeScope : m_activeTreeScopes) {
@@ -352,27 +363,28 @@ void StyleEngine::didRemoveShadowRoot(ShadowRoot* shadowRoot)
void StyleEngine::shadowRootRemovedFromDocument(ShadowRoot* shadowRoot)
{
- if (StyleResolver* styleResolver = resolver()) {
- styleResolver->resetAuthorStyle(*shadowRoot);
-
- if (TreeScopeStyleSheetCollection* collection = styleSheetCollectionFor(*shadowRoot))
- styleResolver->removePendingAuthorStyleSheets(collection->activeAuthorStyleSheets());
- }
+ m_needsGlobalRuleSetUpdate = true;
+ shadowRoot->clearScopedStyleResolver();
m_styleSheetCollectionMap.remove(shadowRoot);
m_activeTreeScopes.remove(shadowRoot);
m_dirtyTreeScopes.remove(shadowRoot);
+ m_treeBoundaryCrossingScopes.remove(&shadowRoot->rootNode());
}
-void StyleEngine::appendActiveAuthorStyleSheets()
+void StyleEngine::addTreeBoundaryCrossingScope(ContainerNode& scope)
{
- DCHECK(isMaster());
+ m_treeBoundaryCrossingScopes.add(&scope);
+}
- m_resolver->appendAuthorStyleSheets(documentStyleSheetCollection()->activeAuthorStyleSheets());
- for (TreeScope* treeScope : m_activeTreeScopes) {
- if (TreeScopeStyleSheetCollection* collection = m_styleSheetCollectionMap.get(treeScope))
- m_resolver->appendAuthorStyleSheets(collection->activeAuthorStyleSheets());
- }
- m_resolver->finishAppendAuthorStyleSheets();
+RuleSet& StyleEngine::ensureRuleSetForSheet(CSSStyleSheet& sheet)
+{
+ if (!sheet.matchesMediaQueries(ensureMediaQueryEvaluator()))
+ return *RuleSet::emptyRuleSet();
+
+ AddRuleFlags addRuleFlags = RuleHasNoSpecialState;
+ if (m_document->getSecurityOrigin()->canRequest(sheet.baseURL()))
+ addRuleFlags = RuleHasDocumentSecurityOrigin;
+ return sheet.contents()->ensureRuleSet(*m_medium, addRuleFlags);
}
void StyleEngine::createResolver()
@@ -385,10 +397,6 @@ void StyleEngine::createResolver()
DCHECK(document().frame());
m_resolver = StyleResolver::create(*m_document);
-
- // A scoped style resolver for document will be created during
- // appendActiveAuthorStyleSheets if needed.
- appendActiveAuthorStyleSheets();
}
void StyleEngine::clearResolver()
@@ -414,15 +422,11 @@ void StyleEngine::clearResolver()
}
}
-void StyleEngine::clearMasterResolver()
-{
- if (Document* master = this->master())
- master->styleEngine().clearResolver();
-}
-
void StyleEngine::didDetach()
{
clearResolver();
+ m_viewportResolver.clear();
+ m_medium = nullptr;
}
bool StyleEngine::shouldClearResolver() const
@@ -430,25 +434,6 @@ 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;
- }
-
- m_didCalculateResolver = true;
- updateActiveStyleSheets(mode);
-}
-
void StyleEngine::clearFontCache()
{
if (m_fontSelector)
@@ -484,6 +469,25 @@ void StyleEngine::removeFontFaceRules(const HeapVector<Member<const StyleRuleFon
m_resolver->invalidateMatchedPropertiesCache();
}
+void StyleEngine::removeFontFaceRules(const HeapVector<Member<StyleRuleFontFace>>& fontFaceRules)
+{
+ if (!m_fontSelector)
+ return;
+
+ FontFaceCache* cache = m_fontSelector->fontFaceCache();
+ for (unsigned i = 0; i < fontFaceRules.size(); ++i)
+ cache->remove(fontFaceRules[i]);
+ if (m_resolver)
+ m_resolver->invalidateMatchedPropertiesCache();
+}
+
+ViewportStyleResolver& StyleEngine::ensureViewportStyleResolver()
+{
+ if (!m_viewportResolver)
+ m_viewportResolver = ViewportStyleResolver::create(m_document);
+ return *m_viewportResolver.get();
+}
+
void StyleEngine::markTreeScopeDirty(TreeScope& scope)
{
if (scope == m_document) {
@@ -493,6 +497,7 @@ void StyleEngine::markTreeScopeDirty(TreeScope& scope)
DCHECK(m_styleSheetCollectionMap.contains(&scope));
m_dirtyTreeScopes.add(&scope);
+ document().scheduleLayoutTreeUpdateIfNeeded();
}
void StyleEngine::markDocumentDirty()
@@ -500,19 +505,21 @@ void StyleEngine::markDocumentDirty()
m_documentScopeDirty = true;
if (document().importLoader())
document().importsController()->master()->styleEngine().markDocumentDirty();
+ else
+ document().scheduleLayoutTreeUpdateIfNeeded();
}
CSSStyleSheet* StyleEngine::createSheet(Element* e, const String& text, TextPosition startPosition, StyleEngineContext &context)
{
CSSStyleSheet* styleSheet = nullptr;
- e->document().styleEngine().addPendingSheet(context);
+ addPendingSheet(context);
AtomicString textContent(text);
HeapHashMap<AtomicString, Member<StyleSheetContents>>::AddResult result = m_textToSheetCache.add(textContent, nullptr);
if (result.isNewEntry || !result.storedValue->value) {
- styleSheet = StyleEngine::parseSheet(e, text, startPosition);
+ styleSheet = parseSheet(e, text, startPosition);
if (result.isNewEntry && styleSheet->contents()->isCacheableForStyleElement()) {
result.storedValue->value = styleSheet->contents();
m_sheetToTextCache.add(styleSheet->contents(), textContent);
@@ -521,19 +528,21 @@ CSSStyleSheet* StyleEngine::createSheet(Element* e, const String& text, TextPosi
StyleSheetContents* contents = result.storedValue->value;
DCHECK(contents);
DCHECK(contents->isCacheableForStyleElement());
- DCHECK_EQ(contents->singleOwnerDocument(), e->document());
+ DCHECK_EQ(contents->singleOwnerDocument(), document());
styleSheet = CSSStyleSheet::createInline(contents, e, startPosition);
}
DCHECK(styleSheet);
styleSheet->setTitle(e->title());
+ if (!e->isInShadowTree())
+ setPreferredStylesheetSetNameIfNotSet(e->title());
return styleSheet;
}
CSSStyleSheet* StyleEngine::parseSheet(Element* e, const String& text, TextPosition startPosition)
{
CSSStyleSheet* styleSheet = nullptr;
- styleSheet = CSSStyleSheet::createInline(e, KURL(), startPosition, e->document().characterSet());
+ styleSheet = CSSStyleSheet::createInline(e, KURL(), startPosition, document().characterSet());
styleSheet->contents()->parseStringAtPosition(text, startPosition);
return styleSheet;
}
@@ -548,6 +557,20 @@ void StyleEngine::removeSheet(StyleSheetContents* contents)
m_sheetToTextCache.remove(contents);
}
+bool StyleEngine::hasRulesForId(const AtomicString& id) const
+{
+ return m_globalRuleSet.m_features.hasSelectorForId(id);
+}
+
+void StyleEngine::updateGlobalRuleSet()
+{
+ if (!m_needsGlobalRuleSetUpdate)
+ return;
+
+ m_globalRuleSet.update(document());
+ m_needsGlobalRuleSetUpdate = false;
+}
+
void StyleEngine::collectScopedStyleFeaturesTo(RuleFeatureSet& features) const
{
HeapHashSet<Member<const StyleSheetContents>> visitedSharedStyleSheetContents;
@@ -607,9 +630,9 @@ void StyleEngine::classChangedForElement(const SpaceSplitString& changedClasses,
return;
InvalidationLists invalidationLists;
unsigned changedSize = changedClasses.size();
- RuleFeatureSet& ruleFeatureSet = ensureResolver().ensureUpdatedRuleFeatureSet();
+ const RuleFeatureSet& ruleFeatures = ruleFeatureSet();
for (unsigned i = 0; i < changedSize; ++i)
- ruleFeatureSet.collectInvalidationSetsForClass(invalidationLists, element, changedClasses[i]);
+ ruleFeatures.collectInvalidationSetsForClass(invalidationLists, element, changedClasses[i]);
m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, element);
}
@@ -628,7 +651,7 @@ void StyleEngine::classChangedForElement(const SpaceSplitString& oldClasses, con
remainingClassBits.ensureSize(oldClasses.size());
InvalidationLists invalidationLists;
- RuleFeatureSet& ruleFeatureSet = ensureResolver().ensureUpdatedRuleFeatureSet();
+ const RuleFeatureSet& ruleFeatures = ruleFeatureSet();
for (unsigned i = 0; i < newClasses.size(); ++i) {
bool found = false;
@@ -643,14 +666,14 @@ void StyleEngine::classChangedForElement(const SpaceSplitString& oldClasses, con
}
// Class was added.
if (!found)
- ruleFeatureSet.collectInvalidationSetsForClass(invalidationLists, element, newClasses[i]);
+ ruleFeatures.collectInvalidationSetsForClass(invalidationLists, element, newClasses[i]);
}
for (unsigned i = 0; i < oldClasses.size(); ++i) {
if (remainingClassBits.quickGet(i))
continue;
// Class was removed.
- ruleFeatureSet.collectInvalidationSetsForClass(invalidationLists, element, oldClasses[i]);
+ ruleFeatures.collectInvalidationSetsForClass(invalidationLists, element, oldClasses[i]);
}
m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, element);
@@ -662,7 +685,7 @@ void StyleEngine::attributeChangedForElement(const QualifiedName& attributeName,
return;
InvalidationLists invalidationLists;
- ensureResolver().ensureUpdatedRuleFeatureSet().collectInvalidationSetsForAttribute(invalidationLists, element, attributeName);
+ ruleFeatureSet().collectInvalidationSetsForAttribute(invalidationLists, element, attributeName);
m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, element);
}
@@ -672,11 +695,11 @@ void StyleEngine::idChangedForElement(const AtomicString& oldId, const AtomicStr
return;
InvalidationLists invalidationLists;
- RuleFeatureSet& ruleFeatureSet = ensureResolver().ensureUpdatedRuleFeatureSet();
+ const RuleFeatureSet& ruleFeatures = ruleFeatureSet();
if (!oldId.isEmpty())
- ruleFeatureSet.collectInvalidationSetsForId(invalidationLists, element, oldId);
+ ruleFeatures.collectInvalidationSetsForId(invalidationLists, element, oldId);
if (!newId.isEmpty())
- ruleFeatureSet.collectInvalidationSetsForId(invalidationLists, element, newId);
+ ruleFeatures.collectInvalidationSetsForId(invalidationLists, element, newId);
m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, element);
}
@@ -686,7 +709,7 @@ void StyleEngine::pseudoStateChangedForElement(CSSSelector::PseudoType pseudoTyp
return;
InvalidationLists invalidationLists;
- ensureResolver().ensureUpdatedRuleFeatureSet().collectInvalidationSetsForPseudoClass(invalidationLists, element, pseudoType);
+ ruleFeatureSet().collectInvalidationSetsForPseudoClass(invalidationLists, element, pseudoType);
m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, element);
}
@@ -702,6 +725,76 @@ void StyleEngine::setStatsEnabled(bool enabled)
m_styleResolverStats->reset();
}
+void StyleEngine::scheduleRuleSetInvalidationsForElement(Element& element, const HeapVector<Member<RuleSet>>& ruleSets)
+{
+ AtomicString id;
+ const SpaceSplitString* classNames = nullptr;
+ bool typeSelectorMatch = false;
+ const AtomicString& shadowPseudoId = element.shadowPseudoId();
+ bool customPseudoMatch = shadowPseudoId.isEmpty();
+
+ if (element.hasID())
+ id = element.idForStyleResolution();
+ if (element.hasClass())
+ classNames = &element.classNames();
+
+ InvalidationLists invalidationLists;
+ for (const auto& ruleSet : ruleSets) {
+
+ if (!id.isNull())
+ ruleSet->features().collectInvalidationSetsForId(invalidationLists, element, id);
+
+ if (classNames) {
+ unsigned classNameCount = classNames->size();
+ for (size_t i = 0; i < classNameCount; i++)
+ ruleSet->features().collectInvalidationSetsForClass(invalidationLists, element, (*classNames)[i]);
+ }
+
+ for (const Attribute& attribute : element.attributes())
+ ruleSet->features().collectInvalidationSetsForAttribute(invalidationLists, element, attribute.name());
+
+ if (element.needsStyleRecalc())
+ continue;
+
+ if (!typeSelectorMatch && ruleSet->tagRules(element.localNameForSelectorMatching())) {
+ typeSelectorMatch = true;
+ element.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleSheetChange));
+ }
+
+ if (!customPseudoMatch && ruleSet->shadowPseudoElementRules(shadowPseudoId)) {
+ customPseudoMatch = true;
+ element.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleSheetChange));
+ }
+ }
+ m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, element);
+}
+
+void StyleEngine::scheduleInvalidationsForRuleSets(TreeScope& treeScope, const HeapVector<Member<RuleSet>>& ruleSets)
+{
+ if (treeScope.rootNode().isShadowRoot()) {
+ Element& host = toShadowRoot(treeScope.rootNode()).host();
+ scheduleRuleSetInvalidationsForElement(host, ruleSets);
+ if (host.getStyleChangeType() >= SubtreeStyleChange)
+ return;
+ }
+
+ Node* stayWithin = &treeScope.rootNode();
+ Element* element = ElementTraversal::firstChild(*stayWithin);
+ while (element) {
+ scheduleRuleSetInvalidationsForElement(*element, ruleSets);
+ if (isHTMLSlotElement(element)) {
+ for (auto& node : toHTMLSlotElement(element)->getDistributedNodes()) {
+ if (node->isElementNode())
+ scheduleRuleSetInvalidationsForElement(*toElement(node), ruleSets);
+ }
+ }
+ if (element->getStyleChangeType() < SubtreeStyleChange)
+ element = ElementTraversal::next(*element, stayWithin);
+ else
+ element = ElementTraversal::nextSkippingChildren(*element, stayWithin);
+ }
+}
+
void StyleEngine::setPreferredStylesheetSetNameIfNotSet(const String& name)
{
if (!m_preferredStylesheetSetName.isEmpty())
@@ -731,16 +824,64 @@ void StyleEngine::setHttpDefaultStyle(const String& content)
{
setPreferredStylesheetSetNameIfNotSet(content);
markDocumentDirty();
- resolverChanged(FullStyleUpdate);
}
-void StyleEngine::ensureFullscreenUAStyle()
+void StyleEngine::ensureUAStyleForFullscreen()
{
- CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetForFullscreen();
- if (!m_resolver)
- return;
- if (!m_resolver->hasFullscreenUAStyle())
- m_resolver->resetRuleFeatures();
+ if (CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetForFullscreen()) {
+ m_needsGlobalRuleSetUpdate = true;
+ updateGlobalRuleSet();
+ }
+}
+
+void StyleEngine::ensureUAStyleForElement(const Element& element)
+{
+ if (CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetsForElement(element)) {
+ m_needsGlobalRuleSetUpdate = true;
+ updateGlobalRuleSet();
+ }
+}
+
+PassRefPtr<ComputedStyle> StyleEngine::findSharedStyle(const ElementResolveContext& elementResolveContext)
+{
+ return SharedStyleFinder(elementResolveContext,
+ m_globalRuleSet.m_features,
+ m_globalRuleSet.m_siblingRuleSet.get(),
+ m_globalRuleSet.m_uncommonAttributeRuleSet.get(),
+ *m_resolver).findSharedStyle();
+}
+
+MediaQueryEvaluator& StyleEngine::ensureMediaQueryEvaluator()
+{
+ if (!m_medium) {
+ if (document().frame())
+ m_medium = new MediaQueryEvaluator(document().frame());
+ else
+ m_medium = new MediaQueryEvaluator("all");
+ }
+ return *m_medium;
+}
+
+bool StyleEngine::mediaQueryAffectedByViewportChange()
+{
+ const MediaQueryEvaluator& evaluator = ensureMediaQueryEvaluator();
+ const auto& results = m_globalRuleSet.m_features.viewportDependentMediaQueryResults;
+ for (unsigned i = 0; i < results.size(); ++i) {
+ if (evaluator.eval(results[i]->expression()) != results[i]->result())
+ return true;
+ }
+ return false;
+}
+
+bool StyleEngine::mediaQueryAffectedByDeviceChange()
+{
+ const MediaQueryEvaluator& evaluator = ensureMediaQueryEvaluator();
+ const auto& results = m_globalRuleSet.m_features.deviceDependentMediaQueryResults;
+ for (unsigned i = 0; i < results.size(); ++i) {
+ if (evaluator.eval(results[i]->expression()) != results[i]->result())
+ return true;
+ }
+ return false;
}
DEFINE_TRACE(StyleEngine)
@@ -750,9 +891,13 @@ DEFINE_TRACE(StyleEngine)
visitor->trace(m_documentStyleSheetCollection);
visitor->trace(m_styleSheetCollectionMap);
visitor->trace(m_resolver);
+ visitor->trace(m_viewportResolver);
+ visitor->trace(m_medium);
visitor->trace(m_styleInvalidator);
visitor->trace(m_dirtyTreeScopes);
visitor->trace(m_activeTreeScopes);
+ visitor->trace(m_treeBoundaryCrossingScopes);
+ visitor->trace(m_globalRuleSet);
visitor->trace(m_fontSelector);
visitor->trace(m_textToSheetCache);
visitor->trace(m_sheetToTextCache);
« no previous file with comments | « third_party/WebKit/Source/core/dom/StyleEngine.h ('k') | third_party/WebKit/Source/core/dom/StyleEngineTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698