nexfep 0.1.2 → 0.1.3

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-CN.md CHANGED
@@ -71,7 +71,7 @@ const win = await pool.createWindow(true, false);
71
71
 
72
72
  ### 窗口操作
73
73
 
74
- ```typescript
74
+ ```javascript
75
75
  window.show();
76
76
  window.hide();
77
77
  window.maximize();
@@ -81,11 +81,9 @@ window.setTitle('新标题');
81
81
  window.openDevTools();
82
82
  ```
83
83
 
84
- ### IPC 通信
84
+ ### 自定义消息
85
85
 
86
- 框架在 WebView 页面加载完成后会自动注入一系列控制函数,建议使用这些注入的函数进行 IPC 通信,而非直接使用 `@webviewjs/webview` 原生包装的 IPC。
87
-
88
- #### 发送自定义消息
86
+ #### 发送消息
89
87
 
90
88
  在页面中通过 `window.postMessage` 发送消息:
91
89
 
@@ -112,7 +110,9 @@ pool.onCustomMessage = (window, data) => {
112
110
  - `window` — 发送消息的窗口对象
113
111
  - `data` — 消息内容,为对象类型(JSON 序列化后会自动通过 `JSON.parse` 转换为对象)
114
112
 
115
- #### 触发自定义事件
113
+ ### 自定义事件
114
+
115
+ #### 触发事件
116
116
 
117
117
  在页面中通过 `window.invoke` 触发事件:
118
118
 
@@ -155,7 +155,44 @@ pool.unhandle('hello', (data) => {
155
155
  - `event` — 事件名称,需要和触发事件时的事件名称一致
156
156
  - `callback` — 事件处理函数,需要和监听事件时的回调函数一致
157
157
 
158
- #### 窗口控制函数
158
+ ### 全局变量
159
+
160
+ #### 设置变量
161
+
162
+ 在页面中通过 `window.setGlobal` 设置全局变量:
163
+
164
+ ```javascript
165
+ window.setGlobal('hello', 'world');
166
+ ```
167
+
168
+ **参数说明**
169
+
170
+ - `name` — 全局变量名称
171
+ - `value` — 全局变量值,任意类型的可序列化数据,会被序列化为 JSON 字符串后发送
172
+
173
+ #### 获取变量
174
+
175
+ 在页面中通过 `window.getGlobal` 获取全局变量:
176
+
177
+ ```javascript
178
+ const value = await window.getGlobal('hello');
179
+ ```
180
+
181
+ **参数说明**
182
+
183
+ - `name` — 全局变量名称
184
+
185
+ #### 全局变量Map
186
+
187
+ 在主进程中通过 `WindowPool.global` 获取一个包含所有全局变量的 `Map<string, any>` 对象,可对其进行设置、获取等操作:
188
+
189
+ ```typescript
190
+ const globals = pool.global;
191
+ globals.set('hello', 'world');
192
+ const value = globals.get('hello');
193
+ ```
194
+
195
+ ### 窗口控制函数
159
196
 
160
197
  页面中可直接调用以下注入函数进行窗口控制:
161
198
 
@@ -248,6 +285,7 @@ if (window.isNexfepLoadDone) {
248
285
  | `createWindow(isShow?, isDecorated?)` | `isShow`: boolean(默认 true), `isDecorated`: boolean(默认 true) | Promise\<Window> | 创建并获取一个窗口 |
249
286
  | `handle(event, callback)` | `event`: string, `callback`: (data: string) => void | 无 | 监听指定事件,当收到事件时触发回调函数 |
250
287
  | `unhandle(event, callback)` | `event`: string, `callback`: (data: string) => void | 无 | 取消监听指定事件回调中的指定函数 |
288
+ | `global` | / | Map\<string, any> | 全局变量Map,类型为 `Map<string, any>` |
251
289
  | `closeWindow(window)` | `window`: Window | Promise\<void> | 关闭指定窗口并回收至池中 |
252
290
  | `closePool()` | 无 | Promise\<void> | 关闭窗口池,退出应用 |
253
291
  | `mainloop()` | 无 | void | 启动应用主循环,阻塞直到应用退出 |
package/README.md CHANGED
@@ -71,7 +71,7 @@ const win = await pool.createWindow(true, false);
71
71
 
72
72
  ### Window Operations
73
73
 
74
- ```typescript
74
+ ```javascript
75
75
  window.show();
76
76
  window.hide();
77
77
  window.maximize();
@@ -81,11 +81,9 @@ window.setTitle('New Title');
81
81
  window.openDevTools();
82
82
  ```
83
83
 
84
- ### IPC Communication
84
+ ### Custom Messages
85
85
 
86
- The framework automatically injects a series of control functions after WebView page loading is complete. It is recommended to use these injected functions for IPC communication, rather than the native IPC wrapped by `@webviewjs/webview`.
87
-
88
- #### Send Custom Messages
86
+ #### Send Messages
89
87
 
90
88
  Send messages via `window.postMessage` in the page:
91
89
 
@@ -112,7 +110,9 @@ pool.onCustomMessage = (window, data) => {
112
110
  - `window` — The window object that sent the message
113
111
  - `data` — Message content, an object type (automatically converted from JSON string via `JSON.parse`)
114
112
 
115
- #### Invoke Custom Events
113
+ ### Custom Events
114
+
115
+ #### Invoke Events
116
116
 
117
117
  Invoke events via `window.invoke` in the page:
118
118
 
@@ -155,7 +155,44 @@ pool.unhandle('hello', (data) => {
155
155
  - `event` — Event name, must match the event name when listening
156
156
  - `callback` — Event handler function, must match the callback function when listening
157
157
 
158
- #### Window Control Functions
158
+ ### Global Variables
159
+
160
+ #### Set Variables
161
+
162
+ Set a global variable via `window.setGlobal` in the page:
163
+
164
+ ```javascript
165
+ window.setGlobal('hello', 'world');
166
+ ```
167
+
168
+ **Parameters**
169
+
170
+ - `name` — Global variable name
171
+ - `value` — Global variable value, any serializable data, will be serialized to JSON string before sending
172
+
173
+ #### Get Variables
174
+
175
+ Get a global variable via `window.getGlobal` in the page:
176
+
177
+ ```javascript
178
+ const value = await window.getGlobal('hello');
179
+ ```
180
+
181
+ **Parameters**
182
+
183
+ - `name` — Global variable name
184
+
185
+ #### Global Variable Map
186
+
187
+ Get a `Map<string, any>` containing all global variables via `WindowPool.global` in the main process, which supports operations like set and get:
188
+
189
+ ```typescript
190
+ const globals = pool.global;
191
+ globals.set('hello', 'world');
192
+ const value = globals.get('hello');
193
+ ```
194
+
195
+ ### Window Control Functions
159
196
 
160
197
  The following injected functions can be directly called in the page for window control:
161
198
 
@@ -246,8 +283,9 @@ if (window.isNexfepLoadDone) {
246
283
  | ------------------------------------- | -------------------------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------ |
247
284
  | `constructor(userDataFolder?)` | `userDataFolder`: string (optional) | WindowPool | Creates a window pool, optionally specifying the WebView2 user data directory |
248
285
  | `createWindow(isShow?, isDecorated?)` | `isShow`: boolean (default true), `isDecorated`: boolean (default true) | Promise\<Window> | Creates and returns a window |
249
- | `handle(event, callback)` | `event`: string, `callback`: (data: string) => void | None | Listens for the specified event, triggers callback when event is received |
250
- | `unhandle(event, callback)` | `event`: string, `callback`: (data: string) => void | None | Removes the specified callback from the event listener |
286
+ | `handle(event, callback)` | `event`: string, `callback`: (data: string) => void | None | Listens for the specified event, triggers callback when event is received |
287
+ | `unhandle(event, callback)` | `event`: string, `callback`: (data: string) => void | None | Removes the specified callback from the event listener |
288
+ | `global` | / | Map\<string, any> | A global variable map of type: `Map<string, any>` |
251
289
  | `closeWindow(window)` | `window`: Window | Promise\<void> | Closes the specified window and returns it to the pool |
252
290
  | `closePool()` | None | Promise\<void> | Closes the window pool and exits the application |
253
291
  | `mainloop()` | None | void | Starts the application main loop, blocking until the application exits |
@@ -282,4 +320,4 @@ pnpm run compile
282
320
 
283
321
  ## License
284
322
 
285
- MIT License
323
+ MIT License
package/index.d.ts CHANGED
@@ -31,6 +31,7 @@ declare class WindowPool {
31
31
  private injectCount;
32
32
  private windowCount;
33
33
  private freeWindowCount;
34
+ global: Map<string, any>;
34
35
  constructor(WindowsWebview2UserDataFolder?: string);
35
36
  __injectCode(window: Window, code: string): Promise<void>;
36
37
  __injectControlFunctions(windowObj: Window): Promise<void>;
package/index.js CHANGED
@@ -63,10 +63,8 @@ class Window {
63
63
  await this.myPool.__injectControlFunctions(this);
64
64
  }
65
65
  async loadHTML(html) {
66
- console.log("Before loadHTML");
67
66
  await this.webview.loadHtml(html);
68
67
  await this.myPool.__injectControlFunctions(this);
69
- console.log("After loadHTML");
70
68
  }
71
69
  }
72
70
  class WindowPool {
@@ -77,6 +75,7 @@ class WindowPool {
77
75
  injectCount;
78
76
  windowCount;
79
77
  freeWindowCount;
78
+ global;
80
79
  constructor(WindowsWebview2UserDataFolder = path.join(process.env.LOCALAPPDATA || os.homedir(), 'NexfepDevelopment.webview2-data')) {
81
80
  if (os.platform() === 'win32') {
82
81
  // 设置 WebView2 用户数据目录(仅 Windows 需要此配置)
@@ -85,7 +84,6 @@ class WindowPool {
85
84
  fs.mkdirSync(userDataDir, { recursive: true });
86
85
  }
87
86
  process.env.WEBVIEW2_USER_DATA_FOLDER = userDataDir;
88
- console.log('WebView2 user data folder:', userDataDir);
89
87
  }
90
88
  this.onCustomMessage = (window, data) => {
91
89
  console.log('Get Custom Message:', data, "from window", window.id);
@@ -96,12 +94,12 @@ class WindowPool {
96
94
  this.windows = [];
97
95
  this.windowCount = 0;
98
96
  this.freeWindowCount = 0;
97
+ this.global = new Map();
99
98
  }
100
99
  async __injectCode(window, code) {
101
100
  await window.webview.evaluateScript(code);
102
101
  }
103
102
  async __injectControlFunctions(windowObj) {
104
- console.log("Create INJECT_CODE");
105
103
  const INJECT_CSS = `
106
104
  [nexfep-area-drag],
107
105
  [nexfep-area-drag] * {
@@ -204,6 +202,26 @@ class WindowPool {
204
202
  });
205
203
  }
206
204
 
205
+ window.setGlobal = (name, value) => {
206
+ const MessageBody = { type: 'NexfepSetGlobal', name: name, value: value }
207
+ window.ipc.postMessage(JSON.stringify(MessageBody));
208
+ }
209
+
210
+ window.getGlobal = (name) => {
211
+ const MessageBody = { type: 'NexfepGetGlobal', eventId: [${this.injectCount}, ++window.eventCount], name: name }
212
+ window.ipc.postMessage(JSON.stringify(MessageBody));
213
+ return new Promise((resolve, reject) => {
214
+ window.addEventListener("nexfep-get-global-result-"+${this.injectCount}+"-"+window.eventCount, (event) => {
215
+ window.removeEventListener("nexfep-get-global-result-"+${this.injectCount}+"-"+window.eventCount, event);
216
+ if(event.detail){
217
+ resolve(event.detail);
218
+ }else{
219
+ resolve();
220
+ }
221
+ });
222
+ });
223
+ }
224
+
207
225
  // 注入 CSS 样式
208
226
  const style = document.createElement('style');
209
227
  style.textContent = \`${INJECT_CSS}\`;
@@ -215,9 +233,7 @@ class WindowPool {
215
233
  // 触发加载完成事件
216
234
  window.dispatchEvent(new Event('nexfep-load-done'));
217
235
  `;
218
- console.log("Before inject code INJECT_CODE");
219
236
  await this.__injectCode(windowObj, INJECT_CODE);
220
- console.log("After inject control functions");
221
237
  }
222
238
  async __createNewWindowObj() {
223
239
  const window = this.app.createBrowserWindow({ title: "Nexfep" });
@@ -284,6 +300,15 @@ class WindowPool {
284
300
  }
285
301
  });
286
302
  }
303
+ else if (dataObj.type == 'NexfepSetGlobal') {
304
+ this.global.set(dataObj.name, dataObj.value);
305
+ }
306
+ else if (dataObj.type == 'NexfepGetGlobal') {
307
+ const value = this.global.get(dataObj.name);
308
+ webview.evaluateScript(`
309
+ window.dispatchEvent(new Event('nexfep-get-global-result-${dataObj.eventId[0]}-${dataObj.eventId[1]}', { detail: ${JSON.stringify(value)} }));
310
+ `);
311
+ }
287
312
  });
288
313
  return windowObj;
289
314
  }
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "webview",
15
15
  "typescript"
16
16
  ],
17
- "version": "0.1.2",
17
+ "version": "0.1.3",
18
18
  "type": "module",
19
19
  "main": "./index.js",
20
20
  "scripts": {