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 14 matching lines...) Expand all Loading... |
25 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 25 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
26 * Boston, MA 02110-1301, USA. | 26 * Boston, MA 02110-1301, USA. |
27 */ | 27 */ |
28 | 28 |
29 #include "config.h" | 29 #include "config.h" |
30 #include "core/css/TreeBoundaryCrossingRules.h" | 30 #include "core/css/TreeBoundaryCrossingRules.h" |
31 | 31 |
32 #include "core/css/ElementRuleCollector.h" | 32 #include "core/css/ElementRuleCollector.h" |
33 #include "core/css/RuleFeature.h" | 33 #include "core/css/RuleFeature.h" |
34 #include "core/dom/StyleEngine.h" | 34 #include "core/dom/StyleEngine.h" |
35 #include "core/dom/shadow/InsertionPoint.h" | |
36 #include "core/dom/shadow/ShadowRoot.h" | 35 #include "core/dom/shadow/ShadowRoot.h" |
37 | 36 |
38 namespace WebCore { | 37 namespace WebCore { |
39 | 38 |
40 static void addRules(RuleSet* ruleSet, const WillBeHeapVector<MinimalRuleData>&
rules) | 39 static void addRules(RuleSet* ruleSet, const WillBeHeapVector<MinimalRuleData>&
rules) |
41 { | 40 { |
42 for (unsigned i = 0; i < rules.size(); ++i) { | 41 for (unsigned i = 0; i < rules.size(); ++i) { |
43 const MinimalRuleData& info = rules[i]; | 42 const MinimalRuleData& info = rules[i]; |
44 ruleSet->addRule(info.m_rule, info.m_selectorIndex, info.m_flags); | 43 ruleSet->addRule(info.m_rule, info.m_selectorIndex, info.m_flags); |
45 } | 44 } |
(...skipping 21 matching lines...) Expand all Loading... |
67 if (m_treeBoundaryCrossingRuleSetMap.isEmpty()) | 66 if (m_treeBoundaryCrossingRuleSetMap.isEmpty()) |
68 return; | 67 return; |
69 | 68 |
70 RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange(); | 69 RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange(); |
71 | 70 |
72 // When comparing rules declared in outer treescopes, outer's rules win. | 71 // When comparing rules declared in outer treescopes, outer's rules win. |
73 CascadeOrder outerCascadeOrder = size() + size(); | 72 CascadeOrder outerCascadeOrder = size() + size(); |
74 // When comparing rules declared in inner treescopes, inner's rules win. | 73 // When comparing rules declared in inner treescopes, inner's rules win. |
75 CascadeOrder innerCascadeOrder = size(); | 74 CascadeOrder innerCascadeOrder = size(); |
76 | 75 |
77 // FIXME: This is n^2 across the number of scoping nodes in the entire docum
ent! We need to walk the | |
78 // ancestors of |element| instead. | |
79 for (DocumentOrderedList::iterator it = m_scopingNodes.begin(); it != m_scop
ingNodes.end(); ++it) { | 76 for (DocumentOrderedList::iterator it = m_scopingNodes.begin(); it != m_scop
ingNodes.end(); ++it) { |
80 const ContainerNode* scopingNode = toContainerNode(*it); | 77 const ContainerNode* scopingNode = toContainerNode(*it); |
81 CSSStyleSheetRuleSubSet* ruleSubSet = m_treeBoundaryCrossingRuleSetMap.g
et(scopingNode); | 78 CSSStyleSheetRuleSubSet* ruleSubSet = m_treeBoundaryCrossingRuleSetMap.g
et(scopingNode); |
82 unsigned boundaryBehavior = SelectorChecker::ScopeContainsLastMatchedEle
ment; | 79 unsigned boundaryBehavior = SelectorChecker::ScopeContainsLastMatchedEle
ment; |
83 bool isInnerTreeScope = element->treeScope().isInclusiveAncestorOf(scopi
ngNode->treeScope()); | 80 bool isInnerTreeScope = element->treeScope().isInclusiveAncestorOf(scopi
ngNode->treeScope()); |
84 | 81 |
85 // If a given scoping node is a shadow root, | 82 // If a given scoping node is a shadow root, |
86 // we should use ScopeIsShadowHost. | 83 // we should use ScopeIsShadowHost. |
87 if (scopingNode && scopingNode->isShadowRoot()) { | 84 if (scopingNode && scopingNode->isShadowRoot()) { |
88 boundaryBehavior |= SelectorChecker::ScopeIsShadowHost; | 85 boundaryBehavior |= SelectorChecker::ScopeIsShadowHost; |
89 scopingNode = toShadowRoot(scopingNode)->host(); | 86 scopingNode = toShadowRoot(scopingNode)->host(); |
90 } | 87 } |
91 | 88 |
92 // FIXME: This is a terrible hack to avoid doing most of the work in thi
s n^2 loop. | |
93 // Instead we should just fix the loop to collect the proper scopes up t
he tree instead | |
94 // of iterating all possible scopes. | |
95 const InsertionPoint* insertionPoint = resolveReprojection(element); | |
96 if ((insertionPoint && !scopingNode->containsIncludingShadowDOM(insertio
nPoint)) | |
97 || (!insertionPoint && !scopingNode->containsIncludingShadowDOM(elem
ent))) { | |
98 ++innerCascadeOrder; | |
99 --outerCascadeOrder; | |
100 continue; | |
101 } | |
102 | |
103 CascadeOrder cascadeOrder = isInnerTreeScope ? innerCascadeOrder : outer
CascadeOrder; | 89 CascadeOrder cascadeOrder = isInnerTreeScope ? innerCascadeOrder : outer
CascadeOrder; |
104 for (CSSStyleSheetRuleSubSet::iterator it = ruleSubSet->begin(); it != r
uleSubSet->end(); ++it) { | 90 for (CSSStyleSheetRuleSubSet::iterator it = ruleSubSet->begin(); it != r
uleSubSet->end(); ++it) { |
105 CSSStyleSheet* parentStyleSheet = it->first; | 91 CSSStyleSheet* parentStyleSheet = it->first; |
106 RuleSet* ruleSet = it->second.get(); | 92 RuleSet* ruleSet = it->second.get(); |
107 collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRul
es, scopingNode, parentStyleSheet), ruleRange, static_cast<SelectorChecker::Beha
viorAtBoundary>(boundaryBehavior), ignoreCascadeScope, cascadeOrder); | 93 collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRul
es, scopingNode, parentStyleSheet), ruleRange, static_cast<SelectorChecker::Beha
viorAtBoundary>(boundaryBehavior), ignoreCascadeScope, cascadeOrder); |
108 } | 94 } |
109 | |
110 ++innerCascadeOrder; | 95 ++innerCascadeOrder; |
111 --outerCascadeOrder; | 96 --outerCascadeOrder; |
112 } | 97 } |
113 } | 98 } |
114 | 99 |
115 void TreeBoundaryCrossingRules::reset(const ContainerNode* scopingNode) | 100 void TreeBoundaryCrossingRules::reset(const ContainerNode* scopingNode) |
116 { | 101 { |
117 m_treeBoundaryCrossingRuleSetMap.remove(scopingNode); | 102 m_treeBoundaryCrossingRuleSetMap.remove(scopingNode); |
118 m_scopingNodes.remove(scopingNode); | 103 m_scopingNodes.remove(scopingNode); |
119 } | 104 } |
120 | 105 |
121 void TreeBoundaryCrossingRules::collectFeaturesFromRuleSubSet(CSSStyleSheetRuleS
ubSet* ruleSubSet, RuleFeatureSet& features) | 106 void TreeBoundaryCrossingRules::collectFeaturesFromRuleSubSet(CSSStyleSheetRuleS
ubSet* ruleSubSet, RuleFeatureSet& features) |
122 { | 107 { |
123 for (CSSStyleSheetRuleSubSet::iterator it = ruleSubSet->begin(); it != ruleS
ubSet->end(); ++it) | 108 for (CSSStyleSheetRuleSubSet::iterator it = ruleSubSet->begin(); it != ruleS
ubSet->end(); ++it) |
124 features.add(it->second->features()); | 109 features.add(it->second->features()); |
125 } | 110 } |
126 | 111 |
127 void TreeBoundaryCrossingRules::collectFeaturesTo(RuleFeatureSet& features) | 112 void TreeBoundaryCrossingRules::collectFeaturesTo(RuleFeatureSet& features) |
128 { | 113 { |
129 for (TreeBoundaryCrossingRuleSetMap::iterator::Values it = m_treeBoundaryCro
ssingRuleSetMap.values().begin(); it != m_treeBoundaryCrossingRuleSetMap.values(
).end(); ++it) | 114 for (TreeBoundaryCrossingRuleSetMap::iterator::Values it = m_treeBoundaryCro
ssingRuleSetMap.values().begin(); it != m_treeBoundaryCrossingRuleSetMap.values(
).end(); ++it) |
130 collectFeaturesFromRuleSubSet(it->get(), features); | 115 collectFeaturesFromRuleSubSet(it->get(), features); |
131 } | 116 } |
132 | 117 |
133 } // namespace WebCore | 118 } // namespace WebCore |
OLD | NEW |