2017-07-03 15:05:22 +00:00
|
|
|
var Class = require('../utils/Class');
|
2017-07-03 16:06:40 +00:00
|
|
|
var GetFastValue = require('../utils/object/GetFastValue');
|
2016-12-06 15:15:42 +00:00
|
|
|
var CONST = require('./const');
|
2017-07-03 15:05:22 +00:00
|
|
|
var GetURL = require('./GetURL');
|
|
|
|
var MergeXHRSettings = require('./MergeXHRSettings');
|
2016-12-01 12:50:58 +00:00
|
|
|
var XHRLoader = require('./XHRLoader');
|
|
|
|
var XHRSettings = require('./XHRSettings');
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2017-07-03 15:05:22 +00:00
|
|
|
// Phaser.Loader.File
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2017-07-03 15:05:22 +00:00
|
|
|
var File = new Class({
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2017-07-03 15:05:22 +00:00
|
|
|
initialize:
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2017-07-03 16:06:40 +00:00
|
|
|
// old signature: type, key, url, responseType, xhrSettings, config
|
|
|
|
function File (fileConfig)
|
2017-07-03 15:05:22 +00:00
|
|
|
{
|
|
|
|
// file type (image, json, etc) for sorting within the Loader
|
2017-07-03 16:06:40 +00:00
|
|
|
this.type = GetFastValue(fileConfig, 'type', false);
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2017-07-03 15:05:22 +00:00
|
|
|
// unique cache key (unique within its file type)
|
2017-07-03 16:06:40 +00:00
|
|
|
this.key = GetFastValue(fileConfig, 'key', false);
|
|
|
|
|
|
|
|
if (!this.type || !this.key)
|
|
|
|
{
|
|
|
|
throw new Error('Error calling \'Loader.' + this.type + '\' invalid key provided.');
|
|
|
|
}
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2017-07-03 15:05:22 +00:00
|
|
|
// The URL of the file, not including baseURL
|
2017-07-05 12:36:45 +00:00
|
|
|
this.url = GetFastValue(fileConfig, 'url');
|
2017-07-03 16:06:40 +00:00
|
|
|
|
2017-07-05 12:36:45 +00:00
|
|
|
if (this.url === undefined)
|
2017-07-03 16:06:40 +00:00
|
|
|
{
|
2017-07-05 12:36:45 +00:00
|
|
|
this.url = GetFastValue(fileConfig, 'path', '') + this.key + '.' + GetFastValue(fileConfig, 'extension', '');
|
2017-07-03 16:06:40 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.url = GetFastValue(fileConfig, 'path', '').concat(this.url);
|
|
|
|
}
|
2017-07-03 15:05:22 +00:00
|
|
|
|
|
|
|
// Set when the Loader calls 'load' on this file
|
|
|
|
this.src = '';
|
2016-12-12 22:27:53 +00:00
|
|
|
|
2017-07-03 16:06:40 +00:00
|
|
|
this.xhrSettings = XHRSettings(GetFastValue(fileConfig, 'responseType', undefined));
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2017-07-03 16:06:40 +00:00
|
|
|
if (GetFastValue(fileConfig, 'xhrSettings', false))
|
2017-07-03 15:05:22 +00:00
|
|
|
{
|
2017-07-03 16:06:40 +00:00
|
|
|
this.xhrSettings = MergeXHRSettings(this.xhrSettings, GetFastValue(fileConfig, 'xhrSettings', {}));
|
2017-07-03 15:05:22 +00:00
|
|
|
}
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2018-01-19 19:13:02 +00:00
|
|
|
// The LoaderPlugin instance that is loading this file
|
|
|
|
this.loader = null;
|
|
|
|
|
2017-07-03 15:05:22 +00:00
|
|
|
this.xhrLoader = null;
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2017-07-03 15:05:22 +00:00
|
|
|
this.state = CONST.FILE_PENDING;
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2017-07-03 15:05:22 +00:00
|
|
|
// Set by onProgress (only if loading via XHR)
|
|
|
|
this.bytesTotal = 0;
|
|
|
|
this.bytesLoaded = -1;
|
|
|
|
this.percentComplete = -1;
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2017-07-03 15:05:22 +00:00
|
|
|
// For CORs based loading.
|
|
|
|
// If this is undefined then the File will check BaseLoader.crossOrigin and use that (if set)
|
|
|
|
this.crossOrigin = undefined;
|
2017-02-04 05:36:06 +00:00
|
|
|
|
2017-07-03 15:05:22 +00:00
|
|
|
// The actual processed file data
|
|
|
|
this.data = undefined;
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2017-07-03 15:05:22 +00:00
|
|
|
// A config object that can be used by file types to store transitional data
|
2017-07-03 16:06:40 +00:00
|
|
|
this.config = GetFastValue(fileConfig, 'config', {});
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2017-07-03 15:05:22 +00:00
|
|
|
// Multipart file? (i.e. an atlas and its json together)
|
|
|
|
this.linkFile = undefined;
|
|
|
|
this.linkType = '';
|
|
|
|
},
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2016-12-01 12:50:58 +00:00
|
|
|
resetXHR: function ()
|
|
|
|
{
|
|
|
|
this.xhrLoader.onload = undefined;
|
|
|
|
this.xhrLoader.onerror = undefined;
|
|
|
|
this.xhrLoader.onprogress = undefined;
|
|
|
|
},
|
|
|
|
|
2018-01-19 19:13:02 +00:00
|
|
|
// Called by the Loader, starts the actual file downloading.
|
|
|
|
// During the load the methods onLoad, onProgress, etc are called based on the XHR events.
|
|
|
|
load: function (loader)
|
|
|
|
{
|
|
|
|
this.loader = loader;
|
|
|
|
|
|
|
|
if (this.state === CONST.FILE_POPULATED)
|
|
|
|
{
|
|
|
|
this.onComplete();
|
|
|
|
|
|
|
|
loader.nextFile(this);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.src = GetURL(this, loader.baseURL);
|
|
|
|
|
|
|
|
if (this.src.indexOf('data:') === 0)
|
|
|
|
{
|
|
|
|
console.log('Local data URI');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.xhrLoader = XHRLoader(this, loader.xhr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-01-19 16:56:41 +00:00
|
|
|
// Called when the file loads, is sent a DOM ProgressEvent
|
2016-12-01 12:50:58 +00:00
|
|
|
onLoad: function (event)
|
|
|
|
{
|
|
|
|
this.resetXHR();
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2018-01-19 17:29:14 +00:00
|
|
|
if (event.target && event.target.status !== 200)
|
|
|
|
{
|
2018-01-19 19:13:02 +00:00
|
|
|
this.loader.nextFile(this, false);
|
2018-01-19 17:29:14 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-01-19 19:13:02 +00:00
|
|
|
this.loader.nextFile(this, true);
|
2018-01-19 17:29:14 +00:00
|
|
|
}
|
2016-12-01 12:50:58 +00:00
|
|
|
},
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2018-01-19 19:13:02 +00:00
|
|
|
// Called when the file errors, is sent a DOM ProgressEvent
|
2016-12-01 12:50:58 +00:00
|
|
|
onError: function (event)
|
|
|
|
{
|
|
|
|
this.resetXHR();
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2018-01-19 19:13:02 +00:00
|
|
|
this.loader.nextFile(this, false);
|
2016-12-01 12:50:58 +00:00
|
|
|
},
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2016-12-01 12:50:58 +00:00
|
|
|
onProgress: function (event)
|
|
|
|
{
|
2016-12-07 01:13:17 +00:00
|
|
|
if (event.lengthComputable)
|
|
|
|
{
|
|
|
|
this.bytesLoaded = event.loaded;
|
|
|
|
this.bytesTotal = event.total;
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2016-12-07 01:13:17 +00:00
|
|
|
this.percentComplete = Math.min((this.bytesLoaded / this.bytesTotal), 1);
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2018-01-19 19:13:02 +00:00
|
|
|
// console.log(this.percentComplete + '% (' + this.bytesLoaded + ' bytes)');
|
|
|
|
this.loader.emit('fileprogress', this, this.percentComplete);
|
|
|
|
}
|
2016-12-01 12:50:58 +00:00
|
|
|
},
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2018-01-19 19:13:02 +00:00
|
|
|
// Usually overriden by the FileTypes and is called by Loader.finishedLoading.
|
|
|
|
// The callback is Loader.processUpdate
|
2016-12-07 00:27:56 +00:00
|
|
|
onProcess: function (callback)
|
2016-12-01 12:50:58 +00:00
|
|
|
{
|
2016-12-07 00:27:56 +00:00
|
|
|
this.state = CONST.FILE_PROCESSING;
|
|
|
|
|
|
|
|
this.onComplete();
|
2016-12-08 16:21:16 +00:00
|
|
|
|
|
|
|
callback(this);
|
2016-12-01 12:50:58 +00:00
|
|
|
},
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2016-12-01 12:50:58 +00:00
|
|
|
onComplete: function ()
|
|
|
|
{
|
2016-12-07 04:43:02 +00:00
|
|
|
if (this.linkFile)
|
|
|
|
{
|
|
|
|
if (this.linkFile.state === CONST.FILE_WAITING_LINKFILE)
|
|
|
|
{
|
|
|
|
// The linkfile has finished processing, and is waiting for this file, so let's do them both
|
|
|
|
this.state = CONST.FILE_COMPLETE;
|
|
|
|
this.linkFile.state = CONST.FILE_COMPLETE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The linkfile still hasn't finished loading and/or processing yet
|
|
|
|
this.state = CONST.FILE_WAITING_LINKFILE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.state = CONST.FILE_COMPLETE;
|
|
|
|
}
|
2016-12-01 12:50:58 +00:00
|
|
|
}
|
2017-07-03 15:05:22 +00:00
|
|
|
|
|
|
|
});
|
2016-11-30 01:24:33 +00:00
|
|
|
|
2017-10-12 16:13:40 +00:00
|
|
|
/**
|
|
|
|
* Static method for creating object URL using URL API and setting it as image 'src' attribute.
|
|
|
|
* If URL API is not supported (usually on old browsers) it falls back to creating Base64 encoded url using FileReader.
|
|
|
|
*
|
|
|
|
* @method createObjectURL
|
|
|
|
* @static
|
|
|
|
* @param image {Image} Image object which 'src' attribute should be set to object URL.
|
|
|
|
* @param blob {Blob} A Blob object to create an object URL for.
|
|
|
|
* @param defaultType {string} Default mime type used if blob type is not available.
|
|
|
|
*/
|
|
|
|
File.createObjectURL = function (image, blob, defaultType)
|
2017-10-12 14:20:42 +00:00
|
|
|
{
|
2017-11-14 12:21:25 +00:00
|
|
|
if (typeof URL === 'function')
|
2017-10-12 14:20:42 +00:00
|
|
|
{
|
2017-10-12 16:13:40 +00:00
|
|
|
image.src = URL.createObjectURL(blob);
|
2017-10-12 14:20:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
var reader = new FileReader();
|
|
|
|
|
2017-11-14 12:21:25 +00:00
|
|
|
reader.onload = function ()
|
2017-10-12 14:20:42 +00:00
|
|
|
{
|
2017-11-14 12:21:25 +00:00
|
|
|
image.removeAttribute('crossOrigin');
|
2017-10-12 16:13:40 +00:00
|
|
|
image.src = 'data:' + (blob.type || defaultType) + ';base64,' + reader.result.split(',')[1];
|
2017-10-12 14:20:42 +00:00
|
|
|
};
|
|
|
|
|
2017-10-12 16:13:40 +00:00
|
|
|
reader.onerror = image.onerror;
|
2017-10-12 14:20:42 +00:00
|
|
|
|
2017-10-12 16:13:40 +00:00
|
|
|
reader.readAsDataURL(blob);
|
2017-10-12 14:20:42 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-10-12 16:13:40 +00:00
|
|
|
/**
|
|
|
|
* Static method for releasing an existing object URL which was previously created
|
|
|
|
* by calling {@link File#createObjectURL} method.
|
|
|
|
*
|
|
|
|
* @method revokeObjectURL
|
|
|
|
* @static
|
|
|
|
* @param image {Image} Image object which 'src' attribute should be revoked.
|
|
|
|
*/
|
|
|
|
File.revokeObjectURL = function (image)
|
2017-10-12 14:20:42 +00:00
|
|
|
{
|
2018-01-18 16:48:25 +00:00
|
|
|
if (typeof URL === 'function')
|
2017-10-12 14:20:42 +00:00
|
|
|
{
|
2017-10-12 16:13:40 +00:00
|
|
|
URL.revokeObjectURL(image.src);
|
2017-10-12 14:20:42 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-11-30 01:24:33 +00:00
|
|
|
module.exports = File;
|