2015-12-15 14:51:16 +00:00
|
|
|
module Banzai
|
|
|
|
module Filter
|
2016-04-21 18:03:37 +00:00
|
|
|
# HTML Filter to modify the attributes of external links
|
2015-05-27 19:39:08 +00:00
|
|
|
class ExternalLinkFilter < HTML::Pipeline::Filter
|
2017-05-02 22:25:58 +00:00
|
|
|
SCHEMES = ['http', 'https', nil].freeze
|
|
|
|
|
2015-05-27 19:39:08 +00:00
|
|
|
def call
|
2016-10-12 05:12:31 +00:00
|
|
|
links.each do |node|
|
2017-05-02 22:25:58 +00:00
|
|
|
uri = uri(node['href'].to_s)
|
|
|
|
next unless uri
|
2016-10-12 05:12:31 +00:00
|
|
|
|
2017-05-02 22:25:58 +00:00
|
|
|
node.set_attribute('href', uri.to_s)
|
2016-10-12 05:12:31 +00:00
|
|
|
|
2017-05-02 22:25:58 +00:00
|
|
|
if SCHEMES.include?(uri.scheme) && external_url?(uri)
|
|
|
|
node.set_attribute('rel', 'nofollow noreferrer noopener')
|
2016-10-12 05:12:31 +00:00
|
|
|
node.set_attribute('target', '_blank')
|
|
|
|
end
|
2015-05-27 19:39:08 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
doc
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2017-05-02 22:25:58 +00:00
|
|
|
def uri(href)
|
|
|
|
URI.parse(href)
|
2017-05-18 15:47:18 +00:00
|
|
|
rescue URI::Error
|
2017-05-02 22:25:58 +00:00
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
2016-10-12 05:12:31 +00:00
|
|
|
def links
|
|
|
|
query = 'descendant-or-self::a[@href and not(@href = "")]'
|
|
|
|
doc.xpath(query)
|
|
|
|
end
|
|
|
|
|
2017-05-02 22:25:58 +00:00
|
|
|
def external_url?(uri)
|
|
|
|
# Relative URLs miss a hostname
|
|
|
|
return false unless uri.hostname
|
2016-10-12 05:12:31 +00:00
|
|
|
|
2017-05-02 22:25:58 +00:00
|
|
|
uri.hostname != internal_url.hostname
|
2016-10-12 05:12:31 +00:00
|
|
|
end
|
|
|
|
|
2015-05-27 19:39:08 +00:00
|
|
|
def internal_url
|
2017-05-02 22:25:58 +00:00
|
|
|
@internal_url ||= URI.parse(Gitlab.config.gitlab.url)
|
2015-05-27 19:39:08 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|