droom 0.4.3 → 0.5.3

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 (396) hide show
  1. checksums.yaml +7 -0
  2. data/app/assets/images/droom/admin_menu.png +0 -0
  3. data/app/assets/images/droom/applications_menu.png +0 -0
  4. data/app/assets/images/droom/arrows_small.png +0 -0
  5. data/app/assets/images/droom/config_menu.png +0 -0
  6. data/app/assets/images/droom/dropdown.png +0 -0
  7. data/app/assets/images/droom/menu/asterisk.png +0 -0
  8. data/app/assets/images/droom/{smalladd.png → menu/smalladd.png} +0 -0
  9. data/app/assets/images/droom/{small_asterisk.png → menu/smallasterisk.png} +0 -0
  10. data/app/assets/images/droom/{smalldelete.png → menu/smalldelete.png} +0 -0
  11. data/app/assets/images/droom/{smalldownload.png → menu/smalldownload.png} +0 -0
  12. data/app/assets/images/droom/{smalledit.png → menu/smalledit.png} +0 -0
  13. data/app/assets/images/droom/message.png +0 -0
  14. data/app/assets/images/droom/missing/scrap.jpg +0 -0
  15. data/app/assets/images/droom/missing/scrap.png +0 -0
  16. data/app/assets/images/droom/missing/thumb.png +0 -0
  17. data/app/assets/images/droom/missing/user.png +0 -0
  18. data/app/assets/images/droom/object_icons.png +0 -0
  19. data/app/assets/images/droom/panel/add.png +0 -0
  20. data/app/assets/images/droom/panel/edit.png +0 -0
  21. data/app/assets/images/droom/panel/manage.png +0 -0
  22. data/app/assets/images/droom/pointer_upwards.png +0 -0
  23. data/app/assets/images/droom/search_menu.png +0 -0
  24. data/app/assets/images/droom/setter.png +0 -0
  25. data/app/assets/images/droom/small_icons.png +0 -0
  26. data/app/assets/images/droom/stream/closer.png +0 -0
  27. data/app/assets/images/droom/stream/next.png +0 -0
  28. data/app/assets/images/droom/stream/prev.png +0 -0
  29. data/app/assets/images/droom/stream/previous.png +0 -0
  30. data/app/assets/images/droom/subscribe.png +0 -0
  31. data/app/assets/javascripts/droom.js.coffee +23 -13
  32. data/app/assets/javascripts/droom/actions.js.coffee +104 -10
  33. data/app/assets/javascripts/droom/ajax.js.coffee +36 -24
  34. data/app/assets/javascripts/droom/extensions.js.coffee +13 -0
  35. data/app/assets/javascripts/droom/lib/jquery.datepicker.js +1026 -0
  36. data/app/assets/javascripts/droom/lib/jquery.deserialize.js +142 -0
  37. data/app/assets/javascripts/droom/lib/jquery_ujs.js +416 -0
  38. data/app/assets/javascripts/droom/lib/swipe.js +568 -0
  39. data/app/assets/javascripts/droom/lib/underscore.js +1276 -0
  40. data/app/assets/javascripts/droom/popups.js.coffee +98 -37
  41. data/app/assets/javascripts/droom/stream.js.coffee +119 -77
  42. data/app/assets/javascripts/droom/utilities.js.coffee +25 -3
  43. data/app/assets/javascripts/droom/widgets.js.coffee +318 -253
  44. data/app/assets/stylesheets/droom.css.sass +482 -955
  45. data/app/assets/stylesheets/droom/_mixins.css.sass +12 -42
  46. data/app/assets/stylesheets/droom/_popups.css.sass +28 -11
  47. data/app/assets/stylesheets/droom/_stream.css.sass +375 -0
  48. data/app/assets/stylesheets/droom/_toolbar.css.sass +0 -6
  49. data/app/assets/stylesheets/droom/_variables.css.sass +4 -2
  50. data/app/controllers/droom/agenda_categories_controller.rb +6 -14
  51. data/app/controllers/droom/api/api_controller.rb +56 -0
  52. data/app/controllers/droom/api/events_controller.rb +74 -0
  53. data/app/controllers/droom/api/users_controller.rb +92 -0
  54. data/app/controllers/droom/api/venues_controller.rb +71 -0
  55. data/app/controllers/droom/calendars_controller.rb +4 -10
  56. data/app/controllers/droom/{user_confirmations_controller.rb → confirmations_controller.rb} +8 -7
  57. data/app/controllers/droom/dashboard_controller.rb +2 -19
  58. data/app/controllers/droom/documents_controller.rb +12 -60
  59. data/app/controllers/droom/dropbox_tokens_controller.rb +3 -4
  60. data/app/controllers/droom/engine_controller.rb +39 -11
  61. data/app/controllers/droom/events_controller.rb +62 -84
  62. data/app/controllers/droom/folders_controller.rb +30 -40
  63. data/app/controllers/droom/group_invitations_controller.rb +6 -23
  64. data/app/controllers/droom/group_permissions_controller.rb +26 -0
  65. data/app/controllers/droom/groups_controller.rb +10 -14
  66. data/app/controllers/droom/invitations_controller.rb +7 -25
  67. data/app/controllers/droom/memberships_controller.rb +13 -18
  68. data/app/controllers/droom/organisations_controller.rb +6 -25
  69. data/app/controllers/droom/permissions_controller.rb +50 -0
  70. data/app/controllers/droom/preferences_controller.rb +9 -10
  71. data/app/controllers/droom/scraps_controller.rb +23 -26
  72. data/app/controllers/droom/services_controller.rb +50 -0
  73. data/app/controllers/droom/suggestions_controller.rb +6 -4
  74. data/app/controllers/droom/users/confirmations_controller.rb +24 -0
  75. data/app/controllers/droom/users/passwords_controller.rb +39 -0
  76. data/app/controllers/droom/users/sessions_controller.rb +7 -0
  77. data/app/controllers/droom/users_controller.rb +60 -38
  78. data/app/controllers/droom/venues_controller.rb +8 -15
  79. data/app/controllers/droom/youtube_controller.rb +1 -1
  80. data/app/helpers/droom/droom_helper.rb +22 -17
  81. data/app/models/droom/ability.rb +81 -0
  82. data/app/models/droom/agenda_category.rb +0 -1
  83. data/app/models/droom/calendar.rb +12 -7
  84. data/app/models/droom/category.rb +4 -10
  85. data/app/models/droom/concerns/slugged.rb +21 -0
  86. data/app/models/droom/document.rb +15 -17
  87. data/app/models/droom/dropbox_document.rb +3 -6
  88. data/app/models/droom/dropbox_token.rb +2 -3
  89. data/app/models/droom/event.rb +117 -163
  90. data/app/models/droom/event_type.rb +25 -0
  91. data/app/models/droom/folder.rb +36 -48
  92. data/app/models/droom/group.rb +35 -27
  93. data/app/models/droom/group_invitation.rb +7 -10
  94. data/app/models/droom/group_permission.rb +29 -0
  95. data/app/models/droom/invitation.rb +14 -23
  96. data/app/models/droom/mailing_list_membership.rb +0 -1
  97. data/app/models/droom/membership.rb +32 -31
  98. data/app/models/droom/organisation.rb +6 -3
  99. data/app/models/droom/permission.rb +19 -0
  100. data/app/models/droom/personal_folder.rb +9 -21
  101. data/app/models/droom/preference.rb +1 -2
  102. data/app/models/droom/scrap.rb +31 -26
  103. data/app/models/droom/service.rb +31 -0
  104. data/app/models/droom/tag.rb +10 -9
  105. data/app/models/droom/tagging.rb +1 -1
  106. data/app/models/droom/user.rb +453 -130
  107. data/app/models/droom/user_permission.rb +8 -0
  108. data/app/models/droom/venue.rb +21 -32
  109. data/app/serializers/droom/user_serializer.rb +45 -0
  110. data/app/serializers/droom/venue_serializer.rb +5 -0
  111. data/app/views/droom/dashboard/_documents.html.haml +1 -1
  112. data/app/views/droom/dashboard/_folders.html.haml +1 -1
  113. data/app/views/droom/dashboard/_future_events.html.haml +10 -8
  114. data/app/views/droom/dashboard/_groups.html.haml +1 -1
  115. data/app/views/droom/dashboard/_past_events.haml +19 -12
  116. data/app/views/droom/dashboard/_stream.html.haml +2 -2
  117. data/app/views/droom/{users/_extra_columns.html.haml → dashboard/_welcome.html.haml} +0 -0
  118. data/app/views/droom/dashboard/index.html.haml +3 -0
  119. data/app/views/droom/documents/_document.html.haml +0 -2
  120. data/app/views/droom/documents/_documents.html.haml +1 -1
  121. data/app/views/droom/documents/_documents_list.html.haml +1 -1
  122. data/app/views/droom/documents/_documents_table.html.haml +1 -1
  123. data/app/views/droom/documents/_form.html.haml +8 -5
  124. data/app/views/droom/documents/_listing.html.haml +4 -2
  125. data/app/views/droom/documents/index.html.haml +13 -7
  126. data/app/views/droom/documents/new.html.haml +1 -4
  127. data/app/views/droom/events/_action_menu.html.haml +2 -2
  128. data/app/views/droom/events/_attachments.html.haml +8 -0
  129. data/app/views/droom/events/_calendar.html.haml +4 -8
  130. data/app/views/droom/events/_event.html.haml +44 -63
  131. data/app/views/droom/events/_event_line.html.haml +1 -1
  132. data/app/views/droom/events/_events.html.haml +18 -2
  133. data/app/views/droom/events/_form.html.haml +26 -19
  134. data/app/views/droom/events/_invitations.html.haml +7 -3
  135. data/app/views/droom/events/_scrap_events.html.haml +8 -0
  136. data/app/views/droom/events/_suggested.html.haml +4 -1
  137. data/app/views/droom/events/calendar.html.haml +8 -0
  138. data/app/views/droom/events/index.html.haml +24 -26
  139. data/app/views/droom/events/show.html.haml +6 -6
  140. data/app/views/droom/folders/_contents.html.haml +34 -4
  141. data/app/views/droom/folders/_folder.html.haml +7 -2
  142. data/app/views/droom/folders/_form.html.haml +11 -8
  143. data/app/views/droom/folders/index.html.haml +19 -22
  144. data/app/views/droom/group_invitations/_attending_groups.html.haml +1 -1
  145. data/app/views/droom/group_permissions/_toggle.html.haml +18 -0
  146. data/app/views/droom/groups/_action_menu.haml +0 -2
  147. data/app/views/droom/groups/_created.html.haml +0 -1
  148. data/app/views/droom/groups/_form.html.haml +3 -0
  149. data/app/views/droom/groups/_group.html.haml +10 -8
  150. data/app/views/droom/groups/_groups.html.haml +1 -1
  151. data/app/views/droom/groups/_search_result.html.haml +1 -1
  152. data/app/views/droom/groups/_suggested.html.haml +1 -1
  153. data/app/views/droom/groups/index.html.haml +15 -16
  154. data/app/views/droom/invitations/_form.html.haml +1 -1
  155. data/app/views/droom/invitations/_invitation.html.haml +1 -1
  156. data/app/views/droom/invitations/_invitations.html.haml +4 -4
  157. data/app/views/droom/memberships/_button.html.haml +5 -5
  158. data/app/views/droom/memberships/_form.html.haml +26 -7
  159. data/app/views/droom/memberships/_member.html.haml +1 -1
  160. data/app/views/droom/memberships/{_membership_toggle.html.haml → _toggle.html.haml} +4 -4
  161. data/app/views/droom/memberships/index.html.haml +9 -0
  162. data/app/views/droom/organisations/_action_menu.html.haml +1 -1
  163. data/app/views/droom/organisations/_organisation.html.haml +2 -2
  164. data/app/views/droom/organisations/_suggested.html.haml +1 -1
  165. data/app/views/droom/organisations/index.html.haml +11 -11
  166. data/app/views/droom/panels/_admin.html.haml +2 -2
  167. data/app/views/droom/panels/_configuration.html.haml +28 -0
  168. data/app/views/droom/panels/_devices.html.haml +2 -4
  169. data/app/views/droom/panels/_search.html.haml +9 -0
  170. data/app/views/droom/permissions/_action_menu.html.haml +10 -0
  171. data/app/views/droom/permissions/_created.html.haml +3 -0
  172. data/app/views/droom/permissions/_form.html.haml +17 -0
  173. data/app/views/droom/permissions/edit.html.haml +7 -0
  174. data/app/views/droom/permissions/new.html.haml +8 -0
  175. data/app/views/droom/permissions/show.html.haml +4 -0
  176. data/app/views/droom/preferences/_checkbox.html.haml +4 -2
  177. data/app/views/droom/scraps/_caption.html.haml +0 -2
  178. data/app/views/droom/scraps/_credit.html.haml +1 -1
  179. data/app/views/droom/scraps/_form.html.haml +68 -69
  180. data/app/views/droom/scraps/_preload.html.haml +4 -0
  181. data/app/views/droom/scraps/_stream.html.haml +11 -3
  182. data/app/views/droom/scraps/_thumb.html.haml +33 -1
  183. data/app/views/droom/scraps/edit.html.haml +6 -1
  184. data/app/views/droom/scraps/full/_document.html.haml +4 -3
  185. data/app/views/droom/scraps/full/_event.html.haml +17 -16
  186. data/app/views/droom/scraps/full/_image.html.haml +1 -2
  187. data/app/views/droom/scraps/full/_link.html.haml +4 -3
  188. data/app/views/droom/scraps/full/_quote.html.haml +4 -7
  189. data/app/views/droom/scraps/full/_text.html.haml +3 -2
  190. data/app/views/droom/scraps/full/_video.html.haml +2 -2
  191. data/app/views/droom/scraps/new.html.haml +6 -1
  192. data/app/views/droom/scraps/show.html.haml +4 -3
  193. data/app/views/droom/services/_action_menu.html.haml +12 -0
  194. data/app/views/droom/services/_created.html.haml +3 -0
  195. data/app/views/droom/services/_form.html.haml +18 -0
  196. data/app/views/droom/services/_services.html.haml +44 -0
  197. data/app/views/droom/services/edit.html.haml +7 -0
  198. data/app/views/droom/services/index.html.haml +5 -0
  199. data/app/views/droom/{people → services}/new.html.haml +4 -3
  200. data/app/views/droom/services/show.html.haml +4 -0
  201. data/app/views/droom/shared/_controls.html.haml +2 -2
  202. data/app/views/droom/shared/_navigation.html.haml +2 -2
  203. data/app/views/droom/shared/_toolbar.html.haml +1 -1
  204. data/app/views/droom/suggestions/index.html.haml +1 -0
  205. data/app/views/droom/users/_action_menu.html.haml +21 -0
  206. data/app/views/droom/users/_suggested.html.haml +14 -0
  207. data/app/views/droom/users/_user.html.haml +2 -2
  208. data/app/views/droom/users/_users.html.haml +7 -0
  209. data/app/views/droom/users/_users_table.html.haml +21 -22
  210. data/app/views/droom/users/admin.html.haml +10 -0
  211. data/app/views/droom/users/confirmations/_after_confirmation.html.haml +2 -0
  212. data/app/views/droom/users/confirmations/_password_required.html.haml +30 -0
  213. data/app/views/droom/users/confirmations/failure.en.html.haml +22 -0
  214. data/app/views/droom/users/confirmations/show.html.haml +13 -0
  215. data/app/views/droom/users/edit.html.haml +2 -10
  216. data/app/views/droom/users/edit/_details.html.haml +13 -0
  217. data/app/views/droom/users/edit/_memberships.html.haml +13 -0
  218. data/app/views/droom/users/edit/_password_fields.html.haml +16 -0
  219. data/app/views/droom/users/edit/_preferences.html.haml +37 -0
  220. data/app/views/droom/users/edit/_profile.html.haml +26 -0
  221. data/app/views/droom/users/edit/_user_fields.html.haml +66 -0
  222. data/app/views/droom/users/index.html.haml +6 -32
  223. data/app/views/droom/users/new.html.haml +3 -0
  224. data/app/views/droom/users/passwords/completed.html.haml +13 -0
  225. data/app/views/{devise → droom/users}/passwords/edit.html.haml +10 -4
  226. data/app/views/{devise → droom/users}/passwords/new.html.haml +4 -3
  227. data/app/views/droom/users/passwords/show.html.haml +6 -0
  228. data/app/views/droom/users/show.html.haml +2 -0
  229. data/app/views/droom/users/show/_listed.html.haml +46 -0
  230. data/app/views/droom/users/show/_profile.html.haml +33 -0
  231. data/app/views/droom/users/show/_tabled.html.haml +28 -0
  232. data/config/initializers/chronic.rb +2 -0
  233. data/config/initializers/devise.rb +35 -2
  234. data/config/initializers/paperclip.rb +11 -6
  235. data/config/locales/devise.en.yml +1 -1
  236. data/config/locales/en.yml +198 -103
  237. data/config/routes.rb +37 -45
  238. data/db/migrate/20130207123614_stream.rb +5 -1
  239. data/db/migrate/20130225095328_create_droom_calendars.rb +0 -1
  240. data/db/migrate/20130627065459_permissions.rb +34 -0
  241. data/db/migrate/20130627071938_users_take_over.rb +38 -0
  242. data/db/migrate/20130627073759_user_properties.rb +34 -0
  243. data/db/migrate/20130627080021_no_more_people.rb +11 -0
  244. data/db/migrate/20130701122935_directory_groups.rb +8 -0
  245. data/db/migrate/20130701123152_remove_old_access_control.rb +16 -0
  246. data/db/migrate/20130729102857_more_scrap_data.rb +12 -0
  247. data/db/migrate/20130904080340_international_names.rb +17 -0
  248. data/db/migrate/20130904080341_honours.rb +5 -0
  249. data/db/migrate/20131124082222_simple_addresses.rb +25 -0
  250. data/db/migrate/20131201093351_event_time_zone.rb +5 -0
  251. data/db/migrate/20131217060311_session_revocable.rb +5 -0
  252. data/db/migrate/20131219180311_event_types.rb +15 -0
  253. data/lib/devise/strategies/cookie_authenticatable.rb +46 -0
  254. data/lib/droom.rb +48 -33
  255. data/lib/droom/auth_cookie.rb +82 -0
  256. data/lib/droom/cropper.rb +24 -0
  257. data/lib/droom/engine.rb +20 -2
  258. data/lib/droom/folders.rb +6 -6
  259. data/lib/droom/lazy_hash.rb +11 -1
  260. data/lib/droom/monkeys.rb +6 -6
  261. data/lib/droom/taggability.rb +1 -1
  262. data/lib/droom/validators.rb +1 -1
  263. data/lib/droom/version.rb +1 -1
  264. data/lib/generators/droom/install/templates/droom_initializer.rb +10 -2
  265. data/lib/paperclip/geometry_transformation.rb +80 -0
  266. data/lib/paperclip/validators/attachment_height_validator.rb +89 -0
  267. data/lib/paperclip/validators/attachment_width_validator.rb +89 -0
  268. data/lib/paperclip_processors/offset_thumbnail.rb +85 -0
  269. data/spec/dummy/config/application.rb +0 -7
  270. data/spec/dummy/config/environments/development.rb +1 -10
  271. data/spec/dummy/config/environments/production.rb +1 -0
  272. data/spec/dummy/config/environments/test.rb +2 -7
  273. data/spec/dummy/db/migrate/20130130120631_folder_ancestry_to_parents.droom.rb +1 -1
  274. data/spec/dummy/db/migrate/20130724124758_dropbox_tokens.droom.rb +10 -0
  275. data/spec/dummy/db/migrate/20130724124759_preference_uuids.droom.rb +6 -0
  276. data/spec/dummy/db/migrate/20130724124760_stream.droom.rb +14 -0
  277. data/spec/dummy/db/migrate/20130724124761_access_token_secret.droom.rb +6 -0
  278. data/spec/dummy/db/migrate/20130724124762_person_image.droom.rb +10 -0
  279. data/spec/dummy/db/migrate/20130724124763_devise_confirmable.droom.rb +14 -0
  280. data/spec/dummy/db/migrate/20130724124764_create_droom_calendars.droom.rb +20 -0
  281. data/spec/dummy/db/migrate/20130724124765_give_scraps_document.droom.rb +6 -0
  282. data/spec/dummy/db/migrate/20130724124766_privateness.droom.rb +10 -0
  283. data/spec/dummy/db/migrate/20130724124767_store_metadata.droom.rb +6 -0
  284. data/spec/dummy/db/migrate/20130724124768_folders_nicely.droom.rb +7 -0
  285. data/spec/dummy/db/migrate/20130724124769_niceties.droom.rb +8 -0
  286. data/spec/dummy/db/migrate/20130724124770_create_droom_dropbox_documents.droom.rb +12 -0
  287. data/spec/dummy/db/migrate/20130724124771_dropbox_documents_changed.droom.rb +6 -0
  288. data/spec/dummy/db/migrate/20130724124772_user_titles.droom.rb +6 -0
  289. data/spec/dummy/db/migrate/20130724124773_permissions.droom.rb +35 -0
  290. data/spec/dummy/db/migrate/20130724124774_users_take_over.droom.rb +39 -0
  291. data/spec/dummy/db/migrate/20130724124775_user_properties.droom.rb +35 -0
  292. data/spec/dummy/db/migrate/20130724124776_no_more_people.droom.rb +12 -0
  293. data/spec/dummy/db/migrate/20130724124777_directory_groups.droom.rb +9 -0
  294. data/spec/dummy/db/migrate/20130724124778_remove_old_access_control.droom.rb +17 -0
  295. data/spec/dummy/db/schema.rb +217 -140
  296. data/spec/factories/documents.rb +0 -5
  297. data/spec/factories/events.rb +0 -9
  298. data/spec/factories/user.rb +4 -2
  299. data/spec/lib/droom/folders_spec.rb +8 -8
  300. data/spec/models/droom/document_spec.rb +6 -43
  301. data/spec/models/droom/event_spec.rb +0 -34
  302. data/spec/models/droom/mailing_list_membership_spec.rb +4 -4
  303. data/spec/models/droom/membership_spec.rb +2 -2
  304. data/spec/spec_helper.rb +1 -10
  305. metadata +322 -282
  306. data/app/assets/images/droom/Untitled-1.png +0 -0
  307. data/app/assets/images/droom/asterisk.png +0 -0
  308. data/app/assets/images/droom/smallmanage.png +0 -0
  309. data/app/assets/javascripts/droom/lib/kalendae.js +0 -1692
  310. data/app/assets/stylesheets/lib/_kalendae.css.sass +0 -139
  311. data/app/controllers/droom/pages_controller.rb +0 -61
  312. data/app/controllers/droom/people_controller.rb +0 -111
  313. data/app/models/droom/document_attachment.rb +0 -37
  314. data/app/models/droom/page.rb +0 -26
  315. data/app/models/droom/person.rb +0 -309
  316. data/app/models/droom/recurrence_rule.rb +0 -82
  317. data/app/models/droom/user_action_observer.rb +0 -12
  318. data/app/views/devise/confirmations/failure.en.html.haml +0 -20
  319. data/app/views/devise/confirmations/show.html.haml +0 -19
  320. data/app/views/droom/confirmations/show.html.haml +0 -40
  321. data/app/views/droom/documents/_document_line.html.haml +0 -2
  322. data/app/views/droom/events/_created.html.haml +0 -2
  323. data/app/views/droom/folders/_attachments.html.haml +0 -3
  324. data/app/views/droom/pages/_contents.html.haml +0 -10
  325. data/app/views/droom/pages/_form.html.haml +0 -36
  326. data/app/views/droom/pages/_full_page.html.haml +0 -17
  327. data/app/views/droom/pages/_page.html.haml +0 -5
  328. data/app/views/droom/pages/_pages.html.haml +0 -2
  329. data/app/views/droom/pages/admin.html.haml +0 -24
  330. data/app/views/droom/pages/edit.html.haml +0 -1
  331. data/app/views/droom/pages/index.html.haml +0 -10
  332. data/app/views/droom/pages/new.html.haml +0 -4
  333. data/app/views/droom/pages/show.html.haml +0 -5
  334. data/app/views/droom/panels/_account.html.haml +0 -16
  335. data/app/views/droom/panels/_readers.html.haml +0 -18
  336. data/app/views/droom/panels/_suggestions.html.haml +0 -15
  337. data/app/views/droom/people/_action_menu.html.haml +0 -22
  338. data/app/views/droom/people/_created.html.haml +0 -6
  339. data/app/views/droom/people/_form.html.haml +0 -66
  340. data/app/views/droom/people/_listing.html.haml +0 -19
  341. data/app/views/droom/people/_memberships.html.haml +0 -24
  342. data/app/views/droom/people/_people.html.haml +0 -5
  343. data/app/views/droom/people/_person.html.haml +0 -32
  344. data/app/views/droom/people/_search_result.html.haml +0 -14
  345. data/app/views/droom/people/_suggested.html.haml +0 -14
  346. data/app/views/droom/people/edit.html.haml +0 -9
  347. data/app/views/droom/people/index.html.haml +0 -8
  348. data/app/views/droom/people/show.html.haml +0 -31
  349. data/app/views/droom/scraps/_heading.html.haml +0 -16
  350. data/app/views/droom/scraps/thumbs/_document.html.haml +0 -9
  351. data/app/views/droom/scraps/thumbs/_event.html.haml +0 -17
  352. data/app/views/droom/scraps/thumbs/_image.html.haml +0 -6
  353. data/app/views/droom/scraps/thumbs/_link.html.haml +0 -10
  354. data/app/views/droom/scraps/thumbs/_quote.html.haml +0 -8
  355. data/app/views/droom/scraps/thumbs/_text.html.haml +0 -8
  356. data/app/views/droom/scraps/thumbs/_video.html.haml +0 -6
  357. data/app/views/droom/users/_extra_columns_header.html.haml +0 -0
  358. data/app/views/droom/users/_extra_columns_note.html.haml +0 -0
  359. data/app/views/droom/users/_form.html.haml +0 -14
  360. data/app/views/droom/users/_password_fields.html.haml +0 -15
  361. data/app/views/droom/users/_user_or_person.html.haml +0 -72
  362. data/app/views/kaminari/_paginator.html.haml +0 -16
  363. data/lib/droom/dav_resource.rb +0 -36
  364. data/lib/droom/model_helpers.rb +0 -25
  365. data/lib/droom/routing.rb +0 -13
  366. data/spec/datasets/calendar_events_dataset.rb +0 -44
  367. data/spec/datasets/calendar_pages_dataset.rb +0 -8
  368. data/spec/datasets/calendar_sites_dataset.rb +0 -6
  369. data/spec/datasets/calendars_dataset.rb +0 -34
  370. data/spec/datasets/documents_dataset.rb +0 -28
  371. data/spec/datasets/recurrence_dataset.rb +0 -7
  372. data/spec/dummy/config/sunspot.yml +0 -17
  373. data/spec/dummy/log/dav.log +0 -1
  374. data/spec/dummy/log/development.log +0 -2
  375. data/spec/dummy/log/test.log +0 -1
  376. data/spec/dummy/solr/conf/admin-extra.html +0 -31
  377. data/spec/dummy/solr/conf/elevate.xml +0 -36
  378. data/spec/dummy/solr/conf/mapping-ISOLatin1Accent.txt +0 -246
  379. data/spec/dummy/solr/conf/protwords.txt +0 -21
  380. data/spec/dummy/solr/conf/schema.xml +0 -238
  381. data/spec/dummy/solr/conf/scripts.conf +0 -24
  382. data/spec/dummy/solr/conf/solrconfig.xml +0 -934
  383. data/spec/dummy/solr/conf/spellings.txt +0 -2
  384. data/spec/dummy/solr/conf/stopwords.txt +0 -58
  385. data/spec/dummy/solr/conf/synonyms.txt +0 -31
  386. data/spec/dummy/solr/data/development/index/segments.gen +0 -0
  387. data/spec/dummy/solr/data/development/index/segments_1 +0 -0
  388. data/spec/dummy/solr/data/development/spellchecker/segments.gen +0 -0
  389. data/spec/dummy/solr/data/development/spellchecker/segments_1 +0 -0
  390. data/spec/dummy/solr/data/test/index/segments.gen +0 -0
  391. data/spec/dummy/solr/data/test/index/segments_3nu +0 -0
  392. data/spec/dummy/solr/data/test/spellchecker/segments.gen +0 -0
  393. data/spec/dummy/solr/data/test/spellchecker/segments_1 +0 -0
  394. data/spec/factories/recurrence_rules.rb +0 -25
  395. data/spec/models/droom/person_spec.rb +0 -72
  396. data/spec/models/droom/recurrence_rule_spec.rb +0 -81
@@ -4,52 +4,51 @@
4
4
 
5
5
  jQuery ($) ->
6
6
 
7
- ## Form Widgets
8
- #
9
- # These attach to a form element and provide a nicer interface by which to update its content.
7
+ $.fn.date_picker = ()->
8
+ @each ->
9
+ new DatePicker(@)
10
10
 
11
11
  class DatePicker
12
+ @month_names: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
12
13
  constructor: (element) ->
13
14
  @_container = $(element)
14
- @_trigger = @_container.find('a')
15
- @_field = @_container.find('input')
16
- @_holder = @_container.find('div.kal')
17
- @_mon = @_container.find('span.mon')
18
- @_dom = @_container.find('span.dom')
19
- @_year = @_container.find('span.year')
20
- @_kal = new Kalendae @_holder[0]
21
- @_holder.hide()
22
- @_trigger.click @toggle
23
- @_container.click @contain
24
- @_kal.subscribe 'change', () =>
25
- @hide()
26
- @_field.val(@_kal.getSelected())
27
- [year, month, day] = @_kal.getSelected().split('-')
28
- @_year.text(year)
29
- @_dom.text(day)
30
- @_mon.text(Kalendae.moment.monthsShort[parseInt(month, 10) - 1])
31
-
32
- contain: (e) =>
33
- e.stopPropagation() if e
34
-
35
- toggle: (e) =>
36
- e.preventDefault() if e
37
- if @_holder.is(':visible') then @hide() else @show()
38
-
39
- show: () =>
40
- @_holder.fadeIn "fast", () =>
41
- @_container.addClass('editing')
42
- $(document).bind "click", @hide
43
-
44
- hide: () =>
45
- $(document).unbind "click", @hide
46
- @_container.removeClass('editing')
47
- @_holder.fadeOut("fast")
48
-
49
- $.fn.date_picker = () ->
50
- @each ->
51
- new DatePicker(@)
52
- @
15
+ if @_container.is("input")
16
+ @_field = @_container
17
+ @_event = 'focus'
18
+ @_simple = true
19
+ else
20
+ @_field = @_container.find('input')
21
+ @_event = 'click'
22
+ @_simple = false
23
+ @_mon = @_container.find('span.mon')
24
+ @_dom = @_container.find('span.dom')
25
+ @_year = @_container.find('span.year')
26
+ initial_date = @getDate()
27
+ @_container.DatePicker
28
+ calendars: 1
29
+ date: initial_date
30
+ current: initial_date
31
+ view: 'days'
32
+ position: 'bottom'
33
+ showOn: @_event
34
+ onChange: @setDate
35
+
36
+ getDate: () =>
37
+ if value = @_field.val()
38
+ new Date(Date.parse(value))
39
+
40
+ setDate: (date) =>
41
+ if date
42
+ $('.datepicker').hide()
43
+ d = $.zeroPad(date.getDate())
44
+ m = DatePicker.month_names[date.getMonth()]
45
+ y = date.getFullYear()
46
+ dateString = [y, m, d].join('-')
47
+ @_field.val(dateString)
48
+ unless @_simple
49
+ @_dom.text(d)
50
+ @_mon.text(m)
51
+ @_year.text(y)
53
52
 
54
53
 
55
54
  class TimePicker
@@ -86,92 +85,105 @@ jQuery ($) ->
86
85
  new TimePicker(@)
87
86
 
88
87
 
89
- #todo: this can now make proper use of the remote mechanism and doesn't need to take over the whole form any more.
90
- #
88
+
89
+
90
+ $.fn.file_picker = () ->
91
+ @each ->
92
+ new FilePicker @
93
+
94
+ $.fn.click_proxy = (target_selector) ->
95
+ this.bind "click", (e) ->
96
+ e.preventDefault()
97
+ $(target_selector).click()
98
+
91
99
  class FilePicker
92
100
  constructor: (element) ->
93
101
  @_container = $(element)
94
- @_form = if form = @_container.attr("data-form") then $(form) else @_container.parent()
95
- @_holder = @_form.parent()
96
- @_link = @_container.find('a.ul')
102
+ @_form = @_container.parents('form')
103
+ @_link = @_container.find('a[data-action="pick"]')
97
104
  @_filefield = @_container.find('input[type="file"]')
98
- @_tip = @_container.find('p.tip')
99
- @_link.click_proxy(@_filefield)
100
- @_extensions = ['doc', 'docx', 'pdf', 'xls', 'xlsx', 'jpg', 'png']
101
- @_filefield.bind 'change', @pick
102
105
  @_file = null
103
106
  @_filename = ""
104
107
  @_ext = ""
105
- @_fields = @_container.siblings('.metadata')
106
- @_form.submit @submit
107
-
108
- pick: (e) =>
109
- @_link.removeClass(@_extensions.join(' '))
108
+ @_fields = @_container.siblings('.non-file-data')
109
+ @_form.bind 'remote:upload', @initProgress
110
+ @_form.bind 'remote:progress', @progress
111
+ @_link.bind 'click', @picker
112
+ @_filefield.bind 'change', @picked
113
+
114
+ picker: (e) =>
115
+ e.preventDefault() if e
116
+ @_filefield.click()
117
+
118
+ extensions: () =>
119
+ @_extensions ?= ['doc', 'docx', 'pdf', 'xls', 'xlsx', 'jpg', 'png']
120
+
121
+ picked: (e) =>
122
+ @_link.removeClass(@extensions().join(' '))
110
123
  if files = @_filefield[0].files
111
- @_file = files.item(0)
112
- @_tip.hide()
113
- @showSelection() if @_file
114
-
115
- submit: (e) =>
116
- unless @_filefield.attr("disabled")
117
- if @_file
118
- e.preventDefault() if e
119
- @_fields.hide()
120
- @_notifier = $('<div class="notifier"></div>').appendTo @_form
121
- @_label = $('<h3 class="filename"></h3>').appendTo @_notifier
122
- @_progress = $('<div class="progress"></div>').appendTo @_notifier
123
- @_bar = $('<div class="bar"></div>').appendTo @_progress
124
- @_status = $('<div class="status"></div>').appendTo @_notifier
125
- @_label.text(@_filename)
126
- @send()
127
-
128
- showSelection: =>
129
- @_filename = @_file.name.split(/[\/\\]/).pop()
130
- @_ext = @_filename.split('.').pop()
131
- @_link.addClass(@_ext) if @_ext in @_extensions
132
- $('input.name').val(@_filename)# if $('input.name').val() is ""
133
-
134
- send: =>
135
- formData = new FormData @_form.get(0)
136
- @xhr = new XMLHttpRequest()
137
- @xhr.onreadystatechange = @update
138
- @xhr.upload.onprogress = @progress
139
- @xhr.upload.onloadend = @finish
140
- url = @_form.attr('action')
141
- @xhr.open 'POST', url, true
142
- @xhr.send formData
143
-
144
- progress: (e) =>
145
- @_status.text("Uploading. Please wait.")
146
- if e.lengthComputable
124
+ if @_file = files.item(0)
125
+ @_previous_filename = @_filename ? ""
126
+ @_filename = @_file.name.split(/[\/\\]/).pop()
127
+ @_ext = @_filename.split('.').pop()
128
+ @display()
129
+
130
+ display: () =>
131
+ @_link.addClass(@_ext) if @_ext in @extensions()
132
+ @_form.find('input.name').val(@_filename) if $('input.name').val() is @_previous_filename
133
+
134
+ initProgress: (e, xhr, settings) =>
135
+ if @_file?
136
+ @_fields.hide()
137
+ @_notifier = $('<div class="notifier"></div>').appendTo @_form
138
+ @_label = $('<h3 class="filename"></h3>').appendTo @_notifier
139
+ @_progress = $('<div class="progress"></div>').appendTo @_notifier
140
+ @_bar = $('<div class="bar"></div>').appendTo @_progress
141
+ @_label.text(@_filename)
142
+ true
143
+
144
+ progress: (e, prog) =>
145
+ if @_file? and prog.lengthComputable
147
146
  full_width = @_progress.width()
148
- progress_width = Math.round(full_width * e.loaded / e.total)
147
+ progress_width = Math.round(full_width * prog.loaded / prog.total)
149
148
  @_bar.width progress_width
150
149
 
151
- update: =>
152
- if @xhr.readyState == 4
153
- if @xhr.status == 200
154
- response = @xhr.responseText
155
- @_form.remove()
156
- @_holder.append(response)
157
- @_holder.trigger "finished", response
150
+ remover: () =>
151
+ unless @_remover?
152
+ @_remover = $('<a href="#" class="remover" />').insertAfter(@_link)
153
+ @_remover.click @remove
154
+ @_remover
158
155
 
159
- finish: (e) =>
160
- @_status.text("Indexing for search. Please wait.")
161
- @_bar.css
162
- "background-color": "green"
156
+ remove: (e) =>
157
+ e.preventDefault() if e
158
+ old_ff = @_filefield
159
+ @_filefield = old_ff.clone().insertAfter(old_ff)
160
+ @_filefield.bind 'change', @picked
161
+ old_ff.remove()
162
+ @_form.find('input.name').val("") if $('input.name').val() is @_filename
163
+ @_filename = ""
164
+ @_ext = ""
165
+ @_remover?.hide()
166
+ @_link.css
167
+ "background-image": @_original_background
163
168
 
164
169
 
165
170
 
166
- $.fn.file_picker = () ->
167
- @each ->
168
- new FilePicker @
169
171
 
170
- $.fn.click_proxy = (target_selector) ->
171
- this.bind "click", (e) ->
172
- e.preventDefault()
173
- $(target_selector).click()
174
172
 
173
+ $.fn.image_picker = () ->
174
+ @each ->
175
+ new ImagePicker @
176
+
177
+ class ImagePicker extends FilePicker
178
+ display: () =>
179
+ @_form.find('input.name').val(@_filename) if $('input.name').val() is @_previous_filename
180
+ @_original_background ?= @_link.css("background-image")
181
+ reader = new FileReader()
182
+ reader.onload = (e) =>
183
+ @_link.css
184
+ "background-image": "url(#{reader.result})"
185
+ @remover().show()
186
+ reader.readAsDataURL(@_file)
175
187
 
176
188
 
177
189
 
@@ -217,6 +229,10 @@ jQuery ($) ->
217
229
  @_field.val(i)
218
230
 
219
231
 
232
+
233
+
234
+
235
+
220
236
  $.fn.password_form = ->
221
237
  @each ->
222
238
  new PasswordForm(@)
@@ -242,7 +258,6 @@ jQuery ($) ->
242
258
  @fields.attr('data-strict', false)
243
259
  @unsubmittable()
244
260
  @confirmation_holder.hide()
245
- console.log 'password form', @
246
261
 
247
262
  checkForm: () =>
248
263
  @fields.removeClass('invalid').addClass('valid')
@@ -282,183 +297,177 @@ jQuery ($) ->
282
297
  if @blocked
283
298
  e.preventDefault()
284
299
  else
285
- # might as well debounce, since we're here
286
300
  @submit.val('please wait')
287
301
  @unsubmittable()
288
302
 
289
303
 
290
- # A captive form submits via an ajax request and pushes its results into the present page in the place
291
- # designated by its 'replacing' attribute.
304
+
305
+
306
+
307
+
308
+ # The basic captive form is a fairly dumb binding between form element and target element.
309
+ # The form is submitted over ajax and the response is displayed in the target.
310
+ #
311
+ # If options.fast is true then any change to an input or select within the form will trigger submission.
312
+ # If options.auto is true then the form will be submitted immediately; more commonly the target is already
313
+ # populated.
292
314
  #
293
- # If options['fast'] is true, the form will submit on every change to a text, radio or checkbox input.
315
+ #todo: this really needs debouncing.
294
316
  #
295
- #todo: This is very old now. Tidy it up with a more standard action structure, and fewer options.
317
+ # There is some slack in the internal structure here because subclasses do more intermediate work.
296
318
 
297
319
  $.fn.captive = (options) ->
298
320
  @each ->
299
321
  new CaptiveForm @, options
300
322
  @
301
323
 
324
+ # The filter form is a fast captive with only one input.
325
+ # It ought to have a cache too, since there is a simple key.
326
+
327
+ $.fn.filter_form = (options) ->
328
+ @each ->
329
+ new CaptiveForm @,
330
+ fast: true
331
+ into: "#found"
332
+ auto: false
333
+ history: false
334
+ @
335
+
336
+ $.fn.table_filter_form = (options) ->
337
+ @each ->
338
+ new CaptiveForm @,
339
+ fast: true
340
+ into: "table"
341
+ auto: false
342
+ history: true
343
+ @
344
+
345
+ # The suggestions form is a fast filter form with history support
346
+ #
347
+ $.fn.suggestion_form = (options) ->
348
+ @each ->
349
+ new CaptiveForm @,
350
+ fast: true
351
+ auto: false
352
+ into: "#suggestion_box"
353
+ history: false
354
+ @
355
+
356
+
302
357
  class CaptiveForm
358
+ @default_options: {
359
+ fast: false
360
+ auto: false
361
+ threshold: 3
362
+ history: false
363
+ }
364
+
303
365
  constructor: (element, opts) ->
304
366
  @_form = $(element)
305
- @_options = $.extend {
306
- fast: false
307
- auto: false
308
- historical: false
309
- }, opts
367
+ @_options = $.extend @constructor.default_options, opts
368
+ @_historical = !!(Modernizr.history and @_options.history or @_form.attr('data-historical'))
310
369
  @_selector = @_form.attr('data-target') || @_options.into
311
370
  @_container = $(@_selector)
371
+ @_original_qs = @serialize()
312
372
  @_original_content = @_container.html()
313
- @_prompt = @_form.find("input[type=\"text\"]")
314
373
  @_request = null
374
+ @_inactive = false
375
+ @_cache = {}
376
+ @_form.bind 'refresh', () =>
377
+ @_form.submit()
315
378
  @_form.remote
316
- on_submit: @prepare
379
+ on_request: @prepare
317
380
  on_cancel: @cancel
318
381
  on_success: @capture
319
- if @_options.fast
320
- @_form.find("input[type=\"text\"]").keyup @keyed
321
- @_form.find("input[type=\"text\"]").change @submit
322
- @_form.find("input[type=\"radio\"]").click @clicked
323
- @_form.find("input[type=\"checkbox\"]").click @clicked
382
+ @submit_soon = _.debounce(@submit, 500)
383
+ @bindInputs() if @_options.fast
384
+ @_form.bind 'refresh', @changed
324
385
  @submit() if @_options.auto
325
-
386
+ if @_historical
387
+ @saveState(@_original_content)
388
+ $(window).bind 'popstate', @restoreState
389
+
390
+ bindInputs: () =>
391
+ @_form.find('input[type="search"]').bind 'keyup', @changed
392
+ @_form.find('input[type="search"]').bind 'change', @changed
393
+ # @_form.find('input[type="search"]').bind 'click', @changed # for the clear-box control in webkit search fields
394
+ @_form.find('input[type="text"]').bind 'keyup', @keyed
395
+ @_form.find('input[type="text"]').bind 'change', @changed
396
+ @_form.find('select').bind 'change', @changed
397
+ @_form.find('input[type="radio"]').bind 'click', @clicked
398
+ @_form.find('input[type="checkbox"]').bind 'click', @clicked
399
+
326
400
  keyed: (e) =>
327
401
  k = e.which
328
- if (k >= 32 and k <= 165) or k == 8
329
- if @_prompt.val() is "" and not @_options.auto
330
- @revert()
331
- else
332
- @submit()
402
+ if k is 13
403
+ @submit(e)
404
+ if (k >= 46 and k <= 90) or (k >= 96 and k <= 111) or k is 8
405
+ @changed(e)
406
+
407
+ changed: (e) =>
408
+ @submit_soon() unless @_inactive
333
409
 
334
410
  clicked: (e) =>
335
- @submit()
411
+ @submit_soon() unless @_inactive
412
+
413
+ serialize: () =>
414
+ parameters = []
415
+ @_form.find(":input").each (i, f) =>
416
+ field = $(f)
417
+ parameters.push field.serialize() unless field.val() is ""
418
+ parameters.join('&')
336
419
 
337
- submit: (e) =>
338
- @_form.submit()
420
+ submit: (e, nocache) =>
421
+ e.preventDefault() if e
422
+ nocache ?= false
423
+ qs = @serialize()
424
+ if !nocache and @_cache[qs]
425
+ @display(@_cache[qs])
426
+ else
427
+ @_form.submit()
339
428
 
340
429
  prepare: (xhr, settings) =>
341
430
  @_container.fadeTo "fast", 0.2
342
- @_request.abort() if @_request
343
- @_request = xhr
344
431
 
345
- capture: (data, status, xhr) =>
432
+ capture: (e, data, status, xhr) =>
433
+ @_cache[@serialize()] = data
346
434
  @display(data)
347
- @_request = null
348
-
435
+ @saveState(data) if @_historical
436
+
349
437
  display: (results) =>
350
438
  replacement = $(results)
351
439
  @_container.empty().append(replacement).fadeTo("fast", 1)
352
440
  replacement.activate()
353
441
  replacement.find('a.cancel').click(@revert)
354
-
442
+
355
443
  revert: (e) =>
356
- e.preventDefault() if e
357
444
  @display(@_original_content)
358
- @_prompt.val("")
359
- @saveState()
360
-
361
-
362
- $.fn.filter_form = (options) ->
363
- options = $.extend(
364
- fast: true
365
- auto: true
366
- into: "#found"
367
- , options)
368
- @each ->
369
- new CaptiveForm @, options
370
- @
371
-
372
-
373
-
374
- # The suggestions form is a fast captive with history support based on a single prompt field.
375
- #
376
- $.fn.suggestion_form = (options) ->
377
- options = $.extend(
378
- fast: true
379
- auto: false
380
- into: "#suggestion_box"
381
- , options)
382
- @each ->
383
- new SuggestionForm @, options
384
- @
385
-
386
- class SuggestionForm extends CaptiveForm
387
- constructor: (element, opts) ->
388
- super
389
- @_prompt = @_form.find("input[type=\"text\"]")
390
- @_param = @_prompt.attr('name')
391
- @_original_term = decodeURIComponent($.urlParam(@_param))
392
- if @_original_term and @_original_term isnt "false" and @_original_term isnt ""
393
- @_prompt.val(@_original_term)
394
- @submit()
395
- if Modernizr.history
396
- $(window).bind 'popstate', @restoreState
397
445
 
398
- capture: (data, status, xhr) =>
399
- @saveState(data) if Modernizr.history
400
- super
401
-
402
- saveState: (results) =>
403
- results ?= @_original_content
404
- term = @_prompt.val()
405
- if term
406
- url = window.location.pathname + "?" + encodeURIComponent(@_param) + "=" + encodeURIComponent(term)
407
- else
408
- url = window.location.pathname
446
+ saveState: (results, qs) =>
447
+ qs ?= @serialize()
448
+ url = window.location.pathname + "?" + qs
449
+ title = document.title + ' search'
409
450
  state =
410
451
  html: results
411
- term: term
412
- history.pushState state, "Search results", url
413
-
452
+ qs: qs
453
+ history.pushState state, title, url
454
+
414
455
  restoreState: (e) =>
415
456
  event = e.originalEvent
457
+ e.preventDefault() if e
416
458
  if event.state? && event.state.html?
417
459
  @display event.state.html
418
- @_prompt.val(event.state.term)
460
+ @_inactive = true
461
+ @_form.deserialize(event.state.qs)
462
+ @_inactive = false
463
+
464
+
419
465
 
420
466
 
421
- # The preferences form is a simple captive that just displays a confirmation message, with or without some control
422
- # links (eg to copy or delete dropboxed folders). It may also include a number of preference blocks, which take care
423
- # of showing and hiding subsidiary options.
424
467
 
425
- $.fn.preferences_form = (options) ->
426
- options = $.extend(
427
- fast: true
428
- clearing: null
429
- replacing: ".confirmation"
430
- , options)
431
- @each ->
432
- $(@).find('span.preference').preferences_block()
433
- new CaptiveForm @, options
434
468
 
435
- # The preferences block is a very minimal subcontent toggle. If the first contained radio or checkbox element
436
- # is checked, anything `.subpreference` is revealed. If its state changes, we show or hide.
437
- #
438
- # Note that to make this work with radio buttons we have applied a small hack to make sure they fire a change event
439
- # on deselection. See $.trigger_change_on_deselect in utilities.js.
440
469
 
441
- $.fn.preferences_block = ->
442
- @each ->
443
- new PreferenceBlock(@)
444
470
 
445
- class PreferenceBlock
446
- constructor: (element) ->
447
- @_container = $(element)
448
- @_input = @_container.find("> input")
449
- @_subprefs = @_container.find('span.subpreference')
450
- if @_subprefs.length
451
- @_input.trigger_change_on_deselect()
452
- @_input.change @set
453
- @set()
454
-
455
- set: (e) =>
456
- # let the event through...
457
- if @_input.is(":checked") then @show() else @hide()
458
- show: () =>
459
- @_subprefs.slideDown()
460
- hide: () =>
461
- @_subprefs.slideUp()
462
471
 
463
472
 
464
473
  # HTML-editing support is provided by WysiHTML, which is an ugly but effective iframe-based solution.
@@ -526,6 +535,7 @@ jQuery ($) ->
526
535
  class Folder
527
536
  constructor: (element) ->
528
537
  @_container = $(element)
538
+ @_label = @_container.attr('data-label')
529
539
  @_list = @_container.children('ul.filing')
530
540
  if @_list[0]
531
541
  @_container.children('a.folder').click @toggle
@@ -533,7 +543,14 @@ jQuery ($) ->
533
543
 
534
544
  set: (e) =>
535
545
  e.preventDefault() if e
536
- if @_container.hasClass('open') then @show() else @hide()
546
+ @_state = localStorage?.getItem("show_folder_#{@_label}")
547
+ @_state ?= @_container.hasClass('open') ? "open" : "closed"
548
+ if @_state is "open"
549
+ @_container.addClass("open")
550
+ @_list.show()
551
+ else
552
+ @_container.removeClass("open")
553
+ @_list.hide()
537
554
 
538
555
  toggle: (e) =>
539
556
  if e
@@ -543,15 +560,47 @@ jQuery ($) ->
543
560
 
544
561
  show: (e) =>
545
562
  e.preventDefault() if e
563
+ localStorage?.setItem("show_folder_#{@_label}", "open")
546
564
  @_container.addClass('open')
547
565
  @_list.stop().slideDown("fast")
548
566
 
549
567
  hide: (e) =>
550
568
  e.preventDefault() if e
569
+ localStorage?.setItem("show_folder_#{@_label}", "closed")
551
570
  @_list.stop().slideUp "normal", () =>
552
571
  @_container.removeClass('open')
553
572
 
554
573
 
574
+ $.fn.slug_field = ->
575
+ @each ->
576
+ new SlugField(@)
577
+
578
+ class SlugField
579
+ constructor: (element) ->
580
+ @_field = $(element)
581
+ @_form = @_field.parents('form')
582
+ selector = @_field.attr('data-base') or 'input[data-role="name"]'
583
+ @_base = @_form.find(selector)
584
+ @_base.bind "keyup", @update
585
+ @_previous_base = @_base.val()
586
+ @set()
587
+
588
+ update: (e) =>
589
+ @set() if $.significantKeypress(e.which)
590
+
591
+ set: () =>
592
+ old_base = @_previous_base
593
+ old_slug = @_field.val()
594
+ new_base = @_base.val()
595
+ # if no slug, or if slug looks like it was set automatically
596
+ if old_slug is "" or old_slug is @slugify(old_base)
597
+ @_field.val @slugify(new_base)
598
+ @_previous_base = new_base
599
+
600
+ slugify: (string) =>
601
+ string.replace(/[^\w\d]+/g, '-').toLowerCase()
602
+
603
+
555
604
  # The Calendar widget is a display of one calendar month in the usual tabular format.
556
605
  # Here we wrap it in a scrolling div to support movement from one month to another and
557
606
  # hook it up to the suggestion box, if that's on the page, so that clicking a day or month
@@ -596,7 +645,7 @@ jQuery ($) ->
596
645
  @_bar = $('<div class="starbar" />').appendTo(@_container)
597
646
  @_mask = $('<div class="starmask" />').appendTo(@_container)
598
647
  @_bar.css
599
- width: @_rating/5 * 80
648
+ width: @_rating / 5 * 80
600
649
 
601
650
  $.fn.star_rating = () ->
602
651
  @each ->
@@ -642,7 +691,7 @@ jQuery ($) ->
642
691
  defaultSelector: () =>
643
692
  '.scrap'
644
693
 
645
- receive: (r) =>
694
+ receive: (e, r) =>
646
695
  response = $(r)
647
696
  @sweep response
648
697
  response.activate()
@@ -766,10 +815,9 @@ jQuery ($) ->
766
815
  old.remove()
767
816
  @init()
768
817
 
769
- # This use of moment depends on the loading of Kalendae, which we use for the date-picker widget above.
770
- #
771
818
  monthName: () =>
772
- Kalendae.moment.months[@_month-1]
819
+ months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
820
+ months[@_month-1]
773
821
 
774
822
  searchForm: =>
775
823
  @_form ?= $('#suggestions')
@@ -811,6 +859,7 @@ jQuery ($) ->
811
859
  submit_form: false
812
860
  threshold: 1
813
861
  type: 'venue'
862
+ width: 300
814
863
  , options)
815
864
  @each ->
816
865
  new Suggester(@, options)
@@ -886,6 +935,7 @@ jQuery ($) ->
886
935
  empty_field: false
887
936
  submit_form: false
888
937
  preload: false
938
+ width: "auto"
889
939
  threshold: 2
890
940
  limit: 10
891
941
  afterSuggest: null
@@ -900,6 +950,7 @@ jQuery ($) ->
900
950
  @dropdown = new Dropdown @prompt,
901
951
  on_select: @select
902
952
  on_keyup: @get
953
+ width: @options.width
903
954
  @button = @form.find("a.search")
904
955
  @previously = null
905
956
  @request = null
@@ -912,6 +963,8 @@ jQuery ($) ->
912
963
  @prompt.bind "paste", @get
913
964
  @form.submit @hide
914
965
  @get(null, true) if @options.preload
966
+
967
+ console.log "suggester", @
915
968
  @
916
969
 
917
970
  reset: () =>
@@ -974,7 +1027,7 @@ jQuery ($) ->
974
1027
 
975
1028
 
976
1029
 
977
- $.fn.video_picker = (options) ->
1030
+ $.fn.youtube_suggester = (options) ->
978
1031
  options = $.extend(
979
1032
  submit_form: true
980
1033
  threshold: 3
@@ -989,9 +1042,10 @@ jQuery ($) ->
989
1042
  class YoutubeSuggester extends Suggester
990
1043
  constructor: () ->
991
1044
  super
992
- @target = $('textarea#scrap_body')
993
- @caption = $('textarea#scrap_note')
994
- @thumb = $('.scrapvideo .thumb')
1045
+ @target = $('input#scrap_youtube_id')
1046
+ @name_field = $('input#scrap_name')
1047
+ @preview_holder = $('div.youtube_preview')
1048
+ @thumb_holder = @prompt.siblings('.thumbnail')
995
1049
 
996
1050
  suggest: (suggestions) =>
997
1051
  @unwait()
@@ -1006,15 +1060,24 @@ jQuery ($) ->
1006
1060
  select: (value, id) =>
1007
1061
  @hide()
1008
1062
  @prompt.trigger 'suggester.change'
1009
- @target.val(id)
1063
+ @prompt.val(id)
1010
1064
  title = $("<div>#{value}</div>").find('.title')
1011
- @caption.val(title.text()) if @caption.val() is ""
1012
- $.get "/videos/#{id}.js", @preview, 'html'
1065
+ @name_field.val(title.text()) if @name_field.val() is ""
1066
+ @get_preview(id)
1067
+ @get_thumbnail(id)
1013
1068
  @options.afterSelect?.call(@, value)
1014
1069
 
1015
- preview: (html) =>
1016
- @thumb.empty().html(html)
1017
-
1070
+ get_preview: (id) =>
1071
+ $.get "/videos/#{id}.js", @show_preview, 'html'
1072
+
1073
+ show_preview: (response) =>
1074
+ @preview_holder.empty().show().html(response)
1075
+
1076
+ get_thumbnail: (id) =>
1077
+ @thumb_holder.css
1078
+ "background-image": "url('http://img.youtube.com/vi/#{id}/3.jpg')"
1079
+
1080
+
1018
1081
 
1019
1082
  # I've just lifted this out of the suggester so that it can be used in other pickers.
1020
1083
 
@@ -1032,10 +1095,12 @@ jQuery ($) ->
1032
1095
  @
1033
1096
 
1034
1097
  place: () =>
1098
+ unless width = @options.width
1099
+ width = @hook.outerWidth() - 2
1035
1100
  @drop.css
1036
1101
  top: @hook.position().top + @hook.outerHeight() - 2
1037
1102
  left: @hook.position().left
1038
- width: @hook.outerWidth() - 2
1103
+ width: width
1039
1104
 
1040
1105
  populate: (items) =>
1041
1106
  @reset()