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/label_reference_filter.rb')
-rw-r--r--lib/banzai/filter/references/label_reference_filter.rb131
1 files changed, 131 insertions, 0 deletions
diff --git a/lib/banzai/filter/references/label_reference_filter.rb b/lib/banzai/filter/references/label_reference_filter.rb
new file mode 100644
index 00000000000..8508aa2b3c3
--- /dev/null
+++ b/lib/banzai/filter/references/label_reference_filter.rb
@@ -0,0 +1,131 @@
+# frozen_string_literal: true
+
+module Banzai
+ module Filter
+ module References
+ # HTML filter that replaces label references with links.
+ class LabelReferenceFilter < AbstractReferenceFilter
+ self.reference_type = :label
+
+ def self.object_class
+ Label
+ end
+
+ def find_object(parent_object, id)
+ find_labels(parent_object).find(id)
+ end
+
+ def references_in(text, pattern = Label.reference_pattern)
+ labels = {}
+ unescaped_html = unescape_html_entities(text).gsub(pattern) do |match|
+ namespace, project = $~[:namespace], $~[:project]
+ project_path = full_project_path(namespace, project)
+ label = find_label_cached(project_path, $~[:label_id], $~[:label_name])
+
+ if label
+ labels[label.id] = yield match, label.id, project, namespace, $~
+ "#{REFERENCE_PLACEHOLDER}#{label.id}"
+ else
+ match
+ end
+ end
+
+ return text if labels.empty?
+
+ escape_with_placeholders(unescaped_html, labels)
+ end
+
+ def find_label_cached(parent_ref, label_id, label_name)
+ cached_call(:banzai_find_label_cached, label_name&.tr('"', '') || label_id, path: [object_class, parent_ref]) do
+ find_label(parent_ref, label_id, label_name)
+ end
+ end
+
+ def find_label(parent_ref, label_id, label_name)
+ parent = parent_from_ref(parent_ref)
+ return unless parent
+
+ label_params = label_params(label_id, label_name)
+ find_labels(parent).find_by(label_params)
+ end
+
+ def find_labels(parent)
+ params = if parent.is_a?(Group)
+ { group_id: parent.id,
+ include_ancestor_groups: true,
+ only_group_labels: true }
+ else
+ { project: parent,
+ include_ancestor_groups: true }
+ end
+
+ LabelsFinder.new(nil, params).execute(skip_authorization: true)
+ end
+
+ # Parameters to pass to `Label.find_by` based on the given arguments
+ #
+ # id - Integer ID to pass. If present, returns {id: id}
+ # name - String name to pass. If `id` is absent, finds by name without
+ # surrounding quotes.
+ #
+ # Returns a Hash.
+ def label_params(id, name)
+ if name
+ { name: name.tr('"', '') }
+ else
+ { id: id.to_i }
+ end
+ end
+
+ def url_for_object(label, parent)
+ label_url_method =
+ if context[:label_url_method]
+ context[:label_url_method]
+ elsif parent.is_a?(Project)
+ :project_issues_url
+ end
+
+ return unless label_url_method
+
+ Gitlab::Routing.url_helpers.public_send(label_url_method, parent, label_name: label.name, only_path: context[:only_path]) # rubocop:disable GitlabSecurity/PublicSend
+ end
+
+ def object_link_text(object, matches)
+ label_suffix = ''
+ parent = project || group
+
+ if project || full_path_ref?(matches)
+ project_path = full_project_path(matches[:namespace], matches[:project])
+ parent_from_ref = from_ref_cached(project_path)
+ reference = parent_from_ref.to_human_reference(parent)
+
+ label_suffix = " <i>in #{ERB::Util.html_escape(reference)}</i>" if reference.present?
+ end
+
+ presenter = object.present(issuable_subject: parent)
+ LabelsHelper.render_colored_label(presenter, suffix: label_suffix)
+ end
+
+ def wrap_link(link, label)
+ presenter = label.present(issuable_subject: project || group)
+ LabelsHelper.wrap_label_html(link, small: true, label: presenter)
+ end
+
+ def full_path_ref?(matches)
+ matches[:namespace] && matches[:project]
+ end
+
+ def reference_class(type, tooltip: true)
+ super + ' gl-link gl-label-link'
+ end
+
+ def object_link_title(object, matches)
+ presenter = object.present(issuable_subject: project || group)
+ LabelsHelper.label_tooltip_title(presenter)
+ end
+ end
+ end
+ end
+end
+
+Banzai::Filter::References::LabelReferenceFilter.prepend_if_ee('EE::Banzai::Filter::References::LabelReferenceFilter')