From f4b3f2fd1e279eae0605e0dd769cea813d9ea63c Mon Sep 17 00:00:00 2001 From: Damien Date: Mon, 24 Jun 2013 22:17:44 +0200 Subject: [PATCH] Consider Markdown header content as post title clarify regexp and correct some bad backtracking add specs rewrite regex convert mardown style title to plain text title fix bad indentation add jasmine test for post-viewer.js tries to fix bad jasmine test --- .../javascripts/app/pages/post-viewer.js | 7 +++- app/helpers/posts_helper.rb | 15 ++++++-- app/presenters/post_presenter.rb | 5 ++- spec/helpers/posts_helper_spec.rb | 36 +++++++++++++++++++ .../javascripts/app/pages/post-viewer_spec.js | 14 ++++++++ spec/presenters/post_presenter_spec.rb | 26 +++++++++++--- 6 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 spec/javascripts/app/pages/post-viewer_spec.js diff --git a/app/assets/javascripts/app/pages/post-viewer.js b/app/assets/javascripts/app/pages/post-viewer.js index fddd01f19..237fdd3f1 100644 --- a/app/assets/javascripts/app/pages/post-viewer.js +++ b/app/assets/javascripts/app/pages/post-viewer.js @@ -73,7 +73,12 @@ app.pages.PostViewer = app.views.Base.extend({ }, postRenderTemplate : function() { - if(this.model.get("title")){ document.title = this.model.get("title"); } + if(this.model.get("title")){ + // formats title to html... + var html_title = app.helpers.textFormatter(this.model.get("title"), this.model); + //... and converts html to plain text + document.title = $('
').html(html_title).text(); + } }, commentAnywhere : function(evt) { diff --git a/app/helpers/posts_helper.rb b/app/helpers/posts_helper.rb index 5d073a853..ddd8d19d1 100644 --- a/app/helpers/posts_helper.rb +++ b/app/helpers/posts_helper.rb @@ -10,7 +10,18 @@ module PostsHelper I18n.t "posts.show.reshare_by", :author => post.author_name else if post.text.present? - truncate(post.text(:plain_text => true), :length => opts.fetch(:length, 20)) + if opts.has_key?(:length) + truncate(post.text(:plain_text => true), :length => opts.fetch(:length)) + elsif /\A(?: # Regexp to match a Markdown header present on first line : + (?.{1,200}\n(?:={1,200}|-{1,200}))(?:\r?\n|$) # Setext-style header + | # or + (?\#{1,6}\s.{1,200})(?:\r?\n|$) # Atx-style header + )/x =~ post.text(:plain_text => true) + return setext_content unless setext_content.nil? + return atx_content unless atx_content.nil? + else + truncate(post.text(:plain_text => true), :length => 20 ) + end elsif post.respond_to?(:photos) && post.photos.present? I18n.t "posts.show.photos_by", :count => post.photos.size, :author => post.author_name end @@ -19,7 +30,7 @@ module PostsHelper def post_iframe_url(post_id, opts={}) opts[:width] ||= 516 - opts[:height] ||= 315 + opts[:height] ||= 315 host = AppConfig.pod_uri.authority "".html_safe end diff --git a/app/presenters/post_presenter.rb b/app/presenters/post_presenter.rb index 03d05f559..919123266 100644 --- a/app/presenters/post_presenter.rb +++ b/app/presenters/post_presenter.rb @@ -1,4 +1,7 @@ class PostPresenter + include PostsHelper + include ActionView::Helpers::TextHelper + attr_accessor :post, :current_user def initialize(post, current_user = nil) @@ -54,7 +57,7 @@ class PostPresenter end def title - @post.text.present? ? @post.text(:plain_text => true) : I18n.translate('posts.presenter.title', :name => @post.author_name) + @post.text.present? ? post_page_title(@post) : I18n.translate('posts.presenter.title', :name => @post.author_name) end def template_name #kill me, lol, I should be client side diff --git a/spec/helpers/posts_helper_spec.rb b/spec/helpers/posts_helper_spec.rb index eb5d5bcd2..b8be45c97 100644 --- a/spec/helpers/posts_helper_spec.rb +++ b/spec/helpers/posts_helper_spec.rb @@ -5,6 +5,42 @@ require 'spec_helper' describe PostsHelper do + + describe '#post_page_title' do + before do + @sm = FactoryGirl.create(:status_message) + end + + context 'with posts with text' do + context 'when :length is passed in parameters' do + it 'returns string of size less or equal to :length' do + @sm = stub(:text => "## My title\n Post content...") + string_size = 12 + post_page_title(@sm, :length => string_size ).size.should <= string_size + end + end + context 'when :length is not passed in parameters' do + context 'with a Markdown header of less than 200 characters on first line'do + it 'returns atx style header' do + @sm = stub(:text => "## My title\n Post content...") + post_page_title(@sm).should == "## My title" + end + it 'returns setext style header' do + @sm = stub(:text => "My title \n======\n Post content...") + post_page_title(@sm).should == "My title \n======" + end + end + context 'without a Markdown header of less than 200 characters on first line 'do + it 'truncates posts to the 20 first characters' do + @sm = stub(:text => "Very, very, very long post") + post_page_title(@sm).should == "Very, very, very ..." + end + end + end + end + end + + describe '#post_iframe_url' do before do @post = FactoryGirl.create(:status_message) diff --git a/spec/javascripts/app/pages/post-viewer_spec.js b/spec/javascripts/app/pages/post-viewer_spec.js new file mode 100644 index 000000000..eeda1184a --- /dev/null +++ b/spec/javascripts/app/pages/post-viewer_spec.js @@ -0,0 +1,14 @@ +describe("app.Pages.PostViewer", function(){ + describe("postRenderTemplate", function(){ + beforeEach(function(){ + app.setPreload('post', factory.post({frame_name : "note"}).attributes); + this.page = new app.pages.PostViewer({id : 2}); + }) + it('translates post title from Markdown to plain text and pushes it in document.title', function () { + this.page.model.set({title : "### My [Markdown](url) *title*" }); + this.page.postRenderTemplate(); + expect(document.title).toEqual("My Markdown title"); + }) + }) +}); + diff --git a/spec/presenters/post_presenter_spec.rb b/spec/presenters/post_presenter_spec.rb index 1d70df86f..707e7fc5d 100644 --- a/spec/presenters/post_presenter_spec.rb +++ b/spec/presenters/post_presenter_spec.rb @@ -76,12 +76,28 @@ describe PostPresenter do end describe '#title' do - it 'includes the text if it is present' do - @sm = stub(:text => "lalalalalalala", :author => bob.person) - @presenter.post = @sm - @presenter.title.should == @sm.text - end + context 'with posts with text' do + context 'with a Markdown header of less than 200 characters on first line'do + it 'returns atx style header' do + @sm = stub(:text => "## My title\n Post content...") + @presenter.post = @sm + @presenter.title.should == "## My title" + end + it 'returns setext style header' do + @sm = stub(:text => "My title \n======\n Post content...") + @presenter.post = @sm + @presenter.title.should == "My title \n======" + end + end + context 'without a Markdown header of less than 200 characters on first line 'do + it 'truncates post to the 20 first characters' do + @sm = stub(:text => "Very, very, very long post") + @presenter.post = @sm + @presenter.title.should == "Very, very, very ..." + end + end + end context 'with posts without text' do it ' displays a messaage with the post class' do