]> git.openstreetmap.org Git - rails.git/commitdiff
Merge remote-tracking branch 'upstream/pull/4272'
authorTom Hughes <tom@compton.nu>
Sun, 25 Feb 2024 13:40:11 +0000 (13:40 +0000)
committerTom Hughes <tom@compton.nu>
Sun, 25 Feb 2024 13:40:11 +0000 (13:40 +0000)
1  2 
app/assets/stylesheets/common.scss
app/helpers/browse_helper.rb
app/views/browse/changeset.html.erb

index 1f7c45db504ab41f3fdb64efb96055937f5e29ee,a2b723ccb361bb2d83dcd1bb869bd791fe4985fe..35c5ba845f0d0085b135d4efead8af8f71e89fa7
@@@ -2,6 -2,34 +2,6 @@@
  @import "bootstrap";
  @import "rails_bootstrap_forms";
  
 -/* Bootstrap + r2 fixes */
 -
 -:root[dir=rtl] {
 -  .bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow {
 -    /* no-r2 */
 -    right: unset !important;
 -    left: calc(-1 * var(--bs-tooltip-arrow-height)) !important;
 -
 -    &::before {
 -      /* no-r2 */
 -      left: unset !important;
 -      right: -1px !important;
 -    }
 -  }
 -
 -  .bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow {
 -    /* no-r2 */
 -    left: unset !important;
 -    right: calc(-1 * var(--bs-tooltip-arrow-height)) !important;
 -
 -    &::before {
 -      /* no-r2 */
 -      right: unset !important;
 -      left: -1px !important;
 -    }
 -  }
 -}
 -
  /* Styles common to large and small screens */
  
  /* Default rules for the body of every page */
@@@ -37,28 -65,29 +37,28 @@@ time[title] 
    vertical-align: top;
    width: 20px;
    height: 20px;
 -  background: transparent image-url("sprite.png") no-repeat 0 0;
 -  background-image: image-url("sprite.svg");
 +  background: transparent image-url("sprite.svg") no-repeat 0 0;
    text-indent: -9999px;
    overflow: hidden;
  }
  
 -.icon.search      { /* no-r2 */ background-position: 0 0; }
 -.icon.donate      { /* no-r2 */ background-position: -20px 0; }
 -.icon.zoomin      { /* no-r2 */ background-position: -40px 0; }
 -.icon.zoomout     { /* no-r2 */ background-position: -60px 0; }
 -.icon.geolocate   { /* no-r2 */ background-position: -80px 0; }
 -.active .icon.geolocate   { /* no-r2 */ background-position: -80px -20px; }
 -.icon.layers      { /* no-r2 */ background-position: -100px 0; }
 -.icon.key         { /* no-r2 */ background-position: -120px 0; }
 -.icon.share       { /* no-r2 */ background-position: -140px 0; }
 -.icon.clipboard   { /* no-r2 */ background-position: -160px 0; }
 -.icon.link        { /* no-r2 */ background-position: -180px 0; }
 -.icon.close       { /* no-r2 */ background-position: -200px 0; }
 -.icon.close:hover { /* no-r2 */ background-position: -200px -20px; }
 -.icon.check       { /* no-r2 */ background-position: -220px 0; }
 -.icon.note        { /* no-r2 */ background-position: -240px 0; }
 -.icon.note.grey   { /* no-r2 */ background-position: -240px -20px; }
 -.icon.query       { /* no-r2 */ background-position: -260px 0; }
 +.icon.search      { /*rtl:ignore*/ background-position: 0 0; }
 +.icon.donate      { /*rtl:ignore*/ background-position: -20px 0; }
 +.icon.zoomin      { /*rtl:ignore*/ background-position: -40px 0; }
 +.icon.zoomout     { /*rtl:ignore*/ background-position: -60px 0; }
 +.icon.geolocate   { /*rtl:ignore*/ background-position: -80px 0; }
 +.active .icon.geolocate   { /*rtl:ignore*/ background-position: -80px -20px; }
 +.icon.layers      { /*rtl:ignore*/ background-position: -100px 0; }
 +.icon.key         { /*rtl:ignore*/ background-position: -120px 0; }
 +.icon.share       { /*rtl:ignore*/ background-position: -140px 0; }
 +.icon.clipboard   { /*rtl:ignore*/ background-position: -160px 0; }
 +.icon.link        { /*rtl:ignore*/ background-position: -180px 0; }
 +.icon.close       { /*rtl:ignore*/ background-position: -200px 0; }
 +.icon.close:hover { /*rtl:ignore*/ background-position: -200px -20px; }
 +.icon.check       { /*rtl:ignore*/ background-position: -220px 0; }
 +.icon.note        { /*rtl:ignore*/ background-position: -240px 0; }
 +.icon.note.grey   { /*rtl:ignore*/ background-position: -240px -20px; }
 +.icon.query       { /*rtl:ignore*/ background-position: -260px 0; }
  
  /* Utility for de-emphasizing content */
  
    border-color: $grey !important;
  }
  
- .border-lightgrey {
-   border-color: $lightgrey !important;
- }
  /* Rules for the header */
  
  #menu-icon {
    display: none;
 -  float: right;
 +  position: absolute;
 +  top: 0;
 +  right: 0;
    background: image-url("menu-icon.png") no-repeat;
    background-size: 30px 30px;
    width: 30px;
@@@ -106,6 -129,10 +102,6 @@@ header 
      padding: $lineheight * 0.5;
    }
  
 -  h1, nav.primary {
 -    float: left;
 -  }
 -
    img.logo {
      margin-top: -2px;
    }
    .btn {
      font-size: 14px;
    }
 -}
  
 +  nav.primary {
 +    margin-right: auto;
 +  }
 +}
  
  nav.primary {
    & > .btn-group .btn-outline-primary {
  }
  
  nav.secondary {
 -  position: absolute;
 -  right: 0;
 -
    .nav-link {
      padding: 0.2rem;
      color: $darkgrey;
@@@ -199,8 -226,15 +195,8 @@@ body.small-nav 
      display: block;
    }
  
 -  nav.primary,
 -  nav.secondary {
 -    float: none !important;
 -    position: relative;
 -    display: block;
 -    clear: both;
 -  }
 -
    header {
 +    flex-direction: column;
      height: auto;
      min-height: $headerHeight;
      background: #fff;
    }
  
    nav.primary {
 +    margin-right: 0;
      padding: 0;
  
 -    ul, li {
 -      border: none;
 -      border-radius: 0;
 -      width: 100%;
 -    }
 -
 -    ul {
 -      border-top: 1px solid #eee;
 -      li {
 -        border-bottom: 1px solid #eee;
 -        border-right: none;
 -        > a {
 -          border-radius: 0;
 -          width: 100%;
 -          text-align: center;
 -          font-size: 15px;
 -        }
 -      }
 -    }
 -
      .btn-group {
        width: 100%;
        padding: 10px;
@@@ -562,6 -615,16 +558,6 @@@ header .search_forms
    display: none;
  }
  
 -/* Rules for the map key which appears in the popout sidebar */
 -
 -#mapkey {
 - .mapkey-table-key img {
 -    display: block;
 -    margin-left: auto;
 -    margin-right: auto;
 -  }
 -}
 -
  /* Rules for search sidebar */
  
  #sidebar .search_results_entry {
@@@ -645,6 -708,17 +641,6 @@@ tr.turn:hover 
      tr:last-child th, tr:last-child td {
        border-bottom: 0;
      }
 -
 -    .colour-preview-box {
 -      width: 14px;
 -      height: 14px;
 -      // add color via inline css on element: background-color: <tag value>;
 -    }
 -  }
 -
 -  span.action-button:hover {
 -    cursor: pointer;
 -    text-decoration: underline;
    }
  
    .note-description {
    }
  }
  
 +/* Force LTR/RTL alignment for placeholder text */
 +
 +.form-control::placeholder {
 +  text-align: left;
 +}
 +
  /* Rules for export sidebar */
  
  .export_form {
      #maxlat { margin-top: -1px; }
      #minlon {
        float: left;
 -      /* no-r2 */ margin-left: -1px;
 +      /*rtl:ignore*/ margin-left: -1px;
      }
      #maxlon {
        float: right;
 -      /* no-r2 */ margin-right: -1px;
 +      /*rtl:ignore*/ margin-right: -1px;
      }
      #minlat { margin-bottom: -1px; }
    }
      height: 400px;
      display: none;
    }
 -  .comments {
 -    max-width: 740px;
 +  .diary-comment .col-auto {
 +    width: 62px;
    }
 -  .diary-comment {
 -    border-top: 1px dashed $grey;
 -    &:first-child {
 -      border-top: 1px solid $grey;
 -    }
 +  .diary-comment .col {
 +    max-width: 690px;
    }
  }
  
@@@ -890,9 -961,10 +886,9 @@@ img.user_thumbnail 
  }
  
  img.user_thumbnail_tiny {
 -  width: auto;
 -  height: auto;
 -  max-width: 25px;
 -  max-height: 25px;
 +  width: 25px;
 +  height: 25px;
 +  object-fit: contain;
  }
  
  /* General styles for action lists / subnavs */
@@@ -972,7 -1044,7 +968,7 @@@ div.secondary-actions 
    }
  
    .sprite.x {
 -    /* no-r2 */ background-position: -50px 0;
 +    /*rtl:ignore*/ background-position: -50px 0;
    }
  
    .sprite.term {
    }
  
    .sprite.node {
 -    /* no-r2 */ background-position: -100px 0;
 +    /*rtl:ignore*/ background-position: -100px 0;
    }
  
    .sprite.way {
 -    /* no-r2 */ background-position: -150px 0;
 +    /*rtl:ignore*/ background-position: -150px 0;
    }
  
    .sprite.tag {
 -    /* no-r2 */ background-position: -200px 0;
 +    /*rtl:ignore*/ background-position: -200px 0;
    }
  
    .sprite.editor {
 -    /* no-r2 */ background-position: -250px 0;
 +    /*rtl:ignore*/ background-position: -250px 0;
    }
  
    .sprite.question {
 -    /* no-r2 */ background-position: -300px 0;
 +    /*rtl:ignore*/ background-position: -300px 0;
    }
  
    .sprite.rules {
 -    /* no-r2 */ background-position: -350px 0;
 +    /*rtl:ignore*/ background-position: -350px 0;
    }
  
    .icon.note {
      background: 40px 40px image-url('about/sprite.png') no-repeat;
  
      &.local {
 -      /* no-r2 */
 +      /*rtl:ignore*/
        background-position: 0px 0px;
      }
      &.community {
 -      /* no-r2 */
 +      /*rtl:ignore*/
        background-position: 0px -40px;
      }
      &.open {
 -      /* no-r2 */
 +      /*rtl:ignore*/
        background-position: 0px -80px;
      }
      &.partners {
 -      /* no-r2 */
 +      /*rtl:ignore*/
        background-position: 0px -120px;
      }
      &.infringement {
 -      /* no-r2 */
 +      /*rtl:ignore*/
        background-position: 0px -160px;
      }
      &.legal {
 -      /* no-r2 */
 +      /*rtl:ignore*/
        background-position: -45px -160px;
      }
    }
index 7aa6e4754d9078344fde557e4f256b34ec2067e3,be32737a4e090e8b750c81ab333871101730e34b..67b3c7cf77fcdb2ed07b1d23a02babdcf513c47e
@@@ -1,25 -1,12 +1,25 @@@
  module BrowseHelper
 -  def printable_name(object, version: false)
 +  def element_single_current_link(type, object, url)
 +    link_to url, { :class => element_class(type, object), :title => element_title(object), :rel => (link_follow(object) if type == "node") } do
 +      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
 +    end
 +  end
 +
 +  def printable_element_name(object)
      id = if object.id.is_a?(Array)
             object.id[0]
           else
             object.id
           end
 -    name = t "printable_name.with_id", :id => id.to_s
 -    name = t "printable_name.with_version", :id => name, :version => object.version.to_s if version
 +    name = id.to_s
  
      # don't look at object tags if redacted, so as to avoid giving
      # away redacted version tag information.
      name
    end
  
 -  def link_class(type, object)
 -    classes = [type]
 +  def printable_element_version(object)
 +    t "printable_name.version", :version => object.version
 +  end
  
 -    if object.redacted?
 -      classes << "deleted"
 +  def element_strikethrough(object, &block)
 +    if object.redacted? || !object.visible?
 +      tag.s(&block)
      else
 -      classes += icon_tags(object).flatten.map { |t| h(t) }
 -      classes << "deleted" unless object.visible?
 +      yield
      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 link_title(object)
 +  def element_title(object)
      if object.redacted?
        ""
      else
      end
    end
  
+   def sidebar_classic_pagination(pages, page_param)
+     max_width_for_default_padding = 35
+     width = 0
+     pagination_items(pages, {}).each do |body|
+       width += 2 # padding width
+       width += body.length
+     end
+     link_classes = ["page-link", { "px-1" => width > max_width_for_default_padding }]
+     tag.ul :class => "pagination pagination-sm mb-1 ms-auto" do
+       pagination_items(pages, {}).each do |body, n|
+         linked = !(n.is_a? String)
+         link = if linked
+                  link_to body, url_for(page_param => n), :class => link_classes
+                else
+                  tag.span body, :class => link_classes
+                end
+         concat tag.li link, :class => ["page-item", { n => !linked }]
+       end
+     end
+   end
    private
  
    ICON_TAGS = %w[aeroway amenity barrier building highway historic landuse leisure man_made natural railway shop tourism waterway].freeze
index ee8eee66e710fdd045a23ca562ed095324e31e59,9225192e1144fd50a154ac9611f5d7c8901e8204..db6b9c966e924a55db0840975df655281b611299
      <% if current_user %>
        <div class="col-auto">
          <% if @changeset.subscribers.exists?(current_user.id) %>
 -          <button class="action-button btn btn-sm btn-primary" name="unsubscribe" data-method="POST" data-url="<%= changeset_unsubscribe_url(@changeset) %>"><%= t("javascripts.changesets.show.unsubscribe") %></button>
 +          <button class="btn btn-sm btn-primary" name="unsubscribe" data-method="POST" data-url="<%= api_changeset_unsubscribe_url(@changeset) %>"><%= t("javascripts.changesets.show.unsubscribe") %></button>
          <% else %>
 -          <button class="action-button btn btn-sm btn-primary" name="subscribe" data-method="POST" data-url="<%= changeset_subscribe_url(@changeset) %>"><%= t("javascripts.changesets.show.subscribe") %></button>
 +          <button class="btn btn-sm btn-primary" name="subscribe" data-method="POST" data-url="<%= api_changeset_subscribe_url(@changeset) %>"><%= t("javascripts.changesets.show.subscribe") %></button>
          <% end %>
        </div>
      <% end %>
    </div>
  
    <% if @comments.length > 0 %>
 -    <div class='changeset-comments'>
 -      <form action="#">
 -        <ul class="list-unstyled">
 -          <% @comments.each do |comment| %>
 -            <% if comment.visible %>
 -              <li id="c<%= comment.id %>">
 -                <small class='text-muted'>
 -                  <%= t(".comment_by_html",
 -                        :time_ago => friendly_date_ago(comment.created_at),
 -                        :user => link_to(comment.author.display_name, user_path(comment.author))) %>
 -                  <% if current_user and current_user.moderator? %>
 -                    — <span class="action-button" data-comment-id="<%= comment.id %>" data-method="POST" data-url="<%= changeset_comment_hide_url(comment.id) %>"><%= t("javascripts.changesets.show.hide_comment") %></span>
 -                  <% end %>
 -                </small>
 -                <div class="mx-2">
 -                  <%= comment.body.to_html %>
 -                </div>
 -              </li>
 -            <% elsif current_user and current_user.moderator? %>
 -              <li id="c<%= comment.id %>">
 -                <small class='text-muted'>
 -                  <%= t(".hidden_comment_by_html",
 -                        :time_ago => friendly_date_ago(comment.created_at),
 -                        :user => link_to(comment.author.display_name, user_path(comment.author))) %>
 -                  — <span class="action-button text-muted" data-comment-id="<%= comment.id %>" data-method="POST" data-url="<%= changeset_comment_unhide_url(comment.id) %>"><%= t("javascripts.changesets.show.unhide_comment") %></span>
 -                 </small>
 -                <div class="mx-2">
 -                  <%= comment.body.to_html %>
 -                </div>
 -              </li>
 +    <ul class="list-unstyled">
 +      <% @comments.each do |comment| %>
 +        <% next unless comment.visible || current_user&.moderator? %>
 +        <li id="c<%= comment.id %>">
 +          <small class='text-muted'>
 +            <%= t comment.visible ? ".comment_by_html" : ".hidden_comment_by_html",
 +                  :time_ago => friendly_date_ago(comment.created_at),
 +                  :user => link_to(comment.author.display_name, user_path(comment.author)) %>
 +            <% if current_user&.moderator? %>
 +              —
 +              <%= tag.button t("javascripts.changesets.show.#{comment.visible ? 'hide' : 'unhide'}_comment"),
 +                             :class => "btn btn-sm small btn-link link-secondary p-0 align-baseline",
 +                             :data => { :method => "POST",
 +                                        :url => comment.visible ? changeset_comment_hide_url(comment) : changeset_comment_unhide_url(comment) } %>
              <% end %>
 -          <% end %>
 -        </ul>
 -      </form>
 -    </div>
 +          </small>
 +          <div class="mx-2">
 +            <%= comment.body.to_html %>
 +          </div>
 +        </li>
 +      <% end %>
 +    </ul>
    <% end %>
  
    <% unless current_user %>
 -    <p class="notice">
 +    <p>
        <%= link_to(t(".join_discussion"), login_path(:referer => request.fullpath)) %>
      </p>
    <% end %>
          <div id="comment-error" class="alert alert-danger p-2 mb-3" hidden>
          </div>
          <div>
 -          <input type="submit" name="comment" value="<%= t("javascripts.changesets.show.comment") %>" data-changeset-id="<%= @changeset.id %>" data-method="POST" data-url="<%= changeset_comment_url(@changeset) %>" disabled="1" class="btn btn-sm btn-primary" />
 +          <button name="comment" data-method="POST" data-url="<%= changeset_comment_url(@changeset) %>" disabled class="btn btn-sm btn-primary"><%= t("javascripts.changesets.show.comment") %></button>
          </div>
        </form>
      <% else %>
 -      <p class="notice">
 +      <p>
          <%= t(".still_open") %>
        </p>
      <% end %>
    <% end %>
  
    <% unless @ways.empty? %>
-     <%= render :partial => "paging_nav", :locals => { :heading => type_and_paginated_count("way", @way_pages), :pages => @way_pages, :page_param => "way_page" } %>
+     <%= render :partial => "paging_nav", :locals => { :type => "way", :pages => @way_pages } %>
      <ul class="list-unstyled">
        <% @ways.each do |way| %>
 -        <li><%= link_to printable_name(way, :version => true), { :action => "way", :id => way.way_id.to_s }, { :class => link_class("way", way), :title => link_title(way) } %></li>
 +        <%= element_list_item "way", way do %>
 +          <%= t "printable_name.current_and_old_links_html",
 +                :current_link => link_to(printable_element_name(way), way_path(way.way_id)),
 +                :old_link => link_to(printable_element_version(way), old_way_path(way.way_id, way.version)) %>
 +        <% end %>
        <% end %>
      </ul>
    <% end %>
  
    <% unless @relations.empty? %>
-     <%= render :partial => "paging_nav", :locals => { :heading => type_and_paginated_count("relation", @relation_pages), :pages => @relation_pages, :page_param => "relation_page" } %>
+     <%= render :partial => "paging_nav", :locals => { :type => "relation", :pages => @relation_pages } %>
      <ul class="list-unstyled">
        <% @relations.each do |relation| %>
 -        <li><%= link_to printable_name(relation, :version => true), { :action => "relation", :id => relation.relation_id.to_s }, { :class => link_class("relation", relation), :title => link_title(relation) } %></li>
 +        <%= element_list_item "relation", relation do %>
 +          <%= t "printable_name.current_and_old_links_html",
 +                :current_link => link_to(printable_element_name(relation), relation_path(relation.relation_id)),
 +                :old_link => link_to(printable_element_version(relation), old_relation_path(relation.relation_id, relation.version)) %>
 +        <% end %>
        <% end %>
      </ul>
    <% end %>
  
    <% unless @nodes.empty? %>
-     <%= render :partial => "paging_nav", :locals => { :heading => type_and_paginated_count("node", @node_pages), :pages => @node_pages, :page_param => "node_page" } %>
+     <%= render :partial => "paging_nav", :locals => { :type => "node", :pages => @node_pages } %>
      <ul class="list-unstyled">
        <% @nodes.each do |node| %>
 -        <li><%= link_to printable_name(node, :version => true), { :action => "node", :id => node.node_id.to_s }, { :class => link_class("node", node), :title => link_title(node), :rel => link_follow(node) } %></li>
 +        <%= element_list_item "node", node do %>
 +          <%= t "printable_name.current_and_old_links_html",
 +                :current_link => link_to(printable_element_name(node), node_path(node.node_id), { :rel => link_follow(node) }),
 +                :old_link => link_to(printable_element_version(node), old_node_path(node.node_id, node.version), { :rel => link_follow(node) }) %>
 +        <% end %>
        <% end %>
      </ul>
    <% end %>
  </div>
  
 +<div class='secondary-actions'>
 +  <%= link_to(t(".changesetxml"), :controller => "api/changesets", :action => "show") %>
 +  &middot;
 +  <%= link_to(t(".osmchangexml"), :controller => "api/changesets", :action => "download") %>
 +</div>
 +
  <% if @next_by_user || @prev_by_user %>
    <div class='secondary-actions'>
      <% if @prev_by_user %>
 -      <%= link_to "<< #{@prev_by_user.id}", :id => @prev_by_user.id %>
 +      <%= link_to({ :id => @prev_by_user.id }, :class => "icon-link") do %>
 +        <%= previous_page_svg_tag :height => 11 %>
 +        <%= @prev_by_user.id %>
 +      <% end %>
        &middot;
      <% end %>
      <%= user = (@prev_by_user || @next_by_user).user.display_name
          link_to tag.bdi(user), :controller => "changesets", :action => "index", :display_name => user %>
      <% if @next_by_user %>
        &middot;
 -      <%= link_to "#{@next_by_user.id} >>", :id => @next_by_user.id %>
 +      <%= link_to({ :id => @next_by_user.id }, :class => "icon-link") do %>
 +        <%= @next_by_user.id %>
 +        <%= next_page_svg_tag :height => 11 %>
 +      <% end %>
      <% end %>
    </div>
  <% end %>
 -
 -<div class='secondary-actions'>
 -  <%= link_to(t(".changesetxml"), :controller => "api/changesets", :action => "show") %>
 -  &middot;
 -  <%= link_to(t(".osmchangexml"), :controller => "api/changesets", :action => "download") %>
 -</div>