aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Petersen <public@petersendidit.com>2011-03-28 22:28:59 -0400
committerDavid Petersen <public@petersendidit.com>2011-03-28 22:28:59 -0400
commitc6a6ef5ee6ed026ed47a96030a341a8b08a201cf (patch)
tree18948b6be890c6c2269f2bd284fe7cca74408065
parent8b0c3618bdebddd98d4c09e77d14c50c4f4d3190 (diff)
downloadjquery-ui-c6a6ef5ee6ed026ed47a96030a341a8b08a201cf.tar.gz
jquery-ui-c6a6ef5ee6ed026ed47a96030a341a8b08a201cf.zip
Tabs: Deprecate select method. Fixes #7138 Tabs: Deprecate select method
-rw-r--r--tests/unit/tabs/tabs_deprecated.js30
-rw-r--r--tests/unit/tabs/tabs_events.js11
-rw-r--r--tests/unit/tabs/tabs_methods.js31
-rw-r--r--tests/unit/tabs/tabs_options.js10
-rw-r--r--tests/unit/tabs/tabs_tickets.js6
-rwxr-xr-xui/jquery.ui.tabs.js99
6 files changed, 110 insertions, 77 deletions
diff --git a/tests/unit/tabs/tabs_deprecated.js b/tests/unit/tabs/tabs_deprecated.js
index 38fa6db71..1abaa0b04 100644
--- a/tests/unit/tabs/tabs_deprecated.js
+++ b/tests/unit/tabs/tabs_deprecated.js
@@ -247,6 +247,36 @@ test('remove', function() {
equals(el.tabs('option', 'selected'), 0, 'update selected property');
});
+test('select', function() {
+ expect(6);
+
+ el = $('#tabs1').tabs();
+
+ el.tabs('select', 1);
+ equals(el.tabs('option', 'active'), 1, 'should select tab');
+
+ el.tabs('destroy');
+ el.tabs({ collapsible: true });
+ el.tabs('select', 0);
+ equals(el.tabs('option', 'active'), -1, 'should collapse tab passing in the already active tab');
+
+ el.tabs('destroy');
+ el.tabs({ collapsible: true });
+ el.tabs('select', -1);
+ equals(el.tabs('option', 'active'), -1, 'should collapse tab passing in -1');
+
+ el.tabs('destroy');
+ el.tabs();
+ el.tabs('select', 0);
+ equals(el.tabs('option', 'active'), 0, 'should not collapse tab if collapsible is not set to true');
+ el.tabs('select', -1);
+ equals(el.tabs('option', 'active'), 0, 'should not collapse tab if collapsible is not set to true');
+
+ el.tabs('select', '#fragment-2');
+ equals(el.tabs('option', 'active'), 1, 'should select tab by id');
+});
+
+
test('#5069 - ui.tabs.add creates two tab panels when using a full URL', function() {
// http://dev.jqueryui.com/ticket/5069
expect(2);
diff --git a/tests/unit/tabs/tabs_events.js b/tests/unit/tabs/tabs_events.js
index 4fedde842..381326533 100644
--- a/tests/unit/tabs/tabs_events.js
+++ b/tests/unit/tabs/tabs_events.js
@@ -8,7 +8,6 @@ module("tabs: events");
test('beforeActivate', function() {
expect(7);
- var eventObj;
el = $('#tabs1').tabs({
beforeActivate: function(event, ui) {
ok(true, 'beforeActivate triggered after initialization');
@@ -17,13 +16,17 @@ test('beforeActivate', function() {
equals(ui.tab, el.find('a')[1], 'contain tab as DOM anchor element');
equals(ui.panel, el.find('div')[1], 'contain panel as DOM div element');
equals(ui.index, 1, 'contain index');
- evenObj = event;
}
});
- el.tabs('select', 1);
+ el.tabs('option', 'active', 1);
+ el.tabs('destroy');
+ el.tabs({
+ beforeActivate: function(event, ui) {
+ equals( event.originalEvent.type, "click", "beforeActivate triggered by click" );
+ }
+ });
el.find( "li:eq(1) a" ).simulate( "click" );
- equals( evenObj.originalEvent.type, "click", "beforeActivate triggered by click" );
});
test('beforeload', function() {
diff --git a/tests/unit/tabs/tabs_methods.js b/tests/unit/tabs/tabs_methods.js
index dbb5c2d15..69dcc872e 100644
--- a/tests/unit/tabs/tabs_methods.js
+++ b/tests/unit/tabs/tabs_methods.js
@@ -130,35 +130,6 @@ test('disable', function() {
same(el.tabs('option', 'disabled'), true, 'set to true');
});
-test('select', function() {
- expect(6);
-
- el = $('#tabs1').tabs();
-
- el.tabs('select', 1);
- equals(el.tabs('option', 'active'), 1, 'should select tab');
-
- el.tabs('destroy');
- el.tabs({ collapsible: true });
- el.tabs('select', 0);
- equals(el.tabs('option', 'active'), -1, 'should collapse tab passing in the already active tab');
-
- el.tabs('destroy');
- el.tabs({ collapsible: true });
- el.tabs('select', -1);
- equals(el.tabs('option', 'active'), -1, 'should collapse tab passing in -1');
-
- el.tabs('destroy');
- el.tabs();
- el.tabs('select', 0);
- equals(el.tabs('option', 'active'), 0, 'should not collapse tab if collapsible is not set to true');
- el.tabs('select', -1);
- equals(el.tabs('option', 'active'), 0, 'should not collapse tab if collapsible is not set to true');
-
- el.tabs('select', '#fragment-2');
- equals(el.tabs('option', 'active'), 1, 'should select tab by id');
-});
-
test('refresh', function() {
expect(5);
@@ -178,7 +149,7 @@ test('refresh', function() {
ul.append('<li><a href="#test1">Test 1</a></li>');
$('<div id="test1">Test Panel 1</div>').insertAfter( ul );
el.tabs('refresh');
- el.tabs('select', 0);
+ el.tabs('option', 'active', 0);
equals( el.tabs('option', 'active'), 0, 'First tab added should be auto active');
ul.append('<li><a href="#test2">Test 2</a></li>');
diff --git a/tests/unit/tabs/tabs_options.js b/tests/unit/tabs/tabs_options.js
index b1a7a5e78..1352a68e5 100644
--- a/tests/unit/tabs/tabs_options.js
+++ b/tests/unit/tabs/tabs_options.js
@@ -13,8 +13,10 @@ test('collapsible', function() {
el.tabs({ collapsible: true });
equals(el.tabs('option', 'collapsible'), true, 'option set');
ok(el.is('.ui-tabs-collapsible'), 'extra class "ui-tabs-collapsible" attached');
- el.tabs('select', 0);
+
+ el.tabs('option', 'active', false);
equals($('div.ui-tabs-hide', '#tabs1').length, 3, 'all panels should be hidden');
+
el.tabs('option', 'collapsible', false);
ok(el.is(':not(.ui-tabs-collapsible)'), 'extra class "ui-tabs-collapsible" not attached');
@@ -37,8 +39,8 @@ test('cookie', function() {
el.tabs({ active: 1, cookie: cookieObj });
equals(cookie(), 1, 'initial cookie value, from active property');
- el.tabs('select', 2);
- equals(cookie(), 2, 'cookie value updated after select');
+ el.tabs('option', 'active', 2);
+ equals(cookie(), 2, 'cookie value updated after activating');
el.tabs('destroy');
$.cookie(cookieName, 1);
@@ -47,7 +49,7 @@ test('cookie', function() {
el.tabs('destroy');
el.tabs({ cookie: cookieObj, collapsible: true });
- el.tabs('select', 0);
+ el.tabs('option', 'active', false);
equals(cookie(), -1, 'cookie value for all tabs unselected');
el.tabs('destroy');
diff --git a/tests/unit/tabs/tabs_tickets.js b/tests/unit/tabs/tabs_tickets.js
index 486d3b6d2..9ff4d6f92 100644
--- a/tests/unit/tabs/tabs_tickets.js
+++ b/tests/unit/tabs/tabs_tickets.js
@@ -13,7 +13,7 @@ test('#2715 - id containing colon', function() {
ok( $('div.ui-tabs-panel:eq(0)', '#tabs2').is(':visible'), 'first panel should be visible' );
ok( $('div.ui-tabs-panel:eq(1)', '#tabs2').is(':hidden'), 'second panel should be hidden' );
- el.tabs('select', 1).tabs('select', 0);
+ el.tabs('option', 'active', 1).tabs('option', 'active', 0);
ok( $('div.ui-tabs-panel:eq(0)', '#tabs2').is(':visible'), 'first panel should be visible' );
ok( $('div.ui-tabs-panel:eq(1)', '#tabs2').is(':hidden'), 'second panel should be hidden' );
@@ -30,10 +30,10 @@ test('#???? - panel containing inline style', function() {
el = $('#tabs2').tabs();
equals(inlineStyle('height'), expected, 'init should not remove inline style');
- el.tabs('select', 1);
+ el.tabs('option', 'active', 1);
equals(inlineStyle('height'), expected, 'show tab should not remove inline style');
- el.tabs('select', 0);
+ el.tabs('option', 'active', 0);
equals(inlineStyle('height'), expected, 'hide tab should not remove inline style');
});
diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js
index 8508f0adb..b35a91e51 100755
--- a/ui/jquery.ui.tabs.js
+++ b/ui/jquery.ui.tabs.js
@@ -96,8 +96,8 @@ $.widget( "ui.tabs", {
this.lis.removeClass( "ui-tabs-selected ui-state-active" );
// check for length avoids error when initializing empty list
if ( o.active >= 0 && this.anchors.length ) {
- var tab = self.anchors[ o.active ],
- panel = self.element.find( self._sanitizeSelector( $( tab ).attr( "aria-controls" ) ) );
+ this.active = this._findActive( o.active );
+ var panel = self.element.find( self._sanitizeSelector( this.active.attr( "aria-controls" ) ) );
panel.removeClass( "ui-tabs-hide" );
@@ -105,7 +105,7 @@ $.widget( "ui.tabs", {
// seems to be expected behavior that the activate callback is fired
self.element.queue( "tabs", function() {
- self._trigger( "activate", null, self._ui( tab, panel[ 0 ] ) );
+ self._trigger( "activate", null, self._ui( self.active[ 0 ], panel[ 0 ] ) );
});
this.load( o.active );
@@ -120,10 +120,9 @@ $.widget( "ui.tabs", {
_setOption: function( key, value ) {
if ( key == "active" ) {
- if (this.options.collapsible && value == this.options.active ) {
- return;
- }
- this.select( value );
+ // _activate() will handle invalid values and update this.option
+ this._activate( value );
+ return
} else {
this.options[ key ] = value;
this.refresh();
@@ -350,10 +349,10 @@ $.widget( "ui.tabs", {
event.preventDefault();
var self = this,
o = this.options,
- el = event.currentTarget,
- $li = $( el ).closest( "li" ),
+ clicked = $( event.currentTarget ),
+ $li = clicked.closest( "li" ),
$hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
- $show = self.element.find( self._sanitizeSelector( $( el ).attr( "aria-controls" ) ) );
+ $show = self.element.find( self._sanitizeSelector( clicked.attr( "aria-controls" ) ) );
// tab is already selected, but not collapsible
if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible ) ||
@@ -364,12 +363,14 @@ $.widget( "ui.tabs", {
// tab is already loading
$li.hasClass( "ui-state-processing" ) ||
// allow canceling by beforeActivate event
- self._trigger( "beforeActivate", event, self._ui( el, $show[ 0 ] ) ) === false ) {
- el.blur();
+ self._trigger( "beforeActivate", event, self._ui( clicked[ 0 ], $show[ 0 ] ) ) === false ) {
+ clicked[ 0 ].blur();
return;
}
- o.active = self.anchors.index( el );
+ o.active = self.anchors.index( clicked );
+
+ self.active = clicked;
if ( self.xhr ) {
self.xhr.abort();
@@ -379,16 +380,17 @@ $.widget( "ui.tabs", {
if ( o.collapsible ) {
if ( $li.hasClass( "ui-tabs-selected" ) ) {
o.active = -1;
+ self.active = null;
if ( o.cookie ) {
self._cookie( o.active, o.cookie );
}
self.element.queue( "tabs", function() {
- self._hideTab( el, $hide );
+ self._hideTab( clicked, $hide );
}).dequeue( "tabs" );
- el.blur();
+ clicked[ 0 ].blur();
return;
} else if ( !$hide.length ) {
if ( o.cookie ) {
@@ -396,13 +398,13 @@ $.widget( "ui.tabs", {
}
self.element.queue( "tabs", function() {
- self._showTab( el, $show, event );
+ self._showTab( clicked, $show, event );
});
// TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
- self.load( self.anchors.index( el ) );
+ self.load( self.anchors.index( clicked ) );
- el.blur();
+ clicked[ 0 ].blur();
return;
}
}
@@ -415,14 +417,14 @@ $.widget( "ui.tabs", {
if ( $show.length ) {
if ( $hide.length ) {
self.element.queue( "tabs", function() {
- self._hideTab( el, $hide );
+ self._hideTab( clicked, $hide );
});
}
self.element.queue( "tabs", function() {
- self._showTab( el, $show, event );
+ self._showTab( clicked, $show, event );
});
- self.load( self.anchors.index( el ) );
+ self.load( self.anchors.index( clicked ) );
} else {
throw "jQuery UI Tabs: Mismatching fragment identifier.";
}
@@ -432,8 +434,31 @@ $.widget( "ui.tabs", {
// in modern browsers; blur() removes focus from address bar in Firefox
// which can become a usability
if ( $.browser.msie ) {
- el.blur();
+ clicked[ 0 ].blur();
+ }
+ },
+
+ _activate: function( index ) {
+ var active = this._findActive( index )[ 0 ];
+
+ // trying to activate the already active panel
+ if ( this.active && active === this.active[ 0 ] ) {
+ return;
}
+
+ // trying to collapse, simulate a click on the current active header
+ active = active || this.active;
+
+ this._eventHandler({
+ target: active,
+ currentTarget: active,
+ preventDefault: $.noop
+ });
+ },
+
+ _findActive: function( selector ) {
+ return typeof selector === "number" ? this.anchors.eq( selector ) :
+ typeof selector === "string" ? this.anchors.filter( "[href$='" + selector + "']" ) : $();
},
_getIndex: function( index ) {
@@ -539,19 +564,6 @@ $.widget( "ui.tabs", {
return this;
},
- select: function( index ) {
- index = this._getIndex( index );
- if ( index == -1 ) {
- if ( this.options.collapsible && this.options.active != -1 ) {
- index = this.options.active;
- } else {
- return this;
- }
- }
- this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
- return this;
- },
-
load: function( index ) {
index = this._getIndex( index );
var self = this,
@@ -834,7 +846,7 @@ if ( $.uiBackCompat !== false ) {
// If selected tab was removed focus tab to the right or
// in case the last tab was removed the tab to the left.
if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
- this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
+ this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
}
o.disabled = $.map(
@@ -947,6 +959,21 @@ if ( $.uiBackCompat !== false ) {
}
};
}( jQuery, jQuery.ui.tabs.prototype ) );
+
+ // select method
+ (function( $, prototype ) {
+ prototype.select = function( index ) {
+ index = this._getIndex( index );
+ if ( index == -1 ) {
+ if ( this.options.collapsible && this.options.selected != -1 ) {
+ index = this.options.selected;
+ } else {
+ return;
+ }
+ }
+ this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
+ };
+ }( jQuery, jQuery.ui.tabs.prototype ) );
}
})( jQuery );
lue='backport/48282/stable25'>backport/48282/stable25 Nextcloud server, a safe home for all your data: https://github.com/nextcloud/serverwww-data
aboutsummaryrefslogtreecommitdiffstats
path: root/core/src/icons.js
blob: 28a30a63c739ce47cd2b10031b208a38b8055a63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
/**
 * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */
/* eslint-disable quote-props */
/* eslint-disable n/no-unpublished-import */
import path from 'path'
import fs from 'fs'
import sass from 'sass'

const colors = {
	dark: '000',
	white: 'fff',
	// gold but for backwards compatibility called yellow
	yellow: 'a08b00',
	red: 'e9322d',
	orange: 'eca700',
	green: '46ba61',
	grey: '969696',
}

const variables = {}
const icons = {
	'add': path.join(__dirname, '../img', 'actions', 'add.svg'),
	'address': path.join(__dirname, '../img', 'actions', 'address.svg'),
	'alert-outline': path.join(__dirname, '../img', 'actions', 'alert-outline.svg'),
	'audio-off': path.join(__dirname, '../img', 'actions', 'audio-off.svg'),
	'audio': path.join(__dirname, '../img', 'actions', 'audio.svg'),
	'calendar': path.join(__dirname, '../img', 'places', 'calendar.svg'),
	'caret': path.join(__dirname, '../img', 'actions', 'caret.svg'),
	'category-app-bundles': path.join(__dirname, '../img', 'categories', 'bundles.svg'),
	'category-auth': path.join(__dirname, '../img', 'categories', 'auth.svg'),
	'category-customization': path.join(__dirname, '../img', 'categories', 'customization.svg'),
	'category-dashboard': path.join(__dirname, '../img', 'categories', 'dashboard.svg'),
	'category-files': path.join(__dirname, '../img', 'categories', 'files.svg'),
	'category-games': path.join(__dirname, '../img', 'categories', 'games.svg'),
	'category-integration': path.join(__dirname, '../img', 'categories', 'integration.svg'),
	'category-monitoring': path.join(__dirname, '../img', 'categories', 'monitoring.svg'),
	'category-multimedia': path.join(__dirname, '../img', 'categories', 'multimedia.svg'),
	'category-office': path.join(__dirname, '../img', 'categories', 'office.svg'),
	'category-organization': path.join(__dirname, '../img', 'categories', 'organization.svg'),
	'category-social': path.join(__dirname, '../img', 'categories', 'social.svg'),
	'category-workflow': path.join(__dirname, '../img', 'categories', 'workflow.svg'),
	'change': path.join(__dirname, '../img', 'actions', 'change.svg'),
	'checkmark': path.join(__dirname, '../img', 'actions', 'checkmark.svg'),
	'circles': path.join(__dirname, '../img', 'apps', 'circles.svg'),
	'clippy': path.join(__dirname, '../img', 'actions', 'clippy.svg'),
	'close': path.join(__dirname, '../img', 'actions', 'close.svg'),
	'comment': path.join(__dirname, '../img', 'actions', 'comment.svg'),
	'confirm-fade': path.join(__dirname, '../img', 'actions', 'confirm-fade.svg'),
	'confirm': path.join(__dirname, '../img', 'actions', 'confirm.svg'),
	'contacts': path.join(__dirname, '../img', 'places', 'contacts.svg'),
	'delete': path.join(__dirname, '../img', 'actions', 'delete.svg'),
	'desktop': path.join(__dirname, '../img', 'clients', 'desktop.svg'),
	'details': path.join(__dirname, '../img', 'actions', 'details.svg'),
	'disabled-user': path.join(__dirname, '../img', 'actions', 'disabled-user.svg'),
	'disabled-users': path.join(__dirname, '../img', 'actions', 'disabled-users.svg'),
	'download': path.join(__dirname, '../img', 'actions', 'download.svg'),
	'edit': path.join(__dirname, '../img', 'actions', 'edit.svg'),
	'encryption': path.join(__dirname, '../../', 'apps/files_external/img', 'app.svg'),
	'error': path.join(__dirname, '../img', 'actions', 'error.svg'),
	'external': path.join(__dirname, '../img', 'actions', 'external.svg'),
	'favorite': path.join(__dirname, '../img', 'actions', 'star-dark.svg'),
	'files': path.join(__dirname, '../img', 'places', 'files.svg'),
	'filter': path.join(__dirname, '../img', 'actions', 'filter.svg'),
	'folder': path.join(__dirname, '../img', 'filetypes', 'folder.svg'),
	'fullscreen': path.join(__dirname, '../img', 'actions', 'fullscreen.svg'),
	'group': path.join(__dirname, '../img', 'actions', 'group.svg'),
	'history': path.join(__dirname, '../img', 'actions', 'history.svg'),
	'home': path.join(__dirname, '../img', 'places', 'home.svg'),
	'info': path.join(__dirname, '../img', 'actions', 'info.svg'),
	'link': path.join(__dirname, '../img', 'places', 'link.svg'),
	'logout': path.join(__dirname, '../img', 'actions', 'logout.svg'),
	'mail': path.join(__dirname, '../img', 'actions', 'mail.svg'),
	'menu-sidebar': path.join(__dirname, '../img', 'actions', 'menu-sidebar.svg'),
	'menu': path.join(__dirname, '../img', 'actions', 'menu.svg'),
	'more': path.join(__dirname, '../img', 'actions', 'more.svg'),
	'music': path.join(__dirname, '../img', 'places', 'music.svg'),
	'password': path.join(__dirname, '../img', 'actions', 'password.svg'),
	'pause': path.join(__dirname, '../img', 'actions', 'pause.svg'),
	'phone': path.join(__dirname, '../img', 'clients', 'phone.svg'),
	'picture': path.join(__dirname, '../img', 'places', 'picture.svg'),
	'play-add': path.join(__dirname, '../img', 'actions', 'play-add.svg'),
	'play-next': path.join(__dirname, '../img', 'actions', 'play-next.svg'),
	'play-previous': path.join(__dirname, '../img', 'actions', 'play-previous.svg'),
	'play': path.join(__dirname, '../img', 'actions', 'play.svg'),
	'projects': path.join(__dirname, '../img', 'actions', 'projects.svg'),
	'public': path.join(__dirname, '../img', 'actions', 'public.svg'),
	'quota': path.join(__dirname, '../img', 'actions', 'quota.svg'),
	'recent': path.join(__dirname, '../img', 'actions', 'recent.svg'),
	'rename': path.join(__dirname, '../img', 'actions', 'rename.svg'),
	'screen-off': path.join(__dirname, '../img', 'actions', 'screen-off.svg'),
	'screen': path.join(__dirname, '../img', 'actions', 'screen.svg'),
	'search': path.join(__dirname, '../img', 'actions', 'search.svg'),
	'settings': path.join(__dirname, '../img', 'actions', 'settings-dark.svg'),
	'share': path.join(__dirname, '../img', 'actions', 'share.svg'),
	'shared': path.join(__dirname, '../img', 'actions', 'share.svg'),
	'sound-off': path.join(__dirname, '../img', 'actions', 'sound-off.svg'),
	'sound': path.join(__dirname, '../img', 'actions', 'sound.svg'),
	'star': path.join(__dirname, '../img', 'actions', 'star.svg'),
	'starred': path.join(__dirname, '../img', 'actions', 'star-dark.svg'),
	'star-rounded': path.join(__dirname, '../img', 'actions', 'star-rounded.svg'),
	'tablet': path.join(__dirname, '../img', 'clients', 'tablet.svg'),
	'tag': path.join(__dirname, '../img', 'actions', 'tag.svg'),
	'talk': path.join(__dirname, '../img', 'apps', 'spreed.svg'),
	'teams': path.join(__dirname, '../img', 'apps', 'circles.svg'),
	'template-add': path.join(__dirname, '../img', 'actions', 'template-add.svg'),
	'timezone': path.join(__dirname, '../img', 'actions', 'timezone.svg'),
	'toggle-background': path.join(__dirname, '../img', 'actions', 'toggle-background.svg'),
	'toggle-filelist': path.join(__dirname, '../img', 'actions', 'toggle-filelist.svg'),
	'toggle-pictures': path.join(__dirname, '../img', 'actions', 'toggle-pictures.svg'),
	'toggle': path.join(__dirname, '../img', 'actions', 'toggle.svg'),
	'triangle-e': path.join(__dirname, '../img', 'actions', 'triangle-e.svg'),
	'triangle-n': path.join(__dirname, '../img', 'actions', 'triangle-n.svg'),
	'triangle-s': path.join(__dirname, '../img', 'actions', 'triangle-s.svg'),
	'unshare': path.join(__dirname, '../img', 'actions', 'unshare.svg'),
	'upload': path.join(__dirname, '../img', 'actions', 'upload.svg'),
	'user-admin': path.join(__dirname, '../img', 'actions', 'user-admin.svg'),
	'user': path.join(__dirname, '../img', 'actions', 'user.svg'),
	'video-off': path.join(__dirname, '../img', 'actions', 'video-off.svg'),
	'video-switch': path.join(__dirname, '../img', 'actions', 'video-switch.svg'),
	'video': path.join(__dirname, '../img', 'actions', 'video.svg'),
	'view-close': path.join(__dirname, '../img', 'actions', 'view-close.svg'),
	'view-download': path.join(__dirname, '../img', 'actions', 'view-download.svg'),
	'view-next': path.join(__dirname, '../img', 'actions', 'arrow-right.svg'),
	'view-pause': path.join(__dirname, '../img', 'actions', 'view-pause.svg'),
	'view-play': path.join(__dirname, '../img', 'actions', 'view-play.svg'),
	'view-previous': path.join(__dirname, '../img', 'actions', 'arrow-left.svg'),
}

const iconsColor = {
	'add-folder-description': {
		path: path.join(__dirname, '../img', 'actions', 'add-folder-description.svg'),
		color: 'grey',
	},
	'settings': {
		path: path.join(__dirname, '../img', 'actions', 'settings.svg'),
		color: 'black',
	},
	'error-color': {
		path: path.join(__dirname, '../img', 'actions', 'error.svg'),
		color: 'red',
	},
	'checkmark-color': {
		path: path.join(__dirname, '../img', 'actions', 'checkmark.svg'),
		color: 'green',
	},
	'starred': {
		path: path.join(__dirname, '../img', 'actions', 'star-dark.svg'),
		color: 'yellow',
	},
	'star': {
		path: path.join(__dirname, '../img', 'actions', 'star-dark.svg'),
		color: 'grey',
	},
	'delete-color': {
		path: path.join(__dirname, '../img', 'actions', 'delete.svg'),
		color: 'red',
	},
	'file': {
		path: path.join(__dirname, '../img', 'filetypes', 'text.svg'),
		color: 'grey',
	},
	'filetype-file': {
		path: path.join(__dirname, '../img', 'filetypes', 'file.svg'),
		color: 'grey',
	},
	'filetype-folder': {
		path: path.join(__dirname, '../img', 'filetypes', 'folder.svg'),
		// TODO: replace primary ?
		color: 'primary',
	},
	'filetype-folder-drag-accept': {
		path: path.join(__dirname, '../img', 'filetypes', 'folder-drag-accept.svg'),
		// TODO: replace primary ?
		color: 'primary',
	},
	'filetype-text': {
		path: path.join(__dirname, '../img', 'filetypes', 'text.svg'),
		color: 'grey',
	},
}

// use this to define aliases to existing icons
// key is the css selector, value is the variable
const iconsAliases = {
	'icon-caret': 'icon-caret-white',
	// starring action
	'icon-star:hover': 'icon-starred',
	'icon-star:focus': 'icon-starred',
	// Un-starring action
	'icon-starred:hover': 'icon-star-grey',
	'icon-starred:focus': 'icon-star-grey',
	// Delete normal
	'icon-delete.no-permission:hover': 'icon-delete-dark',
	'icon-delete.no-permission:focus': 'icon-delete-dark',
	'icon-delete.no-hover:hover': 'icon-delete-dark',
	'icon-delete.no-hover:focus': 'icon-delete-dark',
	'icon-delete:hover': 'icon-delete-color-red',
	'icon-delete:focus': 'icon-delete-color-red',
	// Delete white
	'icon-delete-white.no-permission:hover': 'icon-delete-white',
	'icon-delete-white.no-permission:focus': 'icon-delete-white',
	'icon-delete-white.no-hover:hover': 'icon-delete-white',
	'icon-delete-white.no-hover:focus': 'icon-delete-white',
	'icon-delete-white:hover': 'icon-delete-color-red',
	'icon-delete-white:focus': 'icon-delete-color-red',
	// Default to white
	'icon-view-close': 'icon-view-close-white',
	'icon-view-download': 'icon-view-download-white',
	'icon-view-pause': 'icon-view-pause-white',
	'icon-view-play': 'icon-view-play-white',
	// Default app place to white
	'icon-calendar': 'icon-calendar-white',
	'icon-contacts': 'icon-contacts-white',
	'icon-files': 'icon-files-white',
	// Re-using existing icons
	'icon-category-installed': 'icon-user-dark',
	'icon-category-enabled': 'icon-checkmark-dark',
	'icon-category-disabled': 'icon-close-dark',
	'icon-category-updates': 'icon-download-dark',
	'icon-category-security': 'icon-password-dark',
	'icon-category-search': 'icon-search-dark',
	'icon-category-tools': 'icon-settings-dark',
	'nav-icon-systemtagsfilter': 'icon-tag-dark',
}

const colorSvg = function(svg = '', color = '000') {
	if (!color.match(/^[0-9a-f]{3,6}$/i)) {
		// Prevent not-sane colors from being written into the SVG
		console.warn(color, 'does not match the required format')
		color = '000'
	}

	// add fill (fill is not present on black elements)
	const fillRe = /<((circle|rect|path)((?!fill)[a-z0-9 =".\-#():;,])+)\/>/gmi
	svg = svg.replace(fillRe, '<$1 fill="#' + color + '"/>')

	// replace any fill or stroke colors
	svg = svg.replace(/stroke="#([a-z0-9]{3,6})"/gmi, 'stroke="#' + color + '"')
	svg = svg.replace(/fill="#([a-z0-9]{3,6})"/gmi, 'fill="#' + color + '"')

	return svg
}

const generateVariablesAliases = function(invert = false) {
	let css = ''
	Object.keys(variables).forEach(variable => {
		if (variable.indexOf('original-') !== -1) {
			let finalVariable = variable.replace('original-', '')
			if (invert) {
				finalVariable = finalVariable.replace('white', 'tempwhite')
					.replace('dark', 'white')
					.replace('tempwhite', 'dark')
			}
			css += `${finalVariable}: var(${variable});`
		}
	})
	return css
}

const formatIcon = function(icon, invert = false) {
	const color1 = invert ? 'white' : 'dark'
	const color2 = invert ? 'dark' : 'white'
	return `
	.icon-${icon},
	.icon-${icon}-dark {
		background-image: var(--icon-${icon}-${color1});
	}
	.icon-${icon}-white,
	.icon-${icon}.icon-white {
		background-image: var(--icon-${icon}-${color2});
	}`
}
const formatIconColor = function(icon) {
	const { color } = iconsColor[icon]
	return `
	.icon-${icon} {
		background-image: var(--icon-${icon}-${color});
	}`
}
const formatAlias = function(alias, invert = false) {
	let icon = iconsAliases[alias]
	if (invert) {
		icon = icon.replace('white', 'tempwhite')
			.replace('dark', 'white')
			.replace('tempwhite', 'dark')
	}
	return `
	.${alias} {
		background-image: var(--${icon})
	}`
}

let css = ''
Object.keys(icons).forEach(icon => {
	const path = icons[icon]

	const svg = fs.readFileSync(path, 'utf8')
	const darkSvg = colorSvg(svg, '000000')
	const whiteSvg = colorSvg(svg, 'ffffff')

	variables[`--original-icon-${icon}-dark`] = Buffer.from(darkSvg, 'utf-8').toString('base64')
	variables[`--original-icon-${icon}-white`] = Buffer.from(whiteSvg, 'utf-8').toString('base64')
})

Object.keys(iconsColor).forEach(icon => {
	const { path, color } = iconsColor[icon]

	const svg = fs.readFileSync(path, 'utf8')
	const coloredSvg = colorSvg(svg, colors[color])
	variables[`--icon-${icon}-${color}`] = Buffer.from(coloredSvg, 'utf-8').toString('base64')
})

// ICONS VARIABLES LIST
css += ':root {'
Object.keys(variables).forEach(variable => {
	const data = variables[variable]
	css += `${variable}: url(data:image/svg+xml;base64,${data});`
})
css += '}'

// DEFAULT THEME
css += 'body {'
css += generateVariablesAliases()
Object.keys(icons).forEach(icon => {
	css += formatIcon(icon)
})
Object.keys(iconsColor).forEach(icon => {
	css += formatIconColor(icon)
})
Object.keys(iconsAliases).forEach(alias => {
	css += formatAlias(alias)
})
css += '}'

// DARK THEME MEDIA QUERY
css += '@media (prefers-color-scheme: dark) { body {'
css += generateVariablesAliases(true)
css += '}}'

// DARK THEME
css += '[data-themes*=light] {'
css += generateVariablesAliases()
css += '}'

// DARK THEME
css += '[data-themes*=dark] {'
css += generateVariablesAliases(true)
css += '}'

// WRITE CSS
fs.writeFileSync(path.join(__dirname, '../../dist', 'icons.css'), sass.compileString(css).css)