From 4769a25d592559ce5757bab6794e06fca71e6c81 Mon Sep 17 00:00:00 2001 From: Joe Bivins Date: Sat, 3 Mar 2012 12:14:43 -0500 Subject: [PATCH 1/4] Add ISO 8601 timestamp parsing for legacy browsers. Would cause legacy browsers (e.g. Safari 4.1.3) to show posts in the reverse order and the infinite scroll would not be triggered when scrolling down to the end of the page. --- public/javascripts/app/models/post.js | 26 +++++++++++++++++++- spec/javascripts/app/views/post_view_spec.js | 8 ++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/public/javascripts/app/models/post.js b/public/javascripts/app/models/post.js index c7ad731c6..1a27b5a8a 100644 --- a/public/javascripts/app/models/post.js +++ b/public/javascripts/app/models/post.js @@ -21,7 +21,31 @@ app.models.Post = Backbone.Model.extend({ }, timeOf: function(field) { - return new Date(this.get(field)) /1000; + var timestamp = new Date(this.get(field)) /1000; + + if (isNaN(timestamp)) { + timestamp = this.legacyTimeOf(field); + } + + return timestamp; + }, + + legacyTimeOf: function(field) { + var iso8601_utc_pattern = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.(\d{3}))?Z$/; + var time_components = this.get(field).match(iso8601_utc_pattern); + var timestamp = 0; + + if (time_components != null) { + if (time_components[8] == undefined) { + time_components[8] = 0; + } + + timestamp = Date.UTC(time_components[1], time_components[2] - 1, time_components[3], + time_components[4], time_components[5], time_components[6], + time_components[8]); + } + + return timestamp /1000; }, createReshareUrl : "/reshares", diff --git a/spec/javascripts/app/views/post_view_spec.js b/spec/javascripts/app/views/post_view_spec.js index 9eb66d9a2..17080155a 100644 --- a/spec/javascripts/app/views/post_view_spec.js +++ b/spec/javascripts/app/views/post_view_spec.js @@ -119,5 +119,13 @@ describe("app.views.Post", function(){ }) }) + context("legacy browsers", function(){ + it("supports iso8501 utc timestamps", function(){ + var timestamp = new Date(this.statusMessage.get("created_at")) /1000; + + expect(this.statusMessage.legacyTimeOf("created_at")).toEqual(timestamp); + }) + }) + }) }); From e26fcf836ac249622dae013a8b3fb4d2c3ab7c3a Mon Sep 17 00:00:00 2001 From: Joe Bivins Date: Sat, 3 Mar 2012 12:20:31 -0500 Subject: [PATCH 2/4] Correct JS error in app_spec.js --- spec/javascripts/app/app_spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/javascripts/app/app_spec.js b/spec/javascripts/app/app_spec.js index 96884b650..f85054293 100644 --- a/spec/javascripts/app/app_spec.js +++ b/spec/javascripts/app/app_spec.js @@ -2,6 +2,7 @@ describe("app", function() { describe("user", function() { it("sets the user if given one and returns the current user", function() { expect(app.user()).toBeFalsy() + }); it("sets the user if given one and returns the current user", function() { expect(app.user().authenticated()).toBeFalsy() From 8df0bb85fe36fd26e2919a81e868124311f1d366 Mon Sep 17 00:00:00 2001 From: Joe Bivins Date: Sat, 3 Mar 2012 12:29:09 -0500 Subject: [PATCH 3/4] Wrap the publisher params tag in a div instead of a paragraph. Safari 4.1.3 cited the closing params tag as being an unmatched tag. Changing the paragraph to a div causes the error to disappear. --- app/views/shared/_publisher.html.haml | 2 +- public/javascripts/app/models/post.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/shared/_publisher.html.haml b/app/views/shared/_publisher.html.haml index 2c76eab50..4c8d86094 100644 --- a/app/views/shared/_publisher.html.haml +++ b/app/views/shared/_publisher.html.haml @@ -12,7 +12,7 @@ .content_creation = form_for(StatusMessage.new) do |status| = status.error_messages - %p + %div %params #publisher_textarea_wrapper = link_to( image_tag('deletelabel.png'), "#", :id => "hide_publisher", :title => t('.discard_post')) diff --git a/public/javascripts/app/models/post.js b/public/javascripts/app/models/post.js index 1a27b5a8a..df3abb01e 100644 --- a/public/javascripts/app/models/post.js +++ b/public/javascripts/app/models/post.js @@ -24,7 +24,7 @@ app.models.Post = Backbone.Model.extend({ var timestamp = new Date(this.get(field)) /1000; if (isNaN(timestamp)) { - timestamp = this.legacyTimeOf(field); + timestamp = this.legacyTimeOf(field); } return timestamp; From 7b47edff14fc6c542aa8d4567c395886caa1dc1d Mon Sep 17 00:00:00 2001 From: Joe Bivins Date: Sun, 4 Mar 2012 13:34:27 -0500 Subject: [PATCH 4/4] Move date parsing to a helper. --- .../javascripts/app/helpers/date_formatter.js | 35 +++++++++++++++++++ public/javascripts/app/models/photo.js | 4 +-- public/javascripts/app/models/post.js | 26 +------------- .../app/helpers/date_formatter_spec.js | 33 +++++++++++++++++ spec/javascripts/app/views/post_view_spec.js | 8 ----- 5 files changed, 71 insertions(+), 35 deletions(-) create mode 100644 public/javascripts/app/helpers/date_formatter.js create mode 100644 spec/javascripts/app/helpers/date_formatter_spec.js diff --git a/public/javascripts/app/helpers/date_formatter.js b/public/javascripts/app/helpers/date_formatter.js new file mode 100644 index 000000000..dbcb005b6 --- /dev/null +++ b/public/javascripts/app/helpers/date_formatter.js @@ -0,0 +1,35 @@ +(function(){ + var dateFormatter = function dateFormatter() { + + }; + + dateFormatter.parse = function(date_string) { + var timestamp = new Date(date_string).getTime(); + + if (isNaN(timestamp)) { + timestamp = dateFormatter.parseISO8601UTC(date_string); + } + + return timestamp; + }, + + dateFormatter.parseISO8601UTC = function(date_string) { + var iso8601_utc_pattern = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.(\d{3}))?Z$/; + var time_components = date_string.match(iso8601_utc_pattern); + var timestamp = 0; + + if (time_components != null) { + if (time_components[8] == undefined) { + time_components[8] = 0; + } + + timestamp = Date.UTC(time_components[1], time_components[2] - 1, time_components[3], + time_components[4], time_components[5], time_components[6], + time_components[8]); + } + + return timestamp; + }, + + app.helpers.dateFormatter = dateFormatter; +})(); diff --git a/public/javascripts/app/models/photo.js b/public/javascripts/app/models/photo.js index 05b4a3c1e..cefbb0e1d 100644 --- a/public/javascripts/app/models/photo.js +++ b/public/javascripts/app/models/photo.js @@ -8,7 +8,7 @@ app.models.Photo = Backbone.Model.extend({ }, timeOf: function(field) { - return new Date(this.get(field)) /1000; + return app.helpers.dateFormatter.parse(this.get(field)) / 1000; }, -}); \ No newline at end of file +}); diff --git a/public/javascripts/app/models/post.js b/public/javascripts/app/models/post.js index df3abb01e..a5beb5ecd 100644 --- a/public/javascripts/app/models/post.js +++ b/public/javascripts/app/models/post.js @@ -21,31 +21,7 @@ app.models.Post = Backbone.Model.extend({ }, timeOf: function(field) { - var timestamp = new Date(this.get(field)) /1000; - - if (isNaN(timestamp)) { - timestamp = this.legacyTimeOf(field); - } - - return timestamp; - }, - - legacyTimeOf: function(field) { - var iso8601_utc_pattern = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.(\d{3}))?Z$/; - var time_components = this.get(field).match(iso8601_utc_pattern); - var timestamp = 0; - - if (time_components != null) { - if (time_components[8] == undefined) { - time_components[8] = 0; - } - - timestamp = Date.UTC(time_components[1], time_components[2] - 1, time_components[3], - time_components[4], time_components[5], time_components[6], - time_components[8]); - } - - return timestamp /1000; + return app.helpers.dateFormatter.parse(this.get(field)) / 1000; }, createReshareUrl : "/reshares", diff --git a/spec/javascripts/app/helpers/date_formatter_spec.js b/spec/javascripts/app/helpers/date_formatter_spec.js new file mode 100644 index 000000000..9d317a108 --- /dev/null +++ b/spec/javascripts/app/helpers/date_formatter_spec.js @@ -0,0 +1,33 @@ +describe("app.helpers.dateFormatter", function(){ + + beforeEach(function(){ + this.statusMessage = factory.post(); + this.formatter = app.helpers.dateFormatter; + }) + + describe("parse", function(){ + context("modern web browsers", function(){ + it ("supports ISO 8601 UTC dates", function(){ + var timestamp = new Date(this.statusMessage.get("created_at")).getTime(); + expect(this.formatter.parse(this.statusMessage.get("created_at"))).toEqual(timestamp); + }) + }) + + context("legacy web browsers", function(){ + it("supports ISO 8601 UTC dates", function(){ + var timestamp = new Date(this.statusMessage.get("created_at")).getTime(); + + expect(this.formatter.parseISO8601UTC(this.statusMessage.get("created_at"))).toEqual(timestamp); + }) + }) + + context("status messages", function(){ + it("uses ISO 8601 UTC dates", function(){ + var iso8601_utc_pattern = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.(\d{3}))?Z$/; + + expect(iso8601_utc_pattern.test(this.statusMessage.get("created_at"))).toBe(true); + }) + }) + }) + +}) diff --git a/spec/javascripts/app/views/post_view_spec.js b/spec/javascripts/app/views/post_view_spec.js index 17080155a..9eb66d9a2 100644 --- a/spec/javascripts/app/views/post_view_spec.js +++ b/spec/javascripts/app/views/post_view_spec.js @@ -119,13 +119,5 @@ describe("app.views.Post", function(){ }) }) - context("legacy browsers", function(){ - it("supports iso8501 utc timestamps", function(){ - var timestamp = new Date(this.statusMessage.get("created_at")) /1000; - - expect(this.statusMessage.legacyTimeOf("created_at")).toEqual(timestamp); - }) - }) - }) });