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

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
 
@@ -47,7 +47,7 @@ export function browserRuntimeManifestVersion() { }
47
47
 
48
48
  ```
49
49
 
50
- ### File: `src/generate.js`
50
+ ### ๐Ÿ“„ File: `src/generate.js`
51
51
  ```javascript
52
52
  export function generateHtmlByUserSettings(
53
53
  userSettings,
@@ -56,7 +56,7 @@ export function generateHtmlByUserSettings(
56
56
 
57
57
  ```
58
58
 
59
- ### File: `src/opStorage.js`
59
+ ### ๐Ÿ“„ File: `src/opStorage.js`
60
60
  ```javascript
61
61
  export async function stoOpCheck(k) { }
62
62
 
@@ -74,7 +74,7 @@ export async function stoOpSetNull(k) { }
74
74
 
75
75
  ```
76
76
 
77
- ### File: `src/opTab.js`
77
+ ### ๐Ÿ“„ File: `src/opTab.js`
78
78
  ```javascript
79
79
  export async function tabOpGet(tabId) { }
80
80
 
@@ -106,7 +106,15 @@ export async function tabOpRemoveCssCode(tabId, code) { }
106
106
 
107
107
  ```
108
108
 
109
- ### File: `src/serviceFetch.js`
109
+ ### ๐Ÿ“„ File: `src/serviceCommon.js`
110
+ ```javascript
111
+ export async function serviceElementPicker(message) { }
112
+
113
+ export async function serviceGetFullPageRectData(message) { }
114
+
115
+ ```
116
+
117
+ ### ๐Ÿ“„ File: `src/serviceFetch.js`
110
118
  ```javascript
111
119
  export async function servicePostJson(
112
120
  serverUrl,
@@ -116,7 +124,7 @@ export async function servicePostJson(
116
124
 
117
125
  ```
118
126
 
119
- ### File: `src/serviceGet.js`
127
+ ### ๐Ÿ“„ File: `src/serviceGet.js`
120
128
  ```javascript
121
129
  export function serviceGetDomainByUrl(url) { }
122
130
 
@@ -124,7 +132,7 @@ export function serviceGetCurrentDateYYYYMMDDHHMMSS() { }
124
132
 
125
133
  ```
126
134
 
127
- ### File: `src/serviceOpContent.js`
135
+ ### ๐Ÿ“„ File: `src/serviceOpContent.js`
128
136
  ```javascript
129
137
  export function serviceCopyContentToClipboard(content) { }
130
138
 
@@ -134,13 +142,13 @@ export function serviceRemoveIllegalWord(value) { }
134
142
 
135
143
  ```
136
144
 
137
- ### File: `src/servicePureVideolink.js`
145
+ ### ๐Ÿ“„ File: `src/servicePureVideolink.js`
138
146
  ```javascript
139
147
  export function servicePureVideolinkYTB(videolinkOrigin) { }
140
148
 
141
149
  ```
142
150
 
143
- ### File: `src/serviceUpdateALLStyle.js`
151
+ ### ๐Ÿ“„ File: `src/serviceUpdateTabStyle.js`
144
152
  ```javascript
145
153
  export async function serviceUpdataALLTextNodeColor(message) { }
146
154
 
@@ -148,7 +156,7 @@ export async function serviceUpdataALLNodeBackgroundColor(message) { }
148
156
 
149
157
  ```
150
158
 
151
- ### File: `src/serviceUserSettings.js`
159
+ ### ๐Ÿ“„ File: `src/serviceUserSettings.js`
152
160
  ```javascript
153
161
  export async function serviceInitUserSettings(userSettings) { }
154
162
 
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.0525.2018",
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
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,15 +1,12 @@
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: {
15
12
  * options: ['360', '480', '720', '1080', '1440', '2160'],
@@ -37,7 +34,7 @@ export async function serviceInitUserSettings(userSettings) {
37
34
  }
38
35
 
39
36
  /**
40
- * // todo ๅฝ“ๅ‰่ฟ™ไธชๆ–‡ไปถ ๅปบ่ฎฎไฝฟ็”จ็”Ÿๆˆๅผ่„šๆœฌๆฅๅค„็†
37
+ * // todo
41
38
  * @param userSettings{{}}
42
39
  * @returns {Promise<{}>}
43
40
  */