From 1f710232d83b1671231ae76fa81b25db31c29413 Mon Sep 17 00:00:00 2001 From: Sarah Mei Date: Sat, 28 Jan 2012 22:29:43 -0800 Subject: [PATCH] Clicking 'read more' now removes the link and collapses the adjacent paragraphs. Also: hella semicolons. Fixes #2766 --- .../app/views/stream_object_view.js | 12 ++- .../jasmine_fixtures/streams_spec.rb | 11 ++- .../javascripts/app/views/stream_view_spec.js | 89 ++++++++++++------- 3 files changed, 79 insertions(+), 33 deletions(-) diff --git a/public/javascripts/app/views/stream_object_view.js b/public/javascripts/app/views/stream_object_view.js index 57b44d5dc..c3b570c21 100644 --- a/public/javascripts/app/views/stream_object_view.js +++ b/public/javascripts/app/views/stream_object_view.js @@ -10,7 +10,17 @@ app.views.StreamObject = app.views.Base.extend({ widow: 12, expandPrefix: "", expandText: Diaspora.I18n.t("show_more"), - userCollapse: false + userCollapse: false, + beforeExpand: function() { + var readMoreDiv = $(this).find('.read-more'); + var lastParagraphBeforeReadMore = readMoreDiv.prev(); + var firstParagraphAfterReadMore = $(readMoreDiv.next().find('p')[0]); + + lastParagraphBeforeReadMore.append(firstParagraphAfterReadMore.text()); + + firstParagraphAfterReadMore.remove(); + readMoreDiv.remove(); + } }); }, diff --git a/spec/controllers/jasmine_fixtures/streams_spec.rb b/spec/controllers/jasmine_fixtures/streams_spec.rb index 95f3ed476..08ce6bb3e 100644 --- a/spec/controllers/jasmine_fixtures/streams_spec.rb +++ b/spec/controllers/jasmine_fixtures/streams_spec.rb @@ -14,14 +14,21 @@ describe StreamsController do posts = [] time = Time.now - 10.times do + + 10.times do |i| Timecop.travel time += 1.day do Timecop.travel time += 1.minute posts << alice.post(:status_message, :text => "hella infos yo!", :to => alice.aspects.first.id) Timecop.travel time += 1.minute posts << alice.post(:reshare, :root_guid => Factory(:status_message, :public => true).guid, :to => 'all') Timecop.travel time += 1.minute - posts << alice.post(:status_message, :text => "you're gonna love this.'", :to => alice.aspects.first.id) + if i == 9 + posts << alice.post(:status_message, + :text => "LONG POST TO TEST SHOW MORE. Cardigan trust fund vice, sartorial twee pitchfork +1 quinoa whatever readymade gluten-free. Seitan brooklyn mustache quinoa carles. Gentrify ethical four loko you probably haven't heard of them 3 wolf moon helvetica. Terry richardson +1 artisan, raw denim iphone four loko leggings organic helvetica retro mcsweeney's put a bird on it skateboard 3 wolf moon. Fap skateboard high life 8-bit. Iphone ethical tumblr lo-fi, dreamcatcher irony whatever farm-to-table mustache tofu marfa. Before they sold out next level lomo farm-to-table leggings, williamsburg jean shorts messenger bag. Synth readymade Austin artisan art party, cardigan vice mustache 3 wolf moon craft beer. Messenger bag before they sold out tattooed wayfarers viral photo booth. Food truck master cleanse locavore raw denim. Sustainable master cleanse seitan, trust fund cred yr keffiyeh butcher mlkshk put a bird on it gentrify you probably haven't heard of them vinyl craft beer gluten-free. Master cleanse retro next level messenger bag craft beer. DIY leggings dreamcatcher lo-fi. Etsy carles tattooed mcsweeney's food truck DIY wolf shoreditch.", + :to => alice.aspects.first.id) + else + posts << alice.post(:status_message, :text => "you're gonna love this.", :to => alice.aspects.first.id) + end Timecop.travel time += 1.minute alice.like(1, :target => posts.last) end diff --git a/spec/javascripts/app/views/stream_view_spec.js b/spec/javascripts/app/views/stream_view_spec.js index f7b5aa968..2fc93edb1 100644 --- a/spec/javascripts/app/views/stream_view_spec.js +++ b/spec/javascripts/app/views/stream_view_spec.js @@ -4,25 +4,25 @@ describe("app.views.Stream", function(){ this.posts = $.parseJSON(spec.readFixture("multi_stream_json"))["posts"]; - this.stream = new app.models.Stream() + this.stream = new app.models.Stream(); this.stream.add(this.posts); this.view = new app.views.Stream({model : this.stream}); - app.stream.bind("fetched", this.collectionFetched, this) //untested + app.stream.bind("fetched", this.collectionFetched, this); //untested // do this manually because we've moved loadMore into render?? this.view.render(); _.each(this.view.collection.models, function(post){ this.view.addPost(post); }, this); - }) + }); describe("initialize", function(){ it("binds an infinite scroll listener", function(){ spyOn($.fn, "scroll"); new app.views.Stream({model : this.stream}); - expect($.fn.scroll).toHaveBeenCalled() - }) - }) + expect($.fn.scroll).toHaveBeenCalled(); + }); + }); describe("#render", function(){ beforeEach(function(){ @@ -30,42 +30,71 @@ describe("app.views.Stream", function(){ this.reshare = this.stream.posts.models[1]; this.statusElement = $(this.view.$("#" + this.statusMessage.get("guid"))); this.reshareElement = $(this.view.$("#" + this.reshare.get("guid"))); - }) + }); - context("when rendering a Status Mesasage", function(){ - it("shows the status message in the content area", function(){ - expect(this.statusElement.find(".post-content p").text()).toContain("you're gonna love this") //markdown'ed - }) - }) - }) + context("when rendering a status message", function(){ + it("shows the message in the content area", function(){ + expect(this.statusElement.find(".post-content p").text()).toContain("LONG POST"); //markdown'ed + }); + }); + }); + + describe('clicking read more', function() { + var readMoreLink; + + beforeEach(function() { + this.statusMessage = this.stream.posts.models[0]; + this.statusElement = $(this.view.$("#" + this.statusMessage.get("guid"))); + readMoreLink = this.statusElement.find('.read-more a'); + readMoreLink.text("read more"); + }); + + it('expands the post', function() { + expect(this.statusElement.find('.collapsible .details')).toHaveAttr('style', 'display: none; '); + readMoreLink.click(); + expect(this.statusElement.find('.collapsible .details')).not.toHaveAttr('style', 'display: none; '); + }); + + it('removes the read-more div', function() { + expect(this.statusElement.find('.read-more').length).toEqual(1); + readMoreLink.click(); + expect(this.statusElement.find('.read-more').length).toEqual(0); + }); + + it('collapses the p elements', function() { + expect(this.statusElement.find('.collapsible p').length).toEqual(2); + readMoreLink.click(); + expect(this.statusElement.find('.collapsible p').length).toEqual(1); + }); + }); describe("infScroll", function(){ // NOTE: inf scroll happens at 500px it("calls render when the user is at the bottom of the page", function(){ - spyOn($.fn, "height").andReturn(0) - spyOn($.fn, "scrollTop").andReturn(100) - spyOn(this.view, "render") + spyOn($.fn, "height").andReturn(0); + spyOn($.fn, "scrollTop").andReturn(100); + spyOn(this.view, "render"); this.view.infScroll(); expect(this.view.render).toHaveBeenCalled(); - }) - }) + }); + }); describe("removeLoader", function() { it("emptys the pagination div when the stream is fetched", function(){ - $("#jasmine_content").append($('
OMG
')) - expect($("#paginate").text()).toBe("OMG") - this.view.stream.trigger("fetched") - expect($("#paginate")).toBeEmpty() - }) - }) + $("#jasmine_content").append($('
OMG
')); + expect($("#paginate").text()).toBe("OMG"); + this.view.stream.trigger("fetched"); + expect($("#paginate")).toBeEmpty(); + }); + }); describe("unbindInfScroll", function(){ it("unbinds scroll", function() { - spyOn($.fn, "unbind") - this.view.unbindInfScroll() - expect($.fn.unbind).toHaveBeenCalledWith("scroll") - }) - }) -}) + spyOn($.fn, "unbind"); + this.view.unbindInfScroll(); + expect($.fn.unbind).toHaveBeenCalledWith("scroll"); + }); + }); +});