"use strict";
/**
* For DOM
* */
Object.defineProperty(exports, "__esModule", { value: true });
exports.saveStringToFile = exports.saveBlobToFile = exports.selectAudio = exports.selectVideo = exports.selectImage = exports.selectFile = exports.downloadFile = exports.fileToArrayBuffer = exports.fileToArray = exports.fileToBinaryString = exports.filesToBase64Strings = exports.filesMap = exports.filesForEach = exports.fileToText = exports.fileToBase64String = void 0;
const defer_1 = require("./async/defer");
const blob_1 = require("./blob");
function createAsyncFileReader() {
const defer = (0, defer_1.createDefer)();
const reader = new FileReader();
reader.onload = () => {
if (reader.result === null) {
return defer.reject('unexpected null reader.result');
}
return defer.resolve(reader.result);
};
reader.onerror = defer.reject;
return [defer, reader];
}
async function fileToBase64String(file) {
const [defer, reader] = createAsyncFileReader();
reader.readAsDataURL(file);
return defer.promise.then(blob_1.arrayBufferToString);
}
exports.fileToBase64String = fileToBase64String;
async function fileToText(file) {
const [defer, reader] = createAsyncFileReader();
reader.readAsText(file);
return defer.promise.then();
}
exports.fileToText = fileToText;
function filesForEach(files, f) {
if (Array.isArray(files)) {
files.forEach(f);
}
else {
for (let i = 0; i < files.length; i++) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
f(files.item(i), i, files);
}
}
}
exports.filesForEach = filesForEach;
function filesMap(files, f) {
const xs = new Array(files.length);
filesForEach(files, (file, i, files) => (xs[i] = f(file, i, files)));
return xs;
}
exports.filesMap = filesMap;
async function filesToBase64Strings(files) {
return Promise.all(filesMap(files, file => fileToBase64String(file)));
}
exports.filesToBase64Strings = filesToBase64Strings;
async function fileToBinaryString(file) {
const [defer, reader] = createAsyncFileReader();
reader.readAsBinaryString(file);
return defer.promise.then(blob_1.arrayBufferToString);
}
exports.fileToBinaryString = fileToBinaryString;
async function fileToArray(file) {
const s = await fileToBinaryString(file);
const n = s.length;
const res = new Array(n);
for (let i = 0; i < n; i++) {
res[i] = s.charCodeAt(i);
}
return res;
}
exports.fileToArray = fileToArray;
async function fileToArrayBuffer(file) {
const [defer, reader] = createAsyncFileReader();
reader.readAsArrayBuffer(file);
return defer.promise.then(x => {
if (typeof x === 'string') {
const xs = new ArrayBuffer(x.length);
for (let i = 0, n = x.length; i < n; i++) {
xs[i] = x[i];
}
return xs;
}
else {
return x;
}
});
}
exports.fileToArrayBuffer = fileToArrayBuffer;
// reference: https://ausdemmaschinenraum.wordpress.com/2012/12/06/how-to-save-a-file-from-a-url-with-javascript/
//
// if filename is not given, will get from url
async function downloadFile(url, filename = url.substring(url.lastIndexOf('/') + 1).split('?')[0]) {
const defer = (0, defer_1.createDefer)();
const xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function () {
const a = document.createElement('a');
a.href = window.URL.createObjectURL(xhr.response); // xhr.response is a blob
a.download = filename; // Set the file name.
a.style.display = 'none';
document.body.appendChild(a);
a.click();
defer.resolve(true);
};
xhr.onerror = e => defer.reject(e);
xhr.open('GET', url);
xhr.send();
return defer.promise;
}
exports.downloadFile = downloadFile;
function captureMode(capture) {
if (capture === true) {
return 'camera';
}
if (capture === false) {
return 'album';
}
return 'both';
}
function selectFile(options = {}) {
return new Promise((resolve, reject) => {
if (!options.capture) {
delete options.capture;
}
const input = document.createElement('input');
input.type = 'file';
input.style.display = 'none';
Object.keys(options).forEach(x => (input[x] = options[x]));
document.body.appendChild(input); // for iOS compatibility
input.onchange = _event => {
if (!input.files) {
reject('user canceled');
document.body.removeChild(input);
return;
}
const nFile = input.files.length;
if (nFile < 1) {
reject('no files selected');
}
else {
const files = new Array(nFile);
for (let i = 0; i < nFile; i++) {
files[i] = input.files.item(i);
}
resolve(files);
}
document.body.removeChild(input);
};
input.click();
});
}
exports.selectFile = selectFile;
/**
* must from album
*
*
* must from camera
*
*
* both album and camera
*
* */
function selectImage(options = {}) {
options.accept = options.accept || 'image/*';
if (captureMode(options.capture) === 'both' &&
!options.accept.includes('camera')) {
options.accept += ';capture=camera';
}
return selectFile(options);
}
exports.selectImage = selectImage;
function selectVideo(options = {}) {
options.accept = options.accept || 'video/mp4,video/x-m4v,video/*';
if (captureMode(options.capture) === 'both' &&
!options.accept.includes('camcorder')) {
options.accept += ';capture=camcorder';
}
return selectFile(options);
}
exports.selectVideo = selectVideo;
function selectAudio(options = {}) {
options.accept = options.accept || 'audio/*';
if (captureMode(options.capture) === 'both' &&
!options.accept.includes('microphone')) {
options.accept += ';capture=microphone';
}
return selectFile(options);
}
exports.selectAudio = selectAudio;
function saveBlobToFile(blob, filename) {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
if (filename) {
a.download = filename;
}
a.href = url;
if (document.body) {
a.style.display = 'none';
a.textContent = 'Download file';
document.body.appendChild(a);
}
a.click();
}
exports.saveBlobToFile = saveBlobToFile;
function saveStringToFile(s, type = 'text/plain', filename) {
return saveBlobToFile(new Blob([s], { type }), filename);
}
exports.saveStringToFile = saveStringToFile;