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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 } | 114 } |
115 | 115 |
116 void RuleFeature::trace(Visitor* visitor) | 116 void RuleFeature::trace(Visitor* visitor) |
117 { | 117 { |
118 visitor->trace(rule); | 118 visitor->trace(rule); |
119 } | 119 } |
120 | 120 |
121 // This method is somewhat conservative in what it accepts. | 121 // This method is somewhat conservative in what it accepts. |
122 RuleFeatureSet::InvalidationSetMode RuleFeatureSet::invalidationSetModeForSelect
or(const CSSSelector& selector) | 122 RuleFeatureSet::InvalidationSetMode RuleFeatureSet::invalidationSetModeForSelect
or(const CSSSelector& selector) |
123 { | 123 { |
124 bool foundDescendantRelation = false; | 124 bool foundCombinator = false; |
125 bool foundIdent = false; | 125 bool foundIdent = false; |
126 for (const CSSSelector* component = &selector; component; component = compon
ent->tagHistory()) { | 126 for (const CSSSelector* component = &selector; component; component = compon
ent->tagHistory()) { |
127 | 127 |
128 if (component->match() == CSSSelector::Class || component->match() == CS
SSelector::Id | 128 if (component->match() == CSSSelector::Class || component->match() == CS
SSelector::Id |
129 || (component->match() == CSSSelector::Tag && component->tagQName().
localName() != starAtom) | 129 || (component->match() == CSSSelector::Tag && component->tagQName().
localName() != starAtom) |
130 || component->isAttributeSelector() || component->isCustomPseudoElem
ent()) { | 130 || component->isAttributeSelector() || component->isCustomPseudoElem
ent()) { |
131 if (!foundDescendantRelation) | 131 if (!foundCombinator) |
132 foundIdent = true; | 132 foundIdent = true; |
133 } else if (component->pseudoType() == CSSSelector::PseudoHost || compone
nt->pseudoType() == CSSSelector::PseudoAny) { | 133 } else if (component->pseudoType() == CSSSelector::PseudoHost || compone
nt->pseudoType() == CSSSelector::PseudoAny) { |
134 if (const CSSSelectorList* selectorList = component->selectorList())
{ | 134 if (const CSSSelectorList* selectorList = component->selectorList())
{ |
135 for (const CSSSelector* selector = selectorList->first(); select
or; selector = CSSSelectorList::next(*selector)) { | 135 for (const CSSSelector* selector = selectorList->first(); select
or; selector = CSSSelectorList::next(*selector)) { |
136 InvalidationSetMode hostMode = invalidationSetModeForSelecto
r(*selector); | 136 InvalidationSetMode hostMode = invalidationSetModeForSelecto
r(*selector); |
137 if (hostMode == UseSubtreeStyleChange) | 137 if (hostMode == UseSubtreeStyleChange) |
138 return foundDescendantRelation ? UseLocalStyleChange : U
seSubtreeStyleChange; | 138 return foundCombinator ? UseLocalStyleChange : UseSubtre
eStyleChange; |
139 if (!foundDescendantRelation && hostMode == AddFeatures) | 139 if (!foundCombinator && hostMode == AddFeatures) |
140 foundIdent = true; | 140 foundIdent = true; |
141 } | 141 } |
142 } | 142 } |
143 } else if (!isSkippableComponentForInvalidation(*component)) { | 143 } else if (!isSkippableComponentForInvalidation(*component)) { |
144 return foundDescendantRelation ? UseLocalStyleChange : UseSubtreeSty
leChange; | 144 return foundCombinator ? UseLocalStyleChange : UseSubtreeStyleChange
; |
145 } | 145 } |
146 switch (component->relation()) { | 146 if (component->relation() != CSSSelector::SubSelector) |
147 case CSSSelector::Descendant: | 147 foundCombinator = true; |
148 case CSSSelector::Child: | |
149 case CSSSelector::ShadowPseudo: | |
150 case CSSSelector::ShadowDeep: | |
151 foundDescendantRelation = true; | |
152 // Fall through! | |
153 case CSSSelector::SubSelector: | |
154 case CSSSelector::DirectAdjacent: | |
155 case CSSSelector::IndirectAdjacent: | |
156 continue; | |
157 default: | |
158 // All combinators should be handled above. | |
159 ASSERT_NOT_REACHED(); | |
160 return UseLocalStyleChange; | |
161 } | |
162 } | 148 } |
163 return foundIdent ? AddFeatures : UseLocalStyleChange; | 149 return foundIdent ? AddFeatures : UseLocalStyleChange; |
164 } | 150 } |
165 | 151 |
166 void RuleFeatureSet::extractInvalidationSetFeature(const CSSSelector& selector,
InvalidationSetFeatures& features) | 152 void RuleFeatureSet::extractInvalidationSetFeature(const CSSSelector& selector,
InvalidationSetFeatures& features) |
167 { | 153 { |
168 if (selector.match() == CSSSelector::Tag) | 154 if (selector.match() == CSSSelector::Tag) |
169 features.tagName = selector.tagQName().localName(); | 155 features.tagName = selector.tagQName().localName(); |
170 else if (selector.match() == CSSSelector::Id) | 156 else if (selector.match() == CSSSelector::Id) |
171 features.id = selector.value(); | 157 features.id = selector.value(); |
(...skipping 23 matching lines...) Expand all Loading... |
195 if (selector.match() == CSSSelector::Id) | 181 if (selector.match() == CSSSelector::Id) |
196 return &ensureIdInvalidationSet(selector.value()); | 182 return &ensureIdInvalidationSet(selector.value()); |
197 if (selector.match() == CSSSelector::PseudoClass) { | 183 if (selector.match() == CSSSelector::PseudoClass) { |
198 CSSSelector::PseudoType pseudo = selector.pseudoType(); | 184 CSSSelector::PseudoType pseudo = selector.pseudoType(); |
199 if (pseudo == CSSSelector::PseudoHover || pseudo == CSSSelector::PseudoA
ctive || pseudo == CSSSelector::PseudoFocus) | 185 if (pseudo == CSSSelector::PseudoHover || pseudo == CSSSelector::PseudoA
ctive || pseudo == CSSSelector::PseudoFocus) |
200 return &ensurePseudoInvalidationSet(pseudo); | 186 return &ensurePseudoInvalidationSet(pseudo); |
201 } | 187 } |
202 return 0; | 188 return 0; |
203 } | 189 } |
204 | 190 |
| 191 // Given a selector, update the descendant invalidation sets for the features fo
und |
| 192 // in the selector. The first step is to extract the features from the rightmost |
| 193 // compound selector (extractInvalidationSetFeatures). Secondly, those features
will be |
| 194 // added to the invalidation sets for the features found in the other compound s
electors |
| 195 // (addFeaturesToInvalidationSets). |
| 196 |
205 RuleFeatureSet::InvalidationSetMode RuleFeatureSet::updateInvalidationSets(const
CSSSelector& selector) | 197 RuleFeatureSet::InvalidationSetMode RuleFeatureSet::updateInvalidationSets(const
CSSSelector& selector) |
206 { | 198 { |
207 InvalidationSetMode mode = invalidationSetModeForSelector(selector); | 199 InvalidationSetMode mode = invalidationSetModeForSelector(selector); |
208 if (mode != AddFeatures) | 200 if (mode != AddFeatures) |
209 return mode; | 201 return mode; |
210 | 202 |
211 InvalidationSetFeatures features; | 203 InvalidationSetFeatures features; |
212 if (const CSSSelector* current = extractInvalidationSetFeatures(selector, fe
atures)) | 204 if (const CSSSelector* current = extractInvalidationSetFeatures(selector, fe
atures)) |
213 addFeaturesToInvalidationSets(*current, features); | 205 addFeaturesToInvalidationSets(*current, features); |
214 return AddFeatures; | 206 return AddFeatures; |
(...skipping 24 matching lines...) Expand all Loading... |
239 features.wholeSubtree = true; | 231 features.wholeSubtree = true; |
240 return current->tagHistory(); | 232 return current->tagHistory(); |
241 case CSSSelector::Descendant: | 233 case CSSSelector::Descendant: |
242 case CSSSelector::Child: | 234 case CSSSelector::Child: |
243 return current->tagHistory(); | 235 return current->tagHistory(); |
244 } | 236 } |
245 } | 237 } |
246 return 0; | 238 return 0; |
247 } | 239 } |
248 | 240 |
| 241 // Add features extracted from the rightmost compound selector to descendant inv
alidation |
| 242 // sets for features found in other compound selectors. |
| 243 // |
| 244 // Style invalidation is currently supported for descendants only, not for sibli
ng subtrees. |
| 245 // We use wholeSubtree invalidation for features found left of adjacent combinat
ors as |
| 246 // SubtreeStyleChange will force sibling subtree recalc in |
| 247 // ContainerNode::checkForChildrenAdjacentRuleChanges. |
| 248 // |
| 249 // As we encounter a descendant type of combinator, the features only need to be
checked |
| 250 // against descendants in the same subtree only. Hence wholeSubtree is reset to
false. |
| 251 |
249 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector,
InvalidationSetFeatures& features) | 252 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector,
InvalidationSetFeatures& features) |
250 { | 253 { |
251 for (const CSSSelector* current = &selector; current; current = current->tag
History()) { | 254 for (const CSSSelector* current = &selector; current; current = current->tag
History()) { |
252 if (DescendantInvalidationSet* invalidationSet = invalidationSetForSelec
tor(*current)) { | 255 if (DescendantInvalidationSet* invalidationSet = invalidationSetForSelec
tor(*current)) { |
253 if (features.treeBoundaryCrossing) | 256 if (features.treeBoundaryCrossing) |
254 invalidationSet->setTreeBoundaryCrossing(); | 257 invalidationSet->setTreeBoundaryCrossing(); |
255 if (features.wholeSubtree) { | 258 if (features.wholeSubtree) { |
256 invalidationSet->setWholeSubtreeInvalid(); | 259 invalidationSet->setWholeSubtreeInvalid(); |
257 } else { | 260 } else { |
258 if (!features.id.isEmpty()) | 261 if (!features.id.isEmpty()) |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 visitor->trace(uncommonAttributeRules); | 527 visitor->trace(uncommonAttributeRules); |
525 visitor->trace(m_classInvalidationSets); | 528 visitor->trace(m_classInvalidationSets); |
526 visitor->trace(m_attributeInvalidationSets); | 529 visitor->trace(m_attributeInvalidationSets); |
527 visitor->trace(m_idInvalidationSets); | 530 visitor->trace(m_idInvalidationSets); |
528 visitor->trace(m_pseudoInvalidationSets); | 531 visitor->trace(m_pseudoInvalidationSets); |
529 visitor->trace(m_styleInvalidator); | 532 visitor->trace(m_styleInvalidator); |
530 #endif | 533 #endif |
531 } | 534 } |
532 | 535 |
533 } // namespace blink | 536 } // namespace blink |
OLD | NEW |