2018-07-23 09:32:32 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2015-12-15 14:51:16 +00:00
|
|
|
module Banzai
|
|
|
|
module Filter
|
2015-04-14 22:34:01 +00:00
|
|
|
# HTML filter that replaces label references with links.
|
2016-02-25 12:49:42 +00:00
|
|
|
class LabelReferenceFilter < AbstractReferenceFilter
|
2016-05-26 11:16:43 +00:00
|
|
|
self.reference_type = :label
|
|
|
|
|
2016-02-25 12:49:42 +00:00
|
|
|
def self.object_class
|
|
|
|
Label
|
2015-04-03 00:46:43 +00:00
|
|
|
end
|
|
|
|
|
2018-04-12 09:37:01 +00:00
|
|
|
def find_object(parent_object, id)
|
|
|
|
find_labels(parent_object).find(id)
|
2015-10-07 15:00:48 +00:00
|
|
|
end
|
|
|
|
|
2016-02-25 12:49:42 +00:00
|
|
|
def references_in(text, pattern = Label.reference_pattern)
|
2019-08-16 08:22:57 +00:00
|
|
|
labels = {}
|
|
|
|
unescaped_html = unescape_html_entities(text).gsub(pattern) do |match|
|
2016-11-02 23:49:13 +00:00
|
|
|
namespace, project = $~[:namespace], $~[:project]
|
|
|
|
project_path = full_project_path(namespace, project)
|
2020-07-21 12:09:30 +00:00
|
|
|
label = find_label_cached(project_path, $~[:label_id], $~[:label_name])
|
2015-12-01 15:25:56 +00:00
|
|
|
|
2016-02-25 12:49:42 +00:00
|
|
|
if label
|
2019-08-16 08:22:57 +00:00
|
|
|
labels[label.id] = yield match, label.id, project, namespace, $~
|
|
|
|
"#{REFERENCE_PLACEHOLDER}#{label.id}"
|
2015-04-03 00:46:43 +00:00
|
|
|
else
|
2019-08-16 08:22:57 +00:00
|
|
|
match
|
2015-04-03 00:46:43 +00:00
|
|
|
end
|
|
|
|
end
|
2019-08-16 08:22:57 +00:00
|
|
|
|
|
|
|
return text if labels.empty?
|
|
|
|
|
|
|
|
escape_with_placeholders(unescaped_html, labels)
|
2015-04-03 00:46:43 +00:00
|
|
|
end
|
|
|
|
|
2020-07-21 12:09:30 +00:00
|
|
|
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
|
|
|
|
|
2018-03-30 17:27:03 +00:00
|
|
|
def find_label(parent_ref, label_id, label_name)
|
|
|
|
parent = parent_from_ref(parent_ref)
|
|
|
|
return unless parent
|
2015-04-03 00:46:43 +00:00
|
|
|
|
2016-04-19 10:07:13 +00:00
|
|
|
label_params = label_params(label_id, label_name)
|
2018-03-30 17:27:03 +00:00
|
|
|
find_labels(parent).find_by(label_params)
|
2016-09-20 03:59:26 +00:00
|
|
|
end
|
|
|
|
|
2018-03-30 17:27:03 +00:00
|
|
|
def find_labels(parent)
|
|
|
|
params = if parent.is_a?(Group)
|
|
|
|
{ group_id: parent.id,
|
|
|
|
include_ancestor_groups: true,
|
|
|
|
only_group_labels: true }
|
|
|
|
else
|
2018-10-03 02:56:51 +00:00
|
|
|
{ project: parent,
|
2018-03-30 17:27:03 +00:00
|
|
|
include_ancestor_groups: true }
|
|
|
|
end
|
|
|
|
|
|
|
|
LabelsFinder.new(nil, params).execute(skip_authorization: true)
|
2015-04-03 00:46:43 +00:00
|
|
|
end
|
|
|
|
|
2015-04-10 20:38:34 +00:00
|
|
|
# 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)
|
2015-05-25 20:06:34 +00:00
|
|
|
if name
|
2015-05-15 20:07:25 +00:00
|
|
|
{ name: name.tr('"', '') }
|
2015-05-25 20:06:34 +00:00
|
|
|
else
|
2016-04-19 10:07:13 +00:00
|
|
|
{ id: id.to_i }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-03-30 17:27:03 +00:00
|
|
|
def url_for_object(label, parent)
|
2020-05-27 06:08:13 +00:00
|
|
|
label_url_method =
|
|
|
|
if context[:label_url_method]
|
|
|
|
context[:label_url_method]
|
|
|
|
elsif parent.is_a?(Project)
|
|
|
|
:project_issues_url
|
|
|
|
end
|
2018-03-30 17:27:03 +00:00
|
|
|
|
2020-05-27 06:08:13 +00:00
|
|
|
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
|
2016-04-19 10:07:13 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def object_link_text(object, matches)
|
2018-03-30 17:27:03 +00:00
|
|
|
label_suffix = ''
|
2019-04-23 19:58:20 +00:00
|
|
|
parent = project || group
|
2018-03-30 17:27:03 +00:00
|
|
|
|
|
|
|
if project || full_path_ref?(matches)
|
|
|
|
project_path = full_project_path(matches[:namespace], matches[:project])
|
|
|
|
parent_from_ref = from_ref_cached(project_path)
|
2019-04-23 19:58:20 +00:00
|
|
|
reference = parent_from_ref.to_human_reference(parent)
|
2018-03-30 17:27:03 +00:00
|
|
|
|
2019-10-26 06:06:59 +00:00
|
|
|
label_suffix = " <i>in #{ERB::Util.html_escape(reference)}</i>" if reference.present?
|
2018-03-30 17:27:03 +00:00
|
|
|
end
|
2016-09-29 03:21:47 +00:00
|
|
|
|
2019-04-23 19:58:20 +00:00
|
|
|
presenter = object.present(issuable_subject: parent)
|
2020-02-25 15:08:50 +00:00
|
|
|
LabelsHelper.render_colored_label(presenter, suffix: label_suffix)
|
2019-04-02 10:48:20 +00:00
|
|
|
end
|
|
|
|
|
2020-02-25 15:08:50 +00:00
|
|
|
def wrap_link(link, label)
|
|
|
|
presenter = label.present(issuable_subject: project || group)
|
|
|
|
LabelsHelper.wrap_label_html(link, small: true, label: presenter)
|
2016-09-29 03:21:47 +00:00
|
|
|
end
|
|
|
|
|
2018-03-30 17:27:03 +00:00
|
|
|
def full_path_ref?(matches)
|
|
|
|
matches[:namespace] && matches[:project]
|
|
|
|
end
|
|
|
|
|
2020-02-25 15:08:50 +00:00
|
|
|
def reference_class(type, tooltip: true)
|
|
|
|
super + ' gl-link gl-label-link'
|
|
|
|
end
|
|
|
|
|
2018-04-02 23:25:36 +00:00
|
|
|
def object_link_title(object, matches)
|
2020-02-25 15:08:50 +00:00
|
|
|
presenter = object.present(issuable_subject: project || group)
|
|
|
|
LabelsHelper.label_tooltip_title(presenter)
|
2016-07-17 00:03:56 +00:00
|
|
|
end
|
2015-04-03 00:46:43 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|