]> git.openstreetmap.org Git - rails.git/commitdiff
Write browse element icons as <img>
authorAnton Khorev <tony29@yandex.ru>
Mon, 25 Nov 2024 03:33:37 +0000 (06:33 +0300)
committerAnton Khorev <tony29@yandex.ru>
Mon, 9 Dec 2024 10:22:34 +0000 (13:22 +0300)
12 files changed:
app/assets/stylesheets/browse.scss [deleted file]
app/assets/stylesheets/common.scss
app/helpers/browse_helper.rb
app/views/browse/_containing_relation.html.erb
app/views/browse/_node.html.erb
app/views/browse/_relation.html.erb
app/views/browse/_relation_member.html.erb
app/views/browse/_way.html.erb
app/views/changesets/_elements.html.erb
config/browse_icons.yml [new file with mode: 0644]
config/initializers/browse_icons.rb [new file with mode: 0644]
test/helpers/browse_helper_test.rb

diff --git a/app/assets/stylesheets/browse.scss b/app/assets/stylesheets/browse.scss
deleted file mode 100644 (file)
index 2dac602..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-$map-sidebar-icons: (
-
-  /* Nodes (and ways as areas) */
-
-  ".aeroway.aerodrome": ("filename": "aerodrome.p.16.png"),
-  
-  ".amenity.atm": ("filename": "amenity_atm.16.png", "invert": true),
-  ".amenity.bank": ("filename": "amenity_bank.16.png", "invert": true),
-  ".amenity.bar": ("filename": "amenity_bar.16.png", "invert": true),
-  ".amenity.bench": ("filename": "amenity_bench.16.png", "invert": true),
-  ".amenity.biergarten": ("filename": "amenity_biergarten.16.png", "invert": true),
-  ".amenity.bicycle_parking": ("filename": "amenity_bicycle_parking.16.png"),
-  ".amenity.bicycle_rental": ("filename": "transport_rental_bicycle.16.png"),
-  ".amenity.bus_station": ("filename": "bus_station.n.16.png"),
-  ".amenity.cafe": ("filename": "amenity_cafe.16.png", "invert": true),
-  ".amenity.car_rental": ("filename": "transport_rental_car.16.png"),
-  ".amenity.car_sharing": ("filename": "car_share.p.16.png"),
-  ".amenity.childcare": ("filename": "amenity_childcare.p.16.png"),
-  ".amenity.cinema": ("filename": "amenity_cinema.16.png", "invert": true),
-  ".amenity.courthouse": ("filename": "amenity_courthouse.16.png", "invert": true),
-  ".amenity.dentist": ("filename": "amenity_dentist.16.png"),
-  ".amenity.doctors": ("filename": "amenity_doctors.16.png"),
-  ".amenity.drinking_water": ("filename": "amenity_drinking_water.16.png", "invert": true),
-  ".amenity.fast_food": ("filename": "amenity_fast_food.16.png", "invert": true),
-  ".amenity.fire_station": ("filename": "amenity_fire_station.16.png", "invert": true),
-  ".amenity.fuel": ("filename": "amenity_fuel.16.png"),
-  ".amenity.hospital": ("filename": "amenity_hospital.16.png"),
-  ".amenity.kindergarten": ("filename": "amenity_childcare.p.16.png"),
-  ".amenity.library": ("filename": "library.p.16.png", "invert": true),
-  ".amenity.nightclub": ("filename": "amenity_nightclub.16.png", "invert": true),
-  ".amenity.parking": ("filename": "parking.p.16.png"),
-  ".amenity.pharmacy": ("filename": "amenity_pharmacy.16.png"),
-  ".amenity.place_of_worship": ("filename": "amenity_place_of_worship.16.png", "invert": true),
-  ".amenity.police": ("filename": "amenity_police.16.png", "invert": true),
-  ".amenity.post_box": ("filename": "post_box.p.16.png", "invert": true),
-  ".amenity.post_office": ("filename": "post_office.p.16.png", "invert": true),
-  ".amenity.prison": ("filename": "amenity_prison.16.png", "invert": true),
-  ".amenity.pub": ("filename": "amenity_pub.16.png", "invert": true),
-  ".amenity.restaurant": ("filename": "amenity_restaurant.16.png", "invert": true),
-  ".amenity.recycling": ("filename": "amenity_recycling.16.png", "invert": true),
-  ".amenity.school": ("filename": "education_school.p.16.png"),
-  ".amenity.shelter": ("filename": "shelter2.p.16.png"),
-  ".amenity.taxi": ("filename": "amenity_taxi.16.png"),
-  ".amenity.telephone": ("filename": "telephone.p.16.png", "invert": true),
-  ".amenity.theatre": ("filename": "amenity_theatre.16.png", "invert": true),
-  ".amenity.toilets": ("filename": "amenity_toilets.16.png", "invert": true),
-  ".amenity.townhall": ("filename": "amenity_townhall.16.png", "invert": true),
-  ".amenity.university": ("filename": "education_university.p.16.png"),
-  ".amenity.veterinary": ("filename": "health_veterinary.p.16.png"),
-  ".amenity.waste_basket": ("filename": "amenity_waste_basket.16.png", "invert": true),
-
-  ".barrier.gate": ("filename": "gate2.p.16.png", "invert": true),
-
-  ".highway.bus_stop": ("filename": "highway_bus_stop.16.png"),
-  ".highway.mini_roundabout": ("filename": "mini_round.p.16.png"),
-  ".highway.traffic_signals": ("filename": "traffic_light.png", "invert": true),
-  ".highway.turning_circle": ("filename": "turning_circle.p.16.png"),
-
-  ".historic.archaeological_site": ("filename": "historic_archaeological_site.16.png", "invert": true),
-  ".historic.castle": ("filename": "tourist_castle.p.16.png", "invert": true),
-  ".historic.memorial": ("filename": "historic_memorial.16.png", "invert": true),
-  ".historic.monument": ("filename": "historic_monument.16.png", "invert": true),
-  ".historic.ruins": ("filename": "tourist_ruins.p.16.png", "invert": true),
-  ".historic.wreck": ("filename": "tourist_wreck.p.16.png", "invert": true),
-
-  ".man_made.lighthouse": ("filename": "man_made_lighthouse.16.png"),
-  ".man_made.water_tower": ("filename": "man_made_water_tower.16.png", "invert": true),
-  ".man_made.windmill": ("filename": "man_made_windmill.16.png", "invert": true),
-
-  ".natural.tree": ("filename": "tree.p.16.png"),
-
-  ".office.diplomatic": ("filename": "office_diplomatic.16.png"),
-  ".office.estate_agent": ("filename": "shop_estateagent.16.png"),
-
-  ".railway.halt": ("filename": "halt.p.16.png"),
-  ".railway.station": ("filename": "station.p.16.png"),
-  ".railway.level_crossing": ("filename": "level_crossing.p.16.png", "invert": true),
-
-  ".shop": ("filename": "shop_convenience.p.16.png"),
-  ".shop.alcohol": ("filename": "shop_alcohol.16.png"),
-  ".shop.bakery": ("filename": "shop_bakery.16.png"),
-  ".shop.bicycle": ("filename": "shop_bicycle.16.png"),
-  ".shop.books": ("filename": "shop_books.16.png"),
-  ".shop.butcher": ("filename": "shop_butcher.p.16.png"),
-  ".shop.clothes": ("filename": "shop_clothes.16.png"),
-  ".shop.car_parts": ("filename": "shop_car_parts.16.png"),
-  ".shop.car_repair": ("filename": "shop_car_repair.16.png"),
-  ".shop.convenience": ("filename": "shop_convenience.p.16.png"),
-  ".shop.doityourself": ("filename": "shop_doityourself.16.png"),
-  ".shop.electronics": ("filename": "shop_electronics.16.png"),
-  ".shop.estate_agent": ("filename": "shop_estateagent.16.png"),
-  ".shop.fashion": ("filename": "shop_clothes.16.png"),
-  ".shop.florist": ("filename": "shop_florist.16.png"),
-  ".shop.furniture": ("filename": "shop_furniture.16.png"),
-  ".shop.garden_centre": ("filename": "shop_florist.16.png"),
-  ".shop.gift": ("filename": "shop_gift.16.png"),
-  ".shop.greengrocer": ("filename": "shop_greengrocer.p.16.png"),
-  ".shop.hardware": ("filename": "shop_doityourself.16.png"),
-  ".shop.hairdresser": ("filename": "shop_hairdresser.16.png"),
-  ".shop.jewelry": ("filename": "shop_jewelry.16.png"),
-  ".shop.mobile_phone": ("filename": "shop_mobile_phone.16.png"),
-  ".shop.optician": ("filename": "shop_optician.16.png"),
-  ".shop.pet": ("filename": "shop_pet.16.png"),
-  ".shop.seafood": ("filename": "shop_seafood.16.png"),
-  ".shop.shoes": ("filename": "shop_shoes.16.png"),
-  ".shop.supermarket": ("filename": "shop_supermarket.p.16.png"),
-
-  ".tourism.alpine_hut": ("filename": "tourism_alpine_hut.16.png"),
-  ".tourism.camp_site": ("filename": "tourism_camp_site.16.png"),
-  ".tourism.caravan_site": ("filename": "tourism_caravan_site.16.png"),
-  ".tourism.hostel": ("filename": "tourism_hostel.16.png"),
-  ".tourism.hotel": ("filename": "tourism_hotel.16.png"),
-  ".tourism.motel": ("filename": "tourism_motel.16.png"),
-  ".tourism.museum": ("filename": "tourism_museum.16.png", "invert": true),
-  ".tourism.picnic_site": ("filename": "tourism_picnic_site.16.png", "invert": true),
-  ".tourism.viewpoint": ("filename": "view_point.p.16.png", "invert": true),
-  ".tourism.wilderness_hut": ("filename": "tourism_wilderness_hut.16.png"),
-
-  /* Ways */
-
-  ".aeroway.runway": ("filename": "runway.20.png"),
-  ".aeroway.taxiway": ("filename": "taxiway.20.png"),
-
-  ".barrier.wall": ("filename": "wall.20.png"),
-
-  ".building": ("filename": "building.png"),
-
-  ".highway.bridleway": ("filename": "bridleway.20.png"),
-  ".highway.cycleway": ("filename": "cycleway.20.png"),
-  ".highway.footway": ("filename": "footway.20.png"),
-  ".highway.motorway": ("filename": "motorway.20.png"),
-  ".highway.motorway_link": ("filename": "motorway.20.png"),
-  ".highway.path": ("filename": "path.20.png"),
-  ".highway.pedestrian": ("filename": "service.20.png"),
-  ".highway.primary": ("filename": "primary.20.png"),
-  ".highway.primary_link": ("filename": "primary.20.png"),
-  ".highway.residential": ("filename": "unclassified.20.png"),
-  ".highway.secondary": ("filename": "secondary.20.png"),
-  ".highway.secondary_link": ("filename": "secondary.20.png"),
-  ".highway.service": ("filename": "service.20.png"),
-  ".highway.tertiary": ("filename": "tertiary.20.png"),
-  ".highway.track": ("filename": "track.20.png"),
-  ".highway.trunk": ("filename": "trunk.20.png"),
-  ".highway.trunk_link": ("filename": "trunk.20.png"),
-  ".highway.unclassified": ("filename": "unclassified.20.png"),
-
-  ".landuse.brownfield": ("filename": "brownfield.png"),
-  ".landuse.cemetery": ("filename": "cemetery.png"),
-  ".landuse.commercial": ("filename": "commercial.png"),
-  ".landuse.farmland": ("filename": "farmland.png"),
-  ".landuse.farmyard": ("filename": "farmyard.png"),
-  ".landuse.forest": ("filename": "forest.png"),
-  ".landuse.grass": ("filename": "grass.png"),
-  ".landuse.industrial": ("filename": "industrial.png"),
-  ".landuse.meadow": ("filename": "meadow.png"),
-  ".landuse.military": ("filename": "military.png"),
-  ".landuse.residential": ("filename": "residential.png"),
-  ".landuse.retail": ("filename": "retail.png"),
-  ".landuse.tourism": ("filename": "tourism.png"),
-
-  ".leisure.golf_course": ("filename": "golf.png"),
-  ".leisure.park": ("filename": "park.png"),
-  ".leisure.picnic_table": ("filename": "tourism_picnic_site.16.png", "invert": true),
-  ".leisure.playground": ("filename": "leisure_playground.16.png", "invert": true),
-  ".leisure.pitch": ("filename": "pitch.png"),
-  ".leisure.nature_reserve": ("filename": "reserve.png"),
-  ".leisure.water_park": ("filename": "leisure_water_park.16.png", "invert": true),
-
-  ".natural.grassland": ("filename": "grassland.png"),
-  ".natural.heath": ("filename": "heathland.png"),
-  ".natural.scrub": ("filename": "scrub.png"),
-  ".natural.water": ("filename": "lake.png"),
-  ".natural.wood": ("filename": "wood.png"),
-
-  ".railway.light_rail": ("filename": "light_rail.20.png"),
-  ".railway.rail": ("filename": "rail.20.png"),
-  ".railway.subway": ("filename": "subway.20.png"),
-  ".railway.tram": ("filename": "tram.20.png"),
-
-)
index 668d050d8bbbc42da49826961dc97fcd2fd03563..34dca89937aebaa4edc349ffeb1f55a394cc0840 100644 (file)
@@ -1,6 +1,5 @@
 @use "sass:map";
 @import "parameters";
 @use "sass:map";
 @import "parameters";
-@import "browse";
 @import "bootstrap";
 @import "rails_bootstrap_forms";
 
 @import "bootstrap";
 @import "rails_bootstrap_forms";
 
@@ -970,34 +969,12 @@ img.trace_image {
 
 /* Rules for map sidebar icons */
 
 
 /* Rules for map sidebar icons */
 
-.browse-section {
-  .node::before,
-  .way::before,
-  .relation::before {
-    display: inline-block;
-    width: 25px;
-    margin-left: -25px;
-  }
+.browse-section .browse-element-list {
+  line-height: 20px;
 
 
-  .node, .way, .relation {
-    margin-left: 25px;
-  }
-
-  .node::before     { content: image-url('browse/node.svg'); }
-  .way::before      { content: image-url('browse/way.svg'); }
-  .relation::before { content: image-url('browse/relation.svg'); }
-}
-
-@each $class, $item in $map-sidebar-icons {
-  .browse-section #{$class}::before {
-    content: image-url('browse/#{map.get($item, "filename")}');
-  }
-
-  @if map.get($item, "invert") {
-    @include color-mode(dark) {
-      .browse-section #{$class}::before {
-        filter: invert(.8) hue-rotate(180deg);
-      }
+  @include color-mode(dark) {
+    .browse-icon-invertible {
+      filter: invert(.8) hue-rotate(180deg);
     }
   }
 }
     }
   }
 }
index 69a8f8fa2e57eb5b76a717f98506c5f4752c33da..5cc12bb007d6dd2c5a7ceace2b9b04490c1392b6 100644 (file)
@@ -1,15 +1,38 @@
 module BrowseHelper
 module BrowseHelper
+  def element_icon(type, object)
+    selected_icon_data = { :filename => "#{type}.svg" }
+
+    unless object.redacted?
+      target_tags = object.tags.find_all { |k, _v| BROWSE_ICONS.key? k }.sort
+      title = target_tags.map { |k, v| "#{k}=#{v}" }.to_sentence unless target_tags.empty?
+
+      target_tags.each do |k, v|
+        icon_data = BROWSE_ICONS[k][v] || BROWSE_ICONS[k][:*]
+        selected_icon_data = icon_data if icon_data
+      end
+    end
+
+    image_tag "browse/#{selected_icon_data[:filename]}",
+              :size => 20,
+              :class => ["align-bottom object-fit-none", { "browse-icon-invertible" => selected_icon_data[:invert] }],
+              :title => title
+  end
+
   def element_single_current_link(type, object)
   def element_single_current_link(type, object)
-    link_to object, { :class => element_class(type, object), :title => element_title(object), :rel => (link_follow(object) if type == "node") } do
+    link_to object, { :rel => (link_follow(object) if type == "node") } do
       element_strikethrough object do
         printable_element_name object
       end
     end
   end
 
       element_strikethrough object do
         printable_element_name object
       end
     end
   end
 
-  def element_list_item(type, object, &block)
-    tag.li :class => element_class(type, object), :title => element_title(object) do
-      element_strikethrough object, &block
+  def element_list_item(type, object, &)
+    tag.li(tag.div(element_icon(type, object) + tag.div(&), :class => "d-flex gap-1"))
+  end
+
+  def element_list_item_with_strikethrough(type, object, &)
+    element_list_item type, object do
+      element_strikethrough object, &
     end
   end
 
     end
   end
 
@@ -52,20 +75,6 @@ module BrowseHelper
     end
   end
 
     end
   end
 
-  def element_class(type, object)
-    classes = [type]
-    classes += icon_tags(object).flatten.map { |t| h(t) } unless object.redacted?
-    classes.join(" ")
-  end
-
-  def element_title(object)
-    if object.redacted?
-      ""
-    else
-      h(icon_tags(object).map { |k, v| "#{k}=#{v}" }.to_sentence)
-    end
-  end
-
   def link_follow(object)
     "nofollow" if object.tags.empty?
   end
   def link_follow(object)
     "nofollow" if object.tags.empty?
   end
@@ -107,12 +116,6 @@ module BrowseHelper
 
   private
 
 
   private
 
-  ICON_TAGS = %w[aeroway amenity barrier building highway historic landuse leisure man_made natural office railway shop tourism waterway].freeze
-
-  def icon_tags(object)
-    object.tags.find_all { |k, _v| ICON_TAGS.include? k }.sort
-  end
-
   def name_locales(object)
     object.tags.keys.map { |k| Regexp.last_match(1) if k =~ /^name:(.*)$/ }.flatten
   end
   def name_locales(object)
     object.tags.keys.map { |k| Regexp.last_match(1) if k =~ /^name:(.*)$/ }.flatten
   end
index 2ab0fcf9785d6bd445cabdbdcbbc0eef77af011d..2c107236497a8a7f445d10051fbd53e4f1865ee9 100644 (file)
@@ -1,7 +1,8 @@
-<li><%= linked_name = link_to printable_element_name(containing_relation.relation), containing_relation.relation, :class => "relation"
-        if containing_relation.member_role.blank?
-          linked_name
-        else
-          t ".entry_role_html", :relation_name => linked_name, :relation_role => containing_relation.member_role
-        end %>
-</li>
+<%= element_list_item "relation", containing_relation.relation do %>
+  <%= linked_name = link_to printable_element_name(containing_relation.relation), containing_relation.relation
+      if containing_relation.member_role.blank?
+        linked_name
+      else
+        t ".entry_role_html", :relation_name => linked_name, :relation_role => containing_relation.member_role
+      end %>
+<% end %>
index 0ffe7c68b82dd01c9cbafe2ca6966295d4b8532a..52939d3a1c5587272d64ba7e42b06c96853a6be4 100644 (file)
       <% unless node.ways.empty? %>
         <details <%= "open" if node.ways.count < 10 %>>
           <summary><%= t "browse.part_of_ways", :count => node.ways.uniq.count %></summary>
       <% unless node.ways.empty? %>
         <details <%= "open" if node.ways.count < 10 %>>
           <summary><%= t "browse.part_of_ways", :count => node.ways.uniq.count %></summary>
-          <ul class="list-unstyled">
+          <ul class="list-unstyled browse-element-list">
             <% node.ways.uniq.each do |way| %>
             <% node.ways.uniq.each do |way| %>
-              <li><%= element_single_current_link "way", way %></li>
+              <%= element_list_item "way", way do %>
+                <%= element_single_current_link "way", way %>
+              <% end %>
             <% end %>
           </ul>
         </details>
             <% end %>
           </ul>
         </details>
@@ -25,7 +27,7 @@
       <% unless node.containing_relation_members.empty? %>
         <details <%= "open" if node.containing_relation_members.count < 10 %>>
           <summary><%= t "browse.part_of_relations", :count => node.containing_relation_members.uniq.count %></summary>
       <% unless node.containing_relation_members.empty? %>
         <details <%= "open" if node.containing_relation_members.count < 10 %>>
           <summary><%= t "browse.part_of_relations", :count => node.containing_relation_members.uniq.count %></summary>
-          <ul class="list-unstyled">
+          <ul class="list-unstyled browse-element-list">
             <%= render :partial => "browse/containing_relation", :collection => node.containing_relation_members.uniq %>
           </ul>
         </details>
             <%= render :partial => "browse/containing_relation", :collection => node.containing_relation_members.uniq %>
           </ul>
         </details>
index 5dcdffa47f6cc683d657fa8ad215adf546234c7f..44706790044d6153452ad91d4b41661e15c26a56 100644 (file)
@@ -14,7 +14,7 @@
       <h4><%= t "browse.part_of" %></h4>
       <details <%= "open" if relation.containing_relation_members.count < 10 %>>
         <summary><%= t "browse.part_of_relations", :count => relation.containing_relation_members.uniq.count %></summary>
       <h4><%= t "browse.part_of" %></h4>
       <details <%= "open" if relation.containing_relation_members.count < 10 %>>
         <summary><%= t "browse.part_of_relations", :count => relation.containing_relation_members.uniq.count %></summary>
-        <ul class="list-unstyled">
+        <ul class="list-unstyled browse-element-list">
           <%= render :partial => "browse/containing_relation", :collection => relation.containing_relation_members.uniq %>
         </ul>
       </details>
           <%= render :partial => "browse/containing_relation", :collection => relation.containing_relation_members.uniq %>
         </ul>
       </details>
@@ -24,7 +24,7 @@
       <h4><%= t ".members" %></h4>
       <details <%= "open" if relation.relation_members.count < 10 %>>
         <summary><%= t ".members_count", :count => relation.relation_members.count %></summary>
       <h4><%= t ".members" %></h4>
       <details <%= "open" if relation.relation_members.count < 10 %>>
         <summary><%= t ".members_count", :count => relation.relation_members.count %></summary>
-        <ul class="list-unstyled">
+        <ul class="list-unstyled browse-element-list">
           <%= render :partial => "browse/relation_member", :collection => relation.relation_members %>
         </ul>
       </details>
           <%= render :partial => "browse/relation_member", :collection => relation.relation_members %>
         </ul>
       </details>
index d122f0edfed8f327f2c81893a317cbfb588073d8..c00396fbd84388c31abc8f6c3374d3a7394e16de 100644 (file)
@@ -1,6 +1,6 @@
 <% linked_name = link_to printable_element_name(relation_member.member), relation_member.member, { :rel => link_follow(relation_member.member) }
    type_str = t ".type.#{relation_member.member_type.downcase}" %>
 <% linked_name = link_to printable_element_name(relation_member.member), relation_member.member, { :rel => link_follow(relation_member.member) }
    type_str = t ".type.#{relation_member.member_type.downcase}" %>
-<%= element_list_item relation_member.member_type.downcase, relation_member.member do %>
+<%= element_list_item_with_strikethrough relation_member.member_type.downcase, relation_member.member do %>
   <%= if relation_member.member_role.blank?
         t ".entry_html", :type => type_str, :name => linked_name
       else
   <%= if relation_member.member_role.blank?
         t ".entry_html", :type => type_str, :name => linked_name
       else
index d04eff14030183432704277a9e07802b378c2083..9181a3e0804d7f5e5e198bfba4c27fca7b30bdf4 100644 (file)
@@ -14,7 +14,7 @@
       <h4><%= t "browse.part_of" %></h4>
       <details <%= "open" if way.containing_relation_members.count < 10 %>>
         <summary><%= t "browse.part_of_relations", :count => way.containing_relation_members.uniq.count %></summary>
       <h4><%= t "browse.part_of" %></h4>
       <details <%= "open" if way.containing_relation_members.count < 10 %>>
         <summary><%= t "browse.part_of_relations", :count => way.containing_relation_members.uniq.count %></summary>
-        <ul class="list-unstyled">
+        <ul class="list-unstyled browse-element-list">
           <%= render :partial => "browse/containing_relation", :collection => way.containing_relation_members.uniq %>
         </ul>
       </details>
           <%= render :partial => "browse/containing_relation", :collection => way.containing_relation_members.uniq %>
         </ul>
       </details>
       <h4><%= t ".nodes" %></h4>
       <details <%= "open" if way.way_nodes.count < 10 %>>
         <summary><%= t ".nodes_count", :count => way.way_nodes.count %></summary>
       <h4><%= t ".nodes" %></h4>
       <details <%= "open" if way.way_nodes.count < 10 %>>
         <summary><%= t ".nodes_count", :count => way.way_nodes.count %></summary>
-        <ul class="list-unstyled">
+        <ul class="list-unstyled browse-element-list">
           <% way.way_nodes.each do |wn| %>
           <% way.way_nodes.each do |wn| %>
-            <li>
+            <%= element_list_item "node", wn.node do %>
               <%= element_single_current_link "node", wn.node %>
               <% related_ways = wn.node.ways.reject { |w| w.id == wn.way_id } %>
               <%= element_single_current_link "node", wn.node %>
               <% related_ways = wn.node.ways.reject { |w| w.id == wn.way_id } %>
+              <% icon_connector = " " %>
               <% if related_ways.size > 0 then %>
                 (<%= t ".also_part_of_html",
                        :count => related_ways.size,
               <% if related_ways.size > 0 then %>
                 (<%= t ".also_part_of_html",
                        :count => related_ways.size,
-                       :related_ways => to_sentence(related_ways.map { |w| element_single_current_link "way", w }) %>)
+                       :related_ways => to_sentence(related_ways.map { |w| element_icon("way", w) + icon_connector + element_single_current_link("way", w) }) %>)
               <% end %>
               <% end %>
-            </li>
+            <% end %>
           <% end %>
         </ul>
       </details>
           <% end %>
         </ul>
       </details>
index fd5dd8a26a3cd16ca6aeb5fd9a9b0f47b58fdbcc..a95bed6fa3ab5d73bd55da685cbab8d5c7b9897a 100644 (file)
@@ -1,12 +1,12 @@
 <%= turbo_frame_tag "changeset_#{type.pluralize}" do %>
   <%= render :partial => "paging_nav", :locals => { :type => type, :pages => pages } %>
 <%= turbo_frame_tag "changeset_#{type.pluralize}" do %>
   <%= render :partial => "paging_nav", :locals => { :type => type, :pages => pages } %>
-  <ul class="list-unstyled" data-turbo="false">
+  <ul class="list-unstyled browse-element-list" data-turbo="false">
     <% elements.each do |element| %>
     <% elements.each do |element| %>
-      <%= element_list_item type, element do
-            t "printable_name.current_and_old_links_html",
+      <%= element_list_item_with_strikethrough type, element do %>
+        <%= t "printable_name.current_and_old_links_html",
               :current_link => link_to(printable_element_name(element), :controller => type.pluralize, :action => :show, :id => element.id[0]),
               :current_link => link_to(printable_element_name(element), :controller => type.pluralize, :action => :show, :id => element.id[0]),
-              :old_link => link_to(printable_element_version(element), :controller => "old_#{type.pluralize}", :action => :show, :id => element.id[0], :version => element.version)
-          end %>
+              :old_link => link_to(printable_element_version(element), :controller => "old_#{type.pluralize}", :action => :show, :id => element.id[0], :version => element.version) %>
+      <% end %>
     <% end %>
   </ul>
 <% end %>
     <% end %>
   </ul>
 <% end %>
diff --git a/config/browse_icons.yml b/config/browse_icons.yml
new file mode 100644 (file)
index 0000000..d59c236
--- /dev/null
@@ -0,0 +1,186 @@
+aeroway:
+  aerodrome: { filename: "aerodrome.p.16.png" }
+
+  runway: { filename: "runway.20.png" }
+  taxiway: { filename: "taxiway.20.png" }
+
+amenity:
+  atm: { filename: "amenity_atm.16.png", invert: true }
+  bank: { filename: "amenity_bank.16.png", invert: true }
+  bar: { filename: "amenity_bar.16.png", invert: true }
+  bench: { filename: "amenity_bench.16.png", invert: true }
+  biergarten: { filename: "amenity_biergarten.16.png", invert: true }
+  bicycle_parking: { filename: "amenity_bicycle_parking.16.png" }
+  bicycle_rental: { filename: "transport_rental_bicycle.16.png" }
+  bus_station: { filename: "bus_station.n.16.png" }
+  cafe: { filename: "amenity_cafe.16.png", invert: true }
+  car_rental: { filename: "transport_rental_car.16.png" }
+  car_sharing: { filename: "car_share.p.16.png" }
+  childcare: { filename: "amenity_childcare.p.16.png" }
+  cinema: { filename: "amenity_cinema.16.png", invert: true }
+  courthouse: { filename: "amenity_courthouse.16.png", invert: true }
+  dentist: { filename: "amenity_dentist.16.png" }
+  doctors: { filename: "amenity_doctors.16.png" }
+  drinking_water: { filename: "amenity_drinking_water.16.png", invert: true }
+  fast_food: { filename: "amenity_fast_food.16.png", invert: true }
+  fire_station: { filename: "amenity_fire_station.16.png", invert: true }
+  fuel: { filename: "amenity_fuel.16.png" }
+  hospital: { filename: "amenity_hospital.16.png" }
+  kindergarten: { filename: "amenity_childcare.p.16.png" }
+  library: { filename: "library.p.16.png", invert: true }
+  nightclub: { filename: "amenity_nightclub.16.png", invert: true }
+  parking: { filename: "parking.p.16.png" }
+  pharmacy: { filename: "amenity_pharmacy.16.png" }
+  place_of_worship: { filename: "amenity_place_of_worship.16.png", invert: true }
+  police: { filename: "amenity_police.16.png", invert: true }
+  post_box: { filename: "post_box.p.16.png", invert: true }
+  post_office: { filename: "post_office.p.16.png", invert: true }
+  prison: { filename: "amenity_prison.16.png", invert: true }
+  pub: { filename: "amenity_pub.16.png", invert: true }
+  restaurant: { filename: "amenity_restaurant.16.png", invert: true }
+  recycling: { filename: "amenity_recycling.16.png", invert: true }
+  school: { filename: "education_school.p.16.png" }
+  shelter: { filename: "shelter2.p.16.png" }
+  taxi: { filename: "amenity_taxi.16.png" }
+  telephone: { filename: "telephone.p.16.png", invert: true }
+  theatre: { filename: "amenity_theatre.16.png", invert: true }
+  toilets: { filename: "amenity_toilets.16.png", invert: true }
+  townhall: { filename: "amenity_townhall.16.png", invert: true }
+  university: { filename: "education_university.p.16.png" }
+  veterinary: { filename: "health_veterinary.p.16.png" }
+  waste_basket: { filename: "amenity_waste_basket.16.png", invert: true }
+
+barrier:
+  gate: { filename: "gate2.p.16.png", invert: true }
+
+  wall: { filename: "wall.20.png" }
+
+building:
+  :*: { filename: "building.png" }
+
+highway:
+  bus_stop: { filename: "highway_bus_stop.16.png" }
+  mini_roundabout: { filename: "mini_round.p.16.png" }
+  traffic_signals: { filename: "traffic_light.png", invert: true }
+  turning_circle: { filename: "turning_circle.p.16.png" }
+
+  bridleway: { filename: "bridleway.20.png" }
+  cycleway: { filename: "cycleway.20.png" }
+  footway: { filename: "footway.20.png" }
+  motorway: { filename: "motorway.20.png" }
+  motorway_link: { filename: "motorway.20.png" }
+  path: { filename: "path.20.png" }
+  pedestrian: { filename: "service.20.png" }
+  primary: { filename: "primary.20.png" }
+  primary_link: { filename: "primary.20.png" }
+  residential: { filename: "unclassified.20.png" }
+  secondary: { filename: "secondary.20.png" }
+  secondary_link: { filename: "secondary.20.png" }
+  service: { filename: "service.20.png" }
+  tertiary: { filename: "tertiary.20.png" }
+  track: { filename: "track.20.png" }
+  trunk: { filename: "trunk.20.png" }
+  trunk_link: { filename: "trunk.20.png" }
+  unclassified: { filename: "unclassified.20.png" }
+
+historic:
+  archaeological_site: { filename: "historic_archaeological_site.16.png", invert: true }
+  castle: { filename: "tourist_castle.p.16.png", invert: true }
+  memorial: { filename: "historic_memorial.16.png", invert: true }
+  monument: { filename: "historic_monument.16.png", invert: true }
+  ruins: { filename: "tourist_ruins.p.16.png", invert: true }
+  wreck: { filename: "tourist_wreck.p.16.png", invert: true }
+
+landuse:
+  brownfield: { filename: "brownfield.png" }
+  cemetery: { filename: "cemetery.png" }
+  commercial: { filename: "commercial.png" }
+  farmland: { filename: "farmland.png" }
+  farmyard: { filename: "farmyard.png" }
+  forest: { filename: "forest.png" }
+  grass: { filename: "grass.png" }
+  industrial: { filename: "industrial.png" }
+  meadow: { filename: "meadow.png" }
+  military: { filename: "military.png" }
+  residential: { filename: "residential.png" }
+  retail: { filename: "retail.png" }
+  tourism: { filename: "tourism.png" }
+
+leisure:
+  golf_course: { filename: "golf.png" }
+  park: { filename: "park.png" }
+  picnic_table: { filename: "tourism_picnic_site.16.png", invert: true }
+  playground: { filename: "leisure_playground.16.png", invert: true }
+  pitch: { filename: "pitch.png" }
+  nature_reserve: { filename: "reserve.png" }
+  water_park: { filename: "leisure_water_park.16.png", invert: true }
+
+man_made:
+  lighthouse: { filename: "man_made_lighthouse.16.png" }
+  water_tower: { filename: "man_made_water_tower.16.png", invert: true }
+  windmill: { filename: "man_made_windmill.16.png", invert: true }
+
+natural:
+  tree: { filename: "tree.p.16.png" }
+
+  grassland: { filename: "grassland.png" }
+  heath: { filename: "heathland.png" }
+  scrub: { filename: "scrub.png" }
+  water: { filename: "lake.png" }
+  wood: { filename: "wood.png" }
+
+office:
+  diplomatic: { filename: "office_diplomatic.16.png" }
+  estate_agent: { filename: "shop_estateagent.16.png" }
+
+railway:
+  halt: { filename: "halt.p.16.png" }
+  station: { filename: "station.p.16.png" }
+  level_crossing: { filename: "level_crossing.p.16.png", invert: true }
+
+  light_rail: { filename: "light_rail.20.png" }
+  rail: { filename: "rail.20.png" }
+  subway: { filename: "subway.20.png" }
+  tram: { filename: "tram.20.png" }
+
+shop:
+  :*: { filename: "shop_convenience.p.16.png" }
+  alcohol: { filename: "shop_alcohol.16.png" }
+  bakery: { filename: "shop_bakery.16.png" }
+  bicycle: { filename: "shop_bicycle.16.png" }
+  books: { filename: "shop_books.16.png" }
+  butcher: { filename: "shop_butcher.p.16.png" }
+  clothes: { filename: "shop_clothes.16.png" }
+  car_parts: { filename: "shop_car_parts.16.png" }
+  car_repair: { filename: "shop_car_repair.16.png" }
+  convenience: { filename: "shop_convenience.p.16.png" }
+  doityourself: { filename: "shop_doityourself.16.png" }
+  electronics: { filename: "shop_electronics.16.png" }
+  estate_agent: { filename: "shop_estateagent.16.png" }
+  fashion: { filename: "shop_clothes.16.png" }
+  florist: { filename: "shop_florist.16.png" }
+  furniture: { filename: "shop_furniture.16.png" }
+  garden_centre: { filename: "shop_florist.16.png" }
+  gift: { filename: "shop_gift.16.png" }
+  greengrocer: { filename: "shop_greengrocer.p.16.png" }
+  hardware: { filename: "shop_doityourself.16.png" }
+  hairdresser: { filename: "shop_hairdresser.16.png" }
+  jewelry: { filename: "shop_jewelry.16.png" }
+  mobile_phone: { filename: "shop_mobile_phone.16.png" }
+  optician: { filename: "shop_optician.16.png" }
+  pet: { filename: "shop_pet.16.png" }
+  seafood: { filename: "shop_seafood.16.png" }
+  shoes: { filename: "shop_shoes.16.png" }
+  supermarket: { filename: "shop_supermarket.p.16.png" }
+
+tourism:
+  alpine_hut: { filename: "tourism_alpine_hut.16.png" }
+  camp_site: { filename: "tourism_camp_site.16.png" }
+  caravan_site: { filename: "tourism_caravan_site.16.png" }
+  hostel: { filename: "tourism_hostel.16.png" }
+  hotel: { filename: "tourism_hotel.16.png" }
+  motel: { filename: "tourism_motel.16.png" }
+  museum: { filename: "tourism_museum.16.png", invert: true }
+  picnic_site: { filename: "tourism_picnic_site.16.png", invert: true }
+  viewpoint: { filename: "view_point.p.16.png", invert: true }
+  wilderness_hut: { filename: "tourism_wilderness_hut.16.png" }
diff --git a/config/initializers/browse_icons.rb b/config/initializers/browse_icons.rb
new file mode 100644 (file)
index 0000000..cb53848
--- /dev/null
@@ -0,0 +1,11 @@
+begin
+  BROWSE_ICONS = YAML.load_file(Rails.root.join("config/browse_icons.yml")).transform_values do |tag_key_data|
+    transformed_tag_key_data = {}
+    tag_key_data.each do |tag_value, tag_value_data|
+      transformed_tag_key_data[tag_value] = tag_value_data.deep_symbolize_keys
+    end
+    transformed_tag_key_data
+  end
+rescue StandardError
+  BROWSE_ICONS = {}.freeze
+end
index 4cf0ab69ad3aab53863c4c2872ffda8a45a03073..4162223d1b88919b8b537f9e114499706f1b09a5 100644 (file)
@@ -66,7 +66,7 @@ class BrowseHelperTest < ActionView::TestCase
     assert_equal "<s>test</s>", deleted_output
   end
 
     assert_equal "<s>test</s>", deleted_output
   end
 
-  def test_element_class
+  def test_element_icon
     node = create(:node, :with_history, :version => 2)
     node_v1 = node.old_nodes.find_by(:version => 1)
     node_v2 = node.old_nodes.find_by(:version => 2)
     node = create(:node, :with_history, :version => 2)
     node_v1 = node.old_nodes.find_by(:version => 1)
     node_v2 = node.old_nodes.find_by(:version => 2)
@@ -76,60 +76,35 @@ class BrowseHelperTest < ActionView::TestCase
     add_old_tags_selection(node_v2)
     add_old_tags_selection(node_v1)
 
     add_old_tags_selection(node_v2)
     add_old_tags_selection(node_v1)
 
-    assert_equal "node", element_class("node", create(:node))
-    assert_equal "node", element_class("node", create(:node, :deleted))
-
-    assert_equal "node building yes shop gift tourism museum", element_class("node", node)
-    assert_equal "node building yes shop gift tourism museum", element_class("node", node_v2)
-    assert_equal "node", element_class("node", node_v1)
-  end
-
-  def test_element_title
-    node = create(:node, :with_history, :version => 2)
-    node_v1 = node.old_nodes.find_by(:version => 1)
-    node_v2 = node.old_nodes.find_by(:version => 2)
-    node_v1.redact!(create(:redaction))
-
-    add_tags_selection(node)
-    add_old_tags_selection(node_v2)
-    add_old_tags_selection(node_v1)
-
-    assert_equal "", element_title(create(:node))
-    assert_equal "", element_title(create(:node, :deleted))
-
-    assert_equal "building=yes, shop=gift, and tourism=museum", element_title(node)
-    assert_equal "building=yes, shop=gift, and tourism=museum", element_title(node_v2)
-    assert_equal "", element_title(node_v1)
-  end
-
-  def test_icon_tags
-    node = create(:node, :with_history, :version => 2)
-    node_v1 = node.old_nodes.find_by(:version => 1)
-    node_v2 = node.old_nodes.find_by(:version => 2)
-    node_v1.redact!(create(:redaction))
+    icon = element_icon("node", create(:node))
+    icon_dom = Rails::Dom::Testing.html_document_fragment.parse(icon)
+    assert_dom icon_dom, "img:root", :count => 1 do
+      assert_dom "> @title", 0
+    end
 
 
-    add_tags_selection(node)
+    icon = element_icon("node", create(:node, :deleted))
+    icon_dom = Rails::Dom::Testing.html_document_fragment.parse(icon)
+    assert_dom icon_dom, "img:root", :count => 1 do
+      assert_dom "> @title", 0
+    end
 
 
-    tags = icon_tags(node)
-    assert_equal 3, tags.count
-    assert_includes tags, %w[building yes]
-    assert_includes tags, %w[tourism museum]
-    assert_includes tags, %w[shop gift]
+    icon = element_icon("node", node)
+    icon_dom = Rails::Dom::Testing.html_document_fragment.parse(icon)
+    assert_dom icon_dom, "img:root", :count => 1 do
+      assert_dom "> @title", "building=yes, shop=gift, and tourism=museum"
+    end
 
 
-    add_old_tags_selection(node_v2)
-    add_old_tags_selection(node_v1)
+    icon = element_icon("node", node_v2)
+    icon_dom = Rails::Dom::Testing.html_document_fragment.parse(icon)
+    assert_dom icon_dom, "img:root", :count => 1 do
+      assert_dom "> @title", "building=yes, shop=gift, and tourism=museum"
+    end
 
 
-    tags = icon_tags(node_v2)
-    assert_equal 3, tags.count
-    assert_includes tags, %w[building yes]
-    assert_includes tags, %w[tourism museum]
-    assert_includes tags, %w[shop gift]
-
-    tags = icon_tags(node_v1)
-    assert_equal 3, tags.count
-    assert_includes tags, %w[building yes]
-    assert_includes tags, %w[tourism museum]
-    assert_includes tags, %w[shop gift]
+    icon = element_icon("node", node_v1)
+    icon_dom = Rails::Dom::Testing.html_document_fragment.parse(icon)
+    assert_dom icon_dom, "img:root", :count => 1 do
+      assert_dom "> @title", 0
+    end
   end
 
   private
   end
 
   private