#include "config.h"
#include "core/css/resolver/StyleResolver.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "StylePropertyShorthand.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
+#include "core/MediaTypeNames.h"
+#include "core/StylePropertyShorthand.h"
#include "core/animation/ActiveAnimations.h"
-#include "core/animation/AnimatableLength.h"
-#include "core/animation/AnimatableValue.h"
#include "core/animation/Animation.h"
-#include "core/animation/DocumentTimeline.h"
+#include "core/animation/AnimationTimeline.h"
+#include "core/animation/StyleInterpolation.h"
+#include "core/animation/animatable/AnimatableValue.h"
#include "core/animation/css/CSSAnimatableValueFactory.h"
#include "core/animation/css/CSSAnimations.h"
#include "core/css/CSSCalculationValue.h"
#include "core/css/CSSFontSelector.h"
#include "core/css/CSSKeyframeRule.h"
#include "core/css/CSSKeyframesRule.h"
-#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSReflectValue.h"
#include "core/css/CSSRuleList.h"
#include "core/css/CSSSelector.h"
#include "core/css/CSSStyleRule.h"
#include "core/css/CSSValueList.h"
+#include "core/css/CSSValuePool.h"
#include "core/css/ElementRuleCollector.h"
#include "core/css/FontFace.h"
#include "core/css/MediaQueryEvaluator.h"
#include "core/css/resolver/MediaQueryResult.h"
#include "core/css/resolver/SharedStyleFinder.h"
#include "core/css/resolver/StyleAdjuster.h"
+#include "core/css/resolver/StyleResolverParentScope.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/Text.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLIFrameElement.h"
#include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/style/KeyframeList.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGElement.h"
#include "core/svg/SVGFontFaceElement.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/StdLibExtras.h"
-using namespace std;
-
namespace {
-using namespace WebCore;
+using namespace blink;
void setAnimationUpdateIfNeeded(StyleResolverState& state, Element& element)
{
// If any changes to CSS Animations were detected, stash the update away for application after the
// render object is updated if we're in the appropriate scope.
if (state.animationUpdate())
- element.ensureActiveAnimations()->cssAnimations().setPendingUpdate(state.takeAnimationUpdate());
+ element.ensureActiveAnimations().cssAnimations().setPendingUpdate(state.takeAnimationUpdate());
}
} // namespace
-namespace WebCore {
+namespace blink {
using namespace HTMLNames;
static StylePropertySet* leftToRightDeclaration()
{
- DEFINE_STATIC_REF(MutableStylePropertySet, leftToRightDecl, (MutableStylePropertySet::create()));
+ DEFINE_STATIC_REF_WILL_BE_PERSISTENT(MutableStylePropertySet, leftToRightDecl, (MutableStylePropertySet::create()));
if (leftToRightDecl->isEmpty())
leftToRightDecl->setProperty(CSSPropertyDirection, CSSValueLtr);
return leftToRightDecl;
static StylePropertySet* rightToLeftDeclaration()
{
- DEFINE_STATIC_REF(MutableStylePropertySet, rightToLeftDecl, (MutableStylePropertySet::create()));
+ DEFINE_STATIC_REF_WILL_BE_PERSISTENT(MutableStylePropertySet, rightToLeftDecl, (MutableStylePropertySet::create()));
if (rightToLeftDecl->isEmpty())
rightToLeftDecl->setProperty(CSSPropertyDirection, CSSValueRtl);
return rightToLeftDecl;
static void addFontFaceRule(Document* document, CSSFontSelector* cssFontSelector, const StyleRuleFontFace* fontFaceRule)
{
- RefPtr<FontFace> fontFace = FontFace::create(document, fontFaceRule);
+ RefPtrWillBeRawPtr<FontFace> fontFace = FontFace::create(document, fontFaceRule);
if (fontFace)
cssFontSelector->fontFaceCache()->add(cssFontSelector, fontFaceRule, fontFace);
}
: m_document(document)
, m_viewportStyleResolver(ViewportStyleResolver::create(&document))
, m_needCollectFeatures(false)
+ , m_printMediaType(false)
, m_styleResourceLoader(document.fetcher())
+ , m_styleSharingDepth(0)
, m_styleResolverStatsSequence(0)
, m_accessCount(0)
{
- // Construct document root element default style. This is needed
- // to evaluate media queries that contain relative constraints, like "screen and (max-width: 10em)"
- // This is here instead of constructor because when constructor is run,
- // Document doesn't have documentElement.
- // NOTE: This assumes that element that gets passed to the styleForElement call
- // is always from the document that owns the StyleResolver.
FrameView* view = document.view();
- if (view)
- m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType()));
- else
+ if (view) {
+ m_medium = adoptPtr(new MediaQueryEvaluator(&view->frame()));
+ m_printMediaType = equalIgnoringCase(view->mediaType(), MediaTypeNames::print);
+ } else {
m_medium = adoptPtr(new MediaQueryEvaluator("all"));
-
- Element* root = document.documentElement();
- if (root)
- m_rootDefaultStyle = styleForElement(root, 0, DisallowStyleSharing, MatchOnlyUserAgentRules);
-
- if (m_rootDefaultStyle && view)
- m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType(), &view->frame(), m_rootDefaultStyle.get()));
-
- m_styleTree.clear();
+ }
initWatchedSelectorRules(CSSSelectorWatch::from(document).watchedCallbackSelectors());
#if ENABLE(SVG_FONTS)
if (document.svgExtensions()) {
- const HashSet<SVGFontFaceElement*>& svgFontFaceElements = document.svgExtensions()->svgFontFaceElements();
- HashSet<SVGFontFaceElement*>::const_iterator end = svgFontFaceElements.end();
- for (HashSet<SVGFontFaceElement*>::const_iterator it = svgFontFaceElements.begin(); it != end; ++it)
+ const WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> >& svgFontFaceElements = document.svgExtensions()->svgFontFaceElements();
+ WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> >::const_iterator end = svgFontFaceElements.end();
+ for (WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> >::const_iterator it = svgFontFaceElements.begin(); it != end; ++it)
addFontFaceRule(&document, document.styleEngine()->fontSelector(), (*it)->fontFaceRule());
}
#endif
}
-void StyleResolver::initWatchedSelectorRules(const Vector<RefPtr<StyleRule> >& watchedSelectors)
+void StyleResolver::initWatchedSelectorRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRule> >& watchedSelectors)
{
if (!watchedSelectors.size())
return;
m_watchedSelectorsRules->addStyleRule(watchedSelectors[i].get(), RuleHasNoSpecialState);
}
-void StyleResolver::lazyAppendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+void StyleResolver::lazyAppendAuthorStyleSheets(unsigned firstNew, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
{
unsigned size = styleSheets.size();
for (unsigned i = firstNew; i < size; ++i)
m_pendingStyleSheets.add(styleSheets[i].get());
}
-void StyleResolver::removePendingAuthorStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+void StyleResolver::removePendingAuthorStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
{
for (unsigned i = 0; i < styleSheets.size(); ++i)
m_pendingStyleSheets.remove(styleSheets[i].get());
if (cssSheet->mediaQueries() && !m_medium->eval(cssSheet->mediaQueries(), &m_viewportDependentMediaQueryResults))
return;
- ContainerNode* scopingNode = ScopedStyleResolver::scopingNodeFor(document(), cssSheet);
- if (!scopingNode)
+ TreeScope* treeScope = ScopedStyleResolver::treeScopeFor(document(), cssSheet);
+ if (!treeScope)
return;
- ScopedStyleResolver* resolver = ensureScopedStyleResolver(scopingNode);
- ASSERT(resolver);
- resolver->addRulesFromSheet(cssSheet, *m_medium, this);
+ ScopedStyleResolver& resolver = treeScope->ensureScopedStyleResolver();
+ document().styleEngine()->addScopedStyleResolver(&resolver);
+ resolver.addRulesFromSheet(cssSheet, *m_medium, this);
}
void StyleResolver::appendPendingAuthorStyleSheets()
{
- setBuildScopedStyleTreeInDocumentOrder(false);
- for (ListHashSet<CSSStyleSheet*, 16>::iterator it = m_pendingStyleSheets.begin(); it != m_pendingStyleSheets.end(); ++it)
+ for (WillBeHeapListHashSet<RawPtrWillBeMember<CSSStyleSheet>, 16>::iterator it = m_pendingStyleSheets.begin(); it != m_pendingStyleSheets.end(); ++it)
appendCSSStyleSheet(*it);
m_pendingStyleSheets.clear();
finishAppendAuthorStyleSheets();
}
-void StyleResolver::appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+void StyleResolver::appendAuthorStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<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.
unsigned size = styleSheets.size();
- for (unsigned i = firstNew; i < size; ++i)
+ for (unsigned i = 0; i < size; ++i)
appendCSSStyleSheet(styleSheets[i].get());
}
{
collectFeatures();
- if (document().renderer() && document().renderer()->style())
- document().renderer()->style()->font().update(document().styleEngine()->fontSelector());
+ if (document().renderView() && document().renderView()->style())
+ document().renderView()->style()->font().update(document().styleEngine()->fontSelector());
collectViewportRules();
m_needCollectFeatures = true;
}
-void StyleResolver::addTreeBoundaryCrossingRules(const Vector<MinimalRuleData>& rules, ContainerNode* scope)
+void StyleResolver::processScopedRules(const RuleSet& authorRules, CSSStyleSheet* parentStyleSheet, unsigned parentIndex, ContainerNode& scope)
{
- for (unsigned i = 0; i < rules.size(); ++i) {
- const MinimalRuleData& info = rules[i];
- m_treeBoundaryCrossingRules.addRule(info.m_rule, info.m_selectorIndex, scope, info.m_flags);
- }
-}
-
-void StyleResolver::processScopedRules(const RuleSet& authorRules, const KURL& sheetBaseURL, ContainerNode* scope)
-{
- const Vector<StyleRuleKeyframes*> keyframesRules = authorRules.keyframesRules();
+ const WillBeHeapVector<RawPtrWillBeMember<StyleRuleKeyframes> > keyframesRules = authorRules.keyframesRules();
+ ScopedStyleResolver* resolver = &scope.treeScope().ensureScopedStyleResolver();
+ document().styleEngine()->addScopedStyleResolver(resolver);
for (unsigned i = 0; i < keyframesRules.size(); ++i)
- ensureScopedStyleResolver(scope)->addKeyframeStyle(keyframesRules[i]);
+ resolver->addKeyframeStyle(keyframesRules[i]);
- addTreeBoundaryCrossingRules(authorRules.treeBoundaryCrossingRules(), scope);
+ m_treeBoundaryCrossingRules.addTreeBoundaryCrossingRules(authorRules, parentStyleSheet, parentIndex, scope);
// FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment.
- if (!scope || scope->isDocumentNode()) {
- const Vector<StyleRuleFontFace*> fontFaceRules = authorRules.fontFaceRules();
+ if (scope.isDocumentNode()) {
+ const WillBeHeapVector<RawPtrWillBeMember<StyleRuleFontFace> > fontFaceRules = authorRules.fontFaceRules();
for (unsigned i = 0; i < fontFaceRules.size(); ++i)
- addFontFaceRule(&m_document, document().styleEngine()->fontSelector(), fontFaceRules[i]);
+ addFontFaceRule(m_document, document().styleEngine()->fontSelector(), fontFaceRules[i]);
if (fontFaceRules.size())
invalidateMatchedPropertiesCache();
- } else {
- addTreeBoundaryCrossingRules(authorRules.shadowDistributedRules(), scope);
}
}
-void StyleResolver::resetAuthorStyle(const ContainerNode* scopingNode)
+void StyleResolver::resetAuthorStyle(TreeScope& treeScope)
{
- // FIXME: When chanking scoped attribute, scopingNode's hasScopedHTMLStyleChild has been already modified.
- // So we cannot use hasScopedHTMLStyleChild flag here.
- ScopedStyleResolver* resolver = scopingNode ? m_styleTree.lookupScopedStyleResolverFor(scopingNode) : m_styleTree.scopedStyleResolverForDocument();
+ ScopedStyleResolver* resolver = treeScope.scopedStyleResolver();
if (!resolver)
return;
- 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.
+ document().styleEngine()->removeScopedStyleResolver(resolver);
+ treeScope.clearScopedStyleResolver();
}
-static PassOwnPtr<RuleSet> makeRuleSet(const Vector<RuleFeature>& rules)
+static PassOwnPtrWillBeRawPtr<RuleSet> makeRuleSet(const WillBeHeapVector<RuleFeature>& rules)
{
size_t size = rules.size();
if (!size)
return nullptr;
- OwnPtr<RuleSet> ruleSet = RuleSet::create();
+ OwnPtrWillBeRawPtr<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.release();
if (document().isViewSource())
m_features.add(defaultStyleSheets.defaultViewSourceStyle()->features());
+ if (document().isTransitionDocument())
+ m_features.add(defaultStyleSheets.defaultTransitionStyle()->features());
+
if (m_watchedSelectorsRules)
m_features.add(m_watchedSelectorsRules->features());
m_treeBoundaryCrossingRules.collectFeaturesTo(m_features);
- m_styleTree.collectFeaturesTo(m_features);
+ document().styleEngine()->collectScopedStyleFeaturesTo(m_features);
m_siblingRuleSet = makeRuleSet(m_features.siblingRules);
m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules);
if (!document().inStyleRecalc())
return;
INCREMENT_STYLE_STATS_COUNTER(*this, sharedStyleCandidates);
- if (m_styleSharingList.size() >= styleSharingListSize)
- m_styleSharingList.remove(--m_styleSharingList.end());
- m_styleSharingList.prepend(&element);
+ StyleSharingList& list = styleSharingList();
+ if (list.size() >= styleSharingListSize)
+ list.removeLast();
+ list.prepend(&element);
}
-void StyleResolver::clearStyleSharingList()
+StyleSharingList& StyleResolver::styleSharingList()
{
- m_styleSharingList.clear();
+ m_styleSharingLists.resize(styleSharingMaxDepth);
+
+ // We never put things at depth 0 into the list since that's only the <html> element
+ // and it has no siblings or cousins to share with.
+ unsigned depth = std::max(std::min(m_styleSharingDepth, styleSharingMaxDepth), 1u) - 1u;
+
+ if (!m_styleSharingLists[depth])
+ m_styleSharingLists[depth] = adoptPtrWillBeNoop(new StyleSharingList);
+ return *m_styleSharingLists[depth];
}
-void StyleResolver::fontsNeedUpdate(CSSFontSelector* fontSelector)
+void StyleResolver::clearStyleSharingList()
{
- invalidateMatchedPropertiesCache();
- m_document.setNeedsStyleRecalc(SubtreeStyleChange);
+ m_styleSharingLists.resize(0);
}
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)
// 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()
{
- m_viewportStyleResolver->clearDocument();
-}
-
-inline void StyleResolver::collectTreeBoundaryCrossingRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules)
-{
- if (m_treeBoundaryCrossingRules.isEmpty())
- return;
-
- RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange();
-
- // When comparing rules declared in outer treescopes, outer's rules win.
- CascadeOrder outerCascadeOrder = m_treeBoundaryCrossingRules.size() + m_treeBoundaryCrossingRules.size();
- // When comparing rules declared in inner treescopes, inner's rules win.
- CascadeOrder innerCascadeOrder = m_treeBoundaryCrossingRules.size();
-
- for (DocumentOrderedList::iterator it = m_treeBoundaryCrossingRules.begin(); it != m_treeBoundaryCrossingRules.end(); ++it) {
- const ContainerNode* scopingNode = toContainerNode(*it);
-
- if (ShadowRoot* shadowRoot = scopingNode->containingShadowRoot()) {
- if (!shadowRoot->isActiveForStyling())
- continue;
- }
-
- RuleSet* ruleSet = m_treeBoundaryCrossingRules.ruleSetScopedBy(scopingNode);
- unsigned boundaryBehavior = SelectorChecker::ScopeContainsLastMatchedElement;
- bool isInnerTreeScope = element->treeScope().isInclusiveAncestorOf(scopingNode->treeScope());
-
- // If a given scoping node is a shadow root and a given element is in a descendant tree of tree hosted by
- // the scoping node's shadow host, we should use ScopeIsShadowHost.
- if (scopingNode && scopingNode->isShadowRoot()) {
- if (element->isInDescendantTreeOf(toShadowRoot(scopingNode)->host()))
- boundaryBehavior |= SelectorChecker::ScopeIsShadowHost;
- scopingNode = toShadowRoot(scopingNode)->host();
- }
-
- CascadeOrder cascadeOrder = isInnerTreeScope ? innerCascadeOrder : outerCascadeOrder;
-
- collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRules, scopingNode), ruleRange, static_cast<SelectorChecker::BehaviorAtBoundary>(boundaryBehavior), ignoreCascadeScope, cascadeOrder);
- ++innerCascadeOrder;
- --outerCascadeOrder;
- }
-}
-
-static inline bool applyAuthorStylesOf(const Element* element)
-{
- return element->treeScope().applyAuthorStyles() || (element->shadow() && element->shadow()->applyAuthorStyles());
}
-void StyleResolver::matchAuthorRulesForShadowHost(Element* element, ElementRuleCollector& collector, bool includeEmptyRules, Vector<ScopedStyleResolver*, 8>& resolvers, Vector<ScopedStyleResolver*, 8>& resolversInShadowTree)
+void StyleResolver::matchAuthorRulesForShadowHost(Element* element, ElementRuleCollector& collector, bool includeEmptyRules, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolversInShadowTree)
{
collector.clearMatchedRules();
collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().matchedProperties.size() - 1;
CascadeScope cascadeScope = 0;
CascadeOrder cascadeOrder = 0;
- bool applyAuthorStyles = applyAuthorStylesOf(element);
for (int j = resolversInShadowTree.size() - 1; j >= 0; --j)
- resolversInShadowTree.at(j)->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope, cascadeOrder++);
+ resolversInShadowTree.at(j)->collectMatchingAuthorRules(collector, includeEmptyRules, cascadeScope, cascadeOrder++);
if (resolvers.isEmpty() || resolvers.first()->treeScope() != element->treeScope())
++cascadeScope;
cascadeOrder += resolvers.size();
for (unsigned i = 0; i < resolvers.size(); ++i)
- resolvers.at(i)->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope++, --cascadeOrder);
+ resolvers.at(i)->collectMatchingAuthorRules(collector, includeEmptyRules, cascadeScope++, --cascadeOrder);
- collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
+ m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
collector.sortAndTransferMatchedRules();
}
collector.clearMatchedRules();
collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().matchedProperties.size() - 1;
- bool applyAuthorStyles = applyAuthorStylesOf(element);
- if (m_styleTree.hasOnlyScopedResolverForDocument()) {
- m_styleTree.scopedStyleResolverForDocument()->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, ignoreCascadeScope);
- collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
+ if (document().styleEngine()->hasOnlyScopedResolverForDocument()) {
+ document().scopedStyleResolver()->collectMatchingAuthorRules(collector, includeEmptyRules, ignoreCascadeScope);
+ m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
collector.sortAndTransferMatchedRules();
return;
}
- Vector<ScopedStyleResolver*, 8> resolvers;
- m_styleTree.resolveScopedStyles(element, resolvers);
+ WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolvers;
+ resolveScopedStyles(element, resolvers);
- Vector<ScopedStyleResolver*, 8> resolversInShadowTree;
- m_styleTree.collectScopedResolversForHostedShadowTrees(element, resolversInShadowTree);
+ WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolversInShadowTree;
+ collectScopedResolversForHostedShadowTrees(element, resolversInShadowTree);
if (!resolversInShadowTree.isEmpty()) {
matchAuthorRulesForShadowHost(element, collector, includeEmptyRules, resolvers, resolversInShadowTree);
return;
for (unsigned i = 0; i < resolvers.size(); ++i, --cascadeOrder) {
ScopedStyleResolver* resolver = resolvers.at(i);
// FIXME: Need to clarify how to treat style scoped.
- resolver->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope++, resolver->treeScope() == element->treeScope() && resolver->scopingNode().isShadowRoot() ? 0 : cascadeOrder);
+ resolver->collectMatchingAuthorRules(collector, includeEmptyRules, cascadeScope++, resolver->treeScope() == element->treeScope() && resolver->treeScope().rootNode().isShadowRoot() ? 0 : cascadeOrder);
}
- collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
- collector.sortAndTransferMatchedRules();
-}
-
-void StyleResolver::matchWatchSelectorRules(ElementRuleCollector& collector)
-{
- if (!m_watchedSelectorsRules)
- return;
-
- collector.clearMatchedRules();
- collector.matchedResult().ranges.lastUserRule = collector.matchedResult().matchedProperties.size() - 1;
-
- MatchRequest matchRequest(m_watchedSelectorsRules.get());
- RuleRange ruleRange = collector.matchedResult().ranges.userRuleRange();
- collector.collectMatchingRules(matchRequest, ruleRange);
-
+ m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
collector.sortAndTransferMatchedRules();
}
collector.setMatchingUARules(true);
CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance();
- RuleSet* userAgentStyleSheet = m_medium->mediaTypeMatchSpecific("print")
- ? defaultStyleSheets.defaultPrintStyle() : defaultStyleSheets.defaultStyle();
+ RuleSet* userAgentStyleSheet = m_printMediaType ? defaultStyleSheets.defaultPrintStyle() : defaultStyleSheets.defaultStyle();
matchUARules(collector, userAgentStyleSheet);
// In quirks mode, we match rules from the quirks user agent sheet.
if (document().isViewSource())
matchUARules(collector, defaultStyleSheets.defaultViewSourceStyle());
- collector.setMatchingUARules(false);
+ if (document().isTransitionDocument())
+ matchUARules(collector, defaultStyleSheets.defaultTransitionStyle());
- matchWatchSelectorRules(collector);
+ collector.setMatchingUARules(false);
}
void StyleResolver::matchUARules(ElementRuleCollector& collector, RuleSet* rules)
}
}
-PassRefPtr<RenderStyle> StyleResolver::styleForDocument(Document& document, CSSFontSelector* fontSelector)
+PassRefPtr<RenderStyle> StyleResolver::styleForDocument(Document& document)
{
- const Frame* frame = document.frame();
+ const LocalFrame* frame = document.frame();
RefPtr<RenderStyle> documentStyle = RenderStyle::create();
documentStyle->setDisplay(BLOCK);
documentStyle->setRTLOrdering(document.visuallyOrdered() ? VisualOrder : LogicalOrder);
documentStyle->setZoom(frame && !document.printing() ? frame->pageZoomFactor() : 1);
documentStyle->setLocale(document.contentLanguage());
-
- // This overrides any -webkit-user-modify inherited from the parent iframe.
+ documentStyle->setZIndex(0);
documentStyle->setUserModify(document.inDesignMode() ? READ_WRITE : READ_ONLY);
document.setupFontBuilder(documentStyle.get());
- return documentStyle.release();
-}
-// FIXME: This is duplicated with StyleAdjuster.cpp
-// Perhaps this should move onto ElementResolveContext or even Element?
-static inline bool isAtShadowBoundary(const Element* element)
-{
- if (!element)
- return false;
- ContainerNode* parentNode = element->parentNode();
- return parentNode && parentNode->isShadowRoot();
+ return documentStyle.release();
}
static inline void resetDirectionAndWritingModeOnDocument(Document& document)
static void addContentAttrValuesToFeatures(const Vector<AtomicString>& contentAttrValues, RuleFeatureSet& features)
{
for (size_t i = 0; i < contentAttrValues.size(); ++i)
- features.addAttributeInASelector(contentAttrValues[i]);
+ features.addContentAttr(contentAttrValues[i]);
+}
+
+void StyleResolver::adjustRenderStyle(StyleResolverState& state, Element* element)
+{
+ StyleAdjuster adjuster(document().inQuirksMode());
+ adjuster.adjustRenderStyle(state.style(), state.parentStyle(), element, state.cachedUAStyle());
+}
+
+// Start loading resources referenced by this style.
+void StyleResolver::loadPendingResources(StyleResolverState& state)
+{
+ m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
+ document().styleEngine()->fontSelector()->fontLoader()->loadPendingFonts();
}
PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderStyle* defaultParent, StyleSharingBehavior sharingBehavior,
RuleMatchingBehavior matchingBehavior)
{
ASSERT(document().frame());
- ASSERT(documentSettings());
+ ASSERT(document().settings());
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.
- if (sharingBehavior == AllowStyleSharing && !element->document().haveStylesheetsLoaded() && !element->renderer()) {
+ if (sharingBehavior == AllowStyleSharing && !document().isRenderingReady() && !element->renderer()) {
if (!s_styleNotYetAvailable) {
s_styleNotYetAvailable = RenderStyle::create().leakRef();
s_styleNotYetAvailable->setDisplay(NONE);
s_styleNotYetAvailable->font().update(document().styleEngine()->fontSelector());
}
- element->document().setHasNodesWithPlaceholderStyle();
+
+ document().setHasNodesWithPlaceholderStyle();
return s_styleNotYetAvailable;
}
didAccess();
+ StyleResolverParentScope::ensureParentStackIsPushed();
+
if (element == document().documentElement())
resetDirectionAndWritingModeOnDocument(document());
StyleResolverState state(document(), element, defaultParent);
}
}
- state.fontBuilder().initForStyleResolve(state.document(), state.style(), state.useSVGZoomRules());
+ state.fontBuilder().initForStyleResolve(state.document(), state.style());
if (element->isLink()) {
state.style()->setIsLink(true);
{
ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
- if (matchingBehavior == MatchOnlyUserAgentRules)
- matchUARules(collector);
- else
- matchAllRules(state, collector, matchingBehavior != MatchAllRulesExcludingSMIL);
+ matchAllRules(state, collector, matchingBehavior != MatchAllRulesExcludingSMIL);
applyMatchedProperties(state, collector.matchedResult());
+ applyCallbackSelectors(state);
addContentAttrValuesToFeatures(state.contentAttrValues(), m_features);
}
- {
- StyleAdjuster adjuster(state.cachedUAStyle(), m_document.inQuirksMode());
- adjuster.adjustRenderStyle(state.style(), state.parentStyle(), element);
- }
+
+ // Cache our original display.
+ state.style()->setOriginalDisplay(state.style()->display());
+
+ adjustRenderStyle(state, element);
// FIXME: The CSSWG wants to specify that the effects of animations are applied before
// important rules, but this currently happens here as we require adjustment to have happened
// before deciding which properties to transition.
- applyAnimatedProperties(state, element);
+ if (applyAnimatedProperties(state, element))
+ adjustRenderStyle(state, element);
- // FIXME: Shouldn't this be on RenderBody::styleDidChange?
- if (element->hasTagName(bodyTag))
+ if (isHTMLBodyElement(*element))
document().textLinkColors().setTextColor(state.style()->color());
setAnimationUpdateIfNeeded(state, *element);
return state.takeStyle();
}
-PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element* element, const RenderStyle& elementStyle, RenderStyle* parentStyle, const StyleKeyframe* keyframe, const AtomicString& animationName)
+PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element& element, const RenderStyle& elementStyle, RenderStyle* parentStyle, const StyleKeyframe* keyframe, const AtomicString& animationName)
{
ASSERT(document().frame());
- ASSERT(documentSettings());
+ ASSERT(document().settings());
ASSERT(!hasPendingAuthorStyleSheets());
- if (element == document().documentElement())
+ if (&element == document().documentElement())
resetDirectionAndWritingModeOnDocument(document());
- StyleResolverState state(document(), element, parentStyle);
+ StyleResolverState state(document(), &element, parentStyle);
MatchResult result;
- if (keyframe->properties())
- result.addMatchedProperties(keyframe->properties());
+ result.addMatchedProperties(&keyframe->properties());
ASSERT(!state.style());
state.setStyle(RenderStyle::clone(&elementStyle));
state.setLineHeightValue(0);
- // Make sure that the CSSAnimationData for the animation to which this
- // keyframe belongs is first in the list. This makes sure that if the
- // animation-timing-function property is set for this keyframe, it will be
- // applied to the correct CSSAnimationData object. Note that objects other
- // than the first in the list are ignored when reading the timing function
- // value. See KeyframeValue::timingFunction().
- CSSAnimationDataList* animations = state.style()->accessAnimations();
- ASSERT(animations && !animations->isEmpty());
- while (animations->animation(0)->name() != animationName)
- animations->remove(0);
- ASSERT(!animations->isEmpty() && animations->animation(0)->name() == animationName);
-
- state.fontBuilder().initForStyleResolve(state.document(), state.style(), state.useSVGZoomRules());
+ state.fontBuilder().initForStyleResolve(state.document(), state.style());
// We don't need to bother with !important. Since there is only ever one
// decl, there's nothing to override. So just add the first properties.
+ // We also don't need to bother with animation properties since the only
+ // relevant one is animation-timing-function and we special-case that in
+ // CSSAnimations.cpp
bool inheritedOnly = false;
- if (keyframe->properties()) {
- applyMatchedProperties<AnimationProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
- applyMatchedProperties<HighPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
- }
+ applyMatchedProperties<HighPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
// If our font got dirtied, go ahead and update it now.
updateFont(state);
StyleBuilder::applyProperty(CSSPropertyLineHeight, state, state.lineHeightValue());
// Now do rest of the properties.
- if (keyframe->properties())
- applyMatchedProperties<LowPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
-
- // If our font got dirtied by one of the non-essential font props,
- // go ahead and update it a second time.
- updateFont(state);
+ applyMatchedProperties<LowPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
- // Start loading resources referenced by this style.
- m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
- document().styleEngine()->fontSelector()->loadPendingFonts();
+ loadPendingResources(state);
didAccess();
// This function is used by the WebAnimations JavaScript API method animate().
// FIXME: Remove this when animate() switches away from resolution-dependent parsing.
-PassRefPtr<KeyframeEffectModel> StyleResolver::createKeyframeEffectModel(Element& element, const Vector<RefPtr<MutableStylePropertySet> >& propertySetVector, KeyframeEffectModel::KeyframeVector& keyframes)
+PassRefPtrWillBeRawPtr<AnimatableValue> StyleResolver::createAnimatableValueSnapshot(Element& element, CSSPropertyID property, CSSValue& value)
{
- ASSERT(propertySetVector.size() == keyframes.size());
-
+ RefPtr<RenderStyle> style;
+ if (element.renderStyle())
+ style = RenderStyle::clone(element.renderStyle());
+ else
+ style = RenderStyle::create();
StyleResolverState state(element.document(), &element);
- state.setStyle(RenderStyle::create());
+ state.setStyle(style);
+ state.fontBuilder().initForStyleResolve(state.document(), state.style());
+ return createAnimatableValueSnapshot(state, property, value);
+}
- for (unsigned i = 0; i < propertySetVector.size(); ++i) {
- for (unsigned j = 0; j < propertySetVector[i]->propertyCount(); ++j) {
- CSSPropertyID id = propertySetVector[i]->propertyAt(j).id();
- StyleBuilder::applyProperty(id, state, propertySetVector[i]->getPropertyCSSValue(id).get());
- keyframes[i]->setPropertyValue(id, CSSAnimatableValueFactory::create(id, *state.style()).get());
- }
- }
- return KeyframeEffectModel::create(keyframes);
+PassRefPtrWillBeRawPtr<AnimatableValue> StyleResolver::createAnimatableValueSnapshot(StyleResolverState& state, CSSPropertyID property, CSSValue& value)
+{
+ StyleBuilder::applyProperty(property, state, &value);
+ return CSSAnimatableValueFactory::create(property, *state.style());
}
-PassRefPtr<PseudoElement> StyleResolver::createPseudoElementIfNeeded(Element& parent, PseudoId pseudoId)
+PassRefPtrWillBeRawPtr<PseudoElement> StyleResolver::createPseudoElementIfNeeded(Element& parent, PseudoId pseudoId)
{
RenderObject* parentRenderer = parent.renderer();
if (!parentRenderer)
- return 0;
+ return nullptr;
if (pseudoId < FIRST_INTERNAL_PSEUDOID && !parentRenderer->style()->hasPseudoStyle(pseudoId))
- return 0;
+ return nullptr;
if (pseudoId == BACKDROP && !parent.isInTopLayer())
- return 0;
+ return nullptr;
if (!parentRenderer->canHaveGeneratedChildren())
- return 0;
+ return nullptr;
RenderStyle* parentStyle = parentRenderer->style();
+ if (RenderStyle* cachedStyle = parentStyle->getCachedPseudoStyle(pseudoId)) {
+ if (!pseudoElementRendererIsNeeded(cachedStyle))
+ return nullptr;
+ return PseudoElement::create(&parent, pseudoId);
+ }
+
StyleResolverState state(document(), &parent, parentStyle);
if (!pseudoStyleForElementInternal(parent, pseudoId, parentStyle, state))
- return 0;
+ return nullptr;
RefPtr<RenderStyle> style = state.takeStyle();
ASSERT(style);
+ parentStyle->addCachedPseudoStyle(style);
if (!pseudoElementRendererIsNeeded(style.get()))
- return 0;
+ return nullptr;
- parentStyle->addCachedPseudoStyle(style.release());
- RefPtr<PseudoElement> pseudo = PseudoElement::create(&parent, pseudoId);
+ RefPtrWillBeRawPtr<PseudoElement> pseudo = PseudoElement::create(&parent, pseudoId);
setAnimationUpdateIfNeeded(state, *pseudo);
if (ActiveAnimations* activeAnimations = pseudo->activeAnimations())
bool StyleResolver::pseudoStyleForElementInternal(Element& element, const PseudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle, StyleResolverState& state)
{
ASSERT(document().frame());
- ASSERT(documentSettings());
+ ASSERT(document().settings());
ASSERT(pseudoStyleRequest.pseudoId != FIRST_LINE_INHERITED);
+ StyleResolverParentScope::ensureParentStackIsPushed();
+
if (pseudoStyleRequest.allowsInheritance(state.parentStyle())) {
state.setStyle(RenderStyle::create());
state.style()->inheritFrom(state.parentStyle());
state.setParentStyle(RenderStyle::clone(state.style()));
}
- state.fontBuilder().initForStyleResolve(state.document(), state.style(), state.useSVGZoomRules());
+ state.style()->setStyleType(pseudoStyleRequest.pseudoId);
+ state.fontBuilder().initForStyleResolve(state.document(), state.style());
// Since we don't use pseudo-elements in any of our quirk/print
// user agent rules, don't waste time walking those rules.
if (collector.matchedResult().matchedProperties.isEmpty())
return false;
- state.style()->setStyleType(pseudoStyleRequest.pseudoId);
-
applyMatchedProperties(state, collector.matchedResult());
+ applyCallbackSelectors(state);
addContentAttrValuesToFeatures(state.contentAttrValues(), m_features);
}
- {
- StyleAdjuster adjuster(state.cachedUAStyle(), m_document.inQuirksMode());
- // FIXME: Passing 0 as the Element* introduces a lot of complexity
- // in the adjustRenderStyle code.
- adjuster.adjustRenderStyle(state.style(), state.parentStyle(), 0);
- }
+
+ // Cache our original display.
+ state.style()->setOriginalDisplay(state.style()->display());
+
+ // FIXME: Passing 0 as the Element* introduces a lot of complexity
+ // in the adjustRenderStyle code.
+ adjustRenderStyle(state, 0);
// FIXME: The CSSWG wants to specify that the effects of animations are applied before
// important rules, but this currently happens here as we require adjustment to have happened
// before deciding which properties to transition.
- applyAnimatedProperties(state, element.pseudoElement(pseudoStyleRequest.pseudoId));
+ if (applyAnimatedProperties(state, element.pseudoElement(pseudoStyleRequest.pseudoId)))
+ adjustRenderStyle(state, 0);
didAccess();
{
ASSERT(parentStyle);
if (!element)
- return 0;
+ return nullptr;
StyleResolverState state(document(), element, parentStyle);
- if (!pseudoStyleForElementInternal(*element, pseudoStyleRequest, parentStyle, state))
- return 0;
+ if (!pseudoStyleForElementInternal(*element, pseudoStyleRequest, parentStyle, state)) {
+ if (pseudoStyleRequest.type == PseudoStyleRequest::ForRenderer)
+ return nullptr;
+ return state.takeStyle();
+ }
if (PseudoElement* pseudoElement = element->pseudoElement(pseudoStyleRequest.pseudoId))
setAnimationUpdateIfNeeded(state, *pseudoElement);
ASSERT(rootElementStyle);
state.style()->inheritFrom(rootElementStyle);
- state.fontBuilder().initForStyleResolve(state.document(), state.style(), state.useSVGZoomRules());
+ state.fontBuilder().initForStyleResolve(state.document(), state.style());
PageRuleCollector collector(rootElementStyle, pageIndex);
collector.matchPageRules(CSSDefaultStyleSheets::instance().defaultPrintStyle());
- if (ScopedStyleResolver* scopedResolver = m_styleTree.scopedStyleResolverForDocument())
+ if (ScopedStyleResolver* scopedResolver = document().scopedStyleResolver())
scopedResolver->matchPageRules(collector);
state.setLineHeightValue(0);
addContentAttrValuesToFeatures(state.contentAttrValues(), m_features);
- // Start loading resources referenced by this style.
- m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
- document().styleEngine()->fontSelector()->loadPendingFonts();
+ loadPendingResources(state);
didAccess();
if (document().isMobileDocument())
viewportStyleResolver()->collectViewportRules(defaultStyleSheets.defaultXHTMLMobileProfileStyle(), ViewportStyleResolver::UserAgentOrigin);
- if (ScopedStyleResolver* scopedResolver = m_styleTree.scopedStyleResolverForDocument())
+ if (ScopedStyleResolver* scopedResolver = document().scopedStyleResolver())
scopedResolver->collectViewportRulesTo(this);
viewportStyleResolver()->resolve();
{
StyleResolverState state(document(), 0);
state.setStyle(RenderStyle::create());
- state.fontBuilder().initForStyleResolve(document(), state.style(), state.useSVGZoomRules());
+ state.fontBuilder().initForStyleResolve(document(), state.style());
state.style()->setLineHeight(RenderStyle::initialLineHeight());
state.setLineHeightValue(0);
state.fontBuilder().setInitial(state.style()->effectiveZoom());
{
ASSERT(textNode);
- NodeRenderingTraversal::ParentDetails parentDetails;
- Node* parentNode = NodeRenderingTraversal::parent(textNode, &parentDetails);
- if (!parentNode || !parentNode->renderStyle() || parentDetails.resetStyleInheritance())
+ Node* parentNode = NodeRenderingTraversal::parent(textNode);
+ if (!parentNode || !parentNode->renderStyle())
return defaultStyleForElement();
return parentNode->renderStyle();
}
void StyleResolver::updateFont(StyleResolverState& state)
{
state.fontBuilder().createFont(document().styleEngine()->fontSelector(), state.parentStyle(), state.style());
- if (state.fontBuilder().fontSizeHasViewportUnits())
- state.style()->setHasViewportUnits();
}
-PassRefPtr<StyleRuleList> StyleResolver::styleRulesForElement(Element* element, unsigned rulesToInclude)
+PassRefPtrWillBeRawPtr<StyleRuleList> StyleResolver::styleRulesForElement(Element* element, unsigned rulesToInclude)
{
ASSERT(element);
StyleResolverState state(document(), element);
return collector.matchedStyleRuleList();
}
-PassRefPtr<CSSRuleList> StyleResolver::pseudoCSSRulesForElement(Element* element, PseudoId pseudoId, unsigned rulesToInclude)
+PassRefPtrWillBeRawPtr<CSSRuleList> StyleResolver::pseudoCSSRulesForElement(Element* element, PseudoId pseudoId, unsigned rulesToInclude)
{
ASSERT(element);
StyleResolverState state(document(), element);
return collector.matchedCSSRuleList();
}
-PassRefPtr<CSSRuleList> StyleResolver::cssRulesForElement(Element* element, unsigned rulesToInclude)
+PassRefPtrWillBeRawPtr<CSSRuleList> StyleResolver::cssRulesForElement(Element* element, unsigned rulesToInclude)
{
return pseudoCSSRulesForElement(element, NOPSEUDO, rulesToInclude);
}
// -------------------------------------------------------------------------------------
// this is mostly boring stuff on how to apply a certain rule to the renderstyle...
-void StyleResolver::applyAnimatedProperties(StyleResolverState& state, Element* animatingElement)
+bool StyleResolver::applyAnimatedProperties(StyleResolverState& state, const Element* animatingElement)
{
- const Element* element = state.element();
+ Element* element = state.element();
ASSERT(element);
// The animating element may be this element, or its pseudo element. It is
ASSERT(animatingElement == element || !animatingElement || animatingElement->parentOrShadowHostElement() == element);
if (!(animatingElement && animatingElement->hasActiveAnimations())
- && !(state.style()->transitions() && !state.style()->transitions()->isEmpty())
- && !(state.style()->animations() && !state.style()->animations()->isEmpty()))
- return;
+ && !state.style()->transitions() && !state.style()->animations())
+ return false;
state.setAnimationUpdate(CSSAnimations::calculateUpdate(animatingElement, *element, *state.style(), state.parentStyle(), this));
if (!state.animationUpdate())
+ return false;
+
+ const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolationsForAnimations = state.animationUpdate()->activeInterpolationsForAnimations();
+ const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolationsForTransitions = state.animationUpdate()->activeInterpolationsForTransitions();
+ applyAnimatedProperties<HighPriorityProperties>(state, activeInterpolationsForAnimations);
+ applyAnimatedProperties<HighPriorityProperties>(state, activeInterpolationsForTransitions);
+
+ updateFont(state);
+
+ applyAnimatedProperties<LowPriorityProperties>(state, activeInterpolationsForAnimations);
+ applyAnimatedProperties<LowPriorityProperties>(state, activeInterpolationsForTransitions);
+
+ // Start loading resources used by animations.
+ loadPendingResources(state);
+
+ ASSERT(!state.fontBuilder().fontDirty());
+
+ return true;
+}
+
+static inline ScopedStyleResolver* scopedResolverFor(const Element* element)
+{
+ for (TreeScope* treeScope = &element->treeScope(); treeScope; treeScope = treeScope->parentTreeScope()) {
+ if (ScopedStyleResolver* scopedStyleResolver = treeScope->scopedStyleResolver())
+ return scopedStyleResolver;
+ }
+ return 0;
+}
+
+void StyleResolver::resolveScopedStyles(const Element* element, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers)
+{
+ for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scopedResolver; scopedResolver = scopedResolver->parent())
+ resolvers.append(scopedResolver);
+}
+
+void StyleResolver::collectScopedResolversForHostedShadowTrees(const Element* element, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers)
+{
+ ElementShadow* shadow = element->shadow();
+ if (!shadow)
return;
- const AnimationEffect::CompositableValueMap& compositableValuesForAnimations = state.animationUpdate()->compositableValuesForAnimations();
- const AnimationEffect::CompositableValueMap& compositableValuesForTransitions = state.animationUpdate()->compositableValuesForTransitions();
- applyAnimatedProperties<HighPriorityProperties>(state, compositableValuesForAnimations);
- applyAnimatedProperties<HighPriorityProperties>(state, compositableValuesForTransitions);
- applyAnimatedProperties<LowPriorityProperties>(state, compositableValuesForAnimations);
- applyAnimatedProperties<LowPriorityProperties>(state, compositableValuesForTransitions);
+ // 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 = shadowRoot->scopedStyleResolver())
+ resolvers.append(resolver);
+ }
+ }
+}
- // If the animations/transitions change opacity or transform, we need to update
- // the style to impose the stacking rules. Note that this is also
- // done in StyleResolver::adjustRenderStyle().
- RenderStyle* style = state.style();
- if (style->hasAutoZIndex() && (style->opacity() < 1.0f || style->hasTransform()))
- style->setZIndex(0);
+void StyleResolver::styleTreeResolveScopedKeyframesRules(const Element* element, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers)
+{
+ TreeScope& treeScope = element->treeScope();
+
+ // Add resolvers for shadow roots hosted by the given element.
+ collectScopedResolversForHostedShadowTrees(element, resolvers);
+
+ // Add resolvers while walking up DOM tree from the given element.
+ for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scopedResolver; scopedResolver = scopedResolver->parent()) {
+ if (scopedResolver->treeScope() == treeScope)
+ resolvers.append(scopedResolver);
+ }
}
template <StyleResolver::StyleApplicationPass pass>
-void StyleResolver::applyAnimatedProperties(StyleResolverState& state, const AnimationEffect::CompositableValueMap& compositableValues)
+void StyleResolver::applyAnimatedProperties(StyleResolverState& state, const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolations)
{
- ASSERT(pass != AnimationProperties);
-
- for (AnimationEffect::CompositableValueMap::const_iterator iter = compositableValues.begin(); iter != compositableValues.end(); ++iter) {
+ for (WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >::const_iterator iter = activeInterpolations.begin(); iter != activeInterpolations.end(); ++iter) {
CSSPropertyID property = iter->key;
if (!isPropertyForPass<pass>(property))
continue;
- ASSERT_WITH_MESSAGE(!iter->value->dependsOnUnderlyingValue(), "Web Animations not yet implemented: An interface for compositing onto the underlying value.");
- RefPtr<AnimatableValue> animatableValue = iter->value->compositeOnto(0);
- AnimatedStyleBuilder::applyProperty(property, state, animatableValue.get());
+ const StyleInterpolation* interpolation = toStyleInterpolation(iter->value.get());
+ interpolation->apply(state);
}
}
case CSSPropertyFont:
case CSSPropertyFontFamily:
case CSSPropertyFontSize:
+ case CSSPropertyFontStretch:
case CSSPropertyFontStyle:
case CSSPropertyFontVariant:
case CSSPropertyFontWeight:
return false;
}
+static inline bool isValidFirstLetterStyleProperty(CSSPropertyID id)
+{
+ switch (id) {
+ // Valid ::first-letter properties listed in spec:
+ // http://www.w3.org/TR/css3-selectors/#application-in-css
+ case CSSPropertyBackgroundAttachment:
+ case CSSPropertyBackgroundBlendMode:
+ case CSSPropertyBackgroundClip:
+ case CSSPropertyBackgroundColor:
+ case CSSPropertyBackgroundImage:
+ case CSSPropertyBackgroundOrigin:
+ case CSSPropertyBackgroundPosition:
+ case CSSPropertyBackgroundPositionX:
+ case CSSPropertyBackgroundPositionY:
+ case CSSPropertyBackgroundRepeat:
+ case CSSPropertyBackgroundRepeatX:
+ case CSSPropertyBackgroundRepeatY:
+ case CSSPropertyBackgroundSize:
+ case CSSPropertyBorderBottomColor:
+ case CSSPropertyBorderBottomLeftRadius:
+ case CSSPropertyBorderBottomRightRadius:
+ case CSSPropertyBorderBottomStyle:
+ case CSSPropertyBorderBottomWidth:
+ case CSSPropertyBorderImageOutset:
+ case CSSPropertyBorderImageRepeat:
+ case CSSPropertyBorderImageSlice:
+ case CSSPropertyBorderImageSource:
+ case CSSPropertyBorderImageWidth:
+ case CSSPropertyBorderLeftColor:
+ case CSSPropertyBorderLeftStyle:
+ case CSSPropertyBorderLeftWidth:
+ case CSSPropertyBorderRightColor:
+ case CSSPropertyBorderRightStyle:
+ case CSSPropertyBorderRightWidth:
+ case CSSPropertyBorderTopColor:
+ case CSSPropertyBorderTopLeftRadius:
+ case CSSPropertyBorderTopRightRadius:
+ case CSSPropertyBorderTopStyle:
+ case CSSPropertyBorderTopWidth:
+ case CSSPropertyColor:
+ case CSSPropertyFloat:
+ case CSSPropertyFont:
+ case CSSPropertyFontFamily:
+ case CSSPropertyFontKerning:
+ case CSSPropertyFontSize:
+ case CSSPropertyFontStretch:
+ case CSSPropertyFontStyle:
+ case CSSPropertyFontVariant:
+ case CSSPropertyFontVariantLigatures:
+ case CSSPropertyFontWeight:
+ case CSSPropertyLetterSpacing:
+ case CSSPropertyLineHeight:
+ case CSSPropertyMarginBottom:
+ case CSSPropertyMarginLeft:
+ case CSSPropertyMarginRight:
+ case CSSPropertyMarginTop:
+ case CSSPropertyPaddingBottom:
+ case CSSPropertyPaddingLeft:
+ case CSSPropertyPaddingRight:
+ case CSSPropertyPaddingTop:
+ case CSSPropertyTextTransform:
+ case CSSPropertyVerticalAlign:
+ case CSSPropertyWebkitBackgroundClip:
+ case CSSPropertyWebkitBackgroundComposite:
+ case CSSPropertyWebkitBackgroundOrigin:
+ case CSSPropertyWebkitBackgroundSize:
+ case CSSPropertyWebkitBorderAfter:
+ case CSSPropertyWebkitBorderAfterColor:
+ case CSSPropertyWebkitBorderAfterStyle:
+ case CSSPropertyWebkitBorderAfterWidth:
+ case CSSPropertyWebkitBorderBefore:
+ case CSSPropertyWebkitBorderBeforeColor:
+ case CSSPropertyWebkitBorderBeforeStyle:
+ case CSSPropertyWebkitBorderBeforeWidth:
+ case CSSPropertyWebkitBorderEnd:
+ case CSSPropertyWebkitBorderEndColor:
+ case CSSPropertyWebkitBorderEndStyle:
+ case CSSPropertyWebkitBorderEndWidth:
+ case CSSPropertyWebkitBorderFit:
+ case CSSPropertyWebkitBorderHorizontalSpacing:
+ case CSSPropertyWebkitBorderImage:
+ case CSSPropertyWebkitBorderRadius:
+ case CSSPropertyWebkitBorderStart:
+ case CSSPropertyWebkitBorderStartColor:
+ case CSSPropertyWebkitBorderStartStyle:
+ case CSSPropertyWebkitBorderStartWidth:
+ case CSSPropertyWebkitBorderVerticalSpacing:
+ case CSSPropertyWebkitFontSmoothing:
+ case CSSPropertyWebkitMarginAfter:
+ case CSSPropertyWebkitMarginAfterCollapse:
+ case CSSPropertyWebkitMarginBefore:
+ case CSSPropertyWebkitMarginBeforeCollapse:
+ case CSSPropertyWebkitMarginBottomCollapse:
+ case CSSPropertyWebkitMarginCollapse:
+ case CSSPropertyWebkitMarginEnd:
+ case CSSPropertyWebkitMarginStart:
+ case CSSPropertyWebkitMarginTopCollapse:
+ case CSSPropertyWordSpacing:
+ return true;
+ case CSSPropertyTextDecorationColor:
+ case CSSPropertyTextDecorationLine:
+ case CSSPropertyTextDecorationStyle:
+ return RuntimeEnabledFeatures::css3TextDecorationsEnabled();
+
+ // text-shadow added in text decoration spec:
+ // http://www.w3.org/TR/css-text-decor-3/#text-shadow-property
+ case CSSPropertyTextShadow:
+ // box-shadox added in CSS3 backgrounds spec:
+ // http://www.w3.org/TR/css3-background/#placement
+ case CSSPropertyBoxShadow:
+ case CSSPropertyWebkitBoxShadow:
+ // Properties that we currently support outside of spec.
+ case CSSPropertyWebkitLineBoxContain:
+ case CSSPropertyVisibility:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+// FIXME: Consider refactoring to create a new class which owns the following
+// first/last/range properties.
+// This method returns the first CSSPropertyId of high priority properties.
+// Other properties can depend on high priority properties. For example,
+// border-color property with currentColor value depends on color property.
+// All high priority properties are obtained by using
+// firstCSSPropertyId<HighPriorityProperties> and
+// lastCSSPropertyId<HighPriorityProperties>.
+template<> CSSPropertyID StyleResolver::firstCSSPropertyId<StyleResolver::HighPriorityProperties>()
+{
+ COMPILE_ASSERT(CSSPropertyColor == firstCSSProperty, CSS_color_is_first_high_priority_property);
+ return CSSPropertyColor;
+}
+
+// This method returns the last CSSPropertyId of high priority properties.
+template<> CSSPropertyID StyleResolver::lastCSSPropertyId<StyleResolver::HighPriorityProperties>()
+{
+ COMPILE_ASSERT(CSSPropertyLineHeight == CSSPropertyColor + 18, CSS_line_height_is_end_of_high_prioity_property_range);
+ COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyLineHeight - 1, CSS_zoom_is_before_line_height);
+ return CSSPropertyLineHeight;
+}
+
+// This method returns the first CSSPropertyId of remaining properties,
+// i.e. low priority properties. No properties depend on low priority
+// properties. So we don't need to resolve such properties quickly.
+// All low priority properties are obtained by using
+// firstCSSPropertyId<LowPriorityProperties> and
+// lastCSSPropertyId<LowPriorityProperties>.
+template<> CSSPropertyID StyleResolver::firstCSSPropertyId<StyleResolver::LowPriorityProperties>()
+{
+ COMPILE_ASSERT(CSSPropertyAlignContent == CSSPropertyLineHeight + 1, CSS_background_is_first_low_priority_property);
+ return CSSPropertyAlignContent;
+}
+
+// This method returns the last CSSPropertyId of low priority properties.
+template<> CSSPropertyID StyleResolver::lastCSSPropertyId<StyleResolver::LowPriorityProperties>()
+{
+ return static_cast<CSSPropertyID>(lastCSSProperty);
+}
+
template <StyleResolver::StyleApplicationPass pass>
bool StyleResolver::isPropertyForPass(CSSPropertyID property)
{
- const CSSPropertyID firstAnimationProperty = CSSPropertyDisplay;
- const CSSPropertyID lastAnimationProperty = CSSPropertyTransitionTimingFunction;
- COMPILE_ASSERT(firstCSSProperty == firstAnimationProperty, CSS_first_animation_property_should_be_first_property);
- const CSSPropertyID firstHighPriorityProperty = CSSPropertyColor;
- const CSSPropertyID lastHighPriorityProperty = CSSPropertyLineHeight;
- COMPILE_ASSERT(lastAnimationProperty + 1 == firstHighPriorityProperty, CSS_color_is_first_high_priority_property);
- COMPILE_ASSERT(CSSPropertyLineHeight == firstHighPriorityProperty + 17, CSS_line_height_is_end_of_high_prioity_property_range);
- COMPILE_ASSERT(CSSPropertyZoom == lastHighPriorityProperty - 1, CSS_zoom_is_before_line_height);
- switch (pass) {
- case AnimationProperties:
- return property >= firstAnimationProperty && property <= lastAnimationProperty;
- case HighPriorityProperties:
- return property >= firstHighPriorityProperty && property <= lastHighPriorityProperty;
- case LowPriorityProperties:
- return property > lastHighPriorityProperty;
- }
- ASSERT_NOT_REACHED();
- return false;
+ return firstCSSPropertyId<pass>() <= property && property <= lastCSSPropertyId<pass>();
}
+// This method expands the 'all' shorthand property to longhand properties
+// and applies the expanded longhand properties.
template <StyleResolver::StyleApplicationPass pass>
-void StyleResolver::applyProperties(StyleResolverState& state, const StylePropertySet* properties, StyleRule* rule, bool isImportant, bool inheritedOnly, PropertyWhitelistType propertyWhitelistType)
+void StyleResolver::applyAllProperty(StyleResolverState& state, CSSValue* allValue)
{
- state.setCurrentRule(rule);
+ bool isUnsetValue = !allValue->isInitialValue() && !allValue->isInheritedValue();
+ unsigned startCSSProperty = firstCSSPropertyId<pass>();
+ unsigned endCSSProperty = lastCSSPropertyId<pass>();
+ for (unsigned i = startCSSProperty; i <= endCSSProperty; ++i) {
+ CSSPropertyID propertyId = static_cast<CSSPropertyID>(i);
+
+ // StyleBuilder does not allow any expanded shorthands.
+ if (isExpandedShorthandForAll(propertyId))
+ continue;
+
+ // all shorthand spec says:
+ // The all property is a shorthand that resets all CSS properties
+ // except direction and unicode-bidi.
+ // c.f. http://dev.w3.org/csswg/css-cascade/#all-shorthand
+ // We skip applyProperty when a given property is unicode-bidi or
+ // direction.
+ if (!CSSProperty::isAffectedByAllProperty(propertyId))
+ continue;
+
+ CSSValue* value;
+ if (!isUnsetValue) {
+ value = allValue;
+ } else {
+ if (CSSPropertyMetadata::isInheritedProperty(propertyId))
+ value = cssValuePool().createInheritedValue().get();
+ else
+ value = cssValuePool().createExplicitInitialValue().get();
+ }
+ StyleBuilder::applyProperty(propertyId, state, value);
+ }
+}
+
+template <StyleResolver::StyleApplicationPass pass>
+void StyleResolver::applyProperties(StyleResolverState& state, const StylePropertySet* properties, bool isImportant, bool inheritedOnly, PropertyWhitelistType propertyWhitelistType)
+{
unsigned propertyCount = properties->propertyCount();
for (unsigned i = 0; i < propertyCount; ++i) {
StylePropertySet::PropertyReference current = properties->propertyAt(i);
if (isImportant != current.isImportant())
continue;
+
+ CSSPropertyID property = current.id();
+ if (property == CSSPropertyAll) {
+ applyAllProperty<pass>(state, current.value());
+ continue;
+ }
+
if (inheritedOnly && !current.isInherited()) {
// If the property value is explicitly inherited, we need to apply further non-inherited properties
// as they might override the value inherited here. For this reason we don't allow declarations with
ASSERT(!current.value()->isInheritedValue());
continue;
}
- CSSPropertyID property = current.id();
if (propertyWhitelistType == PropertyWhitelistCue && !isValidCueStyleProperty(property))
continue;
+ if (propertyWhitelistType == PropertyWhitelistFirstLetter && !isValidFirstLetterStyleProperty(property))
+ continue;
if (!isPropertyForPass<pass>(property))
continue;
if (pass == HighPriorityProperties && property == CSSPropertyLineHeight)
if (state.style()->insideLink() != NotInsideLink) {
for (int i = startIndex; i <= endIndex; ++i) {
const MatchedProperties& matchedProperties = matchResult.matchedProperties[i];
- unsigned linkMatchType = matchedProperties.linkMatchType;
+ unsigned linkMatchType = matchedProperties.m_types.linkMatchType;
// FIXME: It would be nicer to pass these as arguments but that requires changes in many places.
state.setApplyPropertyToRegularStyle(linkMatchType & SelectorChecker::MatchLink);
state.setApplyPropertyToVisitedLinkStyle(linkMatchType & SelectorChecker::MatchVisited);
- applyProperties<pass>(state, matchedProperties.properties.get(), matchResult.matchedRules[i], isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.whitelistType));
+ applyProperties<pass>(state, matchedProperties.properties.get(), isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.m_types.whitelistType));
}
state.setApplyPropertyToRegularStyle(true);
state.setApplyPropertyToVisitedLinkStyle(false);
}
for (int i = startIndex; i <= endIndex; ++i) {
const MatchedProperties& matchedProperties = matchResult.matchedProperties[i];
- applyProperties<pass>(state, matchedProperties.properties.get(), matchResult.matchedRules[i], isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.whitelistType));
+ applyProperties<pass>(state, matchedProperties.properties.get(), isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.m_types.whitelistType));
}
}
unsigned cacheHash = matchResult.isCacheable ? computeMatchedPropertiesHash(matchResult.matchedProperties.data(), matchResult.matchedProperties.size()) : 0;
bool applyInheritedOnly = false;
- const CachedMatchedProperties* cachedMatchedProperties = 0;
+ const CachedMatchedProperties* cachedMatchedProperties = cacheHash ? m_matchedPropertiesCache.find(cacheHash, state, matchResult) : 0;
- if (cacheHash && (cachedMatchedProperties = m_matchedPropertiesCache.find(cacheHash, state, matchResult))
- && MatchedPropertiesCache::isCacheable(element, state.style(), state.parentStyle())) {
+ if (cachedMatchedProperties && MatchedPropertiesCache::isCacheable(element, state.style(), state.parentStyle())) {
INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheHit);
// We can build up the style by copying non-inherited properties from an earlier style object built using the same exact
// style declarations. We then only need to apply the inherited properties, if any, as their values can depend on the
applyInheritedOnly = true;
}
- // Apply animation properties in order to apply animation results and trigger transitions below.
- applyMatchedProperties<AnimationProperties>(state, matchResult, false, 0, matchResult.matchedProperties.size() - 1, applyInheritedOnly);
- applyMatchedProperties<AnimationProperties>(state, matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
- applyMatchedProperties<AnimationProperties>(state, matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
- applyMatchedProperties<AnimationProperties>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
-
- // Match transition-property / animation-name length by trimming and
- // lengthening other transition / animation property lists
- // FIXME: This is wrong because we shouldn't affect the computed values
- state.style()->adjustAnimations();
- state.style()->adjustTransitions();
-
// Now we have all of the matched rules in the appropriate order. Walk the rules and apply
// high-priority properties first, i.e., those properties that other properties depend on.
// The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
state.setLineHeightValue(0);
applyMatchedProperties<HighPriorityProperties>(state, matchResult, false, 0, matchResult.matchedProperties.size() - 1, applyInheritedOnly);
applyMatchedProperties<HighPriorityProperties>(state, matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
- applyMatchedProperties<HighPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
applyMatchedProperties<HighPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
+ if (UNLIKELY(isSVGForeignObjectElement(element))) {
+ // RenderSVGRoot handles zooming for the whole SVG subtree, so foreignObject content should not be scaled again.
+ //
+ // FIXME: The following hijacks the zoom property for foreignObject so that children of foreignObject get the
+ // correct font-size in case of zooming. 'zoom' is part of HighPriorityProperties, along with other font-related
+ // properties used as input to the FontBuilder, so resetting it here may cause the FontBuilder to recompute the
+ // font used as inheritable font for foreignObject content. If we want to support zoom on foreignObject we'll
+ // need to find another way of handling the SVG zoom model.
+ state.setEffectiveZoom(RenderStyle::initialZoom());
+ }
+
if (cachedMatchedProperties && cachedMatchedProperties->renderStyle->effectiveZoom() != state.style()->effectiveZoom()) {
state.fontBuilder().setFontDirty(true);
applyInheritedOnly = false;
// Now do the author and user normal priority properties and all the !important properties.
applyMatchedProperties<LowPriorityProperties>(state, matchResult, false, matchResult.ranges.lastUARule + 1, matchResult.matchedProperties.size() - 1, applyInheritedOnly);
applyMatchedProperties<LowPriorityProperties>(state, matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
- applyMatchedProperties<LowPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
applyMatchedProperties<LowPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
- // Start loading resources referenced by this style.
- m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
- document().styleEngine()->fontSelector()->loadPendingFonts();
+ loadPendingResources(state);
if (!cachedMatchedProperties && cacheHash && MatchedPropertiesCache::isCacheable(element, state.style(), state.parentStyle())) {
INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheAdded);
ASSERT(!state.fontBuilder().fontDirty());
}
+void StyleResolver::applyCallbackSelectors(StyleResolverState& state)
+{
+ if (!m_watchedSelectorsRules)
+ return;
+
+ ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
+ collector.setMode(SelectorChecker::CollectingStyleRules);
+
+ MatchRequest matchRequest(m_watchedSelectorsRules.get(), true);
+ RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange();
+ collector.collectMatchingRules(matchRequest, ruleRange);
+ collector.sortAndTransferMatchedRules();
+
+ RefPtrWillBeRawPtr<StyleRuleList> rules = collector.matchedStyleRuleList();
+ if (!rules)
+ return;
+ for (size_t i = 0; i < rules->m_list.size(); i++)
+ state.style()->addCallbackSelector(rules->m_list[i]->selectorList().selectorsText());
+}
+
CSSPropertyValue::CSSPropertyValue(CSSPropertyID id, const StylePropertySet& propertySet)
: property(id), value(propertySet.getPropertyCSSValue(id).get())
{ }
{
if (!m_styleResolverStats)
return;
- fprintf(stderr, "=== Style Resolver Stats (resolve #%u) (%s) ===\n", ++m_styleResolverStatsSequence, m_document.url().string().utf8().data());
+ fprintf(stderr, "=== Style Resolver Stats (resolve #%u) (%s) ===\n", ++m_styleResolverStatsSequence, document().url().string().utf8().data());
fprintf(stderr, "%s\n", m_styleResolverStats->report().utf8().data());
fprintf(stderr, "== Totals ==\n");
fprintf(stderr, "%s\n", m_styleResolverStatsTotals->report().utf8().data());
StyleResolverState state(document(), document().documentElement(), style);
state.setStyle(style);
- state.fontBuilder().initForStyleResolve(document(), style, state.useSVGZoomRules());
+ state.fontBuilder().initForStyleResolve(document(), style);
for (size_t i = 0; i < count; ++i) {
if (properties[i].value) {
bool StyleResolver::mediaQueryAffectedByViewportChange() const
{
for (unsigned i = 0; i < m_viewportDependentMediaQueryResults.size(); ++i) {
- if (m_medium->eval(&m_viewportDependentMediaQueryResults[i]->m_expression) != m_viewportDependentMediaQueryResults[i]->m_result)
+ if (m_medium->eval(m_viewportDependentMediaQueryResults[i]->expression()) != m_viewportDependentMediaQueryResults[i]->result())
return true;
}
return false;
}
-} // namespace WebCore
+void StyleResolver::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_keyframesRuleMap);
+ visitor->trace(m_matchedPropertiesCache);
+ visitor->trace(m_viewportDependentMediaQueryResults);
+ 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_treeBoundaryCrossingRules);
+ visitor->trace(m_styleSharingLists);
+ visitor->trace(m_pendingStyleSheets);
+ visitor->trace(m_document);
+#endif
+}
+
+} // namespace blink