Skip to content

Commit 03656fa

Browse files
committed
Refactor link attributes to a shared constant
1 parent dd067a0 commit 03656fa

File tree

2 files changed

+28
-11
lines changed

2 files changed

+28
-11
lines changed

lib/rich_text.rb

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module RichText
44
DESCRIPTION_MAX_LENGTH = 500
55
DESCRIPTION_WORD_BREAK_THRESHOLD_LENGTH = 450
66
URL_UNSAFE_CHARS = "[^\\w!#$%&'*+,./:;=?@_~^\\-]"
7+
LINK_ATTRIBUTES = 'rel="nofollow noopener noreferrer" dir="auto"'
78

89
def self.new(format, text)
910
case format
@@ -99,12 +100,16 @@ def linkify(text, mode = :urls)
99100
private
100101

101102
def linkify_users(text)
102-
text.gsub(/(?<!\w)@(?:(?:&quot;|["“”])(.+?)(?:&quot;|["“”])|(\w+))/) do |match|
103-
name = ::Regexp.last_match(1) || ::Regexp.last_match(2)
104-
slug = ERB::Util.url_encode(name)
105-
safe_match = match.sub("@", "&#64;")
103+
regex = /(?<!\w)@(?:“([^”]+?)”|”([^”]+?)”|‘([^’]+?)’|’([^’]+?)’|"([^"]+?)"|'([^']+?)'|(\w+))/
104+
105+
text.gsub(regex) do |match|
106+
name = ::Regexp.last_match(1) || ::Regexp.last_match(2) || ::Regexp.last_match(3) || ::Regexp.last_match(4) || ::Regexp.last_match(5) || ::Regexp.last_match(6) || ::Regexp.last_match(7)
107+
next match unless name
108+
slug_name = name.tr("“”‘’", %q(""''))
109+
slug = ERB::Util.url_encode(slug_name)
106110

107-
"<a href=\"/user/#{slug}\" rel=\"nofollow noopener noreferrer\">#{safe_match}</a>"
111+
safe_match = match.sub("@", "&#64;")
112+
"<a href=\"/user/#{slug}\" #{LINK_ATTRIBUTES}>#{safe_match}</a>"
108113
end
109114
end
110115

@@ -139,8 +144,7 @@ def expand_host_shorthands(text)
139144
end
140145

141146
def auto_link(text, mode)
142-
link_attr = 'rel="nofollow noopener noreferrer" dir="auto"'
143-
Rinku.auto_link(text, mode, link_attr) { |url| format_link_text(url) }
147+
Rinku.auto_link(text, mode, LINK_ATTRIBUTES) { |url| format_link_text(url) }
144148
end
145149

146150
def format_link_text(url)

test/lib/rich_text_test.rb

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ def test_markdown_to_html
193193
end
194194

195195
def test_markdown_table_alignment
196-
# Ensure that kramdown table alignment styles are converted to bootstrap classes
197196
markdown_table = <<~MARKDOWN
198197
| foo | bar |
199198
|:----:|----:|
@@ -226,9 +225,11 @@ def test_text_to_html_linkify
226225
end
227226

228227
def test_linkify_username_with_space
229-
text = 'Hello @"Open Mapper"'
230-
html = RichText.new("markdown", text).to_html
231-
assert_match %r{<a href="/user/Open%20Mapper" rel="nofollow noopener noreferrer">&#64;”Open Mapper”</a>}, html
228+
with_settings(:linkify => { :detection_rules => [{ :patterns => ["@(?<username>\\w+)"], :path_template => "user/\\k<username>" }] }) do
229+
text = 'Hello @"Open Mapper"'
230+
html = RichText.new("markdown", text).to_html
231+
assert_match %r{<a href="/user/Open%20Mapper" #{RichText::LINK_ATTRIBUTES}>&#64;[“”]Open Mapper[“”]</a>}o, html
232+
end
232233
end
233234

234235
def test_text_to_html_linkify_replace
@@ -243,6 +244,18 @@ def test_text_to_html_linkify_replace
243244
end
244245
end
245246

247+
def test_linkify_username_with_quotes
248+
text = "Hello @'\"Yo\"'"
249+
html = RichText.new("markdown", text).to_html
250+
assert_match %r{<a href="/user/%22Yo%22" #{RichText::LINK_ATTRIBUTES}>&#64;[‘'’]“Yo”[‘'’]</a>}o, html
251+
end
252+
253+
def test_linkify_short_username
254+
text = "Hello @Yo"
255+
html = RichText.new("markdown", text).to_html
256+
assert_match %r{<a href="/user/Yo" #{RichText::LINK_ATTRIBUTES}>&#64;Yo</a>}o, html
257+
end
258+
246259
def test_text_to_html_linkify_recognize
247260
with_settings(:linkify_hosts => ["replace-me.example.com"], :linkify_hosts_replacement => "repl.example.com") do
248261
r = RichText.new("text", "foo repl.example.com/some/path?query=te<st&limit=20>10#result12 bar")

0 commit comments

Comments
 (0)