Feature #23980 » font_awesome_icons.patch
Gemfile | ||
---|---|---|
18 | 18 |
# Request at least nokogiri 1.6.7.2 because of security advisories |
19 | 19 |
gem "nokogiri", ">= 1.6.7.2" |
20 | 20 | |
21 |
# Request at least rails-html-sanitizer 1.0.3 because of security advisories
|
|
21 |
# Request at least rails-html-sanitizer 1.0.3 because of security advisories |
|
22 | 22 |
gem "rails-html-sanitizer", ">= 1.0.3" |
23 | 23 | |
24 | 24 |
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem |
app/helpers/application_helper.rb | ||
---|---|---|
1358 | 1358 |
encoding = l(:general_csv_encoding) |
1359 | 1359 |
end |
1360 | 1360 | |
1361 |
# Creates an icon tag given an icon name and possible icon |
|
1362 |
# modifiers. |
|
1363 |
# |
|
1364 |
# Examples |
|
1365 |
# |
|
1366 |
# fa_icon "camera-retro" |
|
1367 |
# # => <i class="fa fa-camera-retro"></i> |
|
1368 |
# |
|
1369 |
# fa_icon "camera-retro", text: "Take a photo" |
|
1370 |
# # => <i class="fa fa-camera-retro"></i> Take a photo |
|
1371 |
# fa_icon "chevron-right", text: "Get started", right: true |
|
1372 |
# # => Get started <i class="fa fa-chevron-right"></i> |
|
1373 |
# |
|
1374 |
# fa_icon "camera-retro 2x" |
|
1375 |
# # => <i class="fa fa-camera-retro fa-2x"></i> |
|
1376 |
# fa_icon ["camera-retro", "4x"] |
|
1377 |
# # => <i class="fa fa-camera-retro fa-4x"></i> |
|
1378 |
# fa_icon "spinner spin lg" |
|
1379 |
# # => <i class="fa fa-spinner fa-spin fa-lg"> |
|
1380 |
# |
|
1381 |
# fa_icon "quote-left 4x", class: "pull-left" |
|
1382 |
# # => <i class="fa fa-quote-left fa-4x pull-left"></i> |
|
1383 |
# |
|
1384 |
# fa_icon "user", data: { id: 123 } |
|
1385 |
# # => <i class="fa fa-user" data-id="123"></i> |
|
1386 |
# |
|
1387 |
# content_tag(:li, fa_icon("check li", text: "Bulleted list item")) |
|
1388 |
# # => <li><i class="fa fa-check fa-li"></i> Bulleted list item</li> |
|
1389 |
def fa_icon(names = "flag", options = {}) |
|
1390 |
classes = ["fa"] |
|
1391 |
classes.concat icon_names(names) |
|
1392 |
classes.concat Array(options.delete(:class)) |
|
1393 |
text = options.delete(:text) |
|
1394 |
icon_only = options.delete(:icon_only) |
|
1395 |
right_icon = options.delete(:right) |
|
1396 |
icon = content_tag(:i, nil, options.merge(:class => classes)) |
|
1397 |
icon_join(icon, text, right_icon, icon_only) |
|
1398 |
end |
|
1399 | ||
1400 |
# Creates an stack set of icon tags given a base icon name, a main icon |
|
1401 |
# name, and possible icon modifiers. |
|
1402 |
# |
|
1403 |
# Examples |
|
1404 |
# |
|
1405 |
# fa_stacked_icon "twitter", base: "square-o" |
|
1406 |
# # => <span class="fa-stack"> |
|
1407 |
# # => <i class="fa fa-square-o fa-stack-2x"></i> |
|
1408 |
# # => <i class="fa fa-twitter fa-stack-1x"></i> |
|
1409 |
# # => </span> |
|
1410 |
# |
|
1411 |
# fa_stacked_icon "terminal inverse", base: "square", class: "pull-right", text: "Hi!" |
|
1412 |
# # => <span class="fa-stack pull-right"> |
|
1413 |
# # => <i class="fa fa-square fa-stack-2x"></i> |
|
1414 |
# # => <i class="fa fa-terminal fa-inverse fa-stack-1x"></i> |
|
1415 |
# # => </span> Hi! |
|
1416 |
# |
|
1417 |
# fa_stacked_icon "camera", base: "ban-circle", reverse: true |
|
1418 |
# # => <span class="fa-stack"> |
|
1419 |
# # => <i class="fa fa-camera fa-stack-1x"></i> |
|
1420 |
# # => <i class="fa fa-ban-circle fa-stack-2x"></i> |
|
1421 |
# # => </span> |
|
1422 |
def fa_stacked_icon(names = "flag", options = {}) |
|
1423 |
classes = icon_names("stack").concat(Array(options.delete(:class))) |
|
1424 |
base_names = array_value(options.delete(:base) || "square-o").push("stack-2x") |
|
1425 |
names = array_value(names).push("stack-1x") |
|
1426 |
base = fa_icon(base_names, options.delete(:base_options) || {}) |
|
1427 |
icon = fa_icon(names, options.delete(:icon_options) || {}) |
|
1428 |
icons = [base, icon] |
|
1429 |
icons.reverse! if options.delete(:reverse) |
|
1430 |
text = options.delete(:text) |
|
1431 |
right_icon = options.delete(:right) |
|
1432 |
icon_only = options.delete(:icon_only) |
|
1433 |
stacked_icon = content_tag(:span, safe_join(icons), options.merge(:class => classes)) |
|
1434 |
icon_join(stacked_icon, text, right_icon, icon_only) |
|
1435 |
end |
|
1436 | ||
1361 | 1437 |
private |
1362 | 1438 | |
1363 | 1439 |
def wiki_helper |
... | ... | |
1365 | 1441 |
extend helper |
1366 | 1442 |
return self |
1367 | 1443 |
end |
1444 | ||
1445 |
def icon_join(icon, text, reverse_order = false, icon_only = false) |
|
1446 |
return icon if text.blank? |
|
1447 |
text = icon_only ? content_tag("span", text, :class => "sr-only") : ERB::Util.html_escape(text) |
|
1448 |
elements = [icon, text] |
|
1449 |
elements.reverse! if reverse_order |
|
1450 |
safe_join(elements, " ") |
|
1451 |
end |
|
1452 | ||
1453 |
def icon_names(names = []) |
|
1454 |
array_value(names).map { |n| "fa-#{n}" } |
|
1455 |
end |
|
1456 | ||
1457 |
def array_value(value = []) |
|
1458 |
value.is_a?(Array) ? value : value.to_s.split(/\s+/) |
|
1459 |
end |
|
1368 | 1460 |
end |
app/helpers/journals_helper.rb | ||
---|---|---|
30 | 30 |
css_classes = "wiki" |
31 | 31 |
links = [] |
32 | 32 |
if journal.notes.present? |
33 |
links << link_to(l(:button_quote),
|
|
33 |
links << link_to(fa_icon("quote-left", :text => l(:label_quote), :icon_only => true),
|
|
34 | 34 |
quoted_issue_path(issue, :journal_id => journal), |
35 | 35 |
:remote => true, |
36 | 36 |
:method => 'post', |
37 | 37 |
:title => l(:button_quote), |
38 |
:class => 'icon-only icon-comment'
|
|
38 |
:class => 'icon' |
|
39 | 39 |
) if options[:reply_links] |
40 | 40 | |
41 | 41 |
if journal.editable_by?(User.current) |
42 |
links << link_to(l(:button_edit),
|
|
42 |
links << link_to(fa_icon("pencil", :text => l(:label_edit), :icon_only => true),
|
|
43 | 43 |
edit_journal_path(journal), |
44 | 44 |
:remote => true, |
45 | 45 |
:method => 'get', |
46 | 46 |
:title => l(:button_edit), |
47 |
:class => 'icon-only icon-edit'
|
|
47 |
:class => 'icon' |
|
48 | 48 |
) |
49 |
links << link_to(l(:button_delete),
|
|
49 |
links << link_to(fa_icon("trash", :text => l(:label_delete), :icon_only => true),
|
|
50 | 50 |
journal_path(journal, :journal => {:notes => ""}), |
51 | 51 |
:remote => true, |
52 |
:method => 'put', :data => {:confirm => l(:text_are_you_sure)},
|
|
52 |
:method => 'put', :data => {:confirm => l(:text_are_you_sure)}, |
|
53 | 53 |
:title => l(:button_delete), |
54 |
:class => 'icon-only icon-del'
|
|
54 |
:class => 'icon' |
|
55 | 55 |
) |
56 | 56 |
css_classes << " editable" |
57 | 57 |
end |
app/helpers/watchers_helper.rb | ||
---|---|---|
25 | 25 |
return '' unless objects.any? |
26 | 26 | |
27 | 27 |
watched = Watcher.any_watched?(objects, user) |
28 |
css = [watcher_css(objects), watched ? 'icon icon-fav' : 'icon icon-fav-off'].join(' ')
|
|
29 |
text = watched ? l(:button_unwatch) : l(:button_watch)
|
|
28 |
css = [watcher_css(objects), watched ? 'icon' : 'icon'].join(' ')
|
|
29 |
text = watched ? fa_icon("star", :text => l(:button_unwatch)) : fa_icon("star-o", :text => l(:button_watch))
|
|
30 | 30 |
url = watch_path( |
31 | 31 |
:object_type => objects.first.class.to_s.underscore, |
32 | 32 |
:object_id => (objects.size == 1 ? objects.first.id : objects.map(&:id).sort) |
... | ... | |
58 | 58 |
:object_id => object.id, |
59 | 59 |
:user_id => user} |
60 | 60 |
s << ' ' |
61 |
s << link_to(l(:button_delete), url,
|
|
61 |
s << link_to(fa_icon("trash", :text => l(:button_delete), :icon_only => true), url,
|
|
62 | 62 |
:remote => true, :method => 'delete', |
63 |
:class => "delete icon-only icon-del",
|
|
63 |
:class => "delete icon", |
|
64 | 64 |
:title => l(:button_delete)) |
65 | 65 |
end |
66 | 66 |
content << content_tag('li', s, :class => "user-#{user.id}") |
app/views/attachments/_links.html.erb | ||
---|---|---|
1 | 1 |
<div class="attachments"> |
2 | 2 |
<div class="contextual"> |
3 |
<%= link_to(l(:label_edit_attachments),
|
|
3 |
<%= link_to(fa_icon("pencil", :text => l(:label_edit_attachments), :icon_only => true),
|
|
4 | 4 |
container_attachments_edit_path(container), |
5 | 5 |
:title => l(:label_edit_attachments), |
6 |
:class => 'icon-only icon-edit'
|
|
6 |
:class => 'icon' |
|
7 | 7 |
) if options[:editable] %> |
8 | 8 |
</div> |
9 | 9 |
<% for attachment in attachments %> |
10 |
<p><%= link_to_attachment attachment, :class => 'icon icon-attachment', :download => true -%>
|
|
10 |
<p><%= link_to_attachment attachment, :class => 'icon', :download => true -%> |
|
11 | 11 |
<% if attachment.is_text? || attachment.is_image? %> |
12 |
<%= link_to l(:button_view),
|
|
12 |
<%= link_to fa_icon("search", :text => l(:button_view), :icon_only => true),
|
|
13 | 13 |
{ :controller => 'attachments', :action => 'show', |
14 | 14 |
:id => attachment, :filename => attachment.filename }, |
15 |
:class => 'icon-only icon-magnifier',
|
|
15 |
:class => 'icon', |
|
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 l(:button_delete), attachment_path(attachment),
|
|
21 |
<%= link_to fa_icon("trash", :text => l(:button_delete), :icon_only => true), attachment_path(attachment),
|
|
22 | 22 |
:data => {:confirm => l(:text_are_you_sure)}, |
23 | 23 |
:method => :delete, |
24 |
:class => 'delete icon-only icon-del',
|
|
24 |
:class => 'delete icon', |
|
25 | 25 |
:title => l(:button_delete) %> |
26 | 26 |
<% end %> |
27 | 27 |
<% if options[:author] %> |
app/views/issues/_action_menu.html.erb | ||
---|---|---|
1 | 1 |
<div class="contextual"> |
2 |
<%= 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? %>
|
|
3 |
<%= 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) %>
|
|
2 |
<%= 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? %>
|
|
3 |
<%= 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) %>
|
|
4 | 4 |
<%= watcher_link(@issue, User.current) %> |
5 |
<%= 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? %>
|
|
6 |
<%= link_to l(:button_delete), issue_path(@issue), :data => {:confirm => issues_destroy_confirmation_message(@issue)}, :method => :delete, :class => 'icon icon-del' if @issue.deletable? %>
|
|
5 |
<%= 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? %>
|
|
6 |
<%= 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? %>
|
|
7 | 7 |
</div> |
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(l(:label_relation_delete),
|
|
22 |
<td class="buttons"><%= link_to(fa_icon("chain-broken", :text => l(:label_relation_delete), :icon_only => true),
|
|
23 | 23 |
relation_path(relation), |
24 | 24 |
:remote => true, |
25 | 25 |
:method => :delete, |
26 | 26 |
:data => {:confirm => l(:text_are_you_sure)}, |
27 | 27 |
:title => l(:label_relation_delete), |
28 |
:class => 'icon-only icon-link-break'
|
|
28 |
:class => 'icon' |
|
29 | 29 |
) if User.current.allowed_to?(:manage_issue_relations, @project) %></td> |
30 | 30 |
</tr> |
31 | 31 |
<% end %> |
app/views/issues/show.html.erb | ||
---|---|---|
37 | 37 |
<%= issue_fields_rows do |rows| |
38 | 38 |
rows.left l(:field_status), @issue.status.name, :class => 'status' |
39 | 39 |
rows.left l(:field_priority), @issue.priority.name, :class => 'priority' |
40 | ||
41 | 40 |
unless @issue.disabled_core_fields.include?('assigned_to_id') |
42 | 41 |
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' |
43 | 42 |
end |
... | ... | |
47 | 46 |
unless @issue.disabled_core_fields.include?('fixed_version_id') || (@issue.fixed_version.nil? && @issue.assignable_versions.none?) |
48 | 47 |
rows.left l(:field_fixed_version), (@issue.fixed_version ? link_to_version(@issue.fixed_version) : "-"), :class => 'fixed-version' |
49 | 48 |
end |
50 | ||
51 | 49 |
unless @issue.disabled_core_fields.include?('start_date') |
52 | 50 |
rows.right l(:field_start_date), format_date(@issue.start_date), :class => 'start-date' |
53 | 51 |
end |
... | ... | |
77 | 75 |
<% if @issue.description? %> |
78 | 76 |
<div class="description"> |
79 | 77 |
<div class="contextual"> |
80 |
<%= link_to l(:button_quote), quoted_issue_path(@issue), :remote => true, :method => 'post', :class => 'icon icon-comment' if @issue.notes_addable? %>
|
|
78 |
<%= link_to fa_icon("quote-left", :text => l(:button_quote)), quoted_issue_path(@issue), :remote => true, :method => 'post', :class => 'icon' if @issue.notes_addable? %>
|
|
81 | 79 |
</div> |
82 | 80 | |
83 | 81 |
<p><strong><%=l(:field_description)%></strong></p> |
app/views/layouts/base.html.erb | ||
---|---|---|
16 | 16 |
<%= call_hook :view_layouts_base_html_head %> |
17 | 17 |
<!-- page specific tags --> |
18 | 18 |
<%= yield :header_tags -%> |
19 |
<script src="https://use.fontawesome.com/185de4555c.js"></script> |
|
19 | 20 |
</head> |
20 | 21 |
<body class="<%= body_css_classes %>"> |
21 | 22 |
<%= call_hook :view_layouts_base_body_top %> |
public/stylesheets/application.css | ||
---|---|---|
1128 | 1128 |
.version-overdue a, .issue-overdue a, .project-overdue a {color: #f00;} |
1129 | 1129 | |
1130 | 1130 |
/***** Icons *****/ |
1131 |
.icon { |
|
1132 |
background-position: 0% 50%; |
|
1133 |
background-repeat: no-repeat; |
|
1134 |
padding-left: 20px; |
|
1135 |
padding-top: 2px; |
|
1136 |
padding-bottom: 3px; |
|
1137 |
} |
|
1131 |
.icon {} |
|
1138 | 1132 |
.icon-only { |
1139 | 1133 |
background-position: 0% 50%; |
1140 | 1134 |
background-repeat: no-repeat; |
... | ... | |
1387 | 1381 |
height:1px; |
1388 | 1382 |
overflow:hidden; |
1389 | 1383 |
} |
1384 | ||
1385 |
a.icon i.fa { |
|
1386 |
font-size: 13px; |
|
1387 |
} |