2018-11-18 11:00:15 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2015-12-23 02:04:40 +05:30
|
|
|
module Banzai
|
|
|
|
module Filter
|
2016-06-02 11:05:42 +05:30
|
|
|
# HTML Filter to modify the attributes of external links
|
2015-09-11 14:41:01 +05:30
|
|
|
class ExternalLinkFilter < HTML::Pipeline::Filter
|
2017-08-17 22:00:37 +05:30
|
|
|
SCHEMES = ['http', 'https', nil].freeze
|
|
|
|
|
2015-09-11 14:41:01 +05:30
|
|
|
def call
|
2016-11-03 12:29:30 +05:30
|
|
|
links.each do |node|
|
2017-08-17 22:00:37 +05:30
|
|
|
uri = uri(node['href'].to_s)
|
2016-11-03 12:29:30 +05:30
|
|
|
|
2019-01-03 12:48:30 +05:30
|
|
|
node.set_attribute('href', uri.to_s) if uri
|
2016-11-03 12:29:30 +05:30
|
|
|
|
2019-01-03 12:48:30 +05:30
|
|
|
if SCHEMES.include?(uri&.scheme) && !internal_url?(uri)
|
2017-08-17 22:00:37 +05:30
|
|
|
node.set_attribute('rel', 'nofollow noreferrer noopener')
|
2016-11-03 12:29:30 +05:30
|
|
|
node.set_attribute('target', '_blank')
|
|
|
|
end
|
2015-09-11 14:41:01 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
doc
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2017-08-17 22:00:37 +05:30
|
|
|
def uri(href)
|
|
|
|
URI.parse(href)
|
|
|
|
rescue URI::Error
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
2016-11-03 12:29:30 +05:30
|
|
|
def links
|
|
|
|
query = 'descendant-or-self::a[@href and not(@href = "")]'
|
|
|
|
doc.xpath(query)
|
|
|
|
end
|
|
|
|
|
2019-01-03 12:48:30 +05:30
|
|
|
def internal_url?(uri)
|
|
|
|
return false if uri.nil?
|
2017-08-17 22:00:37 +05:30
|
|
|
# Relative URLs miss a hostname
|
2019-01-03 12:48:30 +05:30
|
|
|
return true unless uri.hostname
|
2016-11-03 12:29:30 +05:30
|
|
|
|
2019-01-03 12:48:30 +05:30
|
|
|
uri.hostname == internal_url.hostname
|
2016-11-03 12:29:30 +05:30
|
|
|
end
|
|
|
|
|
2015-09-11 14:41:01 +05:30
|
|
|
def internal_url
|
2017-08-17 22:00:37 +05:30
|
|
|
@internal_url ||= URI.parse(Gitlab.config.gitlab.url)
|
2015-09-11 14:41:01 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|