]> git.openstreetmap.org Git - rails.git/commitdiff
Merge remote-tracking branch 'upstream/pull/5049'
authorTom Hughes <tom@compton.nu>
Tue, 6 Aug 2024 17:30:27 +0000 (18:30 +0100)
committerTom Hughes <tom@compton.nu>
Tue, 6 Aug 2024 17:30:27 +0000 (18:30 +0100)
Gemfile.lock
app/controllers/diary_entries_controller.rb
app/helpers/open_graph_helper.rb
app/views/layouts/_meta.html.erb
lib/rich_text.rb
test/controllers/diary_entries_controller_test.rb
test/lib/rich_text_test.rb

index e8d918ff5e2e01d48c3fa007dcc7a0d39db20a13..00984911cba78e05b9f568389776d9b6d2e2f30c 100644 (file)
@@ -92,10 +92,10 @@ GEM
       ffi (~> 1.15)
       ffi-compiler (~> 1.0)
     ast (2.4.2)
-    autoprefixer-rails (10.4.16.0)
+    autoprefixer-rails (10.4.19.0)
       execjs (~> 2)
     aws-eventstream (1.3.0)
-    aws-partitions (1.959.0)
+    aws-partitions (1.962.0)
     aws-sdk-core (3.201.3)
       aws-eventstream (~> 1, >= 1.3.0)
       aws-partitions (~> 1, >= 1.651.0)
@@ -104,7 +104,7 @@ GEM
     aws-sdk-kms (1.88.0)
       aws-sdk-core (~> 3, >= 3.201.0)
       aws-sigv4 (~> 1.5)
-    aws-sdk-s3 (1.156.0)
+    aws-sdk-s3 (1.157.0)
       aws-sdk-core (~> 3, >= 3.201.0)
       aws-sdk-kms (~> 1)
       aws-sigv4 (~> 1.5)
@@ -125,7 +125,7 @@ GEM
     bigdecimal (3.1.8)
     binding_of_caller (1.0.1)
       debug_inspector (>= 1.2.0)
-    bootsnap (1.18.3)
+    bootsnap (1.18.4)
       msgpack (~> 1.2)
     bootstrap (5.3.3)
       autoprefixer-rails (>= 9.1.0)
@@ -219,12 +219,12 @@ GEM
       dry-initializer (~> 3.0)
       dry-schema (>= 1.12, < 2)
       zeitwerk (~> 2.6)
-    erb_lint (0.5.0)
+    erb_lint (0.6.0)
       activesupport
       better_html (>= 2.0.1)
       parser (>= 2.7.1.4)
       rainbow
-      rubocop
+      rubocop (>= 1)
       smart_properties
     erubi (1.13.0)
     execjs (2.9.1)
@@ -234,7 +234,7 @@ GEM
     factory_bot_rails (6.4.3)
       factory_bot (~> 6.4)
       railties (>= 5.0.0)
-    faraday (2.10.0)
+    faraday (2.10.1)
       faraday-net_http (>= 2.0, < 3.2)
       logger
     faraday-net_http (3.1.1)
@@ -254,7 +254,7 @@ GEM
     globalid (1.2.1)
       activesupport (>= 6.1)
     google-protobuf (3.25.4)
-    hashdiff (1.1.0)
+    hashdiff (1.1.1)
     hashie (5.0.0)
     highline (3.1.0)
       reline
@@ -485,14 +485,14 @@ GEM
       io-console (~> 0.5)
     request_store (1.7.0)
       rack (>= 1.4)
-    rexml (3.3.3)
+    rexml (3.3.4)
       strscan
     rinku (2.0.6)
     rotp (6.3.0)
     rouge (4.3.0)
     rtlcss (0.2.1)
       mini_racer (>= 0.6.3)
-    rubocop (1.65.0)
+    rubocop (1.65.1)
       json (~> 2.3)
       language_server-protocol (>= 3.17.0)
       parallel (~> 1.10)
@@ -503,7 +503,7 @@ GEM
       rubocop-ast (>= 1.31.1, < 2.0)
       ruby-progressbar (~> 1.7)
       unicode-display_width (>= 2.4.0, < 3.0)
-    rubocop-ast (1.31.3)
+    rubocop-ast (1.32.0)
       parser (>= 3.3.1.0)
     rubocop-capybara (2.21.0)
       rubocop (~> 1.41)
@@ -558,7 +558,7 @@ GEM
     sprockets-exporters_pack (0.1.2)
       brotli (>= 0.2.0)
       sprockets (>= 4.0.0.beta3)
-    sprockets-rails (3.5.1)
+    sprockets-rails (3.5.2)
       actionpack (>= 6.1)
       activesupport (>= 6.1)
       sprockets (>= 3.0.0)
index eaf6ddf9c519021e5d9a0809585fb94edf0f85ce..9962c7efd5f019f0f333bc6174931a7f8791276e 100644 (file)
@@ -69,6 +69,7 @@ class DiaryEntriesController < ApplicationController
     if @entry
       @title = t ".title", :user => params[:display_name], :title => @entry.title
       @og_image = @entry.body.image
+      @og_image_alt = @entry.body.image_alt
       @comments = can?(:unhide, DiaryComment) ? @entry.comments : @entry.visible_comments
     else
       @title = t "diary_entries.no_such_entry.title", :id => params[:id]
index a41831ca69d98bc6e287c495ec94653817245b2b..ad24c73b2fb3c2115d3b0a19b4c3809f18cd0638 100644 (file)
@@ -1,15 +1,16 @@
 module OpenGraphHelper
   require "addressable/uri"
 
-  def opengraph_tags(title = nil, og_image = nil)
+  def opengraph_tags(title = nil, og_image = nil, og_image_alt = nil)
     tags = {
       "og:site_name" => t("layouts.project_name.title"),
       "og:title" => title || t("layouts.project_name.title"),
       "og:type" => "website",
-      "og:image" => og_image_url(og_image),
       "og:url" => url_for(:only_path => false),
       "og:description" => t("layouts.intro_text")
-    }
+    }.merge(
+      opengraph_image_properties(og_image, og_image_alt)
+    )
 
     safe_join(tags.map do |property, content|
       tag.meta(:property => property, :content => content)
@@ -18,12 +19,20 @@ module OpenGraphHelper
 
   private
 
-  def og_image_url(og_image)
+  def opengraph_image_properties(og_image, og_image_alt)
     begin
-      return Addressable::URI.join(root_url, og_image).normalize if og_image
+      if og_image
+        properties = {}
+        properties["og:image"] = Addressable::URI.join(root_url, og_image).normalize
+        properties["og:image:alt"] = og_image_alt if og_image_alt
+        return properties
+      end
     rescue Addressable::URI::InvalidURIError
       # return default image
     end
-    image_url("osm_logo_256.png")
+    {
+      "og:image" => image_url("osm_logo_256.png"),
+      "og:image:alt" => t("layouts.logo.alt_text")
+    }
   end
 end
index 37afbb89498e5cc67a2e101a17c4e83d312bc62f..f09449761a4990c9226fb17c4b9cf64e4fc0d533 100644 (file)
@@ -21,7 +21,7 @@
 <% end -%>
 <%= tag.link :rel => "search", :type => "application/opensearchdescription+xml", :title => "OpenStreetMap Search", :href => asset_path("osm.xml") %>
 <%= tag.meta :name => "description", :content => "OpenStreetMap is the free wiki world map." %>
-<%= opengraph_tags(@title, @og_image) %>
+<%= opengraph_tags(@title, @og_image, @og_image_alt) %>
 <% if flash[:matomo_goal] -%>
 <%= tag.meta :name => "matomo-goal", :content => flash[:matomo_goal] %>
 <% end -%>
index edfa535f434c07d23fb88412ad9dd673c38645d5..a439342f7743f9b1fb8682147f6562a9ff0750ab 100644 (file)
@@ -53,6 +53,10 @@ module RichText
       nil
     end
 
+    def image_alt
+      nil
+    end
+
     protected
 
     def simple_format(text)
@@ -92,9 +96,13 @@ module RichText
     end
 
     def image
-      return @image if defined? @image
+      @image_element = first_image_element(document.root) unless defined? @image_element
+      @image_element.attr["src"] if @image_element
+    end
 
-      @image = first_image_element(document.root)&.attr&.[]("src")
+    def image_alt
+      @image_element = first_image_element(document.root) unless defined? @image_element
+      @image_element.attr["alt"] if @image_element
     end
 
     private
index 24475fc80ac4786ca7b9c77ecce7687c4ca01b3b..e3bbb490dfdf3c56a4d566647405379dd7db5571 100644 (file)
@@ -657,6 +657,9 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest
     assert_dom "head meta[property='og:image']" do
       assert_dom "> @content", ActionController::Base.helpers.image_url("osm_logo_256.png", :host => root_url)
     end
+    assert_dom "head meta[property='og:image:alt']" do
+      assert_dom "> @content", "OpenStreetMap logo"
+    end
   end
 
   def test_show_og_image
@@ -668,6 +671,9 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest
     assert_dom "head meta[property='og:image']" do
       assert_dom "> @content", "https://example.com/picture.jpg"
     end
+    assert_dom "head meta[property='og:image:alt']" do
+      assert_dom "> @content", "some picture"
+    end
   end
 
   def test_show_og_image_with_relative_uri
@@ -679,6 +685,9 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest
     assert_dom "head meta[property='og:image']" do
       assert_dom "> @content", "#{root_url}picture.jpg"
     end
+    assert_dom "head meta[property='og:image:alt']" do
+      assert_dom "> @content", "some local picture"
+    end
   end
 
   def test_show_og_image_with_spaces
@@ -690,6 +699,9 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest
     assert_dom "head meta[property='og:image']" do
       assert_dom "> @content", "https://example.com/the%20picture.jpg"
     end
+    assert_dom "head meta[property='og:image:alt']" do
+      assert_dom "> @content", "some picture"
+    end
   end
 
   def test_show_og_image_with_relative_uri_and_spaces
@@ -701,6 +713,9 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest
     assert_dom "head meta[property='og:image']" do
       assert_dom "> @content", "#{root_url}the%20picture.jpg"
     end
+    assert_dom "head meta[property='og:image:alt']" do
+      assert_dom "> @content", "some local picture"
+    end
   end
 
   def test_show_og_image_with_invalid_uri
@@ -712,6 +727,21 @@ class DiaryEntriesControllerTest < ActionDispatch::IntegrationTest
     assert_dom "head meta[property='og:image']" do
       assert_dom "> @content", ActionController::Base.helpers.image_url("osm_logo_256.png", :host => root_url)
     end
+    assert_dom "head meta[property='og:image:alt']" do
+      assert_dom "> @content", "OpenStreetMap logo"
+    end
+  end
+
+  def test_show_og_image_without_alt
+    user = create(:user)
+    diary_entry = create(:diary_entry, :user => user, :body => "<img src='https://example.com/no_alt.gif'>")
+
+    get diary_entry_path(user, diary_entry)
+    assert_response :success
+    assert_dom "head meta[property='og:image']" do
+      assert_dom "> @content", "https://example.com/no_alt.gif"
+    end
+    assert_dom "head meta[property='og:image:alt']", :count => 0
   end
 
   def test_hide
index e601c36fc5d3b1c27a1443985e9110840fded551..e0b31527669d5f1d8583cdfbe65c483d58a6ec58 100644 (file)
@@ -253,61 +253,79 @@ class RichTextTest < ActiveSupport::TestCase
   def test_text_no_image
     r = RichText.new("text", "foo https://example.com/ bar")
     assert_nil r.image
+    assert_nil r.image_alt
   end
 
   def test_html_no_image
     r = RichText.new("html", "foo <a href='https://example.com/'>bar</a> baz")
     assert_nil r.image
+    assert_nil r.image_alt
   end
 
   def test_markdown_no_image
     r = RichText.new("markdown", "foo [bar](https://example.com/) baz")
     assert_nil r.image
+    assert_nil r.image_alt
   end
 
   def test_markdown_image
     r = RichText.new("markdown", "foo ![bar](https://example.com/image.jpg) baz")
     assert_equal "https://example.com/image.jpg", r.image
+    assert_equal "bar", r.image_alt
   end
 
   def test_markdown_first_image
     r = RichText.new("markdown", "foo ![bar1](https://example.com/image1.jpg) baz\nfoo ![bar2](https://example.com/image2.jpg) baz")
     assert_equal "https://example.com/image1.jpg", r.image
+    assert_equal "bar1", r.image_alt
   end
 
   def test_markdown_image_with_empty_src
     r = RichText.new("markdown", "![invalid]()")
     assert_nil r.image
+    assert_nil r.image_alt
   end
 
   def test_markdown_skip_image_with_empty_src
     r = RichText.new("markdown", "![invalid]() ![valid](https://example.com/valid.gif)")
     assert_equal "https://example.com/valid.gif", r.image
+    assert_equal "valid", r.image_alt
   end
 
   def test_markdown_html_image
+    r = RichText.new("markdown", "<img src='https://example.com/img_element.png' alt='alt text here'>")
+    assert_equal "https://example.com/img_element.png", r.image
+    assert_equal "alt text here", r.image_alt
+  end
+
+  def test_markdown_html_image_without_alt
     r = RichText.new("markdown", "<img src='https://example.com/img_element.png'>")
     assert_equal "https://example.com/img_element.png", r.image
+    assert_nil r.image_alt
   end
 
   def test_markdown_html_image_with_empty_src
-    r = RichText.new("markdown", "<img src=''>")
+    r = RichText.new("markdown", "<img src='' alt='forgot src'>")
     assert_nil r.image
+    assert_nil r.image_alt
   end
 
   def test_markdown_skip_html_image_with_empty_src
-    r = RichText.new("markdown", "<img src=''> <img src='https://example.com/next_img_element.png'>")
+    r = RichText.new("markdown", "<img src='' alt='forgot src'> <img src='https://example.com/next_img_element.png' alt='have src'>")
     assert_equal "https://example.com/next_img_element.png", r.image
+    assert_equal "have src", r.image_alt
   end
 
   def test_markdown_html_image_without_src
-    r = RichText.new("markdown", "<img>")
+    r = RichText.new("markdown", "<img alt='totally forgot src'>")
     assert_nil r.image
+    assert_nil r.image_alt
   end
 
   def test_markdown_skip_html_image_without_src
-    r = RichText.new("markdown", "<img> <img src='https://example.com/next_img_element.png'>")
+    r = RichText.new("markdown", "<img alt='totally forgot src'> <img src='https://example.com/next_img_element.png' alt='have src'>")
     assert_equal "https://example.com/next_img_element.png", r.image
+    assert_equal "have src", r.image_alt
   end
 
   private