solidus_auction 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +26 -0
  3. data/README.md +57 -0
  4. data/Rakefile +30 -0
  5. data/app/assets/javascripts/auctions.js +2 -0
  6. data/app/assets/javascripts/countdown.js +20 -0
  7. data/app/assets/javascripts/local-time.js +1 -0
  8. data/app/assets/javascripts/spree/backend/product_autocomplete.js +50 -0
  9. data/app/assets/javascripts/spree/backend/solidus_auction.js +7 -0
  10. data/app/assets/javascripts/spree/ends_in.js +31 -0
  11. data/app/assets/javascripts/spree/frontend/solidus_auction.js +8 -0
  12. data/app/assets/javascripts/spree/frontend/starts_in.js +32 -0
  13. data/app/assets/javascripts/spree/frontend/votes.js +83 -0
  14. data/app/assets/stylesheets/spree/backend/solidus_auction.css +16 -0
  15. data/app/assets/stylesheets/spree/frontend/solidus_auction.css +24 -0
  16. data/app/controllers/spree/admin/auction_settings_controller.rb +16 -0
  17. data/app/controllers/spree/admin/auctions_controller.rb +46 -0
  18. data/app/controllers/spree/admin/bids_controller.rb +2 -0
  19. data/app/controllers/spree/admin/resource_controller_decorator.rb +9 -0
  20. data/app/controllers/spree/auctions_controller.rb +52 -0
  21. data/app/controllers/spree/bids_controller.rb +48 -0
  22. data/app/controllers/spree/helpers/local_time_helper.rb +77 -0
  23. data/app/controllers/spree/users_controller_decorator.rb +5 -0
  24. data/app/controllers/spree/votes_controller.rb +5 -0
  25. data/app/helpers/spree/strong_params_decorator.rb +8 -0
  26. data/app/models/spree/auction.rb +291 -0
  27. data/app/models/spree/auction_ability.rb +13 -0
  28. data/app/models/spree/bid.rb +19 -0
  29. data/app/models/spree/product_decorator.rb +3 -0
  30. data/app/models/spree/user_decorator.rb +5 -0
  31. data/app/models/spree/variant_decorator.rb +3 -0
  32. data/app/overrides/add_auction_links_to_order_info.rb +6 -0
  33. data/app/overrides/add_auction_settings_tab.rb +8 -0
  34. data/app/overrides/add_auctions_tab_to_admin.rb +8 -0
  35. data/app/overrides/add_auctions_table_to_user_show.rb +6 -0
  36. data/app/overrides/add_auctions_to_main_nav.rb +6 -0
  37. data/app/overrides/add_timezone_to_admin.rb +8 -0
  38. data/app/overrides/change_line_item_delete_button.rb +6 -0
  39. data/app/overrides/change_line_item_link_to.rb +6 -0
  40. data/app/overrides/change_line_item_number_field_disabled.rb +6 -0
  41. data/app/overrides/change_order_item_description.rb +6 -0
  42. data/app/overrides/change_stock_item_name.rb +6 -0
  43. data/app/overrides/change_variant_row_show.rb +6 -0
  44. data/app/overrides/change_variant_stock_item_show.rb +6 -0
  45. data/app/validators/in_future_validator.rb +10 -0
  46. data/app/views/spree/admin/active_shipping_settings/edit.html.erb +108 -0
  47. data/app/views/spree/admin/auction_settings/edit.html.erb +45 -0
  48. data/app/views/spree/admin/auctions/_form.html.erb +189 -0
  49. data/app/views/spree/admin/auctions/edit.html.erb +18 -0
  50. data/app/views/spree/admin/auctions/index.html.erb +89 -0
  51. data/app/views/spree/admin/auctions/new.html.erb +14 -0
  52. data/app/views/spree/admin/shared/_auction_links_to_order_info.html.erb +18 -0
  53. data/app/views/spree/admin/shared/_auction_settings_button.html.erb +3 -0
  54. data/app/views/spree/admin/shared/_auctions_tab.html.erb +3 -0
  55. data/app/views/spree/admin/shared/_time_zone_field.html.erb +5 -0
  56. data/app/views/spree/auctions/_bid_form.html.erb +81 -0
  57. data/app/views/spree/auctions/_bids.html.erb +52 -0
  58. data/app/views/spree/auctions/_image.html.erb +5 -0
  59. data/app/views/spree/auctions/_promotions.html.erb +19 -0
  60. data/app/views/spree/auctions/_properties.html.erb +15 -0
  61. data/app/views/spree/auctions/_taxons.html.erb +14 -0
  62. data/app/views/spree/auctions/_thumbnails.html.erb +19 -0
  63. data/app/views/spree/auctions/index.html.erb +3 -0
  64. data/app/views/spree/auctions/show.html.erb +58 -0
  65. data/app/views/spree/bids/index.html.erb +0 -0
  66. data/app/views/spree/bids/new.html.erb +0 -0
  67. data/app/views/spree/products/_cart_form.html.erb +65 -0
  68. data/app/views/spree/products/_promotions.html.erb +19 -0
  69. data/app/views/spree/products/_properties.html.erb +15 -0
  70. data/app/views/spree/products/_taxons.html.erb +14 -0
  71. data/app/views/spree/products/_thumbnails.html.erb +19 -0
  72. data/app/views/spree/products/index.html.erb +15 -0
  73. data/app/views/spree/products/show.html.erb +51 -0
  74. data/app/views/spree/shared/_auction_order_link.html.erb +9 -0
  75. data/app/views/spree/shared/_auctions.html.erb +39 -0
  76. data/app/views/spree/shared/_auctions_link.html.erb +7 -0
  77. data/app/views/spree/shared/_auctions_table_show.html.erb +93 -0
  78. data/app/views/spree/shared/_ends_in.html.erb +14 -0
  79. data/app/views/spree/shared/_image.html.erb +12 -0
  80. data/app/views/spree/shared/_line_item_delete.html.erb +5 -0
  81. data/app/views/spree/shared/_line_item_link_to.erb +22 -0
  82. data/app/views/spree/shared/_line_item_number_field_disabled.erb +9 -0
  83. data/app/views/spree/shared/_order_item_description.html.erb +15 -0
  84. data/app/views/spree/shared/_starts_in.html.erb +14 -0
  85. data/app/views/spree/shared/_stock_item_name.html.erb +5 -0
  86. data/app/views/spree/shared/_time_in_words_display.html.erb +11 -0
  87. data/app/views/spree/shared/_variant_row_disable.html.erb +21 -0
  88. data/app/views/spree/shared/_variant_stock_item_disable.html.erb +62 -0
  89. data/app/views/spree/shared/_votes.html.erb +12 -0
  90. data/app/views/spree/votes/index.html.erb +13 -0
  91. data/config/locales/en.yml +76 -0
  92. data/config/routes.rb +17 -0
  93. data/db/migrate/20180225234309_create_auctions.rb +25 -0
  94. data/db/migrate/20180225235226_create_bids.rb +13 -0
  95. data/db/migrate/20180316051158_add_deleted_to_spree_auction.rb +5 -0
  96. data/db/migrate/20180320010358_change_auction_reserve_price_column_to_big_decimal.rb +8 -0
  97. data/db/migrate/20180321203019_add_time_zone_to_spree_user.rb +5 -0
  98. data/db/migrate/20180322014713_add_default_to_datetimes.rb +7 -0
  99. data/db/migrate/20180328233438_add_variant_id_to_auction.rb +5 -0
  100. data/db/migrate/20180410025053_acts_as_votable_migration.rb +22 -0
  101. data/db/migrate/20180410031333_add_cached_votes_to_spree_auctions.rb +13 -0
  102. data/lib/assets/javascripts/src/local-time/calendar_date.coffee +37 -0
  103. data/lib/assets/javascripts/src/local-time/config/i18n.coffee +74 -0
  104. data/lib/assets/javascripts/src/local-time/config/locale.coffee +2 -0
  105. data/lib/assets/javascripts/src/local-time/config/timer.coffee +1 -0
  106. data/lib/assets/javascripts/src/local-time/controller.coffee +59 -0
  107. data/lib/assets/javascripts/src/local-time/helpers/date_parse.coffee +15 -0
  108. data/lib/assets/javascripts/src/local-time/helpers/dom.coffee +11 -0
  109. data/lib/assets/javascripts/src/local-time/helpers/i18n.coffee +24 -0
  110. data/lib/assets/javascripts/src/local-time/helpers/strftime.coffee +55 -0
  111. data/lib/assets/javascripts/src/local-time/index.coffee +20 -0
  112. data/lib/assets/javascripts/src/local-time/page_observer.coffee +43 -0
  113. data/lib/assets/javascripts/src/local-time/relative_time.coffee +72 -0
  114. data/lib/assets/javascripts/src/local-time/start.coffee +25 -0
  115. data/lib/generators/solidus_auction/install/install_generator.rb +30 -0
  116. data/lib/local_time.rb +0 -0
  117. data/lib/solidus_auction.rb +3 -0
  118. data/lib/solidus_auction/configuration.rb +8 -0
  119. data/lib/solidus_auction/engine.rb +29 -0
  120. data/lib/solidus_auction/factories.rb +19 -0
  121. data/lib/solidus_auction/version.rb +3 -0
  122. metadata +388 -0
@@ -0,0 +1,12 @@
1
+ <% votes = auction.cached_votes_up %>
2
+ <% if spree_current_user %>
3
+ <% voted_for = spree_current_user.voted_up_on? auction %>
4
+ <div class="votes <%= 'green' if voted_for %>" data-auction-id=<%= auction.id %> data-user-id=<%= spree_current_user.id %> data-voted-for="<%= voted_for ? 'true':'false' %>">
5
+ <% else %>
6
+ <div class="votes" data-auction-id=<%= auction.id %> data-user-id=null>
7
+ <% end %>
8
+ <span>
9
+ <%= votes %>
10
+ </span>
11
+ <i class="fa fa-eye" aria-hidden="true"></i>
12
+ </div>
@@ -0,0 +1,13 @@
1
+ <div data-hook="homepage_auctions">
2
+ <% if @auctions.any? %>
3
+ <%= render partial: 'spree/shared/auctions', locals: { auctions: @auctions } %>
4
+ <% else %>
5
+ <div class="alert alert-info">
6
+ <p>
7
+ <%= Spree.t(:you_have_not_watched_any_auctions_yet) %>
8
+ <%= Spree.t(:check_some_out_here) %>:
9
+ <%= link_to Spree.t(:auctions), auctions_path %>
10
+ </p>
11
+ </div>
12
+ <% end %>
13
+ </div>
@@ -0,0 +1,76 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ spree:
6
+ my_auctions: My Auctions
7
+ auction: Auction
8
+ bid_confirmation_message: Are you sure you want to bid this amount?
9
+ auction_settings: Auction Settings
10
+ current_auctions: Current Auctions
11
+ winning?: Winning?
12
+ watching: watching
13
+ starts_in: Starts in
14
+ starting_soon: Starting Soon
15
+ starting_soon_hours: Starting Soon Hours
16
+ ending_soon: Ending Soon
17
+ ending_soon_hours: Ending Soon Hours
18
+ recently_completed: Recently Completed
19
+ recently_completed_hours: Recently Completed Hours
20
+ number_of_bids_to_show: Number of bids to show
21
+ winning_bid: Winning Bid
22
+ you_have_not_participated_in_an_auction_yet: You have not bid on any auctions yet.
23
+ you_have_not_watched_any_auctions_yet: You have not watched any auctions yet.
24
+ check_some_out_here: Check some out here
25
+ view_order_or_checkout: View Order or Checkout Here
26
+ you_have_won_this_auction: You have won this auction!
27
+ na: N/A
28
+ you_successfully_bid: You successfully bid
29
+ notice_messages:
30
+ auction_cloned: Auction cloned successfully
31
+ auction_not_cloned: Auction not cloned successfully
32
+ product_placeholder: Choose a product
33
+ auction_successfully_created: Auction created successfully
34
+ new_auction: New Auction
35
+ auction_link: Auction Page Link
36
+ associated_order: Associated Order
37
+ waiting_to_start: Waiting to Start
38
+ reserve_met: Reserve met
39
+ reserve_not_met: Reserve not met
40
+ auction_is_complete: Auction is complete.
41
+ must_be_signed_in_to_bid: You must be signed in to bid.
42
+ bid_not_high_enough: Your bid must exceed the current price plus the bid increment.
43
+ autobid_up_to: Auto-bid up to
44
+ met_reserve_price: Met reserve price
45
+ less_than_original_autobid: Less than original auto-bid, ignoring.
46
+ you_were_outbid: You were outbid.
47
+ there_was_a_tie_autobid_wins: There was a tie. Their auto-bid wins.
48
+ title: Title
49
+ reserve_price: Reserve Price
50
+ current_price: Current Price
51
+ starting_price: Starting Price
52
+ complete: Complete
53
+ auctions: Auctions
54
+ ends_in: Ends in
55
+ ends_at: Ends at
56
+ starting_datetime: Start
57
+ current_end_datetime: End
58
+ planned_end_datetime: Planned End
59
+ countdown_seconds: Countdown Seconds
60
+ highest_bidder: Highest Bidder
61
+ bid: Bid
62
+ bids: Bids
63
+ min_bid: Minimum Bid
64
+ admin:
65
+ tab:
66
+ auctions: Auctions
67
+ hints:
68
+ spree/auction:
69
+ title: Many of the fields will be disabled after the auction starts, so be sure to choose wisely!
70
+ reserve_price: The minimum price for someone to win the auction. Not setting a reserve price may, counterintuitively, make bidding more competitive.
71
+ start: Please make sure to set your time zone in your user profile, so this updates correctly.
72
+ planned_end_datetime: After the auction has started, you cannot change this field.
73
+ countdown: This many seconds before the current end datetime, any new, high bids will increase the length of the auction by "time increment" amount of seconds. For example, with countdown as 300 (5 minutes) and time increment as 60 (1 minute), if the current price is $20.00 and somebody bids $30.00 with 3 minutes left, the end of the auction will be 1 minute more into the future, leaving 4 minutes left. It is okay for the time increment to be longer than the countdown.
74
+ bid_increment: When a bidder bids, they have to bid the current price + this amount in order to succesfully bid. For example, if the current price is $25.00 and bid increment is $2.50, the next successful bidder must bid $27.50 or more.
75
+ time_increment: Number of seconds to increase the end of the auction when within countdown.
76
+ end: This is different from "Planned End" because the "countdown" and "time increment" can change the originally chosen date and time.
@@ -0,0 +1,17 @@
1
+ Spree::Core::Engine.routes.draw do
2
+ namespace :admin do
3
+ resources :auctions
4
+ resources :bids
5
+ resource :auction_settings, only: ['show', 'update', 'edit']
6
+ end
7
+ resources :auctions, only: %i{index show}
8
+ resources :votes, only: %i{index}
9
+ get 'vote_up', to: "auctions#vote_up"
10
+ get 'vote_down', to: "auctions#vote_down"
11
+ get 'vote_count', to: "auctions#vote_count"
12
+ get 'starting_soon', to: "auctions#starting_soon"
13
+ get 'ending_soon', to: "auctions#ending_soon"
14
+ get 'recently_completed', to: "auctions#recently_completed"
15
+
16
+ resources :bids, only: %i{index new create}
17
+ end
@@ -0,0 +1,25 @@
1
+ class CreateAuctions < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :spree_auctions do |t|
4
+ t.text :title
5
+ t.text :description
6
+ t.datetime :starting_datetime
7
+ t.datetime :planned_end_datetime
8
+ t.datetime :current_end_datetime
9
+ t.integer :starting_price, default: 0
10
+ t.integer :reserve_price, default: 0
11
+ t.integer :current_price
12
+ t.integer :bid_increment, default: 1
13
+ t.integer :time_increment, default: 0
14
+ t.integer :countdown, default: 0
15
+ t.integer :product_id
16
+ t.integer :creator_id
17
+ t.integer :highest_bidder_id
18
+ t.integer :auction_type_id
19
+ t.integer :store_id
20
+ t.boolean :complete, default: false
21
+
22
+ t.timestamps
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ class CreateBids < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :spree_bids do |t|
4
+ t.integer :auction_id
5
+ t.integer :bidder_id
6
+ t.integer :amount
7
+ t.boolean :visible, default: false
8
+ t.boolean :accepted, default: false
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ class AddDeletedToSpreeAuction < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :spree_auctions, :deleted, :boolean
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ class ChangeAuctionReservePriceColumnToBigDecimal < ActiveRecord::Migration[5.1]
2
+ def change
3
+ change_column :spree_auctions, :reserve_price, :decimal, precision: 12, scale: 2
4
+ change_column :spree_auctions, :current_price, :decimal, precision: 12, scale: 2
5
+ change_column :spree_auctions, :bid_increment, :decimal, precision: 12, scale: 2
6
+ change_column :spree_bids, :amount, :decimal, precision: 12, scale: 2
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ class AddTimeZoneToSpreeUser < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :spree_users, :time_zone, :string, default: "UTC"
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ class AddDefaultToDatetimes < ActiveRecord::Migration[5.1]
2
+ def change
3
+ change_column_default :spree_auctions, :starting_datetime, -> { 'CURRENT_TIMESTAMP' }
4
+ change_column_default :spree_auctions, :planned_end_datetime, -> { 'CURRENT_TIMESTAMP' }
5
+ change_column_default :spree_auctions, :current_end_datetime, -> { 'CURRENT_TIMESTAMP' }
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class AddVariantIdToAuction < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :spree_auctions, :variant_id, :integer
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ class ActsAsVotableMigration < ActiveRecord::Migration[4.2]
2
+ def self.up
3
+ create_table :votes do |t|
4
+
5
+ t.references :votable, :polymorphic => true
6
+ t.references :voter, :polymorphic => true
7
+
8
+ t.boolean :vote_flag
9
+ t.string :vote_scope
10
+ t.integer :vote_weight
11
+
12
+ t.timestamps
13
+ end
14
+
15
+ add_index :votes, [:voter_id, :voter_type, :vote_scope]
16
+ add_index :votes, [:votable_id, :votable_type, :vote_scope]
17
+ end
18
+
19
+ def self.down
20
+ drop_table :votes
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ class AddCachedVotesToSpreeAuctions < ActiveRecord::Migration[5.1]
2
+ def change
3
+ change_table :spree_auctions do |t|
4
+ t.integer :cached_votes_total, default: 0
5
+ t.integer :cached_votes_score, default: 0
6
+ t.integer :cached_votes_up, default: 0
7
+ t.integer :cached_votes_down, default: 0
8
+ t.integer :cached_weighted_score, default: 0
9
+ t.integer :cached_weighted_total, default: 0
10
+ t.float :cached_weighted_average, default: 0.0
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,37 @@
1
+ class LocalTime.CalendarDate
2
+ @fromDate: (date) ->
3
+ new this date.getFullYear(), date.getMonth() + 1, date.getDate()
4
+
5
+ @today: ->
6
+ @fromDate(new Date)
7
+
8
+ constructor: (year, month, day) ->
9
+ @date = new Date Date.UTC(year, month - 1)
10
+ @date.setUTCDate(day)
11
+
12
+ @year = @date.getUTCFullYear()
13
+ @month = @date.getUTCMonth() + 1
14
+ @day = @date.getUTCDate()
15
+ @value = @date.getTime()
16
+
17
+ equals: (calendarDate) ->
18
+ calendarDate?.value is @value
19
+
20
+ is: (calendarDate) ->
21
+ @equals(calendarDate)
22
+
23
+ isToday: ->
24
+ @is(@constructor.today())
25
+
26
+ occursOnSameYearAs: (date) ->
27
+ @year is date?.year
28
+
29
+ occursThisYear: ->
30
+ @occursOnSameYearAs(@constructor.today())
31
+
32
+ daysSince: (date) ->
33
+ if date
34
+ (@date - date.date) / (1000 * 60 * 60 * 24)
35
+
36
+ daysPassed: ->
37
+ @constructor.today().daysSince(this)
@@ -0,0 +1,74 @@
1
+ LocalTime.config.i18n =
2
+ en:
3
+ date:
4
+ dayNames: [
5
+ "Sunday"
6
+ "Monday"
7
+ "Tuesday"
8
+ "Wednesday"
9
+ "Thursday"
10
+ "Friday"
11
+ "Saturday"
12
+ ]
13
+ abbrDayNames: [
14
+ "Sun"
15
+ "Mon"
16
+ "Tue"
17
+ "Wed"
18
+ "Thu"
19
+ "Fri"
20
+ "Sat"
21
+ ]
22
+ monthNames: [
23
+ "January"
24
+ "February"
25
+ "March"
26
+ "April"
27
+ "May"
28
+ "June"
29
+ "July"
30
+ "August"
31
+ "September"
32
+ "October"
33
+ "November"
34
+ "December"
35
+ ]
36
+ abbrMonthNames: [
37
+ "Jan"
38
+ "Feb"
39
+ "Mar"
40
+ "Apr"
41
+ "May"
42
+ "Jun"
43
+ "Jul"
44
+ "Aug"
45
+ "Sep"
46
+ "Oct"
47
+ "Nov"
48
+ "Dec"
49
+ ]
50
+ yesterday: "yesterday"
51
+ today: "today"
52
+ tomorrow: "tomorrow"
53
+ on: "on {date}"
54
+ formats:
55
+ default: "%b %e, %Y"
56
+ thisYear: "%b %e"
57
+ time:
58
+ am: "am"
59
+ pm: "pm"
60
+ singular: "a {time}"
61
+ singularAn: "an {time}"
62
+ elapsed: "{time} ago"
63
+ second: "second"
64
+ seconds: "seconds"
65
+ minute: "minute"
66
+ minutes: "minutes"
67
+ hour: "hour"
68
+ hours: "hours"
69
+ formats:
70
+ default: "%l:%M%P"
71
+ datetime:
72
+ at: "{date} at {time}"
73
+ formats:
74
+ default: "%B %e, %Y at %l:%M%P %Z"
@@ -0,0 +1,2 @@
1
+ LocalTime.config.locale = "en"
2
+ LocalTime.config.defaultLocale = "en"
@@ -0,0 +1 @@
1
+ LocalTime.config.timerInterval = 60 * 1000
@@ -0,0 +1,59 @@
1
+ #= require ./relative_time
2
+ #= require ./page_observer
3
+
4
+ {parseDate, strftime, getI18nValue, config} = LocalTime
5
+
6
+ class LocalTime.Controller
7
+ SELECTOR = "time[data-local]:not([data-localized])"
8
+
9
+ constructor: ->
10
+ @pageObserver = new LocalTime.PageObserver SELECTOR, @processElements
11
+
12
+ start: ->
13
+ unless @started
14
+ @processElements()
15
+ @startTimer()
16
+ @pageObserver.start()
17
+ @started = true
18
+
19
+ startTimer: ->
20
+ if interval = config.timerInterval
21
+ @timer ?= setInterval(@processElements, interval)
22
+
23
+ processElements: (elements = document.querySelectorAll(SELECTOR)) =>
24
+ @processElement(element) for element in elements
25
+ elements.length
26
+
27
+ processElement: (element) ->
28
+ datetime = element.getAttribute("datetime")
29
+ format = element.getAttribute("data-format")
30
+ local = element.getAttribute("data-local")
31
+
32
+ time = parseDate(datetime)
33
+ return if isNaN time
34
+
35
+ unless element.hasAttribute("title")
36
+ title = strftime(time, getI18nValue("datetime.formats.default"))
37
+ element.setAttribute("title", title)
38
+
39
+ element.textContent = switch local
40
+ when "time"
41
+ markAsLocalized(element)
42
+ strftime(time, format)
43
+ when "date"
44
+ markAsLocalized(element)
45
+ relative(time).toDateString()
46
+ when "time-ago"
47
+ relative(time).toString()
48
+ when "time-or-date"
49
+ relative(time).toTimeOrDateString()
50
+ when "weekday"
51
+ relative(time).toWeekdayString()
52
+ when "weekday-or-date"
53
+ relative(time).toWeekdayString() or relative(time).toDateString()
54
+
55
+ markAsLocalized = (element) ->
56
+ element.setAttribute("data-localized", "")
57
+
58
+ relative = (time) ->
59
+ new LocalTime.RelativeTime time
@@ -0,0 +1,15 @@
1
+ # Older browsers do not support ISO8601 (JSON) timestamps in Date.parse
2
+ supportsISO8601 = not isNaN Date.parse("2011-01-01T12:00:00-05:00")
3
+
4
+ LocalTime.parseDate = (dateString) ->
5
+ dateString = dateString.toString()
6
+ dateString = reformatDateString(dateString) unless supportsISO8601
7
+ new Date Date.parse(dateString)
8
+
9
+ iso8601Pattern = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|[-+]?[\d:]+)$/
10
+
11
+ reformatDateString = (dateString) ->
12
+ if matches = dateString.match(iso8601Pattern)
13
+ [_, year, month, day, hour, minute, second, zone] = matches
14
+ offset = zone.replace(":", "") if zone isnt "Z"
15
+ "#{year}/#{month}/#{day} #{hour}:#{minute}:#{second} GMT#{[offset]}"
@@ -0,0 +1,11 @@
1
+ LocalTime.elementMatchesSelector = do ->
2
+ element = document.documentElement
3
+ method = element.matches ?
4
+ element.matchesSelector ?
5
+ element.webkitMatchesSelector ?
6
+ element.mozMatchesSelector ?
7
+ element.msMatchesSelector
8
+
9
+ (element, selector) ->
10
+ if element?.nodeType is Node.ELEMENT_NODE
11
+ method.call(element, selector)