2 * Copyright (C) 2011 Google Inc. All Rights Reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "core/dom/ScriptedAnimationController.h"
29 #include "core/css/MediaQueryListListener.h"
30 #include "core/dom/Document.h"
31 #include "core/dom/FrameRequestCallback.h"
32 #include "core/events/Event.h"
33 #include "core/frame/FrameView.h"
34 #include "core/frame/LocalDOMWindow.h"
35 #include "core/inspector/InspectorInstrumentation.h"
36 #include "core/inspector/InspectorTraceEvents.h"
37 #include "core/loader/DocumentLoader.h"
38 #include "platform/Logging.h"
42 std::pair
<EventTarget
*, StringImpl
*> eventTargetKey(const Event
* event
)
44 return std::make_pair(event
->target(), event
->type().impl());
47 ScriptedAnimationController::ScriptedAnimationController(Document
* document
)
48 : m_document(document
)
49 , m_callbackCollection(document
)
54 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ScriptedAnimationController
);
56 DEFINE_TRACE(ScriptedAnimationController
)
59 visitor
->trace(m_document
);
60 visitor
->trace(m_callbackCollection
);
61 visitor
->trace(m_eventQueue
);
62 visitor
->trace(m_mediaQueryListListeners
);
63 visitor
->trace(m_perFrameEvents
);
67 void ScriptedAnimationController::suspend()
72 void ScriptedAnimationController::resume()
74 // It would be nice to put an ASSERT(m_suspendCount > 0) here, but in WK1 resume() can be called
75 // even when suspend hasn't (if a tab was created in the background).
76 if (m_suspendCount
> 0)
78 scheduleAnimationIfNeeded();
81 void ScriptedAnimationController::dispatchEventsAndCallbacksForPrinting()
83 dispatchEvents(EventNames::MediaQueryListEvent
);
84 callMediaQueryListListeners();
87 ScriptedAnimationController::CallbackId
ScriptedAnimationController::registerCallback(FrameRequestCallback
* callback
)
89 CallbackId id
= m_callbackCollection
.registerCallback(callback
);
90 scheduleAnimationIfNeeded();
94 void ScriptedAnimationController::cancelCallback(CallbackId id
)
96 m_callbackCollection
.cancelCallback(id
);
99 void ScriptedAnimationController::dispatchEvents(const AtomicString
& eventInterfaceFilter
)
101 WillBeHeapVector
<RefPtrWillBeMember
<Event
>> events
;
102 if (eventInterfaceFilter
.isEmpty()) {
103 events
.swap(m_eventQueue
);
104 m_perFrameEvents
.clear();
106 WillBeHeapVector
<RefPtrWillBeMember
<Event
>> remaining
;
107 for (auto& event
: m_eventQueue
) {
108 if (event
&& event
->interfaceName() == eventInterfaceFilter
) {
109 m_perFrameEvents
.remove(eventTargetKey(event
.get()));
110 events
.append(event
.release());
112 remaining
.append(event
.release());
115 remaining
.swap(m_eventQueue
);
119 for (size_t i
= 0; i
< events
.size(); ++i
) {
120 EventTarget
* eventTarget
= events
[i
]->target();
121 // FIXME: we should figure out how to make dispatchEvent properly virtual to avoid
122 // special casting window.
123 // FIXME: We should not fire events for nodes that are no longer in the tree.
124 if (LocalDOMWindow
* window
= eventTarget
->toDOMWindow())
125 window
->dispatchEvent(events
[i
], nullptr);
127 eventTarget
->dispatchEvent(events
[i
]);
129 InspectorInstrumentation::didRemoveEvent(eventTarget
, events
[i
].get());
133 void ScriptedAnimationController::executeCallbacks(double monotonicTimeNow
)
135 // dispatchEvents() runs script which can cause the document to be destroyed.
139 double highResNowMs
= 1000.0 * m_document
->loader()->timing().monotonicTimeToZeroBasedDocumentTime(monotonicTimeNow
);
140 double legacyHighResNowMs
= 1000.0 * m_document
->loader()->timing().monotonicTimeToPseudoWallTime(monotonicTimeNow
);
141 m_callbackCollection
.executeCallbacks(highResNowMs
, legacyHighResNowMs
);
144 void ScriptedAnimationController::callMediaQueryListListeners()
146 MediaQueryListListeners listeners
;
147 listeners
.swap(m_mediaQueryListListeners
);
149 for (const auto& listener
: listeners
) {
150 listener
->notifyMediaQueryChanged();
154 bool ScriptedAnimationController::hasScheduledItems() const
159 return !m_callbackCollection
.isEmpty() || !m_eventQueue
.isEmpty() || !m_mediaQueryListListeners
.isEmpty();
162 void ScriptedAnimationController::serviceScriptedAnimations(double monotonicTimeNow
)
164 if (!hasScheduledItems())
167 RefPtrWillBeRawPtr
<ScriptedAnimationController
> protect(this);
169 callMediaQueryListListeners();
171 executeCallbacks(monotonicTimeNow
);
173 scheduleAnimationIfNeeded();
176 void ScriptedAnimationController::enqueueEvent(PassRefPtrWillBeRawPtr
<Event
> event
)
178 InspectorInstrumentation::didEnqueueEvent(event
->target(), event
.get());
179 m_eventQueue
.append(event
);
180 scheduleAnimationIfNeeded();
183 void ScriptedAnimationController::enqueuePerFrameEvent(PassRefPtrWillBeRawPtr
<Event
> event
)
185 if (!m_perFrameEvents
.add(eventTargetKey(event
.get())).isNewEntry
)
190 void ScriptedAnimationController::enqueueMediaQueryChangeListeners(WillBeHeapVector
<RefPtrWillBeMember
<MediaQueryListListener
>>& listeners
)
192 for (size_t i
= 0; i
< listeners
.size(); ++i
) {
193 m_mediaQueryListListeners
.add(listeners
[i
]);
195 scheduleAnimationIfNeeded();
198 void ScriptedAnimationController::scheduleAnimationIfNeeded()
200 if (!hasScheduledItems())
206 if (FrameView
* frameView
= m_document
->view())
207 frameView
->scheduleAnimation();