react-dropzone 11.7.1 → 12.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc CHANGED
@@ -15,10 +15,8 @@
15
15
  "prettier"
16
16
  ],
17
17
  "extends": [
18
- // TODO: Fix this so we can use
19
- // "okonet/node"
20
18
  "eslint:recommended",
21
- "prettier"
19
+ "plugin:prettier/recommended"
22
20
  ],
23
21
  "rules": {
24
22
  "strict": 0,
package/README.md CHANGED
@@ -6,7 +6,8 @@
6
6
  [![codecov](https://img.shields.io/codecov/c/gh/react-dropzone/react-dropzone/master.svg?style=flat-square)](https://codecov.io/gh/react-dropzone/react-dropzone)
7
7
  [![Open Collective Backers](https://img.shields.io/opencollective/backers/react-dropzone.svg?style=flat-square)](#backers)
8
8
  [![Open Collective Sponsors](https://img.shields.io/opencollective/sponsors/react-dropzone.svg?style=flat-square)](#sponsors)
9
- [![Gitpod](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod&style=flat-square)](https://gitpod.io/#https://github.com/react-dropzone/react-dropzone)
9
+ [![Gitpod](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod&style=flat-square)](https://gitpod.io/#https://github.com/react-dropzone/react-dropzone)
10
+ [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg?style=flat-square)](https://github.com/react-dropzone/.github/blob/main/CODE_OF_CONDUCT.md)
10
11
 
11
12
  Simple React hook to create a HTML5-compliant drag'n'drop zone for files.
12
13
 
@@ -344,6 +345,10 @@ Fortunately, there's the [File System Access API](https://developer.mozilla.org/
344
345
 
345
346
  And this lib makes use of it if available. Though, there's a small catch: using file extensions for the `accept` property is not supported; you must use MIME types as described in [common MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types). Also check [accepting specific file types](https://react-dropzone.js.org/#section-accepting-specific-file-types) for more info on the subject of `accept` limitations.
346
347
 
348
+ Also keep in mind that the FS access API can only be used in [secure contexts](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts).
349
+
350
+ **NOTE** You can disable using the FS access API with the `useFsAccessApi` property: `useDropzone({useFsAccessApi: false})`.
351
+
347
352
  ## Supported Browsers
348
353
  We use [browserslist](https://github.com/browserslist/browserslist) config to state the browser support for this lib, so check it out on [browserslist.dev](https://browserslist.dev/?q=ZGVmYXVsdHM%3D).
349
354
 
@@ -1 +1 @@
1
- module.exports = { extends: ['@commitlint/config-angular'] }
1
+ module.exports = { extends: ["@commitlint/config-angular"] };
package/dist/es/index.js CHANGED
@@ -34,10 +34,10 @@ function _objectWithoutProperties(source, excluded) { if (source == null) return
34
34
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
35
35
 
36
36
  /* eslint prefer-template: 0 */
37
- import React, { forwardRef, Fragment, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef } from 'react';
38
- import PropTypes from 'prop-types';
39
- import { fromEvent } from 'file-selector';
40
- import { allFilesAccepted, composeEventHandlers, fileAccepted, fileMatchSize, filePickerOptionsTypes, canUseFileSystemAccessAPI, isEvtWithFiles, isIeOrEdge, isPropagationStopped, onDocumentDragOver, TOO_MANY_FILES_REJECTION } from './utils/index';
37
+ import React, { forwardRef, Fragment, useCallback, useEffect, useImperativeHandle, useMemo, useReducer, useRef } from "react";
38
+ import PropTypes from "prop-types";
39
+ import { fromEvent } from "file-selector";
40
+ import { allFilesAccepted, composeEventHandlers, fileAccepted, fileMatchSize, filePickerOptionsTypes, canUseFileSystemAccessAPI, isAbort, isEvtWithFiles, isIeOrEdge, isPropagationStopped, isSecurityError, onDocumentDragOver, TOO_MANY_FILES_REJECTION } from "./utils/index";
41
41
  /**
42
42
  * Convenience wrapper component for the `useDropzone` hook
43
43
  *
@@ -71,7 +71,7 @@ var Dropzone = /*#__PURE__*/forwardRef(function (_ref, ref) {
71
71
  open: open
72
72
  })));
73
73
  });
74
- Dropzone.displayName = 'Dropzone'; // Add default props for react-docgen
74
+ Dropzone.displayName = "Dropzone"; // Add default props for react-docgen
75
75
 
76
76
  var defaultProps = {
77
77
  disabled: false,
@@ -86,7 +86,7 @@ var defaultProps = {
86
86
  noDrag: false,
87
87
  noDragEventsBubbling: false,
88
88
  validator: null,
89
- useFsAccessApi: false
89
+ useFsAccessApi: true
90
90
  };
91
91
  Dropzone.defaultProps = defaultProps;
92
92
  Dropzone.propTypes = {
@@ -450,10 +450,10 @@ export function useDropzone() {
450
450
  validator = _defaultProps$options.validator;
451
451
 
452
452
  var onFileDialogOpenCb = useMemo(function () {
453
- return typeof onFileDialogOpen === 'function' ? onFileDialogOpen : noop;
453
+ return typeof onFileDialogOpen === "function" ? onFileDialogOpen : noop;
454
454
  }, [onFileDialogOpen]);
455
455
  var onFileDialogCancelCb = useMemo(function () {
456
- return typeof onFileDialogCancel === 'function' ? onFileDialogCancel : noop;
456
+ return typeof onFileDialogCancel === "function" ? onFileDialogCancel : noop;
457
457
  }, [onFileDialogCancel]);
458
458
  var rootRef = useRef(null);
459
459
  var inputRef = useRef(null);
@@ -465,18 +465,19 @@ export function useDropzone() {
465
465
 
466
466
  var isFocused = state.isFocused,
467
467
  isFileDialogActive = state.isFileDialogActive,
468
- draggedFiles = state.draggedFiles; // Update file dialog active state when the window is focused on
468
+ draggedFiles = state.draggedFiles;
469
+ var fsAccessApiWorksRef = useRef(window.isSecureContext && useFsAccessApi && canUseFileSystemAccessAPI()); // Update file dialog active state when the window is focused on
469
470
 
470
471
  var onWindowFocus = function onWindowFocus() {
471
472
  // Execute the timeout only if the file dialog is opened in the browser
472
- if (isFileDialogActive) {
473
+ if (!fsAccessApiWorksRef.current && isFileDialogActive) {
473
474
  setTimeout(function () {
474
475
  if (inputRef.current) {
475
476
  var files = inputRef.current.files;
476
477
 
477
478
  if (!files.length) {
478
479
  dispatch({
479
- type: 'closeDialog'
480
+ type: "closeDialog"
480
481
  });
481
482
  onFileDialogCancelCb();
482
483
  }
@@ -486,15 +487,11 @@ export function useDropzone() {
486
487
  };
487
488
 
488
489
  useEffect(function () {
489
- if (useFsAccessApi && canUseFileSystemAccessAPI()) {
490
- return function () {};
491
- }
492
-
493
- window.addEventListener('focus', onWindowFocus, false);
490
+ window.addEventListener("focus", onWindowFocus, false);
494
491
  return function () {
495
- window.removeEventListener('focus', onWindowFocus, false);
492
+ window.removeEventListener("focus", onWindowFocus, false);
496
493
  };
497
- }, [inputRef, isFileDialogActive, onFileDialogCancelCb, useFsAccessApi]);
494
+ }, [inputRef, isFileDialogActive, onFileDialogCancelCb, fsAccessApiWorksRef]);
498
495
  var dragTargetsRef = useRef([]);
499
496
 
500
497
  var onDocumentDrop = function onDocumentDrop(event) {
@@ -509,14 +506,14 @@ export function useDropzone() {
509
506
 
510
507
  useEffect(function () {
511
508
  if (preventDropOnDocument) {
512
- document.addEventListener('dragover', onDocumentDragOver, false);
513
- document.addEventListener('drop', onDocumentDrop, false);
509
+ document.addEventListener("dragover", onDocumentDragOver, false);
510
+ document.addEventListener("drop", onDocumentDrop, false);
514
511
  }
515
512
 
516
513
  return function () {
517
514
  if (preventDropOnDocument) {
518
- document.removeEventListener('dragover', onDocumentDragOver);
519
- document.removeEventListener('drop', onDocumentDrop);
515
+ document.removeEventListener("dragover", onDocumentDragOver);
516
+ document.removeEventListener("drop", onDocumentDrop);
520
517
  }
521
518
  };
522
519
  }, [rootRef, preventDropOnDocument]);
@@ -536,7 +533,7 @@ export function useDropzone() {
536
533
  dispatch({
537
534
  draggedFiles: draggedFiles,
538
535
  isDragActive: true,
539
- type: 'setDraggedFiles'
536
+ type: "setDraggedFiles"
540
537
  });
541
538
 
542
539
  if (onDragEnter) {
@@ -553,7 +550,7 @@ export function useDropzone() {
553
550
 
554
551
  if (hasFiles && event.dataTransfer) {
555
552
  try {
556
- event.dataTransfer.dropEffect = 'copy';
553
+ event.dataTransfer.dropEffect = "copy";
557
554
  } catch (_unused) {}
558
555
  /* eslint-disable-line no-empty */
559
556
 
@@ -589,7 +586,7 @@ export function useDropzone() {
589
586
 
590
587
  dispatch({
591
588
  isDragActive: false,
592
- type: 'setDraggedFiles',
589
+ type: "setDraggedFiles",
593
590
  draggedFiles: []
594
591
  });
595
592
 
@@ -645,7 +642,7 @@ export function useDropzone() {
645
642
  dispatch({
646
643
  acceptedFiles: acceptedFiles,
647
644
  fileRejections: fileRejections,
648
- type: 'setFiles'
645
+ type: "setFiles"
649
646
  });
650
647
 
651
648
  if (onDrop) {
@@ -678,14 +675,16 @@ export function useDropzone() {
678
675
  }
679
676
 
680
677
  dispatch({
681
- type: 'reset'
678
+ type: "reset"
682
679
  });
683
680
  }, [getFilesFromEvent, setFiles, noDragEventsBubbling]); // Fn for opening the file dialog programmatically
684
681
 
685
682
  var openFileDialog = useCallback(function () {
686
- if (useFsAccessApi && canUseFileSystemAccessAPI()) {
683
+ // No point to use FS access APIs if context is not secure
684
+ // https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#feature_detection
685
+ if (fsAccessApiWorksRef.current) {
687
686
  dispatch({
688
- type: 'openDialog'
687
+ type: "openDialog"
689
688
  });
690
689
  onFileDialogOpenCb(); // https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker
691
690
 
@@ -696,20 +695,33 @@ export function useDropzone() {
696
695
  window.showOpenFilePicker(opts).then(function (handles) {
697
696
  return getFilesFromEvent(handles);
698
697
  }).then(function (files) {
699
- return setFiles(files, null);
700
- }).catch(function (e) {
701
- return onFileDialogCancelCb(e);
702
- }).finally(function () {
703
- return dispatch({
704
- type: 'closeDialog'
698
+ setFiles(files, null);
699
+ dispatch({
700
+ type: "closeDialog"
705
701
  });
702
+ }).catch(function (e) {
703
+ // AbortError means the user canceled
704
+ if (isAbort(e)) {
705
+ onFileDialogCancelCb(e);
706
+ dispatch({
707
+ type: "closeDialog"
708
+ });
709
+ } else if (isSecurityError(e)) {
710
+ fsAccessApiWorksRef.current = false; // CORS, so cannot use this API
711
+ // Try using the input
712
+
713
+ if (inputRef.current) {
714
+ inputRef.current.value = null;
715
+ inputRef.current.click();
716
+ }
717
+ }
706
718
  });
707
719
  return;
708
720
  }
709
721
 
710
722
  if (inputRef.current) {
711
723
  dispatch({
712
- type: 'openDialog'
724
+ type: "openDialog"
713
725
  });
714
726
  onFileDialogOpenCb();
715
727
  inputRef.current.value = null;
@@ -727,16 +739,16 @@ export function useDropzone() {
727
739
  event.preventDefault();
728
740
  openFileDialog();
729
741
  }
730
- }, [rootRef, inputRef, openFileDialog]); // Update focus state for the dropzone
742
+ }, [rootRef, openFileDialog]); // Update focus state for the dropzone
731
743
 
732
744
  var onFocusCb = useCallback(function () {
733
745
  dispatch({
734
- type: 'focus'
746
+ type: "focus"
735
747
  });
736
748
  }, []);
737
749
  var onBlurCb = useCallback(function () {
738
750
  dispatch({
739
- type: 'blur'
751
+ type: "blur"
740
752
  });
741
753
  }, []); // Cb to open the file dialog when click occurs on the dropzone
742
754
 
@@ -753,7 +765,7 @@ export function useDropzone() {
753
765
  } else {
754
766
  openFileDialog();
755
767
  }
756
- }, [inputRef, noClick, openFileDialog]);
768
+ }, [noClick, openFileDialog]);
757
769
 
758
770
  var composeHandler = function composeHandler(fn) {
759
771
  return disabled ? null : fn;
@@ -777,7 +789,7 @@ export function useDropzone() {
777
789
  return function () {
778
790
  var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
779
791
  _ref2$refKey = _ref2.refKey,
780
- refKey = _ref2$refKey === void 0 ? 'ref' : _ref2$refKey,
792
+ refKey = _ref2$refKey === void 0 ? "ref" : _ref2$refKey,
781
793
  role = _ref2.role,
782
794
  onKeyDown = _ref2.onKeyDown,
783
795
  onFocus = _ref2.onFocus,
@@ -798,7 +810,7 @@ export function useDropzone() {
798
810
  onDragOver: composeDragHandler(composeEventHandlers(onDragOver, onDragOverCb)),
799
811
  onDragLeave: composeDragHandler(composeEventHandlers(onDragLeave, onDragLeaveCb)),
800
812
  onDrop: composeDragHandler(composeEventHandlers(onDrop, onDropCb)),
801
- role: typeof role === 'string' && role !== '' ? role : 'button'
813
+ role: typeof role === "string" && role !== "" ? role : "button"
802
814
  }, refKey, rootRef), !disabled && !noKeyboard ? {
803
815
  tabIndex: 0
804
816
  } : {}), rest);
@@ -811,7 +823,7 @@ export function useDropzone() {
811
823
  return function () {
812
824
  var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
813
825
  _ref3$refKey = _ref3.refKey,
814
- refKey = _ref3$refKey === void 0 ? 'ref' : _ref3$refKey,
826
+ refKey = _ref3$refKey === void 0 ? "ref" : _ref3$refKey,
815
827
  onChange = _ref3.onChange,
816
828
  onClick = _ref3.onClick,
817
829
  rest = _objectWithoutProperties(_ref3, _excluded4);
@@ -819,13 +831,13 @@ export function useDropzone() {
819
831
  var inputProps = _defineProperty({
820
832
  accept: accept,
821
833
  multiple: multiple,
822
- type: 'file',
834
+ type: "file",
823
835
  style: {
824
- display: 'none'
836
+ display: "none"
825
837
  },
826
838
  onChange: composeHandler(composeEventHandlers(onChange, onDropCb)),
827
839
  onClick: composeHandler(composeEventHandlers(onClick, onInputElementClick)),
828
- autoComplete: 'off',
840
+ autoComplete: "off",
829
841
  tabIndex: -1
830
842
  }, refKey, inputRef);
831
843
 
@@ -857,27 +869,27 @@ export function useDropzone() {
857
869
  function reducer(state, action) {
858
870
  /* istanbul ignore next */
859
871
  switch (action.type) {
860
- case 'focus':
872
+ case "focus":
861
873
  return _objectSpread(_objectSpread({}, state), {}, {
862
874
  isFocused: true
863
875
  });
864
876
 
865
- case 'blur':
877
+ case "blur":
866
878
  return _objectSpread(_objectSpread({}, state), {}, {
867
879
  isFocused: false
868
880
  });
869
881
 
870
- case 'openDialog':
882
+ case "openDialog":
871
883
  return _objectSpread(_objectSpread({}, initialState), {}, {
872
884
  isFileDialogActive: true
873
885
  });
874
886
 
875
- case 'closeDialog':
887
+ case "closeDialog":
876
888
  return _objectSpread(_objectSpread({}, state), {}, {
877
889
  isFileDialogActive: false
878
890
  });
879
891
 
880
- case 'setDraggedFiles':
892
+ case "setDraggedFiles":
881
893
  /* eslint no-case-declarations: 0 */
882
894
  var isDragActive = action.isDragActive,
883
895
  draggedFiles = action.draggedFiles;
@@ -886,13 +898,13 @@ function reducer(state, action) {
886
898
  isDragActive: isDragActive
887
899
  });
888
900
 
889
- case 'setFiles':
901
+ case "setFiles":
890
902
  return _objectSpread(_objectSpread({}, state), {}, {
891
903
  acceptedFiles: action.acceptedFiles,
892
904
  fileRejections: action.fileRejections
893
905
  });
894
906
 
895
- case 'reset':
907
+ case "reset":
896
908
  return _objectSpread({}, initialState);
897
909
 
898
910
  default:
@@ -902,4 +914,4 @@ function reducer(state, action) {
902
914
 
903
915
  function noop() {}
904
916
 
905
- export { ErrorCode } from './utils';
917
+ export { ErrorCode } from "./utils";
@@ -18,12 +18,12 @@ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Sy
18
18
 
19
19
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
20
20
 
21
- import accepts from 'attr-accept'; // Error codes
21
+ import accepts from "attr-accept"; // Error codes
22
22
 
23
- export var FILE_INVALID_TYPE = 'file-invalid-type';
24
- export var FILE_TOO_LARGE = 'file-too-large';
25
- export var FILE_TOO_SMALL = 'file-too-small';
26
- export var TOO_MANY_FILES = 'too-many-files';
23
+ export var FILE_INVALID_TYPE = "file-invalid-type";
24
+ export var FILE_TOO_LARGE = "file-too-large";
25
+ export var FILE_TOO_SMALL = "file-too-small";
26
+ export var TOO_MANY_FILES = "too-many-files";
27
27
  export var ErrorCode = {
28
28
  FileInvalidType: FILE_INVALID_TYPE,
29
29
  FileTooLarge: FILE_TOO_LARGE,
@@ -33,7 +33,7 @@ export var ErrorCode = {
33
33
 
34
34
  export var getInvalidTypeRejectionErr = function getInvalidTypeRejectionErr(accept) {
35
35
  accept = Array.isArray(accept) && accept.length === 1 ? accept[0] : accept;
36
- var messageSuffix = Array.isArray(accept) ? "one of ".concat(accept.join(', ')) : accept;
36
+ var messageSuffix = Array.isArray(accept) ? "one of ".concat(accept.join(", ")) : accept;
37
37
  return {
38
38
  code: FILE_INVALID_TYPE,
39
39
  message: "File type must be ".concat(messageSuffix)
@@ -42,23 +42,23 @@ export var getInvalidTypeRejectionErr = function getInvalidTypeRejectionErr(acce
42
42
  export var getTooLargeRejectionErr = function getTooLargeRejectionErr(maxSize) {
43
43
  return {
44
44
  code: FILE_TOO_LARGE,
45
- message: "File is larger than ".concat(maxSize, " ").concat(maxSize === 1 ? 'byte' : 'bytes')
45
+ message: "File is larger than ".concat(maxSize, " ").concat(maxSize === 1 ? "byte" : "bytes")
46
46
  };
47
47
  };
48
48
  export var getTooSmallRejectionErr = function getTooSmallRejectionErr(minSize) {
49
49
  return {
50
50
  code: FILE_TOO_SMALL,
51
- message: "File is smaller than ".concat(minSize, " ").concat(minSize === 1 ? 'byte' : 'bytes')
51
+ message: "File is smaller than ".concat(minSize, " ").concat(minSize === 1 ? "byte" : "bytes")
52
52
  };
53
53
  };
54
54
  export var TOO_MANY_FILES_REJECTION = {
55
55
  code: TOO_MANY_FILES,
56
- message: 'Too many files'
56
+ message: "Too many files"
57
57
  }; // Firefox versions prior to 53 return a bogus MIME type for every file drag, so dragovers with
58
58
  // that MIME type will always be accepted
59
59
 
60
60
  export function fileAccepted(file, accept) {
61
- var isAcceptable = file.type === 'application/x-moz-file' || accepts(file, accept);
61
+ var isAcceptable = file.type === "application/x-moz-file" || accepts(file, accept);
62
62
  return [isAcceptable, isAcceptable ? null : getInvalidTypeRejectionErr(accept)];
63
63
  }
64
64
  export function fileMatchSize(file, minSize, maxSize) {
@@ -104,9 +104,9 @@ export function allFilesAccepted(_ref) {
104
104
  // to check event.cancelBubble
105
105
 
106
106
  export function isPropagationStopped(event) {
107
- if (typeof event.isPropagationStopped === 'function') {
107
+ if (typeof event.isPropagationStopped === "function") {
108
108
  return event.isPropagationStopped();
109
- } else if (typeof event.cancelBubble !== 'undefined') {
109
+ } else if (typeof event.cancelBubble !== "undefined") {
110
110
  return event.cancelBubble;
111
111
  }
112
112
 
@@ -120,11 +120,11 @@ export function isEvtWithFiles(event) {
120
120
 
121
121
 
122
122
  return Array.prototype.some.call(event.dataTransfer.types, function (type) {
123
- return type === 'Files' || type === 'application/x-moz-file';
123
+ return type === "Files" || type === "application/x-moz-file";
124
124
  });
125
125
  }
126
126
  export function isKindFile(item) {
127
- return _typeof(item) === 'object' && item !== null && item.kind === 'file';
127
+ return _typeof(item) === "object" && item !== null && item.kind === "file";
128
128
  } // allow the entire document to be a drag target
129
129
 
130
130
  export function onDocumentDragOver(event) {
@@ -132,11 +132,11 @@ export function onDocumentDragOver(event) {
132
132
  }
133
133
 
134
134
  function isIe(userAgent) {
135
- return userAgent.indexOf('MSIE') !== -1 || userAgent.indexOf('Trident/') !== -1;
135
+ return userAgent.indexOf("MSIE") !== -1 || userAgent.indexOf("Trident/") !== -1;
136
136
  }
137
137
 
138
138
  function isEdge(userAgent) {
139
- return userAgent.indexOf('Edge/') !== -1;
139
+ return userAgent.indexOf("Edge/") !== -1;
140
140
  }
141
141
 
142
142
  export function isIeOrEdge() {
@@ -180,7 +180,7 @@ export function composeEventHandlers() {
180
180
  */
181
181
 
182
182
  export function canUseFileSystemAccessAPI() {
183
- return 'showOpenFilePicker' in window;
183
+ return "showOpenFilePicker" in window;
184
184
  }
185
185
  /**
186
186
  * filePickerOptionsTypes returns the {types} option for https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker
@@ -190,16 +190,38 @@ export function canUseFileSystemAccessAPI() {
190
190
  */
191
191
 
192
192
  export function filePickerOptionsTypes(accept) {
193
- accept = typeof accept === 'string' ? accept.split(',') : accept;
193
+ accept = typeof accept === "string" ? accept.split(",") : accept;
194
194
  return [{
195
- description: 'everything',
195
+ description: "everything",
196
196
  // TODO: Need to handle filtering more elegantly than this!
197
- accept: Array.isArray(accept) // Accept just MIME types as per spec
197
+ accept: Array.isArray(accept) ? // Accept just MIME types as per spec
198
198
  // NOTE: accept can be https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers
199
- ? accept.filter(function (item) {
200
- return item === 'audio/*' || item === 'video/*' || item === 'image/*' || item === 'text/*' || /\w+\/[-+.\w]+/g.test(item);
199
+ accept.filter(function (item) {
200
+ return item === "audio/*" || item === "video/*" || item === "image/*" || item === "text/*" || /\w+\/[-+.\w]+/g.test(item);
201
201
  }).reduce(function (a, b) {
202
202
  return _objectSpread(_objectSpread({}, a), {}, _defineProperty({}, b, []));
203
203
  }, {}) : {}
204
204
  }];
205
+ }
206
+ /**
207
+ * Check if v is an exception caused by aborting a request (e.g window.showOpenFilePicker()).
208
+ *
209
+ * See https://developer.mozilla.org/en-US/docs/Web/API/DOMException.
210
+ * @param {any} v
211
+ * @returns {boolean} True if v is an abort exception.
212
+ */
213
+
214
+ export function isAbort(v) {
215
+ return v instanceof DOMException && (v.name === "AbortError" || v.code === v.ABORT_ERR);
216
+ }
217
+ /**
218
+ * Check if v is a security error.
219
+ *
220
+ * See https://developer.mozilla.org/en-US/docs/Web/API/DOMException.
221
+ * @param {any} v
222
+ * @returns {boolean} True if v is a security error.
223
+ */
224
+
225
+ export function isSecurityError(v) {
226
+ return v instanceof DOMException && (v.name === "SecurityError" || v.code === v.SECURITY_ERR);
205
227
  }