This source file includes following definitions.
- m_dispatchDeferredEventsTimer
- dispatchProgressEvent
- dispatchReadyStateChangeEvent
- dispatchEvent
- dispatchEventAndLoadEnd
- flushDeferredProgressEvent
- deliverProgressEvent
- dispatchDeferredEvents
- fired
- hasEventToDispatch
- suspend
- resume
- trace
#include "config.h"
#include "core/xml/XMLHttpRequestProgressEventThrottle.h"
#include "core/events/EventTarget.h"
#include "core/xml/XMLHttpRequestProgressEvent.h"
namespace WebCore {
const double XMLHttpRequestProgressEventThrottle::minimumProgressEventDispatchingIntervalInSeconds = .05;
XMLHttpRequestProgressEventThrottle::XMLHttpRequestProgressEventThrottle(EventTarget* target)
: m_target(target)
, m_loaded(0)
, m_total(0)
, m_deferEvents(false)
, m_dispatchDeferredEventsTimer(this, &XMLHttpRequestProgressEventThrottle::dispatchDeferredEvents)
{
ASSERT(target);
}
XMLHttpRequestProgressEventThrottle::~XMLHttpRequestProgressEventThrottle()
{
}
void XMLHttpRequestProgressEventThrottle::dispatchProgressEvent(bool lengthComputable, unsigned long long loaded, unsigned long long total)
{
if (m_deferEvents) {
m_deferredProgressEvent = XMLHttpRequestProgressEvent::create(EventTypeNames::progress, lengthComputable, loaded, total);
return;
}
if (!isActive()) {
ASSERT(!m_loaded);
ASSERT(!m_total);
dispatchEvent(XMLHttpRequestProgressEvent::create(EventTypeNames::progress, lengthComputable, loaded, total));
startRepeating(minimumProgressEventDispatchingIntervalInSeconds, FROM_HERE);
return;
}
m_lengthComputable = lengthComputable;
m_loaded = loaded;
m_total = total;
}
void XMLHttpRequestProgressEventThrottle::dispatchReadyStateChangeEvent(PassRefPtrWillBeRawPtr<Event> event, ProgressEventAction progressEventAction)
{
if (progressEventAction == FlushProgressEvent || progressEventAction == FlushDeferredProgressEvent) {
if (!flushDeferredProgressEvent() && progressEventAction == FlushProgressEvent)
deliverProgressEvent();
}
dispatchEvent(event);
}
void XMLHttpRequestProgressEventThrottle::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
{
ASSERT(event);
if (m_deferEvents) {
if (m_deferredEvents.size() > 1 && event->type() == EventTypeNames::readystatechange && event->type() == m_deferredEvents.last()->type()) {
return;
}
m_deferredEvents.append(event);
} else
m_target->dispatchEvent(event);
}
void XMLHttpRequestProgressEventThrottle::dispatchEventAndLoadEnd(const AtomicString& type, bool lengthComputable, unsigned long long bytesSent, unsigned long long total)
{
ASSERT(type == EventTypeNames::load || type == EventTypeNames::abort || type == EventTypeNames::error || type == EventTypeNames::timeout);
dispatchEvent(XMLHttpRequestProgressEvent::create(type, lengthComputable, bytesSent, total));
dispatchEvent(XMLHttpRequestProgressEvent::create(EventTypeNames::loadend, lengthComputable, bytesSent, total));
}
bool XMLHttpRequestProgressEventThrottle::flushDeferredProgressEvent()
{
if (m_deferEvents && m_deferredProgressEvent) {
m_deferredEvents.append(m_deferredProgressEvent);
m_deferredProgressEvent = nullptr;
return true;
}
return false;
}
void XMLHttpRequestProgressEventThrottle::deliverProgressEvent()
{
if (!hasEventToDispatch())
return;
RefPtrWillBeRawPtr<Event> event = XMLHttpRequestProgressEvent::create(EventTypeNames::progress, m_lengthComputable, m_loaded, m_total);
m_loaded = 0;
m_total = 0;
stop();
dispatchEvent(event);
}
void XMLHttpRequestProgressEventThrottle::dispatchDeferredEvents(Timer<XMLHttpRequestProgressEventThrottle>* timer)
{
ASSERT_UNUSED(timer, timer == &m_dispatchDeferredEventsTimer);
ASSERT(m_deferEvents);
m_deferEvents = false;
WillBeHeapVector<RefPtrWillBeMember<Event> > deferredEvents;
m_deferredEvents.swap(deferredEvents);
RefPtrWillBeRawPtr<Event> deferredProgressEvent = m_deferredProgressEvent;
m_deferredProgressEvent = nullptr;
WillBeHeapVector<RefPtrWillBeMember<Event> >::const_iterator it = deferredEvents.begin();
const WillBeHeapVector<RefPtrWillBeMember<Event> >::const_iterator end = deferredEvents.end();
for (; it != end; ++it)
dispatchEvent(*it);
if (deferredProgressEvent)
dispatchEvent(deferredProgressEvent);
}
void XMLHttpRequestProgressEventThrottle::fired()
{
ASSERT(isActive());
if (!hasEventToDispatch()) {
stop();
return;
}
dispatchEvent(XMLHttpRequestProgressEvent::create(EventTypeNames::progress, 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()
{
if (m_dispatchDeferredEventsTimer.isActive()) {
ASSERT(m_deferEvents);
m_dispatchDeferredEventsTimer.stop();
return;
}
ASSERT(!m_deferredProgressEvent);
ASSERT(m_deferredEvents.isEmpty());
ASSERT(!m_deferEvents);
m_deferEvents = true;
if (hasEventToDispatch()) {
m_deferredProgressEvent = XMLHttpRequestProgressEvent::create(EventTypeNames::progress, m_lengthComputable, m_loaded, m_total);
m_total = 0;
m_loaded = 0;
}
stop();
}
void XMLHttpRequestProgressEventThrottle::resume()
{
ASSERT(!m_loaded);
ASSERT(!m_total);
if (m_deferredEvents.isEmpty() && !m_deferredProgressEvent) {
m_deferEvents = false;
return;
}
m_dispatchDeferredEventsTimer.startOneShot(0, FROM_HERE);
}
void XMLHttpRequestProgressEventThrottle::trace(Visitor* visitor)
{
visitor->trace(m_deferredProgressEvent);
visitor->trace(m_deferredEvents);
}
}