Jelajahi Sumber

Updates to release v4.3.9 fix #890 fix #893 fix #894 fix #895

Kartik Visweswaran 8 tahun lalu
induk
melakukan
1d47c3174e
4 mengubah file dengan 217 tambahan dan 112 penghapusan
  1. 4 1
      CHANGE.md
  2. 161 111
      js/fileinput.js
  3. 0 0
      js/fileinput.min.js
  4. 52 0
      npm-debug.log

+ 4 - 1
CHANGE.md

@@ -3,7 +3,7 @@ Change Log: `bootstrap-fileinput`
 
 
 ## version 4.3.9
 ## version 4.3.9
 
 
-**Date:** 02-Mar-2017 (_under development_)
+**Date:** 06-Mar-2017 (_under development_)
 
 
 1. (enh #863): New plugin method `zoom` with parameter `frameId` to allow custom triggering of zoomed preview for each thumbnail frame.
 1. (enh #863): New plugin method `zoom` with parameter `frameId` to allow custom triggering of zoomed preview for each thumbnail frame.
 2. (enh #881): Update Spanish Translations.
 2. (enh #881): Update Spanish Translations.
@@ -14,6 +14,9 @@ Change Log: `bootstrap-fileinput`
 7. Enhance events like `fileclear` and `filepreajax` to be aborted via `event.preventDefault()`.
 7. Enhance events like `fileclear` and `filepreajax` to be aborted via `event.preventDefault()`.
 8. (enh #887): New properties `msgUploadBegin` and `msgUploadEnd` to display a better progress status. The `layoutTemplates.progress` will support a new token `{status}`.
 8. (enh #887): New properties `msgUploadBegin` and `msgUploadEnd` to display a better progress status. The `layoutTemplates.progress` will support a new token `{status}`.
 9. Enhance uploaded thumb frames to not reset or change the frame identifier after successful upload.
 9. Enhance uploaded thumb frames to not reset or change the frame identifier after successful upload.
+10. (bug #890): Fix doubling of images for async bulk uploads when initial preview is returned via ajax response.
+11. (bug #893): Correct `file-success-remove` event handling.
+12. (enh #894, #895): Correct file size validation for empty files.
 
 
 ## version 4.3.8
 ## version 4.3.8
 
 

+ 161 - 111
js/fileinput.js

@@ -84,6 +84,27 @@
             def = def || '';
             def = def || '';
             return (haystack && typeof haystack === 'object' && needle in haystack) ? haystack[needle] : 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) {
         getNum: function (num, def) {
             def = def || 0;
             def = def || 0;
             if (typeof num === "number") {
             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) {
         _clearObjects: function ($el) {
             $el.find('video audio').each(function () {
             $el.find('video audio').each(function () {
                 this.pause();
                 this.pause();
@@ -1709,16 +1642,12 @@
             }, self.ajaxSettings);
             }, self.ajaxSettings);
             self.ajaxRequests.push($.ajax(settings));
             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) {
         _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)) {
             if (!self.showPreview || typeof out !== 'object' || $.isEmptyObject(out)) {
                 return;
                 return;
             }
             }
@@ -1732,9 +1661,9 @@
                     content = content.split(self.initialPreviewDelimiter);
                     content = content.split(self.initialPreviewDelimiter);
                 }
                 }
                 self.overwriteInitial = false;
                 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 ($thumb !== undefined) {
                     if (!allFiles) {
                     if (!allFiles) {
                         index = self.previewCache.add(content, config[0], tags[0], append);
                         index = self.previewCache.add(content, config[0], tags[0], append);
@@ -1775,7 +1704,7 @@
             if (!self.showPreview) {
             if (!self.showPreview) {
                 return;
                 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');
                 var $thumb = $(this), $preview = self.$preview, $remove = $thumb.find('.kv-file-remove');
                 $remove.removeAttr('disabled');
                 $remove.removeAttr('disabled');
                 self._handler($remove, 'click', function () {
                 self._handler($remove, 'click', function () {
@@ -1839,14 +1768,16 @@
                 }
                 }
             };
             };
             chkComplete = function () {
             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) {
                 if (!self.fileBatchCompleted) {
                     return;
                     return;
                 }
                 }
+                if (data && data.content) {
+                    len = data.content.length;
+                }
                 setTimeout(function () {
                 setTimeout(function () {
                     if (self.showPreview) {
                     if (self.showPreview) {
                         self.previewCache.set(u.content, u.config, u.tags, u.append);
                         self.previewCache.set(u.content, u.config, u.tags, u.append);
-                        len = data && data.content ? data.content.length : 0;
                         if (len) {
                         if (len) {
                             for (i = 0; i < u.content.length; i++) {
                             for (i = 0; i < u.content.length; i++) {
                                 j = i + len;
                                 j = i + len;
@@ -1858,9 +1789,9 @@
                                     data.tags[j] = u.tags[i];
                                     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 {
                         } else {
                             self.initialPreview = u.content;
                             self.initialPreview = u.content;
                             self.initialPreviewConfig = u.config;
                             self.initialPreviewConfig = u.config;
@@ -2125,6 +2056,32 @@
             };
             };
             self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError);
             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 () {
         _initFileActions: function () {
             var self = this, $preview = self.$preview;
             var self = this, $preview = self.$preview;
             if (!self.showPreview) {
             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 () {
         _hideFileIcon: function () {
             if (this.overwriteInitial) {
             if (this.overwriteInitial) {
                 this.$captionContainer.find('.kv-caption-icon').hide();
                 this.$captionContainer.find('.kv-caption-icon').hide();
@@ -2195,9 +2241,13 @@
             if (typeof func === 'function') {
             if (typeof func === 'function') {
                 out = func(size);
                 out = func(size);
             } else {
             } 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);
             return self._getLayoutTemplate('size').replace('{sizeText}', out);
         },
         },
@@ -2240,7 +2290,7 @@
             if (!self.showPreview) {
             if (!self.showPreview) {
                 return;
                 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,
                 caption = self.slug(fname), isError = isDisabled === true && !self.isUploadable,
                 data = $h.objUrl.createObjectURL(file);
                 data = $h.objUrl.createObjectURL(file);
             self._clearDefaultPreview();
             self._clearDefaultPreview();
@@ -2257,7 +2307,7 @@
             }
             }
             var self = this, cat = self._parseFileType(file), fname = file ? file.name : '', caption = self.slug(fname),
             var self = this, cat = self._parseFileType(file), fname = file ? file.name : '', caption = self.slug(fname),
                 types = self.allowedPreviewTypes, mimes = self.allowedPreviewMimeTypes, $preview = self.$preview,
                 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,
                 iData = (cat === 'text' || cat === 'html' || cat === 'image') ? theFile.target.result : data, content,
                 chkMimes = mimes && mimes.indexOf(file.type) !== -1;
                 chkMimes = mimes && mimes.indexOf(file.type) !== -1;
             /** @namespace window.DOMPurify */
             /** @namespace window.DOMPurify */

File diff ditekan karena terlalu besar
+ 0 - 0
js/fileinput.min.js


File diff ditekan karena terlalu besar
+ 52 - 0
npm-debug.log


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini