| Index: third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
|
| diff --git a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
|
| index 5940ae92c01354bcc0655cc32c28950f923f917c..cfc0bad999bcbe7b431e564ff82a37efa2e5c33d 100644
|
| --- a/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
|
| +++ b/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
|
| @@ -69,7 +69,6 @@
|
| #include "core/css/resolver/StyleAdjuster.h"
|
| #include "core/css/resolver/StyleResolverState.h"
|
| #include "core/css/resolver/StyleResolverStats.h"
|
| -#include "core/css/resolver/ViewportStyleResolver.h"
|
| #include "core/dom/CSSSelectorWatch.h"
|
| #include "core/dom/FirstLetterPseudoElement.h"
|
| #include "core/dom/NodeComputedStyle.h"
|
| @@ -172,20 +171,9 @@ static void collectScopedResolversForHostedShadowTrees(const Element& element, H
|
|
|
| StyleResolver::StyleResolver(Document& document)
|
| : m_document(document)
|
| - , m_viewportStyleResolver(ViewportStyleResolver::create(&document))
|
| - , m_needCollectFeatures(false)
|
| - , m_printMediaType(false)
|
| - , m_styleSharingDepth(0)
|
| {
|
| - FrameView* view = document.view();
|
| - if (view) {
|
| - m_medium = new MediaQueryEvaluator(&view->frame());
|
| + if (FrameView* view = document.view())
|
| m_printMediaType = equalIgnoringCase(view->mediaType(), MediaTypeNames::print);
|
| - } else {
|
| - m_medium = new MediaQueryEvaluator("all");
|
| - }
|
| -
|
| - initWatchedSelectorRules();
|
| }
|
|
|
| StyleResolver::~StyleResolver()
|
| @@ -197,163 +185,6 @@ void StyleResolver::dispose()
|
| m_matchedPropertiesCache.clear();
|
| }
|
|
|
| -void StyleResolver::initWatchedSelectorRules()
|
| -{
|
| - m_watchedSelectorsRules = nullptr;
|
| - CSSSelectorWatch* watch = CSSSelectorWatch::fromIfExists(*m_document);
|
| - if (!watch)
|
| - return;
|
| - const HeapVector<Member<StyleRule>>& watchedSelectors = watch->watchedCallbackSelectors();
|
| - if (!watchedSelectors.size())
|
| - return;
|
| - m_watchedSelectorsRules = RuleSet::create();
|
| - for (unsigned i = 0; i < watchedSelectors.size(); ++i)
|
| - m_watchedSelectorsRules->addStyleRule(watchedSelectors[i].get(), RuleHasNoSpecialState);
|
| -}
|
| -
|
| -void StyleResolver::lazyAppendAuthorStyleSheets(unsigned firstNew, const HeapVector<Member<CSSStyleSheet>>& styleSheets)
|
| -{
|
| - unsigned size = styleSheets.size();
|
| - for (unsigned i = firstNew; i < size; ++i)
|
| - m_pendingStyleSheets.add(styleSheets[i].get());
|
| -}
|
| -
|
| -void StyleResolver::removePendingAuthorStyleSheets(const HeapVector<Member<CSSStyleSheet>>& styleSheets)
|
| -{
|
| - for (unsigned i = 0; i < styleSheets.size(); ++i)
|
| - m_pendingStyleSheets.remove(styleSheets[i].get());
|
| -}
|
| -
|
| -void StyleResolver::appendCSSStyleSheet(CSSStyleSheet& cssSheet)
|
| -{
|
| - ASSERT(!cssSheet.disabled());
|
| - ASSERT(cssSheet.ownerDocument());
|
| - ASSERT(cssSheet.ownerNode());
|
| - ASSERT(isHTMLStyleElement(cssSheet.ownerNode()) || isSVGStyleElement(cssSheet.ownerNode()) || cssSheet.ownerNode()->treeScope() == cssSheet.ownerDocument());
|
| -
|
| - if (cssSheet.mediaQueries() && !m_medium->eval(cssSheet.mediaQueries(), &m_viewportDependentMediaQueryResults, &m_deviceDependentMediaQueryResults))
|
| - return;
|
| -
|
| - TreeScope* treeScope = &cssSheet.ownerNode()->treeScope();
|
| - // TODO(rune@opera.com): This is a workaround for crbug.com/559292
|
| - // when we're in the middle of removing a subtree with a style element
|
| - // and the treescope has been changed but inDocument and isInShadowTree
|
| - // are not.
|
| - //
|
| - // This check can be removed when crbug.com/567021 is fixed.
|
| - if (cssSheet.ownerNode()->isInShadowTree() && treeScope->rootNode().isDocumentNode())
|
| - return;
|
| -
|
| - // Sheets in the document scope of HTML imports apply to the main document
|
| - // (m_document), so we override it for all document scoped sheets.
|
| - if (treeScope->rootNode().isDocumentNode())
|
| - treeScope = m_document;
|
| - treeScope->ensureScopedStyleResolver().appendCSSStyleSheet(cssSheet, *m_medium);
|
| -}
|
| -
|
| -void StyleResolver::appendPendingAuthorStyleSheets()
|
| -{
|
| - for (const auto& styleSheet : m_pendingStyleSheets)
|
| - appendCSSStyleSheet(*styleSheet);
|
| -
|
| - m_pendingStyleSheets.clear();
|
| - finishAppendAuthorStyleSheets();
|
| -}
|
| -
|
| -void StyleResolver::appendAuthorStyleSheets(const HeapVector<Member<CSSStyleSheet>>& styleSheets)
|
| -{
|
| - // This handles sheets added to the end of the stylesheet list only. In other cases the style resolver
|
| - // needs to be reconstructed. To handle insertions too the rule order numbers would need to be updated.
|
| - for (const auto& styleSheet : styleSheets)
|
| - appendCSSStyleSheet(*styleSheet);
|
| -}
|
| -
|
| -void StyleResolver::finishAppendAuthorStyleSheets()
|
| -{
|
| - collectFeatures();
|
| -
|
| - if (document().layoutView() && document().layoutView()->style())
|
| - document().layoutView()->style()->font().update(document().styleEngine().fontSelector());
|
| -
|
| - m_viewportStyleResolver->collectViewportRules();
|
| -
|
| - document().styleEngine().resetCSSFeatureFlags(m_features);
|
| -}
|
| -
|
| -void StyleResolver::resetRuleFeatures()
|
| -{
|
| - // Need to recreate RuleFeatureSet.
|
| - m_features.clear();
|
| - m_siblingRuleSet.clear();
|
| - m_uncommonAttributeRuleSet.clear();
|
| - m_needCollectFeatures = true;
|
| -}
|
| -
|
| -void StyleResolver::addTreeBoundaryCrossingScope(ContainerNode& scope)
|
| -{
|
| - m_treeBoundaryCrossingScopes.add(&scope);
|
| -}
|
| -
|
| -void StyleResolver::resetAuthorStyle(TreeScope& treeScope)
|
| -{
|
| - m_treeBoundaryCrossingScopes.remove(&treeScope.rootNode());
|
| -
|
| - ScopedStyleResolver* resolver = treeScope.scopedStyleResolver();
|
| - if (!resolver)
|
| - return;
|
| -
|
| - resetRuleFeatures();
|
| -
|
| - if (treeScope.rootNode().isDocumentNode()) {
|
| - resolver->resetAuthorStyle();
|
| - return;
|
| - }
|
| -
|
| - // resolver is going to be freed below.
|
| - treeScope.clearScopedStyleResolver();
|
| -}
|
| -
|
| -static RuleSet* makeRuleSet(const HeapVector<RuleFeature>& rules)
|
| -{
|
| - size_t size = rules.size();
|
| - if (!size)
|
| - return nullptr;
|
| - RuleSet* ruleSet = RuleSet::create();
|
| - for (size_t i = 0; i < size; ++i)
|
| - ruleSet->addRule(rules[i].rule, rules[i].selectorIndex, rules[i].hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState);
|
| - return ruleSet;
|
| -}
|
| -
|
| -void StyleResolver::collectFeatures()
|
| -{
|
| - m_features.clear();
|
| - // Collect all ids and rules using sibling selectors (:first-child and similar)
|
| - // in the current set of stylesheets. Style sharing code uses this information to reject
|
| - // sharing candidates.
|
| - CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance();
|
| - if (defaultStyleSheets.defaultStyle()) {
|
| - m_features.add(defaultStyleSheets.defaultStyle()->features());
|
| - m_hasFullscreenUAStyle = defaultStyleSheets.fullscreenStyleSheet();
|
| - }
|
| -
|
| - if (document().isViewSource())
|
| - m_features.add(defaultStyleSheets.defaultViewSourceStyle()->features());
|
| -
|
| - if (m_watchedSelectorsRules)
|
| - m_features.add(m_watchedSelectorsRules->features());
|
| -
|
| - document().styleEngine().collectScopedStyleFeaturesTo(m_features);
|
| -
|
| - m_siblingRuleSet = makeRuleSet(m_features.siblingRules);
|
| - m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules);
|
| - m_needCollectFeatures = false;
|
| -}
|
| -
|
| -bool StyleResolver::hasRulesForId(const AtomicString& id) const
|
| -{
|
| - return m_features.hasSelectorForId(id);
|
| -}
|
| -
|
| void StyleResolver::addToStyleSharingList(Element& element)
|
| {
|
| ASSERT(RuntimeEnabledFeatures::styleSharingEnabled());
|
| @@ -390,7 +221,7 @@ static inline ScopedStyleResolver* scopedResolverFor(const Element& element)
|
| {
|
| // Ideally, returning element->treeScope().scopedStyleResolver() should be
|
| // enough, but ::cue and custom pseudo elements like ::-webkit-meter-bar pierce
|
| - // through a shadow dom boundary, yet they are not part of m_treeBoundaryCrossingScopes.
|
| + // through a shadow dom boundary, yet they are not part of treeBoundaryCrossingScopes.
|
| // The assumption here is that these rules only pierce through one boundary and
|
| // that the scope of these elements do not have a style resolver due to the fact
|
| // that VTT scopes and UA shadow trees don't have <style> elements. This is
|
| @@ -511,7 +342,8 @@ void StyleResolver::matchScopedRules(const Element& element, ElementRuleCollecto
|
|
|
| bool matchElementScopeDone = !elementScopeResolver && !element.inlineStyle();
|
|
|
| - for (auto it = m_treeBoundaryCrossingScopes.rbegin(); it != m_treeBoundaryCrossingScopes.rend(); ++it) {
|
| + const auto& treeBoundaryCrossingScopes = document().styleEngine().treeBoundaryCrossingScopes();
|
| + for (auto it = treeBoundaryCrossingScopes.rbegin(); it != treeBoundaryCrossingScopes.rend(); ++it) {
|
| const TreeScope& scope = (*it)->treeScope();
|
| ScopedStyleResolver* resolver = scope.scopedStyleResolver();
|
| ASSERT(resolver);
|
| @@ -649,15 +481,16 @@ void StyleResolver::matchAllRules(StyleResolverState& state, ElementRuleCollecto
|
|
|
| void StyleResolver::collectTreeBoundaryCrossingRules(const Element& element, ElementRuleCollector& collector)
|
| {
|
| - if (m_treeBoundaryCrossingScopes.isEmpty())
|
| + const auto& treeBoundaryCrossingScopes = document().styleEngine().treeBoundaryCrossingScopes();
|
| + if (treeBoundaryCrossingScopes.isEmpty())
|
| return;
|
|
|
| // When comparing rules declared in outer treescopes, outer's rules win.
|
| - CascadeOrder outerCascadeOrder = m_treeBoundaryCrossingScopes.size() * 2;
|
| + CascadeOrder outerCascadeOrder = treeBoundaryCrossingScopes.size() * 2;
|
| // When comparing rules declared in inner treescopes, inner's rules win.
|
| - CascadeOrder innerCascadeOrder = m_treeBoundaryCrossingScopes.size();
|
| + CascadeOrder innerCascadeOrder = treeBoundaryCrossingScopes.size();
|
|
|
| - for (const auto& scopingNode : m_treeBoundaryCrossingScopes) {
|
| + for (const auto& scopingNode : treeBoundaryCrossingScopes) {
|
| // Skip rule collection for element when tree boundary crossing rules of scopingNode's
|
| // scope can never apply to it.
|
| bool isInnerTreeScope = element.treeScope().isInclusiveAncestorOf(scopingNode->treeScope());
|
| @@ -712,8 +545,6 @@ PassRefPtr<ComputedStyle> StyleResolver::styleForElement(Element* element, const
|
| {
|
| ASSERT(document().frame());
|
| ASSERT(document().settings());
|
| - ASSERT(!hasPendingAuthorStyleSheets());
|
| - ASSERT(!m_needCollectFeatures);
|
|
|
| // Once an element has a layoutObject, we don't try to destroy it, since otherwise the layoutObject
|
| // will vanish if a style recalc happens during loading.
|
| @@ -736,8 +567,7 @@ PassRefPtr<ComputedStyle> StyleResolver::styleForElement(Element* element, const
|
| ElementResolveContext elementContext(*element);
|
|
|
| if (RuntimeEnabledFeatures::styleSharingEnabled() && sharingBehavior == AllowStyleSharing && (defaultParent || elementContext.parentStyle())) {
|
| - SharedStyleFinder styleFinder(elementContext, m_features, m_siblingRuleSet.get(), m_uncommonAttributeRuleSet.get(), *this);
|
| - if (RefPtr<ComputedStyle> sharedStyle = styleFinder.findSharedStyle())
|
| + if (RefPtr<ComputedStyle> sharedStyle = document().styleEngine().findSharedStyle(elementContext))
|
| return sharedStyle.release();
|
| }
|
|
|
| @@ -783,10 +613,7 @@ PassRefPtr<ComputedStyle> StyleResolver::styleForElement(Element* element, const
|
|
|
| if (!baseComputedStyle) {
|
|
|
| - bool needsCollection = false;
|
| - CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetsForElement(*element, needsCollection);
|
| - if (needsCollection)
|
| - collectFeatures();
|
| + document().styleEngine().ensureUAStyleForElement(*element);
|
|
|
| ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
|
|
|
| @@ -1002,7 +829,6 @@ PassRefPtr<ComputedStyle> StyleResolver::pseudoStyleForElement(Element* element,
|
|
|
| PassRefPtr<ComputedStyle> StyleResolver::styleForPage(int pageIndex)
|
| {
|
| - ASSERT(!hasPendingAuthorStyleSheets());
|
| StyleResolverState state(document(), document().documentElement()); // m_rootElementStyle will be set to the document style.
|
|
|
| RefPtr<ComputedStyle> style = ComputedStyle::create();
|
| @@ -1507,7 +1333,7 @@ void StyleResolver::invalidateMatchedPropertiesCache()
|
|
|
| void StyleResolver::notifyResizeForViewportUnits()
|
| {
|
| - m_viewportStyleResolver->collectViewportRules();
|
| + document().styleEngine().updateActiveStyle();
|
| m_matchedPropertiesCache.clearViewportDependent();
|
| }
|
|
|
| @@ -1652,14 +1478,15 @@ bool StyleResolver::hasAuthorBorder(const StyleResolverState& state)
|
|
|
| void StyleResolver::applyCallbackSelectors(StyleResolverState& state)
|
| {
|
| - if (!m_watchedSelectorsRules)
|
| + RuleSet* watchedSelectorsRuleSet = document().styleEngine().watchedSelectorsRuleSet();
|
| + if (!watchedSelectorsRuleSet)
|
| return;
|
|
|
| ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
|
| collector.setMode(SelectorChecker::CollectingStyleRules);
|
| collector.setIncludeEmptyRules(true);
|
|
|
| - MatchRequest matchRequest(m_watchedSelectorsRules.get());
|
| + MatchRequest matchRequest(watchedSelectorsRuleSet);
|
| collector.collectMatchingRules(matchRequest);
|
| collector.sortAndTransferMatchedRules();
|
|
|
| @@ -1693,51 +1520,11 @@ void StyleResolver::computeFont(ComputedStyle* style, const StylePropertySet& pr
|
| }
|
| }
|
|
|
| -void StyleResolver::addViewportDependentMediaQueries(const MediaQueryResultList& list)
|
| -{
|
| - for (size_t i = 0; i < list.size(); ++i)
|
| - m_viewportDependentMediaQueryResults.append(list[i]);
|
| -}
|
| -
|
| -void StyleResolver::addDeviceDependentMediaQueries(const MediaQueryResultList& list)
|
| -{
|
| - for (size_t i = 0; i < list.size(); ++i)
|
| - m_deviceDependentMediaQueryResults.append(list[i]);
|
| -}
|
| -
|
| -bool StyleResolver::mediaQueryAffectedByViewportChange() const
|
| -{
|
| - for (unsigned i = 0; i < m_viewportDependentMediaQueryResults.size(); ++i) {
|
| - if (m_medium->eval(m_viewportDependentMediaQueryResults[i]->expression()) != m_viewportDependentMediaQueryResults[i]->result())
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool StyleResolver::mediaQueryAffectedByDeviceChange() const
|
| -{
|
| - for (unsigned i = 0; i < m_deviceDependentMediaQueryResults.size(); ++i) {
|
| - if (m_medium->eval(m_deviceDependentMediaQueryResults[i]->expression()) != m_deviceDependentMediaQueryResults[i]->result())
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| DEFINE_TRACE(StyleResolver)
|
| {
|
| visitor->trace(m_matchedPropertiesCache);
|
| - visitor->trace(m_medium);
|
| - visitor->trace(m_viewportDependentMediaQueryResults);
|
| - visitor->trace(m_deviceDependentMediaQueryResults);
|
| visitor->trace(m_selectorFilter);
|
| - visitor->trace(m_viewportStyleResolver);
|
| - visitor->trace(m_features);
|
| - visitor->trace(m_siblingRuleSet);
|
| - visitor->trace(m_uncommonAttributeRuleSet);
|
| - visitor->trace(m_watchedSelectorsRules);
|
| - visitor->trace(m_treeBoundaryCrossingScopes);
|
| visitor->trace(m_styleSharingLists);
|
| - visitor->trace(m_pendingStyleSheets);
|
| visitor->trace(m_document);
|
| }
|
|
|
|
|