file-drops
Version:
A simple in-browser file drop utility
1 lines • 9.34 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../lib/index.js"],"sourcesContent":["import {\n domify\n} from 'min-dom';\n\nvar OVERLAY_HTML = '<div class=\"drop-overlay\">' +\n '<div class=\"box\">' +\n '<div class=\"label\">{label}</div>' +\n '</div>' +\n '</div>';\n\n/**\n * @typedef { {\n * name: string,\n * path: string | undefined,\n * contents: string\n * } } File\n */\n\n/**\n * Add file drop functionality to the given element,\n * calling fn(files...) on drop.\n *\n * @example\n *\n * var node = document.querySelector('#container');\n *\n * var dragOverHandler = fileDrop(handleFiles);\n *\n * node.addEventListener('dragover', dragOverHandler);\n *\n * @param { string } [label='Drop files here']\n * @param { (files: File[], dropEvent: DragEvent) => void } fn\n *\n * @return { (event: DragEvent) => any } drag over handler\n */\nexport default function fileDrop(label, fn) {\n\n if (typeof label === 'function') {\n fn = label;\n label = 'Drop files here';\n }\n\n var self;\n var extraArgs;\n\n // we are bound, if overlay exists\n var overlay;\n\n /**\n * @param { DragEvent } event\n */\n function onDrop(event) {\n\n event.preventDefault();\n\n asyncMap(event.dataTransfer.files, readFile, function(err, files) {\n\n if (err) {\n console.warn('file drop failed', err);\n } else {\n\n var args = extraArgs.concat([ files, event ]);\n\n // cleanup on drop\n // onEnd(event);\n\n // call provided fn with extraArgs..., files, event\n fn.apply(self, args);\n }\n });\n }\n\n function isDragAllowed(dataTransfer) {\n\n // Universal check for all browsers\n return dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files');\n }\n\n /**\n * Drag over event to be registered by clients in respective contexts\n *\n * @param { DragEvent } _event\n */\n function onDragover(_event) {\n\n // (0) extract extra arguments (extraArgs..., event)\n var args = slice(arguments);\n\n /**\n * @type {DragEvent}\n */\n var event = args.pop();\n\n var dataTransfer = event.dataTransfer,\n target = event.currentTarget || event.target;\n\n if (!isDragAllowed(dataTransfer)) {\n return;\n }\n\n // make us a drop zone\n event.preventDefault();\n\n dataTransfer.dropEffect = 'copy';\n\n // only register if we do not drag and drop already\n if (overlay) {\n return;\n }\n\n overlay = createOverlay(label);\n\n target.appendChild(overlay);\n\n self = this;\n extraArgs = args;\n\n\n // do not register events during testing\n if (!target) {\n return;\n }\n\n\n // (2) setup drag listeners\n\n function onLeave(event) {\n\n var relatedTarget = event.relatedTarget;\n\n if (target.contains(relatedTarget)) {\n return;\n }\n\n onEnd(event);\n }\n\n // (2.1) detach on end\n function onEnd(event) {\n\n document.removeEventListener('drop', onDrop);\n document.removeEventListener('drop', onEnd);\n document.removeEventListener('dragleave', onLeave);\n document.removeEventListener('dragend', onEnd);\n document.removeEventListener('dragover', preventDrop);\n\n if (overlay) {\n target.removeChild(overlay);\n overlay = null;\n }\n }\n\n // (2.0) attach drag + cleanup event\n document.addEventListener('drop', onDrop);\n document.addEventListener('drop', onEnd);\n document.addEventListener('dragleave', onLeave);\n document.addEventListener('dragend', onEnd);\n document.addEventListener('dragover', preventDrop);\n }\n\n onDragover.onDrop = onDrop;\n\n return onDragover;\n}\n\n\n// helpers ////////////////////////////////////\n\nfunction readFile(dropFile, done) {\n\n if (!window.FileReader) {\n return done();\n }\n\n var reader = new FileReader();\n\n // Closure to capture the file information.\n reader.onload = function(e) {\n\n done(null, {\n name: dropFile.name,\n path: dropFile.path,\n contents: e.target.result\n });\n };\n\n reader.onerror = function(event) {\n done(event.target.error);\n };\n\n // Read in the image file as a data URL.\n reader.readAsText(dropFile);\n}\n\n\nfunction asyncMap(elements, iterator, done) {\n\n var idx = 0,\n results = [];\n\n function next() {\n\n if (idx === elements.length) {\n done(null, results);\n } else {\n\n iterator(elements[idx], function(err, result) {\n\n if (err) {\n return done(err);\n } else {\n results[idx] = result;\n idx++;\n\n next();\n }\n });\n }\n }\n\n next();\n}\n\nfunction slice(arr) {\n return Array.prototype.slice.call(arr);\n}\n\nfunction createOverlay(label) {\n var markup = OVERLAY_HTML.replace('{label}', label);\n const overlay = domify(markup);\n\n // remove blinking on safari\n overlay.style.pointerEvents = 'none';\n\n return overlay;\n}\n\nfunction preventDrop(event) {\n event.preventDefault();\n}"],"names":["domify"],"mappings":";;;;AAIA,IAAI,YAAY,GAAG,4BAA4B;AAC/C,qBAAqB,mBAAmB;AACxC,wBAAwB,kCAAkC;AAC1D,qBAAqB,QAAQ;AAC7B,mBAAmB,QAAQ;;AAE3B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,SAAS,QAAQ,CAAC,KAAK,EAAE,EAAE,EAAE;;AAE5C,EAAE,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE;AACnC,IAAI,EAAE,GAAG,KAAK;AACd,IAAI,KAAK,GAAG,iBAAiB;AAC7B,EAAE;;AAEF,EAAE,IAAI,IAAI;AACV,EAAE,IAAI,SAAS;;AAEf;AACA,EAAE,IAAI,OAAO;;AAEb;AACA;AACA;AACA,EAAE,SAAS,MAAM,CAAC,KAAK,EAAE;;AAEzB,IAAI,KAAK,CAAC,cAAc,EAAE;;AAE1B,IAAI,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,GAAG,EAAE,KAAK,EAAE;;AAEtE,MAAM,IAAI,GAAG,EAAE;AACf,QAAQ,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,CAAC;AAC7C,MAAM,CAAC,MAAM;;AAEb,QAAQ,IAAI,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;;AAErD;AACA;;AAEA;AACA,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;AAC5B,MAAM;AACN,IAAI,CAAC,CAAC;AACN,EAAE;;AAEF,EAAE,SAAS,aAAa,CAAC,YAAY,EAAE;;AAEvC;AACA,IAAI,OAAO,YAAY,IAAI,YAAY,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;AACrF,EAAE;;AAEF;AACA;AACA;AACA;AACA;AACA,EAAE,SAAS,UAAU,CAAC,MAAM,EAAE;;AAE9B;AACA,IAAI,IAAI,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC;;AAE/B;AACA;AACA;AACA,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE;;AAE1B,IAAI,IAAI,YAAY,GAAG,KAAK,CAAC,YAAY;AACzC,QAAQ,MAAM,GAAG,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,MAAM;;AAEpD,IAAI,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE;AACtC,MAAM;AACN,IAAI;;AAEJ;AACA,IAAI,KAAK,CAAC,cAAc,EAAE;;AAE1B,IAAI,YAAY,CAAC,UAAU,GAAG,MAAM;;AAEpC;AACA,IAAI,IAAI,OAAO,EAAE;AACjB,MAAM;AACN,IAAI;;AAEJ,IAAI,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC;;AAElC,IAAI,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC;;AAE/B,IAAI,IAAI,GAAG,IAAI;AACf,IAAI,SAAS,GAAG,IAAI;;;AAGpB;AACA,IAAI,IAAI,CAAC,MAAM,EAAE;AACjB,MAAM;AACN,IAAI;;;AAGJ;;AAEA,IAAI,SAAS,OAAO,CAAC,KAAK,EAAE;;AAE5B,MAAM,IAAI,aAAa,GAAG,KAAK,CAAC,aAAa;;AAE7C,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE;AAC1C,QAAQ;AACR,MAAM;;AAEN,MAAM,KAAK,CAAM,CAAC;AAClB,IAAI;;AAEJ;AACA,IAAI,SAAS,KAAK,CAAC,KAAK,EAAE;;AAE1B,MAAM,QAAQ,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC;AAClD,MAAM,QAAQ,CAAC,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC;AACjD,MAAM,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,OAAO,CAAC;AACxD,MAAM,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC;AACpD,MAAM,QAAQ,CAAC,mBAAmB,CAAC,UAAU,EAAE,WAAW,CAAC;;AAE3D,MAAM,IAAI,OAAO,EAAE;AACnB,QAAQ,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC;AACnC,QAAQ,OAAO,GAAG,IAAI;AACtB,MAAM;AACN,IAAI;;AAEJ;AACA,IAAI,QAAQ,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC;AAC7C,IAAI,QAAQ,CAAC,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC;AAC5C,IAAI,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,OAAO,CAAC;AACnD,IAAI,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC;AAC/C,IAAI,QAAQ,CAAC,gBAAgB,CAAC,UAAU,EAAE,WAAW,CAAC;AACtD,EAAE;;AAEF,EAAE,UAAU,CAAC,MAAM,GAAG,MAAM;;AAE5B,EAAE,OAAO,UAAU;AACnB;;;AAGA;;AAEA,SAAS,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE;;AAElC,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;AAC1B,IAAI,OAAO,IAAI,EAAE;AACjB,EAAE;;AAEF,EAAE,IAAI,MAAM,GAAG,IAAI,UAAU,EAAE;;AAE/B;AACA,EAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE;;AAE9B,IAAI,IAAI,CAAC,IAAI,EAAE;AACf,MAAM,IAAI,EAAE,QAAQ,CAAC,IAAI;AACzB,MAAM,IAAI,EAAE,QAAQ,CAAC,IAAI;AACzB,MAAM,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC;AACzB,KAAK,CAAC;AACN,EAAE,CAAC;;AAEH,EAAE,MAAM,CAAC,OAAO,GAAG,SAAS,KAAK,EAAE;AACnC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;AAC5B,EAAE,CAAC;;AAEH;AACA,EAAE,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;AAC7B;;;AAGA,SAAS,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;;AAE5C,EAAE,IAAI,GAAG,GAAG,CAAC;AACb,MAAM,OAAO,GAAG,EAAE;;AAElB,EAAE,SAAS,IAAI,GAAG;;AAElB,IAAI,IAAI,GAAG,KAAK,QAAQ,CAAC,MAAM,EAAE;AACjC,MAAM,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;AACzB,IAAI,CAAC,MAAM;;AAEX,MAAM,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,GAAG,EAAE,MAAM,EAAE;;AAEpD,QAAQ,IAAI,GAAG,EAAE;AACjB,UAAU,OAAO,IAAI,CAAC,GAAG,CAAC;AAC1B,QAAQ,CAAC,MAAM;AACf,UAAU,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM;AAC/B,UAAU,GAAG,EAAE;;AAEf,UAAU,IAAI,EAAE;AAChB,QAAQ;AACR,MAAM,CAAC,CAAC;AACR,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,EAAE;AACR;;AAEA,SAAS,KAAK,CAAC,GAAG,EAAE;AACpB,EAAE,OAAO,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;AACxC;;AAEA,SAAS,aAAa,CAAC,KAAK,EAAE;AAC9B,EAAE,IAAI,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC;AACrD,EAAE,MAAM,OAAO,GAAGA,aAAM,CAAC,MAAM,CAAC;;AAEhC;AACA,EAAE,OAAO,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM;;AAEtC,EAAE,OAAO,OAAO;AAChB;;AAEA,SAAS,WAAW,CAAC,KAAK,EAAE;AAC5B,EAAE,KAAK,CAAC,cAAc,EAAE;AACxB;;;;"}