@yufengtadian/freedom-cli 1.12.18 → 1.13.1

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.
Files changed (80) hide show
  1. package/README.md +11 -3
  2. package/lib/build.js +1 -1
  3. package/lib/security.js +2 -2
  4. package/package.json +5 -1
  5. package/shell/darwin-arm64/freedom-shell +0 -0
  6. package/shell/linux-x64/freedom-shell +0 -0
  7. package/shell/win-x64/freedom-shell.exe +0 -0
  8. package/templates/go/go.mod +1 -7
  9. package/templates/go/go.sum +2 -2
  10. package/templates/go/main.go +22 -8
  11. package/templates/go/pkg/freedom/anti_debug_other.go +2 -3
  12. package/templates/go/pkg/freedom/anti_debug_windows.go +10 -12
  13. package/templates/go/pkg/freedom/assets/{index.html → default.html} +1 -1
  14. package/templates/go/pkg/freedom/assets/freedom.js +200 -5
  15. package/templates/go/pkg/freedom/assets_embed.go +11 -13
  16. package/templates/go/pkg/freedom/authenticode_other.go +11 -0
  17. package/templates/go/pkg/freedom/authenticode_windows.go +87 -0
  18. package/templates/go/pkg/freedom/backend_proc.go +291 -53
  19. package/templates/go/pkg/freedom/bridge.go +13 -2
  20. package/templates/go/pkg/freedom/capability.go +77 -0
  21. package/templates/go/pkg/freedom/center_other.go +3 -0
  22. package/templates/go/pkg/freedom/center_windows.go +45 -35
  23. package/templates/go/pkg/freedom/dispatch.go +60 -0
  24. package/templates/go/pkg/freedom/events_windows.go +319 -0
  25. package/templates/go/pkg/freedom/freedom.go +193 -99
  26. package/templates/go/pkg/freedom/msgwindow_windows.go +257 -0
  27. package/templates/go/pkg/freedom/osver_other.go +15 -0
  28. package/templates/go/pkg/freedom/osver_windows.go +121 -0
  29. package/templates/go/pkg/freedom/proc_hide_windows.go +2 -2
  30. package/templates/go/pkg/freedom/{configfile.go → resources.go} +38 -35
  31. package/templates/go/pkg/freedom/security.go +19 -12
  32. package/templates/go/pkg/freedom/singleinstance_other.go +10 -0
  33. package/templates/go/pkg/freedom/singleinstance_windows.go +145 -0
  34. package/templates/go/pkg/freedom/spawn_other.go +11 -0
  35. package/templates/go/pkg/freedom/spawn_windows.go +23 -0
  36. package/templates/go/pkg/freedom/store.go +458 -0
  37. package/templates/go/pkg/freedom/syscap_linux.go +278 -0
  38. package/templates/go/pkg/freedom/syscap_other.go +15 -3
  39. package/templates/go/pkg/freedom/syscap_windows.go +228 -36
  40. package/templates/go/pkg/freedom/sysint_common.go +70 -0
  41. package/templates/go/pkg/freedom/sysint_windows.go +426 -0
  42. package/templates/go/pkg/freedom/tray_common.go +12 -0
  43. package/templates/go/pkg/freedom/tray_linux.go +302 -0
  44. package/templates/go/pkg/freedom/tray_other.go +2 -2
  45. package/templates/go/pkg/freedom/tray_windows.go +69 -39
  46. package/templates/go/pkg/freedom/updater.go +372 -0
  47. package/templates/go/pkg/freedom/window_mgr.go +385 -0
  48. package/templates/go/pkg/freedom/window_other.go +32 -66
  49. package/templates/go/pkg/freedom/window_windows.go +397 -254
  50. package/templates/go/build_all.txt +0 -0
  51. package/templates/go/build_err.txt +0 -0
  52. package/templates/go/gen_config.go +0 -22
  53. package/templates/go/pkg/freedom/center_windows_test.go +0 -32
  54. package/templates/go/pkg/freedom/security_test.go +0 -153
  55. package/templates/go/temp_vet_test/main.go +0 -40
  56. package/templates/go/test_err.txt +0 -0
  57. package/templates/go/vet_err.txt +0 -1
  58. package/templates/go/vet_err2.txt +0 -2
  59. package/templates/go/webview_go/.github/workflows/ci.yaml +0 -62
  60. package/templates/go/webview_go/CHANGELOG.md +0 -15
  61. package/templates/go/webview_go/LICENSE +0 -22
  62. package/templates/go/webview_go/README.md +0 -50
  63. package/templates/go/webview_go/examples/basic/main.go +0 -12
  64. package/templates/go/webview_go/examples/bind/main.go +0 -38
  65. package/templates/go/webview_go/glue.c +0 -36
  66. package/templates/go/webview_go/go.mod +0 -3
  67. package/templates/go/webview_go/go.sum +0 -0
  68. package/templates/go/webview_go/libs/mswebview2/LICENSE +0 -27
  69. package/templates/go/webview_go/libs/mswebview2/include/WebView2.h +0 -23568
  70. package/templates/go/webview_go/libs/mswebview2/include/vendor.go +0 -2
  71. package/templates/go/webview_go/libs/mswebview2/vendor.go +0 -2
  72. package/templates/go/webview_go/libs/mswebview2/version.txt +0 -1
  73. package/templates/go/webview_go/libs/webview/LICENSE +0 -22
  74. package/templates/go/webview_go/libs/webview/include/vendor.go +0 -2
  75. package/templates/go/webview_go/libs/webview/include/webview.h +0 -3871
  76. package/templates/go/webview_go/libs/webview/vendor.go +0 -2
  77. package/templates/go/webview_go/libs/webview/version.txt +0 -1
  78. package/templates/go/webview_go/webview.cc +0 -1
  79. package/templates/go/webview_go/webview.go +0 -481
  80. package/templates/go/webview_go/webview_test.go +0 -50
@@ -1,2 +0,0 @@
1
- // Dummy file to allow vendoring.
2
- package vendor
@@ -1 +0,0 @@
1
- fb6b17d826041411e6346cd9a785a5ceba7987c4
@@ -1 +0,0 @@
1
- #include "webview.h"
@@ -1,481 +0,0 @@
1
- package webview
2
-
3
- /*
4
- #cgo CFLAGS: -I${SRCDIR}/libs/webview/include
5
- #cgo CXXFLAGS: -I${SRCDIR}/libs/webview/include -DWEBVIEW_STATIC
6
-
7
- #cgo linux openbsd freebsd netbsd CXXFLAGS: -DWEBVIEW_GTK -std=c++11
8
- #cgo linux openbsd freebsd netbsd LDFLAGS: -ldl
9
- #cgo linux openbsd freebsd netbsd pkg-config: gtk+-3.0 webkit2gtk-4.0
10
-
11
- #cgo darwin CXXFLAGS: -DWEBVIEW_COCOA -std=c++11
12
- #cgo darwin LDFLAGS: -framework WebKit -ldl
13
-
14
- #cgo windows CXXFLAGS: -DWEBVIEW_EDGE -std=c++14 -I${SRCDIR}/libs/mswebview2/include
15
- #cgo windows LDFLAGS: -static -ladvapi32 -lole32 -lshell32 -lshlwapi -luser32 -lversion
16
-
17
- #include "webview.h"
18
-
19
- #include <stdlib.h>
20
- #include <stdint.h>
21
-
22
- void CgoWebViewDispatch(webview_t w, uintptr_t arg);
23
- void CgoWebViewBind(webview_t w, const char *name, uintptr_t index);
24
- void CgoWebViewUnbind(webview_t w, const char *name);
25
- */
26
- import "C"
27
- import (
28
- _ "github.com/webview/webview_go/libs/mswebview2"
29
- _ "github.com/webview/webview_go/libs/mswebview2/include"
30
- _ "github.com/webview/webview_go/libs/webview"
31
- _ "github.com/webview/webview_go/libs/webview/include"
32
- "encoding/json"
33
- "errors"
34
- "fmt"
35
- "reflect"
36
- "runtime"
37
- "sync"
38
- "sync/atomic"
39
- "unsafe"
40
- )
41
-
42
- func init() {
43
- // Ensure that main.main is called from the main thread
44
- runtime.LockOSThread()
45
- }
46
-
47
- // Hints are used to configure window sizing and resizing
48
- type Hint int
49
-
50
- // WindowAction 是原生窗口控制动作(前端自绘标题栏三按钮使用)。
51
- type WindowAction int
52
-
53
- const (
54
- // WindowMinimize 最小化窗口
55
- WindowMinimize WindowAction = iota
56
- // WindowMaximize 最大化窗口
57
- WindowMaximize
58
- // WindowUnmaximize 取消最大化
59
- WindowUnmaximize
60
- // WindowRestore 还原窗口(取消最大化并恢复到前台)
61
- WindowRestore
62
- // WindowClose 关闭窗口
63
- WindowClose
64
- // WindowToggleMaximize 在最大化/还原间切换
65
- WindowToggleMaximize
66
- // WindowIsMaximized 查询窗口是否最大化
67
- WindowIsMaximized
68
- )
69
-
70
- const (
71
- // Width and height are default size
72
- HintNone = C.WEBVIEW_HINT_NONE
73
-
74
- // Window size can not be changed by a user
75
- HintFixed = C.WEBVIEW_HINT_FIXED
76
-
77
- // Width and height are minimum bounds
78
- HintMin = C.WEBVIEW_HINT_MIN
79
-
80
- // Width and height are maximum bounds
81
- HintMax = C.WEBVIEW_HINT_MAX
82
- )
83
-
84
- type WebView interface {
85
-
86
- // Run runs the main loop until it's terminated. After this function exits -
87
- // you must destroy the webview.
88
- Run()
89
-
90
- // Terminate stops the main loop. It is safe to call this function from
91
- // a background thread.
92
- Terminate()
93
-
94
- // Dispatch posts a function to be executed on the main thread. You normally
95
- // do not need to call this function, unless you want to tweak the native
96
- // window.
97
- Dispatch(f func())
98
-
99
- // Destroy destroys a webview and closes the native window.
100
- Destroy()
101
-
102
- // Window returns a native window handle pointer. When using GTK backend the
103
- // pointer is GtkWindow pointer, when using Cocoa backend the pointer is
104
- // NSWindow pointer, when using Win32 backend the pointer is HWND pointer.
105
- Window() unsafe.Pointer
106
-
107
- // SetTitle updates the title of the native window. Must be called from the UI
108
- // thread.
109
- SetTitle(title string)
110
-
111
- // SetDecorated controls whether the native window shows its system title
112
- // bar decoration. frameless mode should call SetDecorated(false) so the
113
- // front-end can draw its own min/max/close buttons. Must be called from
114
- // the UI thread. On Windows this is a no-op (handled by the freedom shell
115
- // layer via WS_CAPTION / WM_NCHITTEST).
116
- SetDecorated(decorated bool)
117
-
118
- // WindowControl 执行原生窗口控制动作(最小化/最大化/还原/关闭/查询)。
119
- // 返回 0 表示成功,-1 表示平台不支持;WindowIsMaximized 返回 1/0。
120
- // 供前端自绘标题栏三按钮调用。Windows 上由 freedom 壳层处理,此处返回 -1。
121
- WindowControl(action WindowAction) int
122
-
123
- // BeginMoveDrag 发起无边框窗口的原生拖动(macOS/Linux)。
124
- // Windows 由 freedom 壳层用 WM_NCLBUTTONDOWN 处理,此处返回 -1。
125
- BeginMoveDrag() int
126
-
127
- // SetSize updates native window size. See Hint constants.
128
- SetSize(w int, h int, hint Hint)
129
-
130
- // Navigate navigates webview to the given URL. URL may be a properly encoded data.
131
- // URI. Examples:
132
- // w.Navigate("https://github.com/webview/webview")
133
- // w.Navigate("data:text/html,%3Ch1%3EHello%3C%2Fh1%3E")
134
- // w.Navigate("data:text/html;base64,PGgxPkhlbGxvPC9oMT4=")
135
- Navigate(url string)
136
-
137
- // SetHtml sets the webview HTML directly.
138
- // Example: w.SetHtml(w, "<h1>Hello</h1>");
139
- SetHtml(html string)
140
-
141
- // Init injects JavaScript code at the initialization of the new page. Every
142
- // time the webview will open a the new page - this initialization code will
143
- // be executed. It is guaranteed that code is executed before window.onload.
144
- Init(js string)
145
-
146
- // Eval evaluates arbitrary JavaScript code. Evaluation happens asynchronously,
147
- // also the result of the expression is ignored. Use RPC bindings if you want
148
- // to receive notifications about the results of the evaluation.
149
- Eval(js string)
150
-
151
- // Bind binds a callback function so that it will appear under the given name
152
- // as a global JavaScript function. Internally it uses webview_init().
153
- // Callback receives a request string and a user-provided argument pointer.
154
- // Request string is a JSON array of all the arguments passed to the
155
- // JavaScript function.
156
- //
157
- // f must be a function
158
- // f must return either value and error or just error
159
- Bind(name string, f interface{}) error
160
-
161
- // Removes a callback that was previously set by Bind.
162
- Unbind(name string) error
163
- }
164
-
165
- type webview struct {
166
- w C.webview_t
167
- }
168
-
169
- var (
170
- m sync.Mutex
171
- index uintptr
172
- dispatch = map[uintptr]func(){}
173
- bindings = map[uintptr]func(id, req string) (interface{}, error){}
174
- bindNames = map[string]uintptr{} // name -> index,供 Unbind 清理 bindings 条目
175
- // destroyed 标记 C 层 webview 对象已被销毁。Destroy() 置位后:
176
- // - Dispatch / Eval 直接跳过 C 调用,避免向已释放的 webview_t 发消息(悬垂指针崩溃);
177
- // - binding 回调跳过 C.webview_return,避免访问已释放的 C 内存。
178
- // 壳为单窗口单 webview,全局单例标记即可。
179
- destroyed atomic.Bool
180
- )
181
-
182
- func boolToInt(b bool) C.int {
183
- if b {
184
- return 1
185
- }
186
- return 0
187
- }
188
-
189
- // New calls NewWindow to create a new window and a new webview instance. If debug
190
- // is non-zero - developer tools will be enabled (if the platform supports them).
191
- func New(debug bool) WebView { return NewWindow(debug, nil) }
192
-
193
- // NewWindow creates a new webview instance. If debug is non-zero - developer
194
- // tools will be enabled (if the platform supports them). Window parameter can be
195
- // a pointer to the native window handle. If it's non-null - then child WebView is
196
- // embedded into the given parent window. Otherwise a new window is created.
197
- // Depending on the platform, a GtkWindow, NSWindow or HWND pointer can be passed
198
- // here.
199
- func NewWindow(debug bool, window unsafe.Pointer) WebView {
200
- w := &webview{}
201
- w.w = C.webview_create(boolToInt(debug), window)
202
- // B55:webview_create 在目标平台 WebView 初始化失败时可能返回 NULL
203
- //(如 Linux 缺 WebKitGTK、macOS WebKit 不可用),此时返回 nil 让调用方
204
- //(freedom.go Run 的 w == nil 分支)走失败提示,而非持 nil webview_t
205
- // 继续调用 SetTitle/SetSize/Init 等 C API 触发空指针崩溃。
206
- if w.w == nil {
207
- return nil
208
- }
209
- return w
210
- }
211
-
212
- func (w *webview) Destroy() {
213
- // 先置销毁标记:销毁后任何并发 Dispatch/Eval/binding 回调不得再触碰 C 内存。
214
- destroyed.Store(true)
215
- C.webview_destroy(w.w)
216
- }
217
-
218
- func (w *webview) Run() {
219
- if destroyed.Load() {
220
- return
221
- }
222
- C.webview_run(w.w)
223
- }
224
-
225
- func (w *webview) Terminate() {
226
- if destroyed.Load() {
227
- return
228
- }
229
- C.webview_terminate(w.w)
230
- }
231
-
232
- func (w *webview) Window() unsafe.Pointer {
233
- if destroyed.Load() {
234
- return nil
235
- }
236
- return C.webview_get_window(w.w)
237
- }
238
-
239
- func (w *webview) Navigate(url string) {
240
- if destroyed.Load() {
241
- return
242
- }
243
- s := C.CString(url)
244
- defer C.free(unsafe.Pointer(s))
245
- C.webview_navigate(w.w, s)
246
- }
247
-
248
- func (w *webview) SetHtml(html string) {
249
- if destroyed.Load() {
250
- return
251
- }
252
- s := C.CString(html)
253
- defer C.free(unsafe.Pointer(s))
254
- C.webview_set_html(w.w, s)
255
- }
256
-
257
- func (w *webview) SetTitle(title string) {
258
- if destroyed.Load() {
259
- return
260
- }
261
- s := C.CString(title)
262
- defer C.free(unsafe.Pointer(s))
263
- C.webview_set_title(w.w, s)
264
- }
265
-
266
- func (w *webview) SetDecorated(decorated bool) {
267
- if destroyed.Load() {
268
- return
269
- }
270
- C.webview_set_decorated(w.w, boolToInt(decorated))
271
- }
272
-
273
- func (w *webview) WindowControl(action WindowAction) int {
274
- if destroyed.Load() {
275
- return -1
276
- }
277
- return int(C.webview_window_control(w.w, C.webview_window_action_t(action)))
278
- }
279
-
280
- func (w *webview) BeginMoveDrag() int {
281
- if destroyed.Load() {
282
- return -1
283
- }
284
- return int(C.webview_window_begin_move_drag(w.w))
285
- }
286
-
287
- func (w *webview) SetSize(width int, height int, hint Hint) {
288
- if destroyed.Load() {
289
- return
290
- }
291
- C.webview_set_size(w.w, C.int(width), C.int(height), C.webview_hint_t(hint))
292
- }
293
-
294
- func (w *webview) Init(js string) {
295
- if destroyed.Load() {
296
- return
297
- }
298
- s := C.CString(js)
299
- defer C.free(unsafe.Pointer(s))
300
- C.webview_init(w.w, s)
301
- }
302
-
303
- func (w *webview) Eval(js string) {
304
- if destroyed.Load() {
305
- return
306
- }
307
- s := C.CString(js)
308
- defer C.free(unsafe.Pointer(s))
309
- C.webview_eval(w.w, s)
310
- }
311
-
312
- func (w *webview) Dispatch(f func()) {
313
- if destroyed.Load() {
314
- return
315
- }
316
- m.Lock()
317
- for ; dispatch[index] != nil; index++ {
318
- }
319
- dispatch[index] = f
320
- // 在锁内保存局部副本再解锁:解锁后读取共享 index 属数据竞争
321
- //(另一 goroutine 可能在 Lock 内推进 index),race detector 会报,
322
- // 且极端时序下可能把未就绪的 index 传给 C 层导致回调失配。
323
- idx := index
324
- m.Unlock()
325
- C.CgoWebViewDispatch(w.w, C.uintptr_t(idx))
326
- }
327
-
328
- //export _webviewDispatchGoCallback
329
- func _webviewDispatchGoCallback(index unsafe.Pointer) {
330
- // 兜底:回调内任何 panic 不得外泄到 C 层崩掉整个进程。
331
- defer func() { _ = recover() }()
332
- m.Lock()
333
- f := dispatch[uintptr(index)]
334
- delete(dispatch, uintptr(index))
335
- m.Unlock()
336
- if f != nil {
337
- // 入队时 destroyed 可能为 false,但回调真正执行时窗口可能已销毁,
338
- // 二次检查:销毁后 UI 线程即将退出,未执行的派发任务直接丢弃。
339
- if destroyed.Load() {
340
- return
341
- }
342
- f()
343
- }
344
- }
345
-
346
- //export _webviewBindingGoCallback
347
- func _webviewBindingGoCallback(w C.webview_t, id *C.char, req *C.char, index uintptr) {
348
- m.Lock()
349
- f := bindings[uintptr(index)]
350
- m.Unlock()
351
- jsString := func(v interface{}) string { b, _ := json.Marshal(v); return string(b) }
352
- status, result := 0, ""
353
- // 兜底:绑定回调内任何 panic 转为错误回传前端,绝不外泄到 C 层崩进程。
354
- func() {
355
- defer func() {
356
- if r := recover(); r != nil {
357
- status = -1
358
- result = jsString(fmt.Sprintf("freedom: binding panic: %v", r))
359
- }
360
- }()
361
- if res, err := f(C.GoString(id), C.GoString(req)); err != nil {
362
- status = -1
363
- result = jsString(err.Error())
364
- } else if b, err := json.Marshal(res); err != nil {
365
- status = -1
366
- result = jsString(err.Error())
367
- } else {
368
- status = 0
369
- result = string(b)
370
- }
371
- }()
372
- // 窗口已销毁:C 层 webview 对象已被 delete,不能再调用 webview_return,
373
- // 否则访问悬垂 webview_t 导致进程随机崩溃。
374
- if destroyed.Load() {
375
- return
376
- }
377
- s := C.CString(result)
378
- defer C.free(unsafe.Pointer(s))
379
- C.webview_return(w, id, C.int(status), s)
380
- }
381
-
382
- func (w *webview) Bind(name string, f interface{}) error {
383
- if destroyed.Load() {
384
- return errors.New("freedom: webview destroyed")
385
- }
386
- v := reflect.ValueOf(f)
387
- // f must be a function
388
- if v.Kind() != reflect.Func {
389
- return errors.New("only functions can be bound")
390
- }
391
- // f must return either value and error or just error
392
- if n := v.Type().NumOut(); n > 2 {
393
- return errors.New("function may only return a value or a value+error")
394
- }
395
-
396
- binding := func(id, req string) (interface{}, error) {
397
- raw := []json.RawMessage{}
398
- if err := json.Unmarshal([]byte(req), &raw); err != nil {
399
- return nil, err
400
- }
401
-
402
- isVariadic := v.Type().IsVariadic()
403
- numIn := v.Type().NumIn()
404
- if (isVariadic && len(raw) < numIn-1) || (!isVariadic && len(raw) != numIn) {
405
- return nil, errors.New("function arguments mismatch")
406
- }
407
- args := []reflect.Value{}
408
- for i := range raw {
409
- var arg reflect.Value
410
- if isVariadic && i >= numIn-1 {
411
- arg = reflect.New(v.Type().In(numIn - 1).Elem())
412
- } else {
413
- arg = reflect.New(v.Type().In(i))
414
- }
415
- if err := json.Unmarshal(raw[i], arg.Interface()); err != nil {
416
- return nil, err
417
- }
418
- args = append(args, arg.Elem())
419
- }
420
- errorType := reflect.TypeOf((*error)(nil)).Elem()
421
- res := v.Call(args)
422
- switch len(res) {
423
- case 0:
424
- // No results from the function, just return nil
425
- return nil, nil
426
- case 1:
427
- // One result may be a value, or an error
428
- if res[0].Type().Implements(errorType) {
429
- if res[0].Interface() != nil {
430
- return nil, res[0].Interface().(error)
431
- }
432
- return nil, nil
433
- }
434
- return res[0].Interface(), nil
435
- case 2:
436
- // Two results: first one is value, second is error
437
- if !res[1].Type().Implements(errorType) {
438
- return nil, errors.New("second return value must be an error")
439
- }
440
- if res[1].Interface() == nil {
441
- return res[0].Interface(), nil
442
- }
443
- return res[0].Interface(), res[1].Interface().(error)
444
- default:
445
- return nil, errors.New("unexpected number of return values")
446
- }
447
- }
448
-
449
- m.Lock()
450
- for ; bindings[index] != nil; index++ {
451
- }
452
- bindings[index] = binding
453
- bindNames[name] = index
454
- // 锁内保存副本,避免解锁后读取共享 index(与 Dispatch 同类数据竞争)
455
- idx := index
456
- m.Unlock()
457
- cname := C.CString(name)
458
- defer C.free(unsafe.Pointer(cname))
459
- C.CgoWebViewBind(w.w, cname, C.uintptr_t(idx))
460
- return nil
461
- }
462
-
463
- func (w *webview) Unbind(name string) error {
464
- if destroyed.Load() {
465
- return errors.New("freedom: webview destroyed")
466
- }
467
- // 清理 Go 侧 bindings / bindNames 条目,避免 Unbind 后永久泄漏。
468
- // C 侧 binding_context(glue.c calloc,每 Bind 约 16B)在 C++ unbind 中
469
- // 仅 erase map 不 free,会小幅泄漏;但框架内 Bind 次数固定(3~4 个)、
470
- // 进程生命周期内不会反复 Bind/Unbind,实际影响可忽略,故不额外改 C 层。
471
- m.Lock()
472
- if idx, ok := bindNames[name]; ok {
473
- delete(bindings, idx)
474
- delete(bindNames, name)
475
- }
476
- m.Unlock()
477
- cname := C.CString(name)
478
- defer C.free(unsafe.Pointer(cname))
479
- C.CgoWebViewUnbind(w.w, cname)
480
- return nil
481
- }
@@ -1,50 +0,0 @@
1
- package webview
2
-
3
- import (
4
- "flag"
5
- "log"
6
- "os"
7
- "testing"
8
- )
9
-
10
- func Example() {
11
- w := New(true)
12
- defer w.Destroy()
13
- w.SetTitle("Hello")
14
- w.Bind("noop", func() string {
15
- log.Println("hello")
16
- return "hello"
17
- })
18
- w.Bind("add", func(a, b int) int {
19
- return a + b
20
- })
21
- w.Bind("quit", func() {
22
- w.Terminate()
23
- })
24
- w.SetHtml(`<!doctype html>
25
- <html>
26
- <body>hello</body>
27
- <script>
28
- window.onload = function() {
29
- document.body.innerText = ` + "`hello, ${navigator.userAgent}`" + `;
30
- noop().then(function(res) {
31
- console.log('noop res', res);
32
- add(1, 2).then(function(res) {
33
- console.log('add res', res);
34
- quit();
35
- });
36
- });
37
- };
38
- </script>
39
- </html>
40
- )`)
41
- w.Run()
42
- }
43
-
44
- func TestMain(m *testing.M) {
45
- flag.Parse()
46
- if testing.Verbose() {
47
- Example()
48
- }
49
- os.Exit(m.Run())
50
- }