@lynker-desktop/electron-window-manager 0.0.9-alpha.3 → 0.0.9-alpha.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/esm/main/index.d.ts +29 -3
- package/esm/main/index.d.ts.map +1 -1
- package/esm/main/index.js +123 -27
- package/esm/main/index.js.map +1 -1
- package/main/index.d.ts +29 -3
- package/main/index.d.ts.map +1 -1
- package/main/index.js +123 -27
- package/main/index.js.map +1 -1
- package/package.json +2 -2
package/main/index.js
CHANGED
|
@@ -70,12 +70,19 @@ class WindowsManager {
|
|
|
70
70
|
* - 'localhost'、'127.0.0.1'、'::1' 以及局域网 IP(如 192.168.x.x、10.x.x.x、172.16.x.x~172.31.x.x)都视为本地白名单。
|
|
71
71
|
*/
|
|
72
72
|
constructor(preload, loadingViewUrl, errorViewUrl, preloadWebContentsUrl, webviewDomainWhiteList) {
|
|
73
|
+
// 预加载的窗口
|
|
73
74
|
this.preloadedBW = null;
|
|
75
|
+
// 预加载的窗口(无边框,有按钮)
|
|
74
76
|
this.preloadedBW_FramelessWithButtons = null;
|
|
77
|
+
// 预加载的窗口(无边框,无按钮)
|
|
75
78
|
this.preloadedBW_FramelessNoButtons = null;
|
|
79
|
+
// 预加载的浏览器视图
|
|
76
80
|
this.preloadedBV = null;
|
|
77
81
|
this.preloading = false;
|
|
78
82
|
this.webviewDomainWhiteList = [];
|
|
83
|
+
// 创建队列相关属性
|
|
84
|
+
this.createQueue = [];
|
|
85
|
+
this.isCreating = false;
|
|
79
86
|
this.preload = preload;
|
|
80
87
|
this.windows = new Map();
|
|
81
88
|
this.loadingViewUrl = `${loadingViewUrl ?? ''}`;
|
|
@@ -85,10 +92,16 @@ class WindowsManager {
|
|
|
85
92
|
log('log', 'preloadWebContentsUrl: ', this.preloadWebContentsUrl);
|
|
86
93
|
if (this.preloadWebContentsUrl) {
|
|
87
94
|
electron.app.on('ready', () => {
|
|
88
|
-
this.
|
|
95
|
+
if (this.preloadWebContentsUrl) {
|
|
96
|
+
this.setPreloadWebContentsUrl(this.preloadWebContentsUrl);
|
|
97
|
+
}
|
|
89
98
|
});
|
|
90
99
|
}
|
|
91
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* 设置预加载的webContents的url
|
|
103
|
+
* @param preloadWebContentsUrl 预加载的webContents的url
|
|
104
|
+
*/
|
|
92
105
|
setPreloadWebContentsUrl(preloadWebContentsUrl) {
|
|
93
106
|
try {
|
|
94
107
|
this.preloadWebContentsUrl = preloadWebContentsUrl;
|
|
@@ -106,23 +119,30 @@ class WindowsManager {
|
|
|
106
119
|
log('error', 'setPreloadWebContentsUrl error:', error);
|
|
107
120
|
}
|
|
108
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* 预加载实例
|
|
124
|
+
*/
|
|
109
125
|
async _preloadInstances() {
|
|
110
126
|
if (this.preloading)
|
|
111
127
|
return;
|
|
112
128
|
this.preloading = true;
|
|
113
129
|
try {
|
|
114
130
|
if (this.preloadWebContentsUrl) {
|
|
131
|
+
// 预加载的窗口
|
|
115
132
|
this.preloadedBW = this.preloadedBW || await this._createPreloadBW({});
|
|
133
|
+
// 预加载的窗口(无边框,有按钮)
|
|
116
134
|
this.preloadedBW_FramelessWithButtons = this.preloadedBW_FramelessWithButtons || await this._createPreloadBW({
|
|
117
135
|
frame: false,
|
|
118
136
|
transparent: true,
|
|
119
137
|
titleBarStyle: 'hidden',
|
|
120
138
|
});
|
|
139
|
+
// 预加载的窗口(无边框,无按钮)
|
|
121
140
|
this.preloadedBW_FramelessNoButtons = this.preloadedBW_FramelessNoButtons || await this._createPreloadBW({
|
|
122
141
|
frame: false,
|
|
123
142
|
transparent: true,
|
|
124
143
|
titleBarStyle: 'customButtonsOnHover',
|
|
125
144
|
});
|
|
145
|
+
// 预加载的BV
|
|
126
146
|
this.preloadedBV = this.preloadedBV || await this._createPreloadBV();
|
|
127
147
|
}
|
|
128
148
|
}
|
|
@@ -131,15 +151,21 @@ class WindowsManager {
|
|
|
131
151
|
}
|
|
132
152
|
this.preloading = false;
|
|
133
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* 创建预加载的窗口
|
|
156
|
+
* @param options 窗口选项
|
|
157
|
+
* @returns 预加载的窗口
|
|
158
|
+
*/
|
|
134
159
|
_createPreloadBW(options = {}) {
|
|
135
160
|
return new Promise((resolve) => {
|
|
136
161
|
const preload = this.preload;
|
|
137
162
|
const url = this.preloadWebContentsUrl;
|
|
138
163
|
if (this.preloadWebContentsUrl) {
|
|
139
164
|
const instance = new electron.BrowserWindow({
|
|
140
|
-
show: false,
|
|
141
165
|
...options,
|
|
166
|
+
show: false,
|
|
142
167
|
webPreferences: {
|
|
168
|
+
...(options.webPreferences || {}),
|
|
143
169
|
webviewTag: true,
|
|
144
170
|
plugins: true,
|
|
145
171
|
nodeIntegration: true,
|
|
@@ -147,7 +173,6 @@ class WindowsManager {
|
|
|
147
173
|
backgroundThrottling: false,
|
|
148
174
|
webSecurity: false,
|
|
149
175
|
preload: preload,
|
|
150
|
-
...(options.webPreferences || {}),
|
|
151
176
|
}
|
|
152
177
|
});
|
|
153
178
|
try {
|
|
@@ -171,10 +196,14 @@ class WindowsManager {
|
|
|
171
196
|
instance.webContents.once('did-fail-load', () => {
|
|
172
197
|
resolve(instance);
|
|
173
198
|
});
|
|
174
|
-
instance.loadURL(url
|
|
199
|
+
instance.loadURL(url ? `${url}` : 'about:blank');
|
|
175
200
|
}
|
|
176
201
|
});
|
|
177
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* 创建预加载的浏览器视图
|
|
205
|
+
* @returns 预加载的浏览器视图
|
|
206
|
+
*/
|
|
178
207
|
_createPreloadBV() {
|
|
179
208
|
return new Promise((resolve) => {
|
|
180
209
|
const preload = this.preload;
|
|
@@ -217,6 +246,40 @@ class WindowsManager {
|
|
|
217
246
|
});
|
|
218
247
|
}
|
|
219
248
|
create(options) {
|
|
249
|
+
return new Promise((resolve, reject) => {
|
|
250
|
+
// 将创建请求添加到队列
|
|
251
|
+
this.createQueue.push({ options, resolve, reject });
|
|
252
|
+
// 如果当前没有在创建,则开始处理队列
|
|
253
|
+
if (!this.isCreating) {
|
|
254
|
+
this.processCreateQueue();
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* 处理创建队列
|
|
260
|
+
*/
|
|
261
|
+
async processCreateQueue() {
|
|
262
|
+
if (this.isCreating || this.createQueue.length === 0) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
this.isCreating = true;
|
|
266
|
+
while (this.createQueue.length > 0) {
|
|
267
|
+
const { options, resolve, reject } = this.createQueue.shift();
|
|
268
|
+
try {
|
|
269
|
+
const window = await this._createWindow(options);
|
|
270
|
+
resolve(window);
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
log('error', 'create window failed:', error);
|
|
274
|
+
reject(error);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
this.isCreating = false;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* 实际的窗口创建逻辑
|
|
281
|
+
*/
|
|
282
|
+
async _createWindow(options) {
|
|
220
283
|
let window;
|
|
221
284
|
const { usePreload = true, type = 'BW', name = 'anonymous', url, loadingView = { url: undefined }, errorView = { url: undefined }, browserWindow: browserWindowOptions, openDevTools = false, preventOriginClose = false, } = options;
|
|
222
285
|
options.type = type;
|
|
@@ -224,37 +287,46 @@ class WindowsManager {
|
|
|
224
287
|
let preloadWin = null;
|
|
225
288
|
if (type === 'BW' && usePreload && this.preloadWebContentsUrl) {
|
|
226
289
|
const bwOptions = browserWindowOptions || {};
|
|
290
|
+
console.log(11111, bwOptions);
|
|
227
291
|
if (bwOptions.frame === false && bwOptions.titleBarStyle === 'hidden') {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
292
|
+
if (this.preloadedBW_FramelessWithButtons) {
|
|
293
|
+
preloadWin = this.preloadedBW_FramelessWithButtons;
|
|
294
|
+
this.preloadedBW_FramelessWithButtons = null;
|
|
295
|
+
setTimeout(async () => this.preloadedBW_FramelessWithButtons = await this._createPreloadBW({ frame: false, transparent: true, titleBarStyle: 'hidden' }), 0);
|
|
296
|
+
}
|
|
231
297
|
}
|
|
232
298
|
else if (bwOptions.frame === false && bwOptions.titleBarStyle === 'customButtonsOnHover') {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
299
|
+
if (this.preloadedBW_FramelessNoButtons) {
|
|
300
|
+
preloadWin = this.preloadedBW_FramelessNoButtons;
|
|
301
|
+
this.preloadedBW_FramelessNoButtons = null;
|
|
302
|
+
setTimeout(async () => this.preloadedBW_FramelessNoButtons = await this._createPreloadBW({ frame: false, transparent: true, titleBarStyle: 'customButtonsOnHover' }), 0);
|
|
303
|
+
}
|
|
236
304
|
}
|
|
237
305
|
else {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
306
|
+
if (this.preloadedBW) {
|
|
307
|
+
preloadWin = this.preloadedBW;
|
|
308
|
+
this.preloadedBW = null;
|
|
309
|
+
setTimeout(async () => this.preloadedBW = await this._createPreloadBW({}), 0);
|
|
310
|
+
}
|
|
241
311
|
}
|
|
242
312
|
}
|
|
243
313
|
if (type === 'BV' && usePreload && this.preloadWebContentsUrl) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
314
|
+
if (this.preloadedBV) {
|
|
315
|
+
preloadWin = this.preloadedBV;
|
|
316
|
+
this.preloadedBV = null;
|
|
317
|
+
setTimeout(async () => this.preloadedBV = await this._createPreloadBV(), 0);
|
|
318
|
+
}
|
|
247
319
|
}
|
|
248
320
|
if (preloadWin) {
|
|
249
321
|
const win = preloadWin;
|
|
250
|
-
log('log', `${name}
|
|
322
|
+
log('log', `${name} 使用预加载窗口(${type})`, win._id);
|
|
251
323
|
win._type = 'BW';
|
|
252
324
|
win._name = options.name || 'anonymous';
|
|
253
325
|
win._extraData = `${options?.extraData || ''}`;
|
|
254
326
|
win._initUrl = `${options?.url || ''}`;
|
|
255
327
|
// @ts-ignore
|
|
256
|
-
win?.removeAllListeners && win?.removeAllListeners?.();
|
|
257
|
-
win.webContents.removeAllListeners && win.webContents.removeAllListeners();
|
|
328
|
+
// win?.removeAllListeners && win?.removeAllListeners?.();
|
|
329
|
+
// win.webContents.removeAllListeners && win.webContents.removeAllListeners();
|
|
258
330
|
if (type === 'BW') {
|
|
259
331
|
// @ts-ignore
|
|
260
332
|
this._applyBrowserWindowOptions(win, options);
|
|
@@ -364,7 +436,7 @@ class WindowsManager {
|
|
|
364
436
|
if (errorView?.url) {
|
|
365
437
|
if (type === 'BW') {
|
|
366
438
|
const showErrorView = lodash.debounce(() => {
|
|
367
|
-
const _url = window
|
|
439
|
+
const _url = window._initUrl;
|
|
368
440
|
/**
|
|
369
441
|
* 判断是否是错误视图
|
|
370
442
|
*/
|
|
@@ -378,16 +450,37 @@ class WindowsManager {
|
|
|
378
450
|
sessionStorage.setItem(key, "${_url}");
|
|
379
451
|
`);
|
|
380
452
|
}
|
|
381
|
-
},
|
|
453
|
+
}, 1000);
|
|
382
454
|
// @ts-ignore
|
|
383
455
|
window.webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedURL, isMainFrame) => {
|
|
384
456
|
if (isMainFrame) {
|
|
385
457
|
showErrorView();
|
|
386
458
|
}
|
|
387
459
|
});
|
|
460
|
+
// 当开始加载时取消错误视图
|
|
388
461
|
window.webContents.on('did-start-loading', () => {
|
|
389
462
|
showErrorView.cancel();
|
|
390
463
|
});
|
|
464
|
+
// 当导航开始时取消错误视图
|
|
465
|
+
window.webContents.on('did-start-navigation', () => {
|
|
466
|
+
showErrorView.cancel();
|
|
467
|
+
});
|
|
468
|
+
// 当页面重新加载时取消错误视图
|
|
469
|
+
window.webContents.on('did-navigate', () => {
|
|
470
|
+
showErrorView.cancel();
|
|
471
|
+
});
|
|
472
|
+
// 当页面完成加载时取消错误视图
|
|
473
|
+
window.webContents.on('did-finish-load', () => {
|
|
474
|
+
showErrorView.cancel();
|
|
475
|
+
});
|
|
476
|
+
// 当窗口关闭时取消错误视图
|
|
477
|
+
window.webContents.on('close', () => {
|
|
478
|
+
showErrorView.cancel();
|
|
479
|
+
});
|
|
480
|
+
// 当窗口销毁时取消错误视图
|
|
481
|
+
window.webContents.on('destroyed', () => {
|
|
482
|
+
showErrorView.cancel();
|
|
483
|
+
});
|
|
391
484
|
}
|
|
392
485
|
}
|
|
393
486
|
window.webContents.on('did-attach-webview', (_event, webContents) => {
|
|
@@ -469,10 +562,6 @@ class WindowsManager {
|
|
|
469
562
|
parentWin?.addBrowserView(window);
|
|
470
563
|
log('log', 'create - addBrowserView');
|
|
471
564
|
}
|
|
472
|
-
// @ts-ignore
|
|
473
|
-
window.loadURL ? window.loadURL(options.url) : window.webContents.loadURL(options.url);
|
|
474
|
-
// @ts-ignore
|
|
475
|
-
window.focus ? window.focus() : window.webContents.focus();
|
|
476
565
|
this.windows.set(window.id || window._id || window.webContents.id, window);
|
|
477
566
|
log('log', 'create', this.windows.keys());
|
|
478
567
|
// 初始化值
|
|
@@ -565,6 +654,13 @@ class WindowsManager {
|
|
|
565
654
|
log('error', 'focus', error);
|
|
566
655
|
}
|
|
567
656
|
}
|
|
657
|
+
console.log('message xxxx', options.url);
|
|
658
|
+
if (options.url) {
|
|
659
|
+
// @ts-ignore
|
|
660
|
+
window.loadURL ? window.loadURL(options.url) : window.webContents.loadURL(options.url);
|
|
661
|
+
// @ts-ignore
|
|
662
|
+
window.focus ? window.focus() : window.webContents.focus();
|
|
663
|
+
}
|
|
568
664
|
}
|
|
569
665
|
catch (error) {
|
|
570
666
|
log('error', 'create', error);
|
|
@@ -848,7 +944,7 @@ class WindowsManager {
|
|
|
848
944
|
// 生成一个bv 做为预加载资源窗口,加载完成后销毁
|
|
849
945
|
async createPreloadWebContents(url) {
|
|
850
946
|
return new Promise(async (resolve, reject) => {
|
|
851
|
-
let bv = this.create({
|
|
947
|
+
let bv = await this.create({
|
|
852
948
|
type: 'BV',
|
|
853
949
|
url,
|
|
854
950
|
name: `preload-web-contents-${md5(url)}`,
|
|
@@ -903,7 +999,7 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsUrl
|
|
|
903
999
|
winInitUrl: `${findWin?._initUrl || ''}`,
|
|
904
1000
|
};
|
|
905
1001
|
}
|
|
906
|
-
const res = wm.create(opt.data);
|
|
1002
|
+
const res = await wm.create(opt.data);
|
|
907
1003
|
return {
|
|
908
1004
|
winId: Number(`${res.id || res._id || -1}`),
|
|
909
1005
|
winName: `${res?._name || ''}`,
|