blob: f8f287f439073ffa3097afb9c6c94b7965e8341e [file] [log] [blame]
/*
* Copyright (C) 2000 Lars Knoll (knoll@kde.org)
* (C) 2000 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2003, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights
* reserved.
* Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_CONTENT_DATA_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_CONTENT_DATA_H_
#include <memory>
#include <utility>
#include "third_party/blink/renderer/core/style/counter_content.h"
#include "third_party/blink/renderer/core/style/style_image.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink {
class ComputedStyle;
class LayoutObject;
enum class LegacyLayout;
class PseudoElement;
class ContentData : public GarbageCollectedFinalized<ContentData> {
public:
static ContentData* Create(StyleImage*);
static ContentData* Create(const String&);
static ContentData* Create(std::unique_ptr<CounterContent>);
static ContentData* CreateAltText(const String&);
static ContentData* Create(QuoteType);
virtual ~ContentData() = default;
virtual bool IsCounter() const { return false; }
virtual bool IsImage() const { return false; }
virtual bool IsQuote() const { return false; }
virtual bool IsText() const { return false; }
virtual bool IsAltText() const { return false; }
virtual LayoutObject* CreateLayoutObject(PseudoElement&,
ComputedStyle&,
LegacyLayout) const = 0;
virtual ContentData* Clone() const;
ContentData* Next() const { return next_.Get(); }
void SetNext(ContentData* next) { next_ = next; }
virtual bool Equals(const ContentData&) const = 0;
virtual void Trace(blink::Visitor*);
private:
virtual ContentData* CloneInternal() const = 0;
Member<ContentData> next_;
};
class ImageContentData final : public ContentData {
friend class ContentData;
public:
ImageContentData(StyleImage* image) : image_(image) { DCHECK(image_); }
const StyleImage* GetImage() const { return image_.Get(); }
StyleImage* GetImage() { return image_.Get(); }
void SetImage(StyleImage* image) {
DCHECK(image);
image_ = image;
}
bool IsImage() const override { return true; }
LayoutObject* CreateLayoutObject(PseudoElement&,
ComputedStyle&,
LegacyLayout) const override;
bool Equals(const ContentData& data) const override {
if (!data.IsImage())
return false;
return *static_cast<const ImageContentData&>(data).GetImage() ==
*GetImage();
}
void Trace(blink::Visitor*) override;
private:
ContentData* CloneInternal() const override {
StyleImage* image = const_cast<StyleImage*>(this->GetImage());
return Create(image);
}
Member<StyleImage> image_;
};
template <>
struct DowncastTraits<ImageContentData> {
static bool AllowFrom(const ContentData& content) {
return content.IsImage();
}
};
class TextContentData final : public ContentData {
friend class ContentData;
public:
TextContentData(const String& text) : text_(text) {}
const String& GetText() const { return text_; }
void SetText(const String& text) { text_ = text; }
bool IsText() const override { return true; }
LayoutObject* CreateLayoutObject(PseudoElement&,
ComputedStyle&,
LegacyLayout) const override;
bool Equals(const ContentData& data) const override {
if (!data.IsText())
return false;
return static_cast<const TextContentData&>(data).GetText() == GetText();
}
private:
ContentData* CloneInternal() const override { return Create(GetText()); }
String text_;
};
template <>
struct DowncastTraits<TextContentData> {
static bool AllowFrom(const ContentData& content) { return content.IsText(); }
};
class AltTextContentData final : public ContentData {
friend class ContentData;
public:
AltTextContentData(const String& text) : text_(text) {}
String GetText() const { return text_; }
void SetText(const String& text) { text_ = text; }
bool IsAltText() const override { return true; }
LayoutObject* CreateLayoutObject(PseudoElement&,
ComputedStyle&,
LegacyLayout) const override;
bool Equals(const ContentData& data) const override {
if (!data.IsAltText())
return false;
return static_cast<const AltTextContentData&>(data).GetText() == GetText();
}
private:
ContentData* CloneInternal() const override { return Create(GetText()); }
String text_;
};
template <>
struct DowncastTraits<AltTextContentData> {
static bool AllowFrom(const ContentData& content) {
return content.IsAltText();
}
};
class CounterContentData final : public ContentData {
friend class ContentData;
public:
const CounterContent* Counter() const { return counter_.get(); }
void SetCounter(std::unique_ptr<CounterContent> counter) {
counter_ = std::move(counter);
}
CounterContentData(std::unique_ptr<CounterContent> counter)
: counter_(std::move(counter)) {}
bool IsCounter() const override { return true; }
LayoutObject* CreateLayoutObject(PseudoElement&,
ComputedStyle&,
LegacyLayout) const override;
private:
ContentData* CloneInternal() const override {
std::unique_ptr<CounterContent> counter_data =
std::make_unique<CounterContent>(*Counter());
return Create(std::move(counter_data));
}
bool Equals(const ContentData& data) const override {
if (!data.IsCounter())
return false;
return *static_cast<const CounterContentData&>(data).Counter() ==
*Counter();
}
std::unique_ptr<CounterContent> counter_;
};
template <>
struct DowncastTraits<CounterContentData> {
static bool AllowFrom(const ContentData& content) {
return content.IsCounter();
}
};
class QuoteContentData final : public ContentData {
friend class ContentData;
public:
QuoteContentData(QuoteType quote) : quote_(quote) {}
QuoteType Quote() const { return quote_; }
void SetQuote(QuoteType quote) { quote_ = quote; }
bool IsQuote() const override { return true; }
LayoutObject* CreateLayoutObject(PseudoElement&,
ComputedStyle&,
LegacyLayout) const override;
bool Equals(const ContentData& data) const override {
if (!data.IsQuote())
return false;
return static_cast<const QuoteContentData&>(data).Quote() == Quote();
}
private:
ContentData* CloneInternal() const override { return Create(Quote()); }
QuoteType quote_;
};
template <>
struct DowncastTraits<QuoteContentData> {
static bool AllowFrom(const ContentData& content) {
return content.IsQuote();
}
};
inline bool operator==(const ContentData& a, const ContentData& b) {
const ContentData* ptr_a = &a;
const ContentData* ptr_b = &b;
while (ptr_a && ptr_b && ptr_a->Equals(*ptr_b)) {
ptr_a = ptr_a->Next();
ptr_b = ptr_b->Next();
}
return !ptr_a && !ptr_b;
}
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_CONTENT_DATA_H_