]> git.openstreetmap.org Git - rails.git/commitdiff
Merge remote-tracking branch 'upstream/pull/5121' master live
authorTom Hughes <tom@compton.nu>
Wed, 16 Apr 2025 17:14:47 +0000 (18:14 +0100)
committerTom Hughes <tom@compton.nu>
Wed, 16 Apr 2025 17:14:47 +0000 (18:14 +0100)
app/views/diary_entries/_diary_entry.html.erb
app/views/diary_entries/_page.html.erb
app/views/diary_entries/show.html.erb
config/locales/en.yml
lib/rich_text.rb
test/system/diary_entry_test.rb

index a4fb347830e7c2bdfca0c48facadd5f1300ad533..dc41380b3c512fb5d53bca0cb98e1f7fe4840132 100644 (file)
@@ -2,7 +2,15 @@
   <%= 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>&hellip; <%= 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 %>
index c44a5417ea4538c8005322f9925c232a3ad1a4a6..9cba05d20ee9612f3fa8bfb5959d9e544e55c411 100644 (file)
@@ -1,7 +1,7 @@
 <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,
index 9e3e7da650ea0c7b8475153367056849a34b4765..c83189099773364c51be51ad15b72a917dcc6d44 100644 (file)
@@ -14,7 +14,7 @@
   </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">
index 35ba0650bc2f6475d528e3ec37a3f50458e2c533..c9c335ec79a35f0707d1b52895094fe3bb935f6b 100644 (file)
@@ -608,6 +608,7 @@ en:
     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:
index 79249730707cbfa75dfda488c614dba2a01d0b1b..d5422b83148e7fc26d9685720aa4062b266e68ca 100644 (file)
@@ -63,6 +63,48 @@ module RichText
       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)
index ba091c538465d8dcf6ac7471665d49516b7f925a..1cf72c964914a6b925fc81433cf9a53f5f2b738b 100644 (file)
@@ -74,4 +74,54 @@ class DiaryEntrySystemTest < ApplicationSystemTestCase
     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