Index: Source/core/css/resolver/StyleResolver.cpp |
diff --git a/Source/core/css/resolver/StyleResolver.cpp b/Source/core/css/resolver/StyleResolver.cpp |
index 532a9761627637d9196e940af44f51ad9cca6646..7048a3308338cbcfa089748eec7038d12a55ce29 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" |
@@ -126,6 +128,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) |
{ |
@@ -178,6 +181,100 @@ void StyleResolver::initWatchedSelectorRules(const Vector<RefPtr<StyleRule> >& w |
m_watchedSelectorsRules->addStyleRule(watchedSelectors[i].get(), RuleHasNoSpecialState); |
} |
+void StyleResolver::filterViewportRules(const Vector<RefPtr<StyleRuleBase> >& rules, bool& needsResolveViewport) |
+{ |
+ 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()))) |
+ filterViewportRules(mediaRule->childRules(), needsResolveViewport); |
+ } |
+ } |
+} |
+ |
+void StyleResolver::filterViewportRulesFromSheet(StyleSheetContents* sheet, bool& needsResolveViewport) |
+{ |
+ if (!sheet) |
+ return; |
+ |
+ if (sheet->importRules().size() > 0) { |
+ const Vector<RefPtr<StyleRuleImport> >& importRules = sheet->importRules(); |
+ for (unsigned i = 0; i < importRules.size(); ++i) { |
+ StyleRuleImport* importRule = importRules[i].get(); |
+ filterViewportRulesFromSheet(importRule->styleSheet(), needsResolveViewport); |
+ } |
+ } |
+ filterViewportRules(sheet->childRules(), 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; |
+ filterViewportRulesFromSheet(cssSheet->contents(), needsResolveViewport); |
+ } |
+ return needsResolveViewport; |
+} |
+ |
+void StyleResolver::lazyAppendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets) |
+{ |
+ // FIXME: Currently We cannot lazy apppend stylesheets if the sheets have @viewport and @font-face rules. |
+ // Need to find the best place to update pending stylesheets for "viewport" rules. |
+ // Talking about @font-face rules, addFontFaceRule triggers loading font resources. |
+ // If we delays "addFontFaceRule", we probably wait more time until fonts are loaded. |
dglazkov
2013/11/13 16:29:22
/delays/delay/s ... /probably/could/s
tasak
2013/11/14 11:25:46
I removed this, because now we can lazily add @fon
|
+ // At least, we should filter @viewport and @font-face here and should lazily add other rules if possible. |
+ 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) { |
+ CSSStyleSheet* cssSheet = *it; |
+ ASSERT(!cssSheet->disabled()); |
+ if (cssSheet->mediaQueries() && !m_medium->eval(cssSheet->mediaQueries(), &m_viewportDependentMediaQueryResults)) |
+ continue; |
+ |
+ StyleSheetContents* sheet = cssSheet->contents(); |
+ const 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 |
@@ -196,7 +293,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); |
} |
} |
@@ -209,6 +306,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::processScopedRules(const RuleSet& authorRules, const KURL& sheetBaseURL, const ContainerNode* scope) |
@@ -248,6 +356,7 @@ void StyleResolver::resetAuthorStyle(const ContainerNode* scopingNode) |
treeBoundaryCrossingRules().reset(scopingNode); |
resolver->resetAuthorStyle(); |
+ resetRuleFeatures(); |
if (!scopingNode) |
return; |
@@ -310,6 +419,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 |
@@ -647,6 +757,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. |
@@ -740,6 +852,7 @@ PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element* e, const Render |
{ |
ASSERT(document().frame()); |
ASSERT(documentSettings()); |
+ ASSERT(!hasPendingAuthorStyleSheets()); |
if (e == document().documentElement()) |
resetDirectionAndWritingModeOnDocument(document()); |
@@ -798,6 +911,9 @@ void StyleResolver::keyframeStylesForAnimation(Element* e, const RenderStyle& el |
if (!e || list.animationName().isEmpty()) |
return; |
+ if (hasPendingAuthorStyleSheets()) |
+ appendPendingAuthorStyleSheets(); |
+ |
const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframesRule(this, e, list.animationName().impl()); |
if (!keyframesRule) |
return; |
@@ -906,6 +1022,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. |