1/*
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, 2013 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 DocumentStyleSheetCollection_h
29#define DocumentStyleSheetCollection_h
30
31#include <memory>
32#include <wtf/FastMalloc.h>
33#include <wtf/ListHashSet.h>
34#include <wtf/RefPtr.h>
35#include <wtf/Vector.h>
36#include <wtf/text/WTFString.h>
37
38namespace WebCore {
39
40class CSSStyleSheet;
41class Document;
42class Node;
43class StyleSheet;
44class StyleSheetContents;
45class StyleSheetList;
46
47class DocumentStyleSheetCollection {
48    WTF_MAKE_FAST_ALLOCATED;
49public:
50    explicit DocumentStyleSheetCollection(Document&);
51
52    const Vector<RefPtr<StyleSheet>>& styleSheetsForStyleSheetList() const { return m_styleSheetsForStyleSheetList; }
53
54    const Vector<RefPtr<CSSStyleSheet>>& activeAuthorStyleSheets() const { return m_activeAuthorStyleSheets; }
55
56    CSSStyleSheet* pageUserSheet();
57    const Vector<RefPtr<CSSStyleSheet>>& documentUserStyleSheets() const { return m_userStyleSheets; }
58    const Vector<RefPtr<CSSStyleSheet>>& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
59    const Vector<RefPtr<CSSStyleSheet>>& injectedUserStyleSheets() const;
60    const Vector<RefPtr<CSSStyleSheet>>& injectedAuthorStyleSheets() const;
61
62    void addStyleSheetCandidateNode(Node&, bool createdByParser);
63    void removeStyleSheetCandidateNode(Node&);
64
65    void clearPageUserSheet();
66    void updatePageUserSheet();
67    void invalidateInjectedStyleSheetCache();
68    void updateInjectedStyleSheetCache() const;
69
70    void addAuthorSheet(PassRef<StyleSheetContents> authorSheet);
71    void addUserSheet(PassRef<StyleSheetContents> userSheet);
72
73    enum UpdateFlag { NoUpdate = 0, OptimizedUpdate, FullUpdate };
74
75    UpdateFlag pendingUpdateType() const { return m_pendingUpdateType; }
76    void setPendingUpdateType(UpdateFlag updateType)
77    {
78        if (updateType > m_pendingUpdateType)
79            m_pendingUpdateType = updateType;
80    }
81
82    void flushPendingUpdates()
83    {
84        if (m_pendingUpdateType != NoUpdate)
85            updateActiveStyleSheets(m_pendingUpdateType);
86    }
87
88    bool updateActiveStyleSheets(UpdateFlag);
89
90    String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; }
91    String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; }
92    void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; }
93    void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; }
94
95    void addPendingSheet() { m_pendingStylesheets++; }
96    enum RemovePendingSheetNotificationType {
97        RemovePendingSheetNotifyImmediately,
98        RemovePendingSheetNotifyLater
99    };
100    void removePendingSheet(RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
101
102    bool hasPendingSheets() const { return m_pendingStylesheets > 0; }
103
104    bool usesSiblingRules() const { return m_usesSiblingRules || m_usesSiblingRulesOverride; }
105    void setUsesSiblingRulesOverride(bool b) { m_usesSiblingRulesOverride = b; }
106    bool usesFirstLineRules() const { return m_usesFirstLineRules; }
107    bool usesFirstLetterRules() const { return m_usesFirstLetterRules; }
108    bool usesBeforeAfterRules() const { return m_usesBeforeAfterRules || m_usesBeforeAfterRulesOverride; }
109    void setUsesBeforeAfterRulesOverride(bool b) { m_usesBeforeAfterRulesOverride = b; }
110    bool usesRemUnits() const { return m_usesRemUnits; }
111    void setUsesRemUnit(bool b) { m_usesRemUnits = b; }
112
113    void combineCSSFeatureFlags();
114    void resetCSSFeatureFlags();
115
116    bool activeStyleSheetsContains(const CSSStyleSheet*) const;
117
118    void detachFromDocument();
119
120private:
121    void collectActiveStyleSheets(Vector<RefPtr<StyleSheet>>&);
122    enum StyleResolverUpdateType {
123        Reconstruct,
124        Reset,
125        Additive
126    };
127    void analyzeStyleSheetChange(UpdateFlag, const Vector<RefPtr<CSSStyleSheet>>& newStylesheets, StyleResolverUpdateType&, bool& requiresFullStyleRecalc);
128
129    Document& m_document;
130
131    Vector<RefPtr<StyleSheet>> m_styleSheetsForStyleSheetList;
132    Vector<RefPtr<CSSStyleSheet>> m_activeAuthorStyleSheets;
133
134    // This is a mirror of m_activeAuthorStyleSheets that gets populated on demand for activeStyleSheetsContains().
135    mutable std::unique_ptr<HashSet<const CSSStyleSheet*>> m_weakCopyOfActiveStyleSheetListForFastLookup;
136
137    // Track the number of currently loading top-level stylesheets needed for rendering.
138    // Sheets loaded using the @import directive are not included in this count.
139    // We use this count of pending sheets to detect when we can begin attaching
140    // elements and when it is safe to execute scripts.
141    int m_pendingStylesheets;
142
143    RefPtr<CSSStyleSheet> m_pageUserSheet;
144
145    mutable Vector<RefPtr<CSSStyleSheet>> m_injectedUserStyleSheets;
146    mutable Vector<RefPtr<CSSStyleSheet>> m_injectedAuthorStyleSheets;
147    mutable bool m_injectedStyleSheetCacheValid;
148
149    Vector<RefPtr<CSSStyleSheet>> m_userStyleSheets;
150    Vector<RefPtr<CSSStyleSheet>> m_authorStyleSheets;
151
152    bool m_hadActiveLoadingStylesheet;
153    UpdateFlag m_pendingUpdateType;
154
155    typedef ListHashSet<Node*, 32> StyleSheetCandidateListHashSet;
156    StyleSheetCandidateListHashSet m_styleSheetCandidateNodes;
157
158    String m_preferredStylesheetSetName;
159    String m_selectedStylesheetSetName;
160
161    bool m_usesSiblingRules;
162    bool m_usesSiblingRulesOverride;
163    bool m_usesFirstLineRules;
164    bool m_usesFirstLetterRules;
165    bool m_usesBeforeAfterRules;
166    bool m_usesBeforeAfterRulesOverride;
167    bool m_usesRemUnits;
168};
169
170}
171
172#endif
173
174