mirror of
https://github.com/whscullin/apple2js.git
synced 2024-01-12 14:14:38 +00:00
Improve FileChooser behavior with file input element (#197)
Before, the `FileChooser` could create a malformed `accept` parameter by repeating extensions if they were specified by several MIME types. This no longer happens and there is a test for it.
This commit is contained in:
parent
4490cc9bc7
commit
0047b9dbb3
@ -60,17 +60,24 @@ const InputFileChooser = ({
|
||||
//
|
||||
// which allows pretty generous interpretations.
|
||||
//
|
||||
// Update(whscullin) - Adding the MIME type seems to block loading anything
|
||||
// from iCloud when using Safari, so reverting to simply using extensions for
|
||||
// now.
|
||||
const newAccept = [];
|
||||
// However, it turns out that Safari does not like MIME types when
|
||||
// reading from iCloud. It may be related to:
|
||||
//
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=244666
|
||||
//
|
||||
// or it could be related to some permissions issue with iCloud. For
|
||||
// the moment, not adding the MIME type is sufficient.
|
||||
const newAccept: string[] = [];
|
||||
for (const type of accept) {
|
||||
for (const [/* typeString */, suffixes] of Object.entries(type.accept)) {
|
||||
for (let [/* typeString */, suffixes] of Object.entries(type.accept)) {
|
||||
// newAccept.push(typeString);
|
||||
if (Array.isArray(suffixes)) {
|
||||
newAccept.push(...suffixes);
|
||||
} else {
|
||||
newAccept.push(suffixes);
|
||||
if (!Array.isArray(suffixes)) {
|
||||
suffixes = [suffixes];
|
||||
}
|
||||
for (const suffix of suffixes) {
|
||||
if (!newAccept.includes(suffix)) {
|
||||
newAccept.push(suffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -157,6 +164,10 @@ const FilePickerChooser = ({
|
||||
* Using `window.showOpenFilePicker` has the advantage of allowing read/write
|
||||
* access to the file, whereas the regular input element only gives read
|
||||
* access.
|
||||
*
|
||||
* The FileChooser takes an optional `accept` parameter that specifies which
|
||||
* types of files can be opened. The parameter is a map of MIME type to file
|
||||
* extension. If the MIME type is the empty string, t
|
||||
*/
|
||||
export const FileChooser = ({
|
||||
onChange,
|
||||
|
@ -22,6 +22,17 @@ const FAKE_FILE_HANDLE = {
|
||||
isDirectory: false,
|
||||
} as const;
|
||||
|
||||
const TEST_FILE_TYPES = [
|
||||
{
|
||||
description: 'Test description 1',
|
||||
accept: { 'mime1': ['.ext1', '.ext2'] }
|
||||
},
|
||||
{
|
||||
description: 'Test description 2',
|
||||
accept: { 'mime2': ['.ext1', '.ext2'] }
|
||||
}];
|
||||
|
||||
|
||||
const NOP = () => { /* do nothing */ };
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
@ -44,6 +55,13 @@ describe('FileChooser', () => {
|
||||
expect(inputElement.type).toBe('file');
|
||||
});
|
||||
|
||||
it('should pass the correct MIME types and file extensions to the picker', async () => {
|
||||
const onChange = jest.fn();
|
||||
render(<FileChooser control='input' onChange={onChange} accept={TEST_FILE_TYPES} />);
|
||||
const inputElement = await screen.findByRole('button') as HTMLInputElement;
|
||||
expect(inputElement.accept).toBe('.ext1,.ext2');
|
||||
});
|
||||
|
||||
it('should fire a callback with empty list when no files are selected', async () => {
|
||||
const onChange = jest.fn();
|
||||
render(<FileChooser control='input' onChange={onChange} />);
|
||||
@ -97,6 +115,23 @@ describe('FileChooser', () => {
|
||||
expect(container).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should pass the correct MIME types and file extensions to the picker', async () => {
|
||||
mockFilePicker.mockResolvedValueOnce([]);
|
||||
const onChange = jest.fn();
|
||||
render(<FileChooser control='picker' onChange={onChange} accept={TEST_FILE_TYPES} />);
|
||||
|
||||
fireEvent.click(await screen.findByText('Choose File'));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockFilePicker).toBeCalledWith<[OpenFilePickerOptions]>({
|
||||
'excludeAcceptAllOption': true,
|
||||
'multiple': false,
|
||||
'types': TEST_FILE_TYPES
|
||||
});
|
||||
expect(onChange).toBeCalledWith([]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should fire a callback with empty list when no files are selected', async () => {
|
||||
mockFilePicker.mockResolvedValueOnce([]);
|
||||
const onChange = jest.fn();
|
||||
|
Loading…
x
Reference in New Issue
Block a user