• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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