translime-sdk 1.0.1 → 1.0.2

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.
@@ -1,244 +1,285 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const STORAGE_PREFIX = "translime-preview-settings:";
2
+ //#region src/preview-mock.js
3
+ /**
4
+ * Preview Mock 模块
5
+ * 为 preview 模式提供 Electron API 的 mock 实现
6
+ */
7
+ var STORAGE_PREFIX = "translime-preview-settings:";
8
+ /**
9
+ * Mock IPC 实现
10
+ * @returns {Object}
11
+ */
4
12
  function createMockIpc() {
5
- return {
6
- invoke: async (channel, ...args) => {
7
- console.log("[Preview Mock] ipc.invoke:", channel, args);
8
- return null;
9
- },
10
- send: (channel, ...args) => {
11
- console.log("[Preview Mock] ipc.send:", channel, args);
12
- },
13
- on: (channel, callback) => {
14
- console.log("[Preview Mock] ipc.on registered:", channel);
15
- return () => {
16
- console.log("[Preview Mock] ipc.on removed:", channel);
17
- };
18
- },
19
- once: (channel, callback) => {
20
- console.log("[Preview Mock] ipc.once registered:", channel);
21
- },
22
- removeListener: (channel, callback) => {
23
- console.log("[Preview Mock] ipc.removeListener:", channel);
24
- },
25
- removeAllListeners: (channel) => {
26
- console.log("[Preview Mock] ipc.removeAllListeners:", channel);
27
- }
28
- };
13
+ return {
14
+ invoke: async (channel, ...args) => {
15
+ console.log("[Preview Mock] ipc.invoke:", channel, args);
16
+ return null;
17
+ },
18
+ send: (channel, ...args) => {
19
+ console.log("[Preview Mock] ipc.send:", channel, args);
20
+ },
21
+ on: (channel, callback) => {
22
+ console.log("[Preview Mock] ipc.on registered:", channel, Boolean(callback));
23
+ return () => {
24
+ console.log("[Preview Mock] ipc.on removed:", channel);
25
+ };
26
+ },
27
+ once: (channel, callback) => {
28
+ console.log("[Preview Mock] ipc.once registered:", channel, Boolean(callback));
29
+ },
30
+ removeListener: (channel, callback) => {
31
+ console.log("[Preview Mock] ipc.removeListener:", channel, Boolean(callback));
32
+ },
33
+ removeAllListeners: (channel) => {
34
+ console.log("[Preview Mock] ipc.removeAllListeners:", channel);
35
+ }
36
+ };
29
37
  }
38
+ /**
39
+ * Mock Dialog 实现
40
+ * @returns {Object}
41
+ */
30
42
  function createMockDialog() {
31
- return {
32
- showOpenDialog: async (options) => {
33
- console.log("[Preview Mock] showOpenDialog:", options);
34
- return new Promise((resolve) => {
35
- const input = document.createElement("input");
36
- input.type = "file";
37
- if (options?.properties?.includes("openDirectory")) {
38
- input.webkitdirectory = true;
39
- }
40
- if (options?.properties?.includes("multiSelections")) {
41
- input.multiple = true;
42
- }
43
- if (options?.filters) {
44
- const accept = options.filters.flatMap((f) => f.extensions.map((ext) => `.${ext}`)).join(",");
45
- input.accept = accept;
46
- }
47
- input.onchange = () => {
48
- const filePaths = Array.from(input.files || []).map((f) => f.name);
49
- resolve({ canceled: filePaths.length === 0, filePaths });
50
- };
51
- input.oncancel = () => {
52
- resolve({ canceled: true, filePaths: [] });
53
- };
54
- input.click();
55
- });
56
- },
57
- showSaveDialog: async (options) => {
58
- console.log("[Preview Mock] showSaveDialog:", options);
59
- const fileName = prompt("保存文件名:", options?.defaultPath || "file.txt");
60
- return {
61
- canceled: !fileName,
62
- filePath: fileName || void 0
63
- };
64
- },
65
- showMessageBox: async (options) => {
66
- console.log("[Preview Mock] showMessageBox:", options);
67
- const result = confirm(options?.message || "");
68
- return { response: result ? 0 : 1 };
69
- },
70
- showErrorBox: (title, content) => {
71
- console.error("[Preview Mock] showErrorBox:", title, content);
72
- alert(`${title}
73
-
74
- ${content}`);
75
- }
76
- };
43
+ return {
44
+ showOpenDialog: async (options) => {
45
+ console.log("[Preview Mock] showOpenDialog:", options);
46
+ return new Promise((resolve) => {
47
+ const input = document.createElement("input");
48
+ input.type = "file";
49
+ if (options?.properties?.includes("openDirectory")) input.webkitdirectory = true;
50
+ if (options?.properties?.includes("multiSelections")) input.multiple = true;
51
+ if (options?.filters) input.accept = options.filters.flatMap((f) => f.extensions.map((ext) => `.${ext}`)).join(",");
52
+ input.onchange = () => {
53
+ const filePaths = Array.from(input.files || []).map((f) => f.name);
54
+ resolve({
55
+ canceled: filePaths.length === 0,
56
+ filePaths
57
+ });
58
+ };
59
+ input.oncancel = () => {
60
+ resolve({
61
+ canceled: true,
62
+ filePaths: []
63
+ });
64
+ };
65
+ input.click();
66
+ });
67
+ },
68
+ showSaveDialog: async (options) => {
69
+ console.log("[Preview Mock] showSaveDialog:", options);
70
+ const fileName = prompt("保存文件名:", options?.defaultPath || "file.txt");
71
+ return {
72
+ canceled: !fileName,
73
+ filePath: fileName || void 0
74
+ };
75
+ },
76
+ showMessageBox: async (options) => {
77
+ console.log("[Preview Mock] showMessageBox:", options);
78
+ return { response: window.confirm(options?.message || "") ? 0 : 1 };
79
+ },
80
+ showErrorBox: (title, content) => {
81
+ console.error("[Preview Mock] showErrorBox:", title, content);
82
+ alert(`${title}\n\n${content}`);
83
+ }
84
+ };
77
85
  }
86
+ /**
87
+ * Mock Shell 实现
88
+ * @returns {Object}
89
+ */
78
90
  function createMockShell() {
79
- return {
80
- openExternal: async (url) => {
81
- console.log("[Preview Mock] shell.openExternal:", url);
82
- window.open(url, "_blank");
83
- },
84
- openPath: async (path) => {
85
- console.log("[Preview Mock] shell.openPath:", path);
86
- alert(`[Preview] 无法在浏览器中打开路径: ${path}`);
87
- },
88
- showItemInFolder: (path) => {
89
- console.log("[Preview Mock] shell.showItemInFolder:", path);
90
- alert(`[Preview] 无法在浏览器中显示文件夹: ${path}`);
91
- }
92
- };
91
+ return {
92
+ openExternal: async (url) => {
93
+ console.log("[Preview Mock] shell.openExternal:", url);
94
+ window.open(url, "_blank");
95
+ },
96
+ openPath: async (path) => {
97
+ console.log("[Preview Mock] shell.openPath:", path);
98
+ alert(`[Preview] 无法在浏览器中打开路径: ${path}`);
99
+ },
100
+ showItemInFolder: (path) => {
101
+ console.log("[Preview Mock] shell.showItemInFolder:", path);
102
+ alert(`[Preview] 无法在浏览器中显示文件夹: ${path}`);
103
+ }
104
+ };
93
105
  }
106
+ /**
107
+ * Mock Clipboard 实现
108
+ * @returns {Object}
109
+ */
94
110
  function createMockClipboard() {
95
- return {
96
- readText: async () => {
97
- try {
98
- return await navigator.clipboard.readText();
99
- } catch (e) {
100
- console.warn("[Preview Mock] clipboard.readText failed:", e);
101
- return "";
102
- }
103
- },
104
- writeText: async (text) => {
105
- try {
106
- await navigator.clipboard.writeText(text);
107
- console.log("[Preview Mock] clipboard.writeText:", text);
108
- } catch (e) {
109
- console.warn("[Preview Mock] clipboard.writeText failed:", e);
110
- }
111
- },
112
- readImage: async () => {
113
- console.log("[Preview Mock] clipboard.readImage: not supported in preview");
114
- return null;
115
- },
116
- writeImage: async () => {
117
- console.log("[Preview Mock] clipboard.writeImage: not supported in preview");
118
- }
119
- };
111
+ return {
112
+ readText: async () => {
113
+ try {
114
+ return await navigator.clipboard.readText();
115
+ } catch (e) {
116
+ console.warn("[Preview Mock] clipboard.readText failed:", e);
117
+ return "";
118
+ }
119
+ },
120
+ writeText: async (text) => {
121
+ try {
122
+ await navigator.clipboard.writeText(text);
123
+ console.log("[Preview Mock] clipboard.writeText:", text);
124
+ } catch (e) {
125
+ console.warn("[Preview Mock] clipboard.writeText failed:", e);
126
+ }
127
+ },
128
+ readImage: async () => {
129
+ console.log("[Preview Mock] clipboard.readImage: not supported in preview");
130
+ return null;
131
+ },
132
+ writeImage: async () => {
133
+ console.log("[Preview Mock] clipboard.writeImage: not supported in preview");
134
+ }
135
+ };
120
136
  }
137
+ /**
138
+ * Mock Window Control 实现
139
+ * @returns {Object}
140
+ */
121
141
  function createMockWindowControl() {
122
- return {
123
- close: (windowId) => {
124
- console.log("[Preview Mock] windowControl.close:", windowId);
125
- },
126
- minimize: (windowId) => {
127
- console.log("[Preview Mock] windowControl.minimize:", windowId);
128
- },
129
- maximize: (windowId) => {
130
- console.log("[Preview Mock] windowControl.maximize:", windowId);
131
- },
132
- unmaximize: (windowId) => {
133
- console.log("[Preview Mock] windowControl.unmaximize:", windowId);
134
- },
135
- devtools: (windowId) => {
136
- console.log("[Preview Mock] windowControl.devtools:", windowId);
137
- },
138
- isMaximized: async (windowId) => {
139
- console.log("[Preview Mock] windowControl.isMaximized:", windowId);
140
- return false;
141
- }
142
- };
142
+ return {
143
+ close: (windowId) => {
144
+ console.log("[Preview Mock] windowControl.close:", windowId);
145
+ },
146
+ minimize: (windowId) => {
147
+ console.log("[Preview Mock] windowControl.minimize:", windowId);
148
+ },
149
+ maximize: (windowId) => {
150
+ console.log("[Preview Mock] windowControl.maximize:", windowId);
151
+ },
152
+ unmaximize: (windowId) => {
153
+ console.log("[Preview Mock] windowControl.unmaximize:", windowId);
154
+ },
155
+ devtools: (windowId) => {
156
+ console.log("[Preview Mock] windowControl.devtools:", windowId);
157
+ },
158
+ isMaximized: async (windowId) => {
159
+ console.log("[Preview Mock] windowControl.isMaximized:", windowId);
160
+ return false;
161
+ }
162
+ };
143
163
  }
164
+ /**
165
+ * Mock Plugin Settings 实现(使用 localStorage 持久化)
166
+ * @returns {Object}
167
+ */
144
168
  function createMockPluginSettings() {
145
- return {
146
- get: async (pluginId) => {
147
- const key = `${STORAGE_PREFIX}${pluginId}`;
148
- try {
149
- const data = localStorage.getItem(key);
150
- return data ? JSON.parse(data) : {};
151
- } catch (e) {
152
- console.warn("[Preview Mock] getPluginSetting parse error:", e);
153
- return {};
154
- }
155
- },
156
- set: async (pluginId, settings) => {
157
- const key = `${STORAGE_PREFIX}${pluginId}`;
158
- try {
159
- localStorage.setItem(key, JSON.stringify(settings));
160
- console.log("[Preview Mock] setPluginSetting:", pluginId, settings);
161
- } catch (e) {
162
- console.warn("[Preview Mock] setPluginSetting error:", e);
163
- }
164
- }
165
- };
169
+ return {
170
+ get: async (pluginId) => {
171
+ const key = `${STORAGE_PREFIX}${pluginId}`;
172
+ try {
173
+ const data = localStorage.getItem(key);
174
+ return data ? JSON.parse(data) : {};
175
+ } catch (e) {
176
+ console.warn("[Preview Mock] getPluginSetting parse error:", e);
177
+ return {};
178
+ }
179
+ },
180
+ set: async (pluginId, settings) => {
181
+ const key = `${STORAGE_PREFIX}${pluginId}`;
182
+ try {
183
+ localStorage.setItem(key, JSON.stringify(settings));
184
+ console.log("[Preview Mock] setPluginSetting:", pluginId, settings);
185
+ } catch (e) {
186
+ console.warn("[Preview Mock] setPluginSetting error:", e);
187
+ }
188
+ }
189
+ };
166
190
  }
191
+ /**
192
+ * Mock Logger 实现
193
+ * @returns {Object}
194
+ */
167
195
  function createMockLogger() {
168
- return {
169
- log: (...args) => console.log("[Preview]", ...args),
170
- info: (...args) => console.info("[Preview]", ...args),
171
- warn: (...args) => console.warn("[Preview]", ...args),
172
- error: (...args) => console.error("[Preview]", ...args),
173
- debug: (...args) => console.debug("[Preview]", ...args)
174
- };
196
+ return {
197
+ log: (...args) => console.log("[Preview]", ...args),
198
+ info: (...args) => console.info("[Preview]", ...args),
199
+ warn: (...args) => console.warn("[Preview]", ...args),
200
+ error: (...args) => console.error("[Preview]", ...args),
201
+ debug: (...args) => console.debug("[Preview]", ...args)
202
+ };
175
203
  }
204
+ /**
205
+ * 创建完整的 mock electron 对象
206
+ * @returns {Object}
207
+ */
176
208
  function createMockElectron() {
177
- const mockIpc = createMockIpc();
178
- return {
179
- useIpc: () => mockIpc,
180
- dialog: createMockDialog(),
181
- shell: createMockShell(),
182
- clipboard: createMockClipboard(),
183
- openLink: async (url) => {
184
- console.log("[Preview Mock] openLink:", url);
185
- window.open(url, "_blank");
186
- },
187
- versions: {
188
- node: "preview",
189
- chrome: navigator.userAgent.match(/Chrome\/([0-9.]+)/)?.[1] || "unknown",
190
- electron: "preview"
191
- },
192
- APP_ROOT: "/preview",
193
- APPDATA_PATH: "/preview/appdata"
194
- };
209
+ const mockIpc = createMockIpc();
210
+ return {
211
+ useIpc: () => mockIpc,
212
+ dialog: createMockDialog(),
213
+ shell: createMockShell(),
214
+ clipboard: createMockClipboard(),
215
+ openLink: async (url) => {
216
+ console.log("[Preview Mock] openLink:", url);
217
+ window.open(url, "_blank");
218
+ },
219
+ versions: {
220
+ node: "preview",
221
+ chrome: navigator.userAgent.match(/Chrome\/([0-9.]+)/)?.[1] || "unknown",
222
+ electron: "preview"
223
+ },
224
+ APP_ROOT: "/preview",
225
+ APPDATA_PATH: "/preview/appdata"
226
+ };
195
227
  }
228
+ /**
229
+ * 创建完整的 mock ts 对象
230
+ * @returns {Object}
231
+ */
196
232
  function createMockTs() {
197
- const pluginSettings = createMockPluginSettings();
198
- return {
199
- getPluginSetting: pluginSettings.get,
200
- setPluginSetting: pluginSettings.set,
201
- windowControl: createMockWindowControl(),
202
- logger: createMockLogger(),
203
- net: {
204
- request: async (url, options) => {
205
- console.log("[Preview Mock] net.request:", url, options);
206
- try {
207
- const response = await fetch(url, options);
208
- return {
209
- ok: response.ok,
210
- status: response.status,
211
- data: await response.text()
212
- };
213
- } catch (e) {
214
- return { ok: false, status: 0, error: e.message };
215
- }
216
- }
217
- }
218
- };
233
+ const pluginSettings = createMockPluginSettings();
234
+ return {
235
+ getPluginSetting: pluginSettings.get,
236
+ setPluginSetting: pluginSettings.set,
237
+ windowControl: createMockWindowControl(),
238
+ logger: createMockLogger(),
239
+ net: { request: async (url, options) => {
240
+ console.log("[Preview Mock] net.request:", url, options);
241
+ try {
242
+ const response = await fetch(url, options);
243
+ return {
244
+ ok: response.ok,
245
+ status: response.status,
246
+ data: await response.text()
247
+ };
248
+ } catch (e) {
249
+ return {
250
+ ok: false,
251
+ status: 0,
252
+ error: e.message
253
+ };
254
+ }
255
+ } }
256
+ };
219
257
  }
258
+ /**
259
+ * 初始化 preview mock 环境
260
+ * 将 mock 对象注入到 window
261
+ */
220
262
  function initPreviewMock() {
221
- if (typeof window === "undefined") {
222
- return;
223
- }
224
- if (!window.electron) {
225
- window.electron = createMockElectron();
226
- console.log("[Preview Mock] window.electron injected");
227
- }
228
- if (!window.ts) {
229
- window.ts = createMockTs();
230
- console.log("[Preview Mock] window.ts injected");
231
- }
263
+ if (typeof window === "undefined") return;
264
+ if (!window.electron) {
265
+ window.electron = createMockElectron();
266
+ console.log("[Preview Mock] window.electron injected");
267
+ }
268
+ if (!window.ts) {
269
+ window.ts = createMockTs();
270
+ console.log("[Preview Mock] window.ts injected");
271
+ }
232
272
  }
273
+ /**
274
+ * 检查当前是否为 preview 模式
275
+ * @returns {boolean}
276
+ */
233
277
  function isPreviewMode() {
234
- if (typeof __TRANSLIME_PREVIEW__ !== "undefined" && __TRANSLIME_PREVIEW__) {
235
- return true;
236
- }
237
- if (typeof window !== "undefined" && !window.electron && !window.ts) {
238
- return true;
239
- }
240
- return false;
278
+ if (typeof __TRANSLIME_PREVIEW__ !== "undefined" && __TRANSLIME_PREVIEW__) return true;
279
+ if (typeof window !== "undefined" && !window.electron && !window.ts) return true;
280
+ return false;
241
281
  }
282
+ //#endregion
242
283
  exports.createMockClipboard = createMockClipboard;
243
284
  exports.createMockDialog = createMockDialog;
244
285
  exports.createMockElectron = createMockElectron;
@@ -250,4 +291,5 @@ exports.createMockTs = createMockTs;
250
291
  exports.createMockWindowControl = createMockWindowControl;
251
292
  exports.initPreviewMock = initPreviewMock;
252
293
  exports.isPreviewMode = isPreviewMode;
253
- //# sourceMappingURL=preview-mock.cjs.map
294
+
295
+ //# sourceMappingURL=preview-mock.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"preview-mock.cjs","sources":["../src/preview-mock.js"],"sourcesContent":["/**\n * Preview Mock 模块\n * 为 preview 模式提供 Electron API 的 mock 实现\n */\n\nconst STORAGE_PREFIX = 'translime-preview-settings:';\n\n/**\n * Mock IPC 实现\n * @returns {Object}\n */\nexport function createMockIpc() {\n return {\n invoke: async (channel, ...args) => {\n console.log('[Preview Mock] ipc.invoke:', channel, args);\n return null;\n },\n send: (channel, ...args) => {\n console.log('[Preview Mock] ipc.send:', channel, args);\n },\n on: (channel, callback) => {\n console.log('[Preview Mock] ipc.on registered:', channel);\n return () => {\n console.log('[Preview Mock] ipc.on removed:', channel);\n };\n },\n once: (channel, callback) => {\n console.log('[Preview Mock] ipc.once registered:', channel);\n },\n removeListener: (channel, callback) => {\n console.log('[Preview Mock] ipc.removeListener:', channel);\n },\n removeAllListeners: (channel) => {\n console.log('[Preview Mock] ipc.removeAllListeners:', channel);\n },\n };\n}\n\n/**\n * Mock Dialog 实现\n * @returns {Object}\n */\nexport function createMockDialog() {\n return {\n showOpenDialog: async (options) => {\n console.log('[Preview Mock] showOpenDialog:', options);\n // 在 preview 模式下,使用原生 file input 模拟\n return new Promise((resolve) => {\n const input = document.createElement('input');\n input.type = 'file';\n if (options?.properties?.includes('openDirectory')) {\n input.webkitdirectory = true;\n }\n if (options?.properties?.includes('multiSelections')) {\n input.multiple = true;\n }\n if (options?.filters) {\n const accept = options.filters\n .flatMap((f) => f.extensions.map((ext) => `.${ext}`))\n .join(',');\n input.accept = accept;\n }\n input.onchange = () => {\n const filePaths = Array.from(input.files || []).map((f) => f.name);\n resolve({ canceled: filePaths.length === 0, filePaths });\n };\n input.oncancel = () => {\n resolve({ canceled: true, filePaths: [] });\n };\n input.click();\n });\n },\n showSaveDialog: async (options) => {\n console.log('[Preview Mock] showSaveDialog:', options);\n const fileName = prompt('保存文件名:', options?.defaultPath || 'file.txt');\n return {\n canceled: !fileName,\n filePath: fileName || undefined,\n };\n },\n showMessageBox: async (options) => {\n console.log('[Preview Mock] showMessageBox:', options);\n const result = confirm(options?.message || '');\n return { response: result ? 0 : 1 };\n },\n showErrorBox: (title, content) => {\n console.error('[Preview Mock] showErrorBox:', title, content);\n alert(`${title}\\n\\n${content}`);\n },\n };\n}\n\n/**\n * Mock Shell 实现\n * @returns {Object}\n */\nexport function createMockShell() {\n return {\n openExternal: async (url) => {\n console.log('[Preview Mock] shell.openExternal:', url);\n window.open(url, '_blank');\n },\n openPath: async (path) => {\n console.log('[Preview Mock] shell.openPath:', path);\n alert(`[Preview] 无法在浏览器中打开路径: ${path}`);\n },\n showItemInFolder: (path) => {\n console.log('[Preview Mock] shell.showItemInFolder:', path);\n alert(`[Preview] 无法在浏览器中显示文件夹: ${path}`);\n },\n };\n}\n\n/**\n * Mock Clipboard 实现\n * @returns {Object}\n */\nexport function createMockClipboard() {\n return {\n readText: async () => {\n try {\n return await navigator.clipboard.readText();\n } catch (e) {\n console.warn('[Preview Mock] clipboard.readText failed:', e);\n return '';\n }\n },\n writeText: async (text) => {\n try {\n await navigator.clipboard.writeText(text);\n console.log('[Preview Mock] clipboard.writeText:', text);\n } catch (e) {\n console.warn('[Preview Mock] clipboard.writeText failed:', e);\n }\n },\n readImage: async () => {\n console.log('[Preview Mock] clipboard.readImage: not supported in preview');\n return null;\n },\n writeImage: async () => {\n console.log('[Preview Mock] clipboard.writeImage: not supported in preview');\n },\n };\n}\n\n/**\n * Mock Window Control 实现\n * @returns {Object}\n */\nexport function createMockWindowControl() {\n return {\n close: (windowId) => {\n console.log('[Preview Mock] windowControl.close:', windowId);\n },\n minimize: (windowId) => {\n console.log('[Preview Mock] windowControl.minimize:', windowId);\n },\n maximize: (windowId) => {\n console.log('[Preview Mock] windowControl.maximize:', windowId);\n },\n unmaximize: (windowId) => {\n console.log('[Preview Mock] windowControl.unmaximize:', windowId);\n },\n devtools: (windowId) => {\n console.log('[Preview Mock] windowControl.devtools:', windowId);\n },\n isMaximized: async (windowId) => {\n console.log('[Preview Mock] windowControl.isMaximized:', windowId);\n return false;\n },\n };\n}\n\n/**\n * Mock Plugin Settings 实现(使用 localStorage 持久化)\n * @returns {Object}\n */\nexport function createMockPluginSettings() {\n return {\n get: async (pluginId) => {\n const key = `${STORAGE_PREFIX}${pluginId}`;\n try {\n const data = localStorage.getItem(key);\n return data ? JSON.parse(data) : {};\n } catch (e) {\n console.warn('[Preview Mock] getPluginSetting parse error:', e);\n return {};\n }\n },\n set: async (pluginId, settings) => {\n const key = `${STORAGE_PREFIX}${pluginId}`;\n try {\n localStorage.setItem(key, JSON.stringify(settings));\n console.log('[Preview Mock] setPluginSetting:', pluginId, settings);\n } catch (e) {\n console.warn('[Preview Mock] setPluginSetting error:', e);\n }\n },\n };\n}\n\n/**\n * Mock Logger 实现\n * @returns {Object}\n */\nexport function createMockLogger() {\n return {\n log: (...args) => console.log('[Preview]', ...args),\n info: (...args) => console.info('[Preview]', ...args),\n warn: (...args) => console.warn('[Preview]', ...args),\n error: (...args) => console.error('[Preview]', ...args),\n debug: (...args) => console.debug('[Preview]', ...args),\n };\n}\n\n/**\n * 创建完整的 mock electron 对象\n * @returns {Object}\n */\nexport function createMockElectron() {\n const mockIpc = createMockIpc();\n return {\n useIpc: () => mockIpc,\n dialog: createMockDialog(),\n shell: createMockShell(),\n clipboard: createMockClipboard(),\n openLink: async (url) => {\n console.log('[Preview Mock] openLink:', url);\n window.open(url, '_blank');\n },\n versions: {\n node: 'preview',\n chrome: navigator.userAgent.match(/Chrome\\/([0-9.]+)/)?.[1] || 'unknown',\n electron: 'preview',\n },\n APP_ROOT: '/preview',\n APPDATA_PATH: '/preview/appdata',\n };\n}\n\n/**\n * 创建完整的 mock ts 对象\n * @returns {Object}\n */\nexport function createMockTs() {\n const pluginSettings = createMockPluginSettings();\n return {\n getPluginSetting: pluginSettings.get,\n setPluginSetting: pluginSettings.set,\n windowControl: createMockWindowControl(),\n logger: createMockLogger(),\n net: {\n request: async (url, options) => {\n console.log('[Preview Mock] net.request:', url, options);\n try {\n const response = await fetch(url, options);\n return {\n ok: response.ok,\n status: response.status,\n data: await response.text(),\n };\n } catch (e) {\n return { ok: false, status: 0, error: e.message };\n }\n },\n },\n };\n}\n\n/**\n * 初始化 preview mock 环境\n * 将 mock 对象注入到 window\n */\nexport function initPreviewMock() {\n if (typeof window === 'undefined') {\n return;\n }\n\n // 只在未定义时注入,避免覆盖真实环境\n if (!window.electron) {\n window.electron = createMockElectron();\n console.log('[Preview Mock] window.electron injected');\n }\n\n if (!window.ts) {\n window.ts = createMockTs();\n console.log('[Preview Mock] window.ts injected');\n }\n}\n\n/**\n * 检查当前是否为 preview 模式\n * @returns {boolean}\n */\nexport function isPreviewMode() {\n // 通过 Vite define 注入的全局变量判断\n // eslint-disable-next-line no-undef\n if (typeof __TRANSLIME_PREVIEW__ !== 'undefined' && __TRANSLIME_PREVIEW__) {\n return true;\n }\n // 备用检测:检查是否在普通浏览器环境中运行\n if (typeof window !== 'undefined' && !window.electron && !window.ts) {\n return true;\n }\n return false;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"preview-mock.cjs","names":[],"sources":["../src/preview-mock.js"],"sourcesContent":["/**\r\n * Preview Mock 模块\r\n * 为 preview 模式提供 Electron API 的 mock 实现\r\n */\r\n\r\nconst STORAGE_PREFIX = 'translime-preview-settings:';\r\n\r\n/**\r\n * Mock IPC 实现\r\n * @returns {Object}\r\n */\r\nexport function createMockIpc() {\r\n return {\r\n invoke: async (channel, ...args) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] ipc.invoke:', channel, args);\r\n return null;\r\n },\r\n send: (channel, ...args) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] ipc.send:', channel, args);\r\n },\r\n on: (channel, callback) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] ipc.on registered:', channel, Boolean(callback));\r\n return () => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] ipc.on removed:', channel);\r\n };\r\n },\r\n once: (channel, callback) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] ipc.once registered:', channel, Boolean(callback));\r\n },\r\n removeListener: (channel, callback) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] ipc.removeListener:', channel, Boolean(callback));\r\n },\r\n removeAllListeners: (channel) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] ipc.removeAllListeners:', channel);\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Mock Dialog 实现\r\n * @returns {Object}\r\n */\r\nexport function createMockDialog() {\r\n return {\r\n showOpenDialog: async (options) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] showOpenDialog:', options);\r\n // 在 preview 模式下,使用原生 file input 模拟\r\n return new Promise((resolve) => {\r\n const input = document.createElement('input');\r\n input.type = 'file';\r\n if (options?.properties?.includes('openDirectory')) {\r\n input.webkitdirectory = true;\r\n }\r\n if (options?.properties?.includes('multiSelections')) {\r\n input.multiple = true;\r\n }\r\n if (options?.filters) {\r\n const accept = options.filters\r\n .flatMap((f) => f.extensions.map((ext) => `.${ext}`))\r\n .join(',');\r\n input.accept = accept;\r\n }\r\n input.onchange = () => {\r\n const filePaths = Array.from(input.files || []).map((f) => f.name);\r\n resolve({ canceled: filePaths.length === 0, filePaths });\r\n };\r\n input.oncancel = () => {\r\n resolve({ canceled: true, filePaths: [] });\r\n };\r\n input.click();\r\n });\r\n },\r\n showSaveDialog: async (options) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] showSaveDialog:', options);\r\n // eslint-disable-next-line no-alert, no-restricted-globals\r\n const fileName = prompt('保存文件名:', options?.defaultPath || 'file.txt');\r\n return {\r\n canceled: !fileName,\r\n filePath: fileName || undefined,\r\n };\r\n },\r\n showMessageBox: async (options) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] showMessageBox:', options);\r\n const result = window.confirm(options?.message || '');\r\n return { response: result ? 0 : 1 };\r\n },\r\n showErrorBox: (title, content) => {\r\n // eslint-disable-next-line no-console\r\n console.error('[Preview Mock] showErrorBox:', title, content);\r\n // eslint-disable-next-line no-alert, no-restricted-globals\r\n alert(`${title}\\n\\n${content}`);\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Mock Shell 实现\r\n * @returns {Object}\r\n */\r\nexport function createMockShell() {\r\n return {\r\n openExternal: async (url) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] shell.openExternal:', url);\r\n window.open(url, '_blank');\r\n },\r\n openPath: async (path) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] shell.openPath:', path);\r\n // eslint-disable-next-line no-alert, no-restricted-globals\r\n alert(`[Preview] 无法在浏览器中打开路径: ${path}`);\r\n },\r\n showItemInFolder: (path) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] shell.showItemInFolder:', path);\r\n // eslint-disable-next-line no-alert, no-restricted-globals\r\n alert(`[Preview] 无法在浏览器中显示文件夹: ${path}`);\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Mock Clipboard 实现\r\n * @returns {Object}\r\n */\r\nexport function createMockClipboard() {\r\n return {\r\n readText: async () => {\r\n try {\r\n return await navigator.clipboard.readText();\r\n } catch (e) {\r\n console.warn('[Preview Mock] clipboard.readText failed:', e);\r\n return '';\r\n }\r\n },\r\n writeText: async (text) => {\r\n try {\r\n await navigator.clipboard.writeText(text);\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] clipboard.writeText:', text);\r\n } catch (e) {\r\n console.warn('[Preview Mock] clipboard.writeText failed:', e);\r\n }\r\n },\r\n readImage: async () => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] clipboard.readImage: not supported in preview');\r\n return null;\r\n },\r\n writeImage: async () => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] clipboard.writeImage: not supported in preview');\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Mock Window Control 实现\r\n * @returns {Object}\r\n */\r\nexport function createMockWindowControl() {\r\n return {\r\n close: (windowId) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] windowControl.close:', windowId);\r\n },\r\n minimize: (windowId) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] windowControl.minimize:', windowId);\r\n },\r\n maximize: (windowId) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] windowControl.maximize:', windowId);\r\n },\r\n unmaximize: (windowId) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] windowControl.unmaximize:', windowId);\r\n },\r\n devtools: (windowId) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] windowControl.devtools:', windowId);\r\n },\r\n isMaximized: async (windowId) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] windowControl.isMaximized:', windowId);\r\n return false;\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Mock Plugin Settings 实现(使用 localStorage 持久化)\r\n * @returns {Object}\r\n */\r\nexport function createMockPluginSettings() {\r\n return {\r\n get: async (pluginId) => {\r\n const key = `${STORAGE_PREFIX}${pluginId}`;\r\n try {\r\n const data = localStorage.getItem(key);\r\n return data ? JSON.parse(data) : {};\r\n } catch (e) {\r\n console.warn('[Preview Mock] getPluginSetting parse error:', e);\r\n return {};\r\n }\r\n },\r\n set: async (pluginId, settings) => {\r\n const key = `${STORAGE_PREFIX}${pluginId}`;\r\n try {\r\n localStorage.setItem(key, JSON.stringify(settings));\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] setPluginSetting:', pluginId, settings);\r\n } catch (e) {\r\n console.warn('[Preview Mock] setPluginSetting error:', e);\r\n }\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Mock Logger 实现\r\n * @returns {Object}\r\n */\r\nexport function createMockLogger() {\r\n return {\r\n log: (...args) => console.log('[Preview]', ...args),\r\n info: (...args) => console.info('[Preview]', ...args),\r\n warn: (...args) => console.warn('[Preview]', ...args),\r\n error: (...args) => console.error('[Preview]', ...args),\r\n debug: (...args) => console.debug('[Preview]', ...args),\r\n };\r\n}\r\n\r\n/**\r\n * 创建完整的 mock electron 对象\r\n * @returns {Object}\r\n */\r\nexport function createMockElectron() {\r\n const mockIpc = createMockIpc();\r\n return {\r\n useIpc: () => mockIpc,\r\n dialog: createMockDialog(),\r\n shell: createMockShell(),\r\n clipboard: createMockClipboard(),\r\n openLink: async (url) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] openLink:', url);\r\n window.open(url, '_blank');\r\n },\r\n versions: {\r\n node: 'preview',\r\n chrome: navigator.userAgent.match(/Chrome\\/([0-9.]+)/)?.[1] || 'unknown',\r\n electron: 'preview',\r\n },\r\n APP_ROOT: '/preview',\r\n APPDATA_PATH: '/preview/appdata',\r\n };\r\n}\r\n\r\n/**\r\n * 创建完整的 mock ts 对象\r\n * @returns {Object}\r\n */\r\nexport function createMockTs() {\r\n const pluginSettings = createMockPluginSettings();\r\n return {\r\n getPluginSetting: pluginSettings.get,\r\n setPluginSetting: pluginSettings.set,\r\n windowControl: createMockWindowControl(),\r\n logger: createMockLogger(),\r\n net: {\r\n request: async (url, options) => {\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] net.request:', url, options);\r\n try {\r\n const response = await fetch(url, options);\r\n return {\r\n ok: response.ok,\r\n status: response.status,\r\n data: await response.text(),\r\n };\r\n } catch (e) {\r\n return { ok: false, status: 0, error: e.message };\r\n }\r\n },\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * 初始化 preview mock 环境\r\n * 将 mock 对象注入到 window\r\n */\r\nexport function initPreviewMock() {\r\n if (typeof window === 'undefined') {\r\n return;\r\n }\r\n\r\n // 只在未定义时注入,避免覆盖真实环境\r\n if (!window.electron) {\r\n window.electron = createMockElectron();\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] window.electron injected');\r\n }\r\n\r\n if (!window.ts) {\r\n window.ts = createMockTs();\r\n // eslint-disable-next-line no-console\r\n console.log('[Preview Mock] window.ts injected');\r\n }\r\n}\r\n\r\n/**\r\n * 检查当前是否为 preview 模式\r\n * @returns {boolean}\r\n */\r\nexport function isPreviewMode() {\r\n // 通过 Vite define 注入的全局变量判断\r\n // eslint-disable-next-line no-undef\r\n if (typeof __TRANSLIME_PREVIEW__ !== 'undefined' && __TRANSLIME_PREVIEW__) {\r\n return true;\r\n }\r\n // 备用检测:检查是否在普通浏览器环境中运行\r\n if (typeof window !== 'undefined' && !window.electron && !window.ts) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n"],"mappings":"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"}