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 +1 -3
- package/README.md +6 -1
- package/commitlint.config.js +1 -1
- package/dist/es/index.js +66 -54
- package/dist/es/utils/index.js +44 -22
- package/dist/index.js +2 -2
- package/examples/accept/README.md +10 -3
- package/package.json +7 -6
- package/rollup.config.js +20 -20
- package/src/.eslintrc +1 -2
- package/src/index.js +333 -281
- package/src/index.spec.js +1851 -1523
- package/src/utils/index.js +128 -73
- package/src/utils/index.spec.js +440 -289
- package/styleguide.config.js +55 -52
- package/testSetup.js +7 -1
- package/typings/.eslintrc +1 -1
- package/typings/react-dropzone.d.ts +25 -14
- package/typings/tests/accept.tsx +10 -9
- package/typings/tests/all.tsx +7 -5
- package/typings/tests/basic.tsx +8 -7
- package/typings/tests/events.tsx +8 -6
- package/typings/tests/file-dialog.tsx +4 -3
- package/typings/tests/hook.tsx +6 -6
- package/typings/tests/plugin.tsx +11 -22
- package/typings/tests/refs.tsx +4 -4
package/.eslintrc
CHANGED
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
[](https://codecov.io/gh/react-dropzone/react-dropzone)
|
|
7
7
|
[](#backers)
|
|
8
8
|
[](#sponsors)
|
|
9
|
-
[](https://gitpod.io/#https://github.com/react-dropzone/react-dropzone)
|
|
9
|
+
[](https://gitpod.io/#https://github.com/react-dropzone/react-dropzone)
|
|
10
|
+
[](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
|
|
package/commitlint.config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = { extends: [
|
|
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
|
|
38
|
-
import PropTypes from
|
|
39
|
-
import { fromEvent } from
|
|
40
|
-
import { allFilesAccepted, composeEventHandlers, fileAccepted, fileMatchSize, filePickerOptionsTypes, canUseFileSystemAccessAPI, isEvtWithFiles, isIeOrEdge, isPropagationStopped, onDocumentDragOver, TOO_MANY_FILES_REJECTION } from
|
|
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 =
|
|
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:
|
|
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 ===
|
|
453
|
+
return typeof onFileDialogOpen === "function" ? onFileDialogOpen : noop;
|
|
454
454
|
}, [onFileDialogOpen]);
|
|
455
455
|
var onFileDialogCancelCb = useMemo(function () {
|
|
456
|
-
return typeof onFileDialogCancel ===
|
|
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;
|
|
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:
|
|
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
|
-
|
|
490
|
-
return function () {};
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
window.addEventListener('focus', onWindowFocus, false);
|
|
490
|
+
window.addEventListener("focus", onWindowFocus, false);
|
|
494
491
|
return function () {
|
|
495
|
-
window.removeEventListener(
|
|
492
|
+
window.removeEventListener("focus", onWindowFocus, false);
|
|
496
493
|
};
|
|
497
|
-
}, [inputRef, isFileDialogActive, onFileDialogCancelCb,
|
|
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(
|
|
513
|
-
document.addEventListener(
|
|
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(
|
|
519
|
-
document.removeEventListener(
|
|
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:
|
|
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 =
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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:
|
|
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
|
-
|
|
700
|
-
|
|
701
|
-
|
|
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:
|
|
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,
|
|
742
|
+
}, [rootRef, openFileDialog]); // Update focus state for the dropzone
|
|
731
743
|
|
|
732
744
|
var onFocusCb = useCallback(function () {
|
|
733
745
|
dispatch({
|
|
734
|
-
type:
|
|
746
|
+
type: "focus"
|
|
735
747
|
});
|
|
736
748
|
}, []);
|
|
737
749
|
var onBlurCb = useCallback(function () {
|
|
738
750
|
dispatch({
|
|
739
|
-
type:
|
|
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
|
-
}, [
|
|
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 ?
|
|
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 ===
|
|
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 ?
|
|
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:
|
|
834
|
+
type: "file",
|
|
823
835
|
style: {
|
|
824
|
-
display:
|
|
836
|
+
display: "none"
|
|
825
837
|
},
|
|
826
838
|
onChange: composeHandler(composeEventHandlers(onChange, onDropCb)),
|
|
827
839
|
onClick: composeHandler(composeEventHandlers(onClick, onInputElementClick)),
|
|
828
|
-
autoComplete:
|
|
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
|
|
872
|
+
case "focus":
|
|
861
873
|
return _objectSpread(_objectSpread({}, state), {}, {
|
|
862
874
|
isFocused: true
|
|
863
875
|
});
|
|
864
876
|
|
|
865
|
-
case
|
|
877
|
+
case "blur":
|
|
866
878
|
return _objectSpread(_objectSpread({}, state), {}, {
|
|
867
879
|
isFocused: false
|
|
868
880
|
});
|
|
869
881
|
|
|
870
|
-
case
|
|
882
|
+
case "openDialog":
|
|
871
883
|
return _objectSpread(_objectSpread({}, initialState), {}, {
|
|
872
884
|
isFileDialogActive: true
|
|
873
885
|
});
|
|
874
886
|
|
|
875
|
-
case
|
|
887
|
+
case "closeDialog":
|
|
876
888
|
return _objectSpread(_objectSpread({}, state), {}, {
|
|
877
889
|
isFileDialogActive: false
|
|
878
890
|
});
|
|
879
891
|
|
|
880
|
-
case
|
|
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
|
|
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
|
|
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
|
|
917
|
+
export { ErrorCode } from "./utils";
|
package/dist/es/utils/index.js
CHANGED
|
@@ -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
|
|
21
|
+
import accepts from "attr-accept"; // Error codes
|
|
22
22
|
|
|
23
|
-
export var FILE_INVALID_TYPE =
|
|
24
|
-
export var FILE_TOO_LARGE =
|
|
25
|
-
export var FILE_TOO_SMALL =
|
|
26
|
-
export var 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(
|
|
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 ?
|
|
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 ?
|
|
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:
|
|
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 ===
|
|
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 ===
|
|
107
|
+
if (typeof event.isPropagationStopped === "function") {
|
|
108
108
|
return event.isPropagationStopped();
|
|
109
|
-
} else if (typeof event.cancelBubble !==
|
|
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 ===
|
|
123
|
+
return type === "Files" || type === "application/x-moz-file";
|
|
124
124
|
});
|
|
125
125
|
}
|
|
126
126
|
export function isKindFile(item) {
|
|
127
|
-
return _typeof(item) ===
|
|
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(
|
|
135
|
+
return userAgent.indexOf("MSIE") !== -1 || userAgent.indexOf("Trident/") !== -1;
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
function isEdge(userAgent) {
|
|
139
|
-
return userAgent.indexOf(
|
|
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
|
|
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 ===
|
|
193
|
+
accept = typeof accept === "string" ? accept.split(",") : accept;
|
|
194
194
|
return [{
|
|
195
|
-
description:
|
|
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
|
-
|
|
200
|
-
return 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
|
}
|