@vacantthinker/firefox-addon-framework-easy 2026.524.1751 โ†’ 2026.526.908

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 CHANGED
@@ -17,19 +17,19 @@ You can download, clone, or view the complete source code for this application h
17
17
 
18
18
  Below is a list of all public functions found inside the `src` directory:
19
19
 
20
- ### File: `src/baseORM.js`
20
+ ### ๐Ÿ“„ File: `src/baseORM.js`
21
21
  ```javascript
22
22
  export class BaseORM { }
23
23
 
24
24
  ```
25
25
 
26
- ### File: `src/browserNotification.js`
26
+ ### ๐Ÿ“„ File: `src/browserNotification.js`
27
27
  ```javascript
28
28
  export async function browserNotificationCreate(content, title = null) { }
29
29
 
30
30
  ```
31
31
 
32
- ### File: `src/browserRuntime.js`
32
+ ### ๐Ÿ“„ File: `src/browserRuntime.js`
33
33
  ```javascript
34
34
  export function browserRuntimeReload() { }
35
35
 
@@ -45,9 +45,11 @@ export async function browserRuntimePlatformInfo() { }
45
45
 
46
46
  export function browserRuntimeManifestVersion() { }
47
47
 
48
+ export function browserRuntimeManifestName() { }
49
+
48
50
  ```
49
51
 
50
- ### File: `src/generate.js`
52
+ ### ๐Ÿ“„ File: `src/generate.js`
51
53
  ```javascript
52
54
  export function generateHtmlByUserSettings(
53
55
  userSettings,
@@ -56,7 +58,7 @@ export function generateHtmlByUserSettings(
56
58
 
57
59
  ```
58
60
 
59
- ### File: `src/opStorage.js`
61
+ ### ๐Ÿ“„ File: `src/opStorage.js`
60
62
  ```javascript
61
63
  export async function stoOpCheck(k) { }
62
64
 
@@ -74,7 +76,7 @@ export async function stoOpSetNull(k) { }
74
76
 
75
77
  ```
76
78
 
77
- ### File: `src/opTab.js`
79
+ ### ๐Ÿ“„ File: `src/opTab.js`
78
80
  ```javascript
79
81
  export async function tabOpGet(tabId) { }
80
82
 
@@ -106,7 +108,15 @@ export async function tabOpRemoveCssCode(tabId, code) { }
106
108
 
107
109
  ```
108
110
 
109
- ### File: `src/serviceFetch.js`
111
+ ### ๐Ÿ“„ File: `src/serviceCommon.js`
112
+ ```javascript
113
+ export async function serviceElementPicker(message) { }
114
+
115
+ export async function serviceGetFullPageRectData(message) { }
116
+
117
+ ```
118
+
119
+ ### ๐Ÿ“„ File: `src/serviceFetch.js`
110
120
  ```javascript
111
121
  export async function servicePostJson(
112
122
  serverUrl,
@@ -116,7 +126,7 @@ export async function servicePostJson(
116
126
 
117
127
  ```
118
128
 
119
- ### File: `src/serviceGet.js`
129
+ ### ๐Ÿ“„ File: `src/serviceGet.js`
120
130
  ```javascript
121
131
  export function serviceGetDomainByUrl(url) { }
122
132
 
@@ -124,7 +134,7 @@ export function serviceGetCurrentDateYYYYMMDDHHMMSS() { }
124
134
 
125
135
  ```
126
136
 
127
- ### File: `src/serviceOpContent.js`
137
+ ### ๐Ÿ“„ File: `src/serviceOpContent.js`
128
138
  ```javascript
129
139
  export function serviceCopyContentToClipboard(content) { }
130
140
 
@@ -134,13 +144,13 @@ export function serviceRemoveIllegalWord(value) { }
134
144
 
135
145
  ```
136
146
 
137
- ### File: `src/servicePureVideolink.js`
147
+ ### ๐Ÿ“„ File: `src/servicePureVideolink.js`
138
148
  ```javascript
139
149
  export function servicePureVideolinkYTB(videolinkOrigin) { }
140
150
 
141
151
  ```
142
152
 
143
- ### File: `src/serviceUpdateALLStyle.js`
153
+ ### ๐Ÿ“„ File: `src/serviceUpdateTabStyle.js`
144
154
  ```javascript
145
155
  export async function serviceUpdataALLTextNodeColor(message) { }
146
156
 
@@ -148,7 +158,7 @@ export async function serviceUpdataALLNodeBackgroundColor(message) { }
148
158
 
149
159
  ```
150
160
 
151
- ### File: `src/serviceUserSettings.js`
161
+ ### ๐Ÿ“„ File: `src/serviceUserSettings.js`
152
162
  ```javascript
153
163
  export async function serviceInitUserSettings(userSettings) { }
154
164
 
package/index.js CHANGED
@@ -4,9 +4,10 @@ export * from './src/browserRuntime.js'
4
4
  export * from './src/generate.js'
5
5
  export * from './src/opStorage.js'
6
6
  export * from './src/opTab.js'
7
+ export * from './src/serviceCommon.js'
7
8
  export * from './src/serviceFetch.js'
8
9
  export * from './src/serviceGet.js'
9
10
  export * from './src/serviceOpContent.js'
10
11
  export * from './src/servicePureVideolink.js'
11
- export * from './src/serviceUpdateALLStyle.js'
12
+ export * from './src/serviceUpdateTabStyle.js'
12
13
  export * from './src/serviceUserSettings.js'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vacantthinker/firefox-addon-framework-easy",
3
- "version": "2026.0524.1751",
3
+ "version": "2026.0526.0908",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "publishConfig": {
package/publish.sh CHANGED
@@ -47,7 +47,7 @@ EOF
47
47
  # 2. Iterate through all js files, capture multi-line signatures, and append them to README
48
48
  for file in src/*.js; do
49
49
  if [ -f "$file" ]; then
50
- echo "### File: \`$file\`" >> README.md
50
+ echo "### ๐Ÿ“„ File: \`$file\`" >> README.md
51
51
  echo "\`\`\`javascript" >> README.md
52
52
 
53
53
  # Reads multi-line signatures up to the opening brace or semicolon
@@ -56,6 +56,18 @@ export async function browserRuntimePlatformInfo() {
56
56
  return await browser.runtime.getPlatformInfo();
57
57
  }
58
58
 
59
+ /**
60
+ * browser.runtime.getManifest().version;
61
+ * @returns {string}
62
+ */
59
63
  export function browserRuntimeManifestVersion() {
60
64
  return browser.runtime.getManifest().version;
61
- }
65
+ }
66
+
67
+ /**
68
+ * browser.runtime.getManifest().name;
69
+ * @returns {string}
70
+ */
71
+ export function browserRuntimeManifestName() {
72
+ return browser.runtime.getManifest().name;
73
+ }
package/src/generate.js CHANGED
@@ -8,10 +8,6 @@ import {stoOpGet, stoOpSet} from './opStorage.js';
8
8
  * optionType: 'checkbox',
9
9
  * options: ['Searcher1', 'Searcher2'],
10
10
  * selected: ['Searcher1', 'Searcher2'],
11
- * queryTitle: {
12
- * 'Searcher1': 'https://y2down.cc/',
13
- * 'Searcher2': 'https://ssyou.online',
14
- * },
15
11
  * },
16
12
  * videoQuality: {
17
13
  * options: ['360', '480', '720', '1080', '1440', '2160'],
@@ -0,0 +1,176 @@
1
+ /**
2
+ * will get => {{x, y, width, height, uniqueSelector}}
3
+ * @param message{{
4
+ * tabId:number,
5
+ * act:string
6
+ * }}
7
+ * @returns {Promise<void>}
8
+ */
9
+ export async function serviceElementPicker(message) {
10
+ let {tabId} = message;
11
+ await browser.scripting.executeScript({
12
+ target: {tabId},
13
+ args: [message],
14
+ func: async function(message) {
15
+ if (!message) return;
16
+ console.log('picker.js initialized', message);
17
+
18
+ // 1. Create a dedicated "Always On Top" highlighter overlay
19
+ const overlayId = 'extension-element-highlighter-overlay';
20
+ let overlay = document.getElementById(overlayId);
21
+
22
+ if (!overlay) {
23
+ overlay = document.createElement('div');
24
+ overlay.id = overlayId;
25
+ // !important and max z-index guarantees it will never be hidden by site CSS
26
+ overlay.style.cssText = `
27
+ position: fixed !important;
28
+ top: 0 !important;
29
+ left: 0 !important;
30
+ width: 0 !important;
31
+ height: 0 !important;
32
+ background-color: rgba(255, 0, 85, 0.2) !important;
33
+ outline: 2px dashed #ff0055 !important;
34
+ outline-offset: -2px !important;
35
+ z-index: 2147483647 !important;
36
+ pointer-events: none !important;
37
+ transition: all 0.05s ease-out !important;
38
+ display: none !important;
39
+ `;
40
+ // Appending to documentElement (<html>) avoids <body> layout restrictions
41
+ document.documentElement.appendChild(overlay);
42
+ }
43
+
44
+ function getUniqueSelector(el) {
45
+ if (!(el instanceof Element)) return '';
46
+ const path = [];
47
+ while (el.nodeType === Node.ELEMENT_NODE) {
48
+ let selector = el.nodeName.toLowerCase();
49
+ if (el.id) {
50
+ selector += '#' + el.id;
51
+ path.unshift(selector);
52
+ break;
53
+ }
54
+ else {
55
+ let sib = el, nth = 1;
56
+ while (sib = sib.previousElementSibling) {
57
+ if (sib.nodeName.toLowerCase() === selector) nth++;
58
+ }
59
+ if (nth !== 1) selector += `:nth-of-type(${nth})`;
60
+ }
61
+ path.unshift(selector);
62
+ el = el.parentNode;
63
+ }
64
+ return path.join(' > ');
65
+ }
66
+
67
+ function handleMouseOver(e) {
68
+ const target = e.target;
69
+
70
+ // Safety check to ensure we don't try to highlight our own UI
71
+ if (target.id === overlayId) return;
72
+
73
+ // Get exact coordinates of the hovered element
74
+ const rect = target.getBoundingClientRect();
75
+
76
+ // Move the floating overlay exactly over the target
77
+ overlay.style.setProperty('display', 'block', 'important');
78
+ overlay.style.setProperty('top', `${rect.top}px`, 'important');
79
+ overlay.style.setProperty('left', `${rect.left}px`, 'important');
80
+ overlay.style.setProperty('width', `${rect.width}px`, 'important');
81
+ overlay.style.setProperty('height', `${rect.height}px`, 'important');
82
+
83
+ // Change mouse cursor to indicate picking mode
84
+ document.body.style.setProperty('cursor', 'crosshair', 'important');
85
+ }
86
+
87
+ async function handleElementClick(e) {
88
+ e.preventDefault();
89
+ e.stopPropagation();
90
+
91
+ const target = e.target;
92
+
93
+ // Clean up the picker completely
94
+ stopPickingMode();
95
+
96
+ // Calculate screenshot coordinates
97
+ let rect = target.getBoundingClientRect();
98
+ let rectData = {
99
+ height: rect.height,
100
+ width: rect.width,
101
+ x: rect.left + window.scrollX,
102
+ y: rect.top + window.scrollY,
103
+ selector: getUniqueSelector(target),
104
+ };
105
+
106
+ console.log('Target Selected:', {rectData});
107
+
108
+ // Assuming 'target' is your clicked element (e.g., from e.target)
109
+ let messageTakeScreenshot = Object.assign(
110
+ {}, // Start with a fresh, empty object
111
+ message, // Put the original message first so it doesn't overwrite your new data
112
+ rectData,
113
+ {
114
+ // The guaranteed unique CSS path (e.g., "div#wrap > ul > li:nth-of-type(2)")
115
+ uniqueSelector: getUniqueSelector(target),
116
+ },
117
+ );
118
+
119
+ await browser.runtime.sendMessage(messageTakeScreenshot);
120
+ }
121
+
122
+ function startPickingMode() {
123
+ document.addEventListener('mouseover', handleMouseOver, true);
124
+ document.addEventListener('click', handleElementClick, true);
125
+ }
126
+
127
+ function stopPickingMode() {
128
+ document.removeEventListener('mouseover', handleMouseOver, true);
129
+ document.removeEventListener('click', handleElementClick, true);
130
+
131
+ // Restore normal mouse cursor
132
+ document.body.style.removeProperty('cursor');
133
+
134
+ // Remove the overlay from the DOM entirely
135
+ if (overlay) {
136
+ overlay.remove();
137
+ }
138
+ }
139
+
140
+ // Initialize the picker mode
141
+ startPickingMode();
142
+ },
143
+ });
144
+ }
145
+
146
+ /**
147
+ * will get => {{x, y, width, height,}}
148
+ * @param message{{
149
+ * tabId:number,
150
+ * act:string
151
+ * }}
152
+ * @returns {Promise<void>}
153
+ */
154
+ export async function serviceGetFullPageRectData(message) {
155
+ let {tabId} = message;
156
+
157
+ await browser.scripting.executeScript({
158
+ target: {tabId},
159
+ args: [message],
160
+ func: async (message) => {
161
+
162
+ let x = 0, y = 0;
163
+ let width = document.documentElement.scrollWidth;
164
+ let height = document.documentElement.scrollHeight;
165
+
166
+ await browser.runtime.sendMessage(Object.assign(
167
+ {},
168
+ message,
169
+ {
170
+ x, y, width, height,
171
+ },
172
+ ));
173
+ // todo end if (message)
174
+ },
175
+ });
176
+ }
@@ -1,20 +1,19 @@
1
1
  import {stoOpGet, stoOpSet} from './opStorage.js';
2
2
 
3
3
  /**
4
- *
4
+ * this function connect with generateHtmlByUserSettings()
5
+ * example
5
6
  * searchEngine: {
6
7
  * optionType: 'checkbox',
7
8
  * options: ['Searcher1', 'Searcher2'],
8
9
  * selected: ['Searcher1', 'Searcher2'],
9
- * queryTitle: {
10
- * 'Searcher1': 'https://y2down.cc/',
11
- * 'Searcher2': 'https://ssyou.online',
12
- * },
13
10
  * },
14
11
  * videoQuality: {
12
+ * optionType: 'radio',
15
13
  * options: ['360', '480', '720', '1080', '1440', '2160'],
16
14
  * selected: '720',
17
15
  * },
16
+ *
18
17
  *
19
18
  * @param userSettings{{}}
20
19
  * @returns {Promise<void>}
@@ -37,7 +36,7 @@ export async function serviceInitUserSettings(userSettings) {
37
36
  }
38
37
 
39
38
  /**
40
- * // todo ๅฝ“ๅ‰่ฟ™ไธชๆ–‡ไปถ ๅปบ่ฎฎไฝฟ็”จ็”Ÿๆˆๅผ่„šๆœฌๆฅๅค„็†
39
+ * // todo
41
40
  * @param userSettings{{}}
42
41
  * @returns {Promise<{}>}
43
42
  */