<%= render :partial => "diary_entry_heading", :object => diary_entry, :as => "diary_entry" %>
<div class="richtext text-break" xml:lang="<%= diary_entry.language_code %>" lang="<%= diary_entry.language_code %>">
- <%= diary_entry.body.to_html %>
+ <% if truncated %>
+ <% truncated_entry = diary_entry.body.truncate_html(2000) %>
+ <%= truncated_entry[:html] %>
+ <% if truncated_entry[:truncated] %>
+ <p>… <%= link_to t(".full_entry"), diary_entry_path(diary_entry.user, diary_entry) %></p>
+ <% end %>
+ <% else %>
+ <%= diary_entry.body.to_html %>
+ <% end %>
</div>
<% if diary_entry.latitude and diary_entry.longitude %>
<turbo-frame id="pagination" target="_top" data-turbo="false">
<h4><%= t ".recent_entries" %></h4>
- <%= render @entries %>
+ <%= render @entries, :truncated => true %>
<%= render "shared/pagination",
:newer_id => @newer_entries_id,
</div>
<% end %>
-<%= render @entry %>
+<%= render @entry, :truncated => false %>
<%= social_share_buttons(:title => @entry.title, :url => diary_entry_url(@entry.user, @entry)) %>
<div id="comments" class="comments mb-3 overflow-hidden">
diary_entry:
posted_by_html: "Posted by %{link_user} on %{created} in %{language_link}."
updated_at_html: "Last updated on %{updated}."
+ full_entry: See full entry
comment_link: Comment on this entry
reply_link: Send a message to the author
comment_count:
nil
end
+ def truncate_html(max_length = nil, img_length = 1000)
+ html_doc = to_html
+ return html_doc if max_length.nil?
+
+ doc = Nokogiri::HTML::DocumentFragment.parse(html_doc)
+ keep_or_discards = %w[p h1 h2 h3 h4 h5 h6 pre a table ul ol dl]
+ accumulated_length = 0
+ exceeded_node_parent = nil
+ truncated = false
+
+ doc.traverse do |node|
+ if accumulated_length >= max_length
+ if node == exceeded_node_parent
+ exceeded_node_parent = node.parent
+ node.remove if keep_or_discards.include?(node.name)
+ else
+ node.remove
+ end
+ next
+ end
+
+ next unless node.children.empty?
+
+ if node.text?
+ accumulated_length += node.text.length
+ elsif node.name == "img"
+ accumulated_length += img_length
+ end
+
+ if accumulated_length >= max_length
+ truncated = true
+ exceeded_node_parent = node.parent
+ node.remove
+ end
+ end
+
+ {
+ :truncated => truncated,
+ :html => doc.to_html.html_safe
+ }
+ end
+
protected
def simple_format(text)
assert_link "Diary Entries in Portuguese", :href => "/diary/pt"
assert_no_link "Diary Entries in Russian"
end
+
+ test "should not be hidden on the list page" do
+ body = SecureRandom.alphanumeric(1998)
+ create(:diary_entry, :body => body)
+
+ visit diary_entries_path
+
+ assert_content body
+ assert_no_content I18n.t("diary_entries.diary_entry.full_entry")
+ end
+
+ test "should be hidden on the list page" do
+ body = SecureRandom.alphanumeric(2000)
+ create(:diary_entry, :body => body)
+
+ visit diary_entries_path
+
+ assert_no_content body
+ assert_content I18n.t("diary_entries.diary_entry.full_entry")
+ end
+
+ test "should be partially hidden on the list page" do
+ text1 = "a" * 500
+ text2 = "b" * 500
+ text3 = "c" * 999
+ text4 = "dd"
+ text5 = "ff"
+
+ body = "<p>#{text1}</p><div><p>#{text2}</p><p>#{text3}<a href='#'>#{text4}</a></p></div><p>#{text5}</p>"
+ create(:diary_entry, :body => body)
+
+ visit diary_entries_path
+
+ assert_content text1
+ assert_content text2
+ assert_no_content text3
+ assert_no_content text4
+ assert_no_content text5
+ assert_content I18n.t("diary_entries.diary_entry.full_entry")
+ end
+
+ test "should not be hidden on the show page" do
+ body = SecureRandom.alphanumeric(2001)
+ diary_entry = create(:diary_entry, :body => body)
+
+ visit diary_entry_path(diary_entry.user, diary_entry)
+
+ assert_content body
+ assert_no_content I18n.t("diary_entries.diary_entry.full_entry")
+ end
end