Date: Sun, 28 Oct 2012 23:02:50 +0800
Subject: [PATCH 18/33] update jquery ui widget
---
.../vendor/jquery.ui.widget.js | 480 +++++++++++++-----
1 file changed, 363 insertions(+), 117 deletions(-)
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 39287bd..886aff6 100644
--- a/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js
+++ b/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js
@@ -1,12 +1,12 @@
/*
- * jQuery UI Widget 1.8.23+amd
+ * jQuery UI Widget 1.9.1+amd
* https://github.com/blueimp/jQuery-File-Upload
*
- * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
* http://jquery.org/license
*
- * http://docs.jquery.com/UI/Widget
+ * http://api.jqueryui.com/jQuery.widget/
*/
(function (factory) {
@@ -19,40 +19,23 @@
}
}(function( $, undefined ) {
-// jQuery 1.4+
-if ( $.cleanData ) {
- var _cleanData = $.cleanData;
- $.cleanData = function( elems ) {
- for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
- try {
- $( elem ).triggerHandler( "remove" );
- // http://bugs.jquery.com/ticket/8235
- } catch( e ) {}
- }
- _cleanData( elems );
- };
-} else {
- var _remove = $.fn.remove;
- $.fn.remove = function( selector, keepData ) {
- return this.each(function() {
- if ( !keepData ) {
- if ( !selector || $.filter( selector, [ this ] ).length ) {
- $( "*", this ).add( [ this ] ).each(function() {
- try {
- $( this ).triggerHandler( "remove" );
- // http://bugs.jquery.com/ticket/8235
- } catch( e ) {}
- });
- }
- }
- return _remove.call( $(this), selector, keepData );
- });
- };
-}
+var uuid = 0,
+ slice = Array.prototype.slice,
+ _cleanData = $.cleanData;
+$.cleanData = function( elems ) {
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ try {
+ $( elem ).triggerHandler( "remove" );
+ // http://bugs.jquery.com/ticket/8235
+ } catch( e ) {}
+ }
+ _cleanData( elems );
+};
$.widget = function( name, base, prototype ) {
- var namespace = name.split( "." )[ 0 ],
- fullName;
+ var fullName, existingConstructor, constructor, basePrototype,
+ namespace = name.split( "." )[ 0 ];
+
name = name.split( "." )[ 1 ];
fullName = namespace + "-" + name;
@@ -62,81 +45,167 @@ $.widget = function( name, base, prototype ) {
}
// create selector for plugin
- $.expr[ ":" ][ fullName ] = function( elem ) {
- return !!$.data( elem, name );
+ $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
+ return !!$.data( elem, fullName );
};
$[ namespace ] = $[ namespace ] || {};
- $[ namespace ][ name ] = function( options, element ) {
+ existingConstructor = $[ namespace ][ name ];
+ constructor = $[ namespace ][ name ] = function( options, element ) {
+ // allow instantiation without "new" keyword
+ if ( !this._createWidget ) {
+ return new constructor( options, element );
+ }
+
// allow instantiation without initializing for simple inheritance
+ // must use "new" keyword (the code above always passes args)
if ( arguments.length ) {
this._createWidget( options, element );
}
};
-
- var basePrototype = new base();
+ // extend with the existing constructor to carry over any static properties
+ $.extend( constructor, existingConstructor, {
+ version: prototype.version,
+ // copy the object used to create the prototype in case we need to
+ // redefine the widget later
+ _proto: $.extend( {}, prototype ),
+ // track widgets that inherit from this widget in case this widget is
+ // redefined after a widget inherits from it
+ _childConstructors: []
+ });
+
+ basePrototype = new base();
// we need to make the options hash a property directly on the new instance
// otherwise we'll modify the options hash on the prototype that we're
// inheriting from
-// $.each( basePrototype, function( key, val ) {
-// if ( $.isPlainObject(val) ) {
-// basePrototype[ key ] = $.extend( {}, val );
-// }
-// });
- basePrototype.options = $.extend( true, {}, basePrototype.options );
- $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
+ basePrototype.options = $.widget.extend( {}, basePrototype.options );
+ $.each( prototype, function( prop, value ) {
+ if ( $.isFunction( value ) ) {
+ prototype[ prop ] = (function() {
+ var _super = function() {
+ return base.prototype[ prop ].apply( this, arguments );
+ },
+ _superApply = function( args ) {
+ return base.prototype[ prop ].apply( this, args );
+ };
+ return function() {
+ var __super = this._super,
+ __superApply = this._superApply,
+ returnValue;
+
+ this._super = _super;
+ this._superApply = _superApply;
+
+ returnValue = value.apply( this, arguments );
+
+ this._super = __super;
+ this._superApply = __superApply;
+
+ return returnValue;
+ };
+ })();
+ }
+ });
+ constructor.prototype = $.widget.extend( basePrototype, {
+ // 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: basePrototype.widgetEventPrefix || name
+ }, prototype, {
+ constructor: constructor,
namespace: namespace,
widgetName: name,
- widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
- widgetBaseClass: fullName
- }, prototype );
+ // TODO remove widgetBaseClass, see #8155
+ widgetBaseClass: fullName,
+ widgetFullName: fullName
+ });
+
+ // If this widget is being redefined then we need to find all widgets that
+ // are inheriting from it and redefine all of them so that they inherit from
+ // the new version of this widget. We're essentially trying to replace one
+ // level in the prototype chain.
+ if ( existingConstructor ) {
+ $.each( existingConstructor._childConstructors, function( i, child ) {
+ var childPrototype = child.prototype;
+
+ // redefine the child widget using the same prototype that was
+ // originally used, but inherit from the new version of the base
+ $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
+ });
+ // remove the list of existing child constructors from the old constructor
+ // so the old child constructors can be garbage collected
+ delete existingConstructor._childConstructors;
+ } else {
+ base._childConstructors.push( constructor );
+ }
- $.widget.bridge( name, $[ namespace ][ name ] );
+ $.widget.bridge( name, constructor );
+};
+
+$.widget.extend = function( target ) {
+ var input = slice.call( arguments, 1 ),
+ inputIndex = 0,
+ inputLength = input.length,
+ key,
+ value;
+ for ( ; inputIndex < inputLength; inputIndex++ ) {
+ for ( key in input[ inputIndex ] ) {
+ value = input[ inputIndex ][ key ];
+ if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
+ // Clone objects
+ if ( $.isPlainObject( value ) ) {
+ target[ key ] = $.isPlainObject( target[ key ] ) ?
+ $.widget.extend( {}, target[ key ], value ) :
+ // Don't extend strings, arrays, etc. with objects
+ $.widget.extend( {}, value );
+ // Copy everything else by reference
+ } else {
+ target[ key ] = value;
+ }
+ }
+ }
+ }
+ return target;
};
$.widget.bridge = function( name, object ) {
+ var fullName = object.prototype.widgetFullName;
$.fn[ name ] = function( options ) {
var isMethodCall = typeof options === "string",
- args = Array.prototype.slice.call( arguments, 1 ),
+ args = slice.call( arguments, 1 ),
returnValue = this;
// allow multiple hashes to be passed on init
options = !isMethodCall && args.length ?
- $.extend.apply( null, [ true, options ].concat(args) ) :
+ $.widget.extend.apply( null, [ options ].concat(args) ) :
options;
- // prevent calls to internal methods
- if ( isMethodCall && options.charAt( 0 ) === "_" ) {
- return returnValue;
- }
-
if ( isMethodCall ) {
this.each(function() {
- var instance = $.data( this, name ),
- methodValue = instance && $.isFunction( instance[options] ) ?
- instance[ options ].apply( instance, args ) :
- instance;
- // TODO: add this back in 1.9 and use $.error() (see #5972)
-// if ( !instance ) {
-// throw "cannot call methods on " + name + " prior to initialization; " +
-// "attempted to call method '" + options + "'";
-// }
-// if ( !$.isFunction( instance[options] ) ) {
-// throw "no such method '" + options + "' for " + name + " widget instance";
-// }
-// var methodValue = instance[ options ].apply( instance, args );
+ var methodValue,
+ instance = $.data( this, fullName );
+ if ( !instance ) {
+ return $.error( "cannot call methods on " + name + " prior to initialization; " +
+ "attempted to call method '" + options + "'" );
+ }
+ if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
+ return $.error( "no such method '" + options + "' for " + name + " widget instance" );
+ }
+ methodValue = instance[ options ].apply( instance, args );
if ( methodValue !== instance && methodValue !== undefined ) {
- returnValue = methodValue;
+ returnValue = methodValue && methodValue.jquery ?
+ returnValue.pushStack( methodValue.get() ) :
+ methodValue;
return false;
}
});
} else {
this.each(function() {
- var instance = $.data( this, name );
+ var instance = $.data( this, fullName );
if ( instance ) {
instance.option( options || {} )._init();
} else {
- $.data( this, name, new object( options, this ) );
+ new object( options, this );
}
});
}
@@ -145,74 +214,126 @@ $.widget.bridge = function( name, object ) {
};
};
-$.Widget = function( options, element ) {
- // allow instantiation without initializing for simple inheritance
- if ( arguments.length ) {
- this._createWidget( options, element );
- }
-};
+$.Widget = function( /* options, element */ ) {};
+$.Widget._childConstructors = [];
$.Widget.prototype = {
widgetName: "widget",
widgetEventPrefix: "",
+ defaultElement: "",
options: {
- disabled: false
+ disabled: false,
+
+ // callbacks
+ create: null
},
_createWidget: function( options, element ) {
- // $.widget.bridge stores the plugin instance, but we do it anyway
- // so that it's stored even before the _create function runs
- $.data( element, this.widgetName, this );
+ element = $( element || this.defaultElement || this )[ 0 ];
this.element = $( element );
- this.options = $.extend( true, {},
+ this.uuid = uuid++;
+ this.eventNamespace = "." + this.widgetName + this.uuid;
+ this.options = $.widget.extend( {},
this.options,
this._getCreateOptions(),
options );
- var self = this;
- this.element.bind( "remove." + this.widgetName, function() {
- self.destroy();
- });
+ this.bindings = $();
+ this.hoverable = $();
+ this.focusable = $();
+
+ if ( element !== this ) {
+ // 1.9 BC for #7810
+ // TODO remove dual storage
+ $.data( element, this.widgetName, this );
+ $.data( element, this.widgetFullName, this );
+ this._on( this.element, {
+ remove: function( event ) {
+ if ( event.target === element ) {
+ this.destroy();
+ }
+ }
+ });
+ this.document = $( element.style ?
+ // element within the document
+ element.ownerDocument :
+ // element is window or document
+ element.document || element );
+ this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
+ }
this._create();
- this._trigger( "create" );
+ this._trigger( "create", null, this._getCreateEventData() );
this._init();
},
- _getCreateOptions: function() {
- return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
- },
- _create: function() {},
- _init: function() {},
+ _getCreateOptions: $.noop,
+ _getCreateEventData: $.noop,
+ _create: $.noop,
+ _init: $.noop,
destroy: function() {
+ this._destroy();
+ // we can probably remove the unbind calls in 2.0
+ // all event bindings should go through this._on()
this.element
- .unbind( "." + this.widgetName )
- .removeData( this.widgetName );
+ .unbind( this.eventNamespace )
+ // 1.9 BC for #7810
+ // TODO remove dual storage
+ .removeData( this.widgetName )
+ .removeData( this.widgetFullName )
+ // support: jquery <1.6.3
+ // http://bugs.jquery.com/ticket/9413
+ .removeData( $.camelCase( this.widgetFullName ) );
this.widget()
- .unbind( "." + this.widgetName )
+ .unbind( this.eventNamespace )
.removeAttr( "aria-disabled" )
.removeClass(
- this.widgetBaseClass + "-disabled " +
+ this.widgetFullName + "-disabled " +
"ui-state-disabled" );
+
+ // clean up events and states
+ this.bindings.unbind( this.eventNamespace );
+ this.hoverable.removeClass( "ui-state-hover" );
+ this.focusable.removeClass( "ui-state-focus" );
},
+ _destroy: $.noop,
widget: function() {
return this.element;
},
option: function( key, value ) {
- var options = key;
+ var options = key,
+ parts,
+ curOption,
+ i;
if ( arguments.length === 0 ) {
// don't return a reference to the internal hash
- return $.extend( {}, this.options );
+ return $.widget.extend( {}, this.options );
}
- if (typeof key === "string" ) {
- if ( value === undefined ) {
- return this.options[ key ];
- }
+ if ( typeof key === "string" ) {
+ // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
options = {};
- options[ key ] = value;
+ parts = key.split( "." );
+ key = parts.shift();
+ if ( parts.length ) {
+ curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
+ for ( i = 0; i < parts.length - 1; i++ ) {
+ curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
+ curOption = curOption[ parts[ i ] ];
+ }
+ key = parts.pop();
+ if ( value === undefined ) {
+ return curOption[ key ] === undefined ? null : curOption[ key ];
+ }
+ curOption[ key ] = value;
+ } else {
+ if ( value === undefined ) {
+ return this.options[ key ] === undefined ? null : this.options[ key ];
+ }
+ options[ key ] = value;
+ }
}
this._setOptions( options );
@@ -220,10 +341,11 @@ $.Widget.prototype = {
return this;
},
_setOptions: function( options ) {
- var self = this;
- $.each( options, function( key, value ) {
- self._setOption( key, value );
- });
+ var key;
+
+ for ( key in options ) {
+ this._setOption( key, options[ key ] );
+ }
return this;
},
@@ -232,10 +354,10 @@ $.Widget.prototype = {
if ( key === "disabled" ) {
this.widget()
- [ value ? "addClass" : "removeClass"](
- this.widgetBaseClass + "-disabled" + " " +
- "ui-state-disabled" )
+ .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
.attr( "aria-disabled", value );
+ this.hoverable.removeClass( "ui-state-hover" );
+ this.focusable.removeClass( "ui-state-focus" );
}
return this;
@@ -248,6 +370,88 @@ $.Widget.prototype = {
return this._setOption( "disabled", true );
},
+ _on: function( element, handlers ) {
+ var delegateElement,
+ instance = this;
+ // no element argument, shuffle and use this.element
+ if ( !handlers ) {
+ handlers = element;
+ element = this.element;
+ delegateElement = this.widget();
+ } else {
+ // accept selectors, DOM elements
+ element = delegateElement = $( element );
+ this.bindings = this.bindings.add( element );
+ }
+
+ $.each( handlers, function( event, handler ) {
+ function handlerProxy() {
+ // allow widgets to customize the disabled handling
+ // - disabled as an array instead of boolean
+ // - disabled class as method for disabling individual parts
+ if ( instance.options.disabled === true ||
+ $( this ).hasClass( "ui-state-disabled" ) ) {
+ return;
+ }
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
+ .apply( instance, arguments );
+ }
+
+ // copy the guid so direct unbinding works
+ if ( typeof handler !== "string" ) {
+ handlerProxy.guid = handler.guid =
+ handler.guid || handlerProxy.guid || $.guid++;
+ }
+
+ var match = event.match( /^(\w+)\s*(.*)$/ ),
+ eventName = match[1] + instance.eventNamespace,
+ selector = match[2];
+ if ( selector ) {
+ delegateElement.delegate( selector, eventName, handlerProxy );
+ } else {
+ element.bind( eventName, handlerProxy );
+ }
+ });
+ },
+
+ _off: function( element, eventName ) {
+ eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
+ element.unbind( eventName ).undelegate( eventName );
+ },
+
+ _delay: function( handler, delay ) {
+ function handlerProxy() {
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
+ .apply( instance, arguments );
+ }
+ var instance = this;
+ return setTimeout( handlerProxy, delay || 0 );
+ },
+
+ _hoverable: function( element ) {
+ this.hoverable = this.hoverable.add( element );
+ this._on( element, {
+ mouseenter: function( event ) {
+ $( event.currentTarget ).addClass( "ui-state-hover" );
+ },
+ mouseleave: function( event ) {
+ $( event.currentTarget ).removeClass( "ui-state-hover" );
+ }
+ });
+ },
+
+ _focusable: function( element ) {
+ this.focusable = this.focusable.add( element );
+ this._on( element, {
+ focusin: function( event ) {
+ $( event.currentTarget ).addClass( "ui-state-focus" );
+ },
+ focusout: function( event ) {
+ $( event.currentTarget ).removeClass( "ui-state-focus" );
+ }
+ });
+ },
+
_trigger: function( type, event, data ) {
var prop, orig,
callback = this.options[ type ];
@@ -272,11 +476,53 @@ $.Widget.prototype = {
}
this.element.trigger( event, data );
-
- return !( $.isFunction(callback) &&
- callback.call( this.element[0], event, data ) === false ||
+ return !( $.isFunction( callback ) &&
+ callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
event.isDefaultPrevented() );
}
};
+$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
+ $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
+ if ( typeof options === "string" ) {
+ options = { effect: options };
+ }
+ var hasOptions,
+ effectName = !options ?
+ method :
+ options === true || typeof options === "number" ?
+ defaultEffect :
+ options.effect || defaultEffect;
+ options = options || {};
+ if ( typeof options === "number" ) {
+ options = { duration: options };
+ }
+ hasOptions = !$.isEmptyObject( options );
+ options.complete = callback;
+ if ( options.delay ) {
+ element.delay( options.delay );
+ }
+ if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
+ element[ method ]( options );
+ } else if ( effectName !== method && element[ effectName ] ) {
+ element[ effectName ]( options.duration, options.easing, callback );
+ } else {
+ element.queue(function( next ) {
+ $( this )[ method ]();
+ if ( callback ) {
+ callback.call( element[ 0 ] );
+ }
+ next();
+ });
+ }
+ };
+});
+
+// DEPRECATED
+if ( $.uiBackCompat !== false ) {
+ $.Widget.prototype._getCreateOptions = function() {
+ return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
+ };
+}
+
}));
From 9eb4e600877cf91d50b6ab966b429a7fcbc3795c Mon Sep 17 00:00:00 2001
From: Tors Dalid
Date: Sun, 28 Oct 2012 23:03:25 +0800
Subject: [PATCH 19/33] bump version
---
lib/jquery/fileupload/rails/version.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/jquery/fileupload/rails/version.rb b/lib/jquery/fileupload/rails/version.rb
index dd69c2d..517de9f 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.3.4"
+ VERSION = "0.3.5"
end
end
end
From 978ad528091b8c7ef412af6da68b6ec598bbd286 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Lipski?=
Date: Tue, 13 Nov 2012 02:35:41 +0100
Subject: [PATCH 20/33] Update JavaScript assets.
---
.../jquery-fileupload/jquery.fileupload-fp.js | 5 ++++-
.../jquery-fileupload/jquery.fileupload.js | 18 +++++++++---------
2 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
index 2102b8b..fdf18fb 100644
--- a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
+++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
@@ -1,5 +1,5 @@
/*
- * jQuery File Upload File Processing Plugin 1.2
+ * jQuery File Upload File Processing Plugin 1.2.1
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2012, Sebastian Tschan
@@ -86,6 +86,9 @@
loadImage(
file,
function (img) {
+ if (!img.src) {
+ return dfd.rejectWith(that, [data]);
+ }
data.img = img;
dfd.resolveWith(that, [data]);
}
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js
index 5504ebe..6356012 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.19.2
+ * jQuery File Upload Plugin 5.19.3
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
@@ -644,18 +644,18 @@
_onSend: function (e, data) {
var that = this,
jqXHR,
+ aborted,
slot,
pipe,
options = that._getAJAXSettings(data),
- send = function (resolve, args) {
+ send = function () {
that._sending += 1;
// Set timer for bitrate progress calculation:
options._bitrateTimer = new that._BitrateTimer();
jqXHR = jqXHR || (
- (resolve !== false &&
- that._trigger('send', e, options) !== false &&
- (that._chunkedUpload(options) || $.ajax(options))) ||
- that._getXHRPromise(false, options.context, args)
+ ((aborted || that._trigger('send', e, options) === false) &&
+ that._getXHRPromise(false, options.context, aborted)) ||
+ that._chunkedUpload(options) || $.ajax(options)
).done(function (result, textStatus, jqXHR) {
that._onDone(result, textStatus, jqXHR, options);
}).fail(function (jqXHR, textStatus, errorThrown) {
@@ -705,12 +705,12 @@
// which is delegated to the jqXHR object of the current upload,
// and jqXHR callbacks mapped to the equivalent Promise methods:
pipe.abort = function () {
- var args = [undefined, 'abort', 'abort'];
+ aborted = [undefined, 'abort', 'abort'];
if (!jqXHR) {
if (slot) {
- slot.rejectWith(pipe, args);
+ slot.rejectWith(options.context, aborted);
}
- return send(false, args);
+ return send();
}
return jqXHR.abort();
};
From db28426656223c13873d2bcd006581c53c93cb1f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Lipski?=
Date: Tue, 13 Nov 2012 02:36:17 +0100
Subject: [PATCH 21/33] Update readme.
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 232f3e0..936b58b 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ jquery-fileupload-rails is a library that integrates jQuery File Upload for Rail
## Plugin versions
* jQuery File Upload User Interface Plugin 6.11
-* jQuery File Upload Plugin 5.19.2
+* jQuery File Upload Plugin 5.19.3
* jQuery UI Widget 1.9.1+amd
## Installing Gem
From aa6b1f994542c177ba8cf2ddddbb8718645da2ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Lipski?=
Date: Tue, 13 Nov 2012 02:36:34 +0100
Subject: [PATCH 22/33] Bump version.
---
lib/jquery/fileupload/rails/version.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/jquery/fileupload/rails/version.rb b/lib/jquery/fileupload/rails/version.rb
index 517de9f..e037147 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.3.5"
+ VERSION = "0.3.6"
end
end
end
From b5bc1fefaf81acc6db58748620771c07376255bf Mon Sep 17 00:00:00 2001
From: Duncan Beevers
Date: Wed, 5 Dec 2012 16:23:02 -0600
Subject: [PATCH 23/33] Add X-Requested-With param and IFrame middleware
---
README.md | 8 +++
lib/jquery/fileupload/rails/middleware.rb | 59 +++++++++++++++++++
lib/jquery/fileupload/rails/upload.rb | 1 +
.../jquery.iframe-transport.js | 7 +++
4 files changed, 75 insertions(+)
create mode 100644 lib/jquery/fileupload/rails/middleware.rb
diff --git a/README.md b/README.md
index 936b58b..ec2a088 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,14 @@ Require the stylesheet file to app/assets/stylesheets/application.css
*= require jquery.fileupload-ui
+## Using the middleware
+
+The `jquery.iframe-transport` fallback transport has some special caveats regarding the response data type, http status, and character encodings. `jquery-fileupload-rails` includes a middleware that handles these inconsistencies seamlessly. If you decide to use it, create an initializer that adds the middleware to your application's middleware stack.
+
+ ````ruby
+ Rails.application.config.middleware.use JQuery::FileUpload::Rails::Middleware
+ ````
+
## [Example app](https://github.com/tors/jquery-fileupload-rails-paperclip-example)
This app uses paperclip and twitter-bootstrap-rails
diff --git a/lib/jquery/fileupload/rails/middleware.rb b/lib/jquery/fileupload/rails/middleware.rb
new file mode 100644
index 0000000..334ea67
--- /dev/null
+++ b/lib/jquery/fileupload/rails/middleware.rb
@@ -0,0 +1,59 @@
+module JQuery
+ module FileUpload
+ module Rails
+ class Middleware
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ dup._call(env)
+ end
+
+ def _call(env)
+ @status, @headers, @response = @app.call(env)
+ @request = Rack::Request.new(env)
+
+ if iframe_transport?
+ @headers['Content-Type'] = 'text/html'
+ [@status, @headers, self]
+ else
+ [@status, @headers, @response]
+ end
+ end
+
+ def each(&block)
+ block.call(html_document_left) if iframe_transport?
+ @response.each(&block)
+ block.call(html_document_right) if iframe_transport?
+ end
+
+ def iframe_transport?
+ @request.params['X-Requested-With'] == 'IFrame'
+ end
+
+ def html_document_left
+ ""
+ end
+
+ def metadata
+ meta = {}
+ meta['data-status'] = @response.status if @response.respond_to? :status
+ meta['data-statusText'] = @response.status_message if @response.respond_to? :status_message
+ meta['data-type'] = @headers['Content-Type'] if @headers.has_key?('Content-Type')
+ meta.map {|key,value| "#{key}='#{value}'" }.join(' ')
+ end
+
+ private
+
+ def method_missing(method, *args)
+ @response.send(method.intern, *args)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/jquery/fileupload/rails/upload.rb b/lib/jquery/fileupload/rails/upload.rb
index bd8adcb..f02d383 100644
--- a/lib/jquery/fileupload/rails/upload.rb
+++ b/lib/jquery/fileupload/rails/upload.rb
@@ -1,2 +1,3 @@
require "jquery/fileupload/rails/engine"
require "jquery/fileupload/rails/version"
+require "jquery/fileupload/rails/middleware"
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js b/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
index 4749f46..3b10b5c 100644
--- a/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
+++ b/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
@@ -96,6 +96,13 @@
.val(field.value)
.appendTo(form);
});
+ // Add a hidden `X-Requested-With` field with the value `IFrame` to the
+ // form, to help server-side code to determine that the upload happened
+ // through this transport.
+ $('')
+ .prop('name', 'X-Requested-With')
+ .val('IFrame')
+ .appendTo(form);
}
if (options.fileInput && options.fileInput.length &&
options.type === 'POST') {
From 3a5519c75b62cd98f936695c327facba5da41ee6 Mon Sep 17 00:00:00 2001
From: Duncan Beevers
Date: Wed, 5 Dec 2012 16:37:18 -0600
Subject: [PATCH 24/33] Fix code sample formatting in README
---
README.md | 2 --
1 file changed, 2 deletions(-)
diff --git a/README.md b/README.md
index ec2a088..76500b8 100644
--- a/README.md
+++ b/README.md
@@ -52,9 +52,7 @@ Require the stylesheet file to app/assets/stylesheets/application.css
The `jquery.iframe-transport` fallback transport has some special caveats regarding the response data type, http status, and character encodings. `jquery-fileupload-rails` includes a middleware that handles these inconsistencies seamlessly. If you decide to use it, create an initializer that adds the middleware to your application's middleware stack.
- ````ruby
Rails.application.config.middleware.use JQuery::FileUpload::Rails::Middleware
- ````
## [Example app](https://github.com/tors/jquery-fileupload-rails-paperclip-example)
This app uses paperclip and twitter-bootstrap-rails
From 4425d7cf95ab4aae61fbebeedc825876d6f8b196 Mon Sep 17 00:00:00 2001
From: Tors Dalid
Date: Thu, 6 Dec 2012 20:48:40 +0800
Subject: [PATCH 25/33] bump version to include @duncanbeevers middleware
---
lib/jquery/fileupload/rails/version.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/jquery/fileupload/rails/version.rb b/lib/jquery/fileupload/rails/version.rb
index e037147..c802048 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.3.6"
+ VERSION = "0.4.0"
end
end
end
From 9645a2d372454a15f12a702ecc2cf12d10ff255f Mon Sep 17 00:00:00 2001
From: Igor Davydov
Date: Mon, 10 Dec 2012 16:17:33 +0400
Subject: [PATCH 26/33] using sass for stylesheet
---
...jquery.fileupload-ui.css.erb => jquery.fileupload-ui.scss} | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
rename vendor/assets/stylesheets/{jquery.fileupload-ui.css.erb => jquery.fileupload-ui.scss} (91%)
diff --git a/vendor/assets/stylesheets/jquery.fileupload-ui.css.erb b/vendor/assets/stylesheets/jquery.fileupload-ui.scss
similarity index 91%
rename from vendor/assets/stylesheets/jquery.fileupload-ui.css.erb
rename to vendor/assets/stylesheets/jquery.fileupload-ui.scss
index 5ebe411..58a7315 100644
--- a/vendor/assets/stylesheets/jquery.fileupload-ui.css.erb
+++ b/vendor/assets/stylesheets/jquery.fileupload-ui.scss
@@ -37,7 +37,7 @@
width: 200px;
}
.progress-animated .bar {
- background: url(<%= asset_path 'progressbar.gif' %>) !important;
+ background: image-url('progressbar.gif') !important;
filter: none;
}
.fileupload-loading {
@@ -45,7 +45,7 @@
left: 50%;
width: 128px;
height: 128px;
- background: url(<%= asset_path 'loading.gif' %>) center no-repeat;
+ background: image-url('loading.gif') center no-repeat;
display: none;
}
.fileupload-processing .fileupload-loading {
From e3d1258a269c0199679013a23cc6f28e61448ac5 Mon Sep 17 00:00:00 2001
From: Lars Mueller
Date: Fri, 25 Jan 2013 09:04:50 +0100
Subject: [PATCH 27/33] Updating to latest jquery fileupload version
---
.../cors/jquery.postmessage-transport.js | 0
.../cors/jquery.xdr-transport.js | 12 +-
.../jquery-fileupload/jquery.fileupload-fp.js | 0
.../jquery-fileupload/jquery.fileupload-ui.js | 116 ++++++++++++++----
.../jquery-fileupload/jquery.fileupload.js | 114 ++++++++++++-----
.../jquery.iframe-transport.js | 34 ++---
.../vendor/jquery.ui.widget.js | 96 ++++++++-------
7 files changed, 253 insertions(+), 119 deletions(-)
mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js
mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js
mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js
mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js
mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js
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 100644
new mode 100755
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 100644
new mode 100755
index c42c548..d769f45
--- a/vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js
+++ b/vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js
@@ -1,5 +1,5 @@
/*
- * jQuery XDomainRequest Transport Plugin 1.1.2
+ * jQuery XDomainRequest Transport Plugin 1.1.3
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
@@ -36,6 +36,7 @@
var xdr;
return {
send: function (headers, completeCallback) {
+ var addParamChar = /\?/.test(s.url) ? '&' : '?';
function callback(status, statusText, responses, responseHeaders) {
xdr.onload = xdr.onerror = xdr.ontimeout = $.noop;
xdr = null;
@@ -44,12 +45,13 @@
xdr = new XDomainRequest();
// XDomainRequest only supports GET and POST:
if (s.type === 'DELETE') {
- s.url = s.url + (/\?/.test(s.url) ? '&' : '?') +
- '_method=DELETE';
+ s.url = s.url + addParamChar + '_method=DELETE';
s.type = 'POST';
} else if (s.type === 'PUT') {
- s.url = s.url + (/\?/.test(s.url) ? '&' : '?') +
- '_method=PUT';
+ s.url = s.url + addParamChar + '_method=PUT';
+ s.type = 'POST';
+ } else if (s.type === 'PATCH') {
+ s.url = s.url + addParamChar + '_method=PATCH';
s.type = 'POST';
}
xdr.open(s.type, s.url);
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
old mode 100644
new mode 100755
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js
old mode 100644
new mode 100755
index ad7f2f8..a23efdb
--- 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.11
+ * jQuery File Upload User Interface Plugin 7.3
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
@@ -83,7 +83,8 @@
// widget (via file input selection, drag & drop or add API call).
// See the basic file upload widget for more information:
add: function (e, data) {
- var that = $(this).data('fileupload'),
+ var that = $(this).data('blueimp-fileupload') ||
+ $(this).data('fileupload'),
options = that.options,
files = data.files;
$(this).fileupload('process', data).done(function () {
@@ -94,7 +95,7 @@
options.filesContainer[
options.prependFiles ? 'prepend' : 'append'
](data.context);
- that._renderPreviews(files, data.context);
+ that._renderPreviews(data);
that._forceReflow(data.context);
that._transition(data.context).done(
function () {
@@ -109,7 +110,8 @@
},
// Callback for the start of each file upload request:
send: function (e, data) {
- var that = $(this).data('fileupload');
+ var that = $(this).data('blueimp-fileupload') ||
+ $(this).data('fileupload');
if (!data.isValidated) {
if (!data.maxNumberOfFilesAdjusted) {
that._adjustMaxNumberOfFiles(-data.files.length);
@@ -138,13 +140,16 @@
},
// Callback for successful uploads:
done: function (e, data) {
- var that = $(this).data('fileupload'),
- template;
+ var that = $(this).data('blueimp-fileupload') ||
+ $(this).data('fileupload'),
+ files = that._getFilesFromResponse(data),
+ template,
+ deferred;
if (data.context) {
data.context.each(function (index) {
- var file = ($.isArray(data.result) &&
- data.result[index]) ||
- {error: 'Empty file upload result'};
+ var file = files[index] ||
+ {error: 'Empty file upload result'},
+ deferred = that._addFinishedDeferreds();
if (file.error) {
that._adjustMaxNumberOfFiles(1);
}
@@ -158,14 +163,16 @@
function () {
data.context = $(this);
that._trigger('completed', e, data);
+ that._trigger('finished', e, data);
+ deferred.resolve();
}
);
}
);
});
} else {
- if ($.isArray(data.result)) {
- $.each(data.result, function (index, file) {
+ if (files.length) {
+ $.each(files, function (index, file) {
if (data.maxNumberOfFilesAdjusted && file.error) {
that._adjustMaxNumberOfFiles(1);
} else if (!data.maxNumberOfFilesAdjusted &&
@@ -175,21 +182,26 @@
});
data.maxNumberOfFilesAdjusted = true;
}
- template = that._renderDownload(data.result)
+ template = that._renderDownload(files)
.appendTo(that.options.filesContainer);
that._forceReflow(template);
+ deferred = that._addFinishedDeferreds();
that._transition(template).done(
function () {
data.context = $(this);
that._trigger('completed', e, data);
+ that._trigger('finished', e, data);
+ deferred.resolve();
}
);
}
},
// Callback for failed (abort or error) uploads:
fail: function (e, data) {
- var that = $(this).data('fileupload'),
- template;
+ var that = $(this).data('blueimp-fileupload') ||
+ $(this).data('fileupload'),
+ template,
+ deferred;
if (data.maxNumberOfFilesAdjusted) {
that._adjustMaxNumberOfFiles(data.files.length);
}
@@ -199,6 +211,7 @@
var file = data.files[index];
file.error = file.error || data.errorThrown ||
true;
+ deferred = that._addFinishedDeferreds();
that._transition($(this)).done(
function () {
var node = $(this);
@@ -209,15 +222,20 @@
function () {
data.context = $(this);
that._trigger('failed', e, data);
+ that._trigger('finished', e, data);
+ deferred.resolve();
}
);
}
);
} else {
+ deferred = that._addFinishedDeferreds();
that._transition($(this)).done(
function () {
$(this).remove();
that._trigger('failed', e, data);
+ that._trigger('finished', e, data);
+ deferred.resolve();
}
);
}
@@ -227,14 +245,19 @@
.appendTo(that.options.filesContainer)
.data('data', data);
that._forceReflow(data.context);
+ deferred = that._addFinishedDeferreds();
that._transition(data.context).done(
function () {
data.context = $(this);
that._trigger('failed', e, data);
+ that._trigger('finished', e, data);
+ deferred.resolve();
}
);
} else {
that._trigger('failed', e, data);
+ that._trigger('finished', e, data);
+ that._addFinishedDeferreds().resolve();
}
},
// Callback for upload progress events:
@@ -258,7 +281,8 @@
.find('.progress-extended');
if (extendedProgressNode.length) {
extendedProgressNode.html(
- $this.data('fileupload')._renderExtendedProgress(data)
+ ($this.data('blueimp-fileupload') || $this.data('fileupload'))
+ ._renderExtendedProgress(data)
);
}
globalProgressNode
@@ -271,7 +295,9 @@
},
// Callback for uploads start, equivalent to the global ajaxStart event:
start: function (e) {
- var that = $(this).data('fileupload');
+ var that = $(this).data('blueimp-fileupload') ||
+ $(this).data('fileupload');
+ that._resetFinishedDeferreds();
that._transition($(this).find('.fileupload-progress')).done(
function () {
that._trigger('started', e);
@@ -280,20 +306,27 @@
},
// Callback for uploads stop, equivalent to the global ajaxStop event:
stop: function (e) {
- var that = $(this).data('fileupload');
+ var that = $(this).data('blueimp-fileupload') ||
+ $(this).data('fileupload'),
+ deferred = that._addFinishedDeferreds();
+ $.when.apply($, that._getFinishedDeferreds())
+ .done(function () {
+ that._trigger('stopped', e);
+ });
that._transition($(this).find('.fileupload-progress')).done(
function () {
$(this).find('.progress')
.attr('aria-valuenow', '0')
.find('.bar').css('width', '0%');
$(this).find('.progress-extended').html(' ');
- that._trigger('stopped', e);
+ deferred.resolve();
}
);
},
// Callback for file deletion:
destroy: function (e, data) {
- var that = $(this).data('fileupload');
+ var that = $(this).data('blueimp-fileupload') ||
+ $(this).data('fileupload');
if (data.url) {
$.ajax(data);
that._adjustMaxNumberOfFiles(1);
@@ -307,6 +340,29 @@
}
},
+ _resetFinishedDeferreds: function () {
+ this._finishedUploads = [];
+ },
+
+ _addFinishedDeferreds: function (deferred) {
+ if (!deferred) {
+ deferred = $.Deferred();
+ }
+ this._finishedUploads.push(deferred);
+ return deferred;
+ },
+
+ _getFinishedDeferreds: function () {
+ return this._finishedUploads;
+ },
+
+ _getFilesFromResponse: function (data) {
+ if (data.result && $.isArray(data.result.files)) {
+ return data.result.files;
+ }
+ return [];
+ },
+
// Link handler, that allows to download files
// by drag & drop of the links to the desktop:
_enableDragToDesktop: function () {
@@ -361,7 +417,7 @@
if (bits >= 1000) {
return (bits / 1000).toFixed(2) + ' kbit/s';
}
- return bits + ' bit/s';
+ return bits.toFixed(2) + ' bit/s';
},
_formatTime: function (seconds) {
@@ -472,18 +528,22 @@
)) || dfd.resolveWith(node)) && dfd;
},
- _renderPreviews: function (files, nodes) {
+ _renderPreviews: function (data) {
var that = this,
options = this.options;
- nodes.find('.preview span').each(function (index, element) {
- var file = files[index];
+ data.context.find('.preview span').each(function (index, element) {
+ var file = data.files[index];
if (options.previewSourceFileTypes.test(file.type) &&
($.type(options.previewSourceMaxFileSize) !== 'number' ||
file.size < options.previewSourceMaxFileSize)) {
that._processingQueue = that._processingQueue.pipe(function () {
- var dfd = $.Deferred();
+ var dfd = $.Deferred(),
+ ev = $.Event('previewdone', {
+ target: element
+ });
that._renderPreview(file, $(element)).done(
function () {
+ that._trigger(ev.type, ev, data);
dfd.resolveWith(that);
}
);
@@ -691,6 +751,13 @@
this._initRegExpOptions();
},
+ _setOption: function (key, value) {
+ this._super(key, value);
+ if (key === 'maxNumberOfFiles') {
+ this._adjustMaxNumberOfFiles(0);
+ }
+ },
+
_create: function () {
this._super();
this._refreshOptionsList.push(
@@ -704,6 +771,7 @@
return this._processingQueue;
};
}
+ this._resetFinishedDeferreds();
},
enable: function () {
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js
old mode 100644
new mode 100755
index 6356012..04caf69
--- 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.19.3
+ * jQuery File Upload Plugin 5.21
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
@@ -10,7 +10,7 @@
*/
/*jslint nomen: true, unparam: true, regexp: true */
-/*global define, window, document, Blob, FormData, location */
+/*global define, window, document, File, Blob, FormData, location */
(function (factory) {
'use strict';
@@ -33,6 +33,21 @@
$.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader);
$.support.xhrFormDataFileUpload = !!window.FormData;
+ // The form.elements propHook is added to filter serialized elements
+ // to not include file inputs in jQuery 1.9.0.
+ // This hooks directly into jQuery.fn.serializeArray.
+ // For more info, see http://bugs.jquery.com/ticket/13306
+ $.propHooks.elements = {
+ get: function (form) {
+ if ($.nodeName(form, 'form')) {
+ return $.grep(form.elements, function (elem) {
+ return !$.nodeName(elem, 'input') || elem.type !== 'file';
+ });
+ }
+ return null;
+ }
+ };
+
// 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
@@ -140,33 +155,58 @@
},
// Other callbacks:
+
// Callback for the submit event of each file upload:
// submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
+
// Callback for the start of each file upload request:
// send: function (e, data) {}, // .bind('fileuploadsend', func);
+
// Callback for successful uploads:
// done: function (e, data) {}, // .bind('fileuploaddone', func);
+
// Callback for failed (abort or error) uploads:
// fail: function (e, data) {}, // .bind('fileuploadfail', func);
+
// Callback for completed (success, abort or error) requests:
// always: function (e, data) {}, // .bind('fileuploadalways', func);
+
// Callback for upload progress events:
// progress: function (e, data) {}, // .bind('fileuploadprogress', func);
+
// Callback for global upload progress events:
// progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
+
// Callback for uploads start, equivalent to the global ajaxStart event:
// start: function (e) {}, // .bind('fileuploadstart', func);
+
// Callback for uploads stop, equivalent to the global ajaxStop event:
// stop: function (e) {}, // .bind('fileuploadstop', func);
+
// Callback for change events of the fileInput(s):
// change: function (e, data) {}, // .bind('fileuploadchange', func);
+
// Callback for paste events to the pasteZone(s):
// paste: function (e, data) {}, // .bind('fileuploadpaste', func);
+
// Callback for drop events of the dropZone(s):
// drop: function (e, data) {}, // .bind('fileuploaddrop', func);
+
// Callback for dragover events of the dropZone(s):
// dragover: function (e) {}, // .bind('fileuploaddragover', func);
+ // Callback for the start of each chunk upload request:
+ // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);
+
+ // Callback for successful chunk uploads:
+ // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);
+
+ // Callback for failed (abort or error) chunk uploads:
+ // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);
+
+ // Callback for completed (success, abort or error) chunk upload requests:
+ // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);
+
// The plugin options are used as settings object for the ajax calls.
// The following are jQuery ajax settings required for the file uploads:
processData: false,
@@ -209,10 +249,10 @@
if (typeof options.formData === 'function') {
return options.formData(options.form);
}
- if ($.isArray(options.formData)) {
+ if ($.isArray(options.formData)) {
return options.formData;
}
- if (options.formData) {
+ if (options.formData) {
formData = [];
$.each(options.formData, function (name, value) {
formData.push({name: name, value: value});
@@ -341,14 +381,15 @@
if (options.blob) {
options.headers['Content-Disposition'] = 'attachment; filename="' +
encodeURI(file.name) + '"';
- options.headers['Content-Description'] = encodeURI(file.type);
formData.append(paramName, options.blob, file.name);
} else {
$.each(options.files, function (index, file) {
- // File objects are also Blob instances.
+ // Files are also Blob instances, but some browsers
+ // (Firefox 3.6) support the File API but not Blobs.
// This check allows the tests to run with
// dummy objects:
- if (file instanceof Blob) {
+ if ((window.Blob && file instanceof Blob) ||
+ (window.File && file instanceof File)) {
formData.append(
options.paramName[index] || paramName,
file,
@@ -438,7 +479,8 @@
// The HTTP request method must be "POST" or "PUT":
options.type = (options.type || options.form.prop('method') || '')
.toUpperCase();
- if (options.type !== 'POST' && options.type !== 'PUT') {
+ if (options.type !== 'POST' && options.type !== 'PUT' &&
+ options.type !== 'PATCH') {
options.type = 'POST';
}
if (!options.formAcceptCharset) {
@@ -525,7 +567,8 @@
o.blob = slice.call(
file,
ub,
- ub + mcs
+ ub + mcs,
+ file.type
);
// Store the current chunk size, as the blob itself
// will be dereferenced after data processing:
@@ -537,13 +580,15 @@
that._initXHRData(o);
// Add progress listeners for this chunk upload:
that._initProgressListener(o);
- jqXHR = ($.ajax(o) || that._getXHRPromise(false, o.context))
+ jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||
+ that._getXHRPromise(false, o.context))
.done(function (result, textStatus, jqXHR) {
ub = that._getUploadedBytes(jqXHR) ||
(ub + o.chunkSize);
- // Create a progress event if upload is done and
- // no progress event has been invoked for this chunk:
- if (!o.loaded) {
+ // Create a progress event if upload is done and no progress
+ // event has been invoked for this chunk, or there has been
+ // no progress event with loaded equaling total:
+ if (!o.loaded || o.loaded < o.total) {
that._onProgress($.Event('progress', {
lengthComputable: true,
loaded: ub - o.uploadedBytes,
@@ -551,6 +596,11 @@
}), o);
}
options.uploadedBytes = o.uploadedBytes = ub;
+ o.result = result;
+ o.textStatus = textStatus;
+ o.jqXHR = jqXHR;
+ that._trigger('chunkdone', null, o);
+ that._trigger('chunkalways', null, o);
if (ub < fs) {
// File upload not yet complete,
// continue with the next chunk:
@@ -563,6 +613,11 @@
}
})
.fail(function (jqXHR, textStatus, errorThrown) {
+ o.jqXHR = jqXHR;
+ o.textStatus = textStatus;
+ o.errorThrown = errorThrown;
+ that._trigger('chunkfail', null, o);
+ that._trigger('chunkalways', null, o);
dfd.rejectWith(
o.context,
[jqXHR, textStatus, errorThrown]
@@ -593,12 +648,16 @@
},
_onDone: function (result, textStatus, jqXHR, options) {
- if (!this._isXHRUpload(options)) {
- // Create a progress event for each iframe load:
+ if (!this._isXHRUpload(options) || !options.loaded ||
+ options.loaded < options.total) {
+ var total = this._getTotal(options.files) || 1;
+ // Create a progress event for each iframe load,
+ // or if there has been no progress event with
+ // loaded equaling total for XHR uploads:
this._onProgress($.Event('progress', {
lengthComputable: true,
- loaded: 1,
- total: 1
+ loaded: total,
+ total: total
}), options);
}
options.result = result;
@@ -621,15 +680,9 @@
},
_onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
+ // jqXHRorResult, textStatus and jqXHRorError are added to the
+ // options object via done and fail callbacks
this._active -= 1;
- options.textStatus = textStatus;
- if (jqXHRorError && jqXHRorError.always) {
- options.jqXHR = jqXHRorError;
- options.result = jqXHRorResult;
- } else {
- options.jqXHR = jqXHRorResult;
- options.errorThrown = jqXHRorError;
- }
this._trigger('always', null, options);
if (this._active === 0) {
// The stop callback is triggered when all uploads have
@@ -758,7 +811,8 @@
that._onSend(e, this);
return this.jqXHR;
};
- return (result = that._trigger('add', e, newData));
+ result = that._trigger('add', e, newData);
+ return result;
});
return result;
},
@@ -949,10 +1003,12 @@
},
_onDrop: function (e) {
- e.preventDefault();
var that = this,
dataTransfer = e.dataTransfer = e.originalEvent.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) {
@@ -966,10 +1022,10 @@
if (this._trigger('dragover', e) === false) {
return false;
}
- if (dataTransfer) {
+ if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1) {
dataTransfer.dropEffect = 'copy';
+ e.preventDefault();
}
- e.preventDefault();
},
_initEventHandlers: function () {
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js b/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
old mode 100644
new mode 100755
index 3b10b5c..ed25895
--- 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.5
+ * jQuery Iframe Transport Plugin 1.6.1
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
@@ -36,13 +36,26 @@
// equivalent to the return data of .serializeArray(), e.g.:
// [{name: 'a', value: 1}, {name: 'b', value: 2}]
$.ajaxTransport('iframe', function (options) {
- if (options.async && (options.type === 'POST' || options.type === 'GET')) {
+ if (options.async) {
var form,
- iframe;
+ iframe,
+ addParamChar;
return {
send: function (_, completeCallback) {
form = $('');
form.attr('accept-charset', options.formAcceptCharset);
+ addParamChar = /\?/.test(options.url) ? '&' : '?';
+ // XDomainRequest only supports GET and POST:
+ if (options.type === 'DELETE') {
+ options.url = options.url + addParamChar + '_method=DELETE';
+ options.type = 'POST';
+ } else if (options.type === 'PUT') {
+ options.url = options.url + addParamChar + '_method=PUT';
+ options.type = 'POST';
+ } else if (options.type === 'PATCH') {
+ 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
@@ -96,13 +109,6 @@
.val(field.value)
.appendTo(form);
});
- // Add a hidden `X-Requested-With` field with the value `IFrame` to the
- // form, to help server-side code to determine that the upload happened
- // through this transport.
- $('')
- .prop('name', 'X-Requested-With')
- .val('IFrame')
- .appendTo(form);
}
if (options.fileInput && options.fileInput.length &&
options.type === 'POST') {
@@ -162,16 +168,16 @@
$.ajaxSetup({
converters: {
'iframe text': function (iframe) {
- return $(iframe[0].body).text();
+ return iframe && $(iframe[0].body).text();
},
'iframe json': function (iframe) {
- return $.parseJSON($(iframe[0].body).text());
+ return iframe && $.parseJSON($(iframe[0].body).text());
},
'iframe html': function (iframe) {
- return $(iframe[0].body).html();
+ return iframe && $(iframe[0].body).html();
},
'iframe script': function (iframe) {
- return $.globalEval($(iframe[0].body).text());
+ 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
old mode 100644
new mode 100755
index 886aff6..f5d71a1
--- 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.9.1+amd
+ * jQuery UI Widget 1.10.0+amd
* https://github.com/blueimp/jQuery-File-Upload
*
- * Copyright 2012 jQuery Foundation and other contributors
+ * Copyright 2013 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
@@ -34,6 +34,9 @@ $.cleanData = function( elems ) {
$.widget = function( name, base, prototype ) {
var fullName, existingConstructor, constructor, basePrototype,
+ // proxiedPrototype allows the provided prototype to remain unmodified
+ // so that it can be used as a mixin for multiple widgets (#8876)
+ proxiedPrototype = {},
namespace = name.split( "." )[ 0 ];
name = name.split( "." )[ 1 ];
@@ -80,43 +83,43 @@ $.widget = function( name, base, prototype ) {
// inheriting from
basePrototype.options = $.widget.extend( {}, basePrototype.options );
$.each( prototype, function( prop, value ) {
- if ( $.isFunction( value ) ) {
- prototype[ prop ] = (function() {
- var _super = function() {
- return base.prototype[ prop ].apply( this, arguments );
- },
- _superApply = function( args ) {
- return base.prototype[ prop ].apply( this, args );
- };
- return function() {
- var __super = this._super,
- __superApply = this._superApply,
- returnValue;
-
- this._super = _super;
- this._superApply = _superApply;
-
- returnValue = value.apply( this, arguments );
-
- this._super = __super;
- this._superApply = __superApply;
-
- return returnValue;
- };
- })();
+ if ( !$.isFunction( value ) ) {
+ proxiedPrototype[ prop ] = value;
+ return;
}
+ proxiedPrototype[ prop ] = (function() {
+ var _super = function() {
+ return base.prototype[ prop ].apply( this, arguments );
+ },
+ _superApply = function( args ) {
+ return base.prototype[ prop ].apply( this, args );
+ };
+ return function() {
+ var __super = this._super,
+ __superApply = this._superApply,
+ returnValue;
+
+ this._super = _super;
+ this._superApply = _superApply;
+
+ returnValue = value.apply( this, arguments );
+
+ this._super = __super;
+ this._superApply = __superApply;
+
+ return returnValue;
+ };
+ })();
});
constructor.prototype = $.widget.extend( basePrototype, {
// 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: basePrototype.widgetEventPrefix || name
- }, prototype, {
+ widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
+ }, proxiedPrototype, {
constructor: constructor,
namespace: namespace,
widgetName: name,
- // TODO remove widgetBaseClass, see #8155
- widgetBaseClass: fullName,
widgetFullName: fullName
});
@@ -169,7 +172,7 @@ $.widget.extend = function( target ) {
};
$.widget.bridge = function( name, object ) {
- var fullName = object.prototype.widgetFullName;
+ var fullName = object.prototype.widgetFullName || name;
$.fn[ name ] = function( options ) {
var isMethodCall = typeof options === "string",
args = slice.call( arguments, 1 ),
@@ -205,7 +208,7 @@ $.widget.bridge = function( name, object ) {
if ( instance ) {
instance.option( options || {} )._init();
} else {
- new object( options, this );
+ $.data( this, fullName, new object( options, this ) );
}
});
}
@@ -242,11 +245,8 @@ $.Widget.prototype = {
this.focusable = $();
if ( element !== this ) {
- // 1.9 BC for #7810
- // TODO remove dual storage
- $.data( element, this.widgetName, this );
$.data( element, this.widgetFullName, this );
- this._on( this.element, {
+ this._on( true, this.element, {
remove: function( event ) {
if ( event.target === element ) {
this.destroy();
@@ -370,9 +370,17 @@ $.Widget.prototype = {
return this._setOption( "disabled", true );
},
- _on: function( element, handlers ) {
+ _on: function( suppressDisabledCheck, element, handlers ) {
var delegateElement,
instance = this;
+
+ // no suppressDisabledCheck flag, shuffle arguments
+ if ( typeof suppressDisabledCheck !== "boolean" ) {
+ handlers = element;
+ element = suppressDisabledCheck;
+ suppressDisabledCheck = false;
+ }
+
// no element argument, shuffle and use this.element
if ( !handlers ) {
handlers = element;
@@ -389,8 +397,9 @@ $.Widget.prototype = {
// allow widgets to customize the disabled handling
// - disabled as an array instead of boolean
// - disabled class as method for disabling individual parts
- if ( instance.options.disabled === true ||
- $( this ).hasClass( "ui-state-disabled" ) ) {
+ if ( !suppressDisabledCheck &&
+ ( instance.options.disabled === true ||
+ $( this ).hasClass( "ui-state-disabled" ) ) ) {
return;
}
return ( typeof handler === "string" ? instance[ handler ] : handler )
@@ -502,7 +511,7 @@ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
if ( options.delay ) {
element.delay( options.delay );
}
- if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
+ if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
element[ method ]( options );
} else if ( effectName !== method && element[ effectName ] ) {
element[ effectName ]( options.duration, options.easing, callback );
@@ -518,11 +527,4 @@ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
};
});
-// DEPRECATED
-if ( $.uiBackCompat !== false ) {
- $.Widget.prototype._getCreateOptions = function() {
- return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
- };
-}
-
}));
From d99117f29e74778d16361b0d75e46875dcc87101 Mon Sep 17 00:00:00 2001
From: Tors Dalid
Date: Mon, 18 Feb 2013 13:17:01 +0800
Subject: [PATCH 28/33] bump version
---
lib/jquery/fileupload/rails/version.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/jquery/fileupload/rails/version.rb b/lib/jquery/fileupload/rails/version.rb
index c802048..10fbdc9 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.0"
+ VERSION = "0.4.1"
end
end
end
From 9d5aa4476f429dca0a371b4d124588990b45bc6b Mon Sep 17 00:00:00 2001
From: John Rees
Date: Thu, 28 Feb 2013 17:09:39 +0100
Subject: [PATCH 29/33] Added spaces to sprockets //=require
---
README.md | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/README.md b/README.md
index 76500b8..4207f35 100644
--- a/README.md
+++ b/README.md
@@ -22,25 +22,25 @@ Require jquery-fileupload in your app/assets/application.js file.
The snippet above will add the following js files to the mainfest file.
- //=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-fp
+ //= require jquery-fileupload/jquery.fileupload-ui
+ //= require jquery-fileupload/locale
If you only need the basic files, just add the code below to your application.js file. [Basic setup guide](https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin)
- //=require jquery-fileupload/basic
+ //= require jquery-fileupload/basic
The basic setup only includes the following files:
- //=require jquery-fileupload/vendor/jquery.ui.widget
- //=require jquery-fileupload/jquery.iframe-transport
- //=require jquery-fileupload/jquery.fileupload
+ //= require jquery-fileupload/vendor/jquery.ui.widget
+ //= require jquery-fileupload/jquery.iframe-transport
+ //= require jquery-fileupload/jquery.fileupload
## Using the stylesheet
From 0ceda3515bc2cbebbb799081e3443ce3d3c7f929 Mon Sep 17 00:00:00 2001
From: Christopher Manning
Date: Sun, 24 Mar 2013 16:45:04 -0500
Subject: [PATCH 30/33] Update javascript assets from master
---
.../cors/jquery.postmessage-transport.js | 0
.../cors/jquery.xdr-transport.js | 0
.../jquery-fileupload/jquery.fileupload-fp.js | 12 +-
.../jquery-fileupload/jquery.fileupload-ui.js | 36 ++-
.../jquery-fileupload/jquery.fileupload.js | 249 +++++++++++-------
.../jquery.iframe-transport.js | 0
.../vendor/canvas-to-blob.js | 14 +-
.../vendor/jquery.ui.widget.js | 2 +-
.../jquery-fileupload/vendor/load-image.js | 135 +++++++++-
9 files changed, 320 insertions(+), 128 deletions(-)
mode change 100755 => 100644 vendor/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js
mode change 100755 => 100644 vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js
mode change 100755 => 100644 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
mode change 100755 => 100644 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js
mode change 100755 => 100644 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js
mode change 100755 => 100644 vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
mode change 100755 => 100644 vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js
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
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
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
old mode 100755
new mode 100644
index fdf18fb..c782f1e
--- a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
+++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
@@ -1,5 +1,5 @@
/*
- * jQuery File Upload File Processing Plugin 1.2.1
+ * jQuery File Upload File Processing Plugin 1.2.3
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2012, Sebastian Tschan
@@ -62,9 +62,13 @@
// 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();
- });
+ if (data.autoUpload || (data.autoUpload !== false &&
+ ($(this).data('blueimp-fileupload') ||
+ $(this).data('fileupload')).options.autoUpload)) {
+ $(this).fileupload('process', data).done(function () {
+ data.submit();
+ });
+ }
}
},
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 a23efdb..0386fb2
--- 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 7.3
+ * jQuery File Upload User Interface Plugin 7.4.1
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
@@ -263,7 +263,7 @@
// Callback for upload progress events:
progress: function (e, data) {
if (data.context) {
- var progress = parseInt(data.loaded / data.total * 100, 10);
+ var progress = Math.floor(data.loaded / data.total * 100);
data.context.find('.progress')
.attr('aria-valuenow', progress)
.find('.bar').css(
@@ -275,7 +275,7 @@
// Callback for global upload progress events:
progressall: function (e, data) {
var $this = $(this),
- progress = parseInt(data.loaded / data.total * 100, 10),
+ progress = Math.floor(data.loaded / data.total * 100),
globalProgressNode = $this.find('.fileupload-progress'),
extendedProgressNode = globalProgressNode
.find('.progress-extended');
@@ -422,7 +422,7 @@
_formatTime: function (seconds) {
var date = new Date(seconds * 1000),
- days = parseInt(seconds / 86400, 10);
+ days = Math.floor(seconds / 86400);
days = days ? days + 'd ' : '';
return days +
('0' + date.getUTCHours()).slice(-2) + ':' +
@@ -519,6 +519,12 @@
// so we have to resolve manually:
dfd.resolveWith(node);
}
+ node.on('remove', function () {
+ // If the element is removed before the
+ // transition finishes, transition events are
+ // not triggered, resolve manually:
+ dfd.resolveWith(node);
+ });
},
{
maxWidth: options.previewMaxWidth,
@@ -607,7 +613,7 @@
_transition: function (node) {
var dfd = $.Deferred();
- if ($.support.transition && node.hasClass('fade')) {
+ if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {
node.bind(
$.support.transition.end,
function (e) {
@@ -632,27 +638,28 @@
this._on(fileUploadButtonBar.find('.start'), {
click: function (e) {
e.preventDefault();
- filesList.find('.start button').click();
+ filesList.find('.start').click();
}
});
this._on(fileUploadButtonBar.find('.cancel'), {
click: function (e) {
e.preventDefault();
- filesList.find('.cancel button').click();
+ filesList.find('.cancel').click();
}
});
this._on(fileUploadButtonBar.find('.delete'), {
click: function (e) {
e.preventDefault();
- filesList.find('.delete input:checked')
- .siblings('button').click();
+ filesList.find('.toggle:checked')
+ .closest('.template-download')
+ .find('.delete').click();
fileUploadButtonBar.find('.toggle')
.prop('checked', false);
}
});
this._on(fileUploadButtonBar.find('.toggle'), {
change: function (e) {
- filesList.find('.delete input').prop(
+ filesList.find('.toggle').prop(
'checked',
$(e.currentTarget).is(':checked')
);
@@ -662,7 +669,8 @@
_destroyButtonBarEventHandlers: function () {
this._off(
- this.element.find('.fileupload-buttonbar button'),
+ this.element.find('.fileupload-buttonbar')
+ .find('.start, .cancel, .delete'),
'click'
);
this._off(
@@ -674,9 +682,9 @@
_initEventHandlers: function () {
this._super();
this._on(this.options.filesContainer, {
- 'click .start button': this._startHandler,
- 'click .cancel button': this._cancelHandler,
- 'click .delete button': this._deleteHandler
+ 'click .start': this._startHandler,
+ 'click .cancel': this._cancelHandler,
+ 'click .delete': this._deleteHandler
});
this._initButtonBarEventHandlers();
},
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 04caf69..dbee297
--- 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.21
+ * jQuery File Upload Plugin 5.28.4
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
@@ -33,21 +33,6 @@
$.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader);
$.support.xhrFormDataFileUpload = !!window.FormData;
- // The form.elements propHook is added to filter serialized elements
- // to not include file inputs in jQuery 1.9.0.
- // This hooks directly into jQuery.fn.serializeArray.
- // For more info, see http://bugs.jquery.com/ticket/13306
- $.propHooks.elements = {
- get: function (form) {
- if ($.nodeName(form, 'form')) {
- return $.grep(form.elements, function (elem) {
- return !$.nodeName(elem, 'input') || elem.type !== 'file';
- });
- }
- return null;
- }
- };
-
// 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
@@ -127,6 +112,8 @@
progressInterval: 100,
// Interval in milliseconds to calculate progress bitrate:
bitrateInterval: 500,
+ // By default, uploads are started automatically when adding files:
+ autoUpload: true,
// 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
@@ -151,7 +138,11 @@
// handlers using jQuery's Deferred callbacks:
// data.submit().done(func).fail(func).always(func);
add: function (e, data) {
- data.submit();
+ if (data.autoUpload || (data.autoUpload !== false &&
+ ($(this).data('blueimp-fileupload') ||
+ $(this).data('fileupload')).options.autoUpload)) {
+ data.submit();
+ }
},
// Other callbacks:
@@ -224,7 +215,7 @@
],
_BitrateTimer: function () {
- this.timestamp = +(new Date());
+ this.timestamp = (new Date()).getTime();
this.loaded = 0;
this.bitrate = 0;
this.getBitrate = function (now, loaded, interval) {
@@ -252,7 +243,7 @@
if ($.isArray(options.formData)) {
return options.formData;
}
- if (options.formData) {
+ if ($.type(options.formData) === 'object') {
formData = [];
$.each(options.formData, function (name, value) {
formData.push({name: name, value: value});
@@ -270,10 +261,35 @@
return total;
},
+ _initProgressObject: function (obj) {
+ var progress = {
+ loaded: 0,
+ total: 0,
+ bitrate: 0
+ };
+ if (obj._progress) {
+ $.extend(obj._progress, progress);
+ } else {
+ obj._progress = progress;
+ }
+ },
+
+ _initResponseObject: function (obj) {
+ var prop;
+ if (obj._response) {
+ for (prop in obj._response) {
+ if (obj._response.hasOwnProperty(prop)) {
+ delete obj._response[prop];
+ }
+ }
+ } else {
+ obj._response = {};
+ }
+ },
+
_onProgress: function (e, data) {
if (e.lengthComputable) {
- var now = +(new Date()),
- total,
+ var now = (new Date()).getTime(),
loaded;
if (data._time && data.progressInterval &&
(now - data._time < data.progressInterval) &&
@@ -281,16 +297,19 @@
return;
}
data._time = now;
- total = data.total || this._getTotal(data.files);
- loaded = parseInt(
- e.loaded / e.total * (data.chunkSize || total),
- 10
+ loaded = Math.floor(
+ e.loaded / e.total * (data.chunkSize || data._progress.total)
) + (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(
+ // Add the difference from the previously loaded state
+ // to the global loaded counter:
+ this._progress.loaded += (loaded - data._progress.loaded);
+ this._progress.bitrate = this._bitrateTimer.getBitrate(
+ now,
+ this._progress.loaded,
+ data.bitrateInterval
+ );
+ data._progress.loaded = data.loaded = loaded;
+ data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(
now,
loaded,
data.bitrateInterval
@@ -301,16 +320,7 @@
this._trigger('progress', e, data);
// Trigger a global progress event for all current file uploads,
// including ajax calls queued for sequential file uploads:
- this._trigger('progressall', e, {
- lengthComputable: true,
- loaded: this._loaded,
- total: this._total,
- bitrate: this._bitrateTimer.getBitrate(
- now,
- this._loaded,
- data.bitrateInterval
- )
- });
+ this._trigger('progressall', e, this._progress);
}
},
@@ -495,6 +505,21 @@
return options;
},
+ // jQuery 1.6 doesn't provide .state(),
+ // while jQuery 1.8+ removed .isRejected() and .isResolved():
+ _getDeferredState: function (deferred) {
+ if (deferred.state) {
+ return deferred.state();
+ }
+ if (deferred.isResolved()) {
+ return 'resolved';
+ }
+ if (deferred.isRejected()) {
+ return 'rejected';
+ }
+ return 'pending';
+ },
+
// Maps jqXHR callbacks to the equivalent
// methods of the given Promise object:
_enhancePromise: function (promise) {
@@ -519,6 +544,36 @@
return this._enhancePromise(promise);
},
+ // Adds convenience methods to the callback arguments:
+ _addConvenienceMethods: function (e, data) {
+ var that = this;
+ data.submit = function () {
+ if (this.state() !== 'pending') {
+ data.jqXHR = this.jqXHR =
+ (that._trigger('submit', e, this) !== false) &&
+ that._onSend(e, this);
+ }
+ return this.jqXHR || that._getXHRPromise();
+ };
+ data.abort = function () {
+ if (this.jqXHR) {
+ return this.jqXHR.abort();
+ }
+ return that._getXHRPromise();
+ };
+ data.state = function () {
+ if (this.jqXHR) {
+ return that._getDeferredState(this.jqXHR);
+ }
+ };
+ data.progress = function () {
+ return this._progress;
+ };
+ data.response = function () {
+ return this._response;
+ };
+ },
+
// Parses the Range header from the server response
// and returns the uploaded bytes:
_getUploadedBytes: function (jqXHR) {
@@ -561,9 +616,10 @@
);
}
// The chunk upload method:
- upload = function (i) {
+ upload = function () {
// Clone the options object for each chunk upload:
- var o = $.extend({}, options);
+ var o = $.extend({}, options),
+ currentLoaded = o._progress.loaded;
o.blob = slice.call(
file,
ub,
@@ -585,10 +641,10 @@
.done(function (result, textStatus, jqXHR) {
ub = that._getUploadedBytes(jqXHR) ||
(ub + o.chunkSize);
- // Create a progress event if upload is done and no progress
- // event has been invoked for this chunk, or there has been
- // no progress event with loaded equaling total:
- if (!o.loaded || o.loaded < o.total) {
+ // Create a progress event if no final progress event
+ // with loaded equaling total has been triggered
+ // for this chunk:
+ if (o._progress.loaded === currentLoaded) {
that._onProgress($.Event('progress', {
lengthComputable: true,
loaded: ub - o.uploadedBytes,
@@ -640,61 +696,66 @@
this._trigger('start');
// Set timer for global bitrate progress calculation:
this._bitrateTimer = new this._BitrateTimer();
+ // Reset the global progress values:
+ this._progress.loaded = this._progress.total = 0;
+ this._progress.bitrate = 0;
}
+ // Make sure the container objects for the .response() and
+ // .progress() methods on the data object are available
+ // and reset to their initial state:
+ this._initResponseObject(data);
+ this._initProgressObject(data);
+ data._progress.loaded = data.loaded = data.uploadedBytes || 0;
+ data._progress.total = data.total = this._getTotal(data.files) || 1;
+ data._progress.bitrate = data.bitrate = 0;
this._active += 1;
// Initialize the global progress values:
- this._loaded += data.uploadedBytes || 0;
- this._total += this._getTotal(data.files);
+ this._progress.loaded += data.loaded;
+ this._progress.total += data.total;
},
_onDone: function (result, textStatus, jqXHR, options) {
- if (!this._isXHRUpload(options) || !options.loaded ||
- options.loaded < options.total) {
- var total = this._getTotal(options.files) || 1;
- // Create a progress event for each iframe load,
- // or if there has been no progress event with
- // loaded equaling total for XHR uploads:
+ var total = options._progress.total,
+ response = options._response;
+ if (options._progress.loaded < total) {
+ // Create a progress event if no final progress event
+ // with loaded equaling total has been triggered:
this._onProgress($.Event('progress', {
lengthComputable: true,
loaded: total,
total: total
}), options);
}
- options.result = result;
- options.textStatus = textStatus;
- options.jqXHR = jqXHR;
+ response.result = options.result = result;
+ response.textStatus = options.textStatus = textStatus;
+ response.jqXHR = options.jqXHR = jqXHR;
this._trigger('done', null, options);
},
_onFail: function (jqXHR, textStatus, errorThrown, options) {
- options.jqXHR = jqXHR;
- options.textStatus = textStatus;
- options.errorThrown = errorThrown;
- this._trigger('fail', null, options);
+ var response = options._response;
if (options.recalculateProgress) {
// Remove the failed (error or abort) file upload from
// the global progress calculation:
- this._loaded -= options.loaded || options.uploadedBytes || 0;
- this._total -= options.total || this._getTotal(options.files);
+ this._progress.loaded -= options._progress.loaded;
+ this._progress.total -= options._progress.total;
}
+ response.jqXHR = options.jqXHR = jqXHR;
+ response.textStatus = options.textStatus = textStatus;
+ response.errorThrown = options.errorThrown = errorThrown;
+ this._trigger('fail', null, options);
},
_onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
// jqXHRorResult, textStatus and jqXHRorError are added to the
// options object via done and fail callbacks
- this._active -= 1;
this._trigger('always', null, options);
- if (this._active === 0) {
- // The stop callback is triggered when all uploads have
- // been completed, equivalent to the global ajaxStop event:
- this._trigger('stop');
- // Reset the global progress values:
- this._loaded = this._total = 0;
- this._bitrateTimer = null;
- }
},
_onSend: function (e, data) {
+ if (!data.submit) {
+ this._addConvenienceMethods(e, data);
+ }
var that = this,
jqXHR,
aborted,
@@ -714,32 +775,32 @@
}).fail(function (jqXHR, textStatus, errorThrown) {
that._onFail(jqXHR, textStatus, errorThrown, options);
}).always(function (jqXHRorResult, textStatus, jqXHRorError) {
- that._sending -= 1;
that._onAlways(
jqXHRorResult,
textStatus,
jqXHRorError,
options
);
+ that._sending -= 1;
+ that._active -= 1;
if (options.limitConcurrentUploads &&
options.limitConcurrentUploads > that._sending) {
// Start the next queued upload,
// that has not been aborted:
- var nextSlot = that._slots.shift(),
- isPending;
+ var nextSlot = that._slots.shift();
while (nextSlot) {
- // jQuery 1.6 doesn't provide .state(),
- // while jQuery 1.8+ removed .isRejected():
- isPending = nextSlot.state ?
- nextSlot.state() === 'pending' :
- !nextSlot.isRejected();
- if (isPending) {
+ if (that._getDeferredState(nextSlot) === 'pending') {
nextSlot.resolve();
break;
}
nextSlot = that._slots.shift();
}
}
+ if (that._active === 0) {
+ // The stop callback is triggered when all uploads have
+ // been completed, equivalent to the global ajaxStop event:
+ that._trigger('stop');
+ }
});
return jqXHR;
};
@@ -805,12 +866,9 @@
var newData = $.extend({}, data);
newData.files = fileSet ? element : [element];
newData.paramName = paramNameSet[index];
- newData.submit = function () {
- newData.jqXHR = this.jqXHR =
- (that._trigger('submit', e, this) !== false) &&
- that._onSend(e, this);
- return this.jqXHR;
- };
+ that._initResponseObject(newData);
+ that._initProgressObject(newData);
+ that._addConvenienceMethods(e, newData);
result = that._trigger('add', e, newData);
return result;
});
@@ -1084,12 +1142,23 @@
this._initSpecialOptions();
this._slots = [];
this._sequence = this._getXHRPromise(true);
- this._sending = this._active = this._loaded = this._total = 0;
+ this._sending = this._active = 0;
+ this._initProgressObject(this);
this._initEventHandlers();
},
- _destroy: function () {
- this._destroyEventHandlers();
+ // This method is exposed to the widget API and allows to query
+ // the number of active uploads:
+ active: function () {
+ return this._active;
+ },
+
+ // This method is exposed to the widget API and allows to query
+ // the widget upload progress.
+ // It returns an object with loaded, total and bitrate properties
+ // for the running uploads:
+ progress: function () {
+ return this._progress;
},
// This method is exposed to the widget API and allows adding files
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
diff --git a/vendor/assets/javascripts/jquery-fileupload/vendor/canvas-to-blob.js b/vendor/assets/javascripts/jquery-fileupload/vendor/canvas-to-blob.js
index 72edfdb..fcef339 100644
--- a/vendor/assets/javascripts/jquery-fileupload/vendor/canvas-to-blob.js
+++ b/vendor/assets/javascripts/jquery-fileupload/vendor/canvas-to-blob.js
@@ -1,5 +1,5 @@
/*
- * JavaScript Canvas to Blob 2.0.3
+ * JavaScript Canvas to Blob 2.0.5
* https://github.com/blueimp/JavaScript-Canvas-to-Blob
*
* Copyright 2012, Sebastian Tschan
@@ -72,12 +72,16 @@
};
if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {
if (CanvasPrototype.mozGetAsFile) {
- CanvasPrototype.toBlob = function (callback, type) {
- callback(this.mozGetAsFile('blob', type));
+ CanvasPrototype.toBlob = function (callback, type, quality) {
+ if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) {
+ callback(dataURLtoBlob(this.toDataURL(type, quality)));
+ } else {
+ callback(this.mozGetAsFile('blob', type));
+ }
};
} else if (CanvasPrototype.toDataURL && dataURLtoBlob) {
- CanvasPrototype.toBlob = function (callback, type) {
- callback(dataURLtoBlob(this.toDataURL(type)));
+ CanvasPrototype.toBlob = function (callback, type, quality) {
+ callback(dataURLtoBlob(this.toDataURL(type, quality)));
};
}
}
diff --git a/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js b/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js
old mode 100755
new mode 100644
index f5d71a1..fd2948f
--- a/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js
+++ b/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js
@@ -1,5 +1,5 @@
/*
- * jQuery UI Widget 1.10.0+amd
+ * jQuery UI Widget 1.10.1+amd
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013 jQuery Foundation and other contributors
diff --git a/vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js b/vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js
index 96a149e..0155d38 100644
--- a/vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js
+++ b/vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js
@@ -1,15 +1,18 @@
/*
- * JavaScript Load Image 1.2.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 */
+/*jslint nomen: true, bitwise: true */
/*global window, document, URL, webkitURL, Blob, File, FileReader, define */
(function ($) {
@@ -34,6 +37,8 @@
// (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;
}
@@ -41,8 +46,13 @@
img.src = url;
return img;
}
- return loadImage.readFile(file, function (url) {
- img.src = url;
+ 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,
@@ -51,6 +61,99 @@
(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
@@ -66,22 +169,27 @@
(options.minHeight || height) / height
);
if (scale > 1) {
- width = parseInt(width * scale, 10);
- height = parseInt(height * scale, 10);
+ 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 = parseInt(width * scale, 10);
- height = parseInt(height * scale, 10);
+ width = Math.ceil(width * scale);
+ height = Math.ceil(height * scale);
}
if (img.getContext || (options.canvas && canvas.getContext)) {
canvas.width = width;
canvas.height = height;
- canvas.getContext('2d')
- .drawImage(img, 0, 0, width, 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;
@@ -98,13 +206,12 @@
};
// Loads a given File object via FileReader interface,
- // invokes the callback with a data url:
+ // 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 = function (e) {
- callback(e.target.result);
- };
+ fileReader.onload = fileReader.onerror = callback;
fileReader.readAsDataURL(file);
return fileReader;
}
From 3dce496cda19b33a7a63cf41c3cc9ec884fdcf5c Mon Sep 17 00:00:00 2001
From: Rafael Gaspar
Date: Wed, 22 May 2013 14:45:01 -0300
Subject: [PATCH 31/33] Update Assets
---
vendor/assets/images/loading.gif | Bin
vendor/assets/images/progressbar.gif | Bin
.../cors/jquery.postmessage-transport.js | 0
.../cors/jquery.xdr-transport.js | 0
.../jquery.fileupload-angular.js | 348 ++++++++++++++++++
.../jquery.fileupload-process.js | 158 ++++++++
.../jquery.fileupload-resize.js | 212 +++++++++++
.../jquery-fileupload/jquery.fileupload-ui.js | 280 +++-----------
.../jquery.fileupload-validate.js | 116 ++++++
.../jquery-fileupload/jquery.fileupload.js | 166 ++++++---
.../jquery.iframe-transport.js | 12 +-
.../stylesheets/jquery.fileupload-ui.scss | 53 +--
12 files changed, 1027 insertions(+), 318 deletions(-)
mode change 100644 => 100755 vendor/assets/images/loading.gif
mode change 100644 => 100755 vendor/assets/images/progressbar.gif
mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js
mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js
create mode 100755 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js
create mode 100755 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js
create mode 100755 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js
mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js
create mode 100755 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js
mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js
mode change 100644 => 100755 vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
mode change 100644 => 100755 vendor/assets/stylesheets/jquery.fileupload-ui.scss
diff --git a/vendor/assets/images/loading.gif b/vendor/assets/images/loading.gif
old mode 100644
new mode 100755
diff --git a/vendor/assets/images/progressbar.gif b/vendor/assets/images/progressbar.gif
old mode 100644
new mode 100755
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 100644
new mode 100755
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 100644
new mode 100755
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js
new file mode 100755
index 0000000..e7ba784
--- /dev/null
+++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js
@@ -0,0 +1,348 @@
+/*
+ * 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-process.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js
new file mode 100755
index 0000000..2f9eeed
--- /dev/null
+++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js
@@ -0,0 +1,158 @@
+/*
+ * jQuery File Upload Processing Plugin 1.1
+ * 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 */
+/*global define, window */
+
+(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ // Register as an anonymous AMD module:
+ define([
+ 'jquery',
+ './jquery.fileupload'
+ ], factory);
+ } else {
+ // Browser globals:
+ factory(
+ window.jQuery
+ );
+ }
+}(function ($) {
+ 'use strict';
+
+ var originalAdd = $.blueimp.fileupload.prototype.options.add;
+
+ // The File Upload Processing plugin extends the fileupload widget
+ // with file processing functionality:
+ $.widget('blueimp.fileupload', $.blueimp.fileupload, {
+
+ options: {
+ // The list of processing actions:
+ processQueue: [
+ /*
+ {
+ action: 'log',
+ type: 'debug'
+ }
+ */
+ ],
+ add: function (e, data) {
+ var $this = $(this);
+ data.process(function () {
+ return $this.fileupload('process', data);
+ });
+ originalAdd.call(this, e, data);
+ }
+ },
+
+ processActions: {
+ /*
+ log: function (data, options) {
+ console[options.type](
+ 'Processing "' + data.files[data.index].name + '"'
+ );
+ }
+ */
+ },
+
+ _processFile: function (data) {
+ 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) {
+ return that.processActions[settings.action].call(
+ that,
+ data,
+ settings
+ );
+ };
+ chain = chain.pipe(func, settings.always && func);
+ });
+ chain
+ .done(function () {
+ that._trigger('processdone', null, data);
+ that._trigger('processalways', null, data);
+ })
+ .fail(function () {
+ that._trigger('processfail', null, data);
+ that._trigger('processalways', null, data);
+ });
+ return chain;
+ },
+
+ // Replaces the settings of each processQueue item that
+ // are strings starting with an "@", using the remaining
+ // substring as key for the option map,
+ // e.g. "@autoUpload" is replaced with options.autoUpload:
+ _transformProcessQueue: function (options) {
+ var processQueue = [];
+ $.each(options.processQueue, function () {
+ var settings = {};
+ $.each(this, function (key, value) {
+ if ($.type(value) === 'string' &&
+ value.charAt(0) === '@') {
+ settings[key] = options[value.slice(1)];
+ } else {
+ settings[key] = value;
+ }
+ });
+ processQueue.push(settings);
+ });
+ options.processQueue = processQueue;
+ },
+
+ // Returns the number of files currently in the processsing queue:
+ processing: function () {
+ return this._processing;
+ },
+
+ // Processes the files given as files property of the data parameter,
+ // returns a Promise object that allows to bind callbacks:
+ process: function (data) {
+ var that = this,
+ options = $.extend({}, this.options, data);
+ if (options.processQueue && options.processQueue.length) {
+ this._transformProcessQueue(options);
+ if (this._processing === 0) {
+ this._trigger('processstart');
+ }
+ $.each(data.files, function (index, file) {
+ var opts = index ? $.extend({}, options) : options,
+ func = function () {
+ return that._processFile(opts);
+ };
+ opts.index = index;
+ that._processing += 1;
+ that._processingQueue = that._processingQueue.pipe(func, func)
+ .always(function () {
+ that._processing -= 1;
+ if (that._processing === 0) {
+ that._trigger('processstop');
+ }
+ });
+ });
+ }
+ return this._processingQueue;
+ },
+
+ _create: function () {
+ this._super();
+ this._processing = 0;
+ this._processingQueue = $.Deferred().resolveWith(this)
+ .promise();
+ }
+
+ });
+
+}));
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js
new file mode 100755
index 0000000..ae5c5be
--- /dev/null
+++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js
@@ -0,0 +1,212 @@
+/*
+ * 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 100644
new mode 100755
index 0386fb2..5d22346
--- 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 7.4.1
+ * jQuery File Upload User Interface Plugin 8.2.1
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
@@ -19,20 +19,25 @@
define([
'jquery',
'tmpl',
- 'load-image',
- './jquery.fileupload-fp'
+ './jquery.fileupload-resize',
+ './jquery.fileupload-validate'
], factory);
} else {
// Browser globals:
factory(
window.jQuery,
- window.tmpl,
- window.loadImage
+ window.tmpl
);
}
}(function ($, tmpl, loadImage) {
'use strict';
+ $.blueimp.fileupload.prototype._specialOptions.push(
+ 'filesContainer',
+ 'uploadTemplateId',
+ 'downloadTemplateId'
+ );
+
// The UI version extends the file upload widget
// and adds complete user interface interaction:
$.widget('blueimp.fileupload', $.blueimp.fileupload, {
@@ -42,29 +47,6 @@
// as the user clicks on the start buttons. To enable automatic
// uploads, set the following option to true:
autoUpload: false,
- // The following option limits the number of files that are
- // allowed to be uploaded using this widget:
- maxNumberOfFiles: undefined,
- // The maximum allowed file size:
- maxFileSize: undefined,
- // The minimum allowed file size:
- minFileSize: undefined,
- // The regular expression for allowed file types, matches
- // against either file type or file name:
- acceptFileTypes: /.+$/i,
- // The regular expression to define for which files a preview
- // image is shown, matched against the file type:
- previewSourceFileTypes: /^image\/(gif|jpeg|png)$/,
- // The maximum file size of images that are to be displayed as preview:
- previewSourceMaxFileSize: 5000000, // 5MB
- // The maximum width of the preview images:
- previewMaxWidth: 80,
- // The maximum height of the preview images:
- previewMaxHeight: 80,
- // By default, preview images are displayed as canvas elements
- // if supported by the browser. Set the following option to false
- // to always display preview images as img elements:
- previewAsCanvas: true,
// The ID of the upload template:
uploadTemplateId: 'template-upload',
// The ID of the download template:
@@ -79,29 +61,43 @@
// option of the $.ajax upload requests:
dataType: 'json',
+ // Function returning the current number of files,
+ // used by the maxNumberOfFiles validation:
+ getNumberOfFiles: function () {
+ return this.filesContainer.children().length;
+ },
+
+ // Callback to retrieve the list of files from the server response:
+ getFilesFromResponse: function (data) {
+ if (data.result && $.isArray(data.result.files)) {
+ return data.result.files;
+ }
+ return [];
+ },
+
// The add callback is invoked as soon as files are added to the fileupload
// widget (via file input selection, drag & drop or add API call).
// See the basic file upload widget for more information:
add: function (e, data) {
- var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload'),
+ var $this = $(this),
+ that = $this.data('blueimp-fileupload') ||
+ $this.data('fileupload'),
options = that.options,
files = data.files;
- $(this).fileupload('process', data).done(function () {
- that._adjustMaxNumberOfFiles(-files.length);
- data.maxNumberOfFilesAdjusted = true;
- data.files.valid = data.isValidated = that._validate(files);
+ data.process(function () {
+ return $this.fileupload('process', data);
+ }).always(function () {
data.context = that._renderUpload(files).data('data', data);
+ that._renderPreviews(data);
options.filesContainer[
options.prependFiles ? 'prepend' : 'append'
](data.context);
- that._renderPreviews(data);
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.isValidated) {
+ data.autoUpload !== false && !data.files.error) {
data.submit();
}
}
@@ -112,15 +108,6 @@
send: function (e, data) {
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload');
- if (!data.isValidated) {
- if (!data.maxNumberOfFilesAdjusted) {
- that._adjustMaxNumberOfFiles(-data.files.length);
- data.maxNumberOfFilesAdjusted = true;
- }
- if (!that._validate(data.files)) {
- return false;
- }
- }
if (data.context && data.dataType &&
data.dataType.substr(0, 6) === 'iframe') {
// Iframe Transport does not support progress events.
@@ -142,7 +129,9 @@
done: function (e, data) {
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload'),
- files = that._getFilesFromResponse(data),
+ getFilesFromResponse = data.getFilesFromResponse ||
+ that.options.getFilesFromResponse,
+ files = getFilesFromResponse(data),
template,
deferred;
if (data.context) {
@@ -150,9 +139,6 @@
var file = files[index] ||
{error: 'Empty file upload result'},
deferred = that._addFinishedDeferreds();
- if (file.error) {
- that._adjustMaxNumberOfFiles(1);
- }
that._transition($(this)).done(
function () {
var node = $(this);
@@ -171,17 +157,6 @@
);
});
} else {
- if (files.length) {
- $.each(files, function (index, file) {
- if (data.maxNumberOfFilesAdjusted && file.error) {
- that._adjustMaxNumberOfFiles(1);
- } else if (!data.maxNumberOfFilesAdjusted &&
- !file.error) {
- that._adjustMaxNumberOfFiles(-1);
- }
- });
- data.maxNumberOfFilesAdjusted = true;
- }
template = that._renderDownload(files)
.appendTo(that.options.filesContainer);
that._forceReflow(template);
@@ -202,9 +177,6 @@
$(this).data('fileupload'),
template,
deferred;
- if (data.maxNumberOfFilesAdjusted) {
- that._adjustMaxNumberOfFiles(data.files.length);
- }
if (data.context) {
data.context.each(function (index) {
if (data.errorThrown !== 'abort') {
@@ -323,20 +295,26 @@
}
);
},
+ processstart: function () {
+ $(this).addClass('fileupload-processing');
+ },
+ processstop: function () {
+ $(this).removeClass('fileupload-processing');
+ },
// Callback for file deletion:
destroy: function (e, data) {
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload');
if (data.url) {
- $.ajax(data);
- that._adjustMaxNumberOfFiles(1);
+ $.ajax(data).done(function () {
+ that._transition(data.context).done(
+ function () {
+ $(this).remove();
+ that._trigger('destroyed', e, data);
+ }
+ );
+ });
}
- that._transition(data.context).done(
- function () {
- $(this).remove();
- that._trigger('destroyed', e, data);
- }
- );
}
},
@@ -356,13 +334,6 @@
return this._finishedUploads;
},
- _getFilesFromResponse: function (data) {
- if (data.result && $.isArray(data.result.files)) {
- return data.result.files;
- }
- return [];
- },
-
// Link handler, that allows to download files
// by drag & drop of the links to the desktop:
_enableDragToDesktop: function () {
@@ -376,21 +347,10 @@
'DownloadURL',
[type, name, url].join(':')
);
- } catch (err) {}
+ } catch (ignore) {}
});
},
- _adjustMaxNumberOfFiles: function (operand) {
- if (typeof this.options.maxNumberOfFiles === 'number') {
- this.options.maxNumberOfFiles += operand;
- if (this.options.maxNumberOfFiles < 1) {
- this._disableFileInputButton();
- } else {
- this._enableFileInputButton();
- }
- }
- },
-
_formatFileSize: function (bytes) {
if (typeof bytes !== 'number') {
return '';
@@ -446,46 +406,6 @@
this._formatFileSize(data.total);
},
- _hasError: function (file) {
- if (file.error) {
- return file.error;
- }
- // The number of added files is subtracted from
- // maxNumberOfFiles before validation, so we check if
- // maxNumberOfFiles is below 0 (instead of below 1):
- if (this.options.maxNumberOfFiles < 0) {
- return 'Maximum number of files exceeded';
- }
- // Files are accepted if either the file type or the file name
- // matches against the acceptFileTypes regular expression, as
- // only browsers with support for the File API report the type:
- if (!(this.options.acceptFileTypes.test(file.type) ||
- this.options.acceptFileTypes.test(file.name))) {
- return 'Filetype not allowed';
- }
- if (this.options.maxFileSize &&
- file.size > this.options.maxFileSize) {
- return 'File is too big';
- }
- if (typeof file.size === 'number' &&
- file.size < this.options.minFileSize) {
- return 'File is too small';
- }
- return null;
- },
-
- _validate: function (files) {
- var that = this,
- valid = !!files.length;
- $.each(files, function (index, file) {
- file.error = that._hasError(file);
- if (file.error) {
- valid = false;
- }
- });
- return valid;
- },
-
_renderTemplate: function (func, files) {
if (!func) {
return $();
@@ -501,63 +421,10 @@
return $(this.options.templatesContainer).html(result).children();
},
- _renderPreview: function (file, node) {
- var that = this,
- options = this.options,
- dfd = $.Deferred();
- return ((loadImage && loadImage(
- file,
- function (img) {
- node.append(img);
- that._forceReflow(node);
- that._transition(node).done(function () {
- dfd.resolveWith(node);
- });
- if (!$.contains(that.document[0].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);
- }
- node.on('remove', function () {
- // If the element is removed before the
- // transition finishes, transition events are
- // not triggered, resolve manually:
- dfd.resolveWith(node);
- });
- },
- {
- maxWidth: options.previewMaxWidth,
- maxHeight: options.previewMaxHeight,
- canvas: options.previewAsCanvas
- }
- )) || dfd.resolveWith(node)) && dfd;
- },
-
_renderPreviews: function (data) {
- var that = this,
- options = this.options;
- data.context.find('.preview span').each(function (index, element) {
- var file = data.files[index];
- if (options.previewSourceFileTypes.test(file.type) &&
- ($.type(options.previewSourceMaxFileSize) !== 'number' ||
- file.size < options.previewSourceMaxFileSize)) {
- that._processingQueue = that._processingQueue.pipe(function () {
- var dfd = $.Deferred(),
- ev = $.Event('previewdone', {
- target: element
- });
- that._renderPreview(file, $(element)).done(
- function () {
- that._trigger(ev.type, ev, data);
- dfd.resolveWith(that);
- }
- );
- return dfd.promise();
- });
- }
+ data.context.find('.preview').each(function (index, elm) {
+ $(elm).append(data.files[index].preview);
});
- return this._processingQueue;
},
_renderUpload: function (files) {
@@ -601,8 +468,7 @@
var button = $(e.currentTarget);
this._trigger('destroy', e, $.extend({
context: button.closest('.template-download'),
- type: 'DELETE',
- dataType: this.options.dataType
+ type: 'DELETE'
}, button.data()));
},
@@ -731,54 +597,14 @@
}
},
- _stringToRegExp: function (str) {
- var parts = str.split('/'),
- modifiers = parts.pop();
- parts.shift();
- return new RegExp(parts.join('/'), modifiers);
- },
-
- _initRegExpOptions: function () {
- var options = this.options;
- if ($.type(options.acceptFileTypes) === 'string') {
- options.acceptFileTypes = this._stringToRegExp(
- options.acceptFileTypes
- );
- }
- if ($.type(options.previewSourceFileTypes) === 'string') {
- options.previewSourceFileTypes = this._stringToRegExp(
- options.previewSourceFileTypes
- );
- }
- },
-
_initSpecialOptions: function () {
this._super();
this._initFilesContainer();
this._initTemplates();
- this._initRegExpOptions();
- },
-
- _setOption: function (key, value) {
- this._super(key, value);
- if (key === 'maxNumberOfFiles') {
- this._adjustMaxNumberOfFiles(0);
- }
},
_create: function () {
this._super();
- this._refreshOptionsList.push(
- 'filesContainer',
- 'uploadTemplateId',
- 'downloadTemplateId'
- );
- if (!this._processingQueue) {
- this._processingQueue = $.Deferred().resolveWith(this).promise();
- this.process = function () {
- return this._processingQueue;
- };
- }
this._resetFinishedDeferreds();
},
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js
new file mode 100755
index 0000000..2599da8
--- /dev/null
+++ b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js
@@ -0,0 +1,116 @@
+/*
+ * jQuery File Upload Validation Plugin 1.0.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',
+ './jquery.fileupload-process'
+ ], factory);
+ } else {
+ // Browser globals:
+ factory(
+ window.jQuery
+ );
+ }
+}(function ($) {
+ 'use strict';
+
+ // Append to the default processQueue:
+ $.blueimp.fileupload.prototype.options.processQueue.push(
+ {
+ action: 'validate',
+ // Always trigger this action,
+ // even if the previous action was rejected:
+ always: true,
+ // Options taken from the global options map:
+ acceptFileTypes: '@acceptFileTypes',
+ maxFileSize: '@maxFileSize',
+ minFileSize: '@minFileSize',
+ maxNumberOfFiles: '@maxNumberOfFiles',
+ disabled: '@disableValidation'
+ }
+ );
+
+ // The File Upload Validation plugin extends the fileupload widget
+ // with file validation functionality:
+ $.widget('blueimp.fileupload', $.blueimp.fileupload, {
+
+ options: {
+ /*
+ // The regular expression for allowed file types, matches
+ // against either file type or file name:
+ acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
+ // The maximum allowed file size in bytes:
+ maxFileSize: 10000000, // 10 MB
+ // The minimum allowed file size in bytes:
+ minFileSize: undefined, // No minimal file size
+ // The limit of files to be uploaded:
+ maxNumberOfFiles: 10,
+ */
+
+ // Function returning the current number of files,
+ // has to be overriden for maxNumberOfFiles validation:
+ getNumberOfFiles: $.noop,
+
+ // Error and info messages:
+ messages: {
+ maxNumberOfFiles: 'Maximum number of files exceeded',
+ acceptFileTypes: 'File type not allowed',
+ maxFileSize: 'File is too large',
+ minFileSize: 'File is too small'
+ }
+ },
+
+ processActions: {
+
+ validate: function (data, options) {
+ if (options.disabled) {
+ return data;
+ }
+ var dfd = $.Deferred(),
+ settings = this.options,
+ file = data.files[data.index],
+ numberOfFiles = settings.getNumberOfFiles();
+ if (numberOfFiles && $.type(options.maxNumberOfFiles) === 'number' &&
+ numberOfFiles + 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) {
+ file.error = settings.i18n('maxFileSize');
+ } else if ($.type(file.size) === 'number' &&
+ file.size < options.minFileSize) {
+ file.error = settings.i18n('minFileSize');
+ } else {
+ delete file.error;
+ }
+ if (file.error || data.files.error) {
+ data.files.error = true;
+ dfd.rejectWith(this, [data]);
+ } else {
+ dfd.resolveWith(this, [data]);
+ }
+ return dfd.promise();
+ }
+
+ }
+
+ });
+
+}));
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js
old mode 100644
new mode 100755
index dbee297..03678f3
--- 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.28.4
+ * jQuery File Upload Plugin 5.31.1
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
@@ -115,6 +115,23 @@
// By default, uploads are started automatically when adding files:
autoUpload: true,
+ // Error and info messages:
+ messages: {
+ uploadedBytes: 'Uploaded bytes exceed file size'
+ },
+
+ // Translation function, gets the message key to be translated
+ // and an object with context specific data as arguments:
+ i18n: function (message, context) {
+ message = this.messages[message] || message.toString();
+ if (context) {
+ $.each(context, function (key, value) {
+ message = message.replace('{' + key + '}', value);
+ });
+ }
+ return message;
+ },
+
// Additional form data to be sent along with the file uploads can be set
// using this option, which accepts an array of objects with name and
// value properties, a function returning such an array, a FormData
@@ -139,9 +156,10 @@
// data.submit().done(func).fail(func).always(func);
add: function (e, data) {
if (data.autoUpload || (data.autoUpload !== false &&
- ($(this).data('blueimp-fileupload') ||
- $(this).data('fileupload')).options.autoUpload)) {
- data.submit();
+ $(this).fileupload('option', 'autoUpload'))) {
+ data.process().done(function () {
+ data.submit();
+ });
}
},
@@ -205,8 +223,9 @@
cache: false
},
- // A list of options that require a refresh after assigning a new value:
- _refreshOptionsList: [
+ // A list of options that require reinitializing event listeners and/or
+ // special initialization code:
+ _specialOptions: [
'fileInput',
'dropZone',
'pasteZone',
@@ -215,7 +234,7 @@
],
_BitrateTimer: function () {
- this.timestamp = (new Date()).getTime();
+ this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());
this.loaded = 0;
this.bitrate = 0;
this.getBitrate = function (now, loaded, interval) {
@@ -289,7 +308,7 @@
_onProgress: function (e, data) {
if (e.lengthComputable) {
- var now = (new Date()).getTime(),
+ var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
loaded;
if (data._time && data.progressInterval &&
(now - data._time < data.progressInterval) &&
@@ -344,8 +363,14 @@
}
},
+ _isInstanceOf: function (type, obj) {
+ // Cross-frame instanceof check
+ return Object.prototype.toString.call(obj) === '[object ' + type + ']';
+ },
+
_initXHRData: function (options) {
- var formData,
+ var that = this,
+ formData,
file = options.files[0],
// Ignore non-multipart setting if not supported:
multipart = options.multipart || !$.support.xhrFileUpload,
@@ -380,7 +405,7 @@
});
}
} else {
- if (options.formData instanceof FormData) {
+ if (that._isInstanceOf('FormData', options.formData)) {
formData = options.formData;
} else {
formData = new FormData();
@@ -394,12 +419,10 @@
formData.append(paramName, options.blob, file.name);
} else {
$.each(options.files, function (index, file) {
- // Files are also Blob instances, but some browsers
- // (Firefox 3.6) support the File API but not Blobs.
// This check allows the tests to run with
// dummy objects:
- if ((window.Blob && file instanceof Blob) ||
- (window.File && file instanceof File)) {
+ if (that._isInstanceOf('File', file) ||
+ that._isInstanceOf('Blob', file)) {
formData.append(
options.paramName[index] || paramName,
file,
@@ -444,7 +467,7 @@
options.dataType = 'postmessage ' + (options.dataType || '');
}
} else {
- this._initIframeSettings(options, 'iframe');
+ this._initIframeSettings(options);
}
},
@@ -544,9 +567,20 @@
return this._enhancePromise(promise);
},
- // Adds convenience methods to the callback arguments:
+ // Adds convenience methods to the data callback argument:
_addConvenienceMethods: function (e, data) {
- var that = this;
+ var that = this,
+ getPromise = function (data) {
+ return $.Deferred().resolveWith(that, [data]).promise();
+ };
+ data.process = function (resolveFunc, rejectFunc) {
+ if (resolveFunc || rejectFunc) {
+ data._processQueue = this._processQueue =
+ (this._processQueue || getPromise(this))
+ .pipe(resolveFunc, rejectFunc);
+ }
+ return this._processQueue || getPromise(this);
+ };
data.submit = function () {
if (this.state() !== 'pending') {
data.jqXHR = this.jqXHR =
@@ -565,6 +599,9 @@
if (this.jqXHR) {
return that._getDeferredState(this.jqXHR);
}
+ if (this._processQueue) {
+ return that._getDeferredState(this._processQueue);
+ }
};
data.progress = function () {
return this._progress;
@@ -608,7 +645,7 @@
return true;
}
if (ub >= fs) {
- file.error = 'Uploaded bytes exceed file size';
+ file.error = options.i18n('uploadedBytes');
return this._getXHRPromise(
false,
options.context,
@@ -644,7 +681,7 @@
// Create a progress event if no final progress event
// with loaded equaling total has been triggered
// for this chunk:
- if (o._progress.loaded === currentLoaded) {
+ if (currentLoaded + o.chunkSize - o._progress.loaded) {
that._onProgress($.Event('progress', {
lengthComputable: true,
loaded: ub - o.uploadedBytes,
@@ -1045,44 +1082,50 @@
},
_onPaste: function (e) {
- var cbd = e.originalEvent.clipboardData,
- items = (cbd && cbd.items) || [],
+ var items = e.originalEvent && e.originalEvent.clipboardData &&
+ e.originalEvent.clipboardData.items,
data = {files: []};
- $.each(items, function (index, item) {
- var file = item.getAsFile && item.getAsFile();
- if (file) {
- data.files.push(file);
+ if (items && items.length) {
+ $.each(items, function (index, item) {
+ var file = item.getAsFile && item.getAsFile();
+ if (file) {
+ data.files.push(file);
+ }
+ });
+ if (this._trigger('paste', e, data) === false ||
+ this._onAdd(e, data) === false) {
+ return false;
}
- });
- if (this._trigger('paste', e, data) === false ||
- this._onAdd(e, data) === false) {
- return false;
}
},
_onDrop: function (e) {
var that = this,
- dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer,
+ dataTransfer = e.dataTransfer = e.originalEvent &&
+ e.originalEvent.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) {
+ that._onAdd(e, data);
+ }
+ });
}
- this._getDroppedFiles(dataTransfer).always(function (files) {
- data.files = files;
- if (that._trigger('drop', e, data) !== false) {
- that._onAdd(e, data);
- }
- });
},
_onDragOver: function (e) {
- var dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer;
- if (this._trigger('dragover', e) === false) {
- return false;
- }
- if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1) {
- dataTransfer.dropEffect = 'copy';
- e.preventDefault();
+ 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();
+ }
}
},
@@ -1108,12 +1151,12 @@
},
_setOption: function (key, value) {
- var refresh = $.inArray(key, this._refreshOptionsList) !== -1;
- if (refresh) {
+ var reinit = $.inArray(key, this._specialOptions) !== -1;
+ if (reinit) {
this._destroyEventHandlers();
}
this._super(key, value);
- if (refresh) {
+ if (reinit) {
this._initSpecialOptions();
this._initEventHandlers();
}
@@ -1135,10 +1178,35 @@
}
},
- _create: function () {
- var options = this.options;
+ _getRegExp: function (str) {
+ var parts = str.split('/'),
+ modifiers = parts.pop();
+ parts.shift();
+ return new RegExp(parts.join('/'), modifiers);
+ },
+
+ _isRegExpOption: function (key, value) {
+ return key !== 'url' && $.type(value) === 'string' &&
+ /^\/.*\/[igm]{0,3}$/.test(value);
+ },
+
+ _initDataAttributes: function () {
+ var that = this,
+ options = this.options;
// Initialize options set via HTML5 data-attributes:
- $.extend(options, $(this.element[0].cloneNode(false)).data());
+ $.each(
+ $(this.element[0].cloneNode(false)).data(),
+ function (key, value) {
+ if (that._isRegExpOption(key, value)) {
+ value = that._getRegExp(value);
+ }
+ options[key] = value;
+ }
+ );
+ },
+
+ _create: function () {
+ this._initDataAttributes();
this._initSpecialOptions();
this._slots = [];
this._sequence = this._getXHRPromise(true);
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js b/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
old mode 100644
new mode 100755
index ed25895..e04e7a0
--- 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.1
+ * jQuery Iframe Transport Plugin 1.6.2
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
@@ -61,9 +61,10 @@
// 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 = $(
''
+ counter + '">'
).bind('load', function () {
var fileInputClones,
paramNames = $.isArray(options.paramName) ?
@@ -96,7 +97,12 @@
// (happens on form submits to iframe targets):
$('')
.appendTo(form);
- form.remove();
+ window.setTimeout(function () {
+ // Removing the form in a setTimeout call
+ // allows Chrome's developer tools to display
+ // the response result
+ form.remove();
+ }, 0);
});
form
.prop('target', iframe.prop('name'))
diff --git a/vendor/assets/stylesheets/jquery.fileupload-ui.scss b/vendor/assets/stylesheets/jquery.fileupload-ui.scss
old mode 100644
new mode 100755
index 58a7315..72bfcb6
--- a/vendor/assets/stylesheets/jquery.fileupload-ui.scss
+++ b/vendor/assets/stylesheets/jquery.fileupload-ui.scss
@@ -1,6 +1,6 @@
-@charset 'UTF-8';
+@charset "UTF-8";
/*
- * jQuery File Upload UI Plugin CSS 6.3
+ * jQuery File Upload UI Plugin CSS 8.0
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
@@ -13,19 +13,16 @@
.fileinput-button {
position: relative;
overflow: hidden;
- float: left;
- margin-right: 4px;
}
.fileinput-button input {
position: absolute;
top: 0;
right: 0;
margin: 0;
- border: solid transparent;
- border-width: 0 0 100px 200px;
opacity: 0;
filter: alpha(opacity=0);
- -moz-transform: translate(-300px, 0) scale(4);
+ transform: translate(-300px, 0) scale(4);
+ font-size: 23px;
direction: ltr;
cursor: pointer;
}
@@ -33,52 +30,30 @@
.fileupload-buttonbar .toggle {
margin-bottom: 5px;
}
-.files .progress {
- width: 200px;
-}
.progress-animated .bar {
- background: image-url('progressbar.gif') !important;
+ background: url(../img/progressbar.gif) !important;
filter: none;
}
.fileupload-loading {
- position: absolute;
- left: 50%;
- width: 128px;
- height: 128px;
- background: image-url('loading.gif') center no-repeat;
+ float: right;
+ width: 32px;
+ height: 32px;
+ background: url(../img/loading.gif) center no-repeat;
+ background-size: contain;
display: none;
}
.fileupload-processing .fileupload-loading {
display: block;
}
-/* Fix for IE 6: */
-* html .fileinput-button {
- line-height: 22px;
- margin: 1px -3px 0 0;
-}
-
-/* Fix for IE 7: */
-* + html .fileinput-button {
- margin: 1px 0 0 0;
-}
-
-@media (max-width: 480px) {
+@media (max-width: 767px) {
+ .fileupload-buttonbar .toggle,
+ .files .toggle,
.files .btn span {
display: none;
}
- .files .preview * {
- width: 40px;
- }
- .files .name * {
+ .files .name {
width: 80px;
- display: inline-block;
word-wrap: break-word;
}
- .files .progress {
- width: 20px;
- }
- .files .delete {
- width: 60px;
- }
}
From 851cda559c5a7c0e52c4ca8244ba1038e057623a Mon Sep 17 00:00:00 2001
From: Chris Whitman
Date: Wed, 23 May 2012 06:41:04 -0700
Subject: [PATCH 32/33] Remove tmpl.js (JS template engine) from manifest
---
vendor/assets/javascripts/jquery-fileupload/index.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/vendor/assets/javascripts/jquery-fileupload/index.js b/vendor/assets/javascripts/jquery-fileupload/index.js
index 0cda385..3087040 100644
--- a/vendor/assets/javascripts/jquery-fileupload/index.js
+++ b/vendor/assets/javascripts/jquery-fileupload/index.js
@@ -1,7 +1,6 @@
//=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
From 5d7e0cb470862ae8e6cb854d010baf4ff6c8c182 Mon Sep 17 00:00:00 2001
From: Waseem Ahmad
Date: Wed, 17 Apr 2013 03:25:07 +0530
Subject: [PATCH 33/33] Make sure no error is raised if fileupload element is
not present in DOM
---
.../jquery-fileupload/jquery.fileupload-ui.js | 518 ++++++++++--------
1 file changed, 289 insertions(+), 229 deletions(-)
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js b/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js
index 5d22346..6d19391 100755
--- 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 6.8.2
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
@@ -10,7 +10,7 @@
*/
/*jslint nomen: true, unparam: true, regexp: true */
-/*global define, window, URL, webkitURL, FileReader */
+/*global define, window, document, URL, webkitURL, FileReader */
(function (factory) {
'use strict';
@@ -19,34 +19,53 @@
define([
'jquery',
'tmpl',
- './jquery.fileupload-resize',
- './jquery.fileupload-validate'
+ 'load-image',
+ './jquery.fileupload-fp'
], factory);
} else {
// Browser globals:
factory(
window.jQuery,
- window.tmpl
+ window.tmpl,
+ window.loadImage
);
}
}(function ($, tmpl, loadImage) {
'use strict';
- $.blueimp.fileupload.prototype._specialOptions.push(
- 'filesContainer',
- 'uploadTemplateId',
- 'downloadTemplateId'
- );
-
- // The UI version extends the file upload widget
- // and adds complete user interface interaction:
- $.widget('blueimp.fileupload', $.blueimp.fileupload, {
+ // The UI version extends the FP (file processing) version or the basic
+ // file upload widget and adds complete user interface interaction:
+ var parentWidget = ($.blueimpFP || $.blueimp).fileupload;
+ $.widget('blueimpUI.fileupload', parentWidget, {
options: {
// By default, files added to the widget are uploaded as soon
// as the user clicks on the start buttons. To enable automatic
// uploads, set the following option to true:
autoUpload: false,
+ // The following option limits the number of files that are
+ // allowed to be uploaded using this widget:
+ maxNumberOfFiles: undefined,
+ // The maximum allowed file size:
+ maxFileSize: undefined,
+ // The minimum allowed file size:
+ minFileSize: undefined,
+ // The regular expression for allowed file types, matches
+ // against either file type or file name:
+ acceptFileTypes: /.+$/i,
+ // The regular expression to define for which files a preview
+ // image is shown, matched against the file type:
+ previewSourceFileTypes: /^image\/(gif|jpeg|png)$/,
+ // The maximum file size of images that are to be displayed as preview:
+ previewSourceMaxFileSize: 5000000, // 5MB
+ // The maximum width of the preview images:
+ previewMaxWidth: 80,
+ // The maximum height of the preview images:
+ previewMaxHeight: 80,
+ // By default, preview images are displayed as canvas elements
+ // if supported by the browser. Set the following option to false
+ // to always display preview images as img elements:
+ previewAsCanvas: true,
// The ID of the upload template:
uploadTemplateId: 'template-upload',
// The ID of the download template:
@@ -61,43 +80,28 @@
// option of the $.ajax upload requests:
dataType: 'json',
- // Function returning the current number of files,
- // used by the maxNumberOfFiles validation:
- getNumberOfFiles: function () {
- return this.filesContainer.children().length;
- },
-
- // Callback to retrieve the list of files from the server response:
- getFilesFromResponse: function (data) {
- if (data.result && $.isArray(data.result.files)) {
- return data.result.files;
- }
- return [];
- },
-
// The add callback is invoked as soon as files are added to the fileupload
// widget (via file input selection, drag & drop or add API call).
// See the basic file upload widget for more information:
add: function (e, data) {
- var $this = $(this),
- that = $this.data('blueimp-fileupload') ||
- $this.data('fileupload'),
+ var that = $(this).data('fileupload'),
options = that.options,
files = data.files;
- data.process(function () {
- return $this.fileupload('process', data);
- }).always(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).data('data', data);
- that._renderPreviews(data);
options.filesContainer[
options.prependFiles ? 'prepend' : 'append'
](data.context);
+ that._renderPreviews(files, 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.autoUpload !== false && data.isValidated) {
data.submit();
}
}
@@ -106,8 +110,15 @@
},
// Callback for the start of each file upload request:
send: function (e, data) {
- var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload');
+ var that = $(this).data('fileupload');
+ if (!data.isValidated) {
+ if (!data.isAdjusted) {
+ that._adjustMaxNumberOfFiles(-data.files.length);
+ }
+ if (!that._validate(data.files)) {
+ return false;
+ }
+ }
if (data.context && data.dataType &&
data.dataType.substr(0, 6) === 'iframe') {
// Iframe Transport does not support progress events.
@@ -117,73 +128,65 @@
.find('.progress').addClass(
!$.support.transition && 'progress-animated'
)
- .attr('aria-valuenow', 100)
.find('.bar').css(
'width',
- '100%'
+ parseInt(100, 10) + '%'
);
}
return that._trigger('sent', e, data);
},
// Callback for successful uploads:
done: function (e, data) {
- var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload'),
- getFilesFromResponse = data.getFilesFromResponse ||
- that.options.getFilesFromResponse,
- files = getFilesFromResponse(data),
- template,
- deferred;
+ var that = $(this).data('fileupload'),
+ template;
if (data.context) {
data.context.each(function (index) {
- var file = files[index] ||
- {error: 'Empty file upload result'},
- deferred = that._addFinishedDeferreds();
- that._transition($(this)).done(
- function () {
- var node = $(this);
- template = that._renderDownload([file])
- .replaceAll(node);
- that._forceReflow(template);
- that._transition(template).done(
- function () {
- data.context = $(this);
- that._trigger('completed', e, data);
- that._trigger('finished', e, data);
- deferred.resolve();
- }
- );
- }
- );
+ var file = ($.isArray(data.result) &&
+ data.result[index]) || {error: 'emptyResult'};
+ if (file.error) {
+ that._adjustMaxNumberOfFiles(1);
+ }
+ if (that) {
+ that._transition($(this)).done(
+ function () {
+ var node = $(this);
+ template = that._renderDownload([file])
+ .css('height', node.height())
+ .replaceAll(node);
+ that._forceReflow(template);
+ that._transition(template).done(
+ function () {
+ data.context = $(this);
+ that._trigger('completed', e, data);
+ }
+ );
+ }
+ );
+ }
});
} else {
- template = that._renderDownload(files)
+ template = that._renderDownload(data.result)
.appendTo(that.options.filesContainer);
that._forceReflow(template);
- deferred = that._addFinishedDeferreds();
that._transition(template).done(
function () {
data.context = $(this);
that._trigger('completed', e, data);
- that._trigger('finished', e, data);
- deferred.resolve();
}
);
}
},
// Callback for failed (abort or error) uploads:
fail: function (e, data) {
- var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload'),
- template,
- deferred;
+ var that = $(this).data('fileupload'),
+ template;
+ that._adjustMaxNumberOfFiles(data.files.length);
if (data.context) {
data.context.each(function (index) {
if (data.errorThrown !== 'abort') {
var file = data.files[index];
file.error = file.error || data.errorThrown ||
true;
- deferred = that._addFinishedDeferreds();
that._transition($(this)).done(
function () {
var node = $(this);
@@ -194,82 +197,62 @@
function () {
data.context = $(this);
that._trigger('failed', e, data);
- that._trigger('finished', e, data);
- deferred.resolve();
}
);
}
);
} else {
- deferred = that._addFinishedDeferreds();
that._transition($(this)).done(
function () {
$(this).remove();
that._trigger('failed', e, data);
- that._trigger('finished', e, data);
- deferred.resolve();
}
);
}
});
} else if (data.errorThrown !== 'abort') {
+ that._adjustMaxNumberOfFiles(-data.files.length);
data.context = that._renderUpload(data.files)
.appendTo(that.options.filesContainer)
.data('data', data);
that._forceReflow(data.context);
- deferred = that._addFinishedDeferreds();
that._transition(data.context).done(
function () {
data.context = $(this);
that._trigger('failed', e, data);
- that._trigger('finished', e, data);
- deferred.resolve();
}
);
} else {
that._trigger('failed', e, data);
- that._trigger('finished', e, data);
- that._addFinishedDeferreds().resolve();
}
},
// Callback for upload progress events:
progress: function (e, data) {
if (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.find('.bar').css(
+ 'width',
+ parseInt(data.loaded / data.total * 100, 10) + '%'
+ );
}
},
// Callback for global upload progress events:
progressall: function (e, data) {
- var $this = $(this),
- progress = Math.floor(data.loaded / data.total * 100),
- globalProgressNode = $this.find('.fileupload-progress'),
- extendedProgressNode = globalProgressNode
- .find('.progress-extended');
- if (extendedProgressNode.length) {
- extendedProgressNode.html(
- ($this.data('blueimp-fileupload') || $this.data('fileupload'))
- ._renderExtendedProgress(data)
- );
- }
- globalProgressNode
- .find('.progress')
- .attr('aria-valuenow', progress)
+ var $this = $(this);
+ $this.find('.fileupload-progress')
.find('.bar').css(
'width',
- progress + '%'
- );
+ 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('blueimp-fileupload') ||
- $(this).data('fileupload');
- that._resetFinishedDeferreds();
+ var that = $(this).data('fileupload');
that._transition($(this).find('.fileupload-progress')).done(
function () {
that._trigger('started', e);
@@ -278,62 +261,31 @@
},
// Callback for uploads stop, equivalent to the global ajaxStop event:
stop: function (e) {
- var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload'),
- deferred = that._addFinishedDeferreds();
- $.when.apply($, that._getFinishedDeferreds())
- .done(function () {
- that._trigger('stopped', e);
- });
+ var that = $(this).data('fileupload');
that._transition($(this).find('.fileupload-progress')).done(
function () {
- $(this).find('.progress')
- .attr('aria-valuenow', '0')
- .find('.bar').css('width', '0%');
+ $(this).find('.bar').css('width', '0%');
$(this).find('.progress-extended').html(' ');
- deferred.resolve();
+ that._trigger('stopped', e);
}
);
},
- processstart: function () {
- $(this).addClass('fileupload-processing');
- },
- processstop: function () {
- $(this).removeClass('fileupload-processing');
- },
// Callback for file deletion:
destroy: function (e, data) {
- var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload');
+ var that = $(this).data('fileupload');
if (data.url) {
- $.ajax(data).done(function () {
- that._transition(data.context).done(
- function () {
- $(this).remove();
- that._trigger('destroyed', e, data);
- }
- );
- });
+ $.ajax(data);
+ that._adjustMaxNumberOfFiles(1);
}
+ that._transition(data.context).done(
+ function () {
+ $(this).remove();
+ that._trigger('destroyed', e, data);
+ }
+ );
}
},
- _resetFinishedDeferreds: function () {
- this._finishedUploads = [];
- },
-
- _addFinishedDeferreds: function (deferred) {
- if (!deferred) {
- deferred = $.Deferred();
- }
- this._finishedUploads.push(deferred);
- return deferred;
- },
-
- _getFinishedDeferreds: function () {
- return this._finishedUploads;
- },
-
// Link handler, that allows to download files
// by drag & drop of the links to the desktop:
_enableDragToDesktop: function () {
@@ -347,10 +299,21 @@
'DownloadURL',
[type, name, url].join(':')
);
- } catch (ignore) {}
+ } catch (err) {}
});
},
+ _adjustMaxNumberOfFiles: function (operand) {
+ if (typeof this.options.maxNumberOfFiles === 'number') {
+ this.options.maxNumberOfFiles += operand;
+ if (this.options.maxNumberOfFiles < 1) {
+ this._disableFileInputButton();
+ } else {
+ this._enableFileInputButton();
+ }
+ }
+ },
+
_formatFileSize: function (bytes) {
if (typeof bytes !== 'number') {
return '';
@@ -377,12 +340,12 @@
if (bits >= 1000) {
return (bits / 1000).toFixed(2) + ' kbit/s';
}
- return bits.toFixed(2) + ' bit/s';
+ return bits + ' bit/s';
},
_formatTime: function (seconds) {
var date = new Date(seconds * 1000),
- days = Math.floor(seconds / 86400);
+ days = parseInt(seconds / 86400, 10);
days = days ? days + 'd ' : '';
return days +
('0' + date.getUTCHours()).slice(-2) + ':' +
@@ -406,6 +369,46 @@
this._formatFileSize(data.total);
},
+ _hasError: function (file) {
+ if (file.error) {
+ return file.error;
+ }
+ // The number of added files is subtracted from
+ // maxNumberOfFiles before validation, so we check if
+ // maxNumberOfFiles is below 0 (instead of below 1):
+ if (this.options.maxNumberOfFiles < 0) {
+ return 'maxNumberOfFiles';
+ }
+ // Files are accepted if either the file type or the file name
+ // matches against the acceptFileTypes regular expression, as
+ // only browsers with support for the File API report the type:
+ if (!(this.options.acceptFileTypes.test(file.type) ||
+ this.options.acceptFileTypes.test(file.name))) {
+ return 'acceptFileTypes';
+ }
+ if (this.options.maxFileSize &&
+ file.size > this.options.maxFileSize) {
+ return 'maxFileSize';
+ }
+ if (typeof file.size === 'number' &&
+ file.size < this.options.minFileSize) {
+ return 'minFileSize';
+ }
+ return null;
+ },
+
+ _validate: function (files) {
+ var that = this,
+ valid = !!files.length;
+ $.each(files, function (index, file) {
+ file.error = that._hasError(file);
+ if (file.error) {
+ valid = false;
+ }
+ });
+ return valid;
+ },
+
_renderTemplate: function (func, files) {
if (!func) {
return $();
@@ -421,10 +424,53 @@
return $(this.options.templatesContainer).html(result).children();
},
- _renderPreviews: function (data) {
- data.context.find('.preview').each(function (index, elm) {
- $(elm).append(data.files[index].preview);
+ _renderPreview: function (file, node) {
+ var that = this,
+ options = this.options,
+ dfd = $.Deferred();
+ return ((loadImage && loadImage(
+ file,
+ function (img) {
+ node.append(img);
+ that._forceReflow(node);
+ that._transition(node).done(function () {
+ 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
+ }
+ )) || dfd.resolveWith(node)) && dfd;
+ },
+
+ _renderPreviews: function (files, nodes) {
+ var that = this,
+ options = this.options;
+ nodes.find('.preview span').each(function (index, element) {
+ var file = files[index];
+ if (options.previewSourceFileTypes.test(file.type) &&
+ ($.type(options.previewSourceMaxFileSize) !== 'number' ||
+ file.size < options.previewSourceMaxFileSize)) {
+ that._processingQueue = that._processingQueue.pipe(function () {
+ var dfd = $.Deferred();
+ that._renderPreview(file, $(element)).done(
+ function () {
+ dfd.resolveWith(that);
+ }
+ );
+ return dfd.promise();
+ });
+ }
});
+ return this._processingQueue;
},
_renderUpload: function (files) {
@@ -443,7 +489,7 @@
_startHandler: function (e) {
e.preventDefault();
- var button = $(e.currentTarget),
+ var button = $(this),
template = button.closest('.template-upload'),
data = template.data('data');
if (data && data.submit && !data.jqXHR && data.submit()) {
@@ -453,11 +499,11 @@
_cancelHandler: function (e) {
e.preventDefault();
- var template = $(e.currentTarget).closest('.template-upload'),
+ var template = $(this).closest('.template-upload'),
data = template.data('data') || {};
if (!data.jqXHR) {
data.errorThrown = 'abort';
- this._trigger('fail', e, data);
+ e.data.fileupload._trigger('fail', e, data);
} else {
data.jqXHR.abort();
}
@@ -465,21 +511,23 @@
_deleteHandler: function (e) {
e.preventDefault();
- var button = $(e.currentTarget);
- this._trigger('destroy', e, $.extend({
+ var button = $(this);
+ e.data.fileupload._trigger('destroy', e, {
context: button.closest('.template-download'),
- type: 'DELETE'
- }, button.data()));
+ url: button.attr('data-url'),
+ type: button.attr('data-type') || 'DELETE',
+ dataType: e.data.fileupload.options.dataType
+ });
},
_forceReflow: function (node) {
- return $.support.transition && node.length &&
- node[0].offsetWidth;
+ this._reflow = $.support.transition &&
+ node.length && node[0].offsetWidth;
},
_transition: function (node) {
var dfd = $.Deferred();
- if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {
+ if ($.support.transition && node.hasClass('fade')) {
node.bind(
$.support.transition.end,
function (e) {
@@ -500,65 +548,75 @@
_initButtonBarEventHandlers: function () {
var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
- filesList = this.options.filesContainer;
- this._on(fileUploadButtonBar.find('.start'), {
- click: function (e) {
+ filesList = this.options.filesContainer,
+ ns = this.options.namespace;
+ fileUploadButtonBar.find('.start')
+ .bind('click.' + ns, function (e) {
e.preventDefault();
- filesList.find('.start').click();
- }
- });
- this._on(fileUploadButtonBar.find('.cancel'), {
- click: function (e) {
+ filesList.find('.start button').click();
+ });
+ fileUploadButtonBar.find('.cancel')
+ .bind('click.' + ns, function (e) {
e.preventDefault();
- filesList.find('.cancel').click();
- }
- });
- this._on(fileUploadButtonBar.find('.delete'), {
- click: function (e) {
+ filesList.find('.cancel button').click();
+ });
+ fileUploadButtonBar.find('.delete')
+ .bind('click.' + ns, function (e) {
e.preventDefault();
- filesList.find('.toggle:checked')
- .closest('.template-download')
- .find('.delete').click();
+ filesList.find('.delete input:checked')
+ .siblings('button').click();
fileUploadButtonBar.find('.toggle')
.prop('checked', false);
- }
- });
- this._on(fileUploadButtonBar.find('.toggle'), {
- change: function (e) {
- filesList.find('.toggle').prop(
+ });
+ fileUploadButtonBar.find('.toggle')
+ .bind('change.' + ns, function (e) {
+ filesList.find('.delete input').prop(
'checked',
- $(e.currentTarget).is(':checked')
+ $(this).is(':checked')
);
- }
- });
+ });
},
_destroyButtonBarEventHandlers: function () {
- this._off(
- this.element.find('.fileupload-buttonbar')
- .find('.start, .cancel, .delete'),
- 'click'
- );
- this._off(
- this.element.find('.fileupload-buttonbar .toggle'),
- 'change.'
- );
+ this.element.find('.fileupload-buttonbar button')
+ .unbind('click.' + this.options.namespace);
+ this.element.find('.fileupload-buttonbar .toggle')
+ .unbind('change.' + this.options.namespace);
},
_initEventHandlers: function () {
- this._super();
- this._on(this.options.filesContainer, {
- 'click .start': this._startHandler,
- 'click .cancel': this._cancelHandler,
- 'click .delete': this._deleteHandler
- });
+ parentWidget.prototype._initEventHandlers.call(this);
+ var eventData = {fileupload: this};
+ this.options.filesContainer
+ .delegate(
+ '.start button',
+ 'click.' + this.options.namespace,
+ eventData,
+ this._startHandler
+ )
+ .delegate(
+ '.cancel button',
+ 'click.' + this.options.namespace,
+ eventData,
+ this._cancelHandler
+ )
+ .delegate(
+ '.delete button',
+ 'click.' + this.options.namespace,
+ eventData,
+ this._deleteHandler
+ );
this._initButtonBarEventHandlers();
},
_destroyEventHandlers: function () {
+ var options = this.options;
this._destroyButtonBarEventHandlers();
- this._off(this.options.filesContainer, 'click');
- this._super();
+ options.filesContainer
+ .undelegate('.start button', 'click.' + options.namespace)
+ .undelegate('.cancel button', 'click.' + options.namespace)
+ .undelegate('.delete button', 'click.' + options.namespace);
+ parentWidget.prototype._destroyEventHandlers.call(this);
},
_enableFileInputButton: function () {
@@ -575,7 +633,7 @@
_initTemplates: function () {
var options = this.options;
- options.templatesContainer = this.document[0].createElement(
+ options.templatesContainer = document.createElement(
options.filesContainer.prop('nodeName')
);
if (tmpl) {
@@ -598,34 +656,36 @@
},
_initSpecialOptions: function () {
- this._super();
+ parentWidget.prototype._initSpecialOptions.call(this);
this._initFilesContainer();
this._initTemplates();
},
_create: function () {
- this._super();
- this._resetFinishedDeferreds();
+ parentWidget.prototype._create.call(this);
+ this._refreshOptionsList.push(
+ 'filesContainer',
+ 'uploadTemplateId',
+ 'downloadTemplateId'
+ );
+ if (!$.blueimpFP) {
+ this._processingQueue = $.Deferred().resolveWith(this).promise();
+ this.process = function () {
+ return this._processingQueue;
+ };
+ }
},
enable: function () {
- var wasDisabled = false;
- if (this.options.disabled) {
- wasDisabled = true;
- }
- this._super();
- if (wasDisabled) {
- this.element.find('input, button').prop('disabled', false);
- this._enableFileInputButton();
- }
+ parentWidget.prototype.enable.call(this);
+ this.element.find('input, button').prop('disabled', false);
+ this._enableFileInputButton();
},
disable: function () {
- if (!this.options.disabled) {
- this.element.find('input, button').prop('disabled', true);
- this._disableFileInputButton();
- }
- this._super();
+ this.element.find('input, button').prop('disabled', true);
+ this._disableFileInputButton();
+ parentWidget.prototype.disable.call(this);
}
});