15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Julien Chaffraix <jchaffraix@webkit.org>  All right reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/xml/XMLHttpRequestProgressEventThrottle.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/EventTarget.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/xml/XMLHttpRequestProgressEvent.h"
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
33c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciclass XMLHttpRequestProgressEventThrottle::DeferredEvent {
367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccipublic:
377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    DeferredEvent() { clear(); }
387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void set(bool lengthComputable, unsigned long long loaded, unsigned long long total)
397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_isDeferred = true;
417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_lengthComputable = lengthComputable;
427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_loaded = loaded;
437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_total = total;
447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void clear()
467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_isDeferred = false;
487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_lengthComputable = false;
497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_loaded = 0;
507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_total = 0;
517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool isDeferred() const { return m_isDeferred; }
537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool lengthComputable() const { return m_lengthComputable; }
547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    unsigned long long loaded() const { return m_loaded; }
557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    unsigned long long total() const { return m_total; }
567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciprivate:
587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    unsigned long long m_loaded;
597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    unsigned long long m_total;
607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool m_isDeferred;
617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool m_lengthComputable;
627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci};
637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const double XMLHttpRequestProgressEventThrottle::minimumProgressEventDispatchingIntervalInSeconds = .05; // 50 ms per specification.
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)XMLHttpRequestProgressEventThrottle::XMLHttpRequestProgressEventThrottle(EventTarget* target)
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : m_target(target)
687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    , m_deferred(adoptPtr(new DeferredEvent))
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(target);
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)XMLHttpRequestProgressEventThrottle::~XMLHttpRequestProgressEventThrottle()
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
77f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)void XMLHttpRequestProgressEventThrottle::dispatchProgressEvent(const AtomicString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total)
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Given that ResourceDispatcher doesn't deliver an event when suspended,
807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // we don't have to worry about event dispatching while suspended.
81f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (type != EventTypeNames::progress) {
827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_target->dispatchEvent(XMLHttpRequestProgressEvent::create(type, lengthComputable, loaded, total));
83f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        return;
84f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    }
85f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (isActive()) {
877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_deferred->set(lengthComputable, loaded, total);
8876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    } else {
897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_target->dispatchEvent(XMLHttpRequestProgressEvent::create(type, lengthComputable, loaded, total));
907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        startOneShot(minimumProgressEventDispatchingIntervalInSeconds, FROM_HERE);
9176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    }
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid XMLHttpRequestProgressEventThrottle::dispatchReadyStateChangeEvent(PassRefPtrWillBeRawPtr<Event> event, DeferredEventAction action)
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Given that ResourceDispatcher doesn't deliver an event when suspended,
977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // we don't have to worry about event dispatching while suspended.
987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (action == Flush) {
997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        dispatchDeferredEvent();
1007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        stop();
1017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    } else if (action == Clear) {
1027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_deferred->clear();
1037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        stop();
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_target->dispatchEvent(event);
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid XMLHttpRequestProgressEventThrottle::dispatchDeferredEvent()
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (m_deferred->isDeferred()) {
1127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_target->dispatchEvent(XMLHttpRequestProgressEvent::create(EventTypeNames::progress, m_deferred->lengthComputable(), m_deferred->loaded(), m_deferred->total()));
1137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_deferred->clear();
1147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void XMLHttpRequestProgressEventThrottle::fired()
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!m_deferred->isDeferred()) {
1209e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        // No "progress" event was queued since the previous dispatch, we can
1219e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        // safely stop the timer.
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    dispatchDeferredEvent();
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Watch if another "progress" ProgressEvent arrives in the next 50ms.
1287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    startOneShot(minimumProgressEventDispatchingIntervalInSeconds, FROM_HERE);
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void XMLHttpRequestProgressEventThrottle::suspend()
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    stop();
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void XMLHttpRequestProgressEventThrottle::resume()
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!m_deferred->isDeferred())
139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Do not dispatch events inline here, since ExecutionContext is iterating
1427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // over the list of active DOM objects to resume them, and any activated JS
1437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // event-handler could insert new active DOM objects to the list.
1447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    startOneShot(0, FROM_HERE);
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
147a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochvoid XMLHttpRequestProgressEventThrottle::trace(Visitor* visitor)
148a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch{
1495d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    visitor->trace(m_target);
150a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch}
151a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
152c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
153