Fix case of task list with link after text node

pull/8401/head
Oliver Günther 5 years ago
parent eb31d5d3b7
commit ff4d430eb0
No known key found for this signature in database
GPG Key ID: A3A8BDAD7C0C552C
  1. 31
      lib/open_project/text_formatting/filters/sanitization_filter.rb
  2. 65
      spec/lib/open_project/text_formatting/markdown/markdown_todo_list_spec.rb

@ -81,21 +81,34 @@ module OpenProject::TextFormatting
table.css('label.todo-list__label').each do |label|
checkbox = label.css('input[type=checkbox]').first
checked = checkbox.attr('checked') == 'checked' ? 'x' : ' '
checkbox.unlink
li_node = label.ancestors.detect { |node| node.name == 'li' }
# assign all children of the label to its parent
# that might be the LI, or another element (code, link)
parent = label.parent
# However the task list text must be added to the LI
li_node = label.ancestors.detect { |node| node.name == 'li' }
li_node.prepend_child " [#{checked}] "
# Prepend if there is a parent in between
if parent == li_node
parent.add_child label.children
# CKEditor splits text nodes within task lists so that there are multiple labels
# but only the first has a checkbox
# e.g., - [ ] Foo [Bar](https://example.com)
# both Foo and Bar are contained by labels
if checkbox.nil?
# In case we don't have a checkbox, add the content of the label
# or it's parent in case of links directly to the node
to_add = li_node == parent ? label.children : parent
li_node.add_child to_add
else
parent.prepend_child label.children
checked = checkbox.attr('checked') == 'checked' ? 'x' : ' '
checkbox.unlink
# Ensure the task list text is be added as first child to the LI
li_node.prepend_child " [#{checked}] "
# Prepend if there is a parent in between
if parent == li_node
parent.add_child label.children
else
parent.prepend_child label.children
end
end
end
}

@ -197,5 +197,70 @@ describe OpenProject::TextFormatting,
expect(subject).to be_html_eql(expected)
end
end
describe 'with a todo list with a link on second place' do
let(:raw) do
<<~RAW
<table>
<tbody>
<tr>
<td>asdf</td>
<td>asdfasdf</td>
</tr>
<tr>
<td>
<ul class="todo-list">
<li>
<label class="todo-list__label"><input type="checkbox" disabled="disabled">
<span class="todo-list__label__description">asdfasdfasdf </span>
</label>
<a href="https://example.com/">
<label class="todo-list__label">
<span class="todo-list__label__description">foobar</span>
</label>
</a>
</li>
</ul>
</td>
<td></td>
</tr>
</tbody>
</table>
RAW
end
let(:expected) do
<<~EXPECTED
<table>
<tbody>
<tr>
<td>asdf</td>
<td>asdfasdf</td>
</tr>
<tr>
<td>
<ul class="task-list">
<li class="task-list-item">
<input type="checkbox" class="task-list-item-checkbox" disabled>
<span>asdfasdfasdf </span>
<a href="https://example.com/" rel="noopener noreferrer">
<span>foobar</span>
</a>
</li>
</ul>
</td>
<td></td>
</tr>
</tbody>
</table>
EXPECTED
end
subject { format_text(raw) }
it 'should correctly place the link after the text node' do
expect(subject).to be_html_eql(expected)
end
end
end
end

Loading…
Cancel
Save