UNPKG

solid-ui

Version:

UI library for writing Solid read-write-web applications

194 lines (185 loc) • 8.84 kB
"use strict"; var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.makeDraggable = makeDraggable; exports.makeDropTarget = makeDropTarget; exports.uploadFiles = uploadFiles; var debug = _interopRequireWildcard(require("../debug")); var mime = _interopRequireWildcard(require("mime-types")); var style = _interopRequireWildcard(require("../style")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } /* Drag and drop common functionality * * It is easy to make something draggable, or to make it a drag target! * Just call the functions below. In a Solid world, any part of the UI which * represents one thing which has a URI, should be made draggable using makeDraggable. * Any list of things should typically allow you to drag new members of the list * onto it. * The file upload function, uploadFiles, is provided as often as someone drags a file from the computer * desktop. You may want to upload it into the pod. */ /* global FileReader alert */ function makeDropTarget(ele, droppedURIHandler, droppedFileHandler) { var dragoverListener = function dragoverListener(e) { e.preventDefault(); // Need this; otherwise, drop does not work. e.dataTransfer.dropEffect = 'copy'; }; var dragenterListener = function dragenterListener(e) { debug.log('dragenter event dropEffect: ' + e.dataTransfer.dropEffect); if (this.localStyle) { // necessary not sure when if (!this.savedStyle) { this.savedStyle = style.dragEvent; } } e.dataTransfer.dropEffect = 'link'; debug.log('dragenter event dropEffect 2: ' + e.dataTransfer.dropEffect); }; var dragleaveListener = function dragleaveListener(e) { debug.log('dragleave event dropEffect: ' + e.dataTransfer.dropEffect); if (this.savedStyle) { this.localStyle = this.savedStyle; } else { this.localStyle = style.dropEvent; } }; var dropListener = function dropListener(e) { if (e.preventDefault) e.preventDefault(); // stops the browser from redirecting off to the text. debug.log('Drop event. dropEffect: ' + e.dataTransfer.dropEffect); debug.log('Drop event. types: ' + (e.dataTransfer.types ? e.dataTransfer.types.join(', ') : 'NOPE')); var uris = null; var text; if (e.dataTransfer.types) { for (var t = 0; t < e.dataTransfer.types.length; t++) { var type = e.dataTransfer.types[t]; if (type === 'text/uri-list') { uris = e.dataTransfer.getData(type).split('\n'); // @ ignore those starting with # debug.log('Dropped text/uri-list: ' + uris); } else if (type === 'text/plain') { text = e.dataTransfer.getData(type); } else if (type === 'Files' && droppedFileHandler) { var files = e.dataTransfer.files; // FileList object. for (var i = 0; files[i]; i++) { var f = files[i]; debug.log('Filename: ' + f.name + ', type: ' + (f.type || 'n/a') + ' size: ' + f.size + ' bytes, last modified: ' + (f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a')); } droppedFileHandler(files); } } if (uris === null && text && text.slice(0, 4) === 'http') { uris = text; debug.log("Waring: Poor man's drop: using text for URI"); // chrome disables text/uri-list?? } } else { // ... however, if we're IE, we don't have the .types property, so we'll just get the Text value uris = [e.dataTransfer.getData('Text')]; debug.log('WARNING non-standard drop event: ' + uris[0]); } debug.log('Dropped URI list (2): ' + uris); if (uris) { droppedURIHandler(uris); } this.localStyle = style.restoreStyle; // restore style return false; }; // dropListener var addTargetListeners = function addTargetListeners(ele) { if (!ele) { debug.log('@@@ addTargetListeners: ele ' + ele); } ele.addEventListener('dragover', dragoverListener); ele.addEventListener('dragenter', dragenterListener); ele.addEventListener('dragleave', dragleaveListener); ele.addEventListener('drop', dropListener); }; addTargetListeners(ele, droppedURIHandler); } // listen for dropped URIs // Make an HTML element draggable as a URI-identified thing // // Possibly later set the drag image too? // function makeDraggable(tr, obj) { tr.setAttribute('draggable', 'true'); // Stop the image being dragged instead - just the TR tr.addEventListener('dragstart', function (e) { tr.style.fontWeight = 'bold'; e.dataTransfer.setData('text/uri-list', obj.uri); e.dataTransfer.setData('text/plain', obj.uri); e.dataTransfer.setData('text/html', tr.outerHTML); debug.log('Dragstart: ' + tr + ' -> ' + obj + 'de: ' + e.dataTransfer.dropEffect); }, false); tr.addEventListener('drag', function (e) { e.preventDefault(); e.stopPropagation(); // debug.log('Drag: dropEffect: ' + e.dataTransfer.dropEffect) }, false); tr.addEventListener('dragend', function (e) { tr.style.fontWeight = 'normal'; debug.log('Dragend dropeffect: ' + e.dataTransfer.dropEffect); debug.log('Dragend: ' + tr + ' -> ' + obj); }, false); } /** uploadFiles ** ** Generic uploader of local files to the web ** typically called from dropped file handler ** ** @param {Fetcher} fetcher instance of class Fetcher as in kb.fetcher ** @param {Array<File>} files Array of file objects ** @param {String} fileBase URI of folder in which to put files (except images) (no trailing slash) ** @param {String } imageBase URI of folder in which to put images ** @param successHandler function(file, uploadedURI) Called after EACH success upload ** With file object an final URI as params */ function uploadFiles(fetcher, files, fileBase, imageBase, successHandler) { for (var i = 0; files[i]; i++) { var f = files[i]; debug.log(' dropped: Filename: ' + f.name + ', type: ' + (f.type || 'n/a') + ' size: ' + f.size + ' bytes, last modified: ' + (f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a')); // See e.g. https://www.html5rocks.com/en/tutorials/file/dndfiles/ // @@ Add: progress bar(s) var reader = new FileReader(); reader.onload = function (theFile) { return function (e) { var data = e.target.result; var suffix = ''; debug.log(' File read byteLength : ' + data.byteLength); var contentType = theFile.type; if (!theFile.type || theFile.type === '') { // Not known by browser contentType = mime.lookup(theFile.name); if (!contentType) { var msg = 'Filename needs to have an extension which gives a type we know: ' + theFile.name; debug.log(msg); alert(msg); throw new Error(msg); } } else { var extension = mime.extension(theFile.type); // Note not simple: eg .mp3 => audio/mpeg; .mpga => audio/mpeg; audio/mp3 => .mp3 if (extension && extension !== 'false' && !theFile.name.endsWith('.' + extension) && // Not already has preferred extension? and ... theFile.type !== mime.lookup(theFile.name)) { // the mime type of this ext is not the right one? suffix = '_.' + extension; // console.log('MIME TYPE MISMATCH: ' + mime.lookup(theFile.name) + ': adding extension: ' + suffix) } } var folderName = theFile.type.startsWith('image/') ? imageBase || fileBase : fileBase; var destURI = folderName + (folderName.endsWith('/') ? '' : '/') + encodeURIComponent(theFile.name) + suffix; fetcher.webOperation('PUT', destURI, { data: data, contentType: contentType }).then(function (_response) { debug.log(' Upload: put OK: ' + destURI); successHandler(theFile, destURI); }, function (error) { var msg = ' Upload: FAIL ' + destURI + ', Error: ' + error; debug.log(msg); alert(msg); throw new Error(msg); }); }; }(f); reader.readAsArrayBuffer(f); } } //# sourceMappingURL=dragAndDrop.js.map