110.dropUpload.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /** This file is part of KCFinder project
  2. *
  3. * @desc Upload files using drag and drop
  4. * @package KCFinder
  5. * @version 3.12
  6. * @author Forum user (updated by Pavel Tzonkov)
  7. * @copyright 2010-2014 KCFinder Project
  8. * @license http://opensource.org/licenses/GPL-3.0 GPLv3
  9. * @license http://opensource.org/licenses/LGPL-3.0 LGPLv3
  10. * @link http://kcfinder.sunhater.com
  11. */
  12. _.initDropUpload = function() {
  13. if ((typeof XMLHttpRequest == "undefined") ||
  14. (typeof document.addEventListener == "undefined") ||
  15. (typeof File == "undefined") ||
  16. (typeof FileReader == "undefined")
  17. )
  18. return;
  19. if (!XMLHttpRequest.prototype.sendAsBinary) {
  20. XMLHttpRequest.prototype.sendAsBinary = function(datastr) {
  21. var ords = Array.prototype.map.call(datastr, function(x) {
  22. return x.charCodeAt(0) & 0xff;
  23. }),
  24. ui8a = new Uint8Array(ords);
  25. this.send(ui8a.buffer);
  26. }
  27. }
  28. var uploadQueue = [],
  29. uploadInProgress = false,
  30. filesCount = 0,
  31. errors = [],
  32. files = $('#files'),
  33. folders = $('div.folder > a'),
  34. boundary = "------multipartdropuploadboundary" + (new Date).getTime(),
  35. currentFile,
  36. filesDragOver = function(e) {
  37. if (e.preventDefault) e.preventDefault();
  38. $('#files').addClass('drag');
  39. return false;
  40. },
  41. filesDragEnter = function(e) {
  42. if (e.preventDefault) e.preventDefault();
  43. return false;
  44. },
  45. filesDragLeave = function(e) {
  46. if (e.preventDefault) e.preventDefault();
  47. $('#files').removeClass('drag');
  48. return false;
  49. },
  50. filesDrop = function(e) {
  51. if (e.preventDefault) e.preventDefault();
  52. if (e.stopPropagation) e.stopPropagation();
  53. $('#files').removeClass('drag');
  54. if (!$('#folders span.current').first().parent().data('writable')) {
  55. _.alert("Cannot write to upload folder.");
  56. return false;
  57. }
  58. filesCount += e.dataTransfer.files.length;
  59. for (var i = 0; i < e.dataTransfer.files.length; i++) {
  60. var file = e.dataTransfer.files[i];
  61. file.thisTargetDir = _.dir;
  62. uploadQueue.push(file);
  63. }
  64. processUploadQueue();
  65. return false;
  66. },
  67. folderDrag = function(e) {
  68. if (e.preventDefault) e.preventDefault();
  69. return false;
  70. },
  71. folderDrop = function(e, dir) {
  72. if (e.preventDefault) e.preventDefault();
  73. if (e.stopPropagation) e.stopPropagation();
  74. if (!$(dir).data('writable')) {
  75. _.alert(_.label("Cannot write to upload folder."));
  76. return false;
  77. }
  78. filesCount += e.dataTransfer.files.length;
  79. for (var i = 0; i < e.dataTransfer.files.length; i++) {
  80. var file = e.dataTransfer.files[i];
  81. file.thisTargetDir = $(dir).data('path');
  82. uploadQueue.push(file);
  83. }
  84. processUploadQueue();
  85. return false;
  86. };
  87. files.get(0).removeEventListener('dragover', filesDragOver, false);
  88. files.get(0).removeEventListener('dragenter', filesDragEnter, false);
  89. files.get(0).removeEventListener('dragleave', filesDragLeave, false);
  90. files.get(0).removeEventListener('drop', filesDrop, false);
  91. files.get(0).addEventListener('dragover', filesDragOver, false);
  92. files.get(0).addEventListener('dragenter', filesDragEnter, false);
  93. files.get(0).addEventListener('dragleave', filesDragLeave, false);
  94. files.get(0).addEventListener('drop', filesDrop, false);
  95. folders.each(function() {
  96. var folder = this,
  97. dragOver = function(e) {
  98. $(folder).children('span.folder').addClass('context');
  99. return folderDrag(e);
  100. },
  101. dragLeave = function(e) {
  102. $(folder).children('span.folder').removeClass('context');
  103. return folderDrag(e);
  104. },
  105. drop = function(e) {
  106. $(folder).children('span.folder').removeClass('context');
  107. return folderDrop(e, folder);
  108. };
  109. this.removeEventListener('dragover', dragOver, false);
  110. this.removeEventListener('dragenter', folderDrag, false);
  111. this.removeEventListener('dragleave', dragLeave, false);
  112. this.removeEventListener('drop', drop, false);
  113. this.addEventListener('dragover', dragOver, false);
  114. this.addEventListener('dragenter', folderDrag, false);
  115. this.addEventListener('dragleave', dragLeave, false);
  116. this.addEventListener('drop', drop, false);
  117. });
  118. function updateProgress(evt) {
  119. var progress = evt.lengthComputable
  120. ? Math.round((evt.loaded * 100) / evt.total) + '%'
  121. : Math.round(evt.loaded / 1024) + " KB";
  122. $('#loading').html(_.label("Uploading file {number} of {count}... {progress}", {
  123. number: filesCount - uploadQueue.length,
  124. count: filesCount,
  125. progress: progress
  126. }));
  127. }
  128. function processUploadQueue() {
  129. if (uploadInProgress)
  130. return false;
  131. if (uploadQueue && uploadQueue.length) {
  132. var file = uploadQueue.shift();
  133. currentFile = file;
  134. $('#loading').html(_.label("Uploading file {number} of {count}... {progress}", {
  135. number: filesCount - uploadQueue.length,
  136. count: filesCount,
  137. progress: ""
  138. })).show();
  139. var reader = new FileReader();
  140. reader.thisFileName = file.name;
  141. reader.thisFileType = file.type;
  142. reader.thisFileSize = file.size;
  143. reader.thisTargetDir = file.thisTargetDir;
  144. reader.onload = function(evt) {
  145. uploadInProgress = true;
  146. var postbody = '--' + boundary + '\r\nContent-Disposition: form-data; name="upload[]"';
  147. if (evt.target.thisFileName)
  148. postbody += '; filename="' + $.$.utf8encode(evt.target.thisFileName) + '"';
  149. postbody += '\r\n';
  150. if (evt.target.thisFileSize)
  151. postbody += "Content-Length: " + evt.target.thisFileSize + "\r\n";
  152. postbody += "Content-Type: " + evt.target.thisFileType + "\r\n\r\n" + evt.target.result + "\r\n--" + boundary + '\r\nContent-Disposition: form-data; name="dir"\r\n\r\n' + $.$.utf8encode(evt.target.thisTargetDir) + "\r\n--" + boundary + "\r\n--" + boundary + "--\r\n";
  153. var xhr = new XMLHttpRequest();
  154. xhr.thisFileName = evt.target.thisFileName;
  155. if (xhr.upload) {
  156. xhr.upload.thisFileName = evt.target.thisFileName;
  157. xhr.upload.addEventListener("progress", updateProgress, false);
  158. }
  159. xhr.open('post', _.getURL('upload'), true);
  160. xhr.setRequestHeader('Content-Type', "multipart/form-data; boundary=" + boundary);
  161. //xhr.setRequestHeader('Content-Length', postbody.length);
  162. xhr.onload = function(e) {
  163. $('#loading').hide();
  164. if (_.dir == reader.thisTargetDir)
  165. _.fadeFiles();
  166. uploadInProgress = false;
  167. processUploadQueue();
  168. if (xhr.responseText.substr(0, 1) != "/")
  169. errors[errors.length] = xhr.responseText;
  170. };
  171. xhr.sendAsBinary(postbody);
  172. };
  173. reader.onerror = function(evt) {
  174. $('#loading').hide();
  175. uploadInProgress = false;
  176. processUploadQueue();
  177. errors[errors.length] = _.label("Failed to upload {filename}!", {
  178. filename: evt.target.thisFileName
  179. });
  180. };
  181. reader.readAsBinaryString(file);
  182. } else {
  183. filesCount = 0;
  184. var loop = setInterval(function() {
  185. if (uploadInProgress) return;
  186. boundary = "------multipartdropuploadboundary" + (new Date).getTime();
  187. uploadQueue = [];
  188. clearInterval(loop);
  189. if (currentFile.thisTargetDir == _.dir)
  190. _.refresh();
  191. if (errors.length) {
  192. errors = errors.join("\n");
  193. if (errors.replace(/^\s+/g, "").replace(/\s+$/g, "").length)
  194. _.alert(errors);
  195. errors = [];
  196. }
  197. }, 333);
  198. }
  199. }
  200. };