/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

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