asset_host_core 2.0.0.beta

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 (199) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.markdown +138 -0
  3. data/Rakefile +11 -0
  4. data/app/assets/images/asset_host_core/alert-overlay.png +0 -0
  5. data/app/assets/images/asset_host_core/arrow-left.gif +0 -0
  6. data/app/assets/images/asset_host_core/arrow-right.gif +0 -0
  7. data/app/assets/images/asset_host_core/fallback-img-rect.png +0 -0
  8. data/app/assets/images/asset_host_core/videoplayer-play.png +0 -0
  9. data/app/assets/images/asset_host_core/x.png +0 -0
  10. data/app/assets/javascripts/asset_host_core/admin/assets.js.coffee +221 -0
  11. data/app/assets/javascripts/asset_host_core/application.js +20 -0
  12. data/app/assets/javascripts/asset_host_core/assetadmin.js.coffee +56 -0
  13. data/app/assets/javascripts/asset_host_core/assethost.js.coffee.erb +17 -0
  14. data/app/assets/javascripts/asset_host_core/browserui.js.coffee +139 -0
  15. data/app/assets/javascripts/asset_host_core/chooserui.js.coffee +381 -0
  16. data/app/assets/javascripts/asset_host_core/client.js.coffee +29 -0
  17. data/app/assets/javascripts/asset_host_core/clients/BrightcoveVideo.js.coffee +64 -0
  18. data/app/assets/javascripts/asset_host_core/clients/templates/brightcove_embed.jst.eco +18 -0
  19. data/app/assets/javascripts/asset_host_core/clients/templates/vimeo_embed.jst.eco +1 -0
  20. data/app/assets/javascripts/asset_host_core/clients/templates/youtube_embed.jst.eco +1 -0
  21. data/app/assets/javascripts/asset_host_core/clients/vimeo_video.js.coffee +21 -0
  22. data/app/assets/javascripts/asset_host_core/clients/youtube_video.js.coffee +21 -0
  23. data/app/assets/javascripts/asset_host_core/cmsplugin.js.coffee +235 -0
  24. data/app/assets/javascripts/asset_host_core/models.js.coffee +586 -0
  25. data/app/assets/javascripts/asset_host_core/railsCMS.js.coffee +141 -0
  26. data/app/assets/javascripts/asset_host_core/slideshow.js.coffee +428 -0
  27. data/app/assets/javascripts/asset_host_core/templates/after_upload_button.jst.eco +3 -0
  28. data/app/assets/javascripts/asset_host_core/templates/asset_drop_asset.jst.eco +4 -0
  29. data/app/assets/javascripts/asset_host_core/templates/asset_modal.jst.eco +13 -0
  30. data/app/assets/javascripts/asset_host_core/templates/asset_preview.jst.eco +35 -0
  31. data/app/assets/javascripts/asset_host_core/templates/asset_search.jst.eco +2 -0
  32. data/app/assets/javascripts/asset_host_core/templates/browser_asset.jst.eco +1 -0
  33. data/app/assets/javascripts/asset_host_core/templates/browser_asset_tip.jst.eco +3 -0
  34. data/app/assets/javascripts/asset_host_core/templates/edit_modal.jst.eco +40 -0
  35. data/app/assets/javascripts/asset_host_core/templates/import_help.jst.eco +59 -0
  36. data/app/assets/javascripts/asset_host_core/templates/pagination_link.jst.eco +1 -0
  37. data/app/assets/javascripts/asset_host_core/templates/pagination_links.jst.eco +13 -0
  38. data/app/assets/javascripts/asset_host_core/templates/queued_file.jst.eco +11 -0
  39. data/app/assets/javascripts/asset_host_core/templates/save_and_close_view.jst.eco +4 -0
  40. data/app/assets/javascripts/asset_host_core/templates/upload_all_button.jst.eco +4 -0
  41. data/app/assets/javascripts/asset_host_core/templates/url_input.jst.eco +8 -0
  42. data/app/assets/stylesheets/asset_host_core/application.css.scss +384 -0
  43. data/app/assets/stylesheets/asset_host_core/jquery-ui.css +105 -0
  44. data/app/assets/stylesheets/asset_host_core/public.css.scss +204 -0
  45. data/app/assets/stylesheets/asset_host_core/slidetest.css.scss +93 -0
  46. data/app/controllers/asset_host_core/admin/api_users_controller.rb +72 -0
  47. data/app/controllers/asset_host_core/admin/assets_controller.rb +140 -0
  48. data/app/controllers/asset_host_core/admin/base_controller.rb +36 -0
  49. data/app/controllers/asset_host_core/admin/home_controller.rb +13 -0
  50. data/app/controllers/asset_host_core/admin/outputs_controller.rb +55 -0
  51. data/app/controllers/asset_host_core/api/assets_controller.rb +110 -0
  52. data/app/controllers/asset_host_core/api/base_controller.rb +43 -0
  53. data/app/controllers/asset_host_core/api/outputs_controller.rb +33 -0
  54. data/app/controllers/asset_host_core/application_controller.rb +43 -0
  55. data/app/controllers/asset_host_core/public_controller.rb +104 -0
  56. data/app/models/asset_host_core/api_user.rb +44 -0
  57. data/app/models/asset_host_core/api_user_permission.rb +6 -0
  58. data/app/models/asset_host_core/asset.rb +265 -0
  59. data/app/models/asset_host_core/asset_output.rb +69 -0
  60. data/app/models/asset_host_core/brightcove_video.rb +20 -0
  61. data/app/models/asset_host_core/output.rb +52 -0
  62. data/app/models/asset_host_core/permission.rb +19 -0
  63. data/app/models/asset_host_core/video.rb +8 -0
  64. data/app/models/asset_host_core/vimeo_video.rb +17 -0
  65. data/app/models/asset_host_core/youtube_video.rb +17 -0
  66. data/app/views/asset_host_core/admin/api_users/_form_fields.html.erb +5 -0
  67. data/app/views/asset_host_core/admin/api_users/edit.html.erb +26 -0
  68. data/app/views/asset_host_core/admin/api_users/index.html.erb +31 -0
  69. data/app/views/asset_host_core/admin/api_users/new.html.erb +17 -0
  70. data/app/views/asset_host_core/admin/api_users/show.html.erb +23 -0
  71. data/app/views/asset_host_core/admin/assets/index.html.erb +19 -0
  72. data/app/views/asset_host_core/admin/assets/metadata.html.erb +24 -0
  73. data/app/views/asset_host_core/admin/assets/show.html.erb +86 -0
  74. data/app/views/asset_host_core/admin/home/chooser.html.erb +49 -0
  75. data/app/views/asset_host_core/admin/outputs/_form_fields.html.erb +5 -0
  76. data/app/views/asset_host_core/admin/outputs/edit.html.erb +26 -0
  77. data/app/views/asset_host_core/admin/outputs/index.html.erb +27 -0
  78. data/app/views/asset_host_core/admin/outputs/new.html.erb +13 -0
  79. data/app/views/asset_host_core/admin/outputs/show.html.erb +17 -0
  80. data/app/views/asset_host_core/shared/_footerjs.html.erb +3 -0
  81. data/app/views/asset_host_core/shared/_navbar.html.erb +28 -0
  82. data/app/views/kaminari/_first_page.html.erb +3 -0
  83. data/app/views/kaminari/_gap.html.erb +3 -0
  84. data/app/views/kaminari/_last_page.html.erb +3 -0
  85. data/app/views/kaminari/_next_page.html.erb +3 -0
  86. data/app/views/kaminari/_page.html.erb +3 -0
  87. data/app/views/kaminari/_paginator.html.erb +17 -0
  88. data/app/views/kaminari/_prev_page.html.erb +3 -0
  89. data/app/views/layouts/asset_host_core/application.html.erb +54 -0
  90. data/app/views/layouts/asset_host_core/full_width.html.erb +32 -0
  91. data/app/views/layouts/asset_host_core/minimal.html.erb +45 -0
  92. data/config/initializers/simple_form.rb +142 -0
  93. data/config/initializers/simple_form_bootstrap.rb +45 -0
  94. data/config/locales/simple_form.en.yml +26 -0
  95. data/config/routes.rb +49 -0
  96. data/lib/asset_host_core.rb +38 -0
  97. data/lib/asset_host_core/config.rb +39 -0
  98. data/lib/asset_host_core/engine.rb +94 -0
  99. data/lib/asset_host_core/loaders.rb +34 -0
  100. data/lib/asset_host_core/loaders/asset_host.rb +30 -0
  101. data/lib/asset_host_core/loaders/base.rb +22 -0
  102. data/lib/asset_host_core/loaders/brightcove.rb +67 -0
  103. data/lib/asset_host_core/loaders/flickr.rb +114 -0
  104. data/lib/asset_host_core/loaders/url.rb +59 -0
  105. data/lib/asset_host_core/loaders/vimeo.rb +76 -0
  106. data/lib/asset_host_core/loaders/youtube.rb +90 -0
  107. data/lib/asset_host_core/model_methods.rb +61 -0
  108. data/lib/asset_host_core/paperclip.rb +4 -0
  109. data/lib/asset_host_core/paperclip/asset_thumbnail.rb +92 -0
  110. data/lib/asset_host_core/paperclip/attachment.rb +206 -0
  111. data/lib/asset_host_core/paperclip/trimmer.rb +33 -0
  112. data/lib/asset_host_core/resque_job.rb +13 -0
  113. data/lib/asset_host_core/version.rb +3 -0
  114. data/lib/tasks/asset_host_core_tasks.rake +4 -0
  115. data/spec/controllers/admin/api_users_controller_spec.rb +21 -0
  116. data/spec/controllers/admin/assets_controller_spec.rb +59 -0
  117. data/spec/controllers/admin/home_controller_spec.rb +4 -0
  118. data/spec/controllers/admin/outputs_controller_spec.rb +4 -0
  119. data/spec/controllers/api/assets_controller_spec.rb +133 -0
  120. data/spec/controllers/api/outputs_controller_spec.rb +51 -0
  121. data/spec/controllers/public_controller_spec.rb +4 -0
  122. data/spec/factories.rb +39 -0
  123. data/spec/features/api_users_spec.rb +78 -0
  124. data/spec/fixtures/api/brightcove/video.json +137 -0
  125. data/spec/fixtures/api/flickr/photos_getInfo.json +78 -0
  126. data/spec/fixtures/api/flickr/photos_getSizes.json +82 -0
  127. data/spec/fixtures/api/flickr/photos_licenses_getInfo.json +52 -0
  128. data/spec/fixtures/api/vimeo/video.json +28 -0
  129. data/spec/fixtures/api/youtube/discovery.json +5190 -0
  130. data/spec/fixtures/api/youtube/video.json +44 -0
  131. data/spec/fixtures/images/chipmunk.jpg +0 -0
  132. data/spec/fixtures/images/dude.jpg +0 -0
  133. data/spec/fixtures/images/ernie.jpg +0 -0
  134. data/spec/fixtures/images/fry.png +0 -0
  135. data/spec/fixtures/images/hat.jpg +0 -0
  136. data/spec/fixtures/images/spongebob.png +0 -0
  137. data/spec/fixtures/images/stars.jpg +0 -0
  138. data/spec/internal/app/controllers/application_controller.rb +16 -0
  139. data/spec/internal/app/controllers/sessions_controller.rb +24 -0
  140. data/spec/internal/app/models/user.rb +10 -0
  141. data/spec/internal/app/views/sessions/new.html.erb +14 -0
  142. data/spec/internal/config/database.yml +3 -0
  143. data/spec/internal/config/initializers/assethost_config.rb +57 -0
  144. data/spec/internal/config/routes.rb +7 -0
  145. data/spec/internal/db/combustion_test.sqlite +0 -0
  146. data/spec/internal/db/schema.rb +106 -0
  147. data/spec/internal/log/test.log +14769 -0
  148. data/spec/internal/public/favicon.ico +0 -0
  149. data/spec/internal/public/images/1_27f7745237849975ca90591c1fba5934_original. +0 -0
  150. data/spec/internal/public/images/1_7d33319deca787d5bb3f62ff06563ad2_original. +0 -0
  151. data/spec/internal/public/images/1_b6d48c8b1286104ce76649731e09645f_original. +0 -0
  152. data/spec/internal/public/images/1_b6d48c8b1286104ce76649731e09645f_original.jpg +0 -0
  153. data/spec/internal/public/images/1_b6d48c8b1286104ce76649731e09645f_original.txt +0 -0
  154. data/spec/internal/public/images/1_e179cbd27e07cb55042d0db36cdac095_original. +0 -0
  155. data/spec/internal/public/images/1_e669edd3dfd74be66fc38416e82e3a37_original. +0 -0
  156. data/spec/lib/asset_host_core/loaders/asset_host_spec.rb +33 -0
  157. data/spec/lib/asset_host_core/loaders/brightcove_spec.rb +51 -0
  158. data/spec/lib/asset_host_core/loaders/flickr_spec.rb +72 -0
  159. data/spec/lib/asset_host_core/loaders/url_spec.rb +42 -0
  160. data/spec/lib/asset_host_core/loaders/vimeo_spec.rb +51 -0
  161. data/spec/lib/asset_host_core/loaders/youtube_spec.rb +73 -0
  162. data/spec/lib/asset_host_core/loaders_spec.rb +4 -0
  163. data/spec/lib/asset_host_core/model_methods_spec.rb +4 -0
  164. data/spec/lib/asset_host_core/paperclip/asset_thumbnail_spec.rb +4 -0
  165. data/spec/lib/asset_host_core/paperclip/attachment_spec.rb +4 -0
  166. data/spec/lib/asset_host_core/resque_job_spec.rb +4 -0
  167. data/spec/lib/asset_host_core_spec.rb +4 -0
  168. data/spec/models/api_user_spec.rb +58 -0
  169. data/spec/models/asset_output_spec.rb +4 -0
  170. data/spec/models/asset_spec.rb +4 -0
  171. data/spec/models/output_spec.rb +4 -0
  172. data/spec/models/permission_spec.rb +4 -0
  173. data/spec/spec_helper.rb +30 -0
  174. data/spec/support/fixture_loader.rb +9 -0
  175. data/spec/support/param_helper.rb +14 -0
  176. data/spec/support/permission_matcher.rb +17 -0
  177. data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  178. data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  179. data/vendor/assets/images/jquery-ui/ui-bg_flat_10_000000_40x100.png +0 -0
  180. data/vendor/assets/images/jquery-ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  181. data/vendor/assets/images/jquery-ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  182. data/vendor/assets/images/jquery-ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
  183. data/vendor/assets/images/jquery-ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  184. data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  185. data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  186. data/vendor/assets/images/jquery-ui/ui-icons_222222_256x240.png +0 -0
  187. data/vendor/assets/images/jquery-ui/ui-icons_228ef1_256x240.png +0 -0
  188. data/vendor/assets/images/jquery-ui/ui-icons_ef8c08_256x240.png +0 -0
  189. data/vendor/assets/images/jquery-ui/ui-icons_ffd27a_256x240.png +0 -0
  190. data/vendor/assets/images/jquery-ui/ui-icons_ffffff_256x240.png +0 -0
  191. data/vendor/assets/javascripts/backbone.js +1158 -0
  192. data/vendor/assets/javascripts/backbone.modelbinding.js +475 -0
  193. data/vendor/assets/javascripts/exif.js +695 -0
  194. data/vendor/assets/javascripts/jquery-ui.js +5614 -0
  195. data/vendor/assets/javascripts/simplemodal.js +698 -0
  196. data/vendor/assets/javascripts/spin.jquery.js +81 -0
  197. data/vendor/assets/javascripts/spin.min.js +1 -0
  198. data/vendor/assets/javascripts/underscore.min.js +1 -0
  199. metadata +658 -0
@@ -0,0 +1,141 @@
1
+ #= require asset_host_core/assethost
2
+ #= require asset_host_core/models
3
+
4
+ class AssetHost.railsCMS
5
+ DefaultOptions:
6
+ el: ""
7
+ preview: true
8
+
9
+ #----------
10
+
11
+ constructor: (assetdata, options={}) ->
12
+ @options = _.defaults options, @DefaultOptions
13
+
14
+ # add in events
15
+ _.extend @, Backbone.Events
16
+
17
+ # -- load assets -- #
18
+
19
+ @assets = new AssetHost.Models.Assets assetdata
20
+
21
+ # -- initialize our views -- #
22
+
23
+ @assetsView = new railsCMS.CMSAssets collection:@assets
24
+ $(@options.el).html @assetsView.el
25
+
26
+ window.addEventListener "message", (evt) =>
27
+ if evt.data != "LOADED"
28
+ found = {}
29
+
30
+ # reconcile our asset list to the returned list
31
+ _(evt.data).each (a,i) =>
32
+ # do we have this asset?
33
+ if asset = @assets.get(a.id)
34
+ # yes... check for changed caption
35
+ asset.set caption:a.caption, ORDER:i
36
+ else
37
+ # no, needs to be added
38
+ asset = new AssetHost.Models.Asset(a)
39
+ asset.fetch(success: (aobj)=>aobj.set({caption:a.caption,ORDER:i});@assets.add(aobj))
40
+
41
+ found[ a.id ] = true
42
+
43
+ # now check for removed assets
44
+ remove = []
45
+ @assets.each (a,i) =>
46
+ if !found[a.get('id')]
47
+ # not in our return list... delete
48
+ remove.push(a)
49
+
50
+ for a in remove
51
+ @assets.remove(a)
52
+
53
+ @assets.sort()
54
+ @assetsView.render()
55
+
56
+ @trigger("assets",evt.data)
57
+ , false
58
+
59
+ #----------
60
+
61
+ @CMSAsset:
62
+ Backbone.View.extend
63
+ tagName: "li"
64
+
65
+ template:
66
+ '''
67
+ <%= asset.tags[ AssetHost.SIZES.thumb ] %>
68
+ <b><%= asset.title %> (<%= asset.size %>)</b>
69
+ <p><%= asset.caption %></p>
70
+ '''
71
+
72
+ #----------
73
+
74
+ initialize: ->
75
+ @render()
76
+ $(@el).attr("data-asset-url",@model.get('api_url'))
77
+ @model.bind "change", => @render()
78
+
79
+ #----------
80
+
81
+ render: ->
82
+ if @model.get('tags')
83
+ $( @el ).html _.template @template,asset:@model.toJSON()
84
+
85
+ return this
86
+
87
+ #----------
88
+
89
+ @CMSAssets:
90
+ Backbone.View.extend
91
+ tagName: "ul"
92
+ events: { "click button": "_popup" }
93
+
94
+ initialize: ->
95
+ @_views = {}
96
+ @collection.bind "reset", =>
97
+ _(@_views).each (a) => $(a.el).detach(); @_views = {}
98
+
99
+ @collection.bind 'add', (f) =>
100
+ console.log "add event from ", f
101
+ @_views[f.cid] = new railsCMS.CMSAsset({model:f,args:@options.args,rows:@options.rows})
102
+ @render()
103
+
104
+ @collection.bind 'remove', (f) =>
105
+ console.log "remove event from ", f
106
+ $(@_views[f.cid].el).detach()
107
+ delete @_views[f.cid]
108
+ @render()
109
+
110
+
111
+ @render()
112
+
113
+ #----------
114
+
115
+ _popup: (evt) ->
116
+ console.log("evt is ",evt)
117
+ evt.originalEvent.stopPropagation()
118
+ evt.originalEvent.preventDefault()
119
+ newwindow = window.open("http://#{AssetHost.SERVER}#{AssetHost.PATH_PREFIX}/a/chooser", 'chooser', 'height=620,width=1000,scrollbars=1')
120
+
121
+ # attach a listener to wait for the LOADED message
122
+ window.addEventListener "message", (evt) =>
123
+ if evt.data == "LOADED"
124
+ # dispatch our event with the asset data
125
+ newwindow.postMessage @collection.toJSON(), "http://#{AssetHost.SERVER}"
126
+ , false
127
+
128
+ return false
129
+
130
+ #----------
131
+
132
+ render: ->
133
+ @collection.each (a) =>
134
+ @_views[a.cid] ?= new railsCMS.CMSAsset({model:a,args:@options.args,rows:@options.rows})
135
+
136
+ views = _(@_views).sortBy (a) => a.model.get("ORDER")
137
+ $(@el).html( _(views).map (v) -> v.el )
138
+
139
+ $(@el).append( $("<li/>").html( $('<button/>',{text:"Pop Up Asset Chooser"})))
140
+
141
+ @
@@ -0,0 +1,428 @@
1
+ #= require ./assethost
2
+ #= require backbone
3
+ #= require ./models
4
+
5
+ class AssetHost.Slideshow
6
+ DefaultOptions:
7
+ el: "#photo"
8
+ initial: 4
9
+ start: 0
10
+ imgwidth: null
11
+ imgheight: null
12
+ margin: 12
13
+
14
+ constructor: (options) ->
15
+ @options = _(_({}).extend(@DefaultOptions)).extend options||{}
16
+
17
+ # add in events
18
+ _.extend(this, Backbone.Events)
19
+
20
+ $ =>
21
+ # -- create hidden element for dimensioning -- #
22
+ @hidden = $ "<div/>", style:"position:absolute; top:-10000px; width:0px; height:0px;"
23
+ $('body').append @hidden
24
+
25
+ # -- get our parent element -- #
26
+
27
+ @el = $ @options.el
28
+
29
+ # -- create asset collection -- #
30
+
31
+ @assets = new Slideshow.Assets @options.assets
32
+
33
+ # -- create our nav buttons -- #
34
+
35
+ @nav = new Slideshow.NavigationLinks current:@options.start,total:@assets.length
36
+
37
+ # -- set up our slides -- #
38
+
39
+ @slides = new Slideshow.Slides
40
+ collection: @assets
41
+ hidden: @hidden
42
+ initial: @options.initial
43
+ imgwidth: @options.imgwidth
44
+ imgheight: @options.imgheight
45
+ nav: @nav
46
+ margin: @options.margin
47
+
48
+ @el.html @slides.el
49
+ @slides.render()
50
+
51
+ # -- bind slides and nav together -- #
52
+ @nav.bind "slide", (idx) => @slides.slideTo(idx)
53
+ @slides.bind "slide", (idx) =>
54
+ @nav.setCurrent idx
55
+ @trigger "slide", idx
56
+
57
+ #----------
58
+
59
+ @Asset:
60
+ Backbone.Model.extend
61
+ initialize: ->
62
+ # do something
63
+
64
+ @Assets:
65
+ Backbone.Collection.extend
66
+ url: "/"
67
+ model: @Asset
68
+
69
+ #----------
70
+
71
+ @Slide:
72
+ Backbone.View.extend
73
+ tagName: 'li'
74
+ className: "slide"
75
+
76
+ template:
77
+ '''
78
+ <div class="text" style="width: <%= width %>px;margin: 0 auto">
79
+ <div class="credit"><%= credit %></div>
80
+ <p><%= caption %></p>
81
+ </div>
82
+ '''
83
+
84
+ fullTemplate:
85
+ '''
86
+
87
+ '''
88
+
89
+ #----------
90
+
91
+ initialize: ->
92
+ @slides = @options.slides
93
+ @hidden = @options.hidden
94
+ @index = @options.index
95
+
96
+ #----------
97
+
98
+ render: ->
99
+ # -- choose image size -- #
100
+
101
+ # sort of sizes hash
102
+ sizes = @model.get("sizes")
103
+ _(sizes).each (v, k) => v.key = k
104
+ sizes = _(sizes).sortBy (v) -> -v.width
105
+
106
+ # now take the first size that fits
107
+ @imgSize = _(sizes).find (v,i) =>
108
+ if v.width <= $(@el).width()
109
+ # take it
110
+ return true
111
+ else
112
+ return false
113
+
114
+ # -- render text elements -- #
115
+
116
+ # we have to render twice... once to hidden and once to @el.
117
+ # this allows us to get dimensions
118
+
119
+ # create temp element and render
120
+ tmp = $ "<div/>", width:@imgSize.width
121
+
122
+ $(tmp).html _.template @template,
123
+ credit: @model.get("credit")
124
+ caption: @model.get("caption")
125
+ url: @model.get("url")
126
+ width: @imgSize.width
127
+
128
+ @hidden.append tmp
129
+
130
+ # get dimensions
131
+ @textHeight = $(tmp).height()
132
+ @imgHeight = if $(@el).height() then $(@el).height() - @textHeight else @imgSize.height
133
+
134
+ # and remove...
135
+ $(tmp).detach()
136
+
137
+ # now render caption and credit for real
138
+ $(@el).html _.template @template,
139
+ credit: @model.get("credit")
140
+ caption: @model.get("caption")
141
+ url: @model.get("url")
142
+ width: @imgSize.width
143
+
144
+ # -- determine final image size -- #
145
+
146
+ # because we're choosing our image based on horizontal space,
147
+ # we should only have to do our scaling off the vertical size
148
+
149
+ imgh = @imgSize.height
150
+ @scale = 1
151
+
152
+ if imgh > @imgHeight
153
+ vs = @imgHeight / imgh
154
+
155
+ if vs < 1
156
+ @scale = vs
157
+
158
+ # -- create img div with final dimensions -- #
159
+
160
+ @imgDiv = $ "<div/>",
161
+ class:"ah_imgholder"
162
+ style:"width:#{@imgSize.width * @scale}px;height:#{@imgSize.height * @scale}px"
163
+
164
+ $(@el).prepend @imgDiv
165
+
166
+ @
167
+
168
+ #----------
169
+
170
+ loadImage: ->
171
+ if @slides.current == @index then $(@el).fadeOut() else $(@el).hide()
172
+
173
+ @img = $ "<img/>",
174
+ src: @model.get("urls")[@imgSize.key]
175
+ width: @imgSize.width * @scale
176
+ height: @imgSize.height * @scale
177
+
178
+ @hidden.append @img
179
+ @img.load (evt) =>
180
+
181
+ # -- center -- #
182
+
183
+ @imgDiv.css "margin-left", ($(@el).width() - @img.width())/2
184
+ @imgDiv.css "margin-top", (@imgHeight - @img.height())/2
185
+
186
+ # -- add to our element -- #
187
+
188
+ @img.detach()
189
+ @imgDiv.html @img
190
+
191
+ if @slides.current == @index then $(@el).fadeIn('slow') else $(@el).show()
192
+
193
+ # -- tell the loader that we're done -- #
194
+
195
+ @trigger "imgload"
196
+
197
+ #----------
198
+
199
+ @Slides:
200
+ Backbone.View.extend
201
+ className: "slideview"
202
+
203
+ events:
204
+ 'mouseover': '_mouseover'
205
+ 'mouseout': '_mouseout'
206
+
207
+ initialize: ->
208
+ @hidden = @options.hidden
209
+ @slides = []
210
+
211
+ @collection.each (a,idx) =>
212
+ s = new Slideshow.Slide model:a, slides:@, hidden:@hidden, index:idx
213
+ @slides[idx] = s
214
+
215
+ # we need to know the text height of our first slide to
216
+ # dimension space for the rest of the slides
217
+ s = @slides[0]
218
+ $(s.el).css "width", @options.imgwidth+"px"
219
+ s.render()
220
+ txth = s.textHeight
221
+
222
+ @swidth = @options.imgwidth
223
+ @sheight = @options.imgheight + txth
224
+
225
+ console.log "slide height should be ", @sheight
226
+
227
+ @queued = []
228
+ @loaded = []
229
+ @active = false
230
+
231
+ @current = null
232
+
233
+ @hasmouse = false
234
+
235
+ $(window).bind "keydown", (evt) => @_keyhandler(evt)
236
+
237
+ #----------
238
+
239
+ render: () ->
240
+ #$(@el).css "position", "absolute"
241
+ $(@el).attr "tabindex", -1
242
+
243
+ $(@el).css "width", @swidth+"px"
244
+
245
+ totalw = @collection.length * @swidth
246
+
247
+ # check if slide0 has a right margin, and adjust width accordingly
248
+ if @options.margin
249
+ totalw = totalw + @collection.length * @options.margin
250
+
251
+ # height defaults to slide height
252
+ svheight = @sheight
253
+
254
+ if @options.nav
255
+ $(@el).html @options.nav.el
256
+ @options.nav.render()
257
+
258
+ navh = $(@options.nav.el).outerHeight()
259
+
260
+ # add nav height to slideview height
261
+ svheight = svheight + navh
262
+
263
+ # now set height...
264
+ $(@el).css "height", svheight+"px"
265
+
266
+ # create view tray
267
+ @view = $ '<ul/>', style:"position:relative;width:#{totalw}px;height:#{@sheight}px"
268
+
269
+ # drop view into element
270
+ $(@el).prepend @view
271
+
272
+ # add our slides
273
+ _(@slides).each (s,idx) =>
274
+ s.bind "imgload", => @_loaded s, idx
275
+ $(s.el).css "width", @swidth+"px"
276
+ $(s.el).css "height", @sheight+"px"
277
+ $(s.el).css "left", @swidth*idx + (@options.margin||0)*idx + "px"
278
+
279
+ $(@view).append s.render().el
280
+
281
+ # create our load queue
282
+ @queueSlides _.range 0,4
283
+
284
+ #----------
285
+
286
+ _mouseover: (e) ->
287
+ @hasmouse = true
288
+
289
+ _mouseout: (e) ->
290
+ @hasmouse = false
291
+
292
+ _keyhandler: (e) ->
293
+ if @hasmouse
294
+ # is this a keypress we care about?
295
+ if e.which == 37
296
+ @slideBy(-1)
297
+ else if e.which == 39
298
+ @slideBy(1)
299
+
300
+ #----------
301
+
302
+ slideTo: (idx) ->
303
+ # figure out where slide[idx] is at
304
+ @view.stop().animate {left: -$(@slides[idx].el).position().left}, "slow"
305
+ @current = idx
306
+
307
+ @trigger "slide", idx
308
+
309
+ @_updateLoadQueue()
310
+
311
+ #----------
312
+
313
+ slideBy: (idx) ->
314
+ t = @current + idx
315
+
316
+ if @slides[t]
317
+ @slideTo(t)
318
+
319
+ #----------
320
+
321
+ queueSlides: (indexes...) ->
322
+ _(_(indexes).flatten()).each (i) =>
323
+ if !@loaded[i] || @loaded[i] == 0 && !_(@queued).contains(i)
324
+ console.log "queuing #{i}"
325
+ @queued.push i
326
+
327
+ if !@active
328
+ @_fireUpQueue()
329
+
330
+ #----------
331
+
332
+ _updateLoadQueue: ->
333
+ if !@loaded[@current] || @loaded[@current] == 0
334
+ @queued.unshift @current
335
+
336
+ toQueue = []
337
+ _(_.range(@current+1,@current+4)).each (i) => toQueue.push(i) if @slides[i]
338
+ _(_.range(@current-2,@current)).each (i) => toQueue.push(i) if @slides[i]
339
+
340
+ @queueSlides toQueue
341
+
342
+ #----------
343
+
344
+ _fireUpQueue: ->
345
+ return false if !@queued || @queued.length == 0
346
+
347
+ console.log "_fireUpQueue with queue of #{@queued}"
348
+
349
+ i = @queued.shift()
350
+ s = @slides[i]
351
+
352
+ if !@loaded[i] || @loaded[i] == 0
353
+ console.log "triggering load on #{i}"
354
+ @loaded[i] = 1
355
+ @active = i
356
+ s.loadImage()
357
+ else
358
+ @_fireUpQueue()
359
+
360
+ #----------
361
+
362
+ _loaded: (s,idx) ->
363
+ console.log "got _loaded for #{idx}"
364
+ @loaded[idx] = 2
365
+
366
+ if @active == idx
367
+ @active = null
368
+ @_fireUpQueue()
369
+
370
+ #----------
371
+
372
+ @NavigationLinks:
373
+ Backbone.View.extend
374
+ className: "nav"
375
+
376
+ events:
377
+ 'click button': '_buttonClick'
378
+
379
+ template:
380
+ '''
381
+ <div style="width: 15%;">
382
+ <button <% print(prev ? "data-idx='"+prev+"' class='prev-arrow'" : "class='disabled prev-arrow'"); %> >Prev</button>
383
+ </div>
384
+ <div class="buttons" style="width:70%;"></div>
385
+ <div style="width: 15%">
386
+ <button <% print(next ? "data-idx='"+next+"' class='next-arrow'" : "class='disabled next-arrow'"); %> >Next</button>
387
+ </div>
388
+ <br style="clear:both;line-height:0;height:0"/>
389
+ '''
390
+
391
+ #----------
392
+
393
+ initialize: ->
394
+ @total = @options.total
395
+ @current = Number(@options.current) + 1
396
+
397
+ @render()
398
+
399
+ #----------
400
+
401
+ _buttonClick: (evt) ->
402
+ idx = $(evt.currentTarget).attr "data-idx"
403
+
404
+ if idx
405
+ idx = Number(idx) - 1
406
+ console.log "nav trigger slide to #{idx}"
407
+ @trigger "slide", idx
408
+
409
+ #----------
410
+
411
+ setCurrent: (idx) ->
412
+ @current = Number(idx) + 1
413
+ console.log "nav set current to #{@current}"
414
+ @render()
415
+
416
+ #----------
417
+
418
+ render: ->
419
+ buttons = _([1..@total]).map (i) =>
420
+ $("<button/>", {"data-idx":i, text:i, class:if @current == i then "current" else ""})[0]
421
+
422
+ $(@el).html _.template @template,
423
+ current: @current,
424
+ total: @total,
425
+ prev: if @current - 1 > 0 then @current - 1 else null
426
+ next: if @current + 1 <= @total then @current + 1 else null
427
+
428
+ @$(".buttons").html buttons