2011-04-05 Luke Macpherson <macpherson@chromium.org>
[WebKit-https.git] / Source / WebCore / css / CSSStyleApplyProperty.cpp
1 /*
2  * Copyright (C) 2011 Google 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. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26 #include "CSSStyleApplyProperty.h"
27
28 #include "CSSPrimitiveValueMappings.h"
29 #include "CSSStyleSelector.h"
30 #include "Document.h"
31 #include "Element.h"
32 #include "RenderStyle.h"
33 #include <wtf/StdLibExtras.h>
34 #include <wtf/UnusedParam.h>
35
36 using namespace std;
37
38 namespace WebCore {
39
40 class ApplyPropertyNull : public ApplyPropertyBase {
41 public:
42     virtual void inherit(CSSStyleSelector*) const {}
43     virtual void initial(CSSStyleSelector*) const {}
44     virtual void value(CSSStyleSelector*, CSSValue*) const {}
45 };
46
47 template <typename T>
48 class ApplyPropertyDefault : public ApplyPropertyBase {
49 public:
50     ApplyPropertyDefault(T (RenderStyle::*getter)() const, void (RenderStyle::*setter)(T), T (*initial)())
51         : m_getter(getter)
52         , m_setter(setter)
53         , m_initial(initial)
54     {
55     }
56
57     virtual void inherit(CSSStyleSelector* selector) const
58     {
59         (selector->style()->*m_setter)((selector->parentStyle()->*m_getter)());
60     }
61
62     virtual void initial(CSSStyleSelector* selector) const
63     {
64         (selector->style()->*m_setter)((*m_initial)());
65     }
66
67     virtual void value(CSSStyleSelector* selector, CSSValue* value) const
68     {
69         if (value->isPrimitiveValue())
70             (selector->style()->*m_setter)(*(static_cast<CSSPrimitiveValue*>(value)));
71     }
72
73 protected:
74     T (RenderStyle::*m_getter)() const;
75     void (RenderStyle::*m_setter)(T);
76     T (*m_initial)();
77 };
78
79 // CSSPropertyColor
80 class ApplyPropertyColorBase : public ApplyPropertyBase {
81 public:
82     ApplyPropertyColorBase(const Color& (RenderStyle::*getter)() const, const Color& (RenderStyle::*defaultValue)() const, void (RenderStyle::*setter)(const Color&))
83         : m_getter(getter)
84         , m_defaultValue(defaultValue)
85         , m_setter(setter)
86     {
87     }
88     virtual void inherit(CSSStyleSelector* selector) const
89     {
90         const Color& color = (selector->parentStyle()->*m_getter)();
91         if (m_defaultValue && !color.isValid())
92             (selector->style()->*m_setter)((selector->parentStyle()->*m_defaultValue)());
93         else
94             (selector->style()->*m_setter)(color);
95     }
96     virtual void initial(CSSStyleSelector* selector) const
97     {
98         Color color;
99         (selector->style()->*m_setter)(color);
100     }
101     virtual void value(CSSStyleSelector* selector, CSSValue* value) const
102     {
103         if (value->isPrimitiveValue())
104             (selector->style()->*m_setter)(selector->getColorFromPrimitiveValue(static_cast<CSSPrimitiveValue*>(value)));
105     }
106 protected:
107     const Color& (RenderStyle::*m_getter)() const;
108     const Color& (RenderStyle::*m_defaultValue)() const;
109     void (RenderStyle::*m_setter)(const Color&);
110 };
111
112 class ApplyPropertyColor : public ApplyPropertyColorBase {
113 public:
114     ApplyPropertyColor(const Color& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&), Color (*initialValue)())
115         : ApplyPropertyColorBase(getter, 0, setter)
116         , m_initialValue(initialValue)
117     {
118     }
119
120     virtual void initial(CSSStyleSelector* selector) const
121     {
122         (selector->style()->*m_setter)(m_initialValue());
123     }
124
125     virtual void value(CSSStyleSelector* selector, CSSValue* value) const
126     {
127         if (!value->isPrimitiveValue())
128             return;
129
130         if ((static_cast<CSSPrimitiveValue*>(value))->getIdent() == CSSValueCurrentcolor)
131             inherit(selector);
132         else
133             ApplyPropertyColorBase::value(selector, value);
134     }
135 protected:
136     Color (*m_initialValue)();
137 };
138
139 // CSSPropertyDirection
140 class ApplyPropertyDirection : public ApplyPropertyDefault<TextDirection> {
141 public:
142     ApplyPropertyDirection(TextDirection (RenderStyle::*getter)() const, void (RenderStyle::*setter)(TextDirection), TextDirection (*initial)())
143         : ApplyPropertyDefault<TextDirection>(getter, setter, initial)
144     {
145     }
146
147     virtual void value(CSSStyleSelector* selector, CSSValue* value) const
148     {
149         ApplyPropertyDefault<TextDirection>::value(selector, value);
150         Element* element = selector->element();
151         if (element && selector->element() == element->document()->documentElement())
152             element->document()->setDirectionSetOnDocumentElement(true);
153     }
154 };
155
156 const CSSStyleApplyProperty& CSSStyleApplyProperty::sharedCSSStyleApplyProperty()
157 {
158     DEFINE_STATIC_LOCAL(CSSStyleApplyProperty, cssStyleApplyPropertyInstance, ());
159     return cssStyleApplyPropertyInstance;
160 }
161
162
163 CSSStyleApplyProperty::CSSStyleApplyProperty()
164 {
165     for (int i = 0; i < numCSSProperties; ++i)
166        m_propertyMap[i] = 0;
167
168     setPropertyValue(CSSPropertyColor, new ApplyPropertyColor(&RenderStyle::color, &RenderStyle::setColor, RenderStyle::initialColor));
169     setPropertyValue(CSSPropertyDirection, new ApplyPropertyDirection(&RenderStyle::direction, &RenderStyle::setDirection, RenderStyle::initialDirection));
170     setPropertyValue(CSSPropertyBackgroundColor, new ApplyPropertyColorBase(&RenderStyle::backgroundColor, 0, &RenderStyle::setBackgroundColor));
171     setPropertyValue(CSSPropertyBorderBottomColor, new ApplyPropertyColorBase(&RenderStyle::borderBottomColor, &RenderStyle::color, &RenderStyle::setBorderBottomColor));
172     setPropertyValue(CSSPropertyBorderLeftColor, new ApplyPropertyColorBase(&RenderStyle::borderLeftColor, &RenderStyle::color, &RenderStyle::setBorderLeftColor));
173     setPropertyValue(CSSPropertyBorderRightColor, new ApplyPropertyColorBase(&RenderStyle::borderRightColor, &RenderStyle::color, &RenderStyle::setBorderRightColor));
174     setPropertyValue(CSSPropertyBorderTopColor, new ApplyPropertyColorBase(&RenderStyle::borderTopColor, &RenderStyle::color, &RenderStyle::setBorderTopColor));
175     setPropertyValue(CSSPropertyOutlineColor, new ApplyPropertyColorBase(&RenderStyle::outlineColor, &RenderStyle::color, &RenderStyle::setOutlineColor));
176     setPropertyValue(CSSPropertyWebkitColumnRuleColor, new ApplyPropertyColorBase(&RenderStyle::columnRuleColor, &RenderStyle::color, &RenderStyle::setColumnRuleColor));
177     setPropertyValue(CSSPropertyWebkitTextEmphasisColor, new ApplyPropertyColorBase(&RenderStyle::textEmphasisColor, &RenderStyle::color, &RenderStyle::setTextEmphasisColor));
178     setPropertyValue(CSSPropertyWebkitTextFillColor, new ApplyPropertyColorBase(&RenderStyle::textFillColor, &RenderStyle::color, &RenderStyle::setTextFillColor));
179     setPropertyValue(CSSPropertyWebkitTextStrokeColor, new ApplyPropertyColorBase(&RenderStyle::textStrokeColor, &RenderStyle::color, &RenderStyle::setTextStrokeColor));
180 }
181
182
183 }