Skip to content

Commit

Permalink
fix(upload): be robust against missing FileList implementation (#1007)
Browse files Browse the repository at this point in the history
  • Loading branch information
ph-fritsche committed Aug 2, 2022
1 parent 2852509 commit a46b4d7
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 27 deletions.
8 changes: 7 additions & 1 deletion src/utils/dataTransfer/FileList.ts
Expand Up @@ -15,7 +15,13 @@ export function createFileList(
},
}
list.constructor = window.FileList
Object.setPrototypeOf(list, window.FileList.prototype)

// guard for environments without FileList
/* istanbul ignore else */
if (window.FileList as Function | undefined) {
Object.setPrototypeOf(list, window.FileList.prototype)
}

Object.freeze(list)

return list
Expand Down
50 changes: 24 additions & 26 deletions src/utils/edit/setFiles.ts
Expand Up @@ -12,57 +12,55 @@ declare global {
}
}

function restoreProperty<T extends object>(
obj: T,
prop: keyof T,
descriptor?: PropertyDescriptor,
) {
if (descriptor) {
Object.defineProperty(obj, prop, descriptor)
} else {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete obj[prop]
}
}

export function setFiles(
el: HTMLInputElement & {type: 'file'},
files: FileList,
) {
el[fakeFiles]?.restore()

const objectDescriptors = Object.getOwnPropertyDescriptors(el)
const prototypeDescriptors = Object.getOwnPropertyDescriptors(
Object.getPrototypeOf(el),
)
const typeDescr = Object.getOwnPropertyDescriptor(el, 'type')
const valueDescr = Object.getOwnPropertyDescriptor(el, 'value')
const filesDescr = Object.getOwnPropertyDescriptor(el, 'files')

function restore() {
Object.defineProperties(el, {
files: {
...prototypeDescriptors.files,
...objectDescriptors.files,
},
value: {
...prototypeDescriptors.value,
...objectDescriptors.value,
},
type: {
...prototypeDescriptors.type,
...objectDescriptors.type,
},
})
restoreProperty(el, 'type', typeDescr)
restoreProperty(el, 'value', valueDescr)
restoreProperty(el, 'files', filesDescr)
}
el[fakeFiles] = {restore}

Object.defineProperties(el, {
files: {
...prototypeDescriptors.files,
...objectDescriptors.files,
configurable: true,
get: () => files,
},
value: {
...prototypeDescriptors.value,
...objectDescriptors.value,
configurable: true,
get: () => (files.length ? `C:\\fakepath\\${files[0].name}` : ''),
set(v: string) {
if (v === '') {
restore()
} else {
objectDescriptors.value.set?.call(el, v)
valueDescr?.set?.call(el, v)
}
},
},
// eslint-disable-next-line accessor-pairs
type: {
...prototypeDescriptors.type,
...objectDescriptors.type,
configurable: true,
get: () => 'file',
set(v: string) {
if (v !== 'file') {
restore()
Expand Down

0 comments on commit a46b4d7

Please sign in to comment.