15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2007, 2008, 2012 Apple Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "core/css/CSSKeyframeRule.h"
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "core/css/CSSKeyframesRule.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/PropertySetCSSStyleDeclaration.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/StylePropertySet.h"
327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "core/css/parser/CSSParser.h"
3309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/frame/UseCounter.h"
345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "wtf/text/StringBuilder.h"
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
38926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)StyleKeyframe::StyleKeyframe()
39926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
42926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)StyleKeyframe::~StyleKeyframe()
43926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
45926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
468abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)String StyleKeyframe::keyText() const
478abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles){
488abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (m_keyText.isNull()) {
498abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        // Keys are always set when these objects are created.
508abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        ASSERT(m_keys && !m_keys->isEmpty());
518abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        StringBuilder keyText;
528abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        for (unsigned i = 0; i < m_keys->size(); ++i) {
538abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            if (i)
548abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)                keyText.append(',');
557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            keyText.appendNumber(m_keys->at(i) * 100);
568abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            keyText.append('%');
578abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        }
588abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        m_keyText = keyText.toString();
598abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    }
608abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    ASSERT(!m_keyText.isNull());
618abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    return m_keyText;
628abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)}
638abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
648abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)void StyleKeyframe::setKeyText(const String& keyText)
658abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles){
668abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // FIXME: Should we trim whitespace?
678abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // FIXME: Should we leave keyText unchanged when attempting to set to an
688abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // invalid string?
698abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    ASSERT(!keyText.isNull());
708abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    m_keyText = keyText;
718abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    m_keys.clear();
728abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)}
738abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
748abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)const Vector<double>& StyleKeyframe::keys() const
758abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles){
768abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    if (!m_keys) {
778abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        // Keys can only be cleared by setting the key text from JavaScript
788abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        // and this can never be null.
798abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        ASSERT(!m_keyText.isNull());
807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_keys = CSSParser::parseKeyframeKeyList(m_keyText);
818abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    }
828abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    // If an invalid key string was set, m_keys may be empty.
838abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    ASSERT(m_keys);
848abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    return *m_keys;
858abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)}
868abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
878abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)void StyleKeyframe::setKeys(PassOwnPtr<Vector<double> > keys)
888abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles){
898abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    ASSERT(keys && !keys->isEmpty());
908abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    m_keys = keys;
918abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    m_keyText = String();
928abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    ASSERT(m_keyText.isNull());
938abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)}
948abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
95d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)MutableStylePropertySet& StyleKeyframe::mutableProperties()
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_properties->isMutable())
9893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        m_properties = m_properties->mutableCopy();
99197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return *toMutableStylePropertySet(m_properties.get());
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1015267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
102197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid StyleKeyframe::setProperties(PassRefPtrWillBeRawPtr<StylePropertySet> properties)
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
104d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(properties);
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_properties = properties;
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String StyleKeyframe::cssText() const
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    StringBuilder result;
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result.append(keyText());
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result.appendLiteral(" { ");
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String decls = m_properties->asText();
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result.append(decls);
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!decls.isEmpty())
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result.append(' ');
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    result.append('}');
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result.toString();
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1218abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)PassOwnPtr<Vector<double> > StyleKeyframe::createKeyList(CSSParserValueList* keys)
1228abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles){
1238abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    OwnPtr<Vector<double> > keyVector = adoptPtr(new Vector<double>(keys->size()));
1248abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    for (unsigned i = 0; i < keys->size(); ++i) {
125c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        ASSERT(keys->valueAt(i)->unit == blink::CSSPrimitiveValue::CSS_NUMBER);
1268abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        double key = keys->valueAt(i)->fValue;
1278abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        if (key < 0 || key > 100) {
1288abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            // As per http://www.w3.org/TR/css3-animations/#keyframes,
1298abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            // "If a keyframe selector specifies negative percentage values
1308abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            // or values higher than 100%, then the keyframe will be ignored."
1318abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            keyVector->clear();
1328abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            break;
1338abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        }
1348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        keyVector->at(i) = key / 100;
1358abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    }
1368abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    return keyVector.release();
1378abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)}
1388abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
139197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid StyleKeyframe::trace(Visitor* visitor)
140197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
141197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    visitor->trace(m_properties);
142197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
1438abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
1445267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)CSSKeyframeRule::CSSKeyframeRule(StyleKeyframe* keyframe, CSSKeyframesRule* parent)
145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    : CSSRule(0)
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_keyframe(keyframe)
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setParentRule(parent);
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1515267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)CSSKeyframeRule::~CSSKeyframeRule()
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
153323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#if !ENABLE(OILPAN)
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_propertiesCSSOMWrapper)
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_propertiesCSSOMWrapper->clearParentRule();
156323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)#endif
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)CSSStyleDeclaration* CSSKeyframeRule::style() const
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_propertiesCSSOMWrapper)
1625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        m_propertiesCSSOMWrapper = StyleRuleCSSStyleDeclaration::create(m_keyframe->mutableProperties(), const_cast<CSSKeyframeRule*>(this));
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_propertiesCSSOMWrapper.get();
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)void CSSKeyframeRule::reattach(StyleRuleBase*)
167926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
168926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    // No need to reattach, the underlying data is shareable on mutation.
169926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ASSERT_NOT_REACHED();
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
17207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochvoid CSSKeyframeRule::trace(Visitor* visitor)
17307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
17407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    visitor->trace(m_keyframe);
175323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    visitor->trace(m_propertiesCSSOMWrapper);
17607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    CSSRule::trace(visitor);
17707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}
17807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
179c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
180