Commit 1d6d757d authored by Douwe Maan's avatar Douwe Maan

Allow reference format as link href

parent 6dad2bc6
...@@ -178,7 +178,6 @@ module Gitlab ...@@ -178,7 +178,6 @@ module Gitlab
Gitlab::Markdown::SanitizationFilter, Gitlab::Markdown::SanitizationFilter,
Gitlab::Markdown::UploadLinkFilter, Gitlab::Markdown::UploadLinkFilter,
Gitlab::Markdown::RelativeLinkFilter,
Gitlab::Markdown::EmojiFilter, Gitlab::Markdown::EmojiFilter,
Gitlab::Markdown::TableOfContentsFilter, Gitlab::Markdown::TableOfContentsFilter,
Gitlab::Markdown::AutolinkFilter, Gitlab::Markdown::AutolinkFilter,
...@@ -193,6 +192,8 @@ module Gitlab ...@@ -193,6 +192,8 @@ module Gitlab
Gitlab::Markdown::CommitReferenceFilter, Gitlab::Markdown::CommitReferenceFilter,
Gitlab::Markdown::LabelReferenceFilter, Gitlab::Markdown::LabelReferenceFilter,
Gitlab::Markdown::RelativeLinkFilter,
Gitlab::Markdown::TaskListFilter Gitlab::Markdown::TaskListFilter
] ]
end end
......
...@@ -2,7 +2,7 @@ require 'gitlab/markdown' ...@@ -2,7 +2,7 @@ require 'gitlab/markdown'
module Gitlab module Gitlab
module Markdown module Markdown
# Issues, Snippets, Merge Requests, Commits and Commit Ranges share # Issues, Merge Requests, Snippets, Commits and Commit Ranges share
# similar functionality in refernce filtering. # similar functionality in refernce filtering.
class AbstractReferenceFilter < ReferenceFilter class AbstractReferenceFilter < ReferenceFilter
include CrossProjectReference include CrossProjectReference
...@@ -64,8 +64,13 @@ module Gitlab ...@@ -64,8 +64,13 @@ module Gitlab
object_link_filter(content, object_class.reference_pattern) object_link_filter(content, object_class.reference_pattern)
end end
replace_link_nodes_matching(object_class.link_reference_pattern) do |content| replace_link_nodes_with_href(object_class.reference_pattern) do |link, text|
object_link_filter(content, object_class.link_reference_pattern) object_link_filter(link, object_class.reference_pattern, link_text: text)
end
replace_link_nodes_with_text(object_class.link_reference_pattern) do |text|
object_link_filter(text, object_class.link_reference_pattern)
end
end end
end end
...@@ -76,7 +81,7 @@ module Gitlab ...@@ -76,7 +81,7 @@ module Gitlab
# #
# Returns a String with references replaced with links. All links # Returns a String with references replaced with links. All links
# have `gfm` and `gfm-OBJECT_NAME` class names attached for styling. # have `gfm` and `gfm-OBJECT_NAME` class names attached for styling.
def object_link_filter(text, pattern) def object_link_filter(text, pattern, link_text: nil)
references_in(text, pattern) do |match, id, project_ref, matches| references_in(text, pattern) do |match, id, project_ref, matches|
project = project_from_ref(project_ref) project = project_from_ref(project_ref)
...@@ -88,10 +93,13 @@ module Gitlab ...@@ -88,10 +93,13 @@ module Gitlab
url = matches[:url] if matches.names.include?("url") url = matches[:url] if matches.names.include?("url")
url ||= url_for_object(object, project) url ||= url_for_object(object, project)
text = link_text
unless text
text = object.reference_link_text(context[:project]) text = object.reference_link_text(context[:project])
extras = object_link_text_extras(object, matches) extras = object_link_text_extras(object, matches)
text += " (#{extras.join(", ")})" if extras.any? text += " (#{extras.join(", ")})" if extras.any?
end
%(<a href="#{url}" #{data} %(<a href="#{url}" #{data}
title="#{title}" title="#{title}"
......
...@@ -30,6 +30,10 @@ module Gitlab ...@@ -30,6 +30,10 @@ module Gitlab
replace_text_nodes_matching(ExternalIssue.reference_pattern) do |content| replace_text_nodes_matching(ExternalIssue.reference_pattern) do |content|
issue_link_filter(content) issue_link_filter(content)
end end
replace_link_nodes_with_href(ExternalIssue.reference_pattern) do |link, text|
issue_link_filter(link, link_text: text)
end
end end
# Replace `JIRA-123` issue references in text with links to the referenced # Replace `JIRA-123` issue references in text with links to the referenced
...@@ -39,7 +43,7 @@ module Gitlab ...@@ -39,7 +43,7 @@ module Gitlab
# #
# Returns a String with `JIRA-123` references replaced with links. All # Returns a String with `JIRA-123` references replaced with links. All
# links have `gfm` and `gfm-issue` class names attached for styling. # links have `gfm` and `gfm-issue` class names attached for styling.
def issue_link_filter(text) def issue_link_filter(text, link_text: nil)
project = context[:project] project = context[:project]
self.class.references_in(text) do |match, issue| self.class.references_in(text) do |match, issue|
...@@ -49,9 +53,11 @@ module Gitlab ...@@ -49,9 +53,11 @@ module Gitlab
klass = reference_class(:issue) klass = reference_class(:issue)
data = data_attribute(project: project.id) data = data_attribute(project: project.id)
text = link_text || match
%(<a href="#{url}" #{data} %(<a href="#{url}" #{data}
title="#{title}" title="#{title}"
class="#{klass}">#{match}</a>) class="#{klass}">#{text}</a>)
end end
end end
......
...@@ -30,6 +30,10 @@ module Gitlab ...@@ -30,6 +30,10 @@ module Gitlab
replace_text_nodes_matching(Label.reference_pattern) do |content| replace_text_nodes_matching(Label.reference_pattern) do |content|
label_link_filter(content) label_link_filter(content)
end end
replace_link_nodes_with_href(Label.reference_pattern) do |link, text|
label_link_filter(link, link_text: text)
end
end end
# Replace label references in text with links to the label specified. # Replace label references in text with links to the label specified.
...@@ -38,7 +42,7 @@ module Gitlab ...@@ -38,7 +42,7 @@ module Gitlab
# #
# Returns a String with label references replaced with links. All links # Returns a String with label references replaced with links. All links
# have `gfm` and `gfm-label` class names attached for styling. # have `gfm` and `gfm-label` class names attached for styling.
def label_link_filter(text) def label_link_filter(text, link_text: nil)
project = context[:project] project = context[:project]
self.class.references_in(text) do |match, id, name| self.class.references_in(text) do |match, id, name|
...@@ -49,8 +53,10 @@ module Gitlab ...@@ -49,8 +53,10 @@ module Gitlab
klass = reference_class(:label) klass = reference_class(:label)
data = data_attribute(project: project.id, label: label.id) data = data_attribute(project: project.id, label: label.id)
text = link_text || render_colored_label(label)
%(<a href="#{url}" #{data} %(<a href="#{url}" #{data}
class="#{klass}">#{render_colored_label(label)}</a>) class="#{klass}">#{text}</a>)
else else
match match
end end
......
...@@ -122,7 +122,7 @@ module Gitlab ...@@ -122,7 +122,7 @@ module Gitlab
doc doc
end end
def replace_link_nodes_matching(pattern) def replace_link_nodes_with_text(pattern)
return doc if project.nil? return doc if project.nil?
doc.search('a').each do |node| doc.search('a').each do |node|
...@@ -132,6 +132,9 @@ module Gitlab ...@@ -132,6 +132,9 @@ module Gitlab
link = node.attr('href') link = node.attr('href')
text = node.text text = node.text
next unless link && text
link = URI.decode(link)
# Ignore ending punctionation like periods or commas # Ignore ending punctionation like periods or commas
next unless link == text && text =~ /\A#{pattern}/ next unless link == text && text =~ /\A#{pattern}/
...@@ -145,6 +148,30 @@ module Gitlab ...@@ -145,6 +148,30 @@ module Gitlab
doc doc
end end
def replace_link_nodes_with_href(pattern)
return doc if project.nil?
doc.search('a').each do |node|
klass = node.attr('class')
next if klass && klass.include?('gfm')
link = node.attr('href')
text = node.text
next unless link && text
link = URI.decode(link)
next unless link && link =~ /\A#{pattern}\z/
html = yield link, text
next if html == link
node.replace(html)
end
doc
end
# Ensure that a :project key exists in context # Ensure that a :project key exists in context
# #
# Note that while the key might exist, its value could be nil! # Note that while the key might exist, its value could be nil!
......
...@@ -17,6 +17,9 @@ module Gitlab ...@@ -17,6 +17,9 @@ module Gitlab
return doc unless linkable_files? return doc unless linkable_files?
doc.search('a').each do |el| doc.search('a').each do |el|
klass = el.attr('class')
next if klass && klass.include?('gfm')
process_link_attr el.attribute('href') process_link_attr el.attribute('href')
end end
......
...@@ -52,6 +52,10 @@ module Gitlab ...@@ -52,6 +52,10 @@ module Gitlab
replace_text_nodes_matching(User.reference_pattern) do |content| replace_text_nodes_matching(User.reference_pattern) do |content|
user_link_filter(content) user_link_filter(content)
end end
replace_link_nodes_with_href(User.reference_pattern) do |link, text|
user_link_filter(link, link_text: text)
end
end end
# Replace `@user` user references in text with links to the referenced # Replace `@user` user references in text with links to the referenced
...@@ -61,12 +65,12 @@ module Gitlab ...@@ -61,12 +65,12 @@ module Gitlab
# #
# Returns a String with `@user` references replaced with links. All links # Returns a String with `@user` references replaced with links. All links
# have `gfm` and `gfm-project_member` class names attached for styling. # have `gfm` and `gfm-project_member` class names attached for styling.
def user_link_filter(text) def user_link_filter(text, link_text: nil)
self.class.references_in(text) do |match, username| self.class.references_in(text) do |match, username|
if username == 'all' if username == 'all'
link_to_all link_to_all(link_text: link_text)
elsif namespace = Namespace.find_by(path: username) elsif namespace = Namespace.find_by(path: username)
link_to_namespace(namespace) || match link_to_namespace(namespace, link_text: link_text) || match
else else
match match
end end
...@@ -83,36 +87,36 @@ module Gitlab ...@@ -83,36 +87,36 @@ module Gitlab
reference_class(:project_member) reference_class(:project_member)
end end
def link_to_all def link_to_all(link_text: nil)
project = context[:project] project = context[:project]
url = urls.namespace_project_url(project.namespace, project, url = urls.namespace_project_url(project.namespace, project,
only_path: context[:only_path]) only_path: context[:only_path])
data = data_attribute(project: project.id) data = data_attribute(project: project.id)
text = User.reference_prefix + 'all' text = link_text || User.reference_prefix + 'all'
link_tag(url, data, text) link_tag(url, data, text)
end end
def link_to_namespace(namespace) def link_to_namespace(namespace, link_text: nil)
if namespace.is_a?(Group) if namespace.is_a?(Group)
link_to_group(namespace.path, namespace) link_to_group(namespace.path, namespace, link_text: link_text)
else else
link_to_user(namespace.path, namespace) link_to_user(namespace.path, namespace, link_text: link_text)
end end
end end
def link_to_group(group, namespace) def link_to_group(group, namespace, link_text: nil)
url = urls.group_url(group, only_path: context[:only_path]) url = urls.group_url(group, only_path: context[:only_path])
data = data_attribute(group: namespace.id) data = data_attribute(group: namespace.id)
text = Group.reference_prefix + group text = link_text || Group.reference_prefix + group
link_tag(url, data, text) link_tag(url, data, text)
end end
def link_to_user(user, namespace) def link_to_user(user, namespace, link_text: nil)
url = urls.user_url(user, only_path: context[:only_path]) url = urls.user_url(user, only_path: context[:only_path])
data = data_attribute(user: namespace.owner_id) data = data_attribute(user: namespace.owner_id)
text = User.reference_prefix + user text = link_text || User.reference_prefix + user
link_tag(url, data, text) link_tag(url, data, text)
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