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