2008-09-29 Chris Marrin <cmarrin@apple.com>
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 29 Sep 2008 21:31:26 +0000 (21:31 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 29 Sep 2008 21:31:26 +0000 (21:31 +0000)
        Reviewed by Dave Hyatt

        Fixed https://bugs.webkit.org/show_bug.cgi?id=20995
        Rewrite keyframe resolution to be like styleForElement()

        Test: animations/lineheight-animation.html

        * css/CSSStyleSelector.cpp:
        (WebCore::CSSStyleSelector::addKeyframeStyle):
        (WebCore::CSSStyleSelector::~CSSStyleSelector):
        (WebCore::CSSStyleSelector::keyframeStylesForAnimation):
        (WebCore::CSSRuleSet::addRulesFromSheet):
        (WebCore::CSSStyleSelector::mapAnimationName):
        * css/CSSStyleSelector.h:
        * page/animation/CompositeAnimation.cpp:
        (WebCore::CompositeAnimation::updateKeyframeAnimations):
        * page/animation/KeyframeAnimation.cpp:
        (WebCore::KeyframeAnimation::KeyframeAnimation):
        (WebCore::KeyframeAnimation::animate):
        (WebCore::KeyframeAnimation::hasAnimationForProperty):
        (WebCore::KeyframeAnimation::sendAnimationEvent):
        (WebCore::KeyframeAnimation::overrideAnimations):
        (WebCore::KeyframeAnimation::resumeOverriddenAnimations):
        (WebCore::KeyframeAnimation::affectsProperty):
        (WebCore::KeyframeAnimation::validateTransformFunctionList):
        * page/animation/KeyframeAnimation.h:
        * rendering/style/Animation.cpp:
        (WebCore::Animation::animationsMatch):
        * rendering/style/Animation.h:
        * rendering/style/KeyframeList.cpp:
        (WebCore::KeyframeList::~KeyframeList):
        (WebCore::KeyframeList::clear):
        (WebCore::KeyframeList::insert):
        * rendering/style/KeyframeList.h:
        (WebCore::KeyframeValue::KeyframeValue):
        (WebCore::KeyframeList::KeyframeList):
        (WebCore::KeyframeList::operator!=):
        (WebCore::KeyframeList::animationName):
        (WebCore::KeyframeList::addProperty):
        (WebCore::KeyframeList::containsProperty):
        (WebCore::KeyframeList::beginProperties):
        (WebCore::KeyframeList::endProperties):
        (WebCore::KeyframeList::isEmpty):
        (WebCore::KeyframeList::size):
        (WebCore::KeyframeList::beginKeyframes):
        (WebCore::KeyframeList::endKeyframes):
        * rendering/style/RenderStyle.h:
        * rendering/style/StyleRareNonInheritedData.cpp:
        * rendering/style/StyleRareNonInheritedData.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@37077 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
LayoutTests/ChangeLog
LayoutTests/animations/lineheight-animation-expected.txt [new file with mode: 0644]
LayoutTests/animations/lineheight-animation.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/css/CSSStyleSelector.cpp
WebCore/css/CSSStyleSelector.h
WebCore/page/animation/CompositeAnimation.cpp
WebCore/page/animation/KeyframeAnimation.cpp
WebCore/page/animation/KeyframeAnimation.h
WebCore/rendering/style/Animation.cpp
WebCore/rendering/style/Animation.h
WebCore/rendering/style/KeyframeList.cpp
WebCore/rendering/style/KeyframeList.h
WebCore/rendering/style/RenderStyle.h
WebCore/rendering/style/StyleRareNonInheritedData.cpp
WebCore/rendering/style/StyleRareNonInheritedData.h

index 2ae3023..517a002 100644 (file)
@@ -1,5 +1,12 @@
 2008-09-29  Chris Marrin  <cmarrin@apple.com>
 
+        Reviewed by Dave Hyatt
+
+        * animations/lineheight-animation-expected.txt: Added.
+        * animations/lineheight-animation.html: Added.
+
+2008-09-29  Chris Marrin  <cmarrin@apple.com>
+
         Reviewed by Eric Seidel
 
         Clean up fix in PropertyWrapperGetter::equals
diff --git a/LayoutTests/animations/lineheight-animation-expected.txt b/LayoutTests/animations/lineheight-animation-expected.txt
new file mode 100644 (file)
index 0000000..9b8589e
--- /dev/null
@@ -0,0 +1,2 @@
+This test performs an animation of the line-height property. It tests whether or not we are properly getting the font-size. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text.
+PASS
diff --git a/LayoutTests/animations/lineheight-animation.html b/LayoutTests/animations/lineheight-animation.html
new file mode 100644 (file)
index 0000000..f6c31c5
--- /dev/null
@@ -0,0 +1,79 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+   "http://www.w3.org/TR/html4/loose.dtd">
+
+<html lang="en">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+  <title>Line Height Test</title>
+  <style type="text/css" media="screen">
+    #box {
+        position: absolute;
+        left: 0;
+        top: 100px;
+        height: 250px;
+        width: 400px;
+        font-family: "arial";
+        font-size: 10px;
+        border: 1px solid black;
+        -webkit-animation-duration: 10s;
+        -webkit-animation-timing-function: linear;
+        -webkit-animation-name: "anim";
+    }
+    @-webkit-keyframes "anim" {
+        from { line-height: 1em; }
+        to   { line-height: 2em; }
+    }
+    </style>
+    <script type="text/javascript" charset="utf-8">
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+    
+    result = "PASS";
+    const defaultTolerance = 1;
+    
+    function isEqual(actual, desired, tolerance)
+    {
+        if (tolerance == undefined || tolerance == 0)
+            tolerance = defaultTolerance;
+        var diff = Math.abs(actual - desired);
+        return diff < tolerance;
+    }
+    
+    function snapshot()
+    {
+        if (result != "PASS")
+            return;
+            
+        var lineHeight = parseInt(window.getComputedStyle(document.getElementById('box')).lineHeight);
+        var expected = 10;
+        if (!isEqual(lineHeight, expected))
+            result = "FAIL(was:"+lineHeight+", expected:"+expected+")";
+    }
+
+    function start()
+    {
+        setTimeout("snapshot()", 100);
+        
+        window.setTimeout(function() {
+            document.getElementById('result').innerHTML = result;
+            if (window.layoutTestController)
+                layoutTestController.notifyDone();
+        }, 300);
+    }
+    
+    document.addEventListener('webkitAnimationStart', start, false);
+    
+  </script>
+</head>
+<body>
+This test performs an animation of the line-height property. It tests whether or not we are properly getting the font-size.
+<div id="box">
+Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. 
+Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. Here is some text. 
+</div>
+<div id="result">
+</div>
+</body>
+</html>
index fea5b58..3ee2e09 100644 (file)
@@ -1,5 +1,57 @@
 2008-09-29  Chris Marrin  <cmarrin@apple.com>
 
+        Reviewed by Dave Hyatt
+
+        Fixed https://bugs.webkit.org/show_bug.cgi?id=20995
+        Rewrite keyframe resolution to be like styleForElement()
+        
+        Test: animations/lineheight-animation.html
+
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::addKeyframeStyle):
+        (WebCore::CSSStyleSelector::~CSSStyleSelector):
+        (WebCore::CSSStyleSelector::keyframeStylesForAnimation):
+        (WebCore::CSSRuleSet::addRulesFromSheet):
+        (WebCore::CSSStyleSelector::mapAnimationName):
+        * css/CSSStyleSelector.h:
+        * page/animation/CompositeAnimation.cpp:
+        (WebCore::CompositeAnimation::updateKeyframeAnimations):
+        * page/animation/KeyframeAnimation.cpp:
+        (WebCore::KeyframeAnimation::KeyframeAnimation):
+        (WebCore::KeyframeAnimation::animate):
+        (WebCore::KeyframeAnimation::hasAnimationForProperty):
+        (WebCore::KeyframeAnimation::sendAnimationEvent):
+        (WebCore::KeyframeAnimation::overrideAnimations):
+        (WebCore::KeyframeAnimation::resumeOverriddenAnimations):
+        (WebCore::KeyframeAnimation::affectsProperty):
+        (WebCore::KeyframeAnimation::validateTransformFunctionList):
+        * page/animation/KeyframeAnimation.h:
+        * rendering/style/Animation.cpp:
+        (WebCore::Animation::animationsMatch):
+        * rendering/style/Animation.h:
+        * rendering/style/KeyframeList.cpp:
+        (WebCore::KeyframeList::~KeyframeList):
+        (WebCore::KeyframeList::clear):
+        (WebCore::KeyframeList::insert):
+        * rendering/style/KeyframeList.h:
+        (WebCore::KeyframeValue::KeyframeValue):
+        (WebCore::KeyframeList::KeyframeList):
+        (WebCore::KeyframeList::operator!=):
+        (WebCore::KeyframeList::animationName):
+        (WebCore::KeyframeList::addProperty):
+        (WebCore::KeyframeList::containsProperty):
+        (WebCore::KeyframeList::beginProperties):
+        (WebCore::KeyframeList::endProperties):
+        (WebCore::KeyframeList::isEmpty):
+        (WebCore::KeyframeList::size):
+        (WebCore::KeyframeList::beginKeyframes):
+        (WebCore::KeyframeList::endKeyframes):
+        * rendering/style/RenderStyle.h:
+        * rendering/style/StyleRareNonInheritedData.cpp:
+        * rendering/style/StyleRareNonInheritedData.h:
+
+2008-09-29  Chris Marrin  <cmarrin@apple.com>
+
         Reviewed by Eric Seidel
 
         Clean up fix in PropertyWrapperGetter::equals
index ff05403..ef5e1bd 100644 (file)
@@ -444,54 +444,10 @@ CSSStyleSelector::CSSStyleSelector(Document* doc, const String& userStyleSheet,
 }
 
 // This is a simplified style setting function for keyframe styles
-void CSSStyleSelector::addKeyframeStyle(Document* doc, const WebKitCSSKeyframesRule* rule)
+void CSSStyleSelector::addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule)
 {
-    // Create the keyframe list
     AtomicString s(rule->name());
-    RefPtr<KeyframeList> list;
-    if (m_keyframeRuleMap.contains(s.impl()))
-        list = m_keyframeRuleMap.get(s.impl()).get();
-    else {
-        list = KeyframeList::create(s);
-        m_keyframeRuleMap.add(s.impl(), list);
-    }
-    list->clear();
-
-    // Add all the keyframes
-    for (unsigned i = 0; i < rule->length(); ++i) {
-        const WebKitCSSKeyframeRule* kf = rule->item(i);
-        m_style = new (doc->renderArena()) RenderStyle();
-        m_style->ref();
-        CSSMutableStyleDeclaration* decl = kf->style();
-        DeprecatedValueListConstIterator<CSSProperty> end;
-
-        // Record all the properties in this keyframe
-        for (DeprecatedValueListConstIterator<CSSProperty> it = decl->valuesIterator(); it != end; ++it) {
-            const CSSProperty& current = *it;
-            applyProperty(current.id(), current.value());
-            list->addProperty(current.id());
-        }
-
-        // Add this keyframe to all the indicated key times
-        Vector<float> keys;
-        kf->getKeys(keys);
-
-        for (size_t keyIndex = 0; keyIndex < keys.size(); ++keyIndex) {
-            float key = keys[keyIndex];
-            list->insert(key, *m_style);
-        }
-
-        m_style->deref(doc->renderArena());
-        m_style = 0;
-    }
-
-    // Make sure there is a 0% and a 100% keyframe
-    float first = list->beginKeyframes()->key;
-    float last = (list->endKeyframes()-1)->key;
-    if (first != 0 || last != 1) {
-        list->clear();
-        return;
-    }
+    m_keyframesRuleMap.add(s.impl(), rule);
 }
 
 void CSSStyleSelector::init()
@@ -511,7 +467,7 @@ CSSStyleSelector::~CSSStyleSelector()
     delete m_authorStyle;
     delete m_userStyle;
     deleteAllValues(m_viewportDependentMediaQueryResults);
-    m_keyframeRuleMap.clear();
+    m_keyframesRuleMap.clear();
 }
 
 static CSSStyleSheet* parseUASheet(const char* characters, unsigned size)
@@ -1222,6 +1178,77 @@ RenderStyle* CSSStyleSelector::styleForElement(Element* e, RenderStyle* defaultP
     return m_style;
 }
 
+void CSSStyleSelector::keyframeStylesForAnimation(Element* e, const RenderStyle* elementStyle, KeyframeList& list)
+{
+    list.clear();
+    
+    // Get the keyframesRule for this name
+    if (!e || list.animationName().isEmpty())
+        return;
+            
+    if (!m_keyframesRuleMap.contains(list.animationName().impl()))
+        return;
+        
+    const WebKitCSSKeyframesRule* rule = m_keyframesRuleMap.find(list.animationName().impl()).get()->second.get();
+    
+    // Construct and populate the style for each keyframe
+    for (unsigned i = 0; i < rule->length(); ++i) {
+        // Apply the declaration to the style. This is a simplified version of the logic in styleForElement
+        initElementAndPseudoState(e);
+        initForStyleResolve(e);
+        
+        const WebKitCSSKeyframeRule* kf = rule->item(i);
+        addMatchedDeclaration(kf->style());
+
+        // Create the style
+        m_style = new (e->document()->renderArena()) RenderStyle(*elementStyle);
+        m_style->ref();
+        
+        m_lineHeightValue = 0;
+        
+        // We don't need to bother with !important. Since there is only ever one
+        // decl, there's nothing to override. So just add the first properties.
+        applyDeclarations(true, false, 0, m_matchedDecls.size() - 1);
+        
+        // If our font got dirtied, go ahead and update it now.
+        if (m_fontDirty)
+            updateFont();
+
+        // Line-height is set when we are sure we decided on the font-size
+        if (m_lineHeightValue)
+            applyProperty(CSSPropertyLineHeight, m_lineHeightValue);
+        
+        // Now do rest of the properties.
+        applyDeclarations(false, false, 0, m_matchedDecls.size() - 1);
+        
+        // If our font got dirtied by one of the non-essential font props, 
+        // go ahead and update it a second time.
+        if (m_fontDirty)
+            updateFont();
+
+        // Add all the animating properties to the list
+        DeprecatedValueListConstIterator<CSSProperty> end;
+        for (DeprecatedValueListConstIterator<CSSProperty> it = kf->style()->valuesIterator(); it != end; ++it)
+            list.addProperty((*it).id());
+        
+        // Add this keyframe style to all the indicated key times
+        Vector<float> keys;
+        kf->getKeys(keys);
+        for (size_t keyIndex = 0; keyIndex < keys.size(); ++keyIndex) {
+            float key = keys[keyIndex];
+            list.insert(key, m_style);
+        }
+        m_style->deref(e->document()->renderArena());
+        m_style = 0;
+    }
+    
+    // Make sure there is a 0% and a 100% keyframe
+    float first = list.beginKeyframes()->key;
+    float last = (list.endKeyframes()-1)->key;
+    if (first != 0 || last != 1)
+        list.clear();
+}
+
 RenderStyle* CSSStyleSelector::pseudoStyleForElement(RenderStyle::PseudoId pseudo, Element* e, RenderStyle* parentStyle)
 {
     if (!e)
@@ -2415,8 +2442,7 @@ void CSSRuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluat
                         styleSelector->fontSelector()->addFontFaceRule(fontFaceRule);
                     } else if (childItem->isKeyframesRule() && styleSelector) {
                         // Add this keyframe rule to our set.
-                        const WebKitCSSKeyframesRule* keyframesRule = static_cast<WebKitCSSKeyframesRule*>(childItem);
-                        styleSelector->addKeyframeStyle(sheet->doc(), keyframesRule);
+                        styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(childItem));
                     }
                 }   // for rules
             }   // if rules
@@ -2429,10 +2455,8 @@ void CSSRuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluat
             CSSVariablesRule* variables = static_cast<CSSVariablesRule*>(item);
             if (!variables->media() || medium.eval(variables->media(), styleSelector))
                 styleSelector->addVariables(variables);
-        } else if (item->isKeyframesRule()) {
-            WebKitCSSKeyframesRule* r = static_cast<WebKitCSSKeyframesRule*>(item);
-            styleSelector->addKeyframeStyle(sheet->doc(), r);
-        }
+        } else if (item->isKeyframesRule())
+            styleSelector->addKeyframeStyle(static_cast<WebKitCSSKeyframesRule*>(item));
     }
 }
 
@@ -5111,15 +5135,10 @@ void CSSStyleSelector::mapAnimationName(Animation* layer, CSSValue* value)
 
     CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
     
-    if (primitiveValue->getIdent() == CSSValueNone) {
+    if (primitiveValue->getIdent() == CSSValueNone)
         layer->setIsNoneAnimation(true);
-    } else {
+    else
         layer->setName(primitiveValue->getStringValue());
-    
-        // resolve to the keyframes
-        RefPtr<KeyframeList> keyframe = findKeyframeRule(primitiveValue->getStringValue());
-        layer->setAnimationKeyframe(keyframe);
-    }
 }
 
 void CSSStyleSelector::mapAnimationPlayState(Animation* layer, CSSValue* value)
index 20a4050..11f61cd 100644 (file)
@@ -84,6 +84,7 @@ public:
         void initElementAndPseudoState(Element*);
         void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, RenderStyle::PseudoId = RenderStyle::NOPSEUDO);
         RenderStyle* styleForElement(Element*, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false);
+        void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList& list);
 
         RenderStyle* pseudoStyleForElement(RenderStyle::PseudoId, Element*, RenderStyle* parentStyle = 0);
 
@@ -139,18 +140,7 @@ public:
         CSSValue* resolveVariableDependentValue(CSSVariableDependentValue*);
         void resolveVariablesForDeclaration(CSSMutableStyleDeclaration* decl, CSSMutableStyleDeclaration* newDecl, HashSet<String>& usedBlockVariables);
 
-        KeyframeList* findKeyframeRule(const String& name) const
-        {
-            if (name.isEmpty())
-                return 0;
-            
-            AtomicString s(name);
-            if (!m_keyframeRuleMap.contains(s.impl()))
-                return 0;
-            return m_keyframeRuleMap.find(s.impl()).get()->second.get();
-        }
-
-        void addKeyframeStyle(Document* doc, const WebKitCSSKeyframesRule* rule);
+        void addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule);
 
         static bool createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, TransformOperations& outOperations);
 
@@ -182,8 +172,8 @@ public:
         FillLayer m_backgroundData;
         Color m_backgroundColor;
 
-        typedef HashMap<AtomicStringImpl*, RefPtr<KeyframeList> > KeyframeRuleMap;
-        KeyframeRuleMap m_keyframeRuleMap;
+        typedef HashMap<AtomicStringImpl*, RefPtr<WebKitCSSKeyframesRule> > KeyframesRuleMap;
+        KeyframesRuleMap m_keyframesRuleMap;
 
     public:
         static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
index 496d714..f51545a 100644 (file)
@@ -33,7 +33,6 @@
 #include "CSSPropertyNames.h"
 #include "ImplicitAnimation.h"
 #include "KeyframeAnimation.h"
-#include "KeyframeList.h"
 #include "RenderObject.h"
 #include "RenderStyle.h"
 
@@ -154,8 +153,7 @@ void CompositeAnimation::updateKeyframeAnimations(RenderObject* renderer, const
                 // Set the saved animation to this new one, just in case the play state has changed
                 keyframeAnim->setAnimation(anim);
                 keyframeAnim->setIndex(i);
-            } else if ((anim->duration() || anim->delay()) && anim->iterationCount()
-                        && anim->keyframeList() && !anim->keyframeList()->isEmpty()) {
+            } else if ((anim->duration() || anim->delay()) && anim->iterationCount()) {
                 keyframeAnim = new KeyframeAnimation(const_cast<Animation*>(anim), renderer, i, this, currentStyle ? currentStyle : targetStyle);
                 m_keyframeAnimations.set(keyframeAnim->name().impl(), keyframeAnim);
             }
index 1278874..80a4d66 100644 (file)
@@ -30,6 +30,7 @@
 #include "KeyframeAnimation.h"
 
 #include "CSSPropertyNames.h"
+#include "CSSStyleSelector.h"
 #include "CompositeAnimation.h"
 #include "EventNames.h"
 #include "RenderObject.h"
 
 namespace WebCore {
 
+KeyframeAnimation::KeyframeAnimation(const Animation* animation, RenderObject* renderer, int index, CompositeAnimation* compAnim, const RenderStyle* unanimatedStyle)
+    : AnimationBase(animation, renderer, compAnim)
+    , m_keyframes(renderer, animation->name())
+    , m_index(index)
+    , m_unanimatedStyle(0)
+{
+    // Set the transform animation list
+    validateTransformFunctionList();
+    
+    if (unanimatedStyle) {
+        const_cast<RenderStyle*>(unanimatedStyle)->ref();
+        m_unanimatedStyle = unanimatedStyle;
+    }
+    
+    // Get the keyframe RenderStyles
+    if (m_object && m_object->element() && m_object->element()->isElementNode())
+        m_object->document()->styleSelector()->keyframeStylesForAnimation(static_cast<Element*>(m_object->element()), unanimatedStyle, m_keyframes);
+}
+
 KeyframeAnimation::~KeyframeAnimation()
 {
     // Do the cleanup here instead of in the base class so the specialized methods get called
@@ -83,21 +103,19 @@ void KeyframeAnimation::animate(CompositeAnimation* animation, RenderObject* ren
     RenderStyle* toStyle = 0;
     double scale = 1;
     double offset = 0;
-    if (m_keyframes.get()) {
-        Vector<KeyframeValue>::const_iterator end = m_keyframes->endKeyframes();
-        for (Vector<KeyframeValue>::const_iterator it = m_keyframes->beginKeyframes(); it != end; ++it) {
-            if (t < it->key) {
-                // The first key should always be 0, so we should never succeed on the first key
-                if (!fromStyle)
-                    break;
-                scale = 1.0 / (it->key - offset);
-                toStyle = const_cast<RenderStyle*>(&(it->style));
+    Vector<KeyframeValue>::const_iterator endKeyframes = m_keyframes.endKeyframes();
+    for (Vector<KeyframeValue>::const_iterator it = m_keyframes.beginKeyframes(); it != endKeyframes; ++it) {
+        if (t < it->key) {
+            // The first key should always be 0, so we should never succeed on the first key
+            if (!fromStyle)
                 break;
-            }
-
-            offset = it->key;
-            fromStyle = const_cast<RenderStyle*>(&(it->style));
+            scale = 1.0 / (it->key - offset);
+            toStyle = it->style;
+            break;
         }
+
+        offset = it->key;
+        fromStyle = it->style;
     }
 
     // If either style is 0 we have an invalid case, just stop the animation.
@@ -117,8 +135,8 @@ void KeyframeAnimation::animate(CompositeAnimation* animation, RenderObject* ren
 
     double prog = progress(scale, offset, timingFunction);
 
-    HashSet<int>::const_iterator end = m_keyframes->endProperties();
-    for (HashSet<int>::const_iterator it = m_keyframes->beginProperties(); it != end; ++it) {
+    HashSet<int>::const_iterator endProperties = m_keyframes.endProperties();
+    for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) {
         if (blendProperties(this, *it, animatedStyle, fromStyle, toStyle, prog))
             setAnimating();
     }
@@ -126,8 +144,8 @@ void KeyframeAnimation::animate(CompositeAnimation* animation, RenderObject* ren
 
 bool KeyframeAnimation::hasAnimationForProperty(int property) const
 {
-    HashSet<int>::const_iterator end = m_keyframes->endProperties();
-    for (HashSet<int>::const_iterator it = m_keyframes->beginProperties(); it != end; ++it) {
+    HashSet<int>::const_iterator end = m_keyframes.endProperties();
+    for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it) {
         if (*it == property)
             return true;
     }
@@ -180,7 +198,7 @@ bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double
     if (shouldSendEventForListener(listenerType)) {
         if (Element* element = elementForEventDispatch()) {
             m_waitingForEndEvent = true;
-            m_animationEventDispatcher.startTimer(element, m_name, -1, true, eventType, elapsedTime);
+            m_animationEventDispatcher.startTimer(element, m_keyframes.animationName(), -1, true, eventType, elapsedTime);
             return true; // Did dispatch an event
         }
     }
@@ -191,23 +209,23 @@ bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double
 void KeyframeAnimation::overrideAnimations()
 {
     // This will override implicit animations that match the properties in the keyframe animation
-    HashSet<int>::const_iterator end = m_keyframes->endProperties();
-    for (HashSet<int>::const_iterator it = m_keyframes->beginProperties(); it != end; ++it)
+    HashSet<int>::const_iterator end = m_keyframes.endProperties();
+    for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it)
         compositeAnimation()->overrideImplicitAnimations(*it);
 }
 
 void KeyframeAnimation::resumeOverriddenAnimations()
 {
     // This will resume overridden implicit animations
-    HashSet<int>::const_iterator end = m_keyframes->endProperties();
-    for (HashSet<int>::const_iterator it = m_keyframes->beginProperties(); it != end; ++it)
+    HashSet<int>::const_iterator end = m_keyframes.endProperties();
+    for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it)
         compositeAnimation()->resumeOverriddenImplicitAnimations(*it);
 }
 
 bool KeyframeAnimation::affectsProperty(int property) const
 {
-    HashSet<int>::const_iterator end = m_keyframes->endProperties();
-    for (HashSet<int>::const_iterator it = m_keyframes->beginProperties(); it != end; ++it) {
+    HashSet<int>::const_iterator end = m_keyframes.endProperties();
+    for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it) {
         if (*it == property)
             return true;
     }
@@ -218,17 +236,17 @@ void KeyframeAnimation::validateTransformFunctionList()
 {
     m_transformFunctionListValid = false;
     
-    if (!m_keyframes.get() || m_keyframes->size() < 2 || !m_keyframes->containsProperty(CSSPropertyWebkitTransform))
+    if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyWebkitTransform))
         return;
 
-    Vector<KeyframeValue>::const_iterator end = m_keyframes->endKeyframes();
+    Vector<KeyframeValue>::const_iterator end = m_keyframes.endKeyframes();
 
     // Empty transforms match anything, so find the first non-empty entry as the reference
     size_t firstIndex = 0;
     Vector<KeyframeValue>::const_iterator firstIt = end;
     
-    for (Vector<KeyframeValue>::const_iterator it = m_keyframes->beginKeyframes(); it != end; ++it, ++firstIndex) {
-        if (it->style.transform().operations().size() > 0) {
+    for (Vector<KeyframeValue>::const_iterator it = m_keyframes.beginKeyframes(); it != end; ++it, ++firstIndex) {
+        if (it->style->transform().operations().size() > 0) {
             firstIt = it;
             break;
         }
@@ -237,11 +255,11 @@ void KeyframeAnimation::validateTransformFunctionList()
     if (firstIt == end)
         return;
         
-    const TransformOperations* firstVal = &firstIt->style.transform();
+    const TransformOperations* firstVal = &firstIt->style->transform();
     
     // See if the keyframes are valid
     for (Vector<KeyframeValue>::const_iterator it = firstIt+1; it != end; ++it) {
-        const TransformOperations* val = &it->style.transform();
+        const TransformOperations* val = &it->style->transform();
         
         // A null transform matches anything
         if (val->operations().isEmpty())
index 70a65f7..8ee5e90 100644 (file)
@@ -40,28 +40,12 @@ namespace WebCore {
 // for a single RenderObject.
 class KeyframeAnimation : public AnimationBase {
 public:
-    KeyframeAnimation(const Animation* animation, RenderObject* renderer, int index, CompositeAnimation* compAnim, const RenderStyle* unanimatedStyle)
-        : AnimationBase(animation, renderer, compAnim)
-        , m_keyframes(animation->keyframeList())
-        , m_name(animation->name())
-        , m_index(index)
-        , m_unanimatedStyle(0)
-    {
-        // Set the transform animation list
-        validateTransformFunctionList();
-        
-        if (unanimatedStyle) {
-            const_cast<RenderStyle*>(unanimatedStyle)->ref();
-            m_unanimatedStyle = unanimatedStyle;
-        }
-    }
-
+    KeyframeAnimation(const Animation* animation, RenderObject* renderer, int index, CompositeAnimation* compAnim, const RenderStyle* unanimatedStyle);
     virtual ~KeyframeAnimation();
 
     virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, const RenderStyle* targetStyle, RenderStyle*& animatedStyle);
 
-    void setName(const String& s) { m_name = s; }
-    const AtomicString& name() const { return m_name; }
+    const AtomicString& name() const { return m_keyframes.animationName(); }
     int index() const { return m_index; }
     void setIndex(int i) { m_index = i; }
 
@@ -89,8 +73,8 @@ protected:
 
 private:
     // The keyframes that we are blending.
-    RefPtr<KeyframeList> m_keyframes;
-    AtomicString m_name;
+    KeyframeList m_keyframes;
+
     // The order in which this animation appears in the animation-name style.
     int m_index;
 
index 326ce08..ed3a7e7 100644 (file)
@@ -22,7 +22,6 @@
 #include "config.h"
 #include "Animation.h"
 
-#include "KeyframeList.h"
 #include "RenderStyle.h"
 
 namespace WebCore {
@@ -123,25 +122,7 @@ bool Animation::animationsMatch(const Animation* o, bool matchPlayStates) const
     if (!result)
         return false;
 
-    if (matchPlayStates && (m_playState != o->m_playState || m_playStateSet != o->m_playStateSet))
-        return false;
-
-    // now check keyframes
-    if ((m_keyframeList.get() && !o->m_keyframeList.get()) || (!m_keyframeList.get() && o->m_keyframeList.get()))
-        return false;
-    if (!(m_keyframeList.get()))
-        return true;
-    return *m_keyframeList == *o->m_keyframeList;
-}
-
-const RefPtr<KeyframeList>& Animation::keyframeList() const
-{
-    return m_keyframeList;
-}
-
-void Animation::setAnimationKeyframe(const RefPtr<KeyframeList> keyframeList)
-{
-    m_keyframeList = keyframeList;
+    return !matchPlayStates || (m_playState == o->m_playState && m_playStateSet == o->m_playStateSet);
 }
 
 } // namespace WebCore
index 488d5cc..8930e30 100644 (file)
@@ -32,8 +32,6 @@
 
 namespace WebCore {
 
-class KeyframeList;
-
 class Animation : public RefCounted<Animation> {
 public:
     ~Animation();
@@ -84,8 +82,6 @@ public:
     int property() const { return m_property; }
     const TimingFunction& timingFunction() const { return m_timingFunction; }
 
-    const RefPtr<KeyframeList>& keyframeList() const;
-
     void setDelay(double c) { m_delay = c; m_delaySet = true; }
     void setDirection(bool d) { m_direction = d; m_directionSet = true; }
     void setDuration(double d) { ASSERT(d >= 0); m_duration = d; m_durationSet = true; }
@@ -97,8 +93,6 @@ public:
 
     void setIsNoneAnimation(bool n) { m_isNone = n; }
 
-    void setAnimationKeyframe(const RefPtr<KeyframeList> keyframe);
-
     Animation& operator=(const Animation& o);
 
     // return true if all members of this class match (excluding m_next)
@@ -120,8 +114,6 @@ private:
     int m_property;
     TimingFunction m_timingFunction;
 
-    RefPtr<KeyframeList> m_keyframeList;
-
     unsigned m_playState     : 2;
 
     bool m_delaySet          : 1;
index b81952a..e1f8b47 100644 (file)
 
 #include "config.h"
 #include "KeyframeList.h"
+#include "RenderObject.h"
 
 namespace WebCore {
 
+KeyframeList::~KeyframeList()
+{
+    clear();
+}
+
+void KeyframeList::clear()
+{
+    for (Vector<KeyframeValue>::const_iterator it = m_keyframes.begin(); it != m_keyframes.end(); ++it)
+        if (it->style)
+            it->style->deref(m_renderer->renderArena());
+
+    m_keyframes.clear();
+    m_properties.clear();
+}
+
 bool KeyframeList::operator==(const KeyframeList& o) const
 {
     if (m_keyframes.size() != o.m_keyframes.size())
@@ -43,29 +59,38 @@ bool KeyframeList::operator==(const KeyframeList& o) const
     return true;
 }
 
-void KeyframeList::insert(float inKey, const RenderStyle& inStyle)
+void KeyframeList::insert(float key, RenderStyle* style)
 {
-    if (inKey < 0 || inKey > 1)
+    if (key < 0 || key > 1)
         return;
 
+    int index = -1;
+    
     for (size_t i = 0; i < m_keyframes.size(); ++i) {
-        if (m_keyframes[i].key == inKey) {
-            m_keyframes[i].style = inStyle;
-            return;
+        if (m_keyframes[i].key == key) {
+            index = (int) i;
+            break;
         }
-        if (m_keyframes[i].key > inKey) {
+        if (m_keyframes[i].key > key) {
             // insert before
             m_keyframes.insert(i, KeyframeValue());
-            m_keyframes[i].key = inKey;
-            m_keyframes[i].style = inStyle;
-            return;
+            index = (int) i;
+            break;
         }
     }
-
-    // append
-    m_keyframes.append(KeyframeValue());
-    m_keyframes[m_keyframes.size()-1].key = inKey;
-    m_keyframes[m_keyframes.size()-1].style = inStyle;
+    
+    if (index < 0) {
+        // append
+        index = (int) m_keyframes.size();
+        m_keyframes.append(KeyframeValue());
+    }
+    
+    if (style)
+        style->ref();
+    if (m_keyframes[index].style)
+        m_keyframes[index].style->deref(m_renderer->renderArena());
+    m_keyframes[index].key = key;
+    m_keyframes[index].style = style;
 }
 
 } // namespace WebCore
index f89e93f..11c0250 100644 (file)
 #define KeyframeList_h
 
 #include "AtomicString.h"
-#include "RenderStyle.h"
 #include <wtf/Vector.h>
 #include <wtf/HashSet.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
 
 namespace WebCore {
 
+class RenderObject;
+class RenderStyle;
+
 class KeyframeValue {
 public:
     KeyframeValue()
         : key(-1)
+        , style(0)
     {
     }
 
     float key;
-    RenderStyle style;
+    RenderStyle* style;
 };
 
-class KeyframeList : public RefCounted<KeyframeList> {
+class KeyframeList {
 public:
-    static PassRefPtr<KeyframeList> create(const AtomicString& animationName) { return adoptRef(new KeyframeList(animationName)); }
-
+    KeyframeList(RenderObject* renderer, const AtomicString& animationName)
+        : m_animationName(animationName)
+        , m_renderer(renderer)
+    {
+        insert(0, 0);
+        insert(1, 0);
+    }
+    ~KeyframeList();
+        
     bool operator==(const KeyframeList& o) const;
     bool operator!=(const KeyframeList& o) const { return !(*this == o); }
     
     const AtomicString& animationName() const { return m_animationName; }
     
-    void insert(float inKey, const RenderStyle& inStyle);
+    void insert(float key, RenderStyle* style);
     
     void addProperty(int prop) { m_properties.add(prop); }
     bool containsProperty(int prop) const { return m_properties.contains(prop); }
-    HashSet<int>::const_iterator beginProperties() { return m_properties.begin(); }
-    HashSet<int>::const_iterator endProperties() { return m_properties.end(); }
+    HashSet<int>::const_iterator beginProperties() const { return m_properties.begin(); }
+    HashSet<int>::const_iterator endProperties() const { return m_properties.end(); }
     
-    void clear() { m_keyframes.clear(); m_properties.clear(); }
+    void clear();
     bool isEmpty() const { return m_keyframes.isEmpty(); }
     size_t size() const { return m_keyframes.size(); }
     Vector<KeyframeValue>::const_iterator beginKeyframes() const { return m_keyframes.begin(); }
     Vector<KeyframeValue>::const_iterator endKeyframes() const { return m_keyframes.end(); }
 
 private:
-    KeyframeList(const AtomicString& animationName)
-        : m_animationName(animationName)
-    {
-        insert(0, RenderStyle());
-        insert(1, RenderStyle());
-    }
-        
     AtomicString m_animationName;
     Vector<KeyframeValue> m_keyframes;
     HashSet<int> m_properties;       // the properties being animated
+    RenderObject* m_renderer;
 };
 
 } // namespace WebCore
index 81eacc8..7101f1f 100644 (file)
@@ -945,7 +945,6 @@ public:
     void inheritTransitions(const AnimationList* parent) { rareNonInheritedData.access()->m_transitions.set(parent ? new AnimationList(*parent) : 0); }
     void adjustAnimations();
     void adjustTransitions();
-    void updateKeyframes(const CSSStyleSelector* styleSelector) { if (rareNonInheritedData.get()) rareNonInheritedData.access()->updateKeyframes(styleSelector); }
 
     void setLineClamp(int c) { SET_VAR(rareNonInheritedData, lineClamp, c); }
     void setTextSizeAdjust(bool b) { SET_VAR(rareInheritedData, textSizeAdjust, b); }
index c9a7dcf..e8ceeeb 100644 (file)
@@ -23,7 +23,6 @@
 #include "StyleRareNonInheritedData.h"
 
 #include "CSSStyleSelector.h"
-#include "KeyframeList.h"
 #include "RenderStyle.h"
 
 namespace WebCore {
@@ -147,18 +146,6 @@ bool StyleRareNonInheritedData::reflectionDataEquivalent(const StyleRareNonInher
 
 }
 
-void StyleRareNonInheritedData::updateKeyframes(const CSSStyleSelector* styleSelector)
-{
-    if (m_animations) {
-        for (size_t i = 0; i < m_animations->size(); ++i) {
-            if (m_animations->animation(i)->isValidAnimation()) {
-                RefPtr<KeyframeList> keyframe = styleSelector->findKeyframeRule(m_animations->animation(i)->name());
-                m_animations->animation(i)->setAnimationKeyframe(keyframe);
-            }
-        }
-    }
-}
-
 bool StyleRareNonInheritedData::animationDataEquivalent(const StyleRareNonInheritedData& o) const
 {
     if (!m_animations && o.m_animations || m_animations && !o.m_animations)
index 9953a1f..c41dbc3 100644 (file)
@@ -74,7 +74,6 @@ public:
     bool reflectionDataEquivalent(const StyleRareNonInheritedData& o) const;
     bool animationDataEquivalent(const StyleRareNonInheritedData&) const;
     bool transitionDataEquivalent(const StyleRareNonInheritedData&) const;
-    void updateKeyframes(const CSSStyleSelector* styleSelector);
 
     int lineClamp; // An Apple extension.
 #if ENABLE(DASHBOARD_SUPPORT)