| 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(
|
|
|