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