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.
- package/LICENSE +21 -0
- package/README.md +222 -153
- package/dist/index.cjs +231 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +127 -93
- package/dist/index.d.ts +127 -93
- package/dist/index.js +231 -81
- package/dist/index.js.map +1 -1
- package/dist/preview/settings.scss +86 -86
- package/dist/preview-mock.cjs +261 -219
- package/dist/preview-mock.cjs.map +1 -1
- package/dist/preview-mock.js +262 -231
- package/dist/preview-mock.js.map +1 -1
- package/dist/preview-template.html +13 -13
- package/dist/preview.cjs +3106 -3387
- package/dist/preview.cjs.map +1 -1
- package/dist/preview.js +3077 -3370
- package/dist/preview.js.map +1 -1
- package/dist/translime-sdk.css +31 -31
- package/dist/vite-plugin.cjs +142 -174
- package/dist/vite-plugin.cjs.map +1 -1
- package/dist/vite-plugin.d.cts +22 -22
- package/dist/vite-plugin.d.ts +22 -22
- package/dist/vite-plugin.js +134 -172
- package/dist/vite-plugin.js.map +1 -1
- package/package.json +8 -10
package/dist/preview-mock.cjs
CHANGED
|
@@ -1,244 +1,285 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
|
|
235
|
-
|
|
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
|
-
|
|
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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"}
|