1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 1999 Antti Koivisto (koivisto (at) kde.org) 4 * (C) 2001 Dirk Mueller (mueller (at) kde.org) 5 * (C) 2006 Alexey Proskuryakov (ap (at) 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/CSSFontSelectorClient.h" 32 #include "core/css/resolver/StyleResolver.h" 33 #include "core/dom/Document.h" 34 #include "core/dom/DocumentOrderedList.h" 35 #include "core/dom/DocumentStyleSheetCollection.h" 36 #include "platform/heap/Handle.h" 37 #include "wtf/FastAllocBase.h" 38 #include "wtf/ListHashSet.h" 39 #include "wtf/RefPtr.h" 40 #include "wtf/TemporaryChange.h" 41 #include "wtf/Vector.h" 42 #include "wtf/text/WTFString.h" 43 44 namespace blink { 45 46 class CSSFontSelector; 47 class CSSStyleSheet; 48 class Node; 49 class RuleFeatureSet; 50 class ShadowTreeStyleSheetCollection; 51 class StyleRuleFontFace; 52 class StyleSheet; 53 class StyleSheetContents; 54 55 class StyleEngine FINAL : public CSSFontSelectorClient { 56 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; 57 public: 58 59 class IgnoringPendingStylesheet : public TemporaryChange<bool> { 60 public: 61 IgnoringPendingStylesheet(StyleEngine* engine) 62 : TemporaryChange<bool>(engine->m_ignorePendingStylesheets, true) 63 { 64 } 65 }; 66 67 friend class IgnoringPendingStylesheet; 68 69 static PassOwnPtrWillBeRawPtr<StyleEngine> create(Document& document) { return adoptPtrWillBeNoop(new StyleEngine(document)); } 70 71 ~StyleEngine(); 72 73 #if !ENABLE(OILPAN) 74 void detachFromDocument(); 75 #endif 76 77 const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& styleSheetsForStyleSheetList(TreeScope&); 78 const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeAuthorStyleSheets() const; 79 80 const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; } 81 const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& injectedAuthorStyleSheets() const; 82 83 const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > activeStyleSheetsForInspector() const; 84 85 void modifiedStyleSheet(StyleSheet*); 86 void addStyleSheetCandidateNode(Node*, bool createdByParser); 87 void removeStyleSheetCandidateNode(Node*); 88 void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode, TreeScope&); 89 void modifiedStyleSheetCandidateNode(Node*); 90 void enableExitTransitionStylesheets(); 91 void addXSLStyleSheet(ProcessingInstruction*, bool createdByParser); 92 void removeXSLStyleSheet(ProcessingInstruction*); 93 94 void invalidateInjectedStyleSheetCache(); 95 void updateInjectedStyleSheetCache() const; 96 97 void compatibilityModeChanged(); 98 99 void addAuthorSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> authorSheet); 100 101 void clearMediaQueryRuleSetStyleSheets(); 102 void updateStyleSheetsInImport(DocumentStyleSheetCollector& parentCollector); 103 void updateActiveStyleSheets(StyleResolverUpdateMode); 104 105 String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; } 106 String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; } 107 void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; } 108 void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; } 109 110 void selectStylesheetSetName(const String& name) 111 { 112 setPreferredStylesheetSetName(name); 113 setSelectedStylesheetSetName(name); 114 } 115 116 void addPendingSheet(); 117 void removePendingSheet(Node* styleSheetCandidateNode); 118 119 bool hasPendingSheets() const { return m_pendingStylesheets > 0; } 120 bool haveStylesheetsLoaded() const { return !hasPendingSheets() || m_ignorePendingStylesheets; } 121 bool ignoringPendingStylesheets() const { return m_ignorePendingStylesheets; } 122 123 unsigned maxDirectAdjacentSelectors() const { return m_maxDirectAdjacentSelectors; } 124 bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; } 125 void setUsesSiblingRulesOverride(bool b) { m_usesSiblingRulesOverride = b; } 126 bool usesFirstLineRules() const { return m_usesFirstLineRules; } 127 bool usesFirstLetterRules() const { return m_usesFirstLetterRules; } 128 void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; } 129 bool usesRemUnits() const { return m_usesRemUnits; } 130 void setUsesRemUnit(bool b) { m_usesRemUnits = b; } 131 132 void combineCSSFeatureFlags(const RuleFeatureSet&); 133 void resetCSSFeatureFlags(const RuleFeatureSet&); 134 135 void didRemoveShadowRoot(ShadowRoot*); 136 void appendActiveAuthorStyleSheets(); 137 138 StyleResolver* resolver() const 139 { 140 return m_resolver.get(); 141 } 142 143 StyleResolver& ensureResolver() 144 { 145 if (!m_resolver) { 146 createResolver(); 147 } else if (m_resolver->hasPendingAuthorStyleSheets()) { 148 m_resolver->appendPendingAuthorStyleSheets(); 149 } 150 return *m_resolver.get(); 151 } 152 153 bool hasResolver() const { return m_resolver.get(); } 154 void clearResolver(); 155 void clearMasterResolver(); 156 157 CSSFontSelector* fontSelector() { return m_fontSelector.get(); } 158 void removeFontFaceRules(const WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >&); 159 void clearFontCache(); 160 // updateGenericFontFamilySettings is used from WebSettingsImpl. 161 void updateGenericFontFamilySettings(); 162 163 void didDetach(); 164 bool shouldClearResolver() const; 165 void resolverChanged(StyleResolverUpdateMode); 166 unsigned resolverAccessCount() const; 167 168 void markDocumentDirty(); 169 170 PassRefPtrWillBeRawPtr<CSSStyleSheet> createSheet(Element*, const String& text, TextPosition startPosition, bool createdByParser); 171 void removeSheet(StyleSheetContents*); 172 173 void addScopedStyleResolver(const ScopedStyleResolver* resolver) { m_scopedStyleResolvers.add(resolver); } 174 void removeScopedStyleResolver(const ScopedStyleResolver* resolver) { m_scopedStyleResolvers.remove(resolver); } 175 bool hasOnlyScopedResolverForDocument() const { return m_scopedStyleResolvers.size() == 1; } 176 void collectScopedStyleFeaturesTo(RuleFeatureSet&) const; 177 178 virtual void trace(Visitor*) OVERRIDE; 179 180 private: 181 // CSSFontSelectorClient implementation. 182 virtual void fontsNeedUpdate(CSSFontSelector*) OVERRIDE; 183 184 private: 185 StyleEngine(Document&); 186 187 TreeScopeStyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope&); 188 TreeScopeStyleSheetCollection* styleSheetCollectionFor(TreeScope&); 189 bool shouldUpdateDocumentStyleSheetCollection(StyleResolverUpdateMode) const; 190 bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode) const; 191 bool shouldApplyXSLTransform() const; 192 193 void markTreeScopeDirty(TreeScope&); 194 195 bool isMaster() const { return m_isMaster; } 196 Document* master(); 197 Document& document() const { return *m_document; } 198 199 typedef ListHashSet<TreeScope*, 16> TreeScopeSet; 200 static void insertTreeScopeInDocumentOrder(TreeScopeSet&, TreeScope*); 201 void clearMediaQueryRuleSetOnTreeScopeStyleSheets(TreeScopeSet treeScopes); 202 203 void createResolver(); 204 205 static PassRefPtrWillBeRawPtr<CSSStyleSheet> parseSheet(Element*, const String& text, TextPosition startPosition, bool createdByParser); 206 207 const DocumentStyleSheetCollection* documentStyleSheetCollection() const 208 { 209 return m_documentStyleSheetCollection.get(); 210 } 211 212 DocumentStyleSheetCollection* documentStyleSheetCollection() 213 { 214 return m_documentStyleSheetCollection.get(); 215 } 216 217 RawPtrWillBeMember<Document> m_document; 218 bool m_isMaster; 219 220 // Track the number of currently loading top-level stylesheets needed for rendering. 221 // Sheets loaded using the @import directive are not included in this count. 222 // We use this count of pending sheets to detect when we can begin attaching 223 // elements and when it is safe to execute scripts. 224 int m_pendingStylesheets; 225 226 mutable WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > m_injectedAuthorStyleSheets; 227 mutable bool m_injectedStyleSheetCacheValid; 228 229 WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > m_authorStyleSheets; 230 231 OwnPtrWillBeMember<DocumentStyleSheetCollection> m_documentStyleSheetCollection; 232 233 typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<TreeScope>, OwnPtrWillBeMember<ShadowTreeStyleSheetCollection> > StyleSheetCollectionMap; 234 StyleSheetCollectionMap m_styleSheetCollectionMap; 235 typedef WillBeHeapHashSet<RawPtrWillBeMember<const ScopedStyleResolver> > ScopedStyleResolverSet; 236 ScopedStyleResolverSet m_scopedStyleResolvers; 237 238 bool m_documentScopeDirty; 239 TreeScopeSet m_dirtyTreeScopes; 240 TreeScopeSet m_activeTreeScopes; 241 242 String m_preferredStylesheetSetName; 243 String m_selectedStylesheetSetName; 244 245 bool m_usesSiblingRules; 246 bool m_usesSiblingRulesOverride; 247 bool m_usesFirstLineRules; 248 bool m_usesFirstLetterRules; 249 bool m_usesRemUnits; 250 unsigned m_maxDirectAdjacentSelectors; 251 252 bool m_ignorePendingStylesheets; 253 bool m_didCalculateResolver; 254 OwnPtrWillBeMember<StyleResolver> m_resolver; 255 256 RefPtrWillBeMember<CSSFontSelector> m_fontSelector; 257 258 WillBeHeapHashMap<AtomicString, RawPtrWillBeMember<StyleSheetContents> > m_textToSheetCache; 259 WillBeHeapHashMap<RawPtrWillBeMember<StyleSheetContents>, AtomicString> m_sheetToTextCache; 260 261 RefPtrWillBeMember<ProcessingInstruction> m_xslStyleSheet; 262 }; 263 264 } 265 266 #endif 267