Class: Banzai::Filter::LabelReferenceFilter

Inherits:
AbstractReferenceFilter show all
Defined in:
lib/banzai/filter/label_reference_filter.rb

Overview

HTML filter that replaces label references with links.

Constant Summary

Constants inherited from AbstractReferenceFilter

AbstractReferenceFilter::REFERENCE_PLACEHOLDER, AbstractReferenceFilter::REFERENCE_PLACEHOLDER_PATTERN

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from AbstractReferenceFilter

#call, #current_parent_path, #current_project_namespace_path, #data_attributes_for, #find_for_paths, #find_object_cached, #find_object_from_link, #find_object_from_link_cached, #from_ref_cached, identifier, #identifier, #object_class, #object_link_filter, #object_link_text_extras, object_name, object_sym, #object_sym, #parent_per_reference, parse_symbol, #record_identifier, #records_per_parent, references_in, #references_per_parent, #relation_for_paths, symbol_from_match, #url_for_object_cached

Methods included from CrossProjectReference

#parent_from_ref

Methods inherited from ReferenceFilter

call, #call_and_update_nodes, #data_attribute, #each_node, #element_node?, #group, #ignore_ancestor_query, #initialize, #nodes, #project, #replace_link_node_with_href, #replace_link_node_with_text, #replace_text_when_pattern_matches, #skip_project_check?, #text_node?, #user, #validate, #yield_valid_link

Methods included from OutputSafety

#escape_once

Methods included from RequestStoreReferenceCache

#cached_call, #get_or_set_cache

Constructor Details

This class inherits a constructor from Banzai::Filter::ReferenceFilter

Class Method Details

.object_classObject


9
10
11
# File 'lib/banzai/filter/label_reference_filter.rb', line 9

def self.object_class
  Label
end

Instance Method Details

#find_label(parent_ref, label_id, label_name) ⇒ Object


43
44
45
46
47
48
49
# File 'lib/banzai/filter/label_reference_filter.rb', line 43

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

#find_label_cached(parent_ref, label_id, label_name) ⇒ Object


37
38
39
40
41
# File 'lib/banzai/filter/label_reference_filter.rb', line 37

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

#find_labels(parent) ⇒ Object


51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/banzai/filter/label_reference_filter.rb', line 51

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

#find_object(parent_object, id) ⇒ Object


13
14
15
# File 'lib/banzai/filter/label_reference_filter.rb', line 13

def find_object(parent_object, id)
  find_labels(parent_object).find(id)
end

#full_path_ref?(matches) ⇒ Boolean

Returns:

  • (Boolean)

113
114
115
# File 'lib/banzai/filter/label_reference_filter.rb', line 113

def full_path_ref?(matches)
  matches[:namespace] && matches[:project]
end

#label_params(id, name) ⇒ Object

Parameters to pass to `Label.find_by` based on the given arguments

id - Integer ID to pass. If present, returns id name - String name to pass. If `id` is absent, finds by name without

surrounding quotes.

Returns a Hash.


71
72
73
74
75
76
77
# File 'lib/banzai/filter/label_reference_filter.rb', line 71

def label_params(id, name)
  if name
    { name: name.tr('"', '') }
  else
    { id: id.to_i }
  end
end

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/banzai/filter/label_reference_filter.rb', line 92

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

121
122
123
124
# File 'lib/banzai/filter/label_reference_filter.rb', line 121

def object_link_title(object, matches)
  presenter = object.present(issuable_subject: project || group)
  LabelsHelper.label_tooltip_title(presenter)
end

#reference_class(type, tooltip: true) ⇒ Object


117
118
119
# File 'lib/banzai/filter/label_reference_filter.rb', line 117

def reference_class(type, tooltip: true)
  super + ' gl-link gl-label-link'
end

#references_in(text, pattern = Label.reference_pattern) ⇒ Object


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/banzai/filter/label_reference_filter.rb', line 17

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

#url_for_object(label, parent) ⇒ Object


79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/banzai/filter/label_reference_filter.rb', line 79

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

108
109
110
111
# File 'lib/banzai/filter/label_reference_filter.rb', line 108

def wrap_link(link, label)
  presenter = label.present(issuable_subject: project || group)
  LabelsHelper.wrap_label_html(link, small: true, label: presenter)
end