void RuleSet::addChildRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase>>& rules, const MediaQueryEvaluator& medium, AddRuleFlags addRuleFlags) { for (unsigned i = 0; i < rules.size(); ++i) { StyleRuleBase* rule = rules[i].get(); if (rule->isStyleRule()) { StyleRule* styleRule = toStyleRule(rule); const CSSSelectorList& selectorList = styleRule->selectorList(); for (size_t selectorIndex = 0; selectorIndex != kNotFound; selectorIndex = selectorList.indexOfNextSelectorAfter(selectorIndex)) { if (selectorList.selectorCrossesTreeScopes(selectorIndex)) { m_treeBoundaryCrossingRules.append(MinimalRuleData(styleRule, selectorIndex, addRuleFlags)); } else if (selectorList.hasShadowDistributedAt(selectorIndex)) { m_shadowDistributedRules.append(MinimalRuleData(styleRule, selectorIndex, addRuleFlags)); } else { addRule(styleRule, selectorIndex, addRuleFlags); } } } else if (rule->isPageRule()) { addPageRule(toStyleRulePage(rule)); } else if (rule->isMediaRule()) { StyleRuleMedia* mediaRule = toStyleRuleMedia(rule); if ((!mediaRule->mediaQueries() || medium.eval(mediaRule->mediaQueries(), &m_viewportDependentMediaQueryResults))) addChildRules(mediaRule->childRules(), medium, addRuleFlags); } else if (rule->isFontFaceRule()) { addFontFaceRule(toStyleRuleFontFace(rule)); } else if (rule->isKeyframesRule()) { addKeyframesRule(toStyleRuleKeyframes(rule)); } else if (rule->isViewportRule()) { addViewportRule(toStyleRuleViewport(rule)); } else if (rule->isSupportsRule() && toStyleRuleSupports(rule)->conditionIsSupported()) { addChildRules(toStyleRuleSupports(rule)->childRules(), medium, addRuleFlags); } } }
void StyleInvalidationAnalysis::analyzeStyleSheet(StyleSheetContents* styleSheetContents) { ASSERT(!styleSheetContents->isLoading()); // See if all rules on the sheet are scoped to some specific ids or classes. // Then test if we actually have any of those in the tree at the moment. const Vector<RefPtr<StyleRuleImport> >& importRules = styleSheetContents->importRules(); for (unsigned i = 0; i < importRules.size(); ++i) { if (!importRules[i]->styleSheet()) continue; analyzeStyleSheet(importRules[i]->styleSheet()); if (m_dirtiesAllStyle) return; } const Vector<RefPtr<StyleRuleBase> >& rules = styleSheetContents->childRules(); for (unsigned i = 0; i < rules.size(); i++) { StyleRuleBase* rule = rules[i].get(); if (!rule->isStyleRule()) { // FIXME: Media rules and maybe some others could be allowed. m_dirtiesAllStyle = true; return; } StyleRule* styleRule = static_cast<StyleRule*>(rule); if (!determineSelectorScopes(styleRule->selectorList(), m_idScopes, m_classScopes)) { m_dirtiesAllStyle = true; return; } } }
void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase> >& rules, const MediaQueryEvaluator& medium, StyleResolver* resolver, const ContainerNode* scope, bool hasDocumentSecurityOrigin, AddRuleFlags addRuleFlags) { for (unsigned i = 0; i < rules.size(); ++i) { StyleRuleBase* rule = rules[i].get(); if (rule->isStyleRule()) { StyleRule* styleRule = static_cast<StyleRule*>(rule); const CSSSelectorList& selectorList = styleRule->selectorList(); for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = selectorList.indexOfNextSelectorAfter(selectorIndex)) { if (selectorList.hasShadowDistributedAt(selectorIndex)) { if (isDocumentScope(scope)) continue; resolver->ruleSets().shadowDistributedRules().addRule(styleRule, selectorIndex, const_cast<ContainerNode*>(scope), addRuleFlags); } else addRule(styleRule, selectorIndex, addRuleFlags); } } else if (rule->isPageRule()) addPageRule(static_cast<StyleRulePage*>(rule)); else if (rule->isMediaRule()) { StyleRuleMedia* mediaRule = static_cast<StyleRuleMedia*>(rule); if ((!mediaRule->mediaQueries() || medium.eval(mediaRule->mediaQueries(), resolver))) addChildRules(mediaRule->childRules(), medium, resolver, scope, hasDocumentSecurityOrigin, addRuleFlags); } else if (rule->isFontFaceRule() && resolver) { // Add this font face to our set. // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment. if (!isDocumentScope(scope)) continue; const StyleRuleFontFace* fontFaceRule = static_cast<StyleRuleFontFace*>(rule); resolver->fontSelector()->addFontFaceRule(fontFaceRule); resolver->invalidateMatchedPropertiesCache(); } else if (rule->isKeyframesRule() && resolver) { // FIXME (BUG 72462): We don't add @keyframe rules of scoped style sheets for the moment. if (!isDocumentScope(scope)) continue; resolver->addKeyframeStyle(static_cast<StyleRuleKeyframes*>(rule)); } else if (rule->isRegionRule() && resolver) { // FIXME (BUG 72472): We don't add @-webkit-region rules of scoped style sheets for the moment. addRegionRule(static_cast<StyleRuleRegion*>(rule), hasDocumentSecurityOrigin); } else if (rule->isHostRule()) resolver->ensureScopedStyleResolver(scope->shadowHost())->addHostRule(static_cast<StyleRuleHost*>(rule), hasDocumentSecurityOrigin, scope); #if ENABLE(CSS_DEVICE_ADAPTATION) else if (rule->isViewportRule() && resolver) { // @viewport should not be scoped. if (!isDocumentScope(scope)) continue; resolver->viewportStyleResolver()->addViewportRule(static_cast<StyleRuleViewport*>(rule)); } #endif else if (rule->isSupportsRule() && static_cast<StyleRuleSupports*>(rule)->conditionIsSupported()) addChildRules(static_cast<StyleRuleSupports*>(rule)->childRules(), medium, resolver, scope, hasDocumentSecurityOrigin, addRuleFlags); } }
void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase>>& rules, const MediaQueryEvaluator& medium, StyleResolver* resolver, const ContainerNode* scope, bool hasDocumentSecurityOrigin, AddRuleFlags addRuleFlags) { for (unsigned i = 0; i < rules.size(); ++i) { StyleRuleBase* rule = rules[i].get(); if (rule->isStyleRule()) { StyleRule* styleRule = static_cast<StyleRule*>(rule); addStyleRule(styleRule, addRuleFlags); } else if (rule->isPageRule()) addPageRule(static_cast<StyleRulePage*>(rule)); else if (rule->isMediaRule()) { StyleRuleMedia* mediaRule = static_cast<StyleRuleMedia*>(rule); if ((!mediaRule->mediaQueries() || medium.eval(mediaRule->mediaQueries(), resolver))) addChildRules(mediaRule->childRules(), medium, resolver, scope, hasDocumentSecurityOrigin, addRuleFlags); } else if (rule->isFontFaceRule() && resolver) { // Add this font face to our set. // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment. if (scope) continue; const StyleRuleFontFace* fontFaceRule = static_cast<StyleRuleFontFace*>(rule); resolver->fontSelector()->addFontFaceRule(fontFaceRule); resolver->invalidateMatchedPropertiesCache(); } else if (rule->isKeyframesRule() && resolver) { // FIXME (BUG 72462): We don't add @keyframe rules of scoped style sheets for the moment. if (scope) continue; resolver->addKeyframeStyle(static_cast<StyleRuleKeyframes*>(rule)); } #if ENABLE(CSS_REGIONS) else if (rule->isRegionRule() && resolver) { // FIXME (BUG 72472): We don't add @-webkit-region rules of scoped style sheets for the moment. if (scope) continue; addRegionRule(static_cast<StyleRuleRegion*>(rule), hasDocumentSecurityOrigin); } #endif #if ENABLE(SHADOW_DOM) else if (rule->isHostRule()) resolver->addHostRule(static_cast<StyleRuleHost*>(rule), hasDocumentSecurityOrigin, scope); #endif #if ENABLE(CSS_DEVICE_ADAPTATION) else if (rule->isViewportRule() && resolver) { // @viewport should not be scoped. if (scope) continue; resolver->viewportStyleResolver()->addViewportRule(static_cast<StyleRuleViewport*>(rule)); } #endif #if ENABLE(CSS3_CONDITIONAL_RULES) else if (rule->isSupportsRule() && static_cast<StyleRuleSupports*>(rule)->conditionIsSupported()) addChildRules(static_cast<StyleRuleSupports*>(rule)->childRules(), medium, resolver, scope, hasDocumentSecurityOrigin, addRuleFlags); #endif } }
void ScopedStyleResolver::addHostRule(StyleRuleHost* hostRule, bool hasDocumentSecurityOrigin, const ContainerNode* scopingNode) { if (!scopingNode) return; ShadowRoot* shadowRoot = scopingNode->containingShadowRoot(); if (!shadowRoot || !shadowRoot->host()) return; RuleSet* rule = ensureAtHostRuleSetFor(shadowRoot); const Vector<RefPtr<StyleRuleBase> >& childRules = hostRule->childRules(); AddRuleFlags addRuleFlags = static_cast<AddRuleFlags>(hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState); for (unsigned i = 0; i < childRules.size(); ++i) { StyleRuleBase* hostStylingRule = childRules[i].get(); if (hostStylingRule->isStyleRule()) rule->addStyleRule(static_cast<StyleRule*>(hostStylingRule), addRuleFlags); } }
void RuleSet::addRegionRule(StyleRuleRegion* regionRule, bool hasDocumentSecurityOrigin) { OwnPtr<RuleSet> regionRuleSet = RuleSet::create(); // The region rule set should take into account the position inside the parent rule set. // Otherwise, the rules inside region block might be incorrectly positioned before other similar rules from // the stylesheet that contains the region block. regionRuleSet->m_ruleCount = m_ruleCount; // Collect the region rules into a rule set const Vector<RefPtr<StyleRuleBase> >& childRules = regionRule->childRules(); AddRuleFlags addRuleFlags = hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState; addRuleFlags = static_cast<AddRuleFlags>(addRuleFlags | RuleCanUseFastCheckSelector | RuleIsInRegionRule); for (unsigned i = 0; i < childRules.size(); ++i) { StyleRuleBase* regionStylingRule = childRules[i].get(); if (regionStylingRule->isStyleRule()) regionRuleSet->addStyleRule(static_cast<StyleRule*>(regionStylingRule), addRuleFlags); } // Update the "global" rule count so that proper order is maintained m_ruleCount = regionRuleSet->m_ruleCount; m_regionSelectorsAndRuleSets.append(RuleSetSelectorPair(regionRule->selectorList().first(), regionRuleSet.release())); }
void StyleSheetInvalidationAnalysis::analyzeStyleSheet(StyleSheetContents* styleSheetContents) { // Updating the style on the shadow DOM for image fallback content can bring us here when imports // are still getting loaded in the main document. Just need to exit early as we will return here // when the imports finish loading. if (styleSheetContents->isLoading()) return; // See if all rules on the sheet are scoped to some specific ids or classes. // Then test if we actually have any of those in the tree at the moment. const WillBeHeapVector<RefPtrWillBeMember<StyleRuleImport>>& importRules = styleSheetContents->importRules(); for (unsigned i = 0; i < importRules.size(); ++i) { if (!importRules[i]->styleSheet()) continue; analyzeStyleSheet(importRules[i]->styleSheet()); if (m_dirtiesAllStyle) return; } if (m_treeScope->rootNode().isShadowRoot()) return; const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase>>& rules = styleSheetContents->childRules(); for (unsigned i = 0; i < rules.size(); i++) { StyleRuleBase* rule = rules[i].get(); if (!rule->isStyleRule()) { if (ruleAdditionMightRequireDocumentStyleRecalc(rule)) { m_dirtiesAllStyle = true; return; } continue; } StyleRule* styleRule = toStyleRule(rule); if (!determineSelectorScopes(styleRule->selectorList(), m_idScopes, m_classScopes)) { m_dirtiesAllStyle = true; return; } } }
void StyleInvalidationAnalysis::analyzeStyleSheet(StyleSheetContents* styleSheetContents) { ASSERT(!styleSheetContents->isLoading()); // See if all rules on the sheet are scoped to some specific ids or classes. // Then test if we actually have any of those in the tree at the moment. const Vector<RefPtr<StyleRuleImport> >& importRules = styleSheetContents->importRules(); for (unsigned i = 0; i < importRules.size(); ++i) { if (!importRules[i]->styleSheet()) continue; analyzeStyleSheet(importRules[i]->styleSheet()); if (m_dirtiesAllStyle) return; } if (styleSheetContents->hasSingleOwnerNode()) { Node* ownerNode = styleSheetContents->singleOwnerNode(); if (ownerNode && ownerNode->hasTagName(HTMLNames::styleTag) && toHTMLStyleElement(ownerNode)->isRegisteredAsScoped()) { m_scopingNodes.append(determineScopingNodeForStyleScoped(toHTMLStyleElement(ownerNode), styleSheetContents)); return; } } const Vector<RefPtr<StyleRuleBase> >& rules = styleSheetContents->childRules(); for (unsigned i = 0; i < rules.size(); i++) { StyleRuleBase* rule = rules[i].get(); if (!rule->isStyleRule()) { if (ruleAdditionMightRequireDocumentStyleRecalc(rule)) { m_dirtiesAllStyle = true; return; } continue; } StyleRule* styleRule = toStyleRule(rule); if (!determineSelectorScopes(styleRule->selectorList(), m_idScopes, m_classScopes)) { m_dirtiesAllStyle = true; return; } } }
void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase>>& rules, const MediaQueryEvaluator& medium, StyleResolver* resolver, bool hasDocumentSecurityOrigin, AddRuleFlags addRuleFlags) { for (unsigned i = 0; i < rules.size(); ++i) { StyleRuleBase* rule = rules[i].get(); if (rule->isStyleRule()) { StyleRule* styleRule = static_cast<StyleRule*>(rule); addStyleRule(styleRule, addRuleFlags); } else if (rule->isPageRule()) addPageRule(static_cast<StyleRulePage*>(rule)); else if (rule->isMediaRule()) { StyleRuleMedia* mediaRule = static_cast<StyleRuleMedia*>(rule); if ((!mediaRule->mediaQueries() || medium.eval(mediaRule->mediaQueries(), resolver))) addChildRules(mediaRule->childRules(), medium, resolver, hasDocumentSecurityOrigin, addRuleFlags); } else if (rule->isFontFaceRule() && resolver) { // Add this font face to our set. const StyleRuleFontFace* fontFaceRule = static_cast<StyleRuleFontFace*>(rule); resolver->fontSelector()->addFontFaceRule(fontFaceRule); resolver->invalidateMatchedPropertiesCache(); } else if (rule->isKeyframesRule() && resolver) { resolver->addKeyframeStyle(static_cast<StyleRuleKeyframes*>(rule)); } #if ENABLE(CSS_REGIONS) else if (rule->isRegionRule() && resolver) { addRegionRule(static_cast<StyleRuleRegion*>(rule), hasDocumentSecurityOrigin); } #endif #if ENABLE(CSS_DEVICE_ADAPTATION) else if (rule->isViewportRule() && resolver) { resolver->viewportStyleResolver()->addViewportRule(static_cast<StyleRuleViewport*>(rule)); } #endif #if ENABLE(CSS3_CONDITIONAL_RULES) else if (rule->isSupportsRule() && static_cast<StyleRuleSupports*>(rule)->conditionIsSupported()) addChildRules(static_cast<StyleRuleSupports*>(rule)->childRules(), medium, resolver, hasDocumentSecurityOrigin, addRuleFlags); #endif } }
void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase> >& rules, const MediaQueryEvaluator& medium, AddRuleFlags addRuleFlags) { for (unsigned i = 0; i < rules.size(); ++i) { StyleRuleBase* rule = rules[i].get(); if (rule->isStyleRule()) { StyleRule* styleRule = toStyleRule(rule); const CSSSelectorList& selectorList = styleRule->selectorList(); for (size_t selectorIndex = 0; selectorIndex != kNotFound; selectorIndex = selectorList.indexOfNextSelectorAfter(selectorIndex)) addRule(styleRule, selectorIndex, addRuleFlags); } else if (rule->isMediaRule()) { StyleRuleMedia* mediaRule = toStyleRuleMedia(rule); if ((!mediaRule->mediaQueries() || medium.eval(mediaRule->mediaQueries(), &m_viewportDependentMediaQueryResults))) addChildRules(mediaRule->childRules(), medium, addRuleFlags); } else if (rule->isFontFaceRule()) { addFontFaceRule(toStyleRuleFontFace(rule)); } else if (rule->isKeyframesRule()) { addKeyframesRule(toStyleRuleKeyframes(rule)); } else if (rule->isSupportsRule() && toStyleRuleSupports(rule)->conditionIsSupported()) { addChildRules(toStyleRuleSupports(rule)->childRules(), medium, addRuleFlags); } } }
void CSSStyleSheet::addSubresourceStyleURLs(ListHashSet<KURL>& urls) { Deque<CSSStyleSheet*> styleSheetQueue; styleSheetQueue.append(this); while (!styleSheetQueue.isEmpty()) { CSSStyleSheet* styleSheet = styleSheetQueue.takeFirst(); for (unsigned i = 0; i < styleSheet->m_importRules.size(); ++i) { StyleRuleImport* importRule = styleSheet->m_importRules[i].get(); if (importRule->styleSheet()) { styleSheetQueue.append(importRule->styleSheet()); addSubresourceURL(urls, importRule->styleSheet()->baseURL()); } } for (unsigned i = 0; i < styleSheet->m_childRules.size(); ++i) { StyleRuleBase* rule = styleSheet->m_childRules[i].get(); if (rule->isStyleRule()) static_cast<StyleRule*>(rule)->properties()->addSubresourceStyleURLs(urls, this); else if (rule->isFontFaceRule()) static_cast<StyleRuleFontFace*>(rule)->properties()->addSubresourceStyleURLs(urls, this); } } }
void RuleSet::addRulesFromSheet(StyleSheetContents* sheet, const MediaQueryEvaluator& medium, StyleResolver* resolver, const ContainerNode* scope) { ASSERT(sheet); const Vector<RefPtr<StyleRuleImport> >& importRules = sheet->importRules(); for (unsigned i = 0; i < importRules.size(); ++i) { StyleRuleImport* importRule = importRules[i].get(); if (importRule->styleSheet() && (!importRule->mediaQueries() || medium.eval(importRule->mediaQueries(), resolver))) addRulesFromSheet(importRule->styleSheet(), medium, resolver, scope); } bool hasDocumentSecurityOrigin = resolver && resolver->document()->securityOrigin()->canRequest(sheet->baseURL()); AddRuleFlags addRuleFlags = static_cast<AddRuleFlags>((hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : 0) | (!scope ? RuleCanUseFastCheckSelector : 0)); const Vector<RefPtr<StyleRuleBase> >& rules = sheet->childRules(); for (unsigned i = 0; i < rules.size(); ++i) { StyleRuleBase* rule = rules[i].get(); ASSERT(!rule->isImportRule()); if (rule->isStyleRule()) addStyleRule(static_cast<StyleRule*>(rule), addRuleFlags); else if (rule->isPageRule()) addPageRule(static_cast<StyleRulePage*>(rule)); else if (rule->isMediaRule()) { StyleRuleMedia* mediaRule = static_cast<StyleRuleMedia*>(rule); if ((!mediaRule->mediaQueries() || medium.eval(mediaRule->mediaQueries(), resolver))) { // Traverse child elements of the @media rule. const Vector<RefPtr<StyleRuleBase> >& childRules = mediaRule->childRules(); for (unsigned j = 0; j < childRules.size(); ++j) { StyleRuleBase* childRule = childRules[j].get(); if (childRule->isStyleRule()) addStyleRule(static_cast<StyleRule*>(childRule), addRuleFlags); else if (childRule->isPageRule()) addPageRule(static_cast<StyleRulePage*>(childRule)); else if (childRule->isFontFaceRule() && resolver) { // Add this font face to our set. // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment. if (scope) continue; const StyleRuleFontFace* fontFaceRule = static_cast<StyleRuleFontFace*>(childRule); resolver->fontSelector()->addFontFaceRule(fontFaceRule); resolver->invalidateMatchedPropertiesCache(); } else if (childRule->isKeyframesRule() && resolver) { // Add this keyframe rule to our set. // FIXME(BUG 72462): We don't add @keyframe rules of scoped style sheets for the moment. if (scope) continue; resolver->addKeyframeStyle(static_cast<StyleRuleKeyframes*>(childRule)); } #if ENABLE(CSS_DEVICE_ADAPTATION) else if (childRule->isViewportRule() && resolver && !resolver->affectedByViewportChange()) { // @viewport should not be scoped. if (scope) continue; resolver->viewportStyleResolver()->addViewportRule(static_cast<StyleRuleViewport*>(childRule)); } #endif } // for rules } // if rules } else if (rule->isFontFaceRule() && resolver) { // Add this font face to our set. // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment. if (scope) continue; const StyleRuleFontFace* fontFaceRule = static_cast<StyleRuleFontFace*>(rule); resolver->fontSelector()->addFontFaceRule(fontFaceRule); resolver->invalidateMatchedPropertiesCache(); } else if (rule->isKeyframesRule() && resolver) { // FIXME (BUG 72462): We don't add @keyframe rules of scoped style sheets for the moment. if (scope) continue; resolver->addKeyframeStyle(static_cast<StyleRuleKeyframes*>(rule)); } #if ENABLE(CSS_REGIONS) else if (rule->isRegionRule() && resolver) { // FIXME (BUG 72472): We don't add @-webkit-region rules of scoped style sheets for the moment. if (scope) continue; addRegionRule(static_cast<StyleRuleRegion*>(rule), hasDocumentSecurityOrigin); } #endif #if ENABLE(SHADOW_DOM) else if (rule->isHostRule()) resolver->addHostRule(static_cast<StyleRuleHost*>(rule), hasDocumentSecurityOrigin, scope); #endif #if ENABLE(CSS_DEVICE_ADAPTATION) else if (rule->isViewportRule() && resolver) { // @viewport should not be scoped. if (scope) continue; resolver->viewportStyleResolver()->addViewportRule(static_cast<StyleRuleViewport*>(rule)); } #endif } if (m_autoShrinkToFitEnabled) shrinkToFit(); }