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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 } | 193 } |
194 } else if (!foundSiblingSelector && selector->isSiblingSelector()) | 194 } else if (!foundSiblingSelector && selector->isSiblingSelector()) |
195 foundSiblingSelector = true; | 195 foundSiblingSelector = true; |
196 } | 196 } |
197 if (foundSiblingSelector) | 197 if (foundSiblingSelector) |
198 features.siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selec
torIndex(), ruleData.hasDocumentSecurityOrigin())); | 198 features.siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selec
torIndex(), ruleData.hasDocumentSecurityOrigin())); |
199 if (ruleData.containsUncommonAttributeSelector()) | 199 if (ruleData.containsUncommonAttributeSelector()) |
200 features.uncommonAttributeRules.append(RuleFeature(ruleData.rule(), rule
Data.selectorIndex(), ruleData.hasDocumentSecurityOrigin())); | 200 features.uncommonAttributeRules.append(RuleFeature(ruleData.rule(), rule
Data.selectorIndex(), ruleData.hasDocumentSecurityOrigin())); |
201 } | 201 } |
202 | 202 |
203 void RuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map, const RuleDa
ta& ruleData) | 203 void RuleSet::addToRuleSet(AtomicStringImpl* key, PendingRuleMap& map, const Rul
eData& ruleData) |
204 { | 204 { |
205 if (!key) | 205 if (!key) |
206 return; | 206 return; |
207 OwnPtr<Vector<RuleData> >& rules = map.add(key, nullptr).iterator->value; | 207 OwnPtr<LinkedStack<RuleData> >& rules = map.add(key, nullptr).iterator->valu
e; |
208 if (!rules) | 208 if (!rules) |
209 rules = adoptPtr(new Vector<RuleData>); | 209 rules = adoptPtr(new LinkedStack<RuleData>); |
210 rules->append(ruleData); | 210 rules->push(ruleData); |
211 } | 211 } |
212 | 212 |
213 bool RuleSet::findBestRuleSetAndAdd(const CSSSelector* component, RuleData& rule
Data) | 213 bool RuleSet::findBestRuleSetAndAdd(const CSSSelector* component, RuleData& rule
Data) |
214 { | 214 { |
215 if (component->m_match == CSSSelector::Id) { | 215 if (component->m_match == CSSSelector::Id) { |
216 addToRuleSet(component->value().impl(), m_idRules, ruleData); | 216 addToRuleSet(component->value().impl(), ensurePendingRules()->idRules, r
uleData); |
217 return true; | 217 return true; |
218 } | 218 } |
219 if (component->m_match == CSSSelector::Class) { | 219 if (component->m_match == CSSSelector::Class) { |
220 addToRuleSet(component->value().impl(), m_classRules, ruleData); | 220 addToRuleSet(component->value().impl(), ensurePendingRules()->classRules
, ruleData); |
221 return true; | 221 return true; |
222 } | 222 } |
223 if (component->isCustomPseudoElement()) { | 223 if (component->isCustomPseudoElement()) { |
224 addToRuleSet(component->value().impl(), m_shadowPseudoElementRules, rule
Data); | 224 addToRuleSet(component->value().impl(), ensurePendingRules()->shadowPseu
doElementRules, ruleData); |
225 return true; | 225 return true; |
226 } | 226 } |
227 if (component->pseudoType() == CSSSelector::PseudoCue) { | 227 if (component->pseudoType() == CSSSelector::PseudoCue) { |
228 m_cuePseudoRules.append(ruleData); | 228 m_cuePseudoRules.append(ruleData); |
229 return true; | 229 return true; |
230 } | 230 } |
231 if (SelectorChecker::isCommonPseudoClassSelector(component)) { | 231 if (SelectorChecker::isCommonPseudoClassSelector(component)) { |
232 switch (component->pseudoType()) { | 232 switch (component->pseudoType()) { |
233 case CSSSelector::PseudoLink: | 233 case CSSSelector::PseudoLink: |
234 case CSSSelector::PseudoVisited: | 234 case CSSSelector::PseudoVisited: |
(...skipping 10 matching lines...) Expand all Loading... |
245 } | 245 } |
246 | 246 |
247 if (component->m_match == CSSSelector::Tag) { | 247 if (component->m_match == CSSSelector::Tag) { |
248 if (component->tagQName().localName() != starAtom) { | 248 if (component->tagQName().localName() != starAtom) { |
249 // If this is part of a subselector chain, recurse ahead to find a n
arrower set (ID/class.) | 249 // If this is part of a subselector chain, recurse ahead to find a n
arrower set (ID/class.) |
250 if (component->relation() == CSSSelector::SubSelector | 250 if (component->relation() == CSSSelector::SubSelector |
251 && (component->tagHistory()->m_match == CSSSelector::Class || co
mponent->tagHistory()->m_match == CSSSelector::Id || SelectorChecker::isCommonPs
eudoClassSelector(component->tagHistory())) | 251 && (component->tagHistory()->m_match == CSSSelector::Class || co
mponent->tagHistory()->m_match == CSSSelector::Id || SelectorChecker::isCommonPs
eudoClassSelector(component->tagHistory())) |
252 && findBestRuleSetAndAdd(component->tagHistory(), ruleData)) | 252 && findBestRuleSetAndAdd(component->tagHistory(), ruleData)) |
253 return true; | 253 return true; |
254 | 254 |
255 addToRuleSet(component->tagQName().localName().impl(), m_tagRules, r
uleData); | 255 addToRuleSet(component->tagQName().localName().impl(), ensurePending
Rules()->tagRules, ruleData); |
256 return true; | 256 return true; |
257 } | 257 } |
258 } | 258 } |
259 return false; | 259 return false; |
260 } | 260 } |
261 | 261 |
262 void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, AddRuleFlags addR
uleFlags) | 262 void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, AddRuleFlags addR
uleFlags) |
263 { | 263 { |
264 m_hasDirtyRules = true; | |
265 RuleData ruleData(rule, selectorIndex, m_ruleCount++, addRuleFlags); | 264 RuleData ruleData(rule, selectorIndex, m_ruleCount++, addRuleFlags); |
266 collectFeaturesFromRuleData(m_features, ruleData); | 265 collectFeaturesFromRuleData(m_features, ruleData); |
267 | 266 |
268 if (!findBestRuleSetAndAdd(ruleData.selector(), ruleData)) { | 267 if (!findBestRuleSetAndAdd(ruleData.selector(), ruleData)) { |
269 // If we didn't find a specialized map to stick it in, file under univer
sal rules. | 268 // If we didn't find a specialized map to stick it in, file under univer
sal rules. |
270 m_universalRules.append(ruleData); | 269 m_universalRules.append(ruleData); |
271 } | 270 } |
272 } | 271 } |
273 | 272 |
274 void RuleSet::addPageRule(StyleRulePage* rule) | 273 void RuleSet::addPageRule(StyleRulePage* rule) |
275 { | 274 { |
276 m_hasDirtyRules = true; | 275 ensurePendingRules(); // So that m_pageRules.shrinkToFit() gets called. |
277 m_pageRules.append(rule); | 276 m_pageRules.append(rule); |
278 } | 277 } |
279 | 278 |
280 void RuleSet::addRegionRule(StyleRuleRegion* regionRule, bool hasDocumentSecurit
yOrigin) | 279 void RuleSet::addRegionRule(StyleRuleRegion* regionRule, bool hasDocumentSecurit
yOrigin) |
281 { | 280 { |
282 m_hasDirtyRules = true; | 281 ensurePendingRules(); // So that m_regionSelectorsAndRuleSets.shrinkToFit()
gets called. |
283 OwnPtr<RuleSet> regionRuleSet = RuleSet::create(); | 282 OwnPtr<RuleSet> regionRuleSet = RuleSet::create(); |
284 // The region rule set should take into account the position inside the pare
nt rule set. | 283 // The region rule set should take into account the position inside the pare
nt rule set. |
285 // Otherwise, the rules inside region block might be incorrectly positioned
before other similar rules from | 284 // Otherwise, the rules inside region block might be incorrectly positioned
before other similar rules from |
286 // the stylesheet that contains the region block. | 285 // the stylesheet that contains the region block. |
287 regionRuleSet->m_ruleCount = m_ruleCount; | 286 regionRuleSet->m_ruleCount = m_ruleCount; |
288 | 287 |
289 // Collect the region rules into a rule set | 288 // Collect the region rules into a rule set |
290 // FIXME: Should this add other types of rules? (i.e. use addChildRules() di
rectly?) | 289 // FIXME: Should this add other types of rules? (i.e. use addChildRules() di
rectly?) |
291 const Vector<RefPtr<StyleRuleBase> >& childRules = regionRule->childRules(); | 290 const Vector<RefPtr<StyleRuleBase> >& childRules = regionRule->childRules(); |
292 AddRuleFlags addRuleFlags = hasDocumentSecurityOrigin ? RuleHasDocumentSecur
ityOrigin : RuleHasNoSpecialState; | 291 AddRuleFlags addRuleFlags = hasDocumentSecurityOrigin ? RuleHasDocumentSecur
ityOrigin : RuleHasNoSpecialState; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 | 371 |
373 addChildRules(sheet->childRules(), medium, resolver, scope, hasDocumentSecur
ityOrigin, addRuleFlags); | 372 addChildRules(sheet->childRules(), medium, resolver, scope, hasDocumentSecur
ityOrigin, addRuleFlags); |
374 } | 373 } |
375 | 374 |
376 void RuleSet::addStyleRule(StyleRule* rule, AddRuleFlags addRuleFlags) | 375 void RuleSet::addStyleRule(StyleRule* rule, AddRuleFlags addRuleFlags) |
377 { | 376 { |
378 for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = ru
le->selectorList().indexOfNextSelectorAfter(selectorIndex)) | 377 for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = ru
le->selectorList().indexOfNextSelectorAfter(selectorIndex)) |
379 addRule(rule, selectorIndex, addRuleFlags); | 378 addRule(rule, selectorIndex, addRuleFlags); |
380 } | 379 } |
381 | 380 |
382 void RuleSet::shrinkMapVectorsToFit(AtomRuleMap& map) | 381 void RuleSet::compactPendingRules(PendingRuleMap& pendingMap, CompactRuleMap& co
mpactMap) |
383 { | 382 { |
384 RuleSet::AtomRuleMap::iterator end = map.end(); | 383 PendingRuleMap::iterator end = pendingMap.end(); |
385 for (RuleSet::AtomRuleMap::iterator it = map.begin(); it != end; ++it) | 384 for (PendingRuleMap::iterator it = pendingMap.begin(); it != end; ++it) { |
386 it->value->shrinkToFit(); | 385 OwnPtr<LinkedStack<RuleData> > pendingRules = it->value.release(); |
| 386 size_t pendingSize = pendingRules->size(); |
| 387 ASSERT(pendingSize); |
| 388 |
| 389 OwnPtr<Vector<RuleData> >& compactRules = compactMap.add(it->key, nullpt
r).iterator->value; |
| 390 if (!compactRules) { |
| 391 compactRules = adoptPtr(new Vector<RuleData>); |
| 392 compactRules->reserveInitialCapacity(pendingSize); |
| 393 } else { |
| 394 compactRules->reserveCapacity(compactRules->size() + pendingSize); |
| 395 } |
| 396 |
| 397 while (!pendingRules->isEmpty()) { |
| 398 compactRules->append(pendingRules->peek()); |
| 399 pendingRules->pop(); |
| 400 } |
| 401 |
| 402 ASSERT(compactRules->size() == compactRules->capacity()); |
| 403 } |
387 } | 404 } |
388 | 405 |
389 void RuleSet::shrinkToFit() | 406 void RuleSet::compactRules() |
390 { | 407 { |
391 m_hasDirtyRules = false; | 408 ASSERT(m_pendingRules); |
392 shrinkMapVectorsToFit(m_idRules); | 409 OwnPtr<PendingRuleMaps> pendingRules = m_pendingRules.release(); |
393 shrinkMapVectorsToFit(m_classRules); | 410 compactPendingRules(pendingRules->idRules, m_idRules); |
394 shrinkMapVectorsToFit(m_tagRules); | 411 compactPendingRules(pendingRules->classRules, m_classRules); |
395 shrinkMapVectorsToFit(m_shadowPseudoElementRules); | 412 compactPendingRules(pendingRules->tagRules, m_tagRules); |
| 413 compactPendingRules(pendingRules->shadowPseudoElementRules, m_shadowPseudoEl
ementRules); |
396 m_linkPseudoClassRules.shrinkToFit(); | 414 m_linkPseudoClassRules.shrinkToFit(); |
397 m_cuePseudoRules.shrinkToFit(); | 415 m_cuePseudoRules.shrinkToFit(); |
398 m_focusPseudoClassRules.shrinkToFit(); | 416 m_focusPseudoClassRules.shrinkToFit(); |
399 m_universalRules.shrinkToFit(); | 417 m_universalRules.shrinkToFit(); |
400 m_pageRules.shrinkToFit(); | 418 m_pageRules.shrinkToFit(); |
401 } | 419 } |
402 | 420 |
403 } // namespace WebCore | 421 } // namespace WebCore |
OLD | NEW |