- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / CSSKeyframesRule.cpp
1 /*
2  * Copyright (C) 2007, 2008, 2012 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 COMPUTER, 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 COMPUTER, 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 #include "config.h"
27 #include "core/css/CSSKeyframesRule.h"
28
29 #include "core/css/CSSKeyframeRule.h"
30 #include "core/css/CSSParser.h"
31 #include "core/css/CSSRuleList.h"
32 #include "core/css/CSSStyleSheet.h"
33 #include "wtf/text/StringBuilder.h"
34
35 namespace WebCore {
36
37 StyleRuleKeyframes::StyleRuleKeyframes()
38     : StyleRuleBase(Keyframes)
39 {
40 }
41
42 StyleRuleKeyframes::StyleRuleKeyframes(const StyleRuleKeyframes& o)
43     : StyleRuleBase(o)
44     , m_keyframes(o.m_keyframes)
45     , m_name(o.m_name)
46     , m_isPrefixed(o.m_isPrefixed)
47 {
48 }
49
50 StyleRuleKeyframes::~StyleRuleKeyframes()
51 {
52 }
53
54 void StyleRuleKeyframes::parserAppendKeyframe(PassRefPtr<StyleKeyframe> keyframe)
55 {
56     if (!keyframe)
57         return;
58     m_keyframes.append(keyframe);
59 }
60
61 void StyleRuleKeyframes::wrapperAppendKeyframe(PassRefPtr<StyleKeyframe> keyframe)
62 {
63     m_keyframes.append(keyframe);
64 }
65
66 void StyleRuleKeyframes::wrapperRemoveKeyframe(unsigned index)
67 {
68     m_keyframes.remove(index);
69 }
70
71 int StyleRuleKeyframes::findKeyframeIndex(const String& key) const
72 {
73     String percentageString;
74     if (equalIgnoringCase(key, "from"))
75         percentageString = "0%";
76     else if (equalIgnoringCase(key, "to"))
77         percentageString = "100%";
78     else
79         percentageString = key;
80
81     for (unsigned i = 0; i < m_keyframes.size(); ++i) {
82         if (m_keyframes[i]->keyText() == percentageString)
83             return i;
84     }
85     return -1;
86 }
87
88 CSSKeyframesRule::CSSKeyframesRule(StyleRuleKeyframes* keyframesRule, CSSStyleSheet* parent)
89     : CSSRule(parent)
90     , m_keyframesRule(keyframesRule)
91     , m_childRuleCSSOMWrappers(keyframesRule->keyframes().size())
92     , m_isPrefixed(keyframesRule->isVendorPrefixed())
93 {
94 }
95
96 CSSKeyframesRule::~CSSKeyframesRule()
97 {
98     ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size());
99
100     for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
101         if (m_childRuleCSSOMWrappers[i])
102             m_childRuleCSSOMWrappers[i]->setParentRule(0);
103     }
104 }
105
106 void CSSKeyframesRule::setName(const String& name)
107 {
108     CSSStyleSheet::RuleMutationScope mutationScope(this);
109
110     m_keyframesRule->setName(name);
111 }
112
113 void CSSKeyframesRule::insertRule(const String& ruleText)
114 {
115     ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size());
116
117     CSSStyleSheet* styleSheet = parentStyleSheet();
118     CSSParser parser(parserContext(), UseCounter::getFrom(styleSheet));
119     RefPtr<StyleKeyframe> keyframe = parser.parseKeyframeRule(styleSheet ? styleSheet->contents() : 0, ruleText);
120     if (!keyframe)
121         return;
122
123     CSSStyleSheet::RuleMutationScope mutationScope(this);
124
125     m_keyframesRule->wrapperAppendKeyframe(keyframe);
126
127     m_childRuleCSSOMWrappers.grow(length());
128 }
129
130 void CSSKeyframesRule::deleteRule(const String& s)
131 {
132     ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size());
133
134     int i = m_keyframesRule->findKeyframeIndex(s);
135     if (i < 0)
136         return;
137
138     CSSStyleSheet::RuleMutationScope mutationScope(this);
139
140     m_keyframesRule->wrapperRemoveKeyframe(i);
141
142     if (m_childRuleCSSOMWrappers[i])
143         m_childRuleCSSOMWrappers[i]->setParentRule(0);
144     m_childRuleCSSOMWrappers.remove(i);
145 }
146
147 CSSKeyframeRule* CSSKeyframesRule::findRule(const String& s)
148 {
149     int i = m_keyframesRule->findKeyframeIndex(s);
150     return (i >= 0) ? item(i) : 0;
151 }
152
153 String CSSKeyframesRule::cssText() const
154 {
155     StringBuilder result;
156     if (isVendorPrefixed())
157         result.append("@-webkit-keyframes ");
158     else
159         result.append("@keyframes ");
160     result.append(name());
161     result.append(" { \n");
162
163     unsigned size = length();
164     for (unsigned i = 0; i < size; ++i) {
165         result.append("  ");
166         result.append(m_keyframesRule->keyframes()[i]->cssText());
167         result.append("\n");
168     }
169     result.append("}");
170     return result.toString();
171 }
172
173 unsigned CSSKeyframesRule::length() const
174 {
175     return m_keyframesRule->keyframes().size();
176 }
177
178 CSSKeyframeRule* CSSKeyframesRule::item(unsigned index) const
179 {
180     if (index >= length())
181         return 0;
182
183     ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size());
184     RefPtr<CSSKeyframeRule>& rule = m_childRuleCSSOMWrappers[index];
185     if (!rule)
186         rule = adoptRef(new CSSKeyframeRule(m_keyframesRule->keyframes()[index].get(), const_cast<CSSKeyframesRule*>(this)));
187
188     return rule.get();
189 }
190
191 CSSRuleList* CSSKeyframesRule::cssRules()
192 {
193     if (!m_ruleListCSSOMWrapper)
194         m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<CSSKeyframesRule>(this));
195     return m_ruleListCSSOMWrapper.get();
196 }
197
198 void CSSKeyframesRule::reattach(StyleRuleBase* rule)
199 {
200     ASSERT(rule);
201     ASSERT_WITH_SECURITY_IMPLICATION(rule->isKeyframesRule());
202     m_keyframesRule = static_cast<StyleRuleKeyframes*>(rule);
203 }
204
205 } // namespace WebCore