diff --git a/app/assets/javascripts/discourse/components/formatter.js b/app/assets/javascripts/discourse/components/formatter.js
index 891aed9daab..c7a28510674 100644
--- a/app/assets/javascripts/discourse/components/formatter.js
+++ b/app/assets/javascripts/discourse/components/formatter.js
@@ -4,15 +4,10 @@ Discourse.Formatter = (function(){
relativeAgeMedium, relativeAgeMediumSpan, longDate, toTitleCase,
shortDate;
- var shortDateNoYearFormat = Ember.String.i18n("dates.short_date_no_year");
- var longDateFormat = Ember.String.i18n("dates.long_date");
- var shortDateFormat = Ember.String.i18n("dates.short_date");
-
shortDate = function(date){
- return moment(date).format(shortDateFormat);
+ return moment(date).shortDate();
};
-
// http://stackoverflow.com/questions/196972/convert-string-to-title-case-with-javascript
// TODO: locale support ?
toTitleCase = function toTitleCase(str)
@@ -23,14 +18,14 @@ Discourse.Formatter = (function(){
}
longDate = function(dt) {
- return moment(dt).format(longDateFormat);
+ return moment(dt).longDate();
};
updateRelativeAge = function(elems) {
// jQuery .each
elems.each(function(){
var $this = $(this);
- $this.html(relativeAge(new Date($this.data('time')), $this.data('format')));
+ $this.html(relativeAge(new Date($this.data('time')), {format: $this.data('format'), wrapInSpan: false}));
});
};
@@ -38,7 +33,17 @@ Discourse.Formatter = (function(){
options = options || {};
var format = options.format || "tiny";
- return "" + relativeAge(date, options) + "";
+ var append = "";
+
+ if(format === 'medium') {
+ append = " date' title='" + longDate(date);
+ if(options.leaveAgo) {
+ format = 'medium-with-ago';
+ }
+ options.wrapInSpan = false;
+ }
+
+ return "" + relativeAge(date, options) + "";
};
@@ -139,7 +144,7 @@ Discourse.Formatter = (function(){
if ((new Date()).getFullYear() !== date.getFullYear()) {
displayDate = shortDate(date);
} else {
- displayDate = moment(date).format(shortDateNoYearFormat);
+ displayDate = moment(date).shortDateNoYear();
}
} else {
displayDate = relativeAgeMediumSpan(distance, leaveAgo);
@@ -160,6 +165,8 @@ Discourse.Formatter = (function(){
return relativeAgeTiny(date, options);
} else if (format === "medium") {
return relativeAgeMedium(date, options);
+ } else if (format === 'medium-with-ago') {
+ return relativeAgeMedium(date, _.extend(options, {format: 'medium', leaveAgo: true}));
}
return "UNKNOWN FORMAT";
diff --git a/app/assets/javascripts/discourse/helpers/application_helpers.js b/app/assets/javascripts/discourse/helpers/application_helpers.js
index d95b4fdd15f..37385404e4a 100644
--- a/app/assets/javascripts/discourse/helpers/application_helpers.js
+++ b/app/assets/javascripts/discourse/helpers/application_helpers.js
@@ -212,7 +212,7 @@ Handlebars.registerHelper('unboundAge', function(property, options) {
Handlebars.registerHelper('editDate', function(property, options) {
// autoupdating this is going to be painful
var date = new Date(Ember.Handlebars.get(this, property, options));
- return new Handlebars.SafeString(Discourse.Formatter.relativeAge(date, {format: 'medium', leaveAgo: true, wrapInSpan: false}));
+ return new Handlebars.SafeString(Discourse.Formatter.autoUpdatingRelativeAge(date, {format: 'medium', leaveAgo: true, wrapInSpan: false}));
});
/**
@@ -286,6 +286,6 @@ Handlebars.registerHelper('date', function(property, options) {
if (val) {
date = new Date(val);
}
- return new Handlebars.SafeString(Discourse.Formatter.relativeAge(date, {format: 'medium', leaveAgo: leaveAgo}));
+ return new Handlebars.SafeString(Discourse.Formatter.autoUpdatingRelativeAge(date, {format: 'medium', leaveAgo: leaveAgo}));
});
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 0343ca8346f..1a57027aeee 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -8,9 +8,6 @@
en:
js:
dates:
- short_date_no_year: "D MMM"
- short_date: "D MMM, YYYY"
- long_date: "MMMM D, YYYY h:mma"
tiny:
half_a_minute: "< 1m"
less_than_x_seconds:
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index c634369b255..537902f47aa 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -5,6 +5,10 @@
# http://yamllint.com/
en:
+ dates:
+ short_date_no_year: "D MMM"
+ short_date: "D MMM, YYYY"
+ long_date: "MMMM D, YYYY h:mma"
time:
formats:
short: "%m-%d-%Y"
diff --git a/app/assets/javascripts/external/moment.js b/lib/javascripts/moment.js
similarity index 100%
rename from app/assets/javascripts/external/moment.js
rename to lib/javascripts/moment.js
diff --git a/lib/js_locale_helper.rb b/lib/js_locale_helper.rb
index 2fc948efc94..f08cae73a70 100644
--- a/lib/js_locale_helper.rb
+++ b/lib/js_locale_helper.rb
@@ -18,11 +18,26 @@ module JsLocaleHelper
result = generate_message_format(message_formats, locale_str)
result << "I18n.translations = #{translations.to_json};\n"
- result << "I18n.locale = '#{locale_str}'\n"
+ result << "I18n.locale = '#{locale_str}';\n"
+ # loading moment here cause we must customize it
+ result << File.read("#{Rails.root}/lib/javascripts/moment.js")
result << moment_locale(locale_str)
+ result << moment_formats
result
end
+ def self.moment_formats
+ result = ""
+ result << moment_format_function('short_date_no_year')
+ result << moment_format_function('short_date')
+ result << moment_format_function('long_date')
+ end
+
+ def self.moment_format_function(name)
+ format = I18n.t("dates." << name)
+ result = "moment.fn.#{name.camelize(:lower)} = function(){ return this.format('#{format}'); };\n"
+ end
+
def self.moment_locale(locale_str)
filename = Rails.root + "lib/javascript/moment_locale/#{locale_str}.js"
if File.exists?(filename)
diff --git a/spec/javascripts/components/formatter_spec.js b/spec/javascripts/components/formatter_spec.js
index c543bf8c371..b0dcafdebc5 100644
--- a/spec/javascripts/components/formatter_spec.js
+++ b/spec/javascripts/components/formatter_spec.js
@@ -85,12 +85,22 @@ describe("Discourse.Formatter", function() {
describe("autoUpdatingRelativeAge", function(){
it("can format dates", function(){
- var d = new Date();
+ var d = moment().subtract('days',1).toDate();
var $elem = $(Discourse.Formatter.autoUpdatingRelativeAge(d));
-
expect($elem.data('format')).toBe("tiny");
expect($elem.data('time')).toBe(d.getTime());
+
+ $elem = $(Discourse.Formatter.autoUpdatingRelativeAge(d,{format: 'medium', leaveAgo: true}));
+ expect($elem.data('format')).toBe("medium-with-ago");
+ expect($elem.data('time')).toBe(d.getTime());
+ expect($elem.attr('title')).toBe(moment(d).longDate());
+ expect($elem.html()).toBe('1 day ago');
+
+ $elem = $(Discourse.Formatter.autoUpdatingRelativeAge(d,{format: 'medium'}));
+ expect($elem.data('format')).toBe("medium");
+ expect($elem.data('time')).toBe(d.getTime());
+ expect($elem.html()).toBe('1 day');
});
});
@@ -105,6 +115,14 @@ describe("Discourse.Formatter", function() {
expect($elem.html()).toBe("2m");
+
+ d = new Date();
+ $elem = $(Discourse.Formatter.autoUpdatingRelativeAge(d, {format: 'medium', leaveAgo: true}));
+ $elem.data('time', d.getTime() - 2 * 60 * 1000);
+
+ Discourse.Formatter.updateRelativeAge($elem);
+
+ expect($elem.html()).toBe("2 minutes ago");
});
});
});
diff --git a/spec/javascripts/spec.js b/spec/javascripts/spec.js
index c3beb26bf65..e353b71a8ba 100644
--- a/spec/javascripts/spec.js
+++ b/spec/javascripts/spec.js
@@ -1,3 +1,4 @@
+
//= require env
//= require ../../app/assets/javascripts/preload_store.js
@@ -13,16 +14,17 @@
//= require ../../app/assets/javascripts/external_production/ember.js
//= require ../../app/assets/javascripts/external_production/group-helper.js
+//= require ../../app/assets/javascripts/locales/i18n
+//= require ../../app/assets/javascripts/locales/date_locales.js
+//= require ../../app/assets/javascripts/discourse/helpers/i18n_helpers
+//= require ../../app/assets/javascripts/locales/en
+//
// Pagedown customizations
//= require ../../app/assets/javascripts/pagedown_custom.js
// The rest of the externals
//= require_tree ../../app/assets/javascripts/external
-//= require ../../app/assets/javascripts/locales/i18n
-//= require ../../app/assets/javascripts/locales/date_locales.js
-//= require ../../app/assets/javascripts/discourse/helpers/i18n_helpers
-//= require ../../app/assets/javascripts/locales/en
//= require ../../app/assets/javascripts/discourse
// Stuff we need to load first