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 "platform/heap/Handle.h"
36 #include "wtf/FastAllocBase.h"
37 #include "wtf/ListHashSet.h"
38 #include "wtf/RefPtr.h"
39 #include "wtf/TemporaryChange.h"
40 #include "wtf/Vector.h"
41 #include "wtf/text/WTFString.h"
45 class CSSFontSelector;
50 class ShadowTreeStyleSheetCollection;
52 class StyleRuleFontFace;
54 class StyleSheetCollection;
55 class StyleSheetContents;
58 class StyleResolverChange {
61 : m_needsRepaint(false)
62 , m_needsStyleRecalc(false)
65 bool needsRepaint() const { return m_needsRepaint; }
66 bool needsStyleRecalc() const { return m_needsStyleRecalc; }
67 void setNeedsRepaint() { m_needsRepaint = true; }
68 void setNeedsStyleRecalc() { m_needsStyleRecalc = true; }
72 bool m_needsStyleRecalc;
75 class StyleEngine : public NoBaseWillBeGarbageCollectedFinalized<StyleEngine> {
76 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
79 class IgnoringPendingStylesheet : public TemporaryChange<bool> {
81 IgnoringPendingStylesheet(StyleEngine* engine)
82 : TemporaryChange<bool>(engine->m_ignorePendingStylesheets, true)
87 friend class IgnoringPendingStylesheet;
89 static PassOwnPtrWillBeRawPtr<StyleEngine> create(Document& document) { return adoptPtrWillBeNoop(new StyleEngine(document)); }
94 void detachFromDocument();
97 const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& styleSheetsForStyleSheetList(TreeScope&);
98 const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeAuthorStyleSheets() const;
100 const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
101 const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& injectedAuthorStyleSheets() const;
103 const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> > activeStyleSheetsForInspector() const;
105 void modifiedStyleSheet(StyleSheet*);
106 void addStyleSheetCandidateNode(Node*, bool createdByParser);
107 void removeStyleSheetCandidateNode(Node*);
108 void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode, TreeScope&);
109 void modifiedStyleSheetCandidateNode(Node*);
111 void invalidateInjectedStyleSheetCache();
112 void updateInjectedStyleSheetCache() const;
114 void addAuthorSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> authorSheet);
116 void clearMediaQueryRuleSetStyleSheets();
117 void updateStyleSheetsInImport(DocumentStyleSheetCollector& parentCollector);
118 bool updateActiveStyleSheets(StyleResolverUpdateMode);
120 String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; }
121 String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; }
122 void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; }
123 void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; }
125 void selectStylesheetSetName(const String& name)
127 setPreferredStylesheetSetName(name);
128 setSelectedStylesheetSetName(name);
131 void addPendingSheet();
132 enum RemovePendingSheetNotificationType {
133 RemovePendingSheetNotifyImmediately,
134 RemovePendingSheetNotifyLater
136 void removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
138 bool hasPendingSheets() const { return m_pendingStylesheets > 0; }
139 bool haveStylesheetsLoaded() const { return !hasPendingSheets() || m_ignorePendingStylesheets; }
140 bool ignoringPendingStylesheets() const { return m_ignorePendingStylesheets; }
142 unsigned maxDirectAdjacentSelectors() const { return m_maxDirectAdjacentSelectors; }
143 bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; }
144 void setUsesSiblingRulesOverride(bool b) { m_usesSiblingRulesOverride = b; }
145 bool usesFirstLineRules() const { return m_usesFirstLineRules; }
146 bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
147 void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
148 bool usesRemUnits() const { return m_usesRemUnits; }
149 void setUsesRemUnit(bool b) { m_usesRemUnits = b; }
150 bool hasScopedStyleSheet() { return m_documentStyleSheetCollection.scopingNodesForStyleScoped(); }
152 void combineCSSFeatureFlags(const RuleFeatureSet&);
153 void resetCSSFeatureFlags(const RuleFeatureSet&);
155 void didRemoveShadowRoot(ShadowRoot*);
156 void appendActiveAuthorStyleSheets();
158 StyleResolver* resolver() const
160 return m_resolver.get();
163 StyleResolver& ensureResolver()
167 } else if (m_resolver->hasPendingAuthorStyleSheets()) {
168 m_resolver->appendPendingAuthorStyleSheets();
170 return *m_resolver.get();
173 bool hasResolver() const { return m_resolver.get(); }
174 void clearResolver();
175 void clearMasterResolver();
177 CSSFontSelector* fontSelector() { return m_fontSelector.get(); }
178 void removeFontFaceRules(const WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >&);
179 void clearFontCache();
180 // updateGenericFontFamilySettings is used from WebSettingsImpl.
181 void updateGenericFontFamilySettings();
184 bool shouldClearResolver() const;
185 StyleResolverChange resolverChanged(RecalcStyleTime, StyleResolverUpdateMode);
186 unsigned resolverAccessCount() const;
188 void markDocumentDirty();
190 PassRefPtrWillBeRawPtr<CSSStyleSheet> createSheet(Element*, const String& text, TextPosition startPosition, bool createdByParser);
191 void removeSheet(StyleSheetContents*);
193 void trace(Visitor*);
196 StyleEngine(Document&);
198 TreeScopeStyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope&);
199 TreeScopeStyleSheetCollection* styleSheetCollectionFor(TreeScope&);
200 bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode);
202 void markTreeScopeDirty(TreeScope&);
204 bool isMaster() const { return m_isMaster; }
206 Document& document() const { return *m_document; }
208 typedef ListHashSet<TreeScope*, 16> TreeScopeSet;
209 static void insertTreeScopeInDocumentOrder(TreeScopeSet&, TreeScope*);
210 void clearMediaQueryRuleSetOnTreeScopeStyleSheets(TreeScopeSet treeScopes);
212 void createResolver();
214 static PassRefPtrWillBeRawPtr<CSSStyleSheet> parseSheet(Element*, const String& text, TextPosition startPosition, bool createdByParser);
216 RawPtrWillBeMember<Document> m_document;
219 // Track the number of currently loading top-level stylesheets needed for rendering.
220 // Sheets loaded using the @import directive are not included in this count.
221 // We use this count of pending sheets to detect when we can begin attaching
222 // elements and when it is safe to execute scripts.
223 int m_pendingStylesheets;
225 mutable WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > m_injectedAuthorStyleSheets;
226 mutable bool m_injectedStyleSheetCacheValid;
228 WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > m_authorStyleSheets;
230 DocumentStyleSheetCollection m_documentStyleSheetCollection;
231 typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<TreeScope>, OwnPtrWillBeMember<ShadowTreeStyleSheetCollection> > StyleSheetCollectionMap;
232 StyleSheetCollectionMap m_styleSheetCollectionMap;
234 bool m_documentScopeDirty;
235 TreeScopeSet m_dirtyTreeScopes;
236 TreeScopeSet m_activeTreeScopes;
238 String m_preferredStylesheetSetName;
239 String m_selectedStylesheetSetName;
241 bool m_usesSiblingRules;
242 bool m_usesSiblingRulesOverride;
243 bool m_usesFirstLineRules;
244 bool m_usesFirstLetterRules;
246 unsigned m_maxDirectAdjacentSelectors;
248 bool m_ignorePendingStylesheets;
249 bool m_didCalculateResolver;
250 OwnPtrWillBeMember<StyleResolver> m_resolver;
252 RefPtrWillBeMember<CSSFontSelector> m_fontSelector;
254 WillBeHeapHashMap<AtomicString, RawPtrWillBeMember<StyleSheetContents> > m_textToSheetCache;
255 WillBeHeapHashMap<RawPtrWillBeMember<StyleSheetContents>, AtomicString> m_sheetToTextCache;