efront 3.35.14 → 3.36.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.
- package/apps/blank/index.html +1 -21
- package/apps/blank/main.js +1 -1
- package/apps/kugou/singer/keywords.less +1 -0
- package/apps/sciters/main.js +31 -0
- package/coms/basic/#loader.js +3 -4
- package/coms/basic/i18n.js +25 -0
- package/coms/basic/i18n.md +10 -0
- package/coms/basic/parseYML.js +1 -0
- package/coms/basic/refilm_decode.js +2 -1
- package/coms/basic/strings.js +3 -3
- package/coms/compile/Javascript.js +1 -20
- package/coms/compile/autoi18n.js +17 -0
- package/coms/compile/autoi18n_test.js +6 -0
- package/coms/compile/common.js +22 -0
- package/coms/compile/translate.js +131 -0
- package/coms/compile/wraphtml.js +3 -0
- package/coms/docs/md5.js +174 -0
- package/coms/frame/route.js +1 -1
- package/coms/zimoli/XMLHttpRequest.js +33 -1
- package/coms/zimoli/alert.js +1 -1
- package/coms/zimoli/appendChild.js +2 -1
- package/coms/zimoli/button.less +1 -0
- package/coms/zimoli/createEvent.js +8 -3
- package/coms/zimoli/cross.js +1 -1
- package/coms/zimoli/cross_test.js +8 -2
- package/coms/zimoli/forceUpdate.js +2 -6
- package/coms/zimoli/list.js +1 -1
- package/coms/zimoli/on.js +4 -2
- package/coms/zimoli/render.js +5 -2
- package/coms/zimoli/transition.js +4 -5
- package/coms/zimoli/tree.js +5 -3
- package/coms/zimoli/zimoli.js +3 -3
- package/docs/index.html +1 -12
- package/docs/main.xht +2 -1
- package/docs//345/267/245/345/205/267//345/233/275/351/231/205/345/214/226.xht +578 -0
- package/package.json +1 -1
- package/public/efront.js +1 -1
- package/readme.md +1 -1
- package/coms/zimoli/i18n.js +0 -192
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
button {
|
|
3
|
+
padding: 0 16px;
|
|
4
|
+
margin-right: 6px;
|
|
5
|
+
margin-bottom: 6px;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
[error] {
|
|
9
|
+
color: #f24;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
form {
|
|
13
|
+
padding: 0 0 6px 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
form>* {
|
|
17
|
+
margin-right: 16px;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
h2,
|
|
21
|
+
p,
|
|
22
|
+
div {
|
|
23
|
+
padding: 14px 20px;
|
|
24
|
+
margin: 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
hr {
|
|
28
|
+
margin: 0;
|
|
29
|
+
clear: both;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
tr.actived td {
|
|
33
|
+
color: #fff;
|
|
34
|
+
background: #069 !important;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
span,
|
|
38
|
+
a {
|
|
39
|
+
vertical-align: middle;
|
|
40
|
+
}
|
|
41
|
+
</style>
|
|
42
|
+
<p><span>翻译结果仅做为参考,未必完美替换,语法参考<a @click="zimoli.go('/组件/basic/i18n.js',{mark:true})">i18n.js</a></span></p>
|
|
43
|
+
<p -if="!window.showDirectoryPicker" error>国际化工具仅在浏览器支持 showDirectoryPicker 时可用</p>
|
|
44
|
+
<div -else>
|
|
45
|
+
<button @click="chooseFolder">选择代码文件夹</button>
|
|
46
|
+
<button @click="editCode()">修改国际化参数</button>
|
|
47
|
+
<button style="float:right" -if="tableData.length" @click="exportCSV">导出到文件</button>
|
|
48
|
+
<hr />
|
|
49
|
+
<form>
|
|
50
|
+
<checkbox -src="filters" @change="runFilter"></checkbox>
|
|
51
|
+
</form>
|
|
52
|
+
<table #table-element -src="[fields,tableData]" @active="showDetail(event)">
|
|
53
|
+
</table>
|
|
54
|
+
</div>
|
|
55
|
+
<script>
|
|
56
|
+
var baiduFanyiConfig = data.getInstance("fanyi-config");
|
|
57
|
+
var a = button;
|
|
58
|
+
var salt = `efront${Math.random().toString(36).slice(6, 16)}`;
|
|
59
|
+
var requestBaiduFanyi = async function (str, to, from = 'auto') {
|
|
60
|
+
var appid = baiduFanyiConfig.appid || "20210218000700622";
|
|
61
|
+
var sign = baiduFanyiConfig.sign || "xJf0dfXeJdzudCTBn3QS";
|
|
62
|
+
var xhr = await cross("get", "https://fanyi-api.baidu.com/api/trans/vip/translate").send({
|
|
63
|
+
q: str,
|
|
64
|
+
from,
|
|
65
|
+
to,
|
|
66
|
+
appid,
|
|
67
|
+
salt,
|
|
68
|
+
sign: md5(`${appid}${str}${salt}${sign}`),
|
|
69
|
+
});
|
|
70
|
+
var data = JSON.parse(xhr.response);
|
|
71
|
+
return data.trans_result[0].dst;
|
|
72
|
+
};
|
|
73
|
+
var editCode = function () {
|
|
74
|
+
supports.forEach(s => s.checked = false);
|
|
75
|
+
detailScope.supports.forEach(s => s.checked = true);
|
|
76
|
+
var editor = frame$edit("国际化参数", {
|
|
77
|
+
submit(form) {
|
|
78
|
+
if (form.appid && !form.sign || form.sign && !form.appid) {
|
|
79
|
+
return "appid和密钥不能只有一个!";
|
|
80
|
+
}
|
|
81
|
+
detailScope.supports = supports.filter(s => s.checked);
|
|
82
|
+
var smap = {};
|
|
83
|
+
for (var s of detailScope.supports) {
|
|
84
|
+
smap[s.id] = true;
|
|
85
|
+
}
|
|
86
|
+
data.patchInstance('fanyi-config', { appid: form.appid, sign: form.sign, smap }, true);
|
|
87
|
+
}
|
|
88
|
+
}, {
|
|
89
|
+
fields: [
|
|
90
|
+
{ name: "提示", readonly: true, key: 'apply_info', type: 'text' },
|
|
91
|
+
{ name: "appid及密钥申请地址", readonly: true, key: 'apply_url', type: 'anchor' },
|
|
92
|
+
{ name: "appid", key: 'appid', type: 'input' },
|
|
93
|
+
{ name: "密钥", key: 'sign', type: "input" },
|
|
94
|
+
{ name: "目标语言", type: 'checkbox', options: supports }
|
|
95
|
+
], data: {
|
|
96
|
+
apply_url: 'https://fanyi-api.baidu.com/',
|
|
97
|
+
apply_info: 'efront目前使用的翻译接口免费额度受限,如果遇到翻译失败的情况,您可以自己申请一个appid和密钥配置后使用',
|
|
98
|
+
appid: baiduFanyiConfig.appid,
|
|
99
|
+
sign: baiduFanyiConfig.sign
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
popup(editor, [.5, .5]);
|
|
103
|
+
};
|
|
104
|
+
// var supports2 = {
|
|
105
|
+
// 阿布哈兹语: ["ab", "Abkhazian"],
|
|
106
|
+
// 阿法尔: ["aa", "Afar"],
|
|
107
|
+
// 南非荷兰语: ["af", "Afrikaans"],
|
|
108
|
+
// 将: ["ak", "Akan"],
|
|
109
|
+
// 阿尔巴尼亚语: ["sq", "Albanian"],
|
|
110
|
+
// 阿姆哈拉语: ["am", "Amharic"],
|
|
111
|
+
// 阿拉伯语: ["ar", "Arabic"],
|
|
112
|
+
// 阿拉贡语: ["an", "Aragonese"],
|
|
113
|
+
// 亚美尼亚语: ["hy", "Armenian"],
|
|
114
|
+
// 阿萨姆语: ["as", "Assamese"],
|
|
115
|
+
// Avaric公司: ["av", "Avaric"],
|
|
116
|
+
// 阿维斯坦: ["ae", "Avestan"],
|
|
117
|
+
// 艾玛拉: ["ay", "Aymara"],
|
|
118
|
+
// 阿塞拜疆语: ["az", "Azerbaijani"],
|
|
119
|
+
// 班巴拉: ["bm", "Bambara"],
|
|
120
|
+
// 巴什基尔语: ["ba", "Bashkir"],
|
|
121
|
+
// 巴斯克语: ["eu", "Basque"],
|
|
122
|
+
// 白俄罗斯语: ["be", "Belarusian"],
|
|
123
|
+
// "孟加拉语(孟加拉语)": ["bn", "Bengali (Bangla)"],
|
|
124
|
+
// 比哈里: ["bh", "Bihari"],
|
|
125
|
+
// 比斯拉马: ["bi", "Bislama"],
|
|
126
|
+
// 波斯尼亚语: ["bs", "Bosnian"],
|
|
127
|
+
// 布雷顿: ["br", "Breton"],
|
|
128
|
+
// 保加利亚语: ["bg", "Bulgarian"],
|
|
129
|
+
// 缅甸语: ["my", "Burmese"],
|
|
130
|
+
// 加泰罗尼亚语: ["ca", "Catalan"],
|
|
131
|
+
// 查莫罗: ["ch", "Chamorro"],
|
|
132
|
+
// 车臣: ["ce", "Chechen"],
|
|
133
|
+
// "Chichowa、Chewa、Nyanja": ["ny", "Chichewa, Chewa, Nyanja"],
|
|
134
|
+
// 中国人: ["zh", "Chinese"],
|
|
135
|
+
// "中文(简体)": ["zh-Hans", "Chinese (Simplified)"],
|
|
136
|
+
// "中文(繁体)": ["zh-Hant", "Chinese (Traditional)"],
|
|
137
|
+
// 楚瓦什: ["cv", "Chuvash"],
|
|
138
|
+
// 康沃尔语: ["kw", "Cornish"],
|
|
139
|
+
// 科西嘉岛: ["co", "Corsican"],
|
|
140
|
+
// 相信: ["cr", "Cree"],
|
|
141
|
+
// 克罗地亚语: ["hr", "Croatian"],
|
|
142
|
+
// 捷克的: ["cs", "Czech"],
|
|
143
|
+
// 丹麦语: ["da", "Danish"],
|
|
144
|
+
// "迪维希、迪维希和马尔代夫": ["dv", "Divehi, Dhivehi, Maldivian"],
|
|
145
|
+
// 荷兰的: ["nl", "Dutch"],
|
|
146
|
+
// 宗喀语: ["dz", "Dzongkha"],
|
|
147
|
+
// 英语: ["en", "English"],
|
|
148
|
+
// 世界语: ["eo", "Esperanto"],
|
|
149
|
+
// 爱沙尼亚语: ["et", "Estonian"],
|
|
150
|
+
// 母羊: ["ee", "Ewe"],
|
|
151
|
+
// 法罗群岛语: ["fo", "Faroese"],
|
|
152
|
+
// 斐济: ["fj", "Fijian"],
|
|
153
|
+
// 芬兰语: ["fi", "Finnish"],
|
|
154
|
+
// 法语: ["fr", "French"],
|
|
155
|
+
// "Fula、Fula、Pulaar、Pular": ["ff", "Fula, Fulah, Pulaar, Pular"],
|
|
156
|
+
// 加利西亚语: ["gl", "Galician"],
|
|
157
|
+
// "盖尔语(苏格兰)": ["gd", "Gaelic (Scottish)"],
|
|
158
|
+
// "盖尔语(Manx)": ["gv", "Gaelic (Manx)"],
|
|
159
|
+
// 格鲁吉亚语: ["ka", "Georgian"],
|
|
160
|
+
// 德国的: ["de", "German"],
|
|
161
|
+
// 希腊人: ["el", "Greek"],
|
|
162
|
+
// 格陵兰语: ["kl", "Greenlandic"],
|
|
163
|
+
// 瓜拉尼语: ["gn", "Guarani"],
|
|
164
|
+
// 古吉拉特语: ["gu", "Gujarati"],
|
|
165
|
+
// 海地克里奥尔语: ["ht", "Haitian Creole"],
|
|
166
|
+
// 收割台: ["ha", "Hausa"],
|
|
167
|
+
// 希伯来语: ["he", "Hebrew"],
|
|
168
|
+
// 赫雷罗: ["hz", "Herero"],
|
|
169
|
+
// 印地语: ["hi", "Hindi"],
|
|
170
|
+
// 希利摩陀语: ["ho", "Hiri Motu"],
|
|
171
|
+
// 匈牙利语: ["hu", "Hungarian"],
|
|
172
|
+
// 冰岛语: ["is", "Icelandic"],
|
|
173
|
+
// 去: ["io", "Ido"],
|
|
174
|
+
// 伊博: ["ig", "Igbo"],
|
|
175
|
+
// 印度尼西亚语: ["id, in", "Indonesian"],
|
|
176
|
+
// 中间语: ["ia", "Interlingua"],
|
|
177
|
+
// 语际: ["ie", "Interlingue"],
|
|
178
|
+
// 因纽特语: ["iu", "Inuktitut"],
|
|
179
|
+
// 因纽皮亚克: ["ik", "Inupiak"],
|
|
180
|
+
// 爱尔兰的: ["ga", "Irish"],
|
|
181
|
+
// 意大利人: ["it", "Italian"],
|
|
182
|
+
// 日本人: ["ja", "Japanese"],
|
|
183
|
+
// 爪哇语: ["jv", "Javanese"],
|
|
184
|
+
// 格陵兰语Kalaallisut: ["kl", "Kalaallisut, Greenlandic"],
|
|
185
|
+
// 卡纳达语: ["kn", "Kannada"],
|
|
186
|
+
// 卡努里: ["kr", "Kanuri"],
|
|
187
|
+
// 克什米尔: ["ks", "Kashmiri"],
|
|
188
|
+
// 哈萨克语: ["kk", "Kazakh"],
|
|
189
|
+
// 高棉语: ["km", "Khmer"],
|
|
190
|
+
// Kikuyu公司: ["ki", "Kikuyu"],
|
|
191
|
+
// "基尼亚卢旺达语(卢旺达)": ["rw", "Kinyarwanda (Rwanda)"],
|
|
192
|
+
// 基隆迪语: ["rn", "Kirundi"],
|
|
193
|
+
// Kyrgyz: ["ky", "Kyrgyz"],
|
|
194
|
+
// 科米牌手表: ["kv", "Komi"],
|
|
195
|
+
// 孔戈: ["kg", "Kongo"],
|
|
196
|
+
// 韩国人: ["ko", "Korean"],
|
|
197
|
+
// 库尔德语: ["ku", "Kurdish"],
|
|
198
|
+
// 黑色: ["kj", "Kwanyama"],
|
|
199
|
+
// 老挝语: ["lo", "Lao"],
|
|
200
|
+
// 拉丁语: ["la", "Latin"],
|
|
201
|
+
// "拉脱维亚语(Lettish)": ["lv", "Latvian (Lettish)"],
|
|
202
|
+
// "林堡语(林堡语)": ["li", "Limburgish ( Limburger)"],
|
|
203
|
+
// 林加拉: ["ln", "Lingala"],
|
|
204
|
+
// 立陶宛语: ["lt", "Lithuanian"],
|
|
205
|
+
// 卢加加丹加: ["lu", "Luga-Katanga"],
|
|
206
|
+
// "卢甘达,甘达": ["lg", "Luganda, Ganda"],
|
|
207
|
+
// 卢森堡语: ["lb", "Luxembourgish"],
|
|
208
|
+
// 曼克斯牌手表: ["gv", "Manx"],
|
|
209
|
+
// 马其顿语: ["mk", "Macedonian"],
|
|
210
|
+
// 马达加斯加语: ["mg", "Malagasy"],
|
|
211
|
+
// 马来语: ["ms", "Malay"],
|
|
212
|
+
// 马拉雅拉姆语: ["ml", "Malayalam"],
|
|
213
|
+
// 马耳他语: ["mt", "Maltese"],
|
|
214
|
+
// 毛利语: ["mi", "Maori"],
|
|
215
|
+
// 马拉地语: ["mr", "Marathi"],
|
|
216
|
+
// 马绍尔群岛: ["mh", "Marshallese"],
|
|
217
|
+
// 摩尔达维亚语: ["mo", "Moldavian"],
|
|
218
|
+
// 蒙古族的: ["mn", "Mongolian"],
|
|
219
|
+
// 瑙鲁: ["na", "Nauru"],
|
|
220
|
+
// 纳瓦霍语: ["nv", "Navajo"],
|
|
221
|
+
// 恩东加: ["ng", "Ndonga"],
|
|
222
|
+
// 北恩德贝勒: ["nd", "Northern Ndebele"],
|
|
223
|
+
// 尼泊尔语: ["ne", "Nepali"],
|
|
224
|
+
// 挪威语: ["no", "Norwegian"],
|
|
225
|
+
// 挪威bokmål: ["nb", "Norwegian bokmål"],
|
|
226
|
+
// 挪威语nynorsk: ["nn", "Norwegian nynorsk"],
|
|
227
|
+
// 诺苏牌手表: ["ii", "Nuosu"],
|
|
228
|
+
// 奥克语: ["oc", "Occitan"],
|
|
229
|
+
// 齐佩瓦人: ["oj", "Ojibwe"],
|
|
230
|
+
// "古教堂斯拉夫语,古保加利亚语": ["cu", "Old Church Slavonic, Old Bulgarian"],
|
|
231
|
+
// 奥里亚语: ["or", "Oriya"],
|
|
232
|
+
// "奥罗莫语(Afaan Oromo)": ["om", "Oromo (Afaan Oromo)"],
|
|
233
|
+
// 奥塞梯语: ["os", "Ossetian"],
|
|
234
|
+
// 锅: ["pi", "Pāli"],
|
|
235
|
+
// "普什图语,普什图": ["ps", "Pashto, Pushto"],
|
|
236
|
+
// "波斯语(波斯语)": ["fa", "Persian (Farsi)"],
|
|
237
|
+
// 磨光: ["pl", "Polish"],
|
|
238
|
+
// 葡萄牙语: ["pt", "Portuguese"],
|
|
239
|
+
// "旁遮普语(东部)": ["pa", "Punjabi (Eastern)"],
|
|
240
|
+
// 克丘亚: ["qu", "Quechua"],
|
|
241
|
+
// 罗曼什语: ["rm", "Romansh"],
|
|
242
|
+
// 罗马尼亚语: ["ro", "Romanian"],
|
|
243
|
+
// 俄语: ["ru", "Russian"],
|
|
244
|
+
// 萨米语: ["se", "Sami"],
|
|
245
|
+
// 萨摩亚: ["sm", "Samoan"],
|
|
246
|
+
// 桑戈: ["sg", "Sango"],
|
|
247
|
+
// 梵语: ["sa", "Sanskrit"],
|
|
248
|
+
// 塞尔维亚语: ["sr", "Serbian"],
|
|
249
|
+
// "塞尔维亚-克罗地亚语": ["sh", "Serbo-Croatian"],
|
|
250
|
+
// 塞索托: ["st", "Sesotho"],
|
|
251
|
+
// 塞茨瓦纳语: ["tn", "Setswana"],
|
|
252
|
+
// 肖纳: ["sn", "Shona"],
|
|
253
|
+
// 四川彝族: ["ii", "Sichuan Yi"],
|
|
254
|
+
// 信德省: ["sd", "Sindhi"],
|
|
255
|
+
// 僧伽罗语: ["si", "Sinhalese"],
|
|
256
|
+
// 西斯瓦蒂: ["ss", "Siswati"],
|
|
257
|
+
// 斯洛伐克语: ["sk", "Slovak"],
|
|
258
|
+
// 斯洛文尼亚语: ["sl", "Slovenian"],
|
|
259
|
+
// 索马里语: ["so", "Somali"],
|
|
260
|
+
// 南恩德贝勒: ["nr", "Southern Ndebele"],
|
|
261
|
+
// 西班牙的: ["es", "Spanish"],
|
|
262
|
+
// 巽他语: ["su", "Sundanese"],
|
|
263
|
+
// "斯瓦希里语(斯瓦希里)": ["sw", "Swahili (Kiswahili)"],
|
|
264
|
+
// 斯瓦蒂: ["ss", "Swati"],
|
|
265
|
+
// 瑞典的: ["sv", "Swedish"],
|
|
266
|
+
// 塔加洛语: ["tl", "Tagalog"],
|
|
267
|
+
// 塔希提语: ["ty", "Tahitian"],
|
|
268
|
+
// 塔吉克语: ["tg", "Tajik"],
|
|
269
|
+
// 泰米尔语: ["ta", "Tamil"],
|
|
270
|
+
// 升级: ["tt", "Tatar"],
|
|
271
|
+
// 泰卢固语: ["te", "Telugu"],
|
|
272
|
+
// 泰国人: ["th", "Thai"],
|
|
273
|
+
// 藏语: ["bo", "Tibetan"],
|
|
274
|
+
// 提格里尼亚: ["ti", "Tigrinya"],
|
|
275
|
+
// 汤加: ["to", "Tonga"],
|
|
276
|
+
// 聪加人: ["ts", "Tsonga"],
|
|
277
|
+
// 土耳其的: ["tr", "Turkish"],
|
|
278
|
+
// 土库曼人: ["tk", "Turkmen"],
|
|
279
|
+
// Twi公司: ["tw", "Twi"],
|
|
280
|
+
// 维吾尔语: ["ug", "Uyghur"],
|
|
281
|
+
// 乌克兰语: ["uk", "Ukrainian"],
|
|
282
|
+
// 乌尔都语: ["ur", "Urdu"],
|
|
283
|
+
// 乌兹别克: ["uz", "Uzbek"],
|
|
284
|
+
// 出售: ["ve", "Venda"],
|
|
285
|
+
// 越南语: ["vi", "Vietnamese"],
|
|
286
|
+
// 沃拉普克: ["vo", "Volapük"],
|
|
287
|
+
// 瓦隆: ["wa", "Wallon"],
|
|
288
|
+
// 威尔士的: ["cy", "Welsh"],
|
|
289
|
+
// 沃洛夫: ["wo", "Wolof"],
|
|
290
|
+
// 西弗里西亚语: ["fy", "Western Frisian"],
|
|
291
|
+
// 科萨: ["xh", "Xhosa"],
|
|
292
|
+
// 意第绪语: ["yi, ji", "Yiddish"],
|
|
293
|
+
// 约鲁巴语: ["yo", "Yoruba"],
|
|
294
|
+
// "庄,庄": ["za", "Zhuang, Chuang"],
|
|
295
|
+
// 祖鲁语: ["zu", "Zulu"]
|
|
296
|
+
// };
|
|
297
|
+
var supports = [
|
|
298
|
+
{ name: "中文", id: "zh", lang: "zh-CN" },
|
|
299
|
+
{ name: "繁体中文", id: "cht", lang: "zh-TW" },
|
|
300
|
+
{ name: "英语", id: "en", lang: "en" },
|
|
301
|
+
// { name: "文言文", id: "wyw" },
|
|
302
|
+
// { name: "粤语", id: "yue" },
|
|
303
|
+
{ name: "日语", id: "jp", lang: "ja" },
|
|
304
|
+
{ name: "法语", id: "fra", lang: 'fr' },
|
|
305
|
+
{ name: "俄语", id: "ru", lang: 'ru' },
|
|
306
|
+
{ name: "韩语", id: "kor", lang: "ko" },
|
|
307
|
+
{ name: "德语", id: "de", lang: "de" },
|
|
308
|
+
{ name: "意大利语", id: "it", lang: 'it' },
|
|
309
|
+
{ name: "泰语", id: "th", lang: "th" },
|
|
310
|
+
{ name: "越南语", id: "vie", lang: 'vi' },
|
|
311
|
+
{ name: "阿拉伯语", id: "ara", lang: "ar" },
|
|
312
|
+
{ name: "荷兰语", id: "nl", lang: "nl" },
|
|
313
|
+
{ name: "芬兰语", id: "fin", lang: "fi" },
|
|
314
|
+
{ name: "希腊语", id: "el", lang: "el" },
|
|
315
|
+
{ name: "西班牙语", id: "spa", lang: "es" },
|
|
316
|
+
// { name: "葡萄牙语", id: "pt", lang: /pt\-(BR|PT)/ },
|
|
317
|
+
{ name: "匈牙利语", id: "hu", lang: 'hu' },
|
|
318
|
+
{ name: "瑞典语", id: "swe", lang: 'sv' },
|
|
319
|
+
{ name: "丹麦语", id: "dan", lang: 'da' },
|
|
320
|
+
{ name: "捷克语", id: "cs", lang: 'cs' },
|
|
321
|
+
// { name: "波兰语", id: "pl" },
|
|
322
|
+
{ name: "保加利亚语", id: "bul", lang: "bg" },
|
|
323
|
+
{ name: "爱沙尼亚语", id: "est", lang: 'et' },
|
|
324
|
+
{ name: "罗马尼亚语", id: "rom", lang: 'ro' },
|
|
325
|
+
{ name: "斯洛文尼亚语", id: "slo", lang: 'sl' },
|
|
326
|
+
];
|
|
327
|
+
supports.forEach(s => s.key = s.id);
|
|
328
|
+
var getAllText = function (data, e) {
|
|
329
|
+
try {
|
|
330
|
+
if (/^\s*<!doctype\s/i.test(data)) return [];
|
|
331
|
+
if (/\.(xht|vue)$/i.test(e.name)) {
|
|
332
|
+
var { scripts, outerHTML: htmltext, attributes = '', tagName, styles } = compile$scanner2(data, 'html').scoped;
|
|
333
|
+
data = compile$wraphtml(htmltext) + ";\r\n" + scripts.join("\r\n");
|
|
334
|
+
}
|
|
335
|
+
else if (/\.html?$/i.test(e.name)) {
|
|
336
|
+
data = compile$wraphtml(htmltext);
|
|
337
|
+
}
|
|
338
|
+
var code = compile$scanner2(String(data));
|
|
339
|
+
return compile$translate.getI18nPrefixed(code);
|
|
340
|
+
}
|
|
341
|
+
catch (e) {
|
|
342
|
+
alert("提取出错了", "error");
|
|
343
|
+
throw e;
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
var 已找到的字符串 = [];
|
|
347
|
+
var fields = [
|
|
348
|
+
{ name: "字符串", key: "text", width: 280 },
|
|
349
|
+
{ name: "已翻译", key: "liang", width: 80 },
|
|
350
|
+
{ name: "出现文件", key: "files", width: 200 },
|
|
351
|
+
{ name: "出现次数", key: "count", width: 80 },
|
|
352
|
+
];
|
|
353
|
+
var filters = {
|
|
354
|
+
key: "filter",
|
|
355
|
+
options: [
|
|
356
|
+
{
|
|
357
|
+
name: "只看中文", key: "cnonly", get checked() {
|
|
358
|
+
return true;
|
|
359
|
+
},
|
|
360
|
+
set checked(v) {
|
|
361
|
+
alert('暂不支持翻译其他语言', 'warn');
|
|
362
|
+
},
|
|
363
|
+
test(a) {
|
|
364
|
+
return /[\u3400-\ufad9\u{20000}-\u{2a6d6}\u{2fa1d}]/u.test(a.text);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
]
|
|
368
|
+
};
|
|
369
|
+
var tableData = [];
|
|
370
|
+
var runFilter = function () {
|
|
371
|
+
tableData = 已找到的字符串;
|
|
372
|
+
var { options } = filters;
|
|
373
|
+
for (var o of options) {
|
|
374
|
+
if (o.checked) {
|
|
375
|
+
tableData = tableData.filter(o.test);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
var detailWindow;
|
|
380
|
+
var detailScope = {
|
|
381
|
+
drop,
|
|
382
|
+
field,
|
|
383
|
+
textarea,
|
|
384
|
+
supports: baiduFanyiConfig.smap ? supports.filter(s => baiduFanyiConfig.smap[s.id]) : supports.slice(0, 8),
|
|
385
|
+
button,
|
|
386
|
+
lattice,
|
|
387
|
+
fanyi: {},
|
|
388
|
+
a: button,
|
|
389
|
+
async baidu() {
|
|
390
|
+
var fanyi = this.fanyi;
|
|
391
|
+
var liang = this.item.liang;
|
|
392
|
+
for (var s of this.supports) {
|
|
393
|
+
if (fanyi[s.id] && fanyi[s.id].trim()) continue;
|
|
394
|
+
fanyi[s.id] = await requestBaiduFanyi(this.item.text, s.id);
|
|
395
|
+
liang++;
|
|
396
|
+
render.digest();
|
|
397
|
+
}
|
|
398
|
+
this.item.liang = liang;
|
|
399
|
+
},
|
|
400
|
+
save() {
|
|
401
|
+
|
|
402
|
+
},
|
|
403
|
+
close() {
|
|
404
|
+
remove(detailWindow);
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
var activedRow;
|
|
408
|
+
var showDetail = function (event) {
|
|
409
|
+
var tr = getTargetIn(tableElement.children[1], event.active, false);
|
|
410
|
+
if (!detailWindow) {
|
|
411
|
+
detailWindow = view();
|
|
412
|
+
on('submit')(detailWindow, e => e.preventDefault());
|
|
413
|
+
detailWindow.innerHTML = `<div head>翻译: "<span -bind="item?.text"></span>"<drop @click="close()"></drop></div><lattice itemwidth=260 -src="s in supports" body><field style="display:inline-block;padding:0 0 6px 12px;" ><label style="padding-left:0"><span -bind="s.name"></span>(<span -bind="s.lang"></span>)</label><textarea -model="fanyi[s.id]" class='body' style="resize:none"></textarea></field></lattice><div foot><a style="float:left" @click="baidu">一键百度</a></div>`;
|
|
414
|
+
drag.on(detailWindow, detailWindow.firstElementChild);
|
|
415
|
+
resize.on(detailWindow);
|
|
416
|
+
css(detailWindow, `position:absolute;left:0;top:0;bottom:0;width:260px;`);
|
|
417
|
+
detailWindow.initialStyle = "margin-left:-100px;opacity:0";
|
|
418
|
+
render(detailWindow, detailScope);
|
|
419
|
+
on("remove")(detailWindow, function () {
|
|
420
|
+
var count = 0;
|
|
421
|
+
var fanyi = detailScope.fanyi;
|
|
422
|
+
for (var s of supports) {
|
|
423
|
+
if (fanyi[s.id] && fanyi[s.id].trim()) count++;
|
|
424
|
+
}
|
|
425
|
+
detailScope.item.liang = count;
|
|
426
|
+
removeClass(activedRow, "actived");
|
|
427
|
+
activedRow = null;
|
|
428
|
+
})
|
|
429
|
+
|
|
430
|
+
}
|
|
431
|
+
var item = detailScope.item = event.item;
|
|
432
|
+
if (activedRow !== tr) {
|
|
433
|
+
if (activedRow) removeClass(activedRow, 'actived');
|
|
434
|
+
activedRow = tr;
|
|
435
|
+
addClass(activedRow, 'actived');
|
|
436
|
+
}
|
|
437
|
+
if (item.text.length > 160) {
|
|
438
|
+
alert(i18n`文本超长,无法翻译`, 'error');
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
// if (/[\u2028\u2029\r\n]/.test(item.text)) {
|
|
442
|
+
// alert("不能翻译换行符号!", "error");
|
|
443
|
+
// return;
|
|
444
|
+
// }
|
|
445
|
+
if (!item.fanyi) item.fanyi = {}, item.fanyi[supports[0].id] = item.text;
|
|
446
|
+
detailScope.fanyi = item.fanyi;
|
|
447
|
+
|
|
448
|
+
if (!isMounted(detailWindow)) popup(detailWindow);
|
|
449
|
+
}
|
|
450
|
+
var readText = async function (e) {
|
|
451
|
+
var file = await e.getFile();
|
|
452
|
+
var reader = new FileReader();
|
|
453
|
+
awaitable(reader);
|
|
454
|
+
var a = reader.readAsArrayBuffer(file);
|
|
455
|
+
await reader;
|
|
456
|
+
var data = reader.result;
|
|
457
|
+
data = decodeUTF8(new Uint8Array(data));
|
|
458
|
+
return data;
|
|
459
|
+
}
|
|
460
|
+
var chooseFolder = async function () {
|
|
461
|
+
var dp = await window.showDirectoryPicker();
|
|
462
|
+
var msg = alert("正在读取文件列表,请稍候..", false);
|
|
463
|
+
var rest = [dp];
|
|
464
|
+
var result = [];
|
|
465
|
+
dp.path = "";
|
|
466
|
+
var path = "";
|
|
467
|
+
var pretrans = [];
|
|
468
|
+
while (rest.length) {
|
|
469
|
+
var dp = rest.pop();
|
|
470
|
+
path = dp.path
|
|
471
|
+
for await (var [name, e] of dp.entries()) {
|
|
472
|
+
if (/^[\#]/.test(name)) {
|
|
473
|
+
if (e.kind === "file" && /^#.*?\.ya?ml$/i.test(name)) {
|
|
474
|
+
pretrans.push(e);
|
|
475
|
+
}
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
479
|
+
if (/^[\.]|_test\.js$/i.test(name)) continue;
|
|
480
|
+
if (e.kind === "file" && !/\.([mc]?[tj]sx?|xht|vue|html?)$/i.test(name)) continue;
|
|
481
|
+
}
|
|
482
|
+
e.path = path + e.name;
|
|
483
|
+
if (e.kind === 'directory') {
|
|
484
|
+
e.path += '/';
|
|
485
|
+
rest.push(e);
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
result.push(e);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
msg.setText("正在提取字符串..");
|
|
493
|
+
css(msg.firstElementChild, 'text-align:left');
|
|
494
|
+
var textMap = Object.create(null);
|
|
495
|
+
已找到的字符串.is_loading = true;
|
|
496
|
+
var addTranslate = function (translate) {
|
|
497
|
+
var tmap = textMap[translate];
|
|
498
|
+
if (!tmap) tmap = textMap[translate] = Object.create(null), tmap["#count"] = 0;
|
|
499
|
+
if (!tmap[e.path]) tmap[e.path] = [];
|
|
500
|
+
tmap["#count"]++;
|
|
501
|
+
tmap[e.path].push(t);
|
|
502
|
+
}
|
|
503
|
+
for (var e of result) {
|
|
504
|
+
msg.setText("正在提取 " + e.path);
|
|
505
|
+
var data = await readText(e);
|
|
506
|
+
var texts = getAllText(data, e);
|
|
507
|
+
for (var t of texts) {
|
|
508
|
+
if (t.transtype === compile$translate.手动) {
|
|
509
|
+
addTranslate(t.translate);
|
|
510
|
+
}
|
|
511
|
+
else if (t.transtype === compile$translate.字段名) {
|
|
512
|
+
t.fields.forEach(f => addTranslate(f.name));
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
msg.setText("提取完成");
|
|
517
|
+
var result = [];
|
|
518
|
+
var preMap = Object.create(null);
|
|
519
|
+
for (var e of pretrans) {
|
|
520
|
+
var data = await readText(e);
|
|
521
|
+
data = parseYML(data);
|
|
522
|
+
for (var d of data) {
|
|
523
|
+
for (var k in d) {
|
|
524
|
+
preMap[d[k]] = d;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
Object.keys(textMap).map(k => {
|
|
529
|
+
var texts = textMap[k];
|
|
530
|
+
var count = texts["#count"];
|
|
531
|
+
delete texts["#count"];
|
|
532
|
+
var files = Object.keys(texts);
|
|
533
|
+
var liang = 0;
|
|
534
|
+
if (k in preMap) {
|
|
535
|
+
var fanyi = {};
|
|
536
|
+
detailScope.supports.forEach(s => {
|
|
537
|
+
var v = preMap[k][s.lang]
|
|
538
|
+
if (v) {
|
|
539
|
+
fanyi[s.id] = v;
|
|
540
|
+
liang++;
|
|
541
|
+
}
|
|
542
|
+
})
|
|
543
|
+
}
|
|
544
|
+
result.push({ text: k, occurs: texts, files: files.join(',\r\n'), count, fanyi, liang });
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
已找到的字符串 = result;
|
|
548
|
+
runFilter();
|
|
549
|
+
}
|
|
550
|
+
var exportCSV = async function () {
|
|
551
|
+
var checked_supports = detailScope.supports;
|
|
552
|
+
var objs = [];
|
|
553
|
+
for (var d of tableData) {
|
|
554
|
+
var o = {};
|
|
555
|
+
if (!d.fanyi) {
|
|
556
|
+
for (var c of checked_supports) o[c.lang] = '';
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
var f = d.fanyi;
|
|
560
|
+
for (var c of checked_supports) o[c.lang] = f[c.id] || '';
|
|
561
|
+
}
|
|
562
|
+
var c = supports[0];
|
|
563
|
+
o[c.lang] = d.text;
|
|
564
|
+
objs.push(o);
|
|
565
|
+
}
|
|
566
|
+
var f = await window.showSaveFilePicker({
|
|
567
|
+
suggestedName: "#国际化.yml",
|
|
568
|
+
excludeAcceptAllOption: true,
|
|
569
|
+
types: [{
|
|
570
|
+
description: 'yml文件',
|
|
571
|
+
accept: { 'text/plain': ['.yml'] },
|
|
572
|
+
}],
|
|
573
|
+
});
|
|
574
|
+
var w = await f.createWritable();
|
|
575
|
+
await w.write(YAML.stringify(objs));
|
|
576
|
+
await w.close();
|
|
577
|
+
};
|
|
578
|
+
</script>
|