2019-03-13 09:57:05 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Gitlab
|
|
|
|
module Diff
|
|
|
|
class SuggestionsParser
|
|
|
|
# Matches for instance "-1", "+1" or "-1+2".
|
|
|
|
SUGGESTION_CONTEXT = /^(\-(?<above>\d+))?(\+(?<below>\d+))?$/.freeze
|
2019-03-15 13:35:34 -04:00
|
|
|
|
2021-06-01 17:10:06 -04:00
|
|
|
CSS = 'pre.language-suggestion'
|
|
|
|
XPATH = Gitlab::Utils::Nokogiri.css_to_xpath(CSS).freeze
|
|
|
|
|
2019-03-15 13:35:34 -04:00
|
|
|
class << self
|
|
|
|
# Returns an array of Gitlab::Diff::Suggestion which represents each
|
|
|
|
# suggestion in the given text.
|
|
|
|
#
|
2019-06-03 17:52:58 -04:00
|
|
|
def parse(text, position:, project:, supports_suggestion: true)
|
2019-03-15 13:35:34 -04:00
|
|
|
return [] unless position.complete?
|
|
|
|
|
2019-06-03 17:52:58 -04:00
|
|
|
html = Banzai.render(text, project: nil,
|
|
|
|
no_original_data: true,
|
|
|
|
suggestions_filter_enabled: supports_suggestion)
|
2019-03-15 13:35:34 -04:00
|
|
|
doc = Nokogiri::HTML(html)
|
2021-06-01 17:10:06 -04:00
|
|
|
suggestion_nodes = doc.xpath(XPATH)
|
2019-03-15 13:35:34 -04:00
|
|
|
|
|
|
|
return [] if suggestion_nodes.empty?
|
|
|
|
|
|
|
|
diff_file = position.diff_file(project.repository)
|
|
|
|
|
|
|
|
suggestion_nodes.map do |node|
|
|
|
|
lang_param = node['data-lang-params']
|
|
|
|
|
|
|
|
lines_above, lines_below = nil
|
|
|
|
|
|
|
|
if lang_param && suggestion_params = fetch_suggestion_params(lang_param)
|
2021-04-19 17:09:27 -04:00
|
|
|
lines_above = suggestion_params[:above]
|
|
|
|
lines_below = suggestion_params[:below]
|
2019-03-15 13:35:34 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
Gitlab::Diff::Suggestion.new(node.text,
|
|
|
|
line: position.new_line,
|
|
|
|
above: lines_above.to_i,
|
|
|
|
below: lines_below.to_i,
|
|
|
|
diff_file: diff_file)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def fetch_suggestion_params(lang_param)
|
|
|
|
lang_param.match(SUGGESTION_CONTEXT)
|
|
|
|
end
|
|
|
|
end
|
2019-03-13 09:57:05 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|