1/*
2 * Copyright (C) 2015 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "CSSRegisteredCustomProperty.h"
29#include "CSSValue.h"
30#include "CSSVariableReferenceValue.h"
31#include "Length.h"
32#include "StyleImage.h"
33#include <wtf/RefPtr.h>
34#include <wtf/Variant.h>
35#include <wtf/text/WTFString.h>
36
37namespace WebCore {
38
39class CSSParserToken;
40class CSSVariableReferenceValue;
41class RenderStyle;
42
43class CSSCustomPropertyValue final : public CSSValue {
44public:
45 using VariantValue = Variant<Ref<CSSVariableReferenceValue>, CSSValueID, Ref<CSSVariableData>, Length, Ref<StyleImage>>;
46
47 static Ref<CSSCustomPropertyValue> createUnresolved(const AtomString& name, Ref<CSSVariableReferenceValue>&& value)
48 {
49 return adoptRef(*new CSSCustomPropertyValue(name, { WTFMove(value) }));
50 }
51
52 static Ref<CSSCustomPropertyValue> createUnresolved(const AtomString& name, CSSValueID value)
53 {
54 return adoptRef(*new CSSCustomPropertyValue(name, { value }));
55 }
56
57 static Ref<CSSCustomPropertyValue> createWithID(const AtomString& name, CSSValueID id)
58 {
59 ASSERT(id == CSSValueInherit || id == CSSValueInitial || id == CSSValueUnset || id == CSSValueRevert || id == CSSValueInvalid);
60 return adoptRef(*new CSSCustomPropertyValue(name, { id }));
61 }
62
63 static Ref<CSSCustomPropertyValue> createSyntaxAll(const AtomString& name, Ref<CSSVariableData>&& value)
64 {
65 return adoptRef(*new CSSCustomPropertyValue(name, { WTFMove(value) }));
66 }
67
68 static Ref<CSSCustomPropertyValue> createSyntaxLength(const AtomString& name, Length value)
69 {
70 ASSERT(!value.isUndefined());
71 ASSERT(!value.isCalculated());
72 return adoptRef(*new CSSCustomPropertyValue(name, { WTFMove(value) }));
73 }
74
75 static Ref<CSSCustomPropertyValue> createSyntaxImage(const AtomString& name, Ref<StyleImage>&& value)
76 {
77 return adoptRef(*new CSSCustomPropertyValue(name, { WTFMove(value) }));
78 }
79
80 static Ref<CSSCustomPropertyValue> create(const CSSCustomPropertyValue& other)
81 {
82 return adoptRef(*new CSSCustomPropertyValue(other));
83 }
84
85 String customCSSText() const;
86
87 const AtomString& name() const { return m_name; }
88 bool isResolved() const { return !WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(m_value); }
89 bool isUnset() const { return WTF::holds_alternative<CSSValueID>(m_value) && WTF::get<CSSValueID>(m_value) == CSSValueUnset; }
90 bool isInvalid() const { return WTF::holds_alternative<CSSValueID>(m_value) && WTF::get<CSSValueID>(m_value) == CSSValueInvalid; }
91
92 const VariantValue& value() const { return m_value; }
93
94 Vector<CSSParserToken> tokens() const;
95 bool equals(const CSSCustomPropertyValue& other) const;
96
97private:
98 CSSCustomPropertyValue(const AtomString& name, VariantValue&& value)
99 : CSSValue(CustomPropertyClass)
100 , m_name(name)
101 , m_value(WTFMove(value))
102 , m_serialized(false)
103 {
104 }
105
106 CSSCustomPropertyValue(const CSSCustomPropertyValue& other)
107 : CSSValue(CustomPropertyClass)
108 , m_name(other.m_name)
109 , m_value(CSSValueUnset)
110 , m_stringValue(other.m_stringValue)
111 , m_serialized(other.m_serialized)
112 {
113 // No copy constructor for Ref<CSSVariableData>, so we have to do this ourselves
114 auto visitor = WTF::makeVisitor([&](const Ref<CSSVariableReferenceValue>& value) {
115 m_value = value.copyRef();
116 }, [&](const CSSValueID& value) {
117 m_value = value;
118 }, [&](const Ref<CSSVariableData>& value) {
119 m_value = value.copyRef();
120 }, [&](const Length& value) {
121 m_value = value;
122 }, [&](const Ref<StyleImage>& value) {
123 m_value = value.copyRef();
124 });
125 WTF::visit(visitor, other.m_value);
126 }
127
128 const AtomString m_name;
129 VariantValue m_value;
130
131 mutable String m_stringValue;
132 mutable bool m_serialized { false };
133};
134
135} // namespace WebCore
136
137SPECIALIZE_TYPE_TRAITS_CSS_VALUE(CSSCustomPropertyValue, isCustomPropertyValue())
138