BxDolUploader.js 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  1. /**
  2. * Copyright (c) UNA, Inc - https://una.io
  3. * MIT License - https://opensource.org/licenses/MIT
  4. *
  5. * @defgroup UnaCore UNA Core
  6. * @{
  7. */
  8. /**
  9. * Simple Uploader js class
  10. */
  11. function BxDolUploaderBase (sUploaderObject, sStorageObject, sUniqId, options) {
  12. this.init(sUploaderObject, sStorageObject, sUniqId, options);
  13. this._sIframeId = 'bx-form-input-files-' + sUniqId + '-iframe';
  14. this._eForm = null;
  15. }
  16. BxDolUploaderBase.prototype.init = function (sUploaderObject, sStorageObject, sUniqId, options) {
  17. this._isUploadsInProgress = false;
  18. this._sUploaderObject = sUploaderObject;
  19. this._sStorageObject = sStorageObject;
  20. this._sUniqId = sUniqId;
  21. this._sUploaderJsInstance = 'glUploader_' + sUniqId + '_' + this._sUploaderObject;
  22. this._sUploadInProgressContainerId = 'bx-form-input-files-' + sUniqId + '-upload-in-progress-' + this._sUploaderObject;
  23. this._sPopupContainerId = 'bx-form-input-files-' + sUniqId + '-popup-wrapper-' + this._sUploaderObject;
  24. this._sResultContainerId = 'bx-form-input-files-' + sUniqId + '-upload-result';
  25. this._sErrorsContainerId = 'bx-form-input-files-' + sUniqId + '-errors';
  26. this._sProgressContainerId = 'bx-form-input-files-' + sUniqId + '-progress';
  27. this._sFormContainerId = 'bx-form-input-files-' + sUniqId + '-form-cont';
  28. this._sTemplateGhost = options.template_ghost ? options.template_ghost : '<div id="' + this._getFileContainerId('{file_id}') + '"><input type="hidden" name="f[]" value="{file_id}" />{file_name} (<a href="javascript:void(0);" onclick="{js_instance_name}.deleteGhost(\'{file_id}\')">delete</a>)</div>';
  29. this._sTemplateReorder = options.template_reorder ? options.template_reorder : '<div class="bx-uploader-ghost-reorder bx-btn bx-btn-small"><i class="sys-icon bars"></i></div>';
  30. this._sTemplateError = options.template_error_msg ? options.template_error_msg : '<div>{error}</div>' ;
  31. this._sTemplateErrorGhosts = options.template_error_ghosts ? options.template_error_ghosts : this._sTemplateError;
  32. this._isMultiple = undefined == options.multiple || !options.multiple ? false : true;
  33. this._isLatest = undefined == options.latest || !options.latest ? false : true;
  34. this._isReordering = undefined == options.reordering || !options.reordering ? false : true;
  35. this._iContentId = undefined == options.content_id || '' == options.content_id ? '' : parseInt(options.content_id);
  36. this._sImagesTranscoder = options.images_transcoder ? options.images_transcoder : '';
  37. this._isPrivate = undefined == options.storage_private || parseInt(options.storage_private) ? 1 : 0;
  38. this._isErrorShown = false;
  39. this._onUploadBefore = typeof options.on_upload_before === 'function' ? options.on_upload_before : function () {};
  40. this._onUpload = typeof options.on_upload === 'function' ? options.on_upload : function () {};
  41. this._onRestoreGhosts = typeof options.on_restore_ghosts === 'function' ? options.on_restore_ghosts : function () {};
  42. }
  43. BxDolUploaderBase.prototype.isMultiple = function () {
  44. return this._isMultiple;
  45. }
  46. BxDolUploaderBase.prototype.getCurrentFilesCount = function () {
  47. return $('#' + $this._sResultContainerId + ' .bx-uploader-ghost').length;
  48. }
  49. BxDolUploaderBase.prototype.showUploaderForm = function () {
  50. var $this = this;
  51. var sUrl = this._getUrlWithStandardParams() + '&a=show_uploader_form&m=' + (this._isMultiple ? 1 : 0) + '&c=' + this._iContentId + '&p=' + this._isPrivate + '&_t=' + escape(new Date());
  52. $(window).dolPopupAjax({
  53. url: sUrl,
  54. id: {force: true, value: this._sPopupContainerId},
  55. onBeforeShow: function() {
  56. if ($this.isMultiple())
  57. $('#' + $this._sPopupContainerId + ' .bx-uploader-add-more-files').show();
  58. else
  59. $('#' + $this._sPopupContainerId + ' .bx-uploader-add-more-files').hide();
  60. $('#' + $this._sPopupContainerId + ' .bx-popup-element-close').click(function() {
  61. $this.onClickCancel();
  62. });
  63. $("#" + $this._sFormContainerId + " .bx-btn.bx-btn-primary:not(.bx-crop-upload)").hide();
  64. if ('undefined' !== typeof($this.onBeforeShowPopup))
  65. $this.onBeforeShowPopup();
  66. },
  67. onShow: function () {
  68. if ('undefined' !== typeof($this.onShowPopup))
  69. $this.onShowPopup();
  70. },
  71. closeElement: false,
  72. closeOnOuterClick: false
  73. });
  74. }
  75. BxDolUploaderBase.prototype.onClickCancel = function () {
  76. var $this = this;
  77. if (this._isUploadsInProgress) {
  78. bx_confirm(_t('_sys_uploader_confirm_close_popup'), function() {
  79. $this.cancelAll();
  80. $('#' + $this._sPopupContainerId).dolPopupHide({});
  81. });
  82. } else {
  83. $('#' + this._sPopupContainerId).dolPopupHide();
  84. }
  85. }
  86. BxDolUploaderBase.prototype.onBeforeUpload = function (params) {
  87. this._eForm = params;
  88. this._loading(true, false);
  89. this._isUploadsInProgress = true;
  90. this._lockPageFromLeaving();
  91. this._clearErrors();
  92. if(typeof this._onUploadBefore === 'function')
  93. this._onUploadBefore(this);
  94. }
  95. BxDolUploaderBase.prototype.onProgress = function (params) {
  96. }
  97. BxDolUploaderBase.prototype.onUploadCompleted = function (sErrorMsg) {
  98. this._isUploadsInProgress = false;
  99. this._unlockPageFromLeaving();
  100. this._loading(false, true);
  101. if (sErrorMsg.length) {
  102. this.restoreGhosts();
  103. this._showError(sErrorMsg);
  104. } else {
  105. this.restoreGhosts();
  106. $('#' + this._sPopupContainerId).dolPopupHide({});
  107. if(typeof this._onUpload === 'function')
  108. this._onUpload(this, this._iContentId);
  109. }
  110. }
  111. BxDolUploaderBase.prototype.cancelAll = function () {
  112. $('#' + this._sIframeId).attr('src', 'javascript:false;');
  113. this.onUploadCompleted(_t('_sys_uploader_upload_canceled'));
  114. }
  115. BxDolUploaderBase.prototype.restoreGhosts = function (bInitReordering, onComplete) {
  116. var sUrl = this._getUrlWithStandardParams() + '&img_trans=' + this._sImagesTranscoder + '&a=restore_ghosts&f=json' + '&c=' + this._iContentId + '&m=' + (this._isMultiple ? 1 : 0) + '&l=' + (this._isLatest ? 1 : 0) + '&_t=' + escape(new Date());
  117. var $this = this;
  118. bInitReordering = bInitReordering !== undefined ? bInitReordering : this._isReordering;
  119. $.getJSON(sUrl, function (aData) {
  120. if (!$this.isMultiple())
  121. $('#' + $this._sResultContainerId + ' .bx-uploader-ghost').remove();
  122. if ('object' === typeof(aData)) {
  123. if('object' === typeof(aData.g) && 'object' === typeof(aData.o))
  124. for(var i in aData.o) {
  125. var iFileId = aData.o[i];
  126. $this.showGhost(iFileId, aData.g[iFileId]);
  127. }
  128. else
  129. $.each(aData, function(iFileId, oVars) {
  130. $this.showGhost(iFileId, oVars);
  131. });
  132. $('#' + $this._sResultContainerId).bx_show_more_check_overflow().bxProcessHtml();
  133. if(bInitReordering) {
  134. var sClassGhost = 'bx-uploader-ghost';
  135. $('#' + $this._sResultContainerId).find('.' + sClassGhost).each(function() {
  136. if($(this).find('.bx-uploader-ghost-reorder').length == 0)
  137. $(this).find('.bx-base-general-uploader-ghost').prepend($this._sTemplateReorder);
  138. });
  139. var fInitReordering = function() {
  140. $('#' + $this._sResultContainerId).sortable({
  141. items: '.' + sClassGhost,
  142. start: function(oEvent, oUi) {
  143. oUi.item.addClass('bx-uploader-ghost-dragging');
  144. },
  145. stop: function(oEvent, oUi) {
  146. oUi.item.removeClass('bx-uploader-ghost-dragging');
  147. $this.reorderGhosts(oUi.item);
  148. }
  149. });
  150. };
  151. if($.sortable !== undefined)
  152. fInitReordering();
  153. else
  154. setTimeout(fInitReordering, 2000);
  155. }
  156. }
  157. if(typeof onComplete === 'function')
  158. onComplete(aData);
  159. if(typeof this._onRestoreGhosts === 'function')
  160. this._onRestoreGhosts($this, aData);
  161. });
  162. };
  163. BxDolUploaderBase.prototype.reorderGhosts = function(oDraggable) {
  164. var sUrl = this._getUrlWithStandardParams() + '&a=reorder_ghosts&f=json' + '&c=' + this._iContentId + '&' + $('#' + this._sResultContainerId).sortable('serialize', {key: 'ghosts[]'}) + '&_t=' + escape(new Date());
  165. $.getJSON(sUrl, function (aData) {
  166. processJsonData(aData);
  167. });
  168. };
  169. BxDolUploaderBase.prototype.showGhost = function(iId, oVars) {
  170. var oFileContainer = $('#' + this._getFileContainerId(iId));
  171. if(oFileContainer.length > 0)
  172. return;
  173. var sHTML;
  174. if (typeof this._sTemplateGhost == 'object')
  175. sHTML = this._sTemplateGhost[iId];
  176. else
  177. sHTML = this._sTemplateGhost;
  178. for(var i in oVars)
  179. sHTML = sHTML.replace (new RegExp('{' + i + '}', 'g'), oVars[i]);
  180. $('#' + this._sResultContainerId).append(sHTML).trigger( "contentchange" );
  181. oFileContainer.find('.bx-uploader-ghost-preview img').hide().fadeIn(1000);
  182. };
  183. BxDolUploaderBase.prototype.deleteGhost = function (iFileId, onComplete) {
  184. var sUrl = this._getUrlWithStandardParams() + '&a=delete&id=' + iFileId;
  185. var $this = this;
  186. var sFileContainerId = $this._getFileContainerId(iFileId);
  187. bx_loading(sFileContainerId, true);
  188. $.post(sUrl, {_t: escape(new Date())}, function (sMsg) {
  189. var fOnComplete = function(sMsg) {
  190. if(typeof onComplete === 'function')
  191. onComplete(sMsg);
  192. };
  193. bx_loading(sFileContainerId, false);
  194. if ('ok' == sMsg) {
  195. $('#' + sFileContainerId).slideUp('slow', function () {
  196. $(this).remove();
  197. fOnComplete(sMsg);
  198. });
  199. } else {
  200. $('#' + this._sResultContainerId).prepend($this._sTemplateErrorGhosts.replace('{error}', sMsg));
  201. fOnComplete(sMsg);
  202. }
  203. });
  204. };
  205. BxDolUploaderBase.prototype._clearErrors = function () {
  206. $(' #' + this._sErrorsContainerId).html('');
  207. this._isErrorShown = false;
  208. }
  209. BxDolUploaderBase.prototype._showError = function (s, bAppend) {
  210. if (s == undefined || !s.length)
  211. return;
  212. var eCont = $('#' + this._sPopupContainerId).find('[id=' + this._sErrorsContainerId + ']').size() ? $('#' + this._sPopupContainerId).find('[id=' + this._sErrorsContainerId + ']') : $('#' + this._sErrorsContainerId);
  213. if (!bAppend)
  214. eCont.html(this._sTemplateError.replace('{error}', s));
  215. else
  216. eCont.prepend(this._sTemplateError.replace('{error}', s));
  217. this._isErrorShown = true;
  218. };
  219. BxDolUploaderBase.prototype._getFileContainerId = function (iFileId) {
  220. return 'bx-uploader-file-' + this._sStorageObject + '-' + iFileId;
  221. };
  222. BxDolUploaderBase.prototype._getUrlWithStandardParams = function () {
  223. return sUrlRoot + 'storage_uploader.php?uo=' + this._sUploaderObject + '&so=' + this._sStorageObject + '&uid=' + this._sUniqId;
  224. }
  225. BxDolUploaderBase.prototype._lockPageFromLeaving = function () {
  226. $(window).bind('beforeunload', function (e) {
  227. var e = e || window.event;
  228. // for ie, ff
  229. e.returnValue = _t('_sys_uploader_confirm_leaving_page');
  230. // for webkit
  231. return _t('_sys_uploader_confirm_leaving_page');
  232. });
  233. }
  234. BxDolUploaderBase.prototype._unlockPageFromLeaving = function () {
  235. $(window).unbind('beforeunload');
  236. }
  237. BxDolUploaderBase.prototype._loading = function (bShowProgress, bShowForm) {
  238. var eForm = $('#' + this._sFormContainerId + ' .bx-uploader-files-list');
  239. var eBtn = $('#' + this._sFormContainerId + ' .bx-btn-primary');
  240. if (bShowForm) {
  241. if (null != this._eForm) {
  242. eForm.find('.bx-uploader-simple-file').filter(':not(:first)').remove();
  243. if ('undefined' !== typeof(this._eForm.reset))
  244. this._eForm.reset();
  245. }
  246. eForm.show();
  247. eBtn.show();
  248. } else {
  249. eForm.hide();
  250. eBtn.hide();
  251. }
  252. bx_loading($('#' + this._sFormContainerId + ' .bx-uploader-loading').get(0), bShowProgress);
  253. }
  254. BxDolUploaderBase.prototype.getMimeTypefromString = function (ext) {
  255. var mimeTypes =
  256. {
  257. '3gp' : 'video/3gpp',
  258. '3g2' : 'video/3gpp2',
  259. 'a' : 'application/octet-stream',
  260. 'ai' : 'application/postscript',
  261. 'aif' : 'audio/x-aiff',
  262. 'aifc' : 'audio/x-aiff',
  263. 'aiff' : 'audio/x-aiff',
  264. 'asf' : 'video/x-ms-asf',
  265. 'au' : 'audio/basic',
  266. 'avi' : 'video/x-msvideo',
  267. 'avi' : 'video/avi',
  268. 'bat' : 'text/plain',
  269. 'bin' : 'application/octet-stream',
  270. 'bmp' : 'image/x-ms-bmp',
  271. 'c' : 'text/plain',
  272. 'cdf' : 'application/x-cdf',
  273. 'csh' : 'application/x-csh',
  274. 'css' : 'text/css',
  275. 'divx' : 'video/divx',
  276. 'dll' : 'application/octet-stream',
  277. 'doc' : 'application/msword',
  278. 'dot' : 'application/msword',
  279. 'drc' : 'video/drc',
  280. 'dvi' : 'application/x-dvi',
  281. 'eml' : 'message/rfc822',
  282. 'eps' : 'application/postscript',
  283. 'etx' : 'text/x-setext',
  284. 'exe' : 'application/octet-stream',
  285. 'gif' : 'image/gif',
  286. 'gtar' : 'application/x-gtar',
  287. 'h' : 'text/plain',
  288. 'hdf' : 'application/x-hdf',
  289. 'htm' : 'text/html',
  290. 'html' : 'text/html',
  291. 'jpe' : 'image/jpeg',
  292. 'jpeg' : 'image/jpeg',
  293. 'jpg' : 'image/jpeg',
  294. 'js' : 'application/x-javascript',
  295. 'ksh' : 'text/plain',
  296. 'latex' : 'application/x-latex',
  297. 'm1v' : 'video/mpeg',
  298. 'man' : 'application/x-troff-man',
  299. 'me' : 'application/x-troff-me',
  300. 'mht' : 'message/rfc822',
  301. 'mhtml' : 'message/rfc822',
  302. 'mkv' : 'video/x-matroska',
  303. 'mif' : 'application/x-mif',
  304. 'mov' : 'video/quicktime',
  305. 'movie' : 'video/x-sgi-movie',
  306. 'mp2' : 'audio/mpeg',
  307. 'mp3' : 'audio/mpeg',
  308. 'm4a' : ['audio/mp4', 'audio/x-m4a'],
  309. 'mp4' : 'video/mp4',
  310. 'm4v' : 'video/mp4',
  311. 'mpa' : 'video/mpeg',
  312. 'mpe' : 'video/mpeg',
  313. 'mpeg' : 'video/mpeg',
  314. 'mpg' : 'video/mpeg',
  315. 'ms' : 'application/x-troff-ms',
  316. 'nc' : 'application/x-netcdf',
  317. 'nws' : 'message/rfc822',
  318. 'o' : 'application/octet-stream',
  319. 'obj' : 'application/octet-stream',
  320. 'oda' : 'application/oda',
  321. 'ogv' : 'video/ogg',
  322. 'ogg' : 'video/ogg',
  323. 'pbm' : 'image/x-portable-bitmap',
  324. 'pdf' : 'application/pdf',
  325. 'pfx' : 'application/x-pkcs12',
  326. 'pgm' : 'image/x-portable-graymap',
  327. 'png' : 'image/png',
  328. 'pnm' : 'image/x-portable-anymap',
  329. 'pot' : 'application/vnd.ms-powerpoint',
  330. 'ppa' : 'application/vnd.ms-powerpoint',
  331. 'ppm' : 'image/x-portable-pixmap',
  332. 'pps' : 'application/vnd.ms-powerpoint',
  333. 'ppt' : 'application/vnd.ms-powerpoint',
  334. 'pptx' : 'application/vnd.ms-powerpoint',
  335. 'ps' : 'application/postscript',
  336. 'pwz' : 'application/vnd.ms-powerpoint',
  337. 'py' : 'text/x-python',
  338. 'pyc' : 'application/x-python-code',
  339. 'pyo' : 'application/x-python-code',
  340. 'qt' : 'video/quicktime',
  341. 'ra' : 'audio/x-pn-realaudio',
  342. 'ram' : 'application/x-pn-realaudio',
  343. 'ras' : 'image/x-cmu-raster',
  344. 'rdf' : 'application/xml',
  345. 'rgb' : 'image/x-rgb',
  346. 'rm' : 'application/vnd.rn-realmedia',
  347. 'rmvb' : 'application/vnd.rn-realmedia-vbr',
  348. 'roff' : 'application/x-troff',
  349. 'rtx' : 'text/richtext',
  350. 'sgm' : 'text/x-sgml',
  351. 'sgml' : 'text/x-sgml',
  352. 'sh' : 'application/x-sh',
  353. 'shar' : 'application/x-shar',
  354. 'snd' : 'audio/basic',
  355. 'so' : 'application/octet-stream',
  356. 'src' : 'application/x-wais-source',
  357. 'swf' : 'application/x-shockwave-flash',
  358. 't' : 'application/x-troff',
  359. 'tar' : 'application/x-tar',
  360. 'tcl' : 'application/x-tcl',
  361. 'tex' : 'application/x-tex',
  362. 'texi' : 'application/x-texinfo',
  363. 'texinfo': 'application/x-texinfo',
  364. 'tif' : 'image/tiff',
  365. 'tiff' : 'image/tiff',
  366. 'tr' : 'application/x-troff',
  367. 'tsv' : 'text/tab-separated-values',
  368. 'txt' : 'text/plain',
  369. 'ustar' : 'application/x-ustar',
  370. 'vcf' : 'text/x-vcard',
  371. 'wav' : 'audio/x-wav',
  372. 'wav' : 'audio/wav',
  373. 'webm' : 'video/webm',
  374. 'wmv' : 'video/wmv',
  375. 'wiz' : 'application/msword',
  376. 'wsdl' : 'application/xml',
  377. 'xbm' : 'image/x-xbitmap',
  378. 'xlb' : 'application/vnd.ms-excel',
  379. 'xls' : 'application/vnd.ms-excel',
  380. 'xlsx' : 'application/vnd.ms-excel',
  381. 'xml' : 'text/xml',
  382. 'xpdl' : 'application/xml',
  383. 'xpm' : 'image/x-xpixmap',
  384. 'xsl' : 'application/xml',
  385. 'xvid' : 'video/xvid',
  386. 'webp' : 'image/webp',
  387. 'xwd' : 'image/x-xwindowdump',
  388. 'svg' : 'image/svg+xml',
  389. 'zip' : ['application/zip', 'application/x-zip-compressed']
  390. }
  391. return mimeTypes[ext.replace('.', '')];
  392. }
  393. /**
  394. * HTML5 Uploader js class
  395. */
  396. function BxDolUploaderHTML5 (sUploaderObject, sStorageObject, sUniqId, options) {
  397. this.init(sUploaderObject, sStorageObject, sUniqId, options);
  398. this._sIframeId = 'bx-form-input-files-' + sUniqId + '-iframe';
  399. this._eForm = null;
  400. this._sDivId = 'bx-form-input-files-' + sUniqId + '-div-' + this._sUploaderObject;
  401. this._sFocusDivId = 'bx-form-input-files-' + sUniqId + '-focus-' + this._sUploaderObject;
  402. this._uploader = null;
  403. this._aFiles = [];
  404. this.initUploader = function (o) {
  405. var $this = this;
  406. if (null != this._uploader)
  407. this._uploader = null;
  408. var $this = this;
  409. var _options = {
  410. allowProcess: false,
  411. allowPaste: false,
  412. allowRevert: false,
  413. allowRemove: false,
  414. imagePreviewHeight: 100,
  415. credits: {},
  416. allowMultiple: $this._isMultiple ? true : false,
  417. maxFiles: $this.isMultiple() ? 50 : 1,
  418. maxFileSize: o.maxFilesize > 2 ? Math.round(o.maxFilesize) + 'MB' : Math.round(o.maxFilesize*1024) + 'KB',
  419. instantUpload: true,
  420. onaddfile: (error, file) => {
  421. if (error){
  422. $this._uploader.removeFile(file);
  423. if($this._uploader.status != 3)
  424. $this.onUploadCompleted('');
  425. }
  426. else{
  427. $this.onBeforeUpload('');
  428. }
  429. },
  430. onerror: (error) => {
  431. if (error.main)
  432. $this._showError(error.main + '. ' + error.sub);
  433. },
  434. onprocessfiles: (files) => {
  435. $this.onUploadCompleted('');
  436. oProgress.hide();
  437. $this._aFiles = [];
  438. },
  439. onprocessfileprogress(file, progress) {
  440. $this._aFiles[file.source.lastModified+'-'+file.source.size+'-'+file.source.name] = progress * file.source.size;
  441. iTotal = 0;
  442. iUploaded = 0;
  443. for (const propertyName in $this._aFiles) {
  444. iUploaded += $this._aFiles[propertyName];
  445. }
  446. for (i = 0; i < $this._uploader.getFiles().length; i++){
  447. iTotal += $this._uploader.getFiles()[i].source.size;
  448. }
  449. iProgress = iUploaded / iTotal * 100;
  450. oProgress = $('#' + $this._sProgressContainerId);
  451. if (oProgress.parents('.bx-db-container').find('.uploader_progress').length > 0){
  452. oProgress = oProgress.parents('.bx-db-container').find('.uploader_progress');
  453. }
  454. oProgress.show();
  455. oProgress.find('.progress_line').css('width', iProgress + '%');
  456. },
  457. server: {
  458. process: (fieldName, file, metadata, load, error, progress, abort) => {
  459. const formData = new FormData();
  460. formData.append('file', file, file.name);
  461. formData.append('uo', this._sUploaderObject);
  462. formData.append('so', this._sStorageObject);
  463. formData.append('uid', this._sUniqId);
  464. formData.append('m', this._isMultiple ? 1 : 0);
  465. formData.append('c', this._iContentId);
  466. formData.append('p', this._isPrivate);
  467. formData.append('a', 'upload');
  468. const request = new XMLHttpRequest();
  469. request.open('POST', sUrlRoot + 'storage_uploader.php');
  470. request.upload.onprogress = (e) => {
  471. progress(e.lengthComputable, e.loaded, e.total);
  472. };
  473. request.onload = function(res) {
  474. if (request.status >= 200 && request.status < 300) {
  475. var o = null;
  476. try {
  477. o = JSON.parse(request.responseText);
  478. }
  479. catch (e) {}
  480. if (o && 'undefined' !== typeof(o.error)) {
  481. $this._showError(o.error, true);
  482. }
  483. load(request.responseText);
  484. }
  485. else {
  486. error('error');
  487. }
  488. };
  489. request.send(formData);
  490. }
  491. },
  492. };
  493. aAcceptableFiles = [];
  494. if (o.acceptedFiles && o.acceptedFiles != ''){
  495. a = o.acceptedFiles.trim().split(/\s*,\s*/);
  496. a.forEach(function(item, i, arr) {
  497. if ($this.getMimeTypefromString(item)){
  498. oT = $this.getMimeTypefromString(item);
  499. if (Array.isArray(oT)){
  500. oT.forEach(function(oTs, j, ar) {
  501. aAcceptableFiles.push(oTs);
  502. });
  503. }
  504. else{
  505. aAcceptableFiles.push(oT);
  506. }
  507. }
  508. });
  509. }
  510. if (aAcceptableFiles.length){
  511. _options.acceptedFileTypes = aAcceptableFiles;
  512. }
  513. if (o.resizeWidth || o.resizeHeight){
  514. _options.allowImageResize = true;
  515. _options.imageResizeTargetWidth = o.resizeWidth;
  516. _options.imageResizeTargetHeight = o.resizeHeight;
  517. _options.imageResizeMode = o.resizeMethod;
  518. }
  519. else{
  520. _options.allowImageResize = false;
  521. _options.allowImageTransform = false;
  522. }
  523. FilePond.registerPlugin(
  524. FilePondPluginImagePreview,
  525. FilePondPluginFileValidateType,
  526. FilePondPluginFileValidateSize,
  527. FilePondPluginImageTransform,
  528. FilePondPluginImageCrop,
  529. FilePondPluginImageResize,
  530. );
  531. this._uploader = FilePond.create(
  532. document.querySelector('#' + this._sDivId),
  533. $.extend({}, _options, o)
  534. );
  535. if (typeof(glFilepondLocale) !== 'undefined');
  536. this._uploader.setOptions(glFilepondLocale);
  537. // need to be activated if catch paste needed
  538. //this.initPasteEditor();
  539. }
  540. this.onUploadCompleted = function (sErrorMsg) {
  541. if (sErrorMsg.length)
  542. this._showError(sErrorMsg);
  543. var $this = this;
  544. if($this._uploader.status != 3) {
  545. this._isUploadsInProgress = false;
  546. this.restoreGhosts();
  547. if(!this._isErrorShown) {
  548. $('#' + this._sPopupContainerId).dolPopupHide({});
  549. this.removeFiles();
  550. }
  551. if(typeof this._onUpload === 'function')
  552. this._onUpload(this, this._iContentId);
  553. }
  554. }
  555. this.removeFiles = function () {
  556. oFiles = this._uploader.getFiles();
  557. for (i = 0; i < oFiles.length; i++){
  558. this._uploader.removeFile(i);
  559. }
  560. }
  561. this.cancelAll = function () {
  562. this.removeFiles();
  563. }
  564. this.onBeforeUpload = function (params) {
  565. this._isUploadsInProgress = true;
  566. this._clearErrors();
  567. if(typeof this._onUploadBefore === 'function')
  568. this._onUploadBefore(this);
  569. }
  570. this.onProgress = function (params) {
  571. }
  572. this.onClickCancel = function () {
  573. var $this = this;
  574. if (this._isUploadsInProgress) {
  575. bx_confirm(_t('_sys_uploader_confirm_close_popup'), function() {
  576. $this.removeFiles();
  577. $this.cancelAll();
  578. $('#' + $this._sPopupContainerId).dolPopupHide({});
  579. });
  580. } else {
  581. $this.removeFiles();
  582. $('#' + this._sPopupContainerId).dolPopupHide();
  583. }
  584. BxDolUploaderBase.prototype._clearErrors.call(this);
  585. }
  586. this.onShowPopup = function () {
  587. var $this = this;
  588. setTimeout(function () {
  589. $this.focusPasteEditor();
  590. }, 200);
  591. }
  592. this.focusPasteEditor = function () {
  593. $('#' + this._sFocusDivId).focus();
  594. }
  595. this.initPasteEditor = function () {
  596. var $this = this;
  597. $('#' + this._sFocusDivId).on('paste', function (e) {
  598. var aFiles = [];
  599. if (e.type == 'paste') {
  600. var aItems = (e.clipboardData || e.originalEvent.clipboardData).items;
  601. for (var i in aItems) {
  602. var oItem = aItems[i];
  603. if (oItem.kind === 'file')
  604. aFiles.push(oItem.getAsFile());
  605. }
  606. $this._uploader.addFiles(aFiles);
  607. }
  608. });
  609. }
  610. this.showUploaderForm = function() {
  611. this._uploader.browse();
  612. }
  613. this.initUploader({
  614. 'maxFilesize': options.maxFilesize,
  615. 'acceptedFiles': options.acceptedFiles,
  616. 'resizeWidth': options.resizeWidth,
  617. 'resizeHeight': options.resizeHeight,
  618. 'resizeMethod': options.resizeMethod,
  619. 'dictDefaultMessage': options.dictDefaultMessage,
  620. 'dictFileTooBig': options.dictFileTooBig,
  621. 'dictMaxFilesExceeded': options.dictMaxFilesExceeded,
  622. 'dictInvalidFileType': options.dictInvalidFileType,
  623. });
  624. }
  625. BxDolUploaderHTML5.prototype = BxDolUploaderBase.prototype;
  626. function BxDolUploaderSimple(sUploaderObject, sStorageObject, sUniqId, options)
  627. {
  628. BxDolUploaderHTML5.call(this, sUploaderObject, sStorageObject, sUniqId, options);
  629. }
  630. BxDolUploaderSimple.prototype = Object.create(BxDolUploaderHTML5.prototype);
  631. BxDolUploaderSimple.prototype.constructor = BxDolUploaderSimple;
  632. /**
  633. * Crop Image Uploader js class
  634. */
  635. function BxDolUploaderCrop (sUploaderObject, sStorageObject, sUniqId, options) {
  636. this.init(sUploaderObject, sStorageObject, sUniqId, options);
  637. this._eForm = null;
  638. this.initUploader = function (oOptions) {
  639. var $this = this;
  640. var aExt = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
  641. var eCroppie = $("#" + this._sFormContainerId + " .bx-croppie-element").croppie(oOptions);
  642. $("#" + this._sFormContainerId + ' .bx-crop-rotate').on('click', function(ev) {
  643. eCroppie.croppie('rotate', parseInt($(this).data('deg')));
  644. });
  645. $("#" + this._sFormContainerId + " input[name=f]").on("change", function() {
  646. var input = this;
  647. if (input.files && input.files[0]) {
  648. var m = input.files[0].name.match(/\.([A-Za-z0-9]+)$/);
  649. if (2 != m.length || -1 == aExt.indexOf(m[1].toLowerCase())) {
  650. $(input).replaceWith($(input).val('').clone(true));
  651. $this._showError(_t('_sys_uploader_crop_wrong_ext'));
  652. return;
  653. }
  654. $this._clearErrors();
  655. var reader = new FileReader()
  656. reader.onload = function(e) {
  657. eCroppie.croppie('bind', {
  658. url: e.target.result
  659. });
  660. $("#" + $this._sFormContainerId + " .bx-croppie-element").addClass('ready');
  661. $("#" + $this._sFormContainerId + " .bx-crop-action").removeClass('bx-btn-disabled');
  662. $("#" + $this._sFormContainerId + " .bx-croppie-element").data('bx-filename', input.files[0].name.replace(/(\.[A-Za-z0-9]+)$/, '.jpg'));
  663. }
  664. reader.readAsDataURL(input.files[0]);
  665. }
  666. });
  667. $("#" + this._sFormContainerId + " .bx-crop-upload").on('click', function(ev) {
  668. eCroppie.croppie('result', {
  669. type: 'canvas',
  670. size: 'original',
  671. format: 'jpeg',
  672. quality: '0.85',
  673. }).then(function(resp) {
  674. var fd = new FormData();
  675. fd.append("f", dataURItoBlob(resp), $("#" + $this._sFormContainerId + " .bx-croppie-element").data('bx-filename'));
  676. $.each(oOptions.bx_form, function (sName) {
  677. fd.append(sName, this);
  678. });
  679. $this.onBeforeUpload(fd);
  680. $.ajax({
  681. url: sUrlRoot + 'storage_uploader.php',
  682. type: "POST",
  683. processData: false,
  684. contentType: false,
  685. data: fd,
  686. success: function(data) {
  687. eval(data);
  688. },
  689. error: function() {
  690. $this._showError(_t('_sys_uploader_crop_err_upload'));
  691. }
  692. })
  693. });
  694. });
  695. function dataURItoBlob(dataURI) {
  696. var split = dataURI.split(','),
  697. dataTYPE = split[0].match(/:(.*?);/)[1],
  698. binary = atob(split[1]),
  699. array = [];
  700. for (var i = 0; i < binary.length; i++)
  701. array.push(binary.charCodeAt(i));
  702. return new Blob([new Uint8Array(array)], {
  703. type: dataTYPE
  704. });
  705. }
  706. };
  707. }
  708. BxDolUploaderCrop.prototype = BxDolUploaderBase.prototype;
  709. /**
  710. * Record Video Uploader js class
  711. */
  712. function BxDolUploaderRecordVideo (sUploaderObject, sStorageObject, sUniqId, options) {
  713. this._camera = null;
  714. this._blob = null;
  715. this._recorder = null;
  716. this._camera_type = 'user';
  717. this._audio_bitrate = undefined !== options.audio_bitrate ? parseInt(options.audio_bitrate) : 128000;
  718. this._video_bitrate = undefined !== options.video_bitrate ? parseInt(options.video_bitrate) : 1000000;
  719. this.init(sUploaderObject, sStorageObject, sUniqId, options);
  720. this.showUploaderForm = function() {
  721. if (typeof MediaRecorder == 'undefined' || !('requestData' in MediaRecorder.prototype)) {
  722. bx_alert(_t('_sys_uploader_unsupported_browser'));
  723. return;
  724. }
  725. BxDolUploaderBase.prototype.showUploaderForm.call(this);
  726. }
  727. this.onBeforeShowPopup = function() {
  728. this._blob = null;
  729. this._camera = null;
  730. this._recorder = null
  731. this._clearErrors();
  732. $('#bx-upoloader-recording-preview').hide();
  733. $('#bx-upoloader-camera-capture').show();
  734. $('#' + this._sFormContainerId + ' .bx-uploader-record-video-controls').hide();
  735. }
  736. this.switchCamera = function () {
  737. this._camera_type = this._camera_type == 'user' ? 'environment' : 'user';
  738. this.releaseCamera();
  739. this.onShowPopup();
  740. }
  741. this.onShowPopup = function () {
  742. var $this = this;
  743. try {
  744. navigator.mediaDevices.getUserMedia({ audio: true, video: {facingMode: this._camera_type} }).then(function(camera) {
  745. $this._camera = camera;
  746. $this.showCameraCapture();
  747. $('#' + $this._sFormContainerId + ' .bx-uploader-recording-start').show();
  748. $('#' + $this._sFormContainerId + ' .bx-uploader-recording-stop').hide();
  749. $('#' + $this._sFormContainerId + ' .bx-uploader-record-video-controls').show();
  750. navigator.mediaDevices.enumerateDevices().then(function(mediaDevices){
  751. let constraints = navigator.mediaDevices.getSupportedConstraints();
  752. if ($this.getDevicesNum(mediaDevices) > 1 && typeof constraints.facingMode != 'undefined' && constraints.facingMode) {
  753. $('#' + $this._sFormContainerId + ' .bx-record-camera-switch').show();
  754. } else {
  755. $('#' + $this._sFormContainerId + ' .bx-record-camera-switch').hide();
  756. }
  757. });
  758. })
  759. } catch (err) {
  760. $this._showError(_t('_sys_uploader_camera_capture_failed'));
  761. }
  762. }
  763. this.onClickCancel = function () {
  764. this.releaseCamera();
  765. BxDolUploaderBase.prototype.onClickCancel.call(this);
  766. }
  767. this.startRecording = function() {
  768. this._recorder = RecordRTC(this._camera, {
  769. type: 'video',
  770. audioBitsPerSecond: this._audio_bitrate,
  771. videoBitsPerSecond: this._video_bitrate,
  772. disableLogs: true
  773. });
  774. if (!this._recorder) {
  775. this._showError(_t('_sys_uploader_unsupported_browser'));
  776. return;
  777. }
  778. $("#" + this._sFormContainerId + " .bx-btn.bx-btn-primary:not(.bx-crop-upload)").hide();
  779. $('#' + this._sFormContainerId + ' .bx-uploader-recording-start').hide();
  780. $('#' + this._sFormContainerId + ' .bx-uploader-recording-stop').show();
  781. this._recorder.startRecording();
  782. this.showCameraCapture();
  783. }
  784. this.stopRecording = function(bSubmitWhenReady) {
  785. $('#' + this._sFormContainerId + ' .bx-uploader-recording-start').show();
  786. $('#' + this._sFormContainerId + ' .bx-uploader-recording-stop').hide();
  787. var $this = this;
  788. this._recorder.stopRecording(function(){
  789. $this._blob = $this._recorder.getBlob();
  790. $this.showRecordingPreview();
  791. $this._recorder.destroy();
  792. $this._recorder = null;
  793. $("#" + $this._sFormContainerId + " .bx-btn.bx-btn-primary:not(.bx-crop-upload)").show();
  794. if (bSubmitWhenReady)
  795. $this.submitRecording($('#' + $this._sFormContainerId + ' form').get(0));
  796. });
  797. }
  798. this.showCameraCapture = function() {
  799. var video = $('#bx-upoloader-recording-preview').hide().get(0);
  800. if (video.pause !== 'undefined') video.pause();
  801. video.removeAttribute('src');
  802. video = $('#bx-upoloader-camera-capture').show().get(0);
  803. video.srcObject = this._camera;
  804. video.muted = true;
  805. video.volume = 0;
  806. $('#' + this._sFormContainerId + ' .bx-record-video-preview .bx-record-video-preview-filesize').html('');
  807. }
  808. this.showRecordingPreview = function() {
  809. $('#bx-upoloader-camera-capture').hide();
  810. $('#bx-upoloader-recording-preview').show().get(0).src = URL.createObjectURL(this._blob);
  811. var mbytes = (this._blob.size/1024/1024).toFixed(2);
  812. $('#' + this._sFormContainerId + ' .bx-record-video-preview .bx-record-video-preview-filesize').html(mbytes + ' ' + _t('_sys_uploader_record_video_mb'));
  813. }
  814. this.submitRecording = function(form) {
  815. if (this._recorder) {
  816. this.stopRecording(true);
  817. return;
  818. }
  819. this.onBeforeUpload(form);
  820. var data = new FormData(form);
  821. if (this._blob != null) data.append("f[]", this._blob, new Date().toISOString() + '.webm');
  822. var $this = this;
  823. $.ajax({
  824. url: $(form).attr('action'),
  825. type: "POST",
  826. data: data,
  827. processData: false,
  828. contentType: false,
  829. success:function(sErrorMsg, textStatus, jqXHR) {
  830. $this.onUploadCompleted(sErrorMsg);
  831. if (!sErrorMsg.length) {
  832. $this.releaseCamera();
  833. }
  834. },
  835. });
  836. }
  837. this.releaseCamera = function() {
  838. //stop playing recorded file
  839. var video = $('#bx-upoloader-recording-preview').get(0);
  840. if (video.pause != 'undefined') video.pause();
  841. video.removeAttribute('src');
  842. if (this._recorder) {
  843. this._recorder.destroy();
  844. this._recorder = null;
  845. }
  846. if (this._camera) {
  847. if (typeof this._camera.stop != 'undefined') this._camera.stop();
  848. this._camera.getTracks().forEach(function (track) {
  849. if (track.readyState == 'live') {
  850. track.stop();
  851. }
  852. });
  853. }
  854. }
  855. this.getDevicesNum = function(mediaDevices) {
  856. let count = 0;
  857. mediaDevices.forEach(mediaDevice => {
  858. if (mediaDevice.kind === 'videoinput') count++;
  859. });
  860. return count;
  861. }
  862. }
  863. BxDolUploaderRecordVideo.prototype = BxDolUploaderBase.prototype;
  864. function BxDolImageTweak (unique_id, action_url, content_id, field, js_object, allow_tweak) {
  865. var $this = this;
  866. this._sUniqueId = unique_id;
  867. this._sActionUrl = action_url;
  868. this._sContentId = content_id;
  869. this._sField = field;
  870. this._sJsObject = js_object;
  871. this._bAllowTweak = allow_tweak;
  872. this._oContainerButtons = $('.bx-image-edit-buttons-' + unique_id);
  873. this._oContainerButtons.removeClass('hidden');
  874. $("#bx-form-input-files-" + this._sUniqueId + "-upload-result").bind( "contentchange", function(){
  875. $this.uploadComplete($(this));
  876. });
  877. if (this._bAllowTweak){
  878. this._oContainerButtons.find('.bx-image-edit-buttons-edit').removeClass('hidden');
  879. }
  880. }
  881. BxDolImageTweak.prototype.showUploaderForm = function(){
  882. var $this = this;
  883. $('#bx-form-input-files-' + $this._sUniqueId + '-upload-result').html('');
  884. eval($this._sJsObject + '.showUploaderForm()');
  885. }
  886. BxDolImageTweak.prototype.uploadComplete = function(obj){
  887. var $this = this;
  888. var sUrl = $this._sActionUrl + "updateImage/" + $this._sField + "/" + $this._sContentId + "/" + obj.html() + "/";
  889. $this._oContainerButtons.removeClass('bx-image-edit-buttons-no-image');
  890. $.post(sUrl, function (aData) {
  891. var sSelImage = ".bx-image-edit-source-" + $this._sUniqueId;
  892. var sSelPlaceholder = ".bx-image-edit-placeholder-" + $this._sUniqueId;
  893. if ($this._bAllowTweak){
  894. $(sSelImage).css("background-image", "url(" + aData + ")").css('background-position', '').show();
  895. if($(sSelPlaceholder).length > 0)
  896. $(sSelPlaceholder).hide();
  897. else
  898. $(sSelImage).parents('.bx-base-pofile-cover-image.bx-bpci-holder').removeClass('bx-bpci-holder h-32 lg:h-32').addClass('h-64 lg:h-80')
  899. }
  900. else{
  901. $(sSelImage).attr("src", aData).show();
  902. if($(sSelPlaceholder).length > 0)
  903. $(sSelPlaceholder).hide();
  904. else
  905. $(sSelImage).parents('.bx-base-pofile-cover-thumb').find('p.bx-base-pofile-unit-thumb').hide();
  906. }
  907. });
  908. }
  909. BxDolImageTweak.prototype.changePosition = function (){
  910. var $this = this;
  911. $(".bx-image-edit-source-" + $this._sUniqueId).parent().append("<div class='bx-image-edit-move-info'><i class='sys-icon sys-colored arrows-alt '></i>" + _t('_sys_uploader_image_reposition_info') + "</div>");
  912. $(".bx-image-edit-source-" + $this._sUniqueId).addClass('bx-image-edit-move').bind('dragover', function(e){
  913. $(".bx-image-edit-source-" + $this._sUniqueId).parent().find('.bx-image-edit-move-info').remove();
  914. $(".bx-image-edit-source-" + $this._sUniqueId).css('background-position', " 0px " + e.offsetY / $(e.currentTarget).height() * 100 + '%');
  915. });
  916. if (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0)) {
  917. $('body').css('overflow', 'hidden')
  918. $(".bx-image-edit-source-" + $this._sUniqueId).bind('touchmove', function(e){
  919. var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
  920. $(".bx-image-edit-source-" + $this._sUniqueId).parent().find('.bx-image-edit-move-info').remove();
  921. $(".bx-image-edit-source-" + $this._sUniqueId).css('background-position', " 0px " + touch.pageY / $(e.currentTarget).height() * 100 + '%');
  922. });
  923. }
  924. with ($this._oContainerButtons) {
  925. find('.bx-image-edit-buttons-cancel').removeClass('hidden');
  926. find('.bx-image-edit-buttons-save').removeClass('hidden');
  927. find('.bx-image-edit-buttons-edit').addClass('hidden');
  928. find('.bx-image-edit-buttons-upload').addClass('hidden');
  929. }
  930. }
  931. BxDolImageTweak.prototype.cancelPosition = function (){
  932. var $this = this;
  933. $('body').css('overflow', '')
  934. $(".bx-image-edit-source-" + $this._sUniqueId).parent().find('.bx-image-edit-move-info').remove();
  935. $(".bx-image-edit-source-" + $this._sUniqueId).addClass('bx-image-edit-move').unbind('dragover').unbind('touchmove');
  936. with ($this._oContainerButtons) {
  937. find('.bx-image-edit-buttons-cancel').addClass('hidden');
  938. find('.bx-image-edit-buttons-save').addClass('hidden');
  939. find('.bx-image-edit-buttons-edit').removeClass('hidden');
  940. find('.bx-image-edit-buttons-upload').removeClass('hidden');
  941. }
  942. }
  943. BxDolImageTweak.prototype.savePosition = function (){
  944. var $this = this;
  945. $('body').css('overflow', '')
  946. $(".bx-image-edit-source-" + $this._sUniqueId).parent().find('.bx-image-edit-move-info').remove();
  947. $(".bx-image-edit-source-" + $this._sUniqueId).addClass('bx-image-edit-move').unbind('dragover').unbind('touchmove');
  948. $(".bx-image-edit-source-" + $this._sUniqueId).removeClass('bx-image-edit-move')
  949. aPos = $(".bx-image-edit-source-" + $this._sUniqueId).css('background-position').split(' ');
  950. $.post($this._sActionUrl + 'updateImagePosition/' + $this._sContentId + '/' + $this._sField + '/' + aPos[0].replace('%','').replace('px','') + '/' + aPos[1].replace('%','').replace('px','') + '/', function () {
  951. with ($this._oContainerButtons) {
  952. find('.bx-image-edit-buttons-cancel').addClass('hidden');
  953. find('.bx-image-edit-buttons-save').addClass('hidden');
  954. find('.bx-image-edit-buttons-edit').removeClass('hidden');
  955. find('.bx-image-edit-buttons-upload').removeClass('hidden');
  956. }
  957. });
  958. }
  959. /** @} */