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.
- checksums.yaml +7 -0
- data/LICENSE +26 -0
- data/README.md +57 -0
- data/Rakefile +30 -0
- data/app/assets/javascripts/auctions.js +2 -0
- data/app/assets/javascripts/countdown.js +20 -0
- data/app/assets/javascripts/local-time.js +1 -0
- data/app/assets/javascripts/spree/backend/product_autocomplete.js +50 -0
- data/app/assets/javascripts/spree/backend/solidus_auction.js +7 -0
- data/app/assets/javascripts/spree/ends_in.js +31 -0
- data/app/assets/javascripts/spree/frontend/solidus_auction.js +8 -0
- data/app/assets/javascripts/spree/frontend/starts_in.js +32 -0
- data/app/assets/javascripts/spree/frontend/votes.js +83 -0
- data/app/assets/stylesheets/spree/backend/solidus_auction.css +16 -0
- data/app/assets/stylesheets/spree/frontend/solidus_auction.css +24 -0
- data/app/controllers/spree/admin/auction_settings_controller.rb +16 -0
- data/app/controllers/spree/admin/auctions_controller.rb +46 -0
- data/app/controllers/spree/admin/bids_controller.rb +2 -0
- data/app/controllers/spree/admin/resource_controller_decorator.rb +9 -0
- data/app/controllers/spree/auctions_controller.rb +52 -0
- data/app/controllers/spree/bids_controller.rb +48 -0
- data/app/controllers/spree/helpers/local_time_helper.rb +77 -0
- data/app/controllers/spree/users_controller_decorator.rb +5 -0
- data/app/controllers/spree/votes_controller.rb +5 -0
- data/app/helpers/spree/strong_params_decorator.rb +8 -0
- data/app/models/spree/auction.rb +291 -0
- data/app/models/spree/auction_ability.rb +13 -0
- data/app/models/spree/bid.rb +19 -0
- data/app/models/spree/product_decorator.rb +3 -0
- data/app/models/spree/user_decorator.rb +5 -0
- data/app/models/spree/variant_decorator.rb +3 -0
- data/app/overrides/add_auction_links_to_order_info.rb +6 -0
- data/app/overrides/add_auction_settings_tab.rb +8 -0
- data/app/overrides/add_auctions_tab_to_admin.rb +8 -0
- data/app/overrides/add_auctions_table_to_user_show.rb +6 -0
- data/app/overrides/add_auctions_to_main_nav.rb +6 -0
- data/app/overrides/add_timezone_to_admin.rb +8 -0
- data/app/overrides/change_line_item_delete_button.rb +6 -0
- data/app/overrides/change_line_item_link_to.rb +6 -0
- data/app/overrides/change_line_item_number_field_disabled.rb +6 -0
- data/app/overrides/change_order_item_description.rb +6 -0
- data/app/overrides/change_stock_item_name.rb +6 -0
- data/app/overrides/change_variant_row_show.rb +6 -0
- data/app/overrides/change_variant_stock_item_show.rb +6 -0
- data/app/validators/in_future_validator.rb +10 -0
- data/app/views/spree/admin/active_shipping_settings/edit.html.erb +108 -0
- data/app/views/spree/admin/auction_settings/edit.html.erb +45 -0
- data/app/views/spree/admin/auctions/_form.html.erb +189 -0
- data/app/views/spree/admin/auctions/edit.html.erb +18 -0
- data/app/views/spree/admin/auctions/index.html.erb +89 -0
- data/app/views/spree/admin/auctions/new.html.erb +14 -0
- data/app/views/spree/admin/shared/_auction_links_to_order_info.html.erb +18 -0
- data/app/views/spree/admin/shared/_auction_settings_button.html.erb +3 -0
- data/app/views/spree/admin/shared/_auctions_tab.html.erb +3 -0
- data/app/views/spree/admin/shared/_time_zone_field.html.erb +5 -0
- data/app/views/spree/auctions/_bid_form.html.erb +81 -0
- data/app/views/spree/auctions/_bids.html.erb +52 -0
- data/app/views/spree/auctions/_image.html.erb +5 -0
- data/app/views/spree/auctions/_promotions.html.erb +19 -0
- data/app/views/spree/auctions/_properties.html.erb +15 -0
- data/app/views/spree/auctions/_taxons.html.erb +14 -0
- data/app/views/spree/auctions/_thumbnails.html.erb +19 -0
- data/app/views/spree/auctions/index.html.erb +3 -0
- data/app/views/spree/auctions/show.html.erb +58 -0
- data/app/views/spree/bids/index.html.erb +0 -0
- data/app/views/spree/bids/new.html.erb +0 -0
- data/app/views/spree/products/_cart_form.html.erb +65 -0
- data/app/views/spree/products/_promotions.html.erb +19 -0
- data/app/views/spree/products/_properties.html.erb +15 -0
- data/app/views/spree/products/_taxons.html.erb +14 -0
- data/app/views/spree/products/_thumbnails.html.erb +19 -0
- data/app/views/spree/products/index.html.erb +15 -0
- data/app/views/spree/products/show.html.erb +51 -0
- data/app/views/spree/shared/_auction_order_link.html.erb +9 -0
- data/app/views/spree/shared/_auctions.html.erb +39 -0
- data/app/views/spree/shared/_auctions_link.html.erb +7 -0
- data/app/views/spree/shared/_auctions_table_show.html.erb +93 -0
- data/app/views/spree/shared/_ends_in.html.erb +14 -0
- data/app/views/spree/shared/_image.html.erb +12 -0
- data/app/views/spree/shared/_line_item_delete.html.erb +5 -0
- data/app/views/spree/shared/_line_item_link_to.erb +22 -0
- data/app/views/spree/shared/_line_item_number_field_disabled.erb +9 -0
- data/app/views/spree/shared/_order_item_description.html.erb +15 -0
- data/app/views/spree/shared/_starts_in.html.erb +14 -0
- data/app/views/spree/shared/_stock_item_name.html.erb +5 -0
- data/app/views/spree/shared/_time_in_words_display.html.erb +11 -0
- data/app/views/spree/shared/_variant_row_disable.html.erb +21 -0
- data/app/views/spree/shared/_variant_stock_item_disable.html.erb +62 -0
- data/app/views/spree/shared/_votes.html.erb +12 -0
- data/app/views/spree/votes/index.html.erb +13 -0
- data/config/locales/en.yml +76 -0
- data/config/routes.rb +17 -0
- data/db/migrate/20180225234309_create_auctions.rb +25 -0
- data/db/migrate/20180225235226_create_bids.rb +13 -0
- data/db/migrate/20180316051158_add_deleted_to_spree_auction.rb +5 -0
- data/db/migrate/20180320010358_change_auction_reserve_price_column_to_big_decimal.rb +8 -0
- data/db/migrate/20180321203019_add_time_zone_to_spree_user.rb +5 -0
- data/db/migrate/20180322014713_add_default_to_datetimes.rb +7 -0
- data/db/migrate/20180328233438_add_variant_id_to_auction.rb +5 -0
- data/db/migrate/20180410025053_acts_as_votable_migration.rb +22 -0
- data/db/migrate/20180410031333_add_cached_votes_to_spree_auctions.rb +13 -0
- data/lib/assets/javascripts/src/local-time/calendar_date.coffee +37 -0
- data/lib/assets/javascripts/src/local-time/config/i18n.coffee +74 -0
- data/lib/assets/javascripts/src/local-time/config/locale.coffee +2 -0
- data/lib/assets/javascripts/src/local-time/config/timer.coffee +1 -0
- data/lib/assets/javascripts/src/local-time/controller.coffee +59 -0
- data/lib/assets/javascripts/src/local-time/helpers/date_parse.coffee +15 -0
- data/lib/assets/javascripts/src/local-time/helpers/dom.coffee +11 -0
- data/lib/assets/javascripts/src/local-time/helpers/i18n.coffee +24 -0
- data/lib/assets/javascripts/src/local-time/helpers/strftime.coffee +55 -0
- data/lib/assets/javascripts/src/local-time/index.coffee +20 -0
- data/lib/assets/javascripts/src/local-time/page_observer.coffee +43 -0
- data/lib/assets/javascripts/src/local-time/relative_time.coffee +72 -0
- data/lib/assets/javascripts/src/local-time/start.coffee +25 -0
- data/lib/generators/solidus_auction/install/install_generator.rb +30 -0
- data/lib/local_time.rb +0 -0
- data/lib/solidus_auction.rb +3 -0
- data/lib/solidus_auction/configuration.rb +8 -0
- data/lib/solidus_auction/engine.rb +29 -0
- data/lib/solidus_auction/factories.rb +19 -0
- data/lib/solidus_auction/version.rb +3 -0
- 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.
|
data/config/routes.rb
ADDED
|
@@ -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,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,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,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 @@
|
|
|
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)
|