@vacantthinker/firefox-addon-framework-easy 2026.526.1222 → 2026.526.1620
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/README.md +3 -1
- package/package.json +1 -1
- package/src/generate.js +110 -124
- package/src/serviceFetch.js +1 -1
- package/src/serviceUserSettings.js +1 -13
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ export function browserRuntimeManifestName() { }
|
|
|
56
56
|
```javascript
|
|
57
57
|
export function generateHtmlByUserSettings(
|
|
58
58
|
userSettings,
|
|
59
|
-
|
|
59
|
+
radioItemClickCallback,
|
|
60
60
|
) { }
|
|
61
61
|
|
|
62
62
|
```
|
|
@@ -131,6 +131,8 @@ export async function servicePostJson(
|
|
|
131
131
|
handleError,
|
|
132
132
|
) { }
|
|
133
133
|
|
|
134
|
+
export async function serviceSendDataToLocalAria2(message) { }
|
|
135
|
+
|
|
134
136
|
```
|
|
135
137
|
|
|
136
138
|
### 📄 File: `src/serviceGet.js`
|
package/package.json
CHANGED
package/src/generate.js
CHANGED
|
@@ -1,142 +1,128 @@
|
|
|
1
|
-
import {stoOpGet, stoOpSet} from './opStorage.js';
|
|
1
|
+
import { stoOpGet, stoOpSet } from './opStorage.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Generates HTML elements based on a user settings schema object.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* optionType: 'checkbox',
|
|
9
|
-
* options: ['Searcher1', 'Searcher2'],
|
|
10
|
-
* selected: ['Searcher1', 'Searcher2'],
|
|
11
|
-
* },
|
|
12
|
-
* videoQuality: {
|
|
13
|
-
* options: ['360', '480', '720', '1080', '1440', '2160'],
|
|
14
|
-
* selected: '720',
|
|
15
|
-
* },
|
|
16
|
-
* @param userSettings{{}}
|
|
17
|
-
* @param radioItemClickFn{function}
|
|
6
|
+
* @param {Object} userSettings
|
|
7
|
+
* @param {Function} radioItemClickCallback
|
|
18
8
|
* @returns {HTMLFieldSetElement[]}
|
|
19
9
|
*/
|
|
20
10
|
export function generateHtmlByUserSettings(
|
|
21
11
|
userSettings,
|
|
22
|
-
|
|
12
|
+
radioItemClickCallback,
|
|
23
13
|
) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
14
|
+
return Object.keys(userSettings).map((storageKey) => {
|
|
15
|
+
const storageValue = userSettings[storageKey];
|
|
16
|
+
const type = storageValue.type || 'text'; // Default to text if type is not specified
|
|
17
|
+
|
|
18
|
+
// Common container wrapper for every configuration item
|
|
19
|
+
const eleWrap = document.createElement('fieldset');
|
|
20
|
+
const eleTitle = document.createElement('legend');
|
|
21
|
+
eleTitle.textContent = storageKey;
|
|
22
|
+
eleWrap.append(eleTitle);
|
|
23
|
+
|
|
24
|
+
// --- CONDITION 1: CHECKBOX & RADIO ---
|
|
25
|
+
if (type === 'checkbox' || type === 'radio') {
|
|
26
|
+
const options = storageValue.options || [];
|
|
27
|
+
|
|
28
|
+
options.map((option) => {
|
|
29
|
+
const eleLabel = document.createElement('label');
|
|
30
|
+
eleLabel.textContent = option;
|
|
31
|
+
|
|
32
|
+
const eleInput = document.createElement('input');
|
|
33
|
+
eleInput.name = storageKey;
|
|
34
|
+
eleInput.type = type;
|
|
35
|
+
eleInput.value = option;
|
|
36
|
+
|
|
37
|
+
if (type === 'checkbox') {
|
|
38
|
+
stoOpGet(storageKey).then((v) => {
|
|
39
|
+
const initialArray = Array.from(v || storageValue.selected || []);
|
|
40
|
+
const set = new Set(initialArray);
|
|
41
|
+
eleInput.checked = set.has(option);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
eleInput.addEventListener('change', async () => {
|
|
45
|
+
const optionsCurrent = await stoOpGet(storageKey) || storageValue.selected || [];
|
|
46
|
+
const set = new Set(Array.from(optionsCurrent));
|
|
47
|
+
|
|
48
|
+
if (eleInput.checked) {
|
|
49
|
+
set.add(option);
|
|
50
|
+
} else {
|
|
51
|
+
set.delete(option);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const valueNew = Array.from(set);
|
|
55
|
+
console.info(`k=${storageKey} option=${option} eleInput.checked=${eleInput.checked} valueNew=${valueNew}`);
|
|
56
|
+
await stoOpSet(storageKey, valueNew);
|
|
57
|
+
});
|
|
41
58
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
let eleTitle = document.createElement('legend');
|
|
57
|
-
eleTitle.textContent = k;
|
|
58
|
-
eleWrap.append(eleTitle);
|
|
59
|
-
|
|
60
|
-
// console.info(`optionType=${optionType} options=${options}`)
|
|
61
|
-
options.map(
|
|
62
|
-
/**
|
|
63
|
-
*
|
|
64
|
-
* @param option{string}
|
|
65
|
-
*/
|
|
66
|
-
option => {
|
|
67
|
-
|
|
68
|
-
let eleLabel = document.createElement('label');
|
|
69
|
-
eleLabel.textContent = option;
|
|
70
|
-
|
|
71
|
-
let eleInput = document.createElement('input');
|
|
72
|
-
eleInput.name = k;
|
|
73
|
-
eleInput.type = optionType;
|
|
74
|
-
eleInput.value = option;
|
|
75
|
-
|
|
76
|
-
if (optionType === 'checkbox') {
|
|
77
|
-
stoOpGet(k).then(
|
|
78
|
-
/**
|
|
79
|
-
*
|
|
80
|
-
* @param v{string}
|
|
81
|
-
*/
|
|
82
|
-
v => {
|
|
83
|
-
let strings = Array.from(v);
|
|
84
|
-
console.info(`strings=${strings} option=${option}`);
|
|
85
|
-
const set = new Set(strings);
|
|
86
|
-
eleInput.checked = set.has(option);
|
|
87
|
-
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
else if (optionType === 'radio') {
|
|
91
|
-
stoOpGet(k).then(
|
|
92
|
-
/**
|
|
93
|
-
*
|
|
94
|
-
* @param v{string}
|
|
95
|
-
*/
|
|
96
|
-
v => {
|
|
97
|
-
if (option === v) {
|
|
98
|
-
eleInput.checked = true;
|
|
99
|
-
}
|
|
100
|
-
});
|
|
59
|
+
else if (type === 'radio') {
|
|
60
|
+
stoOpGet(storageKey).then((v) => {
|
|
61
|
+
const currentSelected = (v !== undefined && v !== null) ? v : storageValue.selected;
|
|
62
|
+
if (option === currentSelected) {
|
|
63
|
+
eleInput.checked = true;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
eleLabel.onclick = function () {
|
|
68
|
+
stoOpSet(storageKey, option).then(() => {
|
|
69
|
+
console.info(`k=${storageKey} option=${option}`);
|
|
70
|
+
if (typeof radioItemClickCallback === 'function') {
|
|
71
|
+
radioItemClickCallback(storageKey, option);
|
|
101
72
|
}
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
}
|
|
102
76
|
|
|
103
|
-
|
|
77
|
+
eleLabel.append(eleInput);
|
|
78
|
+
return eleLabel;
|
|
79
|
+
}).forEach((ele) => eleWrap.append(ele));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// --- CONDITION 2: TOGGLE BUTTON ---
|
|
83
|
+
else if (type === 'button') {
|
|
84
|
+
const eleButton = document.createElement('button');
|
|
85
|
+
eleButton.type = 'button'; // Prevent accidental form submissions
|
|
86
|
+
|
|
87
|
+
stoOpGet(storageKey).then((v) => {
|
|
88
|
+
// Fallback to default schema configuration if no value is stored yet
|
|
89
|
+
let currentStatus = (v !== undefined && v !== null) ? (v === true || v === 'true') : storageValue.selected;
|
|
90
|
+
eleButton.textContent = String(currentStatus);
|
|
91
|
+
|
|
92
|
+
eleButton.addEventListener('click', async () => {
|
|
93
|
+
currentStatus = !currentStatus; // Toggle state
|
|
94
|
+
eleButton.textContent = String(currentStatus);
|
|
95
|
+
console.info(`k=${storageKey} toggled to=${currentStatus}`);
|
|
96
|
+
await stoOpSet(storageKey, currentStatus);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
104
99
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
let textCurrent = eleLabel.textContent;
|
|
100
|
+
eleWrap.append(eleButton);
|
|
101
|
+
}
|
|
108
102
|
|
|
109
|
-
|
|
110
|
-
|
|
103
|
+
// --- CONDITION 3: NUMBER & TEXT INPUTS ---
|
|
104
|
+
else if (type === 'number' || type === 'text') {
|
|
105
|
+
const eleInput = document.createElement('input');
|
|
106
|
+
eleInput.type = type;
|
|
107
|
+
eleInput.name = storageKey;
|
|
111
108
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
set.delete(textCurrent);
|
|
119
|
-
}
|
|
109
|
+
stoOpGet(storageKey).then((v) => {
|
|
110
|
+
const currentVal = (v !== undefined && v !== null) ? v : storageValue.selected;
|
|
111
|
+
eleInput.value = currentVal;
|
|
112
|
+
});
|
|
120
113
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
114
|
+
// Updates storage on every keystroke/change execution
|
|
115
|
+
eleInput.addEventListener('input', async () => {
|
|
116
|
+
const rawValue = eleInput.value;
|
|
117
|
+
const finalizedValue = type === 'number' ? Number(rawValue) : rawValue;
|
|
125
118
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
eleLabel.onclick = function() {
|
|
130
|
-
stoOpSet(k, option).then(() => {
|
|
131
|
-
console.info(`k=${k} option=${option}`);
|
|
132
|
-
radioItemClickFn(k, option);
|
|
133
|
-
});
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
return eleLabel;
|
|
119
|
+
console.info(`k=${storageKey} value changed to=${finalizedValue}`);
|
|
120
|
+
await stoOpSet(storageKey, finalizedValue);
|
|
121
|
+
});
|
|
137
122
|
|
|
138
|
-
|
|
123
|
+
eleWrap.append(eleInput);
|
|
124
|
+
}
|
|
139
125
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
126
|
+
return eleWrap;
|
|
127
|
+
});
|
|
128
|
+
}
|
package/src/serviceFetch.js
CHANGED
|
@@ -40,7 +40,7 @@ export async function servicePostJson(
|
|
|
40
40
|
* }}
|
|
41
41
|
* @returns {Promise<Response>}
|
|
42
42
|
*/
|
|
43
|
-
async function serviceSendDataToLocalAria2(message) {
|
|
43
|
+
export async function serviceSendDataToLocalAria2(message) {
|
|
44
44
|
let {downlink, filename, rpcsecret, rpcport} = message;
|
|
45
45
|
|
|
46
46
|
const secret = rpcsecret;
|
|
@@ -2,18 +2,6 @@ import {stoOpGet, stoOpSet} from './opStorage.js';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* this function connect with generateHtmlByUserSettings()
|
|
5
|
-
* example
|
|
6
|
-
* searchEngine: {
|
|
7
|
-
* optionType: 'checkbox',
|
|
8
|
-
* options: ['Searcher1', 'Searcher2'],
|
|
9
|
-
* selected: ['Searcher1', 'Searcher2'],
|
|
10
|
-
* },
|
|
11
|
-
* videoQuality: {
|
|
12
|
-
* optionType: 'radio',
|
|
13
|
-
* options: ['360', '480', '720', '1080', '1440', '2160'],
|
|
14
|
-
* selected: '720',
|
|
15
|
-
* },
|
|
16
|
-
*
|
|
17
5
|
*
|
|
18
6
|
* @param userSettings{{}}
|
|
19
7
|
* @returns {Promise<void>}
|
|
@@ -38,7 +26,7 @@ export async function serviceInitUserSettings(userSettings) {
|
|
|
38
26
|
/**
|
|
39
27
|
* // todo
|
|
40
28
|
* @param userSettings{{}}
|
|
41
|
-
* @returns {Promise<{}>}
|
|
29
|
+
* @returns {Promise<{Object}>}
|
|
42
30
|
*/
|
|
43
31
|
export async function serviceGetUserSettings(userSettings) {
|
|
44
32
|
const red = {};
|