diff --git a/app/assets/javascripts/admin/addon/components/resumable-upload.js b/app/assets/javascripts/admin/addon/components/resumable-upload.js
deleted file mode 100644
index 8e3ce18e8cc..00000000000
--- a/app/assets/javascripts/admin/addon/components/resumable-upload.js
+++ /dev/null
@@ -1,140 +0,0 @@
-import discourseComputed, { on } from "discourse-common/utils/decorators";
-import { later, schedule } from "@ember/runloop";
-import Component from "@ember/component";
-import I18n from "I18n";
-import getURL from "discourse-common/lib/get-url";
-import { iconHTML } from "discourse-common/lib/icon-library";
-
-/*global Resumable:true */
-
-/**
- Example usage:
-
- {{resumable-upload
- target="/admin/backups/upload"
- success=(action "successAction")
- error=(action "errorAction")
- uploadText="UPLOAD"
- }}
-**/
-export default Component.extend({
- tagName: "button",
- classNames: ["btn", "ru"],
- classNameBindings: ["isUploading"],
- attributeBindings: ["translatedTitle:title"],
- resumable: null,
- isUploading: false,
- progress: 0,
- rerenderTriggers: ["isUploading", "progress"],
- uploadingIcon: null,
- progressBar: null,
-
- @on("init")
- _initialize() {
- this.resumable = new Resumable({
- target: getURL(this.target),
- maxFiles: 1, // only 1 file at a time
- headers: {
- "X-CSRF-Token": document.querySelector("meta[name='csrf-token']")
- .content,
- },
- });
-
- this.resumable.on("fileAdded", () => {
- // automatically upload the selected file
- this.resumable.upload();
-
- // mark as uploading
- later(() => {
- this.set("isUploading", true);
- this._updateIcon();
- });
- });
-
- this.resumable.on("fileProgress", (file) => {
- // update progress
- later(() => {
- this.set("progress", parseInt(file.progress() * 100, 10));
- this._updateProgressBar();
- });
- });
-
- this.resumable.on("fileSuccess", (file) => {
- later(() => {
- // mark as not uploading anymore
- this._reset();
-
- // fire an event to allow the parent route to reload its model
- this.success(file.fileName);
- });
- });
-
- this.resumable.on("fileError", (file, message) => {
- later(() => {
- // mark as not uploading anymore
- this._reset();
-
- // fire an event to allow the parent route to display the error message
- this.error(file.fileName, message);
- });
- });
- },
-
- @on("didInsertElement")
- _assignBrowse() {
- schedule("afterRender", () => this.resumable.assignBrowse($(this.element)));
- },
-
- @on("willDestroyElement")
- _teardown() {
- if (this.resumable) {
- this.resumable.cancel();
- this.resumable = null;
- }
- },
-
- @discourseComputed("title", "text")
- translatedTitle(title, text) {
- return title ? I18n.t(title) : text;
- },
-
- @discourseComputed("isUploading", "progress")
- text(isUploading, progress) {
- if (isUploading) {
- return progress + " %";
- } else {
- return this.uploadText;
- }
- },
-
- didReceiveAttrs() {
- this._super(...arguments);
- this._updateIcon();
- },
-
- click() {
- if (this.isUploading) {
- this.resumable.cancel();
- later(() => this._reset());
- return false;
- } else {
- return true;
- }
- },
-
- _updateIcon() {
- const icon = this.isUploading ? "times" : "upload";
- this.set("uploadingIcon", `${iconHTML(icon)}`.htmlSafe());
- },
-
- _updateProgressBar() {
- const pb = `${"width:" + this.progress + "%"}`.htmlSafe();
- this.set("progressBar", pb);
- },
-
- _reset() {
- this.setProperties({ isUploading: false, progress: 0 });
- this._updateIcon();
- this._updateProgressBar();
- },
-});
diff --git a/app/assets/javascripts/discourse/app/components/backup-uploader.js b/app/assets/javascripts/discourse/app/components/backup-uploader.js
deleted file mode 100644
index 69e9ba6db09..00000000000
--- a/app/assets/javascripts/discourse/app/components/backup-uploader.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import Component from "@ember/component";
-import I18n from "I18n";
-import UploadMixin from "discourse/mixins/upload";
-import { ajax } from "discourse/lib/ajax";
-import discourseComputed from "discourse-common/utils/decorators";
-import { on } from "@ember/object/evented";
-import { popupAjaxError } from "discourse/lib/ajax-error";
-
-export default Component.extend(UploadMixin, {
- tagName: "span",
-
- @discourseComputed("uploading", "uploadProgress")
- uploadButtonText(uploading, progress) {
- return uploading
- ? I18n.t("admin.backups.upload.uploading_progress", { progress })
- : I18n.t("admin.backups.upload.label");
- },
-
- validateUploadedFilesOptions() {
- return { skipValidation: true };
- },
-
- uploadDone() {
- this.done();
- },
-
- calculateUploadUrl() {
- return "";
- },
-
- uploadOptions() {
- return {
- type: "PUT",
- dataType: "xml",
- autoUpload: false,
- multipart: false,
- };
- },
-
- _init: on("didInsertElement", function () {
- const $upload = $(this.element);
-
- $upload.on("fileuploadadd", (e, data) => {
- ajax("/admin/backups/upload_url", {
- data: { filename: data.files[0].name },
- })
- .then((result) => {
- data.url = result.url;
- data.submit();
- })
- .catch(popupAjaxError);
- });
- }),
-});
diff --git a/app/assets/javascripts/discourse/app/templates/components/backup-uploader.hbs b/app/assets/javascripts/discourse/app/templates/components/backup-uploader.hbs
deleted file mode 100644
index e4e8304b520..00000000000
--- a/app/assets/javascripts/discourse/app/templates/components/backup-uploader.hbs
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/app/assets/javascripts/discourse/ember-cli-build.js b/app/assets/javascripts/discourse/ember-cli-build.js
index 60d47a3cfc2..a643bc1ddf0 100644
--- a/app/assets/javascripts/discourse/ember-cli-build.js
+++ b/app/assets/javascripts/discourse/ember-cli-build.js
@@ -50,10 +50,6 @@ module.exports = function (defaults) {
});
app.import(discourseRoot + "/app/assets/javascripts/polyfills.js");
- let adminVendor = funnel(vendorJs, {
- files: ["resumable.js"],
- });
-
return mergeTrees([
discourseScss(`${discourseRoot}/app/assets/stylesheets`, "testem.scss"),
createI18nTree(discourseRoot, vendorJs),
@@ -64,7 +60,7 @@ module.exports = function (defaults) {
destDir: "assets/highlightjs",
}),
digest(
- concat(mergeTrees([app.options.adminTree, adminVendor]), {
+ concat(mergeTrees([app.options.adminTree]), {
outputFile: `assets/admin.js`,
})
),
diff --git a/app/assets/javascripts/main_include_admin.js b/app/assets/javascripts/main_include_admin.js
index 3b275bd8f59..18afb3ba119 100644
--- a/app/assets/javascripts/main_include_admin.js
+++ b/app/assets/javascripts/main_include_admin.js
@@ -1,3 +1,2 @@
//= require discourse/app/lib/export-result
//= require_tree ./admin/addon
-//= require resumable.js
diff --git a/lib/tasks/javascript.rake b/lib/tasks/javascript.rake
index a8db2fa31c5..d1ecd861e72 100644
--- a/lib/tasks/javascript.rake
+++ b/lib/tasks/javascript.rake
@@ -131,8 +131,6 @@ def dependencies
}, {
source: 'moment-timezone-names-translations/locales/.',
destination: 'moment-timezone-names-locale'
- }, {
- source: 'resumablejs/resumable.js'
}, {
source: 'workbox-sw/build/.',
destination: 'workbox',
diff --git a/package.json b/package.json
index fab7aa0a965..a830aebef44 100644
--- a/package.json
+++ b/package.json
@@ -12,10 +12,10 @@
"@json-editor/json-editor": "^2.6.1",
"@popperjs/core": "v2.10.2",
"@uppy/aws-s3": "^2.0.4",
- "@uppy/utils": "^4.0.3",
"@uppy/aws-s3-multipart": "^2.1.0",
"@uppy/core": "^2.1.0",
"@uppy/drop-target": "^1.1.0",
+ "@uppy/utils": "^4.0.3",
"@uppy/xhr-upload": "^2.0.4",
"ace-builds": "1.4.12",
"blueimp-file-upload": "10.13.0",
@@ -33,7 +33,6 @@
"moment-timezone": "0.5.31",
"moment-timezone-names-translations": "https://github.com/discourse/moment-timezone-names-translations",
"pikaday": "1.8.0",
- "resumablejs": "1.1.0",
"spectrum-colorpicker": "1.8.0",
"workbox-cacheable-response": "^4.3.1",
"workbox-core": "^4.3.1",
diff --git a/vendor/assets/javascripts/resumable.js b/vendor/assets/javascripts/resumable.js
deleted file mode 100644
index 649e6a2a317..00000000000
--- a/vendor/assets/javascripts/resumable.js
+++ /dev/null
@@ -1,1084 +0,0 @@
-/*
-* MIT Licensed
-* http://www.23developer.com/opensource
-* http://github.com/23/resumable.js
-* Steffen Tiedemann Christensen, steffen@23company.com
-*/
-
-(function(){
-"use strict";
-
- var Resumable = function(opts){
- if ( !(this instanceof Resumable) ) {
- return new Resumable(opts);
- }
- this.version = 1.0;
- // SUPPORTED BY BROWSER?
- // Check if these features are support by the browser:
- // - File object type
- // - Blob object type
- // - FileList object type
- // - slicing files
- this.support = (
- (typeof(File)!=='undefined')
- &&
- (typeof(Blob)!=='undefined')
- &&
- (typeof(FileList)!=='undefined')
- &&
- (!!Blob.prototype.webkitSlice||!!Blob.prototype.mozSlice||!!Blob.prototype.slice||false)
- );
- if(!this.support) return(false);
-
-
- // PROPERTIES
- var $ = this;
- $.files = [];
- $.defaults = {
- chunkSize:1*1024*1024,
- forceChunkSize:false,
- simultaneousUploads:3,
- fileParameterName:'file',
- chunkNumberParameterName: 'resumableChunkNumber',
- chunkSizeParameterName: 'resumableChunkSize',
- currentChunkSizeParameterName: 'resumableCurrentChunkSize',
- totalSizeParameterName: 'resumableTotalSize',
- typeParameterName: 'resumableType',
- identifierParameterName: 'resumableIdentifier',
- fileNameParameterName: 'resumableFilename',
- relativePathParameterName: 'resumableRelativePath',
- totalChunksParameterName: 'resumableTotalChunks',
- throttleProgressCallbacks: 0.5,
- query:{},
- headers:{},
- preprocess:null,
- method:'multipart',
- uploadMethod: 'POST',
- testMethod: 'GET',
- prioritizeFirstAndLastChunk:false,
- target:'/',
- testTarget: null,
- parameterNamespace:'',
- testChunks:true,
- generateUniqueIdentifier:null,
- getTarget:null,
- maxChunkRetries:100,
- chunkRetryInterval:undefined,
- permanentErrors:[400, 404, 415, 500, 501],
- maxFiles:undefined,
- withCredentials:false,
- xhrTimeout:0,
- clearInput:true,
- chunkFormat:'blob',
- setChunkTypeFromFile:false,
- maxFilesErrorCallback:function (files, errorCount) {
- var maxFiles = $.getOpt('maxFiles');
- alert('Please upload no more than ' + maxFiles + ' file' + (maxFiles === 1 ? '' : 's') + ' at a time.');
- },
- minFileSize:1,
- minFileSizeErrorCallback:function(file, errorCount) {
- alert(file.fileName||file.name +' is too small, please upload files larger than ' + $h.formatSize($.getOpt('minFileSize')) + '.');
- },
- maxFileSize:undefined,
- maxFileSizeErrorCallback:function(file, errorCount) {
- alert(file.fileName||file.name +' is too large, please upload files less than ' + $h.formatSize($.getOpt('maxFileSize')) + '.');
- },
- fileType: [],
- fileTypeErrorCallback: function(file, errorCount) {
- alert(file.fileName||file.name +' has type not allowed, please upload files of type ' + $.getOpt('fileType') + '.');
- }
- };
- $.opts = opts||{};
- $.getOpt = function(o) {
- var $opt = this;
- // Get multiple option if passed an array
- if(o instanceof Array) {
- var options = {};
- $h.each(o, function(option){
- options[option] = $opt.getOpt(option);
- });
- return options;
- }
- // Otherwise, just return a simple option
- if ($opt instanceof ResumableChunk) {
- if (typeof $opt.opts[o] !== 'undefined') { return $opt.opts[o]; }
- else { $opt = $opt.fileObj; }
- }
- if ($opt instanceof ResumableFile) {
- if (typeof $opt.opts[o] !== 'undefined') { return $opt.opts[o]; }
- else { $opt = $opt.resumableObj; }
- }
- if ($opt instanceof Resumable) {
- if (typeof $opt.opts[o] !== 'undefined') { return $opt.opts[o]; }
- else { return $opt.defaults[o]; }
- }
- };
-
- // EVENTS
- // catchAll(event, ...)
- // fileSuccess(file), fileProgress(file), fileAdded(file, event), filesAdded(files, filesSkipped), fileRetry(file),
- // fileError(file, message), complete(), progress(), error(message, file), pause()
- $.events = [];
- $.on = function(event,callback){
- $.events.push(event.toLowerCase(), callback);
- };
- $.fire = function(){
- // `arguments` is an object, not array, in FF, so:
- var args = [];
- for (var i=0; i 0){
- var fileTypeFound = false;
- for(var index in o.fileType){
- var extension = '.' + o.fileType[index];
- if(fileName.toLowerCase().indexOf(extension.toLowerCase(), fileName.length - extension.length) !== -1){
- fileTypeFound = true;
- break;
- }
- }
- if (!fileTypeFound) {
- o.fileTypeErrorCallback(file, errorCount++);
- return false;
- }
- }
-
- if (typeof(o.minFileSize)!=='undefined' && file.sizeo.maxFileSize) {
- o.maxFileSizeErrorCallback(file, errorCount++);
- return false;
- }
-
- function addFile(uniqueIdentifier){
- if (!$.getFromUniqueIdentifier(uniqueIdentifier)) {(function(){
- file.uniqueIdentifier = uniqueIdentifier;
- var f = new ResumableFile($, file, uniqueIdentifier);
- $.files.push(f);
- files.push(f);
- f.container = (typeof event != 'undefined' ? event.srcElement : null);
- window.setTimeout(function(){
- $.fire('fileAdded', f, event)
- },0);
- })()} else {
- filesSkipped.push(file);
- };
- decreaseReamining();
- }
- // directories have size == 0
- var uniqueIdentifier = $h.generateUniqueIdentifier(file, event);
- if(uniqueIdentifier && typeof uniqueIdentifier.then === 'function'){
- // Promise or Promise-like object provided as unique identifier
- uniqueIdentifier
- .then(
- function(uniqueIdentifier){
- // unique identifier generation succeeded
- addFile(uniqueIdentifier);
- },
- function(){
- // unique identifier generation failed
- // skip further processing, only decrease file count
- decreaseReamining();
- }
- );
- }else{
- // non-Promise provided as unique identifier, process synchronously
- addFile(uniqueIdentifier);
- }
- });
- };
-
- // INTERNAL OBJECT TYPES
- function ResumableFile(resumableObj, file, uniqueIdentifier){
- var $ = this;
- $.opts = {};
- $.getOpt = resumableObj.getOpt;
- $._prevProgress = 0;
- $.resumableObj = resumableObj;
- $.file = file;
- $.fileName = file.fileName||file.name; // Some confusion in different versions of Firefox
- $.size = file.size;
- $.relativePath = file.relativePath || file.webkitRelativePath || $.fileName;
- $.uniqueIdentifier = uniqueIdentifier;
- $._pause = false;
- $.container = '';
- var _error = uniqueIdentifier !== undefined;
-
- // Callback when something happens within the chunk
- var chunkEvent = function(event, message){
- // event can be 'progress', 'success', 'error' or 'retry'
- switch(event){
- case 'progress':
- $.resumableObj.fire('fileProgress', $, message);
- break;
- case 'error':
- $.abort();
- _error = true;
- $.chunks = [];
- $.resumableObj.fire('fileError', $, message);
- break;
- case 'success':
- if(_error) return;
- $.resumableObj.fire('fileProgress', $); // it's at least progress
- if($.isComplete()) {
- $.resumableObj.fire('fileSuccess', $, message);
- }
- break;
- case 'retry':
- $.resumableObj.fire('fileRetry', $);
- break;
- }
- };
-
- // Main code to set up a file object with chunks,
- // packaged to be able to handle retries if needed.
- $.chunks = [];
- $.abort = function(){
- // Stop current uploads
- var abortCount = 0;
- $h.each($.chunks, function(c){
- if(c.status()=='uploading') {
- c.abort();
- abortCount++;
- }
- });
- if(abortCount>0) $.resumableObj.fire('fileProgress', $);
- };
- $.cancel = function(){
- // Reset this file to be void
- var _chunks = $.chunks;
- $.chunks = [];
- // Stop current uploads
- $h.each(_chunks, function(c){
- if(c.status()=='uploading') {
- c.abort();
- $.resumableObj.uploadNextChunk();
- }
- });
- $.resumableObj.removeFile($);
- $.resumableObj.fire('fileProgress', $);
- };
- $.retry = function(){
- $.bootstrap();
- var firedRetry = false;
- $.resumableObj.on('chunkingComplete', function(){
- if(!firedRetry) $.resumableObj.upload();
- firedRetry = true;
- });
- };
- $.bootstrap = function(){
- $.abort();
- _error = false;
- // Rebuild stack of chunks from file
- $.chunks = [];
- $._prevProgress = 0;
- var round = $.getOpt('forceChunkSize') ? Math.ceil : Math.floor;
- var maxOffset = Math.max(round($.file.size/$.getOpt('chunkSize')),1);
- for (var offset=0; offset0.99999 ? 1 : ret));
- ret = Math.max($._prevProgress, ret); // We don't want to lose percentages when an upload is paused
- $._prevProgress = ret;
- return(ret);
- };
- $.isUploading = function(){
- var uploading = false;
- $h.each($.chunks, function(chunk){
- if(chunk.status()=='uploading') {
- uploading = true;
- return(false);
- }
- });
- return(uploading);
- };
- $.isComplete = function(){
- var outstanding = false;
- $h.each($.chunks, function(chunk){
- var status = chunk.status();
- if(status=='pending' || status=='uploading' || chunk.preprocessState === 1) {
- outstanding = true;
- return(false);
- }
- });
- return(!outstanding);
- };
- $.pause = function(pause){
- if(typeof(pause)==='undefined'){
- $._pause = ($._pause ? false : true);
- }else{
- $._pause = pause;
- }
- };
- $.isPaused = function() {
- return $._pause;
- };
-
-
- // Bootstrap and return
- $.resumableObj.fire('chunkingStart', $);
- $.bootstrap();
- return(this);
- }
-
-
- function ResumableChunk(resumableObj, fileObj, offset, callback){
- var $ = this;
- $.opts = {};
- $.getOpt = resumableObj.getOpt;
- $.resumableObj = resumableObj;
- $.fileObj = fileObj;
- $.fileObjSize = fileObj.size;
- $.fileObjType = fileObj.file.type;
- $.offset = offset;
- $.callback = callback;
- $.lastProgressCallback = (new Date);
- $.tested = false;
- $.retries = 0;
- $.pendingRetry = false;
- $.preprocessState = 0; // 0 = unprocessed, 1 = processing, 2 = finished
-
- // Computed properties
- var chunkSize = $.getOpt('chunkSize');
- $.loaded = 0;
- $.startByte = $.offset*chunkSize;
- $.endByte = Math.min($.fileObjSize, ($.offset+1)*chunkSize);
- if ($.fileObjSize-$.endByte < chunkSize && !$.getOpt('forceChunkSize')) {
- // The last chunk will be bigger than the chunk size, but less than 2*chunkSize
- $.endByte = $.fileObjSize;
- }
- $.xhr = null;
-
- // test() makes a GET request without any data to see if the chunk has already been uploaded in a previous session
- $.test = function(){
- // Set up request and listen for event
- $.xhr = new XMLHttpRequest();
-
- var testHandler = function(e){
- $.tested = true;
- var status = $.status();
- if(status=='success') {
- $.callback(status, $.message());
- $.resumableObj.uploadNextChunk();
- } else {
- $.send();
- }
- };
- $.xhr.addEventListener('load', testHandler, false);
- $.xhr.addEventListener('error', testHandler, false);
- $.xhr.addEventListener('timeout', testHandler, false);
-
- // Add data from the query options
- var params = [];
- var parameterNamespace = $.getOpt('parameterNamespace');
- var customQuery = $.getOpt('query');
- if(typeof customQuery == 'function') customQuery = customQuery($.fileObj, $);
- $h.each(customQuery, function(k,v){
- params.push([encodeURIComponent(parameterNamespace+k), encodeURIComponent(v)].join('='));
- });
- // Add extra data to identify chunk
- params = params.concat(
- [
- // define key/value pairs for additional parameters
- ['chunkNumberParameterName', $.offset + 1],
- ['chunkSizeParameterName', $.getOpt('chunkSize')],
- ['currentChunkSizeParameterName', $.endByte - $.startByte],
- ['totalSizeParameterName', $.fileObjSize],
- ['typeParameterName', $.fileObjType],
- ['identifierParameterName', $.fileObj.uniqueIdentifier],
- ['fileNameParameterName', $.fileObj.fileName],
- ['relativePathParameterName', $.fileObj.relativePath],
- ['totalChunksParameterName', $.fileObj.chunks.length]
- ].filter(function(pair){
- // include items that resolve to truthy values
- // i.e. exclude false, null, undefined and empty strings
- return $.getOpt(pair[0]);
- })
- .map(function(pair){
- // map each key/value pair to its final form
- return [
- parameterNamespace + $.getOpt(pair[0]),
- encodeURIComponent(pair[1])
- ].join('=');
- })
- );
- // Append the relevant chunk and send it
- $.xhr.open($.getOpt('testMethod'), $h.getTarget('test', params));
- $.xhr.timeout = $.getOpt('xhrTimeout');
- $.xhr.withCredentials = $.getOpt('withCredentials');
- // Add data from header options
- var customHeaders = $.getOpt('headers');
- if(typeof customHeaders === 'function') {
- customHeaders = customHeaders($.fileObj, $);
- }
- $h.each(customHeaders, function(k,v) {
- $.xhr.setRequestHeader(k, v);
- });
- $.xhr.send(null);
- };
-
- $.preprocessFinished = function(){
- $.preprocessState = 2;
- $.send();
- };
-
- // send() uploads the actual data in a POST call
- $.send = function(){
- var preprocess = $.getOpt('preprocess');
- if(typeof preprocess === 'function') {
- switch($.preprocessState) {
- case 0: $.preprocessState = 1; preprocess($); return;
- case 1: return;
- case 2: break;
- }
- }
- if($.getOpt('testChunks') && !$.tested) {
- $.test();
- return;
- }
-
- // Set up request and listen for event
- $.xhr = new XMLHttpRequest();
-
- // Progress
- $.xhr.upload.addEventListener('progress', function(e){
- if( (new Date) - $.lastProgressCallback > $.getOpt('throttleProgressCallbacks') * 1000 ) {
- $.callback('progress');
- $.lastProgressCallback = (new Date);
- }
- $.loaded=e.loaded||0;
- }, false);
- $.loaded = 0;
- $.pendingRetry = false;
- $.callback('progress');
-
- // Done (either done, failed or retry)
- var doneHandler = function(e){
- var status = $.status();
- if(status=='success'||status=='error') {
- $.callback(status, $.message());
- $.resumableObj.uploadNextChunk();
- } else {
- $.callback('retry', $.message());
- $.abort();
- $.retries++;
- var retryInterval = $.getOpt('chunkRetryInterval');
- if(retryInterval !== undefined) {
- $.pendingRetry = true;
- setTimeout($.send, retryInterval);
- } else {
- $.send();
- }
- }
- };
- $.xhr.addEventListener('load', doneHandler, false);
- $.xhr.addEventListener('error', doneHandler, false);
- $.xhr.addEventListener('timeout', doneHandler, false);
-
- // Set up the basic query data from Resumable
- var query = [
- ['chunkNumberParameterName', $.offset + 1],
- ['chunkSizeParameterName', $.getOpt('chunkSize')],
- ['currentChunkSizeParameterName', $.endByte - $.startByte],
- ['totalSizeParameterName', $.fileObjSize],
- ['typeParameterName', $.fileObjType],
- ['identifierParameterName', $.fileObj.uniqueIdentifier],
- ['fileNameParameterName', $.fileObj.fileName],
- ['relativePathParameterName', $.fileObj.relativePath],
- ['totalChunksParameterName', $.fileObj.chunks.length],
- ].filter(function(pair){
- // include items that resolve to truthy values
- // i.e. exclude false, null, undefined and empty strings
- return $.getOpt(pair[0]);
- })
- .reduce(function(query, pair){
- // assign query key/value
- query[$.getOpt(pair[0])] = pair[1];
- return query;
- }, {});
- // Mix in custom data
- var customQuery = $.getOpt('query');
- if(typeof customQuery == 'function') customQuery = customQuery($.fileObj, $);
- $h.each(customQuery, function(k,v){
- query[k] = v;
- });
-
- var func = ($.fileObj.file.slice ? 'slice' : ($.fileObj.file.mozSlice ? 'mozSlice' : ($.fileObj.file.webkitSlice ? 'webkitSlice' : 'slice')));
- var bytes = $.fileObj.file[func]($.startByte, $.endByte, $.getOpt('setChunkTypeFromFile') ? $.fileObj.file.type : "");
- var data = null;
- var params = [];
-
- var parameterNamespace = $.getOpt('parameterNamespace');
- if ($.getOpt('method') === 'octet') {
- // Add data from the query options
- data = bytes;
- $h.each(query, function (k, v) {
- params.push([encodeURIComponent(parameterNamespace + k), encodeURIComponent(v)].join('='));
- });
- } else {
- // Add data from the query options
- data = new FormData();
- $h.each(query, function (k, v) {
- data.append(parameterNamespace + k, v);
- params.push([encodeURIComponent(parameterNamespace + k), encodeURIComponent(v)].join('='));
- });
- if ($.getOpt('chunkFormat') == 'blob') {
- data.append(parameterNamespace + $.getOpt('fileParameterName'), bytes, $.fileObj.fileName);
- }
- else if ($.getOpt('chunkFormat') == 'base64') {
- var fr = new FileReader();
- fr.onload = function (e) {
- data.append(parameterNamespace + $.getOpt('fileParameterName'), fr.result);
- $.xhr.send(data);
- }
- fr.readAsDataURL(bytes);
- }
- }
-
- var target = $h.getTarget('upload', params);
- var method = $.getOpt('uploadMethod');
-
- $.xhr.open(method, target);
- if ($.getOpt('method') === 'octet') {
- $.xhr.setRequestHeader('Content-Type', 'application/octet-stream');
- }
- $.xhr.timeout = $.getOpt('xhrTimeout');
- $.xhr.withCredentials = $.getOpt('withCredentials');
- // Add data from header options
- var customHeaders = $.getOpt('headers');
- if(typeof customHeaders === 'function') {
- customHeaders = customHeaders($.fileObj, $);
- }
-
- $h.each(customHeaders, function(k,v) {
- $.xhr.setRequestHeader(k, v);
- });
-
- if ($.getOpt('chunkFormat') == 'blob') {
- $.xhr.send(data);
- }
- };
- $.abort = function(){
- // Abort and reset
- if($.xhr) $.xhr.abort();
- $.xhr = null;
- };
- $.status = function(){
- // Returns: 'pending', 'uploading', 'success', 'error'
- if($.pendingRetry) {
- // if pending retry then that's effectively the same as actively uploading,
- // there might just be a slight delay before the retry starts
- return('uploading');
- } else if(!$.xhr) {
- return('pending');
- } else if($.xhr.readyState<4) {
- // Status is really 'OPENED', 'HEADERS_RECEIVED' or 'LOADING' - meaning that stuff is happening
- return('uploading');
- } else {
- if($.xhr.status == 200 || $.xhr.status == 201) {
- // HTTP 200, 201 (created)
- return('success');
- } else if($h.contains($.getOpt('permanentErrors'), $.xhr.status) || $.retries >= $.getOpt('maxChunkRetries')) {
- // HTTP 415/500/501, permanent error
- return('error');
- } else {
- // this should never happen, but we'll reset and queue a retry
- // a likely case for this would be 503 service unavailable
- $.abort();
- return('pending');
- }
- }
- };
- $.message = function(){
- return($.xhr ? $.xhr.responseText : '');
- };
- $.progress = function(relative){
- if(typeof(relative)==='undefined') relative = false;
- var factor = (relative ? ($.endByte-$.startByte)/$.fileObjSize : 1);
- if($.pendingRetry) return(0);
- if(!$.xhr || !$.xhr.status) factor*=.95;
- var s = $.status();
- switch(s){
- case 'success':
- case 'error':
- return(1*factor);
- case 'pending':
- return(0*factor);
- default:
- return($.loaded/($.endByte-$.startByte)*factor);
- }
- };
- return(this);
- }
-
- // QUEUE
- $.uploadNextChunk = function(){
- var found = false;
-
- // In some cases (such as videos) it's really handy to upload the first
- // and last chunk of a file quickly; this let's the server check the file's
- // metadata and determine if there's even a point in continuing.
- if ($.getOpt('prioritizeFirstAndLastChunk')) {
- $h.each($.files, function(file){
- if(file.chunks.length && file.chunks[0].status()=='pending' && file.chunks[0].preprocessState === 0) {
- file.chunks[0].send();
- found = true;
- return(false);
- }
- if(file.chunks.length>1 && file.chunks[file.chunks.length-1].status()=='pending' && file.chunks[file.chunks.length-1].preprocessState === 0) {
- file.chunks[file.chunks.length-1].send();
- found = true;
- return(false);
- }
- });
- if(found) return(true);
- }
-
- // Now, simply look for the next, best thing to upload
- $h.each($.files, function(file){
- if(file.isPaused()===false){
- $h.each(file.chunks, function(chunk){
- if(chunk.status()=='pending' && chunk.preprocessState === 0) {
- chunk.send();
- found = true;
- return(false);
- }
- });
- }
- if(found) return(false);
- });
- if(found) return(true);
-
- // The are no more outstanding chunks to upload, check is everything is done
- var outstanding = false;
- $h.each($.files, function(file){
- if(!file.isComplete()) {
- outstanding = true;
- return(false);
- }
- });
- if(!outstanding) {
- // All chunks have been uploaded, complete
- $.fire('complete');
- }
- return(false);
- };
-
-
- // PUBLIC METHODS FOR RESUMABLE.JS
- $.assignBrowse = function(domNodes, isDirectory){
- if(typeof(domNodes.length)=='undefined') domNodes = [domNodes];
-
- $h.each(domNodes, function(domNode) {
- var input;
- if(domNode.tagName==='INPUT' && domNode.type==='file'){
- input = domNode;
- } else {
- input = document.createElement('input');
- input.setAttribute('type', 'file');
- input.style.display = 'none';
- domNode.addEventListener('click', function(){
- input.style.opacity = 0;
- input.style.display='block';
- input.focus();
- input.click();
- input.style.display='none';
- }, false);
- domNode.appendChild(input);
- }
- var maxFiles = $.getOpt('maxFiles');
- if (typeof(maxFiles)==='undefined'||maxFiles!=1){
- input.setAttribute('multiple', 'multiple');
- } else {
- input.removeAttribute('multiple');
- }
- if(isDirectory){
- input.setAttribute('webkitdirectory', 'webkitdirectory');
- } else {
- input.removeAttribute('webkitdirectory');
- }
- var fileTypes = $.getOpt('fileType');
- if (typeof (fileTypes) !== 'undefined' && fileTypes.length >= 1) {
- input.setAttribute('accept', fileTypes.map(function (e) { return '.' + e }).join(','));
- }
- else {
- input.removeAttribute('accept');
- }
- // When new files are added, simply append them to the overall list
- input.addEventListener('change', function(e){
- appendFilesFromFileList(e.target.files,e);
- var clearInput = $.getOpt('clearInput');
- if (clearInput) {
- e.target.value = '';
- }
- }, false);
- });
- };
- $.assignDrop = function(domNodes){
- if(typeof(domNodes.length)=='undefined') domNodes = [domNodes];
-
- $h.each(domNodes, function(domNode) {
- domNode.addEventListener('dragover', preventDefault, false);
- domNode.addEventListener('dragenter', preventDefault, false);
- domNode.addEventListener('drop', onDrop, false);
- });
- };
- $.unAssignDrop = function(domNodes) {
- if (typeof(domNodes.length) == 'undefined') domNodes = [domNodes];
-
- $h.each(domNodes, function(domNode) {
- domNode.removeEventListener('dragover', preventDefault);
- domNode.removeEventListener('dragenter', preventDefault);
- domNode.removeEventListener('drop', onDrop);
- });
- };
- $.isUploading = function(){
- var uploading = false;
- $h.each($.files, function(file){
- if (file.isUploading()) {
- uploading = true;
- return(false);
- }
- });
- return(uploading);
- };
- $.upload = function(){
- // Make sure we don't start too many uploads at once
- if($.isUploading()) return;
- // Kick off the queue
- $.fire('uploadStart');
- for (var num=1; num<=$.getOpt('simultaneousUploads'); num++) {
- $.uploadNextChunk();
- }
- };
- $.pause = function(){
- // Resume all chunks currently being uploaded
- $h.each($.files, function(file){
- file.abort();
- });
- $.fire('pause');
- };
- $.cancel = function(){
- $.fire('beforeCancel');
- for(var i = $.files.length - 1; i >= 0; i--) {
- $.files[i].cancel();
- }
- $.fire('cancel');
- };
- $.progress = function(){
- var totalDone = 0;
- var totalSize = 0;
- // Resume all chunks currently being uploaded
- $h.each($.files, function(file){
- totalDone += file.progress()*file.size;
- totalSize += file.size;
- });
- return(totalSize>0 ? totalDone/totalSize : 0);
- };
- $.addFile = function(file, event){
- appendFilesFromFileList([file], event);
- };
- $.addFiles = function(files, event){
- appendFilesFromFileList(files, event);
- };
- $.removeFile = function(file){
- for(var i = $.files.length - 1; i >= 0; i--) {
- if($.files[i] === file) {
- $.files.splice(i, 1);
- }
- }
- };
- $.getFromUniqueIdentifier = function(uniqueIdentifier){
- var ret = false;
- $h.each($.files, function(f){
- if(f.uniqueIdentifier==uniqueIdentifier) ret = f;
- });
- return(ret);
- };
- $.getSize = function(){
- var totalSize = 0;
- $h.each($.files, function(file){
- totalSize += file.size;
- });
- return(totalSize);
- };
- $.handleDropEvent = function (e) {
- onDrop(e);
- };
- $.handleChangeEvent = function (e) {
- appendFilesFromFileList(e.target.files, e);
- e.target.value = '';
- };
- $.updateQuery = function(query){
- $.opts.query = query;
- };
-
- return(this);
- };
-
-
- // Node.js-style export for Node and Component
- if (typeof module != 'undefined') {
- module.exports = Resumable;
- } else if (typeof define === "function" && define.amd) {
- // AMD/requirejs: Define the module
- define(function(){
- return Resumable;
- });
- } else {
- // Browser: Expose to window
- window.Resumable = Resumable;
- }
-
-})();
diff --git a/yarn.lock b/yarn.lock
index ac89a473be1..20d51373a63 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3640,11 +3640,6 @@ restore-cursor@^3.1.0:
onetime "^5.1.0"
signal-exit "^3.0.2"
-resumablejs@1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/resumablejs/-/resumablejs-1.1.0.tgz#3160633688ac35bc2a0f119803c190ec369ef4d2"
- integrity sha512-gUTWTtJ2aheRb5svHDGHMtQsBkGxTILpZApT11ODoxEe5D75GhYL7Nc/WYgCcJXY+5RVmm2BEsp2qriCkKWRRg==
-
ret@~0.1.10:
version "0.1.15"
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"