|
@@ -84,6 +84,27 @@
|
|
|
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) {
|
|
|
+ var i, j = 0, out = [];
|
|
|
+ if (!(arr instanceof Array)) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ for (i = 0; i < arr.length; i++) {
|
|
|
+ if (i !== index) {
|
|
|
+ out[j] = arr[i];
|
|
|
+ j++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return out;
|
|
|
+ },
|
|
|
getNum: function (num, def) {
|
|
|
def = def || 0;
|
|
|
if (typeof num === "number") {
|
|
@@ -1424,94 +1445,6 @@
|
|
|
});
|
|
|
});
|
|
|
},
|
|
|
- _initPreviewActions: function () {
|
|
|
- var self = this, $preview = self.$preview, deleteExtraData = self.deleteExtraData || {},
|
|
|
- btnRemove = $h.FRAMES + ' .kv-file-remove',
|
|
|
- resetProgress = function () {
|
|
|
- var hasFiles = self.isUploadable ? self.previewCache.count() : self.$element.get(0).files.length;
|
|
|
- if ($preview.find(btnRemove).length === 0 && !hasFiles) {
|
|
|
- self.reset();
|
|
|
- self.initialCaption = '';
|
|
|
- }
|
|
|
- };
|
|
|
- self._initZoomButton();
|
|
|
- $preview.find(btnRemove).each(function () {
|
|
|
- var $el = $(this), vUrl = $el.data('url') || self.deleteUrl, vKey = $el.data('key');
|
|
|
- if ($h.isEmpty(vUrl) || vKey === undefined) {
|
|
|
- return;
|
|
|
- }
|
|
|
- var $frame = $el.closest($h.FRAMES), cache = self.previewCache.data,
|
|
|
- settings, params, index = $frame.data('fileindex'), config, extraData;
|
|
|
- index = parseInt(index.replace('init_', ''));
|
|
|
- config = $h.isEmpty(cache.config) && $h.isEmpty(cache.config[index]) ? null : cache.config[index];
|
|
|
- extraData = $h.isEmpty(config) || $h.isEmpty(config.extra) ? deleteExtraData : config.extra;
|
|
|
- if (typeof extraData === "function") {
|
|
|
- extraData = extraData();
|
|
|
- }
|
|
|
- params = {id: $el.attr('id'), key: vKey, extra: extraData};
|
|
|
- settings = $.extend(true, {}, {
|
|
|
- url: vUrl,
|
|
|
- type: 'POST',
|
|
|
- dataType: 'json',
|
|
|
- data: $.extend(true, {}, {key: vKey}, extraData),
|
|
|
- beforeSend: function (jqXHR) {
|
|
|
- self.ajaxAborted = false;
|
|
|
- self._raise('filepredelete', [vKey, jqXHR, extraData]);
|
|
|
- if (self.ajaxAborted) {
|
|
|
- jqXHR.abort();
|
|
|
- } else {
|
|
|
- $h.addCss($frame, 'file-uploading');
|
|
|
- $h.addCss($el, 'disabled');
|
|
|
- }
|
|
|
- },
|
|
|
- success: function (data, textStatus, jqXHR) {
|
|
|
- var n, cap;
|
|
|
- if ($h.isEmpty(data) || $h.isEmpty(data.error)) {
|
|
|
- self.previewCache.init();
|
|
|
- index = parseInt(($frame.data('fileindex')).replace('init_', ''));
|
|
|
- self.previewCache.unset(index);
|
|
|
- n = self.previewCache.count();
|
|
|
- cap = n > 0 ? self._getMsgSelected(n) : '';
|
|
|
- self._raise('filedeleted', [vKey, jqXHR, extraData]);
|
|
|
- self._setCaption(cap);
|
|
|
- } else {
|
|
|
- params.jqXHR = jqXHR;
|
|
|
- params.response = data;
|
|
|
- self._showError(data.error, params, 'filedeleteerror');
|
|
|
- $frame.removeClass('file-uploading');
|
|
|
- $el.removeClass('disabled');
|
|
|
- resetProgress();
|
|
|
- return;
|
|
|
- }
|
|
|
- $frame.removeClass('file-uploading').addClass('file-deleted');
|
|
|
- $frame.fadeOut('slow', function () {
|
|
|
- $h.cleanZoomCache($preview.find('#zoom-' + $frame.attr('id')));
|
|
|
- self._clearObjects($frame);
|
|
|
- $frame.remove();
|
|
|
- resetProgress();
|
|
|
- if (!n && self.getFileStack().length === 0) {
|
|
|
- self._setCaption('');
|
|
|
- self.reset();
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
- error: function (jqXHR, textStatus, errorThrown) {
|
|
|
- var op = self.ajaxOperations.deleteThumb, errMsg = self._parseError(op, jqXHR, errorThrown);
|
|
|
- params.jqXHR = jqXHR;
|
|
|
- params.response = {};
|
|
|
- self._showError(errMsg, params, 'filedeleteerror');
|
|
|
- $frame.removeClass('file-uploading');
|
|
|
- resetProgress();
|
|
|
- }
|
|
|
- }, self.ajaxDeleteSettings);
|
|
|
- self._handler($el, 'click', function () {
|
|
|
- if (!self._validateMinCount()) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- $.ajax(settings);
|
|
|
- });
|
|
|
- });
|
|
|
- },
|
|
|
_clearObjects: function ($el) {
|
|
|
$el.find('video audio').each(function () {
|
|
|
this.pause();
|
|
@@ -1709,16 +1642,12 @@
|
|
|
}, self.ajaxSettings);
|
|
|
self.ajaxRequests.push($.ajax(settings));
|
|
|
},
|
|
|
+ _mergeArray: function (prop, content) {
|
|
|
+ var self = this, arr1 = $h.cleanArray(self[prop]), arr2 = $h.cleanArray(content);
|
|
|
+ self[prop] = arr1.concat(arr2);
|
|
|
+ },
|
|
|
_initUploadSuccess: function (out, $thumb, allFiles) {
|
|
|
- var self = this, append, data, index, $div, $newCache, content, config, tags, i,
|
|
|
- mergeArray = function (prop, content) {
|
|
|
- if (!(self[prop] instanceof Array)) {
|
|
|
- self[prop] = [];
|
|
|
- }
|
|
|
- if (content && content.length) {
|
|
|
- self[prop] = self[prop].concat(content);
|
|
|
- }
|
|
|
- };
|
|
|
+ var self = this, append, data, index, $div, $newCache, content, config, tags, i;
|
|
|
if (!self.showPreview || typeof out !== 'object' || $.isEmptyObject(out)) {
|
|
|
return;
|
|
|
}
|
|
@@ -1732,9 +1661,9 @@
|
|
|
content = content.split(self.initialPreviewDelimiter);
|
|
|
}
|
|
|
self.overwriteInitial = false;
|
|
|
- mergeArray('initialPreview', content);
|
|
|
- mergeArray('initialPreviewConfig', config);
|
|
|
- mergeArray('initialPreviewThumbTags', tags);
|
|
|
+ self._mergeArray('initialPreview', content);
|
|
|
+ self._mergeArray('initialPreviewConfig', config);
|
|
|
+ self._mergeArray('initialPreviewThumbTags', tags);
|
|
|
if ($thumb !== undefined) {
|
|
|
if (!allFiles) {
|
|
|
index = self.previewCache.add(content, config[0], tags[0], append);
|
|
@@ -1775,7 +1704,7 @@
|
|
|
if (!self.showPreview) {
|
|
|
return;
|
|
|
}
|
|
|
- self._getThumbs($h.FRAMES + ' .file-preview-success').each(function () {
|
|
|
+ self._getThumbs($h.FRAMES + '.file-preview-success').each(function () {
|
|
|
var $thumb = $(this), $preview = self.$preview, $remove = $thumb.find('.kv-file-remove');
|
|
|
$remove.removeAttr('disabled');
|
|
|
self._handler($remove, 'click', function () {
|
|
@@ -1839,14 +1768,16 @@
|
|
|
}
|
|
|
};
|
|
|
chkComplete = function () {
|
|
|
- var u = self.uploadCache, $initThumbs, i, j, len, data = self.cacheInitialPreview;
|
|
|
+ var u = self.uploadCache, $initThumbs, i, j, len = 0, data = self.cacheInitialPreview;
|
|
|
if (!self.fileBatchCompleted) {
|
|
|
return;
|
|
|
}
|
|
|
+ if (data && data.content) {
|
|
|
+ len = data.content.length;
|
|
|
+ }
|
|
|
setTimeout(function () {
|
|
|
if (self.showPreview) {
|
|
|
self.previewCache.set(u.content, u.config, u.tags, u.append);
|
|
|
- len = data && data.content ? data.content.length : 0;
|
|
|
if (len) {
|
|
|
for (i = 0; i < u.content.length; i++) {
|
|
|
j = i + len;
|
|
@@ -1858,9 +1789,9 @@
|
|
|
data.tags[j] = u.tags[i];
|
|
|
}
|
|
|
}
|
|
|
- self.initialPreview = data.content;
|
|
|
- self.initialPreviewConfig = data.config;
|
|
|
- self.initialPreviewThumbTags = data.tags;
|
|
|
+ self.initialPreview = $h.cleanArray(data.content);
|
|
|
+ self.initialPreviewConfig = $h.cleanArray(data.config);
|
|
|
+ self.initialPreviewThumbTags = $h.cleanArray(data.tags);
|
|
|
} else {
|
|
|
self.initialPreview = u.content;
|
|
|
self.initialPreviewConfig = u.config;
|
|
@@ -2125,6 +2056,32 @@
|
|
|
};
|
|
|
self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError);
|
|
|
},
|
|
|
+ _deleteFileIndex: function ($frame) {
|
|
|
+ var self = this, ind = $frame.attr('data-fileindex');
|
|
|
+ if (ind.substring(0, 5) === 'init_') {
|
|
|
+ ind = parseInt(ind.replace('init_', ''));
|
|
|
+ self.initialPreview = $h.spliceArray(self.initialPreview, ind);
|
|
|
+ self.initialPreviewConfig = $h.spliceArray(self.initialPreviewConfig, ind);
|
|
|
+ self.initialPreviewThumbTags = $h.spliceArray(self.initialPreviewThumbTags, ind);
|
|
|
+ self.$preview.find($h.FRAMES).each(function () {
|
|
|
+ var $nFrame = $(this), nInd = $nFrame.attr('data-fileindex');
|
|
|
+ if (nInd.substring(0, 5) === 'init_') {
|
|
|
+ nInd = parseInt(nInd.replace('init_', ''));
|
|
|
+ if (nInd > ind) {
|
|
|
+ nInd--;
|
|
|
+ $nFrame.attr('data-fileindex', 'init_' + nInd);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (self.uploadAsync) {
|
|
|
+ self.cacheInitialPreview = {
|
|
|
+ content: self.initialPreview,
|
|
|
+ config: self.initialPreviewConfig,
|
|
|
+ tags: self.initialPreviewThumbTags
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
_initFileActions: function () {
|
|
|
var self = this, $preview = self.$preview;
|
|
|
if (!self.showPreview) {
|
|
@@ -2179,6 +2136,95 @@
|
|
|
});
|
|
|
});
|
|
|
},
|
|
|
+ _initPreviewActions: function () {
|
|
|
+ var self = this, $preview = self.$preview, deleteExtraData = self.deleteExtraData || {},
|
|
|
+ btnRemove = $h.FRAMES + ' .kv-file-remove',
|
|
|
+ resetProgress = function () {
|
|
|
+ var hasFiles = self.isUploadable ? self.previewCache.count() : self.$element.get(0).files.length;
|
|
|
+ if ($preview.find(btnRemove).length === 0 && !hasFiles) {
|
|
|
+ self.reset();
|
|
|
+ self.initialCaption = '';
|
|
|
+ }
|
|
|
+ };
|
|
|
+ self._initZoomButton();
|
|
|
+ $preview.find(btnRemove).each(function () {
|
|
|
+ var $el = $(this), vUrl = $el.data('url') || self.deleteUrl, vKey = $el.data('key');
|
|
|
+ if ($h.isEmpty(vUrl) || vKey === undefined) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var $frame = $el.closest($h.FRAMES), cache = self.previewCache.data,
|
|
|
+ settings, params, index = $frame.data('fileindex'), config, extraData;
|
|
|
+ index = parseInt(index.replace('init_', ''));
|
|
|
+ config = $h.isEmpty(cache.config) && $h.isEmpty(cache.config[index]) ? null : cache.config[index];
|
|
|
+ extraData = $h.isEmpty(config) || $h.isEmpty(config.extra) ? deleteExtraData : config.extra;
|
|
|
+ if (typeof extraData === "function") {
|
|
|
+ extraData = extraData();
|
|
|
+ }
|
|
|
+ params = {id: $el.attr('id'), key: vKey, extra: extraData};
|
|
|
+ settings = $.extend(true, {}, {
|
|
|
+ url: vUrl,
|
|
|
+ type: 'POST',
|
|
|
+ dataType: 'json',
|
|
|
+ data: $.extend(true, {}, {key: vKey}, extraData),
|
|
|
+ beforeSend: function (jqXHR) {
|
|
|
+ self.ajaxAborted = false;
|
|
|
+ self._raise('filepredelete', [vKey, jqXHR, extraData]);
|
|
|
+ if (self.ajaxAborted) {
|
|
|
+ jqXHR.abort();
|
|
|
+ } else {
|
|
|
+ $h.addCss($frame, 'file-uploading');
|
|
|
+ $h.addCss($el, 'disabled');
|
|
|
+ }
|
|
|
+ },
|
|
|
+ success: function (data, textStatus, jqXHR) {
|
|
|
+ var n, cap;
|
|
|
+ if ($h.isEmpty(data) || $h.isEmpty(data.error)) {
|
|
|
+ self.previewCache.init();
|
|
|
+ index = parseInt(($frame.data('fileindex')).replace('init_', ''));
|
|
|
+ self.previewCache.unset(index);
|
|
|
+ n = self.previewCache.count();
|
|
|
+ cap = n > 0 ? self._getMsgSelected(n) : '';
|
|
|
+ self._deleteFileIndex($frame);
|
|
|
+ self._setCaption(cap);
|
|
|
+ self._raise('filedeleted', [vKey, jqXHR, extraData]);
|
|
|
+ } else {
|
|
|
+ params.jqXHR = jqXHR;
|
|
|
+ params.response = data;
|
|
|
+ self._showError(data.error, params, 'filedeleteerror');
|
|
|
+ $frame.removeClass('file-uploading');
|
|
|
+ $el.removeClass('disabled');
|
|
|
+ resetProgress();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ $frame.removeClass('file-uploading').addClass('file-deleted');
|
|
|
+ $frame.fadeOut('slow', function () {
|
|
|
+ $h.cleanZoomCache($preview.find('#zoom-' + $frame.attr('id')));
|
|
|
+ self._clearObjects($frame);
|
|
|
+ $frame.remove();
|
|
|
+ resetProgress();
|
|
|
+ if (!n && self.getFileStack().length === 0) {
|
|
|
+ self._setCaption('');
|
|
|
+ self.reset();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ error: function (jqXHR, textStatus, errorThrown) {
|
|
|
+ var op = self.ajaxOperations.deleteThumb, errMsg = self._parseError(op, jqXHR, errorThrown);
|
|
|
+ params.jqXHR = jqXHR;
|
|
|
+ params.response = {};
|
|
|
+ self._showError(errMsg, params, 'filedeleteerror');
|
|
|
+ $frame.removeClass('file-uploading');
|
|
|
+ resetProgress();
|
|
|
+ }
|
|
|
+ }, self.ajaxDeleteSettings);
|
|
|
+ self._handler($el, 'click', function () {
|
|
|
+ if (!self._validateMinCount()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ $.ajax(settings);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
_hideFileIcon: function () {
|
|
|
if (this.overwriteInitial) {
|
|
|
this.$captionContainer.find('.kv-caption-icon').hide();
|
|
@@ -2195,9 +2241,13 @@
|
|
|
if (typeof func === 'function') {
|
|
|
out = func(size);
|
|
|
} else {
|
|
|
- i = Math.floor(Math.log(size) / Math.log(1024));
|
|
|
- sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
|
- out = (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + sizes[i];
|
|
|
+ if (size === 0) {
|
|
|
+ out = '0.00 B';
|
|
|
+ } else {
|
|
|
+ i = Math.floor(Math.log(size) / Math.log(1024));
|
|
|
+ sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
|
+ out = (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + sizes[i];
|
|
|
+ }
|
|
|
}
|
|
|
return self._getLayoutTemplate('size').replace('{sizeText}', out);
|
|
|
},
|
|
@@ -2240,7 +2290,7 @@
|
|
|
if (!self.showPreview) {
|
|
|
return;
|
|
|
}
|
|
|
- var fname = file ? file.name : '', ftype = file ? file.type : '', content, size = file.size,
|
|
|
+ var fname = file ? file.name : '', ftype = file ? file.type : '', content, size = file.size || 0,
|
|
|
caption = self.slug(fname), isError = isDisabled === true && !self.isUploadable,
|
|
|
data = $h.objUrl.createObjectURL(file);
|
|
|
self._clearDefaultPreview();
|
|
@@ -2257,7 +2307,7 @@
|
|
|
}
|
|
|
var self = this, cat = self._parseFileType(file), fname = file ? file.name : '', caption = self.slug(fname),
|
|
|
types = self.allowedPreviewTypes, mimes = self.allowedPreviewMimeTypes, $preview = self.$preview,
|
|
|
- chkTypes = types && types.indexOf(cat) >= 0, size = file.size,
|
|
|
+ chkTypes = types && types.indexOf(cat) >= 0, size = file.size || 0,
|
|
|
iData = (cat === 'text' || cat === 'html' || cat === 'image') ? theFile.target.result : data, content,
|
|
|
chkMimes = mimes && mimes.indexOf(file.type) !== -1;
|
|
|
/** @namespace window.DOMPurify */
|