From c393cc6b4297fc12fdfb2a0f97b38ac3b90a6974 Mon Sep 17 00:00:00 2001 From: Phil Schalm Date: Tue, 6 Feb 2024 01:17:37 -0800 Subject: [PATCH 1/7] Add test for long attribute value containing an "=" sign --- test/fixtures/attributes.html.erb | 3 ++- test/fixtures/attributes.html.expected.erb | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/test/fixtures/attributes.html.erb b/test/fixtures/attributes.html.erb index 68c1352..86015f6 100644 --- a/test/fixtures/attributes.html.erb +++ b/test/fixtures/attributes.html.erb @@ -5,4 +5,5 @@ sizes="(max-width: 600px) 480px, (max-width: 1000px) 800px, 1200px" - data-autocomplete-min-length-value=2> + data-autocomplete-min-length-value=2 + data-url="https://google.ca/this-is-a-long-url-with-a-query-string?query=something"> diff --git a/test/fixtures/attributes.html.expected.erb b/test/fixtures/attributes.html.expected.erb index b2c55ff..816a872 100644 --- a/test/fixtures/attributes.html.expected.erb +++ b/test/fixtures/attributes.html.expected.erb @@ -4,4 +4,5 @@ srcset="image-480w.jpg 480w, image-800w.jpg 800w, image-1200w.jpg 1200w" sizes="(max-width: 600px) 480px, (max-width: 1000px) 800px, 1200px" data-autocomplete-min-length-value="2" + data-url="https://google.ca/this-is-a-long-url-with-a-query-string?query=something" > From c70c54b4b36333b70777fe113b69414507a6de9a Mon Sep 17 00:00:00 2001 From: Phil Schalm Date: Tue, 6 Feb 2024 01:18:03 -0800 Subject: [PATCH 2/7] Update code to handle currently-broken test --- lib/erb/formatter.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/erb/formatter.rb b/lib/erb/formatter.rb index fff8be1..ebc899a 100644 --- a/lib/erb/formatter.rb +++ b/lib/erb/formatter.rb @@ -136,16 +136,17 @@ def format_attributes(tag_name, attrs, tag_closing) attrs.scan(ATTR).flatten.each do |attr| attr.strip! name, value = attr.split('=', 2) - if UNQUOTED_ATTR =~ attr - attr_html << indented("#{name}=\"#{value}\"") - next - end if value.nil? attr_html << indented("#{name}") next end + if value[0] != '"' && value[0] != "'" + attr_html << indented("#{name}=\"#{value}\"") + next + end + value_parts = value[1...-1].strip.split(/\s+/) value_parts.sort_by!(&@css_class_sorter) if name == 'class' && @css_class_sorter From 3e0cf8be8dc57a6b79842c23beb890497a324aa0 Mon Sep 17 00:00:00 2001 From: Phil Schalm Date: Tue, 6 Feb 2024 01:22:42 -0800 Subject: [PATCH 3/7] Add additional test for short urls --- test/fixtures/attributes.html.erb | 3 ++- test/fixtures/attributes.html.expected.erb | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/fixtures/attributes.html.erb b/test/fixtures/attributes.html.erb index 86015f6..5a06523 100644 --- a/test/fixtures/attributes.html.erb +++ b/test/fixtures/attributes.html.erb @@ -6,4 +6,5 @@ (max-width: 1000px) 800px, 1200px" data-autocomplete-min-length-value=2 - data-url="https://google.ca/this-is-a-long-url-with-a-query-string?query=something"> + data-short-url="//test.ccom/?q=v" + data-long-url="https://google.ca/this-is-a-long-url-with-a-query-string?query=something"> diff --git a/test/fixtures/attributes.html.expected.erb b/test/fixtures/attributes.html.expected.erb index 816a872..33e0200 100644 --- a/test/fixtures/attributes.html.expected.erb +++ b/test/fixtures/attributes.html.expected.erb @@ -4,5 +4,6 @@ srcset="image-480w.jpg 480w, image-800w.jpg 800w, image-1200w.jpg 1200w" sizes="(max-width: 600px) 480px, (max-width: 1000px) 800px, 1200px" data-autocomplete-min-length-value="2" - data-url="https://google.ca/this-is-a-long-url-with-a-query-string?query=something" + data-short-url="//test.ccom/?q=v" + data-long-url="https://google.ca/this-is-a-long-url-with-a-query-string?query=something" > From 803b83c0006dcbf1c762361da294791ff8ece7e5 Mon Sep 17 00:00:00 2001 From: Phil Schalm Date: Tue, 6 Feb 2024 01:23:49 -0800 Subject: [PATCH 4/7] Fix test url spelling --- test/fixtures/attributes.html.erb | 2 +- test/fixtures/attributes.html.expected.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fixtures/attributes.html.erb b/test/fixtures/attributes.html.erb index 5a06523..1b35932 100644 --- a/test/fixtures/attributes.html.erb +++ b/test/fixtures/attributes.html.erb @@ -6,5 +6,5 @@ (max-width: 1000px) 800px, 1200px" data-autocomplete-min-length-value=2 - data-short-url="//test.ccom/?q=v" + data-short-url="//test.com/?q=v" data-long-url="https://google.ca/this-is-a-long-url-with-a-query-string?query=something"> diff --git a/test/fixtures/attributes.html.expected.erb b/test/fixtures/attributes.html.expected.erb index 33e0200..14bee4d 100644 --- a/test/fixtures/attributes.html.expected.erb +++ b/test/fixtures/attributes.html.expected.erb @@ -4,6 +4,6 @@ srcset="image-480w.jpg 480w, image-800w.jpg 800w, image-1200w.jpg 1200w" sizes="(max-width: 600px) 480px, (max-width: 1000px) 800px, 1200px" data-autocomplete-min-length-value="2" - data-short-url="//test.ccom/?q=v" + data-short-url="//test.com/?q=v" data-long-url="https://google.ca/this-is-a-long-url-with-a-query-string?query=something" > From 639da9699246f8658548f4e8ed14ae17b94dfe1a Mon Sep 17 00:00:00 2001 From: Phil Schalm Date: Mon, 12 Feb 2024 11:47:44 -0800 Subject: [PATCH 5/7] Add check for single quotes containing a query string --- test/fixtures/attributes.html.erb | 3 ++- test/fixtures/attributes.html.expected.erb | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/test/fixtures/attributes.html.erb b/test/fixtures/attributes.html.erb index 1b35932..daaeb6d 100644 --- a/test/fixtures/attributes.html.erb +++ b/test/fixtures/attributes.html.erb @@ -7,4 +7,5 @@ 1200px" data-autocomplete-min-length-value=2 data-short-url="//test.com/?q=v" - data-long-url="https://google.ca/this-is-a-long-url-with-a-query-string?query=something"> + data-long-url="https://google.ca/this-is-a-long-url-with-a-query-string?query=something" + data-long-url-single='https://google.ca/this-is-a-long-url-with-a-query-string?query=something'> diff --git a/test/fixtures/attributes.html.expected.erb b/test/fixtures/attributes.html.expected.erb index 14bee4d..0aed143 100644 --- a/test/fixtures/attributes.html.expected.erb +++ b/test/fixtures/attributes.html.expected.erb @@ -6,4 +6,5 @@ data-autocomplete-min-length-value="2" data-short-url="//test.com/?q=v" data-long-url="https://google.ca/this-is-a-long-url-with-a-query-string?query=something" + data-long-url-single='https://google.ca/this-is-a-long-url-with-a-query-string?query=something' > From 4ef6e49093e97cda3bb7ca853eb7310a6160b250 Mon Sep 17 00:00:00 2001 From: Elia Schito Date: Mon, 26 Feb 2024 09:58:29 +0100 Subject: [PATCH 6/7] Fix the UNQUOTED_VALUE regexp and use it when checking attributes --- lib/erb/formatter.rb | 4 ++-- test/fixtures/multiline_attributes.html.erb | 6 ++++++ test/fixtures/multiline_attributes.html.expected.erb | 6 ++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/erb/formatter.rb b/lib/erb/formatter.rb index ebc899a..537ddd2 100644 --- a/lib/erb/formatter.rb +++ b/lib/erb/formatter.rb @@ -28,7 +28,7 @@ class Error < StandardError; end # https://stackoverflow.com/a/317081 ATTR_NAME = %r{[^\r\n\t\f\v= '"<>]*[^\r\n\t\f\v= '"<>/]} # not ending with a slash - UNQUOTED_VALUE = ATTR_NAME + UNQUOTED_VALUE = %r{[^<>'"\s]+} UNQUOTED_ATTR = %r{#{ATTR_NAME}=#{UNQUOTED_VALUE}} SINGLE_QUOTE_ATTR = %r{(?:#{ATTR_NAME}='[^']*?')}m DOUBLE_QUOTE_ATTR = %r{(?:#{ATTR_NAME}="[^"]*?")}m @@ -142,7 +142,7 @@ def format_attributes(tag_name, attrs, tag_closing) next end - if value[0] != '"' && value[0] != "'" + if /\A#{UNQUOTED_VALUE}\z/o.match?(value) attr_html << indented("#{name}=\"#{value}\"") next end diff --git a/test/fixtures/multiline_attributes.html.erb b/test/fixtures/multiline_attributes.html.erb index d45f30b..d2cb729 100644 --- a/test/fixtures/multiline_attributes.html.erb +++ b/test/fixtures/multiline_attributes.html.erb @@ -4,3 +4,9 @@ aria-disabled:text-gray-300 aria-disabled:bg-transparent aria-disabled:border-gr + +

diff --git a/test/fixtures/multiline_attributes.html.expected.erb b/test/fixtures/multiline_attributes.html.expected.erb index 8d28ef1..d28d42b 100644 --- a/test/fixtures/multiline_attributes.html.expected.erb +++ b/test/fixtures/multiline_attributes.html.expected.erb @@ -15,3 +15,9 @@ > Foooo + +

From c5d34766abd34c89fdf54f88c34f100fe4824d49 Mon Sep 17 00:00:00 2001 From: Elia Schito Date: Mon, 26 Feb 2024 09:59:05 +0100 Subject: [PATCH 7/7] Extract the regexp for spacing chars into a constant --- lib/erb/formatter.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/erb/formatter.rb b/lib/erb/formatter.rb index 537ddd2..b14b375 100644 --- a/lib/erb/formatter.rb +++ b/lib/erb/formatter.rb @@ -26,6 +26,8 @@ def format(q) class Error < StandardError; end + SPACES = /\s+/m + # https://stackoverflow.com/a/317081 ATTR_NAME = %r{[^\r\n\t\f\v= '"<>]*[^\r\n\t\f\v= '"<>/]} # not ending with a slash UNQUOTED_VALUE = %r{[^<>'"\s]+} @@ -147,7 +149,7 @@ def format_attributes(tag_name, attrs, tag_closing) next end - value_parts = value[1...-1].strip.split(/\s+/) + value_parts = value[1...-1].strip.split(SPACES) value_parts.sort_by!(&@css_class_sorter) if name == 'class' && @css_class_sorter full_attr = "#{name}=#{value[0]}#{value_parts.join(" ")}#{value[-1]}" @@ -232,7 +234,7 @@ def format_text(text) return if text.match?(/\A\s*\z/m) # empty - text = text.gsub(/\s+/m, ' ').strip + text = text.gsub(SPACES, ' ').strip offset = indented("").size # Restore full line width if there are less than 40 columns available