droom 0.4.3 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,1692 +0,0 @@
1
- /********************************************************************
2
- * Kalendae, a framework agnostic javascript date picker *
3
- * Copyright(c) 2012 Jarvis Badgley (chipersoft@gmail.com) *
4
- * http://github.com/ChiperSoft/Kalendae *
5
- * Version 0.2.6 *
6
- ********************************************************************/
7
-
8
- (function (undefined) {
9
-
10
- var today;
11
-
12
- var Kalendae = function (targetElement, options) {
13
- if (typeof document.addEventListener !== 'function') return;
14
-
15
- //if the first argument isn't an element and isn't a string, assume that it is the options object
16
- var is_element = false;
17
- try {
18
- is_element = targetElement instanceof Element;
19
- }
20
- catch (err) {
21
- is_element = !!targetElement && is_element.nodeType === 1;
22
- }
23
- if (!(is_element || typeof(targetElement) === 'string')) options = targetElement;
24
-
25
- var self = this,
26
- classes = self.classes,
27
- opts = self.settings = util.merge(self.defaults, {attachTo:targetElement}, options || {}),
28
- $container = self.container = util.make('div', {'class':classes.container}),
29
- calendars = self.calendars = [],
30
- startDay = moment().day(opts.weekStart),
31
- vsd,
32
- columnHeaders = [],
33
- $cal,
34
- $title,
35
- $caption,
36
- $header,
37
- $days, dayNodes = [],
38
- $span,
39
- i = 0,
40
- j = opts.months;
41
-
42
- if (util.isIE8()) util.addClassName($container, 'ie8');
43
-
44
- //generate the column headers (Su, Mo, Tu, etc)
45
- i = 7;
46
- while (i--) {
47
- columnHeaders.push( startDay.format('ddd').substr(0,opts.columnHeaderLength) );
48
- startDay.add('days',1);
49
- }
50
-
51
- //setup publish/subscribe and apply any subscriptions passed in settings
52
- MinPubSub(self);
53
- if (typeof opts.subscribe === 'object') {
54
- for (i in opts.subscribe) if (opts.subscribe.hasOwnProperty(i)) {
55
- self.subscribe(i, opts.subscribe[i]);
56
- }
57
- }
58
-
59
- //process default selected dates
60
- self._sel = [];
61
- if (!!opts.selected) self.setSelected(opts.selected, false);
62
-
63
- //set the view month
64
- if (!!opts.viewStartDate) {
65
- vsd = moment(opts.viewStartDate, opts.format);
66
- } else if (self._sel.length > 0) {
67
- vsd = moment(self._sel[0]);
68
- } else {
69
- vsd = moment();
70
- }
71
- self.viewStartDate = vsd.date(1);
72
-
73
- var viewDelta = ({
74
- 'past' : opts.months-1,
75
- 'today-past' : opts.months-1,
76
- 'any' : opts.months>2?Math.floor(opts.months/2):0,
77
- 'today-future' : 0,
78
- 'future' : 0
79
- })[this.settings.direction];
80
-
81
-
82
- if (viewDelta && moment().month()==moment(self.viewStartDate).month()){
83
- self.viewStartDate = moment(self.viewStartDate).subtract({M:viewDelta}).date(1);
84
- }
85
-
86
-
87
- if (typeof opts.blackout === 'function') {
88
- self.blackout = opts.blackout;
89
- } else if (!!opts.blackout) {
90
- var bdates = parseDates(opts.blackout, opts.parseSplitDelimiter);
91
- self.blackout = function (input) {
92
- input = moment(input).yearDay();
93
- if (input < 1 || !self._sel || self._sel.length < 1) return false;
94
- var i = bdates.length;
95
- while (i--) if (bdates[i].yearDay() === input) return true;
96
- return false;
97
- }
98
- } else {
99
- self.blackout = function () {return false;}
100
- }
101
-
102
-
103
- self.direction = self.directions[opts.direction] ? self.directions[opts.direction] : self.directions['any'];
104
-
105
-
106
- //for the total months setting, generate N calendar views and add them to the container
107
- j = Math.max(opts.months,1);
108
- while (j--) {
109
- $cal = util.make('div', {'class':classes.calendar}, $container);
110
-
111
- $cal.setAttribute('data-cal-index', j);
112
- if (opts.months > 1) {
113
- if (j == Math.max(opts.months-1,1)) util.addClassName($cal, classes.monthFirst);
114
- else if (j === 0) util.addClassName($cal, classes.monthLast);
115
- else util.addClassName($cal, classes.monthMiddle);
116
- }
117
-
118
- //title bar
119
- $title = util.make('div', {'class':classes.title}, $cal);
120
- util.make('a', {'class':classes.previousYear}, $title); //previous button
121
- util.make('a', {'class':classes.previousMonth}, $title); //previous button
122
- util.make('a', {'class':classes.nextYear}, $title); //next button
123
- util.make('a', {'class':classes.nextMonth}, $title); //next button
124
- $caption = util.make('span', {'class':classes.caption}, $title); //title caption
125
-
126
- //column headers
127
- $header = util.make('div', {'class':classes.header}, $cal);
128
- i = 0;
129
- do {
130
- $span = util.make('span', {}, $header);
131
- $span.innerHTML = columnHeaders[i];
132
- } while (++i < 7)
133
-
134
- //individual day cells
135
- $days = util.make('div', {'class':classes.days}, $cal);
136
- i = 0;
137
- dayNodes = [];
138
- while (i++ < 42) {
139
- dayNodes.push(util.make('span', {}, $days));
140
- }
141
-
142
- //store each calendar view for easy redrawing
143
- calendars.push({
144
- caption:$caption,
145
- days:dayNodes
146
- });
147
-
148
- if (j) util.make('div', {'class':classes.monthSeparator}, $container);
149
- }
150
-
151
- self.draw();
152
-
153
- util.addEvent($container, 'mousedown', function (event, target) {
154
- var clickedDate;
155
- if (util.hasClassName(target, classes.nextMonth)) {
156
- //NEXT MONTH BUTTON
157
- if (!self.disableNext && self.publish('view-changed', self, ['next-month']) !== false) {
158
- self.viewStartDate.add('months',1);
159
- self.draw();
160
- }
161
- return false;
162
-
163
- } else if (util.hasClassName(target, classes.previousMonth)) {
164
- //PREVIOUS MONTH BUTTON
165
- if (!self.disablePreviousMonth && self.publish('view-changed', self, ['previous-month']) !== false) {
166
- self.viewStartDate.subtract('months',1);
167
- self.draw();
168
- }
169
- return false;
170
-
171
- } else if (util.hasClassName(target, classes.nextYear)) {
172
- //NEXT MONTH BUTTON
173
- if (!self.disableNext && self.publish('view-changed', self, ['next-year']) !== false) {
174
- self.viewStartDate.add('years',1);
175
- self.draw();
176
- }
177
- return false;
178
-
179
- } else if (util.hasClassName(target, classes.previousYear)) {
180
- //PREVIOUS MONTH BUTTON
181
- if (!self.disablePreviousMonth && self.publish('view-changed', self, ['previous-year']) !== false) {
182
- self.viewStartDate.subtract('years',1);
183
- self.draw();
184
- }
185
- return false;
186
-
187
-
188
-
189
- } else if (util.hasClassName(target.parentNode, classes.days) && util.hasClassName(target, classes.dayActive) && (clickedDate = target.getAttribute('data-date'))) {
190
- //DAY CLICK
191
- clickedDate = moment(clickedDate, opts.dayAttributeFormat).hours(12);
192
- if (self.publish('date-clicked', self, [clickedDate]) !== false) {
193
-
194
- switch (opts.mode) {
195
- case 'multiple':
196
- if (!self.addSelected(clickedDate)) self.removeSelected(clickedDate);
197
- break;
198
- case 'range':
199
- self.addSelected(clickedDate);
200
- break;
201
- case 'single':
202
- /* falls through */
203
- default:
204
- self.addSelected(clickedDate);
205
- break;
206
- }
207
-
208
- }
209
- return false;
210
-
211
- }
212
- return false;
213
- });
214
-
215
-
216
- if (!!(opts.attachTo = util.$(opts.attachTo))) {
217
- opts.attachTo.appendChild($container);
218
- }
219
-
220
- };
221
-
222
- Kalendae.prototype = {
223
- defaults : {
224
- attachTo: null, /* the element to attach the root container to. can be string or DOMElement */
225
- months: 1, /* total number of months to display side by side */
226
- weekStart: 0, /* day to use for the start of the week. 0 is Sunday */
227
- direction: 'any', /* past, today-past, any, today-future, future */
228
- directionScrolling: true, /* if a direction other than any is defined, prevent scrolling out of range */
229
- viewStartDate: null, /* date in the month to display. When multiple months, this is the left most */
230
- blackout: null, /* array of dates, or function to be passed a date */
231
- selected: null, /* dates already selected. can be string, date, or array of strings or dates. */
232
- mode: 'single', /* single, multiple, range */
233
- format: null, /* string used for parsing dates. */
234
- subscribe: null, /* object containing events to subscribe to */
235
-
236
- columnHeaderLength: 2, /* number of characters to show in the column headers */
237
- titleFormat: 'MMMM, YYYY', /* format mask for month titles. See momentjs.com for rules */
238
- dayNumberFormat: 'D', /* format mask for individual days */
239
- dayAttributeFormat: 'YYYY-MM-DD', /* format mask for the data-date attribute set on every span */
240
- parseSplitDelimiter: /,\s*|\s+-\s+/, /* regex to use for splitting multiple dates from a passed string */
241
- rangeDelimiter: ' - ', /* string to use between dates when outputting in range mode */
242
- multipleDelimiter: ', ', /* string to use between dates when outputting in multiple mode */
243
-
244
- dateClassMap: {}
245
- },
246
- classes : {
247
- container :'kalendae',
248
- calendar :'k-calendar',
249
- monthFirst :'k-first-month',
250
- monthMiddle :'k-middle-month',
251
- monthLast :'k-last-month',
252
- title :'k-title',
253
- previousMonth :'k-btn-previous-month',
254
- nextMonth :'k-btn-next-month',
255
- previousYear :'k-btn-previous-year',
256
- nextYear :'k-btn-next-year',
257
- caption :'k-caption',
258
- header :'k-header',
259
- days :'k-days',
260
- dayOutOfMonth :'k-out-of-month',
261
- dayActive :'k-active',
262
- daySelected :'k-selected',
263
- dayInRange :'k-range',
264
- dayToday :'k-today',
265
- monthSeparator :'k-separator',
266
- disablePreviousMonth :'k-disable-previous-month-btn',
267
- disableNextMonth :'k-disable-next-month-btn',
268
- disablePreviousYear :'k-disable-previous-year-btn',
269
- disableNextYear :'k-disable-next-year-btn'
270
- },
271
-
272
- disablePreviousMonth: false,
273
- disableNextMonth: false,
274
- disablePreviousYear: false,
275
- disableNextYear: false,
276
-
277
- directions: {
278
- 'past' :function (date) {return moment(date).yearDay() >= today.yearDay();},
279
- 'today-past' :function (date) {return moment(date).yearDay() > today.yearDay();},
280
- 'any' :function (date) {return false;},
281
- 'today-future' :function (date) {return moment(date).yearDay() < today.yearDay();},
282
- 'future' :function (date) {return moment(date).yearDay() <= today.yearDay();}
283
- },
284
-
285
- getSelectedAsDates : function () {
286
- var out = [];
287
- var i=0, c = this._sel.length;
288
- for (;i<c;i++) {
289
- out.push(this._sel[i].toDate());
290
- }
291
- return out;
292
- },
293
-
294
- getSelectedAsText : function (format) {
295
- var out = [];
296
- var i=0, c = this._sel.length;
297
- for (;i<c;i++) {
298
- out.push(this._sel[i].format(format || this.settings.format || 'YYYY-MM-DD'))
299
- }
300
- return out;
301
- },
302
-
303
- getSelectedRaw : function () {
304
- var out = [];
305
- var i=0, c = this._sel.length;
306
- for (;i<c;i++) {
307
- out.push(moment(this._sel[i]))
308
- }
309
- return out;
310
- },
311
-
312
- getSelected : function (format) {
313
- var sel = this.getSelectedAsText(format);
314
- switch (this.settings.mode) {
315
- case 'range':
316
- sel.splice(2); //shouldn't be more than two, but lets just make sure.
317
- return sel.join(this.settings.rangeDelimiter);
318
-
319
- case 'multiple':
320
- return sel.join(this.settings.multipleDelimiter);
321
-
322
- case 'single':
323
- /* falls through */
324
- default:
325
- return sel[0];
326
- }
327
- },
328
-
329
- isSelected : function (input) {
330
- input = moment(input).yearDay();
331
- if (input < 1 || !this._sel || this._sel.length < 1) return false;
332
-
333
- switch (this.settings.mode) {
334
- case 'range':
335
- var a = this._sel[0] ? this._sel[0].yearDay() : 0,
336
- b = this._sel[1] ? this._sel[1].yearDay() : 0;
337
-
338
- if (a === input || b === input) return 1;
339
- if (!a || !b) return 0;
340
-
341
- if ((input > a && input < b) || (a<b && input < a && input > b)) return -1;
342
- return false;
343
-
344
- case 'multiple':
345
- var i = this._sel.length;
346
- while (i--) {
347
- if (this._sel[i].yearDay() === input) {
348
- return true;
349
- }
350
- }
351
- return false;
352
-
353
-
354
- case 'single':
355
- /* falls through */
356
- default:
357
- return (this._sel[0] && (this._sel[0].yearDay() === input));
358
- }
359
-
360
- return false;
361
- },
362
-
363
- setSelected : function (input, draw) {
364
- this._sel = parseDates(input, this.settings.parseSplitDelimiter, this.settings.format);
365
- this._sel.sort(function (a,b) {return a.yearDay() - b.yearDay();});
366
-
367
- if (draw !== false) this.draw();
368
- },
369
-
370
- addSelected : function (date, draw) {
371
- date = moment(date).hours(12);
372
- switch (this.settings.mode) {
373
- case 'multiple':
374
- if (!this.isSelected(date)) this._sel.push(date);
375
- else return false;
376
- break;
377
- case 'range':
378
-
379
- if (this._sel.length !== 1) this._sel = [date];
380
- else {
381
- if (date.yearDay() > this._sel[0].yearDay()) this._sel[1] = date;
382
- else this._sel = [date, this._sel[0]];
383
- }
384
- break;
385
- case 'single':
386
- /* falls through */
387
- default:
388
- this._sel = [date];
389
- break;
390
- }
391
- this._sel.sort(function (a,b) {return a.yearDay() - b.yearDay();});
392
- this.publish('change', this);
393
- if (draw !== false) this.draw();
394
- return true;
395
- },
396
-
397
- removeSelected : function (date, draw) {
398
- date = moment(date).yearDay();
399
- var i = this._sel.length;
400
- while (i--) {
401
- if (this._sel[i].yearDay() === date) {
402
- this._sel.splice(i,1);
403
- this.publish('change', this);
404
- if (draw !== false) this.draw();
405
- return true;
406
- }
407
- }
408
- return false;
409
- },
410
-
411
- draw : function draw() {
412
- // return;
413
- var month = moment(this.viewStartDate).hours(12), //force middle of the day to avoid any weird date shifts
414
- day,
415
- classes = this.classes,
416
- cal,
417
- $span,
418
- klass,
419
- i=0, c,
420
- j=0, k,
421
- s,
422
- dateString,
423
- opts = this.settings;
424
-
425
- c = this.calendars.length;
426
-
427
- do {
428
- day = moment(month).date(1);
429
- day.day( day.day() < this.settings.weekStart ? this.settings.weekStart-7 : this.settings.weekStart);
430
- //if the first day of the month is less than our week start, back up a week
431
-
432
- cal = this.calendars[i];
433
- cal.caption.innerHTML = month.format(this.settings.titleFormat);
434
- j = 0;
435
- do {
436
- $span = cal.days[j];
437
-
438
- klass = [];
439
-
440
- s = this.isSelected(day);
441
-
442
- if (s) klass.push(({'-1':classes.dayInRange,'1':classes.daySelected, 'true':classes.daySelected})[s]);
443
-
444
- if (day.month() != month.month()) klass.push(classes.dayOutOfMonth);
445
- else if (!(this.blackout(day) || this.direction(day)) || s>0) klass.push(classes.dayActive);
446
-
447
- if (day.yearDay() === today.yearDay()) klass.push(classes.dayToday);
448
-
449
- dateString = day.format(this.settings.dayAttributeFormat);
450
- if (opts.dateClassMap[dateString]) klass.push(opts.dateClassMap[dateString]);
451
-
452
- $span.innerHTML = day.format(opts.dayNumberFormat);
453
- $span.className = klass.join(' ');
454
- $span.setAttribute('data-date', dateString);
455
-
456
-
457
- day.add('days',1);
458
- } while (++j < 42);
459
- month.add('months',1);
460
- } while (++i < c);
461
-
462
- if (opts.directionScrolling) {
463
- var diff = -(moment().diff(month, 'months'));
464
- if (opts.direction==='today-past' || opts.direction==='past') {
465
-
466
- if (diff < 0) {
467
- this.disableNextMonth = false;
468
- util.removeClassName(this.container, classes.disableNextMonth);
469
- } else {
470
- this.disableNextMonth = true;
471
- util.addClassName(this.container, classes.disableNextMonth);
472
- }
473
-
474
- } else if (opts.direction==='today-future' || opts.direction==='future') {
475
-
476
- if (diff >= opts.months) {
477
- this.disablePreviousMonth = false;
478
- util.removeClassName(this.container, classes.disablePreviousMonth);
479
- } else {
480
- this.disablePreviousMonth = true;
481
- util.addClassName(this.container, classes.disablePreviousMonth);
482
- }
483
-
484
- }
485
-
486
-
487
- if (opts.direction==='today-past' || opts.direction==='past') {
488
- if (month.add({y:1}).diff(moment(), 'months') <= 0) {
489
- this.disableNextYear = false;
490
- util.removeClassName(this.container, classes.disableNextYear);
491
- } else {
492
- this.disableNextYear = true;
493
- util.addClassName(this.container, classes.disableNextYear);
494
- }
495
-
496
- } else if (opts.direction==='today-future' || opts.direction==='future') {
497
- if ((month.subtract({y:1}).diff(moment(), 'months') - (opts.months-1)) >= 0) {
498
- this.disablePreviousYear = false;
499
- util.removeClassName(this.container, classes.disablePreviousYear);
500
- } else {
501
- this.disablePreviousYear = true;
502
- util.addClassName(this.container, classes.disablePreviousYear);
503
- }
504
-
505
- }
506
-
507
- }
508
- }
509
- }
510
-
511
- var parseDates = function (input, delimiter, format) {
512
- var output = [];
513
-
514
- if (typeof input === 'string') {
515
- input = input.split(delimiter);
516
- } else if (!util.isArray(input)) {
517
- input = [input];
518
- }
519
-
520
- var c = input.length;
521
- i = 0;
522
- do {
523
- if (input[i]) output.push( moment(input[i], format).hours(12) );
524
- } while (++i < c);
525
-
526
- return output;
527
- }
528
-
529
-
530
-
531
- window.Kalendae = Kalendae;
532
-
533
- var util = Kalendae.util = {
534
-
535
- isIE8: function() {
536
- return !!( (/msie 8./i).test(navigator.appVersion) && !(/opera/i).test(navigator.userAgent) && window.ActiveXObject && XDomainRequest && !window.msPerformance );
537
- },
538
-
539
- // ELEMENT FUNCTIONS
540
-
541
- $: function (elem) {
542
- return (typeof elem == 'string') ? document.getElementById(elem) : elem;
543
- },
544
-
545
- $$: function (selector) {
546
- return document.querySelectorAll(selector);
547
- },
548
-
549
- make: function (tagName, attributes, attach) {
550
- var k, e = document.createElement(tagName);
551
- if (!!attributes) for (k in attributes) if (attributes.hasOwnProperty(k)) e.setAttribute(k, attributes[k]);
552
- if (!!attach) attach.appendChild(e);
553
- return e;
554
- },
555
-
556
- // Returns true if the DOM element is visible, false if it's hidden.
557
- // Checks if display is anything other than none.
558
- isVisible: function (elem) {
559
- // shamelessly copied from jQuery
560
- return elem.offsetWidth > 0 || elem.offsetHeight > 0;
561
- },
562
-
563
- getStyle: function (elem, styleProp) {
564
- var y;
565
- if (elem.currentStyle) {
566
- y = elem.currentStyle[styleProp];
567
- } else if (window.getComputedStyle) {
568
- y = window.getComputedStyle(elem, null)[styleProp];
569
- }
570
- return y;
571
- },
572
-
573
- domReady:function (f){/in/.test(document.readyState) ? setTimeout(function() {util.domReady(f);},9) : f()},
574
-
575
- // Adds a listener callback to a DOM element which is fired on a specified
576
- // event. Callback is sent the event object and the element that triggered the event
577
- addEvent: function (elem, eventName, callback) {
578
- var listener = function (event) {
579
- event = event || window.event;
580
- var target = event.target || event.srcElement;
581
- var block = callback.apply(elem, [event, target]);
582
- if (block === false) {
583
- if (!!event.preventDefault) event.preventDefault();
584
- else {
585
- event.returnValue = false;
586
- event.cancelBubble = true;
587
- }
588
- }
589
- return block;
590
- };
591
- if (elem.attachEvent) { // IE only. The "on" is mandatory.
592
- elem.attachEvent("on" + eventName, listener);
593
- } else { // Other browsers.
594
- elem.addEventListener(eventName, listener, false);
595
- }
596
- return listener;
597
- },
598
-
599
- // Removes a listener callback from a DOM element which is fired on a specified
600
- // event.
601
- removeEvent: function (elem, event, listener) {
602
- if (elem.detachEvent) { // IE only. The "on" is mandatory.
603
- elem.detachEvent("on" + event, listener);
604
- } else { // Other browsers.
605
- elem.removeEventListener(event, listener, false);
606
- }
607
- },
608
-
609
- hasClassName: function(elem, className) { //copied and modified from Prototype.js
610
- if (!(elem = util.$(elem))) return false;
611
- var eClassName = elem.className;
612
- return (eClassName.length > 0 && (eClassName == className || new RegExp("(^|\\s)" + className + "(\\s|$)").test(eClassName)));
613
- },
614
-
615
- addClassName: function(elem, className) { //copied and modified from Prototype.js
616
- if (!(elem = util.$(elem))) return;
617
- if (!util.hasClassName(elem, className)) elem.className += (elem.className ? ' ' : '') + className;
618
- },
619
-
620
- removeClassName: function(elem, className) { //copied and modified from Prototype.js
621
- if (!(elem = util.$(elem))) return;
622
- elem.className = util.trimString(elem.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' '));
623
- },
624
-
625
- isFixed: function (elem) {
626
- do {
627
- if (util.getStyle(elem, 'position') === 'fixed') return true;
628
- } while ((elem = elem.offsetParent));
629
- return false;
630
- },
631
-
632
- getPosition: function (elem, isInner) {
633
- var x = elem.offsetLeft,
634
- y = elem.offsetTop,
635
- r = {};
636
-
637
- if (!isInner) {
638
- while ((elem = elem.offsetParent)) {
639
- x += elem.offsetLeft;
640
- y += elem.offsetTop;
641
- }
642
- }
643
-
644
- r[0] = r.left = x;
645
- r[1] = r.top = y;
646
- return r;
647
- },
648
-
649
- getHeight: function (elem) {
650
- return elem.offsetHeight || elem.scrollHeight;
651
- },
652
-
653
- getWidth: function (elem) {
654
- return elem.offsetWidth || elem.scrollWidth;
655
- },
656
-
657
-
658
- // TEXT FUNCTIONS
659
-
660
- trimString: function (input) {
661
- return input.replace(/^\s+/, '').replace(/\s+$/, '');
662
- },
663
-
664
-
665
- // OBJECT FUNCTIONS
666
-
667
- merge: function () {
668
- /* Combines multiple objects into one.
669
- * Syntax: util.extend([true], object1, object2, ... objectN)
670
- * If first argument is true, function will merge recursively.
671
- */
672
-
673
- var deep = (arguments[0]===true),
674
- d = {},
675
- i = deep?1:0;
676
-
677
- var _c = function (a, b) {
678
- if (typeof b !== 'object') return;
679
- for (var k in b) if (b.hasOwnProperty(k)) {
680
- //if property is an object or array, merge the contents instead of overwriting, if extend() was called as such
681
- if (deep && typeof a[k] === 'object' && typeof b[k] === 'object') _update(a[k], b[k]);
682
- else a[k] = b[k];
683
- }
684
- return a;
685
- }
686
-
687
- for (; i < arguments.length; i++) {
688
- _c(d, arguments[i]);
689
- }
690
- return d;
691
- },
692
-
693
- isArray: function (array) {
694
- return !(
695
- !array ||
696
- (!array.length || array.length === 0) ||
697
- typeof array !== 'object' ||
698
- !array.constructor ||
699
- array.nodeType ||
700
- array.item
701
- );
702
- }
703
- };
704
-
705
-
706
- //auto-initializaiton code
707
- if (typeof document.addEventListener === 'function') Kalendae.util.domReady(function () {
708
- var els = util.$$('.auto-kal'),
709
- i = els.length,
710
- e,
711
- options,
712
- optionsRaw;
713
-
714
- while (i--) {
715
- e = els[i];
716
- optionsRaw = e.getAttribute('data-kal');
717
- options = (optionsRaw == null || optionsRaw == "") ? {} : (new Function('return {' + optionsRaw + '};'))();
718
-
719
- if (e.tagName === 'INPUT') {
720
- //if element is an input, bind a popup calendar to the input.
721
- new Kalendae.Input(e, options);
722
- } else {
723
- //otherwise, insert a flat calendar into the element.
724
- new Kalendae(util.merge(options, {attachTo:e}));
725
- }
726
-
727
- }
728
- });
729
-
730
- Kalendae.Input = function (targetElement, options) {
731
- if (typeof document.addEventListener !== 'function') return;
732
-
733
- var $input = this.input = util.$(targetElement),
734
- overwriteInput;
735
-
736
- if (!$input || $input.tagName !== 'INPUT') throw "First argument for Kalendae.Input must be an <input> element or a valid element id.";
737
-
738
- var self = this,
739
- classes = self.classes
740
- opts = self.settings = util.merge(self.defaults, options);
741
-
742
- //force attachment to the body
743
- opts.attachTo = window.document.body;
744
-
745
- //if no override provided, use the input's contents
746
- if (!opts.selected) opts.selected = $input.value;
747
- else overwriteInput = true;
748
-
749
- //call our parent constructor
750
- Kalendae.call(self, opts);
751
-
752
- //create the close button
753
- if (opts.closeButton) {
754
- var $closeButton = util.make('a', {'class':classes.closeButton}, self.container)
755
- util.addEvent($closeButton, 'click', function () {
756
- $input.blur();
757
- });
758
- }
759
-
760
- if (overwriteInput) $input.value = self.getSelected();
761
-
762
- var $container = self.container,
763
- noclose = false;
764
-
765
- $container.style.display = 'none';
766
- util.addClassName($container, classes.positioned);
767
-
768
- util.addEvent($container, 'mousedown', function (event, target) {
769
- noclose = true; //IE8 doesn't obey event blocking when it comes to focusing, so we have to do this shit.
770
- });
771
- util.addEvent(window.document, 'mousedown', function (event, target) {
772
- noclose = false;
773
- });
774
-
775
- util.addEvent($input, 'focus', function () {
776
- self.setSelected(this.value);
777
- self.show();
778
- });
779
-
780
- util.addEvent($input, 'blur', function () {
781
- if (noclose) {
782
- noclose = false;
783
- $input.focus();
784
- }
785
- else self.hide();
786
- });
787
- util.addEvent($input, 'keyup', function (event) {
788
- self.setSelected(this.value);
789
- });
790
-
791
- self.subscribe('change', function () {
792
- $input.value = self.getSelected();
793
- });
794
-
795
- };
796
-
797
- Kalendae.Input.prototype = util.merge(Kalendae.prototype, {
798
- defaults : util.merge(Kalendae.prototype.defaults, {
799
- format: 'MM/DD/YYYY',
800
- side: 'bottom',
801
- closeButton: true,
802
- offsetLeft: 0,
803
- offsetTop: 0
804
- }),
805
- classes : util.merge(Kalendae.prototype.classes, {
806
- positioned : 'k-floating',
807
- closeButton: 'k-btn-close'
808
- }),
809
-
810
- show : function () {
811
- var $container = this.container,
812
- style = $container.style,
813
- $input = this.input,
814
- pos = util.getPosition($input);
815
-
816
- style.display = '';
817
- switch (opts.side) {
818
- case 'left':
819
- style.left = (pos.left - util.getWidth($container) + this.settings.offsetLeft) + 'px';
820
- style.top = (pos.top + this.settings.offsetTop) + 'px';
821
- break;
822
- case 'right':
823
- style.left = (pos.left + util.getWidth($input)) + 'px';
824
- style.top = (pos.top + this.settings.offsetTop) + 'px';
825
- break;
826
- case 'top':
827
- style.left = (pos.left + this.settings.offsetLeft) + 'px';
828
- style.top = (pos.top - util.getHeight($container) + this.settings.offsetTop) + 'px';
829
- break;
830
- case 'bottom':
831
- /* falls through */
832
- default:
833
- style.left = (pos.left + this.settings.offsetLeft) + 'px';
834
- style.top = (pos.top + util.getHeight($input) + this.settings.offsetTop) + 'px';
835
- break;
836
- }
837
-
838
- style.position = util.isFixed($input) ? 'fixed' : 'absolute';
839
-
840
- },
841
-
842
- hide : function () {
843
- this.container.style.display = 'none';
844
- }
845
-
846
- });
847
-
848
-
849
- /*!
850
- * MinPubSub, modified for use on Kalendae
851
- * Copyright(c) 2011 Daniel Lamb <daniellmb.com>
852
- * https://github.com/daniellmb/MinPubSub
853
- * MIT Licensed
854
- */
855
-
856
- var MinPubSub = function(d){
857
-
858
- if (!d) d = this;
859
-
860
- // the topic/subscription hash
861
- var cache = d.c_ || {}; //check for "c_" cache for unit testing
862
-
863
- d.publish = function(/* String */ topic, /* Object */ target, /* Array? */ args){
864
- // summary:
865
- // Publish some data on a named topic.
866
- // topic: String
867
- // The channel to publish on
868
- // args: Array?
869
- // The data to publish. Each array item is converted into an ordered
870
- // arguments on the subscribed functions.
871
- //
872
- // example:
873
- // Publish stuff on '/some/topic'. Anything subscribed will be called
874
- // with a function signature like: function(a,b,c){ ... }
875
- //
876
- // publish("/some/topic", ["a","b","c"]);
877
-
878
- var subs = cache[topic],
879
- len = subs ? subs.length : 0,
880
- r;
881
-
882
- //can change loop or reverse array if the order matters
883
- while(len--){
884
- r = subs[len].apply(target, args || []);
885
- if (typeof r === 'boolean') return r;
886
- }
887
- };
888
-
889
- d.subscribe = function(/* String */ topic, /* Function */ callback, /* Boolean */ topPriority){
890
- // summary:
891
- // Register a callback on a named topic.
892
- // topic: String
893
- // The channel to subscribe to
894
- // callback: Function
895
- // The handler event. Anytime something is publish'ed on a
896
- // subscribed channel, the callback will be called with the
897
- // published array as ordered arguments.
898
- //
899
- // returns: Array
900
- // A handle which can be used to unsubscribe this particular subscription.
901
- //
902
- // example:
903
- // subscribe("/some/topic", function(a, b, c){ /* handle data */ });
904
-
905
- if(!cache[topic]){
906
- cache[topic] = [];
907
- }
908
- if (topPriority)
909
- cache[topic].push(callback);
910
- else
911
- cache[topic].unshift(callback);
912
- return [topic, callback]; // Array
913
- };
914
-
915
- d.unsubscribe = function(/* Array */ handle){
916
- // summary:
917
- // Disconnect a subscribed function for a topic.
918
- // handle: Array
919
- // The return value from a subscribe call.
920
- // example:
921
- // var handle = subscribe("/some/topic", function(){});
922
- // unsubscribe(handle);
923
-
924
- var subs = cache[handle[0]],
925
- callback = handle[1],
926
- len = subs ? subs.length : 0;
927
-
928
- while(len--){
929
- if(subs[len] === callback){
930
- subs.splice(len, 1);
931
- }
932
- }
933
- };
934
-
935
- };// moment.js
936
- // Altered slightly for use in Kalendae.js
937
- // version : 1.5.0
938
- // author : Tim Wood
939
- // license : MIT
940
- // momentjs.com
941
-
942
- var moment = Kalendae.moment = (function (Date, undefined) {
943
-
944
- var moment,
945
- round = Math.round,
946
- languages = {},
947
- hasModule = (typeof module !== 'undefined'),
948
- paramsToParse = 'months|monthsShort|monthsParse|weekdays|weekdaysShort|longDateFormat|calendar|relativeTime|ordinal|meridiem'.split('|'),
949
- i,
950
- jsonRegex = /^\/?Date\((\-?\d+)/i,
951
- charactersToReplace = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|zz?|ZZ?|LT|LL?L?L?)/g,
952
- nonuppercaseLetters = /[^A-Z]/g,
953
- timezoneRegex = /\([A-Za-z ]+\)|:[0-9]{2} [A-Z]{3} /g,
954
- tokenCharacters = /(\\)?(MM?M?M?|dd?d?d|DD?D?D?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|ZZ?|T)/g,
955
- inputCharacters = /(\\)?([0-9]+|([a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+|([\+\-]\d\d:?\d\d))/gi,
956
- isoRegex = /\d{4}.\d\d.\d\d(T(\d\d(.\d\d(.\d\d)?)?)?([\+\-]\d\d:?\d\d)?)?/,
957
- isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
958
- isoTimes = [
959
- ['HH:mm:ss', /T\d\d:\d\d:\d\d/],
960
- ['HH:mm', /T\d\d:\d\d/],
961
- ['HH', /T\d\d/]
962
- ],
963
- timezoneParseRegex = /([\+\-]|\d\d)/gi,
964
- VERSION = "1.5.0",
965
- shortcuts = 'Month|Date|Hours|Minutes|Seconds|Milliseconds'.split('|');
966
-
967
- // Moment prototype object
968
- function Moment(date, isUTC) {
969
- this._d = date;
970
- this._isUTC = !!isUTC;
971
- }
972
-
973
- // left zero fill a number
974
- // see http://jsperf.com/left-zero-filling for performance comparison
975
- function leftZeroFill(number, targetLength) {
976
- var output = number + '';
977
- while (output.length < targetLength) {
978
- output = '0' + output;
979
- }
980
- return output;
981
- }
982
-
983
- // helper function for _.addTime and _.subtractTime
984
- function dateAddRemove(date, _input, adding, val) {
985
- var isString = (typeof _input === 'string'),
986
- input = isString ? {} : _input,
987
- ms, d, M, currentDate;
988
- if (isString && val) {
989
- input[_input] = +val;
990
- }
991
- ms = (input.ms || input.milliseconds || 0) +
992
- (input.s || input.seconds || 0) * 1e3 + // 1000
993
- (input.m || input.minutes || 0) * 6e4 + // 1000 * 60
994
- (input.h || input.hours || 0) * 36e5; // 1000 * 60 * 60
995
- d = (input.d || input.days || 0) +
996
- (input.w || input.weeks || 0) * 7;
997
- M = (input.M || input.months || 0) +
998
- (input.y || input.years || 0) * 12;
999
- if (ms) {
1000
- date.setTime(+date + ms * adding);
1001
- }
1002
- if (d) {
1003
- date.setDate(date.getDate() + d * adding);
1004
- }
1005
- if (M) {
1006
- currentDate = date.getDate();
1007
- date.setDate(1);
1008
- date.setMonth(date.getMonth() + M * adding);
1009
- date.setDate(Math.min(new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate(), currentDate));
1010
- }
1011
- return date;
1012
- }
1013
-
1014
- // check if is an array
1015
- function isArray(input) {
1016
- return Object.prototype.toString.call(input) === '[object Array]';
1017
- }
1018
-
1019
- // convert an array to a date.
1020
- // the array should mirror the parameters below
1021
- // note: all values past the year are optional and will default to the lowest possible value.
1022
- // [year, month, day , hour, minute, second, millisecond]
1023
- function dateFromArray(input) {
1024
- return new Date(input[0], input[1] || 0, input[2] || 1, input[3] || 0, input[4] || 0, input[5] || 0, input[6] || 0);
1025
- }
1026
-
1027
- // format date using native date object
1028
- function formatMoment(m, inputString) {
1029
- var currentMonth = m.month(),
1030
- currentDate = m.date(),
1031
- currentYear = m.year(),
1032
- currentDay = m.day(),
1033
- currentHours = m.hours(),
1034
- currentMinutes = m.minutes(),
1035
- currentSeconds = m.seconds(),
1036
- currentZone = -m.zone(),
1037
- ordinal = moment.ordinal,
1038
- meridiem = moment.meridiem;
1039
- // check if the character is a format
1040
- // return formatted string or non string.
1041
- //
1042
- // uses switch/case instead of an object of named functions (like http://phpjs.org/functions/date:380)
1043
- // for minification and performance
1044
- // see http://jsperf.com/object-of-functions-vs-switch for performance comparison
1045
- function replaceFunction(input) {
1046
- // create a couple variables to be used later inside one of the cases.
1047
- var a, b;
1048
- switch (input) {
1049
- // MONTH
1050
- case 'M' :
1051
- return currentMonth + 1;
1052
- case 'Mo' :
1053
- return (currentMonth + 1) + ordinal(currentMonth + 1);
1054
- case 'MM' :
1055
- return leftZeroFill(currentMonth + 1, 2);
1056
- case 'MMM' :
1057
- return moment.monthsShort[currentMonth];
1058
- case 'MMMM' :
1059
- return moment.months[currentMonth];
1060
- // DAY OF MONTH
1061
- case 'D' :
1062
- return currentDate;
1063
- case 'Do' :
1064
- return currentDate + ordinal(currentDate);
1065
- case 'DD' :
1066
- return leftZeroFill(currentDate, 2);
1067
- // DAY OF YEAR
1068
- case 'DDD' :
1069
- a = new Date(currentYear, currentMonth, currentDate);
1070
- b = new Date(currentYear, 0, 1);
1071
- return ~~ (((a - b) / 864e5) + 1.5);
1072
- case 'DDDo' :
1073
- a = replaceFunction('DDD');
1074
- return a + ordinal(a);
1075
- case 'DDDD' :
1076
- return leftZeroFill(replaceFunction('DDD'), 3);
1077
- // WEEKDAY
1078
- case 'd' :
1079
- return currentDay;
1080
- case 'do' :
1081
- return currentDay + ordinal(currentDay);
1082
- case 'ddd' :
1083
- return moment.weekdaysShort[currentDay];
1084
- case 'dddd' :
1085
- return moment.weekdays[currentDay];
1086
- // WEEK OF YEAR
1087
- case 'w' :
1088
- a = new Date(currentYear, currentMonth, currentDate - currentDay + 5);
1089
- b = new Date(a.getFullYear(), 0, 4);
1090
- return ~~ ((a - b) / 864e5 / 7 + 1.5);
1091
- case 'wo' :
1092
- a = replaceFunction('w');
1093
- return a + ordinal(a);
1094
- case 'ww' :
1095
- return leftZeroFill(replaceFunction('w'), 2);
1096
- // YEAR
1097
- case 'YY' :
1098
- return leftZeroFill(currentYear % 100, 2);
1099
- case 'YYYY' :
1100
- return currentYear;
1101
- // AM / PM
1102
- case 'a' :
1103
- return currentHours > 11 ? meridiem.pm : meridiem.am;
1104
- case 'A' :
1105
- return currentHours > 11 ? meridiem.PM : meridiem.AM;
1106
- // 24 HOUR
1107
- case 'H' :
1108
- return currentHours;
1109
- case 'HH' :
1110
- return leftZeroFill(currentHours, 2);
1111
- // 12 HOUR
1112
- case 'h' :
1113
- return currentHours % 12 || 12;
1114
- case 'hh' :
1115
- return leftZeroFill(currentHours % 12 || 12, 2);
1116
- // MINUTE
1117
- case 'm' :
1118
- return currentMinutes;
1119
- case 'mm' :
1120
- return leftZeroFill(currentMinutes, 2);
1121
- // SECOND
1122
- case 's' :
1123
- return currentSeconds;
1124
- case 'ss' :
1125
- return leftZeroFill(currentSeconds, 2);
1126
- // TIMEZONE
1127
- case 'zz' :
1128
- // depreciating 'zz' fall through to 'z'
1129
- case 'z' :
1130
- return (m._d.toString().match(timezoneRegex) || [''])[0].replace(nonuppercaseLetters, '');
1131
- case 'Z' :
1132
- return (currentZone < 0 ? '-' : '+') + leftZeroFill(~~(Math.abs(currentZone) / 60), 2) + ':' + leftZeroFill(~~(Math.abs(currentZone) % 60), 2);
1133
- case 'ZZ' :
1134
- return (currentZone < 0 ? '-' : '+') + leftZeroFill(~~(10 * Math.abs(currentZone) / 6), 4);
1135
- // LONG DATES
1136
- case 'L' :
1137
- case 'LL' :
1138
- case 'LLL' :
1139
- case 'LLLL' :
1140
- case 'LT' :
1141
- return formatMoment(m, moment.longDateFormat[input]);
1142
- // DEFAULT
1143
- default :
1144
- return input.replace(/(^\[)|(\\)|\]$/g, "");
1145
- }
1146
- }
1147
- return inputString.replace(charactersToReplace, replaceFunction);
1148
- }
1149
-
1150
- // date from string and format string
1151
- function makeDateFromStringAndFormat(string, format) {
1152
- var inArray = [0, 0, 1, 0, 0, 0, 0],
1153
- timezoneHours = 0,
1154
- timezoneMinutes = 0,
1155
- isUsingUTC = false,
1156
- inputParts = string.match(inputCharacters),
1157
- formatParts = format.match(tokenCharacters),
1158
- len = Math.min(inputParts.length, formatParts.length),
1159
- i,
1160
- isPm;
1161
-
1162
- // function to convert string input to date
1163
- function addTime(format, input) {
1164
- var a;
1165
- switch (format) {
1166
- // MONTH
1167
- case 'M' :
1168
- // fall through to MM
1169
- case 'MM' :
1170
- inArray[1] = ~~input - 1;
1171
- break;
1172
- case 'MMM' :
1173
- // fall through to MMMM
1174
- case 'MMMM' :
1175
- for (a = 0; a < 12; a++) {
1176
- if (moment.monthsParse[a].test(input)) {
1177
- inArray[1] = a;
1178
- break;
1179
- }
1180
- }
1181
- break;
1182
- // DAY OF MONTH
1183
- case 'D' :
1184
- // fall through to DDDD
1185
- case 'DD' :
1186
- // fall through to DDDD
1187
- case 'DDD' :
1188
- // fall through to DDDD
1189
- case 'DDDD' :
1190
- inArray[2] = ~~input;
1191
- break;
1192
- // YEAR
1193
- case 'YY' :
1194
- input = ~~input;
1195
- inArray[0] = input + (input > 70 ? 1900 : 2000);
1196
- break;
1197
- case 'YYYY' :
1198
- inArray[0] = ~~Math.abs(input);
1199
- break;
1200
- // AM / PM
1201
- case 'a' :
1202
- // fall through to A
1203
- case 'A' :
1204
- isPm = (input.toLowerCase() === 'pm');
1205
- break;
1206
- // 24 HOUR
1207
- case 'H' :
1208
- // fall through to hh
1209
- case 'HH' :
1210
- // fall through to hh
1211
- case 'h' :
1212
- // fall through to hh
1213
- case 'hh' :
1214
- inArray[3] = ~~input;
1215
- break;
1216
- // MINUTE
1217
- case 'm' :
1218
- // fall through to mm
1219
- case 'mm' :
1220
- inArray[4] = ~~input;
1221
- break;
1222
- // SECOND
1223
- case 's' :
1224
- // fall through to ss
1225
- case 'ss' :
1226
- inArray[5] = ~~input;
1227
- break;
1228
- // TIMEZONE
1229
- case 'Z' :
1230
- // fall through to ZZ
1231
- case 'ZZ' :
1232
- isUsingUTC = true;
1233
- a = (input || '').match(timezoneParseRegex);
1234
- if (a && a[1]) {
1235
- timezoneHours = ~~a[1];
1236
- }
1237
- if (a && a[2]) {
1238
- timezoneMinutes = ~~a[2];
1239
- }
1240
- // reverse offsets
1241
- if (a && a[0] === '+') {
1242
- timezoneHours = -timezoneHours;
1243
- timezoneMinutes = -timezoneMinutes;
1244
- }
1245
- break;
1246
- }
1247
- }
1248
- for (i = 0; i < len; i++) {
1249
- addTime(formatParts[i], inputParts[i]);
1250
- }
1251
- // handle am pm
1252
- if (isPm && inArray[3] < 12) {
1253
- inArray[3] += 12;
1254
- }
1255
- // if is 12 am, change hours to 0
1256
- if (isPm === false && inArray[3] === 12) {
1257
- inArray[3] = 0;
1258
- }
1259
- // handle timezone
1260
- inArray[3] += timezoneHours;
1261
- inArray[4] += timezoneMinutes;
1262
- // return
1263
- return isUsingUTC ? new Date(Date.UTC.apply({}, inArray)) : dateFromArray(inArray);
1264
- }
1265
-
1266
- // compare two arrays, return the number of differences
1267
- function compareArrays(array1, array2) {
1268
- var len = Math.min(array1.length, array2.length),
1269
- lengthDiff = Math.abs(array1.length - array2.length),
1270
- diffs = 0,
1271
- i;
1272
- for (i = 0; i < len; i++) {
1273
- if (~~array1[i] !== ~~array2[i]) {
1274
- diffs++;
1275
- }
1276
- }
1277
- return diffs + lengthDiff;
1278
- }
1279
-
1280
- // date from string and array of format strings
1281
- function makeDateFromStringAndArray(string, formats) {
1282
- var output,
1283
- inputParts = string.match(inputCharacters),
1284
- scores = [],
1285
- scoreToBeat = 99,
1286
- i,
1287
- curDate,
1288
- curScore;
1289
- for (i = 0; i < formats.length; i++) {
1290
- curDate = makeDateFromStringAndFormat(string, formats[i]);
1291
- curScore = compareArrays(inputParts, formatMoment(new Moment(curDate), formats[i]).match(inputCharacters));
1292
- if (curScore < scoreToBeat) {
1293
- scoreToBeat = curScore;
1294
- output = curDate;
1295
- }
1296
- }
1297
- return output;
1298
- }
1299
-
1300
- // date from iso format
1301
- function makeDateFromString(string) {
1302
- var format = 'YYYY-MM-DDT',
1303
- i;
1304
- if (isoRegex.exec(string)) {
1305
- for (i = 0; i < 3; i++) {
1306
- if (isoTimes[i][1].exec(string)) {
1307
- format += isoTimes[i][0];
1308
- break;
1309
- }
1310
- }
1311
- return makeDateFromStringAndFormat(string, format + 'Z');
1312
- }
1313
- return new Date(string);
1314
- }
1315
-
1316
- // helper function for _date.from() and _date.fromNow()
1317
- function substituteTimeAgo(string, number, withoutSuffix) {
1318
- var rt = moment.relativeTime[string];
1319
- return (typeof rt === 'function') ?
1320
- rt(number || 1, !!withoutSuffix, string) :
1321
- rt.replace(/%d/i, number || 1);
1322
- }
1323
-
1324
- function relativeTime(milliseconds, withoutSuffix) {
1325
- var seconds = round(Math.abs(milliseconds) / 1000),
1326
- minutes = round(seconds / 60),
1327
- hours = round(minutes / 60),
1328
- days = round(hours / 24),
1329
- years = round(days / 365),
1330
- args = seconds < 45 && ['s', seconds] ||
1331
- minutes === 1 && ['m'] ||
1332
- minutes < 45 && ['mm', minutes] ||
1333
- hours === 1 && ['h'] ||
1334
- hours < 22 && ['hh', hours] ||
1335
- days === 1 && ['d'] ||
1336
- days <= 25 && ['dd', days] ||
1337
- days <= 45 && ['M'] ||
1338
- days < 345 && ['MM', round(days / 30)] ||
1339
- years === 1 && ['y'] || ['yy', years];
1340
- args[2] = withoutSuffix;
1341
- return substituteTimeAgo.apply({}, args);
1342
- }
1343
-
1344
- moment = function (input, format) {
1345
- if (input === null || input === '') {
1346
- return null;
1347
- }
1348
- var date,
1349
- matched;
1350
- // parse Moment object
1351
- if (input && input._d instanceof Date) {
1352
- date = new Date(+input._d);
1353
- // parse string and format
1354
- } else if (format) {
1355
- if (isArray(format)) {
1356
- date = makeDateFromStringAndArray(input, format);
1357
- } else {
1358
- date = makeDateFromStringAndFormat(input, format);
1359
- }
1360
- // evaluate it as a JSON-encoded date
1361
- } else {
1362
- matched = jsonRegex.exec(input);
1363
- date = input === undefined ? new Date() :
1364
- matched ? new Date(+matched[1]) :
1365
- input instanceof Date ? input :
1366
- isArray(input) ? dateFromArray(input) :
1367
- typeof input === 'string' ? makeDateFromString(input) :
1368
- new Date(input);
1369
- }
1370
- return new Moment(date);
1371
- };
1372
-
1373
- // creating with utc
1374
- moment.utc = function (input, format) {
1375
- if (isArray(input)) {
1376
- return new Moment(new Date(Date.UTC.apply({}, input)), true);
1377
- }
1378
- return (format && input) ? moment(input + ' 0', format + ' Z').utc() : moment(input).utc();
1379
- };
1380
-
1381
- // humanizeDuration
1382
- moment.humanizeDuration = function (num, type, withSuffix) {
1383
- var difference = +num,
1384
- rel = moment.relativeTime,
1385
- output;
1386
- switch (type) {
1387
- case "seconds" :
1388
- difference *= 1000; // 1000
1389
- break;
1390
- case "minutes" :
1391
- difference *= 60000; // 60 * 1000
1392
- break;
1393
- case "hours" :
1394
- difference *= 3600000; // 60 * 60 * 1000
1395
- break;
1396
- case "days" :
1397
- difference *= 86400000; // 24 * 60 * 60 * 1000
1398
- break;
1399
- case "weeks" :
1400
- difference *= 604800000; // 7 * 24 * 60 * 60 * 1000
1401
- break;
1402
- case "months" :
1403
- difference *= 2592000000; // 30 * 24 * 60 * 60 * 1000
1404
- break;
1405
- case "years" :
1406
- difference *= 31536000000; // 365 * 24 * 60 * 60 * 1000
1407
- break;
1408
- default :
1409
- withSuffix = !!type;
1410
- break;
1411
- }
1412
- output = relativeTime(difference, !withSuffix);
1413
- return withSuffix ? (difference <= 0 ? rel.past : rel.future).replace(/%s/i, output) : output;
1414
- };
1415
-
1416
- // version number
1417
- moment.version = VERSION;
1418
-
1419
- // default format
1420
- moment.defaultFormat = isoFormat;
1421
-
1422
- // language switching and caching
1423
- moment.lang = function (key, values) {
1424
- var i,
1425
- param,
1426
- req,
1427
- parse = [];
1428
- if (values) {
1429
- for (i = 0; i < 12; i++) {
1430
- parse[i] = new RegExp('^' + values.months[i] + '|^' + values.monthsShort[i].replace('.', ''), 'i');
1431
- }
1432
- values.monthsParse = values.monthsParse || parse;
1433
- languages[key] = values;
1434
- }
1435
- if (languages[key]) {
1436
- for (i = 0; i < paramsToParse.length; i++) {
1437
- param = paramsToParse[i];
1438
- moment[param] = languages[key][param] || moment[param];
1439
- }
1440
- } else {
1441
- if (hasModule) {
1442
- req = require('./lang/' + key);
1443
- moment.lang(key, req);
1444
- }
1445
- }
1446
- };
1447
-
1448
- // set default language
1449
- moment.lang('en', {
1450
- months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
1451
- monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
1452
- weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
1453
- weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
1454
- longDateFormat : {
1455
- LT : "h:mm A",
1456
- L : "MM/DD/YYYY",
1457
- LL : "MMMM D YYYY",
1458
- LLL : "MMMM D YYYY LT",
1459
- LLLL : "dddd, MMMM D YYYY LT"
1460
- },
1461
- meridiem : {
1462
- AM : 'AM',
1463
- am : 'am',
1464
- PM : 'PM',
1465
- pm : 'pm'
1466
- },
1467
- calendar : {
1468
- sameDay : '[Today at] LT',
1469
- nextDay : '[Tomorrow at] LT',
1470
- nextWeek : 'dddd [at] LT',
1471
- lastDay : '[Yesterday at] LT',
1472
- lastWeek : '[last] dddd [at] LT',
1473
- sameElse : 'L'
1474
- },
1475
- relativeTime : {
1476
- future : "in %s",
1477
- past : "%s ago",
1478
- s : "a few seconds",
1479
- m : "a minute",
1480
- mm : "%d minutes",
1481
- h : "an hour",
1482
- hh : "%d hours",
1483
- d : "a day",
1484
- dd : "%d days",
1485
- M : "a month",
1486
- MM : "%d months",
1487
- y : "a year",
1488
- yy : "%d years"
1489
- },
1490
- ordinal : function (number) {
1491
- var b = number % 10;
1492
- return (~~ (number % 100 / 10) === 1) ? 'th' :
1493
- (b === 1) ? 'st' :
1494
- (b === 2) ? 'nd' :
1495
- (b === 3) ? 'rd' : 'th';
1496
- }
1497
- });
1498
-
1499
- // compare moment object
1500
- moment.isMoment = function (obj) {
1501
- return obj instanceof Moment;
1502
- };
1503
-
1504
- // shortcut for prototype
1505
- moment.fn = Moment.prototype = {
1506
-
1507
- clone : function () {
1508
- return moment(this);
1509
- },
1510
-
1511
- valueOf : function () {
1512
- return +this._d;
1513
- },
1514
-
1515
- 'native' : function () {
1516
- return this._d;
1517
- },
1518
-
1519
- toString : function () {
1520
- return this._d.toString();
1521
- },
1522
-
1523
- toDate : function () {
1524
- return this._d;
1525
- },
1526
-
1527
- utc : function () {
1528
- this._isUTC = true;
1529
- return this;
1530
- },
1531
-
1532
- local : function () {
1533
- this._isUTC = false;
1534
- return this;
1535
- },
1536
-
1537
- format : function (inputString) {
1538
- return formatMoment(this, inputString ? inputString : moment.defaultFormat);
1539
- },
1540
-
1541
- add : function (input, val) {
1542
- this._d = dateAddRemove(this._d, input, 1, val);
1543
- return this;
1544
- },
1545
-
1546
- subtract : function (input, val) {
1547
- this._d = dateAddRemove(this._d, input, -1, val);
1548
- return this;
1549
- },
1550
-
1551
- diff : function (input, val, asFloat) {
1552
- var inputMoment = moment(input),
1553
- zoneDiff = (this.zone() - inputMoment.zone()) * 6e4,
1554
- diff = this._d - inputMoment._d - zoneDiff,
1555
- year = this.year() - inputMoment.year(),
1556
- month = this.month() - inputMoment.month(),
1557
- date = this.date() - inputMoment.date(),
1558
- output;
1559
- if (val === 'months') {
1560
- output = year * 12 + month + date / 30;
1561
- } else if (val === 'years') {
1562
- output = year + month / 12;
1563
- } else {
1564
- output = val === 'seconds' ? diff / 1e3 : // 1000
1565
- val === 'minutes' ? diff / 6e4 : // 1000 * 60
1566
- val === 'hours' ? diff / 36e5 : // 1000 * 60 * 60
1567
- val === 'days' ? diff / 864e5 : // 1000 * 60 * 60 * 24
1568
- val === 'weeks' ? diff / 6048e5 : // 1000 * 60 * 60 * 24 * 7
1569
- diff;
1570
- }
1571
- return asFloat ? output : round(output);
1572
- },
1573
-
1574
- from : function (time, withoutSuffix) {
1575
- return moment.humanizeDuration(this.diff(time), !withoutSuffix);
1576
- },
1577
-
1578
- fromNow : function (withoutSuffix) {
1579
- return this.from(moment(), withoutSuffix);
1580
- },
1581
-
1582
- calendar : function () {
1583
- var diff = this.diff(moment().sod(), 'days', true),
1584
- calendar = moment.calendar,
1585
- allElse = calendar.sameElse,
1586
- format = diff < -6 ? allElse :
1587
- diff < -1 ? calendar.lastWeek :
1588
- diff < 0 ? calendar.lastDay :
1589
- diff < 1 ? calendar.sameDay :
1590
- diff < 2 ? calendar.nextDay :
1591
- diff < 7 ? calendar.nextWeek : allElse;
1592
- return this.format(typeof format === 'function' ? format.apply(this) : format);
1593
- },
1594
-
1595
- isLeapYear : function () {
1596
- var year = this.year();
1597
- return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
1598
- },
1599
-
1600
- isDST : function () {
1601
- return (this.zone() < moment([this.year()]).zone() ||
1602
- this.zone() < moment([this.year(), 5]).zone());
1603
- },
1604
-
1605
- day : function (input) {
1606
- var day = this._d.getDay();
1607
- return (typeof input === 'undefined') ? day :
1608
- this.add({ d : input - day });
1609
- },
1610
-
1611
- sod: function () {
1612
- return this.clone()
1613
- .hours(0)
1614
- .minutes(0)
1615
- .seconds(0)
1616
- .milliseconds(0);
1617
- },
1618
-
1619
- eod: function () {
1620
- // end of day = start of day plus 1 day, minus 1 millisecond
1621
- return this.sod().add({
1622
- d : 1,
1623
- ms : -1
1624
- });
1625
- },
1626
-
1627
- zone : function () {
1628
- return this._isUTC ? 0 : this._d.getTimezoneOffset();
1629
- },
1630
-
1631
- daysInMonth : function () {
1632
- return this.clone().month(this.month() + 1).date(0).date();
1633
- }
1634
- };
1635
-
1636
- // helper for adding shortcuts
1637
- function makeShortcut(name, key) {
1638
- moment.fn[name] = function (input) {
1639
- var utc = this._isUTC ? 'UTC' : '';
1640
- if (typeof input !== 'undefined') {
1641
- this._d['set' + utc + key](input);
1642
- return this;
1643
- } else {
1644
- return this._d['get' + utc + key]();
1645
- }
1646
- };
1647
- }
1648
-
1649
- // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds)
1650
- for (i = 0; i < shortcuts.length; i ++) {
1651
- makeShortcut(shortcuts[i].toLowerCase(), shortcuts[i]);
1652
- }
1653
-
1654
- // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear')
1655
- makeShortcut('year', 'FullYear');
1656
-
1657
- return moment;
1658
- })(Date);
1659
-
1660
- //function to reset the date object to 00:00 GMT
1661
- moment.fn.stripTime = function () {
1662
- this._d = new Date(Math.floor(this._d.valueOf() / 86400000) * 86400000);
1663
- return this;
1664
- }
1665
-
1666
-
1667
- //function to get the total number of days since the epoch.
1668
- moment.fn.yearDay = function (input) {
1669
- var yearday = Math.floor(this._d / 86400000);
1670
- return (typeof input === 'undefined') ? yearday :
1671
- this.add({ d : input - yearday });
1672
- }
1673
-
1674
- today = moment().stripTime();
1675
-
1676
- if (typeof jQuery !== 'undefined' && typeof document.addEventListener === 'function') {
1677
- jQuery.fn.kalendae = function (options) {
1678
- this.each(function (i, e) {
1679
- if (e.tagName === 'INPUT') {
1680
- //if element is an input, bind a popup calendar to the input.
1681
- $(e).data('kalendae', new Kalendae.Input(e, options));
1682
- } else {
1683
- //otherwise, insert a flat calendar into the element.
1684
- $(e).data('kalendae', new Kalendae($.extend({}, {attachTo:e}, options)));
1685
- }
1686
- });
1687
- return this;
1688
- }
1689
- }
1690
-
1691
-
1692
- })();