1/* 2 * Copyright (C) 2007, 2008, 2012, 2013 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 "WebKitCSSKeyframesRule.h" 28 29#include "CSSParser.h" 30#include "CSSRuleList.h" 31#include "CSSStyleSheet.h" 32#include "StylePropertySet.h" 33#include "StyleSheet.h" 34#include "WebKitCSSKeyframeRule.h" 35#include <wtf/text/StringBuilder.h> 36 37namespace WebCore { 38 39StyleRuleKeyframes::StyleRuleKeyframes() 40 : StyleRuleBase(Keyframes, 0) 41{ 42} 43 44StyleRuleKeyframes::StyleRuleKeyframes(const StyleRuleKeyframes& o) 45 : StyleRuleBase(o) 46 , m_keyframes(o.m_keyframes) 47 , m_name(o.m_name) 48{ 49} 50 51StyleRuleKeyframes::~StyleRuleKeyframes() 52{ 53} 54 55void StyleRuleKeyframes::parserAppendKeyframe(PassRefPtr<StyleKeyframe> keyframe) 56{ 57 if (!keyframe) 58 return; 59 m_keyframes.append(keyframe); 60} 61 62void StyleRuleKeyframes::wrapperAppendKeyframe(PassRefPtr<StyleKeyframe> keyframe) 63{ 64 m_keyframes.append(keyframe); 65} 66 67void StyleRuleKeyframes::wrapperRemoveKeyframe(unsigned index) 68{ 69 m_keyframes.remove(index); 70} 71 72int StyleRuleKeyframes::findKeyframeIndex(const String& key) const 73{ 74 String percentageString; 75 if (equalIgnoringCase(key, "from")) 76 percentageString = ASCIILiteral("0%"); 77 else if (equalIgnoringCase(key, "to")) 78 percentageString = ASCIILiteral("100%"); 79 else 80 percentageString = key; 81 82 for (unsigned i = 0; i < m_keyframes.size(); ++i) { 83 if (m_keyframes[i]->keyText() == percentageString) 84 return i; 85 } 86 return -1; 87} 88 89WebKitCSSKeyframesRule::WebKitCSSKeyframesRule(StyleRuleKeyframes* keyframesRule, CSSStyleSheet* parent) 90 : CSSRule(parent) 91 , m_keyframesRule(keyframesRule) 92 , m_childRuleCSSOMWrappers(keyframesRule->keyframes().size()) 93{ 94} 95 96WebKitCSSKeyframesRule::~WebKitCSSKeyframesRule() 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 106void WebKitCSSKeyframesRule::setName(const String& name) 107{ 108 CSSStyleSheet::RuleMutationScope mutationScope(this); 109 110 m_keyframesRule->setName(name); 111} 112 113void WebKitCSSKeyframesRule::insertRule(const String& ruleText) 114{ 115 ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size()); 116 117 CSSParser parser(parserContext()); 118 CSSStyleSheet* styleSheet = parentStyleSheet(); 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 130void WebKitCSSKeyframesRule::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 147WebKitCSSKeyframeRule* WebKitCSSKeyframesRule::findRule(const String& s) 148{ 149 int i = m_keyframesRule->findKeyframeIndex(s); 150 return (i >= 0) ? item(i) : 0; 151} 152 153String WebKitCSSKeyframesRule::cssText() const 154{ 155 StringBuilder result; 156 result.appendLiteral("@-webkit-keyframes "); 157 result.append(name()); 158 result.appendLiteral(" { \n"); 159 160 unsigned size = length(); 161 for (unsigned i = 0; i < size; ++i) { 162 result.appendLiteral(" "); 163 result.append(m_keyframesRule->keyframes()[i]->cssText()); 164 result.append('\n'); 165 } 166 result.append('}'); 167 return result.toString(); 168} 169 170unsigned WebKitCSSKeyframesRule::length() const 171{ 172 return m_keyframesRule->keyframes().size(); 173} 174 175WebKitCSSKeyframeRule* WebKitCSSKeyframesRule::item(unsigned index) const 176{ 177 if (index >= length()) 178 return 0; 179 180 ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size()); 181 RefPtr<WebKitCSSKeyframeRule>& rule = m_childRuleCSSOMWrappers[index]; 182 if (!rule) 183 rule = adoptRef(new WebKitCSSKeyframeRule(m_keyframesRule->keyframes()[index].get(), const_cast<WebKitCSSKeyframesRule*>(this))); 184 185 return rule.get(); 186} 187 188CSSRuleList* WebKitCSSKeyframesRule::cssRules() 189{ 190 if (!m_ruleListCSSOMWrapper) 191 m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<WebKitCSSKeyframesRule>(this)); 192 return m_ruleListCSSOMWrapper.get(); 193} 194 195void WebKitCSSKeyframesRule::reattach(StyleRuleBase* rule) 196{ 197 ASSERT(rule); 198 ASSERT_WITH_SECURITY_IMPLICATION(rule->isKeyframesRule()); 199 m_keyframesRule = static_cast<StyleRuleKeyframes*>(rule); 200} 201 202} // namespace WebCore 203