solid-ui
Version:
UI library for writing Solid read-write-web applications
233 lines (190 loc) • 9.72 kB
JavaScript
;
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.makeDropTarget = makeDropTarget;
exports.makeDraggable = makeDraggable;
exports.uploadFiles = uploadFiles;
var debug = _interopRequireWildcard(require("../debug"));
var mime = _interopRequireWildcard(require("mime-types"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/* 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
* represent one thing which has a UR, 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 of 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(); // Neeed else drop does not work [sic]
e.dataTransfer.dropEffect = 'copy';
};
var dragenterListener = function dragenterListener(e) {
debug.log('dragenter event dropEffect: ' + e.dataTransfer.dropEffect);
if (this.style) {
// necessary not sure when
if (!this.savedStyle) {
this.savedStyle = {};
this.savedStyle.border = this.style.border;
this.savedStyle.backgroundColor = this.style.backgroundColor;
this.savedStyle.borderRadius = this.style.borderRadius;
}
this.style.backgroundColor = '#ccc';
this.style.border = '0.25em dashed black';
this.style.borderRadius = '0.3em';
}
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.style.border = this.savedStyle.border;
this.style.backgroundColor = this.savedStyle.backgroundColor;
this.style.borderRadius = this.savedStyle.borderRadius;
} else {
this.style.backgroundColor = 'white';
this.style.border = '0em solid black';
}
};
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.style.backgroundColor = 'white'; // 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 (!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