Skip to content

Commit c88865d

Browse files
committed
fix: use window.FileList instead of implicit global
1 parent c376fbc commit c88865d

File tree

5 files changed

+67
-56
lines changed

5 files changed

+67
-56
lines changed

src/utility/upload.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import {createFileList, isDisabled, isElementType, setFiles} from '../utils'
1+
import {
2+
createFileList,
3+
getWindow,
4+
isDisabled,
5+
isElementType,
6+
setFiles,
7+
} from '../utils'
28
import {Config, Instance} from '../setup'
39

410
export interface uploadInit {
@@ -36,7 +42,7 @@ export async function upload(
3642
return
3743
}
3844

39-
setFiles(input, createFileList(files))
45+
setFiles(input, createFileList(getWindow(element), files))
4046
this.dispatchUIEvent(input, 'input')
4147
this.dispatchUIEvent(input, 'change')
4248
}

src/utils/dataTransfer/DataTransfer.ts

+48-46
Original file line numberDiff line numberDiff line change
@@ -74,63 +74,65 @@ function getTypeMatcher(type: string, exact: boolean) {
7474
}
7575
}
7676

77-
class DataTransferStub implements DataTransfer {
78-
getData(format: string) {
79-
const match =
80-
this.items.find(getTypeMatcher(format, true)) ??
81-
this.items.find(getTypeMatcher(format, false))
82-
83-
let text = ''
84-
match?.getAsString(t => {
85-
text = t
86-
})
87-
88-
return text
89-
}
90-
91-
setData(format: string, data: string) {
92-
const matchIndex = this.items.findIndex(getTypeMatcher(format, true))
93-
94-
const item = new DataTransferItemStub(data, format) as DataTransferItem
95-
if (matchIndex >= 0) {
96-
this.items.splice(matchIndex, 1, item)
97-
} else {
98-
this.items.push(item)
77+
function createDataTransferStub(window: Window & typeof globalThis) {
78+
return new (class DataTransferStub implements DataTransfer {
79+
getData(format: string) {
80+
const match =
81+
this.items.find(getTypeMatcher(format, true)) ??
82+
this.items.find(getTypeMatcher(format, false))
83+
84+
let text = ''
85+
match?.getAsString(t => {
86+
text = t
87+
})
88+
89+
return text
9990
}
100-
}
10191

102-
clearData(format?: string) {
103-
if (format) {
92+
setData(format: string, data: string) {
10493
const matchIndex = this.items.findIndex(getTypeMatcher(format, true))
10594

95+
const item = new DataTransferItemStub(data, format) as DataTransferItem
10696
if (matchIndex >= 0) {
107-
this.items.remove(matchIndex)
97+
this.items.splice(matchIndex, 1, item)
98+
} else {
99+
this.items.push(item)
108100
}
109-
} else {
110-
this.items.clear()
111101
}
112-
}
113-
114-
dropEffect: DataTransfer['dropEffect'] = 'none'
115-
effectAllowed: DataTransfer['effectAllowed'] = 'uninitialized'
116102

117-
readonly items = new DataTransferItemListStub()
118-
readonly files = createFileList([])
103+
clearData(format?: string) {
104+
if (format) {
105+
const matchIndex = this.items.findIndex(getTypeMatcher(format, true))
119106

120-
get types() {
121-
const t = []
122-
if (this.files.length) {
123-
t.push('Files')
107+
if (matchIndex >= 0) {
108+
this.items.remove(matchIndex)
109+
}
110+
} else {
111+
this.items.clear()
112+
}
124113
}
125-
this.items.forEach(i => t.push(i.type))
126114

127-
Object.freeze(t)
115+
dropEffect: DataTransfer['dropEffect'] = 'none'
116+
effectAllowed: DataTransfer['effectAllowed'] = 'uninitialized'
128117

129-
return t
130-
}
118+
readonly items = new DataTransferItemListStub()
119+
readonly files = createFileList(window, [])
131120

132-
/* istanbul ignore next */
133-
setDragImage() {}
121+
get types() {
122+
const t = []
123+
if (this.files.length) {
124+
t.push('Files')
125+
}
126+
this.items.forEach(i => t.push(i.type))
127+
128+
Object.freeze(t)
129+
130+
return t
131+
}
132+
133+
/* istanbul ignore next */
134+
setDragImage() {}
135+
})()
134136
}
135137

136138
export function createDataTransfer(
@@ -140,10 +142,10 @@ export function createDataTransfer(
140142
// Use real DataTransfer if available
141143
const dt =
142144
typeof window.DataTransfer === 'undefined'
143-
? (new DataTransferStub() as DataTransfer)
145+
? createDataTransferStub(window)
144146
: /* istanbul ignore next */ new window.DataTransfer()
145147

146-
Object.defineProperty(dt, 'files', {get: () => createFileList(files)})
148+
Object.defineProperty(dt, 'files', {get: () => createFileList(window, files)})
147149

148150
return dt
149151
}

src/utils/dataTransfer/FileList.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// FileList can not be created per constructor.
22

3-
export function createFileList(files: File[]): FileList {
3+
export function createFileList(
4+
window: Window & typeof globalThis,
5+
files: File[],
6+
): FileList {
47
const list: FileList & Iterable<File> = {
58
...files,
69
length: files.length,
@@ -11,8 +14,8 @@ export function createFileList(files: File[]): FileList {
1114
}
1215
},
1316
}
14-
list.constructor = FileList
15-
Object.setPrototypeOf(list, FileList.prototype)
17+
list.constructor = window.FileList
18+
Object.setPrototypeOf(list, window.FileList.prototype)
1619
Object.freeze(list)
1720

1821
return list

tests/utils/dataTransfer/FileList.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {createFileList} from '#src/utils'
22

33
test('implement FileList', () => {
44
const file = new File(['hello'], 'hello.png', {type: 'image/png'})
5-
const list = createFileList([file])
5+
const list = createFileList(window, [file])
66

77
expect(list).toBeInstanceOf(FileList)
88
expect(list).toHaveLength(1)

tests/utils/edit/setFiles.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ test('set files', () => {
66
`<input type="file"/>`,
77
)
88

9-
const list = createFileList([new File(['foo'], 'foo.txt')])
9+
const list = createFileList(window, [new File(['foo'], 'foo.txt')])
1010
setFiles(element, list)
1111

1212
expect(element).toHaveProperty('files', list)
@@ -20,7 +20,7 @@ test('switching type resets value', () => {
2020

2121
expect(element).toHaveValue('')
2222

23-
const list = createFileList([new File(['foo'], 'foo.txt')])
23+
const list = createFileList(window, [new File(['foo'], 'foo.txt')])
2424
setFiles(element as HTMLInputElement & {type: 'file'}, list)
2525

2626
element.type = 'file'
@@ -38,7 +38,7 @@ test('setting value resets `files`', () => {
3838
`<input type="file"/>`,
3939
)
4040

41-
const list = createFileList([new File(['foo'], 'foo.txt')])
41+
const list = createFileList(window, [new File(['foo'], 'foo.txt')])
4242
setFiles(element, list)
4343

4444
// Everything but an empty string throws an error in the browser
@@ -58,7 +58,7 @@ test('is save to call multiple times', () => {
5858
`<input type="file"/>`,
5959
)
6060

61-
const list = createFileList([new File(['foo'], 'foo.txt')])
61+
const list = createFileList(window, [new File(['foo'], 'foo.txt')])
6262
setFiles(element, list)
6363
setFiles(element, list)
6464

0 commit comments

Comments
 (0)