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 |