diff --git a/app/helpers/html_helper.rb b/app/helpers/html_helper.rb
index a3d0bbab3..7b1b2b298 100644
--- a/app/helpers/html_helper.rb
+++ b/app/helpers/html_helper.rb
@@ -1,5 +1,30 @@
module HtmlHelper
def format_html(html)
- Loofah::HTML5::DocumentFragment.parse(html).scrub!(AutoLinkScrubber.new).to_html.html_safe
+ fragment = Loofah::HTML5::DocumentFragment.parse(html).scrub!(AutoLinkScrubber.new)
+ wrap_tables(fragment)
+ fragment.to_html.html_safe
end
+
+ private
+ def wrap_tables(fragment)
+ # Collect tables first to avoid modifying the collection while iterating
+ tables = fragment.css("table").to_a
+
+ tables.each do |table|
+ # Skip if already wrapped in a table-wrapper div
+ parent = table.parent
+ next if parent&.name == "div" && parent["class"]&.include?("table-wrapper")
+
+ # Save a copy of the table before replacing
+ table_copy = table.dup
+
+ # Create wrapper div
+ wrapper = Nokogiri::XML::Node.new("div", fragment.document)
+ wrapper["class"] = "table-wrapper"
+ wrapper.add_child(table_copy)
+
+ # Replace the original table with the wrapper (which contains the copied table)
+ table.replace(wrapper)
+ end
+ end
end
diff --git a/test/helpers/html_helper_test.rb b/test/helpers/html_helper_test.rb
index 1af507ddf..8880fbacc 100644
--- a/test/helpers/html_helper_test.rb
+++ b/test/helpers/html_helper_test.rb
@@ -119,4 +119,26 @@ class HtmlHelperTest < ActionView::TestCase
assert_no_match(/![]()
),
+ format_html("")
+ end
+
+ test "wrap multiple tables in separate table-wrapper divs" do
+ html = "text
"
+ output = format_html(html)
+
+ assert_match(/.*?first.*?<\/table><\/div>/, output)
+ assert_match(/.*?second.*?<\/table><\/div>/, output)
+ end
+
+ test "don't wrap tables that are already wrapped" do
+ html = %()
+ output = format_html(html)
+
+ # Should not create nested wrappers
+ assert_equal 1, output.scan(/class="table-wrapper"/).length
+ end
end