cj-tauri 2.0.0 → 2.1.0

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 (158) hide show
  1. package/README.md +113 -99
  2. package/bin/cj-tauri.js +287 -287
  3. package/cjpm.toml +63 -52
  4. package/cli/cjpm.toml +22 -22
  5. package/cli/src/doctor.cj +308 -306
  6. package/cli/src/main.cj +129 -129
  7. package/cli/src/manifest.cj +632 -558
  8. package/cli/src/manifest_test.cj +87 -0
  9. package/cli/src/project.cj +770 -770
  10. package/cli/src/resolve.cj +348 -348
  11. package/cli/src/scaffold.cj +369 -369
  12. package/cli/src/sync.cj +526 -526
  13. package/cli/src/util.cj +168 -168
  14. package/cli/templates/app/README.md +51 -48
  15. package/cli/templates/app/assets/capabilities/default.json +7 -7
  16. package/cli/templates/app/assets/ui/index.html +120 -118
  17. package/cli/templates/app/cj-tauri.toml +32 -22
  18. package/cli/templates/app/cjpm.toml +34 -34
  19. package/cli/templates/app/src/main.cj +101 -90
  20. package/cli/templates/app-react/README.md +56 -56
  21. package/cli/templates/app-react/assets/capabilities/default.json +7 -7
  22. package/cli/templates/app-react/assets/ui/index.html +25 -25
  23. package/cli/templates/app-react/assets/ui/package.json +19 -19
  24. package/cli/templates/app-react/assets/ui/src/App.css +67 -67
  25. package/cli/templates/app-react/assets/ui/src/App.jsx +124 -124
  26. package/cli/templates/app-react/assets/ui/src/main.jsx +6 -6
  27. package/cli/templates/app-react/assets/ui/vite.config.js +24 -24
  28. package/cli/templates/app-react/cj-tauri.toml +33 -23
  29. package/cli/templates/app-react/cjpm.toml +34 -34
  30. package/cli/templates/app-react/src/main.cj +91 -91
  31. package/cli/templates/app-vue/README.md +56 -56
  32. package/cli/templates/app-vue/assets/capabilities/default.json +7 -7
  33. package/cli/templates/app-vue/assets/ui/index.html +25 -25
  34. package/cli/templates/app-vue/assets/ui/package.json +18 -18
  35. package/cli/templates/app-vue/assets/ui/src/App.vue +176 -176
  36. package/cli/templates/app-vue/assets/ui/src/main.js +4 -4
  37. package/cli/templates/app-vue/assets/ui/vite.config.js +24 -24
  38. package/cli/templates/app-vue/cj-tauri.toml +33 -23
  39. package/cli/templates/app-vue/cjpm.toml +34 -34
  40. package/cli/templates/app-vue/src/main.cj +91 -91
  41. package/cli/templates/ohos-skeleton/AppScope/app.json5 +13 -13
  42. package/cli/templates/ohos-skeleton/AppScope/resources/base/element/string.json +8 -8
  43. package/cli/templates/ohos-skeleton/AppScope/resources/base/media/layered_image.json +6 -6
  44. package/cli/templates/ohos-skeleton/README.md +84 -79
  45. package/cli/templates/ohos-skeleton/build-hap.sh +15 -0
  46. package/cli/templates/ohos-skeleton/build-profile.json5 +46 -46
  47. package/cli/templates/ohos-skeleton/entry/build-profile.json5 +26 -26
  48. package/cli/templates/ohos-skeleton/entry/cjpm.toml +51 -43
  49. package/cli/templates/ohos-skeleton/entry/hvigorfile.ts +6 -6
  50. package/cli/templates/ohos-skeleton/entry/oh-package.json5 +9 -9
  51. package/cli/templates/ohos-skeleton/entry/src/main/cangjie/ability_stage.cj +17 -17
  52. package/cli/templates/ohos-skeleton/entry/src/main/cangjie/app_host.cj +94 -94
  53. package/cli/templates/ohos-skeleton/entry/src/main/cangjie/dialog_host.cj +217 -0
  54. package/cli/templates/ohos-skeleton/entry/src/main/cangjie/index.cj +527 -167
  55. package/cli/templates/ohos-skeleton/entry/src/main/cangjie/main_ability.cj +139 -139
  56. package/cli/templates/ohos-skeleton/entry/src/main/module.json5 +57 -49
  57. package/cli/templates/ohos-skeleton/entry/src/main/resources/base/element/color.json +8 -8
  58. package/cli/templates/ohos-skeleton/entry/src/main/resources/base/element/string.json +16 -16
  59. package/cli/templates/ohos-skeleton/entry/src/main/resources/base/media/layered_image.json +6 -6
  60. package/cli/templates/ohos-skeleton/entry/src/main/resources/base/profile/main_pages.json +2 -2
  61. package/cli/templates/ohos-skeleton/entry/src/main/resources/rawfile/capabilities.json +6 -6
  62. package/cli/templates/ohos-skeleton/entry/src/main/resources/rawfile/index.html +92 -92
  63. package/cli/templates/ohos-skeleton/hvigor/hvigor-config.json5 +5 -5
  64. package/cli/templates/ohos-skeleton/hvigorfile.ts +6 -6
  65. package/cli/templates/ohos-skeleton/oh-package.json5 +10 -10
  66. package/native/build_win.bat +62 -62
  67. package/native/core/bridge_core.c +1681 -1626
  68. package/native/core/bridge_core.h +675 -618
  69. package/native/core/bridge_js.h +108 -108
  70. package/native/platforms/harmonyos/README.md +115 -6
  71. package/native/platforms/linux/bridge_linux.c +2787 -2485
  72. package/native/platforms/windows/bridge_win.c +3740 -3248
  73. package/native/tests/gtk_threading_probe.c +143 -143
  74. package/native/tests/test_bridge_core.c +1339 -1228
  75. package/package.json +53 -53
  76. package/prebuilt/linux-x64/cj-tauri +0 -0
  77. package/src/api_system.cj +67 -67
  78. package/src/app.cj +325 -969
  79. package/src/app_events.cj +166 -0
  80. package/src/app_host_ops.cj +287 -0
  81. package/src/app_run.cj +283 -0
  82. package/src/app_spec.cj +76 -76
  83. package/src/arkweb_menu.cj +216 -0
  84. package/src/arkweb_script.cj +142 -142
  85. package/src/capability.cj +409 -409
  86. package/src/clipboard_bridge.cj +178 -0
  87. package/src/dialog_spec.cj +79 -0
  88. package/src/dragdrop.cj +26 -26
  89. package/src/embedded_assets.cj +98 -98
  90. package/src/host.cj +752 -607
  91. package/src/host_arkweb.cj +924 -778
  92. package/src/host_webkit.cj +663 -570
  93. package/src/host_webview2.cj +663 -570
  94. package/src/hotkey.cj +66 -66
  95. package/src/ipc_hub.cj +337 -337
  96. package/src/ipc_message.cj +286 -286
  97. package/src/launch.cj +62 -62
  98. package/src/logging.cj +127 -127
  99. package/src/menu.cj +197 -197
  100. package/src/platform/platform_app_context.cj +77 -77
  101. package/src/platform/platform_assets.cj +33 -33
  102. package/src/platform/platform_discover.cj +176 -176
  103. package/src/platform/platform_env.cj +29 -29
  104. package/src/platform/platform_feature.cj +31 -31
  105. package/src/platform/platform_page_source.cj +87 -87
  106. package/src/platform/platform_target_info.cj +32 -32
  107. package/src/platform_host_provider.cj +87 -87
  108. package/src/plugin.cj +333 -333
  109. package/src/plugins/clipboard/plugin_clipboard.cj +152 -152
  110. package/src/plugins/dialog/plugin_dialog.cj +209 -209
  111. package/src/plugins/fs/plugin_fs.cj +105 -1
  112. package/src/plugins/http/http_backend.cj +131 -0
  113. package/src/plugins/http/http_desktop.cj +195 -0
  114. package/src/plugins/http/http_ohos.cj +204 -0
  115. package/src/plugins/http/plugin_http.cj +310 -459
  116. package/src/plugins/log/plugin_log.cj +105 -105
  117. package/src/plugins/menu/plugin_menu.cj +158 -158
  118. package/src/plugins/notification/plugin_notification.cj +154 -154
  119. package/src/plugins/serial/plugin_serial.cj +458 -454
  120. package/src/plugins/serial/serial_bridge.cj +194 -194
  121. package/src/plugins/serial/serial_manager_ohos.cj +92 -0
  122. package/src/plugins/serial/serial_ohos.cj +529 -0
  123. package/src/plugins/shell/plugin_shell.cj +258 -258
  124. package/src/plugins/sqlite/plugin_sqlite.cj +705 -710
  125. package/src/plugins/sqlite/sqlite_ffi.cj +206 -211
  126. package/src/plugins/ws/plugin_ws.cj +488 -470
  127. package/src/process_hidden.cj +174 -174
  128. package/src/scope.cj +391 -391
  129. package/src/shell_event.cj +69 -69
  130. package/src/tests/app_spec_test.cj +126 -127
  131. package/src/tests/capability_test.cj +243 -243
  132. package/src/tests/dialog_spec_test.cj +73 -0
  133. package/src/tests/fake_host.cj +201 -201
  134. package/src/tests/ipc_hub_test.cj +487 -487
  135. package/src/tests/logging_test.cj +62 -62
  136. package/src/tests/platform_contract_test.cj +251 -251
  137. package/src/tests/plugin_clipboard_test.cj +222 -222
  138. package/src/tests/plugin_dialog_test.cj +237 -237
  139. package/src/tests/plugin_fs_test.cj +207 -0
  140. package/src/tests/plugin_http_test.cj +124 -124
  141. package/src/tests/plugin_notification_test.cj +205 -205
  142. package/src/tests/plugin_serial_test.cj +48 -0
  143. package/src/tests/plugin_test.cj +605 -585
  144. package/src/tests/plugin_ws_test.cj +40 -40
  145. package/src/tests/process_hidden_test.cj +129 -129
  146. package/src/tests/scope_test.cj +350 -350
  147. package/src/tests/system_host_test.cj +99 -81
  148. package/src/tests/urlutil_test.cj +53 -53
  149. package/src/tests/version_test.cj +75 -75
  150. package/src/tests/window_registry_test.cj +123 -123
  151. package/src/tray.cj +90 -90
  152. package/src/urlutil.cj +159 -159
  153. package/src/version.cj +44 -44
  154. package/src/window.cj +51 -51
  155. package/src/window_registry.cj +116 -116
  156. package/prebuilt/win32-x64/cj-tauri.exe +0 -0
  157. package/src/plugins/serial/serial_ohos_stub.cj +0 -61
  158. package/src/plugins/sqlite/sqlite_ohos_stub.cj +0 -91
@@ -1,201 +1,201 @@
1
- package cjTauri.tests
2
-
3
- import cjTauri.*
4
- import cjTauri.platform.*
5
- import std.collection.*
6
-
7
- /*
8
- * WebViewHost 的测试替身:记录被调用的痕迹,其余空实现。
9
- * 用途:不创建原生窗口就能测装配路径(TauriApp 装配、WindowRegistry、事件派发)。
10
- * 接口增删方法时这里必须跟着改——那是**有意的**:编译器会点名这一处,
11
- * 免得像 C 桥那样「改了一份忘了另一份」。
12
- */
13
- class FakeHost <: WebViewHost {
14
- // 字段不叫 label:接口有 label() 方法,同名会撞
15
- public let windowLabel: String
16
- public var started: Bool = false
17
- public var startedUrl: String = ""
18
- public var shownHtml: String = ""
19
- public var jsCalls: ArrayList<String> = ArrayList<String>()
20
- public var initScripts: ArrayList<String> = ArrayList<String>()
21
- public var config: WindowConfig = WindowConfig()
22
- public var handler: (String) -> Unit = { _ => }
23
- public var disposed: Bool = false
24
- public var quitCalled: Bool = false
25
- public var devToolsEnabled: Bool = false
26
- // 对话框入参按「调一次记一次」存成字符串:桩不真弹窗,用例要断言的是「谁被调了、带了什么」
27
- public var fileDialogArgs: String = ""
28
- public var messageDialogArgs: String = ""
29
- // 选目录与文件框分开记:用例要断言「走的是目录那条路」,不能与 fileDialogArgs 混为一谈
30
- public var folderDialogTitle: String = ""
31
- // 菜单:线路文本 / 单项状态按原样记下(桩不建真菜单,用例断言的是投下来的内容)
32
- public var menuWire: String = ""
33
- public var menuItemStateArgs: String = ""
34
- // 标题栏副标题:桩只记最后一次文本(用例断言的是「投下来的是什么」)
35
- public var titlebarSubtitleText: String = ""
36
- public var dragDropArgs: String = ""
37
- public var hotkeyWire: String = ""
38
- public var trayWire: String = ""
39
- public var windowVisibleValue: Bool = true
40
- public var minimizeToTrayValue: Bool = false
41
- // shell 事件回调(菜单点击等):用例可以自己调它,模拟「桥把事件送进来了」
42
- public var shellHandler: (String) -> Unit = { _ => }
43
- // 销毁回调:用例可以自己调它,模拟「桥通知本窗销毁了」
44
- public var destroyHandler: () -> Unit = { => }
45
- // 剪贴板 / 通知:写与通知按「调一次记一次」,读值可注入(默认空,用例按需设)
46
- public var clipboardWritten: String = ""
47
- public var clipboardReadValue: Option<String> = None<String>
48
- public var notifiedArgs: String = ""
49
- // 能力位:桩给「有菜单」,用例要测「平台没这个本事」时自行覆盖它
50
- public var caps: Int32 = CJ_CAP_MENU
51
- // load(source) 收敛(批次 3-PR3):记最近一次 load 的来源原文与 resolver 注入痕迹
52
- public var loadedSource: String = ""
53
- public var resolverInjected: Option<AssetResolver> = None
54
-
55
- public init(windowLabel: String) {
56
- this.windowLabel = windowLabel
57
- }
58
-
59
- public func label(): String {
60
- return this.windowLabel
61
- }
62
-
63
- public func setAssetResolver(resolver: Option<AssetResolver>): Unit {
64
- this.resolverInjected = resolver
65
- }
66
-
67
- /**
68
- * 桩的 load 不做资产解析(那是对应真宿主的事,resolvePage 本身有独立单测):
69
- * 只记痕——用例断言的是「装配层把哪种来源投给了宿主」
70
- */
71
- public func load(source: PageSource): Unit {
72
- this.started = true
73
- match (source) {
74
- case Inline(html) => this.shownHtml = html
75
- case Url(url) => this.startedUrl = url
76
- case DevServer(url) => this.startedUrl = url
77
- case Asset(name) => this.loadedSource = "asset:${name}"
78
- }
79
- }
80
-
81
- public func addInitScript(js: String): Unit {
82
- this.initScripts.add(js)
83
- }
84
-
85
- public func reload(): Unit {}
86
-
87
- public func setWindowConfig(config: WindowConfig): Unit {
88
- this.config = config
89
- }
90
-
91
- public func setDevTools(enabled: Bool): Unit {
92
- this.devToolsEnabled = enabled
93
- }
94
-
95
- public func openDevTools(): Unit {}
96
-
97
- public func setMenu(wire: String): Unit {
98
- this.menuWire = wire
99
- }
100
-
101
- public func setMenuItemState(id: String, enabled: Bool, checked: Bool): Unit {
102
- this.menuItemStateArgs = "${id}|${enabled}|${checked}"
103
- }
104
-
105
- public func setTitlebarSubtitle(text: String): Unit {
106
- this.titlebarSubtitleText = text
107
- }
108
-
109
- public func setDragDropPolicy(enabled: Bool, files: Bool): Unit {
110
- this.dragDropArgs = "${enabled}|${files}"
111
- }
112
-
113
- public func setGlobalHotkeys(wire: String): Unit {
114
- this.hotkeyWire = wire
115
- }
116
-
117
- public func setTray(wire: String): Unit {
118
- this.trayWire = wire
119
- }
120
-
121
- // 窗口可见性 / 最小化策略:桩只记最后一次设置(用例断言的是「谁被调了、带了什么」)
122
- public func setWindowVisible(visible: Bool): Unit {
123
- this.windowVisibleValue = visible
124
- }
125
-
126
- public func setMinimizeToTray(enabled: Bool): Unit {
127
- this.minimizeToTrayValue = enabled
128
- }
129
-
130
- public func hostCapabilities(): Int32 {
131
- return this.caps
132
- }
133
-
134
- public func setShellHandler(handler: (String) -> Unit): Unit {
135
- this.shellHandler = handler
136
- }
137
-
138
- public func setDestroyHandler(handler: () -> Unit): Unit {
139
- this.destroyHandler = handler
140
- }
141
-
142
- public func showFileDialog(save: Bool, title: String, filter: String): String {
143
- this.fileDialogArgs = "${save}|${title}|${filter}"
144
- return ""
145
- }
146
-
147
- public func showFileDialogPreset(save: Bool, title: String, filter: String,
148
- defaultName: String): String {
149
- // 记痕带预置名:多窗取证靠它断言「本窗拿到的是本窗预置的名字」
150
- this.fileDialogArgs = "${save}|${title}|${filter}|${defaultName}"
151
- return ""
152
- }
153
-
154
- public func showFolderDialog(title: String): String {
155
- // 桩不真弹窗:记下标题即可(用例断言的是「谁被调了、带了什么」)
156
- this.folderDialogTitle = title
157
- return ""
158
- }
159
-
160
- public func showMessageDialog(kind: String, title: String, message: String): Bool {
161
- this.messageDialogArgs = "${kind}|${title}|${message}"
162
- return false
163
- }
164
-
165
- public func clipboardWriteText(text: String): Bool {
166
- this.clipboardWritten = text
167
- return true
168
- }
169
-
170
- public func clipboardReadText(): Option<String> {
171
- return this.clipboardReadValue
172
- }
173
-
174
- public func notify(title: String, body: String): Bool {
175
- this.notifiedArgs = "${title}|${body}"
176
- return true
177
- }
178
-
179
- public func runJs(js: String): Unit {
180
- this.jsCalls.add(js)
181
- }
182
-
183
- public func quit(): Unit {
184
- this.quitCalled = true
185
- }
186
-
187
- public func setMessageHandler(handler: (String) -> Unit): Unit {
188
- this.handler = handler
189
- }
190
-
191
- // run 收尾开关:run() 阻塞在 waitForExit,用例把它置 true 让 run 返回(批次 3-PR3 的 load 接线用例用)
192
- public var quitNow: Bool = false
193
-
194
- public func shouldQuit(): Bool {
195
- return this.quitNow
196
- }
197
-
198
- public func dispose(): Unit {
199
- this.disposed = true
200
- }
201
- }
1
+ package cjTauri.tests
2
+
3
+ import cjTauri.*
4
+ import cjTauri.platform.*
5
+ import std.collection.*
6
+
7
+ /*
8
+ * WebViewHost 的测试替身:记录被调用的痕迹,其余空实现。
9
+ * 用途:不创建原生窗口就能测装配路径(TauriApp 装配、WindowRegistry、事件派发)。
10
+ * 接口增删方法时这里必须跟着改——那是**有意的**:编译器会点名这一处,
11
+ * 免得像 C 桥那样「改了一份忘了另一份」。
12
+ */
13
+ class FakeHost <: WebViewHost {
14
+ // 字段不叫 label:接口有 label() 方法,同名会撞
15
+ public let windowLabel: String
16
+ public var started: Bool = false
17
+ public var startedUrl: String = ""
18
+ public var shownHtml: String = ""
19
+ public var jsCalls: ArrayList<String> = ArrayList<String>()
20
+ public var initScripts: ArrayList<String> = ArrayList<String>()
21
+ public var config: WindowConfig = WindowConfig()
22
+ public var handler: (String) -> Unit = { _ => }
23
+ public var disposed: Bool = false
24
+ public var quitCalled: Bool = false
25
+ public var devToolsEnabled: Bool = false
26
+ // 对话框入参按「调一次记一次」存成字符串:桩不真弹窗,用例要断言的是「谁被调了、带了什么」
27
+ public var fileDialogArgs: String = ""
28
+ public var messageDialogArgs: String = ""
29
+ // 选目录与文件框分开记:用例要断言「走的是目录那条路」,不能与 fileDialogArgs 混为一谈
30
+ public var folderDialogTitle: String = ""
31
+ // 菜单:线路文本 / 单项状态按原样记下(桩不建真菜单,用例断言的是投下来的内容)
32
+ public var menuWire: String = ""
33
+ public var menuItemStateArgs: String = ""
34
+ // 标题栏副标题:桩只记最后一次文本(用例断言的是「投下来的是什么」)
35
+ public var titlebarSubtitleText: String = ""
36
+ public var dragDropArgs: String = ""
37
+ public var hotkeyWire: String = ""
38
+ public var trayWire: String = ""
39
+ public var windowVisibleValue: Bool = true
40
+ public var minimizeToTrayValue: Bool = false
41
+ // shell 事件回调(菜单点击等):用例可以自己调它,模拟「桥把事件送进来了」
42
+ public var shellHandler: (String) -> Unit = { _ => }
43
+ // 销毁回调:用例可以自己调它,模拟「桥通知本窗销毁了」
44
+ public var destroyHandler: () -> Unit = { => }
45
+ // 剪贴板 / 通知:写与通知按「调一次记一次」,读值可注入(默认空,用例按需设)
46
+ public var clipboardWritten: String = ""
47
+ public var clipboardReadValue: Option<String> = None<String>
48
+ public var notifiedArgs: String = ""
49
+ // 能力位:桩给「有菜单」,用例要测「平台没这个本事」时自行覆盖它
50
+ public var caps: Int32 = CJ_CAP_MENU
51
+ // load(source) 收敛(批次 3-PR3):记最近一次 load 的来源原文与 resolver 注入痕迹
52
+ public var loadedSource: String = ""
53
+ public var resolverInjected: Option<AssetResolver> = None
54
+
55
+ public init(windowLabel: String) {
56
+ this.windowLabel = windowLabel
57
+ }
58
+
59
+ public func label(): String {
60
+ return this.windowLabel
61
+ }
62
+
63
+ public func setAssetResolver(resolver: Option<AssetResolver>): Unit {
64
+ this.resolverInjected = resolver
65
+ }
66
+
67
+ /**
68
+ * 桩的 load 不做资产解析(那是对应真宿主的事,resolvePage 本身有独立单测):
69
+ * 只记痕——用例断言的是「装配层把哪种来源投给了宿主」
70
+ */
71
+ public func load(source: PageSource): Unit {
72
+ this.started = true
73
+ match (source) {
74
+ case Inline(html) => this.shownHtml = html
75
+ case Url(url) => this.startedUrl = url
76
+ case DevServer(url) => this.startedUrl = url
77
+ case Asset(name) => this.loadedSource = "asset:${name}"
78
+ }
79
+ }
80
+
81
+ public func addInitScript(js: String): Unit {
82
+ this.initScripts.add(js)
83
+ }
84
+
85
+ public func reload(): Unit {}
86
+
87
+ public func setWindowConfig(config: WindowConfig): Unit {
88
+ this.config = config
89
+ }
90
+
91
+ public func setDevTools(enabled: Bool): Unit {
92
+ this.devToolsEnabled = enabled
93
+ }
94
+
95
+ public func openDevTools(): Unit {}
96
+
97
+ public func setMenu(wire: String): Unit {
98
+ this.menuWire = wire
99
+ }
100
+
101
+ public func setMenuItemState(id: String, enabled: Bool, checked: Bool): Unit {
102
+ this.menuItemStateArgs = "${id}|${enabled}|${checked}"
103
+ }
104
+
105
+ public func setTitlebarSubtitle(text: String): Unit {
106
+ this.titlebarSubtitleText = text
107
+ }
108
+
109
+ public func setDragDropPolicy(enabled: Bool, files: Bool): Unit {
110
+ this.dragDropArgs = "${enabled}|${files}"
111
+ }
112
+
113
+ public func setGlobalHotkeys(wire: String): Unit {
114
+ this.hotkeyWire = wire
115
+ }
116
+
117
+ public func setTray(wire: String): Unit {
118
+ this.trayWire = wire
119
+ }
120
+
121
+ // 窗口可见性 / 最小化策略:桩只记最后一次设置(用例断言的是「谁被调了、带了什么」)
122
+ public func setWindowVisible(visible: Bool): Unit {
123
+ this.windowVisibleValue = visible
124
+ }
125
+
126
+ public func setMinimizeToTray(enabled: Bool): Unit {
127
+ this.minimizeToTrayValue = enabled
128
+ }
129
+
130
+ public func hostCapabilities(): Int32 {
131
+ return this.caps
132
+ }
133
+
134
+ public func setShellHandler(handler: (String) -> Unit): Unit {
135
+ this.shellHandler = handler
136
+ }
137
+
138
+ public func setDestroyHandler(handler: () -> Unit): Unit {
139
+ this.destroyHandler = handler
140
+ }
141
+
142
+ public func showFileDialog(save: Bool, title: String, filter: String): String {
143
+ this.fileDialogArgs = "${save}|${title}|${filter}"
144
+ return ""
145
+ }
146
+
147
+ public func showFileDialogPreset(save: Bool, title: String, filter: String,
148
+ defaultName: String): String {
149
+ // 记痕带预置名:多窗取证靠它断言「本窗拿到的是本窗预置的名字」
150
+ this.fileDialogArgs = "${save}|${title}|${filter}|${defaultName}"
151
+ return ""
152
+ }
153
+
154
+ public func showFolderDialog(title: String): String {
155
+ // 桩不真弹窗:记下标题即可(用例断言的是「谁被调了、带了什么」)
156
+ this.folderDialogTitle = title
157
+ return ""
158
+ }
159
+
160
+ public func showMessageDialog(kind: String, title: String, message: String): Bool {
161
+ this.messageDialogArgs = "${kind}|${title}|${message}"
162
+ return false
163
+ }
164
+
165
+ public func clipboardWriteText(text: String): Bool {
166
+ this.clipboardWritten = text
167
+ return true
168
+ }
169
+
170
+ public func clipboardReadText(): Option<String> {
171
+ return this.clipboardReadValue
172
+ }
173
+
174
+ public func notify(title: String, body: String): Bool {
175
+ this.notifiedArgs = "${title}|${body}"
176
+ return true
177
+ }
178
+
179
+ public func runJs(js: String): Unit {
180
+ this.jsCalls.add(js)
181
+ }
182
+
183
+ public func quit(): Unit {
184
+ this.quitCalled = true
185
+ }
186
+
187
+ public func setMessageHandler(handler: (String) -> Unit): Unit {
188
+ this.handler = handler
189
+ }
190
+
191
+ // run 收尾开关:run() 阻塞在 waitForExit,用例把它置 true 让 run 返回(批次 3-PR3 的 load 接线用例用)
192
+ public var quitNow: Bool = false
193
+
194
+ public func shouldQuit(): Bool {
195
+ return this.quitNow
196
+ }
197
+
198
+ public func dispose(): Unit {
199
+ this.disposed = true
200
+ }
201
+ }