plusui-native-core 0.1.3 → 0.1.5
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/Core/CMakeLists.txt +190 -7
- package/Core/Features/App/app.cpp +129 -0
- package/Core/Features/App/app.ts +126 -0
- package/Core/Features/Browser/browser.cpp +181 -0
- package/Core/Features/Browser/browser.ts +182 -0
- package/Core/Features/Clipboard/clipboard.cpp +234 -0
- package/Core/Features/Clipboard/clipboard.ts +113 -0
- package/Core/Features/Display/display.cpp +209 -0
- package/Core/Features/Display/display.ts +104 -0
- package/Core/Features/Event/Events.ts +166 -0
- package/Core/Features/Event/events.cpp +200 -0
- package/Core/Features/Keyboard/keyboard.cpp +186 -0
- package/Core/Features/Keyboard/keyboard.ts +175 -0
- package/Core/Features/Menu/context-menu.css +293 -0
- package/Core/Features/Menu/menu.cpp +481 -0
- package/Core/Features/Menu/menu.ts +439 -0
- package/Core/Features/Tray/tray.cpp +310 -0
- package/Core/Features/Tray/tray.ts +68 -0
- package/Core/Features/WebGPU/webgpu.cpp +937 -0
- package/Core/Features/WebGPU/webgpu.ts +1013 -0
- package/Core/Features/WebView/webview.cpp +1052 -0
- package/Core/Features/WebView/webview.ts +510 -0
- package/Core/Features/Window/window.cpp +664 -0
- package/Core/Features/Window/window.ts +142 -0
- package/Core/Features/WindowManager/window_manager.cpp +341 -0
- package/Core/include/plusui/app.hpp +73 -0
- package/Core/include/plusui/browser.hpp +66 -0
- package/Core/include/plusui/clipboard.hpp +41 -0
- package/Core/include/plusui/events.hpp +58 -0
- package/Core/include/{keyboard.hpp → plusui/keyboard.hpp} +21 -44
- package/Core/include/plusui/menu.hpp +153 -0
- package/Core/include/plusui/tray.hpp +93 -0
- package/Core/include/plusui/webgpu.hpp +434 -0
- package/Core/include/plusui/webview.hpp +142 -0
- package/Core/include/plusui/window.hpp +111 -0
- package/Core/include/plusui/window_manager.hpp +57 -0
- package/Core/vendor/WebView2EnvironmentOptions.h +406 -0
- package/Core/vendor/stb_image.h +7988 -0
- package/Core/vendor/webview.h +618 -510
- package/Core/vendor/webview2.h +52079 -0
- package/README.md +19 -0
- package/package.json +12 -15
- package/Core/include/app.hpp +0 -121
- package/Core/include/menu.hpp +0 -79
- package/Core/include/tray.hpp +0 -81
- package/Core/include/window.hpp +0 -106
- package/Core/src/app.cpp +0 -311
- package/Core/src/display.cpp +0 -424
- package/Core/src/tray.cpp +0 -275
- package/Core/src/window.cpp +0 -528
- package/dist/index.d.ts +0 -205
- package/dist/index.js +0 -198
- package/src/index.ts +0 -574
- /package/Core/include/{display.hpp → plusui/display.hpp} +0 -0
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebView API - Web content rendering and JavaScript execution
|
|
3
|
+
*
|
|
4
|
+
* Provides comprehensive webview operations including:
|
|
5
|
+
* - HTML/URL loading
|
|
6
|
+
* - JavaScript execution and bidirectional communication
|
|
7
|
+
* - Navigation controls
|
|
8
|
+
* - Dev tools integration
|
|
9
|
+
* - CSS injection and customization
|
|
10
|
+
* - Event handling for page lifecycle
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export interface WebViewConfig {
|
|
14
|
+
userAgent?: string;
|
|
15
|
+
devtools?: boolean;
|
|
16
|
+
contextMenu?: boolean;
|
|
17
|
+
javascript?: boolean;
|
|
18
|
+
webSecurity?: boolean;
|
|
19
|
+
allowFileAccess?: boolean;
|
|
20
|
+
allowRemoteContent?: boolean;
|
|
21
|
+
dataPath?: string;
|
|
22
|
+
cacheSize?: number; // MB
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type WindowId = number;
|
|
26
|
+
|
|
27
|
+
export interface WebViewAPI {
|
|
28
|
+
// Initialization
|
|
29
|
+
initialize(windowId: WindowId, config?: WebViewConfig): Promise<void>;
|
|
30
|
+
|
|
31
|
+
// Content loading
|
|
32
|
+
loadURL(url: string): Promise<void>;
|
|
33
|
+
loadHTML(html: string, baseURL?: string): Promise<void>;
|
|
34
|
+
loadFile(filePath: string): Promise<void>;
|
|
35
|
+
|
|
36
|
+
// Navigation
|
|
37
|
+
reload(): Promise<void>;
|
|
38
|
+
reloadIgnoringCache(): Promise<void>;
|
|
39
|
+
stop(): Promise<void>;
|
|
40
|
+
goBack(): Promise<void>;
|
|
41
|
+
goForward(): Promise<void>;
|
|
42
|
+
goToOffset(offset: number): Promise<void>;
|
|
43
|
+
canGoBack(): Promise<boolean>;
|
|
44
|
+
canGoForward(): Promise<boolean>;
|
|
45
|
+
clearHistory(): Promise<void>;
|
|
46
|
+
|
|
47
|
+
// JavaScript execution
|
|
48
|
+
executeScript(script: string): Promise<void>;
|
|
49
|
+
executeScriptWithResult<T = any>(script: string): Promise<T>;
|
|
50
|
+
executeScriptAsync(script: string): Promise<void>;
|
|
51
|
+
|
|
52
|
+
// JavaScript bindings
|
|
53
|
+
bind(name: string, callback: (...args: any[]) => any): Promise<void>;
|
|
54
|
+
unbind(name: string): Promise<void>;
|
|
55
|
+
unbindAll(): Promise<void>;
|
|
56
|
+
|
|
57
|
+
// IPC - Message passing
|
|
58
|
+
postMessage(message: string): Promise<void>;
|
|
59
|
+
onMessage(callback: (message: string) => void): () => void;
|
|
60
|
+
|
|
61
|
+
// Dev tools
|
|
62
|
+
openDevTools(): Promise<void>;
|
|
63
|
+
closeDevTools(): Promise<void>;
|
|
64
|
+
toggleDevTools(): Promise<void>;
|
|
65
|
+
isDevToolsOpen(): Promise<boolean>;
|
|
66
|
+
|
|
67
|
+
// Settings
|
|
68
|
+
setUserAgent(userAgent: string): Promise<void>;
|
|
69
|
+
getUserAgent(): Promise<string>;
|
|
70
|
+
setZoom(factor: number): Promise<void>;
|
|
71
|
+
getZoom(): Promise<number>;
|
|
72
|
+
setBackgroundColor(r: number, g: number, b: number, a?: number): Promise<void>;
|
|
73
|
+
setScrollbarsVisible(visible: boolean): Promise<void>;
|
|
74
|
+
|
|
75
|
+
// CSS injection
|
|
76
|
+
injectCSS(css: string): Promise<void>;
|
|
77
|
+
removeCSS(identifier: string): Promise<void>;
|
|
78
|
+
|
|
79
|
+
// JavaScript injection
|
|
80
|
+
injectScript(script: string): Promise<void>;
|
|
81
|
+
injectScriptAtStart(script: string): Promise<void>;
|
|
82
|
+
|
|
83
|
+
// Cache and data
|
|
84
|
+
clearCache(): Promise<void>;
|
|
85
|
+
clearCookies(): Promise<void>;
|
|
86
|
+
clearStorage(): Promise<void>;
|
|
87
|
+
setCookie(name: string, value: string, domain?: string): Promise<void>;
|
|
88
|
+
getCookie(name: string): Promise<string>;
|
|
89
|
+
|
|
90
|
+
// Content control
|
|
91
|
+
setHTML(html: string): Promise<void>;
|
|
92
|
+
getHTML(): Promise<string>;
|
|
93
|
+
setTitle(title: string): Promise<void>;
|
|
94
|
+
getTitle(): Promise<string>;
|
|
95
|
+
|
|
96
|
+
// Print
|
|
97
|
+
print(): Promise<void>;
|
|
98
|
+
printToPDF(path: string): Promise<void>;
|
|
99
|
+
|
|
100
|
+
// Find in page
|
|
101
|
+
find(text: string, forward?: boolean, caseSensitive?: boolean): Promise<void>;
|
|
102
|
+
stopFind(clearSelection?: boolean): Promise<void>;
|
|
103
|
+
|
|
104
|
+
// Security
|
|
105
|
+
setAllowFileAccess(allow: boolean): Promise<void>;
|
|
106
|
+
setAllowRemoteContent(allow: boolean): Promise<void>;
|
|
107
|
+
setWebSecurity(enabled: boolean): Promise<void>;
|
|
108
|
+
|
|
109
|
+
// Download handling
|
|
110
|
+
setDownloadPath(path: string): Promise<void>;
|
|
111
|
+
getDownloadPath(): Promise<string>;
|
|
112
|
+
|
|
113
|
+
// Lifecycle events
|
|
114
|
+
onNavigationStart(callback: (url: string) => boolean): () => void; // Return false to cancel
|
|
115
|
+
onNavigationComplete(callback: () => void): () => void;
|
|
116
|
+
onLoadStart(callback: () => void): () => void;
|
|
117
|
+
onLoadEnd(callback: () => void): () => void;
|
|
118
|
+
onLoadError(callback: (error: string, code: number) => void): () => void;
|
|
119
|
+
onTitleChange(callback: (title: string) => void): () => void;
|
|
120
|
+
onURLChange(callback: (url: string) => void): () => void;
|
|
121
|
+
onFullscreenChange(callback: (isFullscreen: boolean) => void): () => void;
|
|
122
|
+
|
|
123
|
+
// JavaScript events
|
|
124
|
+
onConsoleMessage(callback: (message: string, level: number, source: string) => void): () => void;
|
|
125
|
+
onScriptError(callback: (error: string, code: number) => void): () => void;
|
|
126
|
+
|
|
127
|
+
// Download events
|
|
128
|
+
onDownloadStart(callback: (url: string, filename: string) => void): () => void;
|
|
129
|
+
onDownloadProgress(callback: (url: string, current: number, total: number) => void): () => void;
|
|
130
|
+
onDownloadComplete(callback: (path: string) => void): () => void;
|
|
131
|
+
|
|
132
|
+
// Permission events
|
|
133
|
+
onPermissionRequest(callback: (origin: string, permission: string) => boolean): () => void;
|
|
134
|
+
|
|
135
|
+
// State queries
|
|
136
|
+
isLoading(): Promise<boolean>;
|
|
137
|
+
getURL(): Promise<string>;
|
|
138
|
+
getLoadProgress(): Promise<number>; // 0-100
|
|
139
|
+
canExecuteScripts(): Promise<boolean>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export class WebView implements WebViewAPI {
|
|
143
|
+
private invokeFn: (name: string, args?: unknown[]) => Promise<unknown>;
|
|
144
|
+
private onFn: (event: string, callback: (data: unknown) => void) => () => void;
|
|
145
|
+
private windowId?: WindowId;
|
|
146
|
+
|
|
147
|
+
constructor(
|
|
148
|
+
invokeFn: (name: string, args?: unknown[]) => Promise<unknown>,
|
|
149
|
+
onFn: (event: string, callback: (data: unknown) => void) => () => void,
|
|
150
|
+
windowId?: WindowId
|
|
151
|
+
) {
|
|
152
|
+
this.invokeFn = invokeFn;
|
|
153
|
+
this.onFn = onFn;
|
|
154
|
+
this.windowId = windowId;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Initialization
|
|
158
|
+
async initialize(windowId: WindowId, config?: WebViewConfig): Promise<void> {
|
|
159
|
+
this.windowId = windowId;
|
|
160
|
+
await this.invokeFn('webview.initialize', [windowId, config]);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Content loading
|
|
164
|
+
async loadURL(url: string): Promise<void> {
|
|
165
|
+
await this.invokeFn('webview.loadURL', [url]);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async loadHTML(html: string, baseURL?: string): Promise<void> {
|
|
169
|
+
if (baseURL) {
|
|
170
|
+
await this.invokeFn('webview.loadHTML', [html, baseURL]);
|
|
171
|
+
} else {
|
|
172
|
+
await this.invokeFn('webview.loadHTML', [html]);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async loadFile(filePath: string): Promise<void> {
|
|
177
|
+
await this.invokeFn('webview.loadFile', [filePath]);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Navigation
|
|
181
|
+
async reload(): Promise<void> {
|
|
182
|
+
await this.invokeFn('webview.reload');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async reloadIgnoringCache(): Promise<void> {
|
|
186
|
+
await this.invokeFn('webview.reloadIgnoringCache');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async stop(): Promise<void> {
|
|
190
|
+
await this.invokeFn('webview.stop');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async goBack(): Promise<void> {
|
|
194
|
+
await this.invokeFn('webview.goBack');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
async goForward(): Promise<void> {
|
|
198
|
+
await this.invokeFn('webview.goForward');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async goToOffset(offset: number): Promise<void> {
|
|
202
|
+
await this.invokeFn('webview.goToOffset', [offset]);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async canGoBack(): Promise<boolean> {
|
|
206
|
+
return (await this.invokeFn('webview.canGoBack')) as boolean;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async canGoForward(): Promise<boolean> {
|
|
210
|
+
return (await this.invokeFn('webview.canGoForward')) as boolean;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async clearHistory(): Promise<void> {
|
|
214
|
+
await this.invokeFn('webview.clearHistory');
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// JavaScript execution
|
|
218
|
+
async executeScript(script: string): Promise<void> {
|
|
219
|
+
await this.invokeFn('webview.executeScript', [script]);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async executeScriptWithResult<T = any>(script: string): Promise<T> {
|
|
223
|
+
return (await this.invokeFn('webview.executeScriptWithResult', [script])) as T;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async executeScriptAsync(script: string): Promise<void> {
|
|
227
|
+
await this.invokeFn('webview.executeScriptAsync', [script]);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// JavaScript bindings
|
|
231
|
+
async bind(name: string, callback: (...args: any[]) => any): Promise<void> {
|
|
232
|
+
// Store the callback locally and expose it via IPC
|
|
233
|
+
await this.invokeFn('webview.bind', [name]);
|
|
234
|
+
|
|
235
|
+
// Handle calls from webview
|
|
236
|
+
this.onFn(`webview:call:${name}`, (args: any) => {
|
|
237
|
+
const result = callback(...(Array.isArray(args) ? args : [args]));
|
|
238
|
+
this.invokeFn('webview.bindResponse', [name, result]);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async unbind(name: string): Promise<void> {
|
|
243
|
+
await this.invokeFn('webview.unbind', [name]);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async unbindAll(): Promise<void> {
|
|
247
|
+
await this.invokeFn('webview.unbindAll');
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// IPC
|
|
251
|
+
async postMessage(message: string): Promise<void> {
|
|
252
|
+
await this.invokeFn('webview.postMessage', [message]);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
onMessage(callback: (message: string) => void): () => void {
|
|
256
|
+
return this.onFn('webview:message', (data) => {
|
|
257
|
+
callback(data as string);
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Dev tools
|
|
262
|
+
async openDevTools(): Promise<void> {
|
|
263
|
+
await this.invokeFn('webview.openDevTools');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async closeDevTools(): Promise<void> {
|
|
267
|
+
await this.invokeFn('webview.closeDevTools');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
async toggleDevTools(): Promise<void> {
|
|
271
|
+
await this.invokeFn('webview.toggleDevTools');
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
async isDevToolsOpen(): Promise<boolean> {
|
|
275
|
+
return (await this.invokeFn('webview.isDevToolsOpen')) as boolean;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Settings
|
|
279
|
+
async setUserAgent(userAgent: string): Promise<void> {
|
|
280
|
+
await this.invokeFn('webview.setUserAgent', [userAgent]);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
async getUserAgent(): Promise<string> {
|
|
284
|
+
return (await this.invokeFn('webview.getUserAgent')) as string;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
async setZoom(factor: number): Promise<void> {
|
|
288
|
+
await this.invokeFn('webview.setZoom', [factor]);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
async getZoom(): Promise<number> {
|
|
292
|
+
return (await this.invokeFn('webview.getZoom')) as number;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
async setBackgroundColor(r: number, g: number, b: number, a: number = 255): Promise<void> {
|
|
296
|
+
await this.invokeFn('webview.setBackgroundColor', [r, g, b, a]);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
async setScrollbarsVisible(visible: boolean): Promise<void> {
|
|
300
|
+
await this.invokeFn('webview.setScrollbarsVisible', [visible]);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// CSS injection
|
|
304
|
+
async injectCSS(css: string): Promise<void> {
|
|
305
|
+
await this.invokeFn('webview.injectCSS', [css]);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
async removeCSS(identifier: string): Promise<void> {
|
|
309
|
+
await this.invokeFn('webview.removeCSS', [identifier]);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// JavaScript injection
|
|
313
|
+
async injectScript(script: string): Promise<void> {
|
|
314
|
+
await this.invokeFn('webview.injectScript', [script]);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async injectScriptAtStart(script: string): Promise<void> {
|
|
318
|
+
await this.invokeFn('webview.injectScriptAtStart', [script]);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Cache and data
|
|
322
|
+
async clearCache(): Promise<void> {
|
|
323
|
+
await this.invokeFn('webview.clearCache');
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
async clearCookies(): Promise<void> {
|
|
327
|
+
await this.invokeFn('webview.clearCookies');
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
async clearStorage(): Promise<void> {
|
|
331
|
+
await this.invokeFn('webview.clearStorage');
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async setCookie(name: string, value: string, domain: string = ''): Promise<void> {
|
|
335
|
+
await this.invokeFn('webview.setCookie', [name, value, domain]);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
async getCookie(name: string): Promise<string> {
|
|
339
|
+
return (await this.invokeFn('webview.getCookie', [name])) as string;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Content control
|
|
343
|
+
async setHTML(html: string): Promise<void> {
|
|
344
|
+
await this.invokeFn('webview.setHTML', [html]);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
async getHTML(): Promise<string> {
|
|
348
|
+
return (await this.invokeFn('webview.getHTML')) as string;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
async setTitle(title: string): Promise<void> {
|
|
352
|
+
await this.invokeFn('webview.setTitle', [title]);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
async getTitle(): Promise<string> {
|
|
356
|
+
return (await this.invokeFn('webview.getTitle')) as string;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Print
|
|
360
|
+
async print(): Promise<void> {
|
|
361
|
+
await this.invokeFn('webview.print');
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
async printToPDF(path: string): Promise<void> {
|
|
365
|
+
await this.invokeFn('webview.printToPDF', [path]);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Find in page
|
|
369
|
+
async find(text: string, forward: boolean = true, caseSensitive: boolean = false): Promise<void> {
|
|
370
|
+
await this.invokeFn('webview.find', [text, forward, caseSensitive]);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
async stopFind(clearSelection: boolean = true): Promise<void> {
|
|
374
|
+
await this.invokeFn('webview.stopFind', [clearSelection]);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Security
|
|
378
|
+
async setAllowFileAccess(allow: boolean): Promise<void> {
|
|
379
|
+
await this.invokeFn('webview.setAllowFileAccess', [allow]);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
async setAllowRemoteContent(allow: boolean): Promise<void> {
|
|
383
|
+
await this.invokeFn('webview.setAllowRemoteContent', [allow]);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
async setWebSecurity(enabled: boolean): Promise<void> {
|
|
387
|
+
await this.invokeFn('webview.setWebSecurity', [enabled]);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Download handling
|
|
391
|
+
async setDownloadPath(path: string): Promise<void> {
|
|
392
|
+
await this.invokeFn('webview.setDownloadPath', [path]);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
async getDownloadPath(): Promise<string> {
|
|
396
|
+
return (await this.invokeFn('webview.getDownloadPath')) as string;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Lifecycle events
|
|
400
|
+
onNavigationStart(callback: (url: string) => boolean): () => void {
|
|
401
|
+
return this.onFn('webview:navigationStart', (data: any) => {
|
|
402
|
+
const shouldContinue = callback(data.url);
|
|
403
|
+
this.invokeFn('webview.navigationResponse', [shouldContinue]);
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
onNavigationComplete(callback: () => void): () => void {
|
|
408
|
+
return this.onFn('webview:navigationComplete', callback);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
onLoadStart(callback: () => void): () => void {
|
|
412
|
+
return this.onFn('webview:loadStart', callback);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
onLoadEnd(callback: () => void): () => void {
|
|
416
|
+
return this.onFn('webview:loadEnd', callback);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
onLoadError(callback: (error: string, code: number) => void): () => void {
|
|
420
|
+
return this.onFn('webview:loadError', (data: any) => {
|
|
421
|
+
callback(data.error, data.code);
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
onTitleChange(callback: (title: string) => void): () => void {
|
|
426
|
+
return this.onFn('webview:titleChange', (data) => {
|
|
427
|
+
callback(data as string);
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
onURLChange(callback: (url: string) => void): () => void {
|
|
432
|
+
return this.onFn('webview:urlChange', (data) => {
|
|
433
|
+
callback(data as string);
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
onFullscreenChange(callback: (isFullscreen: boolean) => void): () => void {
|
|
438
|
+
return this.onFn('webview:fullscreenChange', (data) => {
|
|
439
|
+
callback(data as boolean);
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// JavaScript events
|
|
444
|
+
onConsoleMessage(callback: (message: string, level: number, source: string) => void): () => void {
|
|
445
|
+
return this.onFn('webview:console', (data: any) => {
|
|
446
|
+
callback(data.message, data.level, data.source);
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
onScriptError(callback: (error: string, code: number) => void): () => void {
|
|
451
|
+
return this.onFn('webview:scriptError', (data: any) => {
|
|
452
|
+
callback(data.error, data.code);
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Download events
|
|
457
|
+
onDownloadStart(callback: (url: string, filename: string) => void): () => void {
|
|
458
|
+
return this.onFn('webview:downloadStart', (data: any) => {
|
|
459
|
+
callback(data.url, data.filename);
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
onDownloadProgress(callback: (url: string, current: number, total: number) => void): () => void {
|
|
464
|
+
return this.onFn('webview:downloadProgress', (data: any) => {
|
|
465
|
+
callback(data.url, data.current, data.total);
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
onDownloadComplete(callback: (path: string) => void): () => void {
|
|
470
|
+
return this.onFn('webview:downloadComplete', (data) => {
|
|
471
|
+
callback(data as string);
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// Permission events
|
|
476
|
+
onPermissionRequest(callback: (origin: string, permission: string) => boolean): () => void {
|
|
477
|
+
return this.onFn('webview:permissionRequest', (data: any) => {
|
|
478
|
+
const allowed = callback(data.origin, data.permission);
|
|
479
|
+
this.invokeFn('webview.permissionResponse', [allowed]);
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// State queries
|
|
484
|
+
async isLoading(): Promise<boolean> {
|
|
485
|
+
return (await this.invokeFn('webview.isLoading')) as boolean;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
async getURL(): Promise<string> {
|
|
489
|
+
return (await this.invokeFn('webview.getURL')) as string;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
async getLoadProgress(): Promise<number> {
|
|
493
|
+
return (await this.invokeFn('webview.getLoadProgress')) as number;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
async canExecuteScripts(): Promise<boolean> {
|
|
497
|
+
return (await this.invokeFn('webview.canExecuteScripts')) as boolean;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Factory function to create WebView instance
|
|
503
|
+
*/
|
|
504
|
+
export function createWebView(
|
|
505
|
+
invokeFn: (name: string, args?: unknown[]) => Promise<unknown>,
|
|
506
|
+
onFn: (event: string, callback: (data: unknown) => void) => () => void,
|
|
507
|
+
windowId?: WindowId
|
|
508
|
+
): WebView {
|
|
509
|
+
return new WebView(invokeFn, onFn, windowId);
|
|
510
|
+
}
|