Feature #23980 » 0003-Support-expand-collapse-with-svg-icons.patch
app/controllers/icon_sets_controller.rb | ||
---|---|---|
1 |
# frozen_string_literal: true |
|
2 | ||
3 |
# Redmine - project management software |
|
4 |
# Copyright (C) 2006-2022 Jean-Philippe Lang |
|
5 |
# |
|
6 |
# This program is free software; you can redistribute it and/or |
|
7 |
# modify it under the terms of the GNU General Public License |
|
8 |
# as published by the Free Software Foundation; either version 2 |
|
9 |
# of the License, or (at your option) any later version. |
|
10 |
# |
|
11 |
# This program is distributed in the hope that it will be useful, |
|
12 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14 |
# GNU General Public License for more details. |
|
15 |
# |
|
16 |
# You should have received a copy of the GNU General Public License |
|
17 |
# along with this program; if not, write to the Free Software |
|
18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
19 | ||
20 |
class IconSetsController < ApplicationController |
|
21 |
def show |
|
22 |
icons = fetch(params[:id]) |
|
23 |
if icons.present? |
|
24 |
render :json => icons, :content_type => 'application/json' |
|
25 |
else |
|
26 |
render_404 |
|
27 |
end |
|
28 |
end |
|
29 | ||
30 |
private |
|
31 | ||
32 |
def fetch(name) |
|
33 |
IconSet.fetch(name) |
|
34 |
end |
|
35 |
end |
app/views/calendars/show.html.erb | ||
---|---|---|
8 | 8 |
<div id="query_form_with_buttons" class="hide-when-print"> |
9 | 9 |
<div id="query_form_content"> |
10 | 10 |
<fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>"> |
11 |
<legend onclick="toggleFieldset(this);" class="icon icon-<%= @query.new_record? ? "expanded" : "collapsed" %>"><%= l(:label_filter_plural) %></legend>
|
|
11 |
<%= tag.legend l(:label_filter_plural), onclick: "toggleFieldset(this);", class: collapsible(@query.new_record?) %>
|
|
12 | 12 |
<div style="<%= @query.new_record? ? "" : "display: none;" %>"> |
13 | 13 |
<%= render :partial => 'queries/filters', :locals => {:query => @query} %> |
14 | 14 |
</div> |
app/views/gantts/show.html.erb | ||
---|---|---|
14 | 14 |
<div id="query_form_with_buttons" class="hide-when-print"> |
15 | 15 |
<div id="query_form_content"> |
16 | 16 |
<fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>"> |
17 |
<legend onclick="toggleFieldset(this);" class="icon icon-<%= @query.new_record? ? "expanded" : "collapsed" %>"><%= l(:label_filter_plural) %></legend>
|
|
17 |
<%= tag.legend l(:label_filter_plural), onclick: 'toggleFieldset(this);', class: collapsible(@query.new_record?) %>
|
|
18 | 18 |
<div style="<%= @query.new_record? ? "" : "display: none;" %>"> |
19 | 19 |
<%= render :partial => 'queries/filters', :locals => {:query => @query} %> |
20 | 20 |
</div> |
21 | 21 |
</fieldset> |
22 | 22 | |
23 | 23 |
<fieldset id="options" class="collapsible collapsed"> |
24 |
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_options) %></legend>
|
|
24 |
<%= tag.legend l(:label_options), onclick: 'toggleFieldset(this);', class: 'icon icon-collapsed' %>
|
|
25 | 25 |
<div style="display: none;"> |
26 | 26 |
<table> |
27 | 27 |
<tr> |
app/views/imports/_issues_mapping.html.erb | ||
---|---|---|
6 | 6 |
</fieldset> |
7 | 7 | |
8 | 8 |
<fieldset class="box tabular collapsible collapsed"> |
9 |
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_relations_mapping) %></legend>
|
|
9 |
<%= tag.legend l(:label_relations_mapping), onclick: 'toggleFieldset(this);', class: 'icon icon-collapsed' %>
|
|
10 | 10 |
<div id="relations-mapping" style="display: none;"> |
11 | 11 |
<%= render :partial => 'issues_relations_mapping' %> |
12 | 12 |
</div> |
app/views/issues/_list.html.erb | ||
---|---|---|
24 | 24 |
<% reset_cycle %> |
25 | 25 |
<tr class="group open"> |
26 | 26 |
<td colspan="<%= query.inline_columns.size + 2 %>"> |
27 |
<span class="expander icon icon-expanded" onclick="toggleRowGroup(this);"> </span>
|
|
27 |
<%= expander %>
|
|
28 | 28 |
<span class="name"><%= group_name %></span> <span class="badge badge-count count"><%= group_count %></span> <span class="totals"><%= group_totals %></span> |
29 | 29 |
<%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}", |
30 | 30 |
"toggleAllRowGroups(this)", :class => 'toggle-all') %> |
app/views/layouts/base.html.erb | ||
---|---|---|
14 | 14 |
<%= javascript_heads %> |
15 | 15 |
<%= heads_for_theme %> |
16 | 16 |
<%= heads_for_auto_complete(@project) %> |
17 |
<%= preload_icon_link('common') %> |
|
17 | 18 |
<%= call_hook :view_layouts_base_html_head %> |
18 | 19 |
<!-- page specific tags --> |
19 | 20 |
<%= yield :header_tags -%> |
app/views/projects/_list.html.erb | ||
---|---|---|
14 | 14 |
<% reset_cycle %> |
15 | 15 |
<tr class="group open"> |
16 | 16 |
<td colspan="<%= @query.inline_columns.size %>"> |
17 |
<span class="expander icon icon-expanded" onclick="toggleRowGroup(this);"> </span>
|
|
17 |
<%= expander %>
|
|
18 | 18 |
<span class="name"><%= group_name %></span> |
19 | 19 |
<% if group_count %> |
20 | 20 |
<span class="count"><%= group_count %></span> |
app/views/queries/_query_form.html.erb | ||
---|---|---|
5 | 5 |
<div id="query_form_with_buttons" class="hide-when-print"> |
6 | 6 |
<div id="query_form_content"> |
7 | 7 |
<fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>"> |
8 |
<legend onclick="toggleFieldset(this);" class="icon icon-<%= @query.new_record? ? "expanded" : "collapsed" %>"><%= l(:label_filter_plural) %></legend>
|
|
8 |
<%= content_tag('legend', l(:label_filter_plural), :onclick => "toggleFieldset(this);", :class => collapsible(@query.new_record?)) %>
|
|
9 | 9 |
<div style="<%= @query.new_record? ? "" : "display: none;" %>"> |
10 | 10 |
<%= render :partial => 'queries/filters', :locals => {:query => @query} %> |
11 | 11 |
</div> |
... | ... | |
13 | 13 | |
14 | 14 |
<% if @query.available_columns.any? %> |
15 | 15 |
<fieldset id="options" class="collapsible collapsed"> |
16 |
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_options) %></legend>
|
|
16 |
<%= tag.legend l(:label_options), onclick: 'toggleFieldset(this);', class: 'icon icon-collapsed' %>
|
|
17 | 17 |
<div class="hidden"> |
18 | 18 |
<% if @query.available_display_types.size > 1 %> |
19 | 19 |
<div> |
app/views/repositories/_dir_list_content.html.erb | ||
---|---|---|
7 | 7 |
<td style="padding-left: <%=18 * depth%>px;" class="<%= |
8 | 8 |
@repository.report_last_commit ? "filename" : "filename_no_report" %>"> |
9 | 9 |
<% if entry.is_dir? %> |
10 |
<span class="expander icon icon-collapsed" onclick="scmEntryClick('<%= tr_id %>', '<%= escape_javascript(url_for(
|
|
11 |
:action => 'show',
|
|
12 |
:id => @project,
|
|
13 |
:repository_id => @repository.identifier_param,
|
|
14 |
:path => to_path_param(ent_path),
|
|
15 |
:rev => @rev,
|
|
16 |
:depth => (depth + 1),
|
|
17 |
:parent_id => tr_id)) %>');"> </span>
|
|
10 |
<% url = url_for(:action => 'show',
|
|
11 |
:id => @project,
|
|
12 |
:repository_id => @repository.identifier_param,
|
|
13 |
:path => to_path_param(ent_path),
|
|
14 |
:rev => @rev,
|
|
15 |
:depth => (depth + 1),
|
|
16 |
:parent_id => tr_id) %>
|
|
17 |
<%= tag.span ' ', class: 'expander icon icon-collapsed', onclick: "scmEntryClick('#{tr_id}', '#{escape_javascript(url)}')" %>
|
|
18 | 18 |
<% end %> |
19 | 19 |
<%= link_to ent_name, |
20 | 20 |
{:action => (entry.is_dir? ? 'show' : 'entry'), :id => @project, :repository_id => @repository.identifier_param, :path => to_path_param(ent_path), :rev => @rev}, |
app/views/roles/permissions.html.erb | ||
---|---|---|
2 | 2 | |
3 | 3 |
<div class="hide-when-print"> |
4 | 4 |
<fieldset id="filters" class="collapsible collapsed"> |
5 |
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_filter_plural) %></legend>
|
|
5 |
<%= tag.legend l(:label_filter_plural), onclick: 'toggleFieldset(this);', class: 'icon icon-collapsed' %>
|
|
6 | 6 |
<div style="display: none;"> |
7 | 7 |
<%= form_tag({}, :method => :get) do %> |
8 | 8 |
<fieldset> |
... | ... | |
49 | 49 |
<% unless mod.blank? %> |
50 | 50 |
<tr class="group open"> |
51 | 51 |
<td> |
52 |
<span class="expander icon icon-expanded" onclick="toggleRowGroup(this);"> </span>
|
|
52 |
<%= expander %>
|
|
53 | 53 |
<%= l_or_humanize(mod, :prefix => 'project_module_') %> |
54 | 54 |
</td> |
55 | 55 |
<% @roles.each do |role| %> |
app/views/search/index.html.erb | ||
---|---|---|
24 | 24 |
</fieldset> |
25 | 25 | |
26 | 26 |
<fieldset class="collapsible collapsed"> |
27 |
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_options) %></legend>
|
|
27 |
<%= tag.legend l(:label_options), onclick: 'toggleFieldset(this);', class: 'icon icon-collapsed' %>
|
|
28 | 28 |
<div id="options-content" style="display:none;"> |
29 | 29 |
<p><label><%= check_box_tag 'open_issues', 1, @open_issues %> <%= l(:label_search_open_issues_only) %></label></p> |
30 | 30 |
<p> |
app/views/timelog/_list.html.erb | ||
---|---|---|
20 | 20 |
<% reset_cycle %> |
21 | 21 |
<tr class="group open"> |
22 | 22 |
<td colspan="<%= @query.inline_columns.size + 2 %>"> |
23 |
<span class="expander icon icon-expanded" onclick="toggleRowGroup(this);"> </span>
|
|
23 |
<%= expander %>
|
|
24 | 24 |
<span class="name"><%= group_name %></span> |
25 | 25 |
<% if group_count %> |
26 | 26 |
<span class="badge badge-count count"><%= group_count %></span> |
app/views/trackers/fields.html.erb | ||
---|---|---|
20 | 20 |
<tbody> |
21 | 21 |
<tr class="group open"> |
22 | 22 |
<td colspan="<%= @trackers.size + 1 %>"> |
23 |
<span class="expander icon icon-expanded" onclick="toggleRowGroup(this);"> </span>
|
|
23 |
<%= expander %>
|
|
24 | 24 |
<%= l(:field_core_fields) %> |
25 | 25 |
</td> |
26 | 26 |
</tr> |
... | ... | |
44 | 44 |
<% if @custom_fields.any? %> |
45 | 45 |
<tr class="group open"> |
46 | 46 |
<td colspan="<%= @trackers.size + 1 %>"> |
47 |
<span class="expander icon icon-expanded" onclick="toggleRowGroup(this);"> </span>
|
|
47 |
<%= expander %>
|
|
48 | 48 |
<%= l(:label_custom_field_plural) %> |
49 | 49 |
</td> |
50 | 50 |
</tr> |
app/views/wiki/show.html.erb | ||
---|---|---|
62 | 62 |
<%= render(:partial => "wiki/content", :locals => {:content => @content}) %> |
63 | 63 | |
64 | 64 |
<fieldset class="collapsible collapsed hide-when-print"> |
65 |
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_attachment_plural) %> (<%= @page.attachments.length %>)</legend>
|
|
65 |
<%= tag.legend "#{l(:label_attachment_plural)} (#{@page.attachments.length})", onclick: 'toggleFieldset(this);', class: 'icon icon-collapsed' %>
|
|
66 | 66 |
<div style="display: none;"> |
67 | 67 | |
68 | 68 |
<%= link_to_attachments @page, :thumbnails => true %> |
app/views/workflows/edit.html.erb | ||
---|---|---|
40 | 40 |
<%= render :partial => 'form', :locals => {:name => 'always', :workflows => @workflows['always']} %> |
41 | 41 | |
42 | 42 |
<fieldset class="collapsible" style="padding: 0; margin-top: 0.5em;"> |
43 |
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_additional_workflow_transitions_for_author) %></legend>
|
|
43 |
<%= tag.legend l(:label_additional_workflow_transitions_for_author), onclick: 'toggleFieldset(this);', class: 'icon icon-collapsed' %>
|
|
44 | 44 |
<div id="author_workflows" style="margin: 0.5em 0 0.5em 0;"> |
45 | 45 |
<%= render :partial => 'form', :locals => {:name => 'author', :workflows => @workflows['author']} %> |
46 | 46 |
</div> |
... | ... | |
48 | 48 |
<%= javascript_tag "hideFieldset($('#author_workflows'))" unless @workflows['author'].present? %> |
49 | 49 | |
50 | 50 |
<fieldset class="collapsible" style="padding: 0;"> |
51 |
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_additional_workflow_transitions_for_assignee) %></legend>
|
|
51 |
<%= tag.legend l(:label_additional_workflow_transitions_for_assignee), onclick: 'toggleFieldset(this);', class: 'icon icon-collapsed' %>
|
|
52 | 52 |
<div id="assignee_workflows" style="margin: 0.5em 0 0.5em 0;"> |
53 | 53 |
<%= render :partial => 'form', :locals => {:name => 'assignee', :workflows => @workflows['assignee']} %> |
54 | 54 |
</div> |
app/views/workflows/permissions.html.erb | ||
---|---|---|
54 | 54 |
<tbody> |
55 | 55 |
<tr class="group open"> |
56 | 56 |
<td colspan="<%= @statuses.size + 1 %>"> |
57 |
<span class="expander icon icon-expanded" onclick="toggleRowGroup(this);"> </span>
|
|
57 |
<%= expander %>
|
|
58 | 58 |
<%= l(:field_core_fields) %> |
59 | 59 |
</td> |
60 | 60 |
</tr> |
... | ... | |
74 | 74 |
<% if @custom_fields.any? %> |
75 | 75 |
<tr class="group open"> |
76 | 76 |
<td colspan="<%= @statuses.size + 1 %>"> |
77 |
<span class="expander icon icon-expanded" onclick="toggleRowGroup(this);"> </span>
|
|
77 |
<%= expander %>
|
|
78 | 78 |
<%= l(:label_custom_field_plural) %> |
79 | 79 |
</td> |
80 | 80 |
</tr> |
config/routes.rb | ||
---|---|---|
395 | 395 | |
396 | 396 |
get 'robots', :to => 'welcome#robots' |
397 | 397 | |
398 |
# SVG icons map |
|
399 |
resources :icon_sets, id: '/^[a-z]+$/', only: [:show], defaults: { :format => :json } |
|
400 | ||
398 | 401 |
Dir.glob File.expand_path("#{Redmine::Plugin.directory}/*") do |plugin_dir| |
399 | 402 |
file = File.join(plugin_dir, "config/routes.rb") |
400 | 403 |
if File.exist?(file) |
public/javascripts/application.js | ||
---|---|---|
27 | 27 |
$('html, body').animate({scrollTop: $('#'+id).offset().top}, 100); |
28 | 28 |
} |
29 | 29 | |
30 |
/** |
|
31 |
* |
|
32 |
* @param {HTMLElement} elem |
|
33 |
*/ |
|
34 |
function addSVGIcon(elem, iconClass) { |
|
35 |
if (rm.icons && rm.icons.common) { |
|
36 |
const data = rm.icons.common; |
|
37 |
const svg = createSVGIcon(data[iconClass]); |
|
38 |
elem.insertBefore(svg, elem.firstChild); |
|
39 |
} |
|
40 |
} |
|
41 | ||
42 |
/** |
|
43 |
* |
|
44 |
* @param {HTMLElement} elem |
|
45 |
*/ |
|
46 |
function removeSVGIcon(elem) { |
|
47 |
const icon = elem.getElementsByTagName('svg')[0] |
|
48 |
if (icon) { |
|
49 |
elem.removeChild(icon); |
|
50 |
} |
|
51 |
} |
|
52 | ||
53 |
/** |
|
54 |
* |
|
55 |
* @param {string} iconUrl |
|
56 |
* @returns HTMLElement |
|
57 |
*/ |
|
58 |
function createSVGIcon(iconUrl) { |
|
59 |
const xmlns = "http://www.w3.org/2000/svg"; |
|
60 |
const svg = document.createElementNS(xmlns, 'svg'); |
|
61 |
const use = document.createElementNS(xmlns, 'use'); |
|
62 |
use.setAttribute('href', `${iconUrl}#icon`); |
|
63 |
svg.appendChild(use); |
|
64 |
svg.setAttribute('xmlns', xmlns) |
|
65 |
svg.classList.add('s16'); |
|
66 |
return svg |
|
67 |
} |
|
68 | ||
69 |
/** |
|
70 |
* |
|
71 |
* @param {Array<HTMLElement>} elems |
|
72 |
* @param {string} from |
|
73 |
* @param {string} to |
|
74 |
*/ |
|
75 |
function switchClass(elems, from, to) { |
|
76 |
elems.forEach(function(e) { |
|
77 |
e.classList.remove(from); |
|
78 |
removeSVGIcon(e); |
|
79 |
e.classList.add(to); |
|
80 |
addSVGIcon(e, to) |
|
81 |
}) |
|
82 |
} |
|
83 | ||
84 |
/** |
|
85 |
* |
|
86 |
* @param {Array<HTMLElement>} elems |
|
87 |
* @param {string} class1 |
|
88 |
* @param {string} class2 |
|
89 |
*/ |
|
90 |
function toggleClass(elems, class1, class2) { |
|
91 |
const _elems = Array.isArray(elems) ? elems : [elems]; |
|
92 |
_elems.forEach(function(e) { |
|
93 |
removeSVGIcon(e); |
|
94 |
if (e.classList.contains(class1)) { |
|
95 |
e.classList.remove(class1); |
|
96 |
e.classList.add(class2); |
|
97 |
addSVGIcon(e, class2); |
|
98 |
} else if (e.classList.contains(class2)) { |
|
99 |
e.classList.remove(class2); |
|
100 |
e.classList.add(class1); |
|
101 |
addSVGIcon(e, class1); |
|
102 |
} |
|
103 |
}) |
|
104 |
} |
|
105 | ||
30 | 106 |
function toggleRowGroup(el) { |
31 | 107 |
var tr = $(el).parents('tr').first(); |
32 | 108 |
var n = tr.next(); |
33 | 109 |
tr.toggleClass('open'); |
34 |
$(el).toggleClass('icon-expanded icon-collapsed');
|
|
110 |
toggleClass(el, 'icon-expanded', 'icon-collapsed');
|
|
35 | 111 |
while (n.length && !n.hasClass('group')) { |
36 | 112 |
n.toggle(); |
37 | 113 |
n = n.next('tr'); |
... | ... | |
43 | 119 |
tbody.children('tr').each(function(index) { |
44 | 120 |
if ($(this).hasClass('group')) { |
45 | 121 |
$(this).removeClass('open'); |
46 |
$(this).find('.expander').switchClass('icon-expanded', 'icon-collapsed');
|
|
122 |
switchClass($(this).find('.expander').get(), 'icon-expanded', 'icon-collapsed');
|
|
47 | 123 |
} else { |
48 | 124 |
$(this).hide(); |
49 | 125 |
} |
... | ... | |
55 | 131 |
tbody.children('tr').each(function(index) { |
56 | 132 |
if ($(this).hasClass('group')) { |
57 | 133 |
$(this).addClass('open'); |
58 |
$(this).find('.expander').switchClass('icon-collapsed', 'icon-expanded');
|
|
134 |
switchClass($(this).find('.expander').get(), 'icon-collapsed', 'icon-expanded');
|
|
59 | 135 |
} else { |
60 | 136 |
$(this).show(); |
61 | 137 |
} |
... | ... | |
74 | 150 |
function toggleFieldset(el) { |
75 | 151 |
var fieldset = $(el).parents('fieldset').first(); |
76 | 152 |
fieldset.toggleClass('collapsed'); |
77 |
fieldset.children('legend').toggleClass('icon-expanded icon-collapsed');
|
|
153 |
toggleClass(fieldset.children('legend').get(), 'icon-expanded', 'icon-collapsed');
|
|
78 | 154 |
fieldset.children('div').toggle(); |
79 | 155 |
} |
80 | 156 | |
... | ... | |
550 | 626 |
var el = $('#'+id); |
551 | 627 |
if (el.hasClass('open')) { |
552 | 628 |
collapseScmEntry(id); |
553 |
el.find('.expander').switchClass('icon-expanded', 'icon-collapsed');
|
|
629 |
switchClass(el.find('.expander').get(), 'icon-expanded', 'icon-collapsed');
|
|
554 | 630 |
el.addClass('collapsed'); |
555 | 631 |
return false; |
556 | 632 |
} else if (el.hasClass('loaded')) { |
557 | 633 |
expandScmEntry(id); |
558 |
el.find('.expander').switchClass('icon-collapsed', 'icon-expanded');
|
|
634 |
switchClass(el.find('.expander').get(), 'icon-collapsed', 'icon-expanded');
|
|
559 | 635 |
el.removeClass('collapsed'); |
560 | 636 |
return false; |
561 | 637 |
} |
... | ... | |
568 | 644 |
success: function(data) { |
569 | 645 |
el.after(data); |
570 | 646 |
el.addClass('open').addClass('loaded').removeClass('loading'); |
571 |
el.find('.expander').switchClass('icon-collapsed', 'icon-expanded');
|
|
647 |
switchClass(el.find('.expander').get(), 'icon-collapsed', 'icon-expanded');
|
|
572 | 648 |
} |
573 | 649 |
}); |
574 | 650 |
return true; |
... | ... | |
1219 | 1295 |
tribute.attach(element); |
1220 | 1296 |
} |
1221 | 1297 | |
1222 | ||
1223 | 1298 |
$(document).ready(setupAjaxIndicator); |
1224 | 1299 |
$(document).ready(hideOnLoad); |
1225 | 1300 |
$(document).ready(addFormObserversForDoubleSubmit); |
... | ... | |
1231 | 1306 |
$(document).on('focus', '[data-auto-complete=true]', function(event) { |
1232 | 1307 |
inlineAutoComplete(event.target); |
1233 | 1308 |
}); |
1309 | ||
1310 |
window.addEventListener('DOMContentLoaded', function(event) { |
|
1311 |
const common_icon_path = document.getElementById('common_icon_path'); |
|
1312 |
if (common_icon_path !== null) { |
|
1313 |
const url = common_icon_path.getAttribute('href'); |
|
1314 |
fetch(url, { |
|
1315 |
method: 'GET' |
|
1316 |
}) |
|
1317 |
.then(function(response){ |
|
1318 |
response.json().then(function(data) { |
|
1319 |
rm.icons = rm.icons || {} |
|
1320 |
rm.icons.common = data; |
|
1321 |
}) |
|
1322 |
}); |
|
1323 |
} |
|
1324 |
}); |