OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. | 3 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
All rights reserved. |
4 * Copyright (C) 2012 Google Inc. All rights reserved. | 4 * Copyright (C) 2012 Google Inc. All rights reserved. |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 10 matching lines...) Expand all Loading... |
21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O
N | 21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O
N |
22 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 22 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 */ | 25 */ |
26 | 26 |
27 #include "config.h" | 27 #include "config.h" |
28 #include "core/css/resolver/ScopedStyleResolver.h" | 28 #include "core/css/resolver/ScopedStyleResolver.h" |
29 | 29 |
30 #include "core/HTMLNames.h" | 30 #include "core/HTMLNames.h" |
| 31 #include "core/css/CSSFontSelector.h" |
31 #include "core/css/CSSStyleSheet.h" | 32 #include "core/css/CSSStyleSheet.h" |
| 33 #include "core/css/FontFace.h" |
32 #include "core/css/PageRuleCollector.h" | 34 #include "core/css/PageRuleCollector.h" |
33 #include "core/css/RuleFeature.h" | 35 #include "core/css/RuleFeature.h" |
34 #include "core/css/StyleRule.h" | 36 #include "core/css/StyleRule.h" |
35 #include "core/css/StyleSheetContents.h" | 37 #include "core/css/StyleSheetContents.h" |
36 #include "core/css/resolver/StyleResolver.h" // For MatchRequest. | 38 #include "core/css/resolver/StyleResolver.h" // For MatchRequest. |
37 #include "core/css/resolver/ViewportStyleResolver.h" | 39 #include "core/css/resolver/ViewportStyleResolver.h" |
38 #include "core/dom/Document.h" | 40 #include "core/dom/Document.h" |
| 41 #include "core/dom/StyleEngine.h" |
39 #include "core/dom/shadow/ElementShadow.h" | 42 #include "core/dom/shadow/ElementShadow.h" |
40 #include "core/dom/shadow/ShadowRoot.h" | 43 #include "core/dom/shadow/ShadowRoot.h" |
41 #include "core/html/HTMLStyleElement.h" | 44 #include "core/html/HTMLStyleElement.h" |
42 #include "core/svg/SVGStyleElement.h" | 45 #include "core/svg/SVGStyleElement.h" |
43 | 46 |
44 namespace blink { | 47 namespace blink { |
45 | 48 |
46 TreeScope* ScopedStyleResolver::treeScopeFor(Document& document, const CSSStyleS
heet* sheet) | 49 TreeScope* ScopedStyleResolver::treeScopeFor(Document& document, const CSSStyleS
heet* sheet) |
47 { | 50 { |
48 ASSERT(sheet); | 51 ASSERT(sheet); |
(...skipping 13 matching lines...) Expand all Loading... |
62 | 65 |
63 ScopedStyleResolver* ScopedStyleResolver::parent() const | 66 ScopedStyleResolver* ScopedStyleResolver::parent() const |
64 { | 67 { |
65 for (TreeScope* scope = treeScope().parentTreeScope(); scope; scope = scope-
>parentTreeScope()) { | 68 for (TreeScope* scope = treeScope().parentTreeScope(); scope; scope = scope-
>parentTreeScope()) { |
66 if (ScopedStyleResolver* resolver = scope->scopedStyleResolver()) | 69 if (ScopedStyleResolver* resolver = scope->scopedStyleResolver()) |
67 return resolver; | 70 return resolver; |
68 } | 71 } |
69 return 0; | 72 return 0; |
70 } | 73 } |
71 | 74 |
72 unsigned ScopedStyleResolver::appendCSSStyleSheet(CSSStyleSheet* cssSheet) | 75 void ScopedStyleResolver::addKeyframeRules(const RuleSet& ruleSet) |
73 { | 76 { |
74 m_authorStyleSheets.append(cssSheet); | 77 const WillBeHeapVector<RawPtrWillBeMember<StyleRuleKeyframes>> keyframesRule
s = ruleSet.keyframesRules(); |
75 return m_authorStyleSheets.size() - 1; | 78 for (unsigned i = 0; i < keyframesRules.size(); ++i) |
| 79 addKeyframeStyle(keyframesRules[i]); |
| 80 } |
| 81 |
| 82 void ScopedStyleResolver::addFontFaceRules(const RuleSet& ruleSet) |
| 83 { |
| 84 // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets fo
r the moment. |
| 85 if (!treeScope().rootNode().isDocumentNode()) |
| 86 return; |
| 87 |
| 88 Document& document = treeScope().document(); |
| 89 CSSFontSelector* cssFontSelector = document.styleEngine()->fontSelector(); |
| 90 const WillBeHeapVector<RawPtrWillBeMember<StyleRuleFontFace>> fontFaceRules
= ruleSet.fontFaceRules(); |
| 91 for (auto& fontFaceRule : fontFaceRules) { |
| 92 if (RefPtrWillBeRawPtr<FontFace> fontFace = FontFace::create(&document,
fontFaceRule)) |
| 93 cssFontSelector->fontFaceCache()->add(cssFontSelector, fontFaceRule,
fontFace); |
| 94 } |
| 95 if (fontFaceRules.size()) |
| 96 document.styleResolver()->invalidateMatchedPropertiesCache(); |
| 97 } |
| 98 |
| 99 void ScopedStyleResolver::appendCSSStyleSheet(CSSStyleSheet& cssSheet, const Med
iaQueryEvaluator& medium) |
| 100 { |
| 101 unsigned index = m_authorStyleSheets.size(); |
| 102 m_authorStyleSheets.append(&cssSheet); |
| 103 StyleSheetContents* sheet = cssSheet.contents(); |
| 104 AddRuleFlags addRuleFlags = treeScope().document().securityOrigin()->canRequ
est(sheet->baseURL()) ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState; |
| 105 const RuleSet& ruleSet = sheet->ensureRuleSet(medium, addRuleFlags); |
| 106 |
| 107 addKeyframeRules(ruleSet); |
| 108 addFontFaceRules(ruleSet); |
| 109 addTreeBoundaryCrossingRules(ruleSet, &cssSheet, index); |
| 110 treeScope().document().styleResolver()->addMediaQueryResults(ruleSet.viewpor
tDependentMediaQueryResults()); |
76 } | 111 } |
77 | 112 |
78 void ScopedStyleResolver::collectFeaturesTo(RuleFeatureSet& features, HashSet<co
nst StyleSheetContents*>& visitedSharedStyleSheetContents) const | 113 void ScopedStyleResolver::collectFeaturesTo(RuleFeatureSet& features, HashSet<co
nst StyleSheetContents*>& visitedSharedStyleSheetContents) const |
79 { | 114 { |
80 for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) { | 115 for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) { |
81 ASSERT(m_authorStyleSheets[i]->ownerNode()); | 116 ASSERT(m_authorStyleSheets[i]->ownerNode()); |
82 StyleSheetContents* contents = m_authorStyleSheets[i]->contents(); | 117 StyleSheetContents* contents = m_authorStyleSheets[i]->contents(); |
83 if (contents->hasOneClient() || visitedSharedStyleSheetContents.add(cont
ents).isNewEntry) | 118 if (contents->hasOneClient() || visitedSharedStyleSheetContents.add(cont
ents).isNewEntry) |
84 features.add(contents->ruleSet().features()); | 119 features.add(contents->ruleSet().features()); |
85 } | 120 } |
| 121 |
| 122 if (!m_treeBoundaryCrossingRuleSet) |
| 123 return; |
| 124 |
| 125 for (const auto& rules : *m_treeBoundaryCrossingRuleSet) |
| 126 features.add(rules->m_ruleSet->features()); |
86 } | 127 } |
87 | 128 |
88 void ScopedStyleResolver::resetAuthorStyle() | 129 void ScopedStyleResolver::resetAuthorStyle() |
89 { | 130 { |
90 m_authorStyleSheets.clear(); | 131 m_authorStyleSheets.clear(); |
91 m_keyframesRuleMap.clear(); | 132 m_keyframesRuleMap.clear(); |
| 133 m_treeBoundaryCrossingRuleSet = nullptr; |
92 } | 134 } |
93 | 135 |
94 StyleRuleKeyframes* ScopedStyleResolver::keyframeStylesForAnimation(const String
Impl* animationName) | 136 StyleRuleKeyframes* ScopedStyleResolver::keyframeStylesForAnimation(const String
Impl* animationName) |
95 { | 137 { |
96 if (m_keyframesRuleMap.isEmpty()) | 138 if (m_keyframesRuleMap.isEmpty()) |
97 return nullptr; | 139 return nullptr; |
98 | 140 |
99 KeyframesRuleMap::iterator it = m_keyframesRuleMap.find(animationName); | 141 KeyframesRuleMap::iterator it = m_keyframesRuleMap.find(animationName); |
100 if (it == m_keyframesRuleMap.end()) | 142 if (it == m_keyframesRuleMap.end()) |
101 return nullptr; | 143 return nullptr; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 ASSERT(!collector.scopeContainsLastMatchedElement()); | 179 ASSERT(!collector.scopeContainsLastMatchedElement()); |
138 collector.setScopeContainsLastMatchedElement(true); | 180 collector.setScopeContainsLastMatchedElement(true); |
139 for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) { | 181 for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) { |
140 ASSERT(m_authorStyleSheets[i]->ownerNode()); | 182 ASSERT(m_authorStyleSheets[i]->ownerNode()); |
141 MatchRequest matchRequest(&m_authorStyleSheets[i]->contents()->ruleSet()
, includeEmptyRules, &m_scope->rootNode(), m_authorStyleSheets[i], i); | 183 MatchRequest matchRequest(&m_authorStyleSheets[i]->contents()->ruleSet()
, includeEmptyRules, &m_scope->rootNode(), m_authorStyleSheets[i], i); |
142 collector.collectMatchingShadowHostRules(matchRequest, ruleRange, cascad
eOrder); | 184 collector.collectMatchingShadowHostRules(matchRequest, ruleRange, cascad
eOrder); |
143 } | 185 } |
144 collector.setScopeContainsLastMatchedElement(false); | 186 collector.setScopeContainsLastMatchedElement(false); |
145 } | 187 } |
146 | 188 |
| 189 void ScopedStyleResolver::collectMatchingTreeBoundaryCrossingRules(ElementRuleCo
llector& collector, bool includeEmptyRules, CascadeOrder cascadeOrder) |
| 190 { |
| 191 RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange(); |
| 192 for (const auto& rules : *m_treeBoundaryCrossingRuleSet) { |
| 193 MatchRequest request(rules->m_ruleSet.get(), includeEmptyRules, &treeSco
pe().rootNode(), rules->m_parentStyleSheet, rules->m_parentIndex); |
| 194 collector.collectMatchingRules(request, ruleRange, cascadeOrder, true); |
| 195 } |
| 196 } |
| 197 |
147 void ScopedStyleResolver::matchPageRules(PageRuleCollector& collector) | 198 void ScopedStyleResolver::matchPageRules(PageRuleCollector& collector) |
148 { | 199 { |
149 // Only consider the global author RuleSet for @page rules, as per the HTML5
spec. | 200 // Only consider the global author RuleSet for @page rules, as per the HTML5
spec. |
150 ASSERT(m_scope->rootNode().isDocumentNode()); | 201 ASSERT(m_scope->rootNode().isDocumentNode()); |
151 for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) | 202 for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) |
152 collector.matchPageRules(&m_authorStyleSheets[i]->contents()->ruleSet())
; | 203 collector.matchPageRules(&m_authorStyleSheets[i]->contents()->ruleSet())
; |
153 } | 204 } |
154 | 205 |
155 void ScopedStyleResolver::collectViewportRulesTo(StyleResolver* resolver) const | 206 void ScopedStyleResolver::collectViewportRulesTo(StyleResolver* resolver) const |
156 { | 207 { |
157 if (!m_scope->rootNode().isDocumentNode()) | 208 if (!m_scope->rootNode().isDocumentNode()) |
158 return; | 209 return; |
159 for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) | 210 for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) |
160 resolver->viewportStyleResolver()->collectViewportRules(&m_authorStyleSh
eets[i]->contents()->ruleSet(), ViewportStyleResolver::AuthorOrigin); | 211 resolver->viewportStyleResolver()->collectViewportRules(&m_authorStyleSh
eets[i]->contents()->ruleSet(), ViewportStyleResolver::AuthorOrigin); |
161 } | 212 } |
162 | 213 |
163 void ScopedStyleResolver::trace(Visitor* visitor) | 214 void ScopedStyleResolver::trace(Visitor* visitor) |
164 { | 215 { |
165 #if ENABLE(OILPAN) | 216 #if ENABLE(OILPAN) |
166 visitor->trace(m_scope); | 217 visitor->trace(m_scope); |
167 visitor->trace(m_authorStyleSheets); | 218 visitor->trace(m_authorStyleSheets); |
168 visitor->trace(m_keyframesRuleMap); | 219 visitor->trace(m_keyframesRuleMap); |
| 220 visitor->trace(m_treeBoundaryCrossingRuleSet); |
169 #endif | 221 #endif |
170 } | 222 } |
171 | 223 |
| 224 static void addRules(RuleSet* ruleSet, const WillBeHeapVector<MinimalRuleData>&
rules) |
| 225 { |
| 226 for (unsigned i = 0; i < rules.size(); ++i) { |
| 227 const MinimalRuleData& info = rules[i]; |
| 228 ruleSet->addRule(info.m_rule, info.m_selectorIndex, info.m_flags); |
| 229 } |
| 230 } |
| 231 |
| 232 void ScopedStyleResolver::addTreeBoundaryCrossingRules(const RuleSet& authorRule
s, CSSStyleSheet* parentStyleSheet, unsigned sheetIndex) |
| 233 { |
| 234 bool isDocumentScope = treeScope().rootNode().isDocumentNode(); |
| 235 if (authorRules.treeBoundaryCrossingRules().isEmpty() && (isDocumentScope ||
authorRules.shadowDistributedRules().isEmpty())) |
| 236 return; |
| 237 |
| 238 OwnPtrWillBeRawPtr<RuleSet> ruleSetForScope = RuleSet::create(); |
| 239 addRules(ruleSetForScope.get(), authorRules.treeBoundaryCrossingRules()); |
| 240 |
| 241 if (!isDocumentScope) |
| 242 addRules(ruleSetForScope.get(), authorRules.shadowDistributedRules()); |
| 243 |
| 244 if (!m_treeBoundaryCrossingRuleSet) { |
| 245 m_treeBoundaryCrossingRuleSet = adoptPtrWillBeNoop(new CSSStyleSheetRule
SubSet()); |
| 246 treeScope().document().styleResolver()->addTreeBoundaryCrossingScope(tre
eScope().rootNode()); |
| 247 } |
| 248 |
| 249 m_treeBoundaryCrossingRuleSet->append(RuleSubSet::create(parentStyleSheet, s
heetIndex, ruleSetForScope.release())); |
| 250 } |
| 251 |
| 252 void ScopedStyleResolver::RuleSubSet::trace(Visitor* visitor) |
| 253 { |
| 254 visitor->trace(m_ruleSet); |
| 255 } |
| 256 |
172 } // namespace blink | 257 } // namespace blink |
OLD | NEW |