1/*
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB.  If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#ifndef CSSStyleSheet_h
22#define CSSStyleSheet_h
23
24#include "CSSParserMode.h"
25#include "CSSRule.h"
26#include "StyleSheet.h"
27#include <memory>
28#include <wtf/HashMap.h>
29#include <wtf/Noncopyable.h>
30#include <wtf/text/AtomicStringHash.h>
31
32namespace WebCore {
33
34class CSSCharsetRule;
35class CSSImportRule;
36class CSSParser;
37class CSSRule;
38class CSSRuleList;
39class CSSStyleSheet;
40class CachedCSSStyleSheet;
41class Document;
42class MediaQuerySet;
43class SecurityOrigin;
44class StyleRuleKeyframes;
45class StyleSheetContents;
46
47typedef int ExceptionCode;
48
49class CSSStyleSheet final : public StyleSheet {
50public:
51    static PassRef<CSSStyleSheet> create(PassRef<StyleSheetContents>, CSSImportRule* ownerRule = 0);
52    static PassRef<CSSStyleSheet> create(PassRef<StyleSheetContents>, Node* ownerNode);
53    static PassRef<CSSStyleSheet> createInline(Node&, const URL&, const String& encoding = String());
54
55    virtual ~CSSStyleSheet();
56
57    virtual CSSStyleSheet* parentStyleSheet() const override;
58    virtual Node* ownerNode() const override { return m_ownerNode; }
59    virtual MediaList* media() const override;
60    virtual String href() const override;
61    virtual String title() const override { return m_title; }
62    virtual bool disabled() const override { return m_isDisabled; }
63    virtual void setDisabled(bool) override;
64
65    PassRefPtr<CSSRuleList> cssRules();
66    unsigned insertRule(const String& rule, unsigned index, ExceptionCode&);
67    void deleteRule(unsigned index, ExceptionCode&);
68
69    // IE Extensions
70    PassRefPtr<CSSRuleList> rules();
71    int addRule(const String& selector, const String& style, int index, ExceptionCode&);
72    int addRule(const String& selector, const String& style, ExceptionCode&);
73    void removeRule(unsigned index, ExceptionCode& ec) { deleteRule(index, ec); }
74
75    // For CSSRuleList.
76    unsigned length() const;
77    CSSRule* item(unsigned index);
78
79    virtual void clearOwnerNode() override;
80    virtual CSSImportRule* ownerRule() const override { return m_ownerRule; }
81    virtual URL baseURL() const override;
82    virtual bool isLoading() const override;
83
84    void clearOwnerRule() { m_ownerRule = 0; }
85    Document* ownerDocument() const;
86    MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
87    void setMediaQueries(PassRefPtr<MediaQuerySet>);
88    void setTitle(const String& title) { m_title = title; }
89
90    enum RuleMutationType { OtherMutation, RuleInsertion };
91    enum WhetherContentsWereClonedForMutation { ContentsWereNotClonedForMutation = 0, ContentsWereClonedForMutation };
92
93    class RuleMutationScope {
94        WTF_MAKE_NONCOPYABLE(RuleMutationScope);
95    public:
96        RuleMutationScope(CSSStyleSheet*, RuleMutationType = OtherMutation, StyleRuleKeyframes* insertedKeyframesRule = nullptr);
97        RuleMutationScope(CSSRule*);
98        ~RuleMutationScope();
99
100    private:
101        CSSStyleSheet* m_styleSheet;
102        RuleMutationType m_mutationType;
103        WhetherContentsWereClonedForMutation m_contentsWereClonedForMutation;
104        StyleRuleKeyframes* m_insertedKeyframesRule;
105    };
106
107    WhetherContentsWereClonedForMutation willMutateRules();
108    void didMutateRules(RuleMutationType, WhetherContentsWereClonedForMutation, StyleRuleKeyframes* insertedKeyframesRule);
109    void didMutateRuleFromCSSStyleDeclaration();
110    void didMutate();
111
112    void clearChildRuleCSSOMWrappers();
113    void reattachChildRuleCSSOMWrappers();
114
115    StyleSheetContents& contents() { return m_contents.get(); }
116
117    void detachFromDocument() { m_ownerNode = nullptr; }
118
119private:
120    CSSStyleSheet(PassRef<StyleSheetContents>, CSSImportRule* ownerRule);
121    CSSStyleSheet(PassRef<StyleSheetContents>, Node* ownerNode, bool isInlineStylesheet);
122
123    virtual bool isCSSStyleSheet() const override { return true; }
124    virtual String type() const override { return ASCIILiteral("text/css"); }
125
126    bool canAccessRules() const;
127
128    Ref<StyleSheetContents> m_contents;
129    bool m_isInlineStylesheet;
130    bool m_isDisabled;
131    String m_title;
132    RefPtr<MediaQuerySet> m_mediaQueries;
133
134    Node* m_ownerNode;
135    CSSImportRule* m_ownerRule;
136
137    mutable RefPtr<MediaList> m_mediaCSSOMWrapper;
138    mutable Vector<RefPtr<CSSRule>> m_childRuleCSSOMWrappers;
139    mutable std::unique_ptr<CSSRuleList> m_ruleListCSSOMWrapper;
140};
141
142} // namespace
143
144#endif
145