| 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::InvalidationSetMode RuleFeatureSet::supportsClassDescendantInval
idation(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 ? AddFeatures : 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::InvalidationSetMode RuleFeatureSet::updateClassInvalidationSets(
const CSSSelector& selector) |
| 150 { | 150 { |
| 151 if (!supportsClassDescendantInvalidation(selector)) | 151 InvalidationSetMode mode = supportsClassDescendantInvalidation(selector); |
| 152 return false; | 152 if (mode != AddFeatures) |
| 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 AddFeatures; |
| 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 AddFeatures; |
| 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 InvalidationSetMode 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, InvalidationSetMode 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 != AddFeatures
) { |
| 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, InvalidationSetMode 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 |