1/*
2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3 *           (C) 2000 Antti Koivisto (koivisto@kde.org)
4 *           (C) 2000 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB.  If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25#ifndef ContentData_h
26#define ContentData_h
27
28#include "CounterContent.h"
29#include "StyleImage.h"
30#include "RenderPtr.h"
31
32namespace WebCore {
33
34class Document;
35class RenderObject;
36class RenderStyle;
37
38class ContentData {
39    WTF_MAKE_FAST_ALLOCATED;
40public:
41    enum Type {
42        CounterDataType,
43        ImageDataType,
44        QuoteDataType,
45        TextDataType
46    };
47    virtual ~ContentData() { }
48
49    Type type() const { return m_type; }
50
51    bool isCounter() const { return type() == CounterDataType; }
52    bool isImage() const { return type() == ImageDataType; }
53    bool isQuote() const { return type() == QuoteDataType; }
54    bool isText() const { return type() == TextDataType; }
55
56    virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const = 0;
57
58    std::unique_ptr<ContentData> clone() const;
59
60    ContentData* next() const { return m_next.get(); }
61    void setNext(std::unique_ptr<ContentData> next) { m_next = WTF::move(next); }
62
63    void setAltText(const String& alt) { m_altText = alt; }
64    const String& altText() const { return m_altText; }
65
66protected:
67    explicit ContentData(Type type)
68        : m_type(type)
69    {
70    }
71
72private:
73    virtual std::unique_ptr<ContentData> cloneInternal() const = 0;
74
75    std::unique_ptr<ContentData> m_next;
76    String m_altText;
77    Type m_type;
78};
79
80#define CONTENT_DATA_TYPE_CASTS(ToClassName, FromClassName, ContentDataName) \
81    TYPE_CASTS_BASE(ToClassName, FromClassName, resource, resource->is##ContentDataName(), resource.is##ContentDataName())
82
83class ImageContentData final : public ContentData {
84public:
85    explicit ImageContentData(PassRefPtr<StyleImage> image)
86        : ContentData(ImageDataType)
87        , m_image(image)
88    {
89        ASSERT(m_image);
90    }
91
92    const StyleImage& image() const { return *m_image; }
93    void setImage(PassRefPtr<StyleImage> image)
94    {
95        ASSERT(image);
96        m_image = image;
97    }
98
99    virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const override;
100
101private:
102    virtual std::unique_ptr<ContentData> cloneInternal() const override
103    {
104        return std::make_unique<ImageContentData>(m_image.get());
105    }
106
107    RefPtr<StyleImage> m_image;
108};
109
110CONTENT_DATA_TYPE_CASTS(ImageContentData, ContentData, Image)
111
112inline bool operator==(const ImageContentData& a, const ImageContentData& b)
113{
114    return a.image() == b.image();
115}
116
117inline bool operator!=(const ImageContentData& a, const ImageContentData& b)
118{
119    return !(a == b);
120}
121
122class TextContentData final : public ContentData {
123public:
124    explicit TextContentData(const String& text)
125        : ContentData(TextDataType)
126        , m_text(text)
127    {
128    }
129
130    const String& text() const { return m_text; }
131    void setText(const String& text) { m_text = text; }
132
133    virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const override;
134
135private:
136    virtual std::unique_ptr<ContentData> cloneInternal() const override { return std::make_unique<TextContentData>(text()); }
137
138    String m_text;
139};
140
141CONTENT_DATA_TYPE_CASTS(TextContentData, ContentData, Text)
142
143inline bool operator==(const TextContentData& a, const TextContentData& b)
144{
145    return a.text() == b.text();
146}
147
148inline bool operator!=(const TextContentData& a, const TextContentData& b)
149{
150    return !(a == b);
151}
152
153class CounterContentData final : public ContentData {
154public:
155    explicit CounterContentData(std::unique_ptr<CounterContent> counter)
156        : ContentData(CounterDataType)
157        , m_counter(WTF::move(counter))
158    {
159        ASSERT(m_counter);
160    }
161
162    const CounterContent& counter() const { return *m_counter; }
163    void setCounter(std::unique_ptr<CounterContent> counter)
164    {
165        ASSERT(counter);
166        m_counter = WTF::move(counter);
167    }
168
169    virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const override;
170
171private:
172    virtual std::unique_ptr<ContentData> cloneInternal() const override
173    {
174        auto counterData = std::make_unique<CounterContent>(counter());
175        return std::make_unique<CounterContentData>(WTF::move(counterData));
176    }
177
178    std::unique_ptr<CounterContent> m_counter;
179};
180
181CONTENT_DATA_TYPE_CASTS(CounterContentData, ContentData, Counter)
182
183inline bool operator==(const CounterContentData& a, const CounterContentData& b)
184{
185    return a.counter() == b.counter();
186}
187
188inline bool operator!=(const CounterContentData& a, const CounterContentData& b)
189{
190    return !(a == b);
191}
192
193class QuoteContentData final : public ContentData {
194public:
195    explicit QuoteContentData(QuoteType quote)
196        : ContentData(QuoteDataType)
197        , m_quote(quote)
198    {
199    }
200
201    QuoteType quote() const { return m_quote; }
202    void setQuote(QuoteType quote) { m_quote = quote; }
203
204    virtual RenderPtr<RenderObject> createContentRenderer(Document&, const RenderStyle&) const override;
205
206private:
207    virtual std::unique_ptr<ContentData> cloneInternal() const override { return std::make_unique<QuoteContentData>(quote()); }
208
209    QuoteType m_quote;
210};
211
212CONTENT_DATA_TYPE_CASTS(QuoteContentData, ContentData, Quote)
213
214inline bool operator==(const QuoteContentData& a, const QuoteContentData& b)
215{
216    return a.quote() == b.quote();
217}
218
219inline bool operator!=(const QuoteContentData& a, const QuoteContentData& b)
220{
221    return !(a == b);
222}
223
224inline bool operator==(const ContentData& a, const ContentData& b)
225{
226    if (a.type() != b.type())
227        return false;
228
229    switch (a.type()) {
230    case ContentData::CounterDataType:
231        return toCounterContentData(a) == toCounterContentData(b);
232    case ContentData::ImageDataType:
233        return toImageContentData(a) == toImageContentData(b);
234    case ContentData::QuoteDataType:
235        return toQuoteContentData(a) == toQuoteContentData(b);
236    case ContentData::TextDataType:
237        return toTextContentData(a) == toTextContentData(b);
238    }
239
240    ASSERT_NOT_REACHED();
241    return false;
242}
243
244inline bool operator!=(const ContentData& a, const ContentData& b)
245{
246    return !(a == b);
247}
248
249} // namespace WebCore
250
251#endif // ContentData_h
252