animationcontroller.cpp

来自「linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自Web」· C++ 代码 · 共 527 行 · 第 1/2 页

CPP
527
字号
/* * Copyright (C) 2007 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1.  Redistributions of source code must retain the above copyright *     notice, this list of conditions and the following disclaimer.  * 2.  Redistributions in binary form must reproduce the above copyright *     notice, this list of conditions and the following disclaimer in the *     documentation and/or other materials provided with the distribution.  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of *     its contributors may be used to endorse or promote products derived *     from this software without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include "AnimationController.h"#include "AnimationBase.h"#include "AnimationControllerPrivate.h"#include "CSSParser.h"#include "CompositeAnimation.h"#include "EventNames.h"#include "Frame.h"#include "RenderObject.h"#include <wtf/CurrentTime.h>#include <wtf/UnusedParam.h>namespace WebCore {static const double cAnimationTimerDelay = 0.025;static const double cBeginAnimationUpdateTimeNotSet = -1;AnimationControllerPrivate::AnimationControllerPrivate(Frame* frame)    : m_animationTimer(this, &AnimationControllerPrivate::animationTimerFired)    , m_updateRenderingDispatcher(this, &AnimationControllerPrivate::updateRenderingDispatcherFired)    , m_frame(frame)    , m_beginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet)    , m_styleAvailableWaiters(0)    , m_lastStyleAvailableWaiter(0)    , m_responseWaiters(0)    , m_lastResponseWaiter(0)    , m_waitingForAResponse(false){}AnimationControllerPrivate::~AnimationControllerPrivate(){}PassRefPtr<CompositeAnimation> AnimationControllerPrivate::accessCompositeAnimation(RenderObject* renderer){    RefPtr<CompositeAnimation> animation = m_compositeAnimations.get(renderer);    if (!animation) {        animation = CompositeAnimation::create(this);        m_compositeAnimations.set(renderer, animation);    }    return animation;}bool AnimationControllerPrivate::clear(RenderObject* renderer){    // Return false if we didn't do anything OR we are suspended (so we don't try to    // do a setChanged() when suspended).    PassRefPtr<CompositeAnimation> animation = m_compositeAnimations.take(renderer);    if (!animation)        return false;    animation->clearRenderer();    return animation->isSuspended();}void AnimationControllerPrivate::updateAnimationTimer(bool callSetChanged/* = false*/){    double needsService = -1;    bool calledSetChanged = false;    RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();    for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {        RefPtr<CompositeAnimation> compAnim = it->second;        if (!compAnim->isSuspended() && compAnim->hasAnimations()) {            double t = compAnim->willNeedService();            if (t != -1 && (t < needsService || needsService == -1))                needsService = t;            if (needsService == 0) {                if (callSetChanged) {                    Node* node = it->first->node();                    ASSERT(!node || (node->document() && !node->document()->inPageCache()));                    node->setChanged(AnimationStyleChange);                    calledSetChanged = true;                }                else                    break;            }        }    }        if (calledSetChanged)        m_frame->document()->updateRendering();        // If we want service immediately, we start a repeating timer to reduce the overhead of starting    if (needsService == 0) {        if (!m_animationTimer.isActive() || m_animationTimer.repeatInterval() == 0)            m_animationTimer.startRepeating(cAnimationTimerDelay);        return;    }        // If we don't need service, we want to make sure the timer is no longer running    if (needsService < 0) {        if (m_animationTimer.isActive())            m_animationTimer.stop();        return;    }        // Otherwise, we want to start a one-shot timer so we get here again    if (m_animationTimer.isActive())        m_animationTimer.stop();    m_animationTimer.startOneShot(needsService);}void AnimationControllerPrivate::updateRenderingDispatcherFired(Timer<AnimationControllerPrivate>*){    // fire all the events    Vector<EventToDispatch>::const_iterator eventsToDispatchEnd = m_eventsToDispatch.end();    for (Vector<EventToDispatch>::const_iterator it = m_eventsToDispatch.begin(); it != eventsToDispatchEnd; ++it) {        if (it->eventType == eventNames().webkitTransitionEndEvent)            it->element->dispatchWebKitTransitionEvent(it->eventType,it->name, it->elapsedTime);        else            it->element->dispatchWebKitAnimationEvent(it->eventType,it->name, it->elapsedTime);    }        m_eventsToDispatch.clear();        // call setChanged on all the elements    Vector<RefPtr<Node> >::const_iterator nodeChangesToDispatchEnd = m_nodeChangesToDispatch.end();    for (Vector<RefPtr<Node> >::const_iterator it = m_nodeChangesToDispatch.begin(); it != nodeChangesToDispatchEnd; ++it)        (*it)->setChanged(AnimationStyleChange);        m_nodeChangesToDispatch.clear();        if (m_frame)        m_frame->document()->updateRendering();}void AnimationControllerPrivate::startUpdateRenderingDispatcher(){    if (!m_updateRenderingDispatcher.isActive())        m_updateRenderingDispatcher.startOneShot(0);}void AnimationControllerPrivate::addEventToDispatch(PassRefPtr<Element> element, const AtomicString& eventType, const String& name, double elapsedTime){    m_eventsToDispatch.grow(m_eventsToDispatch.size()+1);    EventToDispatch& event = m_eventsToDispatch[m_eventsToDispatch.size()-1];    event.element = element;    event.eventType = eventType;    event.name = name;    event.elapsedTime = elapsedTime;        startUpdateRenderingDispatcher();}void AnimationControllerPrivate::addNodeChangeToDispatch(PassRefPtr<Node> node){    ASSERT(!node || (node->document() && !node->document()->inPageCache()));    if (!node)        return;    m_nodeChangesToDispatch.append(node);    startUpdateRenderingDispatcher();}void AnimationControllerPrivate::animationTimerFired(Timer<AnimationControllerPrivate>*){    // Make sure animationUpdateTime is updated, so that it is current even if no    // styleChange has happened (e.g. accelerated animations)    setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);    // When the timer fires, all we do is call setChanged on all DOM nodes with running animations and then do an immediate    // updateRendering.  It will then call back to us with new information.    updateAnimationTimer(true);}bool AnimationControllerPrivate::isAnimatingPropertyOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const{    RefPtr<CompositeAnimation> animation = m_compositeAnimations.get(renderer);    if (!animation)        return false;    return animation->isAnimatingProperty(property, isRunningNow);}void AnimationControllerPrivate::suspendAnimations(Document* document){    RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();    for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {        RenderObject* renderer = it->first;        RefPtr<CompositeAnimation> compAnim = it->second;        if (renderer->document() == document)            compAnim->suspendAnimations();    }        updateAnimationTimer();}void AnimationControllerPrivate::resumeAnimations(Document* document){    RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();    for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {        RenderObject* renderer = it->first;        RefPtr<CompositeAnimation> compAnim = it->second;        if (renderer->document() == document)            compAnim->resumeAnimations();    }        updateAnimationTimer();}bool AnimationControllerPrivate::pauseAnimationAtTime(RenderObject* renderer, const String& name, double t){    if (!renderer)        return false;    RefPtr<CompositeAnimation> compAnim = accessCompositeAnimation(renderer);    if (!compAnim)        return false;    if (compAnim->pauseAnimationAtTime(name, t)) {        renderer->node()->setChanged(AnimationStyleChange);        startUpdateRenderingDispatcher();        return true;    }    return false;}bool AnimationControllerPrivate::pauseTransitionAtTime(RenderObject* renderer, const String& property, double t){    if (!renderer)        return false;    RefPtr<CompositeAnimation> compAnim = accessCompositeAnimation(renderer);    if (!compAnim)        return false;    if (compAnim->pauseTransitionAtTime(cssPropertyID(property), t)) {        renderer->node()->setChanged(AnimationStyleChange);        startUpdateRenderingDispatcher();        return true;    }    return false;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?