From a437dbfc975b9f7b9adc50163b72d0443fd2062f Mon Sep 17 00:00:00 2001
From: Luiza Pagliari
Date: Fri, 22 May 2015 17:53:09 -0300
Subject: [PATCH] Adding support to l10n
---
locales/en.json | 42 ++++++
package.json | 3 +-
static/js/index.js | 73 +++-------
static/js/timeFormat.js | 85 ++++++++++++
static/tests/backend/specs/timeFormat.js | 161 +++++++++++++++++++++++
templates/commentBarButtons.ejs | 2 +-
templates/comments.html | 21 +--
templates/layout.ejs | 2 +-
templates/menuButtons.ejs | 2 +-
templates/settings.ejs | 2 +-
10 files changed, 322 insertions(+), 71 deletions(-)
create mode 100644 locales/en.json
create mode 100644 static/js/timeFormat.js
create mode 100644 static/tests/backend/specs/timeFormat.js
diff --git a/locales/en.json b/locales/en.json
new file mode 100644
index 00000000..cb2efdd2
--- /dev/null
+++ b/locales/en.json
@@ -0,0 +1,42 @@
+{
+ "ep_comments_page.comment" : "Comment",
+ "ep_comments_page.comments" : "Comments",
+ "ep_comments_page.cancel" : "Cancel",
+ "ep_comments_page.add_comment.title" : "Add new comment on selection",
+ "ep_comments_page.show_comments" : "Show Comments",
+ "ep_comments_page.comments_template.suggested_change" : "Suggested Change:",
+ "ep_comments_page.comments_template.accept_change" : "Accept Change",
+ "ep_comments_page.comments_template.suggest_change_from" : "Suggest change From:",
+ "ep_comments_page.comments_template.to" : "To:",
+ "ep_comments_page.comments_template.include_suggestion" : "Include suggested change",
+ "ep_comments_page.time.seconds_ago" : "{{count}} seconds ago",
+ "ep_comments_page.time.seconds_from_now" : "{{count}} seconds from now",
+ "ep_comments_page.time.one_minute_ago" : "1 minute ago",
+ "ep_comments_page.time.one_minute_from_now" : "1 minute from now",
+ "ep_comments_page.time.minutes_ago" : "{{count}} minutes ago",
+ "ep_comments_page.time.minutes_from_now" : "{{count}} minutes from now",
+ "ep_comments_page.time.one_hour_ago" : "1 hour ago",
+ "ep_comments_page.time.one_hour_from_now" : "1 hour from now",
+ "ep_comments_page.time.hours_ago" : "{{count}} hours ago",
+ "ep_comments_page.time.hours_from_now" : "{{count}} hours from now",
+ "ep_comments_page.time.yesterday" : "yesterday",
+ "ep_comments_page.time.tomorrow" : "tomorrow",
+ "ep_comments_page.time.days_ago" : "{{count}} days ago",
+ "ep_comments_page.time.days_from_now" : "{{count}} days from now",
+ "ep_comments_page.time.last_week" : "last week",
+ "ep_comments_page.time.next_week" : "next week",
+ "ep_comments_page.time.weeks_ago" : "{{count}} weeks ago",
+ "ep_comments_page.time.weeks_from_now" : "{{count}} weeks from now",
+ "ep_comments_page.time.last_month" : "last month",
+ "ep_comments_page.time.next_month" : "next month",
+ "ep_comments_page.time.months_ago" : "{{count}} months ago",
+ "ep_comments_page.time.months_from_now" : "{{count}} months from now",
+ "ep_comments_page.time.last_year" : "last year",
+ "ep_comments_page.time.next_year" : "next year",
+ "ep_comments_page.time.years_ago" : "{{count}} years ago",
+ "ep_comments_page.time.years_from_now" : "{{count}} years from now",
+ "ep_comments_page.time.last_century" : "last century",
+ "ep_comments_page.time.next_century" : "next century",
+ "ep_comments_page.time.centuries_ago" : "{{count}} centuries ago",
+ "ep_comments_page.time.centuries_from_now" : "{{count}} centuries from now"
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 6f845fb2..1cd97541 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,8 @@
],
"dependencies": {
"formidable": "*",
- "socket.io-client": "*"
+ "socket.io-client": "*",
+ "expect": "*"
},
"engines": {
"node": "*"
diff --git a/static/js/index.js b/static/js/index.js
index 8933433b..dbfbb1f5 100644
--- a/static/js/index.js
+++ b/static/js/index.js
@@ -3,13 +3,14 @@ var _, $, jQuery;
var $ = require('ep_etherpad-lite/static/js/rjquery').$;
var _ = require('ep_etherpad-lite/static/js/underscore');
var padcookie = require('ep_etherpad-lite/static/js/pad_cookie').padcookie;
+var prettyDate = require('ep_comments_page/static/js/timeFormat').prettyDate;
var cssFiles = ['ep_comments_page/static/css/comment.css'];
/************************************************************************/
/* ep_comments Plugin */
/************************************************************************/
-// Container
+// Container
function ep_comments(context){
this.container = null;
this.padOuter = null;
@@ -84,7 +85,7 @@ ep_comments.prototype.init = function(){
if( count_comments > padComment.length ) {
window.setTimeout(function() {
self.collectComments();
-
+
}, 9000);
}
}, 3000);
@@ -94,13 +95,13 @@ ep_comments.prototype.init = function(){
}, 300);
});
- // On click comment icon toolbar
+ // On click comment icon toolbar
$('.addComment').on('click', function(e){
$('iframe[name="ace_outer"]').contents().find('#comments').show();
$('iframe[name="ace_outer"]').contents().find('#comments').addClass("active");
e.preventDefault(); // stops focus from being lost
- // If a new comment box doesn't already exist
- // Add a new comment and link it to the selection
+ // If a new comment box doesn't already exist
+ // Add a new comment and link it to the selection
// $('iframe[name="ace_outer"]').contents().find('#sidediv').removeClass('sidedivhidden');
if (self.container.find('#newComment').length == 0) self.addComment();
// console.log("setting focus to .comment-content");
@@ -199,7 +200,7 @@ ep_comments.prototype.init = function(){
};
-// Insert comments container on element use for linenumbers
+// Insert comments container on element use for linenumbers
ep_comments.prototype.findContainers = function(){
var padOuter = $('iframe[name="ace_outer"]').contents();
this.padOuter = padOuter;
@@ -258,10 +259,10 @@ ep_comments.prototype.collectComments = function(callback){
} else {
var prevCommentPos = prevCommentElm.css('top');
var prevCommentHeight = prevCommentElm.innerHeight();
-
+
commentPos = parseInt(prevCommentPos) + prevCommentHeight + 30;
}
-
+
commentElm.css({ 'top': commentPos });
});
@@ -276,7 +277,7 @@ ep_comments.prototype.collectComments = function(callback){
// on hover we should show the reply option
}).on("mouseout", ".sidebar-comment", function(e){
var commentId = e.currentTarget.id;
- var inner = $('iframe[name="ace_outer"]').contents().find('iframe[name="ace_inner"]');
+ var inner = $('iframe[name="ace_outer"]').contents().find('iframe[name="ace_inner"]');
inner.contents().find("head").append("");
// TODO this could potentially break ep_font_color
});
@@ -347,7 +348,7 @@ ep_comments.prototype.removeComment = function(className, id){
// Insert comment container in sidebar
ep_comments.prototype.insertContainer = function(){
- // Add comments
+ // Add comments
$('iframe[name="ace_outer"]').contents().find("#outerdocbody").prepend('');
this.container = this.padOuter.find('#comments');
};
@@ -399,7 +400,7 @@ ep_comments.prototype.insertNewComment = function(comment, callback){
},'getYofRep', true);
};
-// Insert a comment node
+// Insert a comment node
ep_comments.prototype.insertComment = function(commentId, comment, index, isNew){
var template = (isNew === true) ? 'newCommentTemplate' : 'commentsTemplate';
var content = null;
@@ -478,13 +479,13 @@ ep_comments.prototype.getCommentReplies = function (callback){
ep_comments.prototype.getCommentData = function (){
var data = {};
- // Insert comment data
+ // Insert comment data
data.padId = this.padId;
data.comment = {};
data.comment.author = clientVars.userId;
data.comment.name = clientVars.userName;
data.comment.timestamp = new Date().getTime();
-
+
// Si le client est Anonyme
// In English please? :P
if(data.comment.name === undefined){
@@ -494,7 +495,7 @@ ep_comments.prototype.getCommentData = function (){
return data;
}
-// Add a pad comment
+// Add a pad comment
ep_comments.prototype.addComment = function (callback){
var socket = this.socket;
var data = this.getCommentData();
@@ -550,7 +551,7 @@ ep_comments.prototype.addComment = function (callback){
// Save comment
socket.emit('addComment', data, function (commentId, comment){
comment.commentId = commentId;
-
+
//callback(commentId);
ace.callWithAce(function (ace){
// console.log('addComment :: ', commentId);
@@ -630,7 +631,7 @@ ep_comments.prototype.pushComment = function(eventType, callback){
var hooks = {
- // Init pad comments
+ // Init pad comments
postAceInit: function(hook, context){
if(!pad.plugins) pad.plugins = {};
var Comments = new ep_comments(context);
@@ -671,46 +672,6 @@ var hooks = {
};
-function prettyDate(time){
- var time_formats = [
- [60, 'seconds', 1], // 60
- [120, '1 minute ago', '1 minute from now'], // 60*2
- [3600, 'minutes', 60], // 60*60, 60
- [7200, '1 hour ago', '1 hour from now'], // 60*60*2
- [86400, 'hours', 3600], // 60*60*24, 60*60
- [172800, 'yesterday', 'tomorrow'], // 60*60*24*2
- [604800, 'days', 86400], // 60*60*24*7, 60*60*24
- [1209600, 'last week', 'next week'], // 60*60*24*7*4*2
- [2419200, 'weeks', 604800], // 60*60*24*7*4, 60*60*24*7
- [4838400, 'last month', 'next month'], // 60*60*24*7*4*2
- [29030400, 'months', 2419200], // 60*60*24*7*4*12, 60*60*24*7*4
- [58060800, 'last year', 'next year'], // 60*60*24*7*4*12*2
- [2903040000, 'years', 29030400], // 60*60*24*7*4*12*100, 60*60*24*7*4*12
- [5806080000, 'last century', 'next century'], // 60*60*24*7*4*12*100*2
- [58060800000, 'centuries', 2903040000] // 60*60*24*7*4*12*100*20, 60*60*24*7*4*12*100
- ];
- /*
- var time = ('' + date_str).replace(/-/g,"/").replace(/[TZ]/g," ").replace(/^\s\s*/ /*rappel , '').replace(/\s\s*$/, '');
- if(time.substr(time.length-4,1)==".") time =time.substr(0,time.length-4);
- */
- var seconds = (new Date - new Date(time)) / 1000;
- var token = 'ago', list_choice = 1;
- if (seconds < 0) {
- seconds = Math.abs(seconds);
- token = 'from now';
- list_choice = 2;
- }
- var i = 0, format;
- while (format = time_formats[i++])
- if (seconds < format[0]) {
- if (typeof format[2] == 'string')
- return format[list_choice];
- else
- return Math.floor(seconds / format[2]) + ' ' + format[1] + ' ' + token;
- }
- return time;
-};
-
exports.aceEditorCSS = hooks.aceEditorCSS;
exports.postAceInit = hooks.postAceInit;
exports.aceAttribsToClasses = hooks.aceAttribsToClasses;
diff --git a/static/js/timeFormat.js b/static/js/timeFormat.js
new file mode 100644
index 00000000..4f11816e
--- /dev/null
+++ b/static/js/timeFormat.js
@@ -0,0 +1,85 @@
+var localizable = typeof html10n !== "undefined";
+
+l10nKeys = {
+ "seconds" : "ep_comments_page.time.seconds",
+ "1 minute ago" : "ep_comments_page.time.one_minute_ago",
+ "1 minute from now" : "ep_comments_page.time.one_minute_from_now",
+ "minutes" : "ep_comments_page.time.minutes",
+ "1 hour ago" : "ep_comments_page.time.one_hour_ago",
+ "1 hour from now" : "ep_comments_page.time.one_hour_from_now",
+ "hours" : "ep_comments_page.time.hours",
+ "yesterday" : "ep_comments_page.time.yesterday",
+ "tomorrow" : "ep_comments_page.time.tomorrow",
+ "days" : "ep_comments_page.time.days",
+ "last week" : "ep_comments_page.time.last_week",
+ "next week" : "ep_comments_page.time.next_week",
+ "weeks" : "ep_comments_page.time.weeks",
+ "last month" : "ep_comments_page.time.last_month",
+ "next month" : "ep_comments_page.time.next_month",
+ "months" : "ep_comments_page.time.months",
+ "last year" : "ep_comments_page.time.last_year",
+ "next year" : "ep_comments_page.time.next_year",
+ "years" : "ep_comments_page.time.years",
+ "last century" : "ep_comments_page.time.last_century",
+ "next century" : "ep_comments_page.time.next_century",
+ "centuries" : "ep_comments_page.time.centuries"
+}
+
+var time_formats = [
+ [60, 'seconds', 1], // 60
+ [120, '1 minute ago', '1 minute from now'], // 60*2
+ [3600, 'minutes', 60], // 60*60, 60
+ [7200, '1 hour ago', '1 hour from now'], // 60*60*2
+ [86400, 'hours', 3600], // 60*60*24, 60*60
+ [172800, 'yesterday', 'tomorrow'], // 60*60*24*2
+ [604800, 'days', 86400], // 60*60*24*7, 60*60*24
+ [1209600, 'last week', 'next week'], // 60*60*24*7*4*2
+ [2419200, 'weeks', 604800], // 60*60*24*7*4, 60*60*24*7
+ [4838400, 'last month', 'next month'], // 60*60*24*7*4*2
+ [29030400, 'months', 2419200], // 60*60*24*7*4*12, 60*60*24*7*4
+ [58060800, 'last year', 'next year'], // 60*60*24*7*4*12*2
+ [2903040000, 'years', 29030400], // 60*60*24*7*4*12*100, 60*60*24*7*4*12
+ [5806080000, 'last century', 'next century'], // 60*60*24*7*4*12*100*2
+ [58060800000, 'centuries', 2903040000] // 60*60*24*7*4*12*100*20, 60*60*24*7*4*12*100
+];
+
+function prettyDate(time){
+ /*
+ var time = ('' + date_str).replace(/-/g,"/").replace(/[TZ]/g," ").replace(/^\s\s*/ /*rappel , '').replace(/\s\s*$/, '');
+ if(time.substr(time.length-4,1)==".") time =time.substr(0,time.length-4);
+ */
+ var seconds = (new Date - new Date(time)) / 1000;
+ var token = 'ago',
+ list_choice = 1,
+ l10n_appendix = '_ago';
+
+ if (seconds < 0) {
+ seconds = Math.abs(seconds);
+ token = 'from now';
+ l10n_appendix = '_from_now';
+ list_choice = 2;
+ }
+
+ var i = 0, format;
+ while (format = time_formats[i++])
+ if (seconds < format[0]) {
+ var count = Math.floor(seconds / format[2]);
+ var formatted_time;
+ if (localizable) {
+ var key = l10nKeys[format[list_choice]] + l10n_appendix;
+ formatted_time = html10n.get(key, { count: count });
+ }
+
+ // Wasn't able to localize properly the date, so use the default:
+ if (formatted_time === undefined) {
+ if (typeof format[2] == 'string')
+ formatted_time = format[list_choice];
+ else
+ formatted_time = count + ' ' + format[1] + ' ' + token;
+ }
+ return formatted_time;
+ }
+ return time;
+};
+
+exports.prettyDate = prettyDate;
diff --git a/static/tests/backend/specs/timeFormat.js b/static/tests/backend/specs/timeFormat.js
new file mode 100644
index 00000000..bba3befb
--- /dev/null
+++ b/static/tests/backend/specs/timeFormat.js
@@ -0,0 +1,161 @@
+var prettyDate = require("../../../js/timeFormat").prettyDate,
+ expect = require("expect");
+
+describe('time formatting', function() {
+ it("returns '12 seconds ago' when time is 12 seconds in the past", function() {
+ expect(prettyDate(secondsInThePast(12))).toBe('12 seconds ago');
+ });
+
+ it("returns '12 seconds from now' when time is 12 seconds in the future", function() {
+ expect(prettyDate(secondsInTheFuture(12))).toBe('12 seconds from now');
+ });
+
+ it("returns '1 minute ago' when time is 75 seconds in the past", function() {
+ expect(prettyDate(secondsInThePast(75))).toBe('1 minute ago');
+ });
+
+ it("returns '1 minute from now' when time is 75 seconds in the future", function() {
+ expect(prettyDate(secondsInTheFuture(75))).toBe('1 minute from now');
+ });
+
+ it("returns '17 minute ago' when time is some seconds before 17 minutes in the past", function() {
+ expect(prettyDate(secondsInThePast(minutes(17) + 2))).toBe('17 minutes ago');
+ });
+
+ it("returns '17 minute from now' when time is some seconds after 17 minutes in the future", function() {
+ expect(prettyDate(secondsInTheFuture(minutes(17) + 2))).toBe('17 minutes from now');
+ });
+
+ it("returns '1 hour ago' when time is some seconds before 1 hour in the past", function() {
+ expect(prettyDate(secondsInThePast(hours(1) + 3))).toBe('1 hour ago');
+ });
+
+ it("returns '1 hour from now' when time is some seconds after 1 hour in the future", function() {
+ expect(prettyDate(secondsInTheFuture(hours(1) + 3))).toBe('1 hour from now');
+ });
+
+ it("returns '2 hours ago' when time is some seconds before 2 hours in the past", function() {
+ expect(prettyDate(secondsInThePast(hours(2) + 4))).toBe('2 hours ago');
+ });
+
+ it("returns '2 hours from now' when time is some seconds after 2 hours in the future", function() {
+ expect(prettyDate(secondsInTheFuture(hours(2) + 4))).toBe('2 hours from now');
+ });
+
+ it("returns 'yesterday' when time is some seconds before 24 hours in the past", function() {
+ expect(prettyDate(secondsInThePast(hours(24) + 5))).toBe('yesterday');
+ });
+
+ it("returns 'tomorrow' when time is some seconds after 24 hours in the future", function() {
+ expect(prettyDate(secondsInTheFuture(hours(24) + 5))).toBe('tomorrow');
+ });
+
+ it("returns '6 days ago' when time is some seconds before 6 days in the past", function() {
+ expect(prettyDate(secondsInThePast(days(6) + 6))).toBe('6 days ago');
+ });
+
+ it("returns '6 days from now' when time is some seconds after 6 days in the future", function() {
+ expect(prettyDate(secondsInTheFuture(days(6) + 6))).toBe('6 days from now');
+ });
+
+ it("returns 'last week' when time is some seconds before 7 days in the past", function() {
+ expect(prettyDate(secondsInThePast(days(7) + 7))).toBe('last week');
+ });
+
+ it("returns 'next week' when time is some seconds after 7 days in the future", function() {
+ expect(prettyDate(secondsInTheFuture(days(7) + 7))).toBe('next week');
+ });
+
+ it("returns '2 weeks ago' when time is some seconds before 2 weeks in the past", function() {
+ expect(prettyDate(secondsInThePast(weeks(2) + 8))).toBe('2 weeks ago');
+ });
+
+ it("returns '2 weeks from now' when time is some seconds after 2 weeks in the future", function() {
+ expect(prettyDate(secondsInTheFuture(weeks(2) + 8))).toBe('2 weeks from now');
+ });
+
+ it("returns 'last month' when time is some seconds before 4 weeks in the past", function() {
+ expect(prettyDate(secondsInThePast(weeks(4) + 9))).toBe('last month');
+ });
+
+ it("returns 'next month' when time is some seconds after 4 weeks in the future", function() {
+ expect(prettyDate(secondsInTheFuture(weeks(4) + 9))).toBe('next month');
+ });
+
+ it("returns '9 months ago' when time is some seconds before 9 months in the past", function() {
+ expect(prettyDate(secondsInThePast(months(9) + 10))).toBe('9 months ago');
+ });
+
+ it("returns '9 months from now' when time is some seconds after 9 months in the future", function() {
+ expect(prettyDate(secondsInTheFuture(months(9) + 10))).toBe('9 months from now');
+ });
+
+ it("returns 'last year' when time is some seconds before 12 months in the past", function() {
+ expect(prettyDate(secondsInThePast(months(12) + 11))).toBe('last year');
+ });
+
+ it("returns 'next year' when time is some seconds after 12 months in the future", function() {
+ expect(prettyDate(secondsInTheFuture(months(12) + 11))).toBe('next year');
+ });
+
+ it("returns '15 years ago' when time is some seconds before 15 years in the past", function() {
+ expect(prettyDate(secondsInThePast(years(15) + 12))).toBe('15 years ago');
+ });
+
+ it("returns '15 years from now' when time is some seconds after 15 years in the future", function() {
+ expect(prettyDate(secondsInTheFuture(years(15) + 12))).toBe('15 years from now');
+ });
+
+ it("returns 'last century' when time is some seconds before 100 years in the past", function() {
+ expect(prettyDate(secondsInThePast(years(100) + 13))).toBe('last century');
+ });
+
+ it("returns 'next century' when time is some seconds after 100 years in the future", function() {
+ expect(prettyDate(secondsInTheFuture(years(100) + 13))).toBe('next century');
+ });
+
+ it("returns '2 centuries ago' when time is some seconds before 2 centuries in the past", function() {
+ expect(prettyDate(secondsInThePast(centuries(2) + 14))).toBe('2 centuries ago');
+ });
+
+ it("returns '2 centuries from now' when time is some seconds after 2 centuries in the future", function() {
+ expect(prettyDate(secondsInTheFuture(centuries(2) + 14))).toBe('2 centuries from now');
+ });
+
+})
+
+function secondsInThePast(seconds) {
+ return Date.now() - seconds * 1000;
+}
+
+function secondsInTheFuture(seconds) {
+ return Date.now() + seconds * 1000;
+}
+
+function minutes(count) {
+ return 60 * count;
+}
+
+function hours(count) {
+ return 60 * minutes(count);
+}
+
+function days(count) {
+ return 24 * hours(count);
+}
+
+function weeks(count) {
+ return 7 * days(count);
+}
+
+function months(count) {
+ return 4 * weeks(count);
+}
+
+function years(count) {
+ return 12 * months(count);
+}
+
+function centuries(count) {
+ return 100 * years(count);
+}
diff --git a/templates/commentBarButtons.ejs b/templates/commentBarButtons.ejs
index a9657499..bdc2067f 100644
--- a/templates/commentBarButtons.ejs
+++ b/templates/commentBarButtons.ejs
@@ -1,4 +1,4 @@
diff --git a/templates/comments.html b/templates/comments.html
index ed0127cc..5a5723dd 100644
--- a/templates/comments.html
+++ b/templates/comments.html
@@ -6,11 +6,11 @@
{{if changeTo}}
{{/if}}
@@ -21,7 +21,7 @@
Suggest change From:
+
To:
- Comments
+ Comments
diff --git a/templates/menuButtons.ejs b/templates/menuButtons.ejs
index 589701aa..c5ad01ca 100644
--- a/templates/menuButtons.ejs
+++ b/templates/menuButtons.ejs
@@ -1,3 +1,3 @@
diff --git a/templates/settings.ejs b/templates/settings.ejs
index 95e93157..7040e027 100644
--- a/templates/settings.ejs
+++ b/templates/settings.ejs
@@ -1,4 +1,4 @@
-
+