ant-design-vue
Version:
An enterprise-class UI design language and Vue-based implementation
342 lines • 12.1 kB
JavaScript
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _typeof from "@babel/runtime/helpers/esm/typeof";
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
var _excluded = ["componentTag", "prefixCls", "disabled", "id", "multiple", "accept", "capture", "directory", "openFileDialogOnClick", "onMouseenter", "onMouseleave"];
import { createVNode as _createVNode } from "vue";
import _regeneratorRuntime from "@babel/runtime/regenerator";
import defaultRequest from './request';
import getUid from './uid';
import attrAccept from './attr-accept';
import traverseFileTree from './traverseFileTree';
import { uploadProps } from './interface';
import { defineComponent, onBeforeUnmount, onMounted, ref } from 'vue';
import pickAttrs from '../_util/pickAttrs';
import partition from 'lodash-es/partition';
export default defineComponent({
compatConfig: {
MODE: 3
},
name: 'AjaxUploader',
inheritAttrs: false,
props: uploadProps(),
setup: function setup(props, _ref) {
var slots = _ref.slots,
attrs = _ref.attrs,
expose = _ref.expose;
var uid = ref(getUid());
var reqs = {};
var fileInput = ref();
var isMounted = false;
/**
* Process file before upload. When all the file is ready, we start upload.
*/
var processFile = /*#__PURE__*/function () {
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(file, fileList) {
var beforeUpload, transformedFile, action, mergedAction, data, mergedData, parsedData, parsedFile, mergedParsedFile;
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
beforeUpload = props.beforeUpload;
transformedFile = file;
if (!beforeUpload) {
_context.next = 14;
break;
}
_context.prev = 3;
_context.next = 6;
return beforeUpload(file, fileList);
case 6:
transformedFile = _context.sent;
_context.next = 12;
break;
case 9:
_context.prev = 9;
_context.t0 = _context["catch"](3);
// Rejection will also trade as false
transformedFile = false;
case 12:
if (!(transformedFile === false)) {
_context.next = 14;
break;
}
return _context.abrupt("return", {
origin: file,
parsedFile: null,
action: null,
data: null
});
case 14:
// Get latest action
action = props.action;
if (!(typeof action === 'function')) {
_context.next = 21;
break;
}
_context.next = 18;
return action(file);
case 18:
mergedAction = _context.sent;
_context.next = 22;
break;
case 21:
mergedAction = action;
case 22:
// Get latest data
data = props.data;
if (!(typeof data === 'function')) {
_context.next = 29;
break;
}
_context.next = 26;
return data(file);
case 26:
mergedData = _context.sent;
_context.next = 30;
break;
case 29:
mergedData = data;
case 30:
parsedData =
// string type is from legacy `transformFile`.
// Not sure if this will work since no related test case works with it
(_typeof(transformedFile) === 'object' || typeof transformedFile === 'string') && transformedFile ? transformedFile : file;
if (parsedData instanceof File) {
parsedFile = parsedData;
} else {
parsedFile = new File([parsedData], file.name, {
type: file.type
});
}
mergedParsedFile = parsedFile;
mergedParsedFile.uid = file.uid;
return _context.abrupt("return", {
origin: file,
data: mergedData,
parsedFile: mergedParsedFile,
action: mergedAction
});
case 35:
case "end":
return _context.stop();
}
}, _callee, null, [[3, 9]]);
}));
return function processFile(_x, _x2) {
return _ref2.apply(this, arguments);
};
}();
var post = function post(_ref3) {
var data = _ref3.data,
origin = _ref3.origin,
action = _ref3.action,
parsedFile = _ref3.parsedFile;
if (!isMounted) {
return;
}
var onStart = props.onStart,
customRequest = props.customRequest,
name = props.name,
headers = props.headers,
withCredentials = props.withCredentials,
method = props.method;
var uid = origin.uid;
var request = customRequest || defaultRequest;
var requestOption = {
action: action,
filename: name,
data: data,
file: parsedFile,
headers: headers,
withCredentials: withCredentials,
method: method || 'post',
onProgress: function onProgress(e) {
var onProgress = props.onProgress;
onProgress === null || onProgress === void 0 ? void 0 : onProgress(e, parsedFile);
},
onSuccess: function onSuccess(ret, xhr) {
var onSuccess = props.onSuccess;
onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(ret, parsedFile, xhr);
delete reqs[uid];
},
onError: function onError(err, ret) {
var onError = props.onError;
onError === null || onError === void 0 ? void 0 : onError(err, ret, parsedFile);
delete reqs[uid];
}
};
onStart(origin);
reqs[uid] = request(requestOption);
};
var reset = function reset() {
uid.value = getUid();
};
var abort = function abort(file) {
if (file) {
var _uid = file.uid ? file.uid : file;
if (reqs[_uid] && reqs[_uid].abort) {
reqs[_uid].abort();
}
delete reqs[_uid];
} else {
Object.keys(reqs).forEach(function (uid) {
if (reqs[uid] && reqs[uid].abort) {
reqs[uid].abort();
}
delete reqs[uid];
});
}
};
onMounted(function () {
isMounted = true;
});
onBeforeUnmount(function () {
isMounted = false;
abort();
});
var uploadFiles = function uploadFiles(files) {
var originFiles = _toConsumableArray(files);
var postFiles = originFiles.map(function (file) {
// eslint-disable-next-line no-param-reassign
file.uid = getUid();
return processFile(file, originFiles);
});
// Batch upload files
Promise.all(postFiles).then(function (fileList) {
var onBatchStart = props.onBatchStart;
onBatchStart === null || onBatchStart === void 0 ? void 0 : onBatchStart(fileList.map(function (_ref4) {
var origin = _ref4.origin,
parsedFile = _ref4.parsedFile;
return {
file: origin,
parsedFile: parsedFile
};
}));
fileList.filter(function (file) {
return file.parsedFile !== null;
}).forEach(function (file) {
post(file);
});
});
};
var onChange = function onChange(e) {
var accept = props.accept,
directory = props.directory;
var files = e.target.files;
var acceptedFiles = _toConsumableArray(files).filter(function (file) {
return !directory || attrAccept(file, accept);
});
uploadFiles(acceptedFiles);
reset();
};
var onClick = function onClick(e) {
var el = fileInput.value;
if (!el) {
return;
}
var onClick = props.onClick;
// TODO
// if (children && (children as any).type === 'button') {
// const parent = el.parentNode as HTMLInputElement;
// parent.focus();
// parent.querySelector('button').blur();
// }
el.click();
if (onClick) {
onClick(e);
}
};
var onKeyDown = function onKeyDown(e) {
if (e.key === 'Enter') {
onClick(e);
}
};
var onFileDrop = function onFileDrop(e) {
var multiple = props.multiple;
e.preventDefault();
if (e.type === 'dragover') {
return;
}
if (props.directory) {
traverseFileTree(Array.prototype.slice.call(e.dataTransfer.items), uploadFiles, function (_file) {
return attrAccept(_file, props.accept);
});
} else {
var files = partition(Array.prototype.slice.call(e.dataTransfer.files), function (file) {
return attrAccept(file, props.accept);
});
var successFiles = files[0];
var errorFiles = files[1];
if (multiple === false) {
successFiles = successFiles.slice(0, 1);
}
uploadFiles(successFiles);
if (errorFiles.length && props.onReject) props.onReject(errorFiles);
}
};
expose({
abort: abort
});
return function () {
var _cls, _slots$default;
var Tag = props.componentTag,
prefixCls = props.prefixCls,
disabled = props.disabled,
id = props.id,
multiple = props.multiple,
accept = props.accept,
capture = props.capture,
directory = props.directory,
openFileDialogOnClick = props.openFileDialogOnClick,
onMouseenter = props.onMouseenter,
onMouseleave = props.onMouseleave,
otherProps = _objectWithoutProperties(props, _excluded);
var cls = (_cls = {}, _defineProperty(_cls, prefixCls, true), _defineProperty(_cls, "".concat(prefixCls, "-disabled"), disabled), _defineProperty(_cls, attrs.class, !!attrs.class), _cls);
// because input don't have directory/webkitdirectory type declaration
var dirProps = directory ? {
directory: 'directory',
webkitdirectory: 'webkitdirectory'
} : {};
var events = disabled ? {} : {
onClick: openFileDialogOnClick ? onClick : function () {},
onKeydown: openFileDialogOnClick ? onKeyDown : function () {},
onMouseenter: onMouseenter,
onMouseleave: onMouseleave,
onDrop: onFileDrop,
onDragover: onFileDrop,
tabindex: '0'
};
return _createVNode(Tag, _objectSpread(_objectSpread({}, events), {}, {
"class": cls,
"role": "button",
"style": attrs.style
}), {
default: function _default() {
return [_createVNode("input", _objectSpread(_objectSpread(_objectSpread({}, pickAttrs(otherProps, {
aria: true,
data: true
})), {}, {
"id": id,
"type": "file",
"ref": fileInput,
"onClick": function onClick(e) {
return e.stopPropagation();
},
"key": uid.value,
"style": {
display: 'none'
},
"accept": accept
}, dirProps), {}, {
"multiple": multiple,
"onChange": onChange
}, capture != null ? {
capture: capture
} : {}), null), (_slots$default = slots.default) === null || _slots$default === void 0 ? void 0 : _slots$default.call(slots)];
}
});
};
}
});