diff --git a/lib/rails/html/scrubbers.rb b/lib/rails/html/scrubbers.rb index a1317ad..e074e65 100644 --- a/lib/rails/html/scrubbers.rb +++ b/lib/rails/html/scrubbers.rb @@ -195,5 +195,33 @@ def scrub(node) end end end + + # === Rails::HTML::SpaceBlockElementScrubber + # + # +Rails::HTML::SpaceBlockElementScrubber+ removes all undisplayable tags and contents. + # + # It preserves text contents and inserts a space around block level elements. + class SpaceBlockElementScrubber < Loofah::Scrubber # :nodoc: + def initialize + @direction = :bottom_up + end + + def scrub(node) + if Loofah::Elements::LINEBREAKERS.include?(node.name) + replacement = if Loofah::Elements::INLINE_LINE_BREAK.include?(node.name) + " " + else + " #{node.content} " + end + node.add_next_sibling(Nokogiri::XML::Text.new(replacement, node.document)) + node.remove + elsif node.text? + CONTINUE + else + node.before node.children + node.remove + end + end + end end end diff --git a/test/scrubbers_test.rb b/test/scrubbers_test.rb index 8db2d85..ac979b6 100644 --- a/test/scrubbers_test.rb +++ b/test/scrubbers_test.rb @@ -200,6 +200,20 @@ def test_skips_text_nodes end end +class SpaceBlockElementScrubberTest < ScrubberTest + def setup + @scrubber = Rails::HTML::SpaceBlockElementScrubber.new + end + + def test_removes_all_tags_and_keeps_the_text_content_and_adds_spaces + assert_scrubbed %(<div><h1>A list!</h1><ul><li>An element!</li></ul><script>alert("hi!")</script></div>), " A list! An element! " + end + + def test_skips_text_nodes + assert_node_skipped("some text") + end +end + class ReturningStopFromScrubNodeTest < ScrubberTest class ScrubStopper < Rails::HTML::PermitScrubber def scrub_node(node)