From 83ba530b7f635aafd9a89e550e670c721908e8e0 Mon Sep 17 00:00:00 2001
From: Igor Pstyga
Date: Fri, 21 Nov 2014 12:44:26 -0800
Subject: [PATCH 1/4] Move assets to app/assets folder for rails 4
---
{vendor => app}/assets/images/loading.gif | Bin
{vendor => app}/assets/images/progressbar.gif | Bin
.../assets/javascripts/jquery-fileupload/basic.js | 0
.../cors/jquery.postmessage-transport.js | 0
.../jquery-fileupload/cors/jquery.xdr-transport.js | 0
.../assets/javascripts/jquery-fileupload/index.js | 0
.../jquery-fileupload/jquery.fileupload-angular.js | 0
.../jquery-fileupload/jquery.fileupload-fp.js | 0
.../jquery-fileupload/jquery.fileupload-process.js | 0
.../jquery-fileupload/jquery.fileupload-resize.js | 0
.../jquery-fileupload/jquery.fileupload-ui.js | 0
.../jquery-fileupload/jquery.fileupload-validate.js | 0
.../jquery-fileupload/jquery.fileupload.js | 0
.../jquery-fileupload/jquery.iframe-transport.js | 0
.../assets/javascripts/jquery-fileupload/locale.js | 0
.../jquery-fileupload/vendor/canvas-to-blob.js | 0
.../jquery-fileupload/vendor/jquery.ui.widget.js | 0
.../jquery-fileupload/vendor/load-image.js | 0
.../javascripts/jquery-fileupload/vendor/tmpl.js | 0
.../assets/stylesheets/jquery.fileupload-ui.scss | 0
jquery-fileupload-rails.gemspec | 4 ++--
21 files changed, 2 insertions(+), 2 deletions(-)
rename {vendor => app}/assets/images/loading.gif (100%)
mode change 100755 => 100644
rename {vendor => app}/assets/images/progressbar.gif (100%)
mode change 100755 => 100644
rename {vendor => app}/assets/javascripts/jquery-fileupload/basic.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/index.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/jquery.fileupload.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/locale.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/vendor/canvas-to-blob.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/vendor/load-image.js (100%)
rename {vendor => app}/assets/javascripts/jquery-fileupload/vendor/tmpl.js (100%)
rename {vendor => app}/assets/stylesheets/jquery.fileupload-ui.scss (100%)
diff --git a/vendor/assets/images/loading.gif b/app/assets/images/loading.gif
old mode 100755
new mode 100644
similarity index 100%
rename from vendor/assets/images/loading.gif
rename to app/assets/images/loading.gif
diff --git a/vendor/assets/images/progressbar.gif b/app/assets/images/progressbar.gif
old mode 100755
new mode 100644
similarity index 100%
rename from vendor/assets/images/progressbar.gif
rename to app/assets/images/progressbar.gif
diff --git a/vendor/assets/javascripts/jquery-fileupload/basic.js b/app/assets/javascripts/jquery-fileupload/basic.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/basic.js
rename to app/assets/javascripts/jquery-fileupload/basic.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js b/app/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js
rename to app/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js b/app/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js
rename to app/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/index.js b/app/assets/javascripts/jquery-fileupload/index.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/index.js
rename to app/assets/javascripts/jquery-fileupload/index.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js
rename to app/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
rename to app/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js
rename to app/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js
rename to app/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js
rename to app/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js
rename to app/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/jquery.fileupload.js
rename to app/assets/javascripts/jquery-fileupload/jquery.fileupload.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js b/app/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
rename to app/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/locale.js b/app/assets/javascripts/jquery-fileupload/locale.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/locale.js
rename to app/assets/javascripts/jquery-fileupload/locale.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/vendor/canvas-to-blob.js b/app/assets/javascripts/jquery-fileupload/vendor/canvas-to-blob.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/vendor/canvas-to-blob.js
rename to app/assets/javascripts/jquery-fileupload/vendor/canvas-to-blob.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js b/app/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js
rename to app/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js b/app/assets/javascripts/jquery-fileupload/vendor/load-image.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js
rename to app/assets/javascripts/jquery-fileupload/vendor/load-image.js
diff --git a/vendor/assets/javascripts/jquery-fileupload/vendor/tmpl.js b/app/assets/javascripts/jquery-fileupload/vendor/tmpl.js
similarity index 100%
rename from vendor/assets/javascripts/jquery-fileupload/vendor/tmpl.js
rename to app/assets/javascripts/jquery-fileupload/vendor/tmpl.js
diff --git a/vendor/assets/stylesheets/jquery.fileupload-ui.scss b/app/assets/stylesheets/jquery.fileupload-ui.scss
similarity index 100%
rename from vendor/assets/stylesheets/jquery.fileupload-ui.scss
rename to app/assets/stylesheets/jquery.fileupload-ui.scss
diff --git a/jquery-fileupload-rails.gemspec b/jquery-fileupload-rails.gemspec
index 78b5549..cbc4e8c 100644
--- a/jquery-fileupload-rails.gemspec
+++ b/jquery-fileupload-rails.gemspec
@@ -13,12 +13,12 @@ Gem::Specification.new do |s|
s.rubyforge_project = "jquery-fileupload-rails"
- s.files = Dir["lib/**/*"] + Dir["vendor/**/*"] + ["Rakefile", "README.md"]
+ s.files = Dir["lib/**/*"] + Dir["app/**/*"] + ["Rakefile", "README.md"]
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]
s.add_dependency 'railties', '>= 3.1'
s.add_dependency 'actionpack', '>= 3.1'
- s.add_development_dependency 'rails', '>= 3.1'
+ s.add_development_dependency 'rails', '>= 3.1'
end
From 7c89052d182d6cc4c2ff4da0105e558894c7f30c Mon Sep 17 00:00:00 2001
From: Igor Pstyga
Date: Fri, 21 Nov 2014 15:17:22 -0800
Subject: [PATCH 2/4] Update assets to jQuery File Upload 9.8.0.
---
README.md | 32 +-
.../jquery-fileupload/angularjs.js | 12 +
.../jquery-fileupload/basic-plus.js | 11 +
.../javascripts/jquery-fileupload/basic.js | 7 +-
.../cors/jquery.postmessage-transport.js | 8 +-
.../cors/jquery.xdr-transport.js | 3 +-
.../javascripts/jquery-fileupload/index.js | 22 +-
.../jquery-fileupload/jquery-ui.js | 13 +
.../jquery.fileupload-angular.js | 317 ++++++++++------
.../jquery.fileupload-audio.js | 106 ++++++
.../jquery-fileupload/jquery.fileupload-fp.js | 227 ------------
.../jquery.fileupload-image.js | 315 ++++++++++++++++
.../jquery.fileupload-jquery-ui.js | 152 ++++++++
.../jquery.fileupload-process.js | 30 +-
.../jquery.fileupload-resize.js | 212 -----------
.../jquery-fileupload/jquery.fileupload-ui.js | 169 ++++++---
.../jquery.fileupload-validate.js | 29 +-
.../jquery.fileupload-video.js | 106 ++++++
.../jquery-fileupload/jquery.fileupload.js | 338 +++++++++++++-----
.../jquery.iframe-transport.js | 49 ++-
.../vendor/jquery.ui.widget.js | 116 +++---
.../jquery-fileupload/vendor/load-image.js | 337 ++++++++++-------
.../jquery-fileupload/vendor/tmpl.js | 17 +-
.../jquery.fileupload-noscript.scss | 22 ++
.../jquery.fileupload-ui-noscript.scss | 17 +
.../stylesheets/jquery.fileupload-ui.scss | 44 ++-
app/assets/stylesheets/jquery.fileupload.scss | 36 ++
jquery-fileupload-rails.gemspec | 4 +-
28 files changed, 1787 insertions(+), 964 deletions(-)
create mode 100644 app/assets/javascripts/jquery-fileupload/angularjs.js
create mode 100644 app/assets/javascripts/jquery-fileupload/basic-plus.js
mode change 100755 => 100644 app/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js
mode change 100755 => 100644 app/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js
create mode 100644 app/assets/javascripts/jquery-fileupload/jquery-ui.js
mode change 100755 => 100644 app/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js
create mode 100644 app/assets/javascripts/jquery-fileupload/jquery.fileupload-audio.js
delete mode 100644 app/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
create mode 100644 app/assets/javascripts/jquery-fileupload/jquery.fileupload-image.js
create mode 100644 app/assets/javascripts/jquery-fileupload/jquery.fileupload-jquery-ui.js
mode change 100755 => 100644 app/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js
delete mode 100755 app/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js
mode change 100755 => 100644 app/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js
mode change 100755 => 100644 app/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js
create mode 100644 app/assets/javascripts/jquery-fileupload/jquery.fileupload-video.js
mode change 100755 => 100644 app/assets/javascripts/jquery-fileupload/jquery.fileupload.js
mode change 100755 => 100644 app/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
create mode 100644 app/assets/stylesheets/jquery.fileupload-noscript.scss
create mode 100644 app/assets/stylesheets/jquery.fileupload-ui-noscript.scss
mode change 100755 => 100644 app/assets/stylesheets/jquery.fileupload-ui.scss
create mode 100644 app/assets/stylesheets/jquery.fileupload.scss
diff --git a/README.md b/README.md
index 4207f35..25bb8a2 100644
--- a/README.md
+++ b/README.md
@@ -6,9 +6,9 @@ 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.3
-* jQuery UI Widget 1.9.1+amd
+* jQuery File Upload User Interface Plugin 9.6.0
+* jQuery File Upload Plugin 5.42.0
+* jQuery UI Widget 1.11.1
## Installing Gem
@@ -23,14 +23,22 @@ 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/tmpl
//= 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-process
+ //= require jquery-fileupload/jquery.fileupload-image
+ //= require jquery-fileupload/jquery.fileupload-audio
+ //= require jquery-fileupload/jquery.fileupload-video
+ //= require jquery-fileupload/jquery.fileupload-validate
//= require jquery-fileupload/jquery.fileupload-ui
//= require jquery-fileupload/locale
+ //= require jquery-fileupload/jquery.fileupload-angular
+ //= require jquery-fileupload/jquery.fileupload-jquery-ui
+ //= require jquery-fileupload/cors/jquery.postmessage-transport
+ //= require jquery-fileupload/cors/jquery.xdr-transport
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)
@@ -42,12 +50,26 @@ The basic setup only includes the following files:
//= require jquery-fileupload/jquery.iframe-transport
//= require jquery-fileupload/jquery.fileupload
+You can also require the following to get the js from the Basic-Plus, AngularJS and jQuery UI Examples:
+
+ //= require jquery-fileupload/basic-plus
+
+ //= require jquery-fileupload/angularjs
+
+ //= require jquery-fileupload/jquery-ui
+
## Using the stylesheet
Require the stylesheet file to app/assets/stylesheets/application.css
+ *= require jquery.fileupload
*= require jquery.fileupload-ui
+There are also noscript styles for Browsers with Javascript disabled, to use them create a noscript.css and add it to your precompile-list and layout inside a noscript tag:
+
+ *= require jquery.fileupload-noscript
+ *= require jquery.fileupload-ui-noscript
+
## 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.
diff --git a/app/assets/javascripts/jquery-fileupload/angularjs.js b/app/assets/javascripts/jquery-fileupload/angularjs.js
new file mode 100644
index 0000000..7c97327
--- /dev/null
+++ b/app/assets/javascripts/jquery-fileupload/angularjs.js
@@ -0,0 +1,12 @@
+//= require jquery-fileupload/vendor/jquery.ui.widget
+//= require jquery-fileupload/vendor/load-image
+//= require jquery-fileupload/vendor/canvas-to-blob
+//= require jquery-fileupload/jquery.iframe-transport
+//= require jquery-fileupload/jquery.fileupload
+//= require jquery-fileupload/jquery.fileupload-process
+//= require jquery-fileupload/jquery.fileupload-image
+//= require jquery-fileupload/jquery.fileupload-audio
+//= require jquery-fileupload/jquery.fileupload-video
+//= require jquery-fileupload/jquery.fileupload-validate
+//= require jquery-fileupload/jquery.fileupload-angular
+//= require jquery-fileupload/locale
diff --git a/app/assets/javascripts/jquery-fileupload/basic-plus.js b/app/assets/javascripts/jquery-fileupload/basic-plus.js
new file mode 100644
index 0000000..b20313e
--- /dev/null
+++ b/app/assets/javascripts/jquery-fileupload/basic-plus.js
@@ -0,0 +1,11 @@
+//= require jquery-fileupload/vendor/jquery.ui.widget
+//= require jquery-fileupload/vendor/load-image
+//= require jquery-fileupload/vendor/canvas-to-blob
+//= require jquery-fileupload/jquery.iframe-transport
+//= require jquery-fileupload/jquery.fileupload
+//= require jquery-fileupload/jquery.fileupload-process
+//= require jquery-fileupload/jquery.fileupload-image
+//= require jquery-fileupload/jquery.fileupload-audio
+//= require jquery-fileupload/jquery.fileupload-video
+//= require jquery-fileupload/jquery.fileupload-validate
+//= require jquery-fileupload/locale
diff --git a/app/assets/javascripts/jquery-fileupload/basic.js b/app/assets/javascripts/jquery-fileupload/basic.js
index fa302cc..6d07907 100644
--- a/app/assets/javascripts/jquery-fileupload/basic.js
+++ b/app/assets/javascripts/jquery-fileupload/basic.js
@@ -1,4 +1,3 @@
-//=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
diff --git a/app/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js b/app/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js
old mode 100755
new mode 100644
index 931b635..2b4851e
--- a/app/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js
+++ b/app/assets/javascripts/jquery-fileupload/cors/jquery.postmessage-transport.js
@@ -1,5 +1,5 @@
/*
- * jQuery postMessage Transport Plugin 1.1
+ * jQuery postMessage Transport Plugin 1.1.1
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
@@ -9,8 +9,7 @@
* http://www.opensource.org/licenses/MIT
*/
-/*jslint unparam: true, nomen: true */
-/*global define, window, document */
+/* global define, window, document */
(function (factory) {
'use strict';
@@ -64,8 +63,9 @@
xhrUpload = options.xhr().upload;
return {
send: function (_, completeCallback) {
+ counter += 1;
var message = {
- id: 'postmessage-transport-' + (counter += 1)
+ id: 'postmessage-transport-' + counter
},
eventName = 'message.' + message.id;
iframe = $(
diff --git a/app/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js b/app/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js
old mode 100755
new mode 100644
index d769f45..0044cc2
--- a/app/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js
+++ b/app/assets/javascripts/jquery-fileupload/cors/jquery.xdr-transport.js
@@ -12,8 +12,7 @@
* https://github.com/jaubourg/ajaxHooks/
*/
-/*jslint unparam: true */
-/*global define, window, XDomainRequest */
+/* global define, window, XDomainRequest */
(function (factory) {
'use strict';
diff --git a/app/assets/javascripts/jquery-fileupload/index.js b/app/assets/javascripts/jquery-fileupload/index.js
index 0cda385..be03aa8 100644
--- a/app/assets/javascripts/jquery-fileupload/index.js
+++ b/app/assets/javascripts/jquery-fileupload/index.js
@@ -1,9 +1,13 @@
-//=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/tmpl
+//= require jquery-fileupload/vendor/load-image
+//= require jquery-fileupload/vendor/canvas-to-blob
+//= require jquery-fileupload/jquery.iframe-transport
+//= require jquery-fileupload/jquery.fileupload
+//= require jquery-fileupload/jquery.fileupload-process
+//= require jquery-fileupload/jquery.fileupload-image
+//= require jquery-fileupload/jquery.fileupload-audio
+//= require jquery-fileupload/jquery.fileupload-video
+//= require jquery-fileupload/jquery.fileupload-validate
+//= require jquery-fileupload/jquery.fileupload-ui
+//= require jquery-fileupload/locale
diff --git a/app/assets/javascripts/jquery-fileupload/jquery-ui.js b/app/assets/javascripts/jquery-fileupload/jquery-ui.js
new file mode 100644
index 0000000..cd29f8f
--- /dev/null
+++ b/app/assets/javascripts/jquery-fileupload/jquery-ui.js
@@ -0,0 +1,13 @@
+//= require jquery-fileupload/vendor/tmpl
+//= require jquery-fileupload/vendor/load-image
+//= require jquery-fileupload/vendor/canvas-to-blob
+//= require jquery-fileupload/jquery.iframe-transport
+//= require jquery-fileupload/jquery.fileupload
+//= require jquery-fileupload/jquery.fileupload-process
+//= require jquery-fileupload/jquery.fileupload-image
+//= require jquery-fileupload/jquery.fileupload-audio
+//= require jquery-fileupload/jquery.fileupload-video
+//= require jquery-fileupload/jquery.fileupload-validate
+//= require jquery-fileupload/jquery.fileupload-ui
+//= require jquery-fileupload/jquery.fileupload-jquery-ui
+//= require jquery-fileupload/locale
diff --git a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js
old mode 100755
new mode 100644
index e7ba784..e4ef392
--- a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js
+++ b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-angular.js
@@ -1,5 +1,5 @@
/*
- * jQuery File Upload AngularJS Plugin 1.0.1
+ * jQuery File Upload AngularJS Plugin 2.2.0
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
@@ -9,28 +9,73 @@
* http://www.opensource.org/licenses/MIT
*/
-/*jslint nomen: true, unparam: true */
-/*global angular */
+/* jshint nomen:false */
+/* global define, angular */
-(function () {
+(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ // Register as an anonymous AMD module:
+ define([
+ 'jquery',
+ 'angular',
+ './jquery.fileupload-image',
+ './jquery.fileupload-audio',
+ './jquery.fileupload-video',
+ './jquery.fileupload-validate'
+ ], factory);
+ } else {
+ factory();
+ }
+}(function () {
'use strict';
angular.module('blueimp.fileupload', [])
+ // The fileUpload service provides configuration options
+ // for the fileUpload directive and default handlers for
+ // File Upload events:
.provider('fileUpload', function () {
- var scopeApply = function () {
+ var scopeEvalAsync = function (expression) {
var scope = angular.element(this)
- .fileupload('option', 'scope')();
- if (!scope.$$phase) {
- scope.$apply();
- }
+ .fileupload('option', 'scope');
+ // Schedule a new $digest cycle if not already inside of one
+ // and evaluate the given expression:
+ scope.$evalAsync(expression);
+ },
+ addFileMethods = function (scope, data) {
+ var files = data.files,
+ file = files[0];
+ angular.forEach(files, function (file, index) {
+ file._index = index;
+ file.$state = function () {
+ return data.state();
+ };
+ file.$processing = function () {
+ return data.processing();
+ };
+ file.$progress = function () {
+ return data.progress();
+ };
+ file.$response = function () {
+ return data.response();
+ };
+ });
+ file.$submit = function () {
+ if (!file.error) {
+ return data.submit();
+ }
+ };
+ file.$cancel = function () {
+ return data.abort();
+ };
},
$config;
$config = this.defaults = {
handleResponse: function (e, data) {
var files = data.result && data.result.files;
if (files) {
- data.scope().replace(data.files, files);
+ data.scope.replace(data.files, files);
} else if (data.errorThrown ||
data.textStatus === 'error') {
data.files[0].error = data.errorThrown ||
@@ -38,81 +83,72 @@
}
},
add: function (e, data) {
- var scope = data.scope();
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+ var scope = data.scope,
+ filesCopy = [];
+ angular.forEach(data.files, function (file) {
+ filesCopy.push(file);
+ });
+ scope.$apply(function () {
+ addFileMethods(scope, data);
+ var method = scope.option('prependFiles') ?
+ 'unshift' : 'push';
+ Array.prototype[method].apply(scope.queue, data.files);
+ });
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();
- }
- });
+ }).always(function () {
+ scope.$apply(function () {
+ addFileMethods(scope, data);
+ scope.replace(filesCopy, data.files);
+ });
+ }).then(function () {
+ if ((scope.option('autoUpload') ||
+ data.autoUpload) &&
+ data.autoUpload !== false) {
+ data.submit();
}
- );
+ });
},
progress: function (e, data) {
- data.scope().$apply();
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+ data.scope.$apply();
},
done: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var that = this;
- data.scope().$apply(function () {
+ data.scope.$apply(function () {
data.handleResponse.call(that, e, data);
});
},
fail: function (e, data) {
- var that = this;
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+ var that = this,
+ scope = data.scope;
if (data.errorThrown === 'abort') {
+ scope.clear(data.files);
return;
}
- if (data.dataType.indexOf('json') === data.dataType.length - 4) {
- try {
- data.result = angular.fromJson(data.jqXHR.responseText);
- } catch (err) {}
- }
- data.scope().$apply(function () {
+ scope.$apply(function () {
data.handleResponse.call(that, e, data);
});
},
- stop: scopeApply,
- processstart: scopeApply,
- processstop: scopeApply,
+ stop: scopeEvalAsync,
+ processstart: scopeEvalAsync,
+ processstop: scopeEvalAsync,
getNumberOfFiles: function () {
- return this.scope().queue.length;
+ var scope = this.scope;
+ return scope.queue.length - scope.processing();
},
dataType: 'json',
- prependFiles: true,
autoUpload: false
};
this.$get = [
@@ -124,8 +160,9 @@
];
})
+ // Format byte numbers to readable presentations:
.provider('formatFileSizeFilter', function () {
- var $config = this.defaults = {
+ var $config = {
// Byte units following the IEC format
// http://en.wikipedia.org/wiki/Kilobyte
units: [
@@ -134,28 +171,61 @@
{size: 1000, suffix: ' KB'}
]
};
+ this.defaults = $config;
this.$get = function () {
return function (bytes) {
if (!angular.isNumber(bytes)) {
return '';
}
var unit = true,
- i = -1;
+ i = 0,
+ prefix,
+ suffix;
while (unit) {
- unit = $config.units[i += 1];
+ unit = $config.units[i];
+ prefix = unit.prefix || '';
+ suffix = unit.suffix || '';
if (i === $config.units.length - 1 || bytes >= unit.size) {
- return (bytes / unit.size).toFixed(2) + unit.suffix;
+ return prefix + (bytes / unit.size).toFixed(2) + suffix;
}
+ i += 1;
}
};
};
})
+ // The FileUploadController initializes the fileupload widget and
+ // provides scope methods to control the File Upload functionality:
.controller('FileUploadController', [
- '$scope', '$element', '$attrs', 'fileUpload',
- function ($scope, $element, $attrs, fileUpload) {
- $scope.disabled = angular.element('')
- .prop('disabled');
+ '$scope', '$element', '$attrs', '$window', 'fileUpload',
+ function ($scope, $element, $attrs, $window, fileUpload) {
+ var uploadMethods = {
+ progress: function () {
+ return $element.fileupload('progress');
+ },
+ active: function () {
+ return $element.fileupload('active');
+ },
+ option: function (option, data) {
+ if (arguments.length === 1) {
+ return $element.fileupload('option', option);
+ }
+ $element.fileupload('option', option, data);
+ },
+ add: function (data) {
+ return $element.fileupload('add', data);
+ },
+ send: function (data) {
+ return $element.fileupload('send', data);
+ },
+ process: function (data) {
+ return $element.fileupload('process', data);
+ },
+ processing: function (data) {
+ return $element.fileupload('processing', data);
+ }
+ };
+ $scope.disabled = !$window.jQuery.support.fileInput;
$scope.queue = $scope.queue || [];
$scope.clear = function (files) {
var queue = this.queue,
@@ -167,7 +237,8 @@
length = files.length;
}
while (i) {
- if (queue[i -= 1] === file) {
+ i -= 1;
+ if (queue[i] === file) {
return queue.splice(i, length);
}
}
@@ -186,27 +257,6 @@
}
}
};
- $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,
@@ -224,16 +274,26 @@
$scope.cancel = function () {
this.applyOnQueue('$cancel');
};
+ // Add upload methods to the scope:
+ angular.extend($scope, uploadMethods);
// 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;
- }},
+ {scope: $scope},
fileUpload.defaults
)).on('fileuploadadd', function (e, data) {
- data.scope = $scope.option('scope');
+ data.scope = $scope;
+ }).on('fileuploadfail', function (e, data) {
+ if (data.errorThrown === 'abort') {
+ return;
+ }
+ if (data.dataType &&
+ data.dataType.indexOf('json') === data.dataType.length - 4) {
+ try {
+ data.result = angular.fromJson(data.jqXHR.responseText);
+ } catch (ignore) {}
+ }
}).on([
'fileuploadadd',
'fileuploadsubmit',
@@ -260,12 +320,23 @@
'fileuploadprocessalways',
'fileuploadprocessstop'
].join(' '), function (e, data) {
- $scope.$emit(e.type, data);
+ if ($scope.$emit(e.type, data).defaultPrevented) {
+ e.preventDefault();
+ }
+ }).on('remove', function () {
+ // Remove upload methods from the scope,
+ // when the widget is removed:
+ var method;
+ for (method in uploadMethods) {
+ if (uploadMethods.hasOwnProperty(method)) {
+ delete $scope[method];
+ }
+ }
});
// Observe option changes:
$scope.$watch(
- $attrs.fileupload,
- function (newOptions, oldOptions) {
+ $attrs.fileUpload,
+ function (newOptions) {
if (newOptions) {
$element.fileupload('option', newOptions);
}
@@ -274,10 +345,11 @@
}
])
+ // Provide File Upload progress feedback:
.controller('FileUploadProgressController', [
'$scope', '$attrs', '$parse',
function ($scope, $attrs, $parse) {
- var fn = $parse($attrs.progress),
+ var fn = $parse($attrs.fileUploadProgress),
update = function () {
var progress = fn($scope);
if (!progress || !progress.total) {
@@ -289,7 +361,7 @@
};
update();
$scope.$watch(
- $attrs.progress + '.loaded',
+ $attrs.fileUploadProgress + '.loaded',
function (newValue, oldValue) {
if (newValue !== oldValue) {
update();
@@ -299,37 +371,46 @@
}
])
+ // Display File Upload previews:
.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);
- }
+ '$scope', '$element', '$attrs',
+ function ($scope, $element, $attrs) {
+ $scope.$watch(
+ $attrs.fileUploadPreview + '.preview',
+ function (preview) {
+ $element.empty();
+ if (preview) {
+ $element.append(preview);
+ }
+ }
+ );
}
])
- .directive('fileupload', function () {
+ .directive('fileUpload', function () {
return {
- controller: 'FileUploadController'
+ controller: 'FileUploadController',
+ scope: true
};
})
- .directive('progress', function () {
+ .directive('fileUploadProgress', function () {
return {
- controller: 'FileUploadProgressController'
+ controller: 'FileUploadProgressController',
+ scope: true
};
})
- .directive('preview', function () {
+ .directive('fileUploadPreview', function () {
return {
controller: 'FileUploadPreviewController'
};
})
+ // Enhance the HTML5 download attribute to
+ // allow drag&drop of files to the desktop:
.directive('download', function () {
- return function (scope, elm, attrs) {
+ return function (scope, elm) {
elm.on('dragstart', function (e) {
try {
e.originalEvent.dataTransfer.setData(
@@ -340,9 +421,9 @@
elm.prop('href')
].join(':')
);
- } catch (err) {}
+ } catch (ignore) {}
});
};
});
-}());
+}));
diff --git a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-audio.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-audio.js
new file mode 100644
index 0000000..575800e
--- /dev/null
+++ b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-audio.js
@@ -0,0 +1,106 @@
+/*
+ * jQuery File Upload Audio Preview Plugin 1.0.3
+ * https://github.com/blueimp/jQuery-File-Upload
+ *
+ * Copyright 2013, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ */
+
+/* jshint nomen:false */
+/* global define, window, document */
+
+(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ // Register as an anonymous AMD module:
+ define([
+ 'jquery',
+ 'load-image',
+ './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: 'loadAudio',
+ // Use the action as prefix for the "@" options:
+ prefix: true,
+ fileTypes: '@',
+ maxFileSize: '@',
+ disabled: '@disableAudioPreview'
+ },
+ {
+ action: 'setAudio',
+ name: '@audioPreviewName',
+ disabled: '@disableAudioPreview'
+ }
+ );
+
+ // The File Upload Audio Preview plugin extends the fileupload widget
+ // with audio preview functionality:
+ $.widget('blueimp.fileupload', $.blueimp.fileupload, {
+
+ options: {
+ // The regular expression for the types of audio files to load,
+ // matched against the file type:
+ loadAudioFileTypes: /^audio\/.*$/
+ },
+
+ _audioElement: document.createElement('audio'),
+
+ processActions: {
+
+ // Loads the audio file given via data.files and data.index
+ // as audio element if the browser supports playing it.
+ // Accepts the options fileTypes (regular expression)
+ // and maxFileSize (integer) to limit the files to load:
+ loadAudio: function (data, options) {
+ if (options.disabled) {
+ return data;
+ }
+ var file = data.files[data.index],
+ url,
+ audio;
+ if (this._audioElement.canPlayType &&
+ this._audioElement.canPlayType(file.type) &&
+ ($.type(options.maxFileSize) !== 'number' ||
+ file.size <= options.maxFileSize) &&
+ (!options.fileTypes ||
+ options.fileTypes.test(file.type))) {
+ url = loadImage.createObjectURL(file);
+ if (url) {
+ audio = this._audioElement.cloneNode(false);
+ audio.src = url;
+ audio.controls = true;
+ data.audio = audio;
+ return data;
+ }
+ }
+ return data;
+ },
+
+ // Sets the audio element as a property of the file object:
+ setAudio: function (data, options) {
+ if (data.audio && !options.disabled) {
+ data.files[data.index][options.name || 'preview'] = data.audio;
+ }
+ return data;
+ }
+
+ }
+
+ });
+
+}));
diff --git a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
deleted file mode 100644
index c782f1e..0000000
--- a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-fp.js
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * jQuery File Upload File Processing Plugin 1.2.3
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2012, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-/*jslint nomen: true, unparam: true, regexp: true */
-/*global define, window, document */
-
-(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define([
- 'jquery',
- 'load-image',
- 'canvas-to-blob',
- './jquery.fileupload'
- ], factory);
- } else {
- // Browser globals:
- factory(
- window.jQuery,
- window.loadImage
- );
- }
-}(function ($, loadImage) {
- 'use strict';
-
- // The File Upload FP version extends the fileupload widget
- // with file processing functionality:
- $.widget('blueimp.fileupload', $.blueimp.fileupload, {
-
- options: {
- // The list of file processing actions:
- process: [
- /*
- {
- action: 'load',
- fileTypes: /^image\/(gif|jpeg|png)$/,
- maxFileSize: 20000000 // 20MB
- },
- {
- action: 'resize',
- maxWidth: 1920,
- maxHeight: 1200,
- minWidth: 800,
- minHeight: 600
- },
- {
- action: 'save'
- }
- */
- ],
-
- // The add callback is invoked as soon as files are added to the
- // fileupload widget (via file input selection, drag & drop or add
- // API call). See the basic file upload widget for more information:
- add: function (e, data) {
- if (data.autoUpload || (data.autoUpload !== false &&
- ($(this).data('blueimp-fileupload') ||
- $(this).data('fileupload')).options.autoUpload)) {
- $(this).fileupload('process', data).done(function () {
- data.submit();
- });
- }
- }
- },
-
- processActions: {
- // Loads the image given via data.files and data.index
- // as img element if the browser supports canvas.
- // Accepts the options fileTypes (regular expression)
- // and maxFileSize (integer) to limit the files to load:
- load: function (data, options) {
- var that = this,
- file = data.files[data.index],
- dfd = $.Deferred();
- if (window.HTMLCanvasElement &&
- window.HTMLCanvasElement.prototype.toBlob &&
- ($.type(options.maxFileSize) !== 'number' ||
- file.size < options.maxFileSize) &&
- (!options.fileTypes ||
- options.fileTypes.test(file.type))) {
- loadImage(
- file,
- function (img) {
- if (!img.src) {
- return dfd.rejectWith(that, [data]);
- }
- data.img = img;
- dfd.resolveWith(that, [data]);
- }
- );
- } else {
- dfd.rejectWith(that, [data]);
- }
- return dfd.promise();
- },
- // Resizes the image given as data.img and updates
- // data.canvas with the resized image as canvas element.
- // Accepts the options maxWidth, maxHeight, minWidth and
- // minHeight to scale the given image:
- resize: function (data, options) {
- var img = data.img,
- canvas;
- options = $.extend({canvas: true}, options);
- if (img) {
- canvas = loadImage.scale(img, options);
- if (canvas.width !== img.width ||
- canvas.height !== img.height) {
- data.canvas = canvas;
- }
- }
- return data;
- },
- // Saves the processed image given as data.canvas
- // inplace at data.index of data.files:
- save: function (data, options) {
- // Do nothing if no processing has happened:
- if (!data.canvas) {
- return data;
- }
- var that = this,
- file = data.files[data.index],
- name = file.name,
- dfd = $.Deferred(),
- callback = function (blob) {
- if (!blob.name) {
- if (file.type === blob.type) {
- blob.name = file.name;
- } else if (file.name) {
- blob.name = file.name.replace(
- /\..+$/,
- '.' + blob.type.substr(6)
- );
- }
- }
- // Store the created blob at the position
- // of the original file in the files list:
- data.files[data.index] = blob;
- dfd.resolveWith(that, [data]);
- };
- // Use canvas.mozGetAsFile directly, to retain the filename, as
- // Gecko doesn't support the filename option for FormData.append:
- if (data.canvas.mozGetAsFile) {
- callback(data.canvas.mozGetAsFile(
- (/^image\/(jpeg|png)$/.test(file.type) && name) ||
- ((name && name.replace(/\..+$/, '')) ||
- 'blob') + '.png',
- file.type
- ));
- } else {
- data.canvas.toBlob(callback, file.type);
- }
- return dfd.promise();
- }
- },
-
- // Resizes the file at the given index and stores the created blob at
- // the original position of the files list, returns a Promise object:
- _processFile: function (files, index, options) {
- var that = this,
- dfd = $.Deferred().resolveWith(that, [{
- files: files,
- index: index
- }]),
- chain = dfd.promise();
- that._processing += 1;
- $.each(options.process, function (i, settings) {
- chain = chain.pipe(function (data) {
- return that.processActions[settings.action]
- .call(this, data, settings);
- });
- });
- chain.always(function () {
- that._processing -= 1;
- if (that._processing === 0) {
- that.element
- .removeClass('fileupload-processing');
- }
- });
- if (that._processing === 1) {
- that.element.addClass('fileupload-processing');
- }
- return chain;
- },
-
- // Processes the files given as files property of the data parameter,
- // returns a Promise object that allows to bind a done handler, which
- // will be invoked after processing all files (inplace) is done:
- process: function (data) {
- var that = this,
- options = $.extend({}, this.options, data);
- if (options.process && options.process.length &&
- this._isXHRUpload(options)) {
- $.each(data.files, function (index, file) {
- that._processingQueue = that._processingQueue.pipe(
- function () {
- var dfd = $.Deferred();
- that._processFile(data.files, index, options)
- .always(function () {
- dfd.resolveWith(that);
- });
- return dfd.promise();
- }
- );
- });
- }
- return this._processingQueue;
- },
-
- _create: function () {
- this._super();
- this._processing = 0;
- this._processingQueue = $.Deferred().resolveWith(this)
- .promise();
- }
-
- });
-
-}));
diff --git a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-image.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-image.js
new file mode 100644
index 0000000..5bb7026
--- /dev/null
+++ b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-image.js
@@ -0,0 +1,315 @@
+/*
+ * jQuery File Upload Image Preview & Resize Plugin 1.7.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
+ */
+
+/* jshint nomen:false */
+/* global define, window, Blob */
+
+(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ // Register as an anonymous AMD module:
+ define([
+ 'jquery',
+ 'load-image',
+ 'load-image-meta',
+ 'load-image-exif',
+ 'load-image-ios',
+ 'canvas-to-blob',
+ './jquery.fileupload-process'
+ ], factory);
+ } else {
+ // Browser globals:
+ factory(
+ window.jQuery,
+ window.loadImage
+ );
+ }
+}(function ($, loadImage) {
+ 'use strict';
+
+ // Prepend to the default processQueue:
+ $.blueimp.fileupload.prototype.options.processQueue.unshift(
+ {
+ action: 'loadImageMetaData',
+ disableImageHead: '@',
+ disableExif: '@',
+ disableExifThumbnail: '@',
+ disableExifSub: '@',
+ disableExifGps: '@',
+ disabled: '@disableImageMetaDataLoad'
+ },
+ {
+ action: 'loadImage',
+ // Use the action as prefix for the "@" options:
+ prefix: true,
+ fileTypes: '@',
+ maxFileSize: '@',
+ noRevoke: '@',
+ disabled: '@disableImageLoad'
+ },
+ {
+ action: 'resizeImage',
+ // Use "image" as prefix for the "@" options:
+ prefix: 'image',
+ maxWidth: '@',
+ maxHeight: '@',
+ minWidth: '@',
+ minHeight: '@',
+ crop: '@',
+ orientation: '@',
+ forceResize: '@',
+ disabled: '@disableImageResize'
+ },
+ {
+ action: 'saveImage',
+ quality: '@imageQuality',
+ type: '@imageType',
+ disabled: '@disableImageResize'
+ },
+ {
+ action: 'saveImageMetaData',
+ disabled: '@disableImageMetaDataSave'
+ },
+ {
+ action: 'resizeImage',
+ // Use "preview" as prefix for the "@" options:
+ prefix: 'preview',
+ maxWidth: '@',
+ maxHeight: '@',
+ minWidth: '@',
+ minHeight: '@',
+ crop: '@',
+ orientation: '@',
+ thumbnail: '@',
+ canvas: '@',
+ disabled: '@disableImagePreview'
+ },
+ {
+ action: 'setImage',
+ name: '@imagePreviewName',
+ disabled: '@disableImagePreview'
+ },
+ {
+ action: 'deleteImageReferences',
+ disabled: '@disableImageReferencesDeletion'
+ }
+ );
+
+ // The File Upload Resize plugin extends the fileupload widget
+ // with image resize functionality:
+ $.widget('blueimp.fileupload', $.blueimp.fileupload, {
+
+ options: {
+ // The regular expression for the types of images to load:
+ // matched against the file type:
+ loadImageFileTypes: /^image\/(gif|jpeg|png|svg\+xml)$/,
+ // The maximum file size of images to load:
+ loadImageMaxFileSize: 10000000, // 10MB
+ // The maximum width of resized images:
+ imageMaxWidth: 1920,
+ // The maximum height of resized images:
+ imageMaxHeight: 1080,
+ // Defines the image orientation (1-8) or takes the orientation
+ // value from Exif data if set to true:
+ imageOrientation: false,
+ // Define if resized images should be cropped or only scaled:
+ imageCrop: false,
+ // Disable the resize image functionality by default:
+ disableImageResize: true,
+ // The maximum width of the preview images:
+ previewMaxWidth: 80,
+ // The maximum height of the preview images:
+ previewMaxHeight: 80,
+ // Defines the preview orientation (1-8) or takes the orientation
+ // value from Exif data if set to true:
+ previewOrientation: true,
+ // Create the preview using the Exif data thumbnail:
+ previewThumbnail: true,
+ // Define if preview images should be cropped or only scaled:
+ previewCrop: false,
+ // Define if preview images should be resized as canvas elements:
+ previewCanvas: true
+ },
+
+ processActions: {
+
+ // Loads the image given via data.files and data.index
+ // as img element, if the browser supports the File API.
+ // Accepts the options fileTypes (regular expression)
+ // and maxFileSize (integer) to limit the files to load:
+ loadImage: function (data, options) {
+ if (options.disabled) {
+ return data;
+ }
+ var that = this,
+ file = data.files[data.index],
+ dfd = $.Deferred();
+ if (($.type(options.maxFileSize) === 'number' &&
+ file.size > options.maxFileSize) ||
+ (options.fileTypes &&
+ !options.fileTypes.test(file.type)) ||
+ !loadImage(
+ file,
+ function (img) {
+ if (img.src) {
+ data.img = img;
+ }
+ dfd.resolveWith(that, [data]);
+ },
+ options
+ )) {
+ return data;
+ }
+ return dfd.promise();
+ },
+
+ // Resizes the image given as data.canvas or data.img
+ // and updates data.canvas or data.img with the resized image.
+ // Also stores the resized image as preview property.
+ // Accepts the options maxWidth, maxHeight, minWidth,
+ // minHeight, canvas and crop:
+ resizeImage: function (data, options) {
+ if (options.disabled || !(data.canvas || data.img)) {
+ return data;
+ }
+ options = $.extend({canvas: true}, options);
+ var that = this,
+ dfd = $.Deferred(),
+ img = (options.canvas && data.canvas) || data.img,
+ resolve = function (newImg) {
+ if (newImg && (newImg.width !== img.width ||
+ newImg.height !== img.height ||
+ options.forceResize)) {
+ data[newImg.getContext ? 'canvas' : 'img'] = newImg;
+ }
+ data.preview = newImg;
+ dfd.resolveWith(that, [data]);
+ },
+ thumbnail;
+ if (data.exif) {
+ if (options.orientation === true) {
+ options.orientation = data.exif.get('Orientation');
+ }
+ if (options.thumbnail) {
+ thumbnail = data.exif.get('Thumbnail');
+ if (thumbnail) {
+ loadImage(thumbnail, resolve, options);
+ return dfd.promise();
+ }
+ }
+ // Prevent orienting the same image twice:
+ if (data.orientation) {
+ delete options.orientation;
+ } else {
+ data.orientation = options.orientation;
+ }
+ }
+ if (img) {
+ resolve(loadImage.scale(img, options));
+ return dfd.promise();
+ }
+ return data;
+ },
+
+ // Saves the processed image given as data.canvas
+ // inplace at data.index of data.files:
+ saveImage: function (data, options) {
+ if (!data.canvas || options.disabled) {
+ return data;
+ }
+ var that = this,
+ file = data.files[data.index],
+ dfd = $.Deferred();
+ if (data.canvas.toBlob) {
+ data.canvas.toBlob(
+ function (blob) {
+ if (!blob.name) {
+ if (file.type === blob.type) {
+ blob.name = file.name;
+ } else if (file.name) {
+ blob.name = file.name.replace(
+ /\..+$/,
+ '.' + blob.type.substr(6)
+ );
+ }
+ }
+ // Don't restore invalid meta data:
+ if (file.type !== blob.type) {
+ delete data.imageHead;
+ }
+ // Store the created blob at the position
+ // of the original file in the files list:
+ data.files[data.index] = blob;
+ dfd.resolveWith(that, [data]);
+ },
+ options.type || file.type,
+ options.quality
+ );
+ } else {
+ return data;
+ }
+ return dfd.promise();
+ },
+
+ loadImageMetaData: function (data, options) {
+ if (options.disabled) {
+ return data;
+ }
+ var that = this,
+ dfd = $.Deferred();
+ loadImage.parseMetaData(data.files[data.index], function (result) {
+ $.extend(data, result);
+ dfd.resolveWith(that, [data]);
+ }, options);
+ return dfd.promise();
+ },
+
+ saveImageMetaData: function (data, options) {
+ if (!(data.imageHead && data.canvas &&
+ data.canvas.toBlob && !options.disabled)) {
+ return data;
+ }
+ var file = data.files[data.index],
+ blob = new Blob([
+ data.imageHead,
+ // Resized images always have a head size of 20 bytes,
+ // including the JPEG marker and a minimal JFIF header:
+ this._blobSlice.call(file, 20)
+ ], {type: file.type});
+ blob.name = file.name;
+ data.files[data.index] = blob;
+ return data;
+ },
+
+ // Sets the resized version of the image as a property of the
+ // file object, must be called after "saveImage":
+ setImage: function (data, options) {
+ if (data.preview && !options.disabled) {
+ data.files[data.index][options.name || 'preview'] = data.preview;
+ }
+ return data;
+ },
+
+ deleteImageReferences: function (data, options) {
+ if (!options.disabled) {
+ delete data.img;
+ delete data.canvas;
+ delete data.preview;
+ delete data.imageHead;
+ }
+ return data;
+ }
+
+ }
+
+ });
+
+}));
diff --git a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-jquery-ui.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-jquery-ui.js
new file mode 100644
index 0000000..af0a00b
--- /dev/null
+++ b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-jquery-ui.js
@@ -0,0 +1,152 @@
+/*
+ * jQuery File Upload jQuery UI Plugin 8.7.1
+ * https://github.com/blueimp/jQuery-File-Upload
+ *
+ * Copyright 2013, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ */
+
+/* jshint nomen:false */
+/* global define, window */
+
+(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ // Register as an anonymous AMD module:
+ define(['jquery', './jquery.fileupload-ui'], factory);
+ } else {
+ // Browser globals:
+ factory(window.jQuery);
+ }
+}(function ($) {
+ 'use strict';
+
+ $.widget('blueimp.fileupload', $.blueimp.fileupload, {
+
+ options: {
+ processdone: function (e, data) {
+ data.context.find('.start').button('enable');
+ },
+ progress: function (e, data) {
+ if (data.context) {
+ data.context.find('.progress').progressbar(
+ 'option',
+ 'value',
+ parseInt(data.loaded / data.total * 100, 10)
+ );
+ }
+ },
+ progressall: function (e, data) {
+ var $this = $(this);
+ $this.find('.fileupload-progress')
+ .find('.progress').progressbar(
+ 'option',
+ 'value',
+ parseInt(data.loaded / data.total * 100, 10)
+ ).end()
+ .find('.progress-extended').each(function () {
+ $(this).html(
+ ($this.data('blueimp-fileupload') ||
+ $this.data('fileupload'))
+ ._renderExtendedProgress(data)
+ );
+ });
+ }
+ },
+
+ _renderUpload: function (func, files) {
+ var node = this._super(func, files),
+ showIconText = $(window).width() > 480;
+ node.find('.progress').empty().progressbar();
+ node.find('.start').button({
+ icons: {primary: 'ui-icon-circle-arrow-e'},
+ text: showIconText
+ });
+ node.find('.cancel').button({
+ icons: {primary: 'ui-icon-cancel'},
+ text: showIconText
+ });
+ if (node.hasClass('fade')) {
+ node.hide();
+ }
+ return node;
+ },
+
+ _renderDownload: function (func, files) {
+ var node = this._super(func, files),
+ showIconText = $(window).width() > 480;
+ node.find('.delete').button({
+ icons: {primary: 'ui-icon-trash'},
+ text: showIconText
+ });
+ if (node.hasClass('fade')) {
+ node.hide();
+ }
+ return node;
+ },
+
+ _startHandler: function (e) {
+ $(e.currentTarget).button('disable');
+ this._super(e);
+ },
+
+ _transition: function (node) {
+ var deferred = $.Deferred();
+ if (node.hasClass('fade')) {
+ node.fadeToggle(
+ this.options.transitionDuration,
+ this.options.transitionEasing,
+ function () {
+ deferred.resolveWith(node);
+ }
+ );
+ } else {
+ deferred.resolveWith(node);
+ }
+ return deferred;
+ },
+
+ _create: function () {
+ this._super();
+ this.element
+ .find('.fileupload-buttonbar')
+ .find('.fileinput-button').each(function () {
+ var input = $(this).find('input:file').detach();
+ $(this)
+ .button({icons: {primary: 'ui-icon-plusthick'}})
+ .append(input);
+ })
+ .end().find('.start')
+ .button({icons: {primary: 'ui-icon-circle-arrow-e'}})
+ .end().find('.cancel')
+ .button({icons: {primary: 'ui-icon-cancel'}})
+ .end().find('.delete')
+ .button({icons: {primary: 'ui-icon-trash'}})
+ .end().find('.progress').progressbar();
+ },
+
+ _destroy: function () {
+ this.element
+ .find('.fileupload-buttonbar')
+ .find('.fileinput-button').each(function () {
+ var input = $(this).find('input:file').detach();
+ $(this)
+ .button('destroy')
+ .append(input);
+ })
+ .end().find('.start')
+ .button('destroy')
+ .end().find('.cancel')
+ .button('destroy')
+ .end().find('.delete')
+ .button('destroy')
+ .end().find('.progress').progressbar('destroy');
+ this._super();
+ }
+
+ });
+
+}));
diff --git a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js
old mode 100755
new mode 100644
index 2f9eeed..8a6b929
--- a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js
+++ b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-process.js
@@ -1,5 +1,5 @@
/*
- * jQuery File Upload Processing Plugin 1.1
+ * jQuery File Upload Processing Plugin 1.3.0
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2012, Sebastian Tschan
@@ -9,8 +9,8 @@
* http://www.opensource.org/licenses/MIT
*/
-/*jslint nomen: true, unparam: true */
-/*global define, window */
+/* jshint nomen:false */
+/* global define, window */
(function (factory) {
'use strict';
@@ -64,13 +64,17 @@
*/
},
- _processFile: function (data) {
+ _processFile: function (data, originalData) {
var that = this,
dfd = $.Deferred().resolveWith(that, [data]),
chain = dfd.promise();
this._trigger('process', null, data);
$.each(data.processQueue, function (i, settings) {
var func = function (data) {
+ if (originalData.errorThrown) {
+ return $.Deferred()
+ .rejectWith(that, [originalData]).promise();
+ }
return that.processActions[settings.action].call(
that,
data,
@@ -98,14 +102,20 @@
_transformProcessQueue: function (options) {
var processQueue = [];
$.each(options.processQueue, function () {
- var settings = {};
+ var settings = {},
+ action = this.action,
+ prefix = this.prefix === true ? action : this.prefix;
$.each(this, function (key, value) {
if ($.type(value) === 'string' &&
value.charAt(0) === '@') {
- settings[key] = options[value.slice(1)];
+ settings[key] = options[
+ value.slice(1) || (prefix ? prefix +
+ key.charAt(0).toUpperCase() + key.slice(1) : key)
+ ];
} else {
settings[key] = value;
}
+
});
processQueue.push(settings);
});
@@ -127,10 +137,14 @@
if (this._processing === 0) {
this._trigger('processstart');
}
- $.each(data.files, function (index, file) {
+ $.each(data.files, function (index) {
var opts = index ? $.extend({}, options) : options,
func = function () {
- return that._processFile(opts);
+ if (data.errorThrown) {
+ return $.Deferred()
+ .rejectWith(that, [data]).promise();
+ }
+ return that._processFile(opts, data);
};
opts.index = index;
that._processing += 1;
diff --git a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js
deleted file mode 100755
index ae5c5be..0000000
--- a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-resize.js
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * jQuery File Upload Image Resize Plugin 1.1.2
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-/*jslint nomen: true, unparam: true, regexp: true */
-/*global define, window */
-
-(function (factory) {
- 'use strict';
- if (typeof define === 'function' && define.amd) {
- // Register as an anonymous AMD module:
- define([
- 'jquery',
- 'load-image',
- 'canvas-to-blob',
- './jquery.fileupload-process'
- ], factory);
- } else {
- // Browser globals:
- factory(
- window.jQuery,
- window.loadImage
- );
- }
-}(function ($, loadImage) {
- 'use strict';
-
- // Prepend to the default processQueue:
- $.blueimp.fileupload.prototype.options.processQueue.unshift(
- {
- action: 'loadImage',
- fileTypes: '@loadImageFileTypes',
- maxFileSize: '@loadImageMaxFileSize',
- noRevoke: '@loadImageNoRevoke',
- disabled: '@disableImageLoad'
- },
- {
- action: 'resizeImage',
- maxWidth: '@imageMaxWidth',
- maxHeight: '@imageMaxHeight',
- minWidth: '@imageMinWidth',
- minHeight: '@imageMinHeight',
- crop: '@imageCrop',
- disabled: '@disableImageResize'
- },
- {
- action: 'saveImage',
- disabled: '@disableImageResize'
- },
- {
- action: 'resizeImage',
- maxWidth: '@previewMaxWidth',
- maxHeight: '@previewMaxHeight',
- minWidth: '@previewMinWidth',
- minHeight: '@previewMinHeight',
- crop: '@previewCrop',
- canvas: '@previewAsCanvas',
- disabled: '@disableImagePreview'
- },
- {
- action: 'setImage',
- // The name of the property the resized image
- // is saved as on the associated file object:
- name: 'preview',
- disabled: '@disableImagePreview'
- }
- );
-
- // The File Upload Resize plugin extends the fileupload widget
- // with image resize functionality:
- $.widget('blueimp.fileupload', $.blueimp.fileupload, {
-
- options: {
- // The regular expression for the types of images to load:
- // matched against the file type:
- loadImageFileTypes: /^image\/(gif|jpeg|png)$/,
- // The maximum file size of images to load:
- loadImageMaxFileSize: 5000000, // 5MB
- // The maximum width of resized images:
- imageMaxWidth: 1920,
- // The maximum height of resized images:
- imageMaxHeight: 1080,
- // Define if resized images should be cropped or only scaled:
- imageCrop: false,
- // Disable the resize image functionality by default:
- disableImageResize: true,
- // The maximum width of the preview images:
- previewMaxWidth: 80,
- // The maximum height of the preview images:
- previewMaxHeight: 80,
- // Define if preview images should be cropped or only scaled:
- previewCrop: false,
- // Define if preview images should be resized as canvas elements:
- previewAsCanvas: true
- },
-
- processActions: {
-
- // Loads the image given via data.files and data.index
- // as img element if the browser supports canvas.
- // Accepts the options fileTypes (regular expression)
- // and maxFileSize (integer) to limit the files to load:
- loadImage: function (data, options) {
- if (options.disabled) {
- return data;
- }
- var that = this,
- file = data.files[data.index],
- dfd = $.Deferred();
- if (($.type(options.maxFileSize) === 'number' &&
- file.size > options.maxFileSize) ||
- (options.fileTypes &&
- !options.fileTypes.test(file.type)) ||
- !loadImage(
- file,
- function (img) {
- if (!img.src) {
- return dfd.rejectWith(that, [data]);
- }
- data.img = img;
- dfd.resolveWith(that, [data]);
- },
- options
- )) {
- dfd.rejectWith(that, [data]);
- }
- return dfd.promise();
- },
-
- // Resizes the image given as data.canvas or data.img
- // and updates data.canvas or data.img with the resized image.
- // Accepts the options maxWidth, maxHeight, minWidth,
- // minHeight, canvas and crop:
- resizeImage: function (data, options) {
- options = $.extend({canvas: true}, options);
- var img = (options.canvas && data.canvas) || data.img,
- canvas;
- if (img && !options.disabled) {
- canvas = loadImage.scale(img, options);
- if (canvas && (canvas.width !== img.width ||
- canvas.height !== img.height)) {
- data[canvas.getContext ? 'canvas' : 'img'] = canvas;
- }
- }
- return data;
- },
-
- // Saves the processed image given as data.canvas
- // inplace at data.index of data.files:
- saveImage: function (data, options) {
- if (!data.canvas || options.disabled) {
- return data;
- }
- var that = this,
- file = data.files[data.index],
- name = file.name,
- dfd = $.Deferred(),
- callback = function (blob) {
- if (!blob.name) {
- if (file.type === blob.type) {
- blob.name = file.name;
- } else if (file.name) {
- blob.name = file.name.replace(
- /\..+$/,
- '.' + blob.type.substr(6)
- );
- }
- }
- // Store the created blob at the position
- // of the original file in the files list:
- data.files[data.index] = blob;
- dfd.resolveWith(that, [data]);
- };
- // Use canvas.mozGetAsFile directly, to retain the filename, as
- // Gecko doesn't support the filename option for FormData.append:
- if (data.canvas.mozGetAsFile) {
- callback(data.canvas.mozGetAsFile(
- (/^image\/(jpeg|png)$/.test(file.type) && name) ||
- ((name && name.replace(/\..+$/, '')) ||
- 'blob') + '.png',
- file.type
- ));
- } else if (data.canvas.toBlob) {
- data.canvas.toBlob(callback, file.type);
- } else {
- return data;
- }
- return dfd.promise();
- },
-
- // Sets the resized version of the image as a property of the
- // file object, must be called after "saveImage":
- setImage: function (data, options) {
- var img = data.canvas || data.img;
- if (img && !options.disabled) {
- data.files[data.index][options.name] = img;
- }
- return data;
- }
-
- }
-
- });
-
-}));
diff --git a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js
old mode 100755
new mode 100644
index 5d22346..710e869
--- a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js
+++ b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-ui.js
@@ -1,5 +1,5 @@
/*
- * jQuery File Upload User Interface Plugin 8.2.1
+ * jQuery File Upload User Interface Plugin 9.6.0
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
@@ -9,8 +9,8 @@
* http://www.opensource.org/licenses/MIT
*/
-/*jslint nomen: true, unparam: true, regexp: true */
-/*global define, window, URL, webkitURL, FileReader */
+/* jshint nomen:false */
+/* global define, window */
(function (factory) {
'use strict';
@@ -19,7 +19,9 @@
define([
'jquery',
'tmpl',
- './jquery.fileupload-resize',
+ './jquery.fileupload-image',
+ './jquery.fileupload-audio',
+ './jquery.fileupload-video',
'./jquery.fileupload-validate'
], factory);
} else {
@@ -29,7 +31,7 @@
window.tmpl
);
}
-}(function ($, tmpl, loadImage) {
+}(function ($, tmpl) {
'use strict';
$.blueimp.fileupload.prototype._specialOptions.push(
@@ -61,10 +63,16 @@
// option of the $.ajax upload requests:
dataType: 'json',
+ // Error and info messages:
+ messages: {
+ unknownError: 'Unknown error'
+ },
+
// Function returning the current number of files,
// used by the maxNumberOfFiles validation:
getNumberOfFiles: function () {
- return this.filesContainer.children().length;
+ return this.filesContainer.children()
+ .not('.processing').length;
},
// Callback to retrieve the list of files from the server response:
@@ -79,33 +87,53 @@
// widget (via file input selection, drag & drop or add API call).
// See the basic file upload widget for more information:
add: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var $this = $(this),
that = $this.data('blueimp-fileupload') ||
$this.data('fileupload'),
- options = that.options,
- files = data.files;
+ options = that.options;
+ data.context = that._renderUpload(data.files)
+ .data('data', data)
+ .addClass('processing');
+ options.filesContainer[
+ options.prependFiles ? 'prepend' : 'append'
+ ](data.context);
+ that._forceReflow(data.context);
+ that._transition(data.context);
data.process(function () {
return $this.fileupload('process', data);
}).always(function () {
- data.context = that._renderUpload(files).data('data', data);
+ data.context.each(function (index) {
+ $(this).find('.size').text(
+ that._formatFileSize(data.files[index].size)
+ );
+ }).removeClass('processing');
that._renderPreviews(data);
- options.filesContainer[
- options.prependFiles ? 'prepend' : 'append'
- ](data.context);
- that._forceReflow(data.context);
- that._transition(data.context).done(
- function () {
- if ((that._trigger('added', e, data) !== false) &&
- (options.autoUpload || data.autoUpload) &&
- data.autoUpload !== false && !data.files.error) {
- data.submit();
+ }).done(function () {
+ data.context.find('.start').prop('disabled', false);
+ if ((that._trigger('added', e, data) !== false) &&
+ (options.autoUpload || data.autoUpload) &&
+ data.autoUpload !== false) {
+ data.submit();
+ }
+ }).fail(function () {
+ if (data.files.error) {
+ data.context.each(function (index) {
+ var error = data.files[index].error;
+ if (error) {
+ $(this).find('.error').text(error);
}
- }
- );
+ });
+ }
});
},
// Callback for the start of each file upload request:
send: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload');
if (data.context && data.dataType &&
@@ -118,7 +146,7 @@
!$.support.transition && 'progress-animated'
)
.attr('aria-valuenow', 100)
- .find('.bar').css(
+ .children().first().css(
'width',
'100%'
);
@@ -127,6 +155,9 @@
},
// Callback for successful uploads:
done: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload'),
getFilesFromResponse = data.getFilesFromResponse ||
@@ -137,8 +168,8 @@
if (data.context) {
data.context.each(function (index) {
var file = files[index] ||
- {error: 'Empty file upload result'},
- deferred = that._addFinishedDeferreds();
+ {error: 'Empty file upload result'};
+ deferred = that._addFinishedDeferreds();
that._transition($(this)).done(
function () {
var node = $(this);
@@ -157,8 +188,9 @@
);
});
} else {
- template = that._renderDownload(files)
- .appendTo(that.options.filesContainer);
+ template = that._renderDownload(files)[
+ that.options.prependFiles ? 'prependTo' : 'appendTo'
+ ](that.options.filesContainer);
that._forceReflow(template);
deferred = that._addFinishedDeferreds();
that._transition(template).done(
@@ -173,6 +205,9 @@
},
// Callback for failed (abort or error) uploads:
fail: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload'),
template,
@@ -182,7 +217,7 @@
if (data.errorThrown !== 'abort') {
var file = data.files[index];
file.error = file.error || data.errorThrown ||
- true;
+ data.i18n('unknownError');
deferred = that._addFinishedDeferreds();
that._transition($(this)).done(
function () {
@@ -213,8 +248,9 @@
}
});
} else if (data.errorThrown !== 'abort') {
- data.context = that._renderUpload(data.files)
- .appendTo(that.options.filesContainer)
+ data.context = that._renderUpload(data.files)[
+ that.options.prependFiles ? 'prependTo' : 'appendTo'
+ ](that.options.filesContainer)
.data('data', data);
that._forceReflow(data.context);
deferred = that._addFinishedDeferreds();
@@ -234,18 +270,26 @@
},
// Callback for upload progress events:
progress: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
+ var progress = Math.floor(data.loaded / data.total * 100);
if (data.context) {
- var progress = Math.floor(data.loaded / data.total * 100);
- data.context.find('.progress')
- .attr('aria-valuenow', progress)
- .find('.bar').css(
- 'width',
- progress + '%'
- );
+ data.context.each(function () {
+ $(this).find('.progress')
+ .attr('aria-valuenow', progress)
+ .children().first().css(
+ 'width',
+ progress + '%'
+ );
+ });
}
},
// Callback for global upload progress events:
progressall: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var $this = $(this),
progress = Math.floor(data.loaded / data.total * 100),
globalProgressNode = $this.find('.fileupload-progress'),
@@ -260,13 +304,16 @@
globalProgressNode
.find('.progress')
.attr('aria-valuenow', progress)
- .find('.bar').css(
+ .children().first().css(
'width',
progress + '%'
);
},
// Callback for uploads start, equivalent to the global ajaxStart event:
start: function (e) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload');
that._resetFinishedDeferreds();
@@ -278,6 +325,9 @@
},
// Callback for uploads stop, equivalent to the global ajaxStop event:
stop: function (e) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var that = $(this).data('blueimp-fileupload') ||
$(this).data('fileupload'),
deferred = that._addFinishedDeferreds();
@@ -289,31 +339,46 @@
function () {
$(this).find('.progress')
.attr('aria-valuenow', '0')
- .find('.bar').css('width', '0%');
+ .children().first().css('width', '0%');
$(this).find('.progress-extended').html(' ');
deferred.resolve();
}
);
},
- processstart: function () {
+ processstart: function (e) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
$(this).addClass('fileupload-processing');
},
- processstop: function () {
+ processstop: function (e) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
$(this).removeClass('fileupload-processing');
},
// Callback for file deletion:
destroy: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
var that = $(this).data('blueimp-fileupload') ||
- $(this).data('fileupload');
- if (data.url) {
- $.ajax(data).done(function () {
+ $(this).data('fileupload'),
+ removeNode = function () {
that._transition(data.context).done(
function () {
$(this).remove();
that._trigger('destroyed', e, data);
}
);
+ };
+ if (data.url) {
+ data.dataType = data.dataType || that.options.dataType;
+ $.ajax(data).done(removeNode).fail(function () {
+ that._trigger('destroyfailed', e, data);
});
+ } else {
+ removeNode();
}
}
},
@@ -446,20 +511,23 @@
var button = $(e.currentTarget),
template = button.closest('.template-upload'),
data = template.data('data');
- if (data && data.submit && !data.jqXHR && data.submit()) {
- button.prop('disabled', true);
+ button.prop('disabled', true);
+ if (data && data.submit) {
+ data.submit();
}
},
_cancelHandler: function (e) {
e.preventDefault();
- var template = $(e.currentTarget).closest('.template-upload'),
+ var template = $(e.currentTarget)
+ .closest('.template-upload,.template-download'),
data = template.data('data') || {};
- if (!data.jqXHR) {
+ data.context = data.context || template;
+ if (data.abort) {
+ data.abort();
+ } else {
data.errorThrown = 'abort';
this._trigger('fail', e, data);
- } else {
- data.jqXHR.abort();
}
},
@@ -606,6 +674,9 @@
_create: function () {
this._super();
this._resetFinishedDeferreds();
+ if (!$.support.fileInput) {
+ this._disableFileInputButton();
+ }
},
enable: function () {
diff --git a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js
old mode 100755
new mode 100644
index 2599da8..f93a18f
--- a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js
+++ b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-validate.js
@@ -1,5 +1,5 @@
/*
- * jQuery File Upload Validation Plugin 1.0.2
+ * jQuery File Upload Validation Plugin 1.1.2
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
@@ -9,8 +9,7 @@
* http://www.opensource.org/licenses/MIT
*/
-/*jslint nomen: true, unparam: true, regexp: true */
-/*global define, window */
+/* global define, window */
(function (factory) {
'use strict';
@@ -37,10 +36,10 @@
// even if the previous action was rejected:
always: true,
// Options taken from the global options map:
- acceptFileTypes: '@acceptFileTypes',
- maxFileSize: '@maxFileSize',
- minFileSize: '@minFileSize',
- maxNumberOfFiles: '@maxNumberOfFiles',
+ acceptFileTypes: '@',
+ maxFileSize: '@',
+ minFileSize: '@',
+ maxNumberOfFiles: '@',
disabled: '@disableValidation'
}
);
@@ -84,18 +83,22 @@
var dfd = $.Deferred(),
settings = this.options,
file = data.files[data.index],
- numberOfFiles = settings.getNumberOfFiles();
- if (numberOfFiles && $.type(options.maxNumberOfFiles) === 'number' &&
- numberOfFiles + data.files.length > options.maxNumberOfFiles) {
+ fileSize;
+ if (options.minFileSize || options.maxFileSize) {
+ fileSize = file.size;
+ }
+ if ($.type(options.maxNumberOfFiles) === 'number' &&
+ (settings.getNumberOfFiles() || 0) + data.files.length >
+ options.maxNumberOfFiles) {
file.error = settings.i18n('maxNumberOfFiles');
} else if (options.acceptFileTypes &&
!(options.acceptFileTypes.test(file.type) ||
options.acceptFileTypes.test(file.name))) {
file.error = settings.i18n('acceptFileTypes');
- } else if (options.maxFileSize && file.size > options.maxFileSize) {
+ } else if (fileSize > options.maxFileSize) {
file.error = settings.i18n('maxFileSize');
- } else if ($.type(file.size) === 'number' &&
- file.size < options.minFileSize) {
+ } else if ($.type(fileSize) === 'number' &&
+ fileSize < options.minFileSize) {
file.error = settings.i18n('minFileSize');
} else {
delete file.error;
diff --git a/app/assets/javascripts/jquery-fileupload/jquery.fileupload-video.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-video.js
new file mode 100644
index 0000000..3764b27
--- /dev/null
+++ b/app/assets/javascripts/jquery-fileupload/jquery.fileupload-video.js
@@ -0,0 +1,106 @@
+/*
+ * jQuery File Upload Video Preview Plugin 1.0.3
+ * https://github.com/blueimp/jQuery-File-Upload
+ *
+ * Copyright 2013, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ */
+
+/* jshint nomen:false */
+/* global define, window, document */
+
+(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ // Register as an anonymous AMD module:
+ define([
+ 'jquery',
+ 'load-image',
+ './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: 'loadVideo',
+ // Use the action as prefix for the "@" options:
+ prefix: true,
+ fileTypes: '@',
+ maxFileSize: '@',
+ disabled: '@disableVideoPreview'
+ },
+ {
+ action: 'setVideo',
+ name: '@videoPreviewName',
+ disabled: '@disableVideoPreview'
+ }
+ );
+
+ // The File Upload Video Preview plugin extends the fileupload widget
+ // with video preview functionality:
+ $.widget('blueimp.fileupload', $.blueimp.fileupload, {
+
+ options: {
+ // The regular expression for the types of video files to load,
+ // matched against the file type:
+ loadVideoFileTypes: /^video\/.*$/
+ },
+
+ _videoElement: document.createElement('video'),
+
+ processActions: {
+
+ // Loads the video file given via data.files and data.index
+ // as video element if the browser supports playing it.
+ // Accepts the options fileTypes (regular expression)
+ // and maxFileSize (integer) to limit the files to load:
+ loadVideo: function (data, options) {
+ if (options.disabled) {
+ return data;
+ }
+ var file = data.files[data.index],
+ url,
+ video;
+ if (this._videoElement.canPlayType &&
+ this._videoElement.canPlayType(file.type) &&
+ ($.type(options.maxFileSize) !== 'number' ||
+ file.size <= options.maxFileSize) &&
+ (!options.fileTypes ||
+ options.fileTypes.test(file.type))) {
+ url = loadImage.createObjectURL(file);
+ if (url) {
+ video = this._videoElement.cloneNode(false);
+ video.src = url;
+ video.controls = true;
+ data.video = video;
+ return data;
+ }
+ }
+ return data;
+ },
+
+ // Sets the video element as a property of the file object:
+ setVideo: function (data, options) {
+ if (data.video && !options.disabled) {
+ data.files[data.index][options.name || 'preview'] = data.video;
+ }
+ return data;
+ }
+
+ }
+
+ });
+
+}));
diff --git a/app/assets/javascripts/jquery-fileupload/jquery.fileupload.js b/app/assets/javascripts/jquery-fileupload/jquery.fileupload.js
old mode 100755
new mode 100644
index 03678f3..a4cfdc0
--- a/app/assets/javascripts/jquery-fileupload/jquery.fileupload.js
+++ b/app/assets/javascripts/jquery-fileupload/jquery.fileupload.js
@@ -1,5 +1,5 @@
/*
- * jQuery File Upload Plugin 5.31.1
+ * jQuery File Upload Plugin 5.42.0
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
@@ -9,8 +9,8 @@
* http://www.opensource.org/licenses/MIT
*/
-/*jslint nomen: true, unparam: true, regexp: true */
-/*global define, window, document, File, Blob, FormData, location */
+/* jshint nomen:false */
+/* global define, window, document, location, Blob, FormData */
(function (factory) {
'use strict';
@@ -27,12 +27,49 @@
}(function ($) {
'use strict';
+ // Detect file input support, based on
+ // http://viljamis.com/blog/2012/file-upload-support-on-mobile/
+ $.support.fileInput = !(new RegExp(
+ // Handle devices which give false positives for the feature detection:
+ '(Android (1\\.[0156]|2\\.[01]))' +
+ '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +
+ '|(w(eb)?OSBrowser)|(webOS)' +
+ '|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
+ ).test(window.navigator.userAgent) ||
+ // Feature detection for all other devices:
+ $('').prop('disabled'));
+
// The FileReader API is not actually used, but works as feature detection,
- // as e.g. Safari supports XHR file uploads via the FormData API,
- // but not non-multipart XHR file uploads:
- $.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader);
+ // as some Safari versions (5?) support XHR file uploads via the FormData API,
+ // but not non-multipart XHR file uploads.
+ // window.XMLHttpRequestUpload is not available on IE10, so we check for
+ // window.ProgressEvent instead to detect XHR2 file upload capability:
+ $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);
$.support.xhrFormDataFileUpload = !!window.FormData;
+ // Detect support for Blob slicing (required for chunked uploads):
+ $.support.blobSlice = window.Blob && (Blob.prototype.slice ||
+ Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
+
+ // Helper function to create drag handlers for dragover/dragenter/dragleave:
+ function getDragHandler(type) {
+ var isDragOver = type === 'dragover';
+ return function (e) {
+ e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
+ var dataTransfer = e.dataTransfer;
+ if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&
+ this._trigger(
+ type,
+ $.Event(type, {delegatedEvent: e})
+ ) !== false) {
+ e.preventDefault();
+ if (isDragOver) {
+ dataTransfer.dropEffect = 'copy';
+ }
+ }
+ };
+ }
+
// The fileupload widget listens for change events on file input fields defined
// via fileInput setting and paste or drop events of the given dropZone.
// In addition to the default jQuery Widget methods, the fileupload widget
@@ -47,9 +84,9 @@
// The drop target element(s), by the default the complete document.
// Set to null to disable drag & drop support:
dropZone: $(document),
- // The paste target element(s), by the default the complete document.
- // Set to null to disable paste support:
- pasteZone: $(document),
+ // The paste target element(s), by the default undefined.
+ // Set to a DOM node or jQuery object to enable file pasting:
+ pasteZone: undefined,
// The file input field(s), that are listened to for change events.
// If undefined, it is set to the file input fields inside
// of the widget element on plugin initialization.
@@ -72,6 +109,14 @@
// To limit the number of files uploaded with one XHR request,
// set the following option to an integer greater than 0:
limitMultiFileUploads: undefined,
+ // The following option limits the number of files uploaded with one
+ // XHR request to keep the request size under or equal to the defined
+ // limit in bytes:
+ limitMultiFileUploadSize: undefined,
+ // Multipart file uploads add a number of bytes to each uploaded file,
+ // therefore the following option adds an overhead for each file used
+ // in the limitMultiFileUploadSize configuration:
+ limitMultiFileUploadSizeOverhead: 512,
// Set the following option to true to issue all file upload requests
// in a sequential order:
sequentialUploads: false,
@@ -144,17 +189,23 @@
// The add callback is invoked as soon as files are added to the fileupload
// widget (via file input selection, drag & drop, paste or add API call).
// If the singleFileUploads option is enabled, this callback will be
- // called once for each file in the selection for XHR file uplaods, else
+ // called once for each file in the selection for XHR file uploads, else
// once for each file selection.
+ //
// The upload starts when the submit method is invoked on the data parameter.
// The data object contains a files property holding the added files
- // and allows to override plugin options as well as define ajax settings.
+ // and allows you to override plugin options as well as define ajax settings.
+ //
// Listeners for this callback can also be bound the following way:
// .bind('fileuploadadd', func);
+ //
// data.submit() returns a Promise object and allows to attach additional
// handlers using jQuery's Deferred callbacks:
// data.submit().done(func).fail(func).always(func);
add: function (e, data) {
+ if (e.isDefaultPrevented()) {
+ return false;
+ }
if (data.autoUpload || (data.autoUpload !== false &&
$(this).fileupload('option', 'autoUpload'))) {
data.process().done(function () {
@@ -233,6 +284,11 @@
'forceIframeTransport'
],
+ _blobSlice: $.support.blobSlice && function () {
+ var slice = this.slice || this.webkitSlice || this.mozSlice;
+ return slice.apply(this, arguments);
+ },
+
_BitrateTimer: function () {
this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());
this.loaded = 0;
@@ -256,7 +312,7 @@
_getFormData: function (options) {
var formData;
- if (typeof options.formData === 'function') {
+ if ($.type(options.formData) === 'function') {
return options.formData(options.form);
}
if ($.isArray(options.formData)) {
@@ -336,10 +392,18 @@
// Trigger a custom progress event with a total data property set
// to the file size(s) of the current upload and a loaded data
// property calculated accordingly:
- this._trigger('progress', e, data);
+ this._trigger(
+ 'progress',
+ $.Event('progress', {delegatedEvent: e}),
+ data
+ );
// Trigger a global progress event for all current file uploads,
// including ajax calls queued for sequential file uploads:
- this._trigger('progressall', e, this._progress);
+ this._trigger(
+ 'progressall',
+ $.Event('progressall', {delegatedEvent: e}),
+ this._progress
+ );
}
},
@@ -374,15 +438,18 @@
file = options.files[0],
// Ignore non-multipart setting if not supported:
multipart = options.multipart || !$.support.xhrFileUpload,
- paramName = options.paramName[0];
- options.headers = options.headers || {};
+ paramName = $.type(options.paramName) === 'array' ?
+ options.paramName[0] : options.paramName;
+ options.headers = $.extend({}, options.headers);
if (options.contentRange) {
options.headers['Content-Range'] = options.contentRange;
}
- if (!multipart) {
+ if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
options.headers['Content-Disposition'] = 'attachment; filename="' +
encodeURI(file.name) + '"';
- options.contentType = file.type;
+ }
+ if (!multipart) {
+ options.contentType = file.type || 'application/octet-stream';
options.data = options.blob || file;
} else if ($.support.xhrFormDataFileUpload) {
if (options.postMessage) {
@@ -399,7 +466,8 @@
} else {
$.each(options.files, function (index, file) {
formData.push({
- name: options.paramName[index] || paramName,
+ name: ($.type(options.paramName) === 'array' &&
+ options.paramName[index]) || paramName,
value: file
});
});
@@ -414,8 +482,6 @@
});
}
if (options.blob) {
- options.headers['Content-Disposition'] = 'attachment; filename="' +
- encodeURI(file.name) + '"';
formData.append(paramName, options.blob, file.name);
} else {
$.each(options.files, function (index, file) {
@@ -424,9 +490,10 @@
if (that._isInstanceOf('File', file) ||
that._isInstanceOf('Blob', file)) {
formData.append(
- options.paramName[index] || paramName,
+ ($.type(options.paramName) === 'array' &&
+ options.paramName[index]) || paramName,
file,
- file.name
+ file.uploadName || file.name
);
}
});
@@ -439,13 +506,13 @@
},
_initIframeSettings: function (options) {
+ var targetHost = $('').prop('href', options.url).prop('host');
// Setting the dataType to iframe enables the iframe transport:
options.dataType = 'iframe ' + (options.dataType || '');
// The iframe transport accepts a serialized array as form data:
options.formData = this._getFormData(options);
// Add redirect url to form data on cross-domain uploads:
- if (options.redirect && $('').prop('href', options.url)
- .prop('host') !== location.host) {
+ if (options.redirect && targetHost && targetHost !== location.host) {
options.formData.push({
name: options.redirectParamName || 'redirect',
value: options.redirect
@@ -510,8 +577,10 @@
options.url = options.form.prop('action') || location.href;
}
// The HTTP request method must be "POST" or "PUT":
- options.type = (options.type || options.form.prop('method') || '')
- .toUpperCase();
+ options.type = (options.type ||
+ ($.type(options.form.prop('method')) === 'string' &&
+ options.form.prop('method')) || ''
+ ).toUpperCase();
if (options.type !== 'POST' && options.type !== 'PUT' &&
options.type !== 'PATCH') {
options.type = 'POST';
@@ -570,22 +639,32 @@
// Adds convenience methods to the data callback argument:
_addConvenienceMethods: function (e, data) {
var that = this,
- getPromise = function (data) {
- return $.Deferred().resolveWith(that, [data]).promise();
+ getPromise = function (args) {
+ return $.Deferred().resolveWith(that, args).promise();
};
data.process = function (resolveFunc, rejectFunc) {
if (resolveFunc || rejectFunc) {
data._processQueue = this._processQueue =
- (this._processQueue || getPromise(this))
- .pipe(resolveFunc, rejectFunc);
+ (this._processQueue || getPromise([this])).pipe(
+ function () {
+ if (data.errorThrown) {
+ return $.Deferred()
+ .rejectWith(that, [data]).promise();
+ }
+ return getPromise(arguments);
+ }
+ ).pipe(resolveFunc, rejectFunc);
}
- return this._processQueue || getPromise(this);
+ return this._processQueue || getPromise([this]);
};
data.submit = function () {
if (this.state() !== 'pending') {
data.jqXHR = this.jqXHR =
- (that._trigger('submit', e, this) !== false) &&
- that._onSend(e, this);
+ (that._trigger(
+ 'submit',
+ $.Event('submit', {delegatedEvent: e}),
+ this
+ ) !== false) && that._onSend(e, this);
}
return this.jqXHR || that._getXHRPromise();
};
@@ -593,7 +672,9 @@
if (this.jqXHR) {
return this.jqXHR.abort();
}
- return that._getXHRPromise();
+ this.errorThrown = 'abort';
+ that._trigger('fail', null, this);
+ return that._getXHRPromise(false);
};
data.state = function () {
if (this.jqXHR) {
@@ -603,6 +684,10 @@
return that._getDeferredState(this._processQueue);
}
};
+ data.processing = function () {
+ return !this.jqXHR && this._processQueue && that
+ ._getDeferredState(this._processQueue) === 'pending';
+ };
data.progress = function () {
return this._progress;
};
@@ -627,12 +712,13 @@
// should be uploaded in chunks, but does not invoke any
// upload requests:
_chunkedUpload: function (options, testOnly) {
+ options.uploadedBytes = options.uploadedBytes || 0;
var that = this,
file = options.files[0],
fs = file.size,
- ub = options.uploadedBytes = options.uploadedBytes || 0,
+ ub = options.uploadedBytes,
mcs = options.maxChunkSize || fs,
- slice = file.slice || file.webkitSlice || file.mozSlice,
+ slice = this._blobSlice,
dfd = $.Deferred(),
promise = dfd.promise(),
jqXHR,
@@ -804,7 +890,11 @@
// Set timer for bitrate progress calculation:
options._bitrateTimer = new that._BitrateTimer();
jqXHR = jqXHR || (
- ((aborted || that._trigger('send', e, options) === false) &&
+ ((aborted || that._trigger(
+ 'send',
+ $.Event('send', {delegatedEvent: e}),
+ options
+ ) === false) &&
that._getXHRPromise(false, options.context, aborted)) ||
that._chunkedUpload(options) || $.ajax(options)
).done(function (result, textStatus, jqXHR) {
@@ -850,7 +940,8 @@
this._slots.push(slot);
pipe = slot.pipe(send);
} else {
- pipe = (this._sequence = this._sequence.pipe(send, send));
+ this._sequence = this._sequence.pipe(send, send);
+ pipe = this._sequence;
}
// Return the piped Promise object, enhanced with an abort method,
// which is delegated to the jqXHR object of the current upload,
@@ -874,46 +965,80 @@
var that = this,
result = true,
options = $.extend({}, this.options, data),
+ files = data.files,
+ filesLength = files.length,
limit = options.limitMultiFileUploads,
+ limitSize = options.limitMultiFileUploadSize,
+ overhead = options.limitMultiFileUploadSizeOverhead,
+ batchSize = 0,
paramName = this._getParamName(options),
paramNameSet,
paramNameSlice,
fileSet,
- i;
- if (!(options.singleFileUploads || limit) ||
+ i,
+ j = 0;
+ if (limitSize && (!filesLength || files[0].size === undefined)) {
+ limitSize = undefined;
+ }
+ if (!(options.singleFileUploads || limit || limitSize) ||
!this._isXHRUpload(options)) {
- fileSet = [data.files];
+ fileSet = [files];
paramNameSet = [paramName];
- } else if (!options.singleFileUploads && limit) {
+ } else if (!(options.singleFileUploads || limitSize) && limit) {
fileSet = [];
paramNameSet = [];
- for (i = 0; i < data.files.length; i += limit) {
- fileSet.push(data.files.slice(i, i + limit));
+ for (i = 0; i < filesLength; i += limit) {
+ fileSet.push(files.slice(i, i + limit));
paramNameSlice = paramName.slice(i, i + limit);
if (!paramNameSlice.length) {
paramNameSlice = paramName;
}
paramNameSet.push(paramNameSlice);
}
+ } else if (!options.singleFileUploads && limitSize) {
+ fileSet = [];
+ paramNameSet = [];
+ for (i = 0; i < filesLength; i = i + 1) {
+ batchSize += files[i].size + overhead;
+ if (i + 1 === filesLength ||
+ ((batchSize + files[i + 1].size + overhead) > limitSize) ||
+ (limit && i + 1 - j >= limit)) {
+ fileSet.push(files.slice(j, i + 1));
+ paramNameSlice = paramName.slice(j, i + 1);
+ if (!paramNameSlice.length) {
+ paramNameSlice = paramName;
+ }
+ paramNameSet.push(paramNameSlice);
+ j = i + 1;
+ batchSize = 0;
+ }
+ }
} else {
paramNameSet = paramName;
}
- data.originalFiles = data.files;
- $.each(fileSet || data.files, function (index, element) {
+ data.originalFiles = files;
+ $.each(fileSet || files, function (index, element) {
var newData = $.extend({}, data);
newData.files = fileSet ? element : [element];
newData.paramName = paramNameSet[index];
that._initResponseObject(newData);
that._initProgressObject(newData);
that._addConvenienceMethods(e, newData);
- result = that._trigger('add', e, newData);
+ result = that._trigger(
+ 'add',
+ $.Event('add', {delegatedEvent: e}),
+ newData
+ );
return result;
});
return result;
},
- _replaceFileInput: function (input) {
- var inputClone = input.clone(true);
+ _replaceFileInput: function (data) {
+ var input = data.fileInput,
+ inputClone = input.clone(true);
+ // Add a reference for the new cloned file input to the data argument:
+ data.fileInputClone = inputClone;
$('').append(inputClone)[0].reset();
// Detaching allows to insert the fileInput on another form
// without loosing the file input value:
@@ -949,7 +1074,25 @@
// to be returned together in one set:
dfd.resolve([e]);
},
- dirReader;
+ successHandler = function (entries) {
+ that._handleFileTreeEntries(
+ entries,
+ path + entry.name + '/'
+ ).done(function (files) {
+ dfd.resolve(files);
+ }).fail(errorHandler);
+ },
+ readEntries = function () {
+ dirReader.readEntries(function (results) {
+ if (!results.length) {
+ successHandler(entries);
+ } else {
+ entries = entries.concat(results);
+ readEntries();
+ }
+ }, errorHandler);
+ },
+ dirReader, entries = [];
path = path || '';
if (entry.isFile) {
if (entry._file) {
@@ -964,14 +1107,7 @@
}
} else if (entry.isDirectory) {
dirReader = entry.createReader();
- dirReader.readEntries(function (entries) {
- that._handleFileTreeEntries(
- entries,
- path + entry.name + '/'
- ).done(function (files) {
- dfd.resolve(files);
- }).fail(errorHandler);
- }, errorHandler);
+ readEntries();
} else {
// Return an empy list for file system items
// other than files or directories:
@@ -1073,9 +1209,13 @@
this._getFileInputFiles(data.fileInput).always(function (files) {
data.files = files;
if (that.options.replaceFileInput) {
- that._replaceFileInput(data.fileInput);
+ that._replaceFileInput(data);
}
- if (that._trigger('change', e, data) !== false) {
+ if (that._trigger(
+ 'change',
+ $.Event('change', {delegatedEvent: e}),
+ data
+ ) !== false) {
that._onAdd(e, data);
}
});
@@ -1092,60 +1232,65 @@
data.files.push(file);
}
});
- if (this._trigger('paste', e, data) === false ||
- this._onAdd(e, data) === false) {
- return false;
+ if (this._trigger(
+ 'paste',
+ $.Event('paste', {delegatedEvent: e}),
+ data
+ ) !== false) {
+ this._onAdd(e, data);
}
}
},
_onDrop: function (e) {
+ e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
var that = this,
- dataTransfer = e.dataTransfer = e.originalEvent &&
- e.originalEvent.dataTransfer,
+ dataTransfer = e.dataTransfer,
data = {};
if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
e.preventDefault();
this._getDroppedFiles(dataTransfer).always(function (files) {
data.files = files;
- if (that._trigger('drop', e, data) !== false) {
+ if (that._trigger(
+ 'drop',
+ $.Event('drop', {delegatedEvent: e}),
+ data
+ ) !== false) {
that._onAdd(e, data);
}
});
}
},
- _onDragOver: function (e) {
- var dataTransfer = e.dataTransfer = e.originalEvent &&
- e.originalEvent.dataTransfer;
- if (dataTransfer) {
- if (this._trigger('dragover', e) === false) {
- return false;
- }
- if ($.inArray('Files', dataTransfer.types) !== -1) {
- dataTransfer.dropEffect = 'copy';
- e.preventDefault();
- }
- }
- },
+ _onDragOver: getDragHandler('dragover'),
+
+ _onDragEnter: getDragHandler('dragenter'),
+
+ _onDragLeave: getDragHandler('dragleave'),
_initEventHandlers: function () {
if (this._isXHRUpload(this.options)) {
this._on(this.options.dropZone, {
dragover: this._onDragOver,
- drop: this._onDrop
+ drop: this._onDrop,
+ // event.preventDefault() on dragenter is required for IE10+:
+ dragenter: this._onDragEnter,
+ // dragleave is not required, but added for completeness:
+ dragleave: this._onDragLeave
});
this._on(this.options.pasteZone, {
paste: this._onPaste
});
}
- this._on(this.options.fileInput, {
- change: this._onChange
- });
+ if ($.support.fileInput) {
+ this._on(this.options.fileInput, {
+ change: this._onChange
+ });
+ }
},
_destroyEventHandlers: function () {
- this._off(this.options.dropZone, 'dragover drop');
+ this._off(this.options.dropZone, 'dragenter dragleave dragover drop');
this._off(this.options.pasteZone, 'paste');
this._off(this.options.fileInput, 'change');
},
@@ -1192,15 +1337,21 @@
_initDataAttributes: function () {
var that = this,
- options = this.options;
+ options = this.options,
+ clone = $(this.element[0].cloneNode(false));
// Initialize options set via HTML5 data-attributes:
$.each(
- $(this.element[0].cloneNode(false)).data(),
+ clone.data(),
function (key, value) {
- if (that._isRegExpOption(key, value)) {
- value = that._getRegExp(value);
+ var dataAttributeName = 'data-' +
+ // Convert camelCase to hyphen-ated key:
+ key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
+ if (clone.attr(dataAttributeName)) {
+ if (that._isRegExpOption(key, value)) {
+ value = that._getRegExp(value);
+ }
+ options[key] = value;
}
- options[key] = value;
}
);
},
@@ -1275,8 +1426,13 @@
if (aborted) {
return;
}
+ if (!files.length) {
+ dfd.reject();
+ return;
+ }
data.files = files;
- jqXHR = that._onSend(null, data).then(
+ jqXHR = that._onSend(null, data);
+ jqXHR.then(
function (result, textStatus, jqXHR) {
dfd.resolve(result, textStatus, jqXHR);
},
diff --git a/app/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js b/app/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
old mode 100755
new mode 100644
index e04e7a0..8d64b59
--- a/app/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
+++ b/app/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js
@@ -1,5 +1,5 @@
/*
- * jQuery Iframe Transport Plugin 1.6.2
+ * jQuery Iframe Transport Plugin 1.8.2
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
@@ -9,8 +9,7 @@
* http://www.opensource.org/licenses/MIT
*/
-/*jslint unparam: true, nomen: true */
-/*global define, window, document */
+/* global define, window, document */
(function (factory) {
'use strict';
@@ -27,7 +26,7 @@
// Helper variable to create unique names for the transport iframes:
var counter = 0;
- // The iframe transport accepts three additional options:
+ // The iframe transport accepts four additional options:
// options.fileInput: a jQuery collection of file input fields
// options.paramName: the parameter name for the file form data,
// overrides the name property of the file input field(s),
@@ -35,9 +34,16 @@
// options.formData: an array of objects with name and value properties,
// equivalent to the return data of .serializeArray(), e.g.:
// [{name: 'a', value: 1}, {name: 'b', value: 2}]
+ // options.initialIframeSrc: the URL of the initial iframe src,
+ // by default set to "javascript:false;"
$.ajaxTransport('iframe', function (options) {
if (options.async) {
- var form,
+ // javascript:false as initial iframe src
+ // prevents warning popups on HTTPS in IE6:
+ /*jshint scripturl: true */
+ var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
+ /*jshint scripturl: false */
+ form,
iframe,
addParamChar;
return {
@@ -56,15 +62,13 @@
options.url = options.url + addParamChar + '_method=PATCH';
options.type = 'POST';
}
- // javascript:false as initial iframe src
- // prevents warning popups on HTTPS in IE6.
// IE versions below IE8 cannot set the name property of
// elements that have already been added to the DOM,
// so we set the name along with the iframe HTML markup:
counter += 1;
iframe = $(
- ''
+ ''
).bind('load', function () {
var fileInputClones,
paramNames = $.isArray(options.paramName) ?
@@ -95,7 +99,7 @@
);
// Fix for IE endless progress bar activity bug
// (happens on form submits to iframe targets):
- $('')
+ $('')
.appendTo(form);
window.setTimeout(function () {
// Removing the form in a setTimeout call
@@ -138,6 +142,8 @@
.prop('enctype', 'multipart/form-data')
// enctype must be set as encoding for IE:
.prop('encoding', 'multipart/form-data');
+ // Remove the HTML5 form attribute from the input(s):
+ options.fileInput.removeAttr('form');
}
form.submit();
// Insert the file input fields at their original location
@@ -145,7 +151,10 @@
if (fileInputClones && fileInputClones.length) {
options.fileInput.each(function (index, input) {
var clone = $(fileInputClones[index]);
- $(input).prop('name', clone.prop('name'));
+ // Restore the original name and form properties:
+ $(input)
+ .prop('name', clone.prop('name'))
+ .attr('form', clone.attr('form'));
clone.replaceWith(input);
});
}
@@ -159,7 +168,7 @@
// concat is used to avoid the "Script URL" JSLint error:
iframe
.unbind('load')
- .prop('src', 'javascript'.concat(':false;'));
+ .prop('src', initialIframeSrc);
}
if (form) {
form.remove();
@@ -170,7 +179,15 @@
});
// The iframe transport returns the iframe content document as response.
- // The following adds converters from iframe to text, json, html, and script:
+ // The following adds converters from iframe to text, json, html, xml
+ // and script.
+ // Please note that the Content-Type for JSON responses has to be text/plain
+ // or text/html, if the browser doesn't include application/json in the
+ // Accept header, else IE will show a download dialog.
+ // The Content-Type for XML responses on the other hand has to be always
+ // application/xml or text/xml, so IE properly parses the XML response.
+ // See also
+ // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
$.ajaxSetup({
converters: {
'iframe text': function (iframe) {
@@ -182,6 +199,12 @@
'iframe html': function (iframe) {
return iframe && $(iframe[0].body).html();
},
+ 'iframe xml': function (iframe) {
+ var xmlDoc = iframe && iframe[0];
+ return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
+ $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
+ $(xmlDoc.body).html());
+ },
'iframe script': function (iframe) {
return iframe && $.globalEval($(iframe[0].body).text());
}
diff --git a/app/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js b/app/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js
index fd2948f..7899e6b 100644
--- a/app/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js
+++ b/app/assets/javascripts/jquery-fileupload/vendor/jquery.ui.widget.js
@@ -1,36 +1,52 @@
-/*
- * jQuery UI Widget 1.10.1+amd
- * https://github.com/blueimp/jQuery-File-Upload
+/*! jQuery UI - v1.11.1 - 2014-09-17
+* http://jqueryui.com
+* Includes: widget.js
+* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
+
+(function( factory ) {
+ if ( typeof define === "function" && define.amd ) {
+
+ // AMD. Register as an anonymous module.
+ define([ "jquery" ], factory );
+ } else {
+
+ // Browser globals
+ factory( jQuery );
+ }
+}(function( $ ) {
+/*!
+ * jQuery UI Widget 1.11.1
+ * http://jqueryui.com
*
- * Copyright 2013 jQuery Foundation and other contributors
+ * Copyright 2014 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* http://api.jqueryui.com/jQuery.widget/
*/
-(function (factory) {
- if (typeof define === "function" && define.amd) {
- // Register as an anonymous AMD module:
- define(["jquery"], factory);
- } else {
- // Browser globals:
- factory(jQuery);
- }
-}(function( $, undefined ) {
-
-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 );
-};
+
+var widget_uuid = 0,
+ widget_slice = Array.prototype.slice;
+
+$.cleanData = (function( orig ) {
+ return function( elems ) {
+ var events, elem, i;
+ for ( i = 0; (elem = elems[i]) != null; i++ ) {
+ try {
+
+ // Only trigger remove when necessary to save time
+ events = $._data( elem, "events" );
+ if ( events && events.remove ) {
+ $( elem ).triggerHandler( "remove" );
+ }
+
+ // http://bugs.jquery.com/ticket/8235
+ } catch( e ) {}
+ }
+ orig( elems );
+ };
+})( $.cleanData );
$.widget = function( name, base, prototype ) {
var fullName, existingConstructor, constructor, basePrototype,
@@ -115,7 +131,7 @@ $.widget = function( name, base, prototype ) {
// TODO: remove support for widgetEventPrefix
// always use the name + a colon as the prefix, e.g., draggable:start
// don't prefix for widgets that aren't DOM-based
- widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
+ widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
}, proxiedPrototype, {
constructor: constructor,
namespace: namespace,
@@ -143,10 +159,12 @@ $.widget = function( name, base, prototype ) {
}
$.widget.bridge( name, constructor );
+
+ return constructor;
};
$.widget.extend = function( target ) {
- var input = slice.call( arguments, 1 ),
+ var input = widget_slice.call( arguments, 1 ),
inputIndex = 0,
inputLength = input.length,
key,
@@ -175,7 +193,7 @@ $.widget.bridge = function( name, object ) {
var fullName = object.prototype.widgetFullName || name;
$.fn[ name ] = function( options ) {
var isMethodCall = typeof options === "string",
- args = slice.call( arguments, 1 ),
+ args = widget_slice.call( arguments, 1 ),
returnValue = this;
// allow multiple hashes to be passed on init
@@ -187,6 +205,10 @@ $.widget.bridge = function( name, object ) {
this.each(function() {
var methodValue,
instance = $.data( this, fullName );
+ if ( options === "instance" ) {
+ returnValue = instance;
+ return false;
+ }
if ( !instance ) {
return $.error( "cannot call methods on " + name + " prior to initialization; " +
"attempted to call method '" + options + "'" );
@@ -206,7 +228,10 @@ $.widget.bridge = function( name, object ) {
this.each(function() {
var instance = $.data( this, fullName );
if ( instance ) {
- instance.option( options || {} )._init();
+ instance.option( options || {} );
+ if ( instance._init ) {
+ instance._init();
+ }
} else {
$.data( this, fullName, new object( options, this ) );
}
@@ -233,7 +258,7 @@ $.Widget.prototype = {
_createWidget: function( options, element ) {
element = $( element || this.defaultElement || this )[ 0 ];
this.element = $( element );
- this.uuid = uuid++;
+ this.uuid = widget_uuid++;
this.eventNamespace = "." + this.widgetName + this.uuid;
this.options = $.widget.extend( {},
this.options,
@@ -276,9 +301,6 @@ $.Widget.prototype = {
// all event bindings should go through this._on()
this.element
.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
@@ -324,12 +346,12 @@ $.Widget.prototype = {
curOption = curOption[ parts[ i ] ];
}
key = parts.pop();
- if ( value === undefined ) {
+ if ( arguments.length === 1 ) {
return curOption[ key ] === undefined ? null : curOption[ key ];
}
curOption[ key ] = value;
} else {
- if ( value === undefined ) {
+ if ( arguments.length === 1 ) {
return this.options[ key ] === undefined ? null : this.options[ key ];
}
options[ key ] = value;
@@ -354,20 +376,23 @@ $.Widget.prototype = {
if ( key === "disabled" ) {
this.widget()
- .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
- .attr( "aria-disabled", value );
- this.hoverable.removeClass( "ui-state-hover" );
- this.focusable.removeClass( "ui-state-focus" );
+ .toggleClass( this.widgetFullName + "-disabled", !!value );
+
+ // If the widget is becoming disabled, then nothing is interactive
+ if ( value ) {
+ this.hoverable.removeClass( "ui-state-hover" );
+ this.focusable.removeClass( "ui-state-focus" );
+ }
}
return this;
},
enable: function() {
- return this._setOption( "disabled", false );
+ return this._setOptions({ disabled: false });
},
disable: function() {
- return this._setOption( "disabled", true );
+ return this._setOptions({ disabled: true });
},
_on: function( suppressDisabledCheck, element, handlers ) {
@@ -387,7 +412,6 @@ $.Widget.prototype = {
element = this.element;
delegateElement = this.widget();
} else {
- // accept selectors, DOM elements
element = delegateElement = $( element );
this.bindings = this.bindings.add( element );
}
@@ -412,7 +436,7 @@ $.Widget.prototype = {
handler.guid || handlerProxy.guid || $.guid++;
}
- var match = event.match( /^(\w+)\s*(.*)$/ ),
+ var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
eventName = match[1] + instance.eventNamespace,
selector = match[2];
if ( selector ) {
@@ -527,4 +551,8 @@ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
};
});
+var widget = $.widget;
+
+
+
}));
diff --git a/app/assets/javascripts/jquery-fileupload/vendor/load-image.js b/app/assets/javascripts/jquery-fileupload/vendor/load-image.js
index 0155d38..adb63a9 100644
--- a/app/assets/javascripts/jquery-fileupload/vendor/load-image.js
+++ b/app/assets/javascripts/jquery-fileupload/vendor/load-image.js
@@ -1,19 +1,16 @@
/*
- * JavaScript Load Image 1.3.1
+ * JavaScript Load Image 1.10.0
* https://github.com/blueimp/JavaScript-Load-Image
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
- * iOS image scaling fixes based on
- * https://github.com/stomita/ios-imagefile-megapixel
- *
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*/
-/*jslint nomen: true, bitwise: true */
-/*global window, document, URL, webkitURL, Blob, File, FileReader, define */
+/*jslint nomen: true */
+/*global define, window, document, URL, webkitURL, Blob, File, FileReader */
(function ($) {
'use strict';
@@ -30,17 +27,24 @@
if (oUrl && !(options && options.noRevoke)) {
loadImage.revokeObjectURL(oUrl);
}
- callback(loadImage.scale(img, options));
+ if (callback) {
+ callback(loadImage.scale(img, options));
+ }
};
- if ((window.Blob && file instanceof Blob) ||
- // Files are also Blob instances, but some browsers
- // (Firefox 3.6) support the File API but not Blobs:
- (window.File && file instanceof File)) {
+ if (loadImage.isInstanceOf('Blob', file) ||
+ // Files are also Blob instances, but some browsers
+ // (Firefox 3.6) support the File API but not Blobs:
+ loadImage.isInstanceOf('File', file)) {
url = oUrl = loadImage.createObjectURL(file);
// Store the file type for resize processing:
img._type = file.type;
- } else {
+ } else if (typeof file === 'string') {
url = file;
+ if (options && options.crossOrigin) {
+ img.crossOrigin = options.crossOrigin;
+ }
+ } else {
+ return false;
}
if (url) {
img.src = url;
@@ -51,7 +55,9 @@
if (target && target.result) {
img.src = target.result;
} else {
- callback(e);
+ if (callback) {
+ callback(e);
+ }
}
});
},
@@ -61,139 +67,203 @@
(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;
+ loadImage.isInstanceOf = function (type, obj) {
+ // Cross-frame instanceof check
+ return Object.prototype.toString.call(obj) === '[object ' + type + ']';
};
- // 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;
+ // Transform image coordinates, allows to override e.g.
+ // the canvas orientation based on the orientation option,
+ // gets canvas, options passed as arguments:
+ loadImage.transformCoordinates = function () {
+ return;
};
- // 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;
+ // Returns transformed options, allows to override e.g.
+ // maxWidth, maxHeight and crop options based on the aspectRatio.
+ // gets img, options passed as arguments:
+ loadImage.getTransformedOptions = function (img, options) {
+ var aspectRatio = options.aspectRatio,
+ newOptions,
+ i,
+ width,
+ height;
+ if (!aspectRatio) {
+ return options;
}
- 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;
+ newOptions = {};
+ for (i in options) {
+ if (options.hasOwnProperty(i)) {
+ newOptions[i] = options[i];
}
- sy += d;
- dy += dh;
}
- ctx.restore();
- tmpCanvas = tmpCtx = null;
+ newOptions.crop = true;
+ width = img.naturalWidth || img.width;
+ height = img.naturalHeight || img.height;
+ if (width / height > aspectRatio) {
+ newOptions.maxWidth = height * aspectRatio;
+ newOptions.maxHeight = height;
+ } else {
+ newOptions.maxWidth = width;
+ newOptions.maxHeight = width / aspectRatio;
+ }
+ return newOptions;
+ };
+
+ // Canvas render method, allows to override the
+ // rendering e.g. to work around issues on iOS:
+ loadImage.renderImageToCanvas = function (
+ canvas,
+ img,
+ sourceX,
+ sourceY,
+ sourceWidth,
+ sourceHeight,
+ destX,
+ destY,
+ destWidth,
+ destHeight
+ ) {
+ canvas.getContext('2d').drawImage(
+ img,
+ sourceX,
+ sourceY,
+ sourceWidth,
+ sourceHeight,
+ destX,
+ destY,
+ destWidth,
+ destHeight
+ );
+ return canvas;
};
- // Scales the given image (img or canvas HTML element)
+ // This method is used to determine if the target image
+ // should be a canvas element:
+ loadImage.hasCanvasOption = function (options) {
+ return options.canvas || options.crop || options.aspectRatio;
+ };
+
+ // Scales and/or crops the given image (img or canvas HTML element)
// using the given options.
// Returns a canvas object if the browser supports canvas
- // and the canvas option is true or a canvas object is passed
- // as image, else the scaled image:
+ // and the hasCanvasOption method returns true or a canvas
+ // object is passed as image, else the scaled image:
loadImage.scale = function (img, options) {
options = options || {};
var canvas = document.createElement('canvas'),
- width = img.width,
- height = img.height,
- scale = Math.max(
- (options.minWidth || width) / width,
- (options.minHeight || height) / height
- );
- if (scale > 1) {
- width = Math.ceil(width * scale);
- height = Math.ceil(height * scale);
- }
- scale = Math.min(
- (options.maxWidth || width) / width,
- (options.maxHeight || height) / height
- );
- if (scale < 1) {
- width = Math.ceil(width * scale);
- height = Math.ceil(height * scale);
+ useCanvas = img.getContext ||
+ (loadImage.hasCanvasOption(options) && canvas.getContext),
+ width = img.naturalWidth || img.width,
+ height = img.naturalHeight || img.height,
+ destWidth = width,
+ destHeight = height,
+ maxWidth,
+ maxHeight,
+ minWidth,
+ minHeight,
+ sourceWidth,
+ sourceHeight,
+ sourceX,
+ sourceY,
+ tmp,
+ scaleUp = function () {
+ var scale = Math.max(
+ (minWidth || destWidth) / destWidth,
+ (minHeight || destHeight) / destHeight
+ );
+ if (scale > 1) {
+ destWidth = destWidth * scale;
+ destHeight = destHeight * scale;
+ }
+ },
+ scaleDown = function () {
+ var scale = Math.min(
+ (maxWidth || destWidth) / destWidth,
+ (maxHeight || destHeight) / destHeight
+ );
+ if (scale < 1) {
+ destWidth = destWidth * scale;
+ destHeight = destHeight * scale;
+ }
+ };
+ if (useCanvas) {
+ options = loadImage.getTransformedOptions(img, options);
+ sourceX = options.left || 0;
+ sourceY = options.top || 0;
+ if (options.sourceWidth) {
+ sourceWidth = options.sourceWidth;
+ if (options.right !== undefined && options.left === undefined) {
+ sourceX = width - sourceWidth - options.right;
+ }
+ } else {
+ sourceWidth = width - sourceX - (options.right || 0);
+ }
+ if (options.sourceHeight) {
+ sourceHeight = options.sourceHeight;
+ if (options.bottom !== undefined && options.top === undefined) {
+ sourceY = height - sourceHeight - options.bottom;
+ }
+ } else {
+ sourceHeight = height - sourceY - (options.bottom || 0);
+ }
+ destWidth = sourceWidth;
+ destHeight = sourceHeight;
}
- if (img.getContext || (options.canvas && canvas.getContext)) {
- canvas.width = width;
- canvas.height = height;
- if (img._type === 'image/jpeg') {
- loadImage
- .renderImageToCanvas(img, canvas, width, height);
+ maxWidth = options.maxWidth;
+ maxHeight = options.maxHeight;
+ minWidth = options.minWidth;
+ minHeight = options.minHeight;
+ if (useCanvas && maxWidth && maxHeight && options.crop) {
+ destWidth = maxWidth;
+ destHeight = maxHeight;
+ tmp = sourceWidth / sourceHeight - maxWidth / maxHeight;
+ if (tmp < 0) {
+ sourceHeight = maxHeight * sourceWidth / maxWidth;
+ if (options.top === undefined && options.bottom === undefined) {
+ sourceY = (height - sourceHeight) / 2;
+ }
+ } else if (tmp > 0) {
+ sourceWidth = maxWidth * sourceHeight / maxHeight;
+ if (options.left === undefined && options.right === undefined) {
+ sourceX = (width - sourceWidth) / 2;
+ }
+ }
+ } else {
+ if (options.contain || options.cover) {
+ minWidth = maxWidth = maxWidth || minWidth;
+ minHeight = maxHeight = maxHeight || minHeight;
+ }
+ if (options.cover) {
+ scaleDown();
+ scaleUp();
} else {
- canvas.getContext('2d')
- .drawImage(img, 0, 0, width, height);
+ scaleUp();
+ scaleDown();
}
- return canvas;
}
- img.width = width;
- img.height = height;
+ if (useCanvas) {
+ canvas.width = destWidth;
+ canvas.height = destHeight;
+ loadImage.transformCoordinates(
+ canvas,
+ options
+ );
+ return loadImage.renderImageToCanvas(
+ canvas,
+ img,
+ sourceX,
+ sourceY,
+ sourceWidth,
+ sourceHeight,
+ 0,
+ 0,
+ destWidth,
+ destHeight
+ );
+ }
+ img.width = destWidth;
+ img.height = destHeight;
return img;
};
@@ -208,12 +278,15 @@
// Loads a given File object via FileReader interface,
// invokes the callback with the event object (load or error).
// The result can be read via event.target.result:
- loadImage.readFile = function (file, callback) {
- if (window.FileReader && FileReader.prototype.readAsDataURL) {
+ loadImage.readFile = function (file, callback, method) {
+ if (window.FileReader) {
var fileReader = new FileReader();
fileReader.onload = fileReader.onerror = callback;
- fileReader.readAsDataURL(file);
- return fileReader;
+ method = method || 'readAsDataURL';
+ if (fileReader[method]) {
+ fileReader[method](file);
+ return fileReader;
+ }
}
return false;
};
diff --git a/app/assets/javascripts/jquery-fileupload/vendor/tmpl.js b/app/assets/javascripts/jquery-fileupload/vendor/tmpl.js
index c8b4b86..9380053 100644
--- a/app/assets/javascripts/jquery-fileupload/vendor/tmpl.js
+++ b/app/assets/javascripts/jquery-fileupload/vendor/tmpl.js
@@ -1,5 +1,5 @@
/*
- * JavaScript Templates 2.1.0
+ * JavaScript Templates 2.4.1
* https://github.com/blueimp/JavaScript-Templates
*
* Copyright 2011, Sebastian Tschan
@@ -12,7 +12,7 @@
* http://ejohn.org/blog/javascript-micro-templating/
*/
-/*jslint evil: true, regexp: true */
+/*jslint evil: true, regexp: true, unparam: true */
/*global document, define */
(function ($) {
@@ -34,21 +34,21 @@
tmpl.load = function (id) {
return document.getElementById(id).innerHTML;
};
- tmpl.regexp = /([\s'\\])(?![^%]*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g;
+ tmpl.regexp = /([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g;
tmpl.func = function (s, p1, p2, p3, p4, p5) {
- if (p1) { // whitespace, quote and backspace in interpolation context
+ if (p1) { // whitespace, quote and backspace in HTML context
return {
"\n": "\\n",
"\r": "\\r",
"\t": "\\t",
" " : " "
- }[s] || "\\" + s;
+ }[p1] || "\\" + p1;
}
if (p2) { // interpolation: {%=prop%}, or unescaped: {%#prop%}
if (p2 === "=") {
return "'+_e(" + p3 + ")+'";
}
- return "'+(" + p3 + "||'')+'";
+ return "'+(" + p3 + "==null?'':" + p3 + ")+'";
}
if (p4) { // evaluation start tag: {%
return "';";
@@ -66,7 +66,8 @@
"'" : "'"
};
tmpl.encode = function (s) {
- return String(s || "").replace(
+ /*jshint eqnull:true */
+ return (s == null ? "" : "" + s).replace(
tmpl.encReg,
function (c) {
return tmpl.encMap[c] || "";
@@ -74,7 +75,7 @@
);
};
tmpl.arg = "o";
- tmpl.helper = ",print=function(s,e){_s+=e&&(s||'')||_e(s);}" +
+ tmpl.helper = ",print=function(s,e){_s+=e?(s==null?'':s):_e(s);}" +
",include=function(s,d){_s+=tmpl(s,d);}";
if (typeof define === "function" && define.amd) {
define(function () {
diff --git a/app/assets/stylesheets/jquery.fileupload-noscript.scss b/app/assets/stylesheets/jquery.fileupload-noscript.scss
new file mode 100644
index 0000000..64d728f
--- /dev/null
+++ b/app/assets/stylesheets/jquery.fileupload-noscript.scss
@@ -0,0 +1,22 @@
+@charset "UTF-8";
+/*
+ * jQuery File Upload Plugin NoScript CSS 1.2.0
+ * 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
+ */
+
+.fileinput-button input {
+ position: static;
+ opacity: 1;
+ filter: none;
+ font-size: inherit;
+ direction: inherit;
+}
+.fileinput-button span {
+ display: none;
+}
diff --git a/app/assets/stylesheets/jquery.fileupload-ui-noscript.scss b/app/assets/stylesheets/jquery.fileupload-ui-noscript.scss
new file mode 100644
index 0000000..87f110c
--- /dev/null
+++ b/app/assets/stylesheets/jquery.fileupload-ui-noscript.scss
@@ -0,0 +1,17 @@
+@charset "UTF-8";
+/*
+ * jQuery File Upload UI Plugin NoScript CSS 8.8.5
+ * 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
+ */
+
+.fileinput-button i,
+.fileupload-buttonbar .delete,
+.fileupload-buttonbar .toggle {
+ display: none;
+}
diff --git a/app/assets/stylesheets/jquery.fileupload-ui.scss b/app/assets/stylesheets/jquery.fileupload-ui.scss
old mode 100755
new mode 100644
index 72bfcb6..76fb376
--- a/app/assets/stylesheets/jquery.fileupload-ui.scss
+++ b/app/assets/stylesheets/jquery.fileupload-ui.scss
@@ -1,6 +1,6 @@
@charset "UTF-8";
/*
- * jQuery File Upload UI Plugin CSS 8.0
+ * jQuery File Upload UI Plugin CSS 9.0.0
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
@@ -10,40 +10,30 @@
* http://www.opensource.org/licenses/MIT
*/
-.fileinput-button {
- position: relative;
- overflow: hidden;
-}
-.fileinput-button input {
- position: absolute;
- top: 0;
- right: 0;
- margin: 0;
- opacity: 0;
- filter: alpha(opacity=0);
- transform: translate(-300px, 0) scale(4);
- font-size: 23px;
- direction: ltr;
- cursor: pointer;
-}
.fileupload-buttonbar .btn,
.fileupload-buttonbar .toggle {
margin-bottom: 5px;
}
+.progress-animated .progress-bar,
.progress-animated .bar {
- background: url(../img/progressbar.gif) !important;
+ background: url("../img/progressbar.gif") !important;
filter: none;
}
-.fileupload-loading {
+.fileupload-process {
float: right;
+ display: none;
+}
+.fileupload-processing .fileupload-process,
+.files .processing .preview {
+ display: block;
width: 32px;
height: 32px;
- background: url(../img/loading.gif) center no-repeat;
+ background: url("../img/loading.gif") center no-repeat;
background-size: contain;
- display: none;
}
-.fileupload-processing .fileupload-loading {
- display: block;
+.files audio,
+.files video {
+ max-width: 300px;
}
@media (max-width: 767px) {
@@ -56,4 +46,12 @@
width: 80px;
word-wrap: break-word;
}
+ .files audio,
+ .files video {
+ max-width: 80px;
+ }
+ .files img,
+ .files canvas {
+ max-width: 100%;
+ }
}
diff --git a/app/assets/stylesheets/jquery.fileupload.scss b/app/assets/stylesheets/jquery.fileupload.scss
new file mode 100644
index 0000000..fb6044d
--- /dev/null
+++ b/app/assets/stylesheets/jquery.fileupload.scss
@@ -0,0 +1,36 @@
+@charset "UTF-8";
+/*
+ * jQuery File Upload Plugin CSS 1.3.0
+ * 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
+ */
+
+.fileinput-button {
+ position: relative;
+ overflow: hidden;
+}
+.fileinput-button input {
+ position: absolute;
+ top: 0;
+ right: 0;
+ margin: 0;
+ opacity: 0;
+ -ms-filter: 'alpha(opacity=0)';
+ font-size: 200px;
+ direction: ltr;
+ cursor: pointer;
+}
+
+/* Fixes for IE < 8 */
+@media screen\9 {
+ .fileinput-button input {
+ filter: alpha(opacity=0);
+ font-size: 100%;
+ height: 100%;
+ }
+}
diff --git a/jquery-fileupload-rails.gemspec b/jquery-fileupload-rails.gemspec
index cbc4e8c..a8400c3 100644
--- a/jquery-fileupload-rails.gemspec
+++ b/jquery-fileupload-rails.gemspec
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
s.authors = ["Tors Dalid"]
s.email = ["cletedalid@gmail.com"]
s.homepage = "https://github.com/tors/jquery-fileupload-rails"
- s.summary = %q{jQuery File Upload for Rails 3.1 Asset Pipeline}
- s.description = %q{jQuery File Upload by Sebastian Tschan integrated for Rails 3.1 Asset Pipeline}
+ s.summary = %q{jQuery File Upload for Rails 3.1+ Asset Pipeline}
+ s.description = %q{jQuery File Upload by Sebastian Tschan integrated for Rails 3.1+ Asset Pipeline}
s.rubyforge_project = "jquery-fileupload-rails"
From eab6b59fea42582df2a1538b892c8b2fa618d60b Mon Sep 17 00:00:00 2001
From: Igor Pstyga
Date: Fri, 21 Nov 2014 15:35:06 -0800
Subject: [PATCH 3/4] Update Load Image.js
---
.../jquery-fileupload/angularjs.js | 2 +-
.../jquery-fileupload/basic-plus.js | 2 +-
.../javascripts/jquery-fileupload/index.js | 2 +-
.../jquery-fileupload/jquery-ui.js | 2 +-
.../vendor/load-image.all.min.js | 1 +
.../jquery-fileupload/vendor/load-image.js | 301 ------------------
6 files changed, 5 insertions(+), 305 deletions(-)
create mode 100755 app/assets/javascripts/jquery-fileupload/vendor/load-image.all.min.js
delete mode 100644 app/assets/javascripts/jquery-fileupload/vendor/load-image.js
diff --git a/app/assets/javascripts/jquery-fileupload/angularjs.js b/app/assets/javascripts/jquery-fileupload/angularjs.js
index 7c97327..c87d11c 100644
--- a/app/assets/javascripts/jquery-fileupload/angularjs.js
+++ b/app/assets/javascripts/jquery-fileupload/angularjs.js
@@ -1,5 +1,5 @@
//= require jquery-fileupload/vendor/jquery.ui.widget
-//= require jquery-fileupload/vendor/load-image
+//= require jquery-fileupload/vendor/load-image.all.min
//= require jquery-fileupload/vendor/canvas-to-blob
//= require jquery-fileupload/jquery.iframe-transport
//= require jquery-fileupload/jquery.fileupload
diff --git a/app/assets/javascripts/jquery-fileupload/basic-plus.js b/app/assets/javascripts/jquery-fileupload/basic-plus.js
index b20313e..dacdb2e 100644
--- a/app/assets/javascripts/jquery-fileupload/basic-plus.js
+++ b/app/assets/javascripts/jquery-fileupload/basic-plus.js
@@ -1,5 +1,5 @@
//= require jquery-fileupload/vendor/jquery.ui.widget
-//= require jquery-fileupload/vendor/load-image
+//= require jquery-fileupload/vendor/load-image.all.min
//= require jquery-fileupload/vendor/canvas-to-blob
//= require jquery-fileupload/jquery.iframe-transport
//= require jquery-fileupload/jquery.fileupload
diff --git a/app/assets/javascripts/jquery-fileupload/index.js b/app/assets/javascripts/jquery-fileupload/index.js
index be03aa8..58d29a3 100644
--- a/app/assets/javascripts/jquery-fileupload/index.js
+++ b/app/assets/javascripts/jquery-fileupload/index.js
@@ -1,6 +1,6 @@
//= require jquery-fileupload/vendor/jquery.ui.widget
//= require jquery-fileupload/vendor/tmpl
-//= require jquery-fileupload/vendor/load-image
+//= require jquery-fileupload/vendor/load-image.all.min
//= require jquery-fileupload/vendor/canvas-to-blob
//= require jquery-fileupload/jquery.iframe-transport
//= require jquery-fileupload/jquery.fileupload
diff --git a/app/assets/javascripts/jquery-fileupload/jquery-ui.js b/app/assets/javascripts/jquery-fileupload/jquery-ui.js
index cd29f8f..256325d 100644
--- a/app/assets/javascripts/jquery-fileupload/jquery-ui.js
+++ b/app/assets/javascripts/jquery-fileupload/jquery-ui.js
@@ -1,5 +1,5 @@
//= require jquery-fileupload/vendor/tmpl
-//= require jquery-fileupload/vendor/load-image
+//= require jquery-fileupload/vendor/load-image.all.min
//= require jquery-fileupload/vendor/canvas-to-blob
//= require jquery-fileupload/jquery.iframe-transport
//= require jquery-fileupload/jquery.fileupload
diff --git a/app/assets/javascripts/jquery-fileupload/vendor/load-image.all.min.js b/app/assets/javascripts/jquery-fileupload/vendor/load-image.all.min.js
new file mode 100755
index 0000000..befe38a
--- /dev/null
+++ b/app/assets/javascripts/jquery-fileupload/vendor/load-image.all.min.js
@@ -0,0 +1 @@
+!function(a){"use strict";var b=function(a,c,d){var e,f,g=document.createElement("img");if(g.onerror=c,g.onload=function(){!f||d&&d.noRevoke||b.revokeObjectURL(f),c&&c(b.scale(g,d))},b.isInstanceOf("Blob",a)||b.isInstanceOf("File",a))e=f=b.createObjectURL(a),g._type=a.type;else{if("string"!=typeof a)return!1;e=a,d&&d.crossOrigin&&(g.crossOrigin=d.crossOrigin)}return e?(g.src=e,g):b.readFile(a,function(a){var b=a.target;b&&b.result?g.src=b.result:c&&c(a)})},c=window.createObjectURL&&window||window.URL&&URL.revokeObjectURL&&URL||window.webkitURL&&webkitURL;b.isInstanceOf=function(a,b){return Object.prototype.toString.call(b)==="[object "+a+"]"},b.transformCoordinates=function(){},b.getTransformedOptions=function(a,b){var c,d,e,f,g=b.aspectRatio;if(!g)return b;c={};for(d in b)b.hasOwnProperty(d)&&(c[d]=b[d]);return c.crop=!0,e=a.naturalWidth||a.width,f=a.naturalHeight||a.height,e/f>g?(c.maxWidth=f*g,c.maxHeight=f):(c.maxWidth=e,c.maxHeight=e/g),c},b.renderImageToCanvas=function(a,b,c,d,e,f,g,h,i,j){return a.getContext("2d").drawImage(b,c,d,e,f,g,h,i,j),a},b.hasCanvasOption=function(a){return a.canvas||a.crop||a.aspectRatio},b.scale=function(a,c){c=c||{};var d,e,f,g,h,i,j,k,l,m=document.createElement("canvas"),n=a.getContext||b.hasCanvasOption(c)&&m.getContext,o=a.naturalWidth||a.width,p=a.naturalHeight||a.height,q=o,r=p,s=function(){var a=Math.max((f||q)/q,(g||r)/r);a>1&&(q*=a,r*=a)},t=function(){var a=Math.min((d||q)/q,(e||r)/r);1>a&&(q*=a,r*=a)};return n&&(c=b.getTransformedOptions(a,c),j=c.left||0,k=c.top||0,c.sourceWidth?(h=c.sourceWidth,void 0!==c.right&&void 0===c.left&&(j=o-h-c.right)):h=o-j-(c.right||0),c.sourceHeight?(i=c.sourceHeight,void 0!==c.bottom&&void 0===c.top&&(k=p-i-c.bottom)):i=p-k-(c.bottom||0),q=h,r=i),d=c.maxWidth,e=c.maxHeight,f=c.minWidth,g=c.minHeight,n&&d&&e&&c.crop?(q=d,r=e,l=h/i-d/e,0>l?(i=e*h/d,void 0===c.top&&void 0===c.bottom&&(k=(p-i)/2)):l>0&&(h=d*i/e,void 0===c.left&&void 0===c.right&&(j=(o-h)/2))):((c.contain||c.cover)&&(f=d=d||f,g=e=e||g),c.cover?(t(),s()):(s(),t())),n?(m.width=q,m.height=r,b.transformCoordinates(m,c),b.renderImageToCanvas(m,a,j,k,h,i,0,0,q,r)):(a.width=q,a.height=r,a)},b.createObjectURL=function(a){return c?c.createObjectURL(a):!1},b.revokeObjectURL=function(a){return c?c.revokeObjectURL(a):!1},b.readFile=function(a,b,c){if(window.FileReader){var d=new FileReader;if(d.onload=d.onerror=b,c=c||"readAsDataURL",d[c])return d[c](a),d}return!1},"function"==typeof define&&define.amd?define(function(){return b}):a.loadImage=b}(this),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image"],a):a(window.loadImage)}(function(a){"use strict";if(window.navigator&&window.navigator.platform&&/iP(hone|od|ad)/.test(window.navigator.platform)){var b=a.renderImageToCanvas;a.detectSubsampling=function(a){var b,c;return a.width*a.height>1048576?(b=document.createElement("canvas"),b.width=b.height=1,c=b.getContext("2d"),c.drawImage(a,-a.width+1,0),0===c.getImageData(0,0,1,1).data[3]):!1},a.detectVerticalSquash=function(a,b){var c,d,e,f,g,h=a.naturalHeight||a.height,i=document.createElement("canvas"),j=i.getContext("2d");for(b&&(h/=2),i.width=1,i.height=h,j.drawImage(a,0,0),c=j.getImageData(0,0,1,h).data,d=0,e=h,f=h;f>d;)g=c[4*(f-1)+3],0===g?e=f:d=f,f=e+d>>1;return f/h||1},a.renderImageToCanvas=function(c,d,e,f,g,h,i,j,k,l){if("image/jpeg"===d._type){var m,n,o,p,q=c.getContext("2d"),r=document.createElement("canvas"),s=1024,t=r.getContext("2d");if(r.width=s,r.height=s,q.save(),m=a.detectSubsampling(d),m&&(e/=2,f/=2,g/=2,h/=2),n=a.detectVerticalSquash(d,m),m||1!==n){for(f*=n,k=Math.ceil(s*k/g),l=Math.ceil(s*l/h/n),j=0,p=0;h>p;){for(i=0,o=0;g>o;)t.clearRect(0,0,s,s),t.drawImage(d,e,f,g,h,-o,-p,g,h),q.drawImage(r,0,0,s,s,i,j,k,l),o+=s,i+=k;p+=s,j+=l}return q.restore(),c}}return b(c,d,e,f,g,h,i,j,k,l)}}}),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image"],a):a(window.loadImage)}(function(a){"use strict";var b=a.hasCanvasOption,c=a.transformCoordinates,d=a.getTransformedOptions;a.hasCanvasOption=function(c){return b.call(a,c)||c.orientation},a.transformCoordinates=function(b,d){c.call(a,b,d);var e=b.getContext("2d"),f=b.width,g=b.height,h=d.orientation;if(h&&!(h>8))switch(h>4&&(b.width=g,b.height=f),h){case 2:e.translate(f,0),e.scale(-1,1);break;case 3:e.translate(f,g),e.rotate(Math.PI);break;case 4:e.translate(0,g),e.scale(1,-1);break;case 5:e.rotate(.5*Math.PI),e.scale(1,-1);break;case 6:e.rotate(.5*Math.PI),e.translate(0,-g);break;case 7:e.rotate(.5*Math.PI),e.translate(f,-g),e.scale(-1,1);break;case 8:e.rotate(-.5*Math.PI),e.translate(-f,0)}},a.getTransformedOptions=function(b,c){var e,f,g=d.call(a,b,c),h=g.orientation;if(!h||h>8||1===h)return g;e={};for(f in g)g.hasOwnProperty(f)&&(e[f]=g[f]);switch(g.orientation){case 2:e.left=g.right,e.right=g.left;break;case 3:e.left=g.right,e.top=g.bottom,e.right=g.left,e.bottom=g.top;break;case 4:e.top=g.bottom,e.bottom=g.top;break;case 5:e.left=g.top,e.top=g.left,e.right=g.bottom,e.bottom=g.right;break;case 6:e.left=g.top,e.top=g.right,e.right=g.bottom,e.bottom=g.left;break;case 7:e.left=g.bottom,e.top=g.right,e.right=g.top,e.bottom=g.left;break;case 8:e.left=g.bottom,e.top=g.left,e.right=g.top,e.bottom=g.right}return g.orientation>4&&(e.maxWidth=g.maxHeight,e.maxHeight=g.maxWidth,e.minWidth=g.minHeight,e.minHeight=g.minWidth,e.sourceWidth=g.sourceHeight,e.sourceHeight=g.sourceWidth),e}}),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image"],a):a(window.loadImage)}(function(a){"use strict";var b=window.Blob&&(Blob.prototype.slice||Blob.prototype.webkitSlice||Blob.prototype.mozSlice);a.blobSlice=b&&function(){var a=this.slice||this.webkitSlice||this.mozSlice;return a.apply(this,arguments)},a.metaDataParsers={jpeg:{65505:[]}},a.parseMetaData=function(b,c,d){d=d||{};var e=this,f=d.maxMetaDataSize||262144,g={},h=!(window.DataView&&b&&b.size>=12&&"image/jpeg"===b.type&&a.blobSlice);(h||!a.readFile(a.blobSlice.call(b,0,f),function(b){if(b.target.error)return console.log(b.target.error),void c(g);var f,h,i,j,k=b.target.result,l=new DataView(k),m=2,n=l.byteLength-4,o=m;if(65496===l.getUint16(0)){for(;n>m&&(f=l.getUint16(m),f>=65504&&65519>=f||65534===f);){if(h=l.getUint16(m+2)+2,m+h>l.byteLength){console.log("Invalid meta data: Invalid segment size.");break}if(i=a.metaDataParsers.jpeg[f])for(j=0;j6&&(g.imageHead=k.slice?k.slice(0,o):new Uint8Array(k).subarray(0,o))}else console.log("Invalid JPEG file: Missing JPEG marker.");c(g)},"readAsArrayBuffer"))&&c(g)}}),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image","load-image-meta"],a):a(window.loadImage)}(function(a){"use strict";a.ExifMap=function(){return this},a.ExifMap.prototype.map={Orientation:274},a.ExifMap.prototype.get=function(a){return this[a]||this[this.map[a]]},a.getExifThumbnail=function(a,b,c){var d,e,f;if(!c||b+c>a.byteLength)return void console.log("Invalid Exif data: Invalid thumbnail data.");for(d=[],e=0;c>e;e+=1)f=a.getUint8(b+e),d.push((16>f?"0":"")+f.toString(16));return"data:image/jpeg,%"+d.join("%")},a.exifTagTypes={1:{getValue:function(a,b){return a.getUint8(b)},size:1},2:{getValue:function(a,b){return String.fromCharCode(a.getUint8(b))},size:1,ascii:!0},3:{getValue:function(a,b,c){return a.getUint16(b,c)},size:2},4:{getValue:function(a,b,c){return a.getUint32(b,c)},size:4},5:{getValue:function(a,b,c){return a.getUint32(b,c)/a.getUint32(b+4,c)},size:8},9:{getValue:function(a,b,c){return a.getInt32(b,c)},size:4},10:{getValue:function(a,b,c){return a.getInt32(b,c)/a.getInt32(b+4,c)},size:8}},a.exifTagTypes[7]=a.exifTagTypes[1],a.getExifValue=function(b,c,d,e,f,g){var h,i,j,k,l,m,n=a.exifTagTypes[e];if(!n)return void console.log("Invalid Exif data: Invalid tag type.");if(h=n.size*f,i=h>4?c+b.getUint32(d+8,g):d+8,i+h>b.byteLength)return void console.log("Invalid Exif data: Invalid data offset.");if(1===f)return n.getValue(b,i,g);for(j=[],k=0;f>k;k+=1)j[k]=n.getValue(b,i+k*n.size,g);if(n.ascii){for(l="",k=0;ka.byteLength)return void console.log("Invalid Exif data: Invalid directory offset.");if(f=a.getUint16(c,d),g=c+2+12*f,g+4>a.byteLength)return void console.log("Invalid Exif data: Invalid directory size.");for(h=0;f>h;h+=1)this.parseExifTag(a,b,c+2+12*h,d,e);return a.getUint32(g,d)},a.parseExifData=function(b,c,d,e,f){if(!f.disableExif){var g,h,i,j=c+10;if(1165519206===b.getUint32(c+4)){if(j+8>b.byteLength)return void console.log("Invalid Exif data: Invalid segment size.");if(0!==b.getUint16(c+8))return void console.log("Invalid Exif data: Missing byte alignment offset.");switch(b.getUint16(j)){case 18761:g=!0;break;case 19789:g=!1;break;default:return void console.log("Invalid Exif data: Invalid byte alignment marker.")}if(42!==b.getUint16(j+2,g))return void console.log("Invalid Exif data: Missing TIFF marker.");h=b.getUint32(j+4,g),e.exif=new a.ExifMap,h=a.parseExifTags(b,j,j+h,g,e),h&&!f.disableExifThumbnail&&(i={exif:{}},h=a.parseExifTags(b,j,j+h,g,i),i.exif[513]&&(e.exif.Thumbnail=a.getExifThumbnail(b,j+i.exif[513],i.exif[514]))),e.exif[34665]&&!f.disableExifSub&&a.parseExifTags(b,j,j+e.exif[34665],g,e),e.exif[34853]&&!f.disableExifGps&&a.parseExifTags(b,j,j+e.exif[34853],g,e)}}},a.metaDataParsers.jpeg[65505].push(a.parseExifData)}),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image","load-image-exif"],a):a(window.loadImage)}(function(a){"use strict";a.ExifMap.prototype.tags={256:"ImageWidth",257:"ImageHeight",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer",40965:"InteroperabilityIFDPointer",258:"BitsPerSample",259:"Compression",262:"PhotometricInterpretation",274:"Orientation",277:"SamplesPerPixel",284:"PlanarConfiguration",530:"YCbCrSubSampling",531:"YCbCrPositioning",282:"XResolution",283:"YResolution",296:"ResolutionUnit",273:"StripOffsets",278:"RowsPerStrip",279:"StripByteCounts",513:"JPEGInterchangeFormat",514:"JPEGInterchangeFormatLength",301:"TransferFunction",318:"WhitePoint",319:"PrimaryChromaticities",529:"YCbCrCoefficients",532:"ReferenceBlackWhite",306:"DateTime",270:"ImageDescription",271:"Make",272:"Model",305:"Software",315:"Artist",33432:"Copyright",36864:"ExifVersion",40960:"FlashpixVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",42240:"Gamma",37121:"ComponentsConfiguration",37122:"CompressedBitsPerPixel",37500:"MakerNote",37510:"UserComment",40964:"RelatedSoundFile",36867:"DateTimeOriginal",36868:"DateTimeDigitized",37520:"SubSecTime",37521:"SubSecTimeOriginal",37522:"SubSecTimeDigitized",33434:"ExposureTime",33437:"FNumber",34850:"ExposureProgram",34852:"SpectralSensitivity",34855:"PhotographicSensitivity",34856:"OECF",34864:"SensitivityType",34865:"StandardOutputSensitivity",34866:"RecommendedExposureIndex",34867:"ISOSpeed",34868:"ISOSpeedLatitudeyyy",34869:"ISOSpeedLatitudezzz",37377:"ShutterSpeedValue",37378:"ApertureValue",37379:"BrightnessValue",37380:"ExposureBias",37381:"MaxApertureValue",37382:"SubjectDistance",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37396:"SubjectArea",37386:"FocalLength",41483:"FlashEnergy",41484:"SpatialFrequencyResponse",41486:"FocalPlaneXResolution",41487:"FocalPlaneYResolution",41488:"FocalPlaneResolutionUnit",41492:"SubjectLocation",41493:"ExposureIndex",41495:"SensingMethod",41728:"FileSource",41729:"SceneType",41730:"CFAPattern",41985:"CustomRendered",41986:"ExposureMode",41987:"WhiteBalance",41988:"DigitalZoomRatio",41989:"FocalLengthIn35mmFilm",41990:"SceneCaptureType",41991:"GainControl",41992:"Contrast",41993:"Saturation",41994:"Sharpness",41995:"DeviceSettingDescription",41996:"SubjectDistanceRange",42016:"ImageUniqueID",42032:"CameraOwnerName",42033:"BodySerialNumber",42034:"LensSpecification",42035:"LensMake",42036:"LensModel",42037:"LensSerialNumber",0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude",5:"GPSAltitudeRef",6:"GPSAltitude",7:"GPSTimeStamp",8:"GPSSatellites",9:"GPSStatus",10:"GPSMeasureMode",11:"GPSDOP",12:"GPSSpeedRef",13:"GPSSpeed",14:"GPSTrackRef",15:"GPSTrack",16:"GPSImgDirectionRef",17:"GPSImgDirection",18:"GPSMapDatum",19:"GPSDestLatitudeRef",20:"GPSDestLatitude",21:"GPSDestLongitudeRef",22:"GPSDestLongitude",23:"GPSDestBearingRef",24:"GPSDestBearing",25:"GPSDestDistanceRef",26:"GPSDestDistance",27:"GPSProcessingMethod",28:"GPSAreaInformation",29:"GPSDateStamp",30:"GPSDifferential",31:"GPSHPositioningError"},a.ExifMap.prototype.stringValues={ExposureProgram:{0:"Undefined",1:"Manual",2:"Normal program",3:"Aperture priority",4:"Shutter priority",5:"Creative program",6:"Action program",7:"Portrait mode",8:"Landscape mode"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{0:"Unknown",1:"Daylight",2:"Fluorescent",3:"Tungsten (incandescent light)",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 - 5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire",1:"Flash fired",5:"Strobe return light not detected",7:"Strobe return light detected",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},SensingMethod:{1:"Undefined",2:"One-chip color area sensor",3:"Two-chip color area sensor",4:"Three-chip color area sensor",5:"Color sequential area sensor",7:"Trilinear sensor",8:"Color sequential linear sensor"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},SceneType:{1:"Directly photographed"},CustomRendered:{0:"Normal process",1:"Custom process"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},GainControl:{0:"None",1:"Low gain up",2:"High gain up",3:"Low gain down",4:"High gain down"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},SubjectDistanceRange:{0:"Unknown",1:"Macro",2:"Close view",3:"Distant view"},FileSource:{3:"DSC"},ComponentsConfiguration:{0:"",1:"Y",2:"Cb",3:"Cr",4:"R",5:"G",6:"B"},Orientation:{1:"top-left",2:"top-right",3:"bottom-right",4:"bottom-left",5:"left-top",6:"right-top",7:"right-bottom",8:"left-bottom"}},a.ExifMap.prototype.getText=function(a){var b=this.get(a);switch(a){case"LightSource":case"Flash":case"MeteringMode":case"ExposureProgram":case"SensingMethod":case"SceneCaptureType":case"SceneType":case"CustomRendered":case"WhiteBalance":case"GainControl":case"Contrast":case"Saturation":case"Sharpness":case"SubjectDistanceRange":case"FileSource":case"Orientation":return this.stringValues[a][b];case"ExifVersion":case"FlashpixVersion":return String.fromCharCode(b[0],b[1],b[2],b[3]);case"ComponentsConfiguration":return this.stringValues[a][b[0]]+this.stringValues[a][b[1]]+this.stringValues[a][b[2]]+this.stringValues[a][b[3]];case"GPSVersionID":return b[0]+"."+b[1]+"."+b[2]+"."+b[3]}return String(b)},function(a){var b,c=a.tags,d=a.map;for(b in c)c.hasOwnProperty(b)&&(d[c[b]]=b)}(a.ExifMap.prototype),a.ExifMap.prototype.getAll=function(){var a,b,c={};for(a in this)this.hasOwnProperty(a)&&(b=this.tags[a],b&&(c[b]=this.getText(b)));return c}});
\ No newline at end of file
diff --git a/app/assets/javascripts/jquery-fileupload/vendor/load-image.js b/app/assets/javascripts/jquery-fileupload/vendor/load-image.js
deleted file mode 100644
index adb63a9..0000000
--- a/app/assets/javascripts/jquery-fileupload/vendor/load-image.js
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * JavaScript Load Image 1.10.0
- * https://github.com/blueimp/JavaScript-Load-Image
- *
- * Copyright 2011, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-/*jslint nomen: true */
-/*global define, window, document, URL, webkitURL, Blob, File, FileReader */
-
-(function ($) {
- 'use strict';
-
- // Loads an image for a given File object.
- // Invokes the callback with an img or optional canvas
- // element (if supported by the browser) as parameter:
- var loadImage = function (file, callback, options) {
- var img = document.createElement('img'),
- url,
- oUrl;
- img.onerror = callback;
- img.onload = function () {
- if (oUrl && !(options && options.noRevoke)) {
- loadImage.revokeObjectURL(oUrl);
- }
- if (callback) {
- callback(loadImage.scale(img, options));
- }
- };
- if (loadImage.isInstanceOf('Blob', file) ||
- // Files are also Blob instances, but some browsers
- // (Firefox 3.6) support the File API but not Blobs:
- loadImage.isInstanceOf('File', file)) {
- url = oUrl = loadImage.createObjectURL(file);
- // Store the file type for resize processing:
- img._type = file.type;
- } else if (typeof file === 'string') {
- url = file;
- if (options && options.crossOrigin) {
- img.crossOrigin = options.crossOrigin;
- }
- } else {
- return false;
- }
- if (url) {
- img.src = url;
- return img;
- }
- return loadImage.readFile(file, function (e) {
- var target = e.target;
- if (target && target.result) {
- img.src = target.result;
- } else {
- if (callback) {
- callback(e);
- }
- }
- });
- },
- // The check for URL.revokeObjectURL fixes an issue with Opera 12,
- // which provides URL.createObjectURL but doesn't properly implement it:
- urlAPI = (window.createObjectURL && window) ||
- (window.URL && URL.revokeObjectURL && URL) ||
- (window.webkitURL && webkitURL);
-
- loadImage.isInstanceOf = function (type, obj) {
- // Cross-frame instanceof check
- return Object.prototype.toString.call(obj) === '[object ' + type + ']';
- };
-
- // Transform image coordinates, allows to override e.g.
- // the canvas orientation based on the orientation option,
- // gets canvas, options passed as arguments:
- loadImage.transformCoordinates = function () {
- return;
- };
-
- // Returns transformed options, allows to override e.g.
- // maxWidth, maxHeight and crop options based on the aspectRatio.
- // gets img, options passed as arguments:
- loadImage.getTransformedOptions = function (img, options) {
- var aspectRatio = options.aspectRatio,
- newOptions,
- i,
- width,
- height;
- if (!aspectRatio) {
- return options;
- }
- newOptions = {};
- for (i in options) {
- if (options.hasOwnProperty(i)) {
- newOptions[i] = options[i];
- }
- }
- newOptions.crop = true;
- width = img.naturalWidth || img.width;
- height = img.naturalHeight || img.height;
- if (width / height > aspectRatio) {
- newOptions.maxWidth = height * aspectRatio;
- newOptions.maxHeight = height;
- } else {
- newOptions.maxWidth = width;
- newOptions.maxHeight = width / aspectRatio;
- }
- return newOptions;
- };
-
- // Canvas render method, allows to override the
- // rendering e.g. to work around issues on iOS:
- loadImage.renderImageToCanvas = function (
- canvas,
- img,
- sourceX,
- sourceY,
- sourceWidth,
- sourceHeight,
- destX,
- destY,
- destWidth,
- destHeight
- ) {
- canvas.getContext('2d').drawImage(
- img,
- sourceX,
- sourceY,
- sourceWidth,
- sourceHeight,
- destX,
- destY,
- destWidth,
- destHeight
- );
- return canvas;
- };
-
- // This method is used to determine if the target image
- // should be a canvas element:
- loadImage.hasCanvasOption = function (options) {
- return options.canvas || options.crop || options.aspectRatio;
- };
-
- // Scales and/or crops the given image (img or canvas HTML element)
- // using the given options.
- // Returns a canvas object if the browser supports canvas
- // and the hasCanvasOption method returns true or a canvas
- // object is passed as image, else the scaled image:
- loadImage.scale = function (img, options) {
- options = options || {};
- var canvas = document.createElement('canvas'),
- useCanvas = img.getContext ||
- (loadImage.hasCanvasOption(options) && canvas.getContext),
- width = img.naturalWidth || img.width,
- height = img.naturalHeight || img.height,
- destWidth = width,
- destHeight = height,
- maxWidth,
- maxHeight,
- minWidth,
- minHeight,
- sourceWidth,
- sourceHeight,
- sourceX,
- sourceY,
- tmp,
- scaleUp = function () {
- var scale = Math.max(
- (minWidth || destWidth) / destWidth,
- (minHeight || destHeight) / destHeight
- );
- if (scale > 1) {
- destWidth = destWidth * scale;
- destHeight = destHeight * scale;
- }
- },
- scaleDown = function () {
- var scale = Math.min(
- (maxWidth || destWidth) / destWidth,
- (maxHeight || destHeight) / destHeight
- );
- if (scale < 1) {
- destWidth = destWidth * scale;
- destHeight = destHeight * scale;
- }
- };
- if (useCanvas) {
- options = loadImage.getTransformedOptions(img, options);
- sourceX = options.left || 0;
- sourceY = options.top || 0;
- if (options.sourceWidth) {
- sourceWidth = options.sourceWidth;
- if (options.right !== undefined && options.left === undefined) {
- sourceX = width - sourceWidth - options.right;
- }
- } else {
- sourceWidth = width - sourceX - (options.right || 0);
- }
- if (options.sourceHeight) {
- sourceHeight = options.sourceHeight;
- if (options.bottom !== undefined && options.top === undefined) {
- sourceY = height - sourceHeight - options.bottom;
- }
- } else {
- sourceHeight = height - sourceY - (options.bottom || 0);
- }
- destWidth = sourceWidth;
- destHeight = sourceHeight;
- }
- maxWidth = options.maxWidth;
- maxHeight = options.maxHeight;
- minWidth = options.minWidth;
- minHeight = options.minHeight;
- if (useCanvas && maxWidth && maxHeight && options.crop) {
- destWidth = maxWidth;
- destHeight = maxHeight;
- tmp = sourceWidth / sourceHeight - maxWidth / maxHeight;
- if (tmp < 0) {
- sourceHeight = maxHeight * sourceWidth / maxWidth;
- if (options.top === undefined && options.bottom === undefined) {
- sourceY = (height - sourceHeight) / 2;
- }
- } else if (tmp > 0) {
- sourceWidth = maxWidth * sourceHeight / maxHeight;
- if (options.left === undefined && options.right === undefined) {
- sourceX = (width - sourceWidth) / 2;
- }
- }
- } else {
- if (options.contain || options.cover) {
- minWidth = maxWidth = maxWidth || minWidth;
- minHeight = maxHeight = maxHeight || minHeight;
- }
- if (options.cover) {
- scaleDown();
- scaleUp();
- } else {
- scaleUp();
- scaleDown();
- }
- }
- if (useCanvas) {
- canvas.width = destWidth;
- canvas.height = destHeight;
- loadImage.transformCoordinates(
- canvas,
- options
- );
- return loadImage.renderImageToCanvas(
- canvas,
- img,
- sourceX,
- sourceY,
- sourceWidth,
- sourceHeight,
- 0,
- 0,
- destWidth,
- destHeight
- );
- }
- img.width = destWidth;
- img.height = destHeight;
- return img;
- };
-
- loadImage.createObjectURL = function (file) {
- return urlAPI ? urlAPI.createObjectURL(file) : false;
- };
-
- loadImage.revokeObjectURL = function (url) {
- return urlAPI ? urlAPI.revokeObjectURL(url) : false;
- };
-
- // Loads a given File object via FileReader interface,
- // invokes the callback with the event object (load or error).
- // The result can be read via event.target.result:
- loadImage.readFile = function (file, callback, method) {
- if (window.FileReader) {
- var fileReader = new FileReader();
- fileReader.onload = fileReader.onerror = callback;
- method = method || 'readAsDataURL';
- if (fileReader[method]) {
- fileReader[method](file);
- return fileReader;
- }
- }
- return false;
- };
-
- if (typeof define === 'function' && define.amd) {
- define(function () {
- return loadImage;
- });
- } else {
- $.loadImage = loadImage;
- }
-}(this));
From 4ec122b9fac3ca41529c5b63eb256ad3a48b3678 Mon Sep 17 00:00:00 2001
From: Igor Pstyga
Date: Fri, 21 Nov 2014 16:24:52 -0800
Subject: [PATCH 4/4] Use rails helper for image url
---
app/assets/stylesheets/jquery.fileupload-ui.scss | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/assets/stylesheets/jquery.fileupload-ui.scss b/app/assets/stylesheets/jquery.fileupload-ui.scss
index 76fb376..5e854e6 100644
--- a/app/assets/stylesheets/jquery.fileupload-ui.scss
+++ b/app/assets/stylesheets/jquery.fileupload-ui.scss
@@ -16,7 +16,7 @@
}
.progress-animated .progress-bar,
.progress-animated .bar {
- background: url("../img/progressbar.gif") !important;
+ background: image-url("progressbar.gif") !important;
filter: none;
}
.fileupload-process {
@@ -28,7 +28,7 @@
display: block;
width: 32px;
height: 32px;
- background: url("../img/loading.gif") center no-repeat;
+ background: image-url("loading.gif") center no-repeat;
background-size: contain;
}
.files audio,