dropzone.js 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052
  1. /*
  2. *
  3. * More info at [www.dropzonejs.com](http://www.dropzonejs.com)
  4. *
  5. * Copyright (c) 2012, Matias Meno
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. *
  25. */
  26. (function() {
  27. var Dropzone, Emitter, ExifRestore, camelize, contentLoaded, detectVerticalSquash, drawImageIOSFix, noop, without,
  28. slice = [].slice,
  29. extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  30. hasProp = {}.hasOwnProperty;
  31. noop = function() {};
  32. Emitter = (function() {
  33. function Emitter() {}
  34. Emitter.prototype.addEventListener = Emitter.prototype.on;
  35. Emitter.prototype.on = function(event, fn) {
  36. this._callbacks = this._callbacks || {};
  37. if (!this._callbacks[event]) {
  38. this._callbacks[event] = [];
  39. }
  40. this._callbacks[event].push(fn);
  41. return this;
  42. };
  43. Emitter.prototype.emit = function() {
  44. var args, callback, callbacks, event, j, len;
  45. event = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
  46. this._callbacks = this._callbacks || {};
  47. callbacks = this._callbacks[event];
  48. if (callbacks) {
  49. for (j = 0, len = callbacks.length; j < len; j++) {
  50. callback = callbacks[j];
  51. callback.apply(this, args);
  52. }
  53. }
  54. return this;
  55. };
  56. Emitter.prototype.removeListener = Emitter.prototype.off;
  57. Emitter.prototype.removeAllListeners = Emitter.prototype.off;
  58. Emitter.prototype.removeEventListener = Emitter.prototype.off;
  59. Emitter.prototype.off = function(event, fn) {
  60. var callback, callbacks, i, j, len;
  61. if (!this._callbacks || arguments.length === 0) {
  62. this._callbacks = {};
  63. return this;
  64. }
  65. callbacks = this._callbacks[event];
  66. if (!callbacks) {
  67. return this;
  68. }
  69. if (arguments.length === 1) {
  70. delete this._callbacks[event];
  71. return this;
  72. }
  73. for (i = j = 0, len = callbacks.length; j < len; i = ++j) {
  74. callback = callbacks[i];
  75. if (callback === fn) {
  76. callbacks.splice(i, 1);
  77. break;
  78. }
  79. }
  80. return this;
  81. };
  82. return Emitter;
  83. })();
  84. Dropzone = (function(superClass) {
  85. var extend, resolveOption;
  86. extend1(Dropzone, superClass);
  87. Dropzone.prototype.Emitter = Emitter;
  88. /*
  89. This is a list of all available events you can register on a dropzone object.
  90. You can register an event handler like this:
  91. dropzone.on("dragEnter", function() { });
  92. */
  93. Dropzone.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "addedfile", "addedfiles", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded", "maxfilesreached", "queuecomplete"];
  94. Dropzone.prototype.defaultOptions = {
  95. url: null,
  96. method: "POST",
  97. withCredentials: false,
  98. timeout: 300000,
  99. parallelUploads: 2,
  100. uploadMultiple: false,
  101. maxFilesize: 2048,
  102. paramName: "file",
  103. createImageThumbnails: true,
  104. maxThumbnailFilesize: 10,
  105. thumbnailWidth: 120,
  106. thumbnailHeight: 120,
  107. thumbnailMethod: 'crop',
  108. resizeWidth: null,
  109. resizeHeight: null,
  110. resizeMimeType: null,
  111. resizeQuality: 0.8,
  112. resizeMethod: 'contain',
  113. filesizeBase: 1000,
  114. maxFiles: null,
  115. params: {},
  116. headers: null,
  117. clickable: true,
  118. ignoreHiddenFiles: true,
  119. acceptedFiles: null,
  120. acceptedMimeTypes: null,
  121. autoProcessQueue: true,
  122. autoQueue: true,
  123. addRemoveLinks: false,
  124. previewsContainer: null,
  125. hiddenInputContainer: "body",
  126. capture: null,
  127. renameFilename: null,
  128. renameFile: null,
  129. forceFallback: false,
  130. dictDefaultMessage: "Drop files here to upload",
  131. dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.",
  132. dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.",
  133. dictFileTooBig: "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.",
  134. dictInvalidFileType: "You can't upload files of this type.",
  135. dictResponseError: "Server responded with {{statusCode}} code.",
  136. dictCancelUpload: "Cancel upload",
  137. dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?",
  138. dictRemoveFile: "Remove file",
  139. dictRemoveFileConfirmation: null,
  140. dictMaxFilesExceeded: "You can not upload any more files.",
  141. dictFileSizeUnits: {
  142. tb: "TB",
  143. gb: "GB",
  144. mb: "MB",
  145. kb: "KB",
  146. b: "b"
  147. },
  148. init: function() {
  149. return noop;
  150. },
  151. accept: function(file, done) {
  152. return done();
  153. },
  154. fallback: function() {
  155. var child, j, len, messageElement, ref, span;
  156. this.element.className = this.element.className + " dz-browser-not-supported";
  157. ref = this.element.getElementsByTagName("div");
  158. for (j = 0, len = ref.length; j < len; j++) {
  159. child = ref[j];
  160. if (/(^| )dz-message($| )/.test(child.className)) {
  161. messageElement = child;
  162. child.className = "dz-message";
  163. continue;
  164. }
  165. }
  166. if (!messageElement) {
  167. messageElement = Dropzone.createElement("<div class=\"dz-message\"><span></span></div>");
  168. this.element.appendChild(messageElement);
  169. }
  170. span = messageElement.getElementsByTagName("span")[0];
  171. if (span) {
  172. if (span.textContent != null) {
  173. span.textContent = this.options.dictFallbackMessage;
  174. } else if (span.innerText != null) {
  175. span.innerText = this.options.dictFallbackMessage;
  176. }
  177. }
  178. return this.element.appendChild(this.getFallbackForm());
  179. },
  180. resize: function(file, width, height, resizeMethod) {
  181. var info, srcRatio, trgRatio;
  182. info = {
  183. srcX: 0,
  184. srcY: 0,
  185. srcWidth: file.width,
  186. srcHeight: file.height
  187. };
  188. srcRatio = file.width / file.height;
  189. if ((width == null) && (height == null)) {
  190. width = info.srcWidth;
  191. height = info.srcHeight;
  192. } else if (width == null) {
  193. width = height * srcRatio;
  194. } else if (height == null) {
  195. height = width / srcRatio;
  196. }
  197. width = Math.min(width, info.srcWidth);
  198. height = Math.min(height, info.srcHeight);
  199. trgRatio = width / height;
  200. if (info.srcWidth > width || info.srcHeight > height) {
  201. if (resizeMethod === 'crop') {
  202. if (srcRatio > trgRatio) {
  203. info.srcHeight = file.height;
  204. info.srcWidth = info.srcHeight * trgRatio;
  205. } else {
  206. info.srcWidth = file.width;
  207. info.srcHeight = info.srcWidth / trgRatio;
  208. }
  209. } else if (resizeMethod === 'contain') {
  210. if (srcRatio > trgRatio) {
  211. height = width / srcRatio;
  212. } else {
  213. width = height * srcRatio;
  214. }
  215. } else {
  216. throw new Error("Unknown resizeMethod '" + resizeMethod + "'");
  217. }
  218. }
  219. info.srcX = (file.width - info.srcWidth) / 2;
  220. info.srcY = (file.height - info.srcHeight) / 2;
  221. info.trgWidth = width;
  222. info.trgHeight = height;
  223. return info;
  224. },
  225. transformFile: function(file, done) {
  226. if ((this.options.resizeWidth || this.options.resizeHeight) && file.type.match(/image.*/)) {
  227. return this.resizeImage(file, this.options.resizeWidth, this.options.resizeHeight, this.options.resizeMethod, done);
  228. } else {
  229. return done(file);
  230. }
  231. },
  232. previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n <div class=\"dz-image\"><img data-dz-thumbnail /></div>\n <div class=\"dz-details\">\n <div class=\"dz-size\"><span data-dz-size></span></div>\n <div class=\"dz-filename\"><span data-dz-name></span></div>\n </div>\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress></span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n <div class=\"dz-success-mark\">\n <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n <title>Check</title>\n <defs></defs>\n <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n <path d=\"M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835 11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915 C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022 L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" stroke-opacity=\"0.198794158\" stroke=\"#747474\" fill-opacity=\"0.816519475\" fill=\"#FFFFFF\" sketch:type=\"MSShapeGroup\"></path>\n </g>\n </svg>\n </div>\n <div class=\"dz-error-mark\">\n <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n <title>Error</title>\n <defs></defs>\n <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n <g id=\"Check-+-Oval-2\" sketch:type=\"MSLayerGroup\" stroke=\"#747474\" stroke-opacity=\"0.198794158\" fill=\"#FFFFFF\" fill-opacity=\"0.816519475\">\n <path d=\"M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887 38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915 C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564 L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479 14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271 38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" sketch:type=\"MSShapeGroup\"></path>\n </g>\n </g>\n </svg>\n </div>\n</div>",
  233. /*
  234. Those functions register themselves to the events on init and handle all
  235. the user interface specific stuff. Overwriting them won't break the upload
  236. but can break the way it's displayed.
  237. You can overwrite them if you don't like the default behavior. If you just
  238. want to add an additional event handler, register it on the dropzone object
  239. and don't overwrite those options.
  240. */
  241. drop: function(e) {
  242. return this.element.classList.remove("dz-drag-hover");
  243. },
  244. dragstart: noop,
  245. dragend: function(e) {
  246. return this.element.classList.remove("dz-drag-hover");
  247. },
  248. dragenter: function(e) {
  249. return this.element.classList.add("dz-drag-hover");
  250. },
  251. dragover: function(e) {
  252. return this.element.classList.add("dz-drag-hover");
  253. },
  254. dragleave: function(e) {
  255. return this.element.classList.remove("dz-drag-hover");
  256. },
  257. paste: noop,
  258. reset: function() {
  259. return this.element.classList.remove("dz-started");
  260. },
  261. addedfile: function(file) {
  262. var j, k, l, len, len1, len2, node, ref, ref1, ref2, removeFileEvent, removeLink, results;
  263. if (this.element === this.previewsContainer) {
  264. this.element.classList.add("dz-started");
  265. }
  266. if (this.previewsContainer) {
  267. file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim());
  268. file.previewTemplate = file.previewElement;
  269. this.previewsContainer.appendChild(file.previewElement);
  270. ref = file.previewElement.querySelectorAll("[data-dz-name]");
  271. for (j = 0, len = ref.length; j < len; j++) {
  272. node = ref[j];
  273. node.textContent = file.name;
  274. }
  275. ref1 = file.previewElement.querySelectorAll("[data-dz-size]");
  276. for (k = 0, len1 = ref1.length; k < len1; k++) {
  277. node = ref1[k];
  278. node.innerHTML = this.filesize(file.size);
  279. }
  280. if (this.options.addRemoveLinks) {
  281. file._removeLink = Dropzone.createElement("<a class=\"dz-remove\" href=\"javascript:undefined;\" data-dz-remove>" + this.options.dictRemoveFile + "</a>");
  282. file.previewElement.appendChild(file._removeLink);
  283. }
  284. removeFileEvent = (function(_this) {
  285. return function(e) {
  286. e.preventDefault();
  287. e.stopPropagation();
  288. if (file.status === Dropzone.UPLOADING) {
  289. return Dropzone.confirm(_this.options.dictCancelUploadConfirmation, function() {
  290. return _this.removeFile(file);
  291. });
  292. } else {
  293. if (_this.options.dictRemoveFileConfirmation) {
  294. return Dropzone.confirm(_this.options.dictRemoveFileConfirmation, function() {
  295. return _this.removeFile(file);
  296. });
  297. } else {
  298. return _this.removeFile(file);
  299. }
  300. }
  301. };
  302. })(this);
  303. ref2 = file.previewElement.querySelectorAll("[data-dz-remove]");
  304. results = [];
  305. for (l = 0, len2 = ref2.length; l < len2; l++) {
  306. removeLink = ref2[l];
  307. results.push(removeLink.addEventListener("click", removeFileEvent));
  308. }
  309. return results;
  310. }
  311. },
  312. removedfile: function(file) {
  313. var ref;
  314. if (file.previewElement) {
  315. if ((ref = file.previewElement) != null) {
  316. ref.parentNode.removeChild(file.previewElement);
  317. }
  318. }
  319. return this._updateMaxFilesReachedClass();
  320. },
  321. thumbnail: function(file, dataUrl) {
  322. var j, len, ref, thumbnailElement;
  323. if (file.previewElement) {
  324. file.previewElement.classList.remove("dz-file-preview");
  325. ref = file.previewElement.querySelectorAll("[data-dz-thumbnail]");
  326. for (j = 0, len = ref.length; j < len; j++) {
  327. thumbnailElement = ref[j];
  328. thumbnailElement.alt = file.name;
  329. thumbnailElement.src = dataUrl;
  330. }
  331. return setTimeout(((function(_this) {
  332. return function() {
  333. return file.previewElement.classList.add("dz-image-preview");
  334. };
  335. })(this)), 1);
  336. }
  337. },
  338. error: function(file, message) {
  339. var j, len, node, ref, results;
  340. if (file.previewElement) {
  341. file.previewElement.classList.add("dz-error");
  342. if (typeof message !== "String" && message.error) {
  343. message = message.error;
  344. }
  345. ref = file.previewElement.querySelectorAll("[data-dz-errormessage]");
  346. results = [];
  347. for (j = 0, len = ref.length; j < len; j++) {
  348. node = ref[j];
  349. results.push(node.textContent = message);
  350. }
  351. return results;
  352. }
  353. },
  354. errormultiple: noop,
  355. processing: function(file) {
  356. if (file.previewElement) {
  357. file.previewElement.classList.add("dz-processing");
  358. if (file._removeLink) {
  359. return file._removeLink.textContent = this.options.dictCancelUpload;
  360. }
  361. }
  362. },
  363. processingmultiple: noop,
  364. uploadprogress: function(file, progress, bytesSent) {
  365. var j, len, node, ref, results;
  366. if (file.previewElement) {
  367. ref = file.previewElement.querySelectorAll("[data-dz-uploadprogress]");
  368. results = [];
  369. for (j = 0, len = ref.length; j < len; j++) {
  370. node = ref[j];
  371. if (node.nodeName === 'PROGRESS') {
  372. results.push(node.value = progress);
  373. } else {
  374. results.push(node.style.width = progress + "%");
  375. }
  376. }
  377. return results;
  378. }
  379. },
  380. totaluploadprogress: noop,
  381. sending: noop,
  382. sendingmultiple: noop,
  383. success: function(file) {
  384. if (file.previewElement) {
  385. return file.previewElement.classList.add("dz-success");
  386. }
  387. },
  388. successmultiple: noop,
  389. canceled: function(file) {
  390. return this.emit("error", file, "Upload canceled.");
  391. },
  392. canceledmultiple: noop,
  393. complete: function(file) {
  394. if (file._removeLink) {
  395. file._removeLink.textContent = this.options.dictRemoveFile;
  396. }
  397. if (file.previewElement) {
  398. return file.previewElement.classList.add("dz-complete");
  399. }
  400. },
  401. completemultiple: noop,
  402. maxfilesexceeded: noop,
  403. maxfilesreached: noop,
  404. queuecomplete: noop,
  405. addedfiles: noop
  406. };
  407. extend = function() {
  408. var j, key, len, object, objects, target, val;
  409. target = arguments[0], objects = 2 <= arguments.length ? slice.call(arguments, 1) : [];
  410. for (j = 0, len = objects.length; j < len; j++) {
  411. object = objects[j];
  412. for (key in object) {
  413. val = object[key];
  414. target[key] = val;
  415. }
  416. }
  417. return target;
  418. };
  419. function Dropzone(element1, options) {
  420. var elementOptions, fallback, ref;
  421. this.element = element1;
  422. this.version = Dropzone.version;
  423. this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, "");
  424. this.clickableElements = [];
  425. this.listeners = [];
  426. this.files = [];
  427. if (typeof this.element === "string") {
  428. this.element = document.querySelector(this.element);
  429. }
  430. if (!(this.element && (this.element.nodeType != null))) {
  431. throw new Error("Invalid dropzone element.");
  432. }
  433. if (this.element.dropzone) {
  434. throw new Error("Dropzone already attached.");
  435. }
  436. Dropzone.instances.push(this);
  437. this.element.dropzone = this;
  438. elementOptions = (ref = Dropzone.optionsForElement(this.element)) != null ? ref : {};
  439. this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {});
  440. if (this.options.forceFallback || !Dropzone.isBrowserSupported()) {
  441. return this.options.fallback.call(this);
  442. }
  443. if (this.options.url == null) {
  444. this.options.url = this.element.getAttribute("action");
  445. }
  446. if (!this.options.url) {
  447. throw new Error("No URL provided.");
  448. }
  449. if (this.options.acceptedFiles && this.options.acceptedMimeTypes) {
  450. throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated.");
  451. }
  452. if (this.options.acceptedMimeTypes) {
  453. this.options.acceptedFiles = this.options.acceptedMimeTypes;
  454. delete this.options.acceptedMimeTypes;
  455. }
  456. if (this.options.renameFilename != null) {
  457. this.options.renameFile = (function(_this) {
  458. return function(file) {
  459. return _this.options.renameFilename.call(_this, file.name, file);
  460. };
  461. })(this);
  462. }
  463. this.options.method = this.options.method.toUpperCase();
  464. if ((fallback = this.getExistingFallback()) && fallback.parentNode) {
  465. fallback.parentNode.removeChild(fallback);
  466. }
  467. if (this.options.previewsContainer !== false) {
  468. if (this.options.previewsContainer) {
  469. this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, "previewsContainer");
  470. } else {
  471. this.previewsContainer = this.element;
  472. }
  473. }
  474. if (this.options.clickable) {
  475. if (this.options.clickable === true) {
  476. this.clickableElements = [this.element];
  477. } else {
  478. this.clickableElements = Dropzone.getElements(this.options.clickable, "clickable");
  479. }
  480. }
  481. this.init();
  482. }
  483. Dropzone.prototype.getAcceptedFiles = function() {
  484. var file, j, len, ref, results;
  485. ref = this.files;
  486. results = [];
  487. for (j = 0, len = ref.length; j < len; j++) {
  488. file = ref[j];
  489. if (file.accepted) {
  490. results.push(file);
  491. }
  492. }
  493. return results;
  494. };
  495. Dropzone.prototype.getRejectedFiles = function() {
  496. var file, j, len, ref, results;
  497. ref = this.files;
  498. results = [];
  499. for (j = 0, len = ref.length; j < len; j++) {
  500. file = ref[j];
  501. if (!file.accepted) {
  502. results.push(file);
  503. }
  504. }
  505. return results;
  506. };
  507. Dropzone.prototype.getFilesWithStatus = function(status) {
  508. var file, j, len, ref, results;
  509. ref = this.files;
  510. results = [];
  511. for (j = 0, len = ref.length; j < len; j++) {
  512. file = ref[j];
  513. if (file.status === status) {
  514. results.push(file);
  515. }
  516. }
  517. return results;
  518. };
  519. Dropzone.prototype.getQueuedFiles = function() {
  520. return this.getFilesWithStatus(Dropzone.QUEUED);
  521. };
  522. Dropzone.prototype.getUploadingFiles = function() {
  523. return this.getFilesWithStatus(Dropzone.UPLOADING);
  524. };
  525. Dropzone.prototype.getAddedFiles = function() {
  526. return this.getFilesWithStatus(Dropzone.ADDED);
  527. };
  528. Dropzone.prototype.getActiveFiles = function() {
  529. var file, j, len, ref, results;
  530. ref = this.files;
  531. results = [];
  532. for (j = 0, len = ref.length; j < len; j++) {
  533. file = ref[j];
  534. if (file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED) {
  535. results.push(file);
  536. }
  537. }
  538. return results;
  539. };
  540. Dropzone.prototype.init = function() {
  541. var eventName, j, len, noPropagation, ref, ref1, setupHiddenFileInput;
  542. if (this.element.tagName === "form") {
  543. this.element.setAttribute("enctype", "multipart/form-data");
  544. }
  545. if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) {
  546. this.element.appendChild(Dropzone.createElement("<div class=\"dz-default dz-message\"><span>" + this.options.dictDefaultMessage + "</span></div>"));
  547. }
  548. if (this.clickableElements.length) {
  549. setupHiddenFileInput = (function(_this) {
  550. return function() {
  551. if (_this.hiddenFileInput) {
  552. _this.hiddenFileInput.parentNode.removeChild(_this.hiddenFileInput);
  553. }
  554. _this.hiddenFileInput = document.createElement("input");
  555. _this.hiddenFileInput.setAttribute("type", "file");
  556. if ((_this.options.maxFiles == null) || _this.options.maxFiles > 1) {
  557. _this.hiddenFileInput.setAttribute("multiple", "multiple");
  558. }
  559. _this.hiddenFileInput.className = "dz-hidden-input";
  560. if (_this.options.acceptedFiles != null) {
  561. _this.hiddenFileInput.setAttribute("accept", _this.options.acceptedFiles);
  562. }
  563. if (_this.options.capture != null) {
  564. _this.hiddenFileInput.setAttribute("capture", _this.options.capture);
  565. }
  566. _this.hiddenFileInput.style.visibility = "hidden";
  567. _this.hiddenFileInput.style.position = "absolute";
  568. _this.hiddenFileInput.style.top = "0";
  569. _this.hiddenFileInput.style.left = "0";
  570. _this.hiddenFileInput.style.height = "0";
  571. _this.hiddenFileInput.style.width = "0";
  572. document.querySelector(_this.options.hiddenInputContainer).appendChild(_this.hiddenFileInput);
  573. return _this.hiddenFileInput.addEventListener("change", function() {
  574. var file, files, j, len;
  575. files = _this.hiddenFileInput.files;
  576. if (files.length) {
  577. for (j = 0, len = files.length; j < len; j++) {
  578. file = files[j];
  579. _this.addFile(file);
  580. }
  581. }
  582. _this.emit("addedfiles", files);
  583. return setupHiddenFileInput();
  584. });
  585. };
  586. })(this);
  587. setupHiddenFileInput();
  588. }
  589. this.URL = (ref = window.URL) != null ? ref : window.webkitURL;
  590. ref1 = this.events;
  591. for (j = 0, len = ref1.length; j < len; j++) {
  592. eventName = ref1[j];
  593. this.on(eventName, this.options[eventName]);
  594. }
  595. this.on("uploadprogress", (function(_this) {
  596. return function() {
  597. return _this.updateTotalUploadProgress();
  598. };
  599. })(this));
  600. this.on("removedfile", (function(_this) {
  601. return function() {
  602. return _this.updateTotalUploadProgress();
  603. };
  604. })(this));
  605. this.on("canceled", (function(_this) {
  606. return function(file) {
  607. return _this.emit("complete", file);
  608. };
  609. })(this));
  610. this.on("complete", (function(_this) {
  611. return function(file) {
  612. if (_this.getAddedFiles().length === 0 && _this.getUploadingFiles().length === 0 && _this.getQueuedFiles().length === 0) {
  613. return setTimeout((function() {
  614. return _this.emit("queuecomplete");
  615. }), 0);
  616. }
  617. };
  618. })(this));
  619. noPropagation = function(e) {
  620. e.stopPropagation();
  621. if (e.preventDefault) {
  622. return e.preventDefault();
  623. } else {
  624. return e.returnValue = false;
  625. }
  626. };
  627. this.listeners = [
  628. {
  629. element: this.element,
  630. events: {
  631. "dragstart": (function(_this) {
  632. return function(e) {
  633. return _this.emit("dragstart", e);
  634. };
  635. })(this),
  636. "dragenter": (function(_this) {
  637. return function(e) {
  638. noPropagation(e);
  639. return _this.emit("dragenter", e);
  640. };
  641. })(this),
  642. "dragover": (function(_this) {
  643. return function(e) {
  644. var efct;
  645. try {
  646. efct = e.dataTransfer.effectAllowed;
  647. } catch (undefined) {}
  648. e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy';
  649. noPropagation(e);
  650. return _this.emit("dragover", e);
  651. };
  652. })(this),
  653. "dragleave": (function(_this) {
  654. return function(e) {
  655. return _this.emit("dragleave", e);
  656. };
  657. })(this),
  658. "drop": (function(_this) {
  659. return function(e) {
  660. noPropagation(e);
  661. return _this.drop(e);
  662. };
  663. })(this),
  664. "dragend": (function(_this) {
  665. return function(e) {
  666. return _this.emit("dragend", e);
  667. };
  668. })(this)
  669. }
  670. }
  671. ];
  672. this.clickableElements.forEach((function(_this) {
  673. return function(clickableElement) {
  674. return _this.listeners.push({
  675. element: clickableElement,
  676. events: {
  677. "click": function(evt) {
  678. if ((clickableElement !== _this.element) || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(".dz-message")))) {
  679. _this.hiddenFileInput.click();
  680. }
  681. return true;
  682. }
  683. }
  684. });
  685. };
  686. })(this));
  687. this.enable();
  688. return this.options.init.call(this);
  689. };
  690. Dropzone.prototype.destroy = function() {
  691. var ref;
  692. this.disable();
  693. this.removeAllFiles(true);
  694. if ((ref = this.hiddenFileInput) != null ? ref.parentNode : void 0) {
  695. this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput);
  696. this.hiddenFileInput = null;
  697. }
  698. delete this.element.dropzone;
  699. return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1);
  700. };
  701. Dropzone.prototype.updateTotalUploadProgress = function() {
  702. var activeFiles, file, j, len, ref, totalBytes, totalBytesSent, totalUploadProgress;
  703. totalBytesSent = 0;
  704. totalBytes = 0;
  705. activeFiles = this.getActiveFiles();
  706. if (activeFiles.length) {
  707. ref = this.getActiveFiles();
  708. for (j = 0, len = ref.length; j < len; j++) {
  709. file = ref[j];
  710. totalBytesSent += file.upload.bytesSent;
  711. totalBytes += file.upload.total;
  712. }
  713. totalUploadProgress = 100 * totalBytesSent / totalBytes;
  714. } else {
  715. totalUploadProgress = 100;
  716. }
  717. return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent);
  718. };
  719. Dropzone.prototype._getParamName = function(n) {
  720. if (typeof this.options.paramName === "function") {
  721. return this.options.paramName(n);
  722. } else {
  723. return "" + this.options.paramName + (this.options.uploadMultiple ? "[" + n + "]" : "");
  724. }
  725. };
  726. Dropzone.prototype._renameFile = function(file) {
  727. if (typeof this.options.renameFile !== "function") {
  728. return file.name;
  729. }
  730. return this.options.renameFile(file);
  731. };
  732. Dropzone.prototype.getFallbackForm = function() {
  733. var existingFallback, fields, fieldsString, form;
  734. if (existingFallback = this.getExistingFallback()) {
  735. return existingFallback;
  736. }
  737. fieldsString = "<div class=\"dz-fallback\">";
  738. if (this.options.dictFallbackText) {
  739. fieldsString += "<p>" + this.options.dictFallbackText + "</p>";
  740. }
  741. fieldsString += "<input type=\"file\" name=\"" + (this._getParamName(0)) + "\" " + (this.options.uploadMultiple ? 'multiple="multiple"' : void 0) + " /><input type=\"submit\" value=\"Upload!\"></div>";
  742. fields = Dropzone.createElement(fieldsString);
  743. if (this.element.tagName !== "FORM") {
  744. form = Dropzone.createElement("<form action=\"" + this.options.url + "\" enctype=\"multipart/form-data\" method=\"" + this.options.method + "\"></form>");
  745. form.appendChild(fields);
  746. } else {
  747. this.element.setAttribute("enctype", "multipart/form-data");
  748. this.element.setAttribute("method", this.options.method);
  749. }
  750. return form != null ? form : fields;
  751. };
  752. Dropzone.prototype.getExistingFallback = function() {
  753. var fallback, getFallback, j, len, ref, tagName;
  754. getFallback = function(elements) {
  755. var el, j, len;
  756. for (j = 0, len = elements.length; j < len; j++) {
  757. el = elements[j];
  758. if (/(^| )fallback($| )/.test(el.className)) {
  759. return el;
  760. }
  761. }
  762. };
  763. ref = ["div", "form"];
  764. for (j = 0, len = ref.length; j < len; j++) {
  765. tagName = ref[j];
  766. if (fallback = getFallback(this.element.getElementsByTagName(tagName))) {
  767. return fallback;
  768. }
  769. }
  770. };
  771. Dropzone.prototype.setupEventListeners = function() {
  772. var elementListeners, event, j, len, listener, ref, results;
  773. ref = this.listeners;
  774. results = [];
  775. for (j = 0, len = ref.length; j < len; j++) {
  776. elementListeners = ref[j];
  777. results.push((function() {
  778. var ref1, results1;
  779. ref1 = elementListeners.events;
  780. results1 = [];
  781. for (event in ref1) {
  782. listener = ref1[event];
  783. results1.push(elementListeners.element.addEventListener(event, listener, false));
  784. }
  785. return results1;
  786. })());
  787. }
  788. return results;
  789. };
  790. Dropzone.prototype.removeEventListeners = function() {
  791. var elementListeners, event, j, len, listener, ref, results;
  792. ref = this.listeners;
  793. results = [];
  794. for (j = 0, len = ref.length; j < len; j++) {
  795. elementListeners = ref[j];
  796. results.push((function() {
  797. var ref1, results1;
  798. ref1 = elementListeners.events;
  799. results1 = [];
  800. for (event in ref1) {
  801. listener = ref1[event];
  802. results1.push(elementListeners.element.removeEventListener(event, listener, false));
  803. }
  804. return results1;
  805. })());
  806. }
  807. return results;
  808. };
  809. Dropzone.prototype.disable = function() {
  810. var file, j, len, ref, results;
  811. this.clickableElements.forEach(function(element) {
  812. return element.classList.remove("dz-clickable");
  813. });
  814. this.removeEventListeners();
  815. ref = this.files;
  816. results = [];
  817. for (j = 0, len = ref.length; j < len; j++) {
  818. file = ref[j];
  819. results.push(this.cancelUpload(file));
  820. }
  821. return results;
  822. };
  823. Dropzone.prototype.enable = function() {
  824. this.clickableElements.forEach(function(element) {
  825. return element.classList.add("dz-clickable");
  826. });
  827. return this.setupEventListeners();
  828. };
  829. Dropzone.prototype.filesize = function(size) {
  830. var cutoff, i, j, len, selectedSize, selectedUnit, unit, units;
  831. selectedSize = 0;
  832. selectedUnit = "b";
  833. if (size > 0) {
  834. units = ['tb', 'gb', 'mb', 'kb', 'b'];
  835. for (i = j = 0, len = units.length; j < len; i = ++j) {
  836. unit = units[i];
  837. cutoff = Math.pow(this.options.filesizeBase, 4 - i) / 10;
  838. if (size >= cutoff) {
  839. selectedSize = size / Math.pow(this.options.filesizeBase, 4 - i);
  840. selectedUnit = unit;
  841. break;
  842. }
  843. }
  844. selectedSize = Math.round(10 * selectedSize) / 10;
  845. }
  846. return "<strong>" + selectedSize + "</strong> " + this.options.dictFileSizeUnits[selectedUnit];
  847. };
  848. Dropzone.prototype._updateMaxFilesReachedClass = function() {
  849. if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {
  850. if (this.getAcceptedFiles().length === this.options.maxFiles) {
  851. this.emit('maxfilesreached', this.files);
  852. }
  853. return this.element.classList.add("dz-max-files-reached");
  854. } else {
  855. return this.element.classList.remove("dz-max-files-reached");
  856. }
  857. };
  858. Dropzone.prototype.drop = function(e) {
  859. var files, items;
  860. if (!e.dataTransfer) {
  861. return;
  862. }
  863. this.emit("drop", e);
  864. files = e.dataTransfer.files;
  865. this.emit("addedfiles", files);
  866. if (files.length) {
  867. items = e.dataTransfer.items;
  868. if (items && items.length && (items[0].webkitGetAsEntry != null)) {
  869. this._addFilesFromItems(items);
  870. } else {
  871. this.handleFiles(files);
  872. }
  873. }
  874. };
  875. Dropzone.prototype.paste = function(e) {
  876. var items, ref;
  877. if ((e != null ? (ref = e.clipboardData) != null ? ref.items : void 0 : void 0) == null) {
  878. return;
  879. }
  880. this.emit("paste", e);
  881. items = e.clipboardData.items;
  882. if (items.length) {
  883. return this._addFilesFromItems(items);
  884. }
  885. };
  886. Dropzone.prototype.handleFiles = function(files) {
  887. var file, j, len, results;
  888. results = [];
  889. for (j = 0, len = files.length; j < len; j++) {
  890. file = files[j];
  891. results.push(this.addFile(file));
  892. }
  893. return results;
  894. };
  895. Dropzone.prototype._addFilesFromItems = function(items) {
  896. var entry, item, j, len, results;
  897. results = [];
  898. for (j = 0, len = items.length; j < len; j++) {
  899. item = items[j];
  900. if ((item.webkitGetAsEntry != null) && (entry = item.webkitGetAsEntry())) {
  901. if (entry.isFile) {
  902. results.push(this.addFile(item.getAsFile()));
  903. } else if (entry.isDirectory) {
  904. results.push(this._addFilesFromDirectory(entry, entry.name));
  905. } else {
  906. results.push(void 0);
  907. }
  908. } else if (item.getAsFile != null) {
  909. if ((item.kind == null) || item.kind === "file") {
  910. results.push(this.addFile(item.getAsFile()));
  911. } else {
  912. results.push(void 0);
  913. }
  914. } else {
  915. results.push(void 0);
  916. }
  917. }
  918. return results;
  919. };
  920. Dropzone.prototype._addFilesFromDirectory = function(directory, path) {
  921. var dirReader, errorHandler, readEntries;
  922. dirReader = directory.createReader();
  923. errorHandler = function(error) {
  924. return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(error) : void 0 : void 0;
  925. };
  926. readEntries = (function(_this) {
  927. return function() {
  928. return dirReader.readEntries(function(entries) {
  929. var entry, j, len;
  930. if (entries.length > 0) {
  931. for (j = 0, len = entries.length; j < len; j++) {
  932. entry = entries[j];
  933. if (entry.isFile) {
  934. entry.file(function(file) {
  935. if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') {
  936. return;
  937. }
  938. file.fullPath = path + "/" + file.name;
  939. return _this.addFile(file);
  940. });
  941. } else if (entry.isDirectory) {
  942. _this._addFilesFromDirectory(entry, path + "/" + entry.name);
  943. }
  944. }
  945. readEntries();
  946. }
  947. return null;
  948. }, errorHandler);
  949. };
  950. })(this);
  951. return readEntries();
  952. };
  953. Dropzone.prototype.accept = function(file, done) {
  954. if (file.size > this.options.maxFilesize * 1024 * 1024) {
  955. return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize));
  956. } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) {
  957. return done(this.options.dictInvalidFileType);
  958. } else if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) {
  959. done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles));
  960. return this.emit("maxfilesexceeded", file);
  961. } else {
  962. return this.options.accept.call(this, file, done);
  963. }
  964. };
  965. Dropzone.prototype.addFile = function(file) {
  966. file.upload = {
  967. progress: 0,
  968. total: file.size,
  969. bytesSent: 0,
  970. filename: this._renameFile(file)
  971. };
  972. this.files.push(file);
  973. file.status = Dropzone.ADDED;
  974. this.emit("addedfile", file);
  975. this._enqueueThumbnail(file);
  976. return this.accept(file, (function(_this) {
  977. return function(error) {
  978. if (error) {
  979. file.accepted = false;
  980. _this._errorProcessing([file], error);
  981. } else {
  982. file.accepted = true;
  983. if (_this.options.autoQueue) {
  984. _this.enqueueFile(file);
  985. }
  986. }
  987. return _this._updateMaxFilesReachedClass();
  988. };
  989. })(this));
  990. };
  991. Dropzone.prototype.enqueueFiles = function(files) {
  992. var file, j, len;
  993. for (j = 0, len = files.length; j < len; j++) {
  994. file = files[j];
  995. this.enqueueFile(file);
  996. }
  997. return null;
  998. };
  999. Dropzone.prototype.enqueueFile = function(file) {
  1000. if (file.status === Dropzone.ADDED && file.accepted === true) {
  1001. file.status = Dropzone.QUEUED;
  1002. if (this.options.autoProcessQueue) {
  1003. return setTimeout(((function(_this) {
  1004. return function() {
  1005. return _this.processQueue();
  1006. };
  1007. })(this)), 0);
  1008. }
  1009. } else {
  1010. throw new Error("This file can't be queued because it has already been processed or was rejected.");
  1011. }
  1012. };
  1013. Dropzone.prototype._thumbnailQueue = [];
  1014. Dropzone.prototype._processingThumbnail = false;
  1015. Dropzone.prototype._enqueueThumbnail = function(file) {
  1016. if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) {
  1017. this._thumbnailQueue.push(file);
  1018. return setTimeout(((function(_this) {
  1019. return function() {
  1020. return _this._processThumbnailQueue();
  1021. };
  1022. })(this)), 0);
  1023. }
  1024. };
  1025. Dropzone.prototype._processThumbnailQueue = function() {
  1026. var file;
  1027. if (this._processingThumbnail || this._thumbnailQueue.length === 0) {
  1028. return;
  1029. }
  1030. this._processingThumbnail = true;
  1031. file = this._thumbnailQueue.shift();
  1032. return this.createThumbnail(file, this.options.thumbnailWidth, this.options.thumbnailHeight, this.options.thumbnailMethod, true, (function(_this) {
  1033. return function(dataUrl) {
  1034. _this.emit("thumbnail", file, dataUrl);
  1035. _this._processingThumbnail = false;
  1036. return _this._processThumbnailQueue();
  1037. };
  1038. })(this));
  1039. };
  1040. Dropzone.prototype.removeFile = function(file) {
  1041. if (file.status === Dropzone.UPLOADING) {
  1042. this.cancelUpload(file);
  1043. }
  1044. this.files = without(this.files, file);
  1045. this.emit("removedfile", file);
  1046. if (this.files.length === 0) {
  1047. return this.emit("reset");
  1048. }
  1049. };
  1050. Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) {
  1051. var file, j, len, ref;
  1052. if (cancelIfNecessary == null) {
  1053. cancelIfNecessary = false;
  1054. }
  1055. ref = this.files.slice();
  1056. for (j = 0, len = ref.length; j < len; j++) {
  1057. file = ref[j];
  1058. if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) {
  1059. this.removeFile(file);
  1060. }
  1061. }
  1062. return null;
  1063. };
  1064. Dropzone.prototype.resizeImage = function(file, width, height, resizeMethod, callback) {
  1065. return this.createThumbnail(file, width, height, resizeMethod, false, (function(_this) {
  1066. return function(dataUrl, canvas) {
  1067. var resizeMimeType, resizedDataURL;
  1068. if (canvas === null) {
  1069. return callback(file);
  1070. } else {
  1071. resizeMimeType = _this.options.resizeMimeType;
  1072. if (resizeMimeType == null) {
  1073. resizeMimeType = file.type;
  1074. }
  1075. resizedDataURL = canvas.toDataURL(resizeMimeType, _this.options.resizeQuality);
  1076. if (resizeMimeType === 'image/jpeg' || resizeMimeType === 'image/jpg') {
  1077. resizedDataURL = ExifRestore.restore(file.dataURL, resizedDataURL);
  1078. }
  1079. return callback(Dropzone.dataURItoBlob(resizedDataURL));
  1080. }
  1081. };
  1082. })(this));
  1083. };
  1084. Dropzone.prototype.createThumbnail = function(file, width, height, resizeMethod, fixOrientation, callback) {
  1085. var fileReader;
  1086. fileReader = new FileReader;
  1087. fileReader.onload = (function(_this) {
  1088. return function() {
  1089. file.dataURL = fileReader.result;
  1090. if (file.type === "image/svg+xml") {
  1091. if (callback != null) {
  1092. callback(fileReader.result);
  1093. }
  1094. return;
  1095. }
  1096. return _this.createThumbnailFromUrl(file, width, height, resizeMethod, fixOrientation, callback);
  1097. };
  1098. })(this);
  1099. return fileReader.readAsDataURL(file);
  1100. };
  1101. Dropzone.prototype.createThumbnailFromUrl = function(file, width, height, resizeMethod, fixOrientation, callback, crossOrigin) {
  1102. var img;
  1103. img = document.createElement("img");
  1104. if (crossOrigin) {
  1105. img.crossOrigin = crossOrigin;
  1106. }
  1107. img.onload = (function(_this) {
  1108. return function() {
  1109. var loadExif;
  1110. loadExif = function(callback) {
  1111. return callback(1);
  1112. };
  1113. if ((typeof EXIF !== "undefined" && EXIF !== null) && fixOrientation) {
  1114. loadExif = function(callback) {
  1115. return EXIF.getData(img, function() {
  1116. return callback(EXIF.getTag(this, 'Orientation'));
  1117. });
  1118. };
  1119. }
  1120. return loadExif(function(orientation) {
  1121. var canvas, ctx, ref, ref1, ref2, ref3, resizeInfo, thumbnail;
  1122. file.width = img.width;
  1123. file.height = img.height;
  1124. resizeInfo = _this.options.resize.call(_this, file, width, height, resizeMethod);
  1125. canvas = document.createElement("canvas");
  1126. ctx = canvas.getContext("2d");
  1127. canvas.width = resizeInfo.trgWidth;
  1128. canvas.height = resizeInfo.trgHeight;
  1129. if (orientation > 4) {
  1130. canvas.width = resizeInfo.trgHeight;
  1131. canvas.height = resizeInfo.trgWidth;
  1132. }
  1133. switch (orientation) {
  1134. case 2:
  1135. ctx.translate(canvas.width, 0);
  1136. ctx.scale(-1, 1);
  1137. break;
  1138. case 3:
  1139. ctx.translate(canvas.width, canvas.height);
  1140. ctx.rotate(Math.PI);
  1141. break;
  1142. case 4:
  1143. ctx.translate(0, canvas.height);
  1144. ctx.scale(1, -1);
  1145. break;
  1146. case 5:
  1147. ctx.rotate(0.5 * Math.PI);
  1148. ctx.scale(1, -1);
  1149. break;
  1150. case 6:
  1151. ctx.rotate(0.5 * Math.PI);
  1152. ctx.translate(0, -canvas.height);
  1153. break;
  1154. case 7:
  1155. ctx.rotate(0.5 * Math.PI);
  1156. ctx.translate(canvas.width, -canvas.height);
  1157. ctx.scale(-1, 1);
  1158. break;
  1159. case 8:
  1160. ctx.rotate(-0.5 * Math.PI);
  1161. ctx.translate(-canvas.width, 0);
  1162. }
  1163. drawImageIOSFix(ctx, img, (ref = resizeInfo.srcX) != null ? ref : 0, (ref1 = resizeInfo.srcY) != null ? ref1 : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, (ref2 = resizeInfo.trgX) != null ? ref2 : 0, (ref3 = resizeInfo.trgY) != null ? ref3 : 0, resizeInfo.trgWidth, resizeInfo.trgHeight);
  1164. thumbnail = canvas.toDataURL("image/png");
  1165. if (callback != null) {
  1166. return callback(thumbnail, canvas);
  1167. }
  1168. });
  1169. };
  1170. })(this);
  1171. if (callback != null) {
  1172. img.onerror = callback;
  1173. }
  1174. return img.src = file.dataURL;
  1175. };
  1176. Dropzone.prototype.processQueue = function() {
  1177. var i, parallelUploads, processingLength, queuedFiles;
  1178. parallelUploads = this.options.parallelUploads;
  1179. processingLength = this.getUploadingFiles().length;
  1180. i = processingLength;
  1181. if (processingLength >= parallelUploads) {
  1182. return;
  1183. }
  1184. queuedFiles = this.getQueuedFiles();
  1185. if (!(queuedFiles.length > 0)) {
  1186. return;
  1187. }
  1188. if (this.options.uploadMultiple) {
  1189. return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength));
  1190. } else {
  1191. while (i < parallelUploads) {
  1192. if (!queuedFiles.length) {
  1193. return;
  1194. }
  1195. this.processFile(queuedFiles.shift());
  1196. i++;
  1197. }
  1198. }
  1199. };
  1200. Dropzone.prototype.processFile = function(file) {
  1201. return this.processFiles([file]);
  1202. };
  1203. Dropzone.prototype.processFiles = function(files) {
  1204. var file, j, len;
  1205. for (j = 0, len = files.length; j < len; j++) {
  1206. file = files[j];
  1207. file.processing = true;
  1208. file.status = Dropzone.UPLOADING;
  1209. this.emit("processing", file);
  1210. }
  1211. if (this.options.uploadMultiple) {
  1212. this.emit("processingmultiple", files);
  1213. }
  1214. return this.uploadFiles(files);
  1215. };
  1216. Dropzone.prototype._getFilesWithXhr = function(xhr) {
  1217. var file, files;
  1218. return files = (function() {
  1219. var j, len, ref, results;
  1220. ref = this.files;
  1221. results = [];
  1222. for (j = 0, len = ref.length; j < len; j++) {
  1223. file = ref[j];
  1224. if (file.xhr === xhr) {
  1225. results.push(file);
  1226. }
  1227. }
  1228. return results;
  1229. }).call(this);
  1230. };
  1231. Dropzone.prototype.cancelUpload = function(file) {
  1232. var groupedFile, groupedFiles, j, k, len, len1, ref;
  1233. if (file.status === Dropzone.UPLOADING) {
  1234. groupedFiles = this._getFilesWithXhr(file.xhr);
  1235. for (j = 0, len = groupedFiles.length; j < len; j++) {
  1236. groupedFile = groupedFiles[j];
  1237. groupedFile.status = Dropzone.CANCELED;
  1238. }
  1239. file.xhr.abort();
  1240. for (k = 0, len1 = groupedFiles.length; k < len1; k++) {
  1241. groupedFile = groupedFiles[k];
  1242. this.emit("canceled", groupedFile);
  1243. }
  1244. if (this.options.uploadMultiple) {
  1245. this.emit("canceledmultiple", groupedFiles);
  1246. }
  1247. } else if ((ref = file.status) === Dropzone.ADDED || ref === Dropzone.QUEUED) {
  1248. file.status = Dropzone.CANCELED;
  1249. this.emit("canceled", file);
  1250. if (this.options.uploadMultiple) {
  1251. this.emit("canceledmultiple", [file]);
  1252. }
  1253. }
  1254. if (this.options.autoProcessQueue) {
  1255. return this.processQueue();
  1256. }
  1257. };
  1258. resolveOption = function() {
  1259. var args, option;
  1260. option = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
  1261. if (typeof option === 'function') {
  1262. return option.apply(this, args);
  1263. }
  1264. return option;
  1265. };
  1266. Dropzone.prototype.uploadFile = function(file) {
  1267. return this.uploadFiles([file]);
  1268. };
  1269. Dropzone.prototype.uploadFiles = function(files) {
  1270. var doneCounter, doneFunction, file, formData, handleError, headerName, headerValue, headers, i, input, inputName, inputType, j, k, key, l, len, len1, len2, len3, m, method, o, option, progressObj, ref, ref1, ref2, ref3, ref4, ref5, response, results, updateProgress, url, value, xhr;
  1271. xhr = new XMLHttpRequest();
  1272. for (j = 0, len = files.length; j < len; j++) {
  1273. file = files[j];
  1274. file.xhr = xhr;
  1275. }
  1276. method = resolveOption(this.options.method, files);
  1277. url = resolveOption(this.options.url, files);
  1278. xhr.open(method, url, true);
  1279. xhr.timeout = resolveOption(this.options.timeout, files);
  1280. xhr.withCredentials = !!this.options.withCredentials;
  1281. response = null;
  1282. handleError = (function(_this) {
  1283. return function() {
  1284. var k, len1, results;
  1285. results = [];
  1286. for (k = 0, len1 = files.length; k < len1; k++) {
  1287. file = files[k];
  1288. results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr));
  1289. }
  1290. return results;
  1291. };
  1292. })(this);
  1293. updateProgress = (function(_this) {
  1294. return function(e) {
  1295. var allFilesFinished, k, l, len1, len2, len3, m, progress, results;
  1296. if (e != null) {
  1297. progress = 100 * e.loaded / e.total;
  1298. for (k = 0, len1 = files.length; k < len1; k++) {
  1299. file = files[k];
  1300. file.upload.progress = progress;
  1301. file.upload.total = e.total;
  1302. file.upload.bytesSent = e.loaded;
  1303. }
  1304. } else {
  1305. allFilesFinished = true;
  1306. progress = 100;
  1307. for (l = 0, len2 = files.length; l < len2; l++) {
  1308. file = files[l];
  1309. if (!(file.upload.progress === 100 && file.upload.bytesSent === file.upload.total)) {
  1310. allFilesFinished = false;
  1311. }
  1312. file.upload.progress = progress;
  1313. file.upload.bytesSent = file.upload.total;
  1314. }
  1315. if (allFilesFinished) {
  1316. return;
  1317. }
  1318. }
  1319. results = [];
  1320. for (m = 0, len3 = files.length; m < len3; m++) {
  1321. file = files[m];
  1322. results.push(_this.emit("uploadprogress", file, progress, file.upload.bytesSent));
  1323. }
  1324. return results;
  1325. };
  1326. })(this);
  1327. xhr.onload = (function(_this) {
  1328. return function(e) {
  1329. var error1, ref;
  1330. if (files[0].status === Dropzone.CANCELED) {
  1331. return;
  1332. }
  1333. if (xhr.readyState !== 4) {
  1334. return;
  1335. }
  1336. if (xhr.responseType !== 'arraybuffer' && xhr.responseType !== 'blob') {
  1337. response = xhr.responseText;
  1338. if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) {
  1339. try {
  1340. response = JSON.parse(response);
  1341. } catch (error1) {
  1342. e = error1;
  1343. response = "Invalid JSON response from server.";
  1344. }
  1345. }
  1346. }
  1347. updateProgress();
  1348. if (!((200 <= (ref = xhr.status) && ref < 300))) {
  1349. return handleError();
  1350. } else {
  1351. return _this._finished(files, response, e);
  1352. }
  1353. };
  1354. })(this);
  1355. xhr.onerror = (function(_this) {
  1356. return function() {
  1357. if (files[0].status === Dropzone.CANCELED) {
  1358. return;
  1359. }
  1360. return handleError();
  1361. };
  1362. })(this);
  1363. progressObj = (ref = xhr.upload) != null ? ref : xhr;
  1364. progressObj.onprogress = updateProgress;
  1365. headers = {
  1366. "Accept": "application/json",
  1367. "Cache-Control": "no-cache",
  1368. "X-Requested-With": "XMLHttpRequest"
  1369. };
  1370. if (this.options.headers) {
  1371. extend(headers, this.options.headers);
  1372. }
  1373. for (headerName in headers) {
  1374. headerValue = headers[headerName];
  1375. if (headerValue) {
  1376. xhr.setRequestHeader(headerName, headerValue);
  1377. }
  1378. }
  1379. formData = new FormData();
  1380. if (this.options.params) {
  1381. ref1 = this.options.params;
  1382. for (key in ref1) {
  1383. value = ref1[key];
  1384. formData.append(key, value);
  1385. }
  1386. }
  1387. for (k = 0, len1 = files.length; k < len1; k++) {
  1388. file = files[k];
  1389. this.emit("sending", file, xhr, formData);
  1390. }
  1391. if (this.options.uploadMultiple) {
  1392. this.emit("sendingmultiple", files, xhr, formData);
  1393. }
  1394. if (this.element.tagName === "FORM") {
  1395. ref2 = this.element.querySelectorAll("input, textarea, select, button");
  1396. for (l = 0, len2 = ref2.length; l < len2; l++) {
  1397. input = ref2[l];
  1398. inputName = input.getAttribute("name");
  1399. inputType = input.getAttribute("type");
  1400. if (input.tagName === "SELECT" && input.hasAttribute("multiple")) {
  1401. ref3 = input.options;
  1402. for (m = 0, len3 = ref3.length; m < len3; m++) {
  1403. option = ref3[m];
  1404. if (option.selected) {
  1405. formData.append(inputName, option.value);
  1406. }
  1407. }
  1408. } else if (!inputType || ((ref4 = inputType.toLowerCase()) !== "checkbox" && ref4 !== "radio") || input.checked) {
  1409. formData.append(inputName, input.value);
  1410. }
  1411. }
  1412. }
  1413. doneCounter = 0;
  1414. results = [];
  1415. for (i = o = 0, ref5 = files.length - 1; 0 <= ref5 ? o <= ref5 : o >= ref5; i = 0 <= ref5 ? ++o : --o) {
  1416. doneFunction = (function(_this) {
  1417. return function(file, paramName, fileName) {
  1418. return function(transformedFile) {
  1419. formData.append(paramName, transformedFile, fileName);
  1420. if (++doneCounter === files.length) {
  1421. return _this.submitRequest(xhr, formData, files);
  1422. }
  1423. };
  1424. };
  1425. })(this);
  1426. results.push(this.options.transformFile.call(this, files[i], doneFunction(files[i], this._getParamName(i), files[i].upload.filename)));
  1427. }
  1428. return results;
  1429. };
  1430. Dropzone.prototype.submitRequest = function(xhr, formData, files) {
  1431. return xhr.send(formData);
  1432. };
  1433. Dropzone.prototype._finished = function(files, responseText, e) {
  1434. var file, j, len;
  1435. for (j = 0, len = files.length; j < len; j++) {
  1436. file = files[j];
  1437. file.status = Dropzone.SUCCESS;
  1438. this.emit("success", file, responseText, e);
  1439. this.emit("complete", file);
  1440. }
  1441. if (this.options.uploadMultiple) {
  1442. this.emit("successmultiple", files, responseText, e);
  1443. this.emit("completemultiple", files);
  1444. }
  1445. if (this.options.autoProcessQueue) {
  1446. return this.processQueue();
  1447. }
  1448. };
  1449. Dropzone.prototype._errorProcessing = function(files, message, xhr) {
  1450. var file, j, len;
  1451. for (j = 0, len = files.length; j < len; j++) {
  1452. file = files[j];
  1453. file.status = Dropzone.ERROR;
  1454. this.emit("error", file, message, xhr);
  1455. this.emit("complete", file);
  1456. }
  1457. if (this.options.uploadMultiple) {
  1458. this.emit("errormultiple", files, message, xhr);
  1459. this.emit("completemultiple", files);
  1460. }
  1461. if (this.options.autoProcessQueue) {
  1462. return this.processQueue();
  1463. }
  1464. };
  1465. return Dropzone;
  1466. })(Emitter);
  1467. Dropzone.version = "5.1.1";
  1468. Dropzone.options = {};
  1469. Dropzone.optionsForElement = function(element) {
  1470. if (element.getAttribute("id")) {
  1471. return Dropzone.options[camelize(element.getAttribute("id"))];
  1472. } else {
  1473. return void 0;
  1474. }
  1475. };
  1476. Dropzone.instances = [];
  1477. Dropzone.forElement = function(element) {
  1478. if (typeof element === "string") {
  1479. element = document.querySelector(element);
  1480. }
  1481. if ((element != null ? element.dropzone : void 0) == null) {
  1482. throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone.");
  1483. }
  1484. return element.dropzone;
  1485. };
  1486. Dropzone.autoDiscover = true;
  1487. Dropzone.discover = function() {
  1488. var checkElements, dropzone, dropzones, j, len, results;
  1489. if (document.querySelectorAll) {
  1490. dropzones = document.querySelectorAll(".dropzone");
  1491. } else {
  1492. dropzones = [];
  1493. checkElements = function(elements) {
  1494. var el, j, len, results;
  1495. results = [];
  1496. for (j = 0, len = elements.length; j < len; j++) {
  1497. el = elements[j];
  1498. if (/(^| )dropzone($| )/.test(el.className)) {
  1499. results.push(dropzones.push(el));
  1500. } else {
  1501. results.push(void 0);
  1502. }
  1503. }
  1504. return results;
  1505. };
  1506. checkElements(document.getElementsByTagName("div"));
  1507. checkElements(document.getElementsByTagName("form"));
  1508. }
  1509. results = [];
  1510. for (j = 0, len = dropzones.length; j < len; j++) {
  1511. dropzone = dropzones[j];
  1512. if (Dropzone.optionsForElement(dropzone) !== false) {
  1513. results.push(new Dropzone(dropzone));
  1514. } else {
  1515. results.push(void 0);
  1516. }
  1517. }
  1518. return results;
  1519. };
  1520. Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i];
  1521. Dropzone.isBrowserSupported = function() {
  1522. var capableBrowser, j, len, ref, regex;
  1523. capableBrowser = true;
  1524. if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) {
  1525. if (!("classList" in document.createElement("a"))) {
  1526. capableBrowser = false;
  1527. } else {
  1528. ref = Dropzone.blacklistedBrowsers;
  1529. for (j = 0, len = ref.length; j < len; j++) {
  1530. regex = ref[j];
  1531. if (regex.test(navigator.userAgent)) {
  1532. capableBrowser = false;
  1533. continue;
  1534. }
  1535. }
  1536. }
  1537. } else {
  1538. capableBrowser = false;
  1539. }
  1540. return capableBrowser;
  1541. };
  1542. Dropzone.dataURItoBlob = function(dataURI) {
  1543. var ab, byteString, i, ia, j, mimeString, ref;
  1544. byteString = atob(dataURI.split(',')[1]);
  1545. mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
  1546. ab = new ArrayBuffer(byteString.length);
  1547. ia = new Uint8Array(ab);
  1548. for (i = j = 0, ref = byteString.length; 0 <= ref ? j <= ref : j >= ref; i = 0 <= ref ? ++j : --j) {
  1549. ia[i] = byteString.charCodeAt(i);
  1550. }
  1551. return new Blob([ab], {
  1552. type: mimeString
  1553. });
  1554. };
  1555. without = function(list, rejectedItem) {
  1556. var item, j, len, results;
  1557. results = [];
  1558. for (j = 0, len = list.length; j < len; j++) {
  1559. item = list[j];
  1560. if (item !== rejectedItem) {
  1561. results.push(item);
  1562. }
  1563. }
  1564. return results;
  1565. };
  1566. camelize = function(str) {
  1567. return str.replace(/[\-_](\w)/g, function(match) {
  1568. return match.charAt(1).toUpperCase();
  1569. });
  1570. };
  1571. Dropzone.createElement = function(string) {
  1572. var div;
  1573. div = document.createElement("div");
  1574. div.innerHTML = string;
  1575. return div.childNodes[0];
  1576. };
  1577. Dropzone.elementInside = function(element, container) {
  1578. if (element === container) {
  1579. return true;
  1580. }
  1581. while (element = element.parentNode) {
  1582. if (element === container) {
  1583. return true;
  1584. }
  1585. }
  1586. return false;
  1587. };
  1588. Dropzone.getElement = function(el, name) {
  1589. var element;
  1590. if (typeof el === "string") {
  1591. element = document.querySelector(el);
  1592. } else if (el.nodeType != null) {
  1593. element = el;
  1594. }
  1595. if (element == null) {
  1596. throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element.");
  1597. }
  1598. return element;
  1599. };
  1600. Dropzone.getElements = function(els, name) {
  1601. var e, el, elements, error1, j, k, len, len1, ref;
  1602. if (els instanceof Array) {
  1603. elements = [];
  1604. try {
  1605. for (j = 0, len = els.length; j < len; j++) {
  1606. el = els[j];
  1607. elements.push(this.getElement(el, name));
  1608. }
  1609. } catch (error1) {
  1610. e = error1;
  1611. elements = null;
  1612. }
  1613. } else if (typeof els === "string") {
  1614. elements = [];
  1615. ref = document.querySelectorAll(els);
  1616. for (k = 0, len1 = ref.length; k < len1; k++) {
  1617. el = ref[k];
  1618. elements.push(el);
  1619. }
  1620. } else if (els.nodeType != null) {
  1621. elements = [els];
  1622. }
  1623. if (!((elements != null) && elements.length)) {
  1624. throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those.");
  1625. }
  1626. return elements;
  1627. };
  1628. Dropzone.confirm = function(question, accepted, rejected) {
  1629. if (window.confirm(question)) {
  1630. return accepted();
  1631. } else if (rejected != null) {
  1632. return rejected();
  1633. }
  1634. };
  1635. Dropzone.isValidFile = function(file, acceptedFiles) {
  1636. var baseMimeType, j, len, mimeType, validType;
  1637. if (!acceptedFiles) {
  1638. return true;
  1639. }
  1640. acceptedFiles = acceptedFiles.split(",");
  1641. mimeType = file.type;
  1642. baseMimeType = mimeType.replace(/\/.*$/, "");
  1643. for (j = 0, len = acceptedFiles.length; j < len; j++) {
  1644. validType = acceptedFiles[j];
  1645. validType = validType.trim();
  1646. if (validType.charAt(0) === ".") {
  1647. if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) {
  1648. return true;
  1649. }
  1650. } else if (/\/\*$/.test(validType)) {
  1651. if (baseMimeType === validType.replace(/\/.*$/, "")) {
  1652. return true;
  1653. }
  1654. } else {
  1655. if (mimeType === validType) {
  1656. return true;
  1657. }
  1658. }
  1659. }
  1660. return false;
  1661. };
  1662. if (typeof jQuery !== "undefined" && jQuery !== null) {
  1663. jQuery.fn.dropzone = function(options) {
  1664. return this.each(function() {
  1665. return new Dropzone(this, options);
  1666. });
  1667. };
  1668. }
  1669. if (typeof module !== "undefined" && module !== null) {
  1670. module.exports = Dropzone;
  1671. } else {
  1672. window.Dropzone = Dropzone;
  1673. }
  1674. Dropzone.ADDED = "added";
  1675. Dropzone.QUEUED = "queued";
  1676. Dropzone.ACCEPTED = Dropzone.QUEUED;
  1677. Dropzone.UPLOADING = "uploading";
  1678. Dropzone.PROCESSING = Dropzone.UPLOADING;
  1679. Dropzone.CANCELED = "canceled";
  1680. Dropzone.ERROR = "error";
  1681. Dropzone.SUCCESS = "success";
  1682. /*
  1683. Bugfix for iOS 6 and 7
  1684. Source: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios
  1685. based on the work of https://github.com/stomita/ios-imagefile-megapixel
  1686. */
  1687. detectVerticalSquash = function(img) {
  1688. var alpha, canvas, ctx, data, ey, ih, iw, py, ratio, sy;
  1689. iw = img.naturalWidth;
  1690. ih = img.naturalHeight;
  1691. canvas = document.createElement("canvas");
  1692. canvas.width = 1;
  1693. canvas.height = ih;
  1694. ctx = canvas.getContext("2d");
  1695. ctx.drawImage(img, 0, 0);
  1696. data = ctx.getImageData(1, 0, 1, ih).data;
  1697. sy = 0;
  1698. ey = ih;
  1699. py = ih;
  1700. while (py > sy) {
  1701. alpha = data[(py - 1) * 4 + 3];
  1702. if (alpha === 0) {
  1703. ey = py;
  1704. } else {
  1705. sy = py;
  1706. }
  1707. py = (ey + sy) >> 1;
  1708. }
  1709. ratio = py / ih;
  1710. if (ratio === 0) {
  1711. return 1;
  1712. } else {
  1713. return ratio;
  1714. }
  1715. };
  1716. drawImageIOSFix = function(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {
  1717. var vertSquashRatio;
  1718. vertSquashRatio = detectVerticalSquash(img);
  1719. return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);
  1720. };
  1721. ExifRestore = (function() {
  1722. function ExifRestore() {}
  1723. ExifRestore.KEY_STR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  1724. ExifRestore.encode64 = function(input) {
  1725. var chr1, chr2, chr3, enc1, enc2, enc3, enc4, i, output;
  1726. output = '';
  1727. chr1 = void 0;
  1728. chr2 = void 0;
  1729. chr3 = '';
  1730. enc1 = void 0;
  1731. enc2 = void 0;
  1732. enc3 = void 0;
  1733. enc4 = '';
  1734. i = 0;
  1735. while (true) {
  1736. chr1 = input[i++];
  1737. chr2 = input[i++];
  1738. chr3 = input[i++];
  1739. enc1 = chr1 >> 2;
  1740. enc2 = (chr1 & 3) << 4 | chr2 >> 4;
  1741. enc3 = (chr2 & 15) << 2 | chr3 >> 6;
  1742. enc4 = chr3 & 63;
  1743. if (isNaN(chr2)) {
  1744. enc3 = enc4 = 64;
  1745. } else if (isNaN(chr3)) {
  1746. enc4 = 64;
  1747. }
  1748. output = output + this.KEY_STR.charAt(enc1) + this.KEY_STR.charAt(enc2) + this.KEY_STR.charAt(enc3) + this.KEY_STR.charAt(enc4);
  1749. chr1 = chr2 = chr3 = '';
  1750. enc1 = enc2 = enc3 = enc4 = '';
  1751. if (!(i < input.length)) {
  1752. break;
  1753. }
  1754. }
  1755. return output;
  1756. };
  1757. ExifRestore.restore = function(origFileBase64, resizedFileBase64) {
  1758. var image, rawImage, segments;
  1759. if (!origFileBase64.match('data:image/jpeg;base64,')) {
  1760. return resizedFileBase64;
  1761. }
  1762. rawImage = this.decode64(origFileBase64.replace('data:image/jpeg;base64,', ''));
  1763. segments = this.slice2Segments(rawImage);
  1764. image = this.exifManipulation(resizedFileBase64, segments);
  1765. return 'data:image/jpeg;base64,' + this.encode64(image);
  1766. };
  1767. ExifRestore.exifManipulation = function(resizedFileBase64, segments) {
  1768. var aBuffer, exifArray, newImageArray;
  1769. exifArray = this.getExifArray(segments);
  1770. newImageArray = this.insertExif(resizedFileBase64, exifArray);
  1771. aBuffer = new Uint8Array(newImageArray);
  1772. return aBuffer;
  1773. };
  1774. ExifRestore.getExifArray = function(segments) {
  1775. var seg, x;
  1776. seg = void 0;
  1777. x = 0;
  1778. while (x < segments.length) {
  1779. seg = segments[x];
  1780. if (seg[0] === 255 & seg[1] === 225) {
  1781. return seg;
  1782. }
  1783. x++;
  1784. }
  1785. return [];
  1786. };
  1787. ExifRestore.insertExif = function(resizedFileBase64, exifArray) {
  1788. var array, ato, buf, imageData, mae, separatePoint;
  1789. imageData = resizedFileBase64.replace('data:image/jpeg;base64,', '');
  1790. buf = this.decode64(imageData);
  1791. separatePoint = buf.indexOf(255, 3);
  1792. mae = buf.slice(0, separatePoint);
  1793. ato = buf.slice(separatePoint);
  1794. array = mae;
  1795. array = array.concat(exifArray);
  1796. array = array.concat(ato);
  1797. return array;
  1798. };
  1799. ExifRestore.slice2Segments = function(rawImageArray) {
  1800. var endPoint, head, length, seg, segments;
  1801. head = 0;
  1802. segments = [];
  1803. while (true) {
  1804. if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 218) {
  1805. break;
  1806. }
  1807. if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 216) {
  1808. head += 2;
  1809. } else {
  1810. length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3];
  1811. endPoint = head + length + 2;
  1812. seg = rawImageArray.slice(head, endPoint);
  1813. segments.push(seg);
  1814. head = endPoint;
  1815. }
  1816. if (head > rawImageArray.length) {
  1817. break;
  1818. }
  1819. }
  1820. return segments;
  1821. };
  1822. ExifRestore.decode64 = function(input) {
  1823. var base64test, buf, chr1, chr2, chr3, enc1, enc2, enc3, enc4, i, output;
  1824. output = '';
  1825. chr1 = void 0;
  1826. chr2 = void 0;
  1827. chr3 = '';
  1828. enc1 = void 0;
  1829. enc2 = void 0;
  1830. enc3 = void 0;
  1831. enc4 = '';
  1832. i = 0;
  1833. buf = [];
  1834. base64test = /[^A-Za-z0-9\+\/\=]/g;
  1835. if (base64test.exec(input)) {
  1836. console.warning('There were invalid base64 characters in the input text.\n' + 'Valid base64 characters are A-Z, a-z, 0-9, \'+\', \'/\',and \'=\'\n' + 'Expect errors in decoding.');
  1837. }
  1838. input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
  1839. while (true) {
  1840. enc1 = this.KEY_STR.indexOf(input.charAt(i++));
  1841. enc2 = this.KEY_STR.indexOf(input.charAt(i++));
  1842. enc3 = this.KEY_STR.indexOf(input.charAt(i++));
  1843. enc4 = this.KEY_STR.indexOf(input.charAt(i++));
  1844. chr1 = enc1 << 2 | enc2 >> 4;
  1845. chr2 = (enc2 & 15) << 4 | enc3 >> 2;
  1846. chr3 = (enc3 & 3) << 6 | enc4;
  1847. buf.push(chr1);
  1848. if (enc3 !== 64) {
  1849. buf.push(chr2);
  1850. }
  1851. if (enc4 !== 64) {
  1852. buf.push(chr3);
  1853. }
  1854. chr1 = chr2 = chr3 = '';
  1855. enc1 = enc2 = enc3 = enc4 = '';
  1856. if (!(i < input.length)) {
  1857. break;
  1858. }
  1859. }
  1860. return buf;
  1861. };
  1862. return ExifRestore;
  1863. })();
  1864. /*
  1865. * contentloaded.js
  1866. *
  1867. * Author: Diego Perini (diego.perini at gmail.com)
  1868. * Summary: cross-browser wrapper for DOMContentLoaded
  1869. * Updated: 20101020
  1870. * License: MIT
  1871. * Version: 1.2
  1872. *
  1873. * URL:
  1874. * http://javascript.nwbox.com/ContentLoaded/
  1875. * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE
  1876. */
  1877. contentLoaded = function(win, fn) {
  1878. var add, doc, done, init, poll, pre, rem, root, top;
  1879. done = false;
  1880. top = true;
  1881. doc = win.document;
  1882. root = doc.documentElement;
  1883. add = (doc.addEventListener ? "addEventListener" : "attachEvent");
  1884. rem = (doc.addEventListener ? "removeEventListener" : "detachEvent");
  1885. pre = (doc.addEventListener ? "" : "on");
  1886. init = function(e) {
  1887. if (e.type === "readystatechange" && doc.readyState !== "complete") {
  1888. return;
  1889. }
  1890. (e.type === "load" ? win : doc)[rem](pre + e.type, init, false);
  1891. if (!done && (done = true)) {
  1892. return fn.call(win, e.type || e);
  1893. }
  1894. };
  1895. poll = function() {
  1896. var e, error1;
  1897. try {
  1898. root.doScroll("left");
  1899. } catch (error1) {
  1900. e = error1;
  1901. setTimeout(poll, 50);
  1902. return;
  1903. }
  1904. return init("poll");
  1905. };
  1906. if (doc.readyState !== "complete") {
  1907. if (doc.createEventObject && root.doScroll) {
  1908. try {
  1909. top = !win.frameElement;
  1910. } catch (undefined) {}
  1911. if (top) {
  1912. poll();
  1913. }
  1914. }
  1915. doc[add](pre + "DOMContentLoaded", init, false);
  1916. doc[add](pre + "readystatechange", init, false);
  1917. return win[add](pre + "load", init, false);
  1918. }
  1919. };
  1920. Dropzone._autoDiscoverFunction = function() {
  1921. if (Dropzone.autoDiscover) {
  1922. return Dropzone.discover();
  1923. }
  1924. };
  1925. contentLoaded(window, Dropzone._autoDiscoverFunction);
  1926. }).call(this);