Welcome to mirror list, hosted at ThFree Co, Russian Federation.

markdown_content_rewriter_service.rb « services « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4d8f523fa77a7fafce7e8cf2154852c7522623ab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# frozen_string_literal: true

# This service passes Markdown content through our GFM rewriter classes
# which rewrite references to GitLab objects and uploads within the content
# based on their visibility by the `target_parent`.
class MarkdownContentRewriterService
  include Gitlab::Utils::StrongMemoize

  REWRITERS = [Gitlab::Gfm::ReferenceRewriter, Gitlab::Gfm::UploadsRewriter].freeze

  def initialize(current_user, object, field, source_parent, target_parent)
    @current_user = current_user
    @source_parent = source_parent
    @target_parent = target_parent
    @object = object
    @field = field

    validate_parameters!

    @content = object[field].dup.presence
    @html_field = object.cached_markdown_fields.html_field(field)
    @content_html = object.cached_html_for(field)

    @rewriters =
      REWRITERS.map do |rewriter_class|
        rewriter_class.new(@content, content_html, source_parent, current_user)
      end

    @result = {
      field => nil,
      html_field => nil
    }.with_indifferent_access
  end

  def execute
    return result unless content

    unless safe_to_copy_markdown?
      rewriters.each do |rewriter|
        rewriter.rewrite(target_parent)
      end
    end

    result[field] = content
    result[html_field] = content_html if safe_to_copy_markdown?
    result[:skip_markdown_cache_validation] = safe_to_copy_markdown?

    result
  end

  def safe_to_copy_markdown?
    strong_memoize(:safe_to_copy_markdown) do
      rewriters.none?(&:needs_rewrite?)
    end
  end

  private

  def validate_parameters!
    # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39654#note_399095117
    raise ArgumentError, 'The rewriter classes require that `source_parent` is a `Project`' \
      unless source_parent.is_a?(Project)

    if object.cached_markdown_fields[field].nil?
      raise ArgumentError, 'The `field` attribute does not contain cached markdown'
    end
  end

  attr_reader :current_user, :content, :source_parent,
              :target_parent, :rewriters, :content_html,
              :field, :html_field, :object, :result
end