Class: Abqari::Audit::Links
Overview
Broken internal-link / missing-asset detector. Walks every href,
src, and srcset in rendered HTML and flags any same-origin
reference that doesn't resolve to a file we actually emitted.
External (http(s):// to another host) references are skipped
here — Privacy covers them — as are anchors / mailto / tel / data.
Instance Method Summary collapse
Methods inherited from Rule
Constructor Details
This class inherits a constructor from Abqari::Audit::Rule
Instance Method Details
#run ⇒ Object
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/abqari/audit/links.rb', line 13 def run output_paths = build_output_path_set site_host = host_for(@site.config['url']) html_files.each do |file| url = page_url(file) html = File.read(file, encoding: 'UTF-8') # Strip `<pre>…</pre>` and inline `<code>…</code>` blocks # before scanning. Rouge's HTML-lexer highlighting of an # ERB or HTML example wraps the attribute value in # `<span class="s">...</span>`, which a naive `href="…"` # regex picks up as a "broken link" pointing at # `</span><span class=` and similar fragments. Code # samples aren't navigation — skip them. scan_html = html.gsub(%r{<pre\b[^>]*>.*?</pre>}m, '') .gsub(%r{<code\b[^>]*>.*?</code>}m, '') references(scan_html).each do |link| next if link.empty? next if link.start_with?('mailto:', 'tel:', 'data:', 'javascript:', '#') # Same-origin absolute URLs (`https://mysite/gone/`) are # checked like internal links; only cross-host ones are # skipped (Privacy covers those). Previously BOTH branches # fell through, so a broken absolute link to your own domain # was invisible to every rule. if link.start_with?('http://', 'https://') link_host = host_for(link) next unless site_host && link_host == site_host link = (URI(link).path.to_s.empty? ? '/' : URI(link).path) end target = resolve_target(link, url) next if output_paths.include?(target) || output_paths.include?("#{target}index.html") add(category: 'links', severity: 'error', location: url, message: "Broken link/asset: #{link}") end end end |