Skip to content

Commit a46b4d7

Browse files
authored
fix(upload): be robust against missing FileList implementation (#1007)
1 parent 2852509 commit a46b4d7

File tree

2 files changed

+31
-27
lines changed

2 files changed

+31
-27
lines changed

src/utils/dataTransfer/FileList.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ export function createFileList(
1515
},
1616
}
1717
list.constructor = window.FileList
18-
Object.setPrototypeOf(list, window.FileList.prototype)
18+
19+
// guard for environments without FileList
20+
/* istanbul ignore else */
21+
if (window.FileList as Function | undefined) {
22+
Object.setPrototypeOf(list, window.FileList.prototype)
23+
}
24+
1925
Object.freeze(list)
2026

2127
return list

src/utils/edit/setFiles.ts

+24-26
Original file line numberDiff line numberDiff line change
@@ -12,57 +12,55 @@ declare global {
1212
}
1313
}
1414

15+
function restoreProperty<T extends object>(
16+
obj: T,
17+
prop: keyof T,
18+
descriptor?: PropertyDescriptor,
19+
) {
20+
if (descriptor) {
21+
Object.defineProperty(obj, prop, descriptor)
22+
} else {
23+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
24+
delete obj[prop]
25+
}
26+
}
27+
1528
export function setFiles(
1629
el: HTMLInputElement & {type: 'file'},
1730
files: FileList,
1831
) {
1932
el[fakeFiles]?.restore()
2033

21-
const objectDescriptors = Object.getOwnPropertyDescriptors(el)
22-
const prototypeDescriptors = Object.getOwnPropertyDescriptors(
23-
Object.getPrototypeOf(el),
24-
)
34+
const typeDescr = Object.getOwnPropertyDescriptor(el, 'type')
35+
const valueDescr = Object.getOwnPropertyDescriptor(el, 'value')
36+
const filesDescr = Object.getOwnPropertyDescriptor(el, 'files')
2537

2638
function restore() {
27-
Object.defineProperties(el, {
28-
files: {
29-
...prototypeDescriptors.files,
30-
...objectDescriptors.files,
31-
},
32-
value: {
33-
...prototypeDescriptors.value,
34-
...objectDescriptors.value,
35-
},
36-
type: {
37-
...prototypeDescriptors.type,
38-
...objectDescriptors.type,
39-
},
40-
})
39+
restoreProperty(el, 'type', typeDescr)
40+
restoreProperty(el, 'value', valueDescr)
41+
restoreProperty(el, 'files', filesDescr)
4142
}
4243
el[fakeFiles] = {restore}
4344

4445
Object.defineProperties(el, {
4546
files: {
46-
...prototypeDescriptors.files,
47-
...objectDescriptors.files,
47+
configurable: true,
4848
get: () => files,
4949
},
5050
value: {
51-
...prototypeDescriptors.value,
52-
...objectDescriptors.value,
51+
configurable: true,
5352
get: () => (files.length ? `C:\\fakepath\\${files[0].name}` : ''),
5453
set(v: string) {
5554
if (v === '') {
5655
restore()
5756
} else {
58-
objectDescriptors.value.set?.call(el, v)
57+
valueDescr?.set?.call(el, v)
5958
}
6059
},
6160
},
62-
// eslint-disable-next-line accessor-pairs
6361
type: {
64-
...prototypeDescriptors.type,
65-
...objectDescriptors.type,
62+
configurable: true,
63+
get: () => 'file',
6664
set(v: string) {
6765
if (v !== 'file') {
6866
restore()

0 commit comments

Comments
 (0)