1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org) 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved. 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) 8 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) 9 * Copyright (C) 2011 Google Inc. All rights reserved. 10 * 11 * This library is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Library General Public 13 * License as published by the Free Software Foundation; either 14 * version 2 of the License, or (at your option) any later version. 15 * 16 * This library is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Library General Public License for more details. 20 * 21 * You should have received a copy of the GNU Library General Public License 22 * along with this library; see the file COPYING.LIB. If not, write to 23 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 24 * Boston, MA 02110-1301, USA. 25 * 26 */ 27 28 #ifndef StyleEngine_h 29 #define StyleEngine_h 30 31 #include "core/css/resolver/StyleResolver.h" 32 #include "core/dom/Document.h" 33 #include "core/dom/DocumentOrderedList.h" 34 #include "core/dom/DocumentStyleSheetCollection.h" 35 #include "wtf/FastAllocBase.h" 36 #include "wtf/ListHashSet.h" 37 #include "wtf/RefPtr.h" 38 #include "wtf/TemporaryChange.h" 39 #include "wtf/Vector.h" 40 #include "wtf/text/WTFString.h" 41 42 namespace WebCore { 43 44 class CSSFontSelector; 45 class CSSStyleSheet; 46 class FontSelector; 47 class Node; 48 class RuleFeatureSet; 49 class ShadowTreeStyleSheetCollection; 50 class StyleResolver; 51 class StyleSheet; 52 class StyleSheetCollection; 53 class StyleSheetContents; 54 class StyleSheetList; 55 56 class StyleResolverChange { 57 public: StyleResolverChange()58 StyleResolverChange() 59 : m_needsRepaint(false) 60 , m_needsStyleRecalc(false) 61 { } 62 needsRepaint()63 bool needsRepaint() const { return m_needsRepaint; } needsStyleRecalc()64 bool needsStyleRecalc() const { return m_needsStyleRecalc; } setNeedsRepaint()65 void setNeedsRepaint() { m_needsRepaint = true; } setNeedsStyleRecalc()66 void setNeedsStyleRecalc() { m_needsStyleRecalc = true; } 67 68 private: 69 bool m_needsRepaint; 70 bool m_needsStyleRecalc; 71 }; 72 73 class StyleEngine { 74 WTF_MAKE_FAST_ALLOCATED; 75 public: 76 77 class IgnoringPendingStylesheet : public TemporaryChange<bool> { 78 public: IgnoringPendingStylesheet(StyleEngine * engine)79 IgnoringPendingStylesheet(StyleEngine* engine) 80 : TemporaryChange<bool>(engine->m_ignorePendingStylesheets, true) 81 { 82 } 83 }; 84 85 friend class IgnoringPendingStylesheet; 86 create(Document & document)87 static PassOwnPtr<StyleEngine> create(Document& document) { return adoptPtr(new StyleEngine(document)); } 88 89 ~StyleEngine(); 90 91 const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList(TreeScope&); 92 const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const; 93 documentAuthorStyleSheets()94 const Vector<RefPtr<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; } 95 const Vector<RefPtr<CSSStyleSheet> >& injectedAuthorStyleSheets() const; 96 97 void modifiedStyleSheet(StyleSheet*); 98 void addStyleSheetCandidateNode(Node*, bool createdByParser); 99 void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode = 0); 100 void modifiedStyleSheetCandidateNode(Node*); 101 102 void invalidateInjectedStyleSheetCache(); 103 void updateInjectedStyleSheetCache() const; 104 105 void addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet); 106 needsUpdateActiveStylesheetsOnStyleRecalc()107 bool needsUpdateActiveStylesheetsOnStyleRecalc() const { return m_needsUpdateActiveStylesheetsOnStyleRecalc; } 108 109 void clearMediaQueryRuleSetStyleSheets(); 110 bool updateActiveStyleSheets(StyleResolverUpdateMode); 111 preferredStylesheetSetName()112 String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; } selectedStylesheetSetName()113 String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; } setPreferredStylesheetSetName(const String & name)114 void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; } setSelectedStylesheetSetName(const String & name)115 void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; } 116 117 void addPendingSheet(); 118 enum RemovePendingSheetNotificationType { 119 RemovePendingSheetNotifyImmediately, 120 RemovePendingSheetNotifyLater 121 }; 122 void removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately); 123 hasPendingSheets()124 bool hasPendingSheets() const { return m_pendingStylesheets > 0; } haveStylesheetsLoaded()125 bool haveStylesheetsLoaded() const { return !hasPendingSheets() || m_ignorePendingStylesheets; } ignoringPendingStylesheets()126 bool ignoringPendingStylesheets() const { return m_ignorePendingStylesheets; } 127 maxDirectAdjacentSelectors()128 unsigned maxDirectAdjacentSelectors() const { return m_maxDirectAdjacentSelectors; } usesSiblingRules()129 bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; } setUsesSiblingRulesOverride(bool b)130 void setUsesSiblingRulesOverride(bool b) { m_usesSiblingRulesOverride = b; } usesFirstLineRules()131 bool usesFirstLineRules() const { return m_usesFirstLineRules; } usesFirstLetterRules()132 bool usesFirstLetterRules() const { return m_usesFirstLetterRules; } setUsesFirstLetterRules(bool b)133 void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; } usesRemUnits()134 bool usesRemUnits() const { return m_usesRemUnits; } setUsesRemUnit(bool b)135 void setUsesRemUnit(bool b) { m_usesRemUnits = b; } hasScopedStyleSheet()136 bool hasScopedStyleSheet() { return m_documentStyleSheetCollection.scopingNodesForStyleScoped(); } 137 138 void combineCSSFeatureFlags(const RuleFeatureSet&); 139 void resetCSSFeatureFlags(const RuleFeatureSet&); 140 didModifySeamlessParentStyleSheet()141 void didModifySeamlessParentStyleSheet() { markDocumentDirty(); } 142 void didRemoveShadowRoot(ShadowRoot*); 143 void appendActiveAuthorStyleSheets(); 144 void getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const; 145 resolver()146 StyleResolver* resolver() const 147 { 148 return m_resolver.get(); 149 } 150 ensureResolver()151 StyleResolver& ensureResolver() 152 { 153 if (!m_resolver) { 154 createResolver(); 155 } else if (m_resolver->hasPendingAuthorStyleSheets()) { 156 m_resolver->appendPendingAuthorStyleSheets(); 157 } 158 return *m_resolver.get(); 159 } 160 hasResolver()161 bool hasResolver() const { return m_resolver.get(); } 162 void clearResolver(); 163 void clearMasterResolver(); 164 fontSelector()165 CSSFontSelector* fontSelector() { return m_fontSelector.get(); } 166 void resetFontSelector(); 167 168 void didAttach(); 169 void didDetach(); 170 bool shouldClearResolver() const; 171 StyleResolverChange resolverChanged(RecalcStyleTime, StyleResolverUpdateMode); 172 unsigned resolverAccessCount() const; 173 174 void collectDocumentActiveStyleSheets(StyleSheetCollectionBase&); 175 void markDocumentDirty(); 176 177 private: 178 StyleEngine(Document&); 179 180 StyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope&); 181 StyleSheetCollection* styleSheetCollectionFor(TreeScope&); 182 void activeStyleSheetsUpdatedForInspector(); 183 bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode); 184 void resolverThrowawayTimerFired(Timer<StyleEngine>*); 185 186 void markTreeScopeDirty(TreeScope&); 187 isMaster()188 bool isMaster() const { return m_isMaster; } 189 Document* master(); 190 191 typedef ListHashSet<TreeScope*, 16> TreeScopeSet; 192 static void insertTreeScopeInDocumentOrder(TreeScopeSet&, TreeScope*); 193 void clearMediaQueryRuleSetOnTreeScopeStyleSheets(TreeScopeSet treeScopes); 194 195 void createResolver(); 196 197 void notifyPendingStyleSheetAdded(); 198 void notifyPendingStyleSheetRemoved(RemovePendingSheetNotificationType); 199 200 Document& m_document; 201 bool m_isMaster; 202 203 // Track the number of currently loading top-level stylesheets needed for rendering. 204 // Sheets loaded using the @import directive are not included in this count. 205 // We use this count of pending sheets to detect when we can begin attaching 206 // elements and when it is safe to execute scripts. 207 int m_pendingStylesheets; 208 209 mutable Vector<RefPtr<CSSStyleSheet> > m_injectedAuthorStyleSheets; 210 mutable bool m_injectedStyleSheetCacheValid; 211 212 Vector<RefPtr<CSSStyleSheet> > m_authorStyleSheets; 213 214 bool m_needsUpdateActiveStylesheetsOnStyleRecalc; 215 216 DocumentStyleSheetCollection m_documentStyleSheetCollection; 217 HashMap<TreeScope*, OwnPtr<StyleSheetCollection> > m_styleSheetCollectionMap; 218 219 bool m_documentScopeDirty; 220 TreeScopeSet m_dirtyTreeScopes; 221 TreeScopeSet m_activeTreeScopes; 222 223 String m_preferredStylesheetSetName; 224 String m_selectedStylesheetSetName; 225 226 bool m_usesSiblingRules; 227 bool m_usesSiblingRulesOverride; 228 bool m_usesFirstLineRules; 229 bool m_usesFirstLetterRules; 230 bool m_usesRemUnits; 231 unsigned m_maxDirectAdjacentSelectors; 232 233 bool m_ignorePendingStylesheets; 234 bool m_didCalculateResolver; 235 unsigned m_lastResolverAccessCount; 236 Timer<StyleEngine> m_resolverThrowawayTimer; 237 OwnPtr<StyleResolver> m_resolver; 238 239 RefPtr<CSSFontSelector> m_fontSelector; 240 }; 241 242 } 243 244 #endif 245