diff options
author | Sean McGivern <sean@gitlab.com> | 2018-02-22 12:09:27 +0000 |
---|---|---|
committer | Sean McGivern <sean@gitlab.com> | 2018-03-02 13:42:57 +0000 |
commit | cb55bc3c0770adf7122d7cf49b12cb45c43de7ec (patch) | |
tree | 6ec14a9b8b407ac7986b9e940254d63288266379 /lib | |
parent | 1a09d5cda8e9f6b90b85351a16fcddea351b869f (diff) | |
download | gitlab-ce-cb55bc3c0770adf7122d7cf49b12cb45c43de7ec.tar.gz |
Match Rinku's behaviour for closing punctuation in links41719-mr-title-fix
Rinku 2.0.0 (the version we use) will remove the last character of a link if
it's a closing part of a punctuation pair (different types of parentheses and
quotes), unless both of the below are true:
1. The matching pair has different start and end characters.
2. There are equal numbers of both in the matched string (they don't have to be
balanced).
Diffstat (limited to 'lib')
-rw-r--r-- | lib/banzai/filter/autolink_filter.rb | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/lib/banzai/filter/autolink_filter.rb b/lib/banzai/filter/autolink_filter.rb index c4990637971..75b64ae9af2 100644 --- a/lib/banzai/filter/autolink_filter.rb +++ b/lib/banzai/filter/autolink_filter.rb @@ -25,7 +25,7 @@ module Banzai # period or comma for punctuation without those characters being included # in the generated link. # - # Rubular: http://rubular.com/r/cxjPyZc7Sb + # Rubular: http://rubular.com/r/JzPhi6DCZp LINK_PATTERN = %r{([a-z][a-z0-9\+\.-]+://[^\s>]+)(?<!,|\.)} # Text matching LINK_PATTERN inside these elements will not be linked @@ -37,23 +37,17 @@ module Banzai and contains(., '://') ]).freeze + PUNCTUATION_PAIRS = { + "'" => "'", + '"' => '"', + ')' => '(', + ']' => '[', + '}' => '{' + }.freeze + def call return doc if context[:autolink] == false - text_parse - end - - private - - # Return true if any of the UNSAFE_PROTOCOLS strings are included in the URI scheme - def contains_unsafe?(scheme) - return false unless scheme - - scheme = scheme.strip.downcase - Banzai::Filter::SanitizationFilter::UNSAFE_PROTOCOLS.any? { |protocol| scheme.include?(protocol) } - end - - def text_parse doc.xpath(TEXT_QUERY).each do |node| content = node.to_html @@ -69,6 +63,16 @@ module Banzai doc end + private + + # Return true if any of the UNSAFE_PROTOCOLS strings are included in the URI scheme + def contains_unsafe?(scheme) + return false unless scheme + + scheme = scheme.strip.downcase + Banzai::Filter::SanitizationFilter::UNSAFE_PROTOCOLS.any? { |protocol| scheme.include?(protocol) } + end + def autolink_match(match) # start by stripping out dangerous links begin @@ -84,6 +88,22 @@ module Banzai match.gsub!(/((?:&[\w#]+;)+)\z/, '') dropped = ($1 || '').html_safe + # To match the behaviour of Rinku, if the matched link ends with a + # closing part of a matched pair of punctuation, we remove that trailing + # character unless there are an equal number of closing and opening + # characters in the link. + if match.end_with?(*PUNCTUATION_PAIRS.keys) + close_character = match[-1] + close_count = match.count(close_character) + open_character = PUNCTUATION_PAIRS[close_character] + open_count = match.count(open_character) + + if open_count != close_count || open_character == close_character + dropped += close_character + match = match[0..-2] + end + end + options = link_options.merge(href: match) content_tag(:a, match.html_safe, options) + dropped end |