diff --git a/lib/html-proofer/check/links.rb b/lib/html-proofer/check/links.rb index 58f332a3..e35c1879 100644 --- a/lib/html-proofer/check/links.rb +++ b/lib/html-proofer/check/links.rb @@ -51,7 +51,7 @@ def run add_to_external_urls(@link.href) next - elsif !@link.remote? && !@link.exists? + elsif @link.internal? && !@link.exists? add_issue("internally linking to #{@link.href}, which does not exist", line: line, content: content) end diff --git a/lib/html-proofer/element.rb b/lib/html-proofer/element.rb index d792206e..6d1229fd 100644 --- a/lib/html-proofer/element.rb +++ b/lib/html-proofer/element.rb @@ -139,9 +139,22 @@ def external? !internal? end - # path is an anchor, a query or refers to root def internal? - hash_link || param_link || slash_link + relative_link? || internal_absolute_link? + end + + def internal_absolute_link? + url.start_with?('/') + end + + def relative_link? + return false if remote? + + hash_link || param_link || url.start_with?('.') || url =~ /^\w/ + end + + def link_points_to_same_page? + hash_link || param_link end def hash_link @@ -152,10 +165,6 @@ def param_link url.start_with?('?') end - def slash_link - url.start_with?('/') - end - def file_path return if path.nil? || path.empty? @@ -226,9 +235,9 @@ def base def html # If link is on the same page, then URL is on the current page so can use the same HTML as for current page - if hash_link || param_link + if link_points_to_same_page? @html - elsif slash_link + elsif relative_link? # link on another page, e.g. /about#Team - need to get HTML from the other page create_nokogiri(absolute_path) end diff --git a/lib/html-proofer/middleware.rb b/lib/html-proofer/middleware.rb index 87ff5511..b3e2a704 100644 --- a/lib/html-proofer/middleware.rb +++ b/lib/html-proofer/middleware.rb @@ -2,6 +2,8 @@ module HTMLProofer class Middleware + include HTMLProofer::Utils + class InvalidHtmlError < StandardError def initialize(failures) @failures = failures @@ -67,7 +69,7 @@ def call(env) 'response', Middleware.options ).check_parsed( - Nokogiri::HTML(Utils.clean_content(html)), 'response' + Nokogiri::HTML(clean_content(html)), 'response' ) raise InvalidHtmlError, parsed[:failures] unless parsed[:failures].empty? diff --git a/lib/html-proofer/utils.rb b/lib/html-proofer/utils.rb index 56fa513d..d792ad08 100644 --- a/lib/html-proofer/utils.rb +++ b/lib/html-proofer/utils.rb @@ -8,7 +8,7 @@ def pluralize(count, single, plural) "#{count} #{(count == 1 ? single : plural)}" end - def self.create_nokogiri(path) + def create_nokogiri(path) content = if File.exist?(path) && !File.directory?(path) File.open(path).read else @@ -18,7 +18,7 @@ def self.create_nokogiri(path) Nokogiri::HTML(clean_content(content)) end - def self.swap(href, replacement) + def swap(href, replacement) replacement.each do |link, replace| href = href.gsub(link, replace) end @@ -28,7 +28,7 @@ def self.swap(href, replacement) # address a problem with Nokogiri's parsing URL entities # problem from http://git.io/vBYU1 # solution from http://git.io/vBYUi - def self.clean_content(string) + def clean_content(string) string.gsub(%r{(?:https?:)?//([^>]+)}i) do |url| url.gsub(/&(?!amp;)/, '&') end diff --git a/spec/html-proofer/links_spec.rb b/spec/html-proofer/links_spec.rb index d3060c79..45a3a353 100644 --- a/spec/html-proofer/links_spec.rb +++ b/spec/html-proofer/links_spec.rb @@ -6,7 +6,7 @@ it 'fails for broken internal hash (even if the file exists)' do broken_hash_external_filepath = "#{FIXTURES_DIR}/links/broken_hash_external.html" proofer = run_proofer(broken_hash_external_filepath, :file) - expect(proofer.failed_tests.last).to match(%r{linking to ../images/missing_image_alt.html#asdfasfdkafl, but asdfasfdkafl does not exist}) + expect(proofer.failed_tests.last).to match(/linking to internal hash #asdfasfdkafl that does not exist/) end it 'fails for broken hashes on the web when asked (even if the file exists)' do diff --git a/spec/html-proofer/utils_spec.rb b/spec/html-proofer/utils_spec.rb index 8059a67d..655863ce 100644 --- a/spec/html-proofer/utils_spec.rb +++ b/spec/html-proofer/utils_spec.rb @@ -4,18 +4,20 @@ describe HTMLProofer::Utils do describe '::create_nokogiri' do + include HTMLProofer::Utils + it 'passes for a string' do - noko = HTMLProofer::Utils.create_nokogiri '' + noko = create_nokogiri '' expect(noko.css('html').first['lang']).to eq 'jp' end it 'passes for a file' do - noko = HTMLProofer::Utils.create_nokogiri "#{FIXTURES_DIR}/utils/lang-jp.html" + noko = create_nokogiri "#{FIXTURES_DIR}/utils/lang-jp.html" expect(noko.css('html').first['lang']).to eq 'jp' end it 'ignores directories' do - noko = HTMLProofer::Utils.create_nokogiri "#{FIXTURES_DIR}/utils" + noko = create_nokogiri "#{FIXTURES_DIR}/utils" expect(noko.content).to eq 'spec/html-proofer/fixtures/utils' end end