diff options
author | Brett Walker <bwalker@gitlab.com> | 2019-01-24 16:13:35 -0600 |
---|---|---|
committer | Fatih Acet <acetfatih@gmail.com> | 2019-01-30 23:18:18 +0100 |
commit | b119fcb2e49289d26042e559d37fbfae58ac1536 (patch) | |
tree | 791a5a49b9947ab5e7cc66c7547ec291d3f3040e /app/services | |
parent | e42d95fb9e412388eb3215dff674e05c73d65977 (diff) | |
download | gitlab-ce-b119fcb2e49289d26042e559d37fbfae58ac1536.tar.gz |
Refactor and added specs
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/issues/update_service.rb | 16 | ||||
-rw-r--r-- | app/services/task_list_toggle_service.rb | 60 |
2 files changed, 68 insertions, 8 deletions
diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index cf6173da8d4..9c7b8fcc6ab 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -129,17 +129,17 @@ module Issues update_task_params = params.delete(:update_task) return unless update_task_params - updated_content = Taskable.toggle_task(issue.description, issue.description_html, - index: update_task_params[:index], - currently_checked: !update_task_params[:checked], - line_source: update_task_params[:line_source], - line_number: update_task_params[:line_number]) + toggler = TaskListToggleService.new(issue.description, issue.description_html, + index: update_task_params[:index], + currently_checked: !update_task_params[:checked], + line_source: update_task_params[:line_source], + line_number: update_task_params[:line_number]) - unless updated_content.empty? + if toggler.execute # by updating the description_html field at the same time, # the markdown cache won't be considered invalid - params[:description] = updated_content[:content] - params[:description_html] = updated_content[:content_html] + params[:description] = toggler.updated_markdown + params[:description_html] = toggler.updated_markdown_html # since we're updating a very specific line, we don't care whether # the `lock_version` sent from the FE is the same or not. Just diff --git a/app/services/task_list_toggle_service.rb b/app/services/task_list_toggle_service.rb new file mode 100644 index 00000000000..84a875dbaf7 --- /dev/null +++ b/app/services/task_list_toggle_service.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +# Finds the correct checkbox in the passed in markdown/html and toggles it's state, +# returning the updated markdown/html +# We don't care if the text has changed above or below the specific checkbox, as long +# the checkbox still exists at exactly the same line number and the text is equal +# If successful, new values are available in `updated_markdown` and `updated_markdown_html` +class TaskListToggleService + attr_reader :updated_markdown, :updated_markdown_html + + def initialize(markdown, markdown_html, index:, currently_checked:, line_source:, line_number:) + @markdown, @markdown_html = markdown, markdown_html + @index, @currently_checked = index, currently_checked + @line_source, @line_number = line_source, line_number + + @updated_markdown, @updated_markdown_html = nil + end + + def execute + return false unless markdown && markdown_html + + !!(toggle_markdown && toggle_html) + end + + private + + attr_reader :markdown, :markdown_html, :index, :currently_checked, :line_source, :line_number + + def toggle_markdown + source_lines = markdown.split("\n") + markdown_task = source_lines[line_number - 1] + + return unless markdown_task == line_source + return unless source_checkbox = Taskable::ITEM_PATTERN.match(markdown_task) + + if TaskList::Item.new(source_checkbox[1]).complete? + markdown_task.sub!(Taskable::COMPLETE_PATTERN, '[ ]') if currently_checked + else + markdown_task.sub!(Taskable::INCOMPLETE_PATTERN, '[x]') unless currently_checked + end + + source_lines[line_number - 1] = markdown_task + @updated_markdown = source_lines.join("\n") + end + + def toggle_html + html = Nokogiri::HTML.fragment(markdown_html) + html_checkbox = html.css('.task-list-item-checkbox')[index - 1] + # html_checkbox = html.css(".task-list-item[data-sourcepos^='#{changed_line_number}:'] > input.task-list-item-checkbox").first + return unless html_checkbox + + if currently_checked + html_checkbox.remove_attribute('checked') + else + html_checkbox[:checked] = 'checked' + end + + @updated_markdown_html = html.to_html + end +end |