browser-extension-settings 0.0.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/common.ts +1 -1
- package/lib/index.ts +7 -1
- package/lib/settings.ts +169 -82
- package/lib/style.scss +5 -5
- package/lib/switch.ts +10 -2
- package/package.json +6 -2
package/lib/common.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export const besVersion =
|
|
1
|
+
export const besVersion = 15
|
|
2
2
|
export const openButton = `<svg viewBox="0 0 60.2601318359375 84.8134765625" version="1.1" xmlns="http://www.w3.org/2000/svg" class=" glyph-box" style="height: 9.62969px; width: 6.84191px;"><g transform="matrix(1 0 0 1 -6.194965820312518 77.63671875)"><path d="M66.4551-35.2539C66.4551-36.4746 65.9668-37.5977 65.0391-38.4766L26.3672-76.3672C25.4883-77.1973 24.4141-77.6367 23.1445-77.6367C20.6543-77.6367 18.7012-75.7324 18.7012-73.1934C18.7012-71.9727 19.1895-70.8496 19.9707-70.0195L55.5176-35.2539L19.9707-0.488281C19.1895 0.341797 18.7012 1.41602 18.7012 2.68555C18.7012 5.22461 20.6543 7.12891 23.1445 7.12891C24.4141 7.12891 25.4883 6.68945 26.3672 5.81055L65.0391-32.0312C65.9668-32.959 66.4551-34.0332 66.4551-35.2539Z"></path></g></svg>`
|
|
3
3
|
export const openInNewTabButton = `<svg viewBox="0 0 72.127685546875 72.2177734375" version="1.1" xmlns="http://www.w3.org/2000/svg" class=" glyph-box" style="height: 8.19958px; width: 8.18935px;"><g transform="matrix(1 0 0 1 -12.451127929687573 71.3388671875)"><path d="M84.5703-17.334L84.5215-66.4551C84.5215-69.2383 82.7148-71.1914 79.7852-71.1914L30.6641-71.1914C27.9297-71.1914 26.0742-69.0918 26.0742-66.748C26.0742-64.4043 28.1738-62.4023 30.4688-62.4023L47.4609-62.4023L71.2891-63.1836L62.207-55.2246L13.8184-6.73828C12.9395-5.85938 12.4512-4.73633 12.4512-3.66211C12.4512-1.31836 14.5508 0.878906 16.9922 0.878906C18.1152 0.878906 19.1895 0.488281 20.0684-0.439453L68.5547-48.877L76.6113-58.0078L75.7324-35.2051L75.7324-17.1387C75.7324-14.8438 77.7344-12.6953 80.127-12.6953C82.4707-12.6953 84.5703-14.6973 84.5703-17.334Z"></path></g></svg>`
|
package/lib/index.ts
CHANGED
package/lib/settings.ts
CHANGED
|
@@ -33,20 +33,44 @@ type SettingsOptions = {
|
|
|
33
33
|
footer?: string
|
|
34
34
|
settingsTable?: SettingsTable
|
|
35
35
|
onValueChange?: () => void
|
|
36
|
+
onViewUpdate?: (settingsMainView: HTMLElement) => void
|
|
36
37
|
relatedExtensions?: RelatedExtension[]
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
type SettingsTable = Record<
|
|
40
|
+
type SettingsTable = Record<
|
|
41
|
+
string,
|
|
42
|
+
SettingsSwitchItem | SettingsInputItem | SettingsActionItem | SettingsTipItem
|
|
43
|
+
>
|
|
40
44
|
|
|
41
45
|
type SettingsSwitchItem = {
|
|
42
46
|
title: string
|
|
43
47
|
defaultValue: boolean
|
|
48
|
+
type?: "switch"
|
|
49
|
+
group?: number
|
|
44
50
|
}
|
|
45
51
|
|
|
46
52
|
type SettingsInputItem = {
|
|
47
53
|
title: string
|
|
48
54
|
defaultValue: string
|
|
55
|
+
placeholder?: string
|
|
49
56
|
type: string
|
|
57
|
+
group?: number
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
type SettingsActionItem = {
|
|
61
|
+
title: string
|
|
62
|
+
type: string
|
|
63
|
+
onclick?: () => void
|
|
64
|
+
group?: number
|
|
65
|
+
defaultValue?: any
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
type SettingsTipItem = {
|
|
69
|
+
title: string
|
|
70
|
+
type: string
|
|
71
|
+
tipContent: string
|
|
72
|
+
group?: number
|
|
73
|
+
defaultValue?: any
|
|
50
74
|
}
|
|
51
75
|
|
|
52
76
|
type RelatedExtension = {
|
|
@@ -91,10 +115,33 @@ async function saveSattingsValue(key: string, value: any) {
|
|
|
91
115
|
await setValue(storageKey, settings)
|
|
92
116
|
}
|
|
93
117
|
|
|
118
|
+
export async function resetSattingsValues() {
|
|
119
|
+
await setValue(storageKey, {})
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export async function saveSattingsValues(
|
|
123
|
+
values: Record<string, boolean | string | undefined>
|
|
124
|
+
) {
|
|
125
|
+
const settings = await getSettings()
|
|
126
|
+
|
|
127
|
+
for (const key in values) {
|
|
128
|
+
if (Object.hasOwn(values, key)) {
|
|
129
|
+
const value = values[key]
|
|
130
|
+
|
|
131
|
+
settings[key] =
|
|
132
|
+
settingsTable[key] && settingsTable[key].defaultValue === value
|
|
133
|
+
? undefined
|
|
134
|
+
: value
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
await setValue(storageKey, settings)
|
|
139
|
+
}
|
|
140
|
+
|
|
94
141
|
export function getSettingsValue(key: string): boolean | string | undefined {
|
|
95
142
|
return Object.hasOwn(settings, key)
|
|
96
|
-
? settings[key]
|
|
97
|
-
: settingsTable[key]?.defaultValue
|
|
143
|
+
? (settings[key] as boolean | string | undefined)
|
|
144
|
+
: (settingsTable[key]?.defaultValue as boolean | string | undefined)
|
|
98
145
|
}
|
|
99
146
|
|
|
100
147
|
const closeModal = () => {
|
|
@@ -136,28 +183,43 @@ async function updateOptions() {
|
|
|
136
183
|
|
|
137
184
|
for (const key in settingsTable) {
|
|
138
185
|
if (Object.hasOwn(settingsTable, key)) {
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
186
|
+
const item = settingsTable[key]
|
|
187
|
+
const type = item.type || "switch"
|
|
188
|
+
|
|
189
|
+
// console.log(key, type)
|
|
190
|
+
switch (type) {
|
|
191
|
+
case "switch": {
|
|
192
|
+
const checkbox = $(
|
|
193
|
+
`#${settingsElementId} .option_groups .switch_option[data-key="${key}"] input`
|
|
194
|
+
) as HTMLInputElement
|
|
195
|
+
if (checkbox) {
|
|
196
|
+
checkbox.checked = getSettingsValue(key) as boolean
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
break
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
case "textarea": {
|
|
203
|
+
const textArea = $(
|
|
204
|
+
`#${settingsElementId} .option_groups textarea[data-key="${key}"]`
|
|
205
|
+
) as HTMLTextAreaElement
|
|
206
|
+
if (textArea) {
|
|
207
|
+
textArea.value = getSettingsValue(key) as string
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
break
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
default: {
|
|
214
|
+
break
|
|
215
|
+
}
|
|
144
216
|
}
|
|
145
217
|
}
|
|
146
218
|
}
|
|
147
219
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
group2.style.display = getSettingsValue(
|
|
152
|
-
`enableCustomRulesForCurrentSite_${host}`
|
|
153
|
-
)
|
|
154
|
-
? "block"
|
|
155
|
-
: "none"
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const customStyleValue = $(`#${settingsElementId} .option_groups textarea`)
|
|
159
|
-
if (customStyleValue) {
|
|
160
|
-
customStyleValue.value = settings[`customRulesForCurrentSite_${host}`] || ""
|
|
220
|
+
if (typeof settingsOptions.onViewUpdate === "function") {
|
|
221
|
+
const settingsMain = createSettingsElement()
|
|
222
|
+
settingsOptions.onViewUpdate(settingsMain)
|
|
161
223
|
}
|
|
162
224
|
}
|
|
163
225
|
|
|
@@ -231,74 +293,98 @@ function createSettingsElement() {
|
|
|
231
293
|
addElement(settingsMain, "h2", { textContent: settingsOptions.title })
|
|
232
294
|
}
|
|
233
295
|
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
if (
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
},
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
switchOption.dataset.key = key
|
|
248
|
-
|
|
249
|
-
addElement(options, switchOption)
|
|
296
|
+
const optionGroups: HTMLElement[] = []
|
|
297
|
+
const getOptionGroup = (index: number) => {
|
|
298
|
+
if (index > optionGroups.length) {
|
|
299
|
+
for (let i = optionGroups.length; i < index; i++) {
|
|
300
|
+
optionGroups.push(
|
|
301
|
+
addElement(settingsMain!, "div", {
|
|
302
|
+
class: "option_groups",
|
|
303
|
+
})
|
|
304
|
+
)
|
|
250
305
|
}
|
|
251
306
|
}
|
|
307
|
+
|
|
308
|
+
return optionGroups[index - 1]
|
|
252
309
|
}
|
|
253
310
|
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
311
|
+
for (const key in settingsTable) {
|
|
312
|
+
if (Object.hasOwn(settingsTable, key)) {
|
|
313
|
+
const item = settingsTable[key]
|
|
314
|
+
const type = item.type || "switch"
|
|
315
|
+
const group = item.group || 1
|
|
316
|
+
const optionGroup = getOptionGroup(group)
|
|
317
|
+
// console.log(key, item, type, group)
|
|
318
|
+
switch (type) {
|
|
319
|
+
case "switch": {
|
|
320
|
+
const switchOption = createSwitchOption(item.title, {
|
|
321
|
+
async onchange(event: Event) {
|
|
322
|
+
const checkbox = event.target as HTMLInputElement
|
|
323
|
+
if (checkbox) {
|
|
324
|
+
await saveSattingsValue(key, checkbox.checked)
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
switchOption.dataset.key = key
|
|
330
|
+
|
|
331
|
+
addElement(optionGroup, switchOption)
|
|
332
|
+
|
|
333
|
+
break
|
|
334
|
+
}
|
|
266
335
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
336
|
+
case "textarea": {
|
|
337
|
+
let timeoutId: number | undefined
|
|
338
|
+
addElement(optionGroup, "textarea", {
|
|
339
|
+
"data-key": key,
|
|
340
|
+
placeholder: (item as SettingsInputItem).placeholder || "",
|
|
341
|
+
onkeyup(event: Event) {
|
|
342
|
+
const textArea = event.target as HTMLTextAreaElement
|
|
343
|
+
if (timeoutId) {
|
|
344
|
+
clearTimeout(timeoutId)
|
|
345
|
+
timeoutId = undefined
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
timeoutId = setTimeout(async () => {
|
|
349
|
+
if (textArea) {
|
|
350
|
+
await saveSattingsValue(key, textArea.value.trim())
|
|
351
|
+
}
|
|
352
|
+
}, 100)
|
|
353
|
+
},
|
|
354
|
+
})
|
|
355
|
+
|
|
356
|
+
break
|
|
274
357
|
}
|
|
275
|
-
}, 100)
|
|
276
|
-
},
|
|
277
|
-
})
|
|
278
358
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
359
|
+
case "action": {
|
|
360
|
+
addElement(optionGroup, "a", {
|
|
361
|
+
class: "action",
|
|
362
|
+
textContent: item.title,
|
|
363
|
+
onclick: (item as SettingsActionItem).onclick,
|
|
364
|
+
})
|
|
365
|
+
|
|
366
|
+
break
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
case "tip": {
|
|
370
|
+
const tip = addElement(optionGroup, "div", {
|
|
371
|
+
class: "bes_tip",
|
|
372
|
+
})
|
|
373
|
+
addElement(tip, "a", {
|
|
374
|
+
class: "bes_tip_anchor",
|
|
375
|
+
textContent: item.title,
|
|
376
|
+
})
|
|
377
|
+
const tipContent = addElement(tip, "div", {
|
|
378
|
+
class: "bes_tip_content",
|
|
379
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
380
|
+
innerHTML: (item as SettingsTipItem).tipContent,
|
|
381
|
+
})
|
|
382
|
+
break
|
|
383
|
+
}
|
|
384
|
+
// No default
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
302
388
|
|
|
303
389
|
if (settingsOptions.footer) {
|
|
304
390
|
const footer = addElement(settingsMain, "footer")
|
|
@@ -362,6 +448,7 @@ export const initSettings = async (options: SettingsOptions) => {
|
|
|
362
448
|
settingsTable = options.settingsTable || {}
|
|
363
449
|
addValueChangeListener(storageKey, async () => {
|
|
364
450
|
settings = await getSettings()
|
|
451
|
+
// console.log(JSON.stringify(settings, null, 2))
|
|
365
452
|
await updateOptions()
|
|
366
453
|
if (typeof options.onValueChange === "function") {
|
|
367
454
|
options.onValueChange()
|
package/lib/style.scss
CHANGED
|
@@ -213,7 +213,7 @@
|
|
|
213
213
|
margin-right: 10px;
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
.option_groups .
|
|
216
|
+
.option_groups .bes_tip {
|
|
217
217
|
position: relative;
|
|
218
218
|
margin: 0;
|
|
219
219
|
padding: 0 15px 0 0;
|
|
@@ -221,11 +221,11 @@
|
|
|
221
221
|
max-width: none;
|
|
222
222
|
font-size: 14px;
|
|
223
223
|
|
|
224
|
-
.
|
|
224
|
+
.bes_tip_anchor {
|
|
225
225
|
cursor: help;
|
|
226
226
|
text-decoration: underline;
|
|
227
227
|
}
|
|
228
|
-
.
|
|
228
|
+
.bes_tip_content {
|
|
229
229
|
position: absolute;
|
|
230
230
|
bottom: 15px;
|
|
231
231
|
left: 0;
|
|
@@ -240,8 +240,8 @@
|
|
|
240
240
|
box-shadow: 0px 10px 39px 10px rgba(62, 66, 66, 0.22) !important;
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
-
.
|
|
244
|
-
.
|
|
243
|
+
.bes_tip_anchor:hover + .bes_tip_content,
|
|
244
|
+
.bes_tip_content:hover {
|
|
245
245
|
display: block;
|
|
246
246
|
}
|
|
247
247
|
|
package/lib/switch.ts
CHANGED
|
@@ -4,7 +4,12 @@ import {
|
|
|
4
4
|
createElement,
|
|
5
5
|
} from "browser-extension-utils"
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
type SwichOptions = {
|
|
8
|
+
checked?: boolean
|
|
9
|
+
onchange?: (event: Event) => void | Promise<void>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createSwitch(options = {} as SwichOptions): HTMLElement {
|
|
8
13
|
const container = createElement("label", { class: "container" })
|
|
9
14
|
const checkbox = createElement(
|
|
10
15
|
"input",
|
|
@@ -21,7 +26,10 @@ export function createSwitch(options = {}): HTMLElement {
|
|
|
21
26
|
return container
|
|
22
27
|
}
|
|
23
28
|
|
|
24
|
-
export function createSwitchOption(
|
|
29
|
+
export function createSwitchOption(
|
|
30
|
+
text: string,
|
|
31
|
+
options: SwichOptions
|
|
32
|
+
): HTMLElement {
|
|
25
33
|
const div = createElement("div", { class: "switch_option" })
|
|
26
34
|
addElement(div, "span", { textContent: text })
|
|
27
35
|
div.append(createSwitch(options))
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "browser-extension-settings",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Settings module for developing browser extensions and userscripts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"p": "prettier --write .",
|
|
9
|
-
"lint": "
|
|
9
|
+
"lint": "run-s lint:*",
|
|
10
|
+
"lint:code": "prettier --write . && xo --fix",
|
|
11
|
+
"lint:type": "tsc --noemit",
|
|
10
12
|
"test": "echo \"Error: no test specified\" && exit 0"
|
|
11
13
|
},
|
|
12
14
|
"repository": {
|
|
@@ -30,7 +32,9 @@
|
|
|
30
32
|
},
|
|
31
33
|
"devDependencies": {
|
|
32
34
|
"@types/chrome": "^0.0.237",
|
|
35
|
+
"npm-run-all": "^4.1.5",
|
|
33
36
|
"prettier": "^2.8.8",
|
|
37
|
+
"typescript": "^5.1.6",
|
|
34
38
|
"xo": "^0.54.2"
|
|
35
39
|
},
|
|
36
40
|
"files": [
|