Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/banzai/filter/external_link_filter.rb')
-rw-r--r--lib/banzai/filter/external_link_filter.rb34
1 files changed, 30 insertions, 4 deletions
diff --git a/lib/banzai/filter/external_link_filter.rb b/lib/banzai/filter/external_link_filter.rb
index 0a29c547a4d..2f19b59e725 100644
--- a/lib/banzai/filter/external_link_filter.rb
+++ b/lib/banzai/filter/external_link_filter.rb
@@ -3,10 +3,17 @@ module Banzai
# HTML Filter to modify the attributes of external links
class ExternalLinkFilter < HTML::Pipeline::Filter
def call
- # Skip non-HTTP(S) links and internal links
- doc.xpath("descendant-or-self::a[starts-with(@href, 'http') and not(starts-with(@href, '#{internal_url}'))]").each do |node|
- node.set_attribute('rel', 'nofollow noreferrer')
- node.set_attribute('target', '_blank')
+ links.each do |node|
+ href = href_to_lowercase_scheme(node["href"].to_s)
+
+ unless node["href"].to_s == href
+ node.set_attribute('href', href)
+ end
+
+ if href =~ /\Ahttp(s)?:\/\// && external_url?(href)
+ node.set_attribute('rel', 'nofollow noreferrer')
+ node.set_attribute('target', '_blank')
+ end
end
doc
@@ -14,6 +21,25 @@ module Banzai
private
+ def links
+ query = 'descendant-or-self::a[@href and not(@href = "")]'
+ doc.xpath(query)
+ end
+
+ def href_to_lowercase_scheme(href)
+ scheme_match = href.match(/\A(\w+):\/\//)
+
+ if scheme_match
+ scheme_match.to_s.downcase + scheme_match.post_match
+ else
+ href
+ end
+ end
+
+ def external_url?(url)
+ !url.start_with?(internal_url)
+ end
+
def internal_url
@internal_url ||= Gitlab.config.gitlab.url
end