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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/banzai/filter/references/merge_request_reference_filter.rb')
-rw-r--r--lib/banzai/filter/references/merge_request_reference_filter.rb99
1 files changed, 99 insertions, 0 deletions
diff --git a/lib/banzai/filter/references/merge_request_reference_filter.rb b/lib/banzai/filter/references/merge_request_reference_filter.rb
new file mode 100644
index 00000000000..872c33f6873
--- /dev/null
+++ b/lib/banzai/filter/references/merge_request_reference_filter.rb
@@ -0,0 +1,99 @@
+# frozen_string_literal: true
+
+module Banzai
+ module Filter
+ module References
+ # HTML filter that replaces merge request references with links. References
+ # to merge requests that do not exist are ignored.
+ #
+ # This filter supports cross-project references.
+ class MergeRequestReferenceFilter < IssuableReferenceFilter
+ self.reference_type = :merge_request
+
+ def self.object_class
+ MergeRequest
+ end
+
+ def url_for_object(mr, project)
+ h = Gitlab::Routing.url_helpers
+ h.project_merge_request_url(project, mr,
+ only_path: context[:only_path])
+ end
+
+ def object_link_title(object, matches)
+ # The method will return `nil` if object is not a commit
+ # allowing for properly handling the extended MR Tooltip
+ object_link_commit_title(object, matches)
+ end
+
+ def object_link_text_extras(object, matches)
+ extras = super
+
+ if commit_ref = object_link_commit_ref(object, matches)
+ klass = reference_class(:commit, tooltip: false)
+ commit_ref_tag = %(<span class="#{klass}">#{commit_ref}</span>)
+
+ return extras.unshift(commit_ref_tag)
+ end
+
+ path = matches[:path] if matches.names.include?("path")
+
+ case path
+ when '/diffs'
+ extras.unshift "diffs"
+ when '/commits'
+ extras.unshift "commits"
+ when '/builds'
+ extras.unshift "builds"
+ end
+
+ extras
+ end
+
+ def parent_records(parent, ids)
+ parent.merge_requests
+ .where(iid: ids.to_a)
+ .includes(target_project: :namespace)
+ end
+
+ def reference_class(object_sym, options = {})
+ super(object_sym, tooltip: false)
+ end
+
+ def data_attributes_for(text, parent, object, **data)
+ super.merge(project_path: parent.full_path, iid: object.iid, mr_title: object.title)
+ end
+
+ private
+
+ def object_link_commit_title(object, matches)
+ object_link_commit(object, matches)&.title
+ end
+
+ def object_link_commit_ref(object, matches)
+ object_link_commit(object, matches)&.short_id
+ end
+
+ def object_link_commit(object, matches)
+ return unless matches.names.include?('query') && query = matches[:query]
+
+ # Removes leading "?". CGI.parse expects "arg1&arg2&arg3"
+ params = CGI.parse(query.sub(/^\?/, ''))
+
+ return unless commit_sha = params['commit_id']&.first
+
+ if commit = find_commit_by_sha(object, commit_sha)
+ Commit.from_hash(commit.to_hash, object.project)
+ end
+ end
+
+ def find_commit_by_sha(object, commit_sha)
+ @all_commits ||= {}
+ @all_commits[object.id] ||= object.all_commits
+
+ @all_commits[object.id].find { |commit| commit.sha == commit_sha }
+ end
+ end
+ end
+ end
+end