New: added support for continuous load progress notification.

Previously, Cappuccino only called OBJJ_PROGRESS_CALLBACK when an executable or image sprite file was finished loading. Only a slow connection, this would result in long periods with no visible progress.

Now OBJJ_PROGRESS_CALLBACK is called continuously during download via the XHR progress event. All supported browsers except IE 9 support this event.
This commit is contained in:
Aparajita Fishman committed 2013-08-02 17:33:59 -04:00
1 parent b49a872806
commit 4221acf3fd
2 files changed
+71 -23

No files matched your search

+20 -16
View File
@@ -352,8 +352,8 @@ function loadExecutableAndResources(/*Bundle*/ aBundle, /*BOOL*/ shouldExecute)
if (!aBundle.mostEligibleEnvironment())
return failure();
loadExecutableForBundle(aBundle, success, failure);
loadSpritedImagesForBundle(aBundle, success, failure);
loadExecutableForBundle(aBundle, success, failure, progress);
loadSpritedImagesForBundle(aBundle, success, failure, progress);
if (aBundle._loadStatus === CFBundleLoading)
return success();
@@ -373,14 +373,21 @@ function loadExecutableAndResources(/*Bundle*/ aBundle, /*BOOL*/ shouldExecute)
finishBundleLoadingWithError(aBundle, anError || new Error("Could not recognize executable code format in Bundle " + aBundle));
}
function success()
function progress(bytesLoaded)
{
if ((typeof CPApp === "undefined" || !CPApp || !CPApp._finishedLaunching) &&
typeof OBJJ_PROGRESS_CALLBACK === "function" && CPApplicationSizeInBytes)
typeof OBJJ_PROGRESS_CALLBACK === "function")
{
OBJJ_PROGRESS_CALLBACK(MAX(MIN(1.0, CFTotalBytesLoaded / CPApplicationSizeInBytes), 0.0), CPApplicationSizeInBytes, aBundle.bundlePath());
}
CFTotalBytesLoaded += bytesLoaded;
var percent = CPApplicationSizeInBytes ? MAX(MIN(1.0, CFTotalBytesLoaded / CPApplicationSizeInBytes), 0.0) : 0;
OBJJ_PROGRESS_CALLBACK(percent, CPApplicationSizeInBytes, aBundle.bundlePath());
}
}
function success()
{
if (aBundle._loadStatus === CFBundleLoading)
aBundle._loadStatus = CFBundleLoaded;
else
@@ -392,13 +399,13 @@ function loadExecutableAndResources(/*Bundle*/ aBundle, /*BOOL*/ shouldExecute)
function complete()
{
aBundle._eventDispatcher.dispatchEvent(
{
type:"load",
bundle:aBundle
});
}
if (shouldExecute)
executeBundle(aBundle, complete);
else
@@ -406,7 +413,7 @@ function loadExecutableAndResources(/*Bundle*/ aBundle, /*BOOL*/ shouldExecute)
}
}
function loadExecutableForBundle(/*Bundle*/ aBundle, success, failure)
function loadExecutableForBundle(/*Bundle*/ aBundle, success, failure, progress)
{
var executableURL = aBundle.executableURL();
@@ -419,7 +426,6 @@ function loadExecutableForBundle(/*Bundle*/ aBundle, success, failure)
{
try
{
CFTotalBytesLoaded += anEvent.request.responseText().length;
decompileStaticFile(aBundle, anEvent.request.responseText(), executableURL);
aBundle._loadStatus &= ~CFBundleLoadingExecutable;
success();
@@ -428,7 +434,7 @@ function loadExecutableForBundle(/*Bundle*/ aBundle, success, failure)
{
failure(anException);
}
}, failure);
}, failure, progress);
}
function spritedImagesTestURLStringForBundle(/*Bundle*/ aBundle)
@@ -448,7 +454,7 @@ function spritedImagesURLForBundle(/*Bundle*/ aBundle)
return NULL;
}
function loadSpritedImagesForBundle(/*Bundle*/ aBundle, success, failure)
function loadSpritedImagesForBundle(/*Bundle*/ aBundle, success, failure, progress)
{
if (!aBundle.hasSpritedImages())
return;
@@ -458,7 +464,7 @@ function loadSpritedImagesForBundle(/*Bundle*/ aBundle, success, failure)
if (!CFBundleHasTestedSpriteSupport())
return CFBundleTestSpriteSupport(spritedImagesTestURLStringForBundle(aBundle), function()
{
loadSpritedImagesForBundle(aBundle, success, failure);
loadSpritedImagesForBundle(aBundle, success, failure, progress);
});
var spritedImagesURL = spritedImagesURLForBundle(aBundle);
@@ -473,17 +479,15 @@ function loadSpritedImagesForBundle(/*Bundle*/ aBundle, success, failure)
{
try
{
CFTotalBytesLoaded += anEvent.request.responseText().length;
decompileStaticFile(aBundle, anEvent.request.responseText(), spritedImagesURL);
aBundle._loadStatus &= ~CFBundleLoadingSpritedImages;
success();
}
catch(anException)
{
failure(anException);
}
success();
}, failure);
}, failure, progress);
}
var CFBundleSpriteSupportListeners = [],
+51 -7
View File
@@ -63,7 +63,11 @@ var NativeRequest = null;
// We check ActiveXObject first, because we require local file access and
// overrideMimeType feature (which the native XMLHttpRequest does not have in IE).
if (window.ActiveXObject !== undefined)
if (window.XMLHttpRequest)
{
NativeRequest = window.XMLHttpRequest;
}
else if (window.ActiveXObject !== undefined)
{
// DON'T try 4.0 and 5.0: http://bit.ly/microsoft-msxml-explanation
var MSXML_XMLHTTP_OBJECTS = ["Msxml2.XMLHTTP.3.0", "Msxml2.XMLHTTP.6.0"],
@@ -90,9 +94,6 @@ if (window.ActiveXObject !== undefined)
}
}
if (!NativeRequest)
NativeRequest = window.XMLHttpRequest;
GLOBAL(CFHTTPRequest) = function()
{
this._isOpen = false;
@@ -293,7 +294,7 @@ function determineAndDispatchHTTPRequestEvents(/*CFHTTPRequest*/ aRequest)
eventDispatcher.dispatchEvent({ type:readyStates[aRequest.readyState()], request:aRequest});
}
function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure)
function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure, onprogress)
{
var request = new CFHTTPRequest();
@@ -326,17 +327,60 @@ function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure)
}
#endif
var loaded = 0,
progressHandler = null;
function progress(progressEvent)
{
onprogress(progressEvent.loaded - loaded);
loaded = progressEvent.loaded;
}
function success(anEvent)
{
// If the browser can't handle progress events,
// we need to send a progress message with the total
// size of the file when the file finishes loading.
if (onprogress && progressHandler === null)
onprogress(anEvent.request.responseText().length);
onsuccess(anEvent);
}
if (exports.asyncLoader)
{
request.onsuccess = Asynchronous(onsuccess);
request.onsuccess = Asynchronous(success);
request.onfailure = Asynchronous(onfailure);
}
else
{
request.onsuccess = onsuccess;
request.onsuccess = success;
request.onfailure = onfailure;
}
if (onprogress)
{
var supportsProgress = true;
// document.all means IE, window.atob is only supported by IE 10+
if (document.all)
supportsProgress = !!window.atob;
if (supportsProgress)
{
try
{
progressHandler = exports.asyncLoader ? Asynchronous(progress) : progress;
request._nativeRequest.onprogress = progressHandler;
}
catch (anException)
{
// Must be <= IE 9
progressHandler = null;
}
}
}
request.open("GET", aURL.absoluteString(), exports.asyncLoader);
request.send("");
}