diff --git a/Gemfile b/Gemfile index a259b7c..d57e913 100644 --- a/Gemfile +++ b/Gemfile @@ -18,7 +18,7 @@ gem "mimemagic" # Request at least nokogiri 1.6.7.2 because of security advisories gem "nokogiri", ">= 1.6.7.2" -# Request at least rails-html-sanitizer 1.0.3 because of security advisories +# Request at least rails-html-sanitizer 1.0.3 because of security advisories gem "rails-html-sanitizer", ">= 1.0.3" # Windows does not include zoneinfo files, so bundle the tzinfo-data gem diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index aade3cc..b2fc4a3 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1358,6 +1358,82 @@ module ApplicationHelper encoding = l(:general_csv_encoding) end + # Creates an icon tag given an icon name and possible icon + # modifiers. + # + # Examples + # + # fa_icon "camera-retro" + # # => + # + # fa_icon "camera-retro", text: "Take a photo" + # # => Take a photo + # fa_icon "chevron-right", text: "Get started", right: true + # # => Get started + # + # fa_icon "camera-retro 2x" + # # => + # fa_icon ["camera-retro", "4x"] + # # => + # fa_icon "spinner spin lg" + # # => + # + # fa_icon "quote-left 4x", class: "pull-left" + # # => + # + # fa_icon "user", data: { id: 123 } + # # => + # + # content_tag(:li, fa_icon("check li", text: "Bulleted list item")) + # # =>
  • Bulleted list item
  • + def fa_icon(names = "flag", options = {}) + classes = ["fa"] + classes.concat icon_names(names) + classes.concat Array(options.delete(:class)) + text = options.delete(:text) + icon_only = options.delete(:icon_only) + right_icon = options.delete(:right) + icon = content_tag(:i, nil, options.merge(:class => classes)) + icon_join(icon, text, right_icon, icon_only) + end + + # Creates an stack set of icon tags given a base icon name, a main icon + # name, and possible icon modifiers. + # + # Examples + # + # fa_stacked_icon "twitter", base: "square-o" + # # => + # # => + # # => + # # => + # + # fa_stacked_icon "terminal inverse", base: "square", class: "pull-right", text: "Hi!" + # # => + # # => + # # => + # # => Hi! + # + # fa_stacked_icon "camera", base: "ban-circle", reverse: true + # # => + # # => + # # => + # # => + def fa_stacked_icon(names = "flag", options = {}) + classes = icon_names("stack").concat(Array(options.delete(:class))) + base_names = array_value(options.delete(:base) || "square-o").push("stack-2x") + names = array_value(names).push("stack-1x") + base = fa_icon(base_names, options.delete(:base_options) || {}) + icon = fa_icon(names, options.delete(:icon_options) || {}) + icons = [base, icon] + icons.reverse! if options.delete(:reverse) + text = options.delete(:text) + right_icon = options.delete(:right) + icon_only = options.delete(:icon_only) + stacked_icon = content_tag(:span, safe_join(icons), options.merge(:class => classes)) + icon_join(stacked_icon, text, right_icon, icon_only) + end + private def wiki_helper @@ -1365,4 +1441,20 @@ module ApplicationHelper extend helper return self end + + def icon_join(icon, text, reverse_order = false, icon_only = false) + return icon if text.blank? + text = icon_only ? content_tag("span", text, :class => "sr-only") : ERB::Util.html_escape(text) + elements = [icon, text] + elements.reverse! if reverse_order + safe_join(elements, " ") + end + + def icon_names(names = []) + array_value(names).map { |n| "fa-#{n}" } + end + + def array_value(value = []) + value.is_a?(Array) ? value : value.to_s.split(/\s+/) + end end diff --git a/app/helpers/journals_helper.rb b/app/helpers/journals_helper.rb index 0183480..416807f 100644 --- a/app/helpers/journals_helper.rb +++ b/app/helpers/journals_helper.rb @@ -30,28 +30,28 @@ module JournalsHelper css_classes = "wiki" links = [] if journal.notes.present? - links << link_to(l(:button_quote), + links << link_to(fa_icon("quote-left", :text => l(:label_quote), :icon_only => true), quoted_issue_path(issue, :journal_id => journal), :remote => true, :method => 'post', :title => l(:button_quote), - :class => 'icon-only icon-comment' + :class => 'icon' ) if options[:reply_links] if journal.editable_by?(User.current) - links << link_to(l(:button_edit), + links << link_to(fa_icon("pencil", :text => l(:label_edit), :icon_only => true), edit_journal_path(journal), :remote => true, :method => 'get', :title => l(:button_edit), - :class => 'icon-only icon-edit' + :class => 'icon' ) - links << link_to(l(:button_delete), + links << link_to(fa_icon("trash", :text => l(:label_delete), :icon_only => true), journal_path(journal, :journal => {:notes => ""}), :remote => true, - :method => 'put', :data => {:confirm => l(:text_are_you_sure)}, + :method => 'put', :data => {:confirm => l(:text_are_you_sure)}, :title => l(:button_delete), - :class => 'icon-only icon-del' + :class => 'icon' ) css_classes << " editable" end diff --git a/app/helpers/watchers_helper.rb b/app/helpers/watchers_helper.rb index b3e23a4..949df1b 100644 --- a/app/helpers/watchers_helper.rb +++ b/app/helpers/watchers_helper.rb @@ -25,8 +25,8 @@ module WatchersHelper return '' unless objects.any? watched = Watcher.any_watched?(objects, user) - css = [watcher_css(objects), watched ? 'icon icon-fav' : 'icon icon-fav-off'].join(' ') - text = watched ? l(:button_unwatch) : l(:button_watch) + css = [watcher_css(objects), watched ? 'icon' : 'icon'].join(' ') + text = watched ? fa_icon("star", :text => l(:button_unwatch)) : fa_icon("star-o", :text => l(:button_watch)) url = watch_path( :object_type => objects.first.class.to_s.underscore, :object_id => (objects.size == 1 ? objects.first.id : objects.map(&:id).sort) @@ -58,9 +58,9 @@ module WatchersHelper :object_id => object.id, :user_id => user} s << ' ' - s << link_to(l(:button_delete), url, + s << link_to(fa_icon("trash", :text => l(:button_delete), :icon_only => true), url, :remote => true, :method => 'delete', - :class => "delete icon-only icon-del", + :class => "delete icon", :title => l(:button_delete)) end content << content_tag('li', s, :class => "user-#{user.id}") diff --git a/app/views/attachments/_links.html.erb b/app/views/attachments/_links.html.erb index 797f8bb..632b248 100644 --- a/app/views/attachments/_links.html.erb +++ b/app/views/attachments/_links.html.erb @@ -1,27 +1,27 @@
    - <%= link_to(l(:label_edit_attachments), + <%= link_to(fa_icon("pencil", :text => l(:label_edit_attachments), :icon_only => true), container_attachments_edit_path(container), :title => l(:label_edit_attachments), - :class => 'icon-only icon-edit' + :class => 'icon' ) if options[:editable] %>
    <% for attachment in attachments %> -

    <%= link_to_attachment attachment, :class => 'icon icon-attachment', :download => true -%> +

    <%= link_to_attachment attachment, :class => 'icon', :download => true -%> <% if attachment.is_text? || attachment.is_image? %> - <%= link_to l(:button_view), + <%= link_to fa_icon("search", :text => l(:button_view), :icon_only => true), { :controller => 'attachments', :action => 'show', :id => attachment, :filename => attachment.filename }, - :class => 'icon-only icon-magnifier', + :class => 'icon', :title => l(:button_view) %> <% end %> <%= " - #{attachment.description}" unless attachment.description.blank? %> (<%= number_to_human_size attachment.filesize %>) <% if options[:deletable] %> - <%= link_to l(:button_delete), attachment_path(attachment), + <%= link_to fa_icon("trash", :text => l(:button_delete), :icon_only => true), attachment_path(attachment), :data => {:confirm => l(:text_are_you_sure)}, :method => :delete, - :class => 'delete icon-only icon-del', + :class => 'delete icon', :title => l(:button_delete) %> <% end %> <% if options[:author] %> diff --git a/app/views/issues/_action_menu.html.erb b/app/views/issues/_action_menu.html.erb index b535fae..8e5e5dd 100644 --- a/app/views/issues/_action_menu.html.erb +++ b/app/views/issues/_action_menu.html.erb @@ -1,7 +1,7 @@

    -<%= link_to l(:button_edit), edit_issue_path(@issue), :onclick => 'showAndScrollTo("update", "issue_notes"); return false;', :class => 'icon icon-edit', :accesskey => accesskey(:edit) if @issue.editable? %> -<%= link_to l(:button_log_time), new_issue_time_entry_path(@issue), :class => 'icon icon-time-add' if User.current.allowed_to?(:log_time, @project) %> +<%= link_to fa_icon("pencil", :text => l(:button_edit)), edit_issue_path(@issue), :onclick => 'showAndScrollTo("update", "issue_notes"); return false;', :class => 'icon', :accesskey => accesskey(:edit) if @issue.editable? %> +<%= link_to fa_icon("clock-o", :text => l(:button_log_time)), new_issue_time_entry_path(@issue), :class => 'icon' if User.current.allowed_to?(:log_time, @project) %> <%= watcher_link(@issue, User.current) %> -<%= link_to l(:button_copy), project_copy_issue_path(@project, @issue), :class => 'icon icon-copy' if User.current.allowed_to?(:copy_issues, @project) && Issue.allowed_target_projects.any? %> -<%= link_to l(:button_delete), issue_path(@issue), :data => {:confirm => issues_destroy_confirmation_message(@issue)}, :method => :delete, :class => 'icon icon-del' if @issue.deletable? %> +<%= link_to fa_icon("clone", :text => l(:button_copy)), project_copy_issue_path(@project, @issue), :class => 'icon' if User.current.allowed_to?(:copy_issues, @project) && Issue.allowed_target_projects.any? %> +<%= link_to fa_icon("trash", :text => l(:button_delete)), issue_path(@issue), :data => {:confirm => issues_destroy_confirmation_message(@issue)}, :method => :delete, :class => 'icon' if @issue.deletable? %>
    diff --git a/app/views/issues/_relations.html.erb b/app/views/issues/_relations.html.erb index dcf0795..ec11f48 100644 --- a/app/views/issues/_relations.html.erb +++ b/app/views/issues/_relations.html.erb @@ -19,13 +19,13 @@ <%= other_issue.status.name %> <%= format_date(other_issue.start_date) %> <%= format_date(other_issue.due_date) %> - <%= link_to(l(:label_relation_delete), + <%= link_to(fa_icon("chain-broken", :text => l(:label_relation_delete), :icon_only => true), relation_path(relation), :remote => true, :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :title => l(:label_relation_delete), - :class => 'icon-only icon-link-break' + :class => 'icon' ) if User.current.allowed_to?(:manage_issue_relations, @project) %> <% end %> diff --git a/app/views/issues/show.html.erb b/app/views/issues/show.html.erb index 2cbff32..a0c65d6 100644 --- a/app/views/issues/show.html.erb +++ b/app/views/issues/show.html.erb @@ -37,7 +37,6 @@ <%= issue_fields_rows do |rows| rows.left l(:field_status), @issue.status.name, :class => 'status' rows.left l(:field_priority), @issue.priority.name, :class => 'priority' - unless @issue.disabled_core_fields.include?('assigned_to_id') rows.left l(:field_assigned_to), avatar(@issue.assigned_to, :size => "14").to_s.html_safe + (@issue.assigned_to ? link_to_user(@issue.assigned_to) : "-"), :class => 'assigned-to' end @@ -47,7 +46,6 @@ unless @issue.disabled_core_fields.include?('fixed_version_id') || (@issue.fixed_version.nil? && @issue.assignable_versions.none?) rows.left l(:field_fixed_version), (@issue.fixed_version ? link_to_version(@issue.fixed_version) : "-"), :class => 'fixed-version' end - unless @issue.disabled_core_fields.include?('start_date') rows.right l(:field_start_date), format_date(@issue.start_date), :class => 'start-date' end @@ -77,7 +75,7 @@ end %> <% if @issue.description? %>
    - <%= link_to l(:button_quote), quoted_issue_path(@issue), :remote => true, :method => 'post', :class => 'icon icon-comment' if @issue.notes_addable? %> + <%= link_to fa_icon("quote-left", :text => l(:button_quote)), quoted_issue_path(@issue), :remote => true, :method => 'post', :class => 'icon' if @issue.notes_addable? %>

    <%=l(:field_description)%>

    diff --git a/app/views/layouts/base.html.erb b/app/views/layouts/base.html.erb index 6c5a9b2..7dbbdc1 100644 --- a/app/views/layouts/base.html.erb +++ b/app/views/layouts/base.html.erb @@ -16,6 +16,7 @@ <%= call_hook :view_layouts_base_html_head %> <%= yield :header_tags -%> + <%= call_hook :view_layouts_base_body_top %> diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index da89fe2..2cc55df 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -1128,13 +1128,7 @@ a.close-icon:hover {background-image:url('../images/close_hl.png');} .version-overdue a, .issue-overdue a, .project-overdue a {color: #f00;} /***** Icons *****/ -.icon { - background-position: 0% 50%; - background-repeat: no-repeat; - padding-left: 20px; - padding-top: 2px; - padding-bottom: 3px; -} +.icon {} .icon-only { background-position: 0% 50%; background-repeat: no-repeat; @@ -1387,3 +1381,7 @@ color: #555; text-shadow: 1px 1px 0 #fff; height:1px; overflow:hidden; } + +a.icon i.fa { + font-size: 13px; +}