-
Notifications
You must be signed in to change notification settings - Fork 115
/
h5peditor-file-uploader.js
138 lines (122 loc) · 3.94 KB
/
h5peditor-file-uploader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
H5PEditor.FileUploader = (function ($, EventDispatcher) {
/**
* File Upload API for H5P
*
* @class H5PEditor.FileUploader
* @extends H5P.EventDispatcher
* @param {Object} field Required for validating the uploaded file
*/
function FileUploader(field) {
var self = this;
// Initialize event inheritance
EventDispatcher.call(self);
/**
* Triggers the actual upload of the file.
*
* @param {Blob|File} file
* @param {string} filename Required due to validation
*/
self.upload = function (file, filename, context = {}) {
var formData = new FormData();
formData.append('file', file, filename);
formData.append('field', JSON.stringify(field));
formData.append('contentId', H5PEditor.contentId || 0);
// Submit the form
var request = new XMLHttpRequest();
request.upload.onprogress = function (e) {
if (e.lengthComputable) {
self.trigger('uploadProgress', {
...context,
progress: (e.loaded / e.total)
});
}
};
request.onload = function () {
var result;
var uploadComplete = {
...context,
error: null,
data: null
};
try {
result = JSON.parse(request.responseText);
}
catch (err) {
H5P.error(err);
// Add error data to event object
uploadComplete.error = H5PEditor.t('core', 'fileToLarge');
}
if (result !== undefined) {
if (result.error !== undefined) {
uploadComplete.error = result.error;
}
if (result.success === false) {
uploadComplete.error = (result.message ? result.message : H5PEditor.t('core', 'unknownFileUploadError'));
}
}
if (uploadComplete.error === null) {
// No problems, add response data to event object
uploadComplete.data = result;
}
// Allow the widget to process the result
self.trigger('uploadComplete', uploadComplete);
};
request.open('POST', H5PEditor.getAjaxUrl('files'), true);
request.send(formData);
self.trigger('upload');
};
/**
* Upload the list of file objects.
* TODO: Future improvement, iterate for multiple files
*
* @param {File[]} files
*/
self.uploadFiles = function (files, context = {}) {
self.upload(files[0], files[0].name, context);
};
/**
* Open the file selector and trigger upload upon selecting file.
*/
self.openFileSelector = function ({ onChangeCallback, context } = {}) {
// Create a file selector
const input = document.createElement('input');
input.type = 'file';
input.setAttribute('accept', determineAllowedMimeTypes());
input.style='display:none';
input.addEventListener('change', function () {
if (typeof onChangeCallback === 'function') {
onChangeCallback();
}
// When files are selected, upload them
self.uploadFiles(this.files, context);
document.body.removeChild(input);
});
document.body.appendChild(input);
// Open file selector
input.click();
};
/**
* Determine allowed file mimes. Used to make it easier to find and
* select the correct file.
*
* @return {string}
*/
const determineAllowedMimeTypes = function () {
if (field.mimes) {
return field.mimes.join(',');
}
switch (field.type) {
case 'image':
return 'image/jpeg,image/png,image/gif';
case 'audio':
return 'audio/mpeg,audio/x-wav,audio/ogg,audio/mp4';
case 'video':
return 'video/mp4,video/webm,video/ogg';
}
}
}
// Extends the event dispatcher
FileUploader.prototype = Object.create(EventDispatcher.prototype);
FileUploader.prototype.constructor = FileUploader;
return FileUploader;
})(H5P.jQuery, H5P.EventDispatcher);