Class: Jekyll::ExternalLinkAccessibility

Inherits:
Object
  • Object
show all
Defined in:
lib/jekyll-external-link-accessibility.rb,
lib/jekyll-external-link-accessibility/version.rb

Constant Summary collapse

EXTERNAL_SCHEMES =
%w[http:// https:// //].freeze
VERSION =
'0.2.0'

Class Method Summary collapse

Class Method Details

.external_link?(href, site_host) ⇒ Boolean

A link is external only when it points to a different host than the site. Relative links ("/blog/...") and absolute links to our own domain are internal, so they keep their link equity (no nofollow).

Returns:

  • (Boolean)


45
46
47
48
49
50
51
52
# File 'lib/jekyll-external-link-accessibility.rb', line 45

def self.external_link?(href, site_host)
  return false unless href.start_with?(*EXTERNAL_SCHEMES)

  link_host = host_for(href)
  return true if link_host.nil?

  link_host != site_host
end

.host_for(url) ⇒ Object

Returns the lowercased host without a leading "www." so hosts match regardless of case or www prefix.



56
57
58
59
60
61
# File 'lib/jekyll-external-link-accessibility.rb', line 56

def self.host_for(url)
  host = URI.parse(url.to_s).host
  host&.downcase&.sub(/\Awww\./, '')
rescue URI::InvalidURIError
  nil
end


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/jekyll-external-link-accessibility.rb', line 9

def self.modify_links(page)
  config = page.site.config
  site_host = host_for(config['url'])
  doc = Nokogiri::HTML5(page.output)
  doc.css('.post-content a, .post-excerpt a').each do |a|
    next if a['href'].nil? || a['href'].empty? || a['href'].start_with?('#') || a['data-no-external'] == 'true'

    # Every link opens in a new tab so readers don't lose their place. Add the
    # icon and a screen-reader note so both sighted and screen-reader users know.
    a['target'] = external_link_target(config: config) unless a['target']
    a['title'] = external_link_title(config: config) unless a['title']
    a.add_child(" <i class='icon-external-link' aria-hidden='true'></i>")
    a.add_child(
      "<span
        style='overflow: hidden;clip: rect(0,0,0,0);
              position: absolute !important;
              width: 1px;
              height: 1px;
              border: 0;
              word-wrap: normal !important;'>
        opens a new window
      </span>"
    )

    # Only external links get the configured rel (nofollow, etc.) so we don't
    # pass our link equity to other sites.
    if external_link?(a['href'], site_host)
      a['rel'] = external_link_rel(config: config) unless a['rel']
    end
  end
  page.output = doc.to_html
end