1+ import { Plugin , Setting } from 'siyuan' ;
2+
3+ export class SettingUtils {
4+ plugin : Plugin ;
5+ name : string ;
6+ file : string ;
7+
8+ settings : Map < string , ISettingItem > = new Map ( ) ;
9+ elements : Map < string , HTMLElement > = new Map ( ) ;
10+
11+ constructor ( plugin : Plugin , name ?: string , width ?: string , height ?: string ) {
12+ this . name = name ?? 'settings' ;
13+ this . plugin = plugin ;
14+ this . file = this . name . endsWith ( '.json' ) ? this . name : `${ this . name } .json` ;
15+ this . plugin . setting = new Setting ( {
16+ width : width ,
17+ height : height ,
18+ confirmCallback : ( ) => {
19+ for ( let key of this . settings . keys ( ) ) {
20+ this . updateValue ( key ) ;
21+ }
22+ let data = this . dump ( ) ;
23+ this . plugin . data [ this . name ] = data ;
24+ this . save ( ) ;
25+ }
26+ } ) ;
27+ }
28+
29+ async load ( ) {
30+ let data = await this . plugin . loadData ( this . file ) ;
31+ if ( data ) {
32+ for ( let [ key , item ] of this . settings ) {
33+ item . value = data ?. [ key ] ?? item . value ;
34+ }
35+ }
36+ }
37+
38+ async save ( ) {
39+ let data = this . dump ( ) ;
40+ await this . plugin . saveData ( this . file , this . dump ( ) ) ;
41+ return data ;
42+ }
43+
44+ /**
45+ * Get setting item value
46+ * @param key key name
47+ * @returns setting item value
48+ */
49+ get ( key : string ) {
50+ return this . settings . get ( key ) ?. value ;
51+ }
52+
53+ /**
54+ * 将设置项目导出为 JSON 对象
55+ * @returns object
56+ */
57+ dump ( ) : Object {
58+ let data : any = { } ;
59+ for ( let [ key , item ] of this . settings ) {
60+ if ( item . type === 'button' ) continue ;
61+ data [ key ] = item . value ;
62+ }
63+ return data ;
64+ }
65+
66+ addItem ( item : ISettingItem ) {
67+ this . settings . set ( item . key , item ) ;
68+ let itemElement : HTMLElement ;
69+ switch ( item . type ) {
70+ case 'checkbox' :
71+ let element : HTMLInputElement = document . createElement ( 'input' ) ;
72+ element . type = 'checkbox' ;
73+ element . checked = item . value ;
74+ element . className = "b3-switch fn__flex-center" ;
75+ itemElement = element ;
76+ break ;
77+ case 'select' :
78+ let selectElement : HTMLSelectElement = document . createElement ( 'select' ) ;
79+ selectElement . className = "b3-select fn__flex-center fn__size200" ;
80+ for ( let option of item . select ?. options ?? [ ] ) {
81+ let optionElement = document . createElement ( 'option' ) ;
82+ optionElement . value = option . val ;
83+ optionElement . text = option . text ;
84+ selectElement . appendChild ( optionElement ) ;
85+ }
86+ selectElement . value = item . value ;
87+ itemElement = selectElement ;
88+ break ;
89+ case 'slider' :
90+ let sliderElement : HTMLInputElement = document . createElement ( 'input' ) ;
91+ sliderElement . type = 'range' ;
92+ sliderElement . className = 'b3-slider fn__size200' ;
93+ sliderElement . ariaLabel = item . value ;
94+ sliderElement . min = item . slider ?. min . toString ( ) ?? '0' ;
95+ sliderElement . max = item . slider ?. max . toString ( ) ?? '100' ;
96+ sliderElement . step = item . slider ?. step . toString ( ) ?? '1' ;
97+ sliderElement . value = item . value ;
98+ itemElement = sliderElement ;
99+ break ;
100+ case 'textinput' :
101+ let textInputElement : HTMLInputElement = document . createElement ( 'input' ) ;
102+ textInputElement . className = 'b3-text-field fn__flex-center fn__size200' ;
103+ textInputElement . value = item . value ;
104+ itemElement = textInputElement ;
105+ break ;
106+ case 'textarea' :
107+ let textareaElement : HTMLTextAreaElement = document . createElement ( 'textarea' ) ;
108+ textareaElement . className = "b3-text-field fn__block" ;
109+ textareaElement . value = item . value ;
110+ itemElement = textareaElement ;
111+ break ;
112+ case 'button' :
113+ let buttonElement : HTMLButtonElement = document . createElement ( 'button' ) ;
114+ buttonElement . className = "b3-button b3-button--outline fn__flex-center fn__size200" ;
115+ buttonElement . innerText = item . button ?. label ?? 'Button' ;
116+ buttonElement . onclick = item . button ?. callback ?? ( ( ) => { } ) ;
117+ itemElement = buttonElement ;
118+ break ;
119+ }
120+ this . elements . set ( item . key , itemElement ) ;
121+ this . plugin . setting . addItem ( {
122+ title : item . title ,
123+ description : item ?. description ,
124+ createActionElement : ( ) => {
125+ let element = this . getElement ( item . key ) ;
126+ return element ;
127+ }
128+ } )
129+ }
130+
131+ private getElement ( key : string ) {
132+ let item = this . settings . get ( key ) ;
133+ let element = this . elements . get ( key ) as any ;
134+ switch ( item . type ) {
135+ case 'checkbox' :
136+ element . checked = item . value ;
137+ break ;
138+ case 'select' :
139+ element . value = item . value ;
140+ break ;
141+ case 'slider' :
142+ element . value = item . value ;
143+ break ;
144+ case 'textinput' :
145+ element . value = item . value ;
146+ break ;
147+ case 'textarea' :
148+ element . value = item . value ;
149+ break ;
150+ }
151+ return element ;
152+ }
153+
154+ private updateValue ( key : string ) {
155+ let item = this . settings . get ( key ) ;
156+ let element = this . elements . get ( key ) as any ;
157+ switch ( item . type ) {
158+ case 'checkbox' :
159+ item . value = element . checked ;
160+ break ;
161+ case 'select' :
162+ item . value = element . value ;
163+ break ;
164+ case 'slider' :
165+ item . value = element . value ;
166+ break ;
167+ case 'textinput' :
168+ item . value = element . value ;
169+ break ;
170+ case 'textarea' :
171+ item . value = element . value ;
172+ break ;
173+ }
174+ }
175+
176+ }
0 commit comments