Skip to content

Commit

Permalink
Merge branch 'main' into iss-961
Browse files Browse the repository at this point in the history
  • Loading branch information
ph-fritsche authored Jul 15, 2022
2 parents 8099948 + c88865d commit 195abad
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 60 deletions.
57 changes: 53 additions & 4 deletions eslint-local-rules/explicit-globals.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,53 @@
// ignore standard built-in objects
const whitelist = [
'Infinity',
'NaN',
'undefined',
'Object',
'Function',
'Boolean',
'Symbol',
'Error',
'EvalError',
'InternalError',
'RangeError',
'ReferenceError',
'SyntaxError',
'TypeError',
'URIError',
'Number',
'Math',
'Date',
'String',
'RegExp',
'Array',
'Int8Array',
'Uint8Array',
'Uint8ClampedArray',
'Int16Array',
'Uint16Array',
'Int32Array',
'Uint32Array',
'Float32Array',
'Float64Array',
'Map',
'Set',
'WeakMap',
'WeakSet',
'ArrayBuffer',
'DataView',
'JSON',
'Promise',
'Generator',
'GeneratorFunction',
'Reflect',
'Proxy',
'Intl',
'Intl.Collator',
'Intl.DateTimeFormat',
'Intl.NumberFormat',
]

module.exports = {
meta: {
type: 'suggestion',
Expand All @@ -13,13 +63,12 @@ module.exports = {

// `scope` is `GlobalScope` and `scope.variables` are the global variables
scope.variables.forEach(variable => {
// ignore `undefined`
if (variable.name === 'undefined') {
if (whitelist.includes(variable.name)) {
return
}

variable.references.forEach(ref => {
// Ignore types and global standard variables like `Object`
if (ref.resolved.constructor.name === 'ImplicitLibVariable') {
if (ref.identifier.parent.type.startsWith('TS')) {
return
}

Expand Down
10 changes: 8 additions & 2 deletions src/utility/upload.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import {createFileList, isDisabled, isElementType, setFiles} from '../utils'
import {
createFileList,
getWindow,
isDisabled,
isElementType,
setFiles,
} from '../utils'
import {Config, Instance} from '../setup'

export interface uploadInit {
Expand Down Expand Up @@ -36,7 +42,7 @@ export async function upload(
return
}

setFiles(input, createFileList(files))
setFiles(input, createFileList(getWindow(element), files))
this.dispatchUIEvent(input, 'input')
this.dispatchUIEvent(input, 'change')
}
Expand Down
94 changes: 48 additions & 46 deletions src/utils/dataTransfer/DataTransfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,63 +74,65 @@ function getTypeMatcher(type: string, exact: boolean) {
}
}

class DataTransferStub implements DataTransfer {
getData(format: string) {
const match =
this.items.find(getTypeMatcher(format, true)) ??
this.items.find(getTypeMatcher(format, false))

let text = ''
match?.getAsString(t => {
text = t
})

return text
}

setData(format: string, data: string) {
const matchIndex = this.items.findIndex(getTypeMatcher(format, true))

const item = new DataTransferItemStub(data, format) as DataTransferItem
if (matchIndex >= 0) {
this.items.splice(matchIndex, 1, item)
} else {
this.items.push(item)
function createDataTransferStub(window: Window & typeof globalThis) {
return new (class DataTransferStub implements DataTransfer {
getData(format: string) {
const match =
this.items.find(getTypeMatcher(format, true)) ??
this.items.find(getTypeMatcher(format, false))

let text = ''
match?.getAsString(t => {
text = t
})

return text
}
}

clearData(format?: string) {
if (format) {
setData(format: string, data: string) {
const matchIndex = this.items.findIndex(getTypeMatcher(format, true))

const item = new DataTransferItemStub(data, format) as DataTransferItem
if (matchIndex >= 0) {
this.items.remove(matchIndex)
this.items.splice(matchIndex, 1, item)
} else {
this.items.push(item)
}
} else {
this.items.clear()
}
}

dropEffect: DataTransfer['dropEffect'] = 'none'
effectAllowed: DataTransfer['effectAllowed'] = 'uninitialized'

readonly items = new DataTransferItemListStub()
readonly files = createFileList([])
clearData(format?: string) {
if (format) {
const matchIndex = this.items.findIndex(getTypeMatcher(format, true))

get types() {
const t = []
if (this.files.length) {
t.push('Files')
if (matchIndex >= 0) {
this.items.remove(matchIndex)
}
} else {
this.items.clear()
}
}
this.items.forEach(i => t.push(i.type))

Object.freeze(t)
dropEffect: DataTransfer['dropEffect'] = 'none'
effectAllowed: DataTransfer['effectAllowed'] = 'uninitialized'

return t
}
readonly items = new DataTransferItemListStub()
readonly files = createFileList(window, [])

/* istanbul ignore next */
setDragImage() {}
get types() {
const t = []
if (this.files.length) {
t.push('Files')
}
this.items.forEach(i => t.push(i.type))

Object.freeze(t)

return t
}

/* istanbul ignore next */
setDragImage() {}
})()
}

export function createDataTransfer(
Expand All @@ -140,10 +142,10 @@ export function createDataTransfer(
// Use real DataTransfer if available
const dt =
typeof window.DataTransfer === 'undefined'
? (new DataTransferStub() as DataTransfer)
? createDataTransferStub(window)
: /* istanbul ignore next */ new window.DataTransfer()

Object.defineProperty(dt, 'files', {get: () => createFileList(files)})
Object.defineProperty(dt, 'files', {get: () => createFileList(window, files)})

return dt
}
Expand Down
9 changes: 6 additions & 3 deletions src/utils/dataTransfer/FileList.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// FileList can not be created per constructor.

export function createFileList(files: File[]): FileList {
export function createFileList(
window: Window & typeof globalThis,
files: File[],
): FileList {
const list: FileList & Iterable<File> = {
...files,
length: files.length,
Expand All @@ -11,8 +14,8 @@ export function createFileList(files: File[]): FileList {
}
},
}
list.constructor = FileList
Object.setPrototypeOf(list, FileList.prototype)
list.constructor = window.FileList
Object.setPrototypeOf(list, window.FileList.prototype)
Object.freeze(list)

return list
Expand Down
2 changes: 1 addition & 1 deletion tests/utils/dataTransfer/FileList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {createFileList} from '#src/utils'

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

expect(list).toBeInstanceOf(FileList)
expect(list).toHaveLength(1)
Expand Down
8 changes: 4 additions & 4 deletions tests/utils/edit/setFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ test('set files', () => {
`<input type="file"/>`,
)

const list = createFileList([new File(['foo'], 'foo.txt')])
const list = createFileList(window, [new File(['foo'], 'foo.txt')])
setFiles(element, list)

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

expect(element).toHaveValue('')

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

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

const list = createFileList([new File(['foo'], 'foo.txt')])
const list = createFileList(window, [new File(['foo'], 'foo.txt')])
setFiles(element, list)

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

const list = createFileList([new File(['foo'], 'foo.txt')])
const list = createFileList(window, [new File(['foo'], 'foo.txt')])
setFiles(element, list)
setFiles(element, list)

Expand Down

0 comments on commit 195abad

Please sign in to comment.