| 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 |    6  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All | 
|    7  * rights reserved. |    7  * rights reserved. | 
|    8  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |    8  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 
|    9  * (http://www.torchmobile.com/) |    9  * (http://www.torchmobile.com/) | 
|   10  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |   10  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|   21  * Library General Public License for more details. |   21  * Library General Public License for more details. | 
|   22  * |   22  * | 
|   23  * You should have received a copy of the GNU Library General Public License |   23  * You should have received a copy of the GNU Library General Public License | 
|   24  * along with this library; see the file COPYING.LIB.  If not, write to |   24  * along with this library; see the file COPYING.LIB.  If not, write to | 
|   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 "core/dom/TreeScopeStyleSheetCollection.h" |   29 #include "core/dom/TreeScopeStyleSheetCollection.h" | 
|   30  |   30  | 
 |   31 #include "core/css/ActiveStyleSheets.h" | 
|   31 #include "core/css/CSSStyleSheet.h" |   32 #include "core/css/CSSStyleSheet.h" | 
|   32 #include "core/css/StyleRuleImport.h" |   33 #include "core/css/StyleRuleImport.h" | 
|   33 #include "core/css/StyleSheetContents.h" |   34 #include "core/css/StyleSheetContents.h" | 
|   34 #include "core/css/invalidation/StyleSheetInvalidationAnalysis.h" |  | 
|   35 #include "core/css/resolver/StyleResolver.h" |   35 #include "core/css/resolver/StyleResolver.h" | 
|   36 #include "core/dom/Element.h" |   36 #include "core/dom/Element.h" | 
|   37 #include "core/dom/StyleEngine.h" |   37 #include "core/dom/StyleEngine.h" | 
|   38 #include "core/html/HTMLLinkElement.h" |   38 #include "core/html/HTMLLinkElement.h" | 
|   39 #include "core/html/HTMLStyleElement.h" |   39 #include "core/html/HTMLStyleElement.h" | 
|   40  |   40  | 
|   41 namespace blink { |   41 namespace blink { | 
|   42  |   42  | 
|   43 TreeScopeStyleSheetCollection::TreeScopeStyleSheetCollection( |   43 TreeScopeStyleSheetCollection::TreeScopeStyleSheetCollection( | 
|   44     TreeScope& treeScope) |   44     TreeScope& treeScope) | 
|   45     : m_treeScope(treeScope), m_hadActiveLoadingStylesheet(false) {} |   45     : m_treeScope(treeScope) {} | 
|   46  |   46  | 
|   47 void TreeScopeStyleSheetCollection::addStyleSheetCandidateNode(Node& node) { |   47 void TreeScopeStyleSheetCollection::addStyleSheetCandidateNode(Node& node) { | 
|   48   if (!node.isConnected()) |   48   if (node.isConnected()) | 
|   49     return; |   49     m_styleSheetCandidateNodes.add(&node); | 
|   50  |  | 
|   51   m_styleSheetCandidateNodes.add(&node); |  | 
|   52 } |   50 } | 
|   53  |   51  | 
|   54 TreeScopeStyleSheetCollection::StyleResolverUpdateType |   52 bool TreeScopeStyleSheetCollection::mediaQueryAffectingValueChanged() { | 
|   55 TreeScopeStyleSheetCollection::compareStyleSheets( |   53   bool needsActiveStyleUpdate = false; | 
|   56     const HeapVector<Member<CSSStyleSheet>>& oldStyleSheets, |  | 
|   57     const HeapVector<Member<CSSStyleSheet>>& newStylesheets, |  | 
|   58     HeapVector<Member<StyleSheetContents>>& addedSheets) { |  | 
|   59   unsigned newStyleSheetCount = newStylesheets.size(); |  | 
|   60   unsigned oldStyleSheetCount = oldStyleSheets.size(); |  | 
|   61   DCHECK_GE(newStyleSheetCount, oldStyleSheetCount); |  | 
|   62  |  | 
|   63   if (!newStyleSheetCount) |  | 
|   64     return Reconstruct; |  | 
|   65  |  | 
|   66   unsigned newIndex = 0; |  | 
|   67   for (unsigned oldIndex = 0; oldIndex < oldStyleSheetCount; ++oldIndex) { |  | 
|   68     while (oldStyleSheets[oldIndex] != newStylesheets[newIndex]) { |  | 
|   69       addedSheets.append(newStylesheets[newIndex]->contents()); |  | 
|   70       if (++newIndex == newStyleSheetCount) |  | 
|   71         return Reconstruct; |  | 
|   72     } |  | 
|   73     if (++newIndex == newStyleSheetCount) |  | 
|   74       return Reconstruct; |  | 
|   75   } |  | 
|   76   bool hasInsertions = !addedSheets.isEmpty(); |  | 
|   77   while (newIndex < newStyleSheetCount) { |  | 
|   78     addedSheets.append(newStylesheets[newIndex]->contents()); |  | 
|   79     ++newIndex; |  | 
|   80   } |  | 
|   81   // If all new sheets were added at the end of the list we can just add them to |  | 
|   82   // existing StyleResolver.  If there were insertions we need to re-add all the |  | 
|   83   // stylesheets so rules are ordered correctly. |  | 
|   84   return hasInsertions ? Reset : Additive; |  | 
|   85 } |  | 
|   86  |  | 
|   87 bool TreeScopeStyleSheetCollection::activeLoadingStyleSheetLoaded( |  | 
|   88     const HeapVector<Member<CSSStyleSheet>>& newStyleSheets) { |  | 
|   89   // StyleSheets of <style> elements that @import stylesheets are active but |  | 
|   90   // loading. We need to trigger a full recalc when such loads are done. |  | 
|   91   bool hasActiveLoadingStylesheet = false; |  | 
|   92   unsigned newStylesheetCount = newStyleSheets.size(); |  | 
|   93   for (unsigned i = 0; i < newStylesheetCount; ++i) { |  | 
|   94     if (newStyleSheets[i]->isLoading()) |  | 
|   95       hasActiveLoadingStylesheet = true; |  | 
|   96   } |  | 
|   97   if (m_hadActiveLoadingStylesheet && !hasActiveLoadingStylesheet) { |  | 
|   98     m_hadActiveLoadingStylesheet = false; |  | 
|   99     return true; |  | 
|  100   } |  | 
|  101   m_hadActiveLoadingStylesheet = hasActiveLoadingStylesheet; |  | 
|  102   return false; |  | 
|  103 } |  | 
|  104  |  | 
|  105 static bool findFontFaceRulesFromStyleSheetContents( |  | 
|  106     const HeapVector<Member<StyleSheetContents>>& sheets, |  | 
|  107     HeapVector<Member<const StyleRuleFontFace>>& fontFaceRules) { |  | 
|  108   bool hasFontFaceRule = false; |  | 
|  109  |  | 
|  110   for (unsigned i = 0; i < sheets.size(); ++i) { |  | 
|  111     DCHECK(sheets[i]); |  | 
|  112     if (sheets[i]->hasFontFaceRule()) { |  | 
|  113       // FIXME: We don't need this for styles in shadow tree. |  | 
|  114       sheets[i]->findFontFaceRules(fontFaceRules); |  | 
|  115       hasFontFaceRule = true; |  | 
|  116     } |  | 
|  117   } |  | 
|  118   return hasFontFaceRule; |  | 
|  119 } |  | 
|  120  |  | 
|  121 void TreeScopeStyleSheetCollection::analyzeStyleSheetChange( |  | 
|  122     StyleResolverUpdateMode updateMode, |  | 
|  123     const HeapVector<Member<CSSStyleSheet>>& newActiveAuthorStyleSheets, |  | 
|  124     StyleSheetChange& change) { |  | 
|  125   if (activeLoadingStyleSheetLoaded(newActiveAuthorStyleSheets)) |  | 
|  126     return; |  | 
|  127  |  | 
|  128   if (updateMode != AnalyzedStyleUpdate) |  | 
|  129     return; |  | 
|  130  |  | 
|  131   // Find out which stylesheets are new. |  | 
|  132   HeapVector<Member<StyleSheetContents>> addedSheets; |  | 
|  133   if (m_activeAuthorStyleSheets.size() <= newActiveAuthorStyleSheets.size()) { |  | 
|  134     change.styleResolverUpdateType = compareStyleSheets( |  | 
|  135         m_activeAuthorStyleSheets, newActiveAuthorStyleSheets, addedSheets); |  | 
|  136   } else { |  | 
|  137     StyleResolverUpdateType updateType = compareStyleSheets( |  | 
|  138         newActiveAuthorStyleSheets, m_activeAuthorStyleSheets, addedSheets); |  | 
|  139     if (updateType != Additive) { |  | 
|  140       change.styleResolverUpdateType = updateType; |  | 
|  141     } else { |  | 
|  142       change.styleResolverUpdateType = Reset; |  | 
|  143       // If @font-face is removed, needs full style recalc. |  | 
|  144       if (findFontFaceRulesFromStyleSheetContents(addedSheets, |  | 
|  145                                                   change.fontFaceRulesToRemove)) |  | 
|  146         return; |  | 
|  147     } |  | 
|  148   } |  | 
|  149  |  | 
|  150   // FIXME: If styleResolverUpdateType is Reconstruct, we should return early |  | 
|  151   // here since we need to recalc the whole document. It's wrong to use |  | 
|  152   // StyleSheetInvalidationAnalysis since it only looks at the addedSheets. |  | 
|  153  |  | 
|  154   // No point in doing the analysis work if we're just going to recalc the whole |  | 
|  155   // document anyways.  This needs to be done after the compareStyleSheets calls |  | 
|  156   // above to ensure we don't throw away the StyleResolver if we don't need to. |  | 
|  157   if (document().hasPendingForcedStyleRecalc()) |  | 
|  158     return; |  | 
|  159  |  | 
|  160   // If we are already parsing the body and so may have significant amount of |  | 
|  161   // elements, put some effort into trying to avoid style recalcs. |  | 
|  162   if (!document().body() || document().hasNodesWithPlaceholderStyle()) |  | 
|  163     return; |  | 
|  164   StyleSheetInvalidationAnalysis invalidationAnalysis(*m_treeScope, |  | 
|  165                                                       addedSheets); |  | 
|  166   if (invalidationAnalysis.dirtiesAllStyle()) |  | 
|  167     return; |  | 
|  168   invalidationAnalysis.invalidateStyle(); |  | 
|  169   change.requiresFullStyleRecalc = false; |  | 
|  170   return; |  | 
|  171 } |  | 
|  172  |  | 
|  173 void TreeScopeStyleSheetCollection::clearMediaQueryRuleSetStyleSheets() { |  | 
|  174   for (size_t i = 0; i < m_activeAuthorStyleSheets.size(); ++i) { |   54   for (size_t i = 0; i < m_activeAuthorStyleSheets.size(); ++i) { | 
|  175     StyleSheetContents* contents = m_activeAuthorStyleSheets[i]->contents(); |   55     if (m_activeAuthorStyleSheets[i].first->mediaQueries()) | 
 |   56       needsActiveStyleUpdate = true; | 
 |   57     StyleSheetContents* contents = | 
 |   58         m_activeAuthorStyleSheets[i].first->contents(); | 
|  176     if (contents->hasMediaQueries()) |   59     if (contents->hasMediaQueries()) | 
|  177       contents->clearRuleSet(); |   60       contents->clearRuleSet(); | 
|  178   } |   61   } | 
 |   62   return needsActiveStyleUpdate; | 
 |   63 } | 
 |   64  | 
 |   65 void TreeScopeStyleSheetCollection::applyActiveStyleSheetChanges( | 
 |   66     StyleSheetCollection& newCollection) { | 
 |   67   document().styleEngine().applyRuleSetChanges( | 
 |   68       treeScope(), activeAuthorStyleSheets(), | 
 |   69       newCollection.activeAuthorStyleSheets()); | 
 |   70   newCollection.swap(*this); | 
|  179 } |   71 } | 
|  180  |   72  | 
|  181 DEFINE_TRACE(TreeScopeStyleSheetCollection) { |   73 DEFINE_TRACE(TreeScopeStyleSheetCollection) { | 
|  182   visitor->trace(m_treeScope); |   74   visitor->trace(m_treeScope); | 
|  183   visitor->trace(m_styleSheetCandidateNodes); |   75   visitor->trace(m_styleSheetCandidateNodes); | 
|  184   StyleSheetCollection::trace(visitor); |   76   StyleSheetCollection::trace(visitor); | 
|  185 } |   77 } | 
|  186  |   78  | 
|  187 }  // namespace blink |   79 }  // namespace blink | 
| OLD | NEW |