@@ -7,15 +7,34 @@ import '@css/options.css';
7
7
import processKeybind from '@common/utils/process_keybind' ;
8
8
import { ubrowser } from '@shared/constants' ;
9
9
import { getStorageSync , setStorageSync } from '@shared/storage' ;
10
- import { IGNORED_KEYS , SETTING_DEFAULTS , SETTING_NAMES , SETTING_TYPES } from '../common/constants.mjs' ;
10
+ import { IGNORED_KEYS , SETTING_DEFAULTS , SETTING_NAMES , SETTING_TYPES , THEMES } from '../common/constants.mjs' ;
11
11
12
12
// $FlowFixMe
13
- export type EventCallback = ( ev : any ) => void ;
13
+ export type EventCallback = ( ev : any ) => Promise < void > | void ;
14
14
15
15
let unique_counter : number = 1 ;
16
16
let shortcuts_defs : { [ string ] : string } = { } ;
17
17
let color_domain_defs : { [ string ] : string } = { } ;
18
18
19
+ async function loadThemeValues ( theme : string ) : Promise < { [ string ] : mixed } > {
20
+ return new Promise ( ( resolve , reject ) => {
21
+ ubrowser . runtime . getPackageDirectoryEntry ( ( root ) => {
22
+ root . getFile ( `themes/${ theme } .json` , { } , ( fileEntry ) => {
23
+ fileEntry . file ( ( file ) => {
24
+ const reader = new FileReader ( ) ;
25
+ reader . onerror = reject ;
26
+ reader . onabort = reject ;
27
+ reader . onloadend = readerEvent => {
28
+ // $FlowFixMe
29
+ resolve ( JSON . parse ( readerEvent . target . result ) ) ;
30
+ } ;
31
+ reader . readAsText ( file ) ;
32
+ } , reject ) ;
33
+ } , reject ) ;
34
+ } ) ;
35
+ } ) ;
36
+ }
37
+
19
38
function onClickShortcutRemove ( e : MouseEvent ) {
20
39
if ( e . target instanceof HTMLElement ) {
21
40
const el_target = e . target ;
@@ -114,8 +133,10 @@ function saveOptions() {
114
133
}
115
134
const target = document.getElementById(name);
116
135
if (target instanceof HTMLInputElement) {
117
- if ( type === 'edit' || type === 'int' || type === ' option' || type === 'color' ) {
136
+ if (type === 'edit' || type === 'option' || type === 'color') {
118
137
data[name] = target.value;
138
+ } else if (type === 'int') {
139
+ data[name] = Number(target.value);
119
140
} else if (type === 'check') {
120
141
data[name] = target.checked;
121
142
} else if (type === 'json') {
@@ -151,46 +172,46 @@ function saveOptions() {
151
172
setStorageSync(data);
152
173
}
153
174
154
- function applyInputValues ( ) {
155
- getStorageSync ( SETTING_NAMES ) . then ( result => {
156
- const cmd_names = Object . keys ( result ) ;
157
- for ( const name of cmd_names ) {
158
- // $FlowFixMe
159
- const type = SETTING_TYPES [ name ] ;
160
- if ( type === 'manual' ) {
161
- continue ;
162
- }
163
- const elm = document . getElementById ( name ) ;
164
- if ( elm ) {
165
- if ( elm instanceof HTMLInputElement ) {
166
- if ( type === 'edit' || type === 'color' ) {
167
- elm . value = result [ name ] || '' ;
168
- } else if ( type === 'check' ) {
169
- elm . checked = result [ name ] || false ;
170
- } else if ( type === 'int' ) {
171
- elm . value = result [ name ] || 0 ;
172
- } else if ( type === 'json' ) {
173
- elm . value = JSON . stringify ( result [ name ] || { } , null , 4 ) ;
174
- }
175
- } else if ( elm instanceof HTMLTextAreaElement ) {
176
- if ( type === 'edit' ) {
177
- elm . value = result [ name ] || '' ;
178
- } else if ( type === 'json' ) {
179
- elm . value = JSON . stringify ( result [ name ] || { } , null , 4 ) ;
180
- }
181
- } else if ( elm instanceof HTMLSelectElement ) {
182
- if ( type === 'option' ) {
183
- // $FlowIgnore
184
- elm . value = result [ name ] || SETTING_DEFAULTS [ name ] ;
185
- }
175
+ function applyInputValues(values: {[string]: mixed}) {
176
+ const cmd_names = Object.keys(values);
177
+ for (const name of cmd_names) {
178
+ // $FlowFixMe
179
+ const type = SETTING_TYPES[name];
180
+ if (type === 'manual') {
181
+ continue;
182
+ }
183
+ const elm = document.getElementById(name);
184
+ if (elm) {
185
+ if (elm instanceof HTMLInputElement) {
186
+ if ((type === 'edit' || type === 'color') && typeof values[name] === 'string') {
187
+ elm.value = values[name] || '';
188
+ } else if (type === 'check' && typeof values[name] === 'boolean') {
189
+ elm.checked = values[name] || false;
190
+ } else if (type === 'int' && (typeof values[name] === 'number' || typeof values[name] === 'string')) {
191
+ elm.value = new String(values[name] || 0).toString();
192
+ } else if (type === 'json' && typeof values[name] === 'object') {
193
+ elm.value = JSON.stringify(values[name] || {}, null, 4);
194
+ }
195
+ } else if (elm instanceof HTMLTextAreaElement) {
196
+ if (type === 'edit' && typeof values[name] === 'string') {
197
+ elm.value = values[name] || '';
198
+ } else if (type === 'json' && typeof values[name] === 'object') {
199
+ elm.value = JSON.stringify(values[name] || {}, null, 4);
200
+ }
201
+ } else if (elm instanceof HTMLSelectElement) {
202
+ if (type === 'option') {
203
+ // $FlowIgnore
204
+ elm.value = values[name] || SETTING_DEFAULTS[name];
186
205
}
187
206
}
188
207
}
189
- shortcuts_defs = result . shortcuts || { } ;
190
- color_domain_defs = result . colors_domain || { } ;
191
- renderShortcutTable ( ) ;
192
- renderColorDomainTable ( ) ;
193
- } ) ;
208
+ }
209
+ // $FlowFixMe
210
+ shortcuts_defs = values.shortcuts || {};
211
+ // $FlowFixMe
212
+ color_domain_defs = values.colors_domain || {};
213
+ renderShortcutTable();
214
+ renderColorDomainTable();
194
215
}
195
216
196
217
function onSubmitForm(e: Event) {
@@ -263,9 +284,20 @@ function onClickColorDomainAdd() {
263
284
}
264
285
}
265
286
266
- function onClickResetSettings ( ) {
287
+ async function onClickResetSettings ( ) {
267
288
setStorageSync ( SETTING_DEFAULTS ) ;
268
- applyInputValues ( ) ;
289
+ applyInputValues ( await getStorageSync ( SETTING_NAMES ) ) ;
290
+ }
291
+
292
+ async function onChangeThemePreset ( ev : Event ) {
293
+ // $FlowFixMe
294
+ const theme_preset = ev . target . value ;
295
+ try {
296
+ const theme_values = await loadThemeValues ( theme_preset ) ;
297
+ applyInputValues ( theme_values ) ;
298
+ } catch ( e ) {
299
+ console . error ( 'Failed to load theme values:' , e ) ;
300
+ }
269
301
}
270
302
271
303
function _apply_i18n ( selector : string , ikey : string ) {
@@ -338,15 +370,24 @@ function _add_event_listener(selector: string, event_type: string, callback: Eve
338
370
}
339
371
}
340
372
341
- function onDOMLoaded ( ) {
342
- applyInputValues ( ) ;
373
+ async function onDOMLoaded ( ) {
374
+ const config_values = await getStorageSync ( SETTING_NAMES ) ;
375
+ applyInputValues ( config_values ) ;
376
+
343
377
_add_event_listener ( '#form_options' , 'submit' , onSubmitForm ) ;
344
378
_add_event_listener ( '#shortcut_keybind' , 'keydown' , onKeyDownShortcut ) ;
345
379
_add_event_listener ( '#shortcut_keybind' , 'keyup' , onKeyUpShortcut ) ;
346
380
_add_event_listener ( '#add_shortcut' , 'click' , onClickShortcutAdd ) ;
347
381
_add_event_listener ( '#add_color_domain' , 'click' , onClickColorDomainAdd ) ;
348
382
_add_event_listener ( '.reset_settings' , 'click' , onClickResetSettings ) ;
383
+ _add_event_listener ( '#theme_preset' , 'change' , onChangeThemePreset ) ;
349
384
i18n ( ) ;
385
+ for ( const theme of THEMES ) {
386
+ const option = document . createElement ( 'option' ) ;
387
+ option . value = theme [ 0 ] ;
388
+ option . textContent = theme [ 1 ] ;
389
+ document . querySelector ( '#theme_preset' ) ?. appendChild ( option ) ;
390
+ }
350
391
}
351
392
352
393
document . addEventListener ( 'DOMContentLoaded' , onDOMLoaded ) ;
0 commit comments