Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#pragma once
28
29#include <AK/RefCounted.h>
30#include <AK/RefPtr.h>
31#include <AK/String.h>
32#include <AK/StringView.h>
33#include <AK/URL.h>
34#include <AK/WeakPtr.h>
35#include <LibGfx/Color.h>
36#include <LibGfx/Bitmap.h>
37#include <LibHTML/CSS/Length.h>
38#include <LibHTML/CSS/PropertyID.h>
39
40class Document;
41
42namespace CSS {
43enum class ValueID {
44 Invalid,
45 VendorSpecificLink,
46 Center,
47 Left,
48 Right,
49 Justify,
50};
51}
52
53class StyleValue : public RefCounted<StyleValue> {
54public:
55 virtual ~StyleValue();
56
57 enum class Type {
58 Invalid,
59 Inherit,
60 Initial,
61 String,
62 Length,
63 Color,
64 Identifier,
65 Image,
66 };
67
68 Type type() const { return m_type; }
69
70 bool is_inherit() const { return type() == Type::Inherit; }
71 bool is_initial() const { return type() == Type::Initial; }
72 bool is_color() const { return type() == Type::Color; }
73 bool is_identifier() const { return type() == Type::Identifier; }
74 bool is_image() const { return type() == Type::Image; }
75 bool is_string() const { return type() == Type::String; }
76 bool is_length() const { return type() == Type::Length; }
77
78 virtual String to_string() const = 0;
79 virtual Length to_length() const { return {}; }
80 virtual Color to_color(const Document&) const { return {}; }
81
82 virtual bool is_auto() const { return false; }
83
84protected:
85 explicit StyleValue(Type);
86
87private:
88 Type m_type { Type::Invalid };
89};
90
91class StringStyleValue : public StyleValue {
92public:
93 static NonnullRefPtr<StringStyleValue> create(const String& string)
94 {
95 return adopt(*new StringStyleValue(string));
96 }
97 virtual ~StringStyleValue() override {}
98
99 String to_string() const override { return m_string; }
100
101private:
102 explicit StringStyleValue(const String& string)
103 : StyleValue(Type::String)
104 , m_string(string)
105 {
106 }
107
108 String m_string;
109};
110
111class LengthStyleValue : public StyleValue {
112public:
113 static NonnullRefPtr<LengthStyleValue> create(const Length& length)
114 {
115 return adopt(*new LengthStyleValue(length));
116 }
117 virtual ~LengthStyleValue() override {}
118
119 virtual String to_string() const override { return m_length.to_string(); }
120 virtual Length to_length() const override { return m_length; }
121
122 const Length& length() const { return m_length; }
123
124 virtual bool is_auto() const override { return m_length.is_auto(); }
125
126private:
127 explicit LengthStyleValue(const Length& length)
128 : StyleValue(Type::Length)
129 , m_length(length)
130 {
131 }
132
133 Length m_length;
134};
135
136class InitialStyleValue final : public StyleValue {
137public:
138 static NonnullRefPtr<InitialStyleValue> create() { return adopt(*new InitialStyleValue); }
139 virtual ~InitialStyleValue() override {}
140
141 String to_string() const override { return "initial"; }
142
143private:
144 InitialStyleValue()
145 : StyleValue(Type::Initial)
146 {
147 }
148};
149
150class InheritStyleValue final : public StyleValue {
151public:
152 static NonnullRefPtr<InheritStyleValue> create() { return adopt(*new InheritStyleValue); }
153 virtual ~InheritStyleValue() override {}
154
155 String to_string() const override { return "inherit"; }
156
157private:
158 InheritStyleValue()
159 : StyleValue(Type::Inherit)
160 {
161 }
162};
163
164class ColorStyleValue : public StyleValue {
165public:
166 static NonnullRefPtr<ColorStyleValue> create(Color color)
167 {
168 return adopt(*new ColorStyleValue(color));
169 }
170 virtual ~ColorStyleValue() override {}
171
172 Color color() const { return m_color; }
173 String to_string() const override { return m_color.to_string(); }
174 Color to_color(const Document&) const override { return m_color; }
175
176private:
177 explicit ColorStyleValue(Color color)
178 : StyleValue(Type::Color)
179 , m_color(color)
180 {
181 }
182
183 Color m_color;
184};
185
186class IdentifierStyleValue final : public StyleValue {
187public:
188 static NonnullRefPtr<IdentifierStyleValue> create(CSS::ValueID id)
189 {
190 return adopt(*new IdentifierStyleValue(id));
191 }
192 virtual ~IdentifierStyleValue() override {}
193
194 CSS::ValueID id() const { return m_id; }
195
196 virtual String to_string() const override;
197 virtual Color to_color(const Document&) const override;
198
199private:
200 explicit IdentifierStyleValue(CSS::ValueID id)
201 : StyleValue(Type::Identifier)
202 , m_id(id)
203 {
204 }
205
206 CSS::ValueID m_id { CSS::ValueID::Invalid };
207};
208
209class ImageStyleValue final : public StyleValue {
210public:
211 static NonnullRefPtr<ImageStyleValue> create(const URL& url, Document& document) { return adopt(*new ImageStyleValue(url, document)); }
212 virtual ~ImageStyleValue() override {}
213
214 String to_string() const override { return String::format("Image{%s}", m_url.to_string().characters()); }
215
216 const Gfx::Bitmap* bitmap() const { return m_bitmap; }
217
218private:
219 ImageStyleValue(const URL&, Document&);
220
221 URL m_url;
222 WeakPtr<Document> m_document;
223 RefPtr<Gfx::Bitmap> m_bitmap;
224};