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, 2013 Apple Inc.
All rights reserved. | 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc.
All rights 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 // c) the rules comes from a scoped style sheet within the same tree scope | 122 // c) the rules comes from a scoped style sheet within the same tree scope |
123 if (!scopingNode || element->treeScope() == scopingNode->treeScope()) | 123 if (!scopingNode || element->treeScope() == scopingNode->treeScope()) |
124 return true; | 124 return true; |
125 // d) the rules comes from a scoped style sheet within an active shadow root
whose host is the given element | 125 // d) the rules comes from a scoped style sheet within an active shadow root
whose host is the given element |
126 if (element == scopingNode->shadowHost()) | 126 if (element == scopingNode->shadowHost()) |
127 return true; | 127 return true; |
128 return false; | 128 return false; |
129 } | 129 } |
130 | 130 |
131 template<typename RuleDataListType> | 131 template<typename RuleDataListType> |
132 void ElementRuleCollector::collectMatchingRulesForList(const RuleDataListType* r
ules, CascadeOrder cascadeOrder, const MatchRequest& matchRequest) | 132 void ElementRuleCollector::collectMatchingRulesForList(const RuleDataListType* r
ules, const MatchRequest& matchRequest) |
133 { | 133 { |
134 if (!rules) | 134 if (!rules) |
135 return; | 135 return; |
136 | 136 |
137 SelectorChecker checker(m_mode); | 137 SelectorChecker checker(m_mode); |
138 SelectorChecker::SelectorCheckingContext checkerContext(m_context.element(),
SelectorChecker::VisitedMatchEnabled); | 138 SelectorChecker::SelectorCheckingContext checkerContext(m_context.element(),
SelectorChecker::VisitedMatchEnabled); |
139 checkerContext.elementStyle = m_style.get(); | 139 checkerContext.elementStyle = m_style.get(); |
140 checkerContext.scope = matchRequest.scope; | 140 checkerContext.scope = matchRequest.scope; |
141 checkerContext.pseudoId = m_pseudoStyleRequest.pseudoId; | 141 checkerContext.pseudoId = m_pseudoStyleRequest.pseudoId; |
142 checkerContext.scrollbar = m_pseudoStyleRequest.scrollbar; | 142 checkerContext.scrollbar = m_pseudoStyleRequest.scrollbar; |
(...skipping 27 matching lines...) Expand all Loading... |
170 if (!checker.match(checkerContext, result)) { | 170 if (!checker.match(checkerContext, result)) { |
171 rejected++; | 171 rejected++; |
172 continue; | 172 continue; |
173 } | 173 } |
174 if (m_pseudoStyleRequest.pseudoId != NOPSEUDO && m_pseudoStyleRequest.ps
eudoId != result.dynamicPseudo) { | 174 if (m_pseudoStyleRequest.pseudoId != NOPSEUDO && m_pseudoStyleRequest.ps
eudoId != result.dynamicPseudo) { |
175 rejected++; | 175 rejected++; |
176 continue; | 176 continue; |
177 } | 177 } |
178 | 178 |
179 matched++; | 179 matched++; |
180 didMatchRule(ruleData, result, cascadeOrder, matchRequest); | 180 didMatchRule(ruleData, result, matchRequest); |
181 } | 181 } |
182 | 182 |
183 if (StyleResolver* resolver = m_context.element()->document().styleResolver(
)) { | 183 if (StyleResolver* resolver = m_context.element()->document().styleResolver(
)) { |
184 INCREMENT_STYLE_STATS_COUNTER(*resolver, rulesRejected, rejected); | 184 INCREMENT_STYLE_STATS_COUNTER(*resolver, rulesRejected, rejected); |
185 INCREMENT_STYLE_STATS_COUNTER(*resolver, rulesFastRejected, fastRejected
); | 185 INCREMENT_STYLE_STATS_COUNTER(*resolver, rulesFastRejected, fastRejected
); |
186 INCREMENT_STYLE_STATS_COUNTER(*resolver, rulesMatched, matched); | 186 INCREMENT_STYLE_STATS_COUNTER(*resolver, rulesMatched, matched); |
187 } | 187 } |
188 } | 188 } |
189 | 189 |
190 void ElementRuleCollector::collectMatchingRules(const MatchRequest& matchRequest
, CascadeOrder cascadeOrder, bool matchingTreeBoundaryRules) | 190 void ElementRuleCollector::collectMatchingRules(const MatchRequest& matchRequest
, bool matchingTreeBoundaryRules) |
191 { | 191 { |
192 ASSERT(matchRequest.ruleSet); | 192 ASSERT(matchRequest.ruleSet); |
193 ASSERT(m_context.element()); | 193 ASSERT(m_context.element()); |
194 | 194 |
195 Element& element = *m_context.element(); | 195 Element& element = *m_context.element(); |
196 const AtomicString& pseudoId = element.shadowPseudoId(); | 196 const AtomicString& pseudoId = element.shadowPseudoId(); |
197 if (!pseudoId.isEmpty()) { | 197 if (!pseudoId.isEmpty()) { |
198 ASSERT(element.isStyledElement()); | 198 ASSERT(element.isStyledElement()); |
199 collectMatchingRulesForList(matchRequest.ruleSet->shadowPseudoElementRul
es(pseudoId), cascadeOrder, matchRequest); | 199 collectMatchingRulesForList(matchRequest.ruleSet->shadowPseudoElementRul
es(pseudoId), matchRequest); |
200 } | 200 } |
201 | 201 |
202 if (element.isVTTElement()) | 202 if (element.isVTTElement()) |
203 collectMatchingRulesForList(matchRequest.ruleSet->cuePseudoRules(), casc
adeOrder, matchRequest); | 203 collectMatchingRulesForList(matchRequest.ruleSet->cuePseudoRules(), matc
hRequest); |
204 // Check whether other types of rules are applicable in the current tree sco
pe. Criteria for this: | 204 // Check whether other types of rules are applicable in the current tree sco
pe. Criteria for this: |
205 // a) it's a UA rule | 205 // a) it's a UA rule |
206 // b) the rules comes from a scoped style sheet within the same tree scope | 206 // b) the rules comes from a scoped style sheet within the same tree scope |
207 // c) the rules comes from a scoped style sheet within an active shadow root
whose host is the given element | 207 // c) the rules comes from a scoped style sheet within an active shadow root
whose host is the given element |
208 // d) the rules can cross boundaries | 208 // d) the rules can cross boundaries |
209 // b)-e) is checked in rulesApplicableInCurrentTreeScope. | 209 // b)-e) is checked in rulesApplicableInCurrentTreeScope. |
210 if (!m_matchingUARules && !rulesApplicableInCurrentTreeScope(&element, match
Request.scope, matchingTreeBoundaryRules)) | 210 if (!m_matchingUARules && !rulesApplicableInCurrentTreeScope(&element, match
Request.scope, matchingTreeBoundaryRules)) |
211 return; | 211 return; |
212 | 212 |
213 // We need to collect the rules for id, class, tag, and everything else into
a buffer and | 213 // We need to collect the rules for id, class, tag, and everything else into
a buffer and |
214 // then sort the buffer. | 214 // then sort the buffer. |
215 if (element.hasID()) | 215 if (element.hasID()) |
216 collectMatchingRulesForList(matchRequest.ruleSet->idRules(element.idForS
tyleResolution()), cascadeOrder, matchRequest); | 216 collectMatchingRulesForList(matchRequest.ruleSet->idRules(element.idForS
tyleResolution()), matchRequest); |
217 if (element.isStyledElement() && element.hasClass()) { | 217 if (element.isStyledElement() && element.hasClass()) { |
218 for (size_t i = 0; i < element.classNames().size(); ++i) | 218 for (size_t i = 0; i < element.classNames().size(); ++i) |
219 collectMatchingRulesForList(matchRequest.ruleSet->classRules(element
.classNames()[i]), cascadeOrder, matchRequest); | 219 collectMatchingRulesForList(matchRequest.ruleSet->classRules(element
.classNames()[i]), matchRequest); |
220 } | 220 } |
221 | 221 |
222 if (element.isLink()) | 222 if (element.isLink()) |
223 collectMatchingRulesForList(matchRequest.ruleSet->linkPseudoClassRules()
, cascadeOrder, matchRequest); | 223 collectMatchingRulesForList(matchRequest.ruleSet->linkPseudoClassRules()
, matchRequest); |
224 if (SelectorChecker::matchesFocusPseudoClass(element)) | 224 if (SelectorChecker::matchesFocusPseudoClass(element)) |
225 collectMatchingRulesForList(matchRequest.ruleSet->focusPseudoClassRules(
), cascadeOrder, matchRequest); | 225 collectMatchingRulesForList(matchRequest.ruleSet->focusPseudoClassRules(
), matchRequest); |
226 collectMatchingRulesForList(matchRequest.ruleSet->tagRules(element.localName
ForSelectorMatching()), cascadeOrder, matchRequest); | 226 collectMatchingRulesForList(matchRequest.ruleSet->tagRules(element.localName
ForSelectorMatching()), matchRequest); |
227 collectMatchingRulesForList(matchRequest.ruleSet->universalRules(), cascadeO
rder, matchRequest); | 227 collectMatchingRulesForList(matchRequest.ruleSet->universalRules(), matchReq
uest); |
228 } | 228 } |
229 | 229 |
230 void ElementRuleCollector::collectMatchingShadowHostRules(const MatchRequest& ma
tchRequest, CascadeOrder cascadeOrder, bool matchingTreeBoundaryRules) | 230 void ElementRuleCollector::collectMatchingShadowHostRules(const MatchRequest& ma
tchRequest, bool matchingTreeBoundaryRules) |
231 { | 231 { |
232 collectMatchingRulesForList(matchRequest.ruleSet->shadowHostRules(), cascade
Order, matchRequest); | 232 collectMatchingRulesForList(matchRequest.ruleSet->shadowHostRules(), matchRe
quest); |
233 } | 233 } |
234 | 234 |
235 template<class CSSRuleCollection> | 235 template<class CSSRuleCollection> |
236 CSSRule* ElementRuleCollector::findStyleRule(CSSRuleCollection* cssRules, StyleR
ule* styleRule) | 236 CSSRule* ElementRuleCollector::findStyleRule(CSSRuleCollection* cssRules, StyleR
ule* styleRule) |
237 { | 237 { |
238 if (!cssRules) | 238 if (!cssRules) |
239 return 0; | 239 return 0; |
240 CSSRule* result = 0; | 240 CSSRule* result = 0; |
241 for (unsigned i = 0; i < cssRules->length() && !result; ++i) { | 241 for (unsigned i = 0; i < cssRules->length() && !result; ++i) { |
242 CSSRule* cssRule = cssRules->item(i); | 242 CSSRule* cssRule = cssRules->item(i); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 return; | 288 return; |
289 } | 289 } |
290 | 290 |
291 // Now transfer the set of matched rules over to our list of declarations. | 291 // Now transfer the set of matched rules over to our list of declarations. |
292 for (unsigned i = 0; i < m_matchedRules.size(); i++) { | 292 for (unsigned i = 0; i < m_matchedRules.size(); i++) { |
293 const RuleData* ruleData = m_matchedRules[i].ruleData(); | 293 const RuleData* ruleData = m_matchedRules[i].ruleData(); |
294 m_result.addMatchedProperties(&ruleData->rule()->properties(), ruleData-
>linkMatchType(), ruleData->propertyWhitelistType(m_matchingUARules)); | 294 m_result.addMatchedProperties(&ruleData->rule()->properties(), ruleData-
>linkMatchType(), ruleData->propertyWhitelistType(m_matchingUARules)); |
295 } | 295 } |
296 } | 296 } |
297 | 297 |
298 void ElementRuleCollector::didMatchRule(const RuleData& ruleData, const Selector
Checker::MatchResult& result, CascadeOrder cascadeOrder, const MatchRequest& mat
chRequest) | 298 void ElementRuleCollector::didMatchRule(const RuleData& ruleData, const Selector
Checker::MatchResult& result, const MatchRequest& matchRequest) |
299 { | 299 { |
300 PseudoId dynamicPseudo = result.dynamicPseudo; | 300 PseudoId dynamicPseudo = result.dynamicPseudo; |
301 // If we're matching normal rules, set a pseudo bit if | 301 // If we're matching normal rules, set a pseudo bit if |
302 // we really just matched a pseudo-element. | 302 // we really just matched a pseudo-element. |
303 if (dynamicPseudo != NOPSEUDO && m_pseudoStyleRequest.pseudoId == NOPSEUDO)
{ | 303 if (dynamicPseudo != NOPSEUDO && m_pseudoStyleRequest.pseudoId == NOPSEUDO)
{ |
304 if (m_mode == SelectorChecker::CollectingCSSRules || m_mode == SelectorC
hecker::CollectingStyleRules) | 304 if (m_mode == SelectorChecker::CollectingCSSRules || m_mode == SelectorC
hecker::CollectingStyleRules) |
305 return; | 305 return; |
306 // FIXME: Matching should not modify the style directly. | 306 // FIXME: Matching should not modify the style directly. |
307 if (!m_style || dynamicPseudo >= FIRST_INTERNAL_PSEUDOID) | 307 if (!m_style || dynamicPseudo >= FIRST_INTERNAL_PSEUDOID) |
308 return; | 308 return; |
309 if ((dynamicPseudo == BEFORE || dynamicPseudo == AFTER) && !ruleData.rul
e()->properties().hasProperty(CSSPropertyContent)) | 309 if ((dynamicPseudo == BEFORE || dynamicPseudo == AFTER) && !ruleData.rul
e()->properties().hasProperty(CSSPropertyContent)) |
310 return; | 310 return; |
311 m_style->setHasPseudoStyle(dynamicPseudo); | 311 m_style->setHasPseudoStyle(dynamicPseudo); |
312 } else { | 312 } else { |
313 if (m_style && ruleData.containsUncommonAttributeSelector()) | 313 if (m_style && ruleData.containsUncommonAttributeSelector()) |
314 m_style->setUnique(); | 314 m_style->setUnique(); |
315 | 315 |
316 m_matchedRules.append(MatchedRule(&ruleData, result.specificity, cascade
Order, matchRequest.styleSheetIndex, matchRequest.styleSheet)); | 316 m_matchedRules.append(MatchedRule(&ruleData, result.specificity, matchRe
quest.styleSheetIndex, matchRequest.styleSheet)); |
317 } | 317 } |
318 } | 318 } |
319 | 319 |
320 static inline bool compareRules(const MatchedRule& matchedRule1, const MatchedRu
le& matchedRule2) | 320 static inline bool compareRules(const MatchedRule& matchedRule1, const MatchedRu
le& matchedRule2) |
321 { | 321 { |
322 unsigned specificity1 = matchedRule1.specificity(); | 322 unsigned specificity1 = matchedRule1.specificity(); |
323 unsigned specificity2 = matchedRule2.specificity(); | 323 unsigned specificity2 = matchedRule2.specificity(); |
324 if (specificity1 != specificity2) | 324 if (specificity1 != specificity2) |
325 return specificity1 < specificity2; | 325 return specificity1 < specificity2; |
326 | 326 |
(...skipping 14 matching lines...) Expand all Loading... |
341 // should not see the element's treescope. Because RuleSet has no | 341 // should not see the element's treescope. Because RuleSet has no |
342 // information about "scope". | 342 // information about "scope". |
343 MatchRequest matchRequest(ruleSet); | 343 MatchRequest matchRequest(ruleSet); |
344 collectMatchingRules(matchRequest); | 344 collectMatchingRules(matchRequest); |
345 collectMatchingShadowHostRules(matchRequest); | 345 collectMatchingShadowHostRules(matchRequest); |
346 | 346 |
347 return !m_matchedRules.isEmpty(); | 347 return !m_matchedRules.isEmpty(); |
348 } | 348 } |
349 | 349 |
350 } // namespace blink | 350 } // namespace blink |
OLD | NEW |