PageRenderTime 48ms CodeModel.GetById 11ms app.highlight 34ms RepoModel.GetById 1ms app.codeStats 1ms

/lib/banzai/filter/label_reference_filter.rb

https://gitlab.com/vicvega/gitlab-ce
Ruby | 121 lines | 91 code | 21 blank | 9 comment | 12 complexity | 27eb0361c6f3c366eb674c8ec7b1f0dc MD5 | raw file
  1module Banzai
  2  module Filter
  3    # HTML filter that replaces label references with links.
  4    class LabelReferenceFilter < AbstractReferenceFilter
  5      self.reference_type = :label
  6
  7      def self.object_class
  8        Label
  9      end
 10
 11      def find_object(project, id)
 12        find_labels(project).find(id)
 13      end
 14
 15      def self.references_in(text, pattern = Label.reference_pattern)
 16        unescape_html_entities(text).gsub(pattern) do |match|
 17          yield match, $~[:label_id].to_i, $~[:label_name], $~[:project], $~
 18        end
 19      end
 20
 21      def references_in(text, pattern = Label.reference_pattern)
 22        unescape_html_entities(text).gsub(pattern) do |match|
 23          label = find_label($~[:project], $~[:label_id], $~[:label_name])
 24
 25          if label
 26            yield match, label.id, $~[:project], $~
 27          else
 28            match
 29          end
 30        end
 31      end
 32
 33      def find_label(project_ref, label_id, label_name)
 34        project = project_from_ref(project_ref)
 35        return unless project
 36
 37        label_params = label_params(label_id, label_name)
 38        find_labels(project).find_by(label_params)
 39      end
 40
 41      def find_labels(project)
 42        LabelsFinder.new(nil, project_id: project.id).execute(skip_authorization: true)
 43      end
 44
 45      # Parameters to pass to `Label.find_by` based on the given arguments
 46      #
 47      # id   - Integer ID to pass. If present, returns {id: id}
 48      # name - String name to pass. If `id` is absent, finds by name without
 49      #        surrounding quotes.
 50      #
 51      # Returns a Hash.
 52      def label_params(id, name)
 53        if name
 54          { name: name.tr('"', '') }
 55        else
 56          { id: id.to_i }
 57        end
 58      end
 59
 60      def url_for_object(label, project)
 61        h = Gitlab::Routing.url_helpers
 62        h.namespace_project_issues_url(project.namespace, project, label_name: label.name,
 63                                                                   only_path:  context[:only_path])
 64      end
 65
 66      def object_link_text(object, matches)
 67        if same_group?(object) && namespace_match?(matches)
 68          render_same_project_label(object)
 69        elsif same_project?(object)
 70          render_same_project_label(object)
 71        else
 72          render_cross_project_label(object, matches)
 73        end
 74      end
 75
 76      def same_group?(object)
 77        object.is_a?(GroupLabel) && object.group == project.group
 78      end
 79
 80      def namespace_match?(matches)
 81        matches[:project].blank? || matches[:project] == project.path_with_namespace
 82      end
 83
 84      def same_project?(object)
 85        object.is_a?(ProjectLabel) && object.project == project
 86      end
 87
 88      def user
 89        context[:current_user] || context[:author]
 90      end
 91
 92      def project
 93        context[:project]
 94      end
 95
 96      def render_same_project_label(object)
 97        LabelsHelper.render_colored_label(object)
 98      end
 99
100      def render_cross_project_label(object, matches)
101        source_project =
102          if matches[:project]
103            Project.find_with_namespace(matches[:project])
104          else
105            object.project
106          end
107
108        LabelsHelper.render_colored_cross_project_label(object, source_project)
109      end
110
111      def unescape_html_entities(text)
112        CGI.unescapeHTML(text.to_s)
113      end
114
115      def object_link_title(object)
116        # use title of wrapped element instead
117        nil
118      end
119    end
120  end
121end