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#pragma once
22
23#include "ExceptionOr.h"
24#include "StyleSheet.h"
25#include <memory>
26#include <wtf/Noncopyable.h>
27#include <wtf/TypeCasts.h>
28#include <wtf/text/AtomStringHash.h>
29#include <wtf/text/TextPosition.h>
30
31namespace WebCore {
32
33class CSSImportRule;
34class CSSParser;
35class CSSRule;
36class CSSRuleList;
37class CSSStyleSheet;
38class CachedCSSStyleSheet;
39class Document;
40class Element;
41class MediaQuerySet;
42class StyleRuleKeyframes;
43class StyleSheetContents;
44
45namespace Style {
46class Scope;
47}
48
49class CSSStyleSheet final : public StyleSheet {
50public:
51 static Ref<CSSStyleSheet> create(Ref<StyleSheetContents>&&, CSSImportRule* ownerRule = 0);
52 static Ref<CSSStyleSheet> create(Ref<StyleSheetContents>&&, Node& ownerNode, const Optional<bool>& isOriginClean = WTF::nullopt);
53 static Ref<CSSStyleSheet> createInline(Ref<StyleSheetContents>&&, Element& owner, const TextPosition& startPosition);
54
55 virtual ~CSSStyleSheet();
56
57 CSSStyleSheet* parentStyleSheet() const final;
58 Node* ownerNode() const final { return m_ownerNode; }
59 MediaList* media() const final;
60 String href() const final;
61 String title() const final { return m_title; }
62 bool disabled() const final { return m_isDisabled; }
63 void setDisabled(bool) final;
64
65 WEBCORE_EXPORT RefPtr<CSSRuleList> cssRules();
66 WEBCORE_EXPORT ExceptionOr<unsigned> insertRule(const String& rule, unsigned index);
67 WEBCORE_EXPORT ExceptionOr<void> deleteRule(unsigned index);
68
69 WEBCORE_EXPORT RefPtr<CSSRuleList> rules();
70 WEBCORE_EXPORT ExceptionOr<int> addRule(const String& selector, const String& style, Optional<unsigned> index);
71 ExceptionOr<void> removeRule(unsigned index) { return deleteRule(index); }
72
73 // For CSSRuleList.
74 unsigned length() const;
75 CSSRule* item(unsigned index);
76
77 void clearOwnerNode() final;
78 CSSImportRule* ownerRule() const final { return m_ownerRule; }
79 URL baseURL() const final;
80 bool isLoading() const final;
81
82 void clearOwnerRule() { m_ownerRule = 0; }
83
84 Document* ownerDocument() const;
85 CSSStyleSheet& rootStyleSheet();
86 const CSSStyleSheet& rootStyleSheet() const;
87 Style::Scope* styleScope();
88
89 MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
90 void setMediaQueries(Ref<MediaQuerySet>&&);
91 void setTitle(const String& title) { m_title = title; }
92
93 bool hadRulesMutation() const { return m_mutatedRules; }
94 void clearHadRulesMutation() { m_mutatedRules = false; }
95
96 enum RuleMutationType { OtherMutation, RuleInsertion };
97 enum WhetherContentsWereClonedForMutation { ContentsWereNotClonedForMutation = 0, ContentsWereClonedForMutation };
98
99 class RuleMutationScope {
100 WTF_MAKE_NONCOPYABLE(RuleMutationScope);
101 public:
102 RuleMutationScope(CSSStyleSheet*, RuleMutationType = OtherMutation, StyleRuleKeyframes* insertedKeyframesRule = nullptr);
103 RuleMutationScope(CSSRule*);
104 ~RuleMutationScope();
105
106 private:
107 CSSStyleSheet* m_styleSheet;
108 RuleMutationType m_mutationType;
109 WhetherContentsWereClonedForMutation m_contentsWereClonedForMutation;
110 StyleRuleKeyframes* m_insertedKeyframesRule;
111 };
112
113 WhetherContentsWereClonedForMutation willMutateRules();
114 void didMutateRules(RuleMutationType, WhetherContentsWereClonedForMutation, StyleRuleKeyframes* insertedKeyframesRule);
115 void didMutateRuleFromCSSStyleDeclaration();
116 void didMutate();
117
118 void clearChildRuleCSSOMWrappers();
119 void reattachChildRuleCSSOMWrappers();
120
121 StyleSheetContents& contents() { return m_contents; }
122
123 bool isInline() const { return m_isInlineStylesheet; }
124 TextPosition startPosition() const { return m_startPosition; }
125
126 void detachFromDocument() { m_ownerNode = nullptr; }
127
128 bool canAccessRules() const;
129
130private:
131 CSSStyleSheet(Ref<StyleSheetContents>&&, CSSImportRule* ownerRule);
132 CSSStyleSheet(Ref<StyleSheetContents>&&, Node* ownerNode, const TextPosition& startPosition, bool isInlineStylesheet);
133 CSSStyleSheet(Ref<StyleSheetContents>&&, Node& ownerNode, const TextPosition& startPosition, bool isInlineStylesheet, const Optional<bool>&);
134
135 bool isCSSStyleSheet() const final { return true; }
136 String type() const final { return "text/css"_s; }
137
138 Ref<StyleSheetContents> m_contents;
139 bool m_isInlineStylesheet;
140 bool m_isDisabled;
141 bool m_mutatedRules;
142 Optional<bool> m_isOriginClean;
143 String m_title;
144 RefPtr<MediaQuerySet> m_mediaQueries;
145
146 Node* m_ownerNode;
147 CSSImportRule* m_ownerRule;
148
149 TextPosition m_startPosition;
150
151 mutable RefPtr<MediaList> m_mediaCSSOMWrapper;
152 mutable Vector<RefPtr<CSSRule>> m_childRuleCSSOMWrappers;
153 mutable std::unique_ptr<CSSRuleList> m_ruleListCSSOMWrapper;
154};
155
156} // namespace WebCore
157
158SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::CSSStyleSheet)
159 static bool isType(const WebCore::StyleSheet& styleSheet) { return styleSheet.isCSSStyleSheet(); }
160SPECIALIZE_TYPE_TRAITS_END()
161