diff --git a/lib/jquery/fileupload/rails/version.rb b/lib/jquery/fileupload/rails/version.rb index 10fbdc9..532d712 100644 --- a/lib/jquery/fileupload/rails/version.rb +++ b/lib/jquery/fileupload/rails/version.rb @@ -1,7 +1,7 @@ module JQuery module FileUpload module Rails - VERSION = "0.4.1" + VERSION = "0.4.3" end end end diff --git a/vendor/assets/images/loading.gif b/vendor/assets/images/loading.gif old mode 100755 new mode 100644 diff --git a/vendor/assets/images/progressbar.gif b/vendor/assets/images/progressbar.gif old mode 100755 new mode 100644 diff --git a/vendor/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js b/vendor/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js old mode 100755 new mode 100644 index 931b635..2b4851e --- a/vendor/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js +++ b/vendor/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js @@ -1,5 +1,5 @@ /* - * jQuery postMessage Transport Plugin 1.1 + * jQuery postMessage Transport Plugin 1.1.1 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2011, Sebastian Tschan @@ -9,8 +9,7 @@ * http://www.opensource.org/licenses/MIT */ -/*jslint unparam: true, nomen: true */ -/*global define, window, document */ +/* global define, window, document */ (function (factory) { 'use strict'; @@ -64,8 +63,9 @@ xhrUpload = options.xhr().upload; return { send: function (_, completeCallback) { + counter += 1; var message = { - id: 'postmessage-transport-' + (counter += 1) + id: 'postmessage-transport-' + counter }, eventName = 'message.' + message.id; iframe = $( diff --git a/vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js b/vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js old mode 100755 new mode 100644 index d769f45..0044cc2 --- a/vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js +++ b/vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js @@ -12,8 +12,7 @@ * https://github.com/jaubourg/ajaxHooks/ */ -/*jslint unparam: true */ -/*global define, window, XDomainRequest */ +/* global define, window, XDomainRequest */ (function (factory) { 'use strict'; diff --git a/vendor/assets/javascripts/jquery-fileupload/index.js b/vendor/assets/javascripts/jquery-fileupload/index.js index 0cda385..92bc4f1 100644 --- a/vendor/assets/javascripts/jquery-fileupload/index.js +++ b/vendor/assets/javascripts/jquery-fileupload/index.js @@ -1,9 +1,11 @@ -//=require jquery-fileupload/vendor/jquery.ui.widget -//=require jquery-fileupload/vendor/load-image -//=require jquery-fileupload/vendor/canvas-to-blob -//=require jquery-fileupload/vendor/tmpl -//=require jquery-fileupload/jquery.iframe-transport -//=require jquery-fileupload/jquery.fileupload -//=require jquery-fileupload/jquery.fileupload-fp -//=require jquery-fileupload/jquery.fileupload-ui -//=require jquery-fileupload/locale +//= require jquery-fileupload/vendor/jquery.ui.widget +//= require jquery-fileupload/vendor/load-image +//= require jquery-fileupload/vendor/canvas-to-blob +//= require jquery-fileupload/vendor/tmpl +//= require jquery-fileupload/jquery.iframe-transport +//= require jquery-fileupload/jquery.fileupload +//= require jquery-fileupload/jquery.fileupload-process +//= require jquery-fileupload/jquery.fileupload-validate +//= require jquery-fileupload/jquery.fileupload-image +//= require jquery-fileupload/jquery.fileupload-ui +//= require jquery-fileupload/locale diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js deleted file mode 100755 index e7ba784..0000000 --- a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js +++ /dev/null @@ -1,348 +0,0 @@ -/* - * jQuery File Upload AngularJS Plugin 1.0.1 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/*jslint nomen: true, unparam: true */ -/*global angular */ - -(function () { - 'use strict'; - - angular.module('blueimp.fileupload', []) - - .provider('fileUpload', function () { - var scopeApply = function () { - var scope = angular.element(this) - .fileupload('option', 'scope')(); - if (!scope.$$phase) { - scope.$apply(); - } - }, - $config; - $config = this.defaults = { - handleResponse: function (e, data) { - var files = data.result && data.result.files; - if (files) { - data.scope().replace(data.files, files); - } else if (data.errorThrown || - data.textStatus === 'error') { - data.files[0].error = data.errorThrown || - data.textStatus; - } - }, - add: function (e, data) { - var scope = data.scope(); - data.process(function () { - return scope.process(data); - }).always( - function () { - var file = data.files[0], - submit = function () { - return data.submit(); - }; - file.$cancel = function () { - scope.clear(data.files); - return data.abort(); - }; - file.$state = function () { - return data.state(); - }; - file.$progress = function () { - return data.progress(); - }; - file.$response = function () { - return data.response(); - }; - if (file.$state() === 'rejected') { - file._$submit = submit; - } else { - file.$submit = submit; - } - scope.$apply(function () { - var method = scope.option('prependFiles') ? - 'unshift' : 'push'; - Array.prototype[method].apply( - scope.queue, - data.files - ); - if (file.$submit && - (scope.option('autoUpload') || - data.autoUpload) && - data.autoUpload !== false) { - file.$submit(); - } - }); - } - ); - }, - progress: function (e, data) { - data.scope().$apply(); - }, - done: function (e, data) { - var that = this; - data.scope().$apply(function () { - data.handleResponse.call(that, e, data); - }); - }, - fail: function (e, data) { - var that = this; - if (data.errorThrown === 'abort') { - return; - } - if (data.dataType.indexOf('json') === data.dataType.length - 4) { - try { - data.result = angular.fromJson(data.jqXHR.responseText); - } catch (err) {} - } - data.scope().$apply(function () { - data.handleResponse.call(that, e, data); - }); - }, - stop: scopeApply, - processstart: scopeApply, - processstop: scopeApply, - getNumberOfFiles: function () { - return this.scope().queue.length; - }, - dataType: 'json', - prependFiles: true, - autoUpload: false - }; - this.$get = [ - function () { - return { - defaults: $config - }; - } - ]; - }) - - .provider('formatFileSizeFilter', function () { - var $config = this.defaults = { - // Byte units following the IEC format - // http://en.wikipedia.org/wiki/Kilobyte - units: [ - {size: 1000000000, suffix: ' GB'}, - {size: 1000000, suffix: ' MB'}, - {size: 1000, suffix: ' KB'} - ] - }; - this.$get = function () { - return function (bytes) { - if (!angular.isNumber(bytes)) { - return ''; - } - var unit = true, - i = -1; - while (unit) { - unit = $config.units[i += 1]; - if (i === $config.units.length - 1 || bytes >= unit.size) { - return (bytes / unit.size).toFixed(2) + unit.suffix; - } - } - }; - }; - }) - - .controller('FileUploadController', [ - '$scope', '$element', '$attrs', 'fileUpload', - function ($scope, $element, $attrs, fileUpload) { - $scope.disabled = angular.element('') - .prop('disabled'); - $scope.queue = $scope.queue || []; - $scope.clear = function (files) { - var queue = this.queue, - i = queue.length, - file = files, - length = 1; - if (angular.isArray(files)) { - file = files[0]; - length = files.length; - } - while (i) { - if (queue[i -= 1] === file) { - return queue.splice(i, length); - } - } - }; - $scope.replace = function (oldFiles, newFiles) { - var queue = this.queue, - file = oldFiles[0], - i, - j; - for (i = 0; i < queue.length; i += 1) { - if (queue[i] === file) { - for (j = 0; j < newFiles.length; j += 1) { - queue[i + j] = newFiles[j]; - } - return; - } - } - }; - $scope.progress = function () { - return $element.fileupload('progress'); - }; - $scope.active = function () { - return $element.fileupload('active'); - }; - $scope.option = function (option, data) { - return $element.fileupload('option', option, data); - }; - $scope.add = function (data) { - return $element.fileupload('add', data); - }; - $scope.send = function (data) { - return $element.fileupload('send', data); - }; - $scope.process = function (data) { - return $element.fileupload('process', data); - }; - $scope.processing = function (data) { - return $element.fileupload('processing', data); - }; - $scope.applyOnQueue = function (method) { - var list = this.queue.slice(0), - i, - file; - for (i = 0; i < list.length; i += 1) { - file = list[i]; - if (file[method]) { - file[method](); - } - } - }; - $scope.submit = function () { - this.applyOnQueue('$submit'); - }; - $scope.cancel = function () { - this.applyOnQueue('$cancel'); - }; - // The fileupload widget will initialize with - // the options provided via "data-"-parameters, - // as well as those given via options object: - $element.fileupload(angular.extend( - {scope: function () { - return $scope; - }}, - fileUpload.defaults - )).on('fileuploadadd', function (e, data) { - data.scope = $scope.option('scope'); - }).on([ - 'fileuploadadd', - 'fileuploadsubmit', - 'fileuploadsend', - 'fileuploaddone', - 'fileuploadfail', - 'fileuploadalways', - 'fileuploadprogress', - 'fileuploadprogressall', - 'fileuploadstart', - 'fileuploadstop', - 'fileuploadchange', - 'fileuploadpaste', - 'fileuploaddrop', - 'fileuploaddragover', - 'fileuploadchunksend', - 'fileuploadchunkdone', - 'fileuploadchunkfail', - 'fileuploadchunkalways', - 'fileuploadprocessstart', - 'fileuploadprocess', - 'fileuploadprocessdone', - 'fileuploadprocessfail', - 'fileuploadprocessalways', - 'fileuploadprocessstop' - ].join(' '), function (e, data) { - $scope.$emit(e.type, data); - }); - // Observe option changes: - $scope.$watch( - $attrs.fileupload, - function (newOptions, oldOptions) { - if (newOptions) { - $element.fileupload('option', newOptions); - } - } - ); - } - ]) - - .controller('FileUploadProgressController', [ - '$scope', '$attrs', '$parse', - function ($scope, $attrs, $parse) { - var fn = $parse($attrs.progress), - update = function () { - var progress = fn($scope); - if (!progress || !progress.total) { - return; - } - $scope.num = Math.floor( - progress.loaded / progress.total * 100 - ); - }; - update(); - $scope.$watch( - $attrs.progress + '.loaded', - function (newValue, oldValue) { - if (newValue !== oldValue) { - update(); - } - } - ); - } - ]) - - .controller('FileUploadPreviewController', [ - '$scope', '$element', '$attrs', '$parse', - function ($scope, $element, $attrs, $parse) { - var fn = $parse($attrs.preview), - file = fn($scope); - if (file.preview) { - $element.append(file.preview); - } - } - ]) - - .directive('fileupload', function () { - return { - controller: 'FileUploadController' - }; - }) - - .directive('progress', function () { - return { - controller: 'FileUploadProgressController' - }; - }) - - .directive('preview', function () { - return { - controller: 'FileUploadPreviewController' - }; - }) - - .directive('download', function () { - return function (scope, elm, attrs) { - elm.on('dragstart', function (e) { - try { - e.originalEvent.dataTransfer.setData( - 'DownloadURL', - [ - 'application/octet-stream', - elm.prop('download'), - elm.prop('href') - ].join(':') - ); - } catch (err) {} - }); - }; - }); - -}()); diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js deleted file mode 100644 index c782f1e..0000000 --- a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js +++ /dev/null @@ -1,227 +0,0 @@ -/* - * jQuery File Upload File Processing Plugin 1.2.3 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2012, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/*jslint nomen: true, unparam: true, regexp: true */ -/*global define, window, document */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - 'load-image', - 'canvas-to-blob', - './jquery.fileupload' - ], factory); - } else { - // Browser globals: - factory( - window.jQuery, - window.loadImage - ); - } -}(function ($, loadImage) { - 'use strict'; - - // The File Upload FP version extends the fileupload widget - // with file processing functionality: - $.widget('blueimp.fileupload', $.blueimp.fileupload, { - - options: { - // The list of file processing actions: - process: [ - /* - { - action: 'load', - fileTypes: /^image\/(gif|jpeg|png)$/, - maxFileSize: 20000000 // 20MB - }, - { - action: 'resize', - maxWidth: 1920, - maxHeight: 1200, - minWidth: 800, - minHeight: 600 - }, - { - action: 'save' - } - */ - ], - - // 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 (data.autoUpload || (data.autoUpload !== false && - ($(this).data('blueimp-fileupload') || - $(this).data('fileupload')).options.autoUpload)) { - $(this).fileupload('process', data).done(function () { - data.submit(); - }); - } - } - }, - - processActions: { - // Loads the image given via data.files and data.index - // as img element if the browser supports canvas. - // Accepts the options fileTypes (regular expression) - // and maxFileSize (integer) to limit the files to load: - load: function (data, options) { - var that = this, - file = data.files[data.index], - dfd = $.Deferred(); - if (window.HTMLCanvasElement && - window.HTMLCanvasElement.prototype.toBlob && - ($.type(options.maxFileSize) !== 'number' || - file.size < options.maxFileSize) && - (!options.fileTypes || - options.fileTypes.test(file.type))) { - loadImage( - file, - function (img) { - if (!img.src) { - return dfd.rejectWith(that, [data]); - } - data.img = img; - dfd.resolveWith(that, [data]); - } - ); - } else { - dfd.rejectWith(that, [data]); - } - return dfd.promise(); - }, - // Resizes the image given as data.img and updates - // data.canvas with the resized image as canvas element. - // Accepts the options maxWidth, maxHeight, minWidth and - // minHeight to scale the given image: - resize: function (data, options) { - var img = data.img, - canvas; - options = $.extend({canvas: true}, options); - if (img) { - canvas = loadImage.scale(img, options); - if (canvas.width !== img.width || - canvas.height !== img.height) { - data.canvas = canvas; - } - } - return data; - }, - // Saves the processed image given as data.canvas - // inplace at data.index of data.files: - save: function (data, options) { - // Do nothing if no processing has happened: - if (!data.canvas) { - return data; - } - var that = this, - file = data.files[data.index], - name = file.name, - dfd = $.Deferred(), - callback = function (blob) { - if (!blob.name) { - if (file.type === blob.type) { - blob.name = file.name; - } else if (file.name) { - blob.name = file.name.replace( - /\..+$/, - '.' + blob.type.substr(6) - ); - } - } - // Store the created blob at the position - // of the original file in the files list: - data.files[data.index] = blob; - dfd.resolveWith(that, [data]); - }; - // Use canvas.mozGetAsFile directly, to retain the filename, as - // Gecko doesn't support the filename option for FormData.append: - if (data.canvas.mozGetAsFile) { - callback(data.canvas.mozGetAsFile( - (/^image\/(jpeg|png)$/.test(file.type) && name) || - ((name && name.replace(/\..+$/, '')) || - 'blob') + '.png', - file.type - )); - } else { - data.canvas.toBlob(callback, file.type); - } - return dfd.promise(); - } - }, - - // Resizes the file at the given index and stores the created blob at - // the original position of the files list, returns a Promise object: - _processFile: function (files, index, options) { - var that = this, - dfd = $.Deferred().resolveWith(that, [{ - files: files, - index: index - }]), - chain = dfd.promise(); - that._processing += 1; - $.each(options.process, function (i, settings) { - chain = chain.pipe(function (data) { - return that.processActions[settings.action] - .call(this, data, settings); - }); - }); - chain.always(function () { - that._processing -= 1; - if (that._processing === 0) { - that.element - .removeClass('fileupload-processing'); - } - }); - if (that._processing === 1) { - that.element.addClass('fileupload-processing'); - } - return chain; - }, - - // Processes the files given as files property of the data parameter, - // returns a Promise object that allows to bind a done handler, which - // will be invoked after processing all files (inplace) is done: - process: function (data) { - var that = this, - options = $.extend({}, this.options, data); - if (options.process && options.process.length && - this._isXHRUpload(options)) { - $.each(data.files, function (index, file) { - that._processingQueue = that._processingQueue.pipe( - function () { - var dfd = $.Deferred(); - that._processFile(data.files, index, options) - .always(function () { - dfd.resolveWith(that); - }); - return dfd.promise(); - } - ); - }); - } - return this._processingQueue; - }, - - _create: function () { - this._super(); - this._processing = 0; - this._processingQueue = $.Deferred().resolveWith(this) - .promise(); - } - - }); - -})); diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-image.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-image.js new file mode 100644 index 0000000..9a46565 --- /dev/null +++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-image.js @@ -0,0 +1,309 @@ +/* + * jQuery File Upload Image Preview & Resize Plugin 1.7.1 + * https://github.com/blueimp/jQuery-File-Upload + * + * Copyright 2013, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +/* jshint nomen:false */ +/* global define, window */ + +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // Register as an anonymous AMD module: + define([ + 'jquery', + 'load-image', + 'load-image-meta', + 'load-image-exif', + 'load-image-ios', + 'canvas-to-blob', + './jquery.fileupload-process' + ], factory); + } else { + // Browser globals: + factory( + window.jQuery, + window.loadImage + ); + } +}(function ($, loadImage) { + 'use strict'; + + // Prepend to the default processQueue: + $.blueimp.fileupload.prototype.options.processQueue.unshift( + { + action: 'loadImageMetaData', + disableImageHead: '@', + disableExif: '@', + disableExifThumbnail: '@', + disableExifSub: '@', + disableExifGps: '@', + disabled: '@disableImageMetaDataLoad' + }, + { + action: 'loadImage', + // Use the action as prefix for the "@" options: + prefix: true, + fileTypes: '@', + maxFileSize: '@', + noRevoke: '@', + disabled: '@disableImageLoad' + }, + { + action: 'resizeImage', + // Use "image" as prefix for the "@" options: + prefix: 'image', + maxWidth: '@', + maxHeight: '@', + minWidth: '@', + minHeight: '@', + crop: '@', + orientation: '@', + forceResize: '@', + disabled: '@disableImageResize' + }, + { + action: 'saveImage', + quality: '@imageQuality', + type: '@imageType', + disabled: '@disableImageResize' + }, + { + action: 'saveImageMetaData', + disabled: '@disableImageMetaDataSave' + }, + { + action: 'resizeImage', + // Use "preview" as prefix for the "@" options: + prefix: 'preview', + maxWidth: '@', + maxHeight: '@', + minWidth: '@', + minHeight: '@', + crop: '@', + orientation: '@', + thumbnail: '@', + canvas: '@', + disabled: '@disableImagePreview' + }, + { + action: 'setImage', + name: '@imagePreviewName', + disabled: '@disableImagePreview' + }, + { + action: 'deleteImageReferences', + disabled: '@disableImageReferencesDeletion' + } + ); + + // The File Upload Resize plugin extends the fileupload widget + // with image resize functionality: + $.widget('blueimp.fileupload', $.blueimp.fileupload, { + + options: { + // The regular expression for the types of images to load: + // matched against the file type: + loadImageFileTypes: /^image\/(gif|jpeg|png|svg\+xml)$/, + // The maximum file size of images to load: + loadImageMaxFileSize: 10000000, // 10MB + // The maximum width of resized images: + imageMaxWidth: 1920, + // The maximum height of resized images: + imageMaxHeight: 1080, + // Defines the image orientation (1-8) or takes the orientation + // value from Exif data if set to true: + imageOrientation: false, + // Define if resized images should be cropped or only scaled: + imageCrop: false, + // Disable the resize image functionality by default: + disableImageResize: true, + // The maximum width of the preview images: + previewMaxWidth: 80, + // The maximum height of the preview images: + previewMaxHeight: 80, + // Defines the preview orientation (1-8) or takes the orientation + // value from Exif data if set to true: + previewOrientation: true, + // Create the preview using the Exif data thumbnail: + previewThumbnail: true, + // Define if preview images should be cropped or only scaled: + previewCrop: false, + // Define if preview images should be resized as canvas elements: + previewCanvas: true + }, + + processActions: { + + // Loads the image given via data.files and data.index + // as img element, if the browser supports the File API. + // Accepts the options fileTypes (regular expression) + // and maxFileSize (integer) to limit the files to load: + loadImage: function (data, options) { + if (options.disabled) { + return data; + } + var that = this, + file = data.files[data.index], + dfd = $.Deferred(); + if (($.type(options.maxFileSize) === 'number' && + file.size > options.maxFileSize) || + (options.fileTypes && + !options.fileTypes.test(file.type)) || + !loadImage( + file, + function (img) { + if (img.src) { + data.img = img; + } + dfd.resolveWith(that, [data]); + }, + options + )) { + return data; + } + return dfd.promise(); + }, + + // Resizes the image given as data.canvas or data.img + // and updates data.canvas or data.img with the resized image. + // Also stores the resized image as preview property. + // Accepts the options maxWidth, maxHeight, minWidth, + // minHeight, canvas and crop: + resizeImage: function (data, options) { + if (options.disabled || !(data.canvas || data.img)) { + return data; + } + options = $.extend({canvas: true}, options); + var that = this, + dfd = $.Deferred(), + img = (options.canvas && data.canvas) || data.img, + resolve = function (newImg) { + if (newImg && (newImg.width !== img.width || + newImg.height !== img.height || + options.forceResize)) { + data[newImg.getContext ? 'canvas' : 'img'] = newImg; + } + data.preview = newImg; + dfd.resolveWith(that, [data]); + }, + thumbnail; + if (data.exif) { + if (options.orientation === true) { + options.orientation = data.exif.get('Orientation'); + } + if (options.thumbnail) { + thumbnail = data.exif.get('Thumbnail'); + if (thumbnail) { + loadImage(thumbnail, resolve, options); + return dfd.promise(); + } + } + } + if (img) { + resolve(loadImage.scale(img, options)); + return dfd.promise(); + } + return data; + }, + + // Saves the processed image given as data.canvas + // inplace at data.index of data.files: + saveImage: function (data, options) { + if (!data.canvas || options.disabled) { + return data; + } + var that = this, + file = data.files[data.index], + dfd = $.Deferred(); + if (data.canvas.toBlob) { + data.canvas.toBlob( + function (blob) { + if (!blob.name) { + if (file.type === blob.type) { + blob.name = file.name; + } else if (file.name) { + blob.name = file.name.replace( + /\..+$/, + '.' + blob.type.substr(6) + ); + } + } + // Don't restore invalid meta data: + if (file.type !== blob.type) { + delete data.imageHead; + } + // Store the created blob at the position + // of the original file in the files list: + data.files[data.index] = blob; + dfd.resolveWith(that, [data]); + }, + options.type || file.type, + options.quality + ); + } else { + return data; + } + return dfd.promise(); + }, + + loadImageMetaData: function (data, options) { + if (options.disabled) { + return data; + } + var that = this, + dfd = $.Deferred(); + loadImage.parseMetaData(data.files[data.index], function (result) { + $.extend(data, result); + dfd.resolveWith(that, [data]); + }, options); + return dfd.promise(); + }, + + saveImageMetaData: function (data, options) { + if (!(data.imageHead && data.canvas && + data.canvas.toBlob && !options.disabled)) { + return data; + } + var file = data.files[data.index], + blob = new Blob([ + data.imageHead, + // Resized images always have a head size of 20 bytes, + // including the JPEG marker and a minimal JFIF header: + this._blobSlice.call(file, 20) + ], {type: file.type}); + blob.name = file.name; + data.files[data.index] = blob; + return data; + }, + + // Sets the resized version of the image as a property of the + // file object, must be called after "saveImage": + setImage: function (data, options) { + if (data.preview && !options.disabled) { + data.files[data.index][options.name || 'preview'] = data.preview; + } + return data; + }, + + deleteImageReferences: function (data, options) { + if (!options.disabled) { + delete data.img; + delete data.canvas; + delete data.preview; + delete data.imageHead; + } + return data; + } + + } + + }); + +})); diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js old mode 100755 new mode 100644 index 2f9eeed..8a6b929 --- a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js +++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js @@ -1,5 +1,5 @@ /* - * jQuery File Upload Processing Plugin 1.1 + * jQuery File Upload Processing Plugin 1.3.0 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2012, Sebastian Tschan @@ -9,8 +9,8 @@ * http://www.opensource.org/licenses/MIT */ -/*jslint nomen: true, unparam: true */ -/*global define, window */ +/* jshint nomen:false */ +/* global define, window */ (function (factory) { 'use strict'; @@ -64,13 +64,17 @@ */ }, - _processFile: function (data) { + _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, @@ -98,14 +102,20 @@ _transformProcessQueue: function (options) { var processQueue = []; $.each(options.processQueue, function () { - var settings = {}; + 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)]; + settings[key] = options[ + value.slice(1) || (prefix ? prefix + + key.charAt(0).toUpperCase() + key.slice(1) : key) + ]; } else { settings[key] = value; } + }); processQueue.push(settings); }); @@ -127,10 +137,14 @@ if (this._processing === 0) { this._trigger('processstart'); } - $.each(data.files, function (index, file) { + $.each(data.files, function (index) { var opts = index ? $.extend({}, options) : options, func = function () { - return that._processFile(opts); + if (data.errorThrown) { + return $.Deferred() + .rejectWith(that, [data]).promise(); + } + return that._processFile(opts, data); }; opts.index = index; that._processing += 1; diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js deleted file mode 100755 index ae5c5be..0000000 --- a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js +++ /dev/null @@ -1,212 +0,0 @@ -/* - * jQuery File Upload Image Resize Plugin 1.1.2 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/*jslint nomen: true, unparam: true, regexp: true */ -/*global define, window */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - 'load-image', - 'canvas-to-blob', - './jquery.fileupload-process' - ], factory); - } else { - // Browser globals: - factory( - window.jQuery, - window.loadImage - ); - } -}(function ($, loadImage) { - 'use strict'; - - // Prepend to the default processQueue: - $.blueimp.fileupload.prototype.options.processQueue.unshift( - { - action: 'loadImage', - fileTypes: '@loadImageFileTypes', - maxFileSize: '@loadImageMaxFileSize', - noRevoke: '@loadImageNoRevoke', - disabled: '@disableImageLoad' - }, - { - action: 'resizeImage', - maxWidth: '@imageMaxWidth', - maxHeight: '@imageMaxHeight', - minWidth: '@imageMinWidth', - minHeight: '@imageMinHeight', - crop: '@imageCrop', - disabled: '@disableImageResize' - }, - { - action: 'saveImage', - disabled: '@disableImageResize' - }, - { - action: 'resizeImage', - maxWidth: '@previewMaxWidth', - maxHeight: '@previewMaxHeight', - minWidth: '@previewMinWidth', - minHeight: '@previewMinHeight', - crop: '@previewCrop', - canvas: '@previewAsCanvas', - disabled: '@disableImagePreview' - }, - { - action: 'setImage', - // The name of the property the resized image - // is saved as on the associated file object: - name: 'preview', - disabled: '@disableImagePreview' - } - ); - - // The File Upload Resize plugin extends the fileupload widget - // with image resize functionality: - $.widget('blueimp.fileupload', $.blueimp.fileupload, { - - options: { - // The regular expression for the types of images to load: - // matched against the file type: - loadImageFileTypes: /^image\/(gif|jpeg|png)$/, - // The maximum file size of images to load: - loadImageMaxFileSize: 5000000, // 5MB - // The maximum width of resized images: - imageMaxWidth: 1920, - // The maximum height of resized images: - imageMaxHeight: 1080, - // Define if resized images should be cropped or only scaled: - imageCrop: false, - // Disable the resize image functionality by default: - disableImageResize: true, - // The maximum width of the preview images: - previewMaxWidth: 80, - // The maximum height of the preview images: - previewMaxHeight: 80, - // Define if preview images should be cropped or only scaled: - previewCrop: false, - // Define if preview images should be resized as canvas elements: - previewAsCanvas: true - }, - - processActions: { - - // Loads the image given via data.files and data.index - // as img element if the browser supports canvas. - // Accepts the options fileTypes (regular expression) - // and maxFileSize (integer) to limit the files to load: - loadImage: function (data, options) { - if (options.disabled) { - return data; - } - var that = this, - file = data.files[data.index], - dfd = $.Deferred(); - if (($.type(options.maxFileSize) === 'number' && - file.size > options.maxFileSize) || - (options.fileTypes && - !options.fileTypes.test(file.type)) || - !loadImage( - file, - function (img) { - if (!img.src) { - return dfd.rejectWith(that, [data]); - } - data.img = img; - dfd.resolveWith(that, [data]); - }, - options - )) { - dfd.rejectWith(that, [data]); - } - return dfd.promise(); - }, - - // Resizes the image given as data.canvas or data.img - // and updates data.canvas or data.img with the resized image. - // Accepts the options maxWidth, maxHeight, minWidth, - // minHeight, canvas and crop: - resizeImage: function (data, options) { - options = $.extend({canvas: true}, options); - var img = (options.canvas && data.canvas) || data.img, - canvas; - if (img && !options.disabled) { - canvas = loadImage.scale(img, options); - if (canvas && (canvas.width !== img.width || - canvas.height !== img.height)) { - data[canvas.getContext ? 'canvas' : 'img'] = canvas; - } - } - return data; - }, - - // Saves the processed image given as data.canvas - // inplace at data.index of data.files: - saveImage: function (data, options) { - if (!data.canvas || options.disabled) { - return data; - } - var that = this, - file = data.files[data.index], - name = file.name, - dfd = $.Deferred(), - callback = function (blob) { - if (!blob.name) { - if (file.type === blob.type) { - blob.name = file.name; - } else if (file.name) { - blob.name = file.name.replace( - /\..+$/, - '.' + blob.type.substr(6) - ); - } - } - // Store the created blob at the position - // of the original file in the files list: - data.files[data.index] = blob; - dfd.resolveWith(that, [data]); - }; - // Use canvas.mozGetAsFile directly, to retain the filename, as - // Gecko doesn't support the filename option for FormData.append: - if (data.canvas.mozGetAsFile) { - callback(data.canvas.mozGetAsFile( - (/^image\/(jpeg|png)$/.test(file.type) && name) || - ((name && name.replace(/\..+$/, '')) || - 'blob') + '.png', - file.type - )); - } else if (data.canvas.toBlob) { - data.canvas.toBlob(callback, file.type); - } else { - return data; - } - return dfd.promise(); - }, - - // Sets the resized version of the image as a property of the - // file object, must be called after "saveImage": - setImage: function (data, options) { - var img = data.canvas || data.img; - if (img && !options.disabled) { - data.files[data.index][options.name] = img; - } - return data; - } - - } - - }); - -})); diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js old mode 100755 new mode 100644 index 5d22346..248e9f6 --- a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js +++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js @@ -1,5 +1,5 @@ /* - * jQuery File Upload User Interface Plugin 8.2.1 + * jQuery File Upload User Interface Plugin 9.5.2 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2010, Sebastian Tschan @@ -9,8 +9,8 @@ * http://www.opensource.org/licenses/MIT */ -/*jslint nomen: true, unparam: true, regexp: true */ -/*global define, window, URL, webkitURL, FileReader */ +/* jshint nomen:false */ +/* global define, window blada*/ (function (factory) { 'use strict'; @@ -19,7 +19,7 @@ define([ 'jquery', 'tmpl', - './jquery.fileupload-resize', + './jquery.fileupload-image', './jquery.fileupload-validate' ], factory); } else { @@ -29,7 +29,7 @@ window.tmpl ); } -}(function ($, tmpl, loadImage) { +}(function ($, tmpl) { 'use strict'; $.blueimp.fileupload.prototype._specialOptions.push( @@ -64,7 +64,8 @@ // Function returning the current number of files, // used by the maxNumberOfFiles validation: getNumberOfFiles: function () { - return this.filesContainer.children().length; + return this.filesContainer.children() + .not('.processing').length; }, // Callback to retrieve the list of files from the server response: @@ -79,33 +80,53 @@ // 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, - files = data.files; + 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 = that._renderUpload(files).data('data', data); + data.context.each(function (index) { + $(this).find('.size').text( + that._formatFileSize(data.files[index].size) + ); + }).removeClass('processing'); that._renderPreviews(data); - options.filesContainer[ - options.prependFiles ? 'prepend' : 'append' - ](data.context); - that._forceReflow(data.context); - that._transition(data.context).done( - function () { - if ((that._trigger('added', e, data) !== false) && - (options.autoUpload || data.autoUpload) && - data.autoUpload !== false && !data.files.error) { - data.submit(); + }).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 && @@ -118,7 +139,7 @@ !$.support.transition && 'progress-animated' ) .attr('aria-valuenow', 100) - .find('.bar').css( + .children().first().css( 'width', '100%' ); @@ -127,6 +148,9 @@ }, // 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 || @@ -137,8 +161,8 @@ if (data.context) { data.context.each(function (index) { var file = files[index] || - {error: 'Empty file upload result'}, - deferred = that._addFinishedDeferreds(); + {error: 'Empty file upload result'}; + deferred = that._addFinishedDeferreds(); that._transition($(this)).done( function () { var node = $(this); @@ -157,8 +181,9 @@ ); }); } else { - template = that._renderDownload(files) - .appendTo(that.options.filesContainer); + template = that._renderDownload(files)[ + that.options.prependFiles ? 'prependTo' : 'appendTo' + ](that.options.filesContainer); that._forceReflow(template); deferred = that._addFinishedDeferreds(); that._transition(template).done( @@ -173,6 +198,9 @@ }, // 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, @@ -213,8 +241,9 @@ } }); } else if (data.errorThrown !== 'abort') { - data.context = that._renderUpload(data.files) - .appendTo(that.options.filesContainer) + data.context = that._renderUpload(data.files)[ + that.options.prependFiles ? 'prependTo' : 'appendTo' + ](that.options.filesContainer) .data('data', data); that._forceReflow(data.context); deferred = that._addFinishedDeferreds(); @@ -234,18 +263,26 @@ }, // 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) { - var progress = Math.floor(data.loaded / data.total * 100); - data.context.find('.progress') - .attr('aria-valuenow', progress) - .find('.bar').css( - 'width', - progress + '%' - ); + 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'), @@ -260,13 +297,16 @@ globalProgressNode .find('.progress') .attr('aria-valuenow', progress) - .find('.bar').css( + .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(); @@ -278,6 +318,9 @@ }, // 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(); @@ -289,31 +332,46 @@ function () { $(this).find('.progress') .attr('aria-valuenow', '0') - .find('.bar').css('width', '0%'); + .children().first().css('width', '0%'); $(this).find('.progress-extended').html(' '); deferred.resolve(); } ); }, - processstart: function () { + processstart: function (e) { + if (e.isDefaultPrevented()) { + return false; + } $(this).addClass('fileupload-processing'); }, - processstop: function () { + 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'); - if (data.url) { - $.ajax(data).done(function () { + $(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(); } } }, @@ -446,20 +504,23 @@ var button = $(e.currentTarget), template = button.closest('.template-upload'), data = template.data('data'); - if (data && data.submit && !data.jqXHR && data.submit()) { - button.prop('disabled', true); + button.prop('disabled', true); + if (data && data.submit) { + data.submit(); } }, _cancelHandler: function (e) { e.preventDefault(); - var template = $(e.currentTarget).closest('.template-upload'), + var template = $(e.currentTarget) + .closest('.template-upload,.template-download'), data = template.data('data') || {}; - if (!data.jqXHR) { + data.context = data.context || template; + if (data.abort) { + data.abort(); + } else { data.errorThrown = 'abort'; this._trigger('fail', e, data); - } else { - data.jqXHR.abort(); } }, @@ -606,6 +667,9 @@ _create: function () { this._super(); this._resetFinishedDeferreds(); + if (!$.support.fileInput) { + this._disableFileInputButton(); + } }, enable: function () { diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js old mode 100755 new mode 100644 index 2599da8..f93a18f --- a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js +++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js @@ -1,5 +1,5 @@ /* - * jQuery File Upload Validation Plugin 1.0.2 + * jQuery File Upload Validation Plugin 1.1.2 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2013, Sebastian Tschan @@ -9,8 +9,7 @@ * http://www.opensource.org/licenses/MIT */ -/*jslint nomen: true, unparam: true, regexp: true */ -/*global define, window */ +/* global define, window */ (function (factory) { 'use strict'; @@ -37,10 +36,10 @@ // even if the previous action was rejected: always: true, // Options taken from the global options map: - acceptFileTypes: '@acceptFileTypes', - maxFileSize: '@maxFileSize', - minFileSize: '@minFileSize', - maxNumberOfFiles: '@maxNumberOfFiles', + acceptFileTypes: '@', + maxFileSize: '@', + minFileSize: '@', + maxNumberOfFiles: '@', disabled: '@disableValidation' } ); @@ -84,18 +83,22 @@ var dfd = $.Deferred(), settings = this.options, file = data.files[data.index], - numberOfFiles = settings.getNumberOfFiles(); - if (numberOfFiles && $.type(options.maxNumberOfFiles) === 'number' && - numberOfFiles + data.files.length > options.maxNumberOfFiles) { + 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 (options.maxFileSize && file.size > options.maxFileSize) { + } else if (fileSize > options.maxFileSize) { file.error = settings.i18n('maxFileSize'); - } else if ($.type(file.size) === 'number' && - file.size < options.minFileSize) { + } else if ($.type(fileSize) === 'number' && + fileSize < options.minFileSize) { file.error = settings.i18n('minFileSize'); } else { delete file.error; diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js old mode 100755 new mode 100644 index 03678f3..0803592 --- a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js +++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js @@ -1,5 +1,5 @@ /* - * jQuery File Upload Plugin 5.31.1 + * jQuery File Upload Plugin 5.40.1 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2010, Sebastian Tschan @@ -9,8 +9,8 @@ * http://www.opensource.org/licenses/MIT */ -/*jslint nomen: true, unparam: true, regexp: true */ -/*global define, window, document, File, Blob, FormData, location */ +/* jshint nomen:false */ +/* global define, window, document, location, Blob, FormData */ (function (factory) { 'use strict'; @@ -27,12 +27,30 @@ }(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: + $('').prop('disabled')); + // The FileReader API is not actually used, but works as feature detection, - // as e.g. Safari supports XHR file uploads via the FormData API, - // but not non-multipart XHR file uploads: - $.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader); + // 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); + // 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 @@ -72,6 +90,14 @@ // 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, @@ -144,17 +170,23 @@ // 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 uplaods, else + // 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 to override plugin options as well as define ajax settings. + // 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 () { @@ -233,6 +265,11 @@ '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; @@ -256,7 +293,7 @@ _getFormData: function (options) { var formData; - if (typeof options.formData === 'function') { + if ($.type(options.formData) === 'function') { return options.formData(options.form); } if ($.isArray(options.formData)) { @@ -336,10 +373,18 @@ // 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', e, data); + 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', e, this._progress); + this._trigger( + 'progressall', + $.Event('progressall', {delegatedEvent: e}), + this._progress + ); } }, @@ -374,15 +419,18 @@ file = options.files[0], // Ignore non-multipart setting if not supported: multipart = options.multipart || !$.support.xhrFileUpload, - paramName = options.paramName[0]; - options.headers = options.headers || {}; + 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) { + if (!multipart || options.blob || !this._isInstanceOf('File', file)) { options.headers['Content-Disposition'] = 'attachment; filename="' + encodeURI(file.name) + '"'; - options.contentType = file.type; + } + if (!multipart) { + options.contentType = file.type || 'application/octet-stream'; options.data = options.blob || file; } else if ($.support.xhrFormDataFileUpload) { if (options.postMessage) { @@ -399,7 +447,8 @@ } else { $.each(options.files, function (index, file) { formData.push({ - name: options.paramName[index] || paramName, + name: ($.type(options.paramName) === 'array' && + options.paramName[index]) || paramName, value: file }); }); @@ -414,8 +463,6 @@ }); } if (options.blob) { - options.headers['Content-Disposition'] = 'attachment; filename="' + - encodeURI(file.name) + '"'; formData.append(paramName, options.blob, file.name); } else { $.each(options.files, function (index, file) { @@ -424,9 +471,10 @@ if (that._isInstanceOf('File', file) || that._isInstanceOf('Blob', file)) { formData.append( - options.paramName[index] || paramName, + ($.type(options.paramName) === 'array' && + options.paramName[index]) || paramName, file, - file.name + file.uploadName || file.name ); } }); @@ -439,13 +487,13 @@ }, _initIframeSettings: function (options) { + var targetHost = $('').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 && $('').prop('href', options.url) - .prop('host') !== location.host) { + if (options.redirect && targetHost && targetHost !== location.host) { options.formData.push({ name: options.redirectParamName || 'redirect', value: options.redirect @@ -510,8 +558,10 @@ options.url = options.form.prop('action') || location.href; } // The HTTP request method must be "POST" or "PUT": - options.type = (options.type || options.form.prop('method') || '') - .toUpperCase(); + 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'; @@ -570,22 +620,32 @@ // Adds convenience methods to the data callback argument: _addConvenienceMethods: function (e, data) { var that = this, - getPromise = function (data) { - return $.Deferred().resolveWith(that, [data]).promise(); + 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)) - .pipe(resolveFunc, rejectFunc); + (this._processQueue || getPromise([this])).pipe( + function () { + if (data.errorThrown) { + return $.Deferred() + .rejectWith(that, [data]).promise(); + } + return getPromise(arguments); + } + ).pipe(resolveFunc, rejectFunc); } - return this._processQueue || getPromise(this); + return this._processQueue || getPromise([this]); }; data.submit = function () { if (this.state() !== 'pending') { data.jqXHR = this.jqXHR = - (that._trigger('submit', e, this) !== false) && - that._onSend(e, this); + (that._trigger( + 'submit', + $.Event('submit', {delegatedEvent: e}), + this + ) !== false) && that._onSend(e, this); } return this.jqXHR || that._getXHRPromise(); }; @@ -593,7 +653,9 @@ if (this.jqXHR) { return this.jqXHR.abort(); } - return that._getXHRPromise(); + this.errorThrown = 'abort'; + that._trigger('fail', null, this); + return that._getXHRPromise(false); }; data.state = function () { if (this.jqXHR) { @@ -603,6 +665,10 @@ return that._getDeferredState(this._processQueue); } }; + data.processing = function () { + return !this.jqXHR && this._processQueue && that + ._getDeferredState(this._processQueue) === 'pending'; + }; data.progress = function () { return this._progress; }; @@ -627,12 +693,13 @@ // 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 = options.uploadedBytes || 0, + ub = options.uploadedBytes, mcs = options.maxChunkSize || fs, - slice = file.slice || file.webkitSlice || file.mozSlice, + slice = this._blobSlice, dfd = $.Deferred(), promise = dfd.promise(), jqXHR, @@ -804,7 +871,11 @@ // Set timer for bitrate progress calculation: options._bitrateTimer = new that._BitrateTimer(); jqXHR = jqXHR || ( - ((aborted || that._trigger('send', e, options) === false) && + ((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) { @@ -850,7 +921,8 @@ this._slots.push(slot); pipe = slot.pipe(send); } else { - pipe = (this._sequence = this._sequence.pipe(send, send)); + this._sequence = this._sequence.pipe(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, @@ -874,39 +946,70 @@ 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; - if (!(options.singleFileUploads || limit) || + i, + j = 0; + if (limitSize && (!filesLength || files[0].size === undefined)) { + limitSize = undefined; + } + if (!(options.singleFileUploads || limit || limitSize) || !this._isXHRUpload(options)) { - fileSet = [data.files]; + fileSet = [files]; paramNameSet = [paramName]; - } else if (!options.singleFileUploads && limit) { + } else if (!(options.singleFileUploads || limitSize) && limit) { fileSet = []; paramNameSet = []; - for (i = 0; i < data.files.length; i += limit) { - fileSet.push(data.files.slice(i, i + limit)); + 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 = data.files; - $.each(fileSet || data.files, function (index, element) { + 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', e, newData); + result = that._trigger( + 'add', + $.Event('add', {delegatedEvent: e}), + newData + ); return result; }); return result; @@ -1075,7 +1178,11 @@ if (that.options.replaceFileInput) { that._replaceFileInput(data.fileInput); } - if (that._trigger('change', e, data) !== false) { + if (that._trigger( + 'change', + $.Event('change', {delegatedEvent: e}), + data + ) !== false) { that._onAdd(e, data); } }); @@ -1092,23 +1199,30 @@ data.files.push(file); } }); - if (this._trigger('paste', e, data) === false || - this._onAdd(e, data) === false) { - return false; + 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 = e.originalEvent && - e.originalEvent.dataTransfer, + 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', e, data) !== false) { + if (that._trigger( + 'drop', + $.Event('drop', {delegatedEvent: e}), + data + ) !== false) { that._onAdd(e, data); } }); @@ -1116,16 +1230,15 @@ }, _onDragOver: function (e) { - var dataTransfer = e.dataTransfer = e.originalEvent && - e.originalEvent.dataTransfer; - if (dataTransfer) { - if (this._trigger('dragover', e) === false) { - return false; - } - if ($.inArray('Files', dataTransfer.types) !== -1) { - dataTransfer.dropEffect = 'copy'; - e.preventDefault(); - } + e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer; + var dataTransfer = e.dataTransfer; + if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 && + this._trigger( + 'dragover', + $.Event('dragover', {delegatedEvent: e}) + ) !== false) { + e.preventDefault(); + dataTransfer.dropEffect = 'copy'; } }, @@ -1139,9 +1252,11 @@ paste: this._onPaste }); } - this._on(this.options.fileInput, { - change: this._onChange - }); + if ($.support.fileInput) { + this._on(this.options.fileInput, { + change: this._onChange + }); + } }, _destroyEventHandlers: function () { @@ -1192,15 +1307,21 @@ _initDataAttributes: function () { var that = this, - options = this.options; + options = this.options, + clone = $(this.element[0].cloneNode(false)); // Initialize options set via HTML5 data-attributes: $.each( - $(this.element[0].cloneNode(false)).data(), + clone.data(), function (key, value) { - if (that._isRegExpOption(key, value)) { - value = that._getRegExp(value); + var dataAttributeName = 'data-' + + // Convert camelCase to hyphen-ated key: + key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); + if (clone.attr(dataAttributeName)) { + if (that._isRegExpOption(key, value)) { + value = that._getRegExp(value); + } + options[key] = value; } - options[key] = value; } ); }, @@ -1275,6 +1396,10 @@ if (aborted) { return; } + if (!files.length) { + dfd.reject(); + return; + } data.files = files; jqXHR = that._onSend(null, data).then( function (result, textStatus, jqXHR) { diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js b/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js old mode 100755 new mode 100644 index e04e7a0..8d64b59 --- a/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js +++ b/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js @@ -1,5 +1,5 @@ /* - * jQuery Iframe Transport Plugin 1.6.2 + * jQuery Iframe Transport Plugin 1.8.2 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2011, Sebastian Tschan @@ -9,8 +9,7 @@ * http://www.opensource.org/licenses/MIT */ -/*jslint unparam: true, nomen: true */ -/*global define, window, document */ +/* global define, window, document */ (function (factory) { 'use strict'; @@ -27,7 +26,7 @@ // Helper variable to create unique names for the transport iframes: var counter = 0; - // The iframe transport accepts three additional options: + // The iframe transport accepts four additional options: // options.fileInput: a jQuery collection of file input fields // options.paramName: the parameter name for the file form data, // overrides the name property of the file input field(s), @@ -35,9 +34,16 @@ // options.formData: an array of objects with name and value properties, // equivalent to the return data of .serializeArray(), e.g.: // [{name: 'a', value: 1}, {name: 'b', value: 2}] + // options.initialIframeSrc: the URL of the initial iframe src, + // by default set to "javascript:false;" $.ajaxTransport('iframe', function (options) { if (options.async) { - var form, + // javascript:false as initial iframe src + // prevents warning popups on HTTPS in IE6: + /*jshint scripturl: true */ + var initialIframeSrc = options.initialIframeSrc || 'javascript:false;', + /*jshint scripturl: false */ + form, iframe, addParamChar; return { @@ -56,15 +62,13 @@ options.url = options.url + addParamChar + '_method=PATCH'; options.type = 'POST'; } - // javascript:false as initial iframe src - // prevents warning popups on HTTPS in IE6. // IE versions below IE8 cannot set the name property of // elements that have already been added to the DOM, // so we set the name along with the iframe HTML markup: counter += 1; iframe = $( - '' + '' ).bind('load', function () { var fileInputClones, paramNames = $.isArray(options.paramName) ? @@ -95,7 +99,7 @@ ); // Fix for IE endless progress bar activity bug // (happens on form submits to iframe targets): - $('') + $('') .appendTo(form); window.setTimeout(function () { // Removing the form in a setTimeout call @@ -138,6 +142,8 @@ .prop('enctype', 'multipart/form-data') // enctype must be set as encoding for IE: .prop('encoding', 'multipart/form-data'); + // Remove the HTML5 form attribute from the input(s): + options.fileInput.removeAttr('form'); } form.submit(); // Insert the file input fields at their original location @@ -145,7 +151,10 @@ if (fileInputClones && fileInputClones.length) { options.fileInput.each(function (index, input) { var clone = $(fileInputClones[index]); - $(input).prop('name', clone.prop('name')); + // Restore the original name and form properties: + $(input) + .prop('name', clone.prop('name')) + .attr('form', clone.attr('form')); clone.replaceWith(input); }); } @@ -159,7 +168,7 @@ // concat is used to avoid the "Script URL" JSLint error: iframe .unbind('load') - .prop('src', 'javascript'.concat(':false;')); + .prop('src', initialIframeSrc); } if (form) { form.remove(); @@ -170,7 +179,15 @@ }); // The iframe transport returns the iframe content document as response. - // The following adds converters from iframe to text, json, html, and script: + // The following adds converters from iframe to text, json, html, xml + // and script. + // Please note that the Content-Type for JSON responses has to be text/plain + // or text/html, if the browser doesn't include application/json in the + // Accept header, else IE will show a download dialog. + // The Content-Type for XML responses on the other hand has to be always + // application/xml or text/xml, so IE properly parses the XML response. + // See also + // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation $.ajaxSetup({ converters: { 'iframe text': function (iframe) { @@ -182,6 +199,12 @@ 'iframe html': function (iframe) { return iframe && $(iframe[0].body).html(); }, + 'iframe xml': function (iframe) { + var xmlDoc = iframe && iframe[0]; + return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc : + $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) || + $(xmlDoc.body).html()); + }, 'iframe script': function (iframe) { return iframe && $.globalEval($(iframe[0].body).text()); } diff --git a/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js b/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js index fd2948f..c430419 100644 --- a/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js +++ b/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js @@ -1,8 +1,8 @@ -/* - * jQuery UI Widget 1.10.1+amd +/*! + * jQuery UI Widget 1.10.4+amd * https://github.com/blueimp/jQuery-File-Upload * - * Copyright 2013 jQuery Foundation and other contributors + * Copyright 2014 jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license * @@ -115,7 +115,7 @@ $.widget = function( name, base, prototype ) { // TODO: remove support for widgetEventPrefix // always use the name + a colon as the prefix, e.g., draggable:start // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name + widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name }, proxiedPrototype, { constructor: constructor, namespace: namespace, @@ -324,12 +324,12 @@ $.Widget.prototype = { curOption = curOption[ parts[ i ] ]; } key = parts.pop(); - if ( value === undefined ) { + if ( arguments.length === 1 ) { return curOption[ key ] === undefined ? null : curOption[ key ]; } curOption[ key ] = value; } else { - if ( value === undefined ) { + if ( arguments.length === 1 ) { return this.options[ key ] === undefined ? null : this.options[ key ]; } options[ key ] = value; diff --git a/vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js b/vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js index 0155d38..09f3873 100644 --- a/vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js +++ b/vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js @@ -1,228 +1 @@ -/* - * JavaScript Load Image 1.3.1 - * https://github.com/blueimp/JavaScript-Load-Image - * - * Copyright 2011, Sebastian Tschan - * https://blueimp.net - * - * iOS image scaling fixes based on - * https://github.com/stomita/ios-imagefile-megapixel - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/*jslint nomen: true, bitwise: true */ -/*global window, document, URL, webkitURL, Blob, File, FileReader, define */ - -(function ($) { - 'use strict'; - - // Loads an image for a given File object. - // Invokes the callback with an img or optional canvas - // element (if supported by the browser) as parameter: - var loadImage = function (file, callback, options) { - var img = document.createElement('img'), - url, - oUrl; - img.onerror = callback; - img.onload = function () { - if (oUrl && !(options && options.noRevoke)) { - loadImage.revokeObjectURL(oUrl); - } - callback(loadImage.scale(img, options)); - }; - if ((window.Blob && file instanceof Blob) || - // Files are also Blob instances, but some browsers - // (Firefox 3.6) support the File API but not Blobs: - (window.File && file instanceof File)) { - url = oUrl = loadImage.createObjectURL(file); - // Store the file type for resize processing: - img._type = file.type; - } else { - url = file; - } - if (url) { - img.src = url; - return img; - } - return loadImage.readFile(file, function (e) { - var target = e.target; - if (target && target.result) { - img.src = target.result; - } else { - callback(e); - } - }); - }, - // The check for URL.revokeObjectURL fixes an issue with Opera 12, - // which provides URL.createObjectURL but doesn't properly implement it: - urlAPI = (window.createObjectURL && window) || - (window.URL && URL.revokeObjectURL && URL) || - (window.webkitURL && webkitURL); - - // Detects subsampling in JPEG images: - loadImage.detectSubsampling = function (img) { - var iw = img.width, - ih = img.height, - canvas, - ctx; - if (iw * ih > 1024 * 1024) { // only consider mexapixel images - canvas = document.createElement('canvas'); - canvas.width = canvas.height = 1; - ctx = canvas.getContext('2d'); - ctx.drawImage(img, -iw + 1, 0); - // subsampled image becomes half smaller in rendering size. - // check alpha channel value to confirm image is covering edge pixel or not. - // if alpha value is 0 image is not covering, hence subsampled. - return ctx.getImageData(0, 0, 1, 1).data[3] === 0; - } - return false; - }; - - // Detects vertical squash in JPEG images: - loadImage.detectVerticalSquash = function (img, ih) { - var canvas = document.createElement('canvas'), - ctx = canvas.getContext('2d'), - data, - sy, - ey, - py, - alpha; - canvas.width = 1; - canvas.height = ih; - ctx.drawImage(img, 0, 0); - data = ctx.getImageData(0, 0, 1, ih).data; - // search image edge pixel position in case it is squashed vertically: - sy = 0; - ey = ih; - py = ih; - while (py > sy) { - alpha = data[(py - 1) * 4 + 3]; - if (alpha === 0) { - ey = py; - } else { - sy = py; - } - py = (ey + sy) >> 1; - } - return (py / ih) || 1; - }; - - // Renders image to canvas while working around iOS image scaling bugs: - // https://github.com/blueimp/JavaScript-Load-Image/issues/13 - loadImage.renderImageToCanvas = function (img, canvas, width, height) { - var iw = img.width, - ih = img.height, - ctx = canvas.getContext('2d'), - vertSquashRatio, - d = 1024, // size of tiling canvas - tmpCanvas = document.createElement('canvas'), - tmpCtx, - dw, - dh, - dx, - dy, - sx, - sy; - ctx.save(); - if (loadImage.detectSubsampling(img)) { - iw /= 2; - ih /= 2; - } - vertSquashRatio = loadImage.detectVerticalSquash(img, ih); - tmpCanvas.width = tmpCanvas.height = d; - tmpCtx = tmpCanvas.getContext('2d'); - dw = Math.ceil(d * width / iw); - dh = Math.ceil(d * height / ih / vertSquashRatio); - dy = 0; - sy = 0; - while (sy < ih) { - dx = 0; - sx = 0; - while (sx < iw) { - tmpCtx.clearRect(0, 0, d, d); - tmpCtx.drawImage(img, -sx, -sy); - ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh); - sx += d; - dx += dw; - } - sy += d; - dy += dh; - } - ctx.restore(); - tmpCanvas = tmpCtx = null; - }; - - // Scales the given image (img or canvas HTML element) - // using the given options. - // Returns a canvas object if the browser supports canvas - // and the canvas option is true or a canvas object is passed - // as image, else the scaled image: - loadImage.scale = function (img, options) { - options = options || {}; - var canvas = document.createElement('canvas'), - width = img.width, - height = img.height, - scale = Math.max( - (options.minWidth || width) / width, - (options.minHeight || height) / height - ); - if (scale > 1) { - width = Math.ceil(width * scale); - height = Math.ceil(height * scale); - } - scale = Math.min( - (options.maxWidth || width) / width, - (options.maxHeight || height) / height - ); - if (scale < 1) { - width = Math.ceil(width * scale); - height = Math.ceil(height * scale); - } - if (img.getContext || (options.canvas && canvas.getContext)) { - canvas.width = width; - canvas.height = height; - if (img._type === 'image/jpeg') { - loadImage - .renderImageToCanvas(img, canvas, width, height); - } else { - canvas.getContext('2d') - .drawImage(img, 0, 0, width, height); - } - return canvas; - } - img.width = width; - img.height = height; - return img; - }; - - loadImage.createObjectURL = function (file) { - return urlAPI ? urlAPI.createObjectURL(file) : false; - }; - - loadImage.revokeObjectURL = function (url) { - return urlAPI ? urlAPI.revokeObjectURL(url) : false; - }; - - // Loads a given File object via FileReader interface, - // invokes the callback with the event object (load or error). - // The result can be read via event.target.result: - loadImage.readFile = function (file, callback) { - if (window.FileReader && FileReader.prototype.readAsDataURL) { - var fileReader = new FileReader(); - fileReader.onload = fileReader.onerror = callback; - fileReader.readAsDataURL(file); - return fileReader; - } - return false; - }; - - if (typeof define === 'function' && define.amd) { - define(function () { - return loadImage; - }); - } else { - $.loadImage = loadImage; - } -}(this)); +!function(a){"use strict";var b=function(a,c,d){var e,f,g=document.createElement("img");if(g.onerror=c,g.onload=function(){!f||d&&d.noRevoke||b.revokeObjectURL(f),c&&c(b.scale(g,d))},b.isInstanceOf("Blob",a)||b.isInstanceOf("File",a))e=f=b.createObjectURL(a),g._type=a.type;else{if("string"!=typeof a)return!1;e=a,d&&d.crossOrigin&&(g.crossOrigin=d.crossOrigin)}return e?(g.src=e,g):b.readFile(a,function(a){var b=a.target;b&&b.result?g.src=b.result:c&&c(a)})},c=window.createObjectURL&&window||window.URL&&URL.revokeObjectURL&&URL||window.webkitURL&&webkitURL;b.isInstanceOf=function(a,b){return Object.prototype.toString.call(b)==="[object "+a+"]"},b.transformCoordinates=function(){},b.getTransformedOptions=function(a){return a},b.renderImageToCanvas=function(a,b,c,d,e,f,g,h,i,j){return a.getContext("2d").drawImage(b,c,d,e,f,g,h,i,j),a},b.hasCanvasOption=function(a){return a.canvas||a.crop},b.scale=function(a,c){c=c||{};var d,e,f,g,h,i,j,k,l,m=document.createElement("canvas"),n=a.getContext||b.hasCanvasOption(c)&&m.getContext,o=a.naturalWidth||a.width,p=a.naturalHeight||a.height,q=o,r=p,s=function(){var a=Math.max((f||q)/q,(g||r)/r);a>1&&(q=Math.ceil(q*a),r=Math.ceil(r*a))},t=function(){var a=Math.min((d||q)/q,(e||r)/r);1>a&&(q=Math.ceil(q*a),r=Math.ceil(r*a))};return n&&(c=b.getTransformedOptions(c),j=c.left||0,k=c.top||0,c.sourceWidth?(h=c.sourceWidth,void 0!==c.right&&void 0===c.left&&(j=o-h-c.right)):h=o-j-(c.right||0),c.sourceHeight?(i=c.sourceHeight,void 0!==c.bottom&&void 0===c.top&&(k=p-i-c.bottom)):i=p-k-(c.bottom||0),q=h,r=i),d=c.maxWidth,e=c.maxHeight,f=c.minWidth,g=c.minHeight,n&&d&&e&&c.crop?(q=d,r=e,l=h/i-d/e,0>l?(i=e*h/d,void 0===c.top&&void 0===c.bottom&&(k=(p-i)/2)):l>0&&(h=d*i/e,void 0===c.left&&void 0===c.right&&(j=(o-h)/2))):((c.contain||c.cover)&&(f=d=d||f,g=e=e||g),c.cover?(t(),s()):(s(),t())),n?(m.width=q,m.height=r,b.transformCoordinates(m,c),b.renderImageToCanvas(m,a,j,k,h,i,0,0,q,r)):(a.width=q,a.height=r,a)},b.createObjectURL=function(a){return c?c.createObjectURL(a):!1},b.revokeObjectURL=function(a){return c?c.revokeObjectURL(a):!1},b.readFile=function(a,b,c){if(window.FileReader){var d=new FileReader;if(d.onload=d.onerror=b,c=c||"readAsDataURL",d[c])return d[c](a),d}return!1},"function"==typeof define&&define.amd?define(function(){return b}):a.loadImage=b}(this),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image"],a):a(window.loadImage)}(function(a){"use strict";if(window.navigator&&window.navigator.platform&&/iP(hone|od|ad)/.test(window.navigator.platform)){var b=a.renderImageToCanvas;a.detectSubsampling=function(a){var b,c;return a.width*a.height>1048576?(b=document.createElement("canvas"),b.width=b.height=1,c=b.getContext("2d"),c.drawImage(a,-a.width+1,0),0===c.getImageData(0,0,1,1).data[3]):!1},a.detectVerticalSquash=function(a,b){var c,d,e,f,g,h=a.naturalHeight||a.height,i=document.createElement("canvas"),j=i.getContext("2d");for(b&&(h/=2),i.width=1,i.height=h,j.drawImage(a,0,0),c=j.getImageData(0,0,1,h).data,d=0,e=h,f=h;f>d;)g=c[4*(f-1)+3],0===g?e=f:d=f,f=e+d>>1;return f/h||1},a.renderImageToCanvas=function(c,d,e,f,g,h,i,j,k,l){if("image/jpeg"===d._type){var m,n,o,p,q=c.getContext("2d"),r=document.createElement("canvas"),s=1024,t=r.getContext("2d");if(r.width=s,r.height=s,q.save(),m=a.detectSubsampling(d),m&&(e/=2,f/=2,g/=2,h/=2),n=a.detectVerticalSquash(d,m),m||1!==n){for(f*=n,k=Math.ceil(s*k/g),l=Math.ceil(s*l/h/n),j=0,p=0;h>p;){for(i=0,o=0;g>o;)t.clearRect(0,0,s,s),t.drawImage(d,e,f,g,h,-o,-p,g,h),q.drawImage(r,0,0,s,s,i,j,k,l),o+=s,i+=k;p+=s,j+=l}return q.restore(),c}}return b(c,d,e,f,g,h,i,j,k,l)}}}),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image"],a):a(window.loadImage)}(function(a){"use strict";var b=a.hasCanvasOption;a.hasCanvasOption=function(a){return b(a)||a.orientation},a.transformCoordinates=function(a,b){var c=a.getContext("2d"),d=a.width,e=a.height,f=b.orientation;if(f)switch(f>4&&(a.width=e,a.height=d),f){case 2:c.translate(d,0),c.scale(-1,1);break;case 3:c.translate(d,e),c.rotate(Math.PI);break;case 4:c.translate(0,e),c.scale(1,-1);break;case 5:c.rotate(.5*Math.PI),c.scale(1,-1);break;case 6:c.rotate(.5*Math.PI),c.translate(0,-e);break;case 7:c.rotate(.5*Math.PI),c.translate(d,-e),c.scale(-1,1);break;case 8:c.rotate(-.5*Math.PI),c.translate(-d,0)}},a.getTransformedOptions=function(a){if(!a.orientation||1===a.orientation)return a;var b,c={};for(b in a)a.hasOwnProperty(b)&&(c[b]=a[b]);switch(a.orientation){case 2:c.left=a.right,c.right=a.left;break;case 3:c.left=a.right,c.top=a.bottom,c.right=a.left,c.bottom=a.top;break;case 4:c.top=a.bottom,c.bottom=a.top;break;case 5:c.left=a.top,c.top=a.left,c.right=a.bottom,c.bottom=a.right;break;case 6:c.left=a.top,c.top=a.right,c.right=a.bottom,c.bottom=a.left;break;case 7:c.left=a.bottom,c.top=a.right,c.right=a.top,c.bottom=a.left;break;case 8:c.left=a.bottom,c.top=a.left,c.right=a.top,c.bottom=a.right}return a.orientation>4&&(c.maxWidth=a.maxHeight,c.maxHeight=a.maxWidth,c.minWidth=a.minHeight,c.minHeight=a.minWidth,c.sourceWidth=a.sourceHeight,c.sourceHeight=a.sourceWidth),c}}),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image"],a):a(window.loadImage)}(function(a){"use strict";var b=window.Blob&&(Blob.prototype.slice||Blob.prototype.webkitSlice||Blob.prototype.mozSlice);a.blobSlice=b&&function(){var a=this.slice||this.webkitSlice||this.mozSlice;return a.apply(this,arguments)},a.metaDataParsers={jpeg:{65505:[]}},a.parseMetaData=function(b,c,d){d=d||{};var e=this,f=d.maxMetaDataSize||262144,g={},h=!(window.DataView&&b&&b.size>=12&&"image/jpeg"===b.type&&a.blobSlice);(h||!a.readFile(a.blobSlice.call(b,0,f),function(b){if(b.target.error)return console.log(b.target.error),c(g),void 0;var f,h,i,j,k=b.target.result,l=new DataView(k),m=2,n=l.byteLength-4,o=m;if(65496===l.getUint16(0)){for(;n>m&&(f=l.getUint16(m),f>=65504&&65519>=f||65534===f);){if(h=l.getUint16(m+2)+2,m+h>l.byteLength){console.log("Invalid meta data: Invalid segment size.");break}if(i=a.metaDataParsers.jpeg[f])for(j=0;j6&&(g.imageHead=k.slice?k.slice(0,o):new Uint8Array(k).subarray(0,o))}else console.log("Invalid JPEG file: Missing JPEG marker.");c(g)},"readAsArrayBuffer"))&&c(g)}}),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image","load-image-meta"],a):a(window.loadImage)}(function(a){"use strict";a.ExifMap=function(){return this},a.ExifMap.prototype.map={Orientation:274},a.ExifMap.prototype.get=function(a){return this[a]||this[this.map[a]]},a.getExifThumbnail=function(a,b,c){var d,e,f;if(!c||b+c>a.byteLength)return console.log("Invalid Exif data: Invalid thumbnail data."),void 0;for(d=[],e=0;c>e;e+=1)f=a.getUint8(b+e),d.push((16>f?"0":"")+f.toString(16));return"data:image/jpeg,%"+d.join("%")},a.exifTagTypes={1:{getValue:function(a,b){return a.getUint8(b)},size:1},2:{getValue:function(a,b){return String.fromCharCode(a.getUint8(b))},size:1,ascii:!0},3:{getValue:function(a,b,c){return a.getUint16(b,c)},size:2},4:{getValue:function(a,b,c){return a.getUint32(b,c)},size:4},5:{getValue:function(a,b,c){return a.getUint32(b,c)/a.getUint32(b+4,c)},size:8},9:{getValue:function(a,b,c){return a.getInt32(b,c)},size:4},10:{getValue:function(a,b,c){return a.getInt32(b,c)/a.getInt32(b+4,c)},size:8}},a.exifTagTypes[7]=a.exifTagTypes[1],a.getExifValue=function(b,c,d,e,f,g){var h,i,j,k,l,m,n=a.exifTagTypes[e];if(!n)return console.log("Invalid Exif data: Invalid tag type."),void 0;if(h=n.size*f,i=h>4?c+b.getUint32(d+8,g):d+8,i+h>b.byteLength)return console.log("Invalid Exif data: Invalid data offset."),void 0;if(1===f)return n.getValue(b,i,g);for(j=[],k=0;f>k;k+=1)j[k]=n.getValue(b,i+k*n.size,g);if(n.ascii){for(l="",k=0;ka.byteLength)return console.log("Invalid Exif data: Invalid directory offset."),void 0;if(f=a.getUint16(c,d),g=c+2+12*f,g+4>a.byteLength)return console.log("Invalid Exif data: Invalid directory size."),void 0;for(h=0;f>h;h+=1)this.parseExifTag(a,b,c+2+12*h,d,e);return a.getUint32(g,d)},a.parseExifData=function(b,c,d,e,f){if(!f.disableExif){var g,h,i,j=c+10;if(1165519206===b.getUint32(c+4)){if(j+8>b.byteLength)return console.log("Invalid Exif data: Invalid segment size."),void 0;if(0!==b.getUint16(c+8))return console.log("Invalid Exif data: Missing byte alignment offset."),void 0;switch(b.getUint16(j)){case 18761:g=!0;break;case 19789:g=!1;break;default:return console.log("Invalid Exif data: Invalid byte alignment marker."),void 0}if(42!==b.getUint16(j+2,g))return console.log("Invalid Exif data: Missing TIFF marker."),void 0;h=b.getUint32(j+4,g),e.exif=new a.ExifMap,h=a.parseExifTags(b,j,j+h,g,e),h&&!f.disableExifThumbnail&&(i={exif:{}},h=a.parseExifTags(b,j,j+h,g,i),i.exif[513]&&(e.exif.Thumbnail=a.getExifThumbnail(b,j+i.exif[513],i.exif[514]))),e.exif[34665]&&!f.disableExifSub&&a.parseExifTags(b,j,j+e.exif[34665],g,e),e.exif[34853]&&!f.disableExifGps&&a.parseExifTags(b,j,j+e.exif[34853],g,e)}}},a.metaDataParsers.jpeg[65505].push(a.parseExifData)}),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image","load-image-exif"],a):a(window.loadImage)}(function(a){"use strict";a.ExifMap.prototype.tags={256:"ImageWidth",257:"ImageHeight",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer",40965:"InteroperabilityIFDPointer",258:"BitsPerSample",259:"Compression",262:"PhotometricInterpretation",274:"Orientation",277:"SamplesPerPixel",284:"PlanarConfiguration",530:"YCbCrSubSampling",531:"YCbCrPositioning",282:"XResolution",283:"YResolution",296:"ResolutionUnit",273:"StripOffsets",278:"RowsPerStrip",279:"StripByteCounts",513:"JPEGInterchangeFormat",514:"JPEGInterchangeFormatLength",301:"TransferFunction",318:"WhitePoint",319:"PrimaryChromaticities",529:"YCbCrCoefficients",532:"ReferenceBlackWhite",306:"DateTime",270:"ImageDescription",271:"Make",272:"Model",305:"Software",315:"Artist",33432:"Copyright",36864:"ExifVersion",40960:"FlashpixVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",42240:"Gamma",37121:"ComponentsConfiguration",37122:"CompressedBitsPerPixel",37500:"MakerNote",37510:"UserComment",40964:"RelatedSoundFile",36867:"DateTimeOriginal",36868:"DateTimeDigitized",37520:"SubSecTime",37521:"SubSecTimeOriginal",37522:"SubSecTimeDigitized",33434:"ExposureTime",33437:"FNumber",34850:"ExposureProgram",34852:"SpectralSensitivity",34855:"PhotographicSensitivity",34856:"OECF",34864:"SensitivityType",34865:"StandardOutputSensitivity",34866:"RecommendedExposureIndex",34867:"ISOSpeed",34868:"ISOSpeedLatitudeyyy",34869:"ISOSpeedLatitudezzz",37377:"ShutterSpeedValue",37378:"ApertureValue",37379:"BrightnessValue",37380:"ExposureBias",37381:"MaxApertureValue",37382:"SubjectDistance",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37396:"SubjectArea",37386:"FocalLength",41483:"FlashEnergy",41484:"SpatialFrequencyResponse",41486:"FocalPlaneXResolution",41487:"FocalPlaneYResolution",41488:"FocalPlaneResolutionUnit",41492:"SubjectLocation",41493:"ExposureIndex",41495:"SensingMethod",41728:"FileSource",41729:"SceneType",41730:"CFAPattern",41985:"CustomRendered",41986:"ExposureMode",41987:"WhiteBalance",41988:"DigitalZoomRatio",41989:"FocalLengthIn35mmFilm",41990:"SceneCaptureType",41991:"GainControl",41992:"Contrast",41993:"Saturation",41994:"Sharpness",41995:"DeviceSettingDescription",41996:"SubjectDistanceRange",42016:"ImageUniqueID",42032:"CameraOwnerName",42033:"BodySerialNumber",42034:"LensSpecification",42035:"LensMake",42036:"LensModel",42037:"LensSerialNumber",0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude",5:"GPSAltitudeRef",6:"GPSAltitude",7:"GPSTimeStamp",8:"GPSSatellites",9:"GPSStatus",10:"GPSMeasureMode",11:"GPSDOP",12:"GPSSpeedRef",13:"GPSSpeed",14:"GPSTrackRef",15:"GPSTrack",16:"GPSImgDirectionRef",17:"GPSImgDirection",18:"GPSMapDatum",19:"GPSDestLatitudeRef",20:"GPSDestLatitude",21:"GPSDestLongitudeRef",22:"GPSDestLongitude",23:"GPSDestBearingRef",24:"GPSDestBearing",25:"GPSDestDistanceRef",26:"GPSDestDistance",27:"GPSProcessingMethod",28:"GPSAreaInformation",29:"GPSDateStamp",30:"GPSDifferential",31:"GPSHPositioningError"},a.ExifMap.prototype.stringValues={ExposureProgram:{0:"Undefined",1:"Manual",2:"Normal program",3:"Aperture priority",4:"Shutter priority",5:"Creative program",6:"Action program",7:"Portrait mode",8:"Landscape mode"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{0:"Unknown",1:"Daylight",2:"Fluorescent",3:"Tungsten (incandescent light)",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 - 5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire",1:"Flash fired",5:"Strobe return light not detected",7:"Strobe return light detected",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},SensingMethod:{1:"Undefined",2:"One-chip color area sensor",3:"Two-chip color area sensor",4:"Three-chip color area sensor",5:"Color sequential area sensor",7:"Trilinear sensor",8:"Color sequential linear sensor"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},SceneType:{1:"Directly photographed"},CustomRendered:{0:"Normal process",1:"Custom process"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},GainControl:{0:"None",1:"Low gain up",2:"High gain up",3:"Low gain down",4:"High gain down"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},SubjectDistanceRange:{0:"Unknown",1:"Macro",2:"Close view",3:"Distant view"},FileSource:{3:"DSC"},ComponentsConfiguration:{0:"",1:"Y",2:"Cb",3:"Cr",4:"R",5:"G",6:"B"},Orientation:{1:"top-left",2:"top-right",3:"bottom-right",4:"bottom-left",5:"left-top",6:"right-top",7:"right-bottom",8:"left-bottom"}},a.ExifMap.prototype.getText=function(a){var b=this.get(a);switch(a){case"LightSource":case"Flash":case"MeteringMode":case"ExposureProgram":case"SensingMethod":case"SceneCaptureType":case"SceneType":case"CustomRendered":case"WhiteBalance":case"GainControl":case"Contrast":case"Saturation":case"Sharpness":case"SubjectDistanceRange":case"FileSource":case"Orientation":return this.stringValues[a][b];case"ExifVersion":case"FlashpixVersion":return String.fromCharCode(b[0],b[1],b[2],b[3]);case"ComponentsConfiguration":return this.stringValues[a][b[0]]+this.stringValues[a][b[1]]+this.stringValues[a][b[2]]+this.stringValues[a][b[3]];case"GPSVersionID":return b[0]+"."+b[1]+"."+b[2]+"."+b[3]}return String(b)},function(a){var b,c=a.tags,d=a.map;for(b in c)c.hasOwnProperty(b)&&(d[c[b]]=b)}(a.ExifMap.prototype),a.ExifMap.prototype.getAll=function(){var a,b,c={};for(a in this)this.hasOwnProperty(a)&&(b=this.tags[a],b&&(c[b]=this.getText(b)));return c}}); \ No newline at end of file diff --git a/vendor/assets/stylesheets/jquery.fileupload-ui.scss b/vendor/assets/stylesheets/jquery.fileupload-ui.scss old mode 100755 new mode 100644 index 72bfcb6..c4ee8cf --- a/vendor/assets/stylesheets/jquery.fileupload-ui.scss +++ b/vendor/assets/stylesheets/jquery.fileupload-ui.scss @@ -1,6 +1,6 @@ @charset "UTF-8"; /* - * jQuery File Upload UI Plugin CSS 8.0 + * jQuery File Upload UI Plugin CSS 9.0.0 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2010, Sebastian Tschan @@ -10,40 +10,30 @@ * http://www.opensource.org/licenses/MIT */ -.fileinput-button { - position: relative; - overflow: hidden; -} -.fileinput-button input { - position: absolute; - top: 0; - right: 0; - margin: 0; - opacity: 0; - filter: alpha(opacity=0); - transform: translate(-300px, 0) scale(4); - font-size: 23px; - direction: ltr; - cursor: pointer; -} .fileupload-buttonbar .btn, .fileupload-buttonbar .toggle { margin-bottom: 5px; } +.progress-animated .progress-bar, .progress-animated .bar { - background: url(../img/progressbar.gif) !important; + background: url("progressbar.gif") !important; filter: none; } -.fileupload-loading { +.fileupload-process { float: right; + display: none; +} +.fileupload-processing .fileupload-process, +.files .processing .preview { + display: block; width: 32px; height: 32px; - background: url(../img/loading.gif) center no-repeat; + background: url("loading.gif") center no-repeat; background-size: contain; - display: none; } -.fileupload-processing .fileupload-loading { - display: block; +.files audio, +.files video { + max-width: 300px; } @media (max-width: 767px) { @@ -56,4 +46,12 @@ width: 80px; word-wrap: break-word; } + .files audio, + .files video { + max-width: 80px; + } + .files img, + .files canvas { + max-width: 100%; + } }