Files
goTorrent/goTorrentWebUI/node_modules/react-dropzone/dist/es/index.js

619 lines
20 KiB
JavaScript

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/* eslint prefer-template: 0 */
import React from 'react';
import PropTypes from 'prop-types';
import { supportMultiple, fileAccepted, allFilesAccepted, fileMatchSize, onDocumentDragOver, getDataTransferItems } from './utils';
import styles from './utils/styles';
var Dropzone = function (_React$Component) {
_inherits(Dropzone, _React$Component);
function Dropzone(props, context) {
_classCallCheck(this, Dropzone);
var _this = _possibleConstructorReturn(this, (Dropzone.__proto__ || Object.getPrototypeOf(Dropzone)).call(this, props, context));
_this.renderChildren = function (children, isDragActive, isDragAccept, isDragReject) {
if (typeof children === 'function') {
return children(_extends({}, _this.state, {
isDragActive: isDragActive,
isDragAccept: isDragAccept,
isDragReject: isDragReject
}));
}
return children;
};
_this.composeHandlers = _this.composeHandlers.bind(_this);
_this.onClick = _this.onClick.bind(_this);
_this.onDocumentDrop = _this.onDocumentDrop.bind(_this);
_this.onDragEnter = _this.onDragEnter.bind(_this);
_this.onDragLeave = _this.onDragLeave.bind(_this);
_this.onDragOver = _this.onDragOver.bind(_this);
_this.onDragStart = _this.onDragStart.bind(_this);
_this.onDrop = _this.onDrop.bind(_this);
_this.onFileDialogCancel = _this.onFileDialogCancel.bind(_this);
_this.onInputElementClick = _this.onInputElementClick.bind(_this);
_this.setRef = _this.setRef.bind(_this);
_this.setRefs = _this.setRefs.bind(_this);
_this.isFileDialogActive = false;
_this.state = {
draggedFiles: [],
acceptedFiles: [],
rejectedFiles: []
};
return _this;
}
_createClass(Dropzone, [{
key: 'componentDidMount',
value: function componentDidMount() {
var preventDropOnDocument = this.props.preventDropOnDocument;
this.dragTargets = [];
if (preventDropOnDocument) {
document.addEventListener('dragover', onDocumentDragOver, false);
document.addEventListener('drop', this.onDocumentDrop, false);
}
this.fileInputEl.addEventListener('click', this.onInputElementClick, false);
// Tried implementing addEventListener, but didn't work out
document.body.onfocus = this.onFileDialogCancel;
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
var preventDropOnDocument = this.props.preventDropOnDocument;
if (preventDropOnDocument) {
document.removeEventListener('dragover', onDocumentDragOver);
document.removeEventListener('drop', this.onDocumentDrop);
}
if (this.fileInputEl != null) {
this.fileInputEl.removeEventListener('click', this.onInputElementClick, false);
}
// Can be replaced with removeEventListener, if addEventListener works
if (document != null) {
document.body.onfocus = null;
}
}
}, {
key: 'composeHandlers',
value: function composeHandlers(handler) {
if (this.props.disabled) {
return null;
}
return handler;
}
}, {
key: 'onDocumentDrop',
value: function onDocumentDrop(evt) {
if (this.node && this.node.contains(evt.target)) {
// if we intercepted an event for our instance, let it propagate down to the instance's onDrop handler
return;
}
evt.preventDefault();
this.dragTargets = [];
}
}, {
key: 'onDragStart',
value: function onDragStart(evt) {
if (this.props.onDragStart) {
this.props.onDragStart.call(this, evt);
}
}
}, {
key: 'onDragEnter',
value: function onDragEnter(evt) {
evt.preventDefault();
// Count the dropzone and any children that are entered.
if (this.dragTargets.indexOf(evt.target) === -1) {
this.dragTargets.push(evt.target);
}
this.setState({
isDragActive: true, // Do not rely on files for the drag state. It doesn't work in Safari.
draggedFiles: getDataTransferItems(evt)
});
if (this.props.onDragEnter) {
this.props.onDragEnter.call(this, evt);
}
}
}, {
key: 'onDragOver',
value: function onDragOver(evt) {
// eslint-disable-line class-methods-use-this
evt.preventDefault();
evt.stopPropagation();
try {
// The file dialog on Chrome allows users to drag files from the dialog onto
// the dropzone, causing the browser the crash when the file dialog is closed.
// A drop effect of 'none' prevents the file from being dropped
evt.dataTransfer.dropEffect = this.isFileDialogActive ? 'none' : 'copy'; // eslint-disable-line no-param-reassign
} catch (err) {
// continue regardless of error
}
if (this.props.onDragOver) {
this.props.onDragOver.call(this, evt);
}
return false;
}
}, {
key: 'onDragLeave',
value: function onDragLeave(evt) {
var _this2 = this;
evt.preventDefault();
// Only deactivate once the dropzone and all children have been left.
this.dragTargets = this.dragTargets.filter(function (el) {
return el !== evt.target && _this2.node.contains(el);
});
if (this.dragTargets.length > 0) {
return;
}
// Clear dragging files state
this.setState({
isDragActive: false,
draggedFiles: []
});
if (this.props.onDragLeave) {
this.props.onDragLeave.call(this, evt);
}
}
}, {
key: 'onDrop',
value: function onDrop(evt) {
var _this3 = this;
var _props = this.props,
onDrop = _props.onDrop,
onDropAccepted = _props.onDropAccepted,
onDropRejected = _props.onDropRejected,
multiple = _props.multiple,
disablePreview = _props.disablePreview,
accept = _props.accept;
var fileList = getDataTransferItems(evt);
var acceptedFiles = [];
var rejectedFiles = [];
// Stop default browser behavior
evt.preventDefault();
// Reset the counter along with the drag on a drop.
this.dragTargets = [];
this.isFileDialogActive = false;
fileList.forEach(function (file) {
if (!disablePreview) {
try {
file.preview = window.URL.createObjectURL(file); // eslint-disable-line no-param-reassign
} catch (err) {
if (process.env.NODE_ENV !== 'production') {
console.error('Failed to generate preview for file', file, err); // eslint-disable-line no-console
}
}
}
if (fileAccepted(file, accept) && fileMatchSize(file, _this3.props.maxSize, _this3.props.minSize)) {
acceptedFiles.push(file);
} else {
rejectedFiles.push(file);
}
});
if (!multiple) {
// if not in multi mode add any extra accepted files to rejected.
// This will allow end users to easily ignore a multi file drop in "single" mode.
rejectedFiles.push.apply(rejectedFiles, _toConsumableArray(acceptedFiles.splice(1)));
}
if (onDrop) {
onDrop.call(this, acceptedFiles, rejectedFiles, evt);
}
if (rejectedFiles.length > 0 && onDropRejected) {
onDropRejected.call(this, rejectedFiles, evt);
}
if (acceptedFiles.length > 0 && onDropAccepted) {
onDropAccepted.call(this, acceptedFiles, evt);
}
// Clear files value
this.draggedFiles = null;
// Reset drag state
this.setState({
isDragActive: false,
draggedFiles: [],
acceptedFiles: acceptedFiles,
rejectedFiles: rejectedFiles
});
}
}, {
key: 'onClick',
value: function onClick(evt) {
var _props2 = this.props,
onClick = _props2.onClick,
disableClick = _props2.disableClick;
if (!disableClick) {
evt.stopPropagation();
if (onClick) {
onClick.call(this, evt);
}
// in IE11/Edge the file-browser dialog is blocking, ensure this is behind setTimeout
// this is so react can handle state changes in the onClick prop above above
// see: https://github.com/react-dropzone/react-dropzone/issues/450
setTimeout(this.open.bind(this), 0);
}
}
}, {
key: 'onInputElementClick',
value: function onInputElementClick(evt) {
evt.stopPropagation();
if (this.props.inputProps && this.props.inputProps.onClick) {
this.props.inputProps.onClick();
}
}
}, {
key: 'onFileDialogCancel',
value: function onFileDialogCancel() {
// timeout will not recognize context of this method
var onFileDialogCancel = this.props.onFileDialogCancel;
var fileInputEl = this.fileInputEl;
var isFileDialogActive = this.isFileDialogActive;
// execute the timeout only if the onFileDialogCancel is defined and FileDialog
// is opened in the browser
if (onFileDialogCancel && isFileDialogActive) {
setTimeout(function () {
// Returns an object as FileList
var FileList = fileInputEl.files;
if (!FileList.length) {
isFileDialogActive = false;
onFileDialogCancel();
}
}, 300);
}
}
}, {
key: 'setRef',
value: function setRef(ref) {
this.node = ref;
}
}, {
key: 'setRefs',
value: function setRefs(ref) {
this.fileInputEl = ref;
}
/**
* Open system file upload dialog.
*
* @public
*/
}, {
key: 'open',
value: function open() {
this.isFileDialogActive = true;
this.fileInputEl.value = null;
this.fileInputEl.click();
}
}, {
key: 'render',
value: function render() {
var _props3 = this.props,
accept = _props3.accept,
acceptClassName = _props3.acceptClassName,
activeClassName = _props3.activeClassName,
children = _props3.children,
disabled = _props3.disabled,
disabledClassName = _props3.disabledClassName,
inputProps = _props3.inputProps,
multiple = _props3.multiple,
name = _props3.name,
rejectClassName = _props3.rejectClassName,
rest = _objectWithoutProperties(_props3, ['accept', 'acceptClassName', 'activeClassName', 'children', 'disabled', 'disabledClassName', 'inputProps', 'multiple', 'name', 'rejectClassName']);
var acceptStyle = rest.acceptStyle,
activeStyle = rest.activeStyle,
_rest$className = rest.className,
className = _rest$className === undefined ? '' : _rest$className,
disabledStyle = rest.disabledStyle,
rejectStyle = rest.rejectStyle,
style = rest.style,
props = _objectWithoutProperties(rest, ['acceptStyle', 'activeStyle', 'className', 'disabledStyle', 'rejectStyle', 'style']);
var _state = this.state,
isDragActive = _state.isDragActive,
draggedFiles = _state.draggedFiles;
var filesCount = draggedFiles.length;
var isMultipleAllowed = multiple || filesCount <= 1;
var isDragAccept = filesCount > 0 && allFilesAccepted(draggedFiles, this.props.accept);
var isDragReject = filesCount > 0 && (!isDragAccept || !isMultipleAllowed);
var noStyles = !className && !style && !activeStyle && !acceptStyle && !rejectStyle && !disabledStyle;
if (isDragActive && activeClassName) {
className += ' ' + activeClassName;
}
if (isDragAccept && acceptClassName) {
className += ' ' + acceptClassName;
}
if (isDragReject && rejectClassName) {
className += ' ' + rejectClassName;
}
if (disabled && disabledClassName) {
className += ' ' + disabledClassName;
}
if (noStyles) {
style = styles.default;
activeStyle = styles.active;
acceptStyle = style.active;
rejectStyle = styles.rejected;
disabledStyle = styles.disabled;
}
var appliedStyle = _extends({}, style);
if (activeStyle && isDragActive) {
appliedStyle = _extends({}, style, activeStyle);
}
if (acceptStyle && isDragAccept) {
appliedStyle = _extends({}, appliedStyle, acceptStyle);
}
if (rejectStyle && isDragReject) {
appliedStyle = _extends({}, appliedStyle, rejectStyle);
}
if (disabledStyle && disabled) {
appliedStyle = _extends({}, style, disabledStyle);
}
var inputAttributes = {
accept: accept,
disabled: disabled,
type: 'file',
style: { display: 'none' },
multiple: supportMultiple && multiple,
ref: this.setRefs,
onChange: this.onDrop,
autoComplete: 'off'
};
if (name && name.length) {
inputAttributes.name = name;
}
// Destructure custom props away from props used for the div element
var acceptedFiles = props.acceptedFiles,
preventDropOnDocument = props.preventDropOnDocument,
disablePreview = props.disablePreview,
disableClick = props.disableClick,
onDropAccepted = props.onDropAccepted,
onDropRejected = props.onDropRejected,
onFileDialogCancel = props.onFileDialogCancel,
maxSize = props.maxSize,
minSize = props.minSize,
divProps = _objectWithoutProperties(props, ['acceptedFiles', 'preventDropOnDocument', 'disablePreview', 'disableClick', 'onDropAccepted', 'onDropRejected', 'onFileDialogCancel', 'maxSize', 'minSize']);
return React.createElement(
'div',
_extends({
className: className,
style: appliedStyle
}, divProps /* expand user provided props first so event handlers are never overridden */, {
onClick: this.composeHandlers(this.onClick),
onDragStart: this.composeHandlers(this.onDragStart),
onDragEnter: this.composeHandlers(this.onDragEnter),
onDragOver: this.composeHandlers(this.onDragOver),
onDragLeave: this.composeHandlers(this.onDragLeave),
onDrop: this.composeHandlers(this.onDrop),
ref: this.setRef,
'aria-disabled': disabled
}),
this.renderChildren(children, isDragActive, isDragAccept, isDragReject),
React.createElement('input', _extends({}, inputProps /* expand user provided inputProps first so inputAttributes override them */, inputAttributes))
);
}
}]);
return Dropzone;
}(React.Component);
export default Dropzone;
Dropzone.propTypes = {
/**
* Allow specific types of files. See https://github.com/okonet/attr-accept for more information.
* Keep in mind that mime type determination is not reliable across platforms. CSV files,
* for example, are reported as text/plain under macOS but as application/vnd.ms-excel under
* Windows. In some cases there might not be a mime type set at all.
* See: https://github.com/react-dropzone/react-dropzone/issues/276
*/
accept: PropTypes.string,
/**
* Contents of the dropzone
*/
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
/**
* Disallow clicking on the dropzone container to open file dialog
*/
disableClick: PropTypes.bool,
/**
* Enable/disable the dropzone entirely
*/
disabled: PropTypes.bool,
/**
* Enable/disable preview generation
*/
disablePreview: PropTypes.bool,
/**
* If false, allow dropped items to take over the current browser window
*/
preventDropOnDocument: PropTypes.bool,
/**
* Pass additional attributes to the `<input type="file"/>` tag
*/
inputProps: PropTypes.object,
/**
* Allow dropping multiple files
*/
multiple: PropTypes.bool,
/**
* `name` attribute for the input tag
*/
name: PropTypes.string,
/**
* Maximum file size
*/
maxSize: PropTypes.number,
/**
* Minimum file size
*/
minSize: PropTypes.number,
/**
* className
*/
className: PropTypes.string,
/**
* className for active state
*/
activeClassName: PropTypes.string,
/**
* className for accepted state
*/
acceptClassName: PropTypes.string,
/**
* className for rejected state
*/
rejectClassName: PropTypes.string,
/**
* className for disabled state
*/
disabledClassName: PropTypes.string,
/**
* CSS styles to apply
*/
style: PropTypes.object,
/**
* CSS styles to apply when drag is active
*/
activeStyle: PropTypes.object,
/**
* CSS styles to apply when drop will be accepted
*/
acceptStyle: PropTypes.object,
/**
* CSS styles to apply when drop will be rejected
*/
rejectStyle: PropTypes.object,
/**
* CSS styles to apply when dropzone is disabled
*/
disabledStyle: PropTypes.object,
/**
* onClick callback
* @param {Event} event
*/
onClick: PropTypes.func,
/**
* onDrop callback
*/
onDrop: PropTypes.func,
/**
* onDropAccepted callback
*/
onDropAccepted: PropTypes.func,
/**
* onDropRejected callback
*/
onDropRejected: PropTypes.func,
/**
* onDragStart callback
*/
onDragStart: PropTypes.func,
/**
* onDragEnter callback
*/
onDragEnter: PropTypes.func,
/**
* onDragOver callback
*/
onDragOver: PropTypes.func,
/**
* onDragLeave callback
*/
onDragLeave: PropTypes.func,
/**
* Provide a callback on clicking the cancel button of the file dialog
*/
onFileDialogCancel: PropTypes.func
};
Dropzone.defaultProps = {
preventDropOnDocument: true,
disabled: false,
disablePreview: false,
disableClick: false,
multiple: true,
maxSize: Infinity,
minSize: 0
};