clickgo-native 0.0.1-dev → 0.0.3-dev3

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/dist/index.ts CHANGED
@@ -1,365 +1,509 @@
1
+ import * as electron from 'electron';
2
+ import * as path from 'path';
3
+ import * as libFs from './lib/fs';
4
+ export const fs = libFs;
5
+ import * as libTool from './lib/tool';
6
+ export const tool = libTool;
7
+
1
8
  // npm publish --tag dev --access public
2
9
  // --- sass --watch dist/:dist/ --style compressed --no-source-map ---
3
- import * as electron from 'electron';
4
- electron.Menu.setApplicationMenu(null);
5
10
 
6
- /** --- 环境是否已经准备好了 --- */
7
- let isReady: boolean = false;
8
- /** --- 窗体是否显示边框 --- */
9
- let isFrame: boolean = false;
10
- /** --- 是否关闭窗口就退出 --- */
11
- let isQuit: boolean = true;
11
+ /** --- 是否是沉浸式的 --- */
12
+ let isImmersion: boolean = false;
13
+ // --- windows 下是且只会是沉浸式,其他系统以启动的第一个窗体为准绑定大小最小化最大化关闭等功能 ---
12
14
 
13
- // const platform: NodeJS.Platform = process.platform;
14
- const platform: NodeJS.Platform = 'darwin';
15
+ /** --- 窗体是否含有 border 边框,有的话将不是沉浸式,也不会绑定任何窗体的大小和相关事件 --- */
16
+ let hasFrame: boolean = false;
15
17
 
16
- let token: string = '';
17
- /**
18
- * --- 验证 token 是否正确 ---
19
- * @param t 要验证的 token
20
- */
21
- export function verifyToken(t: string): boolean {
22
- if (t !== token) {
23
- return false;
24
- }
25
- return true;
26
- }
18
+ /** --- 是否没有物理窗体时就主动退出软件(进程结束),如果不要窗体只有 node 的话,会用到 false 的情况 --- */
19
+ let isNoFormQuit: boolean = true;
27
20
 
28
- /**
29
- * --- 等到 native 环境装载完毕 ---
30
- */
31
- export async function ready(): Promise<void> {
32
- await electron.app.whenReady();
33
- isReady = true;
34
- }
21
+ /** --- 主窗体 --- */
22
+ let form: electron.BrowserWindow | undefined;
35
23
 
36
- /** --- node 监听前台消息列表 --- */
37
- const listeners: Record<string, Array<{
38
- 'once': boolean;
39
- 'handler': (param?: string) => any | Promise<any>;
40
- }>> = {};
41
- // --- 添加前台监听 ---
42
- export function on(
43
- name: string,
44
- handler: (param?: string) => any | Promise<any>,
45
- once: boolean = false
46
- ): void {
47
- if (!listeners[name]) {
48
- listeners[name] = [];
49
- }
50
- listeners[name].push({
51
- 'once': once,
52
- 'handler': handler
53
- });
54
- }
55
- export function once(name: string, handler: (param?: string) => any | Promise<any>): void {
56
- on(name, handler, true);
57
- }
24
+ /** --- 当前设定的通讯 token --- */
25
+ let token: string = '';
58
26
 
59
- // --- 移除前台监听 ---
60
- export function off(name: string, handler: (param?: string) => any | Promise<any>): void {
61
- if (!listeners[name]) {
62
- return;
63
- }
64
- for (let i = 0; i < listeners[name].length; ++i) {
65
- if (listeners[name][i].handler !== handler) {
66
- continue;
67
- }
68
- listeners[name].splice(i, 1);
69
- if (listeners[name].length === 0) {
70
- delete listeners[name];
71
- break;
72
- }
73
- --i;
74
- }
75
- }
27
+ /** --- 当前系统平台 --- */
28
+ const platform: NodeJS.Platform = process.platform;
29
+ // const platform: NodeJS.Platform = 'darwin';
76
30
 
77
- let win: electron.BrowserWindow | undefined;
78
- function createForm(path: string): void {
79
- const op: Electron.BrowserWindowConstructorOptions = {
80
- 'width': 500,
81
- 'height': 400,
82
- 'frame': isFrame,
83
- 'resizable': false,
84
- 'show': false,
85
- // 'hasShadow': false,
86
- 'center': true,
87
- 'transparent': isFrame ? undefined : true
88
- };
89
- /*
90
- if (platform === 'win32') {
91
- op.transparent = true;
92
- }
93
- */
94
- win = new electron.BrowserWindow(op);
95
- win.webContents.userAgent = 'electron/' + electron.app.getVersion() + ' ' + platform + '/' + process.arch;
96
- win.once('ready-to-show', function(): void {
97
- if (!win) {
98
- return;
99
- }
100
- if (platform === 'win32') {
101
- win.maximize();
102
- win.setIgnoreMouseEvents(true, { 'forward': true });
103
- }
104
- else {
105
- // --- 设置为第一个窗体的大小 ---
106
- }
107
- win.show();
108
- // --- timer ---
109
- const timerFunc = async function(): Promise<void> {
110
- if (!win) {
31
+ /** --- 监听前台的执行的方法,内置的方法,用户可调用方法自行添加 --- */
32
+ const methods: Record<string, {
33
+ 'once': boolean;
34
+ 'handler': (...param: any[]) => any | Promise<any>;
35
+ }> = {
36
+ // --- 成功运行一个 task 后 init ---
37
+ 'cg-init': {
38
+ 'once': true,
39
+ handler: function(t: string) {
40
+ // --- t 是网页传来的 token ---
41
+ if (!t || !form) {
111
42
  return;
112
43
  }
113
- try {
114
- const rtn = await win.webContents.executeJavaScript('window.clickGoNative && clickGoNative.isReady');
115
- if (!rtn) {
116
- // --- 下一次循环 ---
117
- setTimeout(function() {
118
- timerFunc().catch(function(e) {
119
- console.log(e);
120
- });
121
- }, 100);
122
- return;
123
- }
124
- }
125
- catch {
126
- // --- 下一次循环 ---
127
- setTimeout(function() {
128
- timerFunc().catch(function(e) {
129
- console.log(e);
130
- });
131
- }, 100);
44
+ form.resizable = true;
45
+ token = t;
46
+ }
47
+ },
48
+ // --- 完全退出软件进程 ---
49
+ 'cg-quit': {
50
+ 'once': false,
51
+ handler: function(t: string): void {
52
+ if (!t || !form) {
132
53
  return;
133
54
  }
134
- // --- 检测浏览器是否有要执行的内容 ---
135
- const list = JSON.parse(await win.webContents.executeJavaScript('clickGoNative.cgInnerGetSends()')) as Array<{ 'id': number; 'name': string; 'param': string | undefined; }>;
136
- for (const item of list) {
137
- if (!listeners[item.name]) {
138
- continue;
139
- }
140
- // --- 根据 name 执行相关函数 ---
141
- for (let i = 0; i < listeners[item.name].length; ++i) {
142
- const it = listeners[item.name][i];
143
- const result = it.handler(item.param);
144
- if (it.once) {
145
- listeners[item.name].splice(i, 1);
146
- --i;
147
- }
148
- if (result instanceof Promise) {
149
- result.then(function(result) {
150
- if (!win) {
151
- return;
152
- }
153
- win.webContents.executeJavaScript(`clickGoNative.cgInnerReceive(${item.id}, "${item.name}", ${result !== undefined ? (', "' + (result as string).replace(/"/g, '\\"') + '"') : ''})`).catch(function(e) {
154
- console.log(e);
155
- });
156
- }).catch(function(e) {
157
- console.log(e);
158
- });
159
- }
160
- else {
161
- if (!win) {
162
- return;
163
- }
164
- win.webContents.executeJavaScript(`clickGoNative.cgInnerReceive(${item.id}, "${item.name}", ${result !== undefined ? (', "' + (result as string).replace(/"/g, '\\"') + '"') : ''})`).catch(function(e) {
165
- console.log(e);
166
- });
167
- }
168
- if (it.once) {
169
- listeners[item.name].splice(i, 1);
170
- if (listeners[item.name].length === 0) {
171
- delete listeners[item.name];
172
- break;
173
- }
174
- --i;
175
- }
176
- }
177
- }
178
- // --- 下一次循环 ---
179
- setTimeout(function() {
180
- timerFunc().catch(function(e) {
181
- console.log(e);
182
- });
183
- }, 100);
184
- };
185
- timerFunc().catch(function(e) {
186
- console.log(e);
187
- });
188
- });
189
- const lio = path.indexOf('?');
190
- const search = lio === -1 ? '' : path.slice(lio + 1);
191
- if (lio !== -1) {
192
- path = path.slice(0, lio);
193
- }
194
- win.loadFile(path, {
195
- 'search': search
196
- }).catch(function(e): void {
197
- throw e;
198
- });
199
- win.on('close', function() {
200
- win = undefined;
201
- });
202
- }
203
-
204
- export function run(path: string, opt: { 'frame'?: boolean; 'quit'?: boolean; } = {}): void {
205
- if (!isReady) {
206
- return;
207
- }
208
- if (opt.frame !== undefined) {
209
- isFrame = opt.frame;
210
- }
211
- if (opt.quit !== undefined) {
212
- isQuit = opt.quit;
213
- }
214
- createForm(path);
215
- // --- 成功运行一个 task 后 init ---
216
- once('cg-init', function(t): void {
217
- if (!t || !win) {
218
- return;
219
- }
220
- win.resizable = true;
221
- token = t;
222
- });
223
- // --- 退出软件 ---
224
- on('cg-quit', function(j): void {
225
- if (!win || !j) {
226
- return;
227
- }
228
- try {
229
- const rtn = JSON.parse(j);
230
- if (!verifyToken(rtn.token)) {
55
+ if (!verifyToken(t)) {
231
56
  return;
232
57
  }
233
58
  electron.app.quit();
234
59
  }
235
- catch (e) {
236
- console.log(e);
237
- }
238
- });
239
- // --- 设置窗体大小 ---
240
- on('cg-set-size', function(j) {
241
- if (!win || !j) {
242
- return;
243
- }
244
- try {
245
- const rtn = JSON.parse(j);
246
- if (!verifyToken(rtn.token)) {
60
+ },
61
+ // --- 设置实体窗体大小,仅非沉浸式可设置 ---
62
+ 'cg-set-size': {
63
+ 'once': false,
64
+ handler: function(t: string, width: number, height: number): void {
65
+ if (isImmersion || !form || !width || !height) {
247
66
  return;
248
67
  }
249
- if (!rtn.width || !rtn.height) {
68
+ if (!verifyToken(t)) {
250
69
  return;
251
70
  }
252
- win.setSize(rtn.width, rtn.height);
253
- win.center();
254
- }
255
- catch (e) {
256
- console.log(e);
71
+ form.setSize(width, height);
72
+ form.center();
257
73
  }
258
- });
259
- // --- 设置窗体最大化、最小化、还原 ---
260
- on('cg-set-state', function(j) {
261
- if (!win || !j) {
262
- return;
263
- }
264
- try {
265
- const rtn = JSON.parse(j);
266
- if (!verifyToken(rtn.token)) {
74
+ },
75
+ // --- 设置窗体最大化、最小化、还原,仅非 frame 可设置 ---
76
+ 'cg-set-state': {
77
+ 'once': false,
78
+ handler: function(t: string, state: string): void {
79
+ if (hasFrame || !form || !state) {
80
+ return;
81
+ }
82
+ if (!verifyToken(t)) {
267
83
  return;
268
84
  }
269
- switch (rtn.state) {
85
+ switch (state) {
270
86
  case 'max': {
271
- win.maximize();
87
+ form.maximize();
272
88
  break;
273
89
  }
274
90
  case 'min': {
275
- win.minimize();
91
+ form.minimize();
276
92
  break;
277
93
  }
278
94
  default: {
279
- win.restore();
95
+ form.restore();
280
96
  }
281
97
  }
282
98
  }
283
- catch (e) {
284
- console.log(e);
285
- }
286
- });
287
- // --- 响应主 task 被关闭的情况 ---
288
- on('cg-main-close', function(j) {
289
- if (!win || !j) {
290
- return;
99
+ },
100
+ // --- 关闭窗体(可能软件进程不会被退出) ---
101
+ 'cg-close': {
102
+ 'once': false,
103
+ handler: function(t: string): void {
104
+ if (!form) {
105
+ return;
106
+ }
107
+ if (!verifyToken(t)) {
108
+ return;
109
+ }
110
+ form.close();
291
111
  }
292
- try {
293
- const rtn = JSON.parse(j);
294
- if (!verifyToken(rtn.token)) {
112
+ },
113
+ // --- 设置 IgnoreMouseEvents,仅限沉浸式 ---
114
+ 'cg-mouse-ignore': {
115
+ 'once': false,
116
+ handler: function(t: string, val: boolean): void {
117
+ if (!isImmersion || !form) {
295
118
  return;
296
119
  }
297
- if (isQuit) {
298
- electron.app.quit();
120
+ if (!verifyToken(t)) {
121
+ return;
122
+ }
123
+ if (val) {
124
+ form.setIgnoreMouseEvents(true, { 'forward': true });
299
125
  }
300
126
  else {
301
- win.close();
127
+ form.setIgnoreMouseEvents(false);
302
128
  }
303
129
  }
304
- catch (e) {
305
- console.log(e);
130
+ },
131
+ // --- 是否允许最大化 ---
132
+ 'cg-maximizable': {
133
+ 'once': false,
134
+ handler: function(t: string, val: boolean): void {
135
+ if (isImmersion || !form) {
136
+ return;
137
+ }
138
+ if (!verifyToken(t)) {
139
+ return;
140
+ }
141
+ form.setMaximizable(val);
306
142
  }
307
- });
308
- // --- 设置 IgnoreMouseEvents,仅限 windows ---
309
- on('cg-mouse-ignore', function(j) {
310
- if (!win || !j) {
311
- return;
143
+ },
144
+
145
+ // --- fs 相关操作 ---
146
+
147
+ 'cg-fs-getContent': {
148
+ 'once': false,
149
+ handler: async function(
150
+ t: string,
151
+ path: string,
152
+ options: Record<string, any>
153
+ ): Promise<string | Buffer | null> {
154
+ if (!verifyToken(t)) {
155
+ return null;
156
+ }
157
+ return libFs.getContent(path, options);
312
158
  }
313
- try {
314
- const rtn = JSON.parse(j);
315
- if (!verifyToken(rtn.token)) {
316
- return;
159
+ },
160
+ 'cg-fs-putContent': {
161
+ 'once': false,
162
+ handler: async function(
163
+ t: string, path: string, data: string | Buffer, options: Record<string, any>
164
+ ): Promise<boolean> {
165
+ if (!verifyToken(t)) {
166
+ return false;
317
167
  }
318
- if (rtn.param) {
319
- win.setIgnoreMouseEvents(true, { 'forward': true });
168
+ return fs.putContent(path, data, options);
169
+ }
170
+ },
171
+ 'cg-fs-readLink': {
172
+ 'once': false,
173
+ handler: async function(t: string, path: string, encoding?: BufferEncoding): Promise<string | null> {
174
+ if (!verifyToken(t)) {
175
+ return null;
320
176
  }
321
- else {
322
- win.setIgnoreMouseEvents(false);
177
+ return fs.readLink(path, encoding);
178
+ }
179
+ },
180
+ 'cg-fs-symlink': {
181
+ 'once': false,
182
+ handler: async function(t: string, filePath: string, linkPath: string, type?: 'dir' | 'file' | 'junction'): Promise<boolean> {
183
+ if (!verifyToken(t)) {
184
+ return false;
323
185
  }
186
+ return fs.symlink(filePath, linkPath, type);
324
187
  }
325
- catch (e) {
326
- console.log(e);
188
+ },
189
+ 'cg-fs-unlink': {
190
+ 'once': false,
191
+ handler: async function(t: string, path: string): Promise<boolean> {
192
+ if (!verifyToken(t)) {
193
+ return false;
194
+ }
195
+ return fs.unlink(path);
327
196
  }
328
- });
329
- electron.app.on('window-all-closed', function(): void {
330
- /*
331
- // --- MAC ---
332
- if (platform !== 'darwin') {
333
- electron.app.quit();
197
+ },
198
+ 'cg-fs-stats': {
199
+ 'once': false,
200
+ handler: async function(t: string, path: string): Promise<Record<string, any> | null> {
201
+ if (!verifyToken(t)) {
202
+ return null;
203
+ }
204
+ return fs.stats(path);
334
205
  }
335
- */
336
- if (isQuit) {
337
- electron.app.quit();
206
+ },
207
+ 'cg-fs-mkdir': {
208
+ 'once': false,
209
+ handler: async function(t: string, path: string, mode: number): Promise<boolean> {
210
+ if (!verifyToken(t)) {
211
+ return false;
212
+ }
213
+ return fs.mkdir(path, mode);
338
214
  }
339
- });
340
- electron.app.on('activate', function(): void {
341
- if (electron.BrowserWindow.getAllWindows().length === 0) {
215
+ },
216
+ 'cg-fs-rmdir': {
217
+ 'once': false,
218
+ handler: async function(t: string, path: string): Promise<boolean> {
219
+ if (!verifyToken(t)) {
220
+ return false;
221
+ }
222
+ return fs.rmdir(path);
223
+ }
224
+ },
225
+ 'cg-fs-chmod': {
226
+ 'once': false,
227
+ handler: async function(t: string, path: string, mod: string | number): Promise<boolean> {
228
+ if (!verifyToken(t)) {
229
+ return false;
230
+ }
231
+ return fs.chmod(path, mod);
232
+ }
233
+ },
234
+ 'cg-fs-rename': {
235
+ 'once': false,
236
+ handler: async function(t: string, oldPath: string, newPath: string): Promise<boolean> {
237
+ if (!verifyToken(t)) {
238
+ return false;
239
+ }
240
+ return fs.rename(oldPath, newPath);
241
+ }
242
+ },
243
+ 'cg-fs-readDir': {
244
+ 'once': false,
245
+ handler: async function(t: string, path: string, encoding?: BufferEncoding): Promise<any[]> {
246
+ if (!verifyToken(t)) {
247
+ return [];
248
+ }
249
+ return fs.readDir(path, encoding);
250
+ }
251
+ },
252
+ 'cg-fs-copyFile': {
253
+ 'once': false,
254
+ handler: async function(t: string, src: string, dest: string): Promise<boolean> {
255
+ if (!verifyToken(t)) {
256
+ return false;
257
+ }
258
+ return fs.copyFile(src, dest);
259
+ }
260
+ },
261
+
262
+ // --- 无需校验码 ---
263
+
264
+ // --- 测试与 native 的连通性 ---
265
+ 'cg-ping': {
266
+ 'once': false,
267
+ handler: function(t: string): string {
268
+ // --- t 不是 token,传过来什么就会传回去 ---
269
+ return 'pong: ' + t;
270
+ }
271
+ },
272
+ // --- 判断窗体是否是最大化状态 ---
273
+ 'cg-is-max': {
274
+ 'once': false,
275
+ handler: function(): boolean {
276
+ return form?.isMaximized ? true : false;
277
+ }
278
+ }
279
+ };
280
+
281
+ /** --- 全局类 --- */
282
+ export abstract class AbstractBoot {
283
+
284
+ /**
285
+ * --- 是否是沉浸式运行 ---
286
+ */
287
+ public get isImmersion(): boolean {
288
+ return isImmersion;
289
+ }
290
+
291
+ /**
292
+ * --- 是否含有实体窗体边框和标题 ---
293
+ */
294
+ public get hasFrame(): boolean {
295
+ return hasFrame;
296
+ }
297
+
298
+ /**
299
+ * --- 没有实体窗体时整个实体进程是不是会被结束 ---
300
+ */
301
+ public get isNoFormQuit(): boolean {
302
+ return isNoFormQuit;
303
+ }
304
+
305
+ /**
306
+ * --- 当前系统代号 ---
307
+ */
308
+ public get platform(): NodeJS.Platform {
309
+ return platform;
310
+ }
311
+
312
+ /**
313
+ * --- 当前的通讯 token ---
314
+ */
315
+ public get token(): string {
316
+ return token;
317
+ }
318
+
319
+ /** --- 入口方法 --- */
320
+ public abstract main(): void | Promise<void>;
321
+
322
+ /**
323
+ * --- 开始运行起来一个主实体窗体,整个进程本方法只能执行一次 ---
324
+ * @param path 实体窗体网页路径
325
+ * @param opt 参数
326
+ */
327
+ public run(path: string, opt: { 'frame'?: boolean; 'quit'?: boolean; } = {}): void {
328
+ if (opt.frame !== undefined) {
329
+ // --- 默认 false ---
330
+ hasFrame = opt.frame;
331
+ }
332
+ if (opt.quit !== undefined) {
333
+ // --- 默认 true ---
334
+ isNoFormQuit = opt.quit;
335
+ }
336
+ // --- 判断是否是沉浸式 ---
337
+ if (platform === 'win32') {
338
+ // --- 是 Windows 才有可能是沉浸式 ---
339
+ if (!hasFrame) {
340
+ // --- 实体窗体没有边框,一定是沉浸式 ---
341
+ isImmersion = true;
342
+ }
343
+ }
344
+ // --- 创建实体窗体 ---
345
+ createForm(path);
346
+ // --- 监听所有实体窗体关闭事件 ---
347
+ electron.app.on('window-all-closed', function(): void {
348
+ if (isNoFormQuit) {
349
+ electron.app.quit();
350
+ }
351
+ });
352
+ // --- 软件被活动性激活的事件 ---
353
+ electron.app.on('activate', function(): void {
354
+ if (electron.BrowserWindow.getAllWindows().length > 0) {
355
+ return;
356
+ }
342
357
  createForm(path);
343
- // --- 成功运行一个 task init ---
344
- once('cg-init', function(t): void {
345
- if (!t || !win) {
346
- return;
358
+ // --- 成功运行一个 task 后再次添加 init ---
359
+ methods['cg-init'] = {
360
+ 'once': true,
361
+ handler: function(t: string) {
362
+ // --- t 是网页传来的 token ---
363
+ if (!t || !form) {
364
+ return;
365
+ }
366
+ form.resizable = true;
367
+ token = t;
347
368
  }
348
- win.resizable = true;
349
- token = t;
350
- });
369
+ };
370
+ });
371
+ }
372
+
373
+ /**
374
+ * --- 绑定监听网页调用方法的方法 ---
375
+ * @param name 方法名
376
+ * @param handler 要执行的函数
377
+ * @param once 是否只执行一次
378
+ */
379
+ public on(
380
+ name: string,
381
+ handler: (...param: any[]) => any | Promise<any>,
382
+ once: boolean = false
383
+ ): void {
384
+ methods[name] = {
385
+ 'once': once,
386
+ 'handler': handler
387
+ };
388
+ }
389
+
390
+ /**
391
+ * --- 绑定监听网页调用方法的方法但只会执行一次 ---
392
+ * @param name 方法名
393
+ * @param handler 要执行的函数
394
+ */
395
+ public once(name: string, handler: (...param: any[]) => any | Promise<any>): void {
396
+ this.on(name, handler, true);
397
+ }
398
+
399
+ /**
400
+ * --- 解绑监听的方法 ---
401
+ * @param name 方法名
402
+ */
403
+ public off(name: string): void {
404
+ if (!methods[name]) {
405
+ return;
351
406
  }
407
+ delete methods[name];
408
+ }
409
+
410
+ }
411
+
412
+ /** --- 用户调用运行 boot 类 --- */
413
+ export function launcher(boot: AbstractBoot): void {
414
+ (async function() {
415
+ // --- 等到 native 环境装载完毕 ---
416
+ await electron.app.whenReady();
417
+ await fs.refreshDrives();
418
+ // --- 执行回调 ---
419
+ await boot.main();
420
+ })().catch(function() {
421
+ return;
352
422
  });
353
423
  }
354
424
 
355
- // --- listeners 监视 ---
356
- setInterval(function() {
357
- const keysCount: Record<string, number> = {};
358
- let count: number = 0;
359
- for (const key in listeners) {
360
- keysCount[key] = listeners[key].length;
361
- count += keysCount[key];
425
+ // --- 系统启动 ---
426
+
427
+ electron.Menu.setApplicationMenu(null);
428
+
429
+ // --- 实际用来监听网页传输过来的数据 ---
430
+ electron.ipcMain.handle('pre', function(e: electron.IpcMainInvokeEvent, name: string, ...param: any[]): any {
431
+ if (!methods[name]) {
432
+ return;
433
+ }
434
+ const r = methods[name].handler(...param);
435
+ if (methods[name].once) {
436
+ delete methods[name];
437
+ }
438
+ return r;
439
+ });
440
+
441
+ /**
442
+ * --- 验证 token 是否正确 ---
443
+ * @param t 要验证的 token
444
+ */
445
+ export function verifyToken(t: string): boolean {
446
+ if (t !== token) {
447
+ return false;
448
+ }
449
+ return true;
450
+ }
451
+
452
+ /**
453
+ * --- 内部调用用来创建实体窗体的函数 ---
454
+ * @param p 窗体网页路径
455
+ */
456
+ function createForm(p: string): void {
457
+ const op: Electron.BrowserWindowConstructorOptions = {
458
+ 'webPreferences': {
459
+ 'nodeIntegration': false,
460
+ 'contextIsolation': true,
461
+ 'preload': path.join(__dirname, '/pre.js')
462
+ },
463
+ 'width': hasFrame ? 800 : 500,
464
+ 'height': hasFrame ? 600 : 300,
465
+ 'frame': hasFrame,
466
+ 'resizable': false,
467
+ 'show': false,
468
+ 'center': true,
469
+ 'transparent': isImmersion ? true : false
470
+ };
471
+ form = new electron.BrowserWindow(op);
472
+ form.webContents.userAgent = 'electron/' + electron.app.getVersion() + ' ' + platform + '/' + process.arch + ' immersion/' + (isImmersion ? '1' : '0') + ' frame/' + (hasFrame ? '1' : '0');
473
+ // form.webContents.openDevTools();
474
+ form.once('ready-to-show', function(): void {
475
+ if (!form) {
476
+ return;
477
+ }
478
+ if (isImmersion) {
479
+ // --- 沉浸式默认最大化 ---
480
+ form.maximize();
481
+ form.setIgnoreMouseEvents(true, { 'forward': true });
482
+ }
483
+ else {
484
+ // --- 设置为第一个窗体的大小 ---
485
+ }
486
+ form.show();
487
+ });
488
+ const lio = p.indexOf('?');
489
+ const search = lio === -1 ? '' : p.slice(lio + 1);
490
+ if (lio !== -1) {
491
+ p = p.slice(0, lio);
362
492
  }
363
- console.log('keysCount', keysCount);
364
- console.log(`All count: ${count}`);
365
- }, 5000);
493
+ form.loadFile(p, {
494
+ 'search': search
495
+ }).catch(function(e): void {
496
+ throw e;
497
+ });
498
+ form.on('close', function() {
499
+ form = undefined;
500
+ });
501
+ // --- 最大化事件 ---
502
+ form.on('maximize', function() {
503
+ form?.webContents.executeJavaScript('if(window.clickgoNativeWeb){clickgoNativeWeb.invoke("maximize")}') as any;
504
+ });
505
+ // --- 最大化还原 ---
506
+ form.on('unmaximize', function() {
507
+ form?.webContents.executeJavaScript('if(window.clickgoNativeWeb){clickgoNativeWeb.invoke("unmaximize")}') as any;
508
+ });
509
+ }