WebCore/xml/XMLHttpRequestProgressEventThrottle.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2010 Julien Chaffraix <jchaffraix@webkit.org>
       
     3  * All right reserved.
       
     4  *
       
     5  * Redistribution and use in source and binary forms, with or without
       
     6  * modification, are permitted provided that the following conditions
       
     7  * are met:
       
     8  * 1. Redistributions of source code must retain the above copyright
       
     9  *    notice, this list of conditions and the following disclaimer.
       
    10  * 2. Redistributions in binary form must reproduce the above copyright
       
    11  *    notice, this list of conditions and the following disclaimer in the
       
    12  *    documentation and/or other materials provided with the distribution.
       
    13  *
       
    14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    15  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    16  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    17  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    18  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    19  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    20  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    25  */
       
    26 
       
    27 #include "config.h"
       
    28 #include "XMLHttpRequestProgressEventThrottle.h"
       
    29 
       
    30 #include "EventTarget.h"
       
    31 #include "XMLHttpRequestProgressEvent.h"
       
    32 
       
    33 namespace WebCore {
       
    34 
       
    35 const double XMLHttpRequestProgressEventThrottle::minimumProgressEventDispatchingIntervalInSeconds = .05; // 50 ms per specification.
       
    36 
       
    37 XMLHttpRequestProgressEventThrottle::XMLHttpRequestProgressEventThrottle(EventTarget* target)
       
    38     : m_target(target)
       
    39     , m_loaded(0)
       
    40     , m_total(0)
       
    41     , m_suspended(false)
       
    42 {
       
    43     ASSERT(target);
       
    44 }
       
    45 
       
    46 XMLHttpRequestProgressEventThrottle::~XMLHttpRequestProgressEventThrottle()
       
    47 {
       
    48 }
       
    49 
       
    50 void XMLHttpRequestProgressEventThrottle::dispatchProgressEvent(bool lengthComputable, unsigned loaded, unsigned total)
       
    51 {
       
    52     ASSERT(!suspended());
       
    53     if (!isActive()) {
       
    54         // The timer is not active so the least frequent event for now is every byte.
       
    55         // Just go ahead and dispatch the event.
       
    56 
       
    57         // We should not have any pending loaded & total information from a previous run.
       
    58         ASSERT(!m_loaded);
       
    59         ASSERT(!m_total);
       
    60 
       
    61         dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().progressEvent, lengthComputable, loaded, total));
       
    62         startRepeating(minimumProgressEventDispatchingIntervalInSeconds);
       
    63         return;
       
    64     }
       
    65 
       
    66     // The timer is already active so minimumProgressEventDispatchingIntervalInSeconds is the least frequent event.
       
    67     m_lengthComputable = lengthComputable;
       
    68     m_loaded = loaded;
       
    69     m_total = total;
       
    70 }
       
    71 
       
    72 void XMLHttpRequestProgressEventThrottle::dispatchEvent(PassRefPtr<Event> event, ProgressEventAction progressEventAction)
       
    73 {
       
    74     ASSERT(!suspended());
       
    75     // We should not have any pending events from a previous resume.
       
    76     ASSERT(!m_pausedEvent);
       
    77 
       
    78     if (progressEventAction == FlushProgressEvent)
       
    79         flushProgressEvent();
       
    80 
       
    81     m_target->dispatchEvent(event);
       
    82 }
       
    83 
       
    84 void XMLHttpRequestProgressEventThrottle::flushProgressEvent()
       
    85 {
       
    86     if (!hasEventToDispatch())
       
    87         return;
       
    88 
       
    89     PassRefPtr<Event> event = XMLHttpRequestProgressEvent::create(eventNames().progressEvent, m_lengthComputable, m_loaded, m_total);
       
    90     m_loaded = 0;
       
    91     m_total = 0;
       
    92 
       
    93     // We stop the timer as this is called when no more events are supposed to occur.
       
    94     stop();
       
    95 
       
    96     m_target->dispatchEvent(event);
       
    97 }
       
    98 
       
    99 void XMLHttpRequestProgressEventThrottle::dispatchPausedEvent()
       
   100 {
       
   101     ASSERT(!suspended());
       
   102     if (!m_pausedEvent)
       
   103         return;
       
   104 
       
   105     m_target->dispatchEvent(m_pausedEvent);
       
   106     m_pausedEvent = 0;
       
   107 }
       
   108 
       
   109 void XMLHttpRequestProgressEventThrottle::fired()
       
   110 {
       
   111     ASSERT(isActive());
       
   112     ASSERT(!suspended());
       
   113     ASSERT(!m_pausedEvent);
       
   114     if (!hasEventToDispatch()) {
       
   115         // No progress event was queued since the previous dispatch, we can safely stop the timer.
       
   116         stop();
       
   117         return;
       
   118     }
       
   119 
       
   120     m_target->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().progressEvent, m_lengthComputable, m_loaded, m_total));
       
   121     m_total = 0;
       
   122     m_loaded = 0;
       
   123 }
       
   124 
       
   125 bool XMLHttpRequestProgressEventThrottle::hasEventToDispatch() const
       
   126 {
       
   127     return (m_total || m_loaded) && isActive();
       
   128 }
       
   129 
       
   130 void XMLHttpRequestProgressEventThrottle::suspend()
       
   131 {
       
   132     ASSERT(!m_pausedEvent);
       
   133 
       
   134     m_suspended = true;
       
   135     // If we have a progress event waiting to be dispatched,
       
   136     // just queue it.
       
   137     if (hasEventToDispatch()) {
       
   138         m_pausedEvent = XMLHttpRequestProgressEvent::create(eventNames().progressEvent, m_lengthComputable, m_loaded, m_total);
       
   139         m_total = 0;
       
   140         m_loaded = 0;
       
   141     }
       
   142     stop();
       
   143 }
       
   144 
       
   145 void XMLHttpRequestProgressEventThrottle::resume()
       
   146 {
       
   147     ASSERT(!m_loaded);
       
   148     ASSERT(!m_total);
       
   149 
       
   150     m_suspended = false;
       
   151     dispatchPausedEvent();
       
   152 }
       
   153 
       
   154 } // namespace WebCore