glebtv-rails-uploader 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +241 -0
  3. data/Rakefile +26 -0
  4. data/app/assets/javascripts/uploader/application.js +9 -0
  5. data/app/assets/javascripts/uploader/rails_admin.js +25 -0
  6. data/app/assets/stylesheets/uploader/application.css +7 -0
  7. data/app/controllers/uploader/attachments_controller.rb +67 -0
  8. data/app/views/rails_admin/main/_form_rails_uploader.haml +10 -0
  9. data/app/views/uploader/default/_container.html.erb +67 -0
  10. data/app/views/uploader/default/_download.html.erb +17 -0
  11. data/app/views/uploader/default/_upload.html.erb +14 -0
  12. data/config/locales/en.yml +5 -0
  13. data/config/locales/ru.yml +5 -0
  14. data/config/locales/uk.yml +5 -0
  15. data/config/routes.rb +7 -0
  16. data/lib/file_size_validator.rb +66 -0
  17. data/lib/glebtv-rails-uploader.rb +3 -0
  18. data/lib/uploader.rb +35 -0
  19. data/lib/uploader/asset.rb +47 -0
  20. data/lib/uploader/engine.rb +25 -0
  21. data/lib/uploader/fileuploads.rb +109 -0
  22. data/lib/uploader/helpers/field_tag.rb +100 -0
  23. data/lib/uploader/helpers/form_builder.rb +16 -0
  24. data/lib/uploader/helpers/form_tag_helper.rb +16 -0
  25. data/lib/uploader/hooks/active_record.rb +5 -0
  26. data/lib/uploader/hooks/formtastic.rb +14 -0
  27. data/lib/uploader/hooks/simple_form.rb +9 -0
  28. data/lib/uploader/rails_admin/field.rb +28 -0
  29. data/lib/uploader/version.rb +3 -0
  30. data/spec/dummy/README.rdoc +261 -0
  31. data/spec/dummy/Rakefile +7 -0
  32. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  33. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  34. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  35. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  36. data/spec/dummy/app/models/article.rb +7 -0
  37. data/spec/dummy/app/models/asset.rb +27 -0
  38. data/spec/dummy/app/models/picture.rb +5 -0
  39. data/spec/dummy/app/uploaders/picture_uploader.rb +55 -0
  40. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  41. data/spec/dummy/config.ru +4 -0
  42. data/spec/dummy/config/application.rb +58 -0
  43. data/spec/dummy/config/boot.rb +10 -0
  44. data/spec/dummy/config/database.yml +25 -0
  45. data/spec/dummy/config/environment.rb +5 -0
  46. data/spec/dummy/config/environments/development.rb +37 -0
  47. data/spec/dummy/config/environments/production.rb +67 -0
  48. data/spec/dummy/config/environments/test.rb +37 -0
  49. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  50. data/spec/dummy/config/initializers/inflections.rb +15 -0
  51. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  52. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  53. data/spec/dummy/config/initializers/session_store.rb +8 -0
  54. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  55. data/spec/dummy/config/locales/en.yml +5 -0
  56. data/spec/dummy/config/routes.rb +3 -0
  57. data/spec/dummy/db/migrate/20120508093416_create_assets.rb +19 -0
  58. data/spec/dummy/db/migrate/20120508093830_create_articles.rb +10 -0
  59. data/spec/dummy/public/404.html +26 -0
  60. data/spec/dummy/public/422.html +26 -0
  61. data/spec/dummy/public/500.html +25 -0
  62. data/spec/dummy/public/favicon.ico +0 -0
  63. data/spec/dummy/script/rails +6 -0
  64. data/spec/factories/articles.rb +8 -0
  65. data/spec/factories/assets.rb +11 -0
  66. data/spec/factories/files/rails.png +0 -0
  67. data/spec/fileuploads_spec.rb +57 -0
  68. data/spec/requests/attachments_controller_spec.rb +38 -0
  69. data/spec/spec_helper.rb +52 -0
  70. data/spec/uploader_spec.rb +18 -0
  71. data/vendor/assets/images/uploader/but_del_tag2.png +0 -0
  72. data/vendor/assets/images/uploader/ico_attach.png +0 -0
  73. data/vendor/assets/images/uploader/preloader.gif +0 -0
  74. data/vendor/assets/images/uploader/progressBarFillBg.png +0 -0
  75. data/vendor/assets/javascripts/uploader/jquery.fileupload-ip.js +160 -0
  76. data/vendor/assets/javascripts/uploader/jquery.fileupload-ui.js +637 -0
  77. data/vendor/assets/javascripts/uploader/jquery.fileupload.js +904 -0
  78. data/vendor/assets/javascripts/uploader/jquery.iframe-transport.js +171 -0
  79. data/vendor/assets/javascripts/uploader/jquery.ui.widget.js +282 -0
  80. data/vendor/assets/javascripts/uploader/load-image.min.js +1 -0
  81. data/vendor/assets/javascripts/uploader/locales/en.js +27 -0
  82. data/vendor/assets/javascripts/uploader/locales/ru.js +27 -0
  83. data/vendor/assets/javascripts/uploader/locales/uk.js +27 -0
  84. data/vendor/assets/javascripts/uploader/tmpl.min.js +1 -0
  85. data/vendor/assets/stylesheets/uploader/default.css +214 -0
  86. data/vendor/assets/stylesheets/uploader/jquery.fileupload-ui.css +30 -0
  87. metadata +317 -0
@@ -0,0 +1,171 @@
1
+ /*
2
+ * jQuery Iframe Transport Plugin 1.4
3
+ * https://github.com/blueimp/jQuery-File-Upload
4
+ *
5
+ * Copyright 2011, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * Licensed under the MIT license:
9
+ * http://www.opensource.org/licenses/MIT
10
+ */
11
+
12
+ /*jslint unparam: true, nomen: true */
13
+ /*global define, window, document */
14
+
15
+ (function (factory) {
16
+ 'use strict';
17
+ if (typeof define === 'function' && define.amd) {
18
+ // Register as an anonymous AMD module:
19
+ define(['jquery'], factory);
20
+ } else {
21
+ // Browser globals:
22
+ factory(window.jQuery);
23
+ }
24
+ }(function ($) {
25
+ 'use strict';
26
+
27
+ // Helper variable to create unique names for the transport iframes:
28
+ var counter = 0;
29
+
30
+ // The iframe transport accepts three additional options:
31
+ // options.fileInput: a jQuery collection of file input fields
32
+ // options.paramName: the parameter name for the file form data,
33
+ // overrides the name property of the file input field(s),
34
+ // can be a string or an array of strings.
35
+ // options.formData: an array of objects with name and value properties,
36
+ // equivalent to the return data of .serializeArray(), e.g.:
37
+ // [{name: 'a', value: 1}, {name: 'b', value: 2}]
38
+ $.ajaxTransport('iframe', function (options) {
39
+ if (options.async && (options.type === 'POST' || options.type === 'GET')) {
40
+ var form,
41
+ iframe;
42
+ return {
43
+ send: function (_, completeCallback) {
44
+ form = $('<form style="display:none;"></form>');
45
+ // javascript:false as initial iframe src
46
+ // prevents warning popups on HTTPS in IE6.
47
+ // IE versions below IE8 cannot set the name property of
48
+ // elements that have already been added to the DOM,
49
+ // so we set the name along with the iframe HTML markup:
50
+ iframe = $(
51
+ '<iframe src="javascript:false;" name="iframe-transport-' +
52
+ (counter += 1) + '"></iframe>'
53
+ ).bind('load', function () {
54
+ var fileInputClones,
55
+ paramNames = $.isArray(options.paramName) ?
56
+ options.paramName : [options.paramName];
57
+ iframe
58
+ .unbind('load')
59
+ .bind('load', function () {
60
+ var response;
61
+ // Wrap in a try/catch block to catch exceptions thrown
62
+ // when trying to access cross-domain iframe contents:
63
+ try {
64
+ response = iframe.contents();
65
+ // Google Chrome and Firefox do not throw an
66
+ // exception when calling iframe.contents() on
67
+ // cross-domain requests, so we unify the response:
68
+ if (!response.length || !response[0].firstChild) {
69
+ throw new Error();
70
+ }
71
+ } catch (e) {
72
+ response = undefined;
73
+ }
74
+ // The complete callback returns the
75
+ // iframe content document as response object:
76
+ completeCallback(
77
+ 200,
78
+ 'success',
79
+ {'iframe': response}
80
+ );
81
+ // Fix for IE endless progress bar activity bug
82
+ // (happens on form submits to iframe targets):
83
+ $('<iframe src="javascript:false;"></iframe>')
84
+ .appendTo(form);
85
+ form.remove();
86
+ });
87
+ form
88
+ .prop('target', iframe.prop('name'))
89
+ .prop('action', options.url)
90
+ .prop('method', options.type);
91
+ if (options.formData) {
92
+ $.each(options.formData, function (index, field) {
93
+ $('<input type="hidden"/>')
94
+ .prop('name', field.name)
95
+ .val(field.value)
96
+ .appendTo(form);
97
+ });
98
+ }
99
+ if (options.fileInput && options.fileInput.length &&
100
+ options.type === 'POST') {
101
+ fileInputClones = options.fileInput.clone();
102
+ // Insert a clone for each file input field:
103
+ options.fileInput.after(function (index) {
104
+ return fileInputClones[index];
105
+ });
106
+ if (options.paramName) {
107
+ options.fileInput.each(function (index) {
108
+ $(this).prop(
109
+ 'name',
110
+ paramNames[index] || options.paramName
111
+ );
112
+ });
113
+ }
114
+ // Appending the file input fields to the hidden form
115
+ // removes them from their original location:
116
+ form
117
+ .append(options.fileInput)
118
+ .prop('enctype', 'multipart/form-data')
119
+ // enctype must be set as encoding for IE:
120
+ .prop('encoding', 'multipart/form-data');
121
+ }
122
+ form.submit();
123
+ // Insert the file input fields at their original location
124
+ // by replacing the clones with the originals:
125
+ if (fileInputClones && fileInputClones.length) {
126
+ options.fileInput.each(function (index, input) {
127
+ var clone = $(fileInputClones[index]);
128
+ $(input).prop('name', clone.prop('name'));
129
+ clone.replaceWith(input);
130
+ });
131
+ }
132
+ });
133
+ form.append(iframe).appendTo(document.body);
134
+ },
135
+ abort: function () {
136
+ if (iframe) {
137
+ // javascript:false as iframe src aborts the request
138
+ // and prevents warning popups on HTTPS in IE6.
139
+ // concat is used to avoid the "Script URL" JSLint error:
140
+ iframe
141
+ .unbind('load')
142
+ .prop('src', 'javascript'.concat(':false;'));
143
+ }
144
+ if (form) {
145
+ form.remove();
146
+ }
147
+ }
148
+ };
149
+ }
150
+ });
151
+
152
+ // The iframe transport returns the iframe content document as response.
153
+ // The following adds converters from iframe to text, json, html, and script:
154
+ $.ajaxSetup({
155
+ converters: {
156
+ 'iframe text': function (iframe) {
157
+ return $(iframe[0].body).text();
158
+ },
159
+ 'iframe json': function (iframe) {
160
+ return $.parseJSON($(iframe[0].body).text());
161
+ },
162
+ 'iframe html': function (iframe) {
163
+ return $(iframe[0].body).html();
164
+ },
165
+ 'iframe script': function (iframe) {
166
+ return $.globalEval($(iframe[0].body).text());
167
+ }
168
+ }
169
+ });
170
+
171
+ }));
@@ -0,0 +1,282 @@
1
+ /*
2
+ * jQuery UI Widget 1.8.18+amd
3
+ * https://github.com/blueimp/jQuery-File-Upload
4
+ *
5
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
6
+ * Dual licensed under the MIT or GPL Version 2 licenses.
7
+ * http://jquery.org/license
8
+ *
9
+ * http://docs.jquery.com/UI/Widget
10
+ */
11
+
12
+ (function (factory) {
13
+ if (typeof define === "function" && define.amd) {
14
+ // Register as an anonymous AMD module:
15
+ define(["jquery"], factory);
16
+ } else {
17
+ // Browser globals:
18
+ factory(jQuery);
19
+ }
20
+ }(function( $, undefined ) {
21
+
22
+ // jQuery 1.4+
23
+ if ( $.cleanData ) {
24
+ var _cleanData = $.cleanData;
25
+ $.cleanData = function( elems ) {
26
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
27
+ try {
28
+ $( elem ).triggerHandler( "remove" );
29
+ // http://bugs.jquery.com/ticket/8235
30
+ } catch( e ) {}
31
+ }
32
+ _cleanData( elems );
33
+ };
34
+ } else {
35
+ var _remove = $.fn.remove;
36
+ $.fn.remove = function( selector, keepData ) {
37
+ return this.each(function() {
38
+ if ( !keepData ) {
39
+ if ( !selector || $.filter( selector, [ this ] ).length ) {
40
+ $( "*", this ).add( [ this ] ).each(function() {
41
+ try {
42
+ $( this ).triggerHandler( "remove" );
43
+ // http://bugs.jquery.com/ticket/8235
44
+ } catch( e ) {}
45
+ });
46
+ }
47
+ }
48
+ return _remove.call( $(this), selector, keepData );
49
+ });
50
+ };
51
+ }
52
+
53
+ $.widget = function( name, base, prototype ) {
54
+ var namespace = name.split( "." )[ 0 ],
55
+ fullName;
56
+ name = name.split( "." )[ 1 ];
57
+ fullName = namespace + "-" + name;
58
+
59
+ if ( !prototype ) {
60
+ prototype = base;
61
+ base = $.Widget;
62
+ }
63
+
64
+ // create selector for plugin
65
+ $.expr[ ":" ][ fullName ] = function( elem ) {
66
+ return !!$.data( elem, name );
67
+ };
68
+
69
+ $[ namespace ] = $[ namespace ] || {};
70
+ $[ namespace ][ name ] = function( options, element ) {
71
+ // allow instantiation without initializing for simple inheritance
72
+ if ( arguments.length ) {
73
+ this._createWidget( options, element );
74
+ }
75
+ };
76
+
77
+ var basePrototype = new base();
78
+ // we need to make the options hash a property directly on the new instance
79
+ // otherwise we'll modify the options hash on the prototype that we're
80
+ // inheriting from
81
+ // $.each( basePrototype, function( key, val ) {
82
+ // if ( $.isPlainObject(val) ) {
83
+ // basePrototype[ key ] = $.extend( {}, val );
84
+ // }
85
+ // });
86
+ basePrototype.options = $.extend( true, {}, basePrototype.options );
87
+ $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
88
+ namespace: namespace,
89
+ widgetName: name,
90
+ widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
91
+ widgetBaseClass: fullName
92
+ }, prototype );
93
+
94
+ $.widget.bridge( name, $[ namespace ][ name ] );
95
+ };
96
+
97
+ $.widget.bridge = function( name, object ) {
98
+ $.fn[ name ] = function( options ) {
99
+ var isMethodCall = typeof options === "string",
100
+ args = Array.prototype.slice.call( arguments, 1 ),
101
+ returnValue = this;
102
+
103
+ // allow multiple hashes to be passed on init
104
+ options = !isMethodCall && args.length ?
105
+ $.extend.apply( null, [ true, options ].concat(args) ) :
106
+ options;
107
+
108
+ // prevent calls to internal methods
109
+ if ( isMethodCall && options.charAt( 0 ) === "_" ) {
110
+ return returnValue;
111
+ }
112
+
113
+ if ( isMethodCall ) {
114
+ this.each(function() {
115
+ var instance = $.data( this, name ),
116
+ methodValue = instance && $.isFunction( instance[options] ) ?
117
+ instance[ options ].apply( instance, args ) :
118
+ instance;
119
+ // TODO: add this back in 1.9 and use $.error() (see #5972)
120
+ // if ( !instance ) {
121
+ // throw "cannot call methods on " + name + " prior to initialization; " +
122
+ // "attempted to call method '" + options + "'";
123
+ // }
124
+ // if ( !$.isFunction( instance[options] ) ) {
125
+ // throw "no such method '" + options + "' for " + name + " widget instance";
126
+ // }
127
+ // var methodValue = instance[ options ].apply( instance, args );
128
+ if ( methodValue !== instance && methodValue !== undefined ) {
129
+ returnValue = methodValue;
130
+ return false;
131
+ }
132
+ });
133
+ } else {
134
+ this.each(function() {
135
+ var instance = $.data( this, name );
136
+ if ( instance ) {
137
+ instance.option( options || {} )._init();
138
+ } else {
139
+ $.data( this, name, new object( options, this ) );
140
+ }
141
+ });
142
+ }
143
+
144
+ return returnValue;
145
+ };
146
+ };
147
+
148
+ $.Widget = function( options, element ) {
149
+ // allow instantiation without initializing for simple inheritance
150
+ if ( arguments.length ) {
151
+ this._createWidget( options, element );
152
+ }
153
+ };
154
+
155
+ $.Widget.prototype = {
156
+ widgetName: "widget",
157
+ widgetEventPrefix: "",
158
+ options: {
159
+ disabled: false
160
+ },
161
+ _createWidget: function( options, element ) {
162
+ // $.widget.bridge stores the plugin instance, but we do it anyway
163
+ // so that it's stored even before the _create function runs
164
+ $.data( element, this.widgetName, this );
165
+ this.element = $( element );
166
+ this.options = $.extend( true, {},
167
+ this.options,
168
+ this._getCreateOptions(),
169
+ options );
170
+
171
+ var self = this;
172
+ this.element.bind( "remove." + this.widgetName, function() {
173
+ self.destroy();
174
+ });
175
+
176
+ this._create();
177
+ this._trigger( "create" );
178
+ this._init();
179
+ },
180
+ _getCreateOptions: function() {
181
+ return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
182
+ },
183
+ _create: function() {},
184
+ _init: function() {},
185
+
186
+ destroy: function() {
187
+ this.element
188
+ .unbind( "." + this.widgetName )
189
+ .removeData( this.widgetName );
190
+ this.widget()
191
+ .unbind( "." + this.widgetName )
192
+ .removeAttr( "aria-disabled" )
193
+ .removeClass(
194
+ this.widgetBaseClass + "-disabled " +
195
+ "ui-state-disabled" );
196
+ },
197
+
198
+ widget: function() {
199
+ return this.element;
200
+ },
201
+
202
+ option: function( key, value ) {
203
+ var options = key;
204
+
205
+ if ( arguments.length === 0 ) {
206
+ // don't return a reference to the internal hash
207
+ return $.extend( {}, this.options );
208
+ }
209
+
210
+ if (typeof key === "string" ) {
211
+ if ( value === undefined ) {
212
+ return this.options[ key ];
213
+ }
214
+ options = {};
215
+ options[ key ] = value;
216
+ }
217
+
218
+ this._setOptions( options );
219
+
220
+ return this;
221
+ },
222
+ _setOptions: function( options ) {
223
+ var self = this;
224
+ $.each( options, function( key, value ) {
225
+ self._setOption( key, value );
226
+ });
227
+
228
+ return this;
229
+ },
230
+ _setOption: function( key, value ) {
231
+ this.options[ key ] = value;
232
+
233
+ if ( key === "disabled" ) {
234
+ this.widget()
235
+ [ value ? "addClass" : "removeClass"](
236
+ this.widgetBaseClass + "-disabled" + " " +
237
+ "ui-state-disabled" )
238
+ .attr( "aria-disabled", value );
239
+ }
240
+
241
+ return this;
242
+ },
243
+
244
+ enable: function() {
245
+ return this._setOption( "disabled", false );
246
+ },
247
+ disable: function() {
248
+ return this._setOption( "disabled", true );
249
+ },
250
+
251
+ _trigger: function( type, event, data ) {
252
+ var prop, orig,
253
+ callback = this.options[ type ];
254
+
255
+ data = data || {};
256
+ event = $.Event( event );
257
+ event.type = ( type === this.widgetEventPrefix ?
258
+ type :
259
+ this.widgetEventPrefix + type ).toLowerCase();
260
+ // the original event may come from any element
261
+ // so we need to reset the target on the new event
262
+ event.target = this.element[ 0 ];
263
+
264
+ // copy original event properties over to the new event
265
+ orig = event.originalEvent;
266
+ if ( orig ) {
267
+ for ( prop in orig ) {
268
+ if ( !( prop in event ) ) {
269
+ event[ prop ] = orig[ prop ];
270
+ }
271
+ }
272
+ }
273
+
274
+ this.element.trigger( event, data );
275
+
276
+ return !( $.isFunction(callback) &&
277
+ callback.call( this.element[0], event, data ) === false ||
278
+ event.isDefaultPrevented() );
279
+ }
280
+ };
281
+
282
+ }));