| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 return false; | 68 return false; |
| 69 ASSERT(scopeSelector->match() == CSSSelector::Class || scopeSelector->ma
tch() == CSSSelector::Id); | 69 ASSERT(scopeSelector->match() == CSSSelector::Class || scopeSelector->ma
tch() == CSSSelector::Id); |
| 70 if (scopeSelector->match() == CSSSelector::Id) | 70 if (scopeSelector->match() == CSSSelector::Id) |
| 71 idScopes.add(scopeSelector->value().impl()); | 71 idScopes.add(scopeSelector->value().impl()); |
| 72 else | 72 else |
| 73 classScopes.add(scopeSelector->value().impl()); | 73 classScopes.add(scopeSelector->value().impl()); |
| 74 } | 74 } |
| 75 return true; | 75 return true; |
| 76 } | 76 } |
| 77 | 77 |
| 78 static bool hasDistributedRule(StyleSheetContents* styleSheetContents) | |
| 79 { | |
| 80 const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase>>& rules = styleShee
tContents->childRules(); | |
| 81 for (unsigned i = 0; i < rules.size(); i++) { | |
| 82 const StyleRuleBase* rule = rules[i].get(); | |
| 83 if (!rule->isStyleRule()) | |
| 84 continue; | |
| 85 | |
| 86 const StyleRule* styleRule = toStyleRule(rule); | |
| 87 const CSSSelectorList& selectorList = styleRule->selectorList(); | |
| 88 for (size_t selectorIndex = 0; selectorIndex != kNotFound; selectorIndex
= selectorList.indexOfNextSelectorAfter(selectorIndex)) { | |
| 89 if (selectorList.hasShadowDistributedAt(selectorIndex)) | |
| 90 return true; | |
| 91 } | |
| 92 } | |
| 93 return false; | |
| 94 } | |
| 95 | |
| 96 static bool ruleAdditionMightRequireDocumentStyleRecalc(StyleRuleBase* rule) | 78 static bool ruleAdditionMightRequireDocumentStyleRecalc(StyleRuleBase* rule) |
| 97 { | 79 { |
| 98 // This funciton is conservative. We only return false when we know that | 80 // This funciton is conservative. We only return false when we know that |
| 99 // the added @rule can't require style recalcs. | 81 // the added @rule can't require style recalcs. |
| 100 switch (rule->type()) { | 82 switch (rule->type()) { |
| 101 case StyleRule::Import: // Whatever we import should do its own analysis, we
don't need to invalidate the document here! | 83 case StyleRule::Import: // Whatever we import should do its own analysis, we
don't need to invalidate the document here! |
| 102 case StyleRule::Page: // Page rules apply only during printing, we force a f
ull-recalc before printing. | 84 case StyleRule::Page: // Page rules apply only during printing, we force a f
ull-recalc before printing. |
| 103 return false; | 85 return false; |
| 104 | 86 |
| 105 case StyleRule::Media: // If the media rule doesn't apply, we could avoid re
calc. | 87 case StyleRule::Media: // If the media rule doesn't apply, we could avoid re
calc. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 132 // Then test if we actually have any of those in the tree at the moment. | 114 // Then test if we actually have any of those in the tree at the moment. |
| 133 const WillBeHeapVector<RefPtrWillBeMember<StyleRuleImport>>& importRules = s
tyleSheetContents->importRules(); | 115 const WillBeHeapVector<RefPtrWillBeMember<StyleRuleImport>>& importRules = s
tyleSheetContents->importRules(); |
| 134 for (unsigned i = 0; i < importRules.size(); ++i) { | 116 for (unsigned i = 0; i < importRules.size(); ++i) { |
| 135 if (!importRules[i]->styleSheet()) | 117 if (!importRules[i]->styleSheet()) |
| 136 continue; | 118 continue; |
| 137 analyzeStyleSheet(importRules[i]->styleSheet()); | 119 analyzeStyleSheet(importRules[i]->styleSheet()); |
| 138 if (m_dirtiesAllStyle) | 120 if (m_dirtiesAllStyle) |
| 139 return; | 121 return; |
| 140 } | 122 } |
| 141 | 123 |
| 142 if (m_treeScope->rootNode().isShadowRoot()) { | 124 if (m_treeScope->rootNode().isShadowRoot()) |
| 143 if (hasDistributedRule(styleSheetContents)) | |
| 144 m_hasDistributedRules = true; | |
| 145 return; | 125 return; |
| 146 } | |
| 147 | 126 |
| 148 const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase>>& rules = styleShee
tContents->childRules(); | 127 const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase>>& rules = styleShee
tContents->childRules(); |
| 149 for (unsigned i = 0; i < rules.size(); i++) { | 128 for (unsigned i = 0; i < rules.size(); i++) { |
| 150 StyleRuleBase* rule = rules[i].get(); | 129 StyleRuleBase* rule = rules[i].get(); |
| 151 if (!rule->isStyleRule()) { | 130 if (!rule->isStyleRule()) { |
| 152 if (ruleAdditionMightRequireDocumentStyleRecalc(rule)) { | 131 if (ruleAdditionMightRequireDocumentStyleRecalc(rule)) { |
| 153 m_dirtiesAllStyle = true; | 132 m_dirtiesAllStyle = true; |
| 154 return; | 133 return; |
| 155 } | 134 } |
| 156 continue; | 135 continue; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 170 if (classScopes.isEmpty() || !element->hasClass()) | 149 if (classScopes.isEmpty() || !element->hasClass()) |
| 171 return false; | 150 return false; |
| 172 const SpaceSplitString& classNames = element->classNames(); | 151 const SpaceSplitString& classNames = element->classNames(); |
| 173 for (unsigned i = 0; i < classNames.size(); ++i) { | 152 for (unsigned i = 0; i < classNames.size(); ++i) { |
| 174 if (classScopes.contains(classNames[i].impl())) | 153 if (classScopes.contains(classNames[i].impl())) |
| 175 return true; | 154 return true; |
| 176 } | 155 } |
| 177 return false; | 156 return false; |
| 178 } | 157 } |
| 179 | 158 |
| 180 static ContainerNode* outermostShadowHost(ContainerNode& host) | |
| 181 { | |
| 182 ContainerNode* outerHost = &host; | |
| 183 while (outerHost->isInShadowTree()) | |
| 184 outerHost = outerHost->containingShadowRoot()->host(); | |
| 185 return outerHost; | |
| 186 } | |
| 187 | |
| 188 void StyleSheetInvalidationAnalysis::invalidateStyle() | 159 void StyleSheetInvalidationAnalysis::invalidateStyle() |
| 189 { | 160 { |
| 190 ASSERT(!m_dirtiesAllStyle); | 161 ASSERT(!m_dirtiesAllStyle); |
| 191 | 162 |
| 192 if (m_treeScope->rootNode().isShadowRoot()) { | 163 if (m_treeScope->rootNode().isShadowRoot()) { |
| 193 ContainerNode* invalidationRoot = toShadowRoot(m_treeScope->rootNode()).
host(); | 164 ContainerNode* shadowHost = toShadowRoot(m_treeScope->rootNode()).host()
; |
| 194 if (m_hasDistributedRules) | 165 shadowHost->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonFor
Tracing::create(StyleChangeReason::StyleSheetChange)); |
| 195 invalidationRoot = outermostShadowHost(*invalidationRoot); | |
| 196 invalidationRoot->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeRea
sonForTracing::create(StyleChangeReason::StyleSheetChange)); | |
| 197 return; | 166 return; |
| 198 } | 167 } |
| 199 | 168 |
| 200 if (m_idScopes.isEmpty() && m_classScopes.isEmpty()) | 169 if (m_idScopes.isEmpty() && m_classScopes.isEmpty()) |
| 201 return; | 170 return; |
| 202 Element* element = ElementTraversal::firstWithin(m_treeScope->document()); | 171 Element* element = ElementTraversal::firstWithin(m_treeScope->document()); |
| 203 while (element) { | 172 while (element) { |
| 204 if (elementMatchesSelectorScopes(element, m_idScopes, m_classScopes)) { | 173 if (elementMatchesSelectorScopes(element, m_idScopes, m_classScopes)) { |
| 205 element->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonFo
rTracing::create(StyleChangeReason::StyleSheetChange)); | 174 element->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonFo
rTracing::create(StyleChangeReason::StyleSheetChange)); |
| 206 // The whole subtree is now invalidated, we can skip to the next sib
ling. | 175 // The whole subtree is now invalidated, we can skip to the next sib
ling. |
| 207 element = ElementTraversal::nextSkippingChildren(*element); | 176 element = ElementTraversal::nextSkippingChildren(*element); |
| 208 continue; | 177 continue; |
| 209 } | 178 } |
| 210 element = ElementTraversal::next(*element); | 179 element = ElementTraversal::next(*element); |
| 211 } | 180 } |
| 212 } | 181 } |
| 213 | 182 |
| 214 } | 183 } |
| OLD | NEW |