Patch #21805 » 0001-Improve-accessibility-for-icon-only-links-v2.patch
| app/helpers/application_helper.rb | ||
|---|---|---|
| 454 | 454 | end | 
| 455 | 455 | |
| 456 | 456 | def reorder_links(name, url, method = :post) | 
| 457 |     link_to('', | |
| 457 |     link_to(l(:label_sort_highest), | |
| 458 | 458 |             url.merge({"#{name}[move_to]" => 'highest'}), :method => method, | 
| 459 | 459 | :title => l(:label_sort_highest), :class => 'icon-only icon-move-top') + | 
| 460 |     link_to('', | |
| 460 |     link_to(l(:label_sort_higher), | |
| 461 | 461 |             url.merge({"#{name}[move_to]" => 'higher'}), :method => method, | 
| 462 | 462 | :title => l(:label_sort_higher), :class => 'icon-only icon-move-up') + | 
| 463 |     link_to('', | |
| 463 |     link_to(l(:label_sort_lower), | |
| 464 | 464 |             url.merge({"#{name}[move_to]" => 'lower'}), :method => method, | 
| 465 | 465 | :title => l(:label_sort_lower), :class => 'icon-only icon-move-down') + | 
| 466 |     link_to('', | |
| 466 |     link_to(l(:label_sort_lowest), | |
| 467 | 467 |             url.merge({"#{name}[move_to]" => 'lowest'}), :method => method, | 
| 468 | 468 | :title => l(:label_sort_lowest), :class => 'icon-only icon-move-bottom') | 
| 469 | 469 | end | 
| ... | ... | |
| 887 | 887 | @current_section += 1 | 
| 888 | 888 | if @current_section > 1 | 
| 889 | 889 |         content_tag('div', | 
| 890 |           link_to('', options[:edit_section_links].merge(:section => @current_section), | |
| 890 |           link_to(l(:button_edit_section), options[:edit_section_links].merge(:section => @current_section), | |
| 891 | 891 | :class => 'icon-only icon-edit'), | 
| 892 | 892 |           :class => "contextual heading-#{level}", | 
| 893 | 893 | :title => l(:button_edit_section), | 
| app/helpers/email_addresses_helper.rb | ||
|---|---|---|
| 22 | 22 | # Returns a link to enable or disable notifications for the address | 
| 23 | 23 | def toggle_email_address_notify_link(address) | 
| 24 | 24 | if address.notify? | 
| 25 |       link_to '', | |
| 25 |       link_to l(:label_disable_notifications), | |
| 26 | 26 | user_email_address_path(address.user, address, :notify => '0'), | 
| 27 | 27 | :method => :put, :remote => true, | 
| 28 | 28 | :title => l(:label_disable_notifications), | 
| 29 | :class => 'icon icon-email' | |
| 29 |         :class => 'icon-only icon-email' | |
| 30 | 30 | else | 
| 31 |       link_to '', | |
| 31 |       link_to l(:label_enable_notifications), | |
| 32 | 32 | user_email_address_path(address.user, address, :notify => '1'), | 
| 33 | 33 | :method => :put, :remote => true, | 
| 34 | 34 | :title => l(:label_enable_notifications), | 
| 35 | :class => 'icon icon-email-disabled' | |
| 35 |         :class => 'icon-only icon-email-disabled' | |
| 36 | 36 | end | 
| 37 | 37 | end | 
| 38 | 38 | end | 
| app/helpers/issues_helper.rb | ||
|---|---|---|
| 442 | 442 | # Link to the attachment if it has not been removed | 
| 443 | 443 | value = link_to_attachment(atta, :download => true, :only_path => options[:only_path]) | 
| 444 | 444 | if options[:only_path] != false && atta.is_text? | 
| 445 |           value += link_to('', | |
| 445 |           value += link_to(l(:button_view), | |
| 446 | 446 |                            { :controller => 'attachments', :action => 'show', | 
| 447 | 447 | :id => atta, :filename => atta.filename }, | 
| 448 | :class => 'icon icon-magnifier') | |
| 448 | :class => 'icon-only icon-magnifier', | |
| 449 | :title => l(:button_view)) | |
| 449 | 450 | end | 
| 450 | 451 | else | 
| 451 | 452 |         value = content_tag("i", h(value)) if value | 
| app/helpers/journals_helper.rb | ||
|---|---|---|
| 30 | 30 | editable = User.current.logged? && (User.current.allowed_to?(:edit_issue_notes, issue.project) || (journal.user == User.current && User.current.allowed_to?(:edit_own_issue_notes, issue.project))) | 
| 31 | 31 | links = [] | 
| 32 | 32 | if !journal.notes.blank? | 
| 33 |       links << link_to('', | |
| 33 |       links << link_to(l(:button_quote), | |
| 34 | 34 | quoted_issue_path(issue, :journal_id => journal), | 
| 35 | 35 | :remote => true, | 
| 36 | 36 | :method => 'post', | 
| 37 | 37 | :title => l(:button_quote), | 
| 38 | 38 | :class => 'icon-only icon-comment' | 
| 39 | 39 | ) if options[:reply_links] | 
| 40 |       links << link_to('', | |
| 40 |       links << link_to(l(:button_edit), | |
| 41 | 41 | edit_journal_path(journal), | 
| 42 | 42 | :remote => true, | 
| 43 | 43 | :method => 'get', | 
| 44 | 44 | :title => l(:button_edit), | 
| 45 | 45 | :class => 'icon-only icon-edit' | 
| 46 | 46 | ) if editable | 
| 47 |       links << link_to('', | |
| 47 |       links << link_to(l(:button_delete), | |
| 48 | 48 | journal_path(journal, :notes => ""), | 
| 49 | 49 | :remote => true, | 
| 50 | 50 |                        :method => 'put', :data => {:confirm => l(:text_are_you_sure)},  | 
| app/helpers/watchers_helper.rb | ||
|---|---|---|
| 58 | 58 | :object_id => object.id, | 
| 59 | 59 | :user_id => user} | 
| 60 | 60 | s << ' ' | 
| 61 |         s << link_to('', url, | |
| 61 |         s << link_to(l(:button_delete), url, | |
| 62 | 62 | :remote => true, :method => 'delete', | 
| 63 | 63 | :class => "delete icon-only icon-del", | 
| 64 | 64 | :title => l(:button_delete)) | 
| app/views/attachments/_links.html.erb | ||
|---|---|---|
| 1 | 1 | <div class="attachments"> | 
| 2 | 2 | <div class="contextual"> | 
| 3 |   <%= link_to('', | |
| 3 |   <%= link_to(l(:label_edit_attachments), | |
| 4 | 4 | container_attachments_edit_path(container), | 
| 5 | 5 | :title => l(:label_edit_attachments), | 
| 6 | 6 | :class => 'icon-only icon-edit' | 
| ... | ... | |
| 9 | 9 | <% for attachment in attachments %> | 
| 10 | 10 | <p><%= link_to_attachment attachment, :class => 'icon icon-attachment', :download => true -%> | 
| 11 | 11 | <% if attachment.is_text? %> | 
| 12 |     <%= link_to '', | |
| 12 |     <%= link_to l(:button_view), | |
| 13 | 13 |                 { :controller => 'attachments', :action => 'show', | 
| 14 | 14 | :id => attachment, :filename => attachment.filename }, | 
| 15 | :class => 'icon icon-magnifier', | |
| 15 |                 :class => 'icon-only icon-magnifier', | |
| 16 | 16 | :title => l(:button_view) %> | 
| 17 | 17 | <% end %> | 
| 18 | 18 |   <%= " - #{attachment.description}" unless attachment.description.blank? %> | 
| 19 | 19 | <span class="size">(<%= number_to_human_size attachment.filesize %>)</span> | 
| 20 | 20 | <% if options[:deletable] %> | 
| 21 |     <%= link_to '', attachment_path(attachment), | |
| 21 |     <%= link_to l(:button_delete), attachment_path(attachment), | |
| 22 | 22 |                 :data => {:confirm => l(:text_are_you_sure)}, | 
| 23 | 23 | :method => :delete, | 
| 24 | 24 | :class => 'delete icon-only icon-del', | 
| app/views/issues/_attributes.html.erb | ||
|---|---|---|
| 20 | 20 | |
| 21 | 21 | <% if @issue.safe_attribute?('category_id') && @issue.project.issue_categories.any? %> | 
| 22 | 22 | <p><%= f.select :category_id, (@issue.project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true, :required => @issue.required_attribute?('category_id') %> | 
| 23 | <%= link_to('', | |
| 23 | <%= link_to(l(:label_issue_category_new), | |
| 24 | 24 | new_project_issue_category_path(@issue.project), | 
| 25 | 25 | :remote => true, | 
| 26 | 26 | :method => 'get', | 
| ... | ... | |
| 32 | 32 | |
| 33 | 33 | <% if @issue.safe_attribute?('fixed_version_id') && @issue.assignable_versions.any? %> | 
| 34 | 34 | <p><%= f.select :fixed_version_id, version_options_for_select(@issue.assignable_versions, @issue.fixed_version), :include_blank => true, :required => @issue.required_attribute?('fixed_version_id') %> | 
| 35 | <%= link_to('', | |
| 35 | <%= link_to(l(:label_version_new), | |
| 36 | 36 | new_project_version_path(@issue.project), | 
| 37 | 37 | :remote => true, | 
| 38 | 38 | :method => 'get', | 
| app/views/issues/_relations.html.erb | ||
|---|---|---|
| 19 | 19 | <td class="status"><%= other_issue.status.name %></td> | 
| 20 | 20 | <td class="start_date"><%= format_date(other_issue.start_date) %></td> | 
| 21 | 21 | <td class="due_date"><%= format_date(other_issue.due_date) %></td> | 
| 22 |   <td class="buttons"><%= link_to('', | |
| 22 |   <td class="buttons"><%= link_to(l(:label_relation_delete), | |
| 23 | 23 | relation_path(relation), | 
| 24 | 24 | :remote => true, | 
| 25 | 25 | :method => :delete, | 
| app/views/my/blocks/_timelog.html.erb | ||
|---|---|---|
| 42 | 42 |     <td class="hours"><%= html_hours("%.2f" % entry.hours) %></td> | 
| 43 | 43 | <td class="buttons"> | 
| 44 | 44 | <% if entry.editable_by?(@user) -%> | 
| 45 |         <%= link_to '', {:controller => 'timelog', :action => 'edit', :id => entry}, | |
| 45 |         <%= link_to l(:button_edit), {:controller => 'timelog', :action => 'edit', :id => entry}, | |
| 46 | 46 | :title => l(:button_edit), | 
| 47 | 47 | :class => 'icon-only icon-edit' %> | 
| 48 |         <%= link_to '', {:controller => 'timelog', :action => 'destroy', :id => entry}, | |
| 48 |         <%= link_to l(:button_delete), {:controller => 'timelog', :action => 'destroy', :id => entry}, | |
| 49 | 49 |                     :data => {:confirm => l(:text_are_you_sure)}, :method => :delete, | 
| 50 | 50 | :title => l(:button_delete), | 
| 51 | 51 | :class => 'icon-only icon-del' %> | 
| app/views/reports/issue_report.html.erb | ||
|---|---|---|
| 3 | 3 | <div class="splitcontentleft"> | 
| 4 | 4 | <h3> | 
| 5 | 5 | <%=l(:field_tracker)%>  | 
| 6 | <%= link_to '', project_issues_report_details_path(@project, :detail => 'tracker'), :class => 'icon-only icon-zoom-in' %> | |
| 6 | <%= link_to l(:label_details), | |
| 7 | project_issues_report_details_path(@project, :detail => 'tracker'), | |
| 8 | :class => 'icon-only icon-zoom-in', | |
| 9 | :title => l(:label_details) %> | |
| 7 | 10 | </h3> | 
| 8 | 11 | <%= render :partial => 'simple', :locals => { :data => @issues_by_tracker, :field_name => "tracker_id", :rows => @trackers } %> | 
| 9 | 12 | <br /> | 
| 10 | 13 | <h3> | 
| 11 | 14 | <%=l(:field_priority)%>  | 
| 12 | <%= link_to '', project_issues_report_details_path(@project, :detail => 'priority'), :class => 'icon-only icon-zoom-in' %> | |
| 15 | <%= link_to l(:label_details), | |
| 16 | project_issues_report_details_path(@project, :detail => 'priority'), | |
| 17 | :class => 'icon-only icon-zoom-in', | |
| 18 | :title => l(:label_details) %> | |
| 13 | 19 | </h3> | 
| 14 | 20 | <%= render :partial => 'simple', :locals => { :data => @issues_by_priority, :field_name => "priority_id", :rows => @priorities } %> | 
| 15 | 21 | <br /> | 
| 16 | 22 | <h3> | 
| 17 | 23 | <%=l(:field_assigned_to)%>  | 
| 18 | <%= link_to '', project_issues_report_details_path(@project, :detail => 'assigned_to'), :class => 'icon-only icon-zoom-in' %> | |
| 24 | <%= link_to l(:label_details), | |
| 25 | project_issues_report_details_path(@project, :detail => 'assigned_to'), | |
| 26 | :class => 'icon-only icon-zoom-in', | |
| 27 | :title => l(:label_details) %> | |
| 19 | 28 | </h3> | 
| 20 | 29 | <%= render :partial => 'simple', :locals => { :data => @issues_by_assigned_to, :field_name => "assigned_to_id", :rows => @assignees } %> | 
| 21 | 30 | <br /> | 
| 22 | 31 | <h3> | 
| 23 | 32 | <%=l(:field_author)%>  | 
| 24 | <%= link_to '', project_issues_report_details_path(@project, :detail => 'author'), :class => 'icon-only icon-zoom-in' %> | |
| 33 | <%= link_to l(:label_details), | |
| 34 | project_issues_report_details_path(@project, :detail => 'author'), | |
| 35 | :class => 'icon-only icon-zoom-in', | |
| 36 | :title => l(:label_details) %> | |
| 25 | 37 | </h3> | 
| 26 | 38 | <%= render :partial => 'simple', :locals => { :data => @issues_by_author, :field_name => "author_id", :rows => @authors } %> | 
| 27 | 39 | <br /> | 
| ... | ... | |
| 31 | 43 | <div class="splitcontentright"> | 
| 32 | 44 | <h3> | 
| 33 | 45 | <%=l(:field_version)%>  | 
| 34 | <%= link_to '', project_issues_report_details_path(@project, :detail => 'version'), :class => 'icon-only icon-zoom-in' %> | |
| 46 | <%= link_to l(:label_details), | |
| 47 | project_issues_report_details_path(@project, :detail => 'version'), | |
| 48 | :class => 'icon-only icon-zoom-in', | |
| 49 | :title => l(:label_details) %> | |
| 35 | 50 | </h3> | 
| 36 | 51 | <%= render :partial => 'simple', :locals => { :data => @issues_by_version, :field_name => "fixed_version_id", :rows => @versions } %> | 
| 37 | 52 | <br /> | 
| 38 | 53 | <% if @project.children.any? %> | 
| 39 | 54 | <h3> | 
| 40 | 55 | <%=l(:field_subproject)%>  | 
| 41 | <%= link_to '', project_issues_report_details_path(@project, :detail => 'subproject'), :class => 'icon-only icon-zoom-in' %> | |
| 56 | <%= link_to l(:label_details), | |
| 57 | project_issues_report_details_path(@project, :detail => 'subproject'), | |
| 58 | :class => 'icon-only icon-zoom-in', | |
| 59 | :title => l(:label_details) %> | |
| 42 | 60 | </h3> | 
| 43 | 61 | <%= render :partial => 'simple', :locals => { :data => @issues_by_subproject, :field_name => "project_id", :rows => @subprojects } %> | 
| 44 | 62 | <br /> | 
| 45 | 63 | <% end %> | 
| 46 | 64 | <h3> | 
| 47 | 65 | <%=l(:field_category)%>  | 
| 48 | <%= link_to '', project_issues_report_details_path(@project, :detail => 'category'), :class => 'icon-only icon-zoom-in' %> | |
| 66 | <%= link_to l(:label_details), | |
| 67 | project_issues_report_details_path(@project, :detail => 'category'), | |
| 68 | :class => 'icon-only icon-zoom-in', | |
| 69 | :title => l(:label_details) %> | |
| 49 | 70 | </h3> | 
| 50 | 71 | <%= render :partial => 'simple', :locals => { :data => @issues_by_category, :field_name => "category_id", :rows => @categories } %> | 
| 51 | 72 | <br /> | 
| app/views/repositories/_related_issues.html.erb | ||
|---|---|---|
| 11 | 11 | <ul> | 
| 12 | 12 | <% @changeset.issues.visible.each do |issue| %> | 
| 13 | 13 |   <li id="<%= "related-issue-#{issue.id}" %>"><%= link_to_issue issue %> | 
| 14 |     <%= link_to('', | |
| 14 |     <%= link_to(l(:label_relation_delete), | |
| 15 | 15 |                 {:controller => 'repositories', :action => 'remove_related_issue', | 
| 16 | 16 | :id => @project, :repository_id => @repository.identifier_param, | 
| 17 | 17 | :rev => @changeset.identifier, :issue_id => issue}, | 
| app/views/settings/_repositories.html.erb | ||
|---|---|---|
| 119 | 119 | ) %> | 
| 120 | 120 | </td> | 
| 121 | 121 | <td class="buttons"> | 
| 122 |         <%= link_to('', '#', | |
| 123 | :class => 'delete-commit-keywords icon-only icon-del') %> | |
| 122 | <%= link_to(l(:button_delete), '#', | |
| 123 | :class => 'delete-commit-keywords icon-only icon-del', | |
| 124 | :title => l(:button_delete)) %> | |
| 124 | 125 | </td> | 
| 125 | 126 | </tr> | 
| 126 | 127 | <% end %> | 
| ... | ... | |
| 130 | 131 | <td></td> | 
| 131 | 132 | <td></td> | 
| 132 | 133 | <td class="buttons"> | 
| 133 |         <%= link_to('', '#', | |
| 134 | :class => 'add-commit-keywords icon-only icon-add') %> | |
| 134 | <%= link_to(l(:button_add), '#', | |
| 135 | :class => 'add-commit-keywords icon-only icon-add', | |
| 136 | :title => l(:button_add)) %> | |
| 135 | 137 | </td> | 
| 136 | 138 | </tr> | 
| 137 | 139 | </tbody> | 
| app/views/timelog/_list.html.erb | ||
|---|---|---|
| 21 | 21 |     <%= raw @query.inline_columns.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, entry)}</td>"}.join %> | 
| 22 | 22 | <td class="buttons"> | 
| 23 | 23 | <% if entry.editable_by?(User.current) -%> | 
| 24 |         <%= link_to '', edit_time_entry_path(entry), | |
| 24 |         <%= link_to l(:button_edit), edit_time_entry_path(entry), | |
| 25 | 25 | :title => l(:button_edit), | 
| 26 | :class => 'icon icon-edit' %> | |
| 27 |         <%= link_to '', time_entry_path(entry), | |
| 26 |                     :class => 'icon-only icon-edit' %> | |
| 27 |         <%= link_to l(:button_delete), time_entry_path(entry), | |
| 28 | 28 |                     :data => {:confirm => l(:text_are_you_sure)}, | 
| 29 | 29 | :method => :delete, | 
| 30 | 30 | :title => l(:button_delete), | 
| public/stylesheets/application.css | ||
|---|---|---|
| 1101 | 1101 | background-repeat: no-repeat; | 
| 1102 | 1102 | padding-left: 16px; | 
| 1103 | 1103 | } | 
| 1104 | a.icon-only { | |
| 1105 | display: inline-block; | |
| 1106 | width: 0; | |
| 1107 | overflow: hidden; | |
| 1108 | padding-top: 0; | |
| 1109 | padding-bottom: 0; | |
| 1110 | font-size: 8px; | |
| 1111 | } | |
| 1104 | 1112 | |
| 1105 | 1113 | .icon-add { background-image: url(../images/add.png); } | 
| 1106 | 1114 | .icon-edit { background-image: url(../images/edit.png); } | 
| test/unit/helpers/application_helper_test.rb | ||
|---|---|---|
| 1243 | 1243 | |
| 1244 | 1244 | # heading that contains inline code | 
| 1245 | 1245 |     assert_match Regexp.new('<div class="contextual heading-2" title="Edit this section" id="section-4">' + | 
| 1246 | '<a class="icon-only icon-edit" href="/projects/1/wiki/Test/edit\?section=4"></a></div>' + | |
| 1246 |       '<a class="icon-only icon-edit" href="/projects/1/wiki/Test/edit\?section=4">Edit this section</a></div>' + | |
| 1247 | 1247 | '<a name="Subtitle-with-inline-code"></a>' + | 
| 1248 | 1248 | '<h2 >Subtitle with <code>inline code</code><a href="#Subtitle-with-inline-code" class="wiki-anchor">¶</a></h2>'), | 
| 1249 | 1249 | result | 
| 1250 | 1250 | |
| 1251 | 1251 | # last heading | 
| 1252 | 1252 |     assert_match Regexp.new('<div class="contextual heading-2" title="Edit this section" id="section-5">' + | 
| 1253 | '<a class="icon-only icon-edit" href="/projects/1/wiki/Test/edit\?section=5"></a></div>' + | |
| 1253 |       '<a class="icon-only icon-edit" href="/projects/1/wiki/Test/edit\?section=5">Edit this section</a></div>' + | |
| 1254 | 1254 | '<a name="Subtitle-after-pre-tag"></a>' + | 
| 1255 | 1255 | '<h2 >Subtitle after pre tag<a href="#Subtitle-after-pre-tag" class="wiki-anchor">¶</a></h2>'), | 
| 1256 | 1256 | result |