js-uploader
Version:
A JavaScript library for file upload
268 lines • 13.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.webkitGetAsEntryApi = exports.parseFilesByPath = exports.parseDataTransfer = exports.FileDragger = void 0;
var tslib_1 = require("tslib");
var rxjs_1 = require("rxjs");
var operators_1 = require("rxjs/operators");
var shared_1 = require("../../shared");
var mime_1 = require("mime");
var path_1 = require("path");
var __1 = require("../..");
var FileDragger = /** @class */ (function () {
function FileDragger(options, uploadOptions) {
var _this = this;
this.uploadOptions = uploadOptions;
this.subscription = null;
shared_1.Logger.info('FileDragger', this);
var $el = options.$el, onDragover = options.onDragover, onDragenter = options.onDragenter, onDragleave = options.onDragleave, onDrop = options.onDrop;
if (!$el) {
throw new Error();
}
this.$el = $el;
var wrap = function (_e, fn) { return function (e) {
e.preventDefault();
e.stopPropagation();
fn === null || fn === void 0 ? void 0 : fn(e);
}; };
// this.$el.addEventListener('dragover', (e: DragEvent) => wrap(e, onDragover)(e))
// this.$el.addEventListener('dragenter', (e: DragEvent) => wrap(e, onDragenter)(e))
// this.$el.addEventListener('dragleave', (e: DragEvent) => wrap(e, onDragleave)(e))
// this.$el.addEventListener('drop', (e: DragEvent) => wrap(e, onDrop)(e))
// this.file$ = fromEvent(this.$el, 'drop').pipe(
// tap((e) => {
// e.stopPropagation()
// e.preventDefault()
// }),
// filter(() => {
// return !this.subscription?.closed
// }),
// mergeMap((e) =>
// from(parseDataTransfer(e as DragEvent, this.uploadOptions?.fileStatFn, this.uploadOptions?.readdirFn)),
// ),
// )
this.file$ = rxjs_1.merge(rxjs_1.merge(rxjs_1.fromEvent(this.$el, 'dragover').pipe(operators_1.tap(function (event) {
var e = event;
wrap(e, onDragover)(e);
})), rxjs_1.fromEvent(this.$el, 'dragenter').pipe(operators_1.tap(function (event) {
var e = event;
wrap(e, onDragenter)(e);
})), rxjs_1.fromEvent(this.$el, 'dragleave').pipe(operators_1.tap(function (event) {
var e = event;
wrap(e, onDragleave)(e);
})), rxjs_1.fromEvent(this.$el, 'drop').pipe(operators_1.tap(function (event) {
var e = event;
wrap(e, onDrop)(e);
}))).pipe(operators_1.mapTo([]), operators_1.filter(function (val) { return !!val.length; })), rxjs_1.fromEvent(this.$el, 'drop').pipe(operators_1.tap(function (e) {
e.stopPropagation();
e.preventDefault();
}), operators_1.concatMap(function (e) {
var _a, _b;
var res = (_b = (_a = _this.uploadOptions) === null || _a === void 0 ? void 0 : _a.beforeParseDataTransfer) === null || _b === void 0 ? void 0 : _b.call(_a, e);
var before = res instanceof Promise ? res : Promise.resolve(res);
return rxjs_1.from(before).pipe(operators_1.mapTo(e), operators_1.catchError(function () { return rxjs_1.of(null); }));
}), operators_1.filter(function (e) { return !!e; }), operators_1.mergeMap(function (e) {
var _a, _b;
return rxjs_1.from(parseDataTransfer(e, (_a = _this.uploadOptions) === null || _a === void 0 ? void 0 : _a.fileStatFn, (_b = _this.uploadOptions) === null || _b === void 0 ? void 0 : _b.readdirFn));
}))).pipe(operators_1.publishReplay(1));
this.bind();
}
FileDragger.prototype.bind = function () {
this.unbind();
this.subscription = this.file$.connect();
return this;
};
FileDragger.prototype.unbind = function () {
var _a;
(_a = this.subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
this.subscription = null;
return this;
};
return FileDragger;
}());
exports.FileDragger = FileDragger;
function parseDataTransfer(e, fileStat, readdir) {
var _a;
var dataTransfer = e.dataTransfer;
if (!dataTransfer) {
return Promise.resolve([]);
}
shared_1.Logger.info('parseDataTransfer', dataTransfer.files.length, dataTransfer.items.length);
if (__1.isElectron() && typeof fileStat === 'function' && typeof readdir === 'function') {
return parseFilesByPath(dataTransfer, fileStat, readdir);
}
if (((_a = dataTransfer.items) === null || _a === void 0 ? void 0 : _a.length) && typeof dataTransfer.items[0].webkitGetAsEntry === 'function') {
return webkitGetAsEntryApi(dataTransfer);
}
else {
return Promise.resolve(Array.from(dataTransfer.files));
}
}
exports.parseDataTransfer = parseDataTransfer;
function parseFilesByPath(dataTransfer, fileStat, readdir) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var list, rootDir, loop;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
console.time('parseFilesByPath');
list = [];
rootDir = '';
loop = function (filePath) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var stat, error_1, name_1, file, children;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!filePath) {
return [2 /*return*/];
}
stat = null;
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, toPromise(fileStat(filePath))];
case 2:
stat = _a.sent();
return [3 /*break*/, 4];
case 3:
error_1 = _a.sent();
shared_1.Logger.warn(filePath + ' not exists');
return [3 /*break*/, 4];
case 4:
if (!(stat === null || stat === void 0 ? void 0 : stat.isFile())) return [3 /*break*/, 5];
name_1 = path_1.basename(filePath);
file = {
lastModified: stat.mtimeMs,
name: name_1,
size: stat.size,
type: mime_1.getType(filePath),
path: filePath,
relativePath: rootDir ? path_1.relative(rootDir, filePath) : name_1,
};
list.push(file);
return [3 /*break*/, 8];
case 5:
if (!(stat === null || stat === void 0 ? void 0 : stat.isDirectory())) return [3 /*break*/, 8];
return [4 /*yield*/, toPromise(readdir(filePath))];
case 6:
children = _a.sent();
return [4 /*yield*/, rxjs_1.scheduled(children || [], rxjs_1.asyncScheduler)
.pipe(operators_1.concatMap(function (name) { return rxjs_1.from(loop(path_1.join(filePath, name))); }))
.toPromise()
// let promises = (await toPromise(readdir(filePath))).map((name) => loop(join(filePath, name)))
// await Promise.all(promises)
];
case 7:
_a.sent();
_a.label = 8;
case 8: return [2 /*return*/];
}
});
}); };
return [4 /*yield*/, Promise.all(Array.from(dataTransfer.files).map(function (file) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
rootDir = path_1.dirname(file.path);
return [4 /*yield*/, loop(file.path)];
case 1: return [2 /*return*/, _a.sent()];
}
});
}); }))];
case 1:
_a.sent();
console.timeEnd('parseFilesByPath');
return [2 /*return*/, list];
}
});
});
}
exports.parseFilesByPath = parseFilesByPath;
// function toObserverble<T>(input: TPromise<T>): Observable<T> {
// return input && input instanceof Promise ? from(input) : of(input)
// }
function toPromise(input) {
return input && input instanceof Promise ? input : Promise.resolve(input);
}
function webkitGetAsEntryApi(dataTransfer) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var files, promises, createPromiseToAddFileOrParseDirectory, error_2;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
console.time('webkitGetAsEntryApi');
files = [];
promises = [];
createPromiseToAddFileOrParseDirectory = function (entry) {
return new Promise(function (resolve) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var entries;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!entry.isFile) return [3 /*break*/, 1];
entry.file(function (file) {
file.relativePath = getRelativePath(entry);
files.push(file);
resolve();
}, function () { return resolve(); });
return [3 /*break*/, 3];
case 1:
if (!entry.isDirectory) return [3 /*break*/, 3];
return [4 /*yield*/, parseDir(entry.createReader(), [])];
case 2:
entries = _a.sent();
rxjs_1.scheduled(entries || [], rxjs_1.asyncScheduler)
.pipe(operators_1.map(createPromiseToAddFileOrParseDirectory), operators_1.mergeAll())
.subscribe({
complete: resolve,
});
_a.label = 3;
case 3: return [2 /*return*/];
}
});
}); });
};
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
Array.from(dataTransfer.items).forEach(function (item) {
var entry = item.webkitGetAsEntry();
entry && promises.push(createPromiseToAddFileOrParseDirectory(entry));
});
return [4 /*yield*/, Promise.all(promises)];
case 2:
_a.sent();
return [3 /*break*/, 4];
case 3:
error_2 = _a.sent();
shared_1.Logger.error(error_2);
return [3 /*break*/, 4];
case 4:
console.timeEnd('webkitGetAsEntryApi');
return [2 /*return*/, files];
}
});
});
}
exports.webkitGetAsEntryApi = webkitGetAsEntryApi;
function getRelativePath(fileEntry) {
var p = (fileEntry.fullPath || fileEntry.name);
return p.startsWith('/') ? p.substr(1) : p;
// return String(fileEntry.fullPath || fileEntry.name).replace(/^\//, '')
}
function parseDir(directoryReader, oldEntries) {
return new Promise(function (resolve) { return getFilesAndDirectoriesFromDirectory(directoryReader, oldEntries, resolve); });
}
function getFilesAndDirectoriesFromDirectory(directoryReader, oldEntries, callback) {
directoryReader.readEntries(function (entries) {
var newEntries = tslib_1.__spread(oldEntries, entries);
if (entries === null || entries === void 0 ? void 0 : entries.length) {
setTimeout(function () { return getFilesAndDirectoriesFromDirectory(directoryReader, newEntries, callback); });
}
else {
callback(newEntries);
}
}, function () { return callback(oldEntries); });
}
//# sourceMappingURL=FileDragger.js.map