html-proofer 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2d69ea6f2eb74095372c3f46f5b0b40beb25d4c2
4
- data.tar.gz: b788331194e898263a88a47f41c60f77a4f3051a
3
+ metadata.gz: cf114815adfcc6b231c9f8b119d2e5c02dee4738
4
+ data.tar.gz: 382848c036bf27e114796531c07c55c970f8b890
5
5
  SHA512:
6
- metadata.gz: a98a1fd90173d4481caae3c2fa7b702e1d5ab04cd262f4c555d250b7ce4518e29bcb0f3cfba7cd33d88526389bd05f3665b3ebb6ca0a46404057fa01f7663c62
7
- data.tar.gz: 603de7c0256dde6120f0cce01e4803768c09468c620a04d81d6b053bd3d66e72573bc8fbe33efa9597a090fcd3c9f8744826021829e1619fc35fdc584c8c7513
6
+ metadata.gz: be3e69485788801d9ce34e6374eee233b2fe91553fc8051bd8fc96fa1d22792aba37b2b06d44a50a31fb50f832730a883006282e08c52bd917c7da003465b3b5
7
+ data.tar.gz: 235a71993139147fa3a1909da8bfe25d23b1124fb9f5d4e676625650ed5a3b0381aa435957f5781284c386ab7365f425bc4099b784d0309b23f9761a9ae21939
@@ -59,7 +59,7 @@ Mercenary.program(:htmlproofer) do |p|
59
59
  unless opts['url_swap'].nil?
60
60
  options[:url_swap] = {}
61
61
  opts['url_swap'].each do |s|
62
- splt = s.split(/(?<!\\):/,2)
62
+ splt = s.split(/(?<!\\):/, 2)
63
63
 
64
64
  re = splt[0].gsub(/\\:/, ':')
65
65
  string = splt[1].gsub(/\\:/, ':')
@@ -1,7 +1,7 @@
1
1
  module HTMLProofer
2
2
  # Mostly handles issue management and collecting of external URLs.
3
3
  class Check
4
- attr_reader :node, :element, :src, :path, :options, :issues, :external_urls
4
+ attr_reader :node, :html, :element, :src, :path, :options, :issues, :external_urls
5
5
 
6
6
  def initialize(src, path, html, options)
7
7
  @src = src
@@ -18,14 +18,14 @@ module HTMLProofer
18
18
  end
19
19
 
20
20
  def run
21
- fail NotImplementedError, 'HTMLProofer::Check subclasses must implement #run'
21
+ raise NotImplementedError, 'HTMLProofer::Check subclasses must implement #run'
22
22
  end
23
23
 
24
- def add_issue(desc, line: nil, status: -1)
25
- @issues << Issue.new(@path, desc, line: line, status: status)
24
+ def add_issue(desc, line: nil, status: -1, content: nil)
25
+ @issues << Issue.new(@path, desc, line: line, status: status, content: content)
26
26
  end
27
27
 
28
- def add_to_external_urls(url, _)
28
+ def add_to_external_urls(url)
29
29
  return if @external_urls[url]
30
30
  add_path_for_url(url)
31
31
  end
@@ -10,6 +10,6 @@ class FaviconCheck < ::HTMLProofer::Check
10
10
 
11
11
  return if found
12
12
 
13
- add_issue 'no favicon specified'
13
+ add_issue('no favicon specified')
14
14
  end
15
15
  end
@@ -17,32 +17,33 @@ class ImageCheck < ::HTMLProofer::Check
17
17
  @html.css('img').each do |node|
18
18
  @img = create_element(node)
19
19
  line = node.line
20
+ content = node.content
20
21
 
21
22
  next if @img.ignore?
22
23
 
23
24
  # screenshot filenames should return because of terrible names
24
25
  if terrible_filename?
25
- add_issue("image has a terrible filename (#{@img.url})", line: line)
26
+ add_issue("image has a terrible filename (#{@img.url})", line: line, content: content)
26
27
  next
27
28
  end
28
29
 
29
30
  # does the image exist?
30
31
  if missing_src?
31
- add_issue('image has no src or srcset attribute', line: line)
32
+ add_issue('image has no src or srcset attribute', line: line, content: content)
32
33
  else
33
34
  if @img.remote?
34
- add_to_external_urls(@img.url, line)
35
+ add_to_external_urls(@img.url)
35
36
  elsif !@img.exists?
36
- add_issue("internal image #{@img.url} does not exist", line: line)
37
+ add_issue("internal image #{@img.url} does not exist", line: line, content: content)
37
38
  end
38
39
  end
39
40
 
40
41
  if !@img.ignore_alt? && (@img.alt.nil? || (empty_alt_tag? && !@img.ignore_empty_alt?))
41
- add_issue("image #{@img.url} does not have an alt attribute", line: line)
42
+ add_issue("image #{@img.url} does not have an alt attribute", line: line, content: content)
42
43
  end
43
44
 
44
45
  if @img.check_img_http? && @img.scheme == 'http'
45
- add_issue("image #{@img.url} uses the http scheme", line: line)
46
+ add_issue("image #{@img.url} uses the http scheme", line: line, content: content)
46
47
  end
47
48
  end
48
49
 
@@ -12,7 +12,8 @@ class LinkCheck < ::HTMLProofer::Check
12
12
  def run
13
13
  @html.css('a, link').each do |node|
14
14
  @link = create_element(node)
15
- line = @node.line
15
+ line = node.line
16
+ content = node.to_s
16
17
 
17
18
  next if @link.ignore?
18
19
 
@@ -21,17 +22,17 @@ class LinkCheck < ::HTMLProofer::Check
21
22
 
22
23
  # is it even a valid URL?
23
24
  unless @link.valid?
24
- add_issue("#{@link.href} is an invalid URL", line: line)
25
+ add_issue("#{@link.href} is an invalid URL", line: line, content: content)
25
26
  next
26
27
  end
27
28
 
28
- check_schemes(@link, line)
29
+ check_schemes(@link, line, content)
29
30
 
30
31
  # is there even an href?
31
32
  if missing_href?
32
33
  # HTML5 allows dropping the href: http://git.io/vBX0z
33
34
  next if @html.internal_subset.name == 'html' && @html.internal_subset.external_id.nil?
34
- add_issue('anchor has no href attribute', line: line)
35
+ add_issue('anchor has no href attribute', line: line, content: content)
35
36
  next
36
37
  end
37
38
 
@@ -39,66 +40,66 @@ class LinkCheck < ::HTMLProofer::Check
39
40
  next if @link.non_http_remote?
40
41
  # does the file even exist?
41
42
  if @link.remote?
42
- add_to_external_urls(@link.href, line)
43
+ add_to_external_urls(@link.href)
43
44
  next
44
45
  elsif !@link.internal? && !@link.exists?
45
- add_issue("internally linking to #{@link.href}, which does not exist", line: line)
46
+ add_issue("internally linking to #{@link.href}, which does not exist", line: line, content: content)
46
47
  end
47
48
 
48
49
  # does the local directory have a trailing slash?
49
50
  if @link.unslashed_directory? @link.absolute_path
50
- add_issue("internally linking to a directory #{@link.absolute_path} without trailing slash", line: line)
51
+ add_issue("internally linking to a directory #{@link.absolute_path} without trailing slash", line: line, content: content)
51
52
  next
52
53
  end
53
54
 
54
55
  # verify the target hash
55
- handle_hash(@link, line) if @link.hash
56
+ handle_hash(@link, line, content) if @link.hash
56
57
  end
57
58
 
58
59
  external_urls
59
60
  end
60
61
 
61
- def check_schemes(link, line)
62
+ def check_schemes(link, line, content)
62
63
  case link.scheme
63
64
  when 'mailto'
64
- handle_mailto(link, line)
65
+ handle_mailto(link, line, content)
65
66
  when 'tel'
66
- handle_tel(link, line)
67
+ handle_tel(link, line, content)
67
68
  when 'http'
68
69
  return unless @options[:enforce_https]
69
- add_issue("#{link.href} is not an HTTPS link", line: line)
70
+ add_issue("#{link.href} is not an HTTPS link", line: line, content: content)
70
71
  end
71
72
  end
72
73
 
73
- def handle_mailto(link, line)
74
+ def handle_mailto(link, line, content)
74
75
  if link.path.empty?
75
- add_issue("#{link.href} contains no email address", line: line)
76
+ add_issue("#{link.href} contains no email address", line: line, content: content)
76
77
  elsif !link.path.include?('@')
77
- add_issue("#{link.href} contains an invalid email address", line: line)
78
+ add_issue("#{link.href} contains an invalid email address", line: line, content: content)
78
79
  end
79
80
  end
80
81
 
81
- def handle_tel(link, line)
82
- add_issue("#{link.href} contains no phone number", line: line) if link.path.empty?
82
+ def handle_tel(link, line, content)
83
+ add_issue("#{link.href} contains no phone number", line: line, content: content) if link.path.empty?
83
84
  end
84
85
 
85
- def handle_hash(link, line)
86
+ def handle_hash(link, line, content)
86
87
  if link.internal?
87
88
  unless hash_check @html, link.hash
88
- add_issue("linking to internal hash ##{link.hash} that does not exist", line: line)
89
+ add_issue("linking to internal hash ##{link.hash} that does not exist", line: line, content: content)
89
90
  end
90
91
  elsif link.external?
91
- external_link_check(link, line)
92
+ external_link_check(link, line, content)
92
93
  end
93
94
  end
94
95
 
95
- def external_link_check(link, line)
96
+ def external_link_check(link, line, content)
96
97
  if !link.exists?
97
- add_issue("trying to find hash of #{link.href}, but #{link.absolute_path} does not exist", line: line)
98
+ add_issue("trying to find hash of #{link.href}, but #{link.absolute_path} does not exist", line: line, content: content)
98
99
  else
99
100
  target_html = create_nokogiri link.absolute_path
100
101
  unless hash_check target_html, link.hash
101
- add_issue("linking to #{link.href}, but #{link.hash} does not exist", line: line)
102
+ add_issue("linking to #{link.href}, but #{link.hash} does not exist", line: line, content: content)
102
103
  end
103
104
  end
104
105
  end
@@ -9,17 +9,18 @@ class ScriptCheck < ::HTMLProofer::Check
9
9
  @html.css('script').each do |node|
10
10
  @script = create_element(node)
11
11
  line = node.line
12
+ content = node.content
12
13
 
13
14
  next if @script.ignore?
14
15
  next unless node.text.strip.empty?
15
16
 
16
17
  # does the script exist?
17
18
  if missing_src?
18
- add_issue('script is empty and has no src attribute', line: line)
19
+ add_issue('script is empty and has no src attribute', line: line, content: content)
19
20
  elsif @script.remote?
20
- add_to_external_urls(@script.src, line)
21
+ add_to_external_urls(@script.src)
21
22
  elsif !@script.exists?
22
- add_issue("internal script #{@script.src} does not exist", line: line)
23
+ add_issue("internal script #{@script.src} does not exist", line: line, content: content)
23
24
  end
24
25
  end
25
26
 
@@ -22,6 +22,8 @@ module HTMLProofer
22
22
  @type = check.class.name
23
23
  @line = obj.line
24
24
 
25
+ @html = check.html
26
+
25
27
  # fix up missing protocols
26
28
  @href.insert 0, 'http:' if @href =~ %r{^//}
27
29
  @src.insert 0, 'http:' if @src =~ %r{^//}
@@ -29,9 +31,13 @@ module HTMLProofer
29
31
  end
30
32
 
31
33
  def url
32
- url = (@src || @srcset || @href || '').gsub("\u200b", '')
33
- return url if @check.options[:url_swap].empty?
34
- swap(url, @check.options[:url_swap])
34
+ return @url if defined?(@url)
35
+ @url = (@src || @srcset || @href || '').gsub("\u200b", '')
36
+ if base
37
+ @url = Addressable::URI.join(base.attr('href'), url).to_s
38
+ end
39
+ return @url if @check.options[:url_swap].empty?
40
+ @url = swap(@url, @check.options[:url_swap])
35
41
  end
36
42
 
37
43
  def valid?
@@ -68,11 +74,11 @@ module HTMLProofer
68
74
  def ignore?
69
75
  return true if @data_proofer_ignore
70
76
 
71
- return true if url.match(/^javascript:/)
77
+ return true if url =~ /^javascript:/
72
78
 
73
79
  # ignore base64 encoded images
74
80
  if %w(ImageCheck FaviconCheck).include? @type
75
- return true if url.match(/^data:image/)
81
+ return true if url =~ /^data:image/
76
82
  end
77
83
 
78
84
  # ignore user defined URLs
@@ -166,5 +172,9 @@ module HTMLProofer
166
172
  def follow_location?
167
173
  @check.options[:typhoeus] && @check.options[:typhoeus][:followlocation]
168
174
  end
175
+
176
+ def base
177
+ @base ||= @html.at_css('base')
178
+ end
169
179
  end
170
180
  end
@@ -1,12 +1,13 @@
1
1
  module HTMLProofer
2
2
  class Issue
3
- attr_reader :path, :desc, :status, :line
3
+ attr_reader :path, :desc, :status, :line, :content
4
4
 
5
- def initialize(path, desc, line: nil, status: -1)
5
+ def initialize(path, desc, line: nil, status: -1, content: nil)
6
6
  @line = line.nil? ? '' : " (line #{line})"
7
7
  @path = path
8
8
  @desc = desc
9
9
  @status = status
10
+ @content = content
10
11
  end
11
12
 
12
13
  def to_s
@@ -52,7 +53,11 @@ module HTMLProofer
52
53
  if first_report == :status
53
54
  @logger.log :error, " * #{issue}"
54
55
  else
55
- @logger.log :error, " * #{issue.send(second_report)}#{issue.line}"
56
+ msg = " * #{issue.send(second_report)}#{issue.line}"
57
+ if !issue.content.nil? && !issue.content.empty?
58
+ msg = "#{msg}\n #{issue.content}"
59
+ end
60
+ @logger.log(:error, msg)
56
61
  end
57
62
  end
58
63
  end
@@ -1,3 +1,3 @@
1
1
  module HTMLProofer
2
- VERSION = '3.1.0'.freeze
2
+ VERSION = '3.2.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: html-proofer
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garen Torikian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-22 00:00:00.000000000 Z
11
+ date: 2016-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mercenary