From c8cde4821b83e103cc4cca4bdd136b3c077de511 Mon Sep 17 00:00:00 2001 From: Ndame Kital <ndame.kial@smile.fr> Date: Fri, 26 Jun 2020 09:21:42 +0200 Subject: [PATCH] =?UTF-8?q?fix=20probl=C3=A8mes=20webpack=20=C3=A0=20trouv?= =?UTF-8?q?er=20des=20dependances=20existntes=20et=20quelques=20refacto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 2 + src/Resources/assets/js/file_upload.js | 223 --- src/Resources/assets/js/jquery.file_upload.js | 1535 ----------------- .../assets/js/jquery.fileupload-process.js | 178 -- .../assets/js/jquery.fileupload-ui.js | 714 -------- .../assets/js/jquery.fileupload-validate.js | 125 -- src/Resources/assets/js/main.js | 18 +- tests/Fixtures/templates/base.html.twig | 4 +- tests/Fixtures/templates/index.html.twig | 1 - tests/Fixtures/webpack.config.js | 16 +- 10 files changed, 22 insertions(+), 2794 deletions(-) delete mode 100644 src/Resources/assets/js/file_upload.js delete mode 100644 src/Resources/assets/js/jquery.file_upload.js delete mode 100644 src/Resources/assets/js/jquery.fileupload-process.js delete mode 100644 src/Resources/assets/js/jquery.fileupload-ui.js delete mode 100644 src/Resources/assets/js/jquery.fileupload-validate.js diff --git a/composer.json b/composer.json index a7225641..8cd023b4 100644 --- a/composer.json +++ b/composer.json @@ -1,3 +1,4 @@ + { "name": "irstea/file-upload-bundle", "description": "Bundle de gestion de fichiers intégrée à Symfony et Twitter-Bootstrap.", @@ -149,6 +150,7 @@ ], "test:install-assets": [ "@test:clear", + "@test:install-theme-assets", "cd tests/Fixtures && npm install && npm run dev #" ], "test:install-theme-assets": [ diff --git a/src/Resources/assets/js/file_upload.js b/src/Resources/assets/js/file_upload.js deleted file mode 100644 index 42c95ab1..00000000 --- a/src/Resources/assets/js/file_upload.js +++ /dev/null @@ -1,223 +0,0 @@ -const Translator = require('translator'); - -/* - * Copyright (C) 2015 IRSTEA - * All rights reserved. - */ -(function ($, Translator) { - - var formatFileSize = function (size) { - var unit; - if (size > 1000000000) { - size = (size / 1000000000).toFixed(2); - unit = 'Gi'; - } else if (size > 1000000) { - size = (size / 1000000).toFixed(2); - unit = 'Mi'; - } else if (size > 1000) { - size = (size / 1000).toFixed(2); - unit = 'Ki'; - } else { - unit = ''; - } - - return Translator.trans('file_size(%size%,%unit%)', {size: size, unit: unit}, 'file_upload'); - }, - formatBitrate = function (rate) { - return formatFileSize(rate) + '/s'; - }; - - $.blueimp.fileupload.prototype._formatFileSize = formatFileSize; - $.blueimp.fileupload.prototype._formatBitrate = formatBitrate; - - /** Plugin irsteaFileUpload. - */ - $.fn.irsteaFileUpload = function (options) { - - var $this = $(this), - $button = $this.find('.fileinput-button'), - input = $this.find(':file')[0], - $entries = $this.find('.fileinput-entries'), - nextIndex = $entries.find('.fileinput-entry').length, - createUrl = options.createUrl, - uploadPrototype = options.uploadPrototype, - downloadPrototype = options.downloadPrototype, - csrfQuery = '?token=' + options.csrfToken; - - delete options.createUrl; - delete options.uploadPrototype; - delete options.downloadPrototype; - delete options.csrfToken; - - if (options.acceptFileTypes) { - options.acceptFileTypes = new RegExp('^' + options.acceptFileTypes + '$'); - } - - var checkValidity = function () { - var counts = { - upload: $entries.find('.template-upload').length, - download: $entries.find('.template-download').length, - error: $entries.find('.alert-danger').length, - }, - error = ''; - - if (counts.upload > 0) { - error = Translator.trans('file_upload.runningUpload', null, 'validators'); - - } else if (counts.error > 0) { - error = Translator.trans('file_upload.uploadError', null, 'validators'); - - } else if (options.required && counts.download < 1) { - error = Translator.trans('file_upload.required', null, 'validators'); - } - - input.setCustomValidity(error); - - // console.debug(input, counts, input.validationMessage, input.validity); - }, - showError = function (entry, message) { - var $this = $(entry); - if (message) { - $this.find('.error').text(Translator.trans(message)); - } - $this.addClass('alert alert-danger'); - $this.find('.error').show(); - $this.find('.icon') - .removeClass('fa-circle-o-notch fa-spin fa-file-o') - .addClass('fa-exclamation-triangle'); - $this.find('.description').remove(); - $this.find('.id').remove(); - }, - updateDisplay = function (event) { - var hasEntry = false; - $entries.find('.fileinput-entry').each(function () { - var data = $(this).data('data'); - if (data && data.files.error) { - showError(this, data.files[0].error); - } - hasEntry = true; - }); - $button.toggle(options.multiple || !hasEntry); - checkValidity(); - }; - - // Activation - $button.fileupload($.extend( - options, - { - type: 'PUT', - autoUpload: true, - formData: {}, - multipart: false, - uploadTemplateId: null, - downloadTemplateId: null, - filesContainer: $this.find('.fileinput-entries'), - dropZone: $this, - i18n: function(key, values, domain) { - var res = Translator.trans(key, values, domain || 'file_upload'); - if (res !== key) { - return res; - } - res = Translator.trans('file_upload.'+ key, values, 'validators'); - if (res !== 'file_upload.'+ key) { - return res; - } - return Translator.trans(key, values, 'messages'); - }, - uploadTemplate: function (data) { - var rows = $(); - $.each(data.files, function (index, file) { - var row = $(uploadPrototype); - rows = rows.add(row); - row.find('.name').text(file.name); - if (file.error) { - showError(row, file.error); - return; - } - row.find('.size').text(formatFileSize(file.size)); - }); - return rows; - }, - downloadTemplate: function (data) { - var rows = $(); - $.each(data.files, function (index, file) { - var row = $(downloadPrototype.replace(/__index__/g, nextIndex++)); - rows = rows.add(row); - if (file.error) { - row.find('.name').text(file.name); - showError(row, file.error); - return; - } - row.find('.repr').html(file.repr); - row.find('.delete') - .attr('data-type', file.delete_type) - .attr('data-url', file.delete_url + csrfQuery); - row.find('input.id') - .val(file.id); - }); - return rows; - }, - submit: function (e, data) { - var $this = $(this), - file = data.files[0]; - $.post( - createUrl, - {file: {name: file.name, size: file.size, type: file.type, lastModified: file.lastModified}}, - function (response) { - file.icon = response.icon; - data.url = response.put_url + csrfQuery; - data.delete_url = response.delete_url; - data.delete_type = response.delete_type; - data.jqXHR = $this.fileupload('send', data); - } - ) - .fail(function (jqXHR, textStatus, errorThrown) { - file.error = textStatus === "error" ? errorThrown : ('Error #' + jqXHR.status); - data.files.error = true; - showError(data.context, file.error); - }) - .always(updateDisplay); - return false; - }, - progress: function (e, data) { - if (!data.context || e.isDefaultPrevented()) { - return; - } - var percent = data.loaded / data.total * 100, - percentText = percent.toFixed(1); - data.context.each(function () { - var $this = $(data.context); - $this.find('.progress').show(); - $this.find('.progress-bar').css('width', percent + '%').attr('aria-valuenow', percentText); - $this.find('.progress-text').show().html(percentText + '% (' + formatBitrate(data.bitrate) + ')'); - }); - }, - getFilesFromResponse: function (data) { - var files = []; - $.each(data.files, function (index, file) { - files.push($.extend(file, data.result.files[index])); - }); - return files; - }, - } - )).bind({ - fileuploadfailed: function (event, data) { - if (data.delete_url) { - $.ajax(data.delete_url + csrfQuery, {type: data.delete_type}); - checkValidity(); - } - }, - fileuploadadded: updateDisplay, - fileuploadfinished: updateDisplay, - fileuploaddestroyed: updateDisplay, - fileuploadprocessalways: updateDisplay - }); - - if (options.disabled || options.readonly) { - $button.fileupload('disable'); - } - - updateDisplay(); - }; - -})(jQuery, Translator); diff --git a/src/Resources/assets/js/jquery.file_upload.js b/src/Resources/assets/js/jquery.file_upload.js deleted file mode 100644 index 146de7fb..00000000 --- a/src/Resources/assets/js/jquery.file_upload.js +++ /dev/null @@ -1,1535 +0,0 @@ -/* - * jQuery File Upload Plugin - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2010, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * https://opensource.org/licenses/MIT - */ - -/* jshint nomen:false */ -/* global define, require, window, document, location, Blob, FormData */ - -;(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - 'jquery-ui/ui/widget' - ], factory); - } else if (typeof exports === 'object') { - // Node/CommonJS: - factory( - require('jquery'), - require('./vendor/jquery.ui.widget') - ); - } else { - // Browser globals: - factory(window.jQuery); - } -}(function ($) { - 'use strict'; - - // Detect file input support, based on - // http://viljamis.com/blog/2012/file-upload-support-on-mobile/ - $.support.fileInput = !(new RegExp( - // Handle devices which give false positives for the feature detection: - '(Android (1\\.[0156]|2\\.[01]))' + - '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' + - '|(w(eb)?OSBrowser)|(webOS)' + - '|(Kindle/(1\\.0|2\\.[05]|3\\.0))' - ).test(window.navigator.userAgent) || - // Feature detection for all other devices: - $('<input type="file"/>').prop('disabled')); - - // The FileReader API is not actually used, but works as feature detection, - // as some Safari versions (5?) support XHR file uploads via the FormData API, - // but not non-multipart XHR file uploads. - // window.XMLHttpRequestUpload is not available on IE10, so we check for - // window.ProgressEvent instead to detect XHR2 file upload capability: - $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader); - $.support.xhrFormDataFileUpload = !!window.FormData; - - // Detect support for Blob slicing (required for chunked uploads): - $.support.blobSlice = window.Blob && (Blob.prototype.slice || - Blob.prototype.webkitSlice || Blob.prototype.mozSlice); - - // Helper function to create drag handlers for dragover/dragenter/dragleave: - function getDragHandler(type) { - var isDragOver = type === 'dragover'; - return function (e) { - e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer; - var dataTransfer = e.dataTransfer; - if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 && - this._trigger( - type, - $.Event(type, {delegatedEvent: e}) - ) !== false) { - e.preventDefault(); - if (isDragOver) { - dataTransfer.dropEffect = 'copy'; - } - } - }; - } - - // The fileupload widget listens for change events on file input fields defined - // via fileInput setting and paste or drop events of the given dropZone. - // In addition to the default jQuery Widget methods, the fileupload widget - // exposes the "add" and "send" methods, to add or directly send files using - // the fileupload API. - // By default, files added via file input selection, paste, drag & drop or - // "add" method are uploaded immediately, but it is possible to override - // the "add" callback option to queue file uploads. - $.widget('blueimp.fileupload', { - - options: { - // The drop target element(s), by the default the complete document. - // Set to null to disable drag & drop support: - dropZone: $(document), - // The paste target element(s), by the default undefined. - // Set to a DOM node or jQuery object to enable file pasting: - pasteZone: undefined, - // The file input field(s), that are listened to for change events. - // If undefined, it is set to the file input fields inside - // of the widget element on plugin initialization. - // Set to null to disable the change listener. - fileInput: undefined, - // By default, the file input field is replaced with a clone after - // each input field change event. This is required for iframe transport - // queues and allows change events to be fired for the same file - // selection, but can be disabled by setting the following option to false: - replaceFileInput: true, - // The parameter name for the file form data (the request argument name). - // If undefined or empty, the name property of the file input field is - // used, or "files[]" if the file input name property is also empty, - // can be a string or an array of strings: - paramName: undefined, - // By default, each file of a selection is uploaded using an individual - // request for XHR type uploads. Set to false to upload file - // selections in one request each: - singleFileUploads: true, - // To limit the number of files uploaded with one XHR request, - // set the following option to an integer greater than 0: - limitMultiFileUploads: undefined, - // The following option limits the number of files uploaded with one - // XHR request to keep the request size under or equal to the defined - // limit in bytes: - limitMultiFileUploadSize: undefined, - // Multipart file uploads add a number of bytes to each uploaded file, - // therefore the following option adds an overhead for each file used - // in the limitMultiFileUploadSize configuration: - limitMultiFileUploadSizeOverhead: 512, - // Set the following option to true to issue all file upload requests - // in a sequential order: - sequentialUploads: false, - // To limit the number of concurrent uploads, - // set the following option to an integer greater than 0: - limitConcurrentUploads: undefined, - // Set the following option to true to force iframe transport uploads: - forceIframeTransport: false, - // Set the following option to the location of a redirect url on the - // origin server, for cross-domain iframe transport uploads: - redirect: undefined, - // The parameter name for the redirect url, sent as part of the form - // data and set to 'redirect' if this option is empty: - redirectParamName: undefined, - // Set the following option to the location of a postMessage window, - // to enable postMessage transport uploads: - postMessage: undefined, - // By default, XHR file uploads are sent as multipart/form-data. - // The iframe transport is always using multipart/form-data. - // Set to false to enable non-multipart XHR uploads: - multipart: true, - // To upload large files in smaller chunks, set the following option - // to a preferred maximum chunk size. If set to 0, null or undefined, - // or the browser does not support the required Blob API, files will - // be uploaded as a whole. - maxChunkSize: undefined, - // When a non-multipart upload or a chunked multipart upload has been - // aborted, this option can be used to resume the upload by setting - // it to the size of the already uploaded bytes. This option is most - // useful when modifying the options object inside of the "add" or - // "send" callbacks, as the options are cloned for each file upload. - uploadedBytes: undefined, - // By default, failed (abort or error) file uploads are removed from the - // global progress calculation. Set the following option to false to - // prevent recalculating the global progress data: - recalculateProgress: true, - // Interval in milliseconds to calculate and trigger progress events: - progressInterval: 100, - // Interval in milliseconds to calculate progress bitrate: - bitrateInterval: 500, - // By default, uploads are started automatically when adding files: - autoUpload: true, - // By default, duplicate file names are expected to be handled on - // the server-side. If this is not possible (e.g. when uploading - // files directly to Amazon S3), the following option can be set to - // an empty object or an object mapping existing filenames, e.g.: - // { "image.jpg": true, "image (1).jpg": true } - // If it is set, all files will be uploaded with unique filenames, - // adding increasing number suffixes if necessary, e.g.: - // "image (2).jpg" - uniqueFilenames: undefined, - - // Error and info messages: - messages: { - uploadedBytes: 'Uploaded bytes exceed file size' - }, - - // Translation function, gets the message key to be translated - // and an object with context specific data as arguments: - i18n: function (message, context) { - message = this.messages[message] || message.toString(); - if (context) { - $.each(context, function (key, value) { - message = message.replace('{' + key + '}', value); - }); - } - return message; - }, - - // Additional form data to be sent along with the file uploads can be set - // using this option, which accepts an array of objects with name and - // value properties, a function returning such an array, a FormData - // object (for XHR file uploads), or a simple object. - // The form of the first fileInput is given as parameter to the function: - formData: function (form) { - return form.serializeArray(); - }, - - // The add callback is invoked as soon as files are added to the fileupload - // widget (via file input selection, drag & drop, paste or add API call). - // If the singleFileUploads option is enabled, this callback will be - // called once for each file in the selection for XHR file uploads, else - // once for each file selection. - // - // The upload starts when the submit method is invoked on the data parameter. - // The data object contains a files property holding the added files - // and allows you to override plugin options as well as define ajax settings. - // - // Listeners for this callback can also be bound the following way: - // .bind('fileuploadadd', func); - // - // data.submit() returns a Promise object and allows to attach additional - // handlers using jQuery's Deferred callbacks: - // data.submit().done(func).fail(func).always(func); - add: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - if (data.autoUpload || (data.autoUpload !== false && - $(this).fileupload('option', 'autoUpload'))) { - data.process().done(function () { - data.submit(); - }); - } - }, - - // Other callbacks: - - // Callback for the submit event of each file upload: - // submit: function (e, data) {}, // .bind('fileuploadsubmit', func); - - // Callback for the start of each file upload request: - // send: function (e, data) {}, // .bind('fileuploadsend', func); - - // Callback for successful uploads: - // done: function (e, data) {}, // .bind('fileuploaddone', func); - - // Callback for failed (abort or error) uploads: - // fail: function (e, data) {}, // .bind('fileuploadfail', func); - - // Callback for completed (success, abort or error) requests: - // always: function (e, data) {}, // .bind('fileuploadalways', func); - - // Callback for upload progress events: - // progress: function (e, data) {}, // .bind('fileuploadprogress', func); - - // Callback for global upload progress events: - // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func); - - // Callback for uploads start, equivalent to the global ajaxStart event: - // start: function (e) {}, // .bind('fileuploadstart', func); - - // Callback for uploads stop, equivalent to the global ajaxStop event: - // stop: function (e) {}, // .bind('fileuploadstop', func); - - // Callback for change events of the fileInput(s): - // change: function (e, data) {}, // .bind('fileuploadchange', func); - - // Callback for paste events to the pasteZone(s): - // paste: function (e, data) {}, // .bind('fileuploadpaste', func); - - // Callback for drop events of the dropZone(s): - // drop: function (e, data) {}, // .bind('fileuploaddrop', func); - - // Callback for dragover events of the dropZone(s): - // dragover: function (e) {}, // .bind('fileuploaddragover', func); - - // Callback before the start of each chunk upload request (before form data initialization): - // chunkbeforesend: function (e, data) {}, // .bind('fileuploadchunkbeforesend', func); - - // Callback for the start of each chunk upload request: - // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func); - - // Callback for successful chunk uploads: - // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func); - - // Callback for failed (abort or error) chunk uploads: - // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func); - - // Callback for completed (success, abort or error) chunk upload requests: - // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func); - - // The plugin options are used as settings object for the ajax calls. - // The following are jQuery ajax settings required for the file uploads: - processData: false, - contentType: false, - cache: false, - timeout: 0 - }, - - // A list of options that require reinitializing event listeners and/or - // special initialization code: - _specialOptions: [ - 'fileInput', - 'dropZone', - 'pasteZone', - 'multipart', - 'forceIframeTransport' - ], - - _blobSlice: $.support.blobSlice && function () { - var slice = this.slice || this.webkitSlice || this.mozSlice; - return slice.apply(this, arguments); - }, - - _BitrateTimer: function () { - this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime()); - this.loaded = 0; - this.bitrate = 0; - this.getBitrate = function (now, loaded, interval) { - var timeDiff = now - this.timestamp; - if (!this.bitrate || !interval || timeDiff > interval) { - this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8; - this.loaded = loaded; - this.timestamp = now; - } - return this.bitrate; - }; - }, - - _isXHRUpload: function (options) { - return !options.forceIframeTransport && - ((!options.multipart && $.support.xhrFileUpload) || - $.support.xhrFormDataFileUpload); - }, - - _getFormData: function (options) { - var formData; - if ($.type(options.formData) === 'function') { - return options.formData(options.form); - } - if ($.isArray(options.formData)) { - return options.formData; - } - if ($.type(options.formData) === 'object') { - formData = []; - $.each(options.formData, function (name, value) { - formData.push({name: name, value: value}); - }); - return formData; - } - return []; - }, - - _getTotal: function (files) { - var total = 0; - $.each(files, function (index, file) { - total += file.size || 1; - }); - return total; - }, - - _initProgressObject: function (obj) { - var progress = { - loaded: 0, - total: 0, - bitrate: 0 - }; - if (obj._progress) { - $.extend(obj._progress, progress); - } else { - obj._progress = progress; - } - }, - - _initResponseObject: function (obj) { - var prop; - if (obj._response) { - for (prop in obj._response) { - if (obj._response.hasOwnProperty(prop)) { - delete obj._response[prop]; - } - } - } else { - obj._response = {}; - } - }, - - _onProgress: function (e, data) { - if (e.lengthComputable) { - var now = ((Date.now) ? Date.now() : (new Date()).getTime()), - loaded; - if (data._time && data.progressInterval && - (now - data._time < data.progressInterval) && - e.loaded !== e.total) { - return; - } - data._time = now; - loaded = Math.floor( - e.loaded / e.total * (data.chunkSize || data._progress.total) - ) + (data.uploadedBytes || 0); - // Add the difference from the previously loaded state - // to the global loaded counter: - this._progress.loaded += (loaded - data._progress.loaded); - this._progress.bitrate = this._bitrateTimer.getBitrate( - now, - this._progress.loaded, - data.bitrateInterval - ); - data._progress.loaded = data.loaded = loaded; - data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate( - now, - loaded, - data.bitrateInterval - ); - // Trigger a custom progress event with a total data property set - // to the file size(s) of the current upload and a loaded data - // property calculated accordingly: - this._trigger( - 'progress', - $.Event('progress', {delegatedEvent: e}), - data - ); - // Trigger a global progress event for all current file uploads, - // including ajax calls queued for sequential file uploads: - this._trigger( - 'progressall', - $.Event('progressall', {delegatedEvent: e}), - this._progress - ); - } - }, - - _initProgressListener: function (options) { - var that = this, - xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr(); - // Accesss to the native XHR object is required to add event listeners - // for the upload progress event: - if (xhr.upload) { - $(xhr.upload).bind('progress', function (e) { - var oe = e.originalEvent; - // Make sure the progress event properties get copied over: - e.lengthComputable = oe.lengthComputable; - e.loaded = oe.loaded; - e.total = oe.total; - that._onProgress(e, options); - }); - options.xhr = function () { - return xhr; - }; - } - }, - - _deinitProgressListener: function (options) { - var xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr(); - if (xhr.upload) { - $(xhr.upload).unbind('progress'); - } - }, - - _isInstanceOf: function (type, obj) { - // Cross-frame instanceof check - return Object.prototype.toString.call(obj) === '[object ' + type + ']'; - }, - - _getUniqueFilename: function (name, map) { - name = String(name); - if (map[name]) { - name = name.replace( - /(?: \(([\d]+)\))?(\.[^.]+)?$/, - function (_, p1, p2) { - var index = p1 ? Number(p1) + 1 : 1; - var ext = p2 || ''; - return ' (' + index + ')' + ext; - } - ); - return this._getUniqueFilename(name, map); - } - map[name] = true; - return name; - }, - - _initXHRData: function (options) { - var that = this, - formData, - file = options.files[0], - // Ignore non-multipart setting if not supported: - multipart = options.multipart || !$.support.xhrFileUpload, - paramName = $.type(options.paramName) === 'array' ? - options.paramName[0] : options.paramName; - options.headers = $.extend({}, options.headers); - if (options.contentRange) { - options.headers['Content-Range'] = options.contentRange; - } - if (!multipart || options.blob || !this._isInstanceOf('File', file)) { - options.headers['Content-Disposition'] = 'attachment; filename="' + - encodeURI(file.uploadName || file.name) + '"'; - } - if (!multipart) { - options.contentType = file.type || 'application/octet-stream'; - options.data = options.blob || file; - } else if ($.support.xhrFormDataFileUpload) { - if (options.postMessage) { - // window.postMessage does not allow sending FormData - // objects, so we just add the File/Blob objects to - // the formData array and let the postMessage window - // create the FormData object out of this array: - formData = this._getFormData(options); - if (options.blob) { - formData.push({ - name: paramName, - value: options.blob - }); - } else { - $.each(options.files, function (index, file) { - formData.push({ - name: ($.type(options.paramName) === 'array' && - options.paramName[index]) || paramName, - value: file - }); - }); - } - } else { - if (that._isInstanceOf('FormData', options.formData)) { - formData = options.formData; - } else { - formData = new FormData(); - $.each(this._getFormData(options), function (index, field) { - formData.append(field.name, field.value); - }); - } - if (options.blob) { - formData.append( - paramName, - options.blob, - file.uploadName || file.name - ); - } else { - $.each(options.files, function (index, file) { - // This check allows the tests to run with - // dummy objects: - if (that._isInstanceOf('File', file) || - that._isInstanceOf('Blob', file)) { - var fileName = file.uploadName || file.name; - if (options.uniqueFilenames) { - fileName = that._getUniqueFilename( - fileName, - options.uniqueFilenames - ); - } - formData.append( - ($.type(options.paramName) === 'array' && - options.paramName[index]) || paramName, - file, - fileName - ); - } - }); - } - } - options.data = formData; - } - // Blob reference is not needed anymore, free memory: - options.blob = null; - }, - - _initIframeSettings: function (options) { - var targetHost = $('<a></a>').prop('href', options.url).prop('host'); - // Setting the dataType to iframe enables the iframe transport: - options.dataType = 'iframe ' + (options.dataType || ''); - // The iframe transport accepts a serialized array as form data: - options.formData = this._getFormData(options); - // Add redirect url to form data on cross-domain uploads: - if (options.redirect && targetHost && targetHost !== location.host) { - options.formData.push({ - name: options.redirectParamName || 'redirect', - value: options.redirect - }); - } - }, - - _initDataSettings: function (options) { - if (this._isXHRUpload(options)) { - if (!this._chunkedUpload(options, true)) { - if (!options.data) { - this._initXHRData(options); - } - this._initProgressListener(options); - } - if (options.postMessage) { - // Setting the dataType to postmessage enables the - // postMessage transport: - options.dataType = 'postmessage ' + (options.dataType || ''); - } - } else { - this._initIframeSettings(options); - } - }, - - _getParamName: function (options) { - var fileInput = $(options.fileInput), - paramName = options.paramName; - if (!paramName) { - paramName = []; - fileInput.each(function () { - var input = $(this), - name = input.prop('name') || 'files[]', - i = (input.prop('files') || [1]).length; - while (i) { - paramName.push(name); - i -= 1; - } - }); - if (!paramName.length) { - paramName = [fileInput.prop('name') || 'files[]']; - } - } else if (!$.isArray(paramName)) { - paramName = [paramName]; - } - return paramName; - }, - - _initFormSettings: function (options) { - // Retrieve missing options from the input field and the - // associated form, if available: - if (!options.form || !options.form.length) { - options.form = $(options.fileInput.prop('form')); - // If the given file input doesn't have an associated form, - // use the default widget file input's form: - if (!options.form.length) { - options.form = $(this.options.fileInput.prop('form')); - } - } - options.paramName = this._getParamName(options); - if (!options.url) { - options.url = options.form.prop('action') || location.href; - } - // The HTTP request method must be "POST" or "PUT": - options.type = (options.type || - ($.type(options.form.prop('method')) === 'string' && - options.form.prop('method')) || '' - ).toUpperCase(); - if (options.type !== 'POST' && options.type !== 'PUT' && - options.type !== 'PATCH') { - options.type = 'POST'; - } - if (!options.formAcceptCharset) { - options.formAcceptCharset = options.form.attr('accept-charset'); - } - }, - - _getAJAXSettings: function (data) { - var options = $.extend({}, this.options, data); - this._initFormSettings(options); - this._initDataSettings(options); - return options; - }, - - // jQuery 1.6 doesn't provide .state(), - // while jQuery 1.8+ removed .isRejected() and .isResolved(): - _getDeferredState: function (deferred) { - if (deferred.state) { - return deferred.state(); - } - if (deferred.isResolved()) { - return 'resolved'; - } - if (deferred.isRejected()) { - return 'rejected'; - } - return 'pending'; - }, - - // Maps jqXHR callbacks to the equivalent - // methods of the given Promise object: - _enhancePromise: function (promise) { - promise.success = promise.done; - promise.error = promise.fail; - promise.complete = promise.always; - return promise; - }, - - // Creates and returns a Promise object enhanced with - // the jqXHR methods abort, success, error and complete: - _getXHRPromise: function (resolveOrReject, context, args) { - var dfd = $.Deferred(), - promise = dfd.promise(); - context = context || this.options.context || promise; - if (resolveOrReject === true) { - dfd.resolveWith(context, args); - } else if (resolveOrReject === false) { - dfd.rejectWith(context, args); - } - promise.abort = dfd.promise; - return this._enhancePromise(promise); - }, - - // Adds convenience methods to the data callback argument: - _addConvenienceMethods: function (e, data) { - var that = this, - getPromise = function (args) { - return $.Deferred().resolveWith(that, args).promise(); - }; - data.process = function (resolveFunc, rejectFunc) { - if (resolveFunc || rejectFunc) { - data._processQueue = this._processQueue = - (this._processQueue || getPromise([this])).then( - function () { - if (data.errorThrown) { - return $.Deferred() - .rejectWith(that, [data]).promise(); - } - return getPromise(arguments); - } - ).then(resolveFunc, rejectFunc); - } - return this._processQueue || getPromise([this]); - }; - data.submit = function () { - if (this.state() !== 'pending') { - data.jqXHR = this.jqXHR = - (that._trigger( - 'submit', - $.Event('submit', {delegatedEvent: e}), - this - ) !== false) && that._onSend(e, this); - } - return this.jqXHR || that._getXHRPromise(); - }; - data.abort = function () { - if (this.jqXHR) { - return this.jqXHR.abort(); - } - this.errorThrown = 'abort'; - that._trigger('fail', null, this); - return that._getXHRPromise(false); - }; - data.state = function () { - if (this.jqXHR) { - return that._getDeferredState(this.jqXHR); - } - if (this._processQueue) { - return that._getDeferredState(this._processQueue); - } - }; - data.processing = function () { - return !this.jqXHR && this._processQueue && that - ._getDeferredState(this._processQueue) === 'pending'; - }; - data.progress = function () { - return this._progress; - }; - data.response = function () { - return this._response; - }; - }, - - // Parses the Range header from the server response - // and returns the uploaded bytes: - _getUploadedBytes: function (jqXHR) { - var range = jqXHR.getResponseHeader('Range'), - parts = range && range.split('-'), - upperBytesPos = parts && parts.length > 1 && - parseInt(parts[1], 10); - return upperBytesPos && upperBytesPos + 1; - }, - - // Uploads a file in multiple, sequential requests - // by splitting the file up in multiple blob chunks. - // If the second parameter is true, only tests if the file - // should be uploaded in chunks, but does not invoke any - // upload requests: - _chunkedUpload: function (options, testOnly) { - options.uploadedBytes = options.uploadedBytes || 0; - var that = this, - file = options.files[0], - fs = file.size, - ub = options.uploadedBytes, - mcs = options.maxChunkSize || fs, - slice = this._blobSlice, - dfd = $.Deferred(), - promise = dfd.promise(), - jqXHR, - upload; - if (!(this._isXHRUpload(options) && slice && (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)) || - options.data) { - return false; - } - if (testOnly) { - return true; - } - if (ub >= fs) { - file.error = options.i18n('uploadedBytes'); - return this._getXHRPromise( - false, - options.context, - [null, 'error', file.error] - ); - } - // The chunk upload method: - upload = function () { - // Clone the options object for each chunk upload: - var o = $.extend({}, options), - currentLoaded = o._progress.loaded; - o.blob = slice.call( - file, - ub, - ub + ($.type(mcs) === 'function' ? mcs(o) : mcs), - file.type - ); - // Store the current chunk size, as the blob itself - // will be dereferenced after data processing: - o.chunkSize = o.blob.size; - // Expose the chunk bytes position range: - o.contentRange = 'bytes ' + ub + '-' + - (ub + o.chunkSize - 1) + '/' + fs; - // Trigger chunkbeforesend to allow form data to be updated for this chunk - that._trigger('chunkbeforesend', null, o); - // Process the upload data (the blob and potential form data): - that._initXHRData(o); - // Add progress listeners for this chunk upload: - that._initProgressListener(o); - jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) || - that._getXHRPromise(false, o.context)) - .done(function (result, textStatus, jqXHR) { - ub = that._getUploadedBytes(jqXHR) || - (ub + o.chunkSize); - // Create a progress event if no final progress event - // with loaded equaling total has been triggered - // for this chunk: - if (currentLoaded + o.chunkSize - o._progress.loaded) { - that._onProgress($.Event('progress', { - lengthComputable: true, - loaded: ub - o.uploadedBytes, - total: ub - o.uploadedBytes - }), o); - } - options.uploadedBytes = o.uploadedBytes = ub; - o.result = result; - o.textStatus = textStatus; - o.jqXHR = jqXHR; - that._trigger('chunkdone', null, o); - that._trigger('chunkalways', null, o); - if (ub < fs) { - // File upload not yet complete, - // continue with the next chunk: - upload(); - } else { - dfd.resolveWith( - o.context, - [result, textStatus, jqXHR] - ); - } - }) - .fail(function (jqXHR, textStatus, errorThrown) { - o.jqXHR = jqXHR; - o.textStatus = textStatus; - o.errorThrown = errorThrown; - that._trigger('chunkfail', null, o); - that._trigger('chunkalways', null, o); - dfd.rejectWith( - o.context, - [jqXHR, textStatus, errorThrown] - ); - }) - .always(function () { - that._deinitProgressListener(o); - }); - }; - this._enhancePromise(promise); - promise.abort = function () { - return jqXHR.abort(); - }; - upload(); - return promise; - }, - - _beforeSend: function (e, data) { - if (this._active === 0) { - // the start callback is triggered when an upload starts - // and no other uploads are currently running, - // equivalent to the global ajaxStart event: - this._trigger('start'); - // Set timer for global bitrate progress calculation: - this._bitrateTimer = new this._BitrateTimer(); - // Reset the global progress values: - this._progress.loaded = this._progress.total = 0; - this._progress.bitrate = 0; - } - // Make sure the container objects for the .response() and - // .progress() methods on the data object are available - // and reset to their initial state: - this._initResponseObject(data); - this._initProgressObject(data); - data._progress.loaded = data.loaded = data.uploadedBytes || 0; - data._progress.total = data.total = this._getTotal(data.files) || 1; - data._progress.bitrate = data.bitrate = 0; - this._active += 1; - // Initialize the global progress values: - this._progress.loaded += data.loaded; - this._progress.total += data.total; - }, - - _onDone: function (result, textStatus, jqXHR, options) { - var total = options._progress.total, - response = options._response; - if (options._progress.loaded < total) { - // Create a progress event if no final progress event - // with loaded equaling total has been triggered: - this._onProgress($.Event('progress', { - lengthComputable: true, - loaded: total, - total: total - }), options); - } - response.result = options.result = result; - response.textStatus = options.textStatus = textStatus; - response.jqXHR = options.jqXHR = jqXHR; - this._trigger('done', null, options); - }, - - _onFail: function (jqXHR, textStatus, errorThrown, options) { - var response = options._response; - if (options.recalculateProgress) { - // Remove the failed (error or abort) file upload from - // the global progress calculation: - this._progress.loaded -= options._progress.loaded; - this._progress.total -= options._progress.total; - } - response.jqXHR = options.jqXHR = jqXHR; - response.textStatus = options.textStatus = textStatus; - response.errorThrown = options.errorThrown = errorThrown; - this._trigger('fail', null, options); - }, - - _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) { - // jqXHRorResult, textStatus and jqXHRorError are added to the - // options object via done and fail callbacks - this._trigger('always', null, options); - }, - - _onSend: function (e, data) { - if (!data.submit) { - this._addConvenienceMethods(e, data); - } - var that = this, - jqXHR, - aborted, - slot, - pipe, - options = that._getAJAXSettings(data), - send = function () { - that._sending += 1; - // Set timer for bitrate progress calculation: - options._bitrateTimer = new that._BitrateTimer(); - jqXHR = jqXHR || ( - ((aborted || that._trigger( - 'send', - $.Event('send', {delegatedEvent: e}), - options - ) === false) && - that._getXHRPromise(false, options.context, aborted)) || - that._chunkedUpload(options) || $.ajax(options) - ).done(function (result, textStatus, jqXHR) { - that._onDone(result, textStatus, jqXHR, options); - }).fail(function (jqXHR, textStatus, errorThrown) { - that._onFail(jqXHR, textStatus, errorThrown, options); - }).always(function (jqXHRorResult, textStatus, jqXHRorError) { - that._deinitProgressListener(options); - that._onAlways( - jqXHRorResult, - textStatus, - jqXHRorError, - options - ); - that._sending -= 1; - that._active -= 1; - if (options.limitConcurrentUploads && - options.limitConcurrentUploads > that._sending) { - // Start the next queued upload, - // that has not been aborted: - var nextSlot = that._slots.shift(); - while (nextSlot) { - if (that._getDeferredState(nextSlot) === 'pending') { - nextSlot.resolve(); - break; - } - nextSlot = that._slots.shift(); - } - } - if (that._active === 0) { - // The stop callback is triggered when all uploads have - // been completed, equivalent to the global ajaxStop event: - that._trigger('stop'); - } - }); - return jqXHR; - }; - this._beforeSend(e, options); - if (this.options.sequentialUploads || - (this.options.limitConcurrentUploads && - this.options.limitConcurrentUploads <= this._sending)) { - if (this.options.limitConcurrentUploads > 1) { - slot = $.Deferred(); - this._slots.push(slot); - pipe = slot.then(send); - } else { - this._sequence = this._sequence.then(send, send); - pipe = this._sequence; - } - // Return the piped Promise object, enhanced with an abort method, - // which is delegated to the jqXHR object of the current upload, - // and jqXHR callbacks mapped to the equivalent Promise methods: - pipe.abort = function () { - aborted = [undefined, 'abort', 'abort']; - if (!jqXHR) { - if (slot) { - slot.rejectWith(options.context, aborted); - } - return send(); - } - return jqXHR.abort(); - }; - return this._enhancePromise(pipe); - } - return send(); - }, - - _onAdd: function (e, data) { - var that = this, - result = true, - options = $.extend({}, this.options, data), - files = data.files, - filesLength = files.length, - limit = options.limitMultiFileUploads, - limitSize = options.limitMultiFileUploadSize, - overhead = options.limitMultiFileUploadSizeOverhead, - batchSize = 0, - paramName = this._getParamName(options), - paramNameSet, - paramNameSlice, - fileSet, - i, - j = 0; - if (!filesLength) { - return false; - } - if (limitSize && files[0].size === undefined) { - limitSize = undefined; - } - if (!(options.singleFileUploads || limit || limitSize) || - !this._isXHRUpload(options)) { - fileSet = [files]; - paramNameSet = [paramName]; - } else if (!(options.singleFileUploads || limitSize) && limit) { - fileSet = []; - paramNameSet = []; - for (i = 0; i < filesLength; i += limit) { - fileSet.push(files.slice(i, i + limit)); - paramNameSlice = paramName.slice(i, i + limit); - if (!paramNameSlice.length) { - paramNameSlice = paramName; - } - paramNameSet.push(paramNameSlice); - } - } else if (!options.singleFileUploads && limitSize) { - fileSet = []; - paramNameSet = []; - for (i = 0; i < filesLength; i = i + 1) { - batchSize += files[i].size + overhead; - if (i + 1 === filesLength || - ((batchSize + files[i + 1].size + overhead) > limitSize) || - (limit && i + 1 - j >= limit)) { - fileSet.push(files.slice(j, i + 1)); - paramNameSlice = paramName.slice(j, i + 1); - if (!paramNameSlice.length) { - paramNameSlice = paramName; - } - paramNameSet.push(paramNameSlice); - j = i + 1; - batchSize = 0; - } - } - } else { - paramNameSet = paramName; - } - data.originalFiles = files; - $.each(fileSet || files, function (index, element) { - var newData = $.extend({}, data); - newData.files = fileSet ? element : [element]; - newData.paramName = paramNameSet[index]; - that._initResponseObject(newData); - that._initProgressObject(newData); - that._addConvenienceMethods(e, newData); - result = that._trigger( - 'add', - $.Event('add', {delegatedEvent: e}), - newData - ); - return result; - }); - return result; - }, - - _replaceFileInput: function (data) { - var input = data.fileInput, - inputClone = input.clone(true), - restoreFocus = input.is(document.activeElement); - // Add a reference for the new cloned file input to the data argument: - data.fileInputClone = inputClone; - $('<form></form>').append(inputClone)[0].reset(); - // Detaching allows to insert the fileInput on another form - // without loosing the file input value: - input.after(inputClone).detach(); - // If the fileInput had focus before it was detached, - // restore focus to the inputClone. - if (restoreFocus) { - inputClone.focus(); - } - // Avoid memory leaks with the detached file input: - $.cleanData(input.unbind('remove')); - // Replace the original file input element in the fileInput - // elements set with the clone, which has been copied including - // event handlers: - this.options.fileInput = this.options.fileInput.map(function (i, el) { - if (el === input[0]) { - return inputClone[0]; - } - return el; - }); - // If the widget has been initialized on the file input itself, - // override this.element with the file input clone: - if (input[0] === this.element[0]) { - this.element = inputClone; - } - }, - - _handleFileTreeEntry: function (entry, path) { - var that = this, - dfd = $.Deferred(), - entries = [], - dirReader, - errorHandler = function (e) { - if (e && !e.entry) { - e.entry = entry; - } - // Since $.when returns immediately if one - // Deferred is rejected, we use resolve instead. - // This allows valid files and invalid items - // to be returned together in one set: - dfd.resolve([e]); - }, - successHandler = function (entries) { - that._handleFileTreeEntries( - entries, - path + entry.name + '/' - ).done(function (files) { - dfd.resolve(files); - }).fail(errorHandler); - }, - readEntries = function () { - dirReader.readEntries(function (results) { - if (!results.length) { - successHandler(entries); - } else { - entries = entries.concat(results); - readEntries(); - } - }, errorHandler); - }; - path = path || ''; - if (entry.isFile) { - if (entry._file) { - // Workaround for Chrome bug #149735 - entry._file.relativePath = path; - dfd.resolve(entry._file); - } else { - entry.file(function (file) { - file.relativePath = path; - dfd.resolve(file); - }, errorHandler); - } - } else if (entry.isDirectory) { - dirReader = entry.createReader(); - readEntries(); - } else { - // Return an empty list for file system items - // other than files or directories: - dfd.resolve([]); - } - return dfd.promise(); - }, - - _handleFileTreeEntries: function (entries, path) { - var that = this; - return $.when.apply( - $, - $.map(entries, function (entry) { - return that._handleFileTreeEntry(entry, path); - }) - ).then(function () { - return Array.prototype.concat.apply( - [], - arguments - ); - }); - }, - - _getDroppedFiles: function (dataTransfer) { - dataTransfer = dataTransfer || {}; - var items = dataTransfer.items; - if (items && items.length && (items[0].webkitGetAsEntry || - items[0].getAsEntry)) { - return this._handleFileTreeEntries( - $.map(items, function (item) { - var entry; - if (item.webkitGetAsEntry) { - entry = item.webkitGetAsEntry(); - if (entry) { - // Workaround for Chrome bug #149735: - entry._file = item.getAsFile(); - } - return entry; - } - return item.getAsEntry(); - }) - ); - } - return $.Deferred().resolve( - $.makeArray(dataTransfer.files) - ).promise(); - }, - - _getSingleFileInputFiles: function (fileInput) { - fileInput = $(fileInput); - var entries = fileInput.prop('webkitEntries') || - fileInput.prop('entries'), - files, - value; - if (entries && entries.length) { - return this._handleFileTreeEntries(entries); - } - files = $.makeArray(fileInput.prop('files')); - if (!files.length) { - value = fileInput.prop('value'); - if (!value) { - return $.Deferred().resolve([]).promise(); - } - // If the files property is not available, the browser does not - // support the File API and we add a pseudo File object with - // the input value as name with path information removed: - files = [{name: value.replace(/^.*\\/, '')}]; - } else if (files[0].name === undefined && files[0].fileName) { - // File normalization for Safari 4 and Firefox 3: - $.each(files, function (index, file) { - file.name = file.fileName; - file.size = file.fileSize; - }); - } - return $.Deferred().resolve(files).promise(); - }, - - _getFileInputFiles: function (fileInput) { - if (!(fileInput instanceof $) || fileInput.length === 1) { - return this._getSingleFileInputFiles(fileInput); - } - return $.when.apply( - $, - $.map(fileInput, this._getSingleFileInputFiles) - ).then(function () { - return Array.prototype.concat.apply( - [], - arguments - ); - }); - }, - - _onChange: function (e) { - var that = this, - data = { - fileInput: $(e.target), - form: $(e.target.form) - }; - this._getFileInputFiles(data.fileInput).always(function (files) { - data.files = files; - if (that.options.replaceFileInput) { - that._replaceFileInput(data); - } - if (that._trigger( - 'change', - $.Event('change', {delegatedEvent: e}), - data - ) !== false) { - that._onAdd(e, data); - } - }); - }, - - _onPaste: function (e) { - var items = e.originalEvent && e.originalEvent.clipboardData && - e.originalEvent.clipboardData.items, - data = {files: []}; - if (items && items.length) { - $.each(items, function (index, item) { - var file = item.getAsFile && item.getAsFile(); - if (file) { - data.files.push(file); - } - }); - if (this._trigger( - 'paste', - $.Event('paste', {delegatedEvent: e}), - data - ) !== false) { - this._onAdd(e, data); - } - } - }, - - _onDrop: function (e) { - e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer; - var that = this, - dataTransfer = e.dataTransfer, - data = {}; - if (dataTransfer && dataTransfer.files && dataTransfer.files.length) { - e.preventDefault(); - this._getDroppedFiles(dataTransfer).always(function (files) { - data.files = files; - if (that._trigger( - 'drop', - $.Event('drop', {delegatedEvent: e}), - data - ) !== false) { - that._onAdd(e, data); - } - }); - } - }, - - _onDragOver: getDragHandler('dragover'), - - _onDragEnter: getDragHandler('dragenter'), - - _onDragLeave: getDragHandler('dragleave'), - - _initEventHandlers: function () { - if (this._isXHRUpload(this.options)) { - this._on(this.options.dropZone, { - dragover: this._onDragOver, - drop: this._onDrop, - // event.preventDefault() on dragenter is required for IE10+: - dragenter: this._onDragEnter, - // dragleave is not required, but added for completeness: - dragleave: this._onDragLeave - }); - this._on(this.options.pasteZone, { - paste: this._onPaste - }); - } - if ($.support.fileInput) { - this._on(this.options.fileInput, { - change: this._onChange - }); - } - }, - - _destroyEventHandlers: function () { - this._off(this.options.dropZone, 'dragenter dragleave dragover drop'); - this._off(this.options.pasteZone, 'paste'); - this._off(this.options.fileInput, 'change'); - }, - - _destroy: function () { - this._destroyEventHandlers(); - }, - - _setOption: function (key, value) { - var reinit = $.inArray(key, this._specialOptions) !== -1; - if (reinit) { - this._destroyEventHandlers(); - } - this._super(key, value); - if (reinit) { - this._initSpecialOptions(); - this._initEventHandlers(); - } - }, - - _initSpecialOptions: function () { - var options = this.options; - if (options.fileInput === undefined) { - options.fileInput = this.element.is('input[type="file"]') ? - this.element : this.element.find('input[type="file"]'); - } else if (!(options.fileInput instanceof $)) { - options.fileInput = $(options.fileInput); - } - if (!(options.dropZone instanceof $)) { - options.dropZone = $(options.dropZone); - } - if (!(options.pasteZone instanceof $)) { - options.pasteZone = $(options.pasteZone); - } - }, - - _getRegExp: function (str) { - var parts = str.split('/'), - modifiers = parts.pop(); - parts.shift(); - return new RegExp(parts.join('/'), modifiers); - }, - - _isRegExpOption: function (key, value) { - return key !== 'url' && $.type(value) === 'string' && - /^\/.*\/[igm]{0,3}$/.test(value); - }, - - _initDataAttributes: function () { - var that = this, - options = this.options, - data = this.element.data(); - // Initialize options set via HTML5 data-attributes: - $.each( - this.element[0].attributes, - function (index, attr) { - var key = attr.name.toLowerCase(), - value; - if (/^data-/.test(key)) { - // Convert hyphen-ated key to camelCase: - key = key.slice(5).replace(/-[a-z]/g, function (str) { - return str.charAt(1).toUpperCase(); - }); - value = data[key]; - if (that._isRegExpOption(key, value)) { - value = that._getRegExp(value); - } - options[key] = value; - } - } - ); - }, - - _create: function () { - this._initDataAttributes(); - this._initSpecialOptions(); - this._slots = []; - this._sequence = this._getXHRPromise(true); - this._sending = this._active = 0; - this._initProgressObject(this); - this._initEventHandlers(); - }, - - // This method is exposed to the widget API and allows to query - // the number of active uploads: - active: function () { - return this._active; - }, - - // This method is exposed to the widget API and allows to query - // the widget upload progress. - // It returns an object with loaded, total and bitrate properties - // for the running uploads: - progress: function () { - return this._progress; - }, - - // This method is exposed to the widget API and allows adding files - // using the fileupload API. The data parameter accepts an object which - // must have a files property and can contain additional options: - // .fileupload('add', {files: filesList}); - add: function (data) { - var that = this; - if (!data || this.options.disabled) { - return; - } - if (data.fileInput && !data.files) { - this._getFileInputFiles(data.fileInput).always(function (files) { - data.files = files; - that._onAdd(null, data); - }); - } else { - data.files = $.makeArray(data.files); - this._onAdd(null, data); - } - }, - - // This method is exposed to the widget API and allows sending files - // using the fileupload API. The data parameter accepts an object which - // must have a files or fileInput property and can contain additional options: - // .fileupload('send', {files: filesList}); - // The method returns a Promise object for the file upload call. - send: function (data) { - if (data && !this.options.disabled) { - if (data.fileInput && !data.files) { - var that = this, - dfd = $.Deferred(), - promise = dfd.promise(), - jqXHR, - aborted; - promise.abort = function () { - aborted = true; - if (jqXHR) { - return jqXHR.abort(); - } - dfd.reject(null, 'abort', 'abort'); - return promise; - }; - this._getFileInputFiles(data.fileInput).always( - function (files) { - if (aborted) { - return; - } - if (!files.length) { - dfd.reject(); - return; - } - data.files = files; - jqXHR = that._onSend(null, data); - jqXHR.then( - function (result, textStatus, jqXHR) { - dfd.resolve(result, textStatus, jqXHR); - }, - function (jqXHR, textStatus, errorThrown) { - dfd.reject(jqXHR, textStatus, errorThrown); - } - ); - } - ); - return this._enhancePromise(promise); - } - data.files = $.makeArray(data.files); - if (data.files.length) { - return this._onSend(null, data); - } - } - return this._getXHRPromise(false, data && data.context); - } - - }); - -})); diff --git a/src/Resources/assets/js/jquery.fileupload-process.js b/src/Resources/assets/js/jquery.fileupload-process.js deleted file mode 100644 index 7d25dbe1..00000000 --- a/src/Resources/assets/js/jquery.fileupload-process.js +++ /dev/null @@ -1,178 +0,0 @@ -/* - * jQuery File Upload Processing Plugin - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2012, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * https://opensource.org/licenses/MIT - */ - -/* jshint nomen:false */ -/* global define, require, window */ - -;(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - './jquery.fileupload' - ], factory); - } else if (typeof exports === 'object') { - // Node/CommonJS: - factory( - require('jquery'), - require('./jquery.fileupload') - ); - } else { - // Browser globals: - factory( - window.jQuery - ); - } -}(function ($) { - 'use strict'; - - var originalAdd = $.blueimp.fileupload.prototype.options.add; - - // The File Upload Processing plugin extends the fileupload widget - // with file processing functionality: - $.widget('blueimp.fileupload', $.blueimp.fileupload, { - - options: { - // The list of processing actions: - processQueue: [ - /* - { - action: 'log', - type: 'debug' - } - */ - ], - add: function (e, data) { - var $this = $(this); - data.process(function () { - return $this.fileupload('process', data); - }); - originalAdd.call(this, e, data); - } - }, - - processActions: { - /* - log: function (data, options) { - console[options.type]( - 'Processing "' + data.files[data.index].name + '"' - ); - } - */ - }, - - _processFile: function (data, originalData) { - var that = this, - dfd = $.Deferred().resolveWith(that, [data]), - chain = dfd.promise(); - this._trigger('process', null, data); - $.each(data.processQueue, function (i, settings) { - var func = function (data) { - if (originalData.errorThrown) { - return $.Deferred() - .rejectWith(that, [originalData]).promise(); - } - return that.processActions[settings.action].call( - that, - data, - settings - ); - }; - chain = chain.then(func, settings.always && func); - }); - chain - .done(function () { - that._trigger('processdone', null, data); - that._trigger('processalways', null, data); - }) - .fail(function () { - that._trigger('processfail', null, data); - that._trigger('processalways', null, data); - }); - return chain; - }, - - // Replaces the settings of each processQueue item that - // are strings starting with an "@", using the remaining - // substring as key for the option map, - // e.g. "@autoUpload" is replaced with options.autoUpload: - _transformProcessQueue: function (options) { - var processQueue = []; - $.each(options.processQueue, function () { - var settings = {}, - action = this.action, - prefix = this.prefix === true ? action : this.prefix; - $.each(this, function (key, value) { - if ($.type(value) === 'string' && - value.charAt(0) === '@') { - settings[key] = options[ - value.slice(1) || (prefix ? prefix + - key.charAt(0).toUpperCase() + key.slice(1) : key) - ]; - } else { - settings[key] = value; - } - - }); - processQueue.push(settings); - }); - options.processQueue = processQueue; - }, - - // Returns the number of files currently in the processsing queue: - processing: function () { - return this._processing; - }, - - // Processes the files given as files property of the data parameter, - // returns a Promise object that allows to bind callbacks: - process: function (data) { - var that = this, - options = $.extend({}, this.options, data); - if (options.processQueue && options.processQueue.length) { - this._transformProcessQueue(options); - if (this._processing === 0) { - this._trigger('processstart'); - } - $.each(data.files, function (index) { - var opts = index ? $.extend({}, options) : options, - func = function () { - if (data.errorThrown) { - return $.Deferred() - .rejectWith(that, [data]).promise(); - } - return that._processFile(opts, data); - }; - opts.index = index; - that._processing += 1; - that._processingQueue = that._processingQueue.then(func, func) - .always(function () { - that._processing -= 1; - if (that._processing === 0) { - that._trigger('processstop'); - } - }); - }); - } - return this._processingQueue; - }, - - _create: function () { - this._super(); - this._processing = 0; - this._processingQueue = $.Deferred().resolveWith(this) - .promise(); - } - - }); - -})); diff --git a/src/Resources/assets/js/jquery.fileupload-ui.js b/src/Resources/assets/js/jquery.fileupload-ui.js deleted file mode 100644 index a9577cdf..00000000 --- a/src/Resources/assets/js/jquery.fileupload-ui.js +++ /dev/null @@ -1,714 +0,0 @@ -/* - * jQuery File Upload User Interface Plugin - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2010, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * https://opensource.org/licenses/MIT - */ - -/* jshint nomen:false */ -/* global define, require, window */ - -;(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - 'blueimp-tmpl', - './jquery.fileupload-image', - './jquery.fileupload-audio', - './jquery.fileupload-video', - './jquery.fileupload-validate' - ], factory); - } else if (typeof exports === 'object') { - // Node/CommonJS: - factory( - require('jquery'), - require('blueimp-tmpl'), - require('./jquery.fileupload-image'), - require('./jquery.fileupload-audio'), - require('./jquery.fileupload-video'), - require('./jquery.fileupload-validate') - ); - } else { - // Browser globals: - factory( - window.jQuery, - window.tmpl - ); - } -}(function ($, tmpl) { - 'use strict'; - - $.blueimp.fileupload.prototype._specialOptions.push( - 'filesContainer', - 'uploadTemplateId', - 'downloadTemplateId' - ); - - // The UI version extends the file upload widget - // and adds complete user interface interaction: - $.widget('blueimp.fileupload', $.blueimp.fileupload, { - - options: { - // By default, files added to the widget are uploaded as soon - // as the user clicks on the start buttons. To enable automatic - // uploads, set the following option to true: - autoUpload: false, - // The ID of the upload template: - uploadTemplateId: 'template-upload', - // The ID of the download template: - downloadTemplateId: 'template-download', - // The container for the list of files. If undefined, it is set to - // an element with class "files" inside of the widget element: - filesContainer: undefined, - // By default, files are appended to the files container. - // Set the following option to true, to prepend files instead: - prependFiles: false, - // The expected data type of the upload response, sets the dataType - // option of the $.ajax upload requests: - dataType: 'json', - - // Error and info messages: - messages: { - unknownError: 'Unknown error' - }, - - // Function returning the current number of files, - // used by the maxNumberOfFiles validation: - getNumberOfFiles: function () { - return this.filesContainer.children() - .not('.processing').length; - }, - - // Callback to retrieve the list of files from the server response: - getFilesFromResponse: function (data) { - if (data.result && $.isArray(data.result.files)) { - return data.result.files; - } - return []; - }, - - // The add callback is invoked as soon as files are added to the fileupload - // widget (via file input selection, drag & drop or add API call). - // See the basic file upload widget for more information: - add: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var $this = $(this), - that = $this.data('blueimp-fileupload') || - $this.data('fileupload'), - options = that.options; - data.context = that._renderUpload(data.files) - .data('data', data) - .addClass('processing'); - options.filesContainer[ - options.prependFiles ? 'prepend' : 'append' - ](data.context); - that._forceReflow(data.context); - that._transition(data.context); - data.process(function () { - return $this.fileupload('process', data); - }).always(function () { - data.context.each(function (index) { - $(this).find('.size').text( - that._formatFileSize(data.files[index].size) - ); - }).removeClass('processing'); - that._renderPreviews(data); - }).done(function () { - data.context.find('.start').prop('disabled', false); - if ((that._trigger('added', e, data) !== false) && - (options.autoUpload || data.autoUpload) && - data.autoUpload !== false) { - data.submit(); - } - }).fail(function () { - if (data.files.error) { - data.context.each(function (index) { - var error = data.files[index].error; - if (error) { - $(this).find('.error').text(error); - } - }); - } - }); - }, - // Callback for the start of each file upload request: - send: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var that = $(this).data('blueimp-fileupload') || - $(this).data('fileupload'); - if (data.context && data.dataType && - data.dataType.substr(0, 6) === 'iframe') { - // Iframe Transport does not support progress events. - // In lack of an indeterminate progress bar, we set - // the progress to 100%, showing the full animated bar: - data.context - .find('.progress').addClass( - !$.support.transition && 'progress-animated' - ) - .attr('aria-valuenow', 100) - .children().first().css( - 'width', - '100%' - ); - } - return that._trigger('sent', e, data); - }, - // Callback for successful uploads: - done: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var that = $(this).data('blueimp-fileupload') || - $(this).data('fileupload'), - getFilesFromResponse = data.getFilesFromResponse || - that.options.getFilesFromResponse, - files = getFilesFromResponse(data), - template, - deferred; - if (data.context) { - data.context.each(function (index) { - var file = files[index] || - {error: 'Empty file upload result'}; - deferred = that._addFinishedDeferreds(); - that._transition($(this)).done( - function () { - var node = $(this); - template = that._renderDownload([file]) - .replaceAll(node); - that._forceReflow(template); - that._transition(template).done( - function () { - data.context = $(this); - that._trigger('completed', e, data); - that._trigger('finished', e, data); - deferred.resolve(); - } - ); - } - ); - }); - } else { - template = that._renderDownload(files)[ - that.options.prependFiles ? 'prependTo' : 'appendTo' - ](that.options.filesContainer); - that._forceReflow(template); - deferred = that._addFinishedDeferreds(); - that._transition(template).done( - function () { - data.context = $(this); - that._trigger('completed', e, data); - that._trigger('finished', e, data); - deferred.resolve(); - } - ); - } - }, - // Callback for failed (abort or error) uploads: - fail: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var that = $(this).data('blueimp-fileupload') || - $(this).data('fileupload'), - template, - deferred; - if (data.context) { - data.context.each(function (index) { - if (data.errorThrown !== 'abort') { - var file = data.files[index]; - file.error = file.error || data.errorThrown || - data.i18n('unknownError'); - deferred = that._addFinishedDeferreds(); - that._transition($(this)).done( - function () { - var node = $(this); - template = that._renderDownload([file]) - .replaceAll(node); - that._forceReflow(template); - that._transition(template).done( - function () { - data.context = $(this); - that._trigger('failed', e, data); - that._trigger('finished', e, data); - deferred.resolve(); - } - ); - } - ); - } else { - deferred = that._addFinishedDeferreds(); - that._transition($(this)).done( - function () { - $(this).remove(); - that._trigger('failed', e, data); - that._trigger('finished', e, data); - deferred.resolve(); - } - ); - } - }); - } else if (data.errorThrown !== 'abort') { - data.context = that._renderUpload(data.files)[ - that.options.prependFiles ? 'prependTo' : 'appendTo' - ](that.options.filesContainer) - .data('data', data); - that._forceReflow(data.context); - deferred = that._addFinishedDeferreds(); - that._transition(data.context).done( - function () { - data.context = $(this); - that._trigger('failed', e, data); - that._trigger('finished', e, data); - deferred.resolve(); - } - ); - } else { - that._trigger('failed', e, data); - that._trigger('finished', e, data); - that._addFinishedDeferreds().resolve(); - } - }, - // Callback for upload progress events: - progress: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var progress = Math.floor(data.loaded / data.total * 100); - if (data.context) { - data.context.each(function () { - $(this).find('.progress') - .attr('aria-valuenow', progress) - .children().first().css( - 'width', - progress + '%' - ); - }); - } - }, - // Callback for global upload progress events: - progressall: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var $this = $(this), - progress = Math.floor(data.loaded / data.total * 100), - globalProgressNode = $this.find('.fileupload-progress'), - extendedProgressNode = globalProgressNode - .find('.progress-extended'); - if (extendedProgressNode.length) { - extendedProgressNode.html( - ($this.data('blueimp-fileupload') || $this.data('fileupload')) - ._renderExtendedProgress(data) - ); - } - globalProgressNode - .find('.progress') - .attr('aria-valuenow', progress) - .children().first().css( - 'width', - progress + '%' - ); - }, - // Callback for uploads start, equivalent to the global ajaxStart event: - start: function (e) { - if (e.isDefaultPrevented()) { - return false; - } - var that = $(this).data('blueimp-fileupload') || - $(this).data('fileupload'); - that._resetFinishedDeferreds(); - that._transition($(this).find('.fileupload-progress')).done( - function () { - that._trigger('started', e); - } - ); - }, - // Callback for uploads stop, equivalent to the global ajaxStop event: - stop: function (e) { - if (e.isDefaultPrevented()) { - return false; - } - var that = $(this).data('blueimp-fileupload') || - $(this).data('fileupload'), - deferred = that._addFinishedDeferreds(); - $.when.apply($, that._getFinishedDeferreds()) - .done(function () { - that._trigger('stopped', e); - }); - that._transition($(this).find('.fileupload-progress')).done( - function () { - $(this).find('.progress') - .attr('aria-valuenow', '0') - .children().first().css('width', '0%'); - $(this).find('.progress-extended').html(' '); - deferred.resolve(); - } - ); - }, - processstart: function (e) { - if (e.isDefaultPrevented()) { - return false; - } - $(this).addClass('fileupload-processing'); - }, - processstop: function (e) { - if (e.isDefaultPrevented()) { - return false; - } - $(this).removeClass('fileupload-processing'); - }, - // Callback for file deletion: - destroy: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var that = $(this).data('blueimp-fileupload') || - $(this).data('fileupload'), - removeNode = function () { - that._transition(data.context).done( - function () { - $(this).remove(); - that._trigger('destroyed', e, data); - } - ); - }; - if (data.url) { - data.dataType = data.dataType || that.options.dataType; - $.ajax(data).done(removeNode).fail(function () { - that._trigger('destroyfailed', e, data); - }); - } else { - removeNode(); - } - } - }, - - _resetFinishedDeferreds: function () { - this._finishedUploads = []; - }, - - _addFinishedDeferreds: function (deferred) { - if (!deferred) { - deferred = $.Deferred(); - } - this._finishedUploads.push(deferred); - return deferred; - }, - - _getFinishedDeferreds: function () { - return this._finishedUploads; - }, - - // Link handler, that allows to download files - // by drag & drop of the links to the desktop: - _enableDragToDesktop: function () { - var link = $(this), - url = link.prop('href'), - name = link.prop('download'), - type = 'application/octet-stream'; - link.bind('dragstart', function (e) { - try { - e.originalEvent.dataTransfer.setData( - 'DownloadURL', - [type, name, url].join(':') - ); - } catch (ignore) {} - }); - }, - - _formatFileSize: function (bytes) { - if (typeof bytes !== 'number') { - return ''; - } - if (bytes >= 1000000000) { - return (bytes / 1000000000).toFixed(2) + ' GB'; - } - if (bytes >= 1000000) { - return (bytes / 1000000).toFixed(2) + ' MB'; - } - return (bytes / 1000).toFixed(2) + ' KB'; - }, - - _formatBitrate: function (bits) { - if (typeof bits !== 'number') { - return ''; - } - if (bits >= 1000000000) { - return (bits / 1000000000).toFixed(2) + ' Gbit/s'; - } - if (bits >= 1000000) { - return (bits / 1000000).toFixed(2) + ' Mbit/s'; - } - if (bits >= 1000) { - return (bits / 1000).toFixed(2) + ' kbit/s'; - } - return bits.toFixed(2) + ' bit/s'; - }, - - _formatTime: function (seconds) { - var date = new Date(seconds * 1000), - days = Math.floor(seconds / 86400); - days = days ? days + 'd ' : ''; - return days + - ('0' + date.getUTCHours()).slice(-2) + ':' + - ('0' + date.getUTCMinutes()).slice(-2) + ':' + - ('0' + date.getUTCSeconds()).slice(-2); - }, - - _formatPercentage: function (floatValue) { - return (floatValue * 100).toFixed(2) + ' %'; - }, - - _renderExtendedProgress: function (data) { - return this._formatBitrate(data.bitrate) + ' | ' + - this._formatTime( - (data.total - data.loaded) * 8 / data.bitrate - ) + ' | ' + - this._formatPercentage( - data.loaded / data.total - ) + ' | ' + - this._formatFileSize(data.loaded) + ' / ' + - this._formatFileSize(data.total); - }, - - _renderTemplate: function (func, files) { - if (!func) { - return $(); - } - var result = func({ - files: files, - formatFileSize: this._formatFileSize, - options: this.options - }); - if (result instanceof $) { - return result; - } - return $(this.options.templatesContainer).html(result).children(); - }, - - _renderPreviews: function (data) { - data.context.find('.preview').each(function (index, elm) { - $(elm).append(data.files[index].preview); - }); - }, - - _renderUpload: function (files) { - return this._renderTemplate( - this.options.uploadTemplate, - files - ); - }, - - _renderDownload: function (files) { - return this._renderTemplate( - this.options.downloadTemplate, - files - ).find('a[download]').each(this._enableDragToDesktop).end(); - }, - - _startHandler: function (e) { - e.preventDefault(); - var button = $(e.currentTarget), - template = button.closest('.template-upload'), - data = template.data('data'); - button.prop('disabled', true); - if (data && data.submit) { - data.submit(); - } - }, - - _cancelHandler: function (e) { - e.preventDefault(); - var template = $(e.currentTarget) - .closest('.template-upload,.template-download'), - data = template.data('data') || {}; - data.context = data.context || template; - if (data.abort) { - data.abort(); - } else { - data.errorThrown = 'abort'; - this._trigger('fail', e, data); - } - }, - - _deleteHandler: function (e) { - e.preventDefault(); - var button = $(e.currentTarget); - this._trigger('destroy', e, $.extend({ - context: button.closest('.template-download'), - type: 'DELETE' - }, button.data())); - }, - - _forceReflow: function (node) { - return $.support.transition && node.length && - node[0].offsetWidth; - }, - - _transition: function (node) { - var dfd = $.Deferred(); - if ($.support.transition && node.hasClass('fade') && node.is(':visible')) { - node.bind( - $.support.transition.end, - function (e) { - // Make sure we don't respond to other transitions events - // in the container element, e.g. from button elements: - if (e.target === node[0]) { - node.unbind($.support.transition.end); - dfd.resolveWith(node); - } - } - ).toggleClass('in'); - } else { - node.toggleClass('in'); - dfd.resolveWith(node); - } - return dfd; - }, - - _initButtonBarEventHandlers: function () { - var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'), - filesList = this.options.filesContainer; - this._on(fileUploadButtonBar.find('.start'), { - click: function (e) { - e.preventDefault(); - filesList.find('.start').click(); - } - }); - this._on(fileUploadButtonBar.find('.cancel'), { - click: function (e) { - e.preventDefault(); - filesList.find('.cancel').click(); - } - }); - this._on(fileUploadButtonBar.find('.delete'), { - click: function (e) { - e.preventDefault(); - filesList.find('.toggle:checked') - .closest('.template-download') - .find('.delete').click(); - fileUploadButtonBar.find('.toggle') - .prop('checked', false); - } - }); - this._on(fileUploadButtonBar.find('.toggle'), { - change: function (e) { - filesList.find('.toggle').prop( - 'checked', - $(e.currentTarget).is(':checked') - ); - } - }); - }, - - _destroyButtonBarEventHandlers: function () { - this._off( - this.element.find('.fileupload-buttonbar') - .find('.start, .cancel, .delete'), - 'click' - ); - this._off( - this.element.find('.fileupload-buttonbar .toggle'), - 'change.' - ); - }, - - _initEventHandlers: function () { - this._super(); - this._on(this.options.filesContainer, { - 'click .start': this._startHandler, - 'click .cancel': this._cancelHandler, - 'click .delete': this._deleteHandler - }); - this._initButtonBarEventHandlers(); - }, - - _destroyEventHandlers: function () { - this._destroyButtonBarEventHandlers(); - this._off(this.options.filesContainer, 'click'); - this._super(); - }, - - _enableFileInputButton: function () { - this.element.find('.fileinput-button input') - .prop('disabled', false) - .parent().removeClass('disabled'); - }, - - _disableFileInputButton: function () { - this.element.find('.fileinput-button input') - .prop('disabled', true) - .parent().addClass('disabled'); - }, - - _initTemplates: function () { - var options = this.options; - options.templatesContainer = this.document[0].createElement( - options.filesContainer.prop('nodeName') - ); - if (tmpl) { - if (options.uploadTemplateId) { - options.uploadTemplate = tmpl(options.uploadTemplateId); - } - if (options.downloadTemplateId) { - options.downloadTemplate = tmpl(options.downloadTemplateId); - } - } - }, - - _initFilesContainer: function () { - var options = this.options; - if (options.filesContainer === undefined) { - options.filesContainer = this.element.find('.files'); - } else if (!(options.filesContainer instanceof $)) { - options.filesContainer = $(options.filesContainer); - } - }, - - _initSpecialOptions: function () { - this._super(); - this._initFilesContainer(); - this._initTemplates(); - }, - - _create: function () { - this._super(); - this._resetFinishedDeferreds(); - if (!$.support.fileInput) { - this._disableFileInputButton(); - } - }, - - enable: function () { - var wasDisabled = false; - if (this.options.disabled) { - wasDisabled = true; - } - this._super(); - if (wasDisabled) { - this.element.find('input, button').prop('disabled', false); - this._enableFileInputButton(); - } - }, - - disable: function () { - if (!this.options.disabled) { - this.element.find('input, button').prop('disabled', true); - this._disableFileInputButton(); - } - this._super(); - } - - }); - -})); diff --git a/src/Resources/assets/js/jquery.fileupload-validate.js b/src/Resources/assets/js/jquery.fileupload-validate.js deleted file mode 100644 index 7487b76d..00000000 --- a/src/Resources/assets/js/jquery.fileupload-validate.js +++ /dev/null @@ -1,125 +0,0 @@ -/* - * jQuery File Upload Validation Plugin - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * https://opensource.org/licenses/MIT - */ - -/* global define, require, window */ - -;(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - './jquery.fileupload-process' - ], factory); - } else if (typeof exports === 'object') { - // Node/CommonJS: - factory( - require('jquery'), - require('./jquery.fileupload-process') - ); - } else { - // Browser globals: - factory( - window.jQuery - ); - } -}(function ($) { - 'use strict'; - - // Append to the default processQueue: - $.blueimp.fileupload.prototype.options.processQueue.push( - { - action: 'validate', - // Always trigger this action, - // even if the previous action was rejected: - always: true, - // Options taken from the global options map: - acceptFileTypes: '@', - maxFileSize: '@', - minFileSize: '@', - maxNumberOfFiles: '@', - disabled: '@disableValidation' - } - ); - - // The File Upload Validation plugin extends the fileupload widget - // with file validation functionality: - $.widget('blueimp.fileupload', $.blueimp.fileupload, { - - options: { - /* - // The regular expression for allowed file types, matches - // against either file type or file name: - acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, - // The maximum allowed file size in bytes: - maxFileSize: 10000000, // 10 MB - // The minimum allowed file size in bytes: - minFileSize: undefined, // No minimal file size - // The limit of files to be uploaded: - maxNumberOfFiles: 10, - */ - - // Function returning the current number of files, - // has to be overriden for maxNumberOfFiles validation: - getNumberOfFiles: $.noop, - - // Error and info messages: - messages: { - maxNumberOfFiles: 'Maximum number of files exceeded', - acceptFileTypes: 'File type not allowed', - maxFileSize: 'File is too large', - minFileSize: 'File is too small' - } - }, - - processActions: { - - validate: function (data, options) { - if (options.disabled) { - return data; - } - var dfd = $.Deferred(), - settings = this.options, - file = data.files[data.index], - fileSize; - if (options.minFileSize || options.maxFileSize) { - fileSize = file.size; - } - if ($.type(options.maxNumberOfFiles) === 'number' && - (settings.getNumberOfFiles() || 0) + data.files.length > - options.maxNumberOfFiles) { - file.error = settings.i18n('maxNumberOfFiles'); - } else if (options.acceptFileTypes && - !(options.acceptFileTypes.test(file.type) || - options.acceptFileTypes.test(file.name))) { - file.error = settings.i18n('acceptFileTypes'); - } else if (fileSize > options.maxFileSize) { - file.error = settings.i18n('maxFileSize'); - } else if ($.type(fileSize) === 'number' && - fileSize < options.minFileSize) { - file.error = settings.i18n('minFileSize'); - } else { - delete file.error; - } - if (file.error || data.files.error) { - data.files.error = true; - dfd.rejectWith(this, [data]); - } else { - dfd.resolveWith(this, [data]); - } - return dfd.promise(); - } - - } - - }); - -})); diff --git a/src/Resources/assets/js/main.js b/src/Resources/assets/js/main.js index e2c2f6ba..4a78b014 100644 --- a/src/Resources/assets/js/main.js +++ b/src/Resources/assets/js/main.js @@ -1,21 +1,15 @@ import * as jQuery from 'jquery'; global.$ = window.$ = jQuery; -import 'bootstrap-sass'; -import './widget/file_upload.js'; -import '../sass/file_upload.scss'; -import 'blueimp-file-upload/js/vendor/jquery.ui.widget'; -import 'blueimp-file-upload/js/jquery.iframe-transport'; - -import 'blueimp-load-image'; +//css to convert to less +import 'blueimp-file-upload/css/jquery.fileupload.css'; +import 'blueimp-file-upload/css/jquery.fileupload-ui.css'; +import '../sass/file_upload.scss'; -import 'blueimp-file-upload/js/jquery.fileupload'; import 'blueimp-file-upload/js/jquery.fileupload'; import 'blueimp-file-upload/js/jquery.fileupload-process'; import 'blueimp-file-upload/js/jquery.fileupload-validate'; +import 'blueimp-file-upload/js/jquery.fileupload-ui'; +import './widget/file_upload.js'; -//css to convert to less -import 'blueimp-file-upload/css/jquery.fileupload.css'; -import 'blueimp-file-upload/css/jquery.fileupload-ui.css'; - diff --git a/tests/Fixtures/templates/base.html.twig b/tests/Fixtures/templates/base.html.twig index 9dcfde37..0a851d28 100644 --- a/tests/Fixtures/templates/base.html.twig +++ b/tests/Fixtures/templates/base.html.twig @@ -2,7 +2,6 @@ {% block titrePage %} {{ parent() }} - Show case: {{ type | capitalize }} {% endblock %} @@ -12,8 +11,7 @@ {% endblock %} {%- block javascripts %} -{{ parent() }} - + {{ parent() }} {{ encore_entry_script_tags('main') }} {% endblock %} diff --git a/tests/Fixtures/templates/index.html.twig b/tests/Fixtures/templates/index.html.twig index b377ea80..d5d79f5d 100644 --- a/tests/Fixtures/templates/index.html.twig +++ b/tests/Fixtures/templates/index.html.twig @@ -1,5 +1,4 @@ {% extends '/base.html.twig' %} - {% block content -%} {{ form_start(form) }} <div class="tab-content"> diff --git a/tests/Fixtures/webpack.config.js b/tests/Fixtures/webpack.config.js index a8fe4fb0..3a806167 100644 --- a/tests/Fixtures/webpack.config.js +++ b/tests/Fixtures/webpack.config.js @@ -1,4 +1,5 @@ var Encore = require('@symfony/webpack-encore'); + //var config = Encore.getWebpackConfig(); Encore // the project directory where compiled assets will be stored @@ -36,10 +37,19 @@ Encore .addEntry('main', [ './assets/main.js', './assets/main.scss', - './assets/fileupload_demo.js', ]) - .splitEntryChunks(); -module.exports = Encore.getWebpackConfig(); +//module.exports = Encore.getWebpackConfig(); + const config = Encore.getWebpackConfig(); + config.resolve.alias = { + 'load-image': 'blueimp-load-image/js/load-image.js', + 'load-image-meta': 'blueimp-load-image/js/load-image-meta.js', + 'load-image-exif': 'blueimp-load-image/js/load-image-exif.js', + 'load-image-orientation': 'blueimp-load-image/js/load-image-orientation.js', + 'load-image-scale': 'blueimp-load-image/js/load-image-scale.js', + 'canvas-to-blob': 'blueimp-canvas-to-blob/js/canvas-to-blob.js', + 'jquery-ui/widget': 'blueimp-file-upload/js/vendor/jquery.ui.widget.js', +}; +module.exports = config; -- GitLab