glebtv-rails-uploader 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +48 -146
  3. data/Rakefile +2 -2
  4. data/app/assets/javascripts/uploader/application.js +5 -6
  5. data/app/assets/javascripts/uploader/rails_admin.js +6 -25
  6. data/app/assets/stylesheets/uploader/application.css.sass +2 -0
  7. data/app/assets/stylesheets/uploader/{application.css → application.css.scss} +0 -0
  8. data/app/controllers/uploader/attachments_controller.rb +28 -50
  9. data/app/views/rails_admin/main/_form_rails_uploader.haml +1 -10
  10. data/app/views/uploader/default/_container.html.erb +49 -64
  11. data/app/views/uploader/default/_download.html.erb +16 -12
  12. data/app/views/uploader/default/_upload.html.erb +2 -2
  13. data/config/routes.rb +1 -5
  14. data/lib/glebtv-rails-uploader.rb +0 -1
  15. data/lib/uploader.rb +5 -5
  16. data/lib/uploader/asset.rb +84 -41
  17. data/lib/uploader/engine.rb +10 -6
  18. data/lib/uploader/fileuploads.rb +53 -31
  19. data/lib/uploader/helpers/field_tag.rb +24 -35
  20. data/lib/uploader/helpers/form_builder.rb +1 -1
  21. data/lib/uploader/helpers/form_tag_helper.rb +2 -3
  22. data/lib/uploader/hooks/formtastic.rb +10 -4
  23. data/lib/uploader/hooks/simple_form.rb +1 -3
  24. data/lib/uploader/version.rb +1 -1
  25. data/spec/dummy/app/models/article.rb +3 -7
  26. data/spec/dummy/app/models/asset.rb +26 -19
  27. data/spec/dummy/app/models/picture.rb +4 -4
  28. data/spec/dummy/config/application.rb +5 -7
  29. data/spec/dummy/config/environments/development.rb +1 -5
  30. data/spec/dummy/config/environments/production.rb +0 -4
  31. data/spec/dummy/config/environments/test.rb +2 -6
  32. data/spec/dummy/db/migrate/20120508093416_create_assets.rb +3 -1
  33. data/spec/factories/articles.rb +1 -0
  34. data/spec/factories/assets.rb +1 -0
  35. data/spec/fileuploads_spec.rb +2 -2
  36. data/spec/mongoid_spec.rb +4 -6
  37. data/spec/requests/attachments_controller_spec.rb +10 -2
  38. data/spec/spec_helper.rb +7 -3
  39. data/spec/uploader_spec.rb +1 -1
  40. data/{app → vendor}/assets/images/uploader/but_del_tag2.png +0 -0
  41. data/{app → vendor}/assets/images/uploader/ico_attach.png +0 -0
  42. data/{app → vendor}/assets/images/uploader/preloader.gif +0 -0
  43. data/{app → vendor}/assets/images/uploader/progressBarFillBg.png +0 -0
  44. data/vendor/assets/javascripts/uploader/jquery.fileupload-fp.js +8 -4
  45. data/{app → vendor}/assets/javascripts/uploader/jquery.fileupload-ui.js +219 -44
  46. data/{app → vendor}/assets/javascripts/uploader/jquery.fileupload.js +16 -74
  47. data/{app → vendor}/assets/javascripts/uploader/jquery.iframe-transport.js +3 -9
  48. data/vendor/assets/javascripts/uploader/load-image.min.js +1 -0
  49. data/{app → vendor}/assets/javascripts/uploader/locales/en.js +0 -0
  50. data/{app → vendor}/assets/javascripts/uploader/locales/ru.js +0 -0
  51. data/{app → vendor}/assets/javascripts/uploader/locales/uk.js +0 -0
  52. data/vendor/assets/javascripts/uploader/tmpl.min.js +1 -0
  53. data/{app/assets/stylesheets/uploader/default.css → vendor/assets/stylesheets/uploader/default.css.scss} +3 -11
  54. data/{app/assets/stylesheets/uploader/jquery.fileupload-ui.css → vendor/assets/stylesheets/uploader/jquery.fileupload-ui.css.scss} +0 -0
  55. metadata +78 -146
  56. data/app/assets/javascripts/uploader/canvas-to-blob.js +0 -95
  57. data/app/assets/javascripts/uploader/jquery.fileupload-angular.js +0 -348
  58. data/app/assets/javascripts/uploader/jquery.fileupload-process.js +0 -158
  59. data/app/assets/javascripts/uploader/jquery.fileupload-resize.js +0 -212
  60. data/app/assets/javascripts/uploader/jquery.fileupload-validate.js +0 -116
  61. data/app/assets/javascripts/uploader/jquery.ui.widget.js +0 -530
  62. data/app/assets/javascripts/uploader/load-image.js +0 -381
  63. data/app/assets/javascripts/uploader/tmpl.js +0 -86
  64. data/lib/file_size_validator.rb +0 -68
  65. data/spec/dummy/config/mongoid.yml +0 -12
@@ -1,212 +0,0 @@
1
- /*
2
- * jQuery File Upload Image Resize Plugin 1.1.2
3
- * https://github.com/blueimp/jQuery-File-Upload
4
- *
5
- * Copyright 2013, Sebastian Tschan
6
- * https://blueimp.net
7
- *
8
- * Licensed under the MIT license:
9
- * http://www.opensource.org/licenses/MIT
10
- */
11
-
12
- /*jslint nomen: true, unparam: true, regexp: true */
13
- /*global define, window */
14
-
15
- (function (factory) {
16
- 'use strict';
17
- if (typeof define === 'function' && define.amd) {
18
- // Register as an anonymous AMD module:
19
- define([
20
- 'jquery',
21
- 'load-image',
22
- 'canvas-to-blob',
23
- './jquery.fileupload-process'
24
- ], factory);
25
- } else {
26
- // Browser globals:
27
- factory(
28
- window.jQuery,
29
- window.loadImage
30
- );
31
- }
32
- }(function ($, loadImage) {
33
- 'use strict';
34
-
35
- // Prepend to the default processQueue:
36
- $.blueimp.fileupload.prototype.options.processQueue.unshift(
37
- {
38
- action: 'loadImage',
39
- fileTypes: '@loadImageFileTypes',
40
- maxFileSize: '@loadImageMaxFileSize',
41
- noRevoke: '@loadImageNoRevoke',
42
- disabled: '@disableImageLoad'
43
- },
44
- {
45
- action: 'resizeImage',
46
- maxWidth: '@imageMaxWidth',
47
- maxHeight: '@imageMaxHeight',
48
- minWidth: '@imageMinWidth',
49
- minHeight: '@imageMinHeight',
50
- crop: '@imageCrop',
51
- disabled: '@disableImageResize'
52
- },
53
- {
54
- action: 'saveImage',
55
- disabled: '@disableImageResize'
56
- },
57
- {
58
- action: 'resizeImage',
59
- maxWidth: '@previewMaxWidth',
60
- maxHeight: '@previewMaxHeight',
61
- minWidth: '@previewMinWidth',
62
- minHeight: '@previewMinHeight',
63
- crop: '@previewCrop',
64
- canvas: '@previewAsCanvas',
65
- disabled: '@disableImagePreview'
66
- },
67
- {
68
- action: 'setImage',
69
- // The name of the property the resized image
70
- // is saved as on the associated file object:
71
- name: 'preview',
72
- disabled: '@disableImagePreview'
73
- }
74
- );
75
-
76
- // The File Upload Resize plugin extends the fileupload widget
77
- // with image resize functionality:
78
- $.widget('blueimp.fileupload', $.blueimp.fileupload, {
79
-
80
- options: {
81
- // The regular expression for the types of images to load:
82
- // matched against the file type:
83
- loadImageFileTypes: /^image\/(gif|jpeg|png)$/,
84
- // The maximum file size of images to load:
85
- loadImageMaxFileSize: 5000000, // 5MB
86
- // The maximum width of resized images:
87
- imageMaxWidth: 1920,
88
- // The maximum height of resized images:
89
- imageMaxHeight: 1080,
90
- // Define if resized images should be cropped or only scaled:
91
- imageCrop: false,
92
- // Disable the resize image functionality by default:
93
- disableImageResize: true,
94
- // The maximum width of the preview images:
95
- previewMaxWidth: 80,
96
- // The maximum height of the preview images:
97
- previewMaxHeight: 80,
98
- // Define if preview images should be cropped or only scaled:
99
- previewCrop: false,
100
- // Define if preview images should be resized as canvas elements:
101
- previewAsCanvas: true
102
- },
103
-
104
- processActions: {
105
-
106
- // Loads the image given via data.files and data.index
107
- // as img element if the browser supports canvas.
108
- // Accepts the options fileTypes (regular expression)
109
- // and maxFileSize (integer) to limit the files to load:
110
- loadImage: function (data, options) {
111
- if (options.disabled) {
112
- return data;
113
- }
114
- var that = this,
115
- file = data.files[data.index],
116
- dfd = $.Deferred();
117
- if (($.type(options.maxFileSize) === 'number' &&
118
- file.size > options.maxFileSize) ||
119
- (options.fileTypes &&
120
- !options.fileTypes.test(file.type)) ||
121
- !loadImage(
122
- file,
123
- function (img) {
124
- if (!img.src) {
125
- return dfd.rejectWith(that, [data]);
126
- }
127
- data.img = img;
128
- dfd.resolveWith(that, [data]);
129
- },
130
- options
131
- )) {
132
- dfd.rejectWith(that, [data]);
133
- }
134
- return dfd.promise();
135
- },
136
-
137
- // Resizes the image given as data.canvas or data.img
138
- // and updates data.canvas or data.img with the resized image.
139
- // Accepts the options maxWidth, maxHeight, minWidth,
140
- // minHeight, canvas and crop:
141
- resizeImage: function (data, options) {
142
- options = $.extend({canvas: true}, options);
143
- var img = (options.canvas && data.canvas) || data.img,
144
- canvas;
145
- if (img && !options.disabled) {
146
- canvas = loadImage.scale(img, options);
147
- if (canvas && (canvas.width !== img.width ||
148
- canvas.height !== img.height)) {
149
- data[canvas.getContext ? 'canvas' : 'img'] = canvas;
150
- }
151
- }
152
- return data;
153
- },
154
-
155
- // Saves the processed image given as data.canvas
156
- // inplace at data.index of data.files:
157
- saveImage: function (data, options) {
158
- if (!data.canvas || options.disabled) {
159
- return data;
160
- }
161
- var that = this,
162
- file = data.files[data.index],
163
- name = file.name,
164
- dfd = $.Deferred(),
165
- callback = function (blob) {
166
- if (!blob.name) {
167
- if (file.type === blob.type) {
168
- blob.name = file.name;
169
- } else if (file.name) {
170
- blob.name = file.name.replace(
171
- /\..+$/,
172
- '.' + blob.type.substr(6)
173
- );
174
- }
175
- }
176
- // Store the created blob at the position
177
- // of the original file in the files list:
178
- data.files[data.index] = blob;
179
- dfd.resolveWith(that, [data]);
180
- };
181
- // Use canvas.mozGetAsFile directly, to retain the filename, as
182
- // Gecko doesn't support the filename option for FormData.append:
183
- if (data.canvas.mozGetAsFile) {
184
- callback(data.canvas.mozGetAsFile(
185
- (/^image\/(jpeg|png)$/.test(file.type) && name) ||
186
- ((name && name.replace(/\..+$/, '')) ||
187
- 'blob') + '.png',
188
- file.type
189
- ));
190
- } else if (data.canvas.toBlob) {
191
- data.canvas.toBlob(callback, file.type);
192
- } else {
193
- return data;
194
- }
195
- return dfd.promise();
196
- },
197
-
198
- // Sets the resized version of the image as a property of the
199
- // file object, must be called after "saveImage":
200
- setImage: function (data, options) {
201
- var img = data.canvas || data.img;
202
- if (img && !options.disabled) {
203
- data.files[data.index][options.name] = img;
204
- }
205
- return data;
206
- }
207
-
208
- }
209
-
210
- });
211
-
212
- }));
@@ -1,116 +0,0 @@
1
- /*
2
- * jQuery File Upload Validation Plugin 1.0.2
3
- * https://github.com/blueimp/jQuery-File-Upload
4
- *
5
- * Copyright 2013, Sebastian Tschan
6
- * https://blueimp.net
7
- *
8
- * Licensed under the MIT license:
9
- * http://www.opensource.org/licenses/MIT
10
- */
11
-
12
- /*jslint nomen: true, unparam: true, regexp: true */
13
- /*global define, window */
14
-
15
- (function (factory) {
16
- 'use strict';
17
- if (typeof define === 'function' && define.amd) {
18
- // Register as an anonymous AMD module:
19
- define([
20
- 'jquery',
21
- './jquery.fileupload-process'
22
- ], factory);
23
- } else {
24
- // Browser globals:
25
- factory(
26
- window.jQuery
27
- );
28
- }
29
- }(function ($) {
30
- 'use strict';
31
-
32
- // Append to the default processQueue:
33
- $.blueimp.fileupload.prototype.options.processQueue.push(
34
- {
35
- action: 'validate',
36
- // Always trigger this action,
37
- // even if the previous action was rejected:
38
- always: true,
39
- // Options taken from the global options map:
40
- acceptFileTypes: '@acceptFileTypes',
41
- maxFileSize: '@maxFileSize',
42
- minFileSize: '@minFileSize',
43
- maxNumberOfFiles: '@maxNumberOfFiles',
44
- disabled: '@disableValidation'
45
- }
46
- );
47
-
48
- // The File Upload Validation plugin extends the fileupload widget
49
- // with file validation functionality:
50
- $.widget('blueimp.fileupload', $.blueimp.fileupload, {
51
-
52
- options: {
53
- /*
54
- // The regular expression for allowed file types, matches
55
- // against either file type or file name:
56
- acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
57
- // The maximum allowed file size in bytes:
58
- maxFileSize: 10000000, // 10 MB
59
- // The minimum allowed file size in bytes:
60
- minFileSize: undefined, // No minimal file size
61
- // The limit of files to be uploaded:
62
- maxNumberOfFiles: 10,
63
- */
64
-
65
- // Function returning the current number of files,
66
- // has to be overriden for maxNumberOfFiles validation:
67
- getNumberOfFiles: $.noop,
68
-
69
- // Error and info messages:
70
- messages: {
71
- maxNumberOfFiles: 'Maximum number of files exceeded',
72
- acceptFileTypes: 'File type not allowed',
73
- maxFileSize: 'File is too large',
74
- minFileSize: 'File is too small'
75
- }
76
- },
77
-
78
- processActions: {
79
-
80
- validate: function (data, options) {
81
- if (options.disabled) {
82
- return data;
83
- }
84
- var dfd = $.Deferred(),
85
- settings = this.options,
86
- file = data.files[data.index],
87
- numberOfFiles = settings.getNumberOfFiles();
88
- if (numberOfFiles && $.type(options.maxNumberOfFiles) === 'number' &&
89
- numberOfFiles + data.files.length > options.maxNumberOfFiles) {
90
- file.error = settings.i18n('maxNumberOfFiles');
91
- } else if (options.acceptFileTypes &&
92
- !(options.acceptFileTypes.test(file.type) ||
93
- options.acceptFileTypes.test(file.name))) {
94
- file.error = settings.i18n('acceptFileTypes');
95
- } else if (options.maxFileSize && file.size > options.maxFileSize) {
96
- file.error = settings.i18n('maxFileSize');
97
- } else if ($.type(file.size) === 'number' &&
98
- file.size < options.minFileSize) {
99
- file.error = settings.i18n('minFileSize');
100
- } else {
101
- delete file.error;
102
- }
103
- if (file.error || data.files.error) {
104
- data.files.error = true;
105
- dfd.rejectWith(this, [data]);
106
- } else {
107
- dfd.resolveWith(this, [data]);
108
- }
109
- return dfd.promise();
110
- }
111
-
112
- }
113
-
114
- });
115
-
116
- }));
@@ -1,530 +0,0 @@
1
- /*
2
- * jQuery UI Widget 1.10.1+amd
3
- * https://github.com/blueimp/jQuery-File-Upload
4
- *
5
- * Copyright 2013 jQuery Foundation and other contributors
6
- * Released under the MIT license.
7
- * http://jquery.org/license
8
- *
9
- * http://api.jqueryui.com/jQuery.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
- var uuid = 0,
23
- slice = Array.prototype.slice,
24
- _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
-
35
- $.widget = function( name, base, prototype ) {
36
- var fullName, existingConstructor, constructor, basePrototype,
37
- // proxiedPrototype allows the provided prototype to remain unmodified
38
- // so that it can be used as a mixin for multiple widgets (#8876)
39
- proxiedPrototype = {},
40
- namespace = name.split( "." )[ 0 ];
41
-
42
- name = name.split( "." )[ 1 ];
43
- fullName = namespace + "-" + name;
44
-
45
- if ( !prototype ) {
46
- prototype = base;
47
- base = $.Widget;
48
- }
49
-
50
- // create selector for plugin
51
- $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
52
- return !!$.data( elem, fullName );
53
- };
54
-
55
- $[ namespace ] = $[ namespace ] || {};
56
- existingConstructor = $[ namespace ][ name ];
57
- constructor = $[ namespace ][ name ] = function( options, element ) {
58
- // allow instantiation without "new" keyword
59
- if ( !this._createWidget ) {
60
- return new constructor( options, element );
61
- }
62
-
63
- // allow instantiation without initializing for simple inheritance
64
- // must use "new" keyword (the code above always passes args)
65
- if ( arguments.length ) {
66
- this._createWidget( options, element );
67
- }
68
- };
69
- // extend with the existing constructor to carry over any static properties
70
- $.extend( constructor, existingConstructor, {
71
- version: prototype.version,
72
- // copy the object used to create the prototype in case we need to
73
- // redefine the widget later
74
- _proto: $.extend( {}, prototype ),
75
- // track widgets that inherit from this widget in case this widget is
76
- // redefined after a widget inherits from it
77
- _childConstructors: []
78
- });
79
-
80
- basePrototype = new base();
81
- // we need to make the options hash a property directly on the new instance
82
- // otherwise we'll modify the options hash on the prototype that we're
83
- // inheriting from
84
- basePrototype.options = $.widget.extend( {}, basePrototype.options );
85
- $.each( prototype, function( prop, value ) {
86
- if ( !$.isFunction( value ) ) {
87
- proxiedPrototype[ prop ] = value;
88
- return;
89
- }
90
- proxiedPrototype[ prop ] = (function() {
91
- var _super = function() {
92
- return base.prototype[ prop ].apply( this, arguments );
93
- },
94
- _superApply = function( args ) {
95
- return base.prototype[ prop ].apply( this, args );
96
- };
97
- return function() {
98
- var __super = this._super,
99
- __superApply = this._superApply,
100
- returnValue;
101
-
102
- this._super = _super;
103
- this._superApply = _superApply;
104
-
105
- returnValue = value.apply( this, arguments );
106
-
107
- this._super = __super;
108
- this._superApply = __superApply;
109
-
110
- return returnValue;
111
- };
112
- })();
113
- });
114
- constructor.prototype = $.widget.extend( basePrototype, {
115
- // TODO: remove support for widgetEventPrefix
116
- // always use the name + a colon as the prefix, e.g., draggable:start
117
- // don't prefix for widgets that aren't DOM-based
118
- widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
119
- }, proxiedPrototype, {
120
- constructor: constructor,
121
- namespace: namespace,
122
- widgetName: name,
123
- widgetFullName: fullName
124
- });
125
-
126
- // If this widget is being redefined then we need to find all widgets that
127
- // are inheriting from it and redefine all of them so that they inherit from
128
- // the new version of this widget. We're essentially trying to replace one
129
- // level in the prototype chain.
130
- if ( existingConstructor ) {
131
- $.each( existingConstructor._childConstructors, function( i, child ) {
132
- var childPrototype = child.prototype;
133
-
134
- // redefine the child widget using the same prototype that was
135
- // originally used, but inherit from the new version of the base
136
- $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
137
- });
138
- // remove the list of existing child constructors from the old constructor
139
- // so the old child constructors can be garbage collected
140
- delete existingConstructor._childConstructors;
141
- } else {
142
- base._childConstructors.push( constructor );
143
- }
144
-
145
- $.widget.bridge( name, constructor );
146
- };
147
-
148
- $.widget.extend = function( target ) {
149
- var input = slice.call( arguments, 1 ),
150
- inputIndex = 0,
151
- inputLength = input.length,
152
- key,
153
- value;
154
- for ( ; inputIndex < inputLength; inputIndex++ ) {
155
- for ( key in input[ inputIndex ] ) {
156
- value = input[ inputIndex ][ key ];
157
- if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
158
- // Clone objects
159
- if ( $.isPlainObject( value ) ) {
160
- target[ key ] = $.isPlainObject( target[ key ] ) ?
161
- $.widget.extend( {}, target[ key ], value ) :
162
- // Don't extend strings, arrays, etc. with objects
163
- $.widget.extend( {}, value );
164
- // Copy everything else by reference
165
- } else {
166
- target[ key ] = value;
167
- }
168
- }
169
- }
170
- }
171
- return target;
172
- };
173
-
174
- $.widget.bridge = function( name, object ) {
175
- var fullName = object.prototype.widgetFullName || name;
176
- $.fn[ name ] = function( options ) {
177
- var isMethodCall = typeof options === "string",
178
- args = slice.call( arguments, 1 ),
179
- returnValue = this;
180
-
181
- // allow multiple hashes to be passed on init
182
- options = !isMethodCall && args.length ?
183
- $.widget.extend.apply( null, [ options ].concat(args) ) :
184
- options;
185
-
186
- if ( isMethodCall ) {
187
- this.each(function() {
188
- var methodValue,
189
- instance = $.data( this, fullName );
190
- if ( !instance ) {
191
- return $.error( "cannot call methods on " + name + " prior to initialization; " +
192
- "attempted to call method '" + options + "'" );
193
- }
194
- if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
195
- return $.error( "no such method '" + options + "' for " + name + " widget instance" );
196
- }
197
- methodValue = instance[ options ].apply( instance, args );
198
- if ( methodValue !== instance && methodValue !== undefined ) {
199
- returnValue = methodValue && methodValue.jquery ?
200
- returnValue.pushStack( methodValue.get() ) :
201
- methodValue;
202
- return false;
203
- }
204
- });
205
- } else {
206
- this.each(function() {
207
- var instance = $.data( this, fullName );
208
- if ( instance ) {
209
- instance.option( options || {} )._init();
210
- } else {
211
- $.data( this, fullName, new object( options, this ) );
212
- }
213
- });
214
- }
215
-
216
- return returnValue;
217
- };
218
- };
219
-
220
- $.Widget = function( /* options, element */ ) {};
221
- $.Widget._childConstructors = [];
222
-
223
- $.Widget.prototype = {
224
- widgetName: "widget",
225
- widgetEventPrefix: "",
226
- defaultElement: "<div>",
227
- options: {
228
- disabled: false,
229
-
230
- // callbacks
231
- create: null
232
- },
233
- _createWidget: function( options, element ) {
234
- element = $( element || this.defaultElement || this )[ 0 ];
235
- this.element = $( element );
236
- this.uuid = uuid++;
237
- this.eventNamespace = "." + this.widgetName + this.uuid;
238
- this.options = $.widget.extend( {},
239
- this.options,
240
- this._getCreateOptions(),
241
- options );
242
-
243
- this.bindings = $();
244
- this.hoverable = $();
245
- this.focusable = $();
246
-
247
- if ( element !== this ) {
248
- $.data( element, this.widgetFullName, this );
249
- this._on( true, this.element, {
250
- remove: function( event ) {
251
- if ( event.target === element ) {
252
- this.destroy();
253
- }
254
- }
255
- });
256
- this.document = $( element.style ?
257
- // element within the document
258
- element.ownerDocument :
259
- // element is window or document
260
- element.document || element );
261
- this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
262
- }
263
-
264
- this._create();
265
- this._trigger( "create", null, this._getCreateEventData() );
266
- this._init();
267
- },
268
- _getCreateOptions: $.noop,
269
- _getCreateEventData: $.noop,
270
- _create: $.noop,
271
- _init: $.noop,
272
-
273
- destroy: function() {
274
- this._destroy();
275
- // we can probably remove the unbind calls in 2.0
276
- // all event bindings should go through this._on()
277
- this.element
278
- .unbind( this.eventNamespace )
279
- // 1.9 BC for #7810
280
- // TODO remove dual storage
281
- .removeData( this.widgetName )
282
- .removeData( this.widgetFullName )
283
- // support: jquery <1.6.3
284
- // http://bugs.jquery.com/ticket/9413
285
- .removeData( $.camelCase( this.widgetFullName ) );
286
- this.widget()
287
- .unbind( this.eventNamespace )
288
- .removeAttr( "aria-disabled" )
289
- .removeClass(
290
- this.widgetFullName + "-disabled " +
291
- "ui-state-disabled" );
292
-
293
- // clean up events and states
294
- this.bindings.unbind( this.eventNamespace );
295
- this.hoverable.removeClass( "ui-state-hover" );
296
- this.focusable.removeClass( "ui-state-focus" );
297
- },
298
- _destroy: $.noop,
299
-
300
- widget: function() {
301
- return this.element;
302
- },
303
-
304
- option: function( key, value ) {
305
- var options = key,
306
- parts,
307
- curOption,
308
- i;
309
-
310
- if ( arguments.length === 0 ) {
311
- // don't return a reference to the internal hash
312
- return $.widget.extend( {}, this.options );
313
- }
314
-
315
- if ( typeof key === "string" ) {
316
- // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
317
- options = {};
318
- parts = key.split( "." );
319
- key = parts.shift();
320
- if ( parts.length ) {
321
- curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
322
- for ( i = 0; i < parts.length - 1; i++ ) {
323
- curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
324
- curOption = curOption[ parts[ i ] ];
325
- }
326
- key = parts.pop();
327
- if ( value === undefined ) {
328
- return curOption[ key ] === undefined ? null : curOption[ key ];
329
- }
330
- curOption[ key ] = value;
331
- } else {
332
- if ( value === undefined ) {
333
- return this.options[ key ] === undefined ? null : this.options[ key ];
334
- }
335
- options[ key ] = value;
336
- }
337
- }
338
-
339
- this._setOptions( options );
340
-
341
- return this;
342
- },
343
- _setOptions: function( options ) {
344
- var key;
345
-
346
- for ( key in options ) {
347
- this._setOption( key, options[ key ] );
348
- }
349
-
350
- return this;
351
- },
352
- _setOption: function( key, value ) {
353
- this.options[ key ] = value;
354
-
355
- if ( key === "disabled" ) {
356
- this.widget()
357
- .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
358
- .attr( "aria-disabled", value );
359
- this.hoverable.removeClass( "ui-state-hover" );
360
- this.focusable.removeClass( "ui-state-focus" );
361
- }
362
-
363
- return this;
364
- },
365
-
366
- enable: function() {
367
- return this._setOption( "disabled", false );
368
- },
369
- disable: function() {
370
- return this._setOption( "disabled", true );
371
- },
372
-
373
- _on: function( suppressDisabledCheck, element, handlers ) {
374
- var delegateElement,
375
- instance = this;
376
-
377
- // no suppressDisabledCheck flag, shuffle arguments
378
- if ( typeof suppressDisabledCheck !== "boolean" ) {
379
- handlers = element;
380
- element = suppressDisabledCheck;
381
- suppressDisabledCheck = false;
382
- }
383
-
384
- // no element argument, shuffle and use this.element
385
- if ( !handlers ) {
386
- handlers = element;
387
- element = this.element;
388
- delegateElement = this.widget();
389
- } else {
390
- // accept selectors, DOM elements
391
- element = delegateElement = $( element );
392
- this.bindings = this.bindings.add( element );
393
- }
394
-
395
- $.each( handlers, function( event, handler ) {
396
- function handlerProxy() {
397
- // allow widgets to customize the disabled handling
398
- // - disabled as an array instead of boolean
399
- // - disabled class as method for disabling individual parts
400
- if ( !suppressDisabledCheck &&
401
- ( instance.options.disabled === true ||
402
- $( this ).hasClass( "ui-state-disabled" ) ) ) {
403
- return;
404
- }
405
- return ( typeof handler === "string" ? instance[ handler ] : handler )
406
- .apply( instance, arguments );
407
- }
408
-
409
- // copy the guid so direct unbinding works
410
- if ( typeof handler !== "string" ) {
411
- handlerProxy.guid = handler.guid =
412
- handler.guid || handlerProxy.guid || $.guid++;
413
- }
414
-
415
- var match = event.match( /^(\w+)\s*(.*)$/ ),
416
- eventName = match[1] + instance.eventNamespace,
417
- selector = match[2];
418
- if ( selector ) {
419
- delegateElement.delegate( selector, eventName, handlerProxy );
420
- } else {
421
- element.bind( eventName, handlerProxy );
422
- }
423
- });
424
- },
425
-
426
- _off: function( element, eventName ) {
427
- eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
428
- element.unbind( eventName ).undelegate( eventName );
429
- },
430
-
431
- _delay: function( handler, delay ) {
432
- function handlerProxy() {
433
- return ( typeof handler === "string" ? instance[ handler ] : handler )
434
- .apply( instance, arguments );
435
- }
436
- var instance = this;
437
- return setTimeout( handlerProxy, delay || 0 );
438
- },
439
-
440
- _hoverable: function( element ) {
441
- this.hoverable = this.hoverable.add( element );
442
- this._on( element, {
443
- mouseenter: function( event ) {
444
- $( event.currentTarget ).addClass( "ui-state-hover" );
445
- },
446
- mouseleave: function( event ) {
447
- $( event.currentTarget ).removeClass( "ui-state-hover" );
448
- }
449
- });
450
- },
451
-
452
- _focusable: function( element ) {
453
- this.focusable = this.focusable.add( element );
454
- this._on( element, {
455
- focusin: function( event ) {
456
- $( event.currentTarget ).addClass( "ui-state-focus" );
457
- },
458
- focusout: function( event ) {
459
- $( event.currentTarget ).removeClass( "ui-state-focus" );
460
- }
461
- });
462
- },
463
-
464
- _trigger: function( type, event, data ) {
465
- var prop, orig,
466
- callback = this.options[ type ];
467
-
468
- data = data || {};
469
- event = $.Event( event );
470
- event.type = ( type === this.widgetEventPrefix ?
471
- type :
472
- this.widgetEventPrefix + type ).toLowerCase();
473
- // the original event may come from any element
474
- // so we need to reset the target on the new event
475
- event.target = this.element[ 0 ];
476
-
477
- // copy original event properties over to the new event
478
- orig = event.originalEvent;
479
- if ( orig ) {
480
- for ( prop in orig ) {
481
- if ( !( prop in event ) ) {
482
- event[ prop ] = orig[ prop ];
483
- }
484
- }
485
- }
486
-
487
- this.element.trigger( event, data );
488
- return !( $.isFunction( callback ) &&
489
- callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
490
- event.isDefaultPrevented() );
491
- }
492
- };
493
-
494
- $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
495
- $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
496
- if ( typeof options === "string" ) {
497
- options = { effect: options };
498
- }
499
- var hasOptions,
500
- effectName = !options ?
501
- method :
502
- options === true || typeof options === "number" ?
503
- defaultEffect :
504
- options.effect || defaultEffect;
505
- options = options || {};
506
- if ( typeof options === "number" ) {
507
- options = { duration: options };
508
- }
509
- hasOptions = !$.isEmptyObject( options );
510
- options.complete = callback;
511
- if ( options.delay ) {
512
- element.delay( options.delay );
513
- }
514
- if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
515
- element[ method ]( options );
516
- } else if ( effectName !== method && element[ effectName ] ) {
517
- element[ effectName ]( options.duration, options.easing, callback );
518
- } else {
519
- element.queue(function( next ) {
520
- $( this )[ method ]();
521
- if ( callback ) {
522
- callback.call( element[ 0 ] );
523
- }
524
- next();
525
- });
526
- }
527
- };
528
- });
529
-
530
- }));