@bokeh/bokehjs
Version:
Interactive, novel data visualization
112 lines • 4.06 kB
JavaScript
import { InputWidget, InputWidgetView, ClearInput } from "./input_widget";
import { input } from "../../core/dom";
import { isString } from "../../core/util/types";
import * as p from "../../core/properties";
import * as inputs from "../../styles/widgets/inputs.css";
import buttons_css from "../../styles/buttons.css";
export class FileInputView extends InputWidgetView {
static __name__ = "FileInputView";
connect_signals() {
super.connect_signals();
this.model.on_event(ClearInput, () => {
this.model.setv({
value: "", // p.unset,
mime_type: "", // p.unset,
filename: "", // p.unset,
});
this.input_el.value = "";
});
}
stylesheets() {
return [...super.stylesheets(), buttons_css];
}
_render_input() {
const { multiple, disabled, directory } = this.model;
const accept = (() => {
const { accept } = this.model;
return isString(accept) ? accept : accept.join(",");
})();
return this.input_el = input({ type: "file", class: inputs.input, multiple, accept, disabled, webkitdirectory: directory });
}
render() {
super.render();
this.input_el.addEventListener("change", async () => {
const { files } = this.input_el;
if (files != null) {
await this.load_files(files);
}
});
}
async load_files(files) {
const values = [];
const filenames = [];
const mime_types = [];
const { directory, multiple } = this.model;
const accept = (() => {
const { accept } = this.model;
return isString(accept) ? accept : accept.join(",");
})();
for (const file of files) {
const data_url = await this._read_file(file);
const [, mime_type = "", , value = ""] = data_url.split(/[:;,]/, 4);
if (directory) {
const ext = file.name.split(".").pop();
if ((accept.length > 0 && isString(ext)) ? accept.includes(`.${ext}`) : true) {
filenames.push(file.webkitRelativePath);
values.push(value);
mime_types.push(mime_type);
}
}
else {
filenames.push(file.name);
values.push(value);
mime_types.push(mime_type);
}
}
const [value, filename, mime_type] = (() => {
if (directory || multiple) {
return [values, filenames, mime_types];
}
else if (files.length != 0) {
return [values[0], filenames[0], mime_types[0]];
}
else {
return ["", "", ""];
}
})();
this.model.setv({ value, filename, mime_type });
}
_read_file(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const { result } = reader;
if (result != null) {
resolve(result);
}
else {
reject(reader.error ?? new Error(`unable to read '${file.name}'`));
}
};
reader.readAsDataURL(file);
});
}
}
export class FileInput extends InputWidget {
static __name__ = "FileInput";
constructor(attrs) {
super(attrs);
}
static {
this.prototype.default_view = FileInputView;
this.define(({ Bool, Str, List, Or }) => ({
value: [Or(Str, List(Str)), p.unset, { readonly: true }],
mime_type: [Or(Str, List(Str)), p.unset, { readonly: true }],
filename: [Or(Str, List(Str)), p.unset, { readonly: true }],
accept: [Or(Str, List(Str)), ""],
multiple: [Bool, false],
directory: [Bool, false],
}));
}
}
//# sourceMappingURL=file_input.js.map