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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
# frozen_string_literal: true
module Banzai
module Filter
# 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(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(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)
h = Gitlab::Routing.url_helpers
if parent.is_a?(Project)
h.project_issues_url(parent, label_name: label.name, only_path: context[:only_path])
elsif context[:label_url_method]
h.public_send(context[:label_url_method], parent, label_name: label.name, only_path: context[:only_path]) # rubocop:disable GitlabSecurity/PublicSend
end
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 #{reference}</i>" if reference.present?
end
presenter = object.present(issuable_subject: parent)
LabelsHelper.render_colored_label(presenter, label_suffix: label_suffix, title: tooltip_title(presenter))
end
def tooltip_title(label)
nil
end
def full_path_ref?(matches)
matches[:namespace] && matches[:project]
end
def object_link_title(object, matches)
# use title of wrapped element instead
nil
end
end
end
end
Banzai::Filter::LabelReferenceFilter.prepend_if_ee('EE::Banzai::Filter::LabelReferenceFilter')
|