diff --git a/lib/html_proofer/element.rb b/lib/html_proofer/element.rb index 5948f29d..a0bbe55c 100644 --- a/lib/html_proofer/element.rb +++ b/lib/html_proofer/element.rb @@ -82,10 +82,25 @@ def multiple_srcsets? !blank?(srcset) && srcset.split(",").size > 1 end + # From https://github.com/sindresorhus/srcset/blob/f7c48acd7facf18e94dec47e6b96e84e0f0e69dc/index.js#LL1-L16C71 + # This regex represents a loose rule of an “image candidate string”; see https://html.spec.whatwg.org/multipage/images.html#srcset-attribute + # An “image candidate string” roughly consists of the following: + # 1. Zero or more whitespace characters. + # 2. A non-empty URL that does not start or end with `,`. + # 3. Zero or more whitespace characters. + # 4. An optional “descriptor” that starts with a whitespace character. + # 5. Zero or more whitespace characters. + # 6. Each image candidate string is separated by a `,`. + # We intentionally implement a loose rule here so that we can perform more aggressive error handling and reporting in the below code. + + IMAGE_CANDIDATE_REGEX = /\s*([^,]\S*[^,](?:\s+[^,]+)?)\s*(?:,|$)/ + def srcsets return nil if blank?(srcset) - srcset.split(",").map(&:strip) + srcset.split(IMAGE_CANDIDATE_REGEX).select.with_index do |_part, idx| + idx.odd? + end.map(&:strip) end def multiple_sizes? diff --git a/lib/html_proofer/version.rb b/lib/html_proofer/version.rb index 6dcd8598..3154d0f9 100644 --- a/lib/html_proofer/version.rb +++ b/lib/html_proofer/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module HTMLProofer - VERSION = "5.0.2" + VERSION = "5.0.3" end diff --git a/spec/html-proofer/fixtures/images/base64_srcset.html b/spec/html-proofer/fixtures/images/base64_srcset.html new file mode 100644 index 00000000..4161dc97 --- /dev/null +++ b/spec/html-proofer/fixtures/images/base64_srcset.html @@ -0,0 +1 @@ + diff --git a/spec/html-proofer/images_spec.rb b/spec/html-proofer/images_spec.rb index c63813b7..e51a06ff 100644 --- a/spec/html-proofer/images_spec.rb +++ b/spec/html-proofer/images_spec.rb @@ -236,6 +236,12 @@ expect(proofer.failed_checks.first.description).to(eq("internal image /uploads/150-marie-lloyd.jpg does not exist")) end + it "supports base64 srcsets" do + relative_images = File.join(FIXTURES_DIR, "images", "base64_srcset.html") + proofer = run_proofer(relative_images, :file) + expect(proofer.failed_checks).to(eq([])) + end + it "works for images with a swapped data attribute src" do custom_data_src_check = "#{FIXTURES_DIR}/images/data_src_attribute.html" proofer = run_proofer(custom_data_src_check, :file, swap_attributes: { "img" => [["data-src", "src"]] })