Source/WebCore: Correctly set XHR loadend attributes (loaded and total).

https://bugs.webkit.org/show_bug.cgi?id=120828

Patch by Youenn Fablet <youennf@gmail.com> on 2014-01-08
Reviewed by Alexey Proskuryakov.

Added correct initialization of lengthComputable, loaded and total attributes
to XHR ProgressEvent events (load, loadstart, loadend, abort, error and timeout).

XMLHttpRequestProgressEventThrottle and XMLHttpRequestUpload now keep persistent knowledge
of m_loaded and m_total values with this patch.

Code refactoring to handle event dispatching in case of error in a single manner.
XMLHttpRequestProgressEventThrottle::dispatchProgressEvent is renamed as dispatchThrottledProgressEvent
XMLHttpRequestProgressEventThrottle::dispatchEventAndLoadend is replaced by dispatchProgressEvent(const AtomicString&)

Tests: http/tests/xmlhttprequest/loadstart-event-init.html
       http/tests/xmlhttprequest/onabort-progressevent-attributes.html
       http/tests/xmlhttprequest/onload-progressevent-attributes.html
       http/tests/xmlhttprequest/upload-onabort-progressevent-attributes.html
       http/tests/xmlhttprequest/upload-onload-progressevent-attributes.html

* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::callReadyStateChangeListener): changed readystatechange event from ProgressEvent to Event (not cancellable, not bubblable) to better match the spec
(WebCore::XMLHttpRequest::createRequest):
(WebCore::XMLHttpRequest::abort): code refactoring to handle error event dispatching in a single way
(WebCore::XMLHttpRequest::networkError): code refactoring to handle error event dispatching in a single way
(WebCore::XMLHttpRequest::abortError): code refactoring to handle error event dispatching in a single way
(WebCore::XMLHttpRequest::didSendData):
(WebCore::XMLHttpRequest::didReceiveData):
(WebCore::XMLHttpRequest::dispatchErrorEvents): dispatch progress events in case of error
(WebCore::XMLHttpRequest::didTimeout): code refactoring to handle error event dispatching in a single way
* xml/XMLHttpRequest.h:
* xml/XMLHttpRequestProgressEventThrottle.cpp: before the patch, the fact that a progress event is being throttled is stored indirectly (m_loaded or m_total not equal to zero). With the patch, this information is stored in m_hasThrottledProgressEvent. The m_loaded and m_total values are no longer set back to zero after a progress event is dispatched. This allows using these values to correctly initialize other ProgressEvent events (in particular loadend, abort, timeout...)
(WebCore::XMLHttpRequestProgressEventThrottle::XMLHttpRequestProgressEventThrottle):
(WebCore::XMLHttpRequestProgressEventThrottle::dispatchThrottledProgressEvent): always update the new m_loaded and m_total values. If progress event is not sent as part of the function call, store the fact that a progress event is being throttled through m_hasThrottledProgressEvent.
(WebCore::XMLHttpRequestProgressEventThrottle::dispatchProgressEvent): used to send any ProgressEvent event that is not be throttled
(WebCore::XMLHttpRequestProgressEventThrottle::flushProgressEvent): after the call, no progress event is throttled anymore
(WebCore::XMLHttpRequestProgressEventThrottle::fired): after the call, no progress event is throttled anymore
(WebCore::XMLHttpRequestProgressEventThrottle::hasEventToDispatch):
(WebCore::XMLHttpRequestProgressEventThrottle::suspend):
* xml/XMLHttpRequestProgressEventThrottle.h: introduced m_hasThrottledProgressEvent which stores whether a progress event is being throttled and m_computableLength which is used to initialize ProgressEvent computableLength
* xml/XMLHttpRequestUpload.cpp:
(WebCore::XMLHttpRequestUpload::XMLHttpRequestUpload):
(WebCore::XMLHttpRequestUpload::dispatchProgressEvent):
* xml/XMLHttpRequestUpload.h: introduced m_loaded, m_total and m_lengthComputable, similarly to XMLHttpRequestProgressEventThrottle

LayoutTests: Correctly set XHR loadend event attributes (loaded and total).
https://bugs.webkit.org/show_bug.cgi?id=120828

Patch by Youenn Fablet <youennf@gmail.com> on 2014-01-08
Reviewed by Alexey Proskuryakov.

Tests for abort, load, loadstart and loadend ProgressEvent events for XMLHttpRequest and XMLHttpRequestUpload

* fast/xmlhttprequest/xmlhttprequest-get-expected.txt: Changed to correct event values
* http/tests/xmlhttprequest/loadstart-event-init-expected.txt: Added.
* http/tests/xmlhttprequest/loadstart-event-init.html: Added.
* http/tests/xmlhttprequest/onabort-progressevent-attributes-expected.txt: Added.
* http/tests/xmlhttprequest/onabort-progressevent-attributes.html: Added.
* http/tests/xmlhttprequest/onload-progressevent-attributes-expected.txt: Added.
* http/tests/xmlhttprequest/onload-progressevent-attributes.html: Added.
* http/tests/xmlhttprequest/upload-onabort-progressevent-attributes-expected.txt: Added.
* http/tests/xmlhttprequest/upload-onabort-progressevent-attributes.html: Added.
* http/tests/xmlhttprequest/upload-onload-progressevent-attributes-expected.txt: Added.
* http/tests/xmlhttprequest/upload-onload-progressevent-attributes.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@161532 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 50af46e0
2014-01-08 Youenn Fablet <youennf@gmail.com>
Correctly set XHR loadend event attributes (loaded and total).
https://bugs.webkit.org/show_bug.cgi?id=120828
Reviewed by Alexey Proskuryakov.
Tests for abort, load, loadstart and loadend ProgressEvent events for XMLHttpRequest and XMLHttpRequestUpload
* fast/xmlhttprequest/xmlhttprequest-get-expected.txt: Changed to correct event values
* http/tests/xmlhttprequest/loadstart-event-init-expected.txt: Added.
* http/tests/xmlhttprequest/loadstart-event-init.html: Added.
* http/tests/xmlhttprequest/onabort-progressevent-attributes-expected.txt: Added.
* http/tests/xmlhttprequest/onabort-progressevent-attributes.html: Added.
* http/tests/xmlhttprequest/onload-progressevent-attributes-expected.txt: Added.
* http/tests/xmlhttprequest/onload-progressevent-attributes.html: Added.
* http/tests/xmlhttprequest/upload-onabort-progressevent-attributes-expected.txt: Added.
* http/tests/xmlhttprequest/upload-onabort-progressevent-attributes.html: Added.
* http/tests/xmlhttprequest/upload-onload-progressevent-attributes-expected.txt: Added.
* http/tests/xmlhttprequest/upload-onload-progressevent-attributes.html: Added.
2014-01-07 Myles C. Maxfield <mmaxfield@apple.com>
a fractional value of the css letter-spacing property is not rendered as expected
......@@ -53,9 +53,9 @@ eventPhase : '2'
initEvent : 'function initEvent() {
[native code]
}'
lengthComputable : 'false'
loaded : '0'
position : '0'
lengthComputable : 'true'
loaded : '174'
position : '174'
preventDefault : 'function preventDefault() {
[native code]
}'
......@@ -68,7 +68,7 @@ stopPropagation : 'function stopPropagation() {
[native code]
}'
target : '[object XMLHttpRequest]'
total : '0'
totalSize : '0'
total : '174'
totalSize : '174'
type : 'load'
PASS XMLHttpRequest: ensure loadstart event progress members are correctly initialized
<!DOCTYPE html>
<html>
<head>
<title>XMLHttpRequest: ensure loadstart event progress members are correctly initialized</title>
<script src="/js-test-resources/testharness.js"></script>
<script src="/js-test-resources/testharnessreport.js"></script>
</head>
<body>
<div id="log"></div>
<script type="text/javascript">
var test = async_test()
test.step(function() {
var count = 0;
var xhr = new XMLHttpRequest();
xhr.onloadstart = test.step_func(function(e)
{
assert_equals(e.loaded, 0, "loaded member of xhr.loadstart event should be 0")
if (count == 1) {
test.done();
}
})
xhr.upload.onloadstart = test.step_func(function(e)
{
assert_equals(e.loaded, 0, "loaded member of xhr.upload.loadstart event should be 0");
})
xhr.onloadend = function(e)
{
if (count++ < 1) {
xhr.open("POST", "./resources/content.php", true);
xhr.send("test");
}
}
xhr.open("POST", "./resources/content.php", true);
xhr.send("test");
});
</script>
</body>
</html>
Test case for bug 120828: Correctly set XHR loadend attributes (loaded and total).
Verify that abort and loadend events have their ProgressEvent attributes (loaded, total and lengthComputable) correctly set.
PASS
<html>
<head>
<title>Test case for bug 120828 (abort case)</title>
</head>
<body>
<p>Test case for <a href="https://bugs.webkit.org/show_bug.cgi?id=120828"> bug 120828</a>: Correctly set XHR loadend attributes (loaded and total).</p>
<p>Verify that abort and loadend events have their ProgressEvent attributes (loaded, total and lengthComputable) correctly set.</p>
<p id=console></p>
<script type="text/javascript">
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
var status = "PASS";
var total = 0;
var loaded = 0;
function onProgressEvent(e)
{
if (total != e.total || loaded != e.loaded)
fail("Event " + e.type + "total/loaded values not matching: "
+ "(" + e.loaded + " / " + e.total + "), expected (" + loaded + " / " + total + ")");
}
function onUnexpectedProgressEvent(e)
{
fail("unexpected ProgressEvent: " + e.type);
}
function fail(msg)
{
status = "FAILED: " + msg;
completeTest();
status = "";
}
function completeTest()
{
log(status);
if (window.testRunner)
testRunner.notifyDone();
}
function test()
{
var iteration = 2;
var delay = "1000";
var req = new XMLHttpRequest();
req.onprogress = function(e){
total = e.total;
loaded = e.loaded;
req.abort();
};
req.onerror = onUnexpectedProgressEvent;
req.onabort = onProgressEvent;
req.onloadend = function(e) {
onProgressEvent(e);
completeTest();
}
req.open("GET", "resources/download-with-delay.php?iteration=" + iteration + "&delay=" + delay, true);
req.send(null);
}
function log(message)
{
var consoleElt = document.getElementById("console");
consoleElt.innerHTML += message + "<br/>";
}
test();
</script>
</body>
</html>
Test case for bug 120828: Correctly set XHR loadend attributes (loaded and total).
Verify that load and loadend events have their ProgressEvent attributes (loaded, total and lengthComputable) correctly set.
PASS
<html>
<head>
<title>Test case for bug 120828</title>
</head>
<body>
<p> Test case for <a href="https://bugs.webkit.org/show_bug.cgi?id=120828"> bug 120828</a>: Correctly set XHR loadend attributes (loaded and total).</p>
<p> Verify that load and loadend events have their ProgressEvent attributes (loaded, total and lengthComputable) correctly set.</p>
<p id=console></p>
<script type="text/javascript">
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
var status = "PASS";
var total = 0;
var loaded = 0;
function onProgressEvent(e)
{
if (total != e.total || loaded != e.loaded)
fail("Event " + e.type + " total/loaded values not matching: "
+ "(" + e.loaded + " / " + e.total + "), expected (" + loaded + " / " + total + ")");
}
function onUnexpectedProgressEvent(e)
{
fail("unexpected ProgressEvent: " + e.type);
}
function fail(msg)
{
status = "FAILED: " + msg;
completeTest();
status = "";
}
function completeTest()
{
log(status);
if (window.testRunner)
testRunner.notifyDone();
}
function test()
{
var req = new XMLHttpRequest();
req.onreadystatechange = function(e) {
if (req.readyState == req.DONE) {
if (this.status == 200)
total = loaded = req.responseText.length;
else
fail("unexpected status: " + status);
}
}
req.onabort = onUnexpectedProgressEvent;
req.onerror = onUnexpectedProgressEvent;
req.onload = onProgressEvent;
req.onloadend = function(e) {
onProgressEvent(e);
completeTest();
}
req.open("GET", "resources/get.txt", true);
req.send();
}
function log(message)
{
var consoleElt = document.getElementById("console");
consoleElt.innerHTML += message + "<br/>";
}
test();
</script>
</body>
</html>
Test case for bug 120828: Correctly set XHR loadend attributes (loaded and total).
Upload case: verify that abort and loadend events have their ProgressEvent attributes (loaded, total and lengthComputable) correctly set.
PASS
<html>
<head>
<title>Test case for bug 120828 (abort case)</title>
</head>
<body>
<p>Test case for <a href="https://bugs.webkit.org/show_bug.cgi?id=120828"> bug 120828</a>: Correctly set XHR loadend attributes (loaded and total).</p>
<p>Upload case: verify that abort and loadend events have their ProgressEvent attributes (loaded, total and lengthComputable) correctly set.</p>
<p id=console></p>
<script type="text/javascript">
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
var status = "PASS";
var total = 1;
var loaded = 1;
var uploadedData = "d";
function onProgressEvent(e)
{
if (!e.lengthComputable)
fail("Event " + e.type + " lengthComputable is false");
if (e.total != total || e.loaded != loaded)
fail("Event " + e.type + " total/loaded values not matching: "
+ "(" + e.loaded + " / " + e.total + "), expected (" + loaded + " / " + total + ")");
}
function onUnexpectedProgressEvent(e)
{
fail("unexpected ProgressEvent: " + e.type);
}
function fail(msg)
{
status = "FAILED: " + msg;
completeTest();
status = "";
}
function completeTest()
{
log(status);
if (window.testRunner)
testRunner.notifyDone();
}
function test()
{
var req = new XMLHttpRequest();
req.upload.onerror = onUnexpectedProgressEvent;
req.upload.onload = onUnexpectedProgressEvent;
req.upload.onabort = onProgressEvent;
req.upload.onprogress = function(e) {
onProgressEvent(e);
req.abort();
}
req.upload.onloadend = function(e) {
onProgressEvent(e);
completeTest();
}
req.open("POST", "resources/post-echo.cgi", true);
req.send(uploadedData);
}
function log(message)
{
var consoleElt = document.getElementById("console");
consoleElt.innerHTML += message + "<br/>";
}
test();
</script>
</body>
</html>
Test case for bug 120828: Correctly set XHR loadend attributes (loaded and total).
Upload case: verify that load and loadend events have their ProgressEvent attributes (loaded, total and lengthComputable) correctly set.
PASS
<html>
<head>
<title>Test case for bug 120828</title>
</head>
<body>
<p> Test case for <a href="https://bugs.webkit.org/show_bug.cgi?id=120828"> bug 120828</a>: Correctly set XHR loadend attributes (loaded and total).</p>
<p> Upload case: verify that load and loadend events have their ProgressEvent attributes (loaded, total and lengthComputable) correctly set.</p>
<p id=console></p>
<script type="text/javascript">
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
var status = "PASS";
var total = 1;
var loaded = 1;
var uploadedData = "d";
function onProgressEvent(e)
{
if (!e.lengthComputable)
fail("Event " + e.type + "event lengthComputable = false");
if (e.total != total || e.loaded != loaded)
fail("Event " + e.type + "total/loaded values not matching: "
+ "(" + e.loaded + " / " + e.total + "), expected (" + loaded + " / " + total + ")");
}
function onUnexpectedProgressEvent(e)
{
fail("unexpected ProgressEvent: " + e.type);
}
function fail(msg)
{
status = "FAILED: " + msg;
completeTest();
status = "";
}
function completeTest()
{
log(status);
if (window.testRunner)
testRunner.notifyDone();
}
function test()
{
var req = new XMLHttpRequest();
req.upload.onabort = onUnexpectedProgressEvent;
req.upload.onerror = onUnexpectedProgressEvent;
req.upload.onprogress = onProgressEvent;
req.upload.onload = onProgressEvent;
req.upload.onloadend = function(e) {
onProgressEvent(e);
completeTest();
}
req.open("POST", "resources/post-echo.cgi", true);
req.send(uploadedData);
}
function log(message)
{
var consoleElt = document.getElementById("console");
consoleElt.innerHTML += message + "<br/>";
}
test();
</script>
</body>
</html>
2014-01-08 Youenn Fablet <youennf@gmail.com>
Correctly set XHR loadend attributes (loaded and total).
https://bugs.webkit.org/show_bug.cgi?id=120828
Reviewed by Alexey Proskuryakov.
Added correct initialization of lengthComputable, loaded and total attributes
to XHR ProgressEvent events (load, loadstart, loadend, abort, error and timeout).
XMLHttpRequestProgressEventThrottle and XMLHttpRequestUpload now keep persistent knowledge
of m_loaded and m_total values with this patch.
Code refactoring to handle event dispatching in case of error in a single manner.
XMLHttpRequestProgressEventThrottle::dispatchProgressEvent is renamed as dispatchThrottledProgressEvent
XMLHttpRequestProgressEventThrottle::dispatchEventAndLoadend is replaced by dispatchProgressEvent(const AtomicString&)
Tests: http/tests/xmlhttprequest/loadstart-event-init.html
http/tests/xmlhttprequest/onabort-progressevent-attributes.html
http/tests/xmlhttprequest/onload-progressevent-attributes.html
http/tests/xmlhttprequest/upload-onabort-progressevent-attributes.html
http/tests/xmlhttprequest/upload-onload-progressevent-attributes.html
* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::callReadyStateChangeListener): changed readystatechange event from ProgressEvent to Event (not cancellable, not bubblable) to better match the spec
(WebCore::XMLHttpRequest::createRequest):
(WebCore::XMLHttpRequest::abort): code refactoring to handle error event dispatching in a single way
(WebCore::XMLHttpRequest::networkError): code refactoring to handle error event dispatching in a single way
(WebCore::XMLHttpRequest::abortError): code refactoring to handle error event dispatching in a single way
(WebCore::XMLHttpRequest::didSendData):
(WebCore::XMLHttpRequest::didReceiveData):
(WebCore::XMLHttpRequest::dispatchErrorEvents): dispatch progress events in case of error
(WebCore::XMLHttpRequest::didTimeout): code refactoring to handle error event dispatching in a single way
* xml/XMLHttpRequest.h:
* xml/XMLHttpRequestProgressEventThrottle.cpp: before the patch, the fact that a progress event is being throttled is stored indirectly (m_loaded or m_total not equal to zero). With the patch, this information is stored in m_hasThrottledProgressEvent. The m_loaded and m_total values are no longer set back to zero after a progress event is dispatched. This allows using these values to correctly initialize other ProgressEvent events (in particular loadend, abort, timeout...)
(WebCore::XMLHttpRequestProgressEventThrottle::XMLHttpRequestProgressEventThrottle):
(WebCore::XMLHttpRequestProgressEventThrottle::dispatchThrottledProgressEvent): always update the new m_loaded and m_total values. If progress event is not sent as part of the function call, store the fact that a progress event is being throttled through m_hasThrottledProgressEvent.
(WebCore::XMLHttpRequestProgressEventThrottle::dispatchProgressEvent): used to send any ProgressEvent event that is not be throttled
(WebCore::XMLHttpRequestProgressEventThrottle::flushProgressEvent): after the call, no progress event is throttled anymore
(WebCore::XMLHttpRequestProgressEventThrottle::fired): after the call, no progress event is throttled anymore
(WebCore::XMLHttpRequestProgressEventThrottle::hasEventToDispatch):
(WebCore::XMLHttpRequestProgressEventThrottle::suspend):
* xml/XMLHttpRequestProgressEventThrottle.h: introduced m_hasThrottledProgressEvent which stores whether a progress event is being throttled and m_computableLength which is used to initialize ProgressEvent computableLength
* xml/XMLHttpRequestUpload.cpp:
(WebCore::XMLHttpRequestUpload::XMLHttpRequestUpload):
(WebCore::XMLHttpRequestUpload::dispatchProgressEvent):
* xml/XMLHttpRequestUpload.h: introduced m_loaded, m_total and m_lengthComputable, similarly to XMLHttpRequestProgressEventThrottle
2014-01-08 Tim Horton <timothy_horton@apple.com>
TileController can fail to receive exposedRect from the drawing area if set at the wrong time
......@@ -430,14 +430,14 @@ void XMLHttpRequest::callReadyStateChangeListener()
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchXHRReadyStateChangeEvent(scriptExecutionContext(), this);
if (m_async || (m_state <= OPENED || m_state == DONE))
m_progressEventThrottle.dispatchReadyStateChangeEvent(XMLHttpRequestProgressEvent::create(eventNames().readystatechangeEvent), m_state == DONE ? FlushProgressEvent : DoNotFlushProgressEvent);
m_progressEventThrottle.dispatchReadyStateChangeEvent(Event::create(eventNames().readystatechangeEvent, false, false), m_state == DONE ? FlushProgressEvent : DoNotFlushProgressEvent);
InspectorInstrumentation::didDispatchXHRReadyStateChangeEvent(cookie);
if (m_state == DONE && !m_error) {
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchXHRLoadEvent(scriptExecutionContext(), this);
m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadEvent));
m_progressEventThrottle.dispatchProgressEvent(eventNames().loadEvent);
InspectorInstrumentation::didDispatchXHRLoadEvent(cookie);
m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadendEvent));
m_progressEventThrottle.dispatchProgressEvent(eventNames().loadendEvent);
}
}
......@@ -765,10 +765,10 @@ void XMLHttpRequest::createRequest(ExceptionCode& ec)
// Also, only async requests support upload progress events.
bool uploadEvents = false;
if (m_async) {
m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadstartEvent));
m_progressEventThrottle.dispatchProgressEvent(eventNames().loadstartEvent);
if (m_requestEntityBody && m_upload) {
uploadEvents = m_upload->hasEventListeners();
m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadstartEvent));
m_upload->dispatchProgressEvent(eventNames().loadstartEvent);
}
}
......@@ -862,12 +862,7 @@ void XMLHttpRequest::abort()
m_state = UNSENT;
}
m_progressEventThrottle.dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::create(eventNames().abortEvent));
if (!m_uploadComplete) {
m_uploadComplete = true;
if (m_upload && m_uploadEventsAllowed)
m_upload->dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::create(eventNames().abortEvent));
}
dispatchErrorEvents(eventNames().abortEvent);
}
void XMLHttpRequest::internalAbort()
......@@ -928,24 +923,14 @@ void XMLHttpRequest::genericError()
void XMLHttpRequest::networkError()
{
genericError();
if (!m_uploadComplete) {
m_uploadComplete = true;
if (m_upload && m_uploadEventsAllowed)
m_upload->dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::create(eventNames().errorEvent));
}
m_progressEventThrottle.dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::create(eventNames().errorEvent));
dispatchErrorEvents(eventNames().errorEvent);
internalAbort();
}
void XMLHttpRequest::abortError()
{
genericError();
if (!m_uploadComplete) {
m_uploadComplete = true;
if (m_upload && m_uploadEventsAllowed)
m_upload->dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::create(eventNames().abortEvent));
}
m_progressEventThrottle.dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::create(eventNames().abortEvent));
dispatchErrorEvents(eventNames().abortEvent);
}
void XMLHttpRequest::dropProtection()
......@@ -1179,12 +1164,13 @@ void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon
return;
if (m_uploadEventsAllowed)
m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().progressEvent, true, bytesSent, totalBytesToBeSent));
m_upload->dispatchThrottledProgressEvent(true, bytesSent, totalBytesToBeSent);
if (bytesSent == totalBytesToBeSent && !m_uploadComplete) {
m_uploadComplete = true;
if (m_uploadEventsAllowed)
m_upload->dispatchEventAndLoadEnd(XMLHttpRequestProgressEvent::create(eventNames().loadEvent));
if (m_uploadEventsAllowed) {
m_upload->dispatchProgressEvent(eventNames().loadEvent);
m_upload->dispatchProgressEvent(eventNames().loadendEvent);
}
}
}
......@@ -1242,13 +1228,13 @@ void XMLHttpRequest::didReceiveData(const char* data, int len)
}
if (!m_error) {
long long expectedLength = m_response.expectedContentLength();
m_receivedLength += len;
if (m_async) {
long long expectedLength = m_response.expectedContentLength();
bool lengthComputable = expectedLength > 0 && m_receivedLength <= expectedLength;
unsigned long long total = lengthComputable ? expectedLength : 0;
m_progressEventThrottle.dispatchProgressEvent(lengthComputable, m_receivedLength, total);
m_progressEventThrottle.dispatchThrottledProgressEvent(lengthComputable, m_receivedLength, total);
}
if (m_state != LOADING)
......@@ -1259,6 +1245,19 @@ void XMLHttpRequest::didReceiveData(const char* data, int len)
}
}
void XMLHttpRequest::dispatchErrorEvents(const AtomicString& type)
{
if (!m_uploadComplete) {
m_uploadComplete = true;
if (m_upload && m_uploadEventsAllowed) {
m_upload->dispatchProgressEvent(type);
m_upload->dispatchProgressEvent(eventNames().loadendEvent);
}
}
m_progressEventThrottle.dispatchProgressEvent(type);