Commit a472c1bf authored by Grzegorz Bizon's avatar Grzegorz Bizon

Add support for cross project references for labels

parent dbc7bf7f
......@@ -51,7 +51,8 @@ class Label < ActiveRecord::Base
# Pattern used to extract label references from text
def self.reference_pattern
%r{
#{reference_prefix}
(#{Project.reference_pattern})?
#{Regexp.escape(reference_prefix)}
(?:
(?<label_id>\d+) | # Integer-based label ID, or
(?<label_name>
......@@ -62,6 +63,10 @@ class Label < ActiveRecord::Base
}x
end
def self.link_reference_pattern
nil
end
# Returns the String necessary to reference this Label in Markdown
#
# format - Symbol format to use (default: :id, optional: :name)
......
module Banzai
module Filter
# HTML filter that replaces label references with links.
class LabelReferenceFilter < ReferenceFilter
# Public: Find label references in text
#
# LabelReferenceFilter.references_in(text) do |match, id, name|
# "<a href=...>#{Label.find(id)}</a>"
# end
#
# text - String text to search.
#
# Yields the String match, an optional Integer label ID, and an optional
# String label name.
#
# Returns a String replaced with the return of the block.
def self.references_in(text)
text.gsub(Label.reference_pattern) do |match|
yield match, $~[:label_id].to_i, $~[:label_name]
end
end
def self.referenced_by(node)
{ label: LazyReference.new(Label, node.attr("data-label")) }
class LabelReferenceFilter < AbstractReferenceFilter
def self.object_class
Label
end
def call
replace_text_nodes_matching(Label.reference_pattern) do |content|
label_link_filter(content)
def find_object(project, id)
project.labels.find(id)
end
replace_link_nodes_with_href(Label.reference_pattern) do |link, text|
label_link_filter(link, link_text: text)
def self.references_in(text, pattern = Label.reference_pattern)
text.gsub(pattern) do |match|
yield match, $~[:label_id].to_i, $~[:label_name], $~[:project], $~
end
end
# Replace label references in text with links to the label specified.
#
# text - String text to replace references in.
#
# Returns a String with label references replaced with links. All links
# have `gfm` and `gfm-label` class names attached for styling.
def label_link_filter(text, link_text: nil)
project = context[:project]
self.class.references_in(text) do |match, id, name|
params = label_params(id, name)
if label = project.labels.find_by(params)
url = url_for_label(project, label)
klass = reference_class(:label)
data = data_attribute(
original: link_text || match,
project: project.id,
label: label.id
)
def self.referenced_by(node)
{ label: LazyReference.new(Label, node.attr("data-label")) }
end
text = link_text || render_colored_label(label)
def references_in(text, pattern = Label.reference_pattern)
text.gsub(pattern) do |match|
project = project_from_ref($~[:project])
params = label_params($~[:label_id].to_i, $~[:label_name])
label = project.labels.find_by(params)
%(<a href="#{url}" #{data}
class="#{klass}">#{escape_once(text)}</a>)
if label
yield match, label.id, $~[:project], $~
else
match
end
end
end
def url_for_label(project, label)
def url_for_object(label, project)
h = Gitlab::Application.routes.url_helpers
h.namespace_project_issues_url( project.namespace, project, label_name: label.name,
h.namespace_project_issues_url(project.namespace, project, label_name: label.name,
only_path: context[:only_path])
end
def render_colored_label(label)
LabelsHelper.render_colored_label(label)
def object_link_text(object, _matches)
LabelsHelper.render_colored_label(object)
end
# Parameters to pass to `Label.find_by` based on the given arguments
......
......@@ -176,4 +176,23 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
expect(result[:references][:label]).to eq [label]
end
end
describe 'cross project label references' do
let(:another_project) { create(:empty_project, :public) }
let(:label) { create(:label, project: another_project, color: '#00ff00') }
let(:reference) { label.to_reference(project) }
let!(:result) { reference_filter("See #{reference}") }
it 'points to referenced project issues page' do
expect(result.css('a').first.attr('href'))
.to eq urls.namespace_project_issues_url(another_project.namespace,
another_project,
label_name: label.name)
end
it 'has valid color' do
expect(result.css('a span').first.attr('style')).to match /background-color: #00ff00/
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment