Index: Source/WebCore/dom/Document.cpp |
=================================================================== |
--- Source/WebCore/dom/Document.cpp (revision 78732) |
+++ Source/WebCore/dom/Document.cpp (working copy) |
@@ -209,6 +209,7 @@ |
#if ENABLE(REQUEST_ANIMATION_FRAME) |
#include "RequestAnimationFrameCallback.h" |
+#include "ScriptedAnimationController.h" |
#endif |
using namespace std; |
@@ -429,9 +430,6 @@ |
, m_loadEventDelayTimer(this, &Document::loadEventDelayTimerFired) |
, m_directionSetOnDocumentElement(false) |
, m_writingModeSetOnDocumentElement(false) |
-#if ENABLE(REQUEST_ANIMATION_FRAME) |
- , m_nextRequestAnimationFrameCallbackId(0) |
-#endif |
{ |
m_document = this; |
@@ -4732,6 +4730,22 @@ |
callOnMainThread(performTask, new PerformTaskContext(m_weakReference, task)); |
} |
+void Document::suspendScriptedAnimationControllerCallbacks() |
+{ |
+#if ENABLE(REQUEST_ANIMATION_FRAME) |
+ if (m_scriptedAnimationController) |
+ m_scriptedAnimationController->suspend(); |
+#endif |
+} |
+ |
+void Document::resumeScriptedAnimationControllerCallbacks() |
+{ |
+#if ENABLE(REQUEST_ANIMATION_FRAME) |
+ if (m_scriptedAnimationController) |
+ m_scriptedAnimationController->resume(); |
+#endif |
+} |
+ |
Element* Document::findAnchor(const String& name) |
{ |
if (name.isEmpty()) |
@@ -4962,82 +4976,26 @@ |
} |
#if ENABLE(REQUEST_ANIMATION_FRAME) |
-int Document::webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback> callback, Element* e) |
+int Document::webkitRequestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback> callback, Element* animationElement) |
{ |
- if (!m_requestAnimationFrameCallbacks) |
- m_requestAnimationFrameCallbacks = new RequestAnimationFrameCallbackList; |
- int id = m_nextRequestAnimationFrameCallbackId++; |
- callback->m_firedOrCancelled = false; |
- callback->m_id = id; |
- callback->m_element = e; |
- m_requestAnimationFrameCallbacks->append(callback); |
- if (FrameView* v = view()) |
- v->scheduleAnimation(); |
- return id; |
+ if (!m_scriptedAnimationController) |
+ m_scriptedAnimationController = ScriptedAnimationController::create(this); |
+ |
+ return m_scriptedAnimationController->registerCallback(callback, animationElement); |
} |
void Document::webkitCancelRequestAnimationFrame(int id) |
{ |
- if (!m_requestAnimationFrameCallbacks) |
+ if (!m_scriptedAnimationController) |
return; |
- for (size_t i = 0; i < m_requestAnimationFrameCallbacks->size(); ++i) { |
- if (m_requestAnimationFrameCallbacks->at(i)->m_id == id) { |
- m_requestAnimationFrameCallbacks->at(i)->m_firedOrCancelled = true; |
- m_requestAnimationFrameCallbacks->remove(i); |
- return; |
- } |
- } |
+ m_scriptedAnimationController->cancelCallback(id); |
} |
void Document::serviceScriptedAnimations() |
{ |
- if (!m_requestAnimationFrameCallbacks) |
+ if (!m_scriptedAnimationController) |
return; |
- // We want to run the callback for all elements in the document that have registered |
- // for a callback and that are visible. Running the callbacks can cause new callbacks |
- // to be registered, existing callbacks to be cancelled, and elements to gain or lose |
- // visibility so this code has to iterate carefully. |
- |
- // FIXME: Currently, this code doesn't do any visibility tests beyond checking display: |
- |
- // First, generate a list of callbacks to consider. Callbacks registered from this point |
- // on are considered only for the "next" frame, not this one. |
- RequestAnimationFrameCallbackList callbacks(*m_requestAnimationFrameCallbacks); |
- |
- // Firing the callback may cause the visibility of other elements to change. To avoid |
- // missing any callbacks, we keep iterating through the list of candiate callbacks and firing |
- // them until nothing new becomes visible. |
- bool firedCallback; |
- do { |
- firedCallback = false; |
- // A previous iteration may have invalidated style (or layout). Update styles for each iteration |
- // for now since all we check is the existence of a renderer. |
- updateStyleIfNeeded(); |
- for (size_t i = 0; i < callbacks.size(); ++i) { |
- RequestAnimationFrameCallback* callback = callbacks[i].get(); |
- if (!callback->m_firedOrCancelled && (!callback->m_element || callback->m_element->renderer())) { |
- callback->m_firedOrCancelled = true; |
- callback->handleEvent(); |
- firedCallback = true; |
- callbacks.remove(i); |
- break; |
- } |
- } |
- } while (firedCallback); |
- |
- // Remove any callbacks we fired from the list of pending callbacks. |
- for (size_t i = 0; i < m_requestAnimationFrameCallbacks->size();) { |
- if (m_requestAnimationFrameCallbacks->at(i)->m_firedOrCancelled) |
- m_requestAnimationFrameCallbacks->remove(i); |
- else |
- ++i; |
- } |
- |
- // In most cases we expect this list to be empty, so no need to keep around the vector's inline buffer. |
- if (!m_requestAnimationFrameCallbacks->size()) |
- m_requestAnimationFrameCallbacks.clear(); |
- else if (FrameView* v = view()) |
- v->scheduleAnimation(); |
+ m_scriptedAnimationController->serviceScriptedAnimations(time); |
} |
#endif |