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