OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All r
ights reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All r
ights reserved. |
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) | 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) |
8 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 8 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
9 * Copyright (C) 2013 Google Inc. All rights reserved. | 9 * Copyright (C) 2013 Google Inc. All rights reserved. |
10 * | 10 * |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 if (++newIndex == newStyleSheetCount) | 126 if (++newIndex == newStyleSheetCount) |
127 return Reconstruct; | 127 return Reconstruct; |
128 } | 128 } |
129 bool hasInsertions = !addedSheets.isEmpty(); | 129 bool hasInsertions = !addedSheets.isEmpty(); |
130 while (newIndex < newStyleSheetCount) { | 130 while (newIndex < newStyleSheetCount) { |
131 addedSheets.append(newStylesheets[newIndex]->contents()); | 131 addedSheets.append(newStylesheets[newIndex]->contents()); |
132 ++newIndex; | 132 ++newIndex; |
133 } | 133 } |
134 // If all new sheets were added at the end of the list we can just add them
to existing StyleResolver. | 134 // If all new sheets were added at the end of the list we can just add them
to existing StyleResolver. |
135 // If there were insertions we need to re-add all the stylesheets so rules a
re ordered correctly. | 135 // If there were insertions we need to re-add all the stylesheets so rules a
re ordered correctly. |
136 return hasInsertions ? Reset : Additive; | 136 return hasInsertions ? Reconstruct : Additive; |
137 } | 137 } |
138 | 138 |
139 bool StyleSheetCollection::activeLoadingStyleSheetLoaded(const Vector<RefPtr<CSS
StyleSheet> >& newStyleSheets) | 139 bool StyleSheetCollection::activeLoadingStyleSheetLoaded(const Vector<RefPtr<CSS
StyleSheet> >& newStyleSheets) |
140 { | 140 { |
141 // StyleSheets of <style> elements that @import stylesheets are active but l
oading. We need to trigger a full recalc when such loads are done. | 141 // StyleSheets of <style> elements that @import stylesheets are active but l
oading. We need to trigger a full recalc when such loads are done. |
142 bool hasActiveLoadingStylesheet = false; | 142 bool hasActiveLoadingStylesheet = false; |
143 unsigned newStylesheetCount = newStyleSheets.size(); | 143 unsigned newStylesheetCount = newStyleSheets.size(); |
144 for (unsigned i = 0; i < newStylesheetCount; ++i) { | 144 for (unsigned i = 0; i < newStylesheetCount; ++i) { |
145 if (newStyleSheets[i]->isLoading()) | 145 if (newStyleSheets[i]->isLoading()) |
146 hasActiveLoadingStylesheet = true; | 146 hasActiveLoadingStylesheet = true; |
147 } | 147 } |
148 if (m_hadActiveLoadingStylesheet && !hasActiveLoadingStylesheet) { | 148 if (m_hadActiveLoadingStylesheet && !hasActiveLoadingStylesheet) { |
149 m_hadActiveLoadingStylesheet = false; | 149 m_hadActiveLoadingStylesheet = false; |
150 return true; | 150 return true; |
151 } | 151 } |
152 m_hadActiveLoadingStylesheet = hasActiveLoadingStylesheet; | 152 m_hadActiveLoadingStylesheet = hasActiveLoadingStylesheet; |
153 return false; | 153 return false; |
154 } | 154 } |
155 | 155 |
156 static bool styleSheetContentsHasFontFaceRule(Vector<StyleSheetContents*> sheets
) | |
157 { | |
158 for (unsigned i = 0; i < sheets.size(); ++i) { | |
159 ASSERT(sheets[i]); | |
160 if (sheets[i]->hasFontFaceRule()) | |
161 return true; | |
162 } | |
163 return false; | |
164 } | |
165 | |
166 static bool cssStyleSheetHasFontFaceRule(const Vector<RefPtr<CSSStyleSheet> > sh
eets) | |
167 { | |
168 for (unsigned i = 0; i < sheets.size(); ++i) { | |
169 ASSERT(sheets[i]); | |
170 if (sheets[i]->contents()->hasFontFaceRule()) | |
171 return true; | |
172 } | |
173 return false; | |
174 } | |
175 | |
176 void StyleSheetCollection::analyzeStyleSheetChange(StyleResolverUpdateMode updat
eMode, const StyleSheetCollectionBase& newCollection, StyleSheetChange& change) | 156 void StyleSheetCollection::analyzeStyleSheetChange(StyleResolverUpdateMode updat
eMode, const StyleSheetCollectionBase& newCollection, StyleSheetChange& change) |
177 { | 157 { |
178 if (activeLoadingStyleSheetLoaded(newCollection.activeAuthorStyleSheets())) | 158 if (activeLoadingStyleSheetLoaded(newCollection.activeAuthorStyleSheets())) |
179 return; | 159 return; |
180 | 160 |
181 if (updateMode != AnalyzedStyleUpdate) | 161 if (updateMode != AnalyzedStyleUpdate) |
182 return; | 162 return; |
183 | 163 |
184 // Find out which stylesheets are new. | 164 // Find out which stylesheets are new. |
185 Vector<StyleSheetContents*> addedSheets; | 165 Vector<StyleSheetContents*> addedSheets; |
186 if (m_activeAuthorStyleSheets.size() <= newCollection.activeAuthorStyleSheet
s().size()) { | 166 if (m_activeAuthorStyleSheets.size() <= newCollection.activeAuthorStyleSheet
s().size()) |
187 change.styleResolverUpdateType = compareStyleSheets(m_activeAuthorStyleS
heets, newCollection.activeAuthorStyleSheets(), addedSheets); | 167 change.styleResolverUpdateType = compareStyleSheets(m_activeAuthorStyleS
heets, newCollection.activeAuthorStyleSheets(), addedSheets); |
188 } else { | 168 else |
189 StyleResolverUpdateType updateType = compareStyleSheets(newCollection.ac
tiveAuthorStyleSheets(), m_activeAuthorStyleSheets, addedSheets); | 169 compareStyleSheets(newCollection.activeAuthorStyleSheets(), m_activeAuth
orStyleSheets, addedSheets); |
190 if (updateType != Additive) { | |
191 change.styleResolverUpdateType = updateType; | |
192 } else { | |
193 if (styleSheetContentsHasFontFaceRule(addedSheets)) { | |
194 change.styleResolverUpdateType = ResetStyleResolverAndFontSelect
or; | |
195 return; | |
196 } | |
197 // FIXME: since currently all stylesheets are re-added after resetin
g styleresolver, | |
198 // fontSelector should be always reset. After creating RuleSet for e
ach StyleSheetContents, | |
199 // we can avoid appending all stylesheetcontents in reset case. | |
200 // So we can remove "styleSheetContentsHasFontFaceRule(newSheets)". | |
201 if (cssStyleSheetHasFontFaceRule(newCollection.activeAuthorStyleShee
ts())) | |
202 change.styleResolverUpdateType = ResetStyleResolverAndFontSelect
or; | |
203 else | |
204 change.styleResolverUpdateType = Reset; | |
205 } | |
206 } | |
207 | |
208 // FIXME: If styleResolverUpdateType is Reconstruct, we should return early
here since | |
209 // we need to recalc the whole document. It's wrong to use StyleInvalidation
Analysis since | |
210 // it only looks at the addedSheets. | |
211 | 170 |
212 // If we are already parsing the body and so may have significant amount of
elements, put some effort into trying to avoid style recalcs. | 171 // If we are already parsing the body and so may have significant amount of
elements, put some effort into trying to avoid style recalcs. |
213 if (!document()->body() || document()->hasNodesWithPlaceholderStyle()) | 172 if (!document()->body() || document()->hasNodesWithPlaceholderStyle()) |
214 return; | 173 return; |
215 StyleInvalidationAnalysis invalidationAnalysis(addedSheets); | 174 StyleInvalidationAnalysis invalidationAnalysis(addedSheets); |
216 if (invalidationAnalysis.dirtiesAllStyle()) | 175 if (invalidationAnalysis.dirtiesAllStyle()) |
217 return; | 176 return; |
218 invalidationAnalysis.invalidateStyle(*document()); | 177 invalidationAnalysis.invalidateStyle(*document()); |
219 change.requiresFullStyleRecalc = false; | 178 change.requiresFullStyleRecalc = false; |
220 return; | 179 return; |
221 } | 180 } |
222 | 181 |
223 void StyleSheetCollection::clearMediaQueryRuleSetStyleSheets() | 182 void StyleSheetCollection::clearMediaQueryRuleSetStyleSheets() |
224 { | 183 { |
225 for (size_t i = 0; i < m_activeAuthorStyleSheets.size(); ++i) { | 184 for (size_t i = 0; i < m_activeAuthorStyleSheets.size(); ++i) { |
226 StyleSheetContents* contents = m_activeAuthorStyleSheets[i]->contents(); | 185 StyleSheetContents* contents = m_activeAuthorStyleSheets[i]->contents(); |
227 if (contents->hasMediaQueries()) | 186 if (contents->hasMediaQueries()) |
228 contents->clearRuleSet(); | 187 contents->clearRuleSet(); |
229 } | 188 } |
230 } | 189 } |
231 | 190 |
232 void StyleSheetCollection::resetAllRuleSetsInTreeScope(StyleResolver* styleResol
ver) | |
233 { | |
234 // FIXME: If many web developers use style scoped, implement reset RuleSets
in per-scoping node manner. | |
235 if (DocumentOrderedList* styleScopedScopingNodes = scopingNodesForStyleScope
d()) { | |
236 for (DocumentOrderedList::iterator it = styleScopedScopingNodes->begin()
; it != styleScopedScopingNodes->end(); ++it) | |
237 styleResolver->resetAuthorStyle(toContainerNode(*it)); | |
238 } | |
239 if (ListHashSet<Node*, 4>* removedNodes = scopingNodesRemoved()) { | |
240 for (ListHashSet<Node*, 4>::iterator it = removedNodes->begin(); it != r
emovedNodes->end(); ++it) | |
241 styleResolver->resetAuthorStyle(toContainerNode(*it)); | |
242 } | |
243 styleResolver->resetAuthorStyle(toContainerNode(m_treeScope.rootNode())); | |
244 } | |
245 | |
246 static bool styleSheetsUseRemUnits(const Vector<RefPtr<CSSStyleSheet> >& sheets) | 191 static bool styleSheetsUseRemUnits(const Vector<RefPtr<CSSStyleSheet> >& sheets) |
247 { | 192 { |
248 for (unsigned i = 0; i < sheets.size(); ++i) { | 193 for (unsigned i = 0; i < sheets.size(); ++i) { |
249 if (sheets[i]->contents()->usesRemUnits()) | 194 if (sheets[i]->contents()->usesRemUnits()) |
250 return true; | 195 return true; |
251 } | 196 } |
252 return false; | 197 return false; |
253 } | 198 } |
254 | 199 |
255 void StyleSheetCollection::updateUsesRemUnits() | 200 void StyleSheetCollection::updateUsesRemUnits() |
256 { | 201 { |
257 m_usesRemUnits = styleSheetsUseRemUnits(m_activeAuthorStyleSheets); | 202 m_usesRemUnits = styleSheetsUseRemUnits(m_activeAuthorStyleSheets); |
258 } | 203 } |
259 | 204 |
| 205 bool StyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine, StyleRes
olverUpdateMode updateMode) |
| 206 { |
| 207 StyleSheetCollectionBase collection; |
| 208 collectStyleSheets(engine, collection); |
| 209 |
| 210 StyleSheetChange change; |
| 211 analyzeStyleSheetChange(updateMode, collection, change); |
| 212 |
| 213 if (change.styleResolverUpdateType == Reconstruct) { |
| 214 engine->clearResolver(); |
| 215 } else if (StyleResolver* styleResolver = engine->resolverIfExists()) { |
| 216 ASSERT(change.styleResolverUpdateType == Additive); |
| 217 // FIXME: We might have already had styles in child treescope. In this c
ase, we cannot use buildScopedStyleTreeInDocumentOrder. |
| 218 // Need to change "false" to some valid condition. |
| 219 styleResolver->setBuildScopedStyleTreeInDocumentOrder(false); |
| 220 styleResolver->lazyAppendAuthorStyleSheets(m_activeAuthorStyleSheets.siz
e(), collection.activeAuthorStyleSheets()); |
| 221 } |
| 222 |
| 223 m_scopingNodesForStyleScoped.didRemoveScopingNodes(); |
| 224 collection.swap(*this); |
| 225 updateUsesRemUnits(); |
| 226 |
| 227 return change.requiresFullStyleRecalc; |
260 } | 228 } |
| 229 |
| 230 } |
OLD | NEW |