The version of vichan running on lainchan.org
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

193 lignes
4.9KB

  1. /*
  2. * file-selector.js - Add support for drag and drop file selection, and paste from clipboard on supported browsers.
  3. *
  4. * Usage:
  5. * $config['additional_javascript'][] = 'js/jquery.min.js';
  6. * $config['additional_javascript'][] = 'js/ajax.js';
  7. * $config['additional_javascript'][] = 'js/file-selector.js';
  8. */
  9. function init_file_selector(max_images) {
  10. $(document).ready(function () {
  11. // add options panel item
  12. if (window.Options && Options.get_tab('general')) {
  13. Options.extend_tab('general', '<label id="file-drag-drop"><input type="checkbox">' + _('Drag and drop file selection') + '</label>');
  14. $('#file-drag-drop>input').on('click', function() {
  15. if ($('#file-drag-drop>input').is(':checked')) {
  16. localStorage.file_dragdrop = 'true';
  17. } else {
  18. localStorage.file_dragdrop = 'false';
  19. }
  20. });
  21. if (typeof localStorage.file_dragdrop === 'undefined') localStorage.file_dragdrop = 'true';
  22. if (localStorage.file_dragdrop === 'true') $('#file-drag-drop>input').prop('checked', true);
  23. }
  24. });
  25. // disabled by user, or incompatible browser.
  26. if (localStorage.file_dragdrop == 'false' || !(window.URL.createObjectURL && window.File))
  27. return;
  28. // multipost not enabled
  29. if (typeof max_images == 'undefined') {
  30. var max_images = 1;
  31. }
  32. $('<div class="dropzone-wrap" style="display: none;">'+
  33. '<div class="dropzone" tabindex="0">'+
  34. '<div class="file-hint">'+_('Select/drop/paste files here')+'</div>'+
  35. '<div class="file-thumbs"></div>'+
  36. '</div>'+
  37. '</div>'+
  38. '</div>').prependTo('#upload td');
  39. var files = [];
  40. $('#upload_file').remove(); // remove the original file selector
  41. $('.dropzone-wrap').css('user-select', 'none').show(); // let jquery add browser specific prefix
  42. function addFile(file) {
  43. if (files.length == max_images)
  44. return;
  45. files.push(file);
  46. addThumb(file);
  47. }
  48. function removeFile(file) {
  49. files.splice(files.indexOf(file), 1);
  50. }
  51. function getThumbElement(file) {
  52. return $('.tmb-container').filter(function(){return($(this).data('file-ref')==file);});
  53. }
  54. function addThumb(file) {
  55. var fileName = (file.name.length < 24) ? file.name : file.name.substr(0, 22) + '…';
  56. var fileType = file.type.split('/')[0];
  57. var fileExt = file.type.split('/')[1];
  58. var $container = $('<div>')
  59. .addClass('tmb-container')
  60. .data('file-ref', file)
  61. .append(
  62. $('<div>').addClass('remove-btn').html('✖'),
  63. $('<div>').addClass('file-tmb'),
  64. $('<div>').addClass('tmb-filename').html(fileName)
  65. )
  66. .appendTo('.file-thumbs');
  67. var $fileThumb = $container.find('.file-tmb');
  68. if (fileType == 'image') {
  69. // if image file, generate thumbnail
  70. var objURL = window.URL.createObjectURL(file);
  71. $fileThumb.css('background-image', 'url('+ objURL +')');
  72. } else {
  73. $fileThumb.html('<span>' + fileExt.toUpperCase() + '</span>');
  74. }
  75. }
  76. $(document).on('ajax_before_post', function (e, formData) {
  77. for (var i=0; i<max_images; i++) {
  78. var key = 'file';
  79. if (i > 0) key += i + 1;
  80. if (typeof files[i] === 'undefined') break;
  81. formData.append(key, files[i]);
  82. }
  83. });
  84. // clear file queue and UI on success
  85. $(document).on('ajax_after_post', function () {
  86. files = [];
  87. $('.file-thumbs').empty();
  88. });
  89. var dragCounter = 0;
  90. var dropHandlers = {
  91. dragenter: function (e) {
  92. e.stopPropagation();
  93. e.preventDefault();
  94. if (dragCounter === 0) $('.dropzone').addClass('dragover');
  95. dragCounter++;
  96. },
  97. dragover: function (e) {
  98. // needed for webkit to work
  99. e.stopPropagation();
  100. e.preventDefault();
  101. },
  102. dragleave: function (e) {
  103. e.stopPropagation();
  104. e.preventDefault();
  105. dragCounter--;
  106. if (dragCounter === 0) $('.dropzone').removeClass('dragover');
  107. },
  108. drop: function (e) {
  109. e.stopPropagation();
  110. e.preventDefault();
  111. $('.dropzone').removeClass('dragover');
  112. dragCounter = 0;
  113. var fileList = e.originalEvent.dataTransfer.files;
  114. for (var i=0; i<fileList.length; i++) {
  115. addFile(fileList[i]);
  116. }
  117. }
  118. };
  119. // attach handlers
  120. $(document).on(dropHandlers);
  121. $(document).on('click', '.dropzone .remove-btn', function (e) {
  122. e.stopPropagation();
  123. var file = $(e.target).parent().data('file-ref');
  124. getThumbElement(file).remove();
  125. removeFile(file);
  126. });
  127. $(document).on('keypress click', '.dropzone', function (e) {
  128. e.stopPropagation();
  129. // accept mouse click or Enter
  130. if ((e.which != 1 || e.target.className != 'file-hint') &&
  131. e.which != 13)
  132. return;
  133. var $fileSelector = $('<input type="file" multiple>');
  134. $fileSelector.on('change', function (e) {
  135. if (this.files.length > 0) {
  136. for (var i=0; i<this.files.length; i++) {
  137. addFile(this.files[i]);
  138. }
  139. }
  140. $(this).remove();
  141. });
  142. $fileSelector.click();
  143. });
  144. $(document).on('paste', function (e) {
  145. var clipboard = e.originalEvent.clipboardData;
  146. if (typeof clipboard.items != 'undefined' && clipboard.items.length != 0) {
  147. //Webkit
  148. for (var i=0; i<clipboard.items.length; i++) {
  149. if (clipboard.items[i].kind != 'file')
  150. continue;
  151. //convert blob to file
  152. var file = new File([clipboard.items[i].getAsFile()], 'ClipboardImage.png', {type: 'image/png'});
  153. addFile(file);
  154. }
  155. }
  156. });
  157. }