/*!
* Name: vue-upload-component
* Version: 2.8.9
* Author: LianYue
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.VueUploadComponent = factory());
}(this, (function () { 'use strict';
/**
* Creates a XHR request
*
* @param {Object} options
*/
var createRequest = function createRequest(options) {
var xhr = new XMLHttpRequest();
xhr.open(options.method || 'GET', options.url);
xhr.responseType = 'json';
if (options.headers) {
Object.keys(options.headers).forEach(function (key) {
xhr.setRequestHeader(key, options.headers[key]);
});
}
return xhr;
};
/**
* Sends a XHR request with certain body
*
* @param {XMLHttpRequest} xhr
* @param {Object} body
*/
var sendRequest = function sendRequest(xhr, body) {
return new Promise(function (resolve, reject) {
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
var response;
try {
response = JSON.parse(xhr.response);
} catch (err) {
response = xhr.response;
}
resolve(response);
} else {
reject(xhr.response);
}
};
xhr.onerror = function () {
return reject(xhr.response);
};
xhr.send(JSON.stringify(body));
});
};
/**
* Sends a XHR request with certain form data
*
* @param {XMLHttpRequest} xhr
* @param {Object} data
*/
var sendFormRequest = function sendFormRequest(xhr, data) {
var body = new FormData();
for (var name in data) {
body.append(name, data[name]);
}
return new Promise(function (resolve, reject) {
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
var response;
try {
response = JSON.parse(xhr.response);
} catch (err) {
response = xhr.response;
}
resolve(response);
} else {
reject(xhr.response);
}
};
xhr.onerror = function () {
return reject(xhr.response);
};
xhr.send(body);
});
};
/**
* Creates and sends XHR request
*
* @param {Object} options
*
* @returns Promise
*/
function request (options) {
var xhr = createRequest(options);
return sendRequest(xhr, options.body);
}
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var ChunkUploadHandler = function () {
/**
* Constructor
*
* @param {File} file
* @param {Object} options
*/
function ChunkUploadHandler(file, options) {
_classCallCheck(this, ChunkUploadHandler);
this.file = file;
this.options = options;
}
/**
* Gets the max retries from options
*/
_createClass(ChunkUploadHandler, [{
key: 'createChunks',
/**
* Creates all the chunks in the initial state
*/
value: function createChunks() {
this.chunks = [];
var start = 0;
var end = this.chunkSize;
while (start < this.fileSize) {
this.chunks.push({
blob: this.file.file.slice(start, end),
startOffset: start,
active: false,
retries: this.maxRetries
});
start = end;
end = start + this.chunkSize;
}
}
/**
* Updates the progress of the file with the handler's progress
*/
}, {
key: 'updateFileProgress',
value: function updateFileProgress() {
this.file.progress = this.progress;
}
/**
* Paues the upload process
* - Stops all active requests
* - Sets the file not active
*/
}, {
key: 'pause',
value: function pause() {
this.file.active = false;
this.stopChunks();
}
/**
* Stops all the current chunks
*/
}, {
key: 'stopChunks',
value: function stopChunks() {
this.chunksUploading.forEach(function (chunk) {
chunk.xhr.abort();
chunk.active = false;
});
}
/**
* Resumes the file upload
* - Sets the file active
* - Starts the following chunks
*/
}, {
key: 'resume',
value: function resume() {
this.file.active = true;
this.startChunking();
}
/**
* Starts the file upload
*
* @returns Promise
* - resolve The file was uploaded
* - reject The file upload failed
*/
}, {
key: 'upload',
value: function upload() {
var _this = this;
this.promise = new Promise(function (resolve, reject) {
_this.resolve = resolve;
_this.reject = reject;
});
this.start();
return this.promise;
}
/**
* Start phase
* Sends a request to the backend to initialise the chunks
*/
}, {
key: 'start',
value: function start() {
var _this2 = this;
request({
method: 'POST',
headers: Object.assign({}, this.headers, {
'Content-Type': 'application/json'
}),
url: this.action,
body: Object.assign(this.startBody, {
phase: 'start',
mime_type: this.fileType,
size: this.fileSize,
name: this.fileName
})
}).then(function (res) {
if (res.status !== 'success') {
_this2.file.response = res;
return _this2.reject('server');
}
_this2.sessionId = res.data.session_id;
_this2.chunkSize = res.data.end_offset;
_this2.createChunks();
_this2.startChunking();
}).catch(function (res) {
_this2.file.response = res;
_this2.reject('server');
});
}
/**
* Starts to upload chunks
*/
}, {
key: 'startChunking',
value: function startChunking() {
for (var i = 0; i < this.maxActiveChunks; i++) {
this.uploadNextChunk();
}
}
/**
* Uploads the next chunk
* - Won't do anything if the process is paused
* - Will start finish phase if there are no more chunks to upload
*/
}, {
key: 'uploadNextChunk',
value: function uploadNextChunk() {
if (this.file.active) {
if (this.hasChunksToUpload) {
return this.uploadChunk(this.chunksToUpload[0]);
}
if (this.chunksUploading.length === 0) {
return this.finish();
}
}
}
/**
* Uploads a chunk
* - Sends the chunk to the backend
* - Sets the chunk as uploaded if everything went well
* - Decreases the number of retries if anything went wrong
* - Fails if there are no more retries
*
* @param {Object} chunk
*/
}, {
key: 'uploadChunk',
value: function uploadChunk(chunk) {
var _this3 = this;
chunk.progress = 0;
chunk.active = true;
this.updateFileProgress();
chunk.xhr = createRequest({
method: 'POST',
headers: this.headers,
url: this.action
});
chunk.xhr.upload.addEventListener('progress', function (evt) {
if (evt.lengthComputable) {
chunk.progress = Math.round(evt.loaded / evt.total * 100);
}
}, false);
sendFormRequest(chunk.xhr, Object.assign(this.uploadBody, {
phase: 'upload',
session_id: this.sessionId,
start_offset: chunk.startOffset,
chunk: chunk.blob
})).then(function (res) {
chunk.active = false;
if (res.status === 'success') {
chunk.uploaded = true;
} else {
if (chunk.retries-- <= 0) {
_this3.stopChunks();
return _this3.reject('upload');
}
}
_this3.uploadNextChunk();
}).catch(function () {
chunk.active = false;
if (chunk.retries-- <= 0) {
_this3.stopChunks();
return _this3.reject('upload');
}
_this3.uploadNextChunk();
});
}
/**
* Finish phase
* Sends a request to the backend to finish the process
*/
}, {
key: 'finish',
value: function finish() {
var _this4 = this;
this.updateFileProgress();
request({
method: 'POST',
headers: Object.assign({}, this.headers, {
'Content-Type': 'application/json'
}),
url: this.action,
body: Object.assign(this.finishBody, {
phase: 'finish',
session_id: this.sessionId
})
}).then(function (res) {
_this4.file.response = res;
if (res.status !== 'success') {
return _this4.reject('server');
}
_this4.resolve(res);
}).catch(function (res) {
_this4.file.response = res;
_this4.reject('server');
});
}
}, {
key: 'maxRetries',
get: function get() {
return parseInt(this.options.maxRetries);
}
/**
* Gets the max number of active chunks being uploaded at once from options
*/
}, {
key: 'maxActiveChunks',
get: function get() {
return parseInt(this.options.maxActive);
}
/**
* Gets the file type
*/
}, {
key: 'fileType',
get: function get() {
return this.file.type;
}
/**
* Gets the file size
*/
}, {
key: 'fileSize',
get: function get() {
return this.file.size;
}
/**
* Gets the file size
*/
}, {
key: 'fileName',
get: function get() {
return this.file.name;
}
/**
* Gets action (url) to upload the file
*/
}, {
key: 'action',
get: function get() {
return this.options.action || null;
}
/**
* Gets the body to be merged when sending the request in start phase
*/
}, {
key: 'startBody',
get: function get() {
return this.options.startBody || {};
}
/**
* Gets the body to be merged when sending the request in upload phase
*/
}, {
key: 'uploadBody',
get: function get() {
return this.options.uploadBody || {};
}
/**
* Gets the body to be merged when sending the request in finish phase
*/
}, {
key: 'finishBody',
get: function get() {
return this.options.finishBody || {};
}
/**
* Gets the headers of the requests from options
*/
}, {
key: 'headers',
get: function get() {
return this.options.headers || {};
}
/**
* Whether it's ready to upload files or not
*/
}, {
key: 'readyToUpload',
get: function get() {
return !!this.chunks;
}
/**
* Gets the progress of the chunk upload
* - Gets all the completed chunks
* - Gets the progress of all the chunks that are being uploaded
*/
}, {
key: 'progress',
get: function get() {
var _this5 = this;
var completedProgress = this.chunksUploaded.length / this.chunks.length * 100;
var uploadingProgress = this.chunksUploading.reduce(function (progress, chunk) {
return progress + (chunk.progress | 0) / _this5.chunks.length;
}, 0);
return Math.min(completedProgress + uploadingProgress, 100);
}
/**
* Gets all the chunks that are pending to be uploaded
*/
}, {
key: 'chunksToUpload',
get: function get() {
return this.chunks.filter(function (chunk) {
return !chunk.active && !chunk.uploaded;
});
}
/**
* Whether there are chunks to upload or not
*/
}, {
key: 'hasChunksToUpload',
get: function get() {
return this.chunksToUpload.length > 0;
}
/**
* Gets all the chunks that are uploading
*/
}, {
key: 'chunksUploading',
get: function get() {
return this.chunks.filter(function (chunk) {
return !!chunk.xhr && !!chunk.active;
});
}
/**
* Gets all the chunks that have finished uploading
*/
}, {
key: 'chunksUploaded',
get: function get() {
return this.chunks.filter(function (chunk) {
return !!chunk.uploaded;
});
}
}]);
return ChunkUploadHandler;
}();
//
//
//
//
//
//
//
//
//
//
//
//
//
var script = {
methods: {
change: function change(e) {
this.$destroy();
this.$parent.addInputFile(e.target);
// eslint-disable-next-line
new this.constructor({
parent: this.$parent,
el: this.$el
});
}
}
};
var __vue_script__ = script;
/* template */
var __vue_render__ = function __vue_render__() {
var _vm = this;var _h = _vm.$createElement;var _c = _vm._self._c || _h;return _c('input', { attrs: { "type": "file", "name": _vm.$parent.name, "id": _vm.$parent.inputId || _vm.$parent.name, "accept": _vm.$parent.accept, "capture": _vm.$parent.capture, "webkitdirectory": _vm.$parent.directory && _vm.$parent.features.directory, "directory": _vm.$parent.directory && _vm.$parent.features.directory, "multiple": _vm.$parent.multiple && _vm.$parent.features.html5 }, on: { "change": _vm.change } }, []);
};
var __vue_staticRenderFns__ = [];
var __vue_template__ = typeof __vue_render__ !== 'undefined' ? { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ } : {};
/* style */
var __vue_inject_styles__ = undefined;
/* scoped */
var __vue_scope_id__ = undefined;
/* module identifier */
var __vue_module_identifier__ = "data-v-36701cce";
/* functional template */
var __vue_is_functional_template__ = false;
/* component normalizer */
function __vue_normalize__(template, style, script$$1, scope, functional, moduleIdentifier, createInjector, createInjectorSSR) {
var component = script$$1 || {};
if (!component.render) {
component.render = template.render;
component.staticRenderFns = template.staticRenderFns;
component._compiled = true;
if (functional) component.functional = true;
}
component._scopeId = scope;
return component;
}
/* style inject */
/* style inject SSR */
function __vue_create_injector_ssr__(context) {
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__;
}
if (!context) return function () {};
if (!context.hasOwnProperty('styles')) {
Object.defineProperty(context, 'styles', {
enumerable: true,
get: function get() {
return context._styles;
}
});
context._renderStyles = renderStyles;
}
function renderStyles(styles) {
var css = '';
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = styles[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _ref = _step.value;
var ids = _ref.ids,
media = _ref.media,
parts = _ref.parts;
css += '';
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return css;
}
return function addStyle(id, css) {
var group = css.media || 'default';
var style = context._styles[group] || (context._styles[group] = { ids: [], parts: [] });
if (!style.ids.includes(id)) {
style.media = css.media;
style.ids.push(id);
var code = css.source;
style.parts.push(code);
}
};
}
var InputFile = __vue_normalize__(__vue_template__, __vue_inject_styles__, typeof __vue_script__ === 'undefined' ? {} : __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, typeof __vue_create_injector__ !== 'undefined' ? __vue_create_injector__ : function () {}, typeof __vue_create_injector_ssr__ !== 'undefined' ? __vue_create_injector_ssr__ : function () {});
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 _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
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); } }
var CHUNK_DEFAULT_OPTIONS = {
headers: {},
action: '',
minSize: 1048576,
maxActive: 3,
maxRetries: 5,
handler: ChunkUploadHandler
};
var script$1 = {
components: {
InputFile: InputFile
},
props: {
inputId: {
type: String
},
name: {
type: String,
default: 'file'
},
accept: {
type: String
},
capture: {},
multiple: {
type: Boolean
},
maximum: {
type: Number,
default: function _default() {
return this.multiple ? 0 : 1;
}
},
addIndex: {
type: [Boolean, Number]
},
directory: {
type: Boolean
},
postAction: {
type: String
},
putAction: {
type: String
},
customAction: {
type: Function
},
headers: {
type: Object,
default: Object
},
data: {
type: Object,
default: Object
},
timeout: {
type: Number,
default: 0
},
drop: {
default: false
},
dropDirectory: {
type: Boolean,
default: true
},
size: {
type: Number,
default: 0
},
extensions: {
default: Array
},
value: {
type: Array,
default: Array
},
thread: {
type: Number,
default: 1
},
// Chunk upload enabled
chunkEnabled: {
type: Boolean,
default: false
},
// Chunk upload properties
chunk: {
type: Object,
default: function _default() {
return CHUNK_DEFAULT_OPTIONS;
}
}
},
data: function data() {
return {
files: this.value,
features: {
html5: true,
directory: false,
drag: false
},
active: false,
dropActive: false,
uploading: 0,
destroy: false
};
},
/**
* mounted
* @return {[type]} [description]
*/
mounted: function mounted() {
var input = document.createElement('input');
input.type = 'file';
input.multiple = true;
// html5 特征
if (window.FormData && input.files) {
// 上传目录特征
if (typeof input.webkitdirectory === 'boolean' || typeof input.directory === 'boolean') {
this.features.directory = true;
}
// 拖拽特征
if (this.features.html5 && typeof input.ondrop !== 'undefined') {
this.features.drop = true;
}
} else {
this.features.html5 = false;
}
// files 定位缓存
this.maps = {};
this.$nextTick(function () {
// 更新下父级
if (this.$parent) {
this.$parent.$forceUpdate();
}
// 拖拽渲染
this.watchDrop(this.drop);
});
},
/**
* beforeDestroy
* @return {[type]} [description]
*/
beforeDestroy: function beforeDestroy() {
// 已销毁
this.destroy = true;
// 设置成不激活
this.active = false;
},
computed: {
/**
* uploading 正在上传的线程
* @return {[type]} [description]
*/
/**
* uploaded 文件列表是否全部已上传
* @return {[type]} [description]
*/
uploaded: function uploaded() {
var file = void 0;
for (var i = 0; i < this.files.length; i++) {
file = this.files[i];
if (file.fileObject && !file.error && !file.success) {
return false;
}
}
return true;
},
chunkOptions: function chunkOptions() {
return Object.assign(CHUNK_DEFAULT_OPTIONS, this.chunk);
},
className: function className() {
return ['file-uploads', this.features.html5 ? 'file-uploads-html5' : 'file-uploads-html4', this.features.directory && this.directory ? 'file-uploads-directory' : undefined, this.features.drop && this.drop ? 'file-uploads-drop' : undefined];
}
},
watch: {
active: function active(_active) {
this.watchActive(_active);
},
dropActive: function dropActive() {
if (this.$parent) {
this.$parent.$forceUpdate();
}
},
drop: function drop(value) {
this.watchDrop(value);
},
value: function value(files) {
if (this.files === files) {
return;
}
this.files = files;
var oldMaps = this.maps;
// 重写 maps 缓存
this.maps = {};
for (var i = 0; i < this.files.length; i++) {
var file = this.files[i];
this.maps[file.id] = file;
}
// add, update
for (var key in this.maps) {
var newFile = this.maps[key];
var oldFile = oldMaps[key];
if (newFile !== oldFile) {
this.emitFile(newFile, oldFile);
}
}
// delete
for (var _key in oldMaps) {
if (!this.maps[_key]) {
this.emitFile(undefined, oldMaps[_key]);
}
}
}
},
methods: {
// 清空
clear: function clear() {
if (this.files.length) {
var files = this.files;
this.files = [];
// 定位
this.maps = {};
// 事件
this.emitInput();
for (var i = 0; i < files.length; i++) {
this.emitFile(undefined, files[i]);
}
}
return true;
},
// 选择
get: function get(id) {
if (!id) {
return false;
}
if ((typeof id === 'undefined' ? 'undefined' : _typeof(id)) === 'object') {
return this.maps[id.id] || false;
}
return this.maps[id] || false;
},
// 添加
add: function add(_files) {
var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.addIndex;
var files = _files;
var isArray = files instanceof Array;
// 不是数组整理成数组
if (!isArray) {
files = [files];
}
// 遍历规范对象
var addFiles = [];
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (this.features.html5 && file instanceof Blob) {
file = {
file: file,
size: file.size,
name: file.webkitRelativePath || file.relativePath || file.name || 'unknown',
type: file.type
};
}
var fileObject = false;
if (file.fileObject === false) ; else if (file.fileObject) {
fileObject = true;
} else if (typeof Element !== 'undefined' && file.el instanceof Element) {
fileObject = true;
} else if (typeof Blob !== 'undefined' && file.file instanceof Blob) {
fileObject = true;
}
if (fileObject) {
file = _extends({
fileObject: true,
size: -1,
name: 'Filename',
type: '',
active: false,
error: '',
success: false,
putAction: this.putAction,
postAction: this.postAction,
timeout: this.timeout
}, file, {
response: {},
progress: '0.00', // 只读
speed: 0 // 只读
// xhr: false, // 只读
// iframe: false, // 只读
});
file.data = _extends({}, this.data, file.data ? file.data : {});
file.headers = _extends({}, this.headers, file.headers ? file.headers : {});
}
// 必须包含 id
if (!file.id) {
file.id = Math.random().toString(36).substr(2);
}
if (this.emitFilter(file, undefined)) {
continue;
}
// 最大数量限制
if (this.maximum > 1 && addFiles.length + this.files.length >= this.maximum) {
break;
}
addFiles.push(file);
// 最大数量限制
if (this.maximum === 1) {
break;
}
}
// 没有文件
if (!addFiles.length) {
return false;
}
// 如果是 1 清空
if (this.maximum === 1) {
this.clear();
}
// 添加进去 files
var newFiles = void 0;
if (index === true || index === 0) {
newFiles = addFiles.concat(this.files);
} else if (index) {
newFiles = addFiles.concat([]);
newFiles.splice(index, 0, addFiles);
} else {
newFiles = this.files.concat(addFiles);
}
this.files = newFiles;
// 定位
for (var _i = 0; _i < addFiles.length; _i++) {
var _file2 = addFiles[_i];
this.maps[_file2.id] = _file2;
}
// 事件
this.emitInput();
for (var _i2 = 0; _i2 < addFiles.length; _i2++) {
this.emitFile(addFiles[_i2], undefined);
}
return isArray ? addFiles : addFiles[0];
},
// 添加表单文件
addInputFile: function addInputFile(el) {
var files = [];
if (el.files) {
for (var i = 0; i < el.files.length; i++) {
var file = el.files[i];
files.push({
size: file.size,
name: file.webkitRelativePath || file.relativePath || file.name,
type: file.type,
file: file,
el: el
});
}
} else {
var names = el.value.replace(/\\/g, '/').split('/');
files.push({
name: names[names.length - 1],
el: el
});
}
return this.add(files);
},
// 添加 DataTransfer
addDataTransfer: function addDataTransfer(dataTransfer) {
var _this = this;
var files = [];
if (dataTransfer.items && dataTransfer.items.length) {
var items = [];
for (var i = 0; i < dataTransfer.items.length; i++) {
var item = dataTransfer.items[i];
if (item.getAsEntry) {
item = item.getAsEntry() || item.getAsFile();
} else if (item.webkitGetAsEntry) {
item = item.webkitGetAsEntry() || item.getAsFile();
} else {
item = item.getAsFile();
}
if (item) {
items.push(item);
}
}
return new Promise(function (resolve, reject) {
var forEach = function forEach(i) {
var item = items[i];
// 结束 文件数量大于 最大数量
if (!item || _this.maximum > 0 && files.length >= _this.maximum) {
return resolve(_this.add(files));
}
_this.getEntry(item).then(function (results) {
files.push.apply(files, _toConsumableArray(results));
forEach(i + 1);
});
};
forEach(0);
});
}
if (dataTransfer.files.length) {
for (var _i3 = 0; _i3 < dataTransfer.files.length; _i3++) {
files.push(dataTransfer.files[_i3]);
if (this.maximum > 0 && files.length >= this.maximum) {
break;
}
}
return Promise.resolve(this.add(files));
}
return Promise.resolve([]);
},
// 获得 entry
getEntry: function getEntry(entry) {
var _this2 = this;
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
return new Promise(function (resolve, reject) {
if (entry.isFile) {
entry.file(function (file) {
resolve([{
size: file.size,
name: path + file.name,
type: file.type,
file: file
}]);
});
} else if (entry.isDirectory && _this2.dropDirectory) {
var files = [];
var dirReader = entry.createReader();
var readEntries = function readEntries() {
dirReader.readEntries(function (entries) {
var forEach = function forEach(i) {
if (!entries[i] && i === 0 || _this2.maximum > 0 && files.length >= _this2.maximum) {
return resolve(files);
}
if (!entries[i]) {
return readEntries();
}
_this2.getEntry(entries[i], path + entry.name + '/').then(function (results) {
files.push.apply(files, _toConsumableArray(results));
forEach(i + 1);
});
};
forEach(0);
});
};
readEntries();
} else {
resolve([]);
}
});
},
replace: function replace(id1, id2) {
var file1 = this.get(id1);
var file2 = this.get(id2);
if (!file1 || !file2 || file1 === file2) {
return false;
}
var files = this.files.concat([]);
var index1 = files.indexOf(file1);
var index2 = files.indexOf(file2);
if (index1 === -1 || index2 === -1) {
return false;
}
files[index1] = file2;
files[index2] = file1;
this.files = files;
this.emitInput();
return true;
},
// 移除
remove: function remove(id) {
var file = this.get(id);
if (file) {
if (this.emitFilter(undefined, file)) {
return false;
}
var files = this.files.concat([]);
var index = files.indexOf(file);
if (index === -1) {
console.error('remove', file);
return false;
}
files.splice(index, 1);
this.files = files;
// 定位
delete this.maps[file.id];
// 事件
this.emitInput();
this.emitFile(undefined, file);
}
return file;
},
// 更新
update: function update(id, data) {
var file = this.get(id);
if (file) {
var newFile = _extends({}, file, data);
// 停用必须加上错误
if (file.fileObject && file.active && !newFile.active && !newFile.error && !newFile.success) {
newFile.error = 'abort';
}
if (this.emitFilter(newFile, file)) {
return false;
}
var files = this.files.concat([]);
var index = files.indexOf(file);
if (index === -1) {
console.error('update', file);
return false;
}
files.splice(index, 1, newFile);
this.files = files;
// 删除 旧定位 写入 新定位 (已便支持修改id)
delete this.maps[file.id];
this.maps[newFile.id] = newFile;
// 事件
this.emitInput();
this.emitFile(newFile, file);
return newFile;
}
return false;
},
// 预处理 事件 过滤器
emitFilter: function emitFilter(newFile, oldFile) {
var isPrevent = false;
this.$emit('input-filter', newFile, oldFile, function () {
isPrevent = true;
return isPrevent;
});
return isPrevent;
},
// 处理后 事件 分发
emitFile: function emitFile(newFile, oldFile) {
this.$emit('input-file', newFile, oldFile);
if (newFile && newFile.fileObject && newFile.active && (!oldFile || !oldFile.active)) {
this.uploading++;
// 激活
this.$nextTick(function () {
var _this3 = this;
setTimeout(function () {
_this3.upload(newFile).then(function () {
// eslint-disable-next-line
newFile = _this3.get(newFile);
if (newFile && newFile.fileObject) {
_this3.update(newFile, {
active: false,
success: !newFile.error
});
}
}).catch(function (e) {
_this3.update(newFile, {
active: false,
success: false,
error: e.code || e.error || e.message || e
});
});
}, parseInt(Math.random() * 50 + 50, 10));
});
} else if ((!newFile || !newFile.fileObject || !newFile.active) && oldFile && oldFile.fileObject && oldFile.active) {
// 停止
this.uploading--;
}
// 自动延续激活
if (this.active && (Boolean(newFile) !== Boolean(oldFile) || newFile.active !== oldFile.active)) {
this.watchActive(true);
}
},
emitInput: function emitInput() {
this.$emit('input', this.files);
},
// 上传
upload: function upload(id) {
var file = this.get(id);
// 被删除
if (!file) {
return Promise.reject('not_exists');
}
// 不是文件对象
if (!file.fileObject) {
return Promise.reject('file_object');
}
// 有错误直接响应
if (file.error) {
return Promise.reject(file.error);
}
// 已完成直接响应
if (file.success) {
return Promise.resolve(file);
}
// 后缀
var extensions = this.extensions;
if (extensions && (extensions.length || typeof extensions.length === 'undefined')) {
if ((typeof extensions === 'undefined' ? 'undefined' : _typeof(extensions)) !== 'object' || !(extensions instanceof RegExp)) {
if (typeof extensions === 'string') {
extensions = extensions.split(',').map(function (value) {
return value.trim();
}).filter(function (value) {
return value;
});
}
extensions = new RegExp('\\.(' + extensions.join('|').replace(/\./g, '\\.') + ')$', 'i');
}
if (file.name.search(extensions) === -1) {
return Promise.reject('extension');
}
}
// 大小
if (this.size > 0 && file.size >= 0 && file.size > this.size) {
return Promise.reject('size');
}
if (this.customAction) {
return this.customAction(file, this);
}
if (this.features.html5) {
if (this.shouldUseChunkUpload(file)) {
return this.uploadChunk(file);
}
if (file.putAction) {
return this.uploadPut(file);
}
if (file.postAction) {
return this.uploadHtml5(file);
}
}
if (file.postAction) {
return this.uploadHtml4(file);
}
return Promise.reject('No action configured');
},
/**
* Whether this file should be uploaded using chunk upload or not
*
* @param Object file
*/
shouldUseChunkUpload: function shouldUseChunkUpload(file) {
return this.chunkEnabled && !!this.chunkOptions.handler && file.size > this.chunkOptions.minSize;
},
/**
* Upload a file using Chunk method
*
* @param File file
*/
uploadChunk: function uploadChunk(file) {
var HandlerClass = this.chunkOptions.handler;
file.chunk = new HandlerClass(file, this.chunkOptions);
return file.chunk.upload();
},
uploadPut: function uploadPut(file) {
var querys = [];
var value = void 0;
for (var key in file.data) {
value = file.data[key];
if (value !== null && value !== undefined) {
querys.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
}
}
var queryString = querys.length ? (file.putAction.indexOf('?') === -1 ? '?' : '&') + querys.join('&') : '';
var xhr = new XMLHttpRequest();
xhr.open('PUT', file.putAction + queryString);
return this.uploadXhr(xhr, file, file.file);
},
uploadHtml5: function uploadHtml5(file) {
var form = new window.FormData();
var value = void 0;
for (var key in file.data) {
value = file.data[key];
if (value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && typeof value.toString !== 'function') {
if (value instanceof File) {
form.append(key, value, value.name);
} else {
form.append(key, JSON.stringify(value));
}
} else if (value !== null && value !== undefined) {
form.append(key, value);
}
}
form.append(this.name, file.file, file.file.filename || file.name);
var xhr = new XMLHttpRequest();
xhr.open('POST', file.postAction);
return this.uploadXhr(xhr, file, form);
},
uploadXhr: function uploadXhr(xhr, _file, body) {
var _this4 = this;
var file = _file;
var speedTime = 0;
var speedLoaded = 0;
// 进度条
xhr.upload.onprogress = function (e) {
// 还未开始上传 已删除 未激活
file = _this4.get(file);
if (!e.lengthComputable || !file || !file.fileObject || !file.active) {
return;
}
// 进度 速度 每秒更新一次
var speedTime2 = Math.round(Date.now() / 1000);
if (speedTime2 === speedTime) {
return;
}
speedTime = speedTime2;
file = _this4.update(file, {
progress: (e.loaded / e.total * 100).toFixed(2),
speed: e.loaded - speedLoaded
});
speedLoaded = e.loaded;
};
// 检查激活状态
var interval = setInterval(function () {
file = _this4.get(file);
if (file && file.fileObject && !file.success && !file.error && file.active) {
return;
}
if (interval) {
clearInterval(interval);
interval = false;
}
try {
xhr.abort();
xhr.timeout = 1;
} catch (e) {}
}, 100);
return new Promise(function (resolve, reject) {
var complete = void 0;
var fn = function fn(e) {
// 已经处理过了
if (complete) {
return;
}
complete = true;
if (interval) {
clearInterval(interval);
interval = false;
}
file = _this4.get(file);
// 不存在直接响应
if (!file) {
return reject('not_exists');
}
// 不是文件对象
if (!file.fileObject) {
return reject('file_object');
}
// 有错误自动响应
if (file.error) {
return reject(file.error);
}
// 未激活
if (!file.active) {
return reject('abort');
}
// 已完成 直接相应
if (file.success) {
return resolve(file);
}
var data = {};
switch (e.type) {
case 'timeout':
case 'abort':
data.error = e.type;
break;
case 'error':
if (!xhr.status) {
data.error = 'network';
} else if (xhr.status >= 500) {
data.error = 'server';
} else if (xhr.status >= 400) {
data.error = 'denied';
}
break;
default:
if (xhr.status >= 500) {
data.error = 'server';
} else if (xhr.status >= 400) {
data.error = 'denied';
} else {
data.progress = '100.00';
}
}
if (xhr.responseText) {
var contentType = xhr.getResponseHeader('Content-Type');
if (contentType && contentType.indexOf('/json') !== -1) {
data.response = JSON.parse(xhr.responseText);
} else {
data.response = xhr.responseText;
}
}
// 更新
file = _this4.update(file, data);
// 相应错误
if (file.error) {
return reject(file.error);
}
// 响应
return resolve(file);
};
// 事件
xhr.onload = fn;
xhr.onerror = fn;
xhr.onabort = fn;
xhr.ontimeout = fn;
// 超时
if (file.timeout) {
xhr.timeout = file.timeout;
}
// headers
for (var key in file.headers) {
xhr.setRequestHeader(key, file.headers[key]);
}
// 更新 xhr
file = _this4.update(file, { xhr: xhr });
// 开始上传
xhr.send(body);
});
},
uploadHtml4: function uploadHtml4(_file) {
var _this5 = this;
var file = _file;
var onKeydown = function onKeydown(e) {
if (e.keyCode === 27) {
e.preventDefault();
}
};
var iframe = document.createElement('iframe');
iframe.id = 'upload-iframe-' + file.id;
iframe.name = 'upload-iframe-' + file.id;
iframe.src = 'about:blank';
iframe.setAttribute('style', 'width:1px;height:1px;top:-999em;position:absolute; margin-top:-999em;');
var form = document.createElement('form');
form.action = file.postAction;
form.name = 'upload-form-' + file.id;
form.setAttribute('method', 'POST');
form.setAttribute('target', 'upload-iframe-' + file.id);
form.setAttribute('enctype', 'multipart/form-data');
var value = void 0;
var input = void 0;
for (var key in file.data) {
value = file.data[key];
if (value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && typeof value.toString !== 'function') {
value = JSON.stringify(value);
}
if (value !== null && value !== undefined) {
input = document.createElement('input');
input.type = 'hidden';
input.name = key;
input.value = value;
form.appendChild(input);
}
}
form.appendChild(file.el);
document.body.appendChild(iframe).appendChild(form);
var getResponseData = function getResponseData() {
var doc = void 0;
try {
if (iframe.contentWindow) {
doc = iframe.contentWindow.document;
}
} catch (err) {}
if (!doc) {
try {
doc = iframe.contentDocument ? iframe.contentDocument : iframe.document;
} catch (err) {
doc = iframe.document;
}
}
if (doc && doc.body) {
return doc.body.innerHTML;
}
return null;
};
return new Promise(function (resolve, reject) {
setTimeout(function () {
file = _this5.update(file, { iframe: iframe });
// 不存在
if (!file) {
return reject('not_exists');
}
// 定时检查
var interval = setInterval(function () {
file = _this5.get(file);
if (file && file.fileObject && !file.success && !file.error && file.active) {
return;
}
if (interval) {
clearInterval(interval);
interval = false;
}
iframe.onabort({ type: file ? 'abort' : 'not_exists' });
}, 100);
var complete = void 0;
var fn = function fn(e) {
// 已经处理过了
if (complete) {
return;
}
complete = true;
if (interval) {
clearInterval(interval);
interval = false;
}
// 关闭 esc 事件
document.body.removeEventListener('keydown', onKeydown);
file = _this5.get(file);
// 不存在直接响应
if (!file) {
return reject('not_exists');
}
// 不是文件对象
if (!file.fileObject) {
return reject('file_object');
}
// 有错误自动响应
if (file.error) {
return reject(file.error);
}
// 未激活
if (!file.active) {
return reject('abort');
}
// 已完成 直接相应
if (file.success) {
return resolve(file);
}
var response = getResponseData();
var data = {};
switch (e.type) {
case 'abort':
data.error = 'abort';
break;
case 'error':
if (file.error) {
data.error = file.error;
} else if (response === null) {
data.error = 'network';
} else {
data.error = 'denied';
}
break;
default:
if (file.error) {
data.error = file.error;
} else if (data === null) {
data.error = 'network';
} else {
data.progress = '100.00';
}
}
if (response !== null) {
if (response && response.substr(0, 1) === '{' && response.substr(response.length - 1, 1) === '}') {
try {
response = JSON.parse(response);
} catch (err) {}
}
data.response = response;
}
// 更新
file = _this5.update(file, data);
if (file.error) {
return reject(file.error);
}
// 响应
return resolve(file);
};
// 添加事件
iframe.onload = fn;
iframe.onerror = fn;
iframe.onabort = fn;
// 禁止 esc 键
document.body.addEventListener('keydown', onKeydown);
// 提交
form.submit();
}, 50);
}).then(function (res) {
iframe.parentNode && iframe.parentNode.removeChild(iframe);
return res;
}).catch(function (res) {
iframe.parentNode && iframe.parentNode.removeChild(iframe);
return res;
});
},
watchActive: function watchActive(active) {
var file = void 0;
var index = 0;
while (file = this.files[index]) {
index++;
if (!file.fileObject) ; else if (active && !this.destroy) {
if (this.uploading >= this.thread || this.uploading && !this.features.html5) {
break;
}
if (!file.active && !file.error && !file.success) {
this.update(file, { active: true });
}
} else {
if (file.active) {
this.update(file, { active: false });
}
}
}
if (this.uploading === 0) {
this.active = false;
}
},
watchDrop: function watchDrop(_el) {
var el = _el;
if (!this.features.drop) {
return;
}
// 移除挂载
if (this.dropElement) {
try {
document.removeEventListener('dragenter', this.onDragenter, false);
document.removeEventListener('dragleave', this.onDragleave, false);
document.removeEventListener('drop', this.onDocumentDrop, false);
this.dropElement.removeEventListener('dragover', this.onDragover, false);
this.dropElement.removeEventListener('drop', this.onDrop, false);
} catch (e) {}
}
if (!el) {
el = false;
} else if (typeof el === 'string') {
el = document.querySelector(el) || this.$root.$el.querySelector(el);
} else if (el === true) {
el = this.$parent.$el;
}
this.dropElement = el;
if (this.dropElement) {
document.addEventListener('dragenter', this.onDragenter, false);
document.addEventListener('dragleave', this.onDragleave, false);
document.addEventListener('drop', this.onDocumentDrop, false);
this.dropElement.addEventListener('dragover', this.onDragover, false);
this.dropElement.addEventListener('drop', this.onDrop, false);
}
},
onDragenter: function onDragenter(e) {
e.preventDefault();
if (!this.dropActive) {
this.dropActive = true;
}
},
onDragleave: function onDragleave(e) {
e.preventDefault();
if (e.target.nodeName === 'HTML' || e.target === e.explicitOriginalTarget || e.screenX === 0 && e.screenY === 0 && !e.fromElement && e.offsetX <= 0) {
this.dropActive = false;
}
},
onDragover: function onDragover(e) {
e.preventDefault();
},
onDocumentDrop: function onDocumentDrop() {
this.dropActive = false;
},
onDrop: function onDrop(e) {
e.preventDefault();
this.addDataTransfer(e.dataTransfer);
}
}
};
var __vue_script__$1 = script$1;
/* template */
var __vue_render__$1 = function __vue_render__() {
var _vm = this;var _h = _vm.$createElement;var _c = _vm._self._c || _h;return _c('label', { class: _vm.className }, [_vm._t("default"), _vm._ssrNode(" "), _c('input-file')], 2);
};
var __vue_staticRenderFns__$1 = [];
var __vue_template__$1 = typeof __vue_render__$1 !== 'undefined' ? { render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 } : {};
/* style */
var __vue_inject_styles__$1 = undefined;
/* scoped */
var __vue_scope_id__$1 = undefined;
/* module identifier */
var __vue_module_identifier__$1 = "data-v-00c97c04";
/* functional template */
var __vue_is_functional_template__$1 = false;
/* component normalizer */
function __vue_normalize__$1(template, style, script, scope, functional, moduleIdentifier, createInjector, createInjectorSSR) {
var component = script || {};
if (!component.render) {
component.render = template.render;
component.staticRenderFns = template.staticRenderFns;
component._compiled = true;
if (functional) component.functional = true;
}
component._scopeId = scope;
return component;
}
/* style inject */
/* style inject SSR */
function __vue_create_injector_ssr__$1(context) {
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__;
}
if (!context) return function () {};
if (!context.hasOwnProperty('styles')) {
Object.defineProperty(context, 'styles', {
enumerable: true,
get: function get() {
return context._styles;
}
});
context._renderStyles = renderStyles;
}
function renderStyles(styles) {
var css = '';
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = styles[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _ref = _step.value;
var ids = _ref.ids,
media = _ref.media,
parts = _ref.parts;
css += '';
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return css;
}
return function addStyle(id, css) {
var group = css.media || 'default';
var style = context._styles[group] || (context._styles[group] = { ids: [], parts: [] });
if (!style.ids.includes(id)) {
style.media = css.media;
style.ids.push(id);
var code = css.source;
style.parts.push(code);
}
};
}
var FileUpload = __vue_normalize__$1(__vue_template__$1, __vue_inject_styles__$1, typeof __vue_script__$1 === 'undefined' ? {} : __vue_script__$1, __vue_scope_id__$1, __vue_is_functional_template__$1, __vue_module_identifier__$1, typeof __vue_create_injector__ !== 'undefined' ? __vue_create_injector__ : function () {}, typeof __vue_create_injector_ssr__$1 !== 'undefined' ? __vue_create_injector_ssr__$1 : function () {});
var FileUpload$1 = /*#__PURE__*/Object.freeze({
default: FileUpload
});
var require$$0 = ( FileUpload$1 && FileUpload ) || FileUpload$1;
var src = require$$0;
return src;
})));