Better ActionText plain text output for nested lists (#37976)
* Improve plaintext output for nested lists * Update plain_text_conversion_test.rb * Add additional test cases * Refactor a bit * Add changelog entry * Rearrange methods Co-authored-by: Matt Swanson <matt@mdswanson.com>
This commit is contained in:
parent
dedefdd297
commit
0b1f83d0bc
|
@ -1,3 +1,7 @@
|
|||
* Fix an issue with how nested lists were displayed when converting to plain text
|
||||
|
||||
*Matt Swanson*
|
||||
|
||||
* Allow passing in a custom `direct_upload_url` or `blob_url_template` to `rich_text_area_tag`.
|
||||
|
||||
*Lucas Mansur*
|
||||
|
|
|
@ -33,10 +33,18 @@ module ActionText
|
|||
"#{remove_trailing_newlines(plain_text_for_node_children(node))}\n\n"
|
||||
end
|
||||
|
||||
%i[ h1 p ul ol ].each do |element|
|
||||
%i[ h1 p ].each do |element|
|
||||
alias_method :"plain_text_for_#{element}_node", :plain_text_for_block
|
||||
end
|
||||
|
||||
def plain_text_for_list(node, index)
|
||||
"#{break_if_nested_list(node, plain_text_for_block(node))}"
|
||||
end
|
||||
|
||||
%i[ ul ol ].each do |element|
|
||||
alias_method :"plain_text_for_#{element}_node", :plain_text_for_list
|
||||
end
|
||||
|
||||
def plain_text_for_br_node(node, index)
|
||||
"\n"
|
||||
end
|
||||
|
@ -61,7 +69,9 @@ module ActionText
|
|||
def plain_text_for_li_node(node, index)
|
||||
bullet = bullet_for_li_node(node, index)
|
||||
text = remove_trailing_newlines(plain_text_for_node_children(node))
|
||||
"#{bullet} #{text}\n"
|
||||
indentation = indentation_for_li_node(node)
|
||||
|
||||
"#{indentation}#{bullet} #{text}\n"
|
||||
end
|
||||
|
||||
def remove_trailing_newlines(text)
|
||||
|
@ -79,5 +89,24 @@ module ActionText
|
|||
def list_node_name_for_li_node(node)
|
||||
node.ancestors.lazy.map(&:name).grep(/^[uo]l$/).first
|
||||
end
|
||||
|
||||
def indentation_for_li_node(node)
|
||||
depth = list_node_depth_for_node(node)
|
||||
if depth > 1
|
||||
" " * (depth - 1)
|
||||
end
|
||||
end
|
||||
|
||||
def list_node_depth_for_node(node)
|
||||
node.ancestors.map(&:name).grep(/^[uo]l$/).count
|
||||
end
|
||||
|
||||
def break_if_nested_list(node, text)
|
||||
if list_node_depth_for_node(node) > 0
|
||||
"\n#{text}"
|
||||
else
|
||||
text
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -52,6 +52,27 @@ class ActionText::PlainTextConversionTest < ActiveSupport::TestCase
|
|||
)
|
||||
end
|
||||
|
||||
test "basic nested <ul> tags are indented" do
|
||||
assert_converted_to(
|
||||
"• Item 1\n • Item 2",
|
||||
"<ul><li>Item 1<ul><li>Item 2</li></ul></li></ul>"
|
||||
)
|
||||
end
|
||||
|
||||
test "basic nested <ol> tags are indented" do
|
||||
assert_converted_to(
|
||||
"1. Item 1\n 1. Item 2",
|
||||
"<ol><li>Item 1<ol><li>Item 2</li></ol></li></ol>"
|
||||
)
|
||||
end
|
||||
|
||||
test "complex nested / mixed list tags are indented" do
|
||||
assert_converted_to(
|
||||
"• Item 0\n• Item 1\n • Item A\n 1. Item i\n 2. Item ii\n • Item B\n • Item i\n• Item 2",
|
||||
"<ul><li>Item 0</li><li>Item 1<ul><li>Item A<ol><li>Item i</li><li>Item ii</li></ol></li><li>Item B<ul><li>Item i</li></ul></li></ul></li><li>Item 2</li></ul>"
|
||||
)
|
||||
end
|
||||
|
||||
test "<br> tags are separated by one new line" do
|
||||
assert_converted_to(
|
||||
"Hello world!\none\ntwo\nthree",
|
||||
|
|
Loading…
Reference in New Issue