%PDF- %PDF-
| Direktori : /home1/lightco1/www/plugins/system/jsnframework/assets/joomlashine/js/libs/ |
| Current File : //home1/lightco1/www/plugins/system/jsnframework/assets/joomlashine/js/libs/downloader.js |
define([
],
function ()
{
/**
* HTTP Downloader class
*/
var JSNHttpDownload = function (options) {
this.opts = options;
this.userAgent = window.navigator.userAgent;
this.useIFrame = /MSIE/.test(this.userAgent);
this.processId = this.opts.process || this.generateId();
this.useIFrame == true
? this.initIFrame()
: this.initXHR()
};
JSNHttpDownload.prototype = {
/**
* Just return a random string that use to determine
* process ID
*
* @return string
*/
generateId: function () {
var result = '',
chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
length = 10;
for (var i = length; i > 0; --i)
result += chars[Math.round(Math.random() * (chars.length - 1))];
return result;
},
/**
* Method use to create an iframe element, it have
* role as ajax transport
*
* @return void
*/
initIFrame: function () {
var self = this;
this.iframe = document.createElement('iframe');
this.iframe.style.display = 'none';
// Add iframe to document
document.body.appendChild(this.iframe);
// Generate name of callback function
this.progressCallback = '__' + this.processId + '_progress';
this.completeCallback = '__' + this.processId + '_complete';
console.log(this.progressCallback);
// Attach callback functions to window object
window[this.progressCallback] = function (size, downloaded, speed) {
self.progress(size, downloaded, speed);
};
window[this.completeCallback] = function (success) {
self.complete(success);
}
},
/**
* Initialize XMLHttpRequest object, this object use to
* send request to download server and update progress
*
* @return void
*/
initXHR: function () {
var self = this;
this.xhr = null;
try {
this.xhr = new XMLHttpRequest();
if (this.xhr.overrideMimeType)
this.xhr.overrideMimeType('text/xml');
}
catch(e) {
// Switch back to IFrame transport when XHR
// does not support
this.useIFrame = true;
this.initIFrame();
return;
}
},
/**
* This method use to tracking downloaded contents of file
* and update progress bar
*
* @param int size File size
* @param int downloaded Downloaded size
* @param float speed Download speed
*
* @return void
*/
progress: function (size, downloaded, speed) {
var _size = this.convert(size, 2),
_downloaded = this.convert(downloaded, 2),
_speed = this.convert(speed, 2),
_percent = this.round(downloaded/size * 100, 2);
if (typeof(this.opts.progress) == 'function')
this.opts.progress.call(this, _size, _downloaded, _percent, _speed);
},
/**
* This method is auto invoke when download process is completed
*
* @param boolean success This flag is true if download process is successfully
* @return void
*/
complete: function (success, file) {
if (typeof(this.opts.complete) == 'function')
this.opts.complete.call(this, success, file);
},
/**
* Send a request to download server to begin download file
*
* @param object params Parameters that will passed to download URL
*
* @return void
*/
start: function (params) {
var self = this,
urlParams = [],
url = this.opts.url;
if (this.useIFrame == true) params['transport'] = 'iframe';
if (typeof(params) == 'object') {
for (var key in params)
urlParams.push(key + '=' + encodeURIComponent(params[key]));
url.indexOf('?') != -1
? url = url + '&' + urlParams.join('&')
: url = url + '?' + urlParams.join('&');
}
if (this.useIFrame == true) {
this.iframe.src = url;
return;
}
this.xhr.open('GET', url, true);
this.xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
this.xhr.send(null);
this.polling = setInterval(function () {
var completePattern = /\[complete:([^\]]+)\]/,
pathPattern = /\[path:([^\]]+)\]/,
progressPattern = /\[([0-9-\.]+)\s*,\s*([0-9-\.]+)\s*,\s*([0-9-\.]+)\]([^\[]*)$/,
responseText = self.xhr.responseText;
// Update download progress
if (progressPattern.test(responseText)) {
var result = progressPattern.exec(responseText);
self.fileSize = result[1];
self.downloadSpeed = result[3];
self.progress(self.fileSize, result[2], self.downloadSpeed);
}
if (completePattern.test(responseText)) {
var completeMessage = completePattern.exec(responseText)[1];
if (pathPattern.test(responseText)) {
var filePath = pathPattern.exec(responseText)[1];
}
self.complete(completeMessage, filePath || '');
// Stop polling
clearInterval(self.polling);
return;
}
}, 300);
},
/**
* Send a request to download server to stop download
* process
*
* @return void
*/
stop: function () {
this.stopXhr = null;
try { this.stopXhr = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
try { this.stopXhr = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
try { this.stopXhr = new XMLHttpRequest(); } catch(e) {}
if (this.stopXhr == null)
return;
this.stopXhr.open('GET', 'stop.php?process=' + this.processId);
this.stopXhr.send(null);
},
/**
* Returns the rounded value of number to specified
* precision (number of digits after the decimal point).
* precision can also be negative or zero (default).
*
* @param float value Number to be rounded
* @param int precision Number of digits after the decimal point
* @param string mode One of PHP_ROUND_HALF_UP,PHP_ROUND_HALF_DOWN, PHP_ROUND_HALF_EVEN, or PHP_ROUND_HALF_ODD
*
* @return float
*/
round: function (value, precision, mode) {
var m, f, isHalf, sgn;
precision |= 0;
m = Math.pow(10, precision);
value *= m;
sgn = (value > 0) | -(value < 0);
isHalf = value % 1 === 0.5 * sgn;
f = Math.floor(value);
if (isHalf) {
switch (mode) {
case 'PHP_ROUND_HALF_DOWN': value = f + (sgn < 0); break;
case 'PHP_ROUND_HALF_EVEN': value = f + (f % 2 * sgn); break;
case 'PHP_ROUND_HALF_ODD' : value = f + !(f % 2); break;
default: value = f + (sgn > 0);
}
}
return (isHalf ? value : Math.round(value)) / m;
},
/**
* Convert number of bytes into human readable format
*
* @param int bytes Number of bytes to convert
* @param int precision Number of digits after the decimal separator
*
* @return string
*/
convert: function (size, precision) {
var units = ['B', 'KB', 'MB', 'TB'],
currentUnit = 0,
calculatedSize = size;
while (calculatedSize > 1024 && units[currentUnit] !== undefined) {
calculatedSize = calculatedSize / 1024;
currentUnit++;
}
return {
size: this.round(calculatedSize, precision),
unit: units[currentUnit]
}
}
}
return JSNHttpDownload;
});