Sfoglia il codice sorgente

Fix #328: Implement image dimension validations

Kartik Visweswaran 10 anni fa
parent
commit
e9583b11ee

+ 10 - 0
CHANGE.md

@@ -21,6 +21,16 @@ version 4.2.1
 13. (bug #310): Set missing caption icon on error.
 14. (bug #315): Fix parsing of preview settings for default (other) preview.
 15. (bug #327): More correct clearing of preview.
+16. (bug #328): Implement image dimension validations.
+    - New properties added to the plugin:
+        - `minImageWidth`
+        - `minImageHeight`
+        - `maxImageWidth`
+        - `maxImageHeight`
+        - `msgImageWidthSmall`
+        - `msgImageHeightSmall`
+        - `msgImageWidthLarge`
+        - `msgImageHeightLarge`
 
 version 4.2.0
 =============

+ 56 - 0
README.md

@@ -778,6 +778,18 @@ function() {
 }
 ```
 
+### maxImageWidth
+_int_ the maximum allowed image width in `px` if you are uploading image files. Defaults to `null` which means no limit on image width.
+
+### maxImageHeight
+_int_ the maximum allowed image height in `px` if you are uploading image files. Defaults to `null` which means no limit on image height.
+
+### minImageWidth
+_int_ the minimum allowed image width in `px` if you are uploading image files. Defaults to `null` which means no limit on image width.
+
+### minImageHeight
+_int_ the minimum allowed image height in `px` if you are uploading image files. Defaults to `null` which means no limit on image height.
+
 ### maxFileSize
 _float_ the maximum file size for upload in KB.  If set to `0`, it means size allowed is unlimited. Defaults to `0`.
 
@@ -940,6 +952,50 @@ _string_ the message displayed when a folder has been dragged to the drop zone.
 
 - `{n}`: the number of folders dropped.
 
+### msgImageWidthSmall
+_string_ the exception message to be displayed when the file selected for preview is an image and its width is less than the `minImageWidth` setting. Defaults to:
+
+```
+Width of image file "{name}" must be at least {size} px.
+```
+where:
+
+- `{name}`: will be replaced by the file name being uploaded
+- `{size}`: will be replaced by the `minImageWidth` setting.
+
+### msgImageHeightSmall
+_string_ the exception message to be displayed when the file selected for preview is an image and its height is less than the `minImageHeight` setting. Defaults to:
+
+```
+Width of image file "{name}" must be at least {size} px.
+```
+where:
+
+- `{name}`: will be replaced by the file name being uploaded
+- `{size}`: will be replaced by the `minImageHeight` setting.
+
+### msgImageWidthLarge
+_string_ the exception message to be displayed when the file selected for preview is an image and its width exceeds the `maxImageWidth` setting. Defaults to:
+
+```
+Width of image file "{name}" cannot exceed {size} px.
+```
+where:
+
+- `{name}`: will be replaced by the file name being uploaded
+- `{size}`: will be replaced by the `maxImageWidth` setting.
+
+### msgImageHeightLarge
+_string_ the exception message to be displayed when the file selected for preview is an image and its height exceeds the `maxImageHeight` setting. Defaults to:
+
+```
+Height of image file "{name}" cannot exceed {size} px.
+```
+where:
+
+- `{name}`: will be replaced by the file name being uploaded
+- `{size}`: will be replaced by the `maxImageHeight` setting.
+
 ### progressClass
 _string_ the upload progress bar CSS class to be applied when AJAX upload is in process (applicable only for ajax uploads). Defaults to `progress-bar progress-bar-success progress-bar-striped active`. 
 

+ 48 - 15
js/fileinput.js

@@ -860,7 +860,7 @@
                         self.filestack[ind] = undefined;
                         self.clearObjects($frame);
                         $frame.remove();
-                        var filestack = self.getFileStack(), len = filestack.length,
+                        var filestack = self.getFileStack(true), len = filestack.length,
                             chk = previewCache.count(self.id);
                         self.clearFileInput();
                         if (len === 0 && chk === 0) {
@@ -949,6 +949,9 @@
             var self = this, $thumbs = !self.showUploadedThumbs ? self.$preview.find('.file-preview-frame') :
                 self.$preview.find('.file-preview-frame:not(.file-preview-success)');
             $thumbs.remove();
+            if (!self.$preview.find('.file-preview-frame').length) {
+                self.resetErrors();
+            }
         },
         initPreview: function (isInit) {
             var self = this, cap = self.initialCaption || '', out;
@@ -1677,7 +1680,7 @@
                 .repl('{data}', data)
                 .repl('{footer}', footer));
         },
-        previewFile: function (file, theFile, previewId, data) {
+        previewFile: function (i, file, theFile, previewId, data) {
             if (!this.showPreview) {
                 return;
             }
@@ -1718,7 +1721,7 @@
                         .repl('{footer}', footer).repl('{fileindex}', ind);
                 }
                 self.$preview.append("\n" + content);
-                self.autoSizeImage(previewId);
+                self.validateImage(i, previewId);
             } else {
                 self.previewDefault(file, previewId);
             }
@@ -1726,10 +1729,10 @@
         slugDefault: function (text) {
             return isEmpty(text) ? '' : text.split(/(\\|\/)/g).pop().replace(/[^\w\u00C0-\u017F\-.\\\/ ]+/g, '');
         },
-        getFileStack: function () {
-            var self = this;
+        getFileStack: function (skipNull) {
+            var self = this, status;
             return self.filestack.filter(function (n) {
-                return n !== undefined;
+                return (skipNull ? n !== undefined : n !== undefined && n !== null);
             });
         },
         readFiles: function (files) {
@@ -1811,7 +1814,7 @@
                         self.errorHandler(evt, caption);
                     };
                     reader.onload = function (theFile) {
-                        self.previewFile(file, theFile, previewId, previewData);
+                        self.previewFile(i, file, theFile, previewId, previewData);
                         self.initFileActions();
                     };
                     reader.onloadend = function () {
@@ -1963,10 +1966,10 @@
             }
             self.showFolderError(folders);
         },
-        autoSizeImage: function (previewId) {
-            var self = this, $preview = self.$preview,
-                $thumb = $preview.find("#" + previewId),
-                $img = $thumb.find('img'), w1, w2, $cap;
+        validateImage: function (i, previewId) {
+            var self = this, $preview = self.$preview, params, w1, w2, $cap,
+                $thumb = $preview.find("#" + previewId), fname = 'Untitled',
+                $img = $thumb.find('img');
             if (!$img.length) {
                 return;
             }
@@ -1980,13 +1983,35 @@
                 $cap = $img.closest('.file-preview-frame').find('.file-caption-name');
                 if ($cap.length) {
                     $cap.width($img.width());
-                    $cap.attr('title', $cap.text());
-                }
-                self.raise('fileimageloaded', previewId);
+                    fname = $cap.text();
+                    $cap.attr('title', fname);
+                }
+                params = {ind: i, id: previewId};
+                self.checkDimensions(i, 'Small', $img, $thumb, fname, 'Width', params);
+                self.checkDimensions(i, 'Small', $img, $thumb, fname, 'Height', params);
+                self.checkDimensions(i, 'Large', $img, $thumb, fname, 'Width', params);
+                self.checkDimensions(i, 'Large', $img, $thumb, fname, 'Height', params);
+                self.raise('fileimageloaded', [previewId]);
                 objUrl.revokeObjectURL($img.attr('src'));
-
             });
         },
+        checkDimensions: function (i, chk, $img, $thumb, fname, type, params) {
+            var self = this, dim, msg, tag = chk === 'Small' ? 'min' : 'max',
+                limit = self[tag + 'Image' + type], test, $imgEl = $img[0];
+            if (isEmpty(limit)) {
+                return;
+            }
+            msg = self['msgImage' + type + chk];
+            dim = (type === 'Width') ? $imgEl.naturalWidth || $imgEl.width : $imgEl.naturalHeight || $imgEl.height;
+            test = chk === 'Small' ? dim >= limit : dim <= limit;
+            if (!$img.length || test) {
+                return;
+            }
+            msg = msg.replace('{name}', fname).replace('{size}', limit);
+            self.showUploadError(msg, params);
+            self.setThumbStatus($thumb, 'Error');
+            self.filestack[i] = null;
+        },
         initCaption: function () {
             var self = this, cap = self.initialCaption || '';
             if (self.overwriteInitial || isEmpty(cap)) {
@@ -2161,6 +2186,10 @@
         uploadUrl: null,
         uploadAsync: true,
         uploadExtraData: {},
+        minImageWidth: null,
+        minImageHeight: null,
+        maxImageWidth: null,
+        maxImageHeight: null,
         maxFileSize: 0,
         minFileCount: 0,
         maxFileCount: 0,
@@ -2214,6 +2243,10 @@
         msgProgress: 'Loading file {index} of {files} - {name} - {percent}% completed.',
         msgSelected: '{n} {files} selected',
         msgFoldersNotAllowed: 'Drag & drop files only! {n} folder(s) dropped were skipped.',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Drag & drop files here &hellip;'
     };
 

File diff suppressed because it is too large
+ 0 - 0
js/fileinput.min.js


+ 4 - 0
js/fileinput_locale_LANG.js

@@ -36,6 +36,10 @@
         msgProgress: 'Loading file {index} of {files} - {name} - {percent}% completed.',
         msgSelected: '{n} {files} selected',
         msgFoldersNotAllowed: 'Drag & drop files only! Skipped {n} dropped folder(s).',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Drag & drop files here &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_cz.js

@@ -36,6 +36,10 @@
         msgProgress: 'Nahrávání souboru {index} z {files} - {name} - {percent}% dokončeno.',
         msgSelected: '{n} {files} vybrano',
         msgFoldersNotAllowed: 'Táhni a pusť pouze soubory! Vynechané {n} pustěné složk(y).',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Táhni a pusť soubory sem &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_de.js

@@ -34,6 +34,10 @@
         msgProgress: 'Datei {index} von {files} - {name} - zu {percent}% fertiggestellt.',
         msgSelected: '{n} {files} ausgewählt',
         msgFoldersNotAllowed: 'Drag & Drop funktioniert nur bei Dateien! {n} Ordner übersprungen.',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Dateien hierher ziehen &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_el.js

@@ -36,6 +36,10 @@
         msgProgress: 'Φόρτωση αρχείου {index} απο {files} - {name} - {percent}% ολοκληρώθηκε.',
         msgSelected: '{n} {files} επιλέχθηκαν',
         msgFoldersNotAllowed: 'Μπορείτε να σύρετε μόνο αρχεία! Παραβλέφθηκαν {n} φάκελος(οι).',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Σύρετε τα αρχεία εδώ &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_es.js

@@ -36,6 +36,10 @@
         msgProgress: 'Cargando archivo {index} of {files} - {name} - {percent}% completado.',
         msgSelected: '{n} {files} seleccionados',
         msgFoldersNotAllowed: 'Arrastre y suelte únicamente archivos! Se omite {n} carpeta(s).',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Arrastre y suelte los archivos aquí &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_fr.js

@@ -36,6 +36,10 @@
         msgProgress: 'Transmission du fichier {index} sur {files} - {name} - {percent}% faits.',
         msgSelected: '{n} {files} sélectionné(s)',
         msgFoldersNotAllowed: 'Glissez et déposez uniquement des fichiers ! {n} répertoire(s) exclu(s).',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Glissez et déposez les fichiers ici&hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_hu.js

@@ -36,6 +36,10 @@
         msgProgress: 'Feltöltés: {index} / {files} - {name} - {percent}% kész.',
         msgSelected: '{n} {files} kiválasztva.',
         msgFoldersNotAllowed: 'Csak fájlokat húzzon ide! Kihagyva {n} könyvtár.',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Fájlok húzása ide &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_it.js

@@ -38,6 +38,10 @@
         msgProgress: 'Caricamento file {index} di {files} - {name} - {percent}% completato.',
         msgSelected: '{n} {files} selezionati',
         msgFoldersNotAllowed: 'Trascina solo file! Ignorata/e {n} cartella/e.',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Trascina i file qui&hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_nl.js

@@ -36,6 +36,10 @@
         msgProgress: 'Bestanden laden {index} van de {files} - {name} - {percent}% compleet.',
         msgSelected: '{n} {files} geselecteerd',
         msgFoldersNotAllowed: 'Drag & drop bestanden alleen! overgeslagen {n} mappen(s).',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Drag & drop bestanden hier &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_pl.js

@@ -36,6 +36,10 @@
         msgProgress: 'Wczytywanie pliku {index} z {files} - {name} - {percent}% zakończone.',
         msgSelected: '{n} {files} zaznaczonych',
         msgFoldersNotAllowed: 'Metodą przeciągnij i upuść, można przenosić tylko pliki. Pominięto {n} katalogów.',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Przeciągnij i upuść pliki tu &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_pt-BR.js

@@ -36,6 +36,10 @@
         msgProgress: 'Enviando arquivo {index} de {files} - {name} - {percent}% completo.',
         msgSelected: '{n} {files} selecionado(s)',
         msgFoldersNotAllowed: 'Arraste e solte apenas arquivos! {n} soltar pasta(s) ignoradas.',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Arraste e solte os arquivos aqui&hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_pt.js

@@ -36,6 +36,10 @@
         msgProgress: 'A carregar ficheiro {index} de {files} - {name} - {percent}% completo.',
         msgSelected: '{n} {files} seleccionados',
         msgFoldersNotAllowed: 'Arrastar e largar ficheiros apenas! {n} pasta(s) ignoradas.',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Arrastar e largar ficheiros aqui &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_ro.js

@@ -37,6 +37,10 @@
         msgProgress: 'Se încarcă fișierul {index} din {files} - {name} - {percent}% încărcat.',
         msgSelected: '{n} {files} încărcate',
         msgFoldersNotAllowed: 'Se poate doar trăgând fișierele! Se renunță la {n} dosar(e).',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Trage fișierele aici &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_ru.js

@@ -37,6 +37,10 @@
         msgProgress: 'Загрузка файла {index} из {files} - {name} - {percent}% завершено.',
         msgSelected: '{n} {files} выбрано',
         msgFoldersNotAllowed: 'Разрешено только перетаскивание файлов! Пропущено {n} папок.',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Перетащите файлы сюда &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_sk.js

@@ -36,6 +36,10 @@
         msgProgress: 'Nahrávanie súboru {index} z {files} - {name} - {percent}% dokončené.',
         msgSelected: '{n} {files} vybraté',
         msgFoldersNotAllowed: 'Tiahni a pusť iba súbory! Vynechané {n} pustené prečinok(y).',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Tiahni a pusť súbory tu &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_sr.js

@@ -37,6 +37,10 @@
         msgProgress: 'Učitavanje datoteke {index} od {files} - {name} - {percent}% završeno.',
         msgSelected: '{n} {files} je označeno',
         msgFoldersNotAllowed: 'Moguće je prevlačiti samo datoteke! Preskočeno je {n} fascikla.',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Prevucite datoteke ovde &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_th.js

@@ -36,6 +36,10 @@
         msgProgress: 'กำลังโหลดไฟล์ {index} จาก {files} - {name} - {percent}%',
         msgSelected: '{n} {files} ถูกเลือก',
         msgFoldersNotAllowed: 'Drag & drop เฉพาะไฟล์เท่านั้น! ข้าม dropped folder จำนวน {n}',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Drag & drop ไฟล์ตรงนี้ &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_tr.js

@@ -36,6 +36,10 @@
         msgProgress: 'Dosya yükleniyor {index} / {files} - {name} - %{percent} tamamlandı.',
         msgSelected: '{n} {files} seçildi',
         msgFoldersNotAllowed: 'Yalnızca dosyaları sürükleyip bırakabilirsiniz! {n} dizin(ler) göz ardı edildi.',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Dosyaları buraya sürükleyip bırakın &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_uk.js

@@ -37,6 +37,10 @@
         msgProgress: 'Загрузка файла {index} із {files} - {name} - {percent}% завершено.',
         msgSelected: '{n} {files} вибрано',
         msgFoldersNotAllowed: 'Дозволено перетягувати тільки файли! Пропущено {n} папок.',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: 'Перетяніть файли сюди &hellip;'
     };
 })(window.jQuery);

+ 4 - 0
js/fileinput_locale_zh.js

@@ -37,6 +37,10 @@
         msgProgress: '加载第 {index} 文件 共 {files} - {name} - {percent}% 完成.',
         msgSelected: '{n} {files} 选中',
         msgFoldersNotAllowed: '只支持拖拽文件! 跳过 {n} 拖拽的文件夹.',
+        msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.',
+        msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.',
+        msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.',
+        msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.',
         dropZoneTitle: '拖拽文件到这里 &hellip;',
         slugCallback: function(text) {
             return text ? text.split(/(\\|\/)/g).pop().replace(/[^\w\u4e00-\u9fa5\-.\\\/ ]+/g, '') : '';

Some files were not shown because too many files changed in this diff