Files
docuseal/app/javascript/elements/native_upload.js
T
2026-09-23 11:00:17 +03:00

62 lines
1.8 KiB
JavaScript

import { convertImagesInInput } from './convert_upload'
export default class extends HTMLElement {
connectedCallback () {
this.files = []
document.addEventListener('turbo:submit-end', this.onSubmitEnd)
document.addEventListener('native:upload-start', this.onUploadStart)
document.addEventListener('native:upload-chunk', this.onUploadChunk)
document.addEventListener('native:upload-submit', this.onUploadSubmit)
}
disconnectedCallback () {
document.removeEventListener('turbo:submit-end', this.onSubmitEnd)
document.removeEventListener('native:upload-start', this.onUploadStart)
document.removeEventListener('native:upload-chunk', this.onUploadChunk)
document.removeEventListener('native:upload-submit', this.onUploadSubmit)
}
get form () {
return this.querySelector('form')
}
onUploadStart = (event) => {
this.files = []
event.detail.result = true
}
onUploadChunk = ({ detail: { index, name, type, chunk } }) => {
const file = this.files[index] ||= { name, type, chunks: [] }
file.chunks.push(Uint8Array.from(atob(chunk), (char) => char.charCodeAt(0)))
}
onUploadSubmit = (event) => {
event.detail.result = this.submit(event.detail.url)
}
async submit (url) {
const dataTransfer = new DataTransfer()
this.files.forEach(({ name, type, chunks }) => dataTransfer.items.add(new File(chunks, name, { type })))
this.files = []
const input = this.form.querySelector('[type="file"]')
input.files = dataTransfer.files
await convertImagesInInput(input)
this.form.action = url
this.form.requestSubmit()
}
onSubmitEnd = (e) => {
if (e.detail.formSubmission?.formElement !== this.form) return
window.webkit?.messageHandlers?.native?.postMessage({ type: 'upload', success: e.detail.success })
}
}