@oat-sa/tao-core-ui 1.58.1 → 1.58.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/dist/actionbar.js +386 -395
  2. package/dist/adder.js +21 -19
  3. package/dist/animable/absorbable/absorbable.js +204 -213
  4. package/dist/animable/absorbable/css/absorb.css +1 -0
  5. package/dist/animable/absorbable/css/absorb.css.map +1 -1
  6. package/dist/animable/pulsable/pulsable.js +168 -177
  7. package/dist/autocomplete/css/autocomplete.css +1 -0
  8. package/dist/autocomplete/css/autocomplete.css.map +1 -1
  9. package/dist/autocomplete.js +68 -66
  10. package/dist/badge/badge.js +188 -197
  11. package/dist/badge/css/badge.css +1 -0
  12. package/dist/badge/css/badge.css.map +1 -1
  13. package/dist/breadcrumbs.js +275 -284
  14. package/dist/btngrouper.js +5 -5
  15. package/dist/bulkActionPopup.js +490 -495
  16. package/dist/button.js +283 -291
  17. package/dist/cascadingComboBox.js +249 -258
  18. package/dist/ckeditor/ckConfigurator.js +26 -19
  19. package/dist/ckeditor/dtdHandler.js +11 -9
  20. package/dist/class/selector.js +441 -450
  21. package/dist/component/resizable.js +1 -1
  22. package/dist/component/windowed.js +285 -294
  23. package/dist/component.js +419 -428
  24. package/dist/contextualPopup.js +417 -426
  25. package/dist/dashboard.js +300 -309
  26. package/dist/datalist.js +753 -762
  27. package/dist/datatable/filterStrategy/multiple.js +1 -1
  28. package/dist/datatable/filterStrategy/single.js +1 -1
  29. package/dist/datatable.js +1527 -1550
  30. package/dist/dateRange/dateRange.js +393 -402
  31. package/dist/datetime/picker.js +665 -672
  32. package/dist/deleter.js +368 -377
  33. package/dist/destination/selector.js +286 -295
  34. package/dist/dialog/alert.js +3 -3
  35. package/dist/dialog/confirm.js +1 -1
  36. package/dist/dialog/confirmDelete.js +216 -225
  37. package/dist/dialog.js +650 -654
  38. package/dist/disabler.js +8 -8
  39. package/dist/documentViewer/providers/pdfViewer/fallback/viewer.js +166 -175
  40. package/dist/documentViewer/providers/pdfViewer/pdfjs/findBar.js +518 -527
  41. package/dist/documentViewer/providers/pdfViewer/pdfjs/pageView.js +380 -389
  42. package/dist/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +539 -548
  43. package/dist/documentViewer/providers/pdfViewer/pdfjs/viewer.js +369 -378
  44. package/dist/documentViewer/providers/pdfViewer.js +184 -193
  45. package/dist/documentViewer.js +292 -301
  46. package/dist/dropdown.js +383 -392
  47. package/dist/durationer.js +5 -5
  48. package/dist/dynamicComponent.js +597 -598
  49. package/dist/feedback.js +356 -362
  50. package/dist/figure/FigureStateActive.js +117 -108
  51. package/dist/filesender.js +2 -2
  52. package/dist/filter.js +230 -239
  53. package/dist/form/dropdownForm.js +355 -357
  54. package/dist/form/form.js +919 -690
  55. package/dist/form/simpleForm.js +1 -1
  56. package/dist/form/validator/renderer.js +233 -235
  57. package/dist/form/validator/validator.js +257 -189
  58. package/dist/form/widget/definitions.js +1 -1
  59. package/dist/form/widget/providers/checkBox.js +254 -259
  60. package/dist/form/widget/providers/comboBox.js +187 -192
  61. package/dist/form/widget/providers/default.js +8 -9
  62. package/dist/form/widget/providers/hidden.js +170 -179
  63. package/dist/form/widget/providers/hiddenBox.js +262 -267
  64. package/dist/form/widget/providers/radioBox.js +216 -225
  65. package/dist/form/widget/providers/textArea.js +187 -196
  66. package/dist/form/widget/providers/textBox.js +2 -3
  67. package/dist/form/widget/widget.js +473 -475
  68. package/dist/formValidator/formValidator.js +1 -1
  69. package/dist/formValidator/highlighters/message.js +1 -1
  70. package/dist/generis/form/form.js +314 -323
  71. package/dist/generis/validator/validator.js +209 -218
  72. package/dist/generis/widget/checkBox/checkBox.js +218 -227
  73. package/dist/generis/widget/comboBox/comboBox.js +179 -188
  74. package/dist/generis/widget/hiddenBox/hiddenBox.js +220 -229
  75. package/dist/generis/widget/textBox/textBox.js +169 -178
  76. package/dist/generis/widget/widget.js +246 -255
  77. package/dist/groupedComboBox.js +222 -231
  78. package/dist/groupvalidator.js +2 -2
  79. package/dist/highlighter.js +967 -958
  80. package/dist/image/ImgStateActive/helper.js +7 -5
  81. package/dist/image/ImgStateActive/initHelper.js +49 -43
  82. package/dist/image/ImgStateActive/initMediaEditor.js +24 -20
  83. package/dist/image/ImgStateActive/mediaSizer.js +14 -12
  84. package/dist/image/ImgStateActive.js +72 -70
  85. package/dist/incrementer.js +6 -6
  86. package/dist/inplacer.js +6 -6
  87. package/dist/itemButtonList/css/item-button-list.css +1 -0
  88. package/dist/itemButtonList/css/item-button-list.css.map +1 -1
  89. package/dist/itemButtonList.js +439 -435
  90. package/dist/keyNavigation/navigableDomElement.js +51 -38
  91. package/dist/keyNavigation/navigator.js +85 -70
  92. package/dist/listbox.js +460 -469
  93. package/dist/liststyler.js +8 -8
  94. package/dist/loadingButton/loadingButton.js +209 -218
  95. package/dist/lock.js +476 -485
  96. package/dist/login/login.js +475 -484
  97. package/dist/maths/calculator/basicCalculator.js +235 -244
  98. package/dist/maths/calculator/calculatorComponent.js +3 -3
  99. package/dist/maths/calculator/core/board.js +772 -781
  100. package/dist/maths/calculator/core/expression.js +476 -485
  101. package/dist/maths/calculator/core/labels.js +228 -237
  102. package/dist/maths/calculator/core/tokenizer.js +1 -1
  103. package/dist/maths/calculator/core/tokens.js +163 -170
  104. package/dist/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +244 -253
  105. package/dist/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +279 -288
  106. package/dist/maths/calculator/scientificCalculator.js +327 -336
  107. package/dist/mediaEditor/mediaEditorComponent.js +238 -245
  108. package/dist/mediaEditor/plugins/mediaAlignment/helper.js +7 -7
  109. package/dist/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +229 -235
  110. package/dist/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +580 -589
  111. package/dist/mediaplayer/players/html5.js +666 -675
  112. package/dist/mediaplayer/players/youtube.js +419 -424
  113. package/dist/mediaplayer/support.js +11 -10
  114. package/dist/mediaplayer/utils/reminder.js +14 -13
  115. package/dist/mediaplayer/utils/timeObserver.js +10 -11
  116. package/dist/mediaplayer/youtubeManager.js +164 -145
  117. package/dist/mediaplayer.js +1565 -1520
  118. package/dist/mediasizer.js +669 -678
  119. package/dist/modal.js +10 -17
  120. package/dist/pageSizeSelector.js +219 -228
  121. package/dist/pagination/providers/pages.js +280 -289
  122. package/dist/pagination/providers/simple.js +192 -201
  123. package/dist/previewer.js +30 -30
  124. package/dist/progressbar.js +4 -4
  125. package/dist/report.js +347 -356
  126. package/dist/resource/filters.js +271 -280
  127. package/dist/resource/list.js +1264 -1273
  128. package/dist/resource/selector.js +865 -874
  129. package/dist/resource/tree.js +1483 -1492
  130. package/dist/resourcemgr/fileBrowser.js +564 -569
  131. package/dist/resourcemgr/filePreview.js +16 -16
  132. package/dist/resourcemgr/fileSelector.js +515 -524
  133. package/dist/resourcemgr/util/updatePermissions.js +2 -2
  134. package/dist/resourcemgr.js +306 -315
  135. package/dist/searchModal/advancedSearch.js +796 -767
  136. package/dist/searchModal.js +114 -91
  137. package/dist/switch/switch.js +298 -307
  138. package/dist/tabs.js +598 -575
  139. package/dist/taskQueue/status.js +312 -321
  140. package/dist/taskQueue/table.js +375 -384
  141. package/dist/taskQueue/taskQueueModel.js +488 -472
  142. package/dist/taskQueueButton/taskable.js +264 -273
  143. package/dist/taskQueueButton/treeButton.js +189 -198
  144. package/dist/themeLoader.js +24 -23
  145. package/dist/themes.js +1 -1
  146. package/dist/toggler.js +3 -3
  147. package/dist/tooltip.js +295 -304
  148. package/dist/transformer.js +2 -2
  149. package/dist/tristateCheckboxGroup.js +311 -320
  150. package/dist/uploader.js +687 -696
  151. package/dist/validator/Report.js +1 -1
  152. package/dist/validator/Validator.js +3 -3
  153. package/dist/validator/validators.js +9 -9
  154. package/dist/validator.js +240 -230
  155. package/dist/waitForMedia.js +1 -1
  156. package/package.json +3 -3
  157. package/src/animable/absorbable/css/absorb.css +1 -0
  158. package/src/animable/absorbable/css/absorb.css.map +1 -1
  159. package/src/autocomplete/css/autocomplete.css +1 -0
  160. package/src/autocomplete/css/autocomplete.css.map +1 -1
  161. package/src/badge/css/badge.css +1 -0
  162. package/src/badge/css/badge.css.map +1 -1
  163. package/src/ckeditor/ckConfigurator.js +4 -0
  164. package/src/itemButtonList/css/item-button-list.css +1 -0
  165. package/src/itemButtonList/css/item-button-list.css.map +1 -1
  166. package/src/.DS_Store +0 -0
  167. package/src/css/basic.css +0 -7826
  168. package/src/css/basic.css.map +0 -1
  169. package/src/css/ckeditor/skins/tao/css/dialog.css +0 -950
  170. package/src/css/ckeditor/skins/tao/css/dialog.css.map +0 -1
  171. package/src/css/ckeditor/skins/tao/css/editor.css +0 -1850
  172. package/src/css/ckeditor/skins/tao/css/editor.css.map +0 -1
  173. package/src/scss/.DS_Store +0 -0
  174. package/src/scss/basic.scss +0 -16
  175. package/src/scss/ckeditor/skins/tao/scss/dialog.scss +0 -763
  176. package/src/scss/ckeditor/skins/tao/scss/editor.scss +0 -111
  177. package/src/scss/ckeditor/skins/tao/scss/inc/_ck-icons.scss +0 -59
  178. package/src/scss/ckeditor/skins/tao/scss/inc/_colorpanel.scss +0 -118
  179. package/src/scss/ckeditor/skins/tao/scss/inc/_elementspath.scss +0 -69
  180. package/src/scss/ckeditor/skins/tao/scss/inc/_mainui.scss +0 -194
  181. package/src/scss/ckeditor/skins/tao/scss/inc/_menu.scss +0 -181
  182. package/src/scss/ckeditor/skins/tao/scss/inc/_panel.scss +0 -200
  183. package/src/scss/ckeditor/skins/tao/scss/inc/_presets.scss +0 -32
  184. package/src/scss/ckeditor/skins/tao/scss/inc/_reset.scss +0 -101
  185. package/src/scss/ckeditor/skins/tao/scss/inc/_richcombo.scss +0 -213
  186. package/src/scss/ckeditor/skins/tao/scss/inc/_tao.scss +0 -59
  187. package/src/scss/ckeditor/skins/tao/scss/inc/_toolbar.scss +0 -301
  188. package/src/scss/font/source-sans-pro/source-sans-pro-italic.eot +0 -0
  189. package/src/scss/font/source-sans-pro/source-sans-pro-italic.eot.b64 +0 -1
  190. package/src/scss/font/source-sans-pro/source-sans-pro-italic.woff +0 -0
  191. package/src/scss/font/source-sans-pro/source-sans-pro-italic.woff.b64 +0 -1
  192. package/src/scss/font/source-sans-pro/source-sans-pro-regular.eot +0 -0
  193. package/src/scss/font/source-sans-pro/source-sans-pro-regular.eot.b64 +0 -1
  194. package/src/scss/font/source-sans-pro/source-sans-pro-regular.woff +0 -0
  195. package/src/scss/font/source-sans-pro/source-sans-pro-regular.woff.b64 +0 -1
  196. package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.eot +0 -0
  197. package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.eot.b64 +0 -1
  198. package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.woff +0 -0
  199. package/src/scss/font/source-sans-pro/source-sans-pro-semibold-italic.woff.b64 +0 -1
  200. package/src/scss/font/source-sans-pro/source-sans-pro-semibold.eot +0 -0
  201. package/src/scss/font/source-sans-pro/source-sans-pro-semibold.eot.b64 +0 -1
  202. package/src/scss/font/source-sans-pro/source-sans-pro-semibold.woff +0 -0
  203. package/src/scss/font/source-sans-pro/source-sans-pro-semibold.woff.b64 +0 -1
  204. package/src/scss/font/tao/tao.eot +0 -0
  205. package/src/scss/font/tao/tao.svg +0 -235
  206. package/src/scss/font/tao/tao.ttf +0 -0
  207. package/src/scss/font/tao/tao.woff +0 -0
  208. package/src/scss/inc/_base.scss +0 -496
  209. package/src/scss/inc/_bootstrap.scss +0 -6
  210. package/src/scss/inc/_buttons.scss +0 -114
  211. package/src/scss/inc/_colors.scss +0 -88
  212. package/src/scss/inc/_feedback.scss +0 -150
  213. package/src/scss/inc/_flex-grid.scss +0 -15
  214. package/src/scss/inc/_fonts.scss +0 -4
  215. package/src/scss/inc/_forms.scss +0 -827
  216. package/src/scss/inc/_functions.scss +0 -283
  217. package/src/scss/inc/_grid.scss +0 -66
  218. package/src/scss/inc/_jquery.nouislider.scss +0 -254
  219. package/src/scss/inc/_normalize.scss +0 -528
  220. package/src/scss/inc/_report.scss +0 -68
  221. package/src/scss/inc/_secondary-properties.scss +0 -89
  222. package/src/scss/inc/_select2.scss +0 -634
  223. package/src/scss/inc/_toolbars.scss +0 -155
  224. package/src/scss/inc/_tooltip.scss +0 -312
  225. package/src/scss/inc/_variables.scss +0 -21
  226. package/src/scss/inc/base/_highlight.scss +0 -5
  227. package/src/scss/inc/base/_list-style.scss +0 -59
  228. package/src/scss/inc/base/_svg.scss +0 -3
  229. package/src/scss/inc/base/_table.scss +0 -63
  230. package/src/scss/inc/fonts/_source-sans-pro.scss +0 -29
  231. package/src/scss/inc/fonts/_tao-icon-classes.scss +0 -226
  232. package/src/scss/inc/fonts/_tao-icon-def.scss +0 -12
  233. package/src/scss/inc/fonts/_tao-icon-vars.scss +0 -240
package/dist/uploader.js CHANGED
@@ -1,797 +1,788 @@
1
1
  define(['jquery', 'lodash', 'i18n', 'async', 'core/pluginifier', 'util/bytes', 'handlebars', 'lib/dompurify/purify', 'ui/filesender', 'ui/progressbar'], function ($$1, _, __, async, Pluginifier, bytes, Handlebars, DOMPurify, filesender, progressbar) { 'use strict';
2
2
 
3
- $$1 = $$1 && Object.prototype.hasOwnProperty.call($$1, 'default') ? $$1['default'] : $$1;
4
- _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
5
- __ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
6
- async = async && Object.prototype.hasOwnProperty.call(async, 'default') ? async['default'] : async;
7
- Pluginifier = Pluginifier && Object.prototype.hasOwnProperty.call(Pluginifier, 'default') ? Pluginifier['default'] : Pluginifier;
8
- bytes = bytes && Object.prototype.hasOwnProperty.call(bytes, 'default') ? bytes['default'] : bytes;
9
- Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars;
10
- DOMPurify = DOMPurify && Object.prototype.hasOwnProperty.call(DOMPurify, 'default') ? DOMPurify['default'] : DOMPurify;
11
-
3
+ $$1 = $$1 && Object.prototype.hasOwnProperty.call($$1, 'default') ? $$1['default'] : $$1;
4
+ _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _;
5
+ __ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __;
6
+ async = async && Object.prototype.hasOwnProperty.call(async, 'default') ? async['default'] : async;
7
+ Pluginifier = Pluginifier && Object.prototype.hasOwnProperty.call(Pluginifier, 'default') ? Pluginifier['default'] : Pluginifier;
8
+ bytes = bytes && Object.prototype.hasOwnProperty.call(bytes, 'default') ? bytes['default'] : bytes;
9
+ Handlebars = Handlebars && Object.prototype.hasOwnProperty.call(Handlebars, 'default') ? Handlebars['default'] : Handlebars;
10
+ DOMPurify = DOMPurify && Object.prototype.hasOwnProperty.call(DOMPurify, 'default') ? DOMPurify['default'] : DOMPurify;
11
+
12
+ function _typeof(obj) {
13
+ "@babel/helpers - typeof";
14
+
15
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
16
+ return typeof obj;
17
+ } : function (obj) {
18
+ return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
19
+ }, _typeof(obj);
20
+ }
21
+
22
+ function Helpers0 (hb) {
23
+ //register a i18n helper
24
+ hb.registerHelper('__', function (key) {
25
+ return __(key);
26
+ });
12
27
  /**
13
- * This program is free software; you can redistribute it and/or
14
- * modify it under the terms of the GNU General Public License
15
- * as published by the Free Software Foundation; under version 2
16
- * of the License (non-upgradable).
17
- *
18
- * This program is distributed in the hope that it will be useful,
19
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
- * GNU General Public License for more details.
22
- *
23
- * You should have received a copy of the GNU General Public License
24
- * along with this program; if not, write to the Free Software
25
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26
- *
27
- * Copyright (c) 2013-2019 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
28
- *
28
+ * Register dompurify helper
29
29
  *
30
+ * https://github.com/cure53/DOMPurify
31
+ * with config SAFE_FOR_TEMPLATES: true
32
+ * to make output safe for template systems
30
33
  */
31
- function Helpers0 (hb) {
32
- //register a i18n helper
33
- hb.registerHelper('__', function (key) {
34
- return __(key);
35
- });
36
- /**
37
- * Register dompurify helper
38
- *
39
- * https://github.com/cure53/DOMPurify
40
- * with config SAFE_FOR_TEMPLATES: true
41
- * to make output safe for template systems
42
- */
43
34
 
44
- hb.registerHelper('dompurify', function (context) {
45
- return DOMPurify.sanitize(context);
46
- });
47
- /**
48
- * Register join helper
49
- *
50
- * Example :
51
- * var values = {a:v1, b:v2, c:v3};
52
- * Using {{{join attributes '=' ' ' '"'}}} will return : a="v1" b="v2" c="v3"
53
- * Using {{{join values null ' or ' '*'}}} will return : *v1* or *v2* or *v3*
54
- */
55
-
56
- hb.registerHelper('join', function (arr, keyValueGlue, fragmentGlue, wrapper) {
57
- var fragments = [];
58
- keyValueGlue = typeof keyValueGlue === 'string' ? keyValueGlue : undefined;
59
- fragmentGlue = typeof fragmentGlue === 'string' ? fragmentGlue : ' ';
60
- wrapper = typeof wrapper === 'string' ? wrapper : '"';
35
+ hb.registerHelper('dompurify', function (context) {
36
+ return DOMPurify.sanitize(context);
37
+ });
38
+ /**
39
+ * Register join helper
40
+ *
41
+ * Example :
42
+ * var values = {a:v1, b:v2, c:v3};
43
+ * Using {{{join attributes '=' ' ' '"'}}} will return : a="v1" b="v2" c="v3"
44
+ * Using {{{join values null ' or ' '*'}}} will return : *v1* or *v2* or *v3*
45
+ */
61
46
 
62
- _.forIn(arr, function (value, key) {
63
- var fragment = '';
47
+ hb.registerHelper('join', function (arr, keyValueGlue, fragmentGlue, wrapper) {
48
+ var fragments = [];
49
+ keyValueGlue = typeof keyValueGlue === 'string' ? keyValueGlue : undefined;
50
+ fragmentGlue = typeof fragmentGlue === 'string' ? fragmentGlue : ' ';
51
+ wrapper = typeof wrapper === 'string' ? wrapper : '"';
64
52
 
65
- if (value !== null || value !== undefined) {
66
- if (typeof value === 'boolean') {
67
- value = value ? 'true' : 'false';
68
- } else if (typeof value === 'object') {
69
- value = _.values(value).join(' ');
70
- }
71
- } else {
72
- value = '';
73
- }
53
+ _.forIn(arr, function (value, key) {
54
+ var fragment = '';
74
55
 
75
- if (keyValueGlue !== undefined) {
76
- fragment += key + keyValueGlue;
56
+ if (value !== null || value !== undefined) {
57
+ if (typeof value === 'boolean') {
58
+ value = value ? 'true' : 'false';
59
+ } else if (_typeof(value) === 'object') {
60
+ value = _.values(value).join(' ');
77
61
  }
62
+ } else {
63
+ value = '';
64
+ }
78
65
 
79
- fragment += wrapper + value + wrapper;
80
- fragments.push(fragment);
81
- });
82
-
83
- return fragments.join(fragmentGlue);
84
- }); //register a classic "for loop" helper
85
- //it also adds a local variable "i" as the index in each iteration loop
86
-
87
- hb.registerHelper('for', function (startIndex, stopIndex, increment, options) {
88
- var ret = '';
89
- startIndex = parseInt(startIndex);
90
- stopIndex = parseInt(stopIndex);
91
- increment = parseInt(increment);
92
-
93
- for (var i = startIndex; i < stopIndex; i += increment) {
94
- ret += options.fn(_.extend({}, this, {
95
- i: i
96
- }));
66
+ if (keyValueGlue !== undefined) {
67
+ fragment += key + keyValueGlue;
97
68
  }
98
69
 
99
- return ret;
70
+ fragment += wrapper + value + wrapper;
71
+ fragments.push(fragment);
100
72
  });
101
- hb.registerHelper('equal', function (var1, var2, options) {
102
- if (var1 == var2) {
103
- return options.fn(this);
104
- } else {
105
- return options.inverse(this);
106
- }
107
- }); // register a "get property" helper
108
- // it gets the named property from the provided context
109
73
 
110
- hb.registerHelper('property', function (name, context) {
111
- return context[name] || '';
112
- }); // register an 'includes' helper
113
- // it checks if value is in array
74
+ return fragments.join(fragmentGlue);
75
+ }); //register a classic "for loop" helper
76
+ //it also adds a local variable "i" as the index in each iteration loop
114
77
 
115
- hb.registerHelper('includes', function (haystack, needle, options) {
116
- if (_.contains(haystack, needle)) {
117
- return options.fn(this);
118
- }
119
- });
120
- }
78
+ hb.registerHelper('for', function (startIndex, stopIndex, increment, options) {
79
+ var ret = '';
80
+ startIndex = parseInt(startIndex);
81
+ stopIndex = parseInt(stopIndex);
82
+ increment = parseInt(increment);
121
83
 
122
- if (!Helpers0.__initialized) {
123
- Helpers0(Handlebars);
124
- Helpers0.__initialized = true;
125
- }
126
- var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
127
- this.compilerInfo = [4,'>= 1.0.0'];
128
- helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
129
- var buffer = "", stack1, helper, options, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType="function", self=this;
130
-
131
- function program1(depth0,data) {
132
-
133
-
134
- return "multiple";
84
+ for (var i = startIndex; i < stopIndex; i += increment) {
85
+ ret += options.fn(_.extend({}, this, {
86
+ i: i
87
+ }));
135
88
  }
136
89
 
137
- function program3(depth0,data) {
138
-
139
- var buffer = "", helper, options;
140
- buffer += "\n "
141
- + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Drag files here", options) : helperMissing.call(depth0, "__", "Drag files here", options)))
142
- + "\n ";
143
- return buffer;
90
+ return ret;
91
+ });
92
+ hb.registerHelper('equal', function (var1, var2, options) {
93
+ if (var1 == var2) {
94
+ return options.fn(this);
95
+ } else {
96
+ return options.inverse(this);
144
97
  }
98
+ }); // register a "get property" helper
99
+ // it gets the named property from the provided context
145
100
 
146
- function program5(depth0,data) {
147
-
148
- var buffer = "", helper, options;
149
- buffer += "\n "
150
- + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Drag file here", options) : helperMissing.call(depth0, "__", "Drag file here", options)))
151
- + "\n ";
152
- return buffer;
153
- }
101
+ hb.registerHelper('property', function (name, context) {
102
+ return context[name] || '';
103
+ }); // register an 'includes' helper
104
+ // it checks if value is in array
154
105
 
155
- function program7(depth0,data) {
156
-
157
- var buffer = "", helper, options;
158
- buffer += "\n <button type=\"button\" class=\"btn-info btn-reset small\"><span class=\"icon-eraser\"></span>"
159
- + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Reset", options) : helperMissing.call(depth0, "__", "Reset", options)))
160
- + "</button>\n ";
161
- return buffer;
106
+ hb.registerHelper('includes', function (haystack, needle, options) {
107
+ if (_.contains(haystack, needle)) {
108
+ return options.fn(this);
162
109
  }
110
+ });
111
+ }
112
+
113
+ if (!Helpers0.__initialized) {
114
+ Helpers0(Handlebars);
115
+ Helpers0.__initialized = true;
116
+ }
117
+ var Template = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
118
+ this.compilerInfo = [4,'>= 1.0.0'];
119
+ helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
120
+ var buffer = "", stack1, helper, options, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType="function", self=this;
121
+
122
+ function program1(depth0,data) {
123
+
124
+
125
+ return "multiple";
126
+ }
163
127
 
164
- function program9(depth0,data) {
165
-
166
- var buffer = "", stack1, helper;
167
- buffer += "\n <button class=\"btn-success btn-upload small\"><span class=\"icon-upload\"></span>";
168
- if (helper = helpers.uploadBtnText) { stack1 = helper.call(depth0, {hash:{},data:data}); }
169
- else { helper = (depth0 && depth0.uploadBtnText); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
170
- buffer += escapeExpression(stack1)
171
- + "</button>\n ";
172
- return buffer;
173
- }
128
+ function program3(depth0,data) {
129
+
130
+ var buffer = "", helper, options;
131
+ buffer += "\n "
132
+ + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Drag files here", options) : helperMissing.call(depth0, "__", "Drag files here", options)))
133
+ + "\n ";
134
+ return buffer;
135
+ }
174
136
 
175
- buffer += "<div class=\"file-upload grid-row\">\n <span class=\"btn-info btn-browse small col-5\"><span class=\"icon-folder-open\"></span>"
176
- + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Browse...", options) : helperMissing.call(depth0, "__", "Browse...", options)))
177
- + "</span>\n <span class=\"file-name col-7 truncate placeholder\">"
178
- + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "No file selected", options) : helperMissing.call(depth0, "__", "No file selected", options)))
179
- + "</span>\n <input type=\"file\" name=\"";
180
- if (helper = helpers.inputName) { stack1 = helper.call(depth0, {hash:{},data:data}); }
181
- else { helper = (depth0 && depth0.inputName); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
182
- buffer += escapeExpression(stack1)
183
- + "\" ";
184
- stack1 = helpers['if'].call(depth0, (depth0 && depth0.multiple), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
185
- if(stack1 || stack1 === 0) { buffer += stack1; }
186
- buffer += ">\n</div>\n<!--<div class=\"grid-row\" style=\"display:none;\">-->\n<!--<ul class=\"file-list\"></ul>-->\n<!--</div>-->\n<div class=\"grid-row\">\n <div class=\"file-drop col-12\" data-drop-msg=\""
187
- + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Drop the files to upload", options) : helperMissing.call(depth0, "__", "Drop the files to upload", options)))
188
- + "\">\n <div class=\"dragholder\">\n ~ "
189
- + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "or", options) : helperMissing.call(depth0, "__", "or", options)))
190
- + " ~\n <br/>\n ";
191
- stack1 = helpers['if'].call(depth0, (depth0 && depth0.multiple), {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data),data:data});
192
- if(stack1 || stack1 === 0) { buffer += stack1; }
193
- buffer += "\n </div>\n </div>\n</div>\n<div class=\"grid-row\">\n <div class=\"progressbar col-12\"></div>\n <br/>\n</div>\n<div class=\"grid-row\">\n ";
194
- stack1 = helpers['if'].call(depth0, (depth0 && depth0.showResetButton), {hash:{},inverse:self.noop,fn:self.program(7, program7, data),data:data});
195
- if(stack1 || stack1 === 0) { buffer += stack1; }
196
- buffer += "\n ";
197
- stack1 = helpers['if'].call(depth0, (depth0 && depth0.showUploadButton), {hash:{},inverse:self.noop,fn:self.program(9, program9, data),data:data});
198
- if(stack1 || stack1 === 0) { buffer += stack1; }
199
- buffer += "\n</div>";
200
- return buffer;
201
- });
202
- function uploaderTpl(data, options, asString) {
203
- var html = Template(data, options);
204
- return (asString || true) ? html : $(html);
137
+ function program5(depth0,data) {
138
+
139
+ var buffer = "", helper, options;
140
+ buffer += "\n "
141
+ + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Drag file here", options) : helperMissing.call(depth0, "__", "Drag file here", options)))
142
+ + "\n ";
143
+ return buffer;
205
144
  }
206
145
 
207
- if (!Helpers0.__initialized) {
208
- Helpers0(Handlebars);
209
- Helpers0.__initialized = true;
146
+ function program7(depth0,data) {
147
+
148
+ var buffer = "", helper, options;
149
+ buffer += "\n <button type=\"button\" class=\"btn-info btn-reset small\"><span class=\"icon-eraser\"></span>"
150
+ + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Reset", options) : helperMissing.call(depth0, "__", "Reset", options)))
151
+ + "</button>\n ";
152
+ return buffer;
210
153
  }
211
- var Template$1 = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
212
- this.compilerInfo = [4,'>= 1.0.0'];
213
- helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
214
- var buffer = "", stack1, helper, functionType="function", escapeExpression=this.escapeExpression;
215
-
216
-
217
- buffer += "<li data-file-name=\"";
218
- if (helper = helpers.name) { stack1 = helper.call(depth0, {hash:{},data:data}); }
219
- else { helper = (depth0 && depth0.name); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
220
- buffer += escapeExpression(stack1)
221
- + "\">\n ";
222
- if (helper = helpers.name) { stack1 = helper.call(depth0, {hash:{},data:data}); }
223
- else { helper = (depth0 && depth0.name); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
224
- buffer += escapeExpression(stack1)
225
- + "\n <span class=\"size\">";
226
- if (helper = helpers.size) { stack1 = helper.call(depth0, {hash:{},data:data}); }
227
- else { helper = (depth0 && depth0.size); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
228
- buffer += escapeExpression(stack1)
229
- + "</span>\n <span class=\"status\"></span>\n <a href=\"#\" data-role=\"delete\"><span class=\"icon-close\"></span></a>\n</li>\n";
230
- return buffer;
231
- });
232
- function fileEntryTpl(data, options, asString) {
233
- var html = Template$1(data, options);
234
- return (asString || true) ? html : $(html);
154
+
155
+ function program9(depth0,data) {
156
+
157
+ var buffer = "", stack1, helper;
158
+ buffer += "\n <button class=\"btn-success btn-upload small\"><span class=\"icon-upload\"></span>";
159
+ if (helper = helpers.uploadBtnText) { stack1 = helper.call(depth0, {hash:{},data:data}); }
160
+ else { helper = (depth0 && depth0.uploadBtnText); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
161
+ buffer += escapeExpression(stack1)
162
+ + "</button>\n ";
163
+ return buffer;
235
164
  }
236
165
 
166
+ buffer += "<div class=\"file-upload grid-row\">\n <span class=\"btn-info btn-browse small col-5\"><span class=\"icon-folder-open\"></span>"
167
+ + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Browse...", options) : helperMissing.call(depth0, "__", "Browse...", options)))
168
+ + "</span>\n <span class=\"file-name col-7 truncate placeholder\">"
169
+ + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "No file selected", options) : helperMissing.call(depth0, "__", "No file selected", options)))
170
+ + "</span>\n <input type=\"file\" name=\"";
171
+ if (helper = helpers.inputName) { stack1 = helper.call(depth0, {hash:{},data:data}); }
172
+ else { helper = (depth0 && depth0.inputName); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
173
+ buffer += escapeExpression(stack1)
174
+ + "\" ";
175
+ stack1 = helpers['if'].call(depth0, (depth0 && depth0.multiple), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});
176
+ if(stack1 || stack1 === 0) { buffer += stack1; }
177
+ buffer += ">\n</div>\n<!--<div class=\"grid-row\" style=\"display:none;\">-->\n<!--<ul class=\"file-list\"></ul>-->\n<!--</div>-->\n<div class=\"grid-row\">\n <div class=\"file-drop col-12\" data-drop-msg=\""
178
+ + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "Drop the files to upload", options) : helperMissing.call(depth0, "__", "Drop the files to upload", options)))
179
+ + "\">\n <div class=\"dragholder\">\n ~ "
180
+ + escapeExpression((helper = helpers.__ || (depth0 && depth0.__),options={hash:{},data:data},helper ? helper.call(depth0, "or", options) : helperMissing.call(depth0, "__", "or", options)))
181
+ + " ~\n <br/>\n ";
182
+ stack1 = helpers['if'].call(depth0, (depth0 && depth0.multiple), {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data),data:data});
183
+ if(stack1 || stack1 === 0) { buffer += stack1; }
184
+ buffer += "\n </div>\n </div>\n</div>\n<div class=\"grid-row\">\n <div class=\"progressbar col-12\"></div>\n <br/>\n</div>\n<div class=\"grid-row\">\n ";
185
+ stack1 = helpers['if'].call(depth0, (depth0 && depth0.showResetButton), {hash:{},inverse:self.noop,fn:self.program(7, program7, data),data:data});
186
+ if(stack1 || stack1 === 0) { buffer += stack1; }
187
+ buffer += "\n ";
188
+ stack1 = helpers['if'].call(depth0, (depth0 && depth0.showUploadButton), {hash:{},inverse:self.noop,fn:self.program(9, program9, data),data:data});
189
+ if(stack1 || stack1 === 0) { buffer += stack1; }
190
+ buffer += "\n</div>";
191
+ return buffer;
192
+ });
193
+ function uploaderTpl(data, options, asString) {
194
+ var html = Template(data, options);
195
+ return (asString || true) ? html : $(html);
196
+ }
197
+
198
+ if (!Helpers0.__initialized) {
199
+ Helpers0(Handlebars);
200
+ Helpers0.__initialized = true;
201
+ }
202
+ var Template$1 = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
203
+ this.compilerInfo = [4,'>= 1.0.0'];
204
+ helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
205
+ var buffer = "", stack1, helper, functionType="function", escapeExpression=this.escapeExpression;
206
+
207
+
208
+ buffer += "<li data-file-name=\"";
209
+ if (helper = helpers.name) { stack1 = helper.call(depth0, {hash:{},data:data}); }
210
+ else { helper = (depth0 && depth0.name); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
211
+ buffer += escapeExpression(stack1)
212
+ + "\">\n ";
213
+ if (helper = helpers.name) { stack1 = helper.call(depth0, {hash:{},data:data}); }
214
+ else { helper = (depth0 && depth0.name); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
215
+ buffer += escapeExpression(stack1)
216
+ + "\n <span class=\"size\">";
217
+ if (helper = helpers.size) { stack1 = helper.call(depth0, {hash:{},data:data}); }
218
+ else { helper = (depth0 && depth0.size); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
219
+ buffer += escapeExpression(stack1)
220
+ + "</span>\n <span class=\"status\"></span>\n <a href=\"#\" data-role=\"delete\"><span class=\"icon-close\"></span></a>\n</li>\n";
221
+ return buffer;
222
+ });
223
+ function fileEntryTpl(data, options, asString) {
224
+ var html = Template$1(data, options);
225
+ return (asString || true) ? html : $(html);
226
+ }
227
+
228
+ /**
229
+ * @author Bertrand Chevrier <bertrand@taotesting.com>
230
+ */
231
+ var ns = 'uploader';
232
+ var dataNs = 'ui.' + ns; //the plugin defaults
233
+
234
+ var defaults = {
235
+ upload: true,
236
+ read: false,
237
+ multiple: false,
238
+ uploadQueueSize: 3,
239
+ inputName: 'content',
240
+ showResetButton: true,
241
+ showUploadButton: true,
242
+ browseBtnClass: 'btn-browse',
243
+ uploadBtnClass: 'btn-upload',
244
+ resetBtnClass: 'btn-reset',
245
+ fileNameClass: 'file-name',
246
+ dropZoneClass: 'file-drop',
247
+ progressBarClass: 'progressbar',
248
+ dragOverClass: 'drag-hover',
249
+ formAttributes: {
250
+ class: 'uploader uploaderContainer'
251
+ },
252
+ defaultErrMsg: __('Unable to upload file'),
253
+ uploadBtnText: __('Upload'),
254
+
237
255
  /**
238
- * @author Bertrand Chevrier <bertrand@taotesting.com>
256
+ * Make files available before file selection. It can be used to filter.
257
+ * @callback fileSelect
258
+ * @param {Array<File>} files - the selected files
259
+ * @param {Function} [done] - callback with filtered files
260
+ * @returns {undefined|Array<File>} the files to be selected
239
261
  */
240
- const ns = 'uploader';
241
- const dataNs = 'ui.' + ns; //the plugin defaults
242
-
243
- const defaults = {
244
- upload: true,
245
- read: false,
246
- multiple: false,
247
- uploadQueueSize: 3,
248
- inputName: 'content',
249
- showResetButton: true,
250
- showUploadButton: true,
251
- browseBtnClass: 'btn-browse',
252
- uploadBtnClass: 'btn-upload',
253
- resetBtnClass: 'btn-reset',
254
- fileNameClass: 'file-name',
255
- dropZoneClass: 'file-drop',
256
- progressBarClass: 'progressbar',
257
- dragOverClass: 'drag-hover',
258
- formAttributes: {
259
- class: 'uploader uploaderContainer'
260
- },
261
- defaultErrMsg: __('Unable to upload file'),
262
- uploadBtnText: __('Upload'),
263
-
264
- /**
265
- * Make files available before file selection. It can be used to filter.
266
- * @callback fileSelect
267
- * @param {Array<File>} files - the selected files
268
- * @param {Function} [done] - callback with filtered files
269
- * @returns {undefined|Array<File>} the files to be selected
270
- */
271
- fileSelect: function (files, done) {
272
- if (_.isFunction(done)) {
273
- return done(files);
274
- }
275
-
276
- return files;
262
+ fileSelect: function fileSelect(files, done) {
263
+ if (_.isFunction(done)) {
264
+ return done(files);
277
265
  }
278
- }; //feature tests
279
266
 
280
- const tests = {
281
- filereader: typeof FileReader !== 'undefined',
282
- dnd: 'draggable' in document.createElement('span')
283
- };
267
+ return files;
268
+ }
269
+ }; //feature tests
270
+
271
+ var tests = {
272
+ filereader: typeof FileReader !== 'undefined',
273
+ dnd: 'draggable' in document.createElement('span')
274
+ };
275
+ /**
276
+ * Define a jQuery component to help you to manage file(s) upload/reading.
277
+ * @exports ui/uploader
278
+ */
279
+
280
+ var uploader = {
284
281
  /**
285
- * Define a jQuery component to help you to manage file(s) upload/reading.
286
- * @exports ui/uploader
282
+ * Initialize the plugin.
283
+ *
284
+ * Called the jQuery way once registered by the Pluginifier.
285
+ * @example $('selector').uploader();
286
+ *
287
+ * @constructor
288
+ * @param {Object} [options] - the plugin options
289
+ * @param {Boolean} [options.upload = true] - if we upload the file once selected
290
+ * @param {String} [options.uploadUrl] - the URL where the files will be posted
291
+ * @param {jQueryElement} [options.$form] - a form to be used instead
292
+ * @param {Boolean} [options.read = false] - if we can read the file once selected
293
+ * @param {Boolean} [options.multiple = false] - enable to select more multiple files (may be not supported by old browsers)
294
+ * @param {Number} [options.uploadQueueSize = 3] - max parallel uploads (applies only in multiple mode)
295
+ * @param {String} [options.browseBtnClass = btn-browse] - the class to identify the browse button
296
+ * @param {String} [options.uploadBtnClass = btn-upload] - the class to identify the upload button
297
+ * @param {String} [options.resetBtnClass = btn-reset] - the class to identify the reset button
298
+ * @param {String} [options.fileNameClass = file-name] - the class of the elt where the file name is set
299
+ * @param {String} [options.dropZoneClass = file-drop] - the class of the drop file elt
300
+ * @param {String} [options.progressBarClass = progressbar] - the class to identify the progress bar
301
+ * @param {String} [options.dragOverClass = drag-hover] - the class to set to the drop zone when dragging over
302
+ * @param {Function} [options.fileSelect] - called back before selection with files in params and returns the files to select; filter use case
303
+ * @param {Object} [options.formAttributes] - object with all the attributes you want to be on the form element
304
+ * @param {String} [options.defaultErrMsg] - localized error message when something goes wrong
305
+ * @param {String} [options.uploadBtnText] - text on upload button
306
+ * @returns {jQueryElement} for chainingV
287
307
  */
308
+ init: function init(options) {
309
+ //get options using default
310
+ options = _.defaults(options || {}, defaults);
311
+ return this.each(function () {
312
+ var $elt = $$1(this);
313
+ var $builtInForm;
314
+
315
+ if (!$elt.data(dataNs)) {
316
+ $elt.html(uploaderTpl(options)); // form could be inside $elt ...
317
+
318
+ $builtInForm = options.$form && options.$form.length ? options.$form : $elt.find('form'); // ... if not it could be a wrapper
319
+
320
+ if (!$builtInForm.length) {
321
+ $builtInForm = $elt.closest('form');
322
+ } // ... if no form is present wrap $elt in one
323
+
324
+
325
+ if (!$builtInForm.length) {
326
+ $elt.wrap($$1('<form>', options.formAttributes));
327
+ $builtInForm = $elt.parent();
328
+ } //retrieve elements
329
+
330
+
331
+ options.$input = $$1('input[type=file]', $elt);
332
+ options.$browseBtn = $$1('.' + options.browseBtnClass, $elt);
333
+ options.$fileName = $$1('.' + options.fileNameClass, $elt);
334
+ options.$dropZone = $$1('.' + options.dropZoneClass, $elt);
335
+ options.$progressBar = $$1('.' + options.progressBarClass, $elt);
336
+ options.$form = $builtInForm;
337
+ options.$uploadBtn = $$1('.' + options.uploadBtnClass, $elt);
338
+ options.$resetBtn = $$1('.' + options.resetBtnClass, $elt);
339
+ options.useDropZone = tests.dnd;
340
+ options.dropZonePlaceholder = options.$dropZone.html();
341
+ options.fileNamePlaceholder = options.$fileName.text();
342
+ options.files = [];
343
+ $elt.data(dataNs, options);
344
+
345
+ uploader._reset($elt);
346
+
347
+ var inputHandler = function inputHandler(e) {
348
+ // _.values also get the length property of the FileList object,
349
+ // so we go for a plain old loop.
350
+ var finalFiles = [];
351
+
352
+ _.forEach(e.target.files, function (file) {
353
+ finalFiles.push(file);
354
+ });
288
355
 
289
- const uploader = {
290
- /**
291
- * Initialize the plugin.
292
- *
293
- * Called the jQuery way once registered by the Pluginifier.
294
- * @example $('selector').uploader();
295
- *
296
- * @constructor
297
- * @param {Object} [options] - the plugin options
298
- * @param {Boolean} [options.upload = true] - if we upload the file once selected
299
- * @param {String} [options.uploadUrl] - the URL where the files will be posted
300
- * @param {jQueryElement} [options.$form] - a form to be used instead
301
- * @param {Boolean} [options.read = false] - if we can read the file once selected
302
- * @param {Boolean} [options.multiple = false] - enable to select more multiple files (may be not supported by old browsers)
303
- * @param {Number} [options.uploadQueueSize = 3] - max parallel uploads (applies only in multiple mode)
304
- * @param {String} [options.browseBtnClass = btn-browse] - the class to identify the browse button
305
- * @param {String} [options.uploadBtnClass = btn-upload] - the class to identify the upload button
306
- * @param {String} [options.resetBtnClass = btn-reset] - the class to identify the reset button
307
- * @param {String} [options.fileNameClass = file-name] - the class of the elt where the file name is set
308
- * @param {String} [options.dropZoneClass = file-drop] - the class of the drop file elt
309
- * @param {String} [options.progressBarClass = progressbar] - the class to identify the progress bar
310
- * @param {String} [options.dragOverClass = drag-hover] - the class to set to the drop zone when dragging over
311
- * @param {Function} [options.fileSelect] - called back before selection with files in params and returns the files to select; filter use case
312
- * @param {Object} [options.formAttributes] - object with all the attributes you want to be on the form element
313
- * @param {String} [options.defaultErrMsg] - localized error message when something goes wrong
314
- * @param {String} [options.uploadBtnText] - text on upload button
315
- * @returns {jQueryElement} for chainingV
316
- */
317
- init: function (options) {
318
- //get options using default
319
- options = _.defaults(options || {}, defaults);
320
- return this.each(function () {
321
- const $elt = $$1(this);
322
- let $builtInForm;
323
-
324
- if (!$elt.data(dataNs)) {
325
- $elt.html(uploaderTpl(options)); // form could be inside $elt ...
326
-
327
- $builtInForm = options.$form && options.$form.length ? options.$form : $elt.find('form'); // ... if not it could be a wrapper
328
-
329
- if (!$builtInForm.length) {
330
- $builtInForm = $elt.closest('form');
331
- } // ... if no form is present wrap $elt in one
332
-
333
-
334
- if (!$builtInForm.length) {
335
- $elt.wrap($$1('<form>', options.formAttributes));
336
- $builtInForm = $elt.parent();
337
- } //retrieve elements
338
-
339
-
340
- options.$input = $$1('input[type=file]', $elt);
341
- options.$browseBtn = $$1('.' + options.browseBtnClass, $elt);
342
- options.$fileName = $$1('.' + options.fileNameClass, $elt);
343
- options.$dropZone = $$1('.' + options.dropZoneClass, $elt);
344
- options.$progressBar = $$1('.' + options.progressBarClass, $elt);
345
- options.$form = $builtInForm;
346
- options.$uploadBtn = $$1('.' + options.uploadBtnClass, $elt);
347
- options.$resetBtn = $$1('.' + options.resetBtnClass, $elt);
348
- options.useDropZone = tests.dnd;
349
- options.dropZonePlaceholder = options.$dropZone.html();
350
- options.fileNamePlaceholder = options.$fileName.text();
351
- options.files = [];
352
- $elt.data(dataNs, options);
353
-
354
- uploader._reset($elt);
355
-
356
- const inputHandler = function (e) {
357
- // _.values also get the length property of the FileList object,
358
- // so we go for a plain old loop.
359
- const finalFiles = [];
360
-
361
- _.forEach(e.target.files, function (file) {
362
- finalFiles.push(file);
363
- });
356
+ uploader._selectFiles($elt, finalFiles);
364
357
 
365
- uploader._selectFiles($elt, finalFiles);
358
+ options.$input.val('');
359
+ };
366
360
 
367
- options.$input.val('');
368
- };
361
+ var dragOverHandler = function dragOverHandler(e) {
362
+ e.preventDefault();
363
+ e.stopPropagation();
364
+ options.$dropZone.addClass(options.dragOverClass);
365
+ };
369
366
 
370
- const dragOverHandler = function (e) {
371
- e.preventDefault();
372
- e.stopPropagation();
373
- options.$dropZone.addClass(options.dragOverClass);
374
- };
367
+ var dragOutHandler = function dragOutHandler(e) {
368
+ e.preventDefault();
369
+ e.stopPropagation();
370
+ options.$dropZone.removeClass(options.dragOverClass);
371
+ }; //manage input selection
375
372
 
376
- const dragOutHandler = function (e) {
377
- e.preventDefault();
378
- e.stopPropagation();
379
- options.$dropZone.removeClass(options.dragOverClass);
380
- }; //manage input selection
381
373
 
374
+ if (!tests.filereader) {
375
+ throw new Error('FileReader API not supported! Please use a compliant browser!');
376
+ }
382
377
 
383
- if (!tests.filereader) {
384
- throw new Error('FileReader API not supported! Please use a compliant browser!');
385
- }
378
+ options.$input.on('change', inputHandler); // IE Specific hack. It prevents the browseBtn to slightly
379
+ // move on click. Special thanks to Dieter Raber, OAT S.A.
386
380
 
387
- options.$input.on('change', inputHandler); // IE Specific hack. It prevents the browseBtn to slightly
388
- // move on click. Special thanks to Dieter Raber, OAT S.A.
381
+ options.$input.on('mousedown', function (e) {
382
+ e.preventDefault();
383
+ $$1(this).blur();
384
+ return false;
385
+ }); //manage drag and drop selection
389
386
 
390
- options.$input.on('mousedown', function (e) {
387
+ if (options.useDropZone) {
388
+ //prevent drag and drop outside the zone to loose the current context
389
+ $$1(document).off('drop.' + ns).on('drop.' + ns, function (e) {
390
+ e.stopImmediatePropagation();
391
+ e.preventDefault();
392
+ return false;
393
+ });
394
+ $$1(document).off('dragover.' + ns).on('dragover.' + ns, function (e) {
395
+ e.stopImmediatePropagation();
391
396
  e.preventDefault();
392
- $$1(this).blur();
393
397
  return false;
394
- }); //manage drag and drop selection
398
+ });
399
+ options.$dropZone.on('dragover', dragOverHandler).on('dragend', dragOutHandler).on('dragleave', dragOutHandler).on('drop', function (e) {
400
+ var files = [];
401
+ dragOutHandler(e);
402
+
403
+ if (e.target.files) {
404
+ files = _.values(e.target.files);
405
+ } else if (e.originalEvent.files) {
406
+ files = _.values(e.originalEvent.files);
407
+ } else if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files) {
408
+ files = _.values(e.originalEvent.dataTransfer.files);
409
+ }
395
410
 
396
- if (options.useDropZone) {
397
- //prevent drag and drop outside the zone to loose the current context
398
- $$1(document).off('drop.' + ns).on('drop.' + ns, function (e) {
399
- e.stopImmediatePropagation();
400
- e.preventDefault();
401
- return false;
402
- });
403
- $$1(document).off('dragover.' + ns).on('dragover.' + ns, function (e) {
404
- e.stopImmediatePropagation();
405
- e.preventDefault();
406
- return false;
407
- });
408
- options.$dropZone.on('dragover', dragOverHandler).on('dragend', dragOutHandler).on('dragleave', dragOutHandler).on('drop', function (e) {
409
- let files = [];
410
- dragOutHandler(e);
411
-
412
- if (e.target.files) {
413
- files = _.values(e.target.files);
414
- } else if (e.originalEvent.files) {
415
- files = _.values(e.originalEvent.files);
416
- } else if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files) {
417
- files = _.values(e.originalEvent.dataTransfer.files);
411
+ if (files && files.length) {
412
+ var append = options.$dropZone.children('ul').length > 0;
413
+
414
+ if (!options.multiple) {
415
+ files = [files[0]];
416
+ append = false;
418
417
  }
419
418
 
420
- if (files && files.length) {
421
- let append = options.$dropZone.children('ul').length > 0;
419
+ uploader._selectFiles($elt, files, append);
420
+ }
422
421
 
423
- if (!options.multiple) {
424
- files = [files[0]];
425
- append = false;
426
- }
422
+ return false;
423
+ });
424
+ } else {
425
+ options.$dropZone.hide();
426
+ } //getting files
427
427
 
428
- uploader._selectFiles($elt, files, append);
429
- }
430
428
 
431
- return false;
432
- });
433
- } else {
434
- options.$dropZone.hide();
435
- } //getting files
429
+ $elt.on('fileselect.' + ns, function () {
430
+ if (options.files.length === 0) {
431
+ uploader._reset($elt);
432
+ }
436
433
 
434
+ if (options.upload) {
435
+ options.$uploadBtn.off('click').on('click', function (e) {
436
+ e.preventDefault();
437
437
 
438
- $elt.on('fileselect.' + ns, function () {
439
- if (options.files.length === 0) {
440
- uploader._reset($elt);
441
- }
438
+ uploader._upload($elt, options.files);
439
+ }).removeProp('disabled');
440
+ }
442
441
 
443
- if (options.upload) {
444
- options.$uploadBtn.off('click').on('click', function (e) {
445
- e.preventDefault();
442
+ if (options.read) {
443
+ uploader._read($elt, options.files);
444
+ }
446
445
 
447
- uploader._upload($elt, options.files);
448
- }).removeProp('disabled');
449
- }
446
+ options.$resetBtn.off('click').on('click', function (e) {
447
+ e.preventDefault();
450
448
 
451
- if (options.read) {
452
- uploader._read($elt, options.files);
453
- }
449
+ uploader._reset($elt);
450
+ }).removeProp('disabled');
451
+ });
452
+ /**
453
+ * The plugin has been created.
454
+ * @event uploader#create.uploader
455
+ */
454
456
 
455
- options.$resetBtn.off('click').on('click', function (e) {
456
- e.preventDefault();
457
+ $elt.trigger('create.' + ns);
458
+ }
459
+ });
460
+ },
457
461
 
458
- uploader._reset($elt);
459
- }).removeProp('disabled');
460
- });
461
- /**
462
- * The plugin has been created.
463
- * @event uploader#create.uploader
464
- */
462
+ /**
463
+ * Select files to upload/read.
464
+ *
465
+ * Called the jQuery way once registered by the Pluginifier:
466
+ * @example $('selector').uploader('selectFiles', files);
467
+ *
468
+ * @param {jQueryElement} $elt - plugin's element
469
+ * @param {Array<File>} files - the selected files
470
+ * @param {Boolean} [append = false] - in append mode the files are added instead of replaced
471
+ * @fires uploader#fileselect.uploader
472
+ */
473
+ _selectFiles: function _selectFiles($elt, files, append) {
474
+ var self = this;
475
+ var listContent;
476
+ var options = $elt.data(dataNs); //update the file name field with the current number of files selected
477
+
478
+ var updateFileName = function updateFileName() {
479
+ var length = options.files.length;
480
+ options.$fileName.text(length + ' ' + (length > 1 ? __('files selected') : __('file selected'))).removeClass('placeholder');
481
+ };
482
+
483
+ if (files.length <= 0 && !append) {
484
+ //empty file list, so we reset the plugin
485
+ self._reset($elt);
486
+ }
465
487
 
466
- $elt.trigger('create.' + ns);
488
+ if (files.length > 0) {
489
+ //execute the fileSelect function to filter files before selection
490
+ options.fileSelect.call($elt, files, function (filteredFiles) {
491
+ if (append) {
492
+ options.files = options.files.concat(filteredFiles);
493
+ } else {
494
+ options.files = filteredFiles;
467
495
  }
468
- });
469
- },
470
496
 
471
- /**
472
- * Select files to upload/read.
473
- *
474
- * Called the jQuery way once registered by the Pluginifier:
475
- * @example $('selector').uploader('selectFiles', files);
476
- *
477
- * @param {jQueryElement} $elt - plugin's element
478
- * @param {Array<File>} files - the selected files
479
- * @param {Boolean} [append = false] - in append mode the files are added instead of replaced
480
- * @fires uploader#fileselect.uploader
481
- */
482
- _selectFiles: function _selectFiles($elt, files, append) {
483
- const self = this;
484
- let listContent;
485
- const options = $elt.data(dataNs); //update the file name field with the current number of files selected
486
-
487
- const updateFileName = function updateFileName() {
488
- const length = options.files.length;
489
- options.$fileName.text(length + ' ' + (length > 1 ? __('files selected') : __('file selected'))).removeClass('placeholder');
490
- };
491
-
492
- if (files.length <= 0 && !append) {
493
- //empty file list, so we reset the plugin
494
- self._reset($elt);
495
- }
497
+ if (options.useDropZone) {
498
+ updateFileName();
499
+ listContent = _.reduce(filteredFiles, function (acc, file) {
500
+ return acc + fileEntryTpl({
501
+ name: file.name,
502
+ size: bytes.hrSize(file.size)
503
+ });
504
+ }, '');
496
505
 
497
- if (files.length > 0) {
498
- //execute the fileSelect function to filter files before selection
499
- options.fileSelect.call($elt, files, function (filteredFiles) {
500
506
  if (append) {
501
- options.files = options.files.concat(filteredFiles);
507
+ options.$dropZone.children('ul').append(listContent);
502
508
  } else {
503
- options.files = filteredFiles;
509
+ options.$dropZone.html('<ul>' + listContent + '</ul>');
504
510
  }
505
511
 
506
- if (options.useDropZone) {
507
- updateFileName();
508
- listContent = _.reduce(filteredFiles, function (acc, file) {
509
- return acc + fileEntryTpl({
510
- name: file.name,
511
- size: bytes.hrSize(file.size)
512
+ options.$dropZone.off('click.' + ns).on('click.' + ns, '[data-role=delete]', function (e) {
513
+ var $fileEntry = $$1(this).parent();
514
+ var name = $fileEntry.data('file-name');
515
+ e.preventDefault();
516
+ e.stopPropagation();
517
+
518
+ if (name) {
519
+ options.files = _.reject(options.files, {
520
+ name: name
512
521
  });
513
- }, '');
514
522
 
515
- if (append) {
516
- options.$dropZone.children('ul').append(listContent);
517
- } else {
518
- options.$dropZone.html('<ul>' + listContent + '</ul>');
523
+ if (options.files.length === 0) {
524
+ self._reset($elt);
525
+ } else {
526
+ updateFileName();
527
+ }
528
+
529
+ $fileEntry.remove();
519
530
  }
531
+ });
532
+ } else {
533
+ //legacy mode, no dnd support
534
+ options.files = options.files.slice(0, 1);
535
+ options.$fileName.text(files[0].name).removeClass('placeholder');
536
+ }
537
+ /**
538
+ * Files has been selected
539
+ * @event uploader#fileselect.uploader
540
+ */
520
541
 
521
- options.$dropZone.off('click.' + ns).on('click.' + ns, '[data-role=delete]', function (e) {
522
- const $fileEntry = $$1(this).parent();
523
- const name = $fileEntry.data('file-name');
524
- e.preventDefault();
525
- e.stopPropagation();
526
542
 
527
- if (name) {
528
- options.files = _.reject(options.files, {
529
- name: name
530
- });
543
+ $elt.trigger('fileselect.' + ns);
544
+ });
545
+ }
546
+ },
531
547
 
532
- if (options.files.length === 0) {
533
- self._reset($elt);
534
- } else {
535
- updateFileName();
536
- }
548
+ /**
549
+ * Get the selected files.
550
+ *
551
+ * Called the jQuery way once registered by the Pluginifier:
552
+ * @example const files = $('selector').uploader('files');
553
+ *
554
+ * @param {jQueryElement} $elt - plugin's element
555
+ * @returns {Array<File>} the selected files
556
+ */
557
+ _files: function _files($elt) {
558
+ var files = [];
559
+ var options = $elt.data(dataNs);
537
560
 
538
- $fileEntry.remove();
539
- }
540
- });
541
- } else {
542
- //legacy mode, no dnd support
543
- options.files = options.files.slice(0, 1);
544
- options.$fileName.text(files[0].name).removeClass('placeholder');
545
- }
546
- /**
547
- * Files has been selected
548
- * @event uploader#fileselect.uploader
549
- */
561
+ if (options) {
562
+ files = options.files;
563
+ }
550
564
 
565
+ return files;
566
+ },
551
567
 
552
- $elt.trigger('fileselect.' + ns);
553
- });
554
- }
555
- },
568
+ /**
569
+ * Reset the component
570
+ *
571
+ * Called the jQuery way once registered by the Pluginifier:
572
+ * @example $('selector').uploader('reset');
573
+ *
574
+ * @param {jQueryElement} $elt - plugin's element
575
+ * @fires uploader#reset.uploader
576
+ */
577
+ _reset: function _reset($elt) {
578
+ var options = $elt.data(dataNs);
579
+ options.$fileName.text(options.fileNamePlaceholder).addClass('placeholder');
580
+ options.$dropZone.empty().html(options.dropZonePlaceholder);
581
+ options.$uploadBtn.prop('disabled', true);
582
+ options.$resetBtn.prop('disabled', true);
583
+ var importButton = options.$form[0].querySelector('button');
584
+
585
+ if (importButton) {
586
+ importButton.setAttribute('disabled', true);
587
+ }
556
588
 
589
+ if (options.$progressBar) {
590
+ options.$progressBar.removeClass('success').progressbar('destroy').progressbar({
591
+ value: 0
592
+ });
593
+ }
557
594
  /**
558
- * Get the selected files.
559
- *
560
- * Called the jQuery way once registered by the Pluginifier:
561
- * @example const files = $('selector').uploader('files');
562
- *
563
- * @param {jQueryElement} $elt - plugin's element
564
- * @returns {Array<File>} the selected files
595
+ * The plugin has been created.
596
+ * @event uploader#reset.uploader
565
597
  */
566
- _files: function ($elt) {
567
- let files = [];
568
- const options = $elt.data(dataNs);
569
-
570
- if (options) {
571
- files = options.files;
572
- }
573
598
 
574
- return files;
575
- },
576
599
 
577
- /**
578
- * Reset the component
579
- *
580
- * Called the jQuery way once registered by the Pluginifier:
581
- * @example $('selector').uploader('reset');
582
- *
583
- * @param {jQueryElement} $elt - plugin's element
584
- * @fires uploader#reset.uploader
585
- */
586
- _reset: function ($elt) {
587
- const options = $elt.data(dataNs);
588
- options.$fileName.text(options.fileNamePlaceholder).addClass('placeholder');
589
- options.$dropZone.empty().html(options.dropZonePlaceholder);
590
- options.$uploadBtn.prop('disabled', true);
591
- options.$resetBtn.prop('disabled', true);
592
- const importButton = options.$form[0].querySelector('button');
600
+ $elt.trigger('reset.' + ns);
601
+ },
593
602
 
594
- if (importButton) {
595
- importButton.setAttribute('disabled', true);
596
- }
597
-
598
- if (options.$progressBar) {
599
- options.$progressBar.removeClass('success').progressbar('destroy').progressbar({
600
- value: 0
603
+ /**
604
+ * Upload the selected file
605
+ *
606
+ * Called the jQuery way once registered by the Pluginifier:
607
+ * @example $('selector').uploader('upload');
608
+ *
609
+ * @param {jQueryElement} $elt - plugin's element
610
+ * @fires uploader#upload.uploader
611
+ * @fires uploader#fail.uploader
612
+ * @fires uploader#end.uploader
613
+ */
614
+ _upload: function _upload($elt) {
615
+ var length,
616
+ $fileEntries,
617
+ entryHeight,
618
+ errors = [],
619
+ q;
620
+ var options = $elt.data(dataNs);
621
+
622
+ if (options && options.files.length) {
623
+ length = options.files.length;
624
+ $fileEntries = $$1('ul', options.$dropZone);
625
+ entryHeight = $$1('li:first', $fileEntries).outerHeight(); //create an async queue to start uploads
626
+
627
+ q = async.queue(function (file, done) {
628
+ var $fileEntry = $$1('li[data-file-name="' + file.name + '"]', $fileEntries);
629
+ var $status = $$1('.status', $fileEntry);
630
+ var index = $fileEntries.children().index($fileEntry); //update the scroll into the element
631
+
632
+ options.$dropZone.stop(true, true).animate({
633
+ scrollTop: index * entryHeight
634
+ }, 25);
635
+ $status.removeClass('success').removeClass('error').addClass('sending'); //send (upload) the file
636
+
637
+ options.$form.sendfile({
638
+ url: options.uploadUrl,
639
+ file: file,
640
+ loaded: function loaded(result) {
641
+ $status.removeClass('sending').removeClass('error').addClass('success');
642
+ done(null, result);
643
+ },
644
+ failed: function failed(message) {
645
+ message = message || options.defaultErrMsg;
646
+ $status.removeClass('sending').removeClass('success').addClass('error').attr('title', message);
647
+ done(new Error(message));
648
+ }
601
649
  });
602
- }
603
- /**
604
- * The plugin has been created.
605
- * @event uploader#reset.uploader
606
- */
650
+ }, options.uploadQueueSize || 1); //disable buttons
607
651
 
652
+ options.$uploadBtn.prop('disabled', true);
653
+ options.$resetBtn.prop('disabled', true);
654
+ options.$progressBar.progressbar('value', 0); //start pushing uploads into the queue
655
+
656
+ _.forEach(options.files, function (file, index) {
657
+ _.delay(function () {
658
+ q.push(file, function (err, result) {
659
+ var complete = (index + 1) / length * 100;
660
+
661
+ if (err) {
662
+ errors.push(err);
663
+ /**
664
+ * The file fails to upload
665
+ * @event uploader#fail.uploader
666
+ * @param {Object} file - the uploaded file
667
+ * @param {Object} err - the error
668
+ */
669
+
670
+ $elt.trigger('fail.' + ns, [file, err]);
671
+ } else {
672
+ /**
673
+ * A file is uploaded
674
+ * @event uploader#upload.uploader
675
+ * @param {Object} file - the uploaded file
676
+ * @param {Object} result - the upload response
677
+ */
678
+ $elt.trigger('upload.' + ns, [file, result]);
679
+ } //update progress bar regarding the number of files uploaded
680
+
681
+
682
+ options.$progressBar.progressbar('value', complete);
683
+
684
+ if (complete >= 100) {
685
+ if (errors.length === length) {
686
+ options.$progressBar.addClass('error');
687
+ } else if (errors.length > 0) {
688
+ options.$progressBar.addClass('warning');
689
+ } else {
690
+ options.$progressBar.addClass('success');
691
+ }
692
+ /**
693
+ * The upload sequence is complete
694
+ * @event uploader#end.uploader
695
+ */
608
696
 
609
- $elt.trigger('reset.' + ns);
610
- },
611
697
 
612
- /**
613
- * Upload the selected file
614
- *
615
- * Called the jQuery way once registered by the Pluginifier:
616
- * @example $('selector').uploader('upload');
617
- *
618
- * @param {jQueryElement} $elt - plugin's element
619
- * @fires uploader#upload.uploader
620
- * @fires uploader#fail.uploader
621
- * @fires uploader#end.uploader
622
- */
623
- _upload: function ($elt) {
624
- let length,
625
- $fileEntries,
626
- entryHeight,
627
- errors = [],
628
- q;
629
- const options = $elt.data(dataNs);
630
-
631
- if (options && options.files.length) {
632
- length = options.files.length;
633
- $fileEntries = $$1('ul', options.$dropZone);
634
- entryHeight = $$1('li:first', $fileEntries).outerHeight(); //create an async queue to start uploads
635
-
636
- q = async.queue(function (file, done) {
637
- var $fileEntry = $$1('li[data-file-name="' + file.name + '"]', $fileEntries);
638
- var $status = $$1('.status', $fileEntry);
639
- var index = $fileEntries.children().index($fileEntry); //update the scroll into the element
640
-
641
- options.$dropZone.stop(true, true).animate({
642
- scrollTop: index * entryHeight
643
- }, 25);
644
- $status.removeClass('success').removeClass('error').addClass('sending'); //send (upload) the file
645
-
646
- options.$form.sendfile({
647
- url: options.uploadUrl,
648
- file: file,
649
- loaded: function (result) {
650
- $status.removeClass('sending').removeClass('error').addClass('success');
651
- done(null, result);
652
- },
653
- failed: function (message) {
654
- message = message || options.defaultErrMsg;
655
- $status.removeClass('sending').removeClass('success').addClass('error').attr('title', message);
656
- done(new Error(message));
698
+ $elt.trigger('end.' + ns);
657
699
  }
658
700
  });
659
- }, options.uploadQueueSize || 1); //disable buttons
660
-
661
- options.$uploadBtn.prop('disabled', true);
662
- options.$resetBtn.prop('disabled', true);
663
- options.$progressBar.progressbar('value', 0); //start pushing uploads into the queue
664
-
665
- _.forEach(options.files, function (file, index) {
666
- _.delay(function () {
667
- q.push(file, function (err, result) {
668
- var complete = (index + 1) / length * 100;
669
-
670
- if (err) {
671
- errors.push(err);
672
- /**
673
- * The file fails to upload
674
- * @event uploader#fail.uploader
675
- * @param {Object} file - the uploaded file
676
- * @param {Object} err - the error
677
- */
678
-
679
- $elt.trigger('fail.' + ns, [file, err]);
680
- } else {
681
- /**
682
- * A file is uploaded
683
- * @event uploader#upload.uploader
684
- * @param {Object} file - the uploaded file
685
- * @param {Object} result - the upload response
686
- */
687
- $elt.trigger('upload.' + ns, [file, result]);
688
- } //update progress bar regarding the number of files uploaded
689
-
690
-
691
- options.$progressBar.progressbar('value', complete);
692
-
693
- if (complete >= 100) {
694
- if (errors.length === length) {
695
- options.$progressBar.addClass('error');
696
- } else if (errors.length > 0) {
697
- options.$progressBar.addClass('warning');
698
- } else {
699
- options.$progressBar.addClass('success');
700
- }
701
- /**
702
- * The upload sequence is complete
703
- * @event uploader#end.uploader
704
- */
705
-
706
-
707
- $elt.trigger('end.' + ns);
708
- }
709
- });
710
- }, 50);
711
- });
712
- }
713
- },
701
+ }, 50);
702
+ });
703
+ }
704
+ },
714
705
 
715
- /**
716
- * Read the selected file.
717
- *
718
- * TODO update files status and progress bar by file
719
- *
720
- * Called the jQuery way once registered by the Pluginifier:
721
- * @example $('selector').uploader('read');
722
- *
723
- * @param {jQueryElement} $elt - plugin's element
724
- * @fires uploader#readstart.uploader
725
- * @fires uploader#readend.uploader
726
- */
727
- _read: function ($elt) {
728
- var options = $elt.data(dataNs);
729
-
730
- if (options && options.files.length) {
731
- _.forEach(options.files, function (file) {
732
- // Let's read the file to get its base64 encoded content.
733
- var reader = new FileReader();
734
-
735
- reader.onload = function (e) {
736
- options.$progressBar.progressbar('value', 100);
737
- /**
738
- * The read is fininshed
739
- * @event uploader#readend.uploader
740
- * @param {Object} file - the reading file
741
- * @param {Object} result - the content
742
- */
743
-
744
- $elt.trigger('readend.' + ns, [file, e.target.result]);
745
- };
706
+ /**
707
+ * Read the selected file.
708
+ *
709
+ * TODO update files status and progress bar by file
710
+ *
711
+ * Called the jQuery way once registered by the Pluginifier:
712
+ * @example $('selector').uploader('read');
713
+ *
714
+ * @param {jQueryElement} $elt - plugin's element
715
+ * @fires uploader#readstart.uploader
716
+ * @fires uploader#readend.uploader
717
+ */
718
+ _read: function _read($elt) {
719
+ var options = $elt.data(dataNs);
746
720
 
747
- reader.onloadstart = function () {
748
- options.$progressBar.progressbar('value', 0);
749
- /**
750
- * The reading starts
751
- * @event uploader#readstart.uploader
752
- * @param {Object} file - the reading file
753
- */
721
+ if (options && options.files.length) {
722
+ _.forEach(options.files, function (file) {
723
+ // Let's read the file to get its base64 encoded content.
724
+ var reader = new FileReader();
754
725
 
755
- $elt.trigger('readstart.' + ns, [file]);
756
- };
726
+ reader.onload = function (e) {
727
+ options.$progressBar.progressbar('value', 100);
728
+ /**
729
+ * The read is fininshed
730
+ * @event uploader#readend.uploader
731
+ * @param {Object} file - the reading file
732
+ * @param {Object} result - the content
733
+ */
757
734
 
758
- if (options.$progressBar.length) {
759
- reader.onprogress = function (e) {
760
- var percentProgress = Math.ceil(Math.round(e.loaded) / Math.round(e.total) * 100);
761
- options.$progressBar.progressbar('value', percentProgress);
762
- };
763
- }
735
+ $elt.trigger('readend.' + ns, [file, e.target.result]);
736
+ };
764
737
 
765
- reader.readAsDataURL(file);
766
- });
767
- }
768
- },
738
+ reader.onloadstart = function () {
739
+ options.$progressBar.progressbar('value', 0);
740
+ /**
741
+ * The reading starts
742
+ * @event uploader#readstart.uploader
743
+ * @param {Object} file - the reading file
744
+ */
769
745
 
770
- /**
771
- * Destroy completely the plugin.
772
- *
773
- * Called the jQuery way once registered by the Pluginifier:
774
- * @example $('selector').uploader('destroy');
775
- *
776
- * @fires uploader#destroy.uploader
777
- */
778
- destroy: function () {
779
- this.each(function () {
780
- var $elt = $$1(this);
781
- $$1(document).off('drop.' + ns).off('dragover.' + ns);
782
- $elt.empty();
783
- /**
784
- * The plugin has been destroyed.
785
- * @event uploader#destroy.uploader
786
- */
746
+ $elt.trigger('readstart.' + ns, [file]);
747
+ };
748
+
749
+ if (options.$progressBar.length) {
750
+ reader.onprogress = function (e) {
751
+ var percentProgress = Math.ceil(Math.round(e.loaded) / Math.round(e.total) * 100);
752
+ options.$progressBar.progressbar('value', percentProgress);
753
+ };
754
+ }
787
755
 
788
- $elt.trigger('destroy.' + ns);
756
+ reader.readAsDataURL(file);
789
757
  });
790
758
  }
791
- }; //Register the incrementer to behave as a jQuery plugin.
759
+ },
792
760
 
793
- Pluginifier.register(ns, uploader, {
794
- expose: ['reset', 'selectFiles', 'upload', 'read']
795
- });
761
+ /**
762
+ * Destroy completely the plugin.
763
+ *
764
+ * Called the jQuery way once registered by the Pluginifier:
765
+ * @example $('selector').uploader('destroy');
766
+ *
767
+ * @fires uploader#destroy.uploader
768
+ */
769
+ destroy: function destroy() {
770
+ this.each(function () {
771
+ var $elt = $$1(this);
772
+ $$1(document).off('drop.' + ns).off('dragover.' + ns);
773
+ $elt.empty();
774
+ /**
775
+ * The plugin has been destroyed.
776
+ * @event uploader#destroy.uploader
777
+ */
778
+
779
+ $elt.trigger('destroy.' + ns);
780
+ });
781
+ }
782
+ }; //Register the incrementer to behave as a jQuery plugin.
783
+
784
+ Pluginifier.register(ns, uploader, {
785
+ expose: ['reset', 'selectFiles', 'upload', 'read']
786
+ });
796
787
 
797
788
  });