summaryrefslogtreecommitdiffstats
path: root/WebCore/dom/DeviceOrientationController.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/dom/DeviceOrientationController.cpp')
-rw-r--r--WebCore/dom/DeviceOrientationController.cpp39
1 files changed, 29 insertions, 10 deletions
diff --git a/WebCore/dom/DeviceOrientationController.cpp b/WebCore/dom/DeviceOrientationController.cpp
index f6867ec..a6a33f5 100644
--- a/WebCore/dom/DeviceOrientationController.cpp
+++ b/WebCore/dom/DeviceOrientationController.cpp
@@ -37,21 +37,38 @@ namespace WebCore {
DeviceOrientationController::DeviceOrientationController(Page* page, DeviceOrientationClient* client)
: m_page(page)
, m_client(client)
+ , m_timer(this, &DeviceOrientationController::timerFired)
{
}
+void DeviceOrientationController::timerFired(Timer<DeviceOrientationController>* timer)
+{
+ ASSERT_UNUSED(timer, timer == &m_timer);
+ ASSERT(!m_client || m_client->lastOrientation());
+
+ RefPtr<DeviceOrientation> orientation = m_client ? m_client->lastOrientation() : DeviceOrientation::create();
+ RefPtr<DeviceOrientationEvent> event = DeviceOrientationEvent::create(eventNames().deviceorientationEvent, orientation.get());
+
+ Vector<DOMWindow*> listenersVector;
+ copyToVector(m_newListeners, listenersVector);
+ m_newListeners.clear();
+ for (size_t i = 0; i < listenersVector.size(); ++i)
+ listenersVector[i]->dispatchEvent(event);
+}
+
void DeviceOrientationController::addListener(DOMWindow* window)
{
- // If no client is present, signal that no orientation data is available.
- // If the client already has an orientation, call back to this new listener
- // immediately.
- if (!m_client) {
- RefPtr<DeviceOrientation> emptyOrientation = DeviceOrientation::create();
- window->dispatchEvent(DeviceOrientationEvent::create(eventNames().deviceorientationEvent, emptyOrientation.get()));
- } else if (m_client && m_client->lastOrientation())
- window->dispatchEvent(DeviceOrientationEvent::create(eventNames().deviceorientationEvent, m_client->lastOrientation()));
-
- // The client may call back synchronously.
+ // If no client is present, we should fire an event with all parameters null. If
+ // the client already has an orientation, we should fire an event with that
+ // orientation. In both cases, the event is fired asynchronously, but without
+ // waiting for the client to get a new orientation.
+ if (!m_client || m_client->lastOrientation()) {
+ m_newListeners.add(window);
+ if (!m_timer.isActive())
+ m_timer.startOneShot(0);
+ }
+
+ // The client must not call back synchronously.
bool wasEmpty = m_listeners.isEmpty();
m_listeners.add(window);
if (wasEmpty && m_client)
@@ -61,6 +78,7 @@ void DeviceOrientationController::addListener(DOMWindow* window)
void DeviceOrientationController::removeListener(DOMWindow* window)
{
m_listeners.remove(window);
+ m_newListeners.remove(window);
if (m_listeners.isEmpty() && m_client)
m_client->stopUpdating();
}
@@ -72,6 +90,7 @@ void DeviceOrientationController::removeAllListeners(DOMWindow* window)
return;
m_listeners.removeAll(window);
+ m_newListeners.remove(window);
if (m_listeners.isEmpty() && m_client)
m_client->stopUpdating();
}