assetable 0.1.10 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +8 -8
  2. data/README.rdoc +9 -7
  3. data/app/assets/javascripts/assetable/assetable.js.coffee +16 -0
  4. data/app/assets/javascripts/assetable/assetable_uploader.js.coffee +40 -118
  5. data/app/assets/javascripts/assetable/gallery.js.coffee +12 -10
  6. data/app/assets/javascripts/assetable/uploader.js.coffee +27 -11
  7. data/app/assets/javascripts/vendor/jquery-ui-1.10.3.custom.js +285 -19
  8. data/app/assets/stylesheets/assetable/components/_gallery.css.sass +31 -0
  9. data/app/assets/stylesheets/assetable/components/_uploader.css.sass +2 -2
  10. data/app/assets/stylesheets/assetable/core/_utilities.css.sass +5 -1
  11. data/app/controllers/assetable/assets_controller.rb +19 -10
  12. data/app/controllers/assetable/external_services_controller.rb +9 -5
  13. data/app/helpers/assetable/asset_helper.rb +7 -0
  14. data/app/inputs/gallery_input.rb +28 -0
  15. data/app/inputs/uploader_input.rb +24 -0
  16. data/app/models/asset_attachment.rb +27 -0
  17. data/app/models/gallery.rb +3 -1
  18. data/app/views/assetable/assets/_asset.html.haml +30 -21
  19. data/app/views/assetable/assets/_directions.html.haml +9 -0
  20. data/app/views/assetable/assets/_form.html.haml +3 -5
  21. data/app/views/assetable/assets/_table.html.haml +22 -0
  22. data/app/views/assetable/assets/create.js.erb +7 -0
  23. data/app/views/assetable/assets/edit.js.erb +1 -0
  24. data/app/views/assetable/assets/index.js.erb +18 -0
  25. data/app/views/assetable/assets/insert.js.erb +9 -0
  26. data/app/views/assetable/assets/update.js.erb +2 -0
  27. data/app/views/assetable/external_services/_form.html.haml +3 -2
  28. data/app/views/assetable/external_services/create.js.erb +9 -0
  29. data/app/views/assetable/external_services/new.js.erb +1 -0
  30. data/app/views/assetable/shared/_asset_preview.html.haml +21 -0
  31. data/app/views/assetable/shared/templates/_asset_item.html.haml +29 -0
  32. data/app/views/assetable/shared/templates/_gallery_item.html.haml +42 -0
  33. data/config/initializers/uploader_input.rb +1 -1
  34. data/config/routes.rb +3 -1
  35. data/db/migrate/20140220053656_add_sort_order_to_asset_attachments.rb +15 -0
  36. data/lib/assetable.rb +6 -3
  37. data/lib/assetable/{core.rb → active_record/base.rb} +2 -2
  38. data/lib/assetable/inputs/uploaders.rb +27 -0
  39. data/lib/assetable/version.rb +1 -1
  40. metadata +40 -10
  41. data/app/views/assetable/assets/edit.html.haml +0 -1
  42. data/app/views/assetable/external_services/new.html.haml +0 -1
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZTFjYWI5NzVhMGUzYjhiNjEzMDdmNzJkYmYzY2ZjZDQyMDQ4ZjY4OQ==
4
+ M2ZiYjc4YjE3M2Q5MmU4OWNlOTc3OGM2MWUzZThhMmUyOTNiOGUyZg==
5
5
  data.tar.gz: !binary |-
6
- YWM4OTJiYjY3NWNmODZiODdmNmI1NTZkN2Y1OTM1Y2RkOWY5YmQ4MA==
6
+ MmFmOWFmZDE5YTEwZTZlZTNhYzNiNGNjOWJmMDNkYTEyMGNmMjRlNA==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- YzljYzI4YzE2YWJhOGE1MWNlYTg5YmIxMWI2NmRiZWY1ZjU2YTA4OThmOGUx
10
- ZDZhZWU2MGYzYzE0NTVkODYwZmZlOWFkOGI4NjczMjFiYzc4NWI5Y2FkMTBm
11
- YjM0YzEyMzAxMWQ4MTkwNGVhM2FmOWQ2YmZjYWNhMjhiYWI1YTA=
9
+ YjlmODEyNDc5NTM5ZTk3NDE1NDEzNTlhN2QwZGIyNzE0YTI0MGQ0YmEwY2Uy
10
+ ZDc3Njk0NGRiNTZjZWM5MWQ0MWE3YTM0MjY3MTdhZDlhYWMwYmE5NTVlYWE3
11
+ NTQyZGQxMTdmZGZiYzA4YjMzNmQxNzMyMGQzNDhiNjQ4M2NmMDc=
12
12
  data.tar.gz: !binary |-
13
- ZTZiZGNiMWQyOGJiYzJhYTE3NjViNWI2OWFiYzYzNGI1NmM4OGI5ZmI0NTQx
14
- MzJkN2MwMGI0ZmZkYTY1MWNlZGZiODJiNTk5ZDQzYTI1MjE1ZTliYjlkMjk0
15
- ZjBlMzdjMzVlYTdjYmZiNGExZjRlZGNhMTg0MDVlMTE4N2FiY2E=
13
+ YjliMzQ3MDljMzdlZGM3MjgwNWU3MzVmY2ZhNGEwN2QzYjRhZTg0Y2M0NzU4
14
+ Y2UzNDUxMWE3MjFlNWVkN2RjOGIzZDkzM2VhN2MwYzgxYWYzNGFkOThlYjJl
15
+ YjY4Y2I0OWRlZDMzYzJhNmI3YTU4MTllNTg1MTM2NTdjMzA2NTU=
@@ -1,6 +1,8 @@
1
1
  = Assetable
2
2
 
3
- Easily add Assets to your Active Record models, including images, videos and almost any kind of documents. Includes an uploader, media gallery and much more.
3
+ Easily add Assets to your Rails app, including images, videos and almost any kind of documents. Includes an uploader, media gallery and much more.
4
+
5
+ This is still an early beta release. While the majority of uploading works, the media gallery selector is still in an early alpha.
4
6
 
5
7
  === Installation
6
8
 
@@ -8,7 +10,7 @@ Easily add Assets to your Active Record models, including images, videos and alm
8
10
 
9
11
  Add this line to your application's Gemfile:
10
12
 
11
- gem 'bootstrap_sass_rails'
13
+ gem 'assetable'
12
14
 
13
15
  And then execute:
14
16
 
@@ -16,7 +18,7 @@ And then execute:
16
18
 
17
19
  Or install it yourself as:
18
20
 
19
- $ gem install bootstrap_sass_rails
21
+ $ gem install assetable
20
22
 
21
23
 
22
24
  ==== Migrations
@@ -38,7 +40,7 @@ Add the Stylesheet and Javascripts to your project:
38
40
 
39
41
  Javascript:
40
42
 
41
- //= import uploader
43
+ //= require assetable/assetable
42
44
 
43
45
 
44
46
  ==== Configuration
@@ -152,12 +154,12 @@ In order to start uploading assets, you'll need to add the uploader to your form
152
154
 
153
155
  = form_for @user do |f|
154
156
  ...
155
- = f.uploader :avatar
157
+ = f.input :avatar, as: :uploader
156
158
  ...
157
159
 
158
160
  # You can also pass typical params to the uploader
159
161
  = form_for @user do |f|
160
- = f.uploader :avatar, class: "classname", id: "something-else"
162
+ = f.inputer :avatar, as: :uploader, input_html: { class: "classname", id: "something-else" }
161
163
 
162
164
  Make sure the assetable uploader javascript is added.
163
165
 
@@ -166,7 +168,7 @@ Make sure the assetable uploader javascript is added.
166
168
 
167
169
  = form_for @user do |f|
168
170
  ...
169
- = f.gallery :gallery
171
+ = f.input :gallery, as: :gallery
170
172
  ...
171
173
 
172
174
  It's that easy!
@@ -0,0 +1,16 @@
1
+ #= require_self
2
+
3
+ #= require moxie
4
+ #= require plupload.dev
5
+ #= require plupload.settings
6
+ #= require jquery.plupload.queue
7
+ #= require vendor/jquery-ui-1.10.3.custom
8
+ #= require vendor/bootstrap-modal
9
+
10
+
11
+ #= require assetable/assetable_uploader
12
+ #= require assetable/uploader
13
+ #= require assetable/gallery
14
+ #= require assetable/asset_gallery
15
+
16
+ window.Assetable = {}
@@ -19,37 +19,47 @@
19
19
  max_file_count: 0
20
20
  unique_names: true
21
21
  url: null
22
+ uploader_id: null
22
23
 
23
24
  assetable_uploader = this
24
25
 
25
26
  init = ->
26
27
  # merge the options with the defaults
27
28
  assetable_uploader.options = jQuery.extend({}, defaults, options)
28
- assetable_uploader.id = assetable_uploader.attr('id')
29
+
30
+ hidden_field = $(assetable_uploader).find('input[type="hidden"].assetable-uploader-input')
31
+ assetable_uploader.options.fieldname = hidden_field.attr('name')
32
+ assetable_uploader.options.uploader_id = hidden_field.attr('id')
33
+ $(hidden_field, assetable_uploader).remove() if assetable_uploader.options.gallery
34
+
35
+ $(assetable_uploader).attr('id', assetable_uploader.options.uploader_id)
36
+ $(assetable_uploader).find('.browse-btn').attr('id', "#{assetable_uploader.options.uploader_id}-browse-btn")
37
+ $(assetable_uploader).find('.drop-element').attr('id', "#{assetable_uploader.options.uploader_id}-drop-element")
38
+
39
+ # Add parameters to third party button
40
+ third_party_btn = $(assetable_uploader).find('.btn-third-party')
41
+ $(third_party_btn).attr('href', $(third_party_btn).attr('href') + "?fieldname=#{assetable_uploader.options.fieldname}&uploader_id=#{assetable_uploader.options.uploader_id}")
42
+
29
43
  bind_uploader()
30
44
 
31
45
 
32
46
  bind_uploader = ->
33
47
 
34
48
  # Create our extra HTML for the copy and queu
35
- # upload_directions = '<div class="uploader-directions" id="' + assetable_uploader.id + '-drop-area"><div class="uploader-directions-image"></div><div class="uploader-directions-copy">Drag and drop files or <a href="#" class="browse-btn" id="' + assetable_uploader.id + '-browse-btn">add them manually</a></div></div>'
36
- # upload_directions = '<div class="uploader-directions" id="' + assetable_uploader.id + '-drop-area"><div class="uploader-directions-image"></div><div class="uploader-directions-copy"><a href="#" class="browse-btn" id="' + assetable_uploader.id + '-browse-btn">select file</a> or <a href="#" class="btn-open-asset-gallery">open gallery</a></div></div>'
37
- upload_directions = '<div class="uploader-directions" id="' + assetable_uploader.id + '-drop-area"><div class="uploader-directions-image"></div><div class="uploader-directions-copy"><a href="#" class="browse-btn" id="' + assetable_uploader.id + '-browse-btn">select file</a> ' + assetable_uploader.options.directions + '</div></div>'
38
49
  upload_queue = '<ul class="upload-queue"></ul>'
39
50
  # Add to the uploader
40
- $(assetable_uploader).append(upload_directions)
41
51
  $(assetable_uploader).append(upload_queue)
42
52
 
43
53
 
44
54
  # Instantiate the uploader
45
55
  uploader = new plupload.Uploader(
46
56
  runtimes: "html5"
47
- browse_button: "#{assetable_uploader.id}-browse-btn"
57
+ browse_button: "#{assetable_uploader.options.uploader_id}-browse-btn"
48
58
  url: assetable_uploader.options.url
49
59
  max_file_size: assetable_uploader.options.max_file_size
50
60
  unique_names: assetable_uploader.options.unique_names
51
61
  dragdrop: assetable_uploader.options.drag_drop
52
- drop_element: assetable_uploader.id
62
+ drop_element: assetable_uploader.options.uploader_id
53
63
  multiple_queues: assetable_uploader.options.multiple_queues
54
64
  multi_selection: assetable_uploader.options.multi_selection
55
65
  max_file_count: assetable_uploader.options.max_file_count
@@ -57,27 +67,26 @@
57
67
  multipart_params:
58
68
  authenticity_token: assetable_uploader.options.authenticity_token
59
69
  fieldname: assetable_uploader.options.fieldname
70
+ gallery: assetable_uploader.options.gallery
71
+ uploader_id: assetable_uploader.options.uploader_id
60
72
 
61
73
  # Filter file types
62
- # filter: [
63
- # title: "Image files"
64
- # extensions: "jpg,gif,png"
65
- # ,
66
- # title: "Video files"
67
- # extensions: "mov,mp4,mpeg4"
68
- # ]
74
+ filters:
75
+ mime_types : [
76
+ title: "Image files"
77
+ extensions: "jpg,gif,png"
78
+ ,
79
+ title: "Video files"
80
+ extensions: "mov,mp4,mpeg4"
81
+ ,
82
+ title: "Zip Files"
83
+ extensions: "zip"
84
+ ]
85
+ max_file_size: assetable_uploader.options.max_file_size
86
+ prevent_duplicates: true
69
87
  )
70
88
 
71
89
 
72
-
73
- # # Uploader Template
74
- # template = "<div class=\"current_preview current_" + uploader_id + "\">" + content + "</div>" + "<div class=\"koh_pluploader\" id=\"" + uploader_id + "_drop_area\">" + "<a id=\"" + uploader_id + "_browse_btn\" href=\"#\"><span class=\"link_color\">Attach files by dragging & dropping them here</span> or add them manually</a>" + "<ul class=\"upload_queue\"></ul>" + "</div>" + ((if allow_select_mg then "<a href=\"#\" class=\"attach_image\" uid=\"" + uploader_id + "\" target=\"" + container + "\">select from media gallery</a>" else ""))
75
-
76
- # # Initialize binding
77
- # uploader.bind "Init", (up, params) ->
78
- # $("#" + container).html template
79
-
80
-
81
90
  # # Initiate the uploader
82
91
  uploader.init()
83
92
 
@@ -94,9 +103,7 @@
94
103
 
95
104
  # Listen for upload complete
96
105
  uploader.bind "FileUploaded", (up, file, info) ->
97
- if assetable_uploader.options.FileUploaded
98
- json = jQuery.parseJSON(info.response)
99
- assetable_uploader.options.FileUploaded json
106
+ eval(info.response)
100
107
  $("li#" + file.id, assetable_uploader).fadeOut().remove()
101
108
 
102
109
 
@@ -104,10 +111,11 @@
104
111
  uploader.bind "QueueChanged", (up, files) ->
105
112
  uploader.start()
106
113
  up.refresh()
114
+
107
115
  # # Listen for errors
108
- # uploader.bind "Error", (up, err) ->
109
- # $("#" + container).append "<div class=\"notice error\">" + "<span class=\"block\">Error: " + err.code + "</div>" + "<span class=\"block\">Message: " + err.message + "</div>" + ((if err.file then "<span clas=\"block\">" + err.file.name + "</span>" else "")) + "</div>"
110
- # up.refresh() # Reposition Flash/Silverlight
116
+ uploader.bind "Error", (up, err) ->
117
+
118
+
111
119
 
112
120
  draggable_selector = (if assetable_uploader.options.gallery then $('.uploader-directions', assetable_uploader) else $(assetable_uploader))
113
121
 
@@ -132,27 +140,8 @@
132
140
  $(assetable_uploader).on "click", ".btn-uploader-remove-asset", (e)->
133
141
  e.preventDefault()
134
142
  if assetable_uploader.options.fileRemoved
135
- assetable_uploader.options.fileRemoved this, assetable_uploader
136
-
137
-
138
- $(assetable_uploader).on "click", ".btn-uploader-edit-asset", (e)->
139
- e.preventDefault()
140
- $.ajax
141
- url: $(this).attr('href')
142
- data: {fieldname: assetable_uploader.options.fieldname}
143
- type: 'GET'
143
+ assetable_uploader.options.fileRemoved assetable_uploader, this
144
144
 
145
- success: (response)->
146
- $response = $(response)
147
- $response.modal()
148
-
149
- $('form.form-edit-asset').on 'ajax:beforeSend', ()->
150
- # console.log "form submitting..."
151
-
152
- $('form.form-edit-asset').on 'ajax:success', (data, status, xhr)->
153
- if status.success
154
- $response.modal('hide').remove()
155
- assetable_uploader.options.fileUpdated status
156
145
 
157
146
 
158
147
  $(assetable_uploader).on "click", ".btn-open-asset-gallery", (e)->
@@ -161,75 +150,8 @@
161
150
  # if assetable_uploader.options.openAssetGallery
162
151
  # assetable_uploader.options.openAssetGallery this, assetable_uploader
163
152
 
164
- # $(assetable_uploader).on "click", ".btn-third-party-service", (e)->
165
- # e.preventDefault()
166
- # console.log "boom"
167
-
168
-
169
- # Add a third party service
170
- $(assetable_uploader).on "click", ".btn-third-party-service", (e)->
171
- e.preventDefault()
172
- $.ajax
173
- url: $(this).attr('href')
174
- data: {fieldname: assetable_uploader.options.fieldname}
175
- type: 'GET'
176
-
177
- success: (response)->
178
- $response = $(response)
179
- $response.modal()
180
-
181
- $('form#new_external_service').on 'ajax:beforeSend', ()->
182
- # console.log "form submitting..."
183
-
184
- $('form#new_external_service').on 'ajax:success', (data, status, xhr)->
185
- if status.success
186
- $response.modal('hide').remove()
187
- assetable_uploader.options.FileUploaded status
188
-
189
-
190
-
191
-
153
+
192
154
 
193
155
  init()
194
156
 
195
- ) jQuery
196
-
197
-
198
-
199
-
200
- bind_uploaders = ->
201
- # Bind the koh uploader and galleries to a page
202
- $(".uploader").each ->
203
- # Check that it's not already bound
204
- unless $(this).hasClass("uploadable")
205
- $(this).addClass "uploadable"
206
- $this = $(this)
207
- $this.removeClass "uploader"
208
-
209
- field = $this.attr("data-uploader-input-name")
210
-
211
- $this.assetable_uploader
212
- multi_selection: false
213
- url: "/assetable/assets"
214
- fieldname: field
215
- directions: $this.attr('data-uploader-directions')
216
- max_file_size: $this.attr("data-max-file-size")
217
- authenticity_token: $("meta[name=\"csrf-token\"]").attr("content")
218
- onUploaded: (resp) ->
219
- $this.find('.uploader-data-wrapper').html(resp.html)
220
- $this.addClass("uploader-has-asset")
221
- fileRemoved: (button, item) ->
222
- return false unless $(item).hasClass("uploader-has-asset")
223
- $('.uploader-preview', item).html('<input type="hidden" name="' + field + '" />')
224
- $(item).removeClass("uploader-has-asset")
225
- fileUpdated: (resp) ->
226
- $this.find('div.uploader-preview[data-asset-id="' + resp.id + '"]').replaceWith(resp.html)
227
- # openAssetGallery: (button, item) ->
228
-
229
-
230
-
231
- window.Assetable.bind_uploaders = bind_uploaders
232
-
233
- $(document).ready ->
234
-
235
- window.Assetable.bind_uploaders()
157
+ ) jQuery
@@ -1,4 +1,5 @@
1
1
  bind_galleries = ->
2
+
2
3
  # Bind the koh uploader and galleries to a page
3
4
  $(".gallery-uploader").each ->
4
5
  # Check that it's not already bound
@@ -6,21 +7,16 @@ bind_galleries = ->
6
7
  $(this).addClass "uploadable"
7
8
  $this = $(this)
8
9
  $this.removeClass "uploader"
9
-
10
- field = $this.attr("data-uploader-input-name")
11
10
 
12
11
  $this.assetable_uploader
13
12
  multi_selection: true
14
13
  gallery: true
15
- url: "/assetable/assets"
16
- fieldname: field
14
+ url: "/assetable/assets.js"
17
15
  authenticity_token: $("meta[name=\"csrf-token\"]").attr("content")
18
- onUploaded: (resp) ->
19
- $this.find('.uploader-data-wrapper').append(resp.html)
20
- fileRemoved: (button, item) ->
21
- $(button).closest('.uploader-preview').remove()
22
- fileUpdated: (resp) ->
23
- $this.find('div.uploader-preview[data-asset-id="' + resp.id + '"]').replaceWith(resp.html)
16
+ fileRemoved: (item, button) ->
17
+ $(button).parentsUntil('.uploader-preview').parent().find('.assetable-gallery-item-remove').val('1')
18
+ $(button).parentsUntil('.uploader-preview').parent().fadeOut()
19
+
24
20
 
25
21
  # Make the gallery sortable
26
22
  $(this).sortable
@@ -28,10 +24,16 @@ bind_galleries = ->
28
24
  distance: 50
29
25
  tolerance: 'pointer'
30
26
  placeholder: 'uploader-sortable-placeholder'
27
+ update: (event, ui) ->
28
+ $gallery = $(this)
29
+
30
+ $('input.assetable-gallery-item-sort-order', $gallery).each (index) ->
31
+ $(this).val(index)
31
32
 
32
33
 
33
34
  window.Assetable.bind_galleries = bind_galleries
34
35
 
36
+
35
37
  $(document).ready ->
36
38
 
37
39
  window.Assetable.bind_galleries()
@@ -1,14 +1,30 @@
1
- #= require_self
1
+ bind_uploaders = ->
2
2
 
3
- #= require moxie
4
- #= require plupload.dev
5
- #= require plupload.settings
6
- #= require jquery.plupload.queue
7
- #= require vendor/jquery-ui-1.10.3.custom
8
- #= require vendor/bootstrap-modal
3
+ $('.assetable-uploader').each ->
4
+ unless $(this).hasClass("uploadable")
5
+ $(this).addClass "uploadable"
6
+ $this = $(this)
7
+ $this.removeClass "assetable-uploader"
9
8
 
10
- #= require assetable/assetable_uploader
11
- #= require assetable/gallery
12
- #= require assetable/asset_gallery
9
+ $this.assetable_uploader
10
+ multi_selection: false
11
+ url: "/assetable/assets.js"
12
+ # directions: $this.attr('data-uploader-directions')
13
+ # max_file_size: $this.attr("data-max-file-size")
14
+ authenticity_token: $("meta[name=\"csrf-token\"]").attr("content")
15
+ fileRemoved: (item, button) ->
16
+ # Remove the asset preview and input when removed. No need
17
+ # to add an empty input as one already exists in the DOM
18
+ $('.uploader-preview', item).html('')
13
19
 
14
- window.Assetable = {}
20
+
21
+ window.Assetable.bind_uploaders = bind_uploaders
22
+
23
+ $(document).ready ->
24
+
25
+ window.Assetable.bind_uploaders()
26
+
27
+ # Remove assetable modals on close
28
+ $(document).on "hidden.bs.modal", ".assetable-modal", ->
29
+ $(this).remove()
30
+ return
@@ -1,7 +1,7 @@
1
- /*! jQuery UI - v1.10.3 - 2013-12-03
1
+ /*! jQuery UI - v1.10.4 - 2014-02-17
2
2
  * http://jqueryui.com
3
- * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.sortable.js
4
- * Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
3
+ * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.selectable.js, jquery.ui.sortable.js
4
+ * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
5
5
 
6
6
  (function( $, undefined ) {
7
7
 
@@ -12,7 +12,7 @@ var uuid = 0,
12
12
  $.ui = $.ui || {};
13
13
 
14
14
  $.extend( $.ui, {
15
- version: "1.10.3",
15
+ version: "1.10.4",
16
16
 
17
17
  keyCode: {
18
18
  BACKSPACE: 8,
@@ -411,7 +411,7 @@ $.widget = function( name, base, prototype ) {
411
411
  // TODO: remove support for widgetEventPrefix
412
412
  // always use the name + a colon as the prefix, e.g., draggable:start
413
413
  // don't prefix for widgets that aren't DOM-based
414
- widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
414
+ widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
415
415
  }, proxiedPrototype, {
416
416
  constructor: constructor,
417
417
  namespace: namespace,
@@ -620,12 +620,12 @@ $.Widget.prototype = {
620
620
  curOption = curOption[ parts[ i ] ];
621
621
  }
622
622
  key = parts.pop();
623
- if ( value === undefined ) {
623
+ if ( arguments.length === 1 ) {
624
624
  return curOption[ key ] === undefined ? null : curOption[ key ];
625
625
  }
626
626
  curOption[ key ] = value;
627
627
  } else {
628
- if ( value === undefined ) {
628
+ if ( arguments.length === 1 ) {
629
629
  return this.options[ key ] === undefined ? null : this.options[ key ];
630
630
  }
631
631
  options[ key ] = value;
@@ -832,7 +832,7 @@ $( document ).mouseup( function() {
832
832
  });
833
833
 
834
834
  $.widget("ui.mouse", {
835
- version: "1.10.3",
835
+ version: "1.10.4",
836
836
  options: {
837
837
  cancel: "input,textarea,button,select,option",
838
838
  distance: 1,
@@ -982,7 +982,267 @@ $.widget("ui.mouse", {
982
982
  })(jQuery);
983
983
  (function( $, undefined ) {
984
984
 
985
- /*jshint loopfunc: true */
985
+ $.widget("ui.selectable", $.ui.mouse, {
986
+ version: "1.10.4",
987
+ options: {
988
+ appendTo: "body",
989
+ autoRefresh: true,
990
+ distance: 0,
991
+ filter: "*",
992
+ tolerance: "touch",
993
+
994
+ // callbacks
995
+ selected: null,
996
+ selecting: null,
997
+ start: null,
998
+ stop: null,
999
+ unselected: null,
1000
+ unselecting: null
1001
+ },
1002
+ _create: function() {
1003
+ var selectees,
1004
+ that = this;
1005
+
1006
+ this.element.addClass("ui-selectable");
1007
+
1008
+ this.dragged = false;
1009
+
1010
+ // cache selectee children based on filter
1011
+ this.refresh = function() {
1012
+ selectees = $(that.options.filter, that.element[0]);
1013
+ selectees.addClass("ui-selectee");
1014
+ selectees.each(function() {
1015
+ var $this = $(this),
1016
+ pos = $this.offset();
1017
+ $.data(this, "selectable-item", {
1018
+ element: this,
1019
+ $element: $this,
1020
+ left: pos.left,
1021
+ top: pos.top,
1022
+ right: pos.left + $this.outerWidth(),
1023
+ bottom: pos.top + $this.outerHeight(),
1024
+ startselected: false,
1025
+ selected: $this.hasClass("ui-selected"),
1026
+ selecting: $this.hasClass("ui-selecting"),
1027
+ unselecting: $this.hasClass("ui-unselecting")
1028
+ });
1029
+ });
1030
+ };
1031
+ this.refresh();
1032
+
1033
+ this.selectees = selectees.addClass("ui-selectee");
1034
+
1035
+ this._mouseInit();
1036
+
1037
+ this.helper = $("<div class='ui-selectable-helper'></div>");
1038
+ },
1039
+
1040
+ _destroy: function() {
1041
+ this.selectees
1042
+ .removeClass("ui-selectee")
1043
+ .removeData("selectable-item");
1044
+ this.element
1045
+ .removeClass("ui-selectable ui-selectable-disabled");
1046
+ this._mouseDestroy();
1047
+ },
1048
+
1049
+ _mouseStart: function(event) {
1050
+ var that = this,
1051
+ options = this.options;
1052
+
1053
+ this.opos = [event.pageX, event.pageY];
1054
+
1055
+ if (this.options.disabled) {
1056
+ return;
1057
+ }
1058
+
1059
+ this.selectees = $(options.filter, this.element[0]);
1060
+
1061
+ this._trigger("start", event);
1062
+
1063
+ $(options.appendTo).append(this.helper);
1064
+ // position helper (lasso)
1065
+ this.helper.css({
1066
+ "left": event.pageX,
1067
+ "top": event.pageY,
1068
+ "width": 0,
1069
+ "height": 0
1070
+ });
1071
+
1072
+ if (options.autoRefresh) {
1073
+ this.refresh();
1074
+ }
1075
+
1076
+ this.selectees.filter(".ui-selected").each(function() {
1077
+ var selectee = $.data(this, "selectable-item");
1078
+ selectee.startselected = true;
1079
+ if (!event.metaKey && !event.ctrlKey) {
1080
+ selectee.$element.removeClass("ui-selected");
1081
+ selectee.selected = false;
1082
+ selectee.$element.addClass("ui-unselecting");
1083
+ selectee.unselecting = true;
1084
+ // selectable UNSELECTING callback
1085
+ that._trigger("unselecting", event, {
1086
+ unselecting: selectee.element
1087
+ });
1088
+ }
1089
+ });
1090
+
1091
+ $(event.target).parents().addBack().each(function() {
1092
+ var doSelect,
1093
+ selectee = $.data(this, "selectable-item");
1094
+ if (selectee) {
1095
+ doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
1096
+ selectee.$element
1097
+ .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
1098
+ .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
1099
+ selectee.unselecting = !doSelect;
1100
+ selectee.selecting = doSelect;
1101
+ selectee.selected = doSelect;
1102
+ // selectable (UN)SELECTING callback
1103
+ if (doSelect) {
1104
+ that._trigger("selecting", event, {
1105
+ selecting: selectee.element
1106
+ });
1107
+ } else {
1108
+ that._trigger("unselecting", event, {
1109
+ unselecting: selectee.element
1110
+ });
1111
+ }
1112
+ return false;
1113
+ }
1114
+ });
1115
+
1116
+ },
1117
+
1118
+ _mouseDrag: function(event) {
1119
+
1120
+ this.dragged = true;
1121
+
1122
+ if (this.options.disabled) {
1123
+ return;
1124
+ }
1125
+
1126
+ var tmp,
1127
+ that = this,
1128
+ options = this.options,
1129
+ x1 = this.opos[0],
1130
+ y1 = this.opos[1],
1131
+ x2 = event.pageX,
1132
+ y2 = event.pageY;
1133
+
1134
+ if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
1135
+ if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
1136
+ this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
1137
+
1138
+ this.selectees.each(function() {
1139
+ var selectee = $.data(this, "selectable-item"),
1140
+ hit = false;
1141
+
1142
+ //prevent helper from being selected if appendTo: selectable
1143
+ if (!selectee || selectee.element === that.element[0]) {
1144
+ return;
1145
+ }
1146
+
1147
+ if (options.tolerance === "touch") {
1148
+ hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
1149
+ } else if (options.tolerance === "fit") {
1150
+ hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
1151
+ }
1152
+
1153
+ if (hit) {
1154
+ // SELECT
1155
+ if (selectee.selected) {
1156
+ selectee.$element.removeClass("ui-selected");
1157
+ selectee.selected = false;
1158
+ }
1159
+ if (selectee.unselecting) {
1160
+ selectee.$element.removeClass("ui-unselecting");
1161
+ selectee.unselecting = false;
1162
+ }
1163
+ if (!selectee.selecting) {
1164
+ selectee.$element.addClass("ui-selecting");
1165
+ selectee.selecting = true;
1166
+ // selectable SELECTING callback
1167
+ that._trigger("selecting", event, {
1168
+ selecting: selectee.element
1169
+ });
1170
+ }
1171
+ } else {
1172
+ // UNSELECT
1173
+ if (selectee.selecting) {
1174
+ if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
1175
+ selectee.$element.removeClass("ui-selecting");
1176
+ selectee.selecting = false;
1177
+ selectee.$element.addClass("ui-selected");
1178
+ selectee.selected = true;
1179
+ } else {
1180
+ selectee.$element.removeClass("ui-selecting");
1181
+ selectee.selecting = false;
1182
+ if (selectee.startselected) {
1183
+ selectee.$element.addClass("ui-unselecting");
1184
+ selectee.unselecting = true;
1185
+ }
1186
+ // selectable UNSELECTING callback
1187
+ that._trigger("unselecting", event, {
1188
+ unselecting: selectee.element
1189
+ });
1190
+ }
1191
+ }
1192
+ if (selectee.selected) {
1193
+ if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
1194
+ selectee.$element.removeClass("ui-selected");
1195
+ selectee.selected = false;
1196
+
1197
+ selectee.$element.addClass("ui-unselecting");
1198
+ selectee.unselecting = true;
1199
+ // selectable UNSELECTING callback
1200
+ that._trigger("unselecting", event, {
1201
+ unselecting: selectee.element
1202
+ });
1203
+ }
1204
+ }
1205
+ }
1206
+ });
1207
+
1208
+ return false;
1209
+ },
1210
+
1211
+ _mouseStop: function(event) {
1212
+ var that = this;
1213
+
1214
+ this.dragged = false;
1215
+
1216
+ $(".ui-unselecting", this.element[0]).each(function() {
1217
+ var selectee = $.data(this, "selectable-item");
1218
+ selectee.$element.removeClass("ui-unselecting");
1219
+ selectee.unselecting = false;
1220
+ selectee.startselected = false;
1221
+ that._trigger("unselected", event, {
1222
+ unselected: selectee.element
1223
+ });
1224
+ });
1225
+ $(".ui-selecting", this.element[0]).each(function() {
1226
+ var selectee = $.data(this, "selectable-item");
1227
+ selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
1228
+ selectee.selecting = false;
1229
+ selectee.selected = true;
1230
+ selectee.startselected = true;
1231
+ that._trigger("selected", event, {
1232
+ selected: selectee.element
1233
+ });
1234
+ });
1235
+ this._trigger("stop", event);
1236
+
1237
+ this.helper.remove();
1238
+
1239
+ return false;
1240
+ }
1241
+
1242
+ });
1243
+
1244
+ })(jQuery);
1245
+ (function( $, undefined ) {
986
1246
 
987
1247
  function isOverAxis( x, reference, size ) {
988
1248
  return ( x > reference ) && ( x < ( reference + size ) );
@@ -993,7 +1253,7 @@ function isFloating(item) {
993
1253
  }
994
1254
 
995
1255
  $.widget("ui.sortable", $.ui.mouse, {
996
- version: "1.10.3",
1256
+ version: "1.10.4",
997
1257
  widgetEventPrefix: "sort",
998
1258
  ready: false,
999
1259
  options: {
@@ -1334,12 +1594,12 @@ $.widget("ui.sortable", $.ui.mouse, {
1334
1594
  }
1335
1595
 
1336
1596
  // Only put the placeholder inside the current Container, skip all
1337
- // items form other containers. This works because when moving
1597
+ // items from other containers. This works because when moving
1338
1598
  // an item from one container to another the
1339
1599
  // currentContainer is switched before the placeholder is moved.
1340
1600
  //
1341
- // Without this moving items in "sub-sortables" can cause the placeholder to jitter
1342
- // beetween the outer and inner container.
1601
+ // Without this, moving items in "sub-sortables" can cause
1602
+ // the placeholder to jitter beetween the outer and inner container.
1343
1603
  if (item.instance !== this.currentContainer) {
1344
1604
  continue;
1345
1605
  }
@@ -1607,10 +1867,11 @@ $.widget("ui.sortable", $.ui.mouse, {
1607
1867
 
1608
1868
  queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
1609
1869
 
1870
+ function addItems() {
1871
+ items.push( this );
1872
+ }
1610
1873
  for (i = queries.length - 1; i >= 0; i--){
1611
- queries[i][0].each(function() {
1612
- items.push(this);
1613
- });
1874
+ queries[i][0].each( addItems );
1614
1875
  }
1615
1876
 
1616
1877
  return $(items);
@@ -2168,12 +2429,17 @@ $.widget("ui.sortable", $.ui.mouse, {
2168
2429
 
2169
2430
 
2170
2431
  //Post events to containers
2432
+ function delayEvent( type, instance, container ) {
2433
+ return function( event ) {
2434
+ container._trigger( type, event, instance._uiHash( instance ) );
2435
+ };
2436
+ }
2171
2437
  for (i = this.containers.length - 1; i >= 0; i--){
2172
- if(!noPropagation) {
2173
- delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
2438
+ if (!noPropagation) {
2439
+ delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
2174
2440
  }
2175
2441
  if(this.containers[i].containerCache.over) {
2176
- delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
2442
+ delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
2177
2443
  this.containers[i].containerCache.over = 0;
2178
2444
  }
2179
2445
  }