@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 */
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;
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;
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;
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 {
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;
}
}
}
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 */
}
.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;
}
}
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
<% 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") %>
+ ·
+ <%= 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 %>
·
<% 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 %>
·
- <%= 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") %>
- ·
- <%= link_to(t(".osmchangexml"), :controller => "api/changesets", :action => "download") %>
-</div>