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

Unified Diff: Source/core/css/resolver/StyleResolver.cpp

Issue 42543007: StyleResolver should update RuleSets lazily. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Revised Created 7 years, 1 month 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
« no previous file with comments | « Source/core/css/resolver/StyleResolver.h ('k') | Source/core/dom/Document.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/css/resolver/StyleResolver.cpp
diff --git a/Source/core/css/resolver/StyleResolver.cpp b/Source/core/css/resolver/StyleResolver.cpp
index 547c0a81ca61db86859492dadcf69ad437050a9b..71c714ff23c76b63bd992b1d0ba54ef52f8e4701 100644
--- a/Source/core/css/resolver/StyleResolver.cpp
+++ b/Source/core/css/resolver/StyleResolver.cpp
@@ -57,6 +57,8 @@
#include "core/css/PageRuleCollector.h"
#include "core/css/RuleSet.h"
#include "core/css/StylePropertySet.h"
+#include "core/css/StyleRuleImport.h"
+#include "core/css/StyleSheetContents.h"
#include "core/css/resolver/AnimatedStyleBuilder.h"
#include "core/css/resolver/MatchResult.h"
#include "core/css/resolver/MediaQueryResult.h"
@@ -106,6 +108,12 @@ using namespace HTMLNames;
RenderStyle* StyleResolver::s_styleNotYetAvailable;
+inline bool isDocumentScope(const ContainerNode* scope)
+{
+ // FIXME: scope should not be null. scope should be a ShadowRoot or a Document.
+ return !scope || scope->isDocumentNode();
+}
+
static StylePropertySet* leftToRightDeclaration()
{
DEFINE_STATIC_REF(MutableStylePropertySet, leftToRightDecl, (MutableStylePropertySet::create()));
@@ -126,6 +134,7 @@ StyleResolver::StyleResolver(Document& document)
: m_document(document)
, m_fontSelector(CSSFontSelector::create(&document))
, m_viewportStyleResolver(ViewportStyleResolver::create(&document))
+ , m_needCollectFeatures(false)
, m_styleResourceLoader(document.fetcher())
, m_styleResolverStatsSequence(0)
, m_accessCount(0)
@@ -179,6 +188,106 @@ void StyleResolver::initWatchedSelectorRules(const Vector<RefPtr<StyleRule> >& w
m_watchedSelectorsRules->addStyleRule(watchedSelectors[i].get(), RuleHasNoSpecialState);
}
+bool StyleResolver::filterViewportRules(const Vector<RefPtr<StyleRuleBase> >& rules)
+{
+ bool needsResolveViewport = false;
+
+ for (unsigned i = 0; i < rules.size(); ++i) {
+ StyleRuleBase* rule = rules[i].get();
+
+ if (rule->isViewportRule()) {
+ m_styleTree.ensureScopedStyleResolver(m_document)->addViewportRule(toStyleRuleViewport(rule));
+ needsResolveViewport = true;
+ } else if (rule->isMediaRule()) {
+ const StyleRuleMedia* mediaRule = toStyleRuleMedia(rule);
+ if ((!mediaRule->mediaQueries() || m_medium->eval(mediaRule->mediaQueries(), viewportDependentMediaQueryResults()))) {
+ if (filterViewportRules(mediaRule->childRules()))
+ needsResolveViewport = true;
+ }
+ }
+ }
+ return needsResolveViewport;
+}
+
+bool StyleResolver::filterViewportRulesFromSheet(StyleSheetContents* sheet)
+{
+ if (!sheet)
+ return false;
+
+ bool needsResolveViewport = false;
+ const Vector<RefPtr<StyleRuleImport> >& importRules = sheet->importRules();
+ for (unsigned i = 0; i < importRules.size(); ++i) {
+ StyleRuleImport* importRule = importRules[i].get();
+ if (filterViewportRulesFromSheet(importRule->styleSheet()))
+ needsResolveViewport = true;
+ }
+
+ if (filterViewportRules(sheet->childRules()))
+ needsResolveViewport = true;
+ return needsResolveViewport;
+}
+
+bool StyleResolver::filterViewportRulesFromAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+{
+ bool needsResolveViewport = false;
+
+ unsigned size = styleSheets.size();
+ for (unsigned i = firstNew; i < size; ++i) {
+ CSSStyleSheet* cssSheet = styleSheets[i].get();
+ ASSERT(!cssSheet->disabled());
+ if (cssSheet->mediaQueries() && !m_medium->eval(cssSheet->mediaQueries(), &m_viewportDependentMediaQueryResults))
+ continue;
+ if (cssSheet->ownerNode()->isInShadowTree() || !isDocumentScope(ScopedStyleResolver::scopingNodeFor(cssSheet)))
+ continue;
+ if (filterViewportRulesFromSheet(cssSheet->contents()))
+ needsResolveViewport = true;
+ }
+ return needsResolveViewport;
+}
+
+void StyleResolver::lazyAppendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+{
+ // FIXME: Currently We cannot lazy apppend stylesheets if the sheets have @viewport rules.
+ // Need to find the best place to update pending stylesheets for "viewport" rules.
+ bool needsResolveViewport = filterViewportRulesFromAuthorStyleSheets(firstNew, styleSheets);
+
+ unsigned size = styleSheets.size();
+ for (unsigned i = firstNew; i < size; ++i)
+ m_pendingStyleSheets.add(styleSheets[i].get());
+
+ if (needsResolveViewport)
+ collectViewportRules();
+}
+
+void StyleResolver::removePendingAuthorStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+{
+ for (unsigned i = 0; i < styleSheets.size(); ++i)
+ m_pendingStyleSheets.remove(styleSheets[i].get());
+}
+
+void StyleResolver::appendPendingAuthorStyleSheets()
+{
+ setBuildScopedStyleTreeInDocumentOrder(false);
+ for (ListHashSet<CSSStyleSheet*, 16>::iterator it = m_pendingStyleSheets.begin(); it != m_pendingStyleSheets.end(); ++it) {
ojan 2013/11/19 17:35:05 Is it safe for StyleResolver to hold raw pointers
+ CSSStyleSheet* cssSheet = *it;
+ ASSERT(!cssSheet->disabled());
+ if (cssSheet->mediaQueries() && !m_medium->eval(cssSheet->mediaQueries(), &m_viewportDependentMediaQueryResults))
+ continue;
+
+ StyleSheetContents* sheet = cssSheet->contents();
+ ContainerNode* scopingNode = ScopedStyleResolver::scopingNodeFor(cssSheet);
+ if (!scopingNode && cssSheet->ownerNode() && cssSheet->ownerNode()->isInShadowTree())
+ continue;
+
+ ScopedStyleResolver* resolver = ensureScopedStyleResolver(scopingNode);
+ ASSERT(resolver);
+ resolver->addRulesFromSheet(sheet, *m_medium, this, true);
+ m_inspectorCSSOMWrappers.collectFromStyleSheetIfNeeded(cssSheet);
+ }
+ m_pendingStyleSheets.clear();
+ finishAppendAuthorStyleSheets();
+}
+
void StyleResolver::appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
{
// This handles sheets added to the end of the stylesheet list only. In other cases the style resolver
@@ -197,7 +306,7 @@ void StyleResolver::appendAuthorStyleSheets(unsigned firstNew, const Vector<RefP
ScopedStyleResolver* resolver = ensureScopedStyleResolver(scopingNode);
ASSERT(resolver);
- resolver->addRulesFromSheet(sheet, *m_medium, this);
+ resolver->addRulesFromSheet(sheet, *m_medium, this, false);
m_inspectorCSSOMWrappers.collectFromStyleSheetIfNeeded(cssSheet);
}
}
@@ -210,6 +319,17 @@ void StyleResolver::finishAppendAuthorStyleSheets()
document().renderer()->style()->font().update(fontSelector());
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::addTreeBoundaryCrossingRules(const Vector<MinimalRuleData>& rules, ContainerNode* scope)
@@ -272,6 +392,7 @@ void StyleResolver::resetAuthorStyle(const ContainerNode* scopingNode)
treeBoundaryCrossingRules().reset(scopingNode);
resolver->resetAuthorStyle();
+ resetRuleFeatures();
if (!scopingNode)
return;
@@ -334,6 +455,7 @@ void StyleResolver::collectFeatures()
m_siblingRuleSet = makeRuleSet(m_features.siblingRules);
m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules);
+ m_needCollectFeatures = false;
}
bool StyleResolver::hasRulesForId(const AtomicString& id) const
@@ -662,6 +784,8 @@ PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS
{
ASSERT(document().frame());
ASSERT(documentSettings());
+ ASSERT(!hasPendingAuthorStyleSheets());
+ ASSERT(!m_needCollectFeatures);
// Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
// will vanish if a style recalc happens during loading.
@@ -755,6 +879,7 @@ PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element* e, const Render
{
ASSERT(document().frame());
ASSERT(documentSettings());
+ ASSERT(!hasPendingAuthorStyleSheets());
if (e == document().documentElement())
resetDirectionAndWritingModeOnDocument(document());
@@ -814,6 +939,7 @@ void StyleResolver::keyframeStylesForAnimation(Element* e, const RenderStyle& el
if (!e || list.animationName().isEmpty())
return;
+ ASSERT(!hasPendingAuthorStyleSheets());
const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframesRule(this, e, list.animationName().impl());
if (!keyframesRule)
return;
@@ -922,6 +1048,7 @@ PassRefPtr<RenderStyle> StyleResolver::pseudoStyleForElement(Element* e, const P
PassRefPtr<RenderStyle> StyleResolver::styleForPage(int pageIndex)
{
+ ASSERT(!hasPendingAuthorStyleSheets());
resetDirectionAndWritingModeOnDocument(document());
StyleResolverState state(document(), document().documentElement()); // m_rootElementStyle will be set to the document style.
« no previous file with comments | « Source/core/css/resolver/StyleResolver.h ('k') | Source/core/dom/Document.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698