diff options
Diffstat (limited to 'lib/gitlab/diff/suggestions_parser.rb')
-rw-r--r-- | lib/gitlab/diff/suggestions_parser.rb | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/gitlab/diff/suggestions_parser.rb b/lib/gitlab/diff/suggestions_parser.rb new file mode 100644 index 00000000000..6e17ffaf6ff --- /dev/null +++ b/lib/gitlab/diff/suggestions_parser.rb @@ -0,0 +1,53 @@ +# 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 + + class << self + # Returns an array of Gitlab::Diff::Suggestion which represents each + # suggestion in the given text. + # + def parse(text, position:, project:, supports_suggestion: true) + return [] unless position.complete? + + html = Banzai.render(text, project: nil, + no_original_data: true, + suggestions_filter_enabled: supports_suggestion) + doc = Nokogiri::HTML(html) + suggestion_nodes = doc.search('pre.suggestion') + + 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) + lines_above, lines_below = + suggestion_params[:above], + suggestion_params[:below] + 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 + end + end +end |