html-proofer 3.14.1 → 3.16.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 +4 -4
- data/bin/htmlproofer +12 -6
- data/lib/html-proofer.rb +2 -2
- data/lib/html-proofer/cache.rb +1 -2
- data/lib/html-proofer/check.rb +3 -2
- data/lib/html-proofer/check/html.rb +23 -14
- data/lib/html-proofer/check/links.rb +1 -1
- data/lib/html-proofer/check/opengraph.rb +4 -4
- data/lib/html-proofer/configuration.rb +4 -1
- data/lib/html-proofer/element.rb +21 -14
- data/lib/html-proofer/log.rb +15 -11
- data/lib/html-proofer/middleware.rb +4 -3
- data/lib/html-proofer/runner.rb +23 -3
- data/lib/html-proofer/url_validator.rb +6 -1
- data/lib/html-proofer/utils.rb +2 -11
- data/lib/html-proofer/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39ffac5e6c23ab7b75d99dd69779be2109ed8b02dc4a5cb0a33740119cb66766
|
4
|
+
data.tar.gz: cdaf142dfde936fa1d88d410499c04fdbbb3b9814bc00ba6800ff3edb8acee50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34a4253b2eb9674060583c0f9006f9c36204bfd8bbb3e347293874e8db3248153e1efcdb13cbb9a5fc7967aabe478773a6a33c3c2372b4e819ecc0c41af43f36
|
7
|
+
data.tar.gz: 34530aeb5fb2836568aa5f7ebea7f154ef8e58c82ac0803aeba5632f704e7aed6c8111a095546c56b1331fa3dc1b563b08eac7cff0205aee4056815ebd8a6478
|
data/bin/htmlproofer
CHANGED
@@ -20,13 +20,13 @@ Mercenary.program(:htmlproofer) do |p|
|
|
20
20
|
p.option 'as_links', '--as-links', 'Assumes that `PATH` is a comma-separated array of links to check.'
|
21
21
|
p.option 'alt_ignore', '--alt-ignore image1,[image2,...]', Array, 'A comma-separated list of Strings or RegExps containing `img`s whose missing `alt` tags are safe to ignore'
|
22
22
|
p.option 'assume_extension', '--assume-extension', 'Automatically add extension (e.g. `.html`) to file paths, to allow extensionless URLs (as supported by Jekyll 3 and GitHub Pages) (default: `false`).'
|
23
|
-
p.option 'checks_to_ignore', '--checks-to-ignore check1,[check2,...]', Array, '
|
23
|
+
p.option 'checks_to_ignore', '--checks-to-ignore check1,[check2,...]', Array, 'A comma-separated list of Strings indicating which checks you do not want to run (default: `[]`)'
|
24
24
|
p.option 'check_external_hash', '--check-external-hash', 'Checks whether external hashes exist (even if the webpage exists). This slows the checker down (default: `false`).'
|
25
25
|
p.option 'check_favicon', '--check-favicon', 'Enables the favicon checker (default: `false`).'
|
26
|
-
p.option 'check_html', '--check-html', 'Enables HTML validation errors from
|
26
|
+
p.option 'check_html', '--check-html', 'Enables HTML validation errors from Nokogumbo (default: `false`).'
|
27
27
|
p.option 'check_img_http', '--check-img-http', 'Fails an image if it\'s marked as `http` (default: `false`).'
|
28
28
|
p.option 'check_opengraph', '--check-opengraph', 'Enables the Open Graph checker (default: `false`).'
|
29
|
-
p.option 'check_sri', '--check-sri', 'Check that `<link>` and `<script>` external resources
|
29
|
+
p.option 'check_sri', '--check-sri', 'Check that `<link>` and `<script>` external resources use SRI (default: `false`).'
|
30
30
|
p.option 'directory_index_file', '--directory-index-file <filename>', String, 'Sets the file to look for when a link refers to a directory. (default: `index.html`)'
|
31
31
|
p.option 'disable_external', '--disable-external', 'If `true`, does not run the external link checker, which can take a lot of time (default: `false`)'
|
32
32
|
p.option 'empty_alt_ignore', '--empty-alt-ignore', 'If `true`, ignores images with empty alt tags'
|
@@ -37,9 +37,12 @@ Mercenary.program(:htmlproofer) do |p|
|
|
37
37
|
p.option 'file_ignore', '--file-ignore file1,[file2,...]', Array, 'A comma-separated list of Strings or RegExps containing file paths that are safe to ignore'
|
38
38
|
p.option 'http_status_ignore', '--http-status-ignore 123,[xxx, ...]', Array, 'A comma-separated list of numbers representing status codes to ignore.'
|
39
39
|
p.option 'internal_domains', '--internal-domains domain1,[domain2,...]', Array, 'A comma-separated list of Strings containing domains that will be treated as internal urls.'
|
40
|
-
p.option 'report_invalid_tags', '--report-invalid-tags', '
|
41
|
-
p.option 'report_missing_names', '--report-missing-names', '
|
42
|
-
p.option 'report_script_embeds', '--report-script-embeds', '
|
40
|
+
p.option 'report_invalid_tags', '--report-invalid-tags', 'When `check_html` is enabled, HTML markup that is unknown to Nokogumbo are reported as errors (default: `false`)'
|
41
|
+
p.option 'report_missing_names', '--report-missing-names', 'When `check_html` is enabled, HTML markup that are missing entity names are reported as errors (default: `false`)'
|
42
|
+
p.option 'report_script_embeds', '--report-script-embeds', 'When `check_html` is enabled, `script` tags containing markup are reported as errors (default: `false`)'
|
43
|
+
p.option 'report_missing_doctype', '--report-missing-doctype', 'When `check_html` is enabled, HTML markup with missing or out-of-order `DOCTYPE` are reported as errors (default: `false`)'
|
44
|
+
p.option 'report_eof_tags', '--report-eof-tags', 'When `check_html` is enabled, HTML markup with tags that are malformed are reported as errors (default: `false`)'
|
45
|
+
p.option 'report_mismatched_tags', '--report-mismatched-tags', 'When `check_html` is enabled, HTML markup with mismatched tags are reported as errors (default: `false`)'
|
43
46
|
p.option 'log_level', '--log-level <level>', String, 'Sets the logging level, as determined by Yell. One of `:debug`, `:info`, `:warn`, `:error`, or `:fatal`. (default: `:info`)'
|
44
47
|
p.option 'only_4xx', '--only-4xx', 'Only reports errors for links that fall within the 4xx status code range'
|
45
48
|
p.option 'storage_dir', '--storage-dir PATH', String, 'Directory where to store the cache log (default: "tmp/.htmlproofer")'
|
@@ -80,6 +83,9 @@ Mercenary.program(:htmlproofer) do |p|
|
|
80
83
|
options[:validation][:report_script_embeds] = opts['report_script_embeds'] unless opts['report_script_embeds'].nil?
|
81
84
|
options[:validation][:report_missing_names] = opts['report_missing_names'] unless opts['report_missing_names'].nil?
|
82
85
|
options[:validation][:report_invalid_tags] = opts['report_invalid_tags'] unless opts['report_invalid_tags'].nil?
|
86
|
+
options[:validation][:report_missing_doctype] = opts['report_missing_doctype'] unless opts['report_missing_doctype'].nil?
|
87
|
+
options[:validation][:report_eof_tags] = opts['report_eof_tags'] unless opts['report_eof_tags'].nil?
|
88
|
+
options[:validation][:report_mismatched_tags] = opts['report_mismatched_tags'] unless opts['report_mismatched_tags'].nil?
|
83
89
|
|
84
90
|
options[:typhoeus] = HTMLProofer::Configuration.parse_json_option('typhoeus_config', opts['typhoeus_config']) unless opts['typhoeus_config'].nil?
|
85
91
|
|
data/lib/html-proofer.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
def require_all(path)
|
4
4
|
dir = File.join(File.dirname(__FILE__), path)
|
5
|
-
Dir[File.join(dir, '*.rb')].each do |f|
|
5
|
+
Dir[File.join(dir, '*.rb')].sort.each do |f|
|
6
6
|
require f
|
7
7
|
end
|
8
8
|
end
|
@@ -17,7 +17,7 @@ require 'fileutils'
|
|
17
17
|
begin
|
18
18
|
require 'awesome_print'
|
19
19
|
require 'pry-byebug'
|
20
|
-
rescue LoadError; end # rubocop:disable Lint/
|
20
|
+
rescue LoadError; end # rubocop:disable Lint/SuppressedException
|
21
21
|
module HTMLProofer
|
22
22
|
def self.check_file(file, options = {})
|
23
23
|
raise ArgumentError unless file.is_a?(String)
|
data/lib/html-proofer/cache.rb
CHANGED
@@ -120,9 +120,8 @@ module HTMLProofer
|
|
120
120
|
@cache_log.each_pair do |url, cache|
|
121
121
|
if within_timeframe?(cache['time'])
|
122
122
|
next if cache['message'].empty? # these were successes to skip
|
123
|
-
else
|
124
|
-
urls_to_check[url] = cache['filenames'] # recheck expired links
|
125
123
|
end
|
124
|
+
urls_to_check[url] = cache['filenames'] # recheck expired links
|
126
125
|
end
|
127
126
|
urls_to_check
|
128
127
|
end
|
data/lib/html-proofer/check.rb
CHANGED
@@ -5,10 +5,11 @@ module HTMLProofer
|
|
5
5
|
class Check
|
6
6
|
attr_reader :node, :html, :element, :src, :path, :options, :issues, :external_urls
|
7
7
|
|
8
|
-
def initialize(src, path, html, options)
|
8
|
+
def initialize(src, path, html, logger, options)
|
9
9
|
@src = src
|
10
10
|
@path = path
|
11
11
|
@html = remove_ignored(html)
|
12
|
+
@logger = logger
|
12
13
|
@options = options
|
13
14
|
@issues = []
|
14
15
|
@external_urls = {}
|
@@ -16,7 +17,7 @@ module HTMLProofer
|
|
16
17
|
|
17
18
|
def create_element(node)
|
18
19
|
@node = node
|
19
|
-
Element.new(node, self)
|
20
|
+
Element.new(node, self, @logger)
|
20
21
|
end
|
21
22
|
|
22
23
|
def run
|
@@ -1,28 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class HtmlCheck < ::HTMLProofer::Check
|
4
|
+
# tags embedded in scripts are used in templating languages: http://git.io/vOovv
|
4
5
|
SCRIPT_EMBEDS_MSG = /Element script embeds close tag/.freeze
|
5
6
|
INVALID_TAG_MSG = /Tag ([\w\-:]+) invalid/.freeze
|
6
7
|
INVALID_PREFIX = /Namespace prefix/.freeze
|
7
8
|
PARSE_ENTITY_REF = /htmlParseEntityRef: no name/.freeze
|
9
|
+
DOCTYPE_MSG = /Expected a doctype token/.freeze
|
10
|
+
EOF_IN_TAG = /End of input in tag/.freeze
|
11
|
+
MISMATCHED_TAGS = /That tag isn't allowed here/.freeze
|
8
12
|
|
9
13
|
def run
|
10
14
|
@html.errors.each do |error|
|
11
|
-
message
|
12
|
-
|
13
|
-
|
14
|
-
if message =~ INVALID_TAG_MSG || message =~ INVALID_PREFIX
|
15
|
-
next unless options[:validation][:report_invalid_tags]
|
16
|
-
end
|
17
|
-
|
18
|
-
if message =~ PARSE_ENTITY_REF
|
19
|
-
next unless options[:validation][:report_missing_names]
|
20
|
-
end
|
21
|
-
|
22
|
-
# tags embedded in scripts are used in templating languages: http://git.io/vOovv
|
23
|
-
next if !options[:validation][:report_script_embeds] && message =~ SCRIPT_EMBEDS_MSG
|
15
|
+
add_issue(error.message, line: error.line) if report?(error.message)
|
16
|
+
end
|
17
|
+
end
|
24
18
|
|
25
|
-
|
19
|
+
def report?(message)
|
20
|
+
case message
|
21
|
+
when SCRIPT_EMBEDS_MSG
|
22
|
+
options[:validation][:report_script_embeds]
|
23
|
+
when INVALID_TAG_MSG, INVALID_PREFIX
|
24
|
+
options[:validation][:report_invalid_tags]
|
25
|
+
when PARSE_ENTITY_REF
|
26
|
+
options[:validation][:report_missing_names]
|
27
|
+
when DOCTYPE_MSG
|
28
|
+
options[:validation][:report_missing_doctype]
|
29
|
+
when EOF_IN_TAG
|
30
|
+
options[:validation][:report_eof_tags]
|
31
|
+
when MISMATCHED_TAGS
|
32
|
+
options[:validation][:report_mismatched_tags]
|
33
|
+
else
|
34
|
+
true
|
26
35
|
end
|
27
36
|
end
|
28
37
|
end
|
@@ -34,7 +34,7 @@ class LinkCheck < ::HTMLProofer::Check
|
|
34
34
|
if missing_href?
|
35
35
|
next if @link.allow_missing_href?
|
36
36
|
# HTML5 allows dropping the href: http://git.io/vBX0z
|
37
|
-
next if @html.internal_subset.name == 'html' && @html.internal_subset.external_id.nil?
|
37
|
+
next if @html.internal_subset.nil? || (@html.internal_subset.name == 'html' && @html.internal_subset.external_id.nil?)
|
38
38
|
|
39
39
|
add_issue('anchor has no href attribute', line: line, content: content)
|
40
40
|
next
|
@@ -3,12 +3,12 @@
|
|
3
3
|
class OpenGraphElement < ::HTMLProofer::Element
|
4
4
|
attr_reader :src
|
5
5
|
|
6
|
-
def initialize(obj, check)
|
7
|
-
super(obj, check)
|
6
|
+
def initialize(obj, check, logger)
|
7
|
+
super(obj, check, logger)
|
8
8
|
# Fake up src from the content attribute
|
9
9
|
instance_variable_set('@src', @content)
|
10
10
|
|
11
|
-
@src.insert 0, 'http:' if
|
11
|
+
@src.insert 0, 'http:' if %r{^//}.match?(@src)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -23,7 +23,7 @@ class OpenGraphCheck < ::HTMLProofer::Check
|
|
23
23
|
|
24
24
|
def run
|
25
25
|
@html.css('meta[property="og:url"], meta[property="og:image"]').each do |m|
|
26
|
-
@opengraph = OpenGraphElement.new(m, self)
|
26
|
+
@opengraph = OpenGraphElement.new(m, self, @logger)
|
27
27
|
|
28
28
|
next if @opengraph.ignore?
|
29
29
|
|
@@ -51,7 +51,10 @@ module HTMLProofer
|
|
51
51
|
VALIDATION_DEFAULTS = {
|
52
52
|
report_script_embeds: false,
|
53
53
|
report_missing_names: false,
|
54
|
-
report_invalid_tags: false
|
54
|
+
report_invalid_tags: false,
|
55
|
+
report_missing_doctype: false,
|
56
|
+
report_eof_tags: false,
|
57
|
+
report_mismatched_tags: false
|
55
58
|
}.freeze
|
56
59
|
|
57
60
|
CACHE_DEFAULTS = {}.freeze
|
data/lib/html-proofer/element.rb
CHANGED
@@ -10,12 +10,18 @@ module HTMLProofer
|
|
10
10
|
|
11
11
|
attr_reader :id, :name, :alt, :href, :link, :src, :line, :data_proofer_ignore
|
12
12
|
|
13
|
-
def initialize(obj, check)
|
13
|
+
def initialize(obj, check, logger)
|
14
|
+
@logger = logger
|
14
15
|
# Construct readable ivars for every element
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
begin
|
17
|
+
obj.attributes.each_pair do |attribute, value|
|
18
|
+
name = attribute.tr('-:.;@', '_').to_s.to_sym
|
19
|
+
(class << self; self; end).send(:attr_reader, name)
|
20
|
+
instance_variable_set("@#{name}", value.value)
|
21
|
+
end
|
22
|
+
rescue NameError => e
|
23
|
+
@logger.log :error, "Attribute set `#{obj}` contains an error!"
|
24
|
+
raise e
|
19
25
|
end
|
20
26
|
|
21
27
|
@aria_hidden = defined?(@aria_hidden) && @aria_hidden == 'true' ? true : false
|
@@ -36,19 +42,19 @@ module HTMLProofer
|
|
36
42
|
|
37
43
|
# fix up missing protocols
|
38
44
|
if defined?(@href)
|
39
|
-
@href.insert(0, 'http:') if
|
45
|
+
@href.insert(0, 'http:') if %r{^//}.match?(@href)
|
40
46
|
else
|
41
47
|
@href = nil
|
42
48
|
end
|
43
49
|
|
44
50
|
if defined?(@src)
|
45
|
-
@src.insert(0, 'http:') if
|
51
|
+
@src.insert(0, 'http:') if %r{^//}.match?(@src)
|
46
52
|
else
|
47
53
|
@src = nil
|
48
54
|
end
|
49
55
|
|
50
56
|
if defined?(@srcset)
|
51
|
-
@srcset.insert(0, 'http:') if
|
57
|
+
@srcset.insert(0, 'http:') if %r{^//}.match?(@srcset)
|
52
58
|
else
|
53
59
|
@srcset = nil
|
54
60
|
end
|
@@ -99,11 +105,11 @@ module HTMLProofer
|
|
99
105
|
return true if @data_proofer_ignore
|
100
106
|
return true if @parent_ignorable
|
101
107
|
|
102
|
-
return true if
|
108
|
+
return true if /^javascript:/.match?(url)
|
103
109
|
|
104
110
|
# ignore base64 encoded images
|
105
111
|
if %w[ImageCheck FaviconCheck].include? @type
|
106
|
-
return true if
|
112
|
+
return true if /^data:image/.match?(url)
|
107
113
|
end
|
108
114
|
|
109
115
|
# ignore user defined URLs
|
@@ -172,7 +178,7 @@ module HTMLProofer
|
|
172
178
|
|
173
179
|
path_dot_ext = path + @check.options[:extension] if @check.options[:assume_extension]
|
174
180
|
|
175
|
-
if
|
181
|
+
if %r{^/}.match?(path) # path relative to root
|
176
182
|
if File.directory?(@check.src)
|
177
183
|
base = @check.src
|
178
184
|
else
|
@@ -211,10 +217,11 @@ module HTMLProofer
|
|
211
217
|
|
212
218
|
def ignores_pattern_check(links)
|
213
219
|
links.each do |ignore|
|
214
|
-
|
220
|
+
case ignore
|
221
|
+
when String
|
215
222
|
return true if ignore == url
|
216
|
-
|
217
|
-
return true if ignore
|
223
|
+
when Regexp
|
224
|
+
return true if ignore&.match?(url)
|
218
225
|
end
|
219
226
|
end
|
220
227
|
|
data/lib/html-proofer/log.rb
CHANGED
@@ -7,16 +7,27 @@ module HTMLProofer
|
|
7
7
|
class Log
|
8
8
|
include Yell::Loggable
|
9
9
|
|
10
|
+
STDOUT_LEVELS = %i[debug info warn].freeze
|
11
|
+
STDERR_LEVELS = %i[error fatal].freeze
|
12
|
+
|
10
13
|
def initialize(log_level)
|
11
14
|
@logger = Yell.new(format: false, \
|
12
15
|
name: 'HTMLProofer', \
|
13
16
|
level: "gte.#{log_level}") do |l|
|
14
|
-
l.adapter :stdout, level:
|
15
|
-
l.adapter :stderr, level:
|
17
|
+
l.adapter :stdout, level: 'lte.warn'
|
18
|
+
l.adapter :stderr, level: 'gte.error'
|
16
19
|
end
|
17
20
|
end
|
18
21
|
|
19
22
|
def log(level, message)
|
23
|
+
log_with_color(level, message)
|
24
|
+
end
|
25
|
+
|
26
|
+
def log_with_color(level, message)
|
27
|
+
@logger.send level, colorize(level, message)
|
28
|
+
end
|
29
|
+
|
30
|
+
def colorize(level, message)
|
20
31
|
color = case level
|
21
32
|
when :debug
|
22
33
|
:cyan
|
@@ -28,15 +39,8 @@ module HTMLProofer
|
|
28
39
|
:red
|
29
40
|
end
|
30
41
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
def log_with_color(level, color, message)
|
35
|
-
@logger.send level, colorize(color, message)
|
36
|
-
end
|
37
|
-
|
38
|
-
def colorize(color, message)
|
39
|
-
if $stdout.isatty && $stderr.isatty
|
42
|
+
if (STDOUT_LEVELS.include?(level) && $stdout.isatty) || \
|
43
|
+
(STDERR_LEVELS.include?(level) && $stderr.isatty)
|
40
44
|
Rainbow(message).send(color)
|
41
45
|
else
|
42
46
|
message
|
@@ -21,7 +21,8 @@ module HTMLProofer
|
|
21
21
|
allow_hash_href: true,
|
22
22
|
check_external_hash: true,
|
23
23
|
check_html: true,
|
24
|
-
url_ignore: [/.*/] # Don't try to check local files exist
|
24
|
+
url_ignore: [/.*/], # Don't try to check if local files exist
|
25
|
+
validation: { report_eof_tags: true }
|
25
26
|
}
|
26
27
|
end
|
27
28
|
|
@@ -52,7 +53,7 @@ module HTMLProofer
|
|
52
53
|
def call(env)
|
53
54
|
result = @app.call(env)
|
54
55
|
return result if env['REQUEST_METHOD'] != 'GET'
|
55
|
-
return result if env['QUERY_STRING']
|
56
|
+
return result if /proofer-ignore/.match?(env['QUERY_STRING'])
|
56
57
|
return result if result.first != 200
|
57
58
|
|
58
59
|
body = []
|
@@ -69,7 +70,7 @@ module HTMLProofer
|
|
69
70
|
'response',
|
70
71
|
Middleware.options
|
71
72
|
).check_parsed(
|
72
|
-
Nokogiri::
|
73
|
+
Nokogiri::HTML5(html, max_errors: -1), 'response'
|
73
74
|
)
|
74
75
|
|
75
76
|
raise InvalidHtmlError, parsed[:failures] unless parsed[:failures].empty?
|
data/lib/html-proofer/runner.rb
CHANGED
@@ -31,6 +31,7 @@ module HTMLProofer
|
|
31
31
|
end
|
32
32
|
|
33
33
|
@failures = []
|
34
|
+
@before_request = []
|
34
35
|
end
|
35
36
|
|
36
37
|
def run
|
@@ -45,7 +46,7 @@ module HTMLProofer
|
|
45
46
|
end
|
46
47
|
|
47
48
|
if @failures.empty?
|
48
|
-
@logger.
|
49
|
+
@logger.log :info, 'HTML-Proofer finished successfully.'
|
49
50
|
else
|
50
51
|
print_failed_tests
|
51
52
|
end
|
@@ -100,7 +101,7 @@ module HTMLProofer
|
|
100
101
|
@src.each do |src|
|
101
102
|
checks.each do |klass|
|
102
103
|
@logger.log :debug, "Checking #{klass.to_s.downcase} on #{path} ..."
|
103
|
-
check = Object.const_get(klass).new(src, path, html, @options)
|
104
|
+
check = Object.const_get(klass).new(src, path, html, @logger, @options)
|
104
105
|
check.run
|
105
106
|
external_urls = check.external_urls
|
106
107
|
external_urls = Hash[check.external_urls.map { |url, file| [swap(url, @options[:url_swap]), file] }] if @options[:url_swap]
|
@@ -117,6 +118,7 @@ module HTMLProofer
|
|
117
118
|
|
118
119
|
def validate_urls
|
119
120
|
url_validator = HTMLProofer::UrlValidator.new(@logger, @external_urls, @options)
|
121
|
+
url_validator.before_request = @before_request
|
120
122
|
@failures.concat(url_validator.run)
|
121
123
|
@external_urls = url_validator.external_urls
|
122
124
|
end
|
@@ -147,6 +149,8 @@ module HTMLProofer
|
|
147
149
|
def checks
|
148
150
|
return @checks if defined?(@checks) && !@checks.nil?
|
149
151
|
|
152
|
+
return (@checks = ['LinkCheck']) if @type == :links
|
153
|
+
|
150
154
|
@checks = HTMLProofer::Check.subchecks.map(&:name)
|
151
155
|
@checks.delete('FaviconCheck') unless @options[:check_favicon]
|
152
156
|
@checks.delete('HtmlCheck') unless @options[:check_html]
|
@@ -169,7 +173,23 @@ module HTMLProofer
|
|
169
173
|
sorted_failures.sort_and_report
|
170
174
|
count = @failures.length
|
171
175
|
failure_text = pluralize(count, 'failure', 'failures')
|
172
|
-
raise @logger.colorize :
|
176
|
+
raise @logger.colorize :fatal, "HTML-Proofer found #{failure_text}!"
|
177
|
+
end
|
178
|
+
|
179
|
+
# Set before_request callback.
|
180
|
+
#
|
181
|
+
# @example Set before_request.
|
182
|
+
# request.before_request { |request| p "yay" }
|
183
|
+
#
|
184
|
+
# @param [ Block ] block The block to execute.
|
185
|
+
#
|
186
|
+
# @yield [ Typhoeus::Request ]
|
187
|
+
#
|
188
|
+
# @return [ Array<Block> ] All before_request blocks.
|
189
|
+
def before_request(&block)
|
190
|
+
@before_request ||= []
|
191
|
+
@before_request << block if block_given?
|
192
|
+
@before_request
|
173
193
|
end
|
174
194
|
end
|
175
195
|
end
|
@@ -10,6 +10,7 @@ module HTMLProofer
|
|
10
10
|
include HTMLProofer::Utils
|
11
11
|
|
12
12
|
attr_reader :external_urls
|
13
|
+
attr_writer :before_request
|
13
14
|
|
14
15
|
def initialize(logger, external_urls, options)
|
15
16
|
@logger = logger
|
@@ -18,6 +19,7 @@ module HTMLProofer
|
|
18
19
|
@options = options
|
19
20
|
@hydra = Typhoeus::Hydra.new(@options[:hydra])
|
20
21
|
@cache = Cache.new(@logger, @options[:cache])
|
22
|
+
@before_request = []
|
21
23
|
end
|
22
24
|
|
23
25
|
def run
|
@@ -137,6 +139,9 @@ module HTMLProofer
|
|
137
139
|
def queue_request(method, href, filenames)
|
138
140
|
opts = @options[:typhoeus].merge(method: method)
|
139
141
|
request = Typhoeus::Request.new(href, opts)
|
142
|
+
@before_request.each do |callback|
|
143
|
+
callback.call(request)
|
144
|
+
end
|
140
145
|
request.on_complete { |response| response_handler(response, filenames) }
|
141
146
|
@hydra.queue request
|
142
147
|
end
|
@@ -146,7 +151,7 @@ module HTMLProofer
|
|
146
151
|
href = response.request.base_url.to_s
|
147
152
|
method = response.request.options[:method]
|
148
153
|
response_code = response.code
|
149
|
-
response.body.
|
154
|
+
response.body.delete!("\x00")
|
150
155
|
|
151
156
|
debug_msg = if filenames.nil?
|
152
157
|
"Received a #{response_code} for #{href}"
|
data/lib/html-proofer/utils.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'nokogumbo'
|
4
4
|
|
5
5
|
module HTMLProofer
|
6
6
|
module Utils
|
@@ -15,7 +15,7 @@ module HTMLProofer
|
|
15
15
|
path
|
16
16
|
end
|
17
17
|
|
18
|
-
Nokogiri::
|
18
|
+
Nokogiri::HTML5(content, max_errors: -1)
|
19
19
|
end
|
20
20
|
|
21
21
|
def swap(href, replacement)
|
@@ -24,14 +24,5 @@ module HTMLProofer
|
|
24
24
|
end
|
25
25
|
href
|
26
26
|
end
|
27
|
-
|
28
|
-
# address a problem with Nokogiri's parsing URL entities
|
29
|
-
# problem from http://git.io/vBYU1
|
30
|
-
# solution from http://git.io/vBYUi
|
31
|
-
def clean_content(string)
|
32
|
-
string.gsub(%r{(?:https?:)?//([^>]+)}i) do |url|
|
33
|
-
url.gsub(/&(?!amp;)/, '&')
|
34
|
-
end
|
35
|
-
end
|
36
27
|
end
|
37
28
|
end
|
data/lib/html-proofer/version.rb
CHANGED
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.
|
4
|
+
version: 3.16.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:
|
11
|
+
date: 2020-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -39,19 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0.3'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: nokogumbo
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '2.0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '2.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: parallel
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -308,7 +308,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
308
308
|
- !ruby/object:Gem::Version
|
309
309
|
version: '0'
|
310
310
|
requirements: []
|
311
|
-
rubygems_version: 3.
|
311
|
+
rubygems_version: 3.1.2
|
312
312
|
signing_key:
|
313
313
|
specification_version: 4
|
314
314
|
summary: A set of tests to validate your HTML output. These tests check if your image
|