| 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 |