/* | |
* Copyright (C) 2010 Julien Chaffraix <jchaffraix@webkit.org> | |
* All right 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. | |
* | |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT | |
* OWNER OR 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 "XMLHttpRequestProgressEventThrottle.h" | |
#include "EventTarget.h" | |
#include "XMLHttpRequestProgressEvent.h" | |
namespace WebCore { | |
const double XMLHttpRequestProgressEventThrottle::minimumProgressEventDispatchingIntervalInSeconds = .05; // 50 ms per specification. | |
XMLHttpRequestProgressEventThrottle::XMLHttpRequestProgressEventThrottle(EventTarget* target) | |
: m_target(target) | |
, m_loaded(0) | |
, m_total(0) | |
, m_suspended(false) | |
{ | |
ASSERT(target); | |
} | |
XMLHttpRequestProgressEventThrottle::~XMLHttpRequestProgressEventThrottle() | |
{ | |
} | |
void XMLHttpRequestProgressEventThrottle::dispatchProgressEvent(bool lengthComputable, unsigned loaded, unsigned total) | |
{ | |
ASSERT(!suspended()); | |
if (!isActive()) { | |
// The timer is not active so the least frequent event for now is every byte. | |
// Just go ahead and dispatch the event. | |
// We should not have any pending loaded & total information from a previous run. | |
ASSERT(!m_loaded); | |
ASSERT(!m_total); | |
dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().progressEvent, lengthComputable, loaded, total)); | |
startRepeating(minimumProgressEventDispatchingIntervalInSeconds); | |
return; | |
} | |
// The timer is already active so minimumProgressEventDispatchingIntervalInSeconds is the least frequent event. | |
m_lengthComputable = lengthComputable; | |
m_loaded = loaded; | |
m_total = total; | |
} | |
void XMLHttpRequestProgressEventThrottle::dispatchEvent(PassRefPtr<Event> event, ProgressEventAction progressEventAction) | |
{ | |
ASSERT(!suspended()); | |
// We should not have any pending events from a previous resume. | |
ASSERT(!m_pausedEvent); | |
if (progressEventAction == FlushProgressEvent) | |
flushProgressEvent(); | |
m_target->dispatchEvent(event); | |
} | |
void XMLHttpRequestProgressEventThrottle::flushProgressEvent() | |
{ | |
if (!hasEventToDispatch()) | |
return; | |
PassRefPtr<Event> event = XMLHttpRequestProgressEvent::create(eventNames().progressEvent, m_lengthComputable, m_loaded, m_total); | |
m_loaded = 0; | |
m_total = 0; | |
// We stop the timer as this is called when no more events are supposed to occur. | |
stop(); | |
m_target->dispatchEvent(event); | |
} | |
void XMLHttpRequestProgressEventThrottle::dispatchPausedEvent() | |
{ | |
ASSERT(!suspended()); | |
if (!m_pausedEvent) | |
return; | |
m_target->dispatchEvent(m_pausedEvent); | |
m_pausedEvent = 0; | |
} | |
void XMLHttpRequestProgressEventThrottle::fired() | |
{ | |
ASSERT(isActive()); | |
ASSERT(!suspended()); | |
ASSERT(!m_pausedEvent); | |
if (!hasEventToDispatch()) { | |
// No progress event was queued since the previous dispatch, we can safely stop the timer. | |
stop(); | |
return; | |
} | |
m_target->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().progressEvent, m_lengthComputable, m_loaded, m_total)); | |
m_total = 0; | |
m_loaded = 0; | |
} | |
bool XMLHttpRequestProgressEventThrottle::hasEventToDispatch() const | |
{ | |
return (m_total || m_loaded) && isActive(); | |
} | |
void XMLHttpRequestProgressEventThrottle::suspend() | |
{ | |
ASSERT(!m_pausedEvent); | |
m_suspended = true; | |
// If we have a progress event waiting to be dispatched, | |
// just queue it. | |
if (hasEventToDispatch()) { | |
m_pausedEvent = XMLHttpRequestProgressEvent::create(eventNames().progressEvent, m_lengthComputable, m_loaded, m_total); | |
m_total = 0; | |
m_loaded = 0; | |
} | |
stop(); | |
} | |
void XMLHttpRequestProgressEventThrottle::resume() | |
{ | |
ASSERT(!m_loaded); | |
ASSERT(!m_total); | |
m_suspended = false; | |
dispatchPausedEvent(); | |
} | |
} // namespace WebCore |