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.
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.
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.
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.
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"
44 class CSSFontSelector;
49 class ShadowTreeStyleSheetCollection;
51 class StyleRuleFontFace;
53 class StyleSheetCollection;
54 class StyleSheetContents;
57 class StyleResolverChange {
60 : m_needsRepaint(false)
61 , m_needsStyleRecalc(false)
64 bool needsRepaint() const { return m_needsRepaint; }
65 bool needsStyleRecalc() const { return m_needsStyleRecalc; }
66 void setNeedsRepaint() { m_needsRepaint = true; }
67 void setNeedsStyleRecalc() { m_needsStyleRecalc = true; }
71 bool m_needsStyleRecalc;
75 WTF_MAKE_FAST_ALLOCATED;
78 class IgnoringPendingStylesheet : public TemporaryChange<bool> {
80 IgnoringPendingStylesheet(StyleEngine* engine)
81 : TemporaryChange<bool>(engine->m_ignorePendingStylesheets, true)
86 friend class IgnoringPendingStylesheet;
88 static PassOwnPtr<StyleEngine> create(Document& document) { return adoptPtr(new StyleEngine(document)); }
92 const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList(TreeScope&);
93 const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const;
95 const Vector<RefPtr<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
96 const Vector<RefPtr<CSSStyleSheet> >& injectedAuthorStyleSheets() const;
98 const Vector<RefPtr<StyleSheet> > activeStyleSheetsForInspector() const;
100 void modifiedStyleSheet(StyleSheet*);
101 void addStyleSheetCandidateNode(Node*, bool createdByParser);
102 void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode = 0);
103 void modifiedStyleSheetCandidateNode(Node*);
105 void invalidateInjectedStyleSheetCache();
106 void updateInjectedStyleSheetCache() const;
108 void addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet);
110 void clearMediaQueryRuleSetStyleSheets();
111 void updateStyleSheetsInImport(DocumentStyleSheetCollector& parentCollector);
112 bool updateActiveStyleSheets(StyleResolverUpdateMode);
114 String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; }
115 String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; }
116 void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; }
117 void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; }
119 void selectStylesheetSetName(const String& name)
121 setPreferredStylesheetSetName(name);
122 setSelectedStylesheetSetName(name);
125 void addPendingSheet();
126 enum RemovePendingSheetNotificationType {
127 RemovePendingSheetNotifyImmediately,
128 RemovePendingSheetNotifyLater
130 void removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
132 bool hasPendingSheets() const { return m_pendingStylesheets > 0; }
133 bool haveStylesheetsLoaded() const { return !hasPendingSheets() || m_ignorePendingStylesheets; }
134 bool ignoringPendingStylesheets() const { return m_ignorePendingStylesheets; }
136 unsigned maxDirectAdjacentSelectors() const { return m_maxDirectAdjacentSelectors; }
137 bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; }
138 void setUsesSiblingRulesOverride(bool b) { m_usesSiblingRulesOverride = b; }
139 bool usesFirstLineRules() const { return m_usesFirstLineRules; }
140 bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
141 void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
142 bool usesRemUnits() const { return m_usesRemUnits; }
143 void setUsesRemUnit(bool b) { m_usesRemUnits = b; }
144 bool hasScopedStyleSheet() { return m_documentStyleSheetCollection.scopingNodesForStyleScoped(); }
146 void combineCSSFeatureFlags(const RuleFeatureSet&);
147 void resetCSSFeatureFlags(const RuleFeatureSet&);
149 void didRemoveShadowRoot(ShadowRoot*);
150 void appendActiveAuthorStyleSheets();
152 StyleResolver* resolver() const
154 return m_resolver.get();
157 StyleResolver& ensureResolver()
161 } else if (m_resolver->hasPendingAuthorStyleSheets()) {
162 m_resolver->appendPendingAuthorStyleSheets();
164 return *m_resolver.get();
167 bool hasResolver() const { return m_resolver.get(); }
168 void clearResolver();
169 void clearMasterResolver();
171 CSSFontSelector* fontSelector() { return m_fontSelector.get(); }
172 void removeFontFaceRules(const Vector<const StyleRuleFontFace*>&);
173 void clearFontCache();
174 // updateGenericFontFamilySettings is used from WebSettingsImpl.
175 void updateGenericFontFamilySettings();
178 bool shouldClearResolver() const;
179 StyleResolverChange resolverChanged(RecalcStyleTime, StyleResolverUpdateMode);
180 unsigned resolverAccessCount() const;
182 void markDocumentDirty();
184 static PassRefPtr<CSSStyleSheet> createSheet(Element*, const String& text, TextPosition startPosition, bool createdByParser);
185 static void removeSheet(StyleSheetContents*);
188 StyleEngine(Document&);
190 TreeScopeStyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope&);
191 TreeScopeStyleSheetCollection* styleSheetCollectionFor(TreeScope&);
192 bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode);
194 void markTreeScopeDirty(TreeScope&);
196 bool isMaster() const { return m_isMaster; }
199 typedef ListHashSet<TreeScope*, 16> TreeScopeSet;
200 static void insertTreeScopeInDocumentOrder(TreeScopeSet&, TreeScope*);
201 void clearMediaQueryRuleSetOnTreeScopeStyleSheets(TreeScopeSet treeScopes);
203 void createResolver();
205 void notifyPendingStyleSheetAdded();
206 void notifyPendingStyleSheetRemoved(RemovePendingSheetNotificationType);
208 static PassRefPtr<CSSStyleSheet> parseSheet(Element*, const String& text, TextPosition startPosition, bool createdByParser);
210 Document& m_document;
213 // Track the number of currently loading top-level stylesheets needed for rendering.
214 // Sheets loaded using the @import directive are not included in this count.
215 // We use this count of pending sheets to detect when we can begin attaching
216 // elements and when it is safe to execute scripts.
217 int m_pendingStylesheets;
219 mutable Vector<RefPtr<CSSStyleSheet> > m_injectedAuthorStyleSheets;
220 mutable bool m_injectedStyleSheetCacheValid;
222 Vector<RefPtr<CSSStyleSheet> > m_authorStyleSheets;
224 DocumentStyleSheetCollection m_documentStyleSheetCollection;
225 HashMap<TreeScope*, OwnPtr<TreeScopeStyleSheetCollection> > m_styleSheetCollectionMap;
227 bool m_documentScopeDirty;
228 TreeScopeSet m_dirtyTreeScopes;
229 TreeScopeSet m_activeTreeScopes;
231 String m_preferredStylesheetSetName;
232 String m_selectedStylesheetSetName;
234 bool m_usesSiblingRules;
235 bool m_usesSiblingRulesOverride;
236 bool m_usesFirstLineRules;
237 bool m_usesFirstLetterRules;
239 unsigned m_maxDirectAdjacentSelectors;
241 bool m_ignorePendingStylesheets;
242 bool m_didCalculateResolver;
243 OwnPtr<StyleResolver> m_resolver;
245 RefPtr<CSSFontSelector> m_fontSelector;