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 "core/rendering/style/CounterContent.h"
29#include "core/rendering/style/StyleImage.h"
30#include "wtf/OwnPtr.h"
31#include "wtf/PassOwnPtr.h"
32
33namespace blink {
34
35class Document;
36class RenderObject;
37class RenderStyle;
38
39class ContentData {
40    WTF_MAKE_FAST_ALLOCATED;
41public:
42    static PassOwnPtr<ContentData> create(PassRefPtr<StyleImage>);
43    static PassOwnPtr<ContentData> create(const String&);
44    static PassOwnPtr<ContentData> create(PassOwnPtr<CounterContent>);
45    static PassOwnPtr<ContentData> create(QuoteType);
46
47    virtual ~ContentData() { }
48
49    virtual bool isCounter() const { return false; }
50    virtual bool isImage() const { return false; }
51    virtual bool isQuote() const { return false; }
52    virtual bool isText() const { return false; }
53
54    virtual RenderObject* createRenderer(Document&, RenderStyle*) const = 0;
55
56    virtual PassOwnPtr<ContentData> clone() const;
57
58    ContentData* next() const { return m_next.get(); }
59    void setNext(PassOwnPtr<ContentData> next) { m_next = next; }
60
61    virtual bool equals(const ContentData&) const = 0;
62
63private:
64    virtual PassOwnPtr<ContentData> cloneInternal() const = 0;
65
66    OwnPtr<ContentData> m_next;
67};
68
69#define DEFINE_CONTENT_DATA_TYPE_CASTS(typeName) \
70    DEFINE_TYPE_CASTS(typeName##ContentData, ContentData, content, content->is##typeName(), content.is##typeName())
71
72class ImageContentData FINAL : public ContentData {
73    friend class ContentData;
74public:
75    const StyleImage* image() const { return m_image.get(); }
76    StyleImage* image() { return m_image.get(); }
77    void setImage(PassRefPtr<StyleImage> image) { m_image = image; }
78
79    virtual bool isImage() const OVERRIDE { return true; }
80    virtual RenderObject* createRenderer(Document&, RenderStyle*) const OVERRIDE;
81
82    virtual bool equals(const ContentData& data) const OVERRIDE
83    {
84        if (!data.isImage())
85            return false;
86        return *static_cast<const ImageContentData&>(data).image() == *image();
87    }
88
89private:
90    ImageContentData(PassRefPtr<StyleImage> image)
91        : m_image(image)
92    {
93    }
94
95    virtual PassOwnPtr<ContentData> cloneInternal() const OVERRIDE
96    {
97        RefPtr<StyleImage> image = const_cast<StyleImage*>(this->image());
98        return create(image.release());
99    }
100
101    RefPtr<StyleImage> m_image;
102};
103
104DEFINE_CONTENT_DATA_TYPE_CASTS(Image);
105
106class TextContentData FINAL : public ContentData {
107    friend class ContentData;
108public:
109    const String& text() const { return m_text; }
110    void setText(const String& text) { m_text = text; }
111
112    virtual bool isText() const OVERRIDE { return true; }
113    virtual RenderObject* createRenderer(Document&, RenderStyle*) const OVERRIDE;
114
115    virtual bool equals(const ContentData& data) const OVERRIDE
116    {
117        if (!data.isText())
118            return false;
119        return static_cast<const TextContentData&>(data).text() == text();
120    }
121
122private:
123    TextContentData(const String& text)
124        : m_text(text)
125    {
126    }
127
128    virtual PassOwnPtr<ContentData> cloneInternal() const OVERRIDE { return create(text()); }
129
130    String m_text;
131};
132
133DEFINE_CONTENT_DATA_TYPE_CASTS(Text);
134
135class CounterContentData FINAL : public ContentData {
136    friend class ContentData;
137public:
138    const CounterContent* counter() const { return m_counter.get(); }
139    void setCounter(PassOwnPtr<CounterContent> counter) { m_counter = counter; }
140
141    virtual bool isCounter() const OVERRIDE { return true; }
142    virtual RenderObject* createRenderer(Document&, RenderStyle*) const OVERRIDE;
143
144private:
145    CounterContentData(PassOwnPtr<CounterContent> counter)
146        : m_counter(counter)
147    {
148    }
149
150    virtual PassOwnPtr<ContentData> cloneInternal() const OVERRIDE
151    {
152        OwnPtr<CounterContent> counterData = adoptPtr(new CounterContent(*counter()));
153        return create(counterData.release());
154    }
155
156    virtual bool equals(const ContentData& data) const OVERRIDE
157    {
158        if (!data.isCounter())
159            return false;
160        return *static_cast<const CounterContentData&>(data).counter() == *counter();
161    }
162
163    OwnPtr<CounterContent> m_counter;
164};
165
166DEFINE_CONTENT_DATA_TYPE_CASTS(Counter);
167
168class QuoteContentData FINAL : public ContentData {
169    friend class ContentData;
170public:
171    QuoteType quote() const { return m_quote; }
172    void setQuote(QuoteType quote) { m_quote = quote; }
173
174    virtual bool isQuote() const OVERRIDE { return true; }
175    virtual RenderObject* createRenderer(Document&, RenderStyle*) const OVERRIDE;
176
177    virtual bool equals(const ContentData& data) const OVERRIDE
178    {
179        if (!data.isQuote())
180            return false;
181        return static_cast<const QuoteContentData&>(data).quote() == quote();
182    }
183
184private:
185    QuoteContentData(QuoteType quote)
186        : m_quote(quote)
187    {
188    }
189
190    virtual PassOwnPtr<ContentData> cloneInternal() const OVERRIDE { return create(quote()); }
191
192    QuoteType m_quote;
193};
194
195DEFINE_CONTENT_DATA_TYPE_CASTS(Quote);
196
197inline bool operator==(const ContentData& a, const ContentData& b)
198{
199    return a.equals(b);
200}
201
202inline bool operator!=(const ContentData& a, const ContentData& b)
203{
204    return !(a == b);
205}
206
207} // namespace blink
208
209#endif // ContentData_h
210