diff --git a/README.md b/README.md index 6951515..8ccc9a3 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ jquery-fileupload-rails is a library that integrates jQuery File Upload for Rails 3.1 Asset Pipeline. -jquery-fileupload-rails is currently using jQuery-File-Plugin version 6.5.5. +jquery-fileupload-rails is currently using jQuery-File-Plugin version 6.7.0. ## Installing Gem @@ -24,7 +24,7 @@ The snippet above will add the following js files to the mainfest file. //=require jquery-fileupload/vendor/tmpl //=require jquery-fileupload/jquery.iframe-transport //=require jquery-fileupload/jquery.fileupload - //=require jquery-fileupload/jquery.fileupload-ip + //=require jquery-fileupload/jquery.fileupload-fp //=require jquery-fileupload/jquery.fileupload-ui //=require jquery-fileupload/locale @@ -39,7 +39,7 @@ The basic setup only includes the following files: //=require jquery-fileupload/jquery.fileupload ## Using the stylesheet - + Require the stylesheet file to app/assets/stylesheets/application.css *= require jquery.fileupload-ui diff --git a/vendor/assets/javascripts/jquery-fileupload/index.js b/vendor/assets/javascripts/jquery-fileupload/index.js index 50fff8f..0cda385 100644 --- a/vendor/assets/javascripts/jquery-fileupload/index.js +++ b/vendor/assets/javascripts/jquery-fileupload/index.js @@ -4,6 +4,6 @@ //=require jquery-fileupload/vendor/tmpl //=require jquery-fileupload/jquery.iframe-transport //=require jquery-fileupload/jquery.fileupload -//=require jquery-fileupload/jquery.fileupload-ip +//=require jquery-fileupload/jquery.fileupload-fp //=require jquery-fileupload/jquery.fileupload-ui //=require jquery-fileupload/locale diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js new file mode 100644 index 0000000..634fb5e --- /dev/null +++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js @@ -0,0 +1,219 @@ +/* + * jQuery File Upload File Processing Plugin 1.0 + * 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 IP version extends the basic fileupload widget + // with file processing functionality: + $.widget('blueimpFP.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) { + $(this).fileupload('process', data).done(function () { + data.submit(); + }); + } + }, + + processActions: { + // Loads the image given via data.files and data.index + // as canvas element. + // 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 (canvas) { + data.canvas = canvas; + dfd.resolveWith(that, [data]); + }, + {canvas: true} + ); + } else { + dfd.rejectWith(that, [data]); + } + return dfd.promise(); + }, + // Resizes the image given as data.canvas and updates + // data.canvas with the resized image. + // Accepts the options maxWidth, maxHeight, minWidth and + // minHeight to scale the given image: + resize: function (data, options) { + if (data.canvas) { + var canvas = loadImage.scale(data.canvas, options); + if (canvas.width !== data.canvas.width || + canvas.height !== data.canvas.height) { + data.canvas = canvas; + data.processed = true; + } + } + 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 || !data.processed) { + 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 () { + $.blueimp.fileupload.prototype._create.call(this); + this._processing = 0; + this._processingQueue = $.Deferred().resolveWith(this) + .promise(); + } + + }); + +})); diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ip.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ip.js deleted file mode 100644 index 4f71b62..0000000 --- a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ip.js +++ /dev/null @@ -1,160 +0,0 @@ -/* - * jQuery File Upload Image Processing Plugin 1.0.6 - * 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, - window.canvasToBlob - ); - } -}(function ($, loadImage, canvasToBlob) { - 'use strict'; - - // The File Upload IP version extends the basic fileupload widget - // with image processing functionality: - $.widget('blueimpIP.fileupload', $.blueimp.fileupload, { - - options: { - // The regular expression to define which image files are to be - // resized, given that the browser supports the operation: - resizeSourceFileTypes: /^image\/(gif|jpeg|png)$/, - // The maximum file size of images that are to be resized: - resizeSourceMaxFileSize: 20000000, // 20MB - // The maximum width of the resized images: - resizeMaxWidth: undefined, - // The maximum height of the resized images: - resizeMaxHeight: undefined, - // The minimum width of the resized images: - resizeMinWidth: undefined, - // The minimum height of the resized images: - resizeMinHeight: undefined, - - // 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) { - $(this).fileupload('resize', data).done(function () { - data.submit(); - }); - } - }, - - // Resizes the image file at the given index and stores the created blob - // at the original position of the files list, returns a Promise object: - _resizeImage: function (files, index, options) { - var that = this, - file = files[index], - deferred = $.Deferred(), - canvas, - blob; - options = options || this.options; - loadImage( - file, - function (img) { - var width = img.width, - height = img.height; - canvas = loadImage.scale(img, { - maxWidth: options.resizeMaxWidth, - maxHeight: options.resizeMaxHeight, - minWidth: options.resizeMinWidth, - minHeight: options.resizeMinHeight, - canvas: true - }); - if (width !== canvas.width || height !== canvas.height) { - canvasToBlob(canvas, 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) - ); - } - } - files[index] = blob; - deferred.resolveWith(that); - }, file); - } else { - deferred.resolveWith(that); - } - } - ); - return deferred.promise(); - }, - - // Resizes the images 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 images is done: - resize: function (data) { - var that = this, - options = $.extend({}, this.options, data), - resizeAll = $.type(options.resizeSourceMaxFileSize) !== 'number', - isXHRUpload = this._isXHRUpload(options); - $.each(data.files, function (index, file) { - if (isXHRUpload && that._resizeSupport && - (options.resizeMaxWidth || options.resizeMaxHeight || - options.resizeMinWidth || options.resizeMinHeight) && - (resizeAll || file.size < options.resizeSourceMaxFileSize) && - options.resizeSourceFileTypes.test(file.type)) { - that._processing += 1; - if (that._processing === 1) { - that.element.addClass('fileupload-processing'); - } - that._processingQueue = that._processingQueue.pipe(function () { - var deferred = $.Deferred(); - that._resizeImage( - data.files, - index, - options - ).done(function () { - that._processing -= 1; - if (that._processing === 0) { - that.element - .removeClass('fileupload-processing'); - } - deferred.resolveWith(that); - }); - return deferred.promise(); - }); - } - }); - return this._processingQueue; - }, - - _create: function () { - $.blueimp.fileupload.prototype._create.call(this); - this._processing = 0; - this._processingQueue = $.Deferred().resolveWith(this).promise(); - this._resizeSupport = canvasToBlob && canvasToBlob( - document.createElement('canvas'), - $.noop - ); - } - - }); - -})); diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js index 1489787..57ef7b6 100644 --- 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 6.6.3 + * jQuery File Upload User Interface Plugin 6.8.2 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2010, Sebastian Tschan @@ -20,7 +20,7 @@ 'jquery', 'tmpl', 'load-image', - './jquery.fileupload-ip' + './jquery.fileupload-fp' ], factory); } else { // Browser globals: @@ -33,9 +33,9 @@ }(function ($, tmpl, loadImage) { 'use strict'; - // The UI version extends the IP (image processing) version or the basic + // The UI version extends the FP (file processing) version or the basic // file upload widget and adds complete user interface interaction: - var parentWidget = ($.blueimpIP || $.blueimp).fileupload; + var parentWidget = ($.blueimpFP || $.blueimp).fileupload; $.widget('blueimpUI.fileupload', parentWidget, { options: { @@ -70,6 +70,12 @@ uploadTemplateId: 'template-upload', // The ID of the download template: downloadTemplateId: 'template-download', + // The container for the list of files. If undefined, it is set to + // an element with class "files" inside of the widget element: + filesContainer: undefined, + // By default, files are appended to the files container. + // Set the following option to true, to prepend files instead: + prependFiles: false, // The expected data type of the upload response, sets the dataType // option of the $.ajax upload requests: dataType: 'json', @@ -81,13 +87,14 @@ var that = $(this).data('fileupload'), options = that.options, files = data.files; - $(this).fileupload('resize', data).done(data, function () { + $(this).fileupload('process', data).done(function () { that._adjustMaxNumberOfFiles(-files.length); data.isAdjusted = true; data.files.valid = data.isValidated = that._validate(files); - data.context = that._renderUpload(files) - .appendTo(options.filesContainer) - .data('data', data); + data.context = that._renderUpload(files).data('data', data); + options.filesContainer[ + options.prependFiles ? 'prepend' : 'append' + ](data.context); that._renderPreviews(files, data.context); that._forceReflow(data.context); that._transition(data.context).done( @@ -131,8 +138,7 @@ // Callback for successful uploads: done: function (e, data) { var that = $(this).data('fileupload'), - template, - preview; + template; if (data.context) { data.context.each(function (index) { var file = ($.isArray(data.result) && @@ -221,7 +227,7 @@ // Callback for upload progress events: progress: function (e, data) { if (data.context) { - data.context.find('.progress .bar').css( + data.context.find('.bar').css( 'width', parseInt(data.loaded / data.total * 100, 10) + '%' ); @@ -229,15 +235,23 @@ }, // Callback for global upload progress events: progressall: function (e, data) { - $(this).find('.fileupload-buttonbar .progress .bar').css( - 'width', - parseInt(data.loaded / data.total * 100, 10) + '%' - ); + var $this = $(this); + $this.find('.fileupload-progress') + .find('.bar').css( + 'width', + parseInt(data.loaded / data.total * 100, 10) + '%' + ).end() + .find('.progress-extended').each(function () { + $(this).html( + $this.data('fileupload') + ._renderExtendedProgress(data) + ); + }); }, // Callback for uploads start, equivalent to the global ajaxStart event: start: function (e) { var that = $(this).data('fileupload'); - that._transition($(this).find('.fileupload-buttonbar .progress')).done( + that._transition($(this).find('.fileupload-progress')).done( function () { that._trigger('started', e); } @@ -246,9 +260,10 @@ // Callback for uploads stop, equivalent to the global ajaxStop event: stop: function (e) { var that = $(this).data('fileupload'); - that._transition($(this).find('.fileupload-buttonbar .progress')).done( + that._transition($(this).find('.fileupload-progress')).done( function () { $(this).find('.bar').css('width', '0%'); + $(this).find('.progress-extended').html(' '); that._trigger('stopped', e); } ); @@ -258,8 +273,8 @@ var that = $(this).data('fileupload'); if (data.url) { $.ajax(data); + that._adjustMaxNumberOfFiles(1); } - that._adjustMaxNumberOfFiles(1); that._transition(data.context).done( function () { $(this).remove(); @@ -310,6 +325,48 @@ return (bytes / 1000).toFixed(2) + ' KB'; }, + _formatBitrate: function (bits) { + if (typeof bits !== 'number') { + return ''; + } + if (bits >= 1000000000) { + return (bits / 1000000000).toFixed(2) + ' Gbit/s'; + } + if (bits >= 1000000) { + return (bits / 1000000).toFixed(2) + ' Mbit/s'; + } + if (bits >= 1000) { + return (bits / 1000).toFixed(2) + ' kbit/s'; + } + return bits + ' bit/s'; + }, + + _formatTime: function (seconds) { + var date = new Date(seconds * 1000), + days = parseInt(seconds / 86400, 10); + days = days ? days + 'd ' : ''; + return days + + ('0' + date.getUTCHours()).slice(-2) + ':' + + ('0' + date.getUTCMinutes()).slice(-2) + ':' + + ('0' + date.getUTCSeconds()).slice(-2); + }, + + _formatPercentage: function (floatValue) { + return (floatValue * 100).toFixed(2) + ' %'; + }, + + _renderExtendedProgress: function (data) { + return this._formatBitrate(data.bitrate) + ' | ' + + this._formatTime( + (data.total - data.loaded) * 8 / data.bitrate + ) + ' | ' + + this._formatPercentage( + data.loaded / data.total + ) + ' | ' + + this._formatFileSize(data.loaded) + ' / ' + + this._formatFileSize(data.total); + }, + _hasError: function (file) { if (file.error) { return file.error; @@ -368,22 +425,28 @@ _renderPreview: function (file, node) { var that = this, options = this.options, - deferred = $.Deferred(); + dfd = $.Deferred(); return ((loadImage && loadImage( file, function (img) { node.append(img); that._forceReflow(node); that._transition(node).done(function () { - deferred.resolveWith(node); + dfd.resolveWith(node); }); + if (!$.contains(document.body, node[0])) { + // If the element is not part of the DOM, + // transition events are not triggered, + // so we have to resolve manually: + dfd.resolveWith(node); + } }, { maxWidth: options.previewMaxWidth, maxHeight: options.previewMaxHeight, canvas: options.previewAsCanvas } - )) || deferred.resolveWith(node)) && deferred; + )) || dfd.resolveWith(node)) && dfd; }, _renderPreviews: function (files, nodes) { @@ -395,13 +458,13 @@ ($.type(options.previewSourceMaxFileSize) !== 'number' || file.size < options.previewSourceMaxFileSize)) { that._processingQueue = that._processingQueue.pipe(function () { - var deferred = $.Deferred(); + var dfd = $.Deferred(); that._renderPreview(file, $(element)).done( function () { - deferred.resolveWith(that); + dfd.resolveWith(that); } ); - return deferred.promise(); + return dfd.promise(); }); } }); @@ -461,8 +524,7 @@ }, _transition: function (node) { - var that = this, - deferred = $.Deferred(); + var dfd = $.Deferred(); if ($.support.transition && node.hasClass('fade')) { node.bind( $.support.transition.end, @@ -471,15 +533,15 @@ // in the container element, e.g. from button elements: if (e.target === node[0]) { node.unbind($.support.transition.end); - deferred.resolveWith(node); + dfd.resolveWith(node); } } ).toggleClass('in'); } else { node.toggleClass('in'); - deferred.resolveWith(node); + dfd.resolveWith(node); } - return deferred; + return dfd; }, _initButtonBarEventHandlers: function () { @@ -604,9 +666,9 @@ 'uploadTemplateId', 'downloadTemplateId' ); - if (!$.blueimpIP) { + if (!$.blueimpFP) { this._processingQueue = $.Deferred().resolveWith(this).promise(); - this.resize = function () { + this.process = function () { return this._processingQueue; }; } diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js index 8fb8562..40661c1 100644 --- 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.10.0 + * jQuery File Upload Plugin 5.11.2 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2010, Sebastian Tschan @@ -109,6 +109,10 @@ // global progress calculation. Set the following option to false to // prevent recalculating the global progress data: recalculateProgress: true, + // Interval in milliseconds to calculate and trigger progress events: + progressInterval: 100, + // Interval in milliseconds to calculate progress bitrate: + bitrateInterval: 500, // Additional form data to be sent along with the file uploads can be set // using this option, which accepts an array of objects with name and @@ -180,6 +184,21 @@ 'forceIframeTransport' ], + _BitrateTimer: function () { + this.timestamp = +(new Date()); + this.loaded = 0; + this.bitrate = 0; + this.getBitrate = function (now, loaded, interval) { + var timeDiff = now - this.timestamp; + if (!this.bitrate || !interval || timeDiff > interval) { + this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8; + this.loaded = loaded; + this.timestamp = now; + } + return this.bitrate; + }; + }, + _isXHRUpload: function (options) { return !options.forceIframeTransport && ((!options.multipart && $.support.xhrFileUpload) || @@ -190,9 +209,11 @@ var formData; if (typeof options.formData === 'function') { return options.formData(options.form); - } else if ($.isArray(options.formData)) { + } + if ($.isArray(options.formData)) { return options.formData; - } else if (options.formData) { + } + if (options.formData) { formData = []; $.each(options.formData, function (name, value) { formData.push({name: name, value: value}); @@ -212,15 +233,29 @@ _onProgress: function (e, data) { if (e.lengthComputable) { - var total = data.total || this._getTotal(data.files), - loaded = parseInt( - e.loaded / e.total * (data.chunkSize || total), - 10 - ) + (data.uploadedBytes || 0); + var now = +(new Date()), + total, + loaded; + if (data._time && data.progressInterval && + (now - data._time < data.progressInterval) && + e.loaded !== e.total) { + return; + } + data._time = now; + total = data.total || this._getTotal(data.files); + loaded = parseInt( + e.loaded / e.total * (data.chunkSize || total), + 10 + ) + (data.uploadedBytes || 0); this._loaded += loaded - (data.loaded || data.uploadedBytes || 0); data.lengthComputable = true; data.loaded = loaded; data.total = total; + data.bitrate = data._bitrateTimer.getBitrate( + now, + loaded, + data.bitrateInterval + ); // Trigger a custom progress event with a total data property set // to the file size(s) of the current upload and a loaded data // property calculated accordingly: @@ -230,7 +265,12 @@ this._trigger('progressall', e, { lengthComputable: true, loaded: this._loaded, - total: this._total + total: this._total, + bitrate: this._bitrateTimer.getBitrate( + now, + this._loaded, + data.bitrateInterval + ) }); } }, @@ -530,6 +570,8 @@ // and no other uploads are currently running, // equivalent to the global ajaxStart event: this._trigger('start'); + // Set timer for global bitrate progress calculation: + this._bitrateTimer = new this._BitrateTimer(); } this._active += 1; // Initialize the global progress values: @@ -582,6 +624,7 @@ this._trigger('stop'); // Reset the global progress values: this._loaded = this._total = 0; + this._bitrateTimer = null; } }, @@ -593,6 +636,8 @@ options = that._getAJAXSettings(data), send = function (resolve, args) { that._sending += 1; + // Set timer for bitrate progress calculation: + options._bitrateTimer = new that._BitrateTimer(); jqXHR = jqXHR || ( (resolve !== false && that._trigger('send', e, options) !== false && @@ -846,10 +891,9 @@ }, _create: function () { - var options = this.options, - dataOpts = $.extend({}, this.element.data()); - dataOpts[this.widgetName] = undefined; - $.extend(options, dataOpts); + var options = this.options; + // Initialize options set via HTML5 data-attributes: + $.extend(options, $(this.element[0].cloneNode(false)).data()); options.namespace = options.namespace || this.widgetName; this._initSpecialOptions(); this._slots = []; diff --git a/vendor/assets/javascripts/jquery-fileupload/locale.js b/vendor/assets/javascripts/jquery-fileupload/locale.js index 92f6997..ea64b0a 100644 --- a/vendor/assets/javascripts/jquery-fileupload/locale.js +++ b/vendor/assets/javascripts/jquery-fileupload/locale.js @@ -1,5 +1,5 @@ /* - * jQuery File Upload Plugin Localization Example 6.5 + * jQuery File Upload Plugin Localization Example 6.5.1 * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2012, Sebastian Tschan @@ -9,6 +9,8 @@ * http://www.opensource.org/licenses/MIT */ +/*global window */ + window.locale = { "fileupload": { "errors": {