doc-fui-ds
Version:
Doc
1,169 lines (1,157 loc) • 294 kB
JavaScript
/*!
* bootstrap-fileinput v5.2.7
* http://plugins.krajee.com/file-input
*
* Author: Kartik Visweswaran
* Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com
*
* Licensed under the BSD-3-Clause
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
*/
(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else if (typeof module === 'object' && typeof module.exports === 'object') {
factory(require('jquery'));
} else {
factory(window.jQuery);
}
}(function ($) {
'use strict';
$.fn.fileinputLocales = {};
$.fn.fileinputThemes = {};
if (!$.fn.fileinputBsVersion) {
$.fn.fileinputBsVersion = (window.bootstrap && window.bootstrap.Alert && window.bootstrap.Alert.VERSION) ||
(window.Alert && window.Alert.VERSION) || '3.x.x';
}
String.prototype.setTokens = function (replacePairs) {
var str = this.toString(), key, re;
for (key in replacePairs) {
if (replacePairs.hasOwnProperty(key)) {
re = new RegExp('\{' + key + '\}', 'g');
str = str.replace(re, replacePairs[key]);
}
}
return str;
};
if (!Array.prototype.flatMap) { // polyfill flatMap
Array.prototype.flatMap = function (lambda) {
return [].concat(this.map(lambda));
};
}
var $h, FileInput;
// fileinput helper object for all global variables and internal helper methods
$h = {
FRAMES: '.kv-preview-thumb',
SORT_CSS: 'file-sortable',
INIT_FLAG: 'init-',
SCRIPT_SRC: document && document.currentScript && document.currentScript.src || null,
OBJECT_PARAMS: '<param name="controller" value="true" />\n' +
'<param name="allowFullScreen" value="true" />\n' +
'<param name="allowScriptAccess" value="always" />\n' +
'<param name="autoPlay" value="false" />\n' +
'<param name="autoStart" value="false" />\n' +
'<param name="quality" value="high" />\n',
DEFAULT_PREVIEW: '<div class="file-preview-other">\n' +
'<span class="{previewFileIconClass}">{previewFileIcon}</span>\n' +
'</div>',
MODAL_ID: 'kvFileinputModal',
MODAL_EVENTS: ['show', 'shown', 'hide', 'hidden', 'loaded'],
logMessages: {
ajaxError: '{status}: {error}. Error Details: {text}.',
badDroppedFiles: 'Error scanning dropped files!',
badExifParser: 'Error loading the piexif.js library. {details}',
badInputType: 'The input "type" must be set to "file" for initializing the "bootstrap-fileinput" plugin.',
exifWarning: 'To avoid this warning, either set "autoOrientImage" to "false" OR ensure you have loaded ' +
'the "piexif.js" library correctly on your page before the "fileinput.js" script.',
invalidChunkSize: 'Invalid upload chunk size: "{chunkSize}". Resumable uploads are disabled.',
invalidThumb: 'Invalid thumb frame with id: "{id}".',
noResumableSupport: 'The browser does not support resumable or chunk uploads.',
noUploadUrl: 'The "uploadUrl" is not set. Ajax uploads and resumable uploads have been disabled.',
retryStatus: 'Retrying upload for chunk # {chunk} for {filename}... retry # {retry}.',
chunkQueueError: 'Could not push task to ajax pool for chunk index # {index}.',
resumableMaxRetriesReached: 'Maximum resumable ajax retries ({n}) reached.',
resumableRetryError: 'Could not retry the resumable request (try # {n})... aborting.',
resumableAborting: 'Aborting / cancelling the resumable request.',
resumableRequestError: 'Error processing resumable request. {msg}'
},
objUrl: window.URL || window.webkitURL,
getZoomPlaceholder: function () { // used to prevent 404 errors in URL parsing
var src = $h.SCRIPT_SRC, srcPath, zoomVar = '?kvTemp__2873389129__=';
if (!src) {
return zoomVar;
}
srcPath = src.substring(0, src.lastIndexOf("/"));
return srcPath.substring(0, srcPath.lastIndexOf("/") + 1) + 'img/loading.gif' + zoomVar;
},
isBs: function (ver) {
var chk = $.trim(($.fn.fileinputBsVersion || '') + '');
ver = parseInt(ver, 10);
if (!chk) {
return ver === 4;
}
return ver === parseInt(chk.charAt(0), 10);
},
defaultButtonCss: function (fill) {
return 'btn-default btn-' + (fill ? '' : 'outline-') + 'secondary';
},
now: function () {
return new Date().getTime();
},
round: function (num) {
num = parseFloat(num);
return isNaN(num) ? 0 : Math.floor(Math.round(num));
},
getArray: function (obj) {
var i, arr = [], len = obj && obj.length || 0;
for (i = 0; i < len; i++) {
arr.push(obj[i]);
}
return arr;
},
getFileRelativePath: function (file) {
/** @namespace file.relativePath */
/** @namespace file.webkitRelativePath */
return String(file.newPath || file.relativePath || file.webkitRelativePath || $h.getFileName(file) || null);
},
getFileId: function (file, generateFileId) {
var relativePath = $h.getFileRelativePath(file);
if (typeof generateFileId === 'function') {
return generateFileId(file);
}
if (!file) {
return null;
}
if (!relativePath) {
return null;
}
return (file.size + '_' + encodeURIComponent(relativePath).replace(/%/g, '_'));
},
getFrameSelector: function (id, selector) {
selector = selector || '';
return '[id="' + id + '"]' + selector;
},
getZoomSelector: function (id, selector) {
return $h.getFrameSelector('zoom-' + id, selector);
},
getFrameElement: function ($element, id, selector) {
return $element.find($h.getFrameSelector(id, selector));
},
getZoomElement: function ($element, id, selector) {
return $element.find($h.getZoomSelector(id, selector));
},
getElapsed: function (seconds) {
var delta = seconds, out = '', result = {}, structure = {
year: 31536000,
month: 2592000,
week: 604800, // uncomment row to ignore
day: 86400, // feel free to add your own row
hour: 3600,
minute: 60,
second: 1
};
$h.getObjectKeys(structure).forEach(function (key) {
result[key] = Math.floor(delta / structure[key]);
delta -= result[key] * structure[key];
});
$.each(result, function (key, value) {
if (value > 0) {
out += (out ? ' ' : '') + value + key.substring(0, 1);
}
});
return out;
},
debounce: function (func, delay) {
var inDebounce;
return function () {
var args = arguments, context = this;
clearTimeout(inDebounce);
inDebounce = setTimeout(function () {
func.apply(context, args);
}, delay);
};
},
stopEvent: function (e) {
e.stopPropagation();
e.preventDefault();
},
getFileName: function (file) {
/** @namespace file.fileName */
return file ? (file.fileName || file.name || '') : ''; // some confusion in different versions of Firefox
},
createObjectURL: function (data) {
if ($h.objUrl && $h.objUrl.createObjectURL && data) {
return $h.objUrl.createObjectURL(data);
}
return '';
},
revokeObjectURL: function (data) {
if ($h.objUrl && $h.objUrl.revokeObjectURL && data) {
$h.objUrl.revokeObjectURL(data);
}
},
compare: function (input, str, exact) {
return input !== undefined && (exact ? input === str : input.match(str));
},
isIE: function (ver) {
var div, status;
// check for IE versions < 11
if (navigator.appName !== 'Microsoft Internet Explorer') {
return false;
}
if (ver === 10) {
return new RegExp('msie\\s' + ver, 'i').test(navigator.userAgent);
}
div = document.createElement('div');
div.innerHTML = '<!--[if IE ' + ver + ']> <i></i> <![endif]-->';
status = div.getElementsByTagName('i').length;
document.body.appendChild(div);
div.parentNode.removeChild(div);
return status;
},
canOrientImage: function ($el) {
var $img = $(document.createElement('img')).css({width: '1px', height: '1px'}).insertAfter($el),
flag = $img.css('image-orientation');
$img.remove();
return !!flag;
},
canAssignFilesToInput: function () {
var input = document.createElement('input');
try {
input.type = 'file';
input.files = null;
return true;
} catch (err) {
return false;
}
},
getDragDropFolders: function (items) {
var i, item, len = items ? items.length : 0, folders = 0;
if (len > 0 && items[0].webkitGetAsEntry()) {
for (i = 0; i < len; i++) {
item = items[i].webkitGetAsEntry();
if (item && item.isDirectory) {
folders++;
}
}
}
return folders;
},
initModal: function ($modal) {
var $body = $('body');
if ($body.length) {
$modal.appendTo($body);
}
},
isFunction: function (v) {
return typeof v === 'function';
},
isEmpty: function (value, trim) {
if (value === undefined || value === null || value === '') {
return true;
}
if ($h.isString(value) && trim) {
return $.trim(value) === '';
}
if ($h.isArray(value)) {
return value.length === 0;
}
if ($.isPlainObject(value) && $.isEmptyObject(value)) {
return true
}
return false;
},
isArray: function (a) {
return Array.isArray(a) || Object.prototype.toString.call(a) === '[object Array]';
},
isString: function (a) {
return Object.prototype.toString.call(a) === '[object String]';
},
ifSet: function (needle, haystack, def) {
def = def || '';
return (haystack && typeof haystack === 'object' && needle in haystack) ? haystack[needle] : def;
},
cleanArray: function (arr) {
if (!(arr instanceof Array)) {
arr = [];
}
return arr.filter(function (e) {
return (e !== undefined && e !== null);
});
},
spliceArray: function (arr, index, reverseOrder) {
var i, j = 0, out = [], newArr;
if (!(arr instanceof Array)) {
return [];
}
newArr = $.extend(true, [], arr);
if (reverseOrder) {
newArr.reverse();
}
for (i = 0; i < newArr.length; i++) {
if (i !== index) {
out[j] = newArr[i];
j++;
}
}
if (reverseOrder) {
out.reverse();
}
return out;
},
getNum: function (num, def) {
def = def || 0;
if (typeof num === 'number') {
return num;
}
if (typeof num === 'string') {
num = parseFloat(num);
}
return isNaN(num) ? def : num;
},
hasFileAPISupport: function () {
return !!(window.File && window.FileReader);
},
hasDragDropSupport: function () {
var div = document.createElement('div');
/** @namespace div.draggable */
/** @namespace div.ondragstart */
/** @namespace div.ondrop */
return !$h.isIE(9) &&
(div.draggable !== undefined || (div.ondragstart !== undefined && div.ondrop !== undefined));
},
hasFileUploadSupport: function () {
return $h.hasFileAPISupport() && window.FormData;
},
hasBlobSupport: function () {
try {
return !!window.Blob && Boolean(new Blob());
} catch (e) {
return false;
}
},
hasArrayBufferViewSupport: function () {
try {
return new Blob([new Uint8Array(100)]).size === 100;
} catch (e) {
return false;
}
},
hasResumableUploadSupport: function () {
/** @namespace Blob.prototype.webkitSlice */
/** @namespace Blob.prototype.mozSlice */
return $h.hasFileUploadSupport() && $h.hasBlobSupport() && $h.hasArrayBufferViewSupport() &&
(!!Blob.prototype.webkitSlice || !!Blob.prototype.mozSlice || !!Blob.prototype.slice || false);
},
dataURI2Blob: function (dataURI) {
var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder ||
window.MSBlobBuilder, canBlob = $h.hasBlobSupport(), byteStr, arrayBuffer, intArray, i, mimeStr, bb,
canProceed = (canBlob || BlobBuilder) && window.atob && window.ArrayBuffer && window.Uint8Array;
if (!canProceed) {
return null;
}
if (dataURI.split(',')[0].indexOf('base64') >= 0) {
byteStr = atob(dataURI.split(',')[1]);
} else {
byteStr = decodeURIComponent(dataURI.split(',')[1]);
}
arrayBuffer = new ArrayBuffer(byteStr.length);
intArray = new Uint8Array(arrayBuffer);
for (i = 0; i < byteStr.length; i += 1) {
intArray[i] = byteStr.charCodeAt(i);
}
mimeStr = dataURI.split(',')[0].split(':')[1].split(';')[0];
if (canBlob) {
return new Blob([$h.hasArrayBufferViewSupport() ? intArray : arrayBuffer], {type: mimeStr});
}
bb = new BlobBuilder();
bb.append(arrayBuffer);
return bb.getBlob(mimeStr);
},
arrayBuffer2String: function (buffer) {
if (window.TextDecoder) {
return new TextDecoder('utf-8').decode(buffer);
}
var array = Array.prototype.slice.apply(new Uint8Array(buffer)), out = '', i = 0, len, c, char2, char3;
len = array.length;
while (i < len) {
c = array[i++];
switch (c >> 4) { // jshint ignore:line
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
// 0xxxxxxx
out += String.fromCharCode(c);
break;
case 12:
case 13:
// 110x xxxx 10xx xxxx
char2 = array[i++];
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); // jshint ignore:line
break;
case 14:
// 1110 xxxx 10xx xxxx 10xx xxxx
char2 = array[i++];
char3 = array[i++];
out += String.fromCharCode(((c & 0x0F) << 12) | // jshint ignore:line
((char2 & 0x3F) << 6) | // jshint ignore:line
((char3 & 0x3F) << 0)); // jshint ignore:line
break;
}
}
return out;
},
isHtml: function (str) {
var a = document.createElement('div');
a.innerHTML = str;
for (var c = a.childNodes, i = c.length; i--;) {
if (c[i].nodeType === 1) {
return true;
}
}
return false;
},
isSvg: function (str) {
return str.match(/^\s*<\?xml/i) && (str.match(/<!DOCTYPE svg/i) || str.match(/<svg/i));
},
getMimeType: function (signature, contents, type) {
switch (signature) {
case 'ffd8ffe0':
case 'ffd8ffe1':
case 'ffd8ffe2':
return 'image/jpeg';
case '89504e47':
return 'image/png';
case '47494638':
return 'image/gif';
case '49492a00':
return 'image/tiff';
case '52494646':
return 'image/webp';
case '66747970':
return 'video/3gp';
case '4f676753':
return 'video/ogg';
case '1a45dfa3':
return 'video/mkv';
case '000001ba':
case '000001b3':
return 'video/mpeg';
case '3026b275':
return 'video/wmv';
case '25504446':
return 'application/pdf';
case '25215053':
return 'application/ps';
case '504b0304':
case '504b0506':
case '504b0508':
return 'application/zip';
case '377abcaf':
return 'application/7z';
case '75737461':
return 'application/tar';
case '7801730d':
return 'application/dmg';
default:
switch (signature.substring(0, 6)) {
case '435753':
return 'application/x-shockwave-flash';
case '494433':
return 'audio/mp3';
case '425a68':
return 'application/bzip';
default:
switch (signature.substring(0, 4)) {
case '424d':
return 'image/bmp';
case 'fffb':
return 'audio/mp3';
case '4d5a':
return 'application/exe';
case '1f9d':
case '1fa0':
return 'application/zip';
case '1f8b':
return 'application/gzip';
default:
return contents && !contents.match(
/[^\u0000-\u007f]/) ? 'application/text-plain' : type;
}
}
}
},
addCss: function ($el, css) {
$el.removeClass(css).addClass(css);
},
getElement: function (options, param, value) {
return ($h.isEmpty(options) || $h.isEmpty(options[param])) ? value : $(options[param]);
},
createElement: function (str, tag) {
tag = tag || 'div';
return $($.parseHTML('<' + tag + '>' + str + '</' + tag + '>'));
},
uniqId: function () {
return (new Date().getTime() + Math.floor(Math.random() * Math.pow(10, 15))).toString(36);
},
cspBuffer: {
CSP_ATTRIB: 'data-csp-01928735', // a randomly named temporary attribute to store the CSP elem id
domElementsStyles: {},
stash: function (htmlString) {
var self = this, outerDom = $.parseHTML('<div>' + htmlString + '</div>'), $el = $(outerDom);
$el.find('[style]').each(function (key, elem) {
var $elem = $(elem), styleDeclaration = $elem[0].style, id = $h.uniqId(), styles = {};
if (styleDeclaration && styleDeclaration.length) {
$(styleDeclaration).each(function () {
styles[this] = styleDeclaration[this];
});
self.domElementsStyles[id] = styles;
$elem.removeAttr('style').attr(self.CSP_ATTRIB, id);
}
});
$el.filter('*').removeAttr('style'); // make sure all style attr are removed
var values = Object.values ? Object.values(outerDom) : Object.keys(outerDom).map(function (itm) {
return outerDom[itm];
});
return values.flatMap(function (elem) {
return elem.innerHTML;
}).join('');
},
apply: function (domElement) {
var self = this, $el = $(domElement);
$el.find('[' + self.CSP_ATTRIB + ']').each(function (key, elem) {
var $elem = $(elem), id = $elem.attr(self.CSP_ATTRIB), styles = self.domElementsStyles[id];
if (styles) {
$elem.css(styles);
}
$elem.removeAttr(self.CSP_ATTRIB);
});
self.domElementsStyles = {};
}
},
setHtml: function ($elem, htmlString) {
var buf = $h.cspBuffer;
$elem.html(buf.stash(htmlString));
buf.apply($elem);
return $elem;
},
htmlEncode: function (str, undefVal) {
if (str === undefined) {
return undefVal || null;
}
return str.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
},
replaceTags: function (str, tags) {
var out = str;
if (!tags) {
return out;
}
$.each(tags, function (key, value) {
if (typeof value === 'function') {
value = value();
}
out = out.split(key).join(value);
});
return out;
},
cleanMemory: function ($thumb) {
var data = $thumb.is('img') ? $thumb.attr('src') : $thumb.find('source').attr('src');
$h.revokeObjectURL(data);
},
findFileName: function (filePath) {
var sepIndex = filePath.lastIndexOf('/');
if (sepIndex === -1) {
sepIndex = filePath.lastIndexOf('\\');
}
return filePath.split(filePath.substring(sepIndex, sepIndex + 1)).pop();
},
checkFullScreen: function () {
return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement ||
document.msFullscreenElement;
},
toggleFullScreen: function (maximize) {
var doc = document, de = doc.documentElement, isFullScreen = $h.checkFullScreen();
if (de && maximize && !isFullScreen) {
if (de.requestFullscreen) {
de.requestFullscreen();
} else {
if (de.msRequestFullscreen) {
de.msRequestFullscreen();
} else {
if (de.mozRequestFullScreen) {
de.mozRequestFullScreen();
} else {
if (de.webkitRequestFullscreen) {
de.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
}
}
}
}
} else {
if (isFullScreen) {
if (doc.exitFullscreen) {
doc.exitFullscreen();
} else {
if (doc.msExitFullscreen) {
doc.msExitFullscreen();
} else {
if (doc.mozCancelFullScreen) {
doc.mozCancelFullScreen();
} else {
if (doc.webkitExitFullscreen) {
doc.webkitExitFullscreen();
}
}
}
}
}
}
},
moveArray: function (arr, oldIndex, newIndex, reverseOrder) {
var newArr = $.extend(true, [], arr);
if (reverseOrder) {
newArr.reverse();
}
if (newIndex >= newArr.length) {
var k = newIndex - newArr.length;
while ((k--) + 1) {
newArr.push(undefined);
}
}
newArr.splice(newIndex, 0, newArr.splice(oldIndex, 1)[0]);
if (reverseOrder) {
newArr.reverse();
}
return newArr;
},
closeButton: function (css) {
css = ($h.isBs(5) ? 'btn-close' : 'close') + (css ? ' ' + css : '');
return '<button type="button" class="' + css + '" aria-label="Close">\n' +
($h.isBs(5) ? '' : ' <span aria-hidden="true">×</span>\n') +
'</button>';
},
getRotation: function (value) {
switch (value) {
case 2:
return 'rotateY(180deg)';
case 3:
return 'rotate(180deg)';
case 4:
return 'rotate(180deg) rotateY(180deg)';
case 5:
return 'rotate(270deg) rotateY(180deg)';
case 6:
return 'rotate(90deg)';
case 7:
return 'rotate(90deg) rotateY(180deg)';
case 8:
return 'rotate(270deg)';
default:
return '';
}
},
setTransform: function (el, val) {
if (!el) {
return;
}
el.style.transform = val;
el.style.webkitTransform = val;
el.style['-moz-transform'] = val;
el.style['-ms-transform'] = val;
el.style['-o-transform'] = val;
},
getObjectKeys: function (obj) {
var keys = [];
if (obj) {
$.each(obj, function (key) {
keys.push(key);
});
}
return keys;
},
getObjectSize: function (obj) {
return $h.getObjectKeys(obj).length;
},
/**
* Small dependency injection for the task manager
* https://gist.github.com/fearphage/4341799
*/
whenAll: function (array) {
var s = [].slice, resolveValues = arguments.length === 1 && $h.isArray(array) ? array : s.call(arguments),
deferred = $.Deferred(), i, failed = 0, value, length = resolveValues.length,
remaining = length, rejectContexts, rejectValues, resolveContexts, updateFunc;
rejectContexts = rejectValues = resolveContexts = Array(length);
updateFunc = function (index, contexts, values) {
return function () {
if (values !== resolveValues) {
failed++;
}
deferred.notifyWith(contexts[index] = this, values[index] = s.call(arguments));
if (!(--remaining)) {
deferred[(!failed ? 'resolve' : 'reject') + 'With'](contexts, values);
}
};
};
for (i = 0; i < length; i++) {
if ((value = resolveValues[i]) && $.isFunction(value.promise)) {
value.promise()
.done(updateFunc(i, resolveContexts, resolveValues))
.fail(updateFunc(i, rejectContexts, rejectValues));
} else {
deferred.notifyWith(this, value);
--remaining;
}
}
if (!remaining) {
deferred.resolveWith(resolveContexts, resolveValues);
}
return deferred.promise();
}
};
FileInput = function (element, options) {
var self = this;
self.$element = $(element);
self.$parent = self.$element.parent();
if (!self._validate()) {
return;
}
self.isPreviewable = $h.hasFileAPISupport();
self.isIE9 = $h.isIE(9);
self.isIE10 = $h.isIE(10);
if (self.isPreviewable || self.isIE9) {
self._init(options);
self._listen();
}
self.$element.removeClass('file-loading');
};
FileInput.prototype = {
constructor: FileInput,
_cleanup: function () {
var self = this;
self.reader = null;
self.clearFileStack();
self.fileBatchCompleted = true;
self.isError = false;
self.isDuplicateError = false;
self.isPersistentError = false;
self.cancelling = false;
self.paused = false;
self.lastProgress = 0;
self._initAjax();
},
_isAborted: function () {
var self = this;
return self.cancelling || self.paused;
},
_initAjax: function () {
var self = this, tm = self.taskManager = {
pool: {},
addPool: function (id) {
return (tm.pool[id] = new tm.TasksPool(id));
},
getPool: function (id) {
return tm.pool[id];
},
addTask: function (id, logic) { // add standalone task directly from task manager
return new tm.Task(id, logic);
},
TasksPool: function (id) {
var tp = this;
tp.id = id;
tp.cancelled = false;
tp.cancelledDeferrer = $.Deferred();
tp.tasks = {};
tp.addTask = function (id, logic) {
return (tp.tasks[id] = new tm.Task(id, logic));
};
tp.size = function () {
return $h.getObjectSize(tp.tasks);
};
tp.run = function (maxThreads) {
var i = 0, failed = false, task, tasksList = $h.getObjectKeys(tp.tasks).map(function (key) {
return tp.tasks[key];
}), tasksDone = [], deferred = $.Deferred(), enqueue, callback;
if (tp.cancelled) {
tp.cancelledDeferrer.resolve();
return deferred.reject();
}
// if run all at once
if (!maxThreads) {
var tasksDeferredList = $h.getObjectKeys(tp.tasks).map(function (key) {
return tp.tasks[key].deferred;
});
// when all are done
$h.whenAll(tasksDeferredList).done(function () {
var argv = $h.getArray(arguments);
if (!tp.cancelled) {
deferred.resolve.apply(null, argv);
tp.cancelledDeferrer.reject();
} else {
deferred.reject.apply(null, argv);
tp.cancelledDeferrer.resolve();
}
}).fail(function () {
var argv = $h.getArray(arguments);
deferred.reject.apply(null, argv);
if (!tp.cancelled) {
tp.cancelledDeferrer.reject();
} else {
tp.cancelledDeferrer.resolve();
}
});
// run all tasks
$.each(tp.tasks, function (id) {
task = tp.tasks[id];
task.run();
});
return deferred;
}
enqueue = function (task) {
$.when(task.deferred)
.fail(function () {
failed = true;
callback.apply(null, arguments);
})
.always(callback);
};
callback = function () {
var argv = $h.getArray(arguments);
// notify a task just ended
deferred.notify(argv);
tasksDone.push(argv);
if (tp.cancelled) {
deferred.reject.apply(null, tasksDone);
tp.cancelledDeferrer.resolve();
return;
}
if (tasksDone.length === tp.size()) {
if (failed) {
deferred.reject.apply(null, tasksDone);
} else {
deferred.resolve.apply(null, tasksDone);
}
}
// if there are any tasks remaining
if (tasksList.length) {
task = tasksList.shift();
enqueue(task);
task.run();
}
};
// run the first "maxThreads" tasks
while (tasksList.length && i++ < maxThreads) {
task = tasksList.shift();
enqueue(task);
task.run();
}
return deferred;
};
tp.cancel = function () {
tp.cancelled = true;
return tp.cancelledDeferrer;
};
},
Task: function (id, logic) {
var tk = this;
tk.id = id;
tk.deferred = $.Deferred();
tk.logic = logic;
tk.context = null;
tk.run = function () {
var argv = $h.getArray(arguments);
argv.unshift(tk.deferred); // add deferrer as first argument
logic.apply(tk.context, argv); // run task
return tk.deferred; // return deferrer
};
tk.runWithContext = function (context) {
tk.context = context;
return tk.run();
};
}
};
self.ajaxQueue = [];
self.ajaxRequests = [];
self.ajaxPool = null;
self.ajaxAborted = false;
},
_init: function (options, refreshMode) {
var self = this, f, $el = self.$element, $cont, t, tmp;
self.options = options;
self.zoomPlaceholder = $h.getZoomPlaceholder();
self.canOrientImage = $h.canOrientImage($el);
$.each(options, function (key, value) {
switch (key) {
case 'minFileCount':
case 'maxFileCount':
case 'maxTotalFileCount':
case 'minFileSize':
case 'maxFileSize':
case 'maxFilePreviewSize':
case 'resizeQuality':
case 'resizeIfSizeMoreThan':
case 'progressUploadThreshold':
case 'initialPreviewCount':
case 'zoomModalHeight':
case 'minImageHeight':
case 'maxImageHeight':
case 'minImageWidth':
case 'maxImageWidth':
case 'bytesToKB':
self[key] = $h.getNum(value);
break;
default:
self[key] = value;
break;
}
});
if (!self.bytesToKB || self.bytesToKB <= 0) {
self.bytesToKB = 1024;
}
if (self.errorCloseButton === undefined) {
self.errorCloseButton = $h.closeButton('kv-error-close' + ($h.isBs(5) ? ' float-end' : ''));
}
if (self.maxTotalFileCount > 0 && self.maxTotalFileCount < self.maxFileCount) {
self.maxTotalFileCount = self.maxFileCount;
}
if (self.rtl) { // swap buttons for rtl
tmp = self.previewZoomButtonIcons.prev;
self.previewZoomButtonIcons.prev = self.previewZoomButtonIcons.next;
self.previewZoomButtonIcons.next = tmp;
}
// validate chunk threads to not exceed maxAjaxThreads
if (!isNaN(self.maxAjaxThreads) && self.maxAjaxThreads < self.resumableUploadOptions.maxThreads) {
self.resumableUploadOptions.maxThreads = self.maxAjaxThreads;
}
self._initFileManager();
if (typeof self.autoOrientImage === 'function') {
self.autoOrientImage = self.autoOrientImage();
}
if (typeof self.autoOrientImageInitial === 'function') {
self.autoOrientImageInitial = self.autoOrientImageInitial();
}
if (!refreshMode) {
self._cleanup();
}
self.duplicateErrors = [];
self.$form = $el.closest('form');
self._initTemplateDefaults();
self.uploadFileAttr = !$h.isEmpty($el.attr('name')) ? $el.attr('name') : 'file_data';
t = self._getLayoutTemplate('progress');
self.progressTemplate = t.replace('{class}', self.progressClass);
self.progressInfoTemplate = t.replace('{class}', self.progressInfoClass);
self.progressPauseTemplate = t.replace('{class}', self.progressPauseClass);
self.progressCompleteTemplate = t.replace('{class}', self.progressCompleteClass);
self.progressErrorTemplate = t.replace('{class}', self.progressErrorClass);
self.isDisabled = $el.attr('disabled') || $el.attr('readonly');
if (self.isDisabled) {
$el.attr('disabled', true);
}
self.isClickable = self.browseOnZoneClick && self.showPreview &&
(self.dropZoneEnabled || !$h.isEmpty(self.defaultPreviewContent));
self.isAjaxUpload = $h.hasFileUploadSupport() && !$h.isEmpty(self.uploadUrl);
self.dropZoneEnabled = $h.hasDragDropSupport() && self.dropZoneEnabled;
if (!self.isAjaxUpload) {
self.dropZoneEnabled = self.dropZoneEnabled && $h.canAssignFilesToInput();
}
self.slug = typeof options.slugCallback === 'function' ? options.slugCallback : self._slugDefault;
self.mainTemplate = self.showCaption ? self._getLayoutTemplate('main1') : self._getLayoutTemplate('main2');
self.captionTemplate = self._getLayoutTemplate('caption');
self.previewGenericTemplate = self._getPreviewTemplate('generic');
if (!self.imageCanvas && self.resizeImage && (self.maxImageWidth || self.maxImageHeight)) {
self.imageCanvas = document.createElement('canvas');
self.imageCanvasContext = self.imageCanvas.getContext('2d');
}
if ($h.isEmpty($el.attr('id'))) {
$el.attr('id', $h.uniqId());
}
self.namespace = '.fileinput_' + $el.attr('id').replace(/-/g, '_');
if (self.$container === undefined) {
self.$container = self._createContainer();
} else {
self._refreshContainer();
}
$cont = self.$container;
self.$dropZone = $cont.find('.file-drop-zone');
self.$progress = $cont.find('.kv-upload-progress');
self.$btnUpload = $cont.find('.fileinput-upload');
self.$captionContainer = $h.getElement(options, 'elCaptionContainer', $cont.find('.file-caption'));
self.$caption = $h.getElement(options, 'elCaptionText', $cont.find('.file-caption-name'));
if (!$h.isEmpty(self.msgPlaceholder)) {
f = $el.attr('multiple') ? self.filePlural : self.fileSingle;
self.$caption.attr('placeholder', self.msgPlaceholder.replace('{files}', f));
}
self.$captionIcon = self.$captionContainer.find('.file-caption-icon');
self.$previewContainer = $h.getElement(options, 'elPreviewContainer', $cont.find('.file-preview'));
self.$preview = $h.getElement(options, 'elPreviewImage', $cont.find('.file-preview-thumbnails'));
self.$previewStatus = $h.getElement(options, 'elPreviewStatus', $cont.find('.file-preview-status'));
self.$errorContainer = $h.getElement(options, 'elErrorContainer',
self.$previewContainer.find('.kv-fileinput-error'));
self._validateDisabled();
if (!$h.isEmpty(self.msgErrorClass)) {
$h.addCss(self.$errorContainer, self.msgErrorClass);
}
if (!refreshMode) {
self._resetErrors();
self.$errorContainer.hide();
self.previewInitId = 'thumb-' + $el.attr('id');
self._initPreviewCache();
self._initPreview(true);
self._initPreviewActions();
if (self.$parent.hasClass('file-loading')) {
self.$container.insertBefore(self.$parent);
self.$parent.remove();
}
} else {
if (!self._errorsExist()) {
self.$errorContainer.hide();
}
}
self._setFileDropZoneTitle();
if ($el.attr('disabled')) {
self.disable();
}
self._initZoom();
if (self.hideThumbnailContent) {
$h.addCss(self.$preview, 'hide-content');
}
},
_initFileManager: function () {
var self = this;
self.uploadStartTime = $h.now();
self.fileManager = {
stack: {},
filesProcessed: [],
errors: [],
loadedImages: {},
totalImages: 0,
totalFiles: null,
totalSize: null,
uploadedSize: 0,
stats: {},
bpsLog: [],
bps: 0,
initStats: function (id) {
var data = {started: $h.now()};
if (id) {
self.fileManager.stats[id] = data;
} else {
self.fileManager.stats = data;
}
},
getUploadStats: function (id, loaded, total) {
var fm = self.fileManager,
started = id ? fm.stats[id] && fm.stats[id].started || $h.now() : self.uploadStartTime,
elapsed = ($h.now() - started) / 1000, bps = Math.ceil(elapsed ? loaded / elapsed : 0),
pendingBytes = total - loaded, out, delay = fm.bpsLog.length ? self.bitrateUpdateDelay : 0;
setTimeout(function () {
var i, j = 0, n = 0, len, beg;
fm.bpsLog.push(bps);
fm.bpsLog.sort(function (a, b) {
return a - b;
});
len = fm.bpsLog.length;
beg = len > 10 ? len - 10 : Math.ceil(len / 2);
for (i = len; i > beg; i--) {
n = parseFloat(fm.bpsLog[i]);
j++;
}
fm.bps = (j > 0 ? n / j : 0) * 64;
}, delay);
out = {
fileId: id,
started: started,
elapsed: elapsed,
loaded: loaded,
total: total,
bps: fm.bps,
bitrate: self._getSize(fm.bps, self.bitRateUnits),
pendingBytes: pendingBytes
};
if (id) {
fm.stats[id] = out;
} else {
fm.stats = out;
}
return out;
},
exists: function (id) {
return $.inArray(id, self.fileManager.getIdList()) !== -1;
},
count: function () {
return self.fileManager.getIdList().length;
},
total: function () {
var fm = self.fileManager;
if (!fm.totalFiles) {
fm.totalFiles = fm.count();
}
return fm.totalFiles;
},
getTotalSize: function () {
var fm = self.fileManager;
if (fm.totalSize) {
return fm.totalSize;
}
fm.totalSize = 0;
$.each(self.getFileStack(), function (id, f) {
var size = parseFloat(f.size);
fm.totalSize += isNaN(size) ? 0 : size;
});
return fm.totalSize;
},
add: function (file, id) {
if (!id) {
id = self.fileManager.getId(file);
}
if (!id) {
return;
}
self.fileManager.stack[id] = {
file: file,
name: $h.getFileName(file),
relativePath: $h.getFileRelativePath(file),
size: file.size,
nameFmt: self._getFileName(file, ''),
sizeFmt: self._getSize(file.size)
};
},
remove: function ($thumb) {
var id = self._getThumbFileId($thumb);
self.fileManager.removeFile(id);
},
removeFile: function (id) {
var fm = self.fileManager;
if (!id) {
return;
}
delete fm.stack[id];
delete fm.loadedImages[id];
},
move: function (idFrom, idTo) {
var result = {}, stack = self.fileManager.stack;
if (!idFrom && !idTo || idFrom === idTo) {
return;
}
$.each(stack, function (k, v) {
if (k !== idFrom) {
result[k] = v;
}
if (k === idTo) {
result[idFrom] = stack[idFrom];
}
});
self.fileManager.stack = result;
},
list: function () {
var files = [];
$.each(self.getFileStack(), function (k, v) {