diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 1dd96cbad..37bfcf0de 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -944,16 +944,27 @@ module ApplicationHelper attachments += obj.attachments if obj.respond_to?(:attachments) end if attachments.present? - text.gsub!(/src="([^\/"]+\.(bmp|gif|jpg|jpe|jpeg|png|webp))"(\s+alt="([^"]*)")?/i) do |m| - filename, ext, alt, alttext = $1, $2, $3, $4 + title_and_alt_re = /\s+(title|alt)="([^"]*)"/i + + text.gsub!(/src="([^\/"]+\.(bmp|gif|jpg|jpe|jpeg|png|webp))"([^>]*)/i) do |m| + filename, ext, other_attrs = $1, $2, $3 + # search for the picture in attachments if found = Attachment.latest_attach(attachments, CGI.unescape(filename)) image_url = download_named_attachment_url(found, found.filename, :only_path => only_path) desc = found.description.to_s.delete('"') - if !desc.blank? && alttext.blank? - alt = " title=\"#{desc}\" alt=\"#{desc}\"" - end - "src=\"#{image_url}\"#{alt} loading=\"lazy\"" + + # remove title and alt attributes after extracting them + title_and_alt = other_attrs.scan(title_and_alt_re).to_h + other_attrs.gsub!(title_and_alt_re, '') + + title_and_alt_attrs = if !desc.blank? && title_and_alt['alt'].blank? + " title=\"#{desc}\" alt=\"#{desc}\"" + else + # restore original title and alt attributes + " #{title_and_alt.map { |k, v| %[#{k}="#{v}"] }.join(' ')}" + end + "src=\"#{image_url}\"#{title_and_alt_attrs} loading=\"lazy\"#{other_attrs}" else m end diff --git a/test/helpers/application_helper_test.rb b/test/helpers/application_helper_test.rb index 443ad4698..70c112732 100644 --- a/test/helpers/application_helper_test.rb +++ b/test/helpers/application_helper_test.rb @@ -202,11 +202,11 @@ class ApplicationHelperTest < Redmine::HelperTest attachments = Attachment.all with_settings text_formatting: 'textile' do # When alt text is set - assert_match %r[This is a logo], + assert_match %r[alt text], textilizable('!logo.gif(alt text)!', attachments: attachments) # When alt text and style are set - assert_match %r[This is a logo], + assert_match %r[alt text], textilizable('!{width:100px}logo.gif(alt text)!', attachments: attachments) # When alt text is not set