diff options
author | Brett Walker <bwalker@gitlab.com> | 2019-03-28 18:45:59 -0500 |
---|---|---|
committer | Brett Walker <bwalker@gitlab.com> | 2019-04-03 12:16:12 -0500 |
commit | cbbc1207bd90eda33b159eb398ae53544f9a6891 (patch) | |
tree | 7edde7e3c0ea432e4bb962952a72edf9eea4dab2 | |
parent | 9f6ab1a5953eff45da9b8d2a5fcb92fe7b44a95d (diff) | |
download | gitlab-ce-58717-checkbox-in-issue-description-cannot-be-checked-if-the-description-contains-a-blockquote.tar.gz |
Use the indexed checkbox to find line in the DOM58717-checkbox-in-issue-description-cannot-be-checked-if-the-description-contains-a-blockquote
4 files changed, 44 insertions, 12 deletions
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index 04dfcfbc22d..f363cb03a3f 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -272,7 +272,8 @@ class IssuableBaseService < BaseService tasklist_toggler = TaskListToggleService.new(issuable.description, issuable.description_html, line_source: update_task_params[:line_source], line_number: update_task_params[:line_number].to_i, - toggle_as_checked: update_task_params[:checked]) + toggle_as_checked: update_task_params[:checked], + index: update_task_params[:index]) unless tasklist_toggler.execute # if we make it here, the data is much newer than we thought it was - fail fast diff --git a/app/services/task_list_toggle_service.rb b/app/services/task_list_toggle_service.rb index f6602a35033..800787e5c51 100644 --- a/app/services/task_list_toggle_service.rb +++ b/app/services/task_list_toggle_service.rb @@ -8,10 +8,11 @@ class TaskListToggleService attr_reader :updated_markdown, :updated_markdown_html - def initialize(markdown, markdown_html, line_source:, line_number:, toggle_as_checked:) + def initialize(markdown, markdown_html, line_source:, line_number:, toggle_as_checked:, index:) @markdown, @markdown_html = markdown, markdown_html @line_source, @line_number = line_source, line_number @toggle_as_checked = toggle_as_checked + @index = index @updated_markdown, @updated_markdown_html = nil end @@ -26,6 +27,7 @@ class TaskListToggleService attr_reader :markdown, :markdown_html, :toggle_as_checked attr_reader :line_source, :line_number + attr_reader :index def toggle_markdown source_lines = markdown.split("\n") @@ -64,9 +66,12 @@ class TaskListToggleService @updated_markdown_html = html.to_html end - # When using CommonMark, we should be able to use the embedded `sourcepos` attribute to - # target the exact line in the DOM. + # At the moment, we can't use the CommonMark `sourcepos` + # html.css(".task-list-item[data-sourcepos^='#{line_number}:'] input.task-list-item-checkbox").first + # because special tags that change the line numbering (like the GitLab blockquote) will + # cause it to break. + # Use the indexed checkbox instead to target the exact line in the DOM. def get_html_checkbox(html) - html.css(".task-list-item[data-sourcepos^='#{line_number}:'] input.task-list-item-checkbox").first + html.css('.task-list-item-checkbox')[index - 1] end end diff --git a/changelogs/unreleased/58717-checkbox-in-issue-description-cannot-be-checked-if-the-description-contains-a-blockquote.yml b/changelogs/unreleased/58717-checkbox-in-issue-description-cannot-be-checked-if-the-description-contains-a-blockquote.yml new file mode 100644 index 00000000000..7c1dde260b7 --- /dev/null +++ b/changelogs/unreleased/58717-checkbox-in-issue-description-cannot-be-checked-if-the-description-contains-a-blockquote.yml @@ -0,0 +1,5 @@ +--- +title: Allow task lists that follow a blockquote to work correctly +merge_request: 26748 +author: +type: fixed diff --git a/spec/services/task_list_toggle_service_spec.rb b/spec/services/task_list_toggle_service_spec.rb index b1260cf740a..3c69757aac4 100644 --- a/spec/services/task_list_toggle_service_spec.rb +++ b/spec/services/task_list_toggle_service_spec.rb @@ -52,7 +52,7 @@ describe TaskListToggleService do it 'checks Task 1' do toggler = described_class.new(markdown, markdown_html, toggle_as_checked: true, - line_source: '* [ ] Task 1', line_number: 1) + line_source: '* [ ] Task 1', line_number: 1, index: 1) expect(toggler.execute).to be_truthy expect(toggler.updated_markdown.lines[0]).to eq "* [x] Task 1\n" @@ -62,7 +62,7 @@ describe TaskListToggleService do it 'unchecks Item 1' do toggler = described_class.new(markdown, markdown_html, toggle_as_checked: false, - line_source: '1. [X] Item 1', line_number: 6) + line_source: '1. [X] Item 1', line_number: 6, index: 3) expect(toggler.execute).to be_truthy expect(toggler.updated_markdown.lines[5]).to eq "1. [ ] Item 1\n" @@ -72,7 +72,7 @@ describe TaskListToggleService do it 'checks task in loose list' do toggler = described_class.new(markdown, markdown_html, toggle_as_checked: true, - line_source: '- [ ] loose list', line_number: 9) + line_source: '- [ ] loose list', line_number: 9, index: 5) expect(toggler.execute).to be_truthy expect(toggler.updated_markdown.lines[8]).to eq "- [x] loose list\n" @@ -82,7 +82,7 @@ describe TaskListToggleService do it 'returns false if line_source does not match the text' do toggler = described_class.new(markdown, markdown_html, toggle_as_checked: false, - line_source: '* [x] Task Added', line_number: 2) + line_source: '* [x] Task Added', line_number: 2, index: 2) expect(toggler.execute).to be_falsey end @@ -91,7 +91,7 @@ describe TaskListToggleService do rn_markdown = markdown.gsub("\n", "\r\n") toggler = described_class.new(rn_markdown, markdown_html, toggle_as_checked: true, - line_source: '* [ ] Task 1', line_number: 1) + line_source: '* [ ] Task 1', line_number: 1, index: 1) expect(toggler.execute).to be_truthy expect(toggler.updated_markdown.lines[0]).to eq "* [x] Task 1\r\n" @@ -101,7 +101,7 @@ describe TaskListToggleService do it 'returns false if markdown is nil' do toggler = described_class.new(nil, markdown_html, toggle_as_checked: false, - line_source: '* [x] Task Added', line_number: 2) + line_source: '* [x] Task Added', line_number: 2, index: 2) expect(toggler.execute).to be_falsey end @@ -109,8 +109,29 @@ describe TaskListToggleService do it 'returns false if markdown_html is nil' do toggler = described_class.new(markdown, nil, toggle_as_checked: false, - line_source: '* [x] Task Added', line_number: 2) + line_source: '* [x] Task Added', line_number: 2, index: 2) expect(toggler.execute).to be_falsey end + + it 'properly handles a GitLab blockquote' do + markdown = + <<-EOT.strip_heredoc + >>> + gitlab blockquote + >>> + + * [ ] Task 1 + * [x] Task 2 + EOT + + markdown_html = Banzai::Pipeline::FullPipeline.call(markdown, project: nil)[:output].to_html + toggler = described_class.new(markdown, markdown_html, + toggle_as_checked: true, + line_source: '* [ ] Task 1', line_number: 5, index: 1) + + expect(toggler.execute).to be_truthy + expect(toggler.updated_markdown.lines[4]).to eq "* [x] Task 1\n" + expect(toggler.updated_markdown_html).to include('disabled checked> Task 1') + end end |