Commit b3c70d00 authored by Vinnie Okada's avatar Vinnie Okada

Improve dashboard note view and add tests

Update the `#first_line_in_markdown` method so that the first line of
parsed text is displayed more reliably, and the continuation indicators
("...") are displayed in all cases where the note is truncated.

Also add Rspec tests for `EventsHelper#event_note`.
parent 5b2a42a0
......@@ -137,7 +137,7 @@ module EventsHelper
def event_note(text)
text = first_line_in_markdown(text, 150)
sanitize(text, tags: %w(a img b pre p))
sanitize(text, tags: %w(a img b pre code p))
end
def event_commit_title(message)
......
......@@ -56,16 +56,9 @@ module GitlabMarkdownHelper
# +max_chars+ limit. If the length limit falls within a tag's contents, then
# the tag contents are truncated without removing the closing tag.
def first_line_in_markdown(text, max_chars = nil)
line = text.split("\n").find do |i|
i.present? && markdown(i).present?
end
if line
md = markdown(line)
truncated = truncate_visible(md, max_chars || md.length)
end
md = markdown(text).strip
truncated
truncate_visible(md, max_chars || md.length) if md.present?
end
def render_wiki_content(wiki_page)
......@@ -221,22 +214,44 @@ module GitlabMarkdownHelper
def truncate_visible(text, max_chars)
doc = Nokogiri::HTML.fragment(text)
content_length = 0
truncated = false
doc.traverse do |node|
if node.text? || node.content.empty?
if content_length >= max_chars
if truncated
node.remove
next
end
# Handle line breaks within a node
if node.content.strip.lines.length > 1
node.content = "#{node.content.lines.first.chomp}..."
truncated = true
end
num_remaining = max_chars - content_length
if node.content.length > num_remaining
node.content = node.content.truncate(num_remaining)
truncated = true
end
content_length += node.content.length
end
truncated = truncate_if_block(node, truncated)
end
doc.to_html
end
# Used by #truncate_visible. If +node+ is the first block element, and the
# text hasn't already been truncated, then append "..." to the node contents
# and return true. Otherwise return false.
def truncate_if_block(node, truncated)
if node.element? && node.description.block? && !truncated
node.content = "#{node.content}..." if node.next_sibling
true
else
truncated
end
end
end
require 'spec_helper'
describe EventsHelper do
include ApplicationHelper
include GitlabMarkdownHelper
it 'should display one line of plain text without alteration' do
input = 'A short, plain note'
expect(event_note(input)).to match(input)
expect(event_note(input)).not_to match(/\.\.\.\z/)
end
it 'should display inline code' do
input = 'A note with `inline code`'
expected = 'A note with <code>inline code</code>'
expect(event_note(input)).to match(expected)
end
it 'should truncate a note with multiple paragraphs' do
input = "Paragraph 1\n\nParagraph 2"
expected = 'Paragraph 1...'
expect(event_note(input)).to match(expected)
end
it 'should display the first line of a code block' do
input = "```\nCode block\nwith two lines\n```"
expected = '<pre><code class="">Code block...</code></pre>'
expect(event_note(input)).to match(expected)
end
it 'should truncate a single long line of text' do
text = 'The quick brown fox jumped over the lazy dog twice' # 50 chars
input = "#{text}#{text}#{text}#{text}" # 200 chars
expected = "#{text}#{text}".sub(/.{3}/, '...')
expect(event_note(input)).to match(expected)
end
it 'should preserve a link href when link text is truncated' do
text = 'The quick brown fox jumped over the lazy dog' # 44 chars
input = "#{text}#{text}#{text} " # 133 chars
link_url = 'http://example.com/foo/bar/baz' # 30 chars
input << link_url
expected_link_text = 'http://example...</a>'
expect(event_note(input)).to match(link_url)
expect(event_note(input)).to match(expected_link_text)
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment