PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/js/mage/adminhtml/flexuploader.js

https://bitbucket.org/sevenly/magento-ce
JavaScript | 372 lines | 326 code | 15 blank | 31 comment | 63 complexity | 323a7703f4e513f129f32e7128ee95f8 MD5 | raw file
  1. /**
  2. * Magento
  3. *
  4. * NOTICE OF LICENSE
  5. *
  6. * This source file is subject to the Academic Free License (AFL 3.0)
  7. * that is bundled with this package in the file LICENSE_AFL.txt.
  8. * It is also available through the world-wide-web at this URL:
  9. * http://opensource.org/licenses/afl-3.0.php
  10. * If you did not receive a copy of the license and are unable to
  11. * obtain it through the world-wide-web, please send an email
  12. * to license@magentocommerce.com so we can send you a copy immediately.
  13. *
  14. * DISCLAIMER
  15. *
  16. * Do not edit or add to this file if you wish to upgrade Magento to newer
  17. * versions in the future. If you wish to customize Magento for your
  18. * needs please refer to http://www.magentocommerce.com for more information.
  19. *
  20. * @category Mage
  21. * @package Mage_Adminhtml
  22. * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  23. * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
  24. */
  25. if(!window.Flex) {
  26. alert('Flex library not loaded');
  27. } else {
  28. Flex.Uploader = Class.create();
  29. Flex.Uploader.prototype = {
  30. flex: null,
  31. uploader:null,
  32. filters:null,
  33. containerId:null,
  34. flexContainerId:null,
  35. container:null,
  36. files:null,
  37. fileRowTemplate:null,
  38. fileProgressTemplate:null,
  39. templatesPattern: /(^|.|\r|\n)(\{\{(.*?)\}\})/,
  40. onFilesComplete: false,
  41. onFileProgress: true,
  42. onFileRemove: false,
  43. onContainerHideBefore:null,
  44. initialize: function(containerId, uploaderSrc, config) {
  45. this.containerId = containerId;
  46. this.container = $(containerId);
  47. this.container.controller = this;
  48. this.config = config;
  49. this.flexContainerId = this.containerId + '-flash';
  50. Element.insert(
  51. // window.document.body,
  52. this.containerId,
  53. {'before':'<div id="'+this.flexContainerId+'" class="flex" style="position:relative;float:right;"></div>'}
  54. );
  55. flexWidth = 230;
  56. if (this.config.width) {
  57. flexWidth = this.config.width;
  58. }
  59. this.flex = new Flex.Object({
  60. left: 100,
  61. top: 300,
  62. width: flexWidth,
  63. height: 20,
  64. src: uploaderSrc,
  65. wmode: 'transparent'
  66. });
  67. // this.getInnerElement('browse').disabled = true;
  68. // this.getInnerElement('upload').disabled = true;
  69. this.fileRowTemplate = new Template(
  70. this.getInnerElement('template').innerHTML,
  71. this.templatesPattern
  72. );
  73. this.fileProgressTemplate = new Template(
  74. this.getInnerElement('template-progress').innerHTML,
  75. this.templatesPattern
  76. );
  77. this.flex.onBridgeInit = this.handleBridgeInit.bind(this);
  78. if (this.flex.detectFlashVersion(9, 0, 28)) {
  79. this.flex.apply(this.flexContainerId);
  80. } else {
  81. // this.getInnerElement('browse').hide();
  82. // this.getInnerElement('upload').hide();
  83. this.getInnerElement('install-flash').show();
  84. }
  85. this.onContainerHideBefore = this.handleContainerHideBefore.bind(this);
  86. },
  87. getInnerElement: function(elementName) {
  88. return $(this.containerId + '-' + elementName);
  89. },
  90. getFileId: function(file) {
  91. var id;
  92. if(typeof file == 'object') {
  93. id = file.id;
  94. } else {
  95. id = file;
  96. }
  97. return this.containerId + '-file-' + id;
  98. },
  99. getDeleteButton: function(file) {
  100. return $(this.getFileId(file) + '-delete');
  101. },
  102. handleBridgeInit: function() {
  103. this.uploader = this.flex.getBridge().getUpload();
  104. if (this.config.filters) {
  105. $H(this.config.filters).each(function(pair) {
  106. this.uploader.addTypeFilter(pair.key, pair.value.label, pair.value.files);
  107. }.bind(this));
  108. delete(this.config.filters);
  109. this.uploader.setUseTypeFilter(true);
  110. }
  111. this.uploader.setConfig(this.config);
  112. this.uploader.addEventListener('select', this.handleSelect.bind(this));
  113. this.uploader.addEventListener('complete', this.handleComplete.bind(this));
  114. this.uploader.addEventListener('progress', this.handleProgress.bind(this));
  115. this.uploader.addEventListener('error', this.handleError.bind(this));
  116. this.uploader.addEventListener('removeall', this.handleRemoveAll.bind(this));
  117. // this.getInnerElement('browse').disabled = false;
  118. // this.getInnerElement('upload').disabled = false;
  119. },
  120. browse: function() {
  121. this.uploader.browse();
  122. },
  123. upload: function() {
  124. this.uploader.upload();
  125. this.files = this.uploader.getFilesInfo();
  126. this.updateFiles();
  127. },
  128. removeFile: function(id) {
  129. this.uploader.removeFile(id);
  130. $(this.getFileId(id)).remove();
  131. if (this.onFileRemove) {
  132. this.onFileRemove(id);
  133. }
  134. this.files = this.uploader.getFilesInfo();
  135. this.updateFiles();
  136. },
  137. removeAllFiles: function() {
  138. this.files.each(function(file) {
  139. this.removeFile(file.id);
  140. }.bind(this));
  141. this.files = this.uploader.getFilesInfo();
  142. this.updateFiles();
  143. },
  144. handleSelect: function (event) {
  145. this.files = event.getData().files;
  146. this.checkFileSize();
  147. this.updateFiles();
  148. this.getInnerElement('upload').show();
  149. if (this.onFileSelect) {
  150. this.onFileSelect();
  151. }
  152. },
  153. handleProgress: function (event) {
  154. var file = event.getData().file;
  155. this.updateFile(file);
  156. if (this.onFileProgress) {
  157. this.onFileProgress(file);
  158. }
  159. },
  160. handleError: function (event) {
  161. this.updateFile(event.getData().file);
  162. },
  163. handleComplete: function (event) {
  164. this.files = event.getData().files;
  165. this.updateFiles();
  166. if (this.onFilesComplete) {
  167. this.onFilesComplete(this.files);
  168. }
  169. },
  170. handleRemoveAll: function (event) {
  171. this.files.each(function(file) {
  172. $(this.getFileId(file.id)).remove();
  173. }.bind(this));
  174. if (this.onFileRemoveAll) {
  175. this.onFileRemoveAll();
  176. }
  177. this.files = this.uploader.getFilesInfo();
  178. this.updateFiles();
  179. },
  180. handleRemove: function (event) {
  181. this.files = this.uploader.getFilesInfo();
  182. this.updateFiles();
  183. },
  184. updateFiles: function () {
  185. this.files.each(function(file) {
  186. this.updateFile(file);
  187. }.bind(this));
  188. },
  189. updateFile: function (file) {
  190. if (!$(this.getFileId(file))) {
  191. if (this.config.replace_browse_with_remove) {
  192. $(this.containerId+'-new').show();
  193. $(this.containerId+'-new').innerHTML = this.fileRowTemplate.evaluate(this.getFileVars(file));
  194. $(this.containerId+'-old').hide();
  195. this.flex.getBridge().hideBrowseButton();
  196. } else {
  197. Element.insert(this.container, {bottom: this.fileRowTemplate.evaluate(this.getFileVars(file))});
  198. }
  199. }
  200. if (file.status == 'full_complete' && file.response.isJSON()) {
  201. var response = file.response.evalJSON();
  202. if (typeof response == 'object') {
  203. if (typeof response.cookie == 'object') {
  204. var date = new Date();
  205. date.setTime(date.getTime()+(parseInt(response.cookie.lifetime)*1000));
  206. document.cookie = escape(response.cookie.name) + "="
  207. + escape(response.cookie.value)
  208. + "; expires=" + date.toGMTString()
  209. + (response.cookie.path.blank() ? "" : "; path=" + response.cookie.path)
  210. + (response.cookie.domain.blank() ? "" : "; domain=" + response.cookie.domain);
  211. }
  212. if (typeof response.error != 'undefined' && response.error != 0) {
  213. file.status = 'error';
  214. file.errorText = response.error;
  215. }
  216. }
  217. }
  218. if (file.status == 'full_complete' && !file.response.isJSON()) {
  219. file.status = 'error';
  220. }
  221. var progress = $(this.getFileId(file)).getElementsByClassName('progress-text')[0];
  222. if ((file.status=='progress') || (file.status=='complete')) {
  223. $(this.getFileId(file)).addClassName('progress');
  224. $(this.getFileId(file)).removeClassName('new');
  225. $(this.getFileId(file)).removeClassName('error');
  226. if (file.progress && file.progress.total) {
  227. progress.update(this.fileProgressTemplate.evaluate(this.getFileProgressVars(file)));
  228. } else {
  229. progress.update('');
  230. }
  231. if (! this.config.replace_browse_with_remove) {
  232. this.getDeleteButton(file).hide();
  233. }
  234. } else if (file.status=='error') {
  235. $(this.getFileId(file)).addClassName('error');
  236. $(this.getFileId(file)).removeClassName('progress');
  237. $(this.getFileId(file)).removeClassName('new');
  238. var errorText = file.errorText ? file.errorText : this.errorText(file);
  239. if (this.config.replace_browse_with_remove) {
  240. this.flex.getBridge().hideBrowseButton();
  241. } else {
  242. this.getDeleteButton(file).show();
  243. }
  244. progress.update(errorText);
  245. } else if (file.status=='full_complete') {
  246. $(this.getFileId(file)).addClassName('complete');
  247. $(this.getFileId(file)).removeClassName('progress');
  248. $(this.getFileId(file)).removeClassName('error');
  249. if (this.config.replace_browse_with_remove) {
  250. this.flex.getBridge().hideRemoveButton();
  251. }
  252. progress.update(this.translate('Complete'));
  253. }
  254. },
  255. getDebugStr: function(obj) {
  256. return Object.toJSON(obj).replace('&', '&amp;').replace('>', '&gt;').replace('<', '&lt;');
  257. },
  258. getFileVars: function(file) {
  259. return {
  260. id : this.getFileId(file),
  261. fileId : file.id,
  262. name : file.name,
  263. size : this.formatSize(file.size)
  264. };
  265. },
  266. getFileProgressVars: function(file) {
  267. return {
  268. total : this.formatSize(file.progress.total),
  269. uploaded : this.formatSize(file.progress.loaded),
  270. percent : this.round((file.progress.loaded/file.progress.total)*100)
  271. };
  272. },
  273. formatSize: function(size) {
  274. if (size > 1024 * 1024 * 1024 * 1024) {
  275. return this.round(size / (1024 * 1024 * 1024 * 1024)) + ' ' + this.translate('TB');
  276. } else if (size > 1024 * 1024 * 1024) {
  277. return this.round(size / (1024 * 1024 * 1024)) + ' ' + this.translate('GB');
  278. } else if (size > 1024 * 1024) {
  279. return this.round(size / (1024 * 1024)) + ' ' + this.translate('MB');
  280. } else if (size > 1024) {
  281. return this.round(size / (1024)) + ' ' + this.translate('kB');
  282. }
  283. return size + ' ' + this.translate('B');
  284. },
  285. round: function(number) {
  286. return Math.round(number*100)/100;
  287. },
  288. checkFileSize: function() {
  289. newFiles = [];
  290. hasTooBigFiles = false;
  291. this.files.each(function(file){
  292. if (file.size > maxUploadFileSizeInBytes) {
  293. hasTooBigFiles = true;
  294. this.uploader.removeFile(file.id)
  295. } else {
  296. newFiles.push(file)
  297. }
  298. }.bind(this));
  299. this.files = newFiles;
  300. if (hasTooBigFiles) {
  301. alert(
  302. this.translate('Maximum allowed file size for upload is')+' '+maxUploadFileSize+".\n"+this.translate('Please check your server PHP settings.')
  303. );
  304. }
  305. },
  306. translate: function(text) {
  307. try {
  308. if(Translator){
  309. return Translator.translate(text);
  310. }
  311. }
  312. catch(e){}
  313. return text;
  314. },
  315. errorText: function(file) {
  316. var error = '';
  317. switch(file.errorCode) {
  318. case 1: // Size 0
  319. error = 'File size should be more than 0 bytes';
  320. break;
  321. case 2: // Http error
  322. error = 'Upload HTTP Error';
  323. break;
  324. case 3: // I/O error
  325. error = 'Upload I/O Error';
  326. break;
  327. case 4: // Security error
  328. error = 'Upload Security Error';
  329. break;
  330. case 5: // SSL self-signed certificate
  331. error = 'SSL Error: Invalid or self-signed certificate';
  332. break;
  333. }
  334. if(error) {
  335. return this.translate(error);
  336. }
  337. return error;
  338. },
  339. handleContainerHideBefore: function(container) {
  340. if (container && Element.descendantOf(this.container, container) && !this.checkAllComplete()) {
  341. if (! confirm('There are files that were selected but not uploaded yet. After switching to another tab your selections will be lost. Do you wish to continue ?')) {
  342. return 'cannotchange';
  343. } else {
  344. this.removeAllFiles();
  345. }
  346. }
  347. },
  348. checkAllComplete: function() {
  349. if (this.files) {
  350. return !this.files.any(function(file) {
  351. return (file.status !== 'full_complete')
  352. });
  353. }
  354. return true;
  355. }
  356. }
  357. }