html-proofer 4.3.0 → 4.4.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/lib/html_proofer/attribute/url.rb +4 -3
- data/lib/html_proofer/check/favicon.rb +4 -1
- data/lib/html_proofer/check/images.rb +11 -14
- data/lib/html_proofer/check/links.rb +7 -1
- data/lib/html_proofer/check/open_graph.rb +3 -0
- data/lib/html_proofer/check/scripts.rb +4 -1
- data/lib/html_proofer/check.rb +20 -18
- data/lib/html_proofer/configuration.rb +27 -25
- data/lib/html_proofer/version.rb +1 -1
- data/lib/html_proofer.rb +25 -23
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98bde6dd5e32f42e5983fd1aaa7bf02d3359b40f2b4a8b5360a5826abf2cc674
|
4
|
+
data.tar.gz: 9b7d57fd18e625ab7cc91c46faceac510b05ba5290f665fb5dd333b92446b00b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a666be806bbb70028488b3ef89f1325d7b5faaec9f48e105220db2d2f7dd022c12dabac828949ffd2100bdc2b4e3bd4c1f9ce9df48bab17b9106d9453eb49f01
|
7
|
+
data.tar.gz: 8a58bb5b120ab3cf3eb0e692f3f52f4385bd5923d3a7c91e95dddd17d8b0e25d20dd207872099665ac37737afb6b4ed86d04d39bc7793c6af2abcd35390d2051
|
@@ -20,12 +20,13 @@ module HTMLProofer
|
|
20
20
|
|
21
21
|
swap_urls!
|
22
22
|
clean_url!
|
23
|
-
|
24
|
-
# convert "//" links to "https://"
|
25
|
-
@url.start_with?("//") ? @url = "https:#{@url}" : @url
|
26
23
|
end
|
27
24
|
end
|
28
25
|
|
26
|
+
def protocol_relative?
|
27
|
+
url.start_with?("//")
|
28
|
+
end
|
29
|
+
|
29
30
|
def to_s
|
30
31
|
@url
|
31
32
|
end
|
@@ -16,7 +16,10 @@ module HTMLProofer
|
|
16
16
|
return if immediate_redirect?
|
17
17
|
|
18
18
|
if found
|
19
|
-
if @favicon.url.
|
19
|
+
if @favicon.url.protocol_relative?
|
20
|
+
add_failure("favicon link #{@favicon.url} is a protocol-relative URL, use explicit https:// instead",
|
21
|
+
line: @favicon.line, content: @favicon.content)
|
22
|
+
elsif @favicon.url.remote?
|
20
23
|
add_to_external_urls(@favicon.url, @favicon.line)
|
21
24
|
elsif !@favicon.url.exists?
|
22
25
|
add_failure("internal favicon #{@favicon.url.raw_attribute} does not exist", line: @favicon.line,
|
@@ -6,7 +6,7 @@ module HTMLProofer
|
|
6
6
|
SCREEN_SHOT_REGEX = /Screen(?: |%20)Shot(?: |%20)\d+-\d+-\d+(?: |%20)at(?: |%20)\d+.\d+.\d+/.freeze
|
7
7
|
|
8
8
|
def run
|
9
|
-
@html.css("img").each do |node|
|
9
|
+
@html.css("img, source").each do |node|
|
10
10
|
@img = create_element(node)
|
11
11
|
|
12
12
|
next if @img.ignore?
|
@@ -18,26 +18,22 @@ module HTMLProofer
|
|
18
18
|
# does the image exist?
|
19
19
|
if missing_src?
|
20
20
|
add_failure("image has no src or srcset attribute", line: @img.line, content: @img.content)
|
21
|
+
elsif @img.url.protocol_relative?
|
22
|
+
add_failure("image link #{@img.url} is a protocol-relative URL, use explicit https:// instead",
|
23
|
+
line: @img.line, content: @img.content)
|
21
24
|
elsif @img.url.remote?
|
22
25
|
add_to_external_urls(@img.url, @img.line)
|
23
26
|
elsif !@img.url.exists? && !@img.multiple_srcsets? && !@img.multiple_sizes?
|
24
27
|
add_failure("internal image #{@img.url.raw_attribute} does not exist", line: @img.line,
|
25
28
|
content: @img.content)
|
26
|
-
elsif @img.multiple_srcsets?
|
27
|
-
@img.srcsets.each do |srcset|
|
28
|
-
srcset_url = HTMLProofer::Attribute::Url.new(@runner, srcset, base_url: @img.base_url, extract_size: true)
|
29
|
-
|
30
|
-
if srcset_url.remote?
|
31
|
-
add_to_external_urls(srcset_url.url, @img.line)
|
32
|
-
elsif !srcset_url.exists?
|
33
|
-
add_failure("internal image #{srcset} does not exist", line: @img.line, content: @img.content)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
elsif @img.multiple_sizes?
|
29
|
+
elsif @img.multiple_srcsets? || @img.multiple_sizes?
|
37
30
|
@img.srcsets_wo_sizes.each do |srcset|
|
38
31
|
srcset_url = HTMLProofer::Attribute::Url.new(@runner, srcset, base_url: @img.base_url, extract_size: true)
|
39
32
|
|
40
|
-
if srcset_url.
|
33
|
+
if srcset_url.protocol_relative?
|
34
|
+
add_failure("image link #{srcset_url.url} is a protocol-relative URL, use explicit https:// instead",
|
35
|
+
line: @img.line, content: @img.content)
|
36
|
+
elsif srcset_url.remote?
|
41
37
|
add_to_external_urls(srcset_url.url, @img.line)
|
42
38
|
elsif !srcset_url.exists?
|
43
39
|
add_failure("internal image #{srcset} does not exist", line: @img.line, content: @img.content)
|
@@ -45,7 +41,8 @@ module HTMLProofer
|
|
45
41
|
end
|
46
42
|
end
|
47
43
|
|
48
|
-
|
44
|
+
# if this is an img element, check that the alt attribute is present
|
45
|
+
if @img.img_tag? && !ignore_element?
|
49
46
|
if missing_alt_tag? && !ignore_missing_alt?
|
50
47
|
add_failure("image #{@img.url.raw_attribute} does not have an alt attribute", line: @img.line,
|
51
48
|
content: @img.content)
|
@@ -4,7 +4,7 @@ module HTMLProofer
|
|
4
4
|
class Check
|
5
5
|
class Links < HTMLProofer::Check
|
6
6
|
def run
|
7
|
-
@html.css("a, link
|
7
|
+
@html.css("a, link").each do |node|
|
8
8
|
@link = create_element(node)
|
9
9
|
|
10
10
|
next if @link.ignore?
|
@@ -28,6 +28,12 @@ module HTMLProofer
|
|
28
28
|
next
|
29
29
|
end
|
30
30
|
|
31
|
+
if @link.url.protocol_relative?
|
32
|
+
add_failure("#{@link.url} is a protocol-relative URL, use explicit https:// instead",
|
33
|
+
line: @link.line, content: @link.content)
|
34
|
+
next
|
35
|
+
end
|
36
|
+
|
31
37
|
check_schemes
|
32
38
|
|
33
39
|
# intentionally down here because we still want valid? & missing_href? to execute
|
@@ -16,6 +16,9 @@ module HTMLProofer
|
|
16
16
|
add_failure("open graph content attribute is empty", line: @open_graph.line, content: @open_graph.content)
|
17
17
|
elsif !@open_graph.url.valid?
|
18
18
|
add_failure("#{@open_graph.src} is an invalid URL", line: @open_graph.line)
|
19
|
+
elsif @open_graph.url.protocol_relative?
|
20
|
+
add_failure("open graph link #{@open_graph.url} is a protocol-relative URL, use explicit https:// instead",
|
21
|
+
line: @open_graph.line, content: @open_graph.content)
|
19
22
|
elsif @open_graph.url.remote?
|
20
23
|
add_to_external_urls(@open_graph.url, @open_graph.line)
|
21
24
|
else
|
@@ -13,8 +13,11 @@ module HTMLProofer
|
|
13
13
|
# does the script exist?
|
14
14
|
if missing_src?
|
15
15
|
add_failure("script is empty and has no src attribute", line: @script.line, content: @script.content)
|
16
|
+
elsif @script.url.protocol_relative?
|
17
|
+
add_failure("script link #{@script.url} is a protocol-relative URL, use explicit https:// instead",
|
18
|
+
line: @script.line, content: @script.content)
|
16
19
|
elsif @script.url.remote?
|
17
|
-
add_to_external_urls(@script.
|
20
|
+
add_to_external_urls(@script.url, @script.line)
|
18
21
|
check_sri if @runner.check_sri?
|
19
22
|
elsif !@script.url.exists?
|
20
23
|
add_failure("internal script reference #{@script.src} does not exist", line: @script.line,
|
data/lib/html_proofer/check.rb
CHANGED
@@ -29,28 +29,10 @@ module HTMLProofer
|
|
29
29
|
content: content)
|
30
30
|
end
|
31
31
|
|
32
|
-
def self.subchecks(runner_options)
|
33
|
-
# grab all known checks
|
34
|
-
checks = ObjectSpace.each_object(Class).select do |klass|
|
35
|
-
klass < self
|
36
|
-
end
|
37
|
-
|
38
|
-
# remove any checks not explicitly included
|
39
|
-
checks.each_with_object([]) do |check, arr|
|
40
|
-
next unless runner_options[:checks].include?(check.short_name)
|
41
|
-
|
42
|
-
arr << check
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
32
|
def short_name
|
47
33
|
self.class.name.split("::").last
|
48
34
|
end
|
49
35
|
|
50
|
-
def self.short_name
|
51
|
-
name.split("::").last
|
52
|
-
end
|
53
|
-
|
54
36
|
def add_to_internal_urls(url, line)
|
55
37
|
url_string = url.raw_attribute
|
56
38
|
|
@@ -74,6 +56,26 @@ module HTMLProofer
|
|
74
56
|
@external_urls[url_string] << { filename: @runner.current_filename, line: line }
|
75
57
|
end
|
76
58
|
|
59
|
+
class << self
|
60
|
+
def subchecks(runner_options)
|
61
|
+
# grab all known checks
|
62
|
+
checks = ObjectSpace.each_object(Class).select do |klass|
|
63
|
+
klass < self
|
64
|
+
end
|
65
|
+
|
66
|
+
# remove any checks not explicitly included
|
67
|
+
checks.each_with_object([]) do |check, arr|
|
68
|
+
next unless runner_options[:checks].include?(check.short_name)
|
69
|
+
|
70
|
+
arr << check
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def short_name
|
75
|
+
name.split("::").last
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
77
79
|
private def base_url
|
78
80
|
return @base_url if defined?(@base_url)
|
79
81
|
|
@@ -47,42 +47,44 @@ module HTMLProofer
|
|
47
47
|
|
48
48
|
CACHE_DEFAULTS = {}.freeze
|
49
49
|
|
50
|
-
|
51
|
-
|
50
|
+
class << self
|
51
|
+
def generate_defaults(opts)
|
52
|
+
options = PROOFER_DEFAULTS.merge(opts)
|
52
53
|
|
53
|
-
|
54
|
-
|
54
|
+
options[:typhoeus] = HTMLProofer::Configuration::TYPHOEUS_DEFAULTS.merge(opts[:typhoeus] || {})
|
55
|
+
options[:hydra] = HTMLProofer::Configuration::HYDRA_DEFAULTS.merge(opts[:hydra] || {})
|
55
56
|
|
56
|
-
|
57
|
-
|
57
|
+
options[:parallel] = HTMLProofer::Configuration::PARALLEL_DEFAULTS.merge(opts[:parallel] || {})
|
58
|
+
options[:cache] = HTMLProofer::Configuration::CACHE_DEFAULTS.merge(opts[:cache] || {})
|
58
59
|
|
59
|
-
|
60
|
+
options.delete(:src)
|
60
61
|
|
61
|
-
|
62
|
-
|
62
|
+
options
|
63
|
+
end
|
63
64
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
65
|
+
def to_regex?(item)
|
66
|
+
if item.start_with?("/") && item.end_with?("/")
|
67
|
+
Regexp.new(item[1...-1])
|
68
|
+
else
|
69
|
+
item
|
70
|
+
end
|
69
71
|
end
|
70
|
-
end
|
71
72
|
|
72
|
-
|
73
|
-
|
74
|
-
|
73
|
+
def parse_json_option(option_name, config, symbolize_names: true)
|
74
|
+
raise ArgumentError, "Must provide an option name in string format." unless option_name.is_a?(String)
|
75
|
+
raise ArgumentError, "Must provide an option name in string format." if option_name.strip.empty?
|
75
76
|
|
76
|
-
|
77
|
+
return {} if config.nil?
|
77
78
|
|
78
|
-
|
79
|
+
raise ArgumentError, "Must provide a JSON configuration in string format." unless config.is_a?(String)
|
79
80
|
|
80
|
-
|
81
|
+
return {} if config.strip.empty?
|
81
82
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
83
|
+
begin
|
84
|
+
JSON.parse(config, { symbolize_names: symbolize_names })
|
85
|
+
rescue StandardError
|
86
|
+
raise ArgumentError, "Option '#{option_name} did not contain valid JSON."
|
87
|
+
end
|
86
88
|
end
|
87
89
|
end
|
88
90
|
end
|
data/lib/html_proofer/version.rb
CHANGED
data/lib/html_proofer.rb
CHANGED
@@ -20,37 +20,39 @@ if ENV.fetch("DEBUG", false)
|
|
20
20
|
end
|
21
21
|
|
22
22
|
module HTMLProofer
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
class << self
|
24
|
+
def check_file(file, options = {})
|
25
|
+
raise ArgumentError unless file.is_a?(String)
|
26
|
+
raise ArgumentError, "#{file} does not exist" unless File.exist?(file)
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
options[:type] = :file
|
29
|
+
HTMLProofer::Runner.new(file, options)
|
30
|
+
end
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
def check_directory(directory, options = {})
|
33
|
+
raise ArgumentError unless directory.is_a?(String)
|
34
|
+
raise ArgumentError, "#{directory} does not exist" unless Dir.exist?(directory)
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
options[:type] = :directory
|
37
|
+
HTMLProofer::Runner.new([directory], options)
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
40
|
+
def check_directories(directories, options = {})
|
41
|
+
raise ArgumentError unless directories.is_a?(Array)
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
options[:type] = :directory
|
44
|
+
directories.each do |directory|
|
45
|
+
raise ArgumentError, "#{directory} does not exist" unless Dir.exist?(directory)
|
46
|
+
end
|
47
|
+
HTMLProofer::Runner.new(directories, options)
|
45
48
|
end
|
46
|
-
HTMLProofer::Runner.new(directories, options)
|
47
|
-
end
|
48
49
|
|
49
|
-
|
50
|
-
|
50
|
+
def check_links(links, options = {})
|
51
|
+
raise ArgumentError unless links.is_a?(Array)
|
51
52
|
|
52
|
-
|
53
|
-
|
53
|
+
options[:type] = :links
|
54
|
+
HTMLProofer::Runner.new(links, options)
|
55
|
+
end
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
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: 4.
|
4
|
+
version: 4.4.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: 2022-
|
11
|
+
date: 2022-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|