Commit 25b84315 authored by kochi@chromium.org's avatar kochi@chromium.org

Remove all members in ScopedStyleTree for preparing class removal

As a part of ScopedStyleTree removal (issue 392018),
remove all private members in ScopedStyleTree.

|m_cache| is no longer necessary as ScopedStyleResolver
lookup from an element no longer require ascending the
DOM tree up, thanks to <style scoped> removal.

Unfortunately |m_authorStyles| cannot be removed completely
- StyleResolver still has to clear ScopedStyleResolvers
which are associated with TreeScopes, and thus moved from
ScopedStyleTree to StyleResolver (and renamed
|m_scopedStyleResolvers| to match what it contains).

BUG=392018
TEST=no layout test failures

Review URL: https://codereview.chromium.org/418833002

git-svn-id: svn://svn.chromium.org/blink/trunk@179051 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent d50ac5a4
......@@ -618,10 +618,8 @@ RuleSet& StyleSheetContents::ensureRuleSet(const MediaQueryEvaluator& medium, Ad
static void clearResolvers(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >& clients)
{
for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator it = clients.begin(); it != clients.end(); ++it) {
if (Document* document = (*it)->ownerDocument()) {
if (Document* document = (*it)->ownerDocument())
document->styleEngine()->clearResolver();
document->clearScopedStyleResolver();
}
}
}
......
......@@ -80,7 +80,7 @@ void ScopedStyleResolver::addRulesFromSheet(CSSStyleSheet* cssSheet, const Media
resolver->processScopedRules(ruleSet, cssSheet, treeScope().rootNode());
}
void ScopedStyleResolver::collectFeaturesTo(RuleFeatureSet& features, HashSet<const StyleSheetContents*>& visitedSharedStyleSheetContents)
void ScopedStyleResolver::collectFeaturesTo(RuleFeatureSet& features, HashSet<const StyleSheetContents*>& visitedSharedStyleSheetContents) const
{
for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) {
StyleSheetContents* contents = m_authorStyleSheets[i]->contents();
......
......@@ -66,7 +66,7 @@ public:
void collectMatchingAuthorRules(ElementRuleCollector&, bool includeEmptyRules, bool applyAuthorStyles, CascadeScope, CascadeOrder = ignoreCascadeOrder);
void matchPageRules(PageRuleCollector&);
void addRulesFromSheet(CSSStyleSheet*, const MediaQueryEvaluator&, StyleResolver*);
void collectFeaturesTo(RuleFeatureSet&, HashSet<const StyleSheetContents*>& visitedSharedStyleSheetContents);
void collectFeaturesTo(RuleFeatureSet&, HashSet<const StyleSheetContents*>& visitedSharedStyleSheetContents) const;
void resetAuthorStyle();
void collectViewportRulesTo(StyleResolver*) const;
......
......@@ -40,31 +40,6 @@ ScopedStyleTree::ScopedStyleTree()
{
}
ScopedStyleTree::~ScopedStyleTree()
{
#if !ENABLE(OILPAN)
for (HashMap<RawPtr<const ContainerNode>, RawPtr<ScopedStyleResolver> >::iterator it = m_authorStyles.begin(); it != m_authorStyles.end(); ++it)
it->key->treeScope().clearScopedStyleResolver();
#endif
}
ScopedStyleResolver* ScopedStyleTree::ensureScopedStyleResolver(ContainerNode& scopingNode)
{
ASSERT(scopingNode.isShadowRoot() || scopingNode.isDocumentNode());
m_authorStyles.add(&scopingNode, &scopingNode.treeScope().ensureScopedStyleResolver());
return scopingNode.treeScope().scopedStyleResolver();
}
ScopedStyleResolver* ScopedStyleTree::scopedStyleResolverFor(const ContainerNode& scopingNode)
{
if (!isShadowHost(&scopingNode)
&& !scopingNode.isDocumentNode()
&& !scopingNode.isShadowRoot())
return 0;
return scopingNode.treeScope().scopedStyleResolver();
}
void ScopedStyleTree::resolveScopedStyles(const Element* element, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers)
{
for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scopedResolver; scopedResolver = scopedResolver->parent())
......@@ -80,7 +55,7 @@ void ScopedStyleTree::collectScopedResolversForHostedShadowTrees(const Element*
// Adding scoped resolver for active shadow roots for shadow host styling.
for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
if (shadowRoot->numberOfStyles() > 0) {
if (ScopedStyleResolver* resolver = scopedStyleResolverFor(*shadowRoot))
if (ScopedStyleResolver* resolver = shadowRoot->scopedStyleResolver())
resolvers.append(resolver);
}
}
......@@ -102,78 +77,17 @@ void ScopedStyleTree::resolveScopedKeyframesRules(const Element* element, WillBe
}
}
inline ScopedStyleResolver* ScopedStyleTree::enclosingScopedStyleResolverFor(const ContainerNode* scopingNode)
inline ScopedStyleResolver* ScopedStyleTree::scopedResolverFor(const Element* element)
{
for (; scopingNode; scopingNode = scopingNode->parentOrShadowHostNode()) {
if (ScopedStyleResolver* scopedStyleResolver = scopedStyleResolverFor(*scopingNode))
for (TreeScope* treeScope = &element->treeScope(); treeScope; treeScope = treeScope->parentTreeScope()) {
if (ScopedStyleResolver* scopedStyleResolver = treeScope->scopedStyleResolver())
return scopedStyleResolver;
}
return 0;
}
void ScopedStyleTree::resolveStyleCache(const ContainerNode* scopingNode)
{
m_cache.scopedResolver = enclosingScopedStyleResolverFor(scopingNode);
m_cache.nodeForScopedStyles = scopingNode;
}
void ScopedStyleTree::pushStyleCache(const ContainerNode& scopingNode, const ContainerNode* parent)
{
if (m_authorStyles.isEmpty())
return;
if (!cacheIsValid(parent)) {
resolveStyleCache(&scopingNode);
return;
}
ScopedStyleResolver* scopedResolver = scopedStyleResolverFor(scopingNode);
if (scopedResolver)
m_cache.scopedResolver = scopedResolver;
m_cache.nodeForScopedStyles = &scopingNode;
}
void ScopedStyleTree::popStyleCache(const ContainerNode& scopingNode)
{
if (!cacheIsValid(&scopingNode))
return;
if (m_cache.scopedResolver && m_cache.scopedResolver->scopingNode() == scopingNode)
m_cache.scopedResolver = m_cache.scopedResolver->parent();
m_cache.nodeForScopedStyles = scopingNode.parentOrShadowHostNode();
}
void ScopedStyleTree::collectFeaturesTo(RuleFeatureSet& features)
{
HashSet<const StyleSheetContents*> visitedSharedStyleSheetContents;
for (WillBeHeapHashMap<RawPtrWillBeMember<const ContainerNode>, RawPtrWillBeMember<ScopedStyleResolver> >::iterator it = m_authorStyles.begin(); it != m_authorStyles.end(); ++it)
it->value->collectFeaturesTo(features, visitedSharedStyleSheetContents);
}
void ScopedStyleTree::remove(const ContainerNode* scopingNode)
{
if (!scopingNode || scopingNode->isDocumentNode())
return;
ScopedStyleResolver* resolver = scopingNode->treeScope().scopedStyleResolver();
if (!resolver)
return;
if (m_cache.scopedResolver == resolver)
m_cache.clear();
// resolver is going to be freed below.
resolver = 0;
m_authorStyles.remove(scopingNode);
scopingNode->treeScope().clearScopedStyleResolver();
}
void ScopedStyleTree::trace(Visitor* visitor)
{
#if ENABLE(OILPAN)
visitor->trace(m_authorStyles);
visitor->trace(m_cache);
#endif
}
} // namespace blink
......@@ -39,71 +39,17 @@ class ScopedStyleTree {
DISALLOW_ALLOCATION();
public:
ScopedStyleTree();
~ScopedStyleTree();
ScopedStyleResolver* ensureScopedStyleResolver(ContainerNode& scopingNode);
ScopedStyleResolver* scopedStyleResolverFor(const ContainerNode& scopingNode);
// for fast-path.
bool hasOnlyScopedResolverForDocument() const { return m_authorStyles.size() == 1; }
void resolveScopedStyles(const Element*, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>&);
void collectScopedResolversForHostedShadowTrees(const Element*, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>&);
void resolveScopedKeyframesRules(const Element*, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>&);
ScopedStyleResolver* scopedResolverFor(const Element*);
void remove(const ContainerNode* scopingNode);
void pushStyleCache(const ContainerNode& scopingNode, const ContainerNode* parent);
void popStyleCache(const ContainerNode& scopingNode);
void collectFeaturesTo(RuleFeatureSet& features);
void trace(Visitor*);
private:
bool cacheIsValid(const ContainerNode* parent) const { return parent && parent == m_cache.nodeForScopedStyles; }
void resolveStyleCache(const ContainerNode* scopingNode);
ScopedStyleResolver* enclosingScopedStyleResolverFor(const ContainerNode* scopingNode);
WillBeHeapHashMap<RawPtrWillBeMember<const ContainerNode>, RawPtrWillBeMember<ScopedStyleResolver> > m_authorStyles;
class ScopedStyleCache {
DISALLOW_ALLOCATION();
public:
RawPtrWillBeMember<ScopedStyleResolver> scopedResolver;
RawPtrWillBeMember<const ContainerNode> nodeForScopedStyles;
ScopedStyleCache()
: scopedResolver(nullptr)
, nodeForScopedStyles(nullptr)
{
}
void clear()
{
scopedResolver = nullptr;
nodeForScopedStyles = nullptr;
}
void trace(Visitor* visitor)
{
visitor->trace(scopedResolver);
visitor->trace(nodeForScopedStyles);
}
};
ScopedStyleCache m_cache;
ScopedStyleResolver* scopedResolverFor(const Element*);
};
inline ScopedStyleResolver* ScopedStyleTree::scopedResolverFor(const Element* element)
{
if (!cacheIsValid(element))
resolveStyleCache(element);
return m_cache.scopedResolver;
}
} // namespace blink
#endif // ScopedStyleTree_h
......@@ -143,7 +143,7 @@ StyleResolver::StyleResolver(Document& document)
else
m_medium = adoptPtr(new MediaQueryEvaluator("all"));
m_styleTree.ensureScopedStyleResolver(document);
m_scopedStyleResolvers.add(&document.ensureScopedStyleResolver());
initWatchedSelectorRules(CSSSelectorWatch::from(document).watchedCallbackSelectors());
......@@ -190,7 +190,8 @@ void StyleResolver::appendCSSStyleSheet(CSSStyleSheet* cssSheet)
if (!scopingNode)
return;
ScopedStyleResolver* resolver = m_styleTree.ensureScopedStyleResolver(*scopingNode);
ScopedStyleResolver* resolver = &scopingNode->treeScope().ensureScopedStyleResolver();
m_scopedStyleResolvers.add(resolver);
ASSERT(resolver);
resolver->addRulesFromSheet(cssSheet, *m_medium, this);
}
......@@ -237,8 +238,10 @@ void StyleResolver::resetRuleFeatures()
void StyleResolver::processScopedRules(const RuleSet& authorRules, CSSStyleSheet* parentStyleSheet, ContainerNode& scope)
{
const WillBeHeapVector<RawPtrWillBeMember<StyleRuleKeyframes> > keyframesRules = authorRules.keyframesRules();
ScopedStyleResolver* resolver = &scope.treeScope().ensureScopedStyleResolver();
m_scopedStyleResolvers.add(resolver);
for (unsigned i = 0; i < keyframesRules.size(); ++i)
m_styleTree.ensureScopedStyleResolver(scope)->addKeyframeStyle(keyframesRules[i]);
resolver->addKeyframeStyle(keyframesRules[i]);
m_treeBoundaryCrossingRules.addTreeBoundaryCrossingRules(authorRules, scope, parentStyleSheet);
......@@ -252,20 +255,22 @@ void StyleResolver::processScopedRules(const RuleSet& authorRules, CSSStyleSheet
}
}
void StyleResolver::resetAuthorStyle(const ContainerNode* scopingNode)
void StyleResolver::resetAuthorStyle(TreeScope& treeScope)
{
ScopedStyleResolver* resolver = scopingNode ? scopingNode->treeScope().scopedStyleResolver() : m_document.scopedStyleResolver();
ScopedStyleResolver* resolver = treeScope.scopedStyleResolver();
if (!resolver)
return;
m_treeBoundaryCrossingRules.reset(scopingNode);
m_treeBoundaryCrossingRules.reset(&treeScope.rootNode());
resolver->resetAuthorStyle();
resetRuleFeatures();
if (!scopingNode)
if (treeScope.rootNode().isDocumentNode())
return;
m_styleTree.remove(scopingNode);
// resolver is going to be freed below.
m_scopedStyleResolvers.remove(resolver);
treeScope.clearScopedStyleResolver();
}
static PassOwnPtrWillBeRawPtr<RuleSet> makeRuleSet(const WillBeHeapVector<RuleFeature>& rules)
......@@ -300,7 +305,9 @@ void StyleResolver::collectFeatures()
m_treeBoundaryCrossingRules.collectFeaturesTo(m_features);
m_styleTree.collectFeaturesTo(m_features);
HashSet<const StyleSheetContents*> visitedSharedStyleSheetContents;
for (WillBeHeapHashSet<RawPtrWillBeMember<const ScopedStyleResolver> >::iterator it = m_scopedStyleResolvers.begin(); it != m_scopedStyleResolvers.end(); ++it)
(*it)->collectFeaturesTo(m_features, visitedSharedStyleSheetContents);
m_siblingRuleSet = makeRuleSet(m_features.siblingRules);
m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules);
......@@ -355,9 +362,6 @@ void StyleResolver::pushParentElement(Element& parent)
m_selectorFilter.setupParentStack(parent);
else
m_selectorFilter.pushParent(parent);
// Note: We mustn't skip ShadowRoot nodes for the scope stack.
m_styleTree.pushStyleCache(parent, parent.parentOrShadowHostNode());
}
void StyleResolver::popParentElement(Element& parent)
......@@ -366,20 +370,6 @@ void StyleResolver::popParentElement(Element& parent)
// Pause maintaining the stack in this case.
if (m_selectorFilter.parentStackIsConsistent(&parent))
m_selectorFilter.popParent();
m_styleTree.popStyleCache(parent);
}
void StyleResolver::pushParentShadowRoot(const ShadowRoot& shadowRoot)
{
ASSERT(shadowRoot.host());
m_styleTree.pushStyleCache(shadowRoot, shadowRoot.host());
}
void StyleResolver::popParentShadowRoot(const ShadowRoot& shadowRoot)
{
ASSERT(shadowRoot.host());
m_styleTree.popStyleCache(shadowRoot);
}
StyleResolver::~StyleResolver()
......@@ -419,7 +409,7 @@ void StyleResolver::matchAuthorRules(Element* element, ElementRuleCollector& col
collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().matchedProperties.size() - 1;
bool applyAuthorStyles = applyAuthorStylesOf(element);
if (m_styleTree.hasOnlyScopedResolverForDocument()) {
if (m_scopedStyleResolvers.size() == 1) {
m_document.scopedStyleResolver()->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, ignoreCascadeScope);
m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
collector.sortAndTransferMatchedRules();
......@@ -1574,6 +1564,7 @@ void StyleResolver::trace(Visitor* visitor)
visitor->trace(m_treeBoundaryCrossingRules);
visitor->trace(m_pendingStyleSheets);
visitor->trace(m_styleTree);
visitor->trace(m_scopedStyleResolvers);
#endif
}
......
......@@ -111,8 +111,6 @@ public:
// Using these during tree walk will allow style selector to optimize child and descendant selector lookups.
void pushParentElement(Element&);
void popParentElement(Element&);
void pushParentShadowRoot(const ShadowRoot&);
void popParentShadowRoot(const ShadowRoot&);
PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, StyleSharingBehavior = AllowStyleSharing,
RuleMatchingBehavior = MatchAllRules);
......@@ -136,7 +134,7 @@ public:
// FIXME: It could be better to call appendAuthorStyleSheets() directly after we factor StyleResolver further.
// https://bugs.webkit.org/show_bug.cgi?id=108890
void appendAuthorStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >&);
void resetAuthorStyle(const ContainerNode*);
void resetAuthorStyle(TreeScope&);
void finishAppendAuthorStyleSheets();
void processScopedRules(const RuleSet& authorRules, CSSStyleSheet*, ContainerNode& scope);
......@@ -148,7 +146,7 @@ public:
SelectorFilter& selectorFilter() { return m_selectorFilter; }
bool styleTreeHasOnlyScopedResolverForDocument() const { return m_styleTree.hasOnlyScopedResolverForDocument(); }
bool styleTreeHasOnlyScopedResolverForDocument() const { return m_scopedStyleResolvers.size() == 1; }
void styleTreeResolveScopedKeyframesRules(const Element* element, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers)
{
......@@ -300,6 +298,8 @@ private:
WillBeHeapListHashSet<RawPtrWillBeMember<CSSStyleSheet>, 16> m_pendingStyleSheets;
ScopedStyleTree m_styleTree;
// FIXME: Probably this should move to StyleEngine eventually.
WillBeHeapHashSet<RawPtrWillBeMember<const ScopedStyleResolver> > m_scopedStyleResolvers;
// FIXME: The entire logic of collecting features on StyleResolver, as well as transferring them
// between various parts of machinery smells wrong. This needs to be better somehow.
......
......@@ -51,8 +51,6 @@ inline StyleResolverParentScope::~StyleResolverParentScope()
return;
if (m_parent.isElementNode())
m_resolver.popParentElement(toElement(m_parent));
else
m_resolver.popParentShadowRoot(toShadowRoot(m_parent));
}
inline void StyleResolverParentScope::ensureParentStackIsPushed()
......@@ -69,8 +67,6 @@ inline void StyleResolverParentScope::pushParentIfNeeded()
m_previous->pushParentIfNeeded();
if (m_parent.isElementNode())
m_resolver.pushParentElement(toElement(m_parent));
else
m_resolver.pushParentShadowRoot(toShadowRoot(m_parent));
m_pushed = true;
}
......
......@@ -107,7 +107,7 @@ void DocumentStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine,
} else if (StyleResolver* styleResolver = engine->resolver()) {
if (change.styleResolverUpdateType != Additive) {
ASSERT(change.styleResolverUpdateType == Reset);
styleResolver->resetAuthorStyle(&m_treeScope.rootNode());
styleResolver->resetAuthorStyle(m_treeScope);
engine->removeFontFaceRules(change.fontFaceRulesToRemove);
styleResolver->removePendingAuthorStyleSheets(m_activeAuthorStyleSheets);
styleResolver->lazyAppendAuthorStyleSheets(0, collection.activeAuthorStyleSheets());
......
......@@ -99,7 +99,7 @@ void ShadowTreeStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine
if (change.styleResolverUpdateType != Additive) {
// We should not destroy StyleResolver when we find any stylesheet update in a shadow tree.
// In this case, we will reset rulesets created from style elements in the shadow tree.
styleResolver->resetAuthorStyle(&m_treeScope.rootNode());
styleResolver->resetAuthorStyle(m_treeScope);
styleResolver->removePendingAuthorStyleSheets(m_activeAuthorStyleSheets);
styleResolver->lazyAppendAuthorStyleSheets(0, collection.activeAuthorStyleSheets());
} else {
......
......@@ -486,6 +486,11 @@ void StyleEngine::clearResolver()
{
ASSERT(!document().inStyleRecalc());
ASSERT(isMaster() || !m_resolver);
m_document->clearScopedStyleResolver();
for (StyleSheetCollectionMap::iterator it = m_styleSheetCollectionMap.begin(); it != m_styleSheetCollectionMap.end(); ++it)
it->key->clearScopedStyleResolver();
if (m_resolver)
document().updateStyleInvalidationIfNeeded();
m_resolver.clear();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment