OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) | 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) |
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) | 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) |
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All r ights reserved. | 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All r ights reserved. |
6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> | 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) |
9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. |
10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 case CSSSelector::PseudoUnresolved: | 93 case CSSSelector::PseudoUnresolved: |
94 return true; | 94 return true; |
95 default: | 95 default: |
96 return false; | 96 return false; |
97 } | 97 } |
98 ASSERT_NOT_REACHED(); | 98 ASSERT_NOT_REACHED(); |
99 return false; | 99 return false; |
100 } | 100 } |
101 | 101 |
102 // This method is somewhat conservative in what it accepts. | 102 // This method is somewhat conservative in what it accepts. |
103 static bool supportsClassDescendantInvalidation(const CSSSelector& selector) | 103 RuleFeatureSet::InvalidationMode RuleFeatureSet::supportsClassDescendantInvalida tion(const CSSSelector& selector) |
104 { | 104 { |
105 bool foundDescendantRelation = false; | 105 bool foundDescendantRelation = false; |
106 bool foundIdent = false; | 106 bool foundIdent = false; |
107 for (const CSSSelector* component = &selector; component; component = compon ent->tagHistory()) { | 107 for (const CSSSelector* component = &selector; component; component = compon ent->tagHistory()) { |
108 | 108 |
109 // FIXME: We should allow pseudo elements, but we need to change how the y hook | 109 // FIXME: We should allow pseudo elements, but we need to change how the y hook |
110 // into recalcStyle by moving them to recalcOwnStyle instead of recalcCh ildStyle. | 110 // into recalcStyle by moving them to recalcOwnStyle instead of recalcCh ildStyle. |
111 | 111 |
112 // FIXME: next up: Tag and Id. | 112 // FIXME: next up: Tag and Id. |
113 if (component->m_match == CSSSelector::Class) { | 113 if (component->m_match == CSSSelector::Class) { |
114 if (!foundDescendantRelation) | 114 if (!foundDescendantRelation) |
115 foundIdent = true; | 115 foundIdent = true; |
116 } else if (!isSkippableComponentForInvalidation(*component)) { | 116 } else if (!isSkippableComponentForInvalidation(*component)) { |
117 return false; | 117 return foundDescendantRelation ? UseLocalStyleChange : UseSubtreeSty leChange; |
118 } | 118 } |
119 // FIXME: We can probably support ShadowAll and ShadowDeep. | 119 // FIXME: We can probably support ShadowAll and ShadowDeep. |
120 switch (component->relation()) { | 120 switch (component->relation()) { |
121 case CSSSelector::Descendant: | 121 case CSSSelector::Descendant: |
122 case CSSSelector::Child: | 122 case CSSSelector::Child: |
123 foundDescendantRelation = true; | 123 foundDescendantRelation = true; |
124 // Fall through! | 124 // Fall through! |
125 case CSSSelector::SubSelector: | 125 case CSSSelector::SubSelector: |
126 continue; | 126 continue; |
127 default: | 127 default: |
128 return false; | 128 return UseLocalStyleChange; |
129 } | 129 } |
130 } | 130 } |
131 return foundIdent; | 131 return foundIdent ? UseInvalidationSets : UseLocalStyleChange; |
132 } | 132 } |
133 | 133 |
134 void extractClassIdOrTag(const CSSSelector& selector, Vector<AtomicString>& clas ses, AtomicString& id, AtomicString& tagName) | 134 void extractClassIdOrTag(const CSSSelector& selector, Vector<AtomicString>& clas ses, AtomicString& id, AtomicString& tagName) |
135 { | 135 { |
136 if (selector.m_match == CSSSelector::Tag) | 136 if (selector.m_match == CSSSelector::Tag) |
137 tagName = selector.tagQName().localName(); | 137 tagName = selector.tagQName().localName(); |
138 else if (selector.m_match == CSSSelector::Id) | 138 else if (selector.m_match == CSSSelector::Id) |
139 id = selector.value(); | 139 id = selector.value(); |
140 else if (selector.m_match == CSSSelector::Class) | 140 else if (selector.m_match == CSSSelector::Class) |
141 classes.append(selector.value()); | 141 classes.append(selector.value()); |
142 } | 142 } |
143 | 143 |
144 RuleFeatureSet::RuleFeatureSet() | 144 RuleFeatureSet::RuleFeatureSet() |
145 : m_targetedStyleRecalcEnabled(RuntimeEnabledFeatures::targetedStyleRecalcEn abled()) | 145 : m_targetedStyleRecalcEnabled(RuntimeEnabledFeatures::targetedStyleRecalcEn abled()) |
146 { | 146 { |
147 } | 147 } |
148 | 148 |
149 bool RuleFeatureSet::updateClassInvalidationSets(const CSSSelector& selector) | 149 RuleFeatureSet::InvalidationMode RuleFeatureSet::updateClassInvalidationSets(con st CSSSelector& selector) |
150 { | 150 { |
151 if (!supportsClassDescendantInvalidation(selector)) | 151 InvalidationMode mode = supportsClassDescendantInvalidation(selector); |
152 return false; | 152 if (mode != UseInvalidationSets) |
153 return mode; | |
153 | 154 |
154 Vector<AtomicString> classes; | 155 Vector<AtomicString> classes; |
155 AtomicString id; | 156 AtomicString id; |
156 AtomicString tagName; | 157 AtomicString tagName; |
157 | 158 |
158 const CSSSelector* lastSelector = &selector; | 159 const CSSSelector* lastSelector = &selector; |
159 for (; lastSelector; lastSelector = lastSelector->tagHistory()) { | 160 for (; lastSelector; lastSelector = lastSelector->tagHistory()) { |
160 extractClassIdOrTag(*lastSelector, classes, id, tagName); | 161 extractClassIdOrTag(*lastSelector, classes, id, tagName); |
161 if (lastSelector->m_match == CSSSelector::Class) | 162 if (lastSelector->m_match == CSSSelector::Class) |
162 ensureClassInvalidationSet(lastSelector->value()); | 163 ensureClassInvalidationSet(lastSelector->value()); |
163 if (lastSelector->relation() != CSSSelector::SubSelector) | 164 if (lastSelector->relation() != CSSSelector::SubSelector) |
164 break; | 165 break; |
165 } | 166 } |
166 | 167 |
167 if (!lastSelector) | 168 if (!lastSelector) |
168 return true; | 169 return UseInvalidationSets; |
169 | 170 |
170 for (const CSSSelector* current = lastSelector->tagHistory(); current; curre nt = current->tagHistory()) { | 171 for (const CSSSelector* current = lastSelector->tagHistory(); current; curre nt = current->tagHistory()) { |
171 if (current->m_match == CSSSelector::Class) { | 172 if (current->m_match == CSSSelector::Class) { |
172 DescendantInvalidationSet& invalidationSet = ensureClassInvalidation Set(current->value()); | 173 DescendantInvalidationSet& invalidationSet = ensureClassInvalidation Set(current->value()); |
173 if (!id.isEmpty()) | 174 if (!id.isEmpty()) |
174 invalidationSet.addId(id); | 175 invalidationSet.addId(id); |
175 if (!tagName.isEmpty()) | 176 if (!tagName.isEmpty()) |
176 invalidationSet.addTagName(tagName); | 177 invalidationSet.addTagName(tagName); |
177 for (Vector<AtomicString>::const_iterator it = classes.begin(); it ! = classes.end(); ++it) { | 178 for (Vector<AtomicString>::const_iterator it = classes.begin(); it ! = classes.end(); ++it) { |
178 invalidationSet.addClass(*it); | 179 invalidationSet.addClass(*it); |
179 } | 180 } |
180 } | 181 } |
181 } | 182 } |
182 return true; | 183 return UseInvalidationSets; |
183 } | 184 } |
184 | 185 |
185 void RuleFeatureSet::addAttributeInASelector(const AtomicString& attributeName) | 186 void RuleFeatureSet::addAttributeInASelector(const AtomicString& attributeName) |
186 { | 187 { |
187 m_metadata.attrsInRules.add(attributeName); | 188 m_metadata.attrsInRules.add(attributeName); |
188 } | 189 } |
189 | 190 |
190 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData) | 191 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData) |
191 { | 192 { |
192 FeatureMetadata metadata; | 193 FeatureMetadata metadata; |
193 bool selectorUsesClassInvalidationSet = false; | 194 InvalidationMode mode = UseSubtreeStyleChange; |
194 if (m_targetedStyleRecalcEnabled) | 195 if (m_targetedStyleRecalcEnabled) |
195 selectorUsesClassInvalidationSet = updateClassInvalidationSets(ruleData. selector()); | 196 mode = updateClassInvalidationSets(ruleData.selector()); |
196 | 197 |
197 SelectorFeatureCollectionMode collectionMode; | 198 collectFeaturesFromSelector(ruleData.selector(), metadata, mode); |
198 if (selectorUsesClassInvalidationSet) | |
199 collectionMode = DontProcessClasses; | |
200 else | |
201 collectionMode = ProcessClasses; | |
202 collectFeaturesFromSelector(ruleData.selector(), metadata, collectionMode); | |
203 m_metadata.add(metadata); | 199 m_metadata.add(metadata); |
204 | 200 |
205 if (metadata.foundSiblingSelector) | 201 if (metadata.foundSiblingSelector) |
206 siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex( ), ruleData.hasDocumentSecurityOrigin())); | 202 siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex( ), ruleData.hasDocumentSecurityOrigin())); |
207 if (ruleData.containsUncommonAttributeSelector()) | 203 if (ruleData.containsUncommonAttributeSelector()) |
208 uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.sele ctorIndex(), ruleData.hasDocumentSecurityOrigin())); | 204 uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.sele ctorIndex(), ruleData.hasDocumentSecurityOrigin())); |
209 } | 205 } |
210 | 206 |
211 DescendantInvalidationSet& RuleFeatureSet::ensureClassInvalidationSet(const Atom icString& className) | 207 DescendantInvalidationSet& RuleFeatureSet::ensureClassInvalidationSet(const Atom icString& className) |
212 { | 208 { |
213 InvalidationSetMap::AddResult addResult = m_classInvalidationSets.add(classN ame, nullptr); | 209 InvalidationSetMap::AddResult addResult = m_classInvalidationSets.add(classN ame, nullptr); |
214 if (addResult.isNewEntry) | 210 if (addResult.isNewEntry) |
215 addResult.storedValue->value = DescendantInvalidationSet::create(); | 211 addResult.storedValue->value = DescendantInvalidationSet::create(); |
216 return *addResult.storedValue->value; | 212 return *addResult.storedValue->value; |
217 } | 213 } |
218 | 214 |
219 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector) | 215 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector) |
220 { | 216 { |
221 collectFeaturesFromSelector(selector, m_metadata, ProcessClasses); | 217 collectFeaturesFromSelector(selector, m_metadata, UseSubtreeStyleChange); |
222 } | 218 } |
223 | 219 |
224 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru leFeatureSet::FeatureMetadata& metadata, SelectorFeatureCollectionMode collectio nMode) | 220 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru leFeatureSet::FeatureMetadata& metadata, InvalidationMode mode) |
225 { | 221 { |
226 unsigned maxDirectAdjacentSelectors = 0; | 222 unsigned maxDirectAdjacentSelectors = 0; |
227 | 223 |
228 for (const CSSSelector* current = &selector; current; current = current->tag History()) { | 224 for (const CSSSelector* current = &selector; current; current = current->tag History()) { |
229 if (current->m_match == CSSSelector::Id) { | 225 if (current->m_match == CSSSelector::Id) { |
230 metadata.idsInRules.add(current->value()); | 226 metadata.idsInRules.add(current->value()); |
231 } else if (current->m_match == CSSSelector::Class && collectionMode == P rocessClasses) { | 227 } else if (current->m_match == CSSSelector::Class && mode != UseInvalida tionSets) { |
esprehn
2014/03/13 23:28:13
This is confusing since you're saying "mode is not
rune
2014/03/14 13:01:19
Renamed now.
| |
232 DescendantInvalidationSet& invalidationSet = ensureClassInvalidation Set(current->value()); | 228 DescendantInvalidationSet& invalidationSet = ensureClassInvalidation Set(current->value()); |
233 invalidationSet.setWholeSubtreeInvalid(); | 229 if (mode == UseSubtreeStyleChange) |
230 invalidationSet.setWholeSubtreeInvalid(); | |
234 } else if (current->isAttributeSelector()) { | 231 } else if (current->isAttributeSelector()) { |
235 metadata.attrsInRules.add(current->attribute().localName()); | 232 metadata.attrsInRules.add(current->attribute().localName()); |
236 } | 233 } |
237 if (current->pseudoType() == CSSSelector::PseudoFirstLine) | 234 if (current->pseudoType() == CSSSelector::PseudoFirstLine) |
238 metadata.usesFirstLineRules = true; | 235 metadata.usesFirstLineRules = true; |
239 if (current->isDirectAdjacentSelector()) { | 236 if (current->isDirectAdjacentSelector()) { |
240 maxDirectAdjacentSelectors++; | 237 maxDirectAdjacentSelectors++; |
241 } else if (maxDirectAdjacentSelectors) { | 238 } else if (maxDirectAdjacentSelectors) { |
242 if (maxDirectAdjacentSelectors > metadata.maxDirectAdjacentSelectors ) | 239 if (maxDirectAdjacentSelectors > metadata.maxDirectAdjacentSelectors ) |
243 metadata.maxDirectAdjacentSelectors = maxDirectAdjacentSelectors ; | 240 metadata.maxDirectAdjacentSelectors = maxDirectAdjacentSelectors ; |
244 maxDirectAdjacentSelectors = 0; | 241 maxDirectAdjacentSelectors = 0; |
245 } | 242 } |
246 if (current->isSiblingSelector()) | 243 if (current->isSiblingSelector()) |
247 metadata.foundSiblingSelector = true; | 244 metadata.foundSiblingSelector = true; |
248 | 245 |
249 collectFeaturesFromSelectorList(current->selectorList(), metadata, colle ctionMode); | 246 collectFeaturesFromSelectorList(current->selectorList(), metadata, mode) ; |
247 | |
248 if (mode == UseLocalStyleChange && current->relation() != CSSSelector::S ubSelector) | |
249 mode = UseSubtreeStyleChange; | |
250 } | 250 } |
251 | 251 |
252 ASSERT(!maxDirectAdjacentSelectors); | 252 ASSERT(!maxDirectAdjacentSelectors); |
253 } | 253 } |
254 | 254 |
255 void RuleFeatureSet::collectFeaturesFromSelectorList(const CSSSelectorList* sele ctorList, RuleFeatureSet::FeatureMetadata& metadata, SelectorFeatureCollectionMo de collectionMode) | 255 void RuleFeatureSet::collectFeaturesFromSelectorList(const CSSSelectorList* sele ctorList, RuleFeatureSet::FeatureMetadata& metadata, InvalidationMode mode) |
256 { | 256 { |
257 if (!selectorList) | 257 if (!selectorList) |
258 return; | 258 return; |
259 | 259 |
260 for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector)) | 260 for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector)) |
261 collectFeaturesFromSelector(*selector, metadata, collectionMode); | 261 collectFeaturesFromSelector(*selector, metadata, mode); |
262 } | 262 } |
263 | 263 |
264 void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other) | 264 void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other) |
265 { | 265 { |
266 usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules; | 266 usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules; |
267 maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxD irectAdjacentSelectors); | 267 maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxD irectAdjacentSelectors); |
268 | 268 |
269 HashSet<AtomicString>::const_iterator end = other.idsInRules.end(); | 269 HashSet<AtomicString>::const_iterator end = other.idsInRules.end(); |
270 for (HashSet<AtomicString>::const_iterator it = other.idsInRules.begin(); it != end; ++it) | 270 for (HashSet<AtomicString>::const_iterator it = other.idsInRules.begin(); it != end; ++it) |
271 idsInRules.add(*it); | 271 idsInRules.add(*it); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
444 } | 444 } |
445 | 445 |
446 invalidationClasses.remove(oldSize, invalidationClasses.size() - oldSize); | 446 invalidationClasses.remove(oldSize, invalidationClasses.size() - oldSize); |
447 element->clearChildNeedsStyleInvalidation(); | 447 element->clearChildNeedsStyleInvalidation(); |
448 element->clearNeedsStyleInvalidation(); | 448 element->clearNeedsStyleInvalidation(); |
449 | 449 |
450 return thisElementNeedsStyleRecalc; | 450 return thisElementNeedsStyleRecalc; |
451 } | 451 } |
452 | 452 |
453 } // namespace WebCore | 453 } // namespace WebCore |
OLD | NEW |