DragDrop.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import Utils from '../core/Utils'
  2. import Plugin from './Plugin'
  3. import templateDragDrop from '../templates/dragdrop.js'
  4. /**
  5. * Drag & Drop plugin
  6. *
  7. */
  8. export default class DragDrop extends Plugin {
  9. constructor (core, opts) {
  10. super(core, opts)
  11. this.type = 'selecter'
  12. // set default options
  13. const defaultOptions = {
  14. autoSubmit: true
  15. }
  16. // merge default options with the ones set by user
  17. this.opts = Object.assign({}, defaultOptions, opts)
  18. this.isDragDropSupported = this.checkDragDropSupport()
  19. this.initHtml()
  20. // crazy stuff so that ‘this’ will behave in class
  21. this.listenForEvents = this.listenForEvents.bind(this)
  22. this.handleDrop = this.handleDrop.bind(this)
  23. this.checkDragDropSupport = this.checkDragDropSupport.bind(this)
  24. this.handleInputChange = this.handleInputChange.bind(this)
  25. }
  26. initHtml () {
  27. this.dragDropContainer = document.querySelectorAll('.UppyDragDrop')[0]
  28. this.dragDropContainer.innerHTML = templateDragDrop({
  29. endpoint: this.opts.endpoint,
  30. chooseFile: this.core.i18n('chooseFile'),
  31. orDragDrop: this.core.i18n('orDragDrop'),
  32. showUploadBtn: this.opts.autoSubmit,
  33. upload: this.core.i18n('upload')
  34. })
  35. // get the element where the Drag & Drop event will occur
  36. this.dropzone = document.querySelectorAll(this.opts.target)[0]
  37. this.dropzoneInput = document.querySelectorAll('.UppyDragDrop-input')[0]
  38. this.status = document.querySelectorAll('.UppyDragDrop-status')[0]
  39. }
  40. /**
  41. * Checks if the browser supports Drag & Drop
  42. * @return {Boolean} true if supported, false otherwise
  43. */
  44. checkDragDropSupport () {
  45. const div = document.createElement('div')
  46. if (!('draggable' in div) || !('ondragstart' in div && 'ondrop' in div)) {
  47. return false
  48. }
  49. if (!('FormData' in window)) {
  50. return false
  51. }
  52. if (!('FileReader' in window)) {
  53. return false
  54. }
  55. return true
  56. }
  57. listenForEvents () {
  58. console.log(`waiting for some files to be dropped on ${this.opts.target}`)
  59. if (this.isDragDropSupported) {
  60. Utils.addClass(this.dropzone, 'is-dragdrop-supported')
  61. }
  62. // prevent default actions for all drag & drop events
  63. const strEvents = 'drag dragstart dragend dragover dragenter dragleave drop'
  64. Utils.addListenerMulti(this.dropzone, strEvents, (e) => {
  65. e.preventDefault()
  66. e.stopPropagation()
  67. })
  68. // Toggle is-dragover state when files are dragged over or dropped
  69. Utils.addListenerMulti(this.dropzone, 'dragover dragenter', (e) => {
  70. Utils.addClass(this.dropzone, 'is-dragover')
  71. })
  72. Utils.addListenerMulti(this.dropzone, 'dragleave dragend drop', (e) => {
  73. Utils.removeClass(this.dropzone, 'is-dragover')
  74. })
  75. const onDrop = new Promise((resolve, reject) => {
  76. this.dropzone.addEventListener('drop', (e) => {
  77. resolve(this.handleDrop.bind(null, e))
  78. })
  79. })
  80. const onInput = new Promise((resolve, reject) => {
  81. this.dropzoneInput.addEventListener('change', (e) => {
  82. resolve(this.handleInputChange.bind(null, e))
  83. })
  84. })
  85. return Promise.race([onDrop, onInput]).then(handler => handler())
  86. // this.dropzone.addEventListener('drop', this.handleDrop);
  87. // this.dropzoneInput.addEventListener('change', this.handleInputChange);
  88. }
  89. displayStatus (status) {
  90. this.status.innerHTML = status
  91. }
  92. handleDrop (e) {
  93. console.log('all right, someone dropped something here...')
  94. const files = e.dataTransfer.files
  95. // files = Array.from(files);
  96. // const formData = new FormData(this.dropzone);
  97. // console.log('pizza', formData);
  98. // for (var i = 0; i < files.length; i++) {
  99. // formData.append('file', files[i]);
  100. // console.log('pizza', files[i]);
  101. // }
  102. return Promise.resolve({from: 'DragDrop', files: files})
  103. }
  104. handleInputChange () {
  105. // const fileInput = document.querySelectorAll('.UppyDragDrop-input')[0];
  106. const formData = new FormData(this.dropzone)
  107. console.log('@todo: No support for formData yet', formData)
  108. const files = []
  109. return Promise.resolve({from: 'DragDrop', files: files})
  110. }
  111. run (results) {
  112. console.log({
  113. class: 'DragDrop',
  114. method: 'run',
  115. results: results
  116. })
  117. return this.listenForEvents()
  118. }
  119. }