html-proofer 3.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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