@lynker-desktop/electron-window-manager 0.0.9-alpha.2 → 0.0.9-alpha.20
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/common/index.d.ts +17 -0
- package/common/index.d.ts.map +1 -1
- package/esm/common/index.d.ts +17 -0
- package/esm/common/index.d.ts.map +1 -1
- package/esm/main/index.d.ts +34 -8
- package/esm/main/index.d.ts.map +1 -1
- package/esm/main/index.js +402 -96
- package/esm/main/index.js.map +1 -1
- package/esm/renderer/index.d.ts +4 -4
- package/esm/renderer/index.d.ts.map +1 -1
- package/esm/renderer/index.js +6 -6
- package/esm/renderer/index.js.map +1 -1
- package/main/index.d.ts +34 -8
- package/main/index.d.ts.map +1 -1
- package/main/index.js +402 -96
- package/main/index.js.map +1 -1
- package/package.json +2 -2
- package/renderer/index.d.ts +4 -4
- package/renderer/index.d.ts.map +1 -1
- package/renderer/index.js +6 -6
- package/renderer/index.js.map +1 -1
package/esm/main/index.js
CHANGED
|
@@ -56,30 +56,43 @@ class WindowsManager {
|
|
|
56
56
|
* - 不带点的(如 example.com)只匹配主域名。
|
|
57
57
|
* - 'localhost'、'127.0.0.1'、'::1' 以及局域网 IP(如 192.168.x.x、10.x.x.x、172.16.x.x~172.31.x.x)都视为本地白名单。
|
|
58
58
|
*/
|
|
59
|
-
constructor(preload, loadingViewUrl, errorViewUrl,
|
|
59
|
+
constructor(preload, loadingViewUrl, errorViewUrl, preloadWebContentsConfig, webviewDomainWhiteList) {
|
|
60
|
+
// 预加载的窗口
|
|
60
61
|
this.preloadedBW = null;
|
|
62
|
+
// 预加载的窗口(无边框,有按钮)
|
|
61
63
|
this.preloadedBW_FramelessWithButtons = null;
|
|
64
|
+
// 预加载的窗口(无边框,无按钮)
|
|
62
65
|
this.preloadedBW_FramelessNoButtons = null;
|
|
66
|
+
// 预加载的浏览器视图
|
|
63
67
|
this.preloadedBV = null;
|
|
64
68
|
this.preloading = false;
|
|
65
69
|
this.webviewDomainWhiteList = [];
|
|
70
|
+
// 创建队列相关属性
|
|
71
|
+
this.createQueue = [];
|
|
72
|
+
this.isCreating = false;
|
|
66
73
|
this.preload = preload;
|
|
67
74
|
this.windows = new Map();
|
|
68
75
|
this.loadingViewUrl = `${loadingViewUrl ?? ''}`;
|
|
69
76
|
this.errorViewUrl = `${errorViewUrl ?? ''}`;
|
|
70
|
-
this.
|
|
77
|
+
this.preloadWebContentsConfig = preloadWebContentsConfig;
|
|
71
78
|
this.webviewDomainWhiteList = webviewDomainWhiteList || [];
|
|
72
|
-
log('log', '
|
|
73
|
-
if (this.
|
|
74
|
-
app.
|
|
75
|
-
this.
|
|
79
|
+
log('log', 'preloadWebContentsConfig: ', this.preloadWebContentsConfig);
|
|
80
|
+
if (this.preloadWebContentsConfig) {
|
|
81
|
+
app.whenReady().then(() => {
|
|
82
|
+
if (this.preloadWebContentsConfig) {
|
|
83
|
+
this.setPreloadWebContentsConfig(this.preloadWebContentsConfig);
|
|
84
|
+
}
|
|
76
85
|
});
|
|
77
86
|
}
|
|
78
87
|
}
|
|
79
|
-
|
|
88
|
+
/**
|
|
89
|
+
* 设置预加载的webContents配置
|
|
90
|
+
* @param preloadWebContentsConfig 预加载的webContents配置
|
|
91
|
+
*/
|
|
92
|
+
setPreloadWebContentsConfig(preloadWebContentsConfig) {
|
|
80
93
|
try {
|
|
81
|
-
this.
|
|
82
|
-
if (this.
|
|
94
|
+
this.preloadWebContentsConfig = preloadWebContentsConfig;
|
|
95
|
+
if (this.preloadWebContentsConfig) {
|
|
83
96
|
this._preloadInstances();
|
|
84
97
|
}
|
|
85
98
|
else {
|
|
@@ -90,27 +103,65 @@ class WindowsManager {
|
|
|
90
103
|
}
|
|
91
104
|
}
|
|
92
105
|
catch (error) {
|
|
93
|
-
log('error', '
|
|
106
|
+
log('error', 'setPreloadWebContentsConfig error:', error);
|
|
94
107
|
}
|
|
95
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* 预加载实例
|
|
111
|
+
*/
|
|
96
112
|
async _preloadInstances() {
|
|
97
113
|
if (this.preloading)
|
|
98
114
|
return;
|
|
99
115
|
this.preloading = true;
|
|
100
116
|
try {
|
|
101
|
-
if (this.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
117
|
+
if (this.preloadWebContentsConfig) {
|
|
118
|
+
log('log', 'preloadWebContentsConfig: ', this.preloadWebContentsConfig);
|
|
119
|
+
// 根据配置决定是否预加载普通窗口
|
|
120
|
+
if (this.preloadWebContentsConfig.enableBW !== false) {
|
|
121
|
+
if (!this.preloadedBW) {
|
|
122
|
+
this._createPreloadBW({}).then(i => {
|
|
123
|
+
this.preloadedBW = i;
|
|
124
|
+
log('log', 'init preloadedBW: ', !!this.preloadedBW);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// 根据配置决定是否预加载无边框有按钮的窗口
|
|
129
|
+
if (this.preloadWebContentsConfig.enableBW_FramelessWithButtons !== false) {
|
|
130
|
+
if (!this.preloadedBW_FramelessWithButtons) {
|
|
131
|
+
this._createPreloadBW({
|
|
132
|
+
frame: false,
|
|
133
|
+
// transparent: true,
|
|
134
|
+
autoHideMenuBar: true,
|
|
135
|
+
titleBarStyle: 'hidden',
|
|
136
|
+
}).then(i => {
|
|
137
|
+
this.preloadedBW_FramelessWithButtons = i;
|
|
138
|
+
log('log', 'init preloadedBW_FramelessWithButtons: ', !!this.preloadedBW_FramelessWithButtons);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// 根据配置决定是否预加载无边框无按钮的窗口
|
|
143
|
+
if (this.preloadWebContentsConfig.enableBW_FramelessNoButtons !== false) {
|
|
144
|
+
if (!this.preloadedBW_FramelessNoButtons) {
|
|
145
|
+
this._createPreloadBW({
|
|
146
|
+
frame: false,
|
|
147
|
+
// transparent: true,
|
|
148
|
+
autoHideMenuBar: true,
|
|
149
|
+
titleBarStyle: 'default',
|
|
150
|
+
}).then(i => {
|
|
151
|
+
this.preloadedBW_FramelessNoButtons = i;
|
|
152
|
+
log('log', 'init preloadedBW_FramelessNoButtons: ', !!this.preloadedBW_FramelessNoButtons);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// 根据配置决定是否预加载浏览器视图
|
|
157
|
+
if (this.preloadWebContentsConfig.enableBV !== false) {
|
|
158
|
+
if (!this.preloadedBV) {
|
|
159
|
+
this._createPreloadBV().then(i => {
|
|
160
|
+
this.preloadedBV = i;
|
|
161
|
+
log('log', 'init preloadedBV: ', !!this.preloadedBV);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
114
165
|
}
|
|
115
166
|
}
|
|
116
167
|
catch (e) {
|
|
@@ -118,23 +169,30 @@ class WindowsManager {
|
|
|
118
169
|
}
|
|
119
170
|
this.preloading = false;
|
|
120
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* 创建预加载的窗口
|
|
174
|
+
* @param options 窗口选项
|
|
175
|
+
* @returns 预加载的窗口
|
|
176
|
+
*/
|
|
121
177
|
_createPreloadBW(options = {}) {
|
|
122
178
|
return new Promise((resolve) => {
|
|
123
179
|
const preload = this.preload;
|
|
124
|
-
const url = this.
|
|
125
|
-
if (this.
|
|
180
|
+
const url = this.preloadWebContentsConfig?.url;
|
|
181
|
+
if (this.preloadWebContentsConfig?.url) {
|
|
182
|
+
const webPreferences = (options.webPreferences || {});
|
|
126
183
|
const instance = new BrowserWindow({
|
|
127
184
|
show: false,
|
|
185
|
+
backgroundColor: '#ffffff',
|
|
128
186
|
...options,
|
|
129
187
|
webPreferences: {
|
|
188
|
+
...webPreferences,
|
|
130
189
|
webviewTag: true,
|
|
131
190
|
plugins: true,
|
|
132
191
|
nodeIntegration: true,
|
|
133
192
|
contextIsolation: false,
|
|
134
193
|
backgroundThrottling: false,
|
|
135
194
|
webSecurity: false,
|
|
136
|
-
preload: preload,
|
|
137
|
-
...(options.webPreferences || {}),
|
|
195
|
+
preload: webPreferences.preload || preload,
|
|
138
196
|
}
|
|
139
197
|
});
|
|
140
198
|
try {
|
|
@@ -151,31 +209,41 @@ class WindowsManager {
|
|
|
151
209
|
log('error', '预加载 BW 设置 _id 失败', error);
|
|
152
210
|
}
|
|
153
211
|
// @ts-ignore
|
|
154
|
-
log('log', '创建预BW: ', instance._id, this.
|
|
155
|
-
instance.webContents.once('did-finish-load', () => {
|
|
156
|
-
|
|
157
|
-
});
|
|
158
|
-
instance.webContents.once('did-fail-load', () => {
|
|
159
|
-
|
|
160
|
-
});
|
|
161
|
-
instance.loadURL(url
|
|
212
|
+
log('log', '创建预BW: ', instance._id, this.preloadWebContentsConfig?.url);
|
|
213
|
+
// instance.webContents.once('did-finish-load', () => {
|
|
214
|
+
// resolve(instance as BWItem);
|
|
215
|
+
// });
|
|
216
|
+
// instance.webContents.once('did-fail-load', () => {
|
|
217
|
+
// resolve(instance as BWItem);
|
|
218
|
+
// });
|
|
219
|
+
instance.loadURL(url ? `${url}` : 'about:blank');
|
|
220
|
+
resolve(instance);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
resolve(null);
|
|
162
224
|
}
|
|
163
225
|
});
|
|
164
226
|
}
|
|
165
|
-
|
|
227
|
+
/**
|
|
228
|
+
* 创建预加载的浏览器视图
|
|
229
|
+
* @returns 预加载的浏览器视图
|
|
230
|
+
*/
|
|
231
|
+
_createPreloadBV(options = {}) {
|
|
166
232
|
return new Promise((resolve) => {
|
|
167
233
|
const preload = this.preload;
|
|
168
|
-
const url = this.
|
|
169
|
-
if (this.
|
|
234
|
+
const url = this.preloadWebContentsConfig?.url;
|
|
235
|
+
if (this.preloadWebContentsConfig?.url) {
|
|
236
|
+
const webPreferences = (options.webPreferences || {});
|
|
170
237
|
const instance = new BrowserView({
|
|
171
238
|
webPreferences: {
|
|
239
|
+
...webPreferences,
|
|
172
240
|
webviewTag: true,
|
|
173
241
|
plugins: true,
|
|
174
242
|
nodeIntegration: true,
|
|
175
243
|
contextIsolation: false,
|
|
176
244
|
// backgroundThrottling: false,
|
|
177
245
|
webSecurity: false,
|
|
178
|
-
preload: preload,
|
|
246
|
+
preload: webPreferences.preload || preload,
|
|
179
247
|
}
|
|
180
248
|
});
|
|
181
249
|
try {
|
|
@@ -192,56 +260,123 @@ class WindowsManager {
|
|
|
192
260
|
log('error', '预加载 BV 设置 _id 失败', error);
|
|
193
261
|
}
|
|
194
262
|
// @ts-ignore
|
|
195
|
-
log('log', '创建预BV: ', instance._id, this.
|
|
196
|
-
instance.webContents.once('did-finish-load', () => {
|
|
197
|
-
|
|
198
|
-
});
|
|
199
|
-
instance.webContents.once('did-fail-load', () => {
|
|
200
|
-
|
|
201
|
-
});
|
|
263
|
+
log('log', '创建预BV: ', instance._id, this.preloadWebContentsConfig?.url);
|
|
264
|
+
// instance.webContents.once('did-finish-load', () => {
|
|
265
|
+
// resolve(instance as BVItem);
|
|
266
|
+
// });
|
|
267
|
+
// instance.webContents.once('did-fail-load', () => {
|
|
268
|
+
// resolve(instance as BVItem);
|
|
269
|
+
// });
|
|
202
270
|
instance.webContents.loadURL(url || 'about:blank');
|
|
271
|
+
resolve(instance);
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
resolve(null);
|
|
203
275
|
}
|
|
204
276
|
});
|
|
205
277
|
}
|
|
206
278
|
create(options) {
|
|
279
|
+
return new Promise((resolve, reject) => {
|
|
280
|
+
// 将创建请求添加到队列
|
|
281
|
+
this.createQueue.push({ options, resolve, reject });
|
|
282
|
+
// 如果当前没有在创建,则开始处理队列
|
|
283
|
+
if (!this.isCreating) {
|
|
284
|
+
this.processCreateQueue();
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* 处理创建队列
|
|
290
|
+
*/
|
|
291
|
+
async processCreateQueue() {
|
|
292
|
+
if (this.isCreating || this.createQueue.length === 0) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
this.isCreating = true;
|
|
296
|
+
while (this.createQueue.length > 0) {
|
|
297
|
+
const { options, resolve, reject } = this.createQueue.shift();
|
|
298
|
+
try {
|
|
299
|
+
const window = await this._createWindow(options);
|
|
300
|
+
resolve(window);
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
log('error', 'create window failed:', error);
|
|
304
|
+
reject(error);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
this.isCreating = false;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* 实际的窗口创建逻辑
|
|
311
|
+
*/
|
|
312
|
+
async _createWindow(options) {
|
|
207
313
|
let window;
|
|
208
314
|
const { usePreload = true, type = 'BW', name = 'anonymous', url, loadingView = { url: undefined }, errorView = { url: undefined }, browserWindow: browserWindowOptions, openDevTools = false, preventOriginClose = false, } = options;
|
|
209
315
|
options.type = type;
|
|
210
316
|
// 优先复用预创建实例
|
|
211
317
|
let preloadWin = null;
|
|
212
|
-
if (type === 'BW' && usePreload && this.
|
|
318
|
+
if (type === 'BW' && usePreload && this.preloadWebContentsConfig?.url) {
|
|
213
319
|
const bwOptions = browserWindowOptions || {};
|
|
214
|
-
if (bwOptions.frame === false
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
320
|
+
if (bwOptions.frame === false) {
|
|
321
|
+
if (bwOptions.titleBarStyle === 'default' || !bwOptions.titleBarStyle) {
|
|
322
|
+
if (this.preloadWebContentsConfig.enableBW_FramelessNoButtons !== false && this.preloadedBW_FramelessNoButtons) {
|
|
323
|
+
preloadWin = this.preloadedBW_FramelessNoButtons;
|
|
324
|
+
this.preloadedBW_FramelessNoButtons = await this._createPreloadBW({
|
|
325
|
+
frame: false,
|
|
326
|
+
// transparent: true,
|
|
327
|
+
titleBarStyle: 'default',
|
|
328
|
+
webPreferences: {
|
|
329
|
+
preload: bwOptions?.webPreferences?.preload || this.preload,
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
if (this.preloadWebContentsConfig.enableBW_FramelessWithButtons !== false && this.preloadedBW_FramelessWithButtons) {
|
|
336
|
+
preloadWin = this.preloadedBW_FramelessWithButtons;
|
|
337
|
+
this.preloadedBW_FramelessWithButtons = await this._createPreloadBW({
|
|
338
|
+
frame: false,
|
|
339
|
+
// transparent: true,
|
|
340
|
+
titleBarStyle: 'hidden',
|
|
341
|
+
webPreferences: {
|
|
342
|
+
preload: this.preload,
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
223
347
|
}
|
|
224
348
|
else {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
349
|
+
if (this.preloadWebContentsConfig.enableBW !== false && this.preloadedBW) {
|
|
350
|
+
preloadWin = this.preloadedBW;
|
|
351
|
+
this.preloadedBW = await this._createPreloadBW({
|
|
352
|
+
webPreferences: {
|
|
353
|
+
preload: bwOptions?.webPreferences?.preload || this.preload,
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
}
|
|
228
357
|
}
|
|
229
358
|
}
|
|
230
|
-
if (type === 'BV' && usePreload && this.
|
|
231
|
-
|
|
232
|
-
this.preloadedBV
|
|
233
|
-
|
|
359
|
+
if (type === 'BV' && usePreload && this.preloadWebContentsConfig?.url) {
|
|
360
|
+
const bvOptions = browserWindowOptions || {};
|
|
361
|
+
if (this.preloadWebContentsConfig.enableBV !== false && this.preloadedBV) {
|
|
362
|
+
preloadWin = this.preloadedBV;
|
|
363
|
+
this.preloadedBV = await this._createPreloadBV({
|
|
364
|
+
webPreferences: {
|
|
365
|
+
preload: bvOptions?.webPreferences?.preload || this.preload,
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
}
|
|
234
369
|
}
|
|
235
370
|
if (preloadWin) {
|
|
236
371
|
const win = preloadWin;
|
|
237
|
-
log('log', `${name}
|
|
372
|
+
log('log', `${name} 使用预加载窗口(${type})`, win._id);
|
|
238
373
|
win._type = 'BW';
|
|
239
374
|
win._name = options.name || 'anonymous';
|
|
240
375
|
win._extraData = `${options?.extraData || ''}`;
|
|
241
376
|
win._initUrl = `${options?.url || ''}`;
|
|
242
377
|
// @ts-ignore
|
|
243
|
-
win?.removeAllListeners && win?.removeAllListeners?.();
|
|
244
|
-
win.webContents.removeAllListeners && win.webContents.removeAllListeners();
|
|
378
|
+
// win?.removeAllListeners && win?.removeAllListeners?.();
|
|
379
|
+
// win.webContents.removeAllListeners && win.webContents.removeAllListeners();
|
|
245
380
|
if (type === 'BW') {
|
|
246
381
|
// @ts-ignore
|
|
247
382
|
this._applyBrowserWindowOptions(win, options);
|
|
@@ -249,27 +384,79 @@ class WindowsManager {
|
|
|
249
384
|
if (type === 'BV') {
|
|
250
385
|
this._applyBrowserViewOptions(win, options);
|
|
251
386
|
}
|
|
387
|
+
if (typeof this.preloadWebContentsConfig?.customLoadURL === 'function') {
|
|
388
|
+
try {
|
|
389
|
+
if (type === 'BW') {
|
|
390
|
+
// @ts-ignore
|
|
391
|
+
const originLoadURL = win.loadURL;
|
|
392
|
+
// @ts-ignore
|
|
393
|
+
win.loadURL = async (url) => {
|
|
394
|
+
return new Promise(async (resolve, reject) => {
|
|
395
|
+
try {
|
|
396
|
+
console.error('customLoadURL win.loadURL');
|
|
397
|
+
// @ts-ignore
|
|
398
|
+
await this.preloadWebContentsConfig.customLoadURL(url || 'about:blank', (url) => originLoadURL.call(win, url), win.webContents);
|
|
399
|
+
try {
|
|
400
|
+
win.emit('ready-to-show');
|
|
401
|
+
}
|
|
402
|
+
catch (error) {
|
|
403
|
+
log('error', 'emit ready-to-show event failed:', error);
|
|
404
|
+
}
|
|
405
|
+
resolve(undefined);
|
|
406
|
+
}
|
|
407
|
+
catch (error) {
|
|
408
|
+
reject(error);
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
const originWebContentsLoadURL = win.webContents.loadURL;
|
|
414
|
+
// @ts-ignore
|
|
415
|
+
win.webContents.loadURL = async (url) => {
|
|
416
|
+
return new Promise(async (resolve, reject) => {
|
|
417
|
+
try {
|
|
418
|
+
console.error('customLoadURL win.webContents.loadURL');
|
|
419
|
+
// @ts-ignore
|
|
420
|
+
await this.preloadWebContentsConfig.customLoadURL(url || 'about:blank', (url) => originWebContentsLoadURL.call(win.webContents, url), win.webContents);
|
|
421
|
+
try {
|
|
422
|
+
win.webContents.emit('ready-to-show');
|
|
423
|
+
}
|
|
424
|
+
catch (error) {
|
|
425
|
+
log('error', 'emit ready-to-show event failed:', error);
|
|
426
|
+
}
|
|
427
|
+
resolve(undefined);
|
|
428
|
+
}
|
|
429
|
+
catch (error) {
|
|
430
|
+
reject(error);
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
catch (error) {
|
|
436
|
+
console.error('customLoadURL error', error);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
252
439
|
window = win;
|
|
253
440
|
}
|
|
254
441
|
try {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
442
|
+
loadingView.url = `${loadingView?.url ?? this.loadingViewUrl}`;
|
|
443
|
+
lodash.merge(options, {
|
|
444
|
+
loadingView,
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
catch (error) {
|
|
448
|
+
log('error', 'loadingView error:', loadingView, this.loadingViewUrl);
|
|
449
|
+
}
|
|
450
|
+
try {
|
|
451
|
+
errorView.url = `${errorView?.url ?? this.errorViewUrl}`;
|
|
452
|
+
lodash.merge(options, {
|
|
453
|
+
errorView,
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
catch (error) {
|
|
457
|
+
log('error', 'errorView error:', errorView, this.errorViewUrl);
|
|
458
|
+
}
|
|
459
|
+
try {
|
|
273
460
|
let parentWin = undefined;
|
|
274
461
|
if (typeof browserWindowOptions?.parent === 'number') {
|
|
275
462
|
parentWin = BrowserWindow.fromId(browserWindowOptions?.parent) || undefined;
|
|
@@ -323,6 +510,8 @@ class WindowsManager {
|
|
|
323
510
|
log('error', 'enable: ', error);
|
|
324
511
|
}
|
|
325
512
|
}
|
|
513
|
+
// 停止加载
|
|
514
|
+
// window.webContents?.stop?.();
|
|
326
515
|
// @ts-ignore
|
|
327
516
|
try {
|
|
328
517
|
window.id = Number(`${window.id || window.webContents.id}`);
|
|
@@ -351,7 +540,7 @@ class WindowsManager {
|
|
|
351
540
|
if (errorView?.url) {
|
|
352
541
|
if (type === 'BW') {
|
|
353
542
|
const showErrorView = lodash.debounce(() => {
|
|
354
|
-
const _url = window
|
|
543
|
+
const _url = window._initUrl;
|
|
355
544
|
/**
|
|
356
545
|
* 判断是否是错误视图
|
|
357
546
|
*/
|
|
@@ -365,16 +554,37 @@ class WindowsManager {
|
|
|
365
554
|
sessionStorage.setItem(key, "${_url}");
|
|
366
555
|
`);
|
|
367
556
|
}
|
|
368
|
-
},
|
|
557
|
+
}, 1000);
|
|
369
558
|
// @ts-ignore
|
|
370
559
|
window.webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedURL, isMainFrame) => {
|
|
371
560
|
if (isMainFrame) {
|
|
372
561
|
showErrorView();
|
|
373
562
|
}
|
|
374
563
|
});
|
|
564
|
+
// 当开始加载时取消错误视图
|
|
375
565
|
window.webContents.on('did-start-loading', () => {
|
|
376
566
|
showErrorView.cancel();
|
|
377
567
|
});
|
|
568
|
+
// 当导航开始时取消错误视图
|
|
569
|
+
window.webContents.on('did-start-navigation', () => {
|
|
570
|
+
showErrorView.cancel();
|
|
571
|
+
});
|
|
572
|
+
// 当页面重新加载时取消错误视图
|
|
573
|
+
window.webContents.on('did-navigate', () => {
|
|
574
|
+
showErrorView.cancel();
|
|
575
|
+
});
|
|
576
|
+
// 当页面完成加载时取消错误视图
|
|
577
|
+
window.webContents.on('did-finish-load', () => {
|
|
578
|
+
showErrorView.cancel();
|
|
579
|
+
});
|
|
580
|
+
// 当窗口关闭时取消错误视图
|
|
581
|
+
window.webContents.on('close', () => {
|
|
582
|
+
showErrorView.cancel();
|
|
583
|
+
});
|
|
584
|
+
// 当窗口销毁时取消错误视图
|
|
585
|
+
window.webContents.on('destroyed', () => {
|
|
586
|
+
showErrorView.cancel();
|
|
587
|
+
});
|
|
378
588
|
}
|
|
379
589
|
}
|
|
380
590
|
window.webContents.on('did-attach-webview', (_event, webContents) => {
|
|
@@ -456,10 +666,6 @@ class WindowsManager {
|
|
|
456
666
|
parentWin?.addBrowserView(window);
|
|
457
667
|
log('log', 'create - addBrowserView');
|
|
458
668
|
}
|
|
459
|
-
// @ts-ignore
|
|
460
|
-
window.loadURL ? window.loadURL(options.url) : window.webContents.loadURL(options.url);
|
|
461
|
-
// @ts-ignore
|
|
462
|
-
window.focus ? window.focus() : window.webContents.focus();
|
|
463
669
|
this.windows.set(window.id || window._id || window.webContents.id, window);
|
|
464
670
|
log('log', 'create', this.windows.keys());
|
|
465
671
|
// 初始化值
|
|
@@ -552,6 +758,12 @@ class WindowsManager {
|
|
|
552
758
|
log('error', 'focus', error);
|
|
553
759
|
}
|
|
554
760
|
}
|
|
761
|
+
if (options.url) {
|
|
762
|
+
// @ts-ignore
|
|
763
|
+
window.loadURL ? window.loadURL(options.url) : window.webContents.loadURL(options.url);
|
|
764
|
+
// @ts-ignore
|
|
765
|
+
window.focus ? window.focus() : window.webContents.focus();
|
|
766
|
+
}
|
|
555
767
|
}
|
|
556
768
|
catch (error) {
|
|
557
769
|
log('error', 'create', error);
|
|
@@ -815,6 +1027,86 @@ class WindowsManager {
|
|
|
815
1027
|
if (typeof browserWindowOptions.alwaysOnTop === 'boolean') {
|
|
816
1028
|
win.setAlwaysOnTop(browserWindowOptions.alwaysOnTop);
|
|
817
1029
|
}
|
|
1030
|
+
// 设置背景颜色
|
|
1031
|
+
if (typeof browserWindowOptions.backgroundColor === 'string') {
|
|
1032
|
+
win.setBackgroundColor(browserWindowOptions.backgroundColor);
|
|
1033
|
+
}
|
|
1034
|
+
// 居中
|
|
1035
|
+
if (browserWindowOptions?.center !== false) {
|
|
1036
|
+
win.center();
|
|
1037
|
+
}
|
|
1038
|
+
// 设置窗口移动
|
|
1039
|
+
if (typeof browserWindowOptions.movable === 'boolean') {
|
|
1040
|
+
win.setMovable(browserWindowOptions.movable);
|
|
1041
|
+
}
|
|
1042
|
+
// 设置窗口大小调整
|
|
1043
|
+
if (typeof browserWindowOptions.resizable === 'boolean') {
|
|
1044
|
+
win.setResizable(browserWindowOptions.resizable);
|
|
1045
|
+
}
|
|
1046
|
+
// 设置全屏模式
|
|
1047
|
+
if (typeof browserWindowOptions.fullscreenable === 'boolean') {
|
|
1048
|
+
win.setFullScreenable(browserWindowOptions.fullscreenable);
|
|
1049
|
+
}
|
|
1050
|
+
// 设置窗口阴影
|
|
1051
|
+
if (typeof browserWindowOptions.hasShadow === 'boolean') {
|
|
1052
|
+
win.setHasShadow(browserWindowOptions.hasShadow);
|
|
1053
|
+
}
|
|
1054
|
+
// 设置窗口最小尺寸
|
|
1055
|
+
if (typeof browserWindowOptions.minWidth === 'number' && typeof browserWindowOptions.minHeight === 'number') {
|
|
1056
|
+
win.setMinimumSize(browserWindowOptions.minWidth, browserWindowOptions.minHeight);
|
|
1057
|
+
}
|
|
1058
|
+
// 设置窗口最大尺寸
|
|
1059
|
+
if (typeof browserWindowOptions.maxWidth === 'number' && typeof browserWindowOptions.maxHeight === 'number') {
|
|
1060
|
+
win.setMaximumSize(browserWindowOptions.maxWidth, browserWindowOptions.maxHeight);
|
|
1061
|
+
}
|
|
1062
|
+
// 设置窗口位置
|
|
1063
|
+
if (typeof browserWindowOptions.x === 'number' && typeof browserWindowOptions.y === 'number') {
|
|
1064
|
+
win.setPosition(browserWindowOptions.x, browserWindowOptions.y);
|
|
1065
|
+
}
|
|
1066
|
+
// 设置窗口标题
|
|
1067
|
+
if (typeof browserWindowOptions.title === 'string') {
|
|
1068
|
+
win.setTitle(browserWindowOptions.title);
|
|
1069
|
+
}
|
|
1070
|
+
// 设置窗口图标
|
|
1071
|
+
if (typeof browserWindowOptions.icon === 'string') {
|
|
1072
|
+
win.setIcon(browserWindowOptions.icon);
|
|
1073
|
+
}
|
|
1074
|
+
// 设置窗口菜单栏可见性
|
|
1075
|
+
if (typeof browserWindowOptions.autoHideMenuBar === 'boolean') {
|
|
1076
|
+
win.setAutoHideMenuBar(browserWindowOptions.autoHideMenuBar);
|
|
1077
|
+
}
|
|
1078
|
+
// 设置窗口最小化按钮
|
|
1079
|
+
if (browserWindowOptions.minimizable === false) {
|
|
1080
|
+
win.setMinimizable(false);
|
|
1081
|
+
}
|
|
1082
|
+
// 设置窗口最大化按钮
|
|
1083
|
+
if (browserWindowOptions.maximizable === false) {
|
|
1084
|
+
win.setMaximizable(false);
|
|
1085
|
+
}
|
|
1086
|
+
// 设置窗口关闭按钮
|
|
1087
|
+
if (browserWindowOptions.closable === false) {
|
|
1088
|
+
win.setClosable(false);
|
|
1089
|
+
}
|
|
1090
|
+
// 设置窗口焦点
|
|
1091
|
+
if (browserWindowOptions.focusable === false) {
|
|
1092
|
+
win.setFocusable(false);
|
|
1093
|
+
}
|
|
1094
|
+
// 设置窗口全屏
|
|
1095
|
+
if (browserWindowOptions.fullscreen === true) {
|
|
1096
|
+
win.setFullScreen(true);
|
|
1097
|
+
}
|
|
1098
|
+
// 设置窗口背景材质
|
|
1099
|
+
if (typeof browserWindowOptions.vibrancy === 'string') {
|
|
1100
|
+
win.setVibrancy(browserWindowOptions.vibrancy);
|
|
1101
|
+
}
|
|
1102
|
+
// 设置窗口透明度
|
|
1103
|
+
if (typeof browserWindowOptions.opacity === 'number') {
|
|
1104
|
+
win.setOpacity(browserWindowOptions.opacity);
|
|
1105
|
+
}
|
|
1106
|
+
// 设置窗口显示状态
|
|
1107
|
+
if (browserWindowOptions.show === false) {
|
|
1108
|
+
win.hide();
|
|
1109
|
+
}
|
|
818
1110
|
// 可继续扩展其他动态属性
|
|
819
1111
|
}
|
|
820
1112
|
_applyBrowserViewOptions(view, options) {
|
|
@@ -830,12 +1122,26 @@ class WindowsManager {
|
|
|
830
1122
|
if (typeof browserWindowOptions.width === 'number' && typeof browserWindowOptions.height === 'number') {
|
|
831
1123
|
view.setBounds({ x: 0, y: 0, width: browserWindowOptions.width, height: browserWindowOptions.height });
|
|
832
1124
|
}
|
|
1125
|
+
// 设置视图位置
|
|
1126
|
+
if (typeof browserWindowOptions.x === 'number' && typeof browserWindowOptions.y === 'number') {
|
|
1127
|
+
const bounds = view.getBounds();
|
|
1128
|
+
view.setBounds({
|
|
1129
|
+
x: browserWindowOptions.x,
|
|
1130
|
+
y: browserWindowOptions.y,
|
|
1131
|
+
width: bounds.width,
|
|
1132
|
+
height: bounds.height
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
1135
|
+
// 设置视图背景颜色
|
|
1136
|
+
if (typeof browserWindowOptions.backgroundColor === 'string') {
|
|
1137
|
+
view.setBackgroundColor(browserWindowOptions.backgroundColor);
|
|
1138
|
+
}
|
|
833
1139
|
// 可继续扩展其他动态属性
|
|
834
1140
|
}
|
|
835
1141
|
// 生成一个bv 做为预加载资源窗口,加载完成后销毁
|
|
836
1142
|
async createPreloadWebContents(url) {
|
|
837
1143
|
return new Promise(async (resolve, reject) => {
|
|
838
|
-
let bv = this.create({
|
|
1144
|
+
let bv = await this.create({
|
|
839
1145
|
type: 'BV',
|
|
840
1146
|
url,
|
|
841
1147
|
name: `preload-web-contents-${md5(url)}`,
|
|
@@ -858,7 +1164,7 @@ class WindowsManager {
|
|
|
858
1164
|
// @ts-ignore
|
|
859
1165
|
global['__ELECTRON_WINDOWS_MANAGER__'] = undefined;
|
|
860
1166
|
let isInitialized = false;
|
|
861
|
-
const initialize = (preload, loadingViewUrl, errorViewUrl,
|
|
1167
|
+
const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsConfig, webviewDomainWhiteList) => {
|
|
862
1168
|
// @ts-ignore
|
|
863
1169
|
if (isInitialized && global['__ELECTRON_WINDOWS_MANAGER__']) {
|
|
864
1170
|
// @ts-ignore
|
|
@@ -866,7 +1172,7 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsUrl
|
|
|
866
1172
|
}
|
|
867
1173
|
isInitialized = true;
|
|
868
1174
|
// @ts-ignore
|
|
869
|
-
const wm = global['__ELECTRON_WINDOWS_MANAGER__'] = new WindowsManager(preload, loadingViewUrl, errorViewUrl,
|
|
1175
|
+
const wm = global['__ELECTRON_WINDOWS_MANAGER__'] = new WindowsManager(preload, loadingViewUrl, errorViewUrl, preloadWebContentsConfig, webviewDomainWhiteList);
|
|
870
1176
|
eIpc.mainIPC.handleRenderer('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', async (data) => {
|
|
871
1177
|
if (data?.type === 'create') {
|
|
872
1178
|
const opt = data;
|
|
@@ -890,7 +1196,7 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsUrl
|
|
|
890
1196
|
winInitUrl: `${findWin?._initUrl || ''}`,
|
|
891
1197
|
};
|
|
892
1198
|
}
|
|
893
|
-
const res = wm.create(opt.data);
|
|
1199
|
+
const res = await wm.create(opt.data);
|
|
894
1200
|
return {
|
|
895
1201
|
winId: Number(`${res.id || res._id || -1}`),
|
|
896
1202
|
winName: `${res?._name || ''}`,
|
|
@@ -1026,9 +1332,9 @@ const initialize = (preload, loadingViewUrl, errorViewUrl, preloadWebContentsUrl
|
|
|
1026
1332
|
return undefined;
|
|
1027
1333
|
}
|
|
1028
1334
|
// 是否开启预加载窗口
|
|
1029
|
-
if (data?.type === '
|
|
1335
|
+
if (data?.type === 'setPreloadWebContentsConfig') {
|
|
1030
1336
|
const opt = data;
|
|
1031
|
-
wm.
|
|
1337
|
+
wm.setPreloadWebContentsConfig(opt.data);
|
|
1032
1338
|
}
|
|
1033
1339
|
if (data?.type === 'createPreloadWebContents') {
|
|
1034
1340
|
const opt = data;
|