Home | History | Annotate | Download | only in dom
      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/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:
     58     StyleResolverChange()
     59         : m_needsRepaint(false)
     60         , m_needsStyleRecalc(false)
     61     { }
     62 
     63     bool needsRepaint() const { return m_needsRepaint; }
     64     bool needsStyleRecalc() const { return m_needsStyleRecalc; }
     65     void setNeedsRepaint() { m_needsRepaint = true; }
     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:
     79         IgnoringPendingStylesheet(StyleEngine* engine)
     80             : TemporaryChange<bool>(engine->m_ignorePendingStylesheets, true)
     81         {
     82         }
     83     };
     84 
     85     friend class IgnoringPendingStylesheet;
     86 
     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 
     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 
    107     bool needsUpdateActiveStylesheetsOnStyleRecalc() const { return m_needsUpdateActiveStylesheetsOnStyleRecalc; }
    108 
    109     void clearMediaQueryRuleSetStyleSheets();
    110     bool updateActiveStyleSheets(StyleResolverUpdateMode);
    111 
    112     String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; }
    113     String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; }
    114     void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = 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 
    124     bool hasPendingSheets() const { return m_pendingStylesheets > 0; }
    125     bool haveStylesheetsLoaded() const { return !hasPendingSheets() || m_ignorePendingStylesheets; }
    126     bool ignoringPendingStylesheets() const { return m_ignorePendingStylesheets; }
    127 
    128     unsigned maxDirectAdjacentSelectors() const { return m_maxDirectAdjacentSelectors; }
    129     bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; }
    130     void setUsesSiblingRulesOverride(bool b) { m_usesSiblingRulesOverride = b; }
    131     bool usesFirstLineRules() const { return m_usesFirstLineRules; }
    132     bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
    133     void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
    134     bool usesRemUnits() const { return m_usesRemUnits; }
    135     void setUsesRemUnit(bool b) { m_usesRemUnits = b; }
    136     bool hasScopedStyleSheet() { return m_documentStyleSheetCollection.scopingNodesForStyleScoped(); }
    137 
    138     void combineCSSFeatureFlags(const RuleFeatureSet&);
    139     void resetCSSFeatureFlags(const RuleFeatureSet&);
    140 
    141     void didModifySeamlessParentStyleSheet() { markDocumentDirty(); }
    142     void didRemoveShadowRoot(ShadowRoot*);
    143     void appendActiveAuthorStyleSheets();
    144     void getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const;
    145 
    146     StyleResolver* resolver() const
    147     {
    148         return m_resolver.get();
    149     }
    150 
    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 
    161     bool hasResolver() const { return m_resolver.get(); }
    162     void clearResolver();
    163     void clearMasterResolver();
    164 
    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 
    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