i18n-jsautotranslate 1.0.0 → 2.6.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/index.js +3042 -596
- package/package.json +2 -2
- package/readme.md +116 -298
package/index.js
CHANGED
|
@@ -1,671 +1,3117 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
国际化,网页自动翻译。
|
|
4
|
+
作者:管雷鸣
|
|
5
|
+
开原仓库:https://github.com/xnx3/translate
|
|
6
|
+
|
|
7
|
+
*/
|
|
2
8
|
const translate = {
|
|
3
|
-
|
|
4
|
-
|
|
9
|
+
/*
|
|
10
|
+
* 当前的版本
|
|
11
|
+
*/
|
|
12
|
+
version: '2.6.0.20230816',
|
|
13
|
+
useVersion: 'v1', //当前使用的版本,默认使用v1. 可使用 setUseVersion2(); //来设置使用v2
|
|
5
14
|
setUseVersion2: function () {
|
|
6
|
-
translate.useVersion =
|
|
15
|
+
translate.useVersion = 'v2';
|
|
7
16
|
},
|
|
17
|
+
/*
|
|
18
|
+
* 翻译的对象,也就是 new google.translate.TranslateElement(...)
|
|
19
|
+
*/
|
|
8
20
|
translate: null,
|
|
9
|
-
|
|
10
|
-
|
|
21
|
+
/*
|
|
22
|
+
* 支持哪些语言切换,包括:de,hi,lt,hr,lv,ht,hu,zh-CN,hy,uk,mg,id,ur,mk,ml,mn,af,mr,uz,ms,el,mt,is,it,my,es,et,eu,ar,pt-PT,ja,ne,az,fa,ro,nl,en-GB,no,be,fi,ru,bg,fr,bs,sd,se,si,sk,sl,ga,sn,so,gd,ca,sq,sr,kk,st,km,kn,sv,ko,sw,gl,zh-TW,pt-BR,co,ta,gu,ky,cs,pa,te,tg,th,la,cy,pl,da,tr
|
|
23
|
+
* 已废弃,请使用 translate.selectLanguageTag.languages
|
|
24
|
+
*/
|
|
25
|
+
includedLanguages: 'zh-CN,zh-TW,en',
|
|
26
|
+
/*
|
|
27
|
+
* 资源文件url的路径
|
|
28
|
+
*/
|
|
29
|
+
resourcesUrl: '//res.zvo.cn/translate',
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 默认出现的选择语言的 select 选择框,可以通过这个选择切换语言。
|
|
33
|
+
*/
|
|
11
34
|
selectLanguageTag: {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
translate.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
a = document.createElement("select");
|
|
35
|
-
a.id = "translateSelectLanguage", a.className = "translateSelectLanguage";
|
|
36
|
-
for (var n = 0; n < e.list.length; n++) {
|
|
37
|
-
var l = document.createElement("option");
|
|
38
|
-
if (l.setAttribute("value", e.list[n].id), translate.selectLanguageTag.languages
|
|
39
|
-
.length > 0) {
|
|
40
|
-
var r = ("," + translate.selectLanguageTag.languages + ",").toLowerCase();
|
|
41
|
-
if (console.log(r), r.indexOf("," + e.list[n].id.toLowerCase() + ",") <
|
|
42
|
-
0) continue
|
|
43
|
-
}
|
|
44
|
-
null != translate.to && void 0 !== translate.to && translate.to.length > 0 ?
|
|
45
|
-
translate.to == e.list[n].id && l.setAttribute("selected", "selected") :
|
|
46
|
-
e.list[n].id == translate.language.getLocal() && l.setAttribute(
|
|
47
|
-
"selected", "selected"), l.appendChild(document.createTextNode(e.list[
|
|
48
|
-
n].name)), a.appendChild(l)
|
|
49
|
-
}
|
|
50
|
-
window.addEventListener ? a.addEventListener("change", t, !1) : a.attachEvent(
|
|
51
|
-
"onchange", t), document.getElementById("translate").appendChild(a)
|
|
52
|
-
} else console.log("load language list error : " + e.info)
|
|
53
|
-
})
|
|
35
|
+
/* 是否显示 select选择语言的选择框,true显示; false不显示。默认为true */
|
|
36
|
+
show: true,
|
|
37
|
+
/*
|
|
38
|
+
支持哪些语言切换
|
|
39
|
+
v1.x 版本包括:de,hi,lt,hr,lv,ht,hu,zh-CN,hy,uk,mg,id,ur,mk,ml,mn,af,mr,uz,ms,el,mt,is,it,my,es,et,eu,ar,pt-PT,ja,ne,az,fa,ro,nl,en-GB,no,be,fi,ru,bg,fr,bs,sd,se,si,sk,sl,ga,sn,so,gd,ca,sq,sr,kk,st,km,kn,sv,ko,sw,gl,zh-TW,pt-BR,co,ta,gu,ky,cs,pa,te,tg,th,la,cy,pl,da,tr
|
|
40
|
+
v2.x 版本根据后端翻译服务不同,支持的语言也不同。具体支持哪些,可通过 http://api.translate.zvo.cn/doc/language.json.html 获取 (如果您私有部署的,将请求域名换为您自己私有部署的域名)
|
|
41
|
+
*/
|
|
42
|
+
languages: '',
|
|
43
|
+
alreadyRender: false, //当前是否已渲染过了 true为是 v2.2增加
|
|
44
|
+
selectOnChange: function (event) {
|
|
45
|
+
var language = event.target.value;
|
|
46
|
+
translate.changeLanguage(language);
|
|
47
|
+
},
|
|
48
|
+
render: function () { //v2增加
|
|
49
|
+
if (translate.selectLanguageTag.alreadyRender) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
translate.selectLanguageTag.alreadyRender = true;
|
|
53
|
+
|
|
54
|
+
//判断如果不显示select选择语言,直接就隐藏掉
|
|
55
|
+
if (!translate.selectLanguageTag.show) {
|
|
56
|
+
return;
|
|
54
57
|
}
|
|
58
|
+
|
|
59
|
+
//判断translate 的id是否存在,不存在就创建一个
|
|
60
|
+
if (document.getElementById('translate') == null) {
|
|
61
|
+
var body_trans = document.getElementsByTagName('body')[0];
|
|
62
|
+
var div = document.createElement("div"); //创建一个script标签
|
|
63
|
+
div.id = "translate";
|
|
64
|
+
body_trans.appendChild(div);
|
|
65
|
+
} else {
|
|
66
|
+
//存在,那么判断一下 select是否存在,要是存在就不重复创建了
|
|
67
|
+
if (document.getElementById('translateSelectLanguage') != null) {
|
|
68
|
+
//select存在了,就不重复创建了
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//从服务器加载支持的语言库
|
|
74
|
+
translate.request.post(translate.request.api.host + translate.request.api.language + '?v=' + translate.version, {}, function (data) {
|
|
75
|
+
if (data.result == 0) {
|
|
76
|
+
console.log('load language list error : ' + data.info);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
//select的onchange事件
|
|
81
|
+
var onchange = function (event) { translate.selectLanguageTag.selectOnChange(event); }
|
|
82
|
+
|
|
83
|
+
//创建 select 标签
|
|
84
|
+
var selectLanguage = document.createElement("select");
|
|
85
|
+
selectLanguage.id = 'translateSelectLanguage';
|
|
86
|
+
selectLanguage.className = 'translateSelectLanguage';
|
|
87
|
+
for (var i = 0; i < data.list.length; i++) {
|
|
88
|
+
var option = document.createElement("option");
|
|
89
|
+
option.setAttribute("value", data.list[i].id);
|
|
90
|
+
|
|
91
|
+
//判断 selectLanguageTag.languages 中允许使用哪些
|
|
92
|
+
|
|
93
|
+
if (translate.selectLanguageTag.languages.length > 0) {
|
|
94
|
+
//设置了自定义显示的语言
|
|
95
|
+
|
|
96
|
+
//都转小写判断
|
|
97
|
+
var langs_indexof = (',' + translate.selectLanguageTag.languages + ',').toLowerCase();
|
|
98
|
+
console.log(langs_indexof)
|
|
99
|
+
if (langs_indexof.indexOf(',' + data.list[i].id.toLowerCase() + ',') < 0) {
|
|
100
|
+
//没发现,那不显示这个语种,调出
|
|
101
|
+
continue
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/*判断默认要选中哪个语言*/
|
|
106
|
+
if (translate.to != null && typeof (translate.to) != 'undefined' && translate.to.length > 0) {
|
|
107
|
+
//设置了目标语言,那就进行判断显示目标语言
|
|
108
|
+
|
|
109
|
+
if (translate.to == data.list[i].id) {
|
|
110
|
+
option.setAttribute("selected", 'selected');
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
//没设置目标语言,那默认选中当前本地的语种
|
|
114
|
+
if (data.list[i].id == translate.language.getLocal()) {
|
|
115
|
+
option.setAttribute("selected", 'selected');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
option.appendChild(document.createTextNode(data.list[i].name));
|
|
120
|
+
selectLanguage.appendChild(option);
|
|
121
|
+
}
|
|
122
|
+
//增加 onchange 事件
|
|
123
|
+
if (window.addEventListener) { // Mozilla, Netscape, Firefox
|
|
124
|
+
selectLanguage.addEventListener('change', onchange, false);
|
|
125
|
+
} else { // IE
|
|
126
|
+
selectLanguage.attachEvent('onchange', onchange);
|
|
127
|
+
}
|
|
128
|
+
//将select加入进网页显示
|
|
129
|
+
document.getElementById('translate').appendChild(selectLanguage);
|
|
130
|
+
/*
|
|
131
|
+
try{
|
|
132
|
+
document.getElementById('translateSelectLanguage').style.width = '94px';
|
|
133
|
+
}catch(e){ console.log(e);}
|
|
134
|
+
*/
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
|
|
55
138
|
}
|
|
56
139
|
},
|
|
57
|
-
|
|
140
|
+
|
|
141
|
+
/*
|
|
142
|
+
* 当前本地语言
|
|
143
|
+
*/
|
|
144
|
+
//localLanguage:'zh-CN',
|
|
145
|
+
localLanguage: 'zh-CN',
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* google翻译执行的
|
|
149
|
+
*/
|
|
58
150
|
googleTranslateElementInit: function () {
|
|
59
|
-
var
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
151
|
+
var selectId = '';
|
|
152
|
+
if (document.getElementById('translate') != null) { // && document.getElementById('translate').innerHTML.indexOf('translateSelectLanguage') > 0
|
|
153
|
+
//已经创建过了,存在
|
|
154
|
+
selectId = 'translate';
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
translate.translate = new google.translate.TranslateElement(
|
|
158
|
+
{
|
|
159
|
+
//这参数没用,请忽略
|
|
160
|
+
pageLanguage: 'zh-CN',
|
|
161
|
+
//一共80种语言选择,这个是你需要翻译的语言,比如你只需要翻译成越南和英语,这里就只写en,vi
|
|
162
|
+
//includedLanguages: 'de,hi,lt,hr,lv,ht,hu,zh-CN,hy,uk,mg,id,ur,mk,ml,mn,af,mr,uz,ms,el,mt,is,it,my,es,et,eu,ar,pt-PT,ja,ne,az,fa,ro,nl,en-GB,no,be,fi,ru,bg,fr,bs,sd,se,si,sk,sl,ga,sn,so,gd,ca,sq,sr,kk,st,km,kn,sv,ko,sw,gl,zh-TW,pt-BR,co,ta,gu,ky,cs,pa,te,tg,th,la,cy,pl,da,tr',
|
|
63
163
|
includedLanguages: translate.selectLanguageTag.languages,
|
|
64
|
-
|
|
65
|
-
|
|
164
|
+
//选择语言的样式,这个是面板,还有下拉框的样式,具体的记不到了,找不到api~~
|
|
165
|
+
layout: 0,
|
|
166
|
+
//自动显示翻译横幅,就是翻译后顶部出现的那个,有点丑,设置这个属性不起作用的话,请看文章底部的其他方法
|
|
167
|
+
//autoDisplay: false,
|
|
168
|
+
//disableAutoTranslation:false,
|
|
169
|
+
//还有些其他参数,由于原插件不再维护,找不到详细api了,将就了,实在不行直接上dom操作
|
|
170
|
+
},
|
|
171
|
+
selectId //触发按钮的id
|
|
172
|
+
);
|
|
66
173
|
},
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* 初始化,如加载js、css资源
|
|
177
|
+
*/
|
|
67
178
|
init: function () {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
179
|
+
/****** 先判断当前协议,定义资源路径 ******/
|
|
180
|
+
var protocol = window.location.protocol;
|
|
181
|
+
if (window.location.protocol == 'file:') {
|
|
182
|
+
//本地的,那就用http
|
|
183
|
+
protocol = 'http:';
|
|
184
|
+
}
|
|
185
|
+
if (this.resourcesUrl.indexOf('://') == -1) {
|
|
186
|
+
//还没设置过,进行设置
|
|
187
|
+
this.resourcesUrl = protocol + this.resourcesUrl;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
//this.resourcesUrl = 'file://G:/git/translate';
|
|
191
|
+
|
|
71
192
|
},
|
|
193
|
+
/**
|
|
194
|
+
* 执行翻译操作
|
|
195
|
+
*/
|
|
72
196
|
execute_v1: function () {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
197
|
+
/*********** 判断translate 的id是否存在,不存在就创建一个 */
|
|
198
|
+
if (document.getElementById('translate') == null) {
|
|
199
|
+
if (translate.selectLanguageTag.show) {
|
|
200
|
+
var body_trans = document.getElementsByTagName('body')[0];
|
|
201
|
+
var div = document.createElement("div"); //创建一个script标签
|
|
202
|
+
div.id = "translate";
|
|
203
|
+
body_trans.appendChild(div);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* 处理1.0 - 1.1 升级的 */
|
|
208
|
+
if (translate.includedLanguages == '') {
|
|
209
|
+
//如果未设置,用默认的
|
|
210
|
+
translate.selectLanguageTag.languages = translate.includedLanguages;
|
|
211
|
+
}
|
|
212
|
+
/* 用户1.0版本设置过这个,那么就以这个为主 */
|
|
213
|
+
console.log('translate.js tip: translate.includedLanguages obsolete, please use the translate.selectLanguageTag.languages are set');
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
/****** 先加载资源 ******/
|
|
217
|
+
var head0 = document.getElementsByTagName('head')[0];
|
|
218
|
+
var script = document.createElement("script"); //创建一个script标签
|
|
219
|
+
script.type = "text/javascript";
|
|
220
|
+
//script.async = true;
|
|
221
|
+
script.src = this.resourcesUrl + '/js/element.js';
|
|
222
|
+
head0.appendChild(script);
|
|
85
223
|
},
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* 设置Cookie,失效时间一年。
|
|
227
|
+
* @param name
|
|
228
|
+
* @param value
|
|
229
|
+
*/
|
|
230
|
+
setCookie: function (name, value) {
|
|
231
|
+
var cookieString = name + "=" + escape(value);
|
|
232
|
+
document.cookie = cookieString;
|
|
89
233
|
},
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
234
|
+
|
|
235
|
+
//获取Cookie。若是不存再,返回空字符串
|
|
236
|
+
getCookie: function (name) {
|
|
237
|
+
var strCookie = document.cookie;
|
|
238
|
+
var arrCookie = strCookie.split("; ");
|
|
239
|
+
for (var i = 0; i < arrCookie.length; i++) {
|
|
240
|
+
var arr = arrCookie[i].split("=");
|
|
241
|
+
if (arr[0] == name) {
|
|
242
|
+
return unescape(arr[1]);
|
|
243
|
+
}
|
|
94
244
|
}
|
|
95
|
-
return ""
|
|
245
|
+
return "";
|
|
96
246
|
},
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* 获取当前页面采用的是什么语言
|
|
250
|
+
* 返回值如 en、zh-CN、zh-TW (如果是第一次用,没有设置过,那么返回的是 translate.localLanguage 设置的值)
|
|
251
|
+
*/
|
|
97
252
|
currentLanguage: function () {
|
|
98
|
-
translate.check();
|
|
99
|
-
var
|
|
100
|
-
|
|
253
|
+
//translate.check();
|
|
254
|
+
var cookieValue = translate.getCookie('googtrans');
|
|
255
|
+
if (cookieValue.length > 0) {
|
|
256
|
+
return cookieValue.substr(cookieValue.lastIndexOf('/') + 1, cookieValue.length - 1);
|
|
257
|
+
} else {
|
|
258
|
+
return translate.localLanguage;
|
|
259
|
+
}
|
|
101
260
|
},
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* 切换语言,比如切换为英语、法语
|
|
264
|
+
* @param languageName 要切换的语言语种。传入如 en、zh-CN
|
|
265
|
+
* 会自动根据传入的语言来判断使用哪种版本。比如传入 en、zh-CN 等,则会使用v1.x版本
|
|
266
|
+
* 传入 chinese_simplified 、english 等,则会使用 v2.x版本
|
|
267
|
+
*/
|
|
268
|
+
changeLanguage: function (languageName) {
|
|
269
|
+
//判断使用的是否是v1.x
|
|
270
|
+
var v1 = ',en,de,hi,lt,hr,lv,ht,hu,zh-CN,hy,uk,mg,id,ur,mk,ml,mn,af,mr,uz,ms,el,mt,is,it,my,es,et,eu,ar,pt-PT,ja,ne,az,fa,ro,nl,en-GB,no,be,fi,ru,bg,fr,bs,sd,se,si,sk,sl,ga,sn,so,gd,ca,sq,sr,kk,st,km,kn,sv,ko,sw,gl,zh-TW,pt-BR,co,ta,gu,ky,cs,pa,te,tg,th,la,cy,pl,da,tr,';
|
|
271
|
+
if (v1.indexOf(',' + languageName + ',') > -1) {
|
|
272
|
+
//用的是v1.x
|
|
273
|
+
console.log('您使用的是v1版本的切换语种方式,v1已在2021年就以废弃,请更换为v2,参考文档: http://translate.zvo.cn/41549.html');
|
|
106
274
|
translate.check();
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
275
|
+
|
|
276
|
+
var googtrans = '/' + translate.localLanguage + '/' + languageName;
|
|
277
|
+
|
|
278
|
+
//先清空泛解析域名的设置
|
|
279
|
+
var s = document.location.host.split('.');
|
|
280
|
+
if (s.length > 2) {
|
|
281
|
+
var fanDomain = s[s.length - 2] + '.' + s[s.length - 1];
|
|
282
|
+
document.cookie = 'googtrans=;expires=' + (new Date(1)) + ';domain=' + fanDomain + ';path=/';
|
|
283
|
+
document.cookie = 'googtrans=' + googtrans + ';domain=' + fanDomain + ';path=/';
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
translate.setCookie('googtrans', '' + googtrans);
|
|
287
|
+
location.reload();
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
//用的是v2.x或更高
|
|
292
|
+
translate.setUseVersion2();
|
|
293
|
+
//判断是否是第一次翻译,如果是,那就不用刷新页面了。 true则是需要刷新,不是第一次翻译
|
|
294
|
+
if (translate.to != null && translate.to.length > 0) {
|
|
295
|
+
//当前目标值有值,且目标语言跟当前语言不一致,那当前才是已经被翻译过的
|
|
296
|
+
if (translate.to != translate.language.getLocal()) {
|
|
297
|
+
var isReload = true; //标记要刷新页面
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
translate.to = languageName;
|
|
303
|
+
translate.storage.set('to', languageName); //设置目标翻译语言
|
|
304
|
+
|
|
305
|
+
if (isReload) {
|
|
306
|
+
location.reload(); //刷新页面
|
|
307
|
+
} else {
|
|
308
|
+
//不用刷新,直接翻译
|
|
309
|
+
translate.execute(); //翻译
|
|
310
|
+
}
|
|
119
311
|
},
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* 自检提示,适用于 v1.x, 在 v2.x中已废弃
|
|
315
|
+
*/
|
|
120
316
|
check: function () {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
317
|
+
if (window.location.protocol == 'file:') {
|
|
318
|
+
console.log('\r\n---WARNING----\r\ntranslate.js 主动翻译组件自检异常,当前协议是file协议,翻译组件要在正常的线上http、https协议下才能正常使用翻译功能\r\n------------');
|
|
319
|
+
}
|
|
124
320
|
},
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
/**************************** v2.0 */
|
|
324
|
+
to: '', //翻译为的目标语言,如 english 、chinese_simplified
|
|
325
|
+
//用户第一次打开网页时,自动判断当前用户所在国家使用的是哪种语言,来自动进行切换为用户所在国家的语种。
|
|
326
|
+
//如果使用后,第二次在用,那就优先以用户所选择的为主,这个就不管用了
|
|
327
|
+
//默认是false,不使用,可设置true:使用
|
|
328
|
+
//使用 setAutoDiscriminateLocalLanguage 进行设置
|
|
329
|
+
autoDiscriminateLocalLanguage: false,
|
|
330
|
+
documents: [], //指定要翻译的元素的集合,可设置多个,如设置: document.getElementsByTagName('DIV')
|
|
331
|
+
//翻译时忽略的一些东西,比如忽略某个tag、某个class等
|
|
128
332
|
ignore: {
|
|
129
|
-
tag: [
|
|
130
|
-
class: [
|
|
333
|
+
tag: ['style', 'script', 'link', 'pre', 'code'],
|
|
334
|
+
class: ['ignore', 'translateSelectLanguage'],
|
|
131
335
|
id: [],
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
336
|
+
/*
|
|
337
|
+
传入一个元素,判断这个元素是否是被忽略的元素。 这个会找父类,看看父类中是否包含在忽略的之中。
|
|
338
|
+
return true是在忽略的之中,false不再忽略的之中
|
|
339
|
+
*/
|
|
340
|
+
isIgnore: function (ele) {
|
|
341
|
+
if (ele == null || typeof (ele) == 'undefined') {
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
var parentNode = ele;
|
|
346
|
+
var maxnumber = 100; //最大循环次数,避免死循环
|
|
347
|
+
while (maxnumber-- > 0) {
|
|
348
|
+
if (parentNode == null || typeof (parentNode) == 'undefined') {
|
|
349
|
+
//没有父元素了
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
//判断Tag
|
|
354
|
+
//var tagName = parentNode.nodeName.toLowerCase(); //tag名字,小写
|
|
355
|
+
var nodename = translate.element.getNodeName(parentNode).toLowerCase(); //tag名字,小写
|
|
356
|
+
if (nodename.length > 0) {
|
|
357
|
+
//有nodename
|
|
358
|
+
if (nodename == 'body' || nodename == 'html' || nodename == '#document') {
|
|
359
|
+
//上层元素已经是顶级元素了,那肯定就不是了
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
if (translate.ignore.tag.indexOf(nodename) > -1) {
|
|
363
|
+
//发现ignore.tag 当前是处于被忽略的 tag
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
//判断class name
|
|
370
|
+
if (parentNode.className != null) {
|
|
371
|
+
var classNames = parentNode.className;
|
|
372
|
+
if (classNames == null || typeof (classNames) != 'string') {
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
//console.log('className:'+typeof(classNames));
|
|
376
|
+
//console.log(classNames);
|
|
377
|
+
classNames = classNames.trim().split(' ');
|
|
378
|
+
for (var c_index = 0; c_index < classNames.length; c_index++) {
|
|
379
|
+
if (classNames[c_index] != null && classNames[c_index].trim().length > 0) {
|
|
380
|
+
//有效的class name,进行判断
|
|
381
|
+
if (translate.ignore.class.indexOf(classNames[c_index]) > -1) {
|
|
382
|
+
//发现ignore.class 当前是处于被忽略的 class
|
|
383
|
+
return true;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
//判断id
|
|
390
|
+
if (parentNode.id != null && typeof (parentNode.id) != 'undefined') {
|
|
391
|
+
//有效的class name,进行判断
|
|
392
|
+
if (translate.ignore.id.indexOf(parentNode.id) > -1) {
|
|
393
|
+
//发现ignore.id 当前是处于被忽略的 id
|
|
394
|
+
return true;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
//赋予判断的元素向上一级
|
|
399
|
+
parentNode = parentNode.parentNode;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
return false;
|
|
153
403
|
}
|
|
154
404
|
},
|
|
405
|
+
//自定义翻译术语
|
|
155
406
|
nomenclature: {
|
|
156
|
-
|
|
407
|
+
/*
|
|
408
|
+
术语表
|
|
409
|
+
一维:要转换的语种,如 english
|
|
410
|
+
二维:翻译至的目标语种,如 english
|
|
411
|
+
三维:要转换的字符串,如 "你好"
|
|
412
|
+
结果:自定义的翻译结果,如 “Hallo”
|
|
413
|
+
*/
|
|
414
|
+
data: new Array(),
|
|
415
|
+
|
|
416
|
+
/*
|
|
417
|
+
原始术语表,可编辑的
|
|
418
|
+
一维:要自定义目标词
|
|
419
|
+
二维:针对的是哪个语种
|
|
420
|
+
值:要翻译为什么内容
|
|
421
|
+
|
|
422
|
+
其设置如
|
|
423
|
+
var data = new Array();
|
|
424
|
+
data['版本'] = {
|
|
425
|
+
english : 'banben',
|
|
426
|
+
korean : 'BanBen'
|
|
427
|
+
};
|
|
428
|
+
data['国际化'] = {
|
|
429
|
+
english : 'guojihua',
|
|
430
|
+
korean : 'GuoJiHua'
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
【已过时】
|
|
434
|
+
*/
|
|
157
435
|
old_Data: [],
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
)
|
|
436
|
+
/*
|
|
437
|
+
set:function(data){
|
|
438
|
+
translate.nomenclature.data = data;
|
|
162
439
|
},
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
440
|
+
*/
|
|
441
|
+
set: function (data) {
|
|
442
|
+
alert('请将 translate.nomenclature.set 更换为 append,具体使用可参考: https://github.com/xnx3/translate ');
|
|
443
|
+
},
|
|
444
|
+
/*
|
|
445
|
+
向当前术语库中追加自定义术语。如果追加的数据重复,会自动去重
|
|
446
|
+
传入参数:
|
|
447
|
+
from 要转换的语种
|
|
448
|
+
to 翻译至的目标语种
|
|
449
|
+
properties 属于配置表,格式如:
|
|
450
|
+
你好=Hello
|
|
451
|
+
世界=ShiJie
|
|
452
|
+
|
|
453
|
+
*/
|
|
454
|
+
append: function (from, to, properties) {
|
|
455
|
+
if (typeof (translate.nomenclature.data[from]) == 'undefined') {
|
|
456
|
+
translate.nomenclature.data[from] = new Array();
|
|
457
|
+
}
|
|
458
|
+
if (typeof (translate.nomenclature.data[from][to]) == 'undefined') {
|
|
459
|
+
translate.nomenclature.data[from][to] = new Array();
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
//将properties进行分析
|
|
463
|
+
//按行拆分
|
|
464
|
+
var line = properties.split('\n');
|
|
465
|
+
//console.log(line)
|
|
466
|
+
for (var line_index = 0; line_index < line.length; line_index++) {
|
|
467
|
+
var item = line[line_index].trim();
|
|
468
|
+
if (item.length < 1) {
|
|
469
|
+
//空行,忽略
|
|
470
|
+
continue;
|
|
175
471
|
}
|
|
472
|
+
var kvs = item.split('=');
|
|
473
|
+
//console.log(kvs)
|
|
474
|
+
if (kvs.length != 2) {
|
|
475
|
+
//不是key、value构成的,忽略
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
var key = kvs[0].trim();
|
|
479
|
+
var value = kvs[1].trim();
|
|
480
|
+
//console.log(key)
|
|
481
|
+
if (key.length == 0 || value.length == 0) {
|
|
482
|
+
//其中某个有空,则忽略
|
|
483
|
+
continue;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
//加入,如果之前有加入,则会覆盖
|
|
488
|
+
translate.nomenclature.data[from][to][key] = value;
|
|
489
|
+
//console.log(local+', '+target+', key:'+key+', value:'+value);
|
|
176
490
|
}
|
|
491
|
+
|
|
492
|
+
//追加完后,对整个对象数组进行排序,key越大越在前面
|
|
493
|
+
translate.nomenclature.data[from][to] = translate.util.objSort(translate.nomenclature.data[from][to]);
|
|
494
|
+
|
|
177
495
|
},
|
|
496
|
+
//获取当前定义的术语表
|
|
178
497
|
get: function () {
|
|
179
|
-
return translate.nomenclature.data
|
|
180
|
-
},
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
498
|
+
return translate.nomenclature.data;
|
|
499
|
+
},
|
|
500
|
+
//对传入的str字符进行替换,将其中的自定义术语提前进行替换,然后将替换后的结果返回
|
|
501
|
+
dispose: function (str) {
|
|
502
|
+
if (str == null || str.length == 0) {
|
|
503
|
+
return str;
|
|
504
|
+
}
|
|
505
|
+
//if(translate.nomenclature.data.length == 0){
|
|
506
|
+
// return str;
|
|
507
|
+
//}
|
|
508
|
+
//判断当前翻译的两种语种是否有自定义术语库
|
|
509
|
+
//console.log(typeof(translate.nomenclature.data[translate.language.getLocal()][translate.to]))
|
|
510
|
+
if (typeof (translate.nomenclature.data[translate.language.getLocal()]) == 'undefined' || typeof (translate.nomenclature.data[translate.language.getLocal()][translate.to]) == 'undefined') {
|
|
511
|
+
return str;
|
|
512
|
+
}
|
|
513
|
+
//console.log(str)
|
|
514
|
+
for (var originalText in translate.nomenclature.data[translate.language.getLocal()][translate.to]) {
|
|
515
|
+
var translateText = translate.nomenclature.data[translate.language.getLocal()][translate.to][originalText];
|
|
516
|
+
if (typeof (translateText) == 'function') {
|
|
517
|
+
//进行异常的预处理调出
|
|
518
|
+
continue;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
var index = str.indexOf(originalText);
|
|
522
|
+
if (index > -1) {
|
|
523
|
+
//console.log('find -- '+originalText+', \t'+translateText);
|
|
524
|
+
if (translate.language.getLocal() == 'english') {
|
|
525
|
+
//如果本地语种是英文,那么还要判断它的前后,避免比如要替换 is 将 display 中的is给替换,将单词给强行拆分了
|
|
526
|
+
|
|
527
|
+
//判断这个词前面是否符合
|
|
528
|
+
var beforeChar = ''; //前面的字符
|
|
529
|
+
if (index == 0) {
|
|
530
|
+
//前面没别的字符了,那前面合适
|
|
531
|
+
} else {
|
|
532
|
+
//前面有别的字符,判断是什么字符,如果是英文,那么这个是不能被拆分的,要忽略
|
|
533
|
+
beforeChar = str.substr(index - 1, 1);
|
|
534
|
+
//console.log('beforeChar:'+beforeChar+', str:'+str)
|
|
535
|
+
var lang = translate.language.getCharLanguage(beforeChar);
|
|
536
|
+
//console.log(lang);
|
|
537
|
+
if (lang == 'english') {
|
|
538
|
+
//调出,不能强拆
|
|
539
|
+
continue;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
//判断这个词的后面是否符合
|
|
544
|
+
var afterChar = ''; //后面的字符
|
|
545
|
+
if (index + originalText.length == str.length) {
|
|
546
|
+
//后面没别的字符了,那前面合适
|
|
547
|
+
//console.log(originalText+', meile '+str)
|
|
548
|
+
} else {
|
|
549
|
+
//后面有别的字符,判断是什么字符,如果是英文,那么这个是不能被拆分的,要忽略
|
|
550
|
+
afterChar = str.substr(index + originalText.length, 1);
|
|
551
|
+
var lang = translate.language.getCharLanguage(afterChar);
|
|
552
|
+
if (lang == 'english') {
|
|
553
|
+
//跳出,不能强拆
|
|
194
554
|
continue;
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
str = str.replace(new RegExp(beforeChar + originalText + afterChar, 'g'), beforeChar + translateText + afterChar);
|
|
559
|
+
} else {
|
|
560
|
+
//其他情况,如汉语、汉语等语种
|
|
561
|
+
str = str.replace(new RegExp(originalText, 'g'), translateText);
|
|
562
|
+
}
|
|
563
|
+
|
|
201
564
|
}
|
|
202
565
|
}
|
|
203
|
-
|
|
204
|
-
|
|
566
|
+
|
|
567
|
+
return str;
|
|
568
|
+
|
|
569
|
+
/*
|
|
570
|
+
//遍历一维
|
|
571
|
+
for(var originalText in translate.nomenclature.data){
|
|
572
|
+
var languageResult = translate.nomenclature.data[originalText];
|
|
573
|
+
if(typeof(languageResult) == 'function'){
|
|
574
|
+
//进行异常的预处理调出
|
|
575
|
+
continue;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
if(typeof(languageResult[translate.to]) == 'undefined'){
|
|
579
|
+
//console.log('und');
|
|
580
|
+
continue;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
//var hash = translate.util.hash(originalText);
|
|
584
|
+
|
|
585
|
+
//console.log(originalText+',\t'+str);
|
|
586
|
+
if(str.indexOf(originalText) > -1){
|
|
587
|
+
//console.log('find -- '+originalText+', \t'+languageResult[translate.to]);
|
|
588
|
+
str = str.replace(new RegExp(originalText,'g'),languageResult[translate.to]);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
return str;
|
|
594
|
+
*/
|
|
595
|
+
},
|
|
596
|
+
|
|
597
|
+
},
|
|
598
|
+
office: {
|
|
599
|
+
/*
|
|
600
|
+
网页上翻译之后,自动导出当前页面的术语库
|
|
601
|
+
|
|
602
|
+
需要先指定本地语种,会自动将本地语种进行配置术语库
|
|
603
|
+
|
|
604
|
+
*/
|
|
605
|
+
export: function () {
|
|
606
|
+
if (translate.language.getLocal() == translate.language.getCurrent()) {
|
|
607
|
+
alert('本地语种跟要翻译的语种一致,无需导出');
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
var text = '';
|
|
612
|
+
for (var uuid in translate.nodeQueue) {
|
|
613
|
+
var queueValue = translate.nodeQueue[uuid];
|
|
614
|
+
for (var lang in translate.nodeQueue[uuid].list) {
|
|
615
|
+
//console.log('------'+lang)
|
|
616
|
+
if (typeof (lang) != 'string' || lang.length < 1) {
|
|
617
|
+
continue;
|
|
618
|
+
}
|
|
619
|
+
//if(translate.language.getLocal() == lang){
|
|
620
|
+
//console.log(translate.nodeQueue[uuid].list[lang]);
|
|
621
|
+
for (var hash in translate.nodeQueue[uuid].list[lang]) {
|
|
622
|
+
//console.log(translate.nodeQueue[uuid].list[lang][hash].original);
|
|
623
|
+
//console.log(translate.nodeQueue[uuid].list[lang][hash].original);
|
|
624
|
+
text = text + '\n' + translate.nodeQueue[uuid].list[lang][hash].original + '=' + translate.storage.get('hash_' + translate.language.getCurrent() + '_' + hash);
|
|
625
|
+
|
|
626
|
+
}
|
|
627
|
+
//}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
if (text.length > 0) {
|
|
633
|
+
//有内容
|
|
634
|
+
text = 'translate.office.append(\'' + translate.language.getCurrent() + '\',`' + text + '\n`);';
|
|
635
|
+
//console.log(text);
|
|
636
|
+
translate.util.loadMsgJs();
|
|
637
|
+
msg.popups({
|
|
638
|
+
text: '<textarea id="msgPopupsTextarea" style="width:100%; height:100%;">loaing...</textarea>',
|
|
639
|
+
width: '750px',
|
|
640
|
+
height: '600px',
|
|
641
|
+
padding: '1px',
|
|
642
|
+
});
|
|
643
|
+
document.getElementById('msgPopupsTextarea').value = text;
|
|
644
|
+
} else {
|
|
645
|
+
msg.alert('无有效内容');
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
},
|
|
650
|
+
//显示导出面板
|
|
651
|
+
showPanel: function () {
|
|
652
|
+
let panel = document.createElement('div');
|
|
653
|
+
panel.setAttribute('id', 'translate_export');
|
|
654
|
+
panel.setAttribute('class', 'ignore');
|
|
655
|
+
|
|
656
|
+
//导出按钮
|
|
657
|
+
let button = document.createElement('button');
|
|
658
|
+
button.onclick = function () {
|
|
659
|
+
translate.office.export();
|
|
660
|
+
};
|
|
661
|
+
button.innerHTML = '导出配置信息';
|
|
662
|
+
button.setAttribute('style', 'margin-left: 72px; margin-top: 30px; margin-bottom: 20px; font-size: 25px;');
|
|
663
|
+
panel.appendChild(button);
|
|
664
|
+
|
|
665
|
+
//说明文字
|
|
666
|
+
let textdiv = document.createElement('div');
|
|
667
|
+
textdiv.innerHTML = '1. 首先将当前语种切换为你要翻译的语种<br/>2. 点击导出按钮,将翻译的配置信息导出<br/>3. 将导出的配置信息粘贴到代码中,即可完成<br/><a href="asd" target="_black" style="color: aliceblue;">点此进行查阅详细使用说明</a>';
|
|
668
|
+
textdiv.setAttribute('style', 'font-size: 14px; padding: 12px;');
|
|
669
|
+
|
|
670
|
+
panel.appendChild(textdiv);
|
|
671
|
+
|
|
672
|
+
panel.setAttribute('style', 'background-color: black; color: #fff; width: 320px; height: 200px; position: fixed; bottom: 50px; right: 50px;');
|
|
673
|
+
//把元素节点添加到body元素节点中成为其子节点,放在body的现有子节点的最后
|
|
674
|
+
document.body.appendChild(panel);
|
|
675
|
+
|
|
676
|
+
translate.util.loadMsgJs();
|
|
677
|
+
},
|
|
678
|
+
/*
|
|
679
|
+
追加离线翻译数据。如果追加的数据重复,会自动去重
|
|
680
|
+
传入参数:
|
|
681
|
+
from 要转换的语种
|
|
682
|
+
to 翻译至的目标语种
|
|
683
|
+
properties 属于配置表,格式如:
|
|
684
|
+
你好=Hello
|
|
685
|
+
世界=ShiJie
|
|
686
|
+
这个传入参数跟 translate.nomenclature.append 的传入参数格式是一致的
|
|
687
|
+
*/
|
|
688
|
+
append: function (to, properties) {
|
|
689
|
+
//console.log(properties)
|
|
690
|
+
//将properties进行分析
|
|
691
|
+
//按行拆分
|
|
692
|
+
var line = properties.split('\n');
|
|
693
|
+
//console.log(line)
|
|
694
|
+
for (var line_index = 0; line_index < line.length; line_index++) {
|
|
695
|
+
var item = line[line_index].trim();
|
|
696
|
+
if (item.length < 1) {
|
|
697
|
+
//空行,忽略
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
700
|
+
var kvs = item.split('=');
|
|
701
|
+
//console.log(kvs)
|
|
702
|
+
if (kvs.length != 2) {
|
|
703
|
+
//不是key、value构成的,忽略
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
var key = kvs[0];
|
|
707
|
+
var value = kvs[1];
|
|
708
|
+
//console.log(key)
|
|
709
|
+
if (key.length == 0 || value.length == 0) {
|
|
710
|
+
//其中某个有空,则忽略
|
|
711
|
+
continue;
|
|
712
|
+
}
|
|
713
|
+
//console.log('set---'+key);
|
|
714
|
+
//加入 storate
|
|
715
|
+
translate.storage.set('hash_' + to + '_' + translate.util.hash(key), value);
|
|
716
|
+
}
|
|
717
|
+
},
|
|
205
718
|
},
|
|
206
719
|
setAutoDiscriminateLocalLanguage: function () {
|
|
207
|
-
translate.autoDiscriminateLocalLanguage =
|
|
720
|
+
translate.autoDiscriminateLocalLanguage = true;
|
|
208
721
|
},
|
|
722
|
+
/*
|
|
723
|
+
待翻译的页面的node队列
|
|
724
|
+
一维:key:uuid,也就是execute每次执行都会创建一个翻译队列,这个是翻译队列的唯一标识。
|
|
725
|
+
value:
|
|
726
|
+
k/v
|
|
727
|
+
二维:对象形态,具体有:
|
|
728
|
+
key:expireTime 当前一维数组key的过期时间,到达过期时间会自动删除掉这个一维数组。如果<0则代表永不删除,常驻内存
|
|
729
|
+
value:list 待翻译的页面的node队列
|
|
730
|
+
三维:针对二维的value, key:english、chinese_simplified等语种,这里的key便是对value的判断,取value中的要翻译的词是什么语种,对其进行了语种分类 value: k/v
|
|
731
|
+
四维:针对三维的value, key:要翻译的词(经过语种分割的)的hash, value: node数组
|
|
732
|
+
五维:针对四维的value, 这是个对象, 其中
|
|
733
|
+
original: 是三维的key的hash的原始文字,也就是 node 中的原始文字。
|
|
734
|
+
cacheHash: 如果翻译时匹配到了自定义术语库中的词,那么翻译完后存入到缓存中时,其缓存的翻译前字符串已经不是original,二是匹配完术语库后的文本的hash了。所以这里额外多增加了这个属性。如果匹配了术语库,那这里就是要进行缓存的翻译前文本的hash,如果未使用术语库,这里就跟其key-hash 相同。
|
|
735
|
+
translateText: 针对 original 的经过加工过的文字,比如经过自定义术语操作后的,待翻译的文字。
|
|
736
|
+
nodes: 有哪些node元素中包含了这个词,都会在这里记录
|
|
737
|
+
beforeText: node元素中进行翻译结果赋予时,额外在翻译结果的前面加上的字符串。其应用场景为,如果中英文混合场景下,避免中文跟英文挨着导致翻译为英语后,连到一块了。默认是空字符串 ''
|
|
738
|
+
afterText: node元素中进行翻译结果赋予时,额外在翻译结果的后面加上的字符串。其应用场景为,如果中英文混合场景下,避免中文跟英文挨着导致翻译为英语后,连到一块了。默认是空字符串 ''
|
|
739
|
+
六维:针对五维的 nodes,将各个具体的 node 以及 其操作的 attribute 以数组形式列出
|
|
740
|
+
七维:针对六维列出的nodes数组,其中包含:
|
|
741
|
+
node: 具体操作的node元素
|
|
742
|
+
attribute: 也就是翻译文本针对的是什么,是node本身(nodeValue),还是 node 的某个属性,比如title属性,这则是设置为 "title"。如果这里不为空,那就是针对的属性操作的。 如果这里为空或者undefined ,那就是针对node本身,也就是 nodeValue 的字符串操作的
|
|
743
|
+
|
|
744
|
+
生命周期: 当execute()执行时创建, 当execute结束(其中的所有request接收到响应并渲染完毕)时销毁(当前暂时不销毁,以方便调试)
|
|
745
|
+
*/
|
|
209
746
|
nodeQueue: {},
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
747
|
+
//指定要翻译的元素的集合,可传入一个元素或多个元素
|
|
748
|
+
//如设置一个元素,可传入如: document.getElementsById('test')
|
|
749
|
+
//如设置多个元素,可传入如: document.getElementsByTagName('DIV')
|
|
750
|
+
setDocuments: function (documents) {
|
|
751
|
+
if (documents == null || typeof (documents) == 'undefined') {
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
if (typeof (documents.length) == 'undefined') {
|
|
756
|
+
//不是数组,是单个元素
|
|
757
|
+
translate.documents[0] = documents;
|
|
758
|
+
} else {
|
|
759
|
+
//是数组,直接赋予
|
|
760
|
+
translate.documents = documents;
|
|
761
|
+
}
|
|
762
|
+
//清空翻译队列,下次翻译时重新检索
|
|
763
|
+
translate.nodeQueue = {};
|
|
764
|
+
console.log('set documents , clear translate.nodeQueue');
|
|
213
765
|
},
|
|
766
|
+
//获取当前指定翻译的元素(数组形式 [document,document,...])
|
|
767
|
+
//如果用户未使用setDocuments 指定的,那么返回整个网页
|
|
214
768
|
getDocuments: function () {
|
|
215
|
-
|
|
216
|
-
|
|
769
|
+
if (translate.documents != null && typeof (translate.documents) != 'undefined' && translate.documents.length > 0) {
|
|
770
|
+
// setDocuments 指定的
|
|
771
|
+
return translate.documents;
|
|
772
|
+
} else {
|
|
773
|
+
//未使用 setDocuments指定,那就是整个网页了
|
|
774
|
+
return document.all; //翻译所有的
|
|
775
|
+
}
|
|
217
776
|
},
|
|
218
777
|
listener: {
|
|
219
|
-
|
|
220
|
-
|
|
778
|
+
//当前页面打开后,是否已经执行完execute() 方法进行翻译了,只要执行完一次,这里便是true。 (多种语言的API请求完毕并已渲染html)
|
|
779
|
+
isExecuteFinish: false,
|
|
780
|
+
//是否已经使用了 translate.listener.start() 了,如果使用了,那这里为true,多次调用 translate.listener.start() 只有第一次有效
|
|
781
|
+
isStart: false,
|
|
782
|
+
//translate.listener.start(); //开启html页面变化的监控,对变化部分会进行自动翻译。注意,这里变化区域,是指使用 translate.setDocuments(...) 设置的区域。如果未设置,那么为监控整个网页的变化
|
|
221
783
|
start: function () {
|
|
784
|
+
|
|
222
785
|
translate.temp_linstenerStartInterval = setInterval(function () {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
786
|
+
if (document.readyState == 'complete') {
|
|
787
|
+
//dom加载完成,进行启动
|
|
788
|
+
clearInterval(translate.temp_linstenerStartInterval);//停止
|
|
789
|
+
translate.listener.addListener();
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
//if(translate.listener.isExecuteFinish){ //执行完过一次,那才能使用
|
|
793
|
+
/*if(translate.listener.isStart){
|
|
794
|
+
//已开启了
|
|
795
|
+
return;
|
|
796
|
+
}*/
|
|
797
|
+
|
|
798
|
+
//console.log('translate.temp_linstenerStartInterval Finish!');
|
|
799
|
+
//}
|
|
800
|
+
}, 50);
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
// window.onload = function(){
|
|
804
|
+
/* if(translate.listener.isStart){
|
|
805
|
+
//已开启了
|
|
806
|
+
return;
|
|
807
|
+
} */
|
|
808
|
+
|
|
809
|
+
//判断是否是执行完一次了
|
|
810
|
+
// translate.temp_linstenerStartInterval = setInterval(function(){
|
|
811
|
+
//if(translate.listener.isExecuteFinish){ //执行完过一次,那才能使用
|
|
812
|
+
/*if(translate.listener.isStart){
|
|
813
|
+
//已开启了
|
|
814
|
+
return;
|
|
815
|
+
}*/
|
|
816
|
+
// clearInterval(translate.temp_linstenerStartInterval);//停止
|
|
817
|
+
// translate.listener.addListener();
|
|
818
|
+
//console.log('translate.temp_linstenerStartInterval Finish!');
|
|
819
|
+
//}
|
|
820
|
+
// }, 50);
|
|
821
|
+
// }
|
|
822
|
+
|
|
823
|
+
|
|
226
824
|
},
|
|
825
|
+
//增加监听,开始监听。这个不要直接调用,需要使用上面的 start() 开启
|
|
227
826
|
addListener: function () {
|
|
228
|
-
translate.listener.isStart =
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
827
|
+
translate.listener.isStart = true; //记录已执行过启动方法了
|
|
828
|
+
|
|
829
|
+
// 观察器的配置(需要观察什么变动)
|
|
830
|
+
const config = { attributes: true, childList: true, subtree: true };
|
|
831
|
+
// 当观察到变动时执行的回调函数
|
|
832
|
+
const callback = function (mutationsList, observer) {
|
|
833
|
+
var documents = []; //有变动的元素
|
|
834
|
+
|
|
835
|
+
// Use traditional 'for loops' for IE 11
|
|
836
|
+
for (let mutation of mutationsList) {
|
|
837
|
+
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
|
|
838
|
+
//多了个组件
|
|
839
|
+
documents.push.apply(documents, mutation.addedNodes);
|
|
840
|
+
// console.log(mutation.addedNodes);
|
|
841
|
+
//}else if (mutation.type === 'attributes') {
|
|
842
|
+
// console.log('The ' + mutation.attributeName + ' attribute was modified.');
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
//console.log(documents);
|
|
847
|
+
if (documents.length > 0) {
|
|
848
|
+
//有变动,需要看看是否需要翻译
|
|
849
|
+
translate.execute(documents); //指定要翻译的元素的集合,可传入一个或多个元素。如果不设置,默认翻译整个网页
|
|
850
|
+
}
|
|
851
|
+
};
|
|
852
|
+
// 创建一个观察器实例并传入回调函数
|
|
853
|
+
const observer = new MutationObserver(callback);
|
|
854
|
+
// 以上述配置开始观察目标节点
|
|
855
|
+
var docs = translate.getDocuments();
|
|
856
|
+
for (var docs_index = 0; docs_index < docs.length; docs_index++) {
|
|
857
|
+
var doc = docs[docs_index];
|
|
858
|
+
if (doc != null) {
|
|
859
|
+
observer.observe(doc, config);
|
|
860
|
+
}
|
|
243
861
|
}
|
|
244
862
|
},
|
|
245
|
-
|
|
863
|
+
/*
|
|
864
|
+
每当执行完一次渲染任务(翻译)时会触发此。注意页面一次翻译会触发多个渲染任务。普通情况下,一次页面的翻译可能会触发两三次渲染任务。
|
|
865
|
+
另外如果页面中有ajax交互方面的信息,时,每次ajax信息刷新后,也会进行翻译,也是一次渲染任务。
|
|
866
|
+
这个是为了方便扩展使用。比如在layui中扩展,监控 select 的渲染
|
|
867
|
+
*/
|
|
868
|
+
renderTaskFinish: function (renderTask) {
|
|
869
|
+
//console.log(renderTask);
|
|
870
|
+
}
|
|
246
871
|
},
|
|
872
|
+
//对翻译结果进行替换渲染的任务,将待翻译内容替换为翻译内容的过程
|
|
247
873
|
renderTask: class {
|
|
248
874
|
constructor() {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
875
|
+
/*
|
|
876
|
+
* 任务列表
|
|
877
|
+
* 一维数组 [hash] = tasks; tasks 是多个task的数组集合
|
|
878
|
+
* 二维数组 [task,task,...],存放多个 task,每个task是一个替换。这里的数组是同一个nodeValue的多个task替换
|
|
879
|
+
* 三维数组 task['originalText'] 、 task['resultText'] 存放要替换的字符串
|
|
880
|
+
task['attribute'] 存放要替换的属性,比如 a标签的title属性。 如果是直接替换node.nodeValue ,那这个没有
|
|
881
|
+
*/
|
|
882
|
+
this.taskQueue = [];
|
|
883
|
+
|
|
884
|
+
/*
|
|
885
|
+
* 要进行翻译的node元素,
|
|
886
|
+
* 一维数组 key:node.nodeValue 的 hash , value:node的元素数组
|
|
887
|
+
* 二维数组,也就是value中包含的node集合 [node,node,...]
|
|
888
|
+
*/
|
|
889
|
+
this.nodes = [];
|
|
259
890
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* 向替换队列中增加替换任务
|
|
894
|
+
* node:要替换的字符属于那个node元素
|
|
895
|
+
* originalText:待翻译的字符
|
|
896
|
+
* resultText:翻译后的结果字符
|
|
897
|
+
* attribute: 要替换的是哪个属性,比如 a标签的title属性,这里便是传入title。如果不是替换属性,这里不用传入,或者传入null
|
|
898
|
+
*/
|
|
899
|
+
add(node, originalText, resultText, attribute) {
|
|
900
|
+
var nodeAnaly = translate.element.nodeAnalyse.get(node, attribute); //node解析
|
|
901
|
+
//var hash = translate.util.hash(translate.element.getTextByNode(node)); //node中内容的hash
|
|
902
|
+
var hash = translate.util.hash(nodeAnaly['text']);
|
|
903
|
+
//console.log('--------------'+hash);
|
|
904
|
+
//console.log(nodeAnaly);
|
|
905
|
+
//console.log(node);
|
|
906
|
+
//console.log('originalText:'+originalText+', resultText:'+resultText+', attribute:'+attribute);
|
|
907
|
+
/****** 加入翻译的元素队列 */
|
|
908
|
+
if (typeof (this.nodes[hash]) == 'undefined') {
|
|
909
|
+
this.nodes[hash] = new Array();
|
|
263
910
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
this)
|
|
273
|
-
}
|
|
274
|
-
},
|
|
275
|
-
execute: function (e) {
|
|
276
|
-
if ("undefined" != typeof doc && (translate.useVersion = "v2"), "v1" != translate.useVersion) {
|
|
277
|
-
var t = translate.util.uuid();
|
|
278
|
-
if (translate.nodeQueue[t] = new Array, translate.nodeQueue[t].expireTime = Date.now() + 12e4,
|
|
279
|
-
translate.nodeQueue[t].list = new Array, null == translate.to || "" == translate.to) {
|
|
280
|
-
var a = translate.storage.get("to");
|
|
281
|
-
null != a && void 0 !== a && a.length > 0 && (translate.to = a)
|
|
911
|
+
this.nodes[hash].push(node);
|
|
912
|
+
//console.log(node)
|
|
913
|
+
|
|
914
|
+
/****** 加入翻译的任务队列 */
|
|
915
|
+
var tasks = this.taskQueue[hash];
|
|
916
|
+
if (tasks == null || typeof (tasks) == 'undefined') {
|
|
917
|
+
//console.log(node.nodeValue);
|
|
918
|
+
tasks = new Array(); //任务列表,存放多个 task,每个task是一个替换。这里的数组是同一个nodeValue的多个task替换
|
|
282
919
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
if (
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
if (null == e) return void cnosole.log(
|
|
293
|
-
"translate.execute(...) 涓紶鍏ョ殑瑕佺炕璇戠殑鐩爣鍖哄煙涓嶅瓨鍦ㄣ€�");
|
|
294
|
-
void 0 === e.length ? (n = new Array)[0] = e : n = e
|
|
295
|
-
} else n = translate.getDocuments();
|
|
296
|
-
for (var l = 0; l < n.length & l < 20; l++) {
|
|
297
|
-
var r = n[l];
|
|
298
|
-
translate.element.whileNodes(t, r)
|
|
299
|
-
}
|
|
300
|
-
var s = {},
|
|
301
|
-
o = {};
|
|
302
|
-
for (var u in translate.nodeQueue[t].list) {
|
|
303
|
-
if (null == u || void 0 === u || 0 == u.length || "undefined" == u) continue;
|
|
304
|
-
s[u] = [], o[u] = [];
|
|
305
|
-
let e = new translate.renderTask;
|
|
306
|
-
for (var i in translate.nodeQueue[t].list[u])
|
|
307
|
-
if ("function" != typeof translate.nodeQueue[t].list[u][i]) {
|
|
308
|
-
var g = translate.nodeQueue[t].list[u][i].original,
|
|
309
|
-
c = translate.nodeQueue[t].list[u][i].translateText,
|
|
310
|
-
d = g == c ? i : translate.util.hash(c);
|
|
311
|
-
translate.nodeQueue[t].list[u][i].cacheHash = d;
|
|
312
|
-
var f = translate.storage.get("hash_" + translate.to + "_" + d);
|
|
313
|
-
if (null != f && f.length > 0)
|
|
314
|
-
for (var h = 0; h < translate.nodeQueue[t].list[u][i].nodes.length; h++) e.add(
|
|
315
|
-
translate.nodeQueue[t].list[u][i].nodes[h], g, translate.nodeQueue[
|
|
316
|
-
t].list[u][i].beforeText + f + translate.nodeQueue[t].list[u][i]
|
|
317
|
-
.afterText);
|
|
318
|
-
else s[u].push(c), o[u].push(i)
|
|
319
|
-
} e.execute()
|
|
320
|
-
}
|
|
321
|
-
var v = [];
|
|
322
|
-
for (var u in translate.nodeQueue[t].list) s[u].length < 1 || v.push(u);
|
|
323
|
-
if (translate.listener.isExecuteFinish || (translate.temp_executeFinishNumber = 0,
|
|
324
|
-
translate.temp_executeFinishInterval = setInterval(function () {
|
|
325
|
-
translate.temp_executeFinishNumber == v.length && (translate.listener.isExecuteFinish = !
|
|
326
|
-
0, clearInterval(translate.temp_executeFinishInterval))
|
|
327
|
-
}, 50)), 0 != v.length)
|
|
328
|
-
for (var p in v) {
|
|
329
|
-
u = v[p];
|
|
330
|
-
if (void 0 === s[u] || s[u].length < 1) return;
|
|
331
|
-
var m = translate.request.api.host + translate.request.api.translate + "?v=" +
|
|
332
|
-
translate.version,
|
|
333
|
-
x = {
|
|
334
|
-
from: u,
|
|
335
|
-
to: translate.to,
|
|
336
|
-
text: encodeURIComponent(JSON.stringify(s[u]))
|
|
337
|
-
};
|
|
338
|
-
translate.request.post(m, x, function (e) {
|
|
339
|
-
if (0 == e.result) return console.log("=======ERROR START======="),
|
|
340
|
-
console.log(s[e.from]), console.log("response : " + e.info),
|
|
341
|
-
console.log("=======ERROR END ======="), void translate.temp_executeFinishNumber++;
|
|
342
|
-
let a = new translate.renderTask;
|
|
343
|
-
for (var n = 0; n < o[e.from].length; n++) {
|
|
344
|
-
var l = e.from,
|
|
345
|
-
r = e.text[n],
|
|
346
|
-
u = o[e.from][n],
|
|
347
|
-
i = translate.nodeQueue[t].list[l][u].cacheHash,
|
|
348
|
-
g = "";
|
|
349
|
-
try {
|
|
350
|
-
g = translate.nodeQueue[t].list[l][u].original
|
|
351
|
-
} catch (e) {
|
|
352
|
-
console.log("uuid:" + t + ", originalWord:" + g + ", lang:" + l +
|
|
353
|
-
", hash:" + u + ", text:" + r + ", queue:" + translate.nodeQueue[
|
|
354
|
-
t]), console.log(e);
|
|
355
|
-
continue
|
|
356
|
-
}
|
|
357
|
-
for (var c = 0; c < translate.nodeQueue[t].list[l][u].nodes.length; c++)
|
|
358
|
-
a.add(translate.nodeQueue[t].list[l][u].nodes[c], g, translate.nodeQueue[
|
|
359
|
-
t].list[l][u].beforeText + r + translate.nodeQueue[t].list[
|
|
360
|
-
l][u].afterText);
|
|
361
|
-
translate.storage.set("hash_" + e.to + "_" + i, r)
|
|
362
|
-
}
|
|
363
|
-
a.execute(), translate.temp_executeFinishNumber++
|
|
364
|
-
})
|
|
365
|
-
}
|
|
920
|
+
var task = new Array();
|
|
921
|
+
|
|
922
|
+
//v2.3.3 增加 -- 开始
|
|
923
|
+
//这里要进行处理,因为有时候翻译前,它前或者后是有空格的,但是翻译后会把前或者后的空格给自动弄没了,如果是这种情况,要手动补上
|
|
924
|
+
if (originalText.substr(0, 1) == ' ') {
|
|
925
|
+
//console.log('第一个字符是空格');
|
|
926
|
+
if (resultText.substr(0, 1) != ' ') {
|
|
927
|
+
//翻译结果的第一个字符不是空格,那么补上
|
|
928
|
+
resultText = ' ' + resultText;
|
|
366
929
|
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
return translate.element.nodeAnalyse.analyse(e, "", "")
|
|
374
|
-
},
|
|
375
|
-
set: function (e, t, a) {
|
|
376
|
-
translate.element.nodeAnalyse.analyse(e, t, a)
|
|
377
|
-
},
|
|
378
|
-
analyse: function (e, t, a) {
|
|
379
|
-
var n = new Array;
|
|
380
|
-
n.node = e, n.text = "";
|
|
381
|
-
var l = translate.element.getNodeName(e);
|
|
382
|
-
"#text" == l && (void 0 !== e.parentNode && "TEXTAREA" == translate.element.getNodeName(e.parentNode) &&
|
|
383
|
-
(l = "TEXTAREA", e = e.parentNode));
|
|
384
|
-
if ("INPUT" == l || "TEXTAREA" == l) {
|
|
385
|
-
if (null == e.attributes || void 0 === e.attributes) return n.text = "", n;
|
|
386
|
-
if ("INPUT" == l && void 0 !== e.attributes.type && null != typeof e.attributes.type.nodeValue &&
|
|
387
|
-
("button" == e.attributes.type.nodeValue.toLowerCase() || "submit" == e.attributes.type
|
|
388
|
-
.nodeValue.toLowerCase())) {
|
|
389
|
-
var r = e.attributes.value;
|
|
390
|
-
if (null != r && void 0 !== r && void 0 !== r.nodeValue && r.nodeValue.length > 0)
|
|
391
|
-
return void 0 !== t && t.length > 0 && (r.nodeValue = r.nodeValue.replace(new RegExp(
|
|
392
|
-
translate.util.regExp.pattern(t), "g"), translate.util.regExp.resultText(
|
|
393
|
-
a))), n.text = r.nodeValue, n.node = r, n
|
|
394
|
-
}
|
|
395
|
-
return void 0 !== e.attributes.placeholder ? (void 0 !== t && t.length > 0 && (e.attributes
|
|
396
|
-
.placeholder.nodeValue = e.attributes.placeholder.nodeValue.replace(new RegExp(
|
|
397
|
-
translate.util.regExp.pattern(t), "g"), translate.util.regExp.resultText(
|
|
398
|
-
a))), n.text = e.attributes.placeholder.nodeValue, n.node = e.attributes.placeholder,
|
|
399
|
-
n) : (n.text = "", n)
|
|
400
|
-
}
|
|
401
|
-
if ("META" == l) {
|
|
402
|
-
if (void 0 !== e.name && null != e.name) {
|
|
403
|
-
var s = e.name.toLowerCase();
|
|
404
|
-
if ("keywords" == s || "description" == s) return void 0 !== t && t.length > 0 && (e.content =
|
|
405
|
-
e.content.replace(new RegExp(translate.util.regExp.pattern(t), "g"),
|
|
406
|
-
translate.util.regExp.resultText(a))), n.text = e.content, n
|
|
407
|
-
}
|
|
408
|
-
return n.text = "", n
|
|
409
|
-
}
|
|
410
|
-
return "IMG" == l ? void 0 === e.alt || null == e.alt ? (n.text = "", n) : (void 0 !== t && t.length >
|
|
411
|
-
0 && (e.alt = e.alt.replace(new RegExp(translate.util.regExp.pattern(t), "g"),
|
|
412
|
-
translate.util.regExp.resultText(a))), n.text = e.alt, n) : (null == e.nodeValue ||
|
|
413
|
-
void 0 === e.nodeValue ? n.text = "" : 0 == e.nodeValue.trim().length ? n.text = "" : (
|
|
414
|
-
void 0 !== t && t.length > 0 && (e.nodeValue = e.nodeValue.replace(new RegExp(
|
|
415
|
-
translate.util.regExp.pattern(t), "g"), translate.util.regExp.resultText(
|
|
416
|
-
a))), n.text = e.nodeValue), n)
|
|
417
|
-
}
|
|
418
|
-
},
|
|
419
|
-
getNodeName: function (e) {
|
|
420
|
-
return null == e || void 0 === e ? "" : null == e.nodeName || void 0 === e.nodeName ? "" : e.nodeName
|
|
421
|
-
},
|
|
422
|
-
whileNodes: function (e, t) {
|
|
423
|
-
if (null != t && void 0 !== t) {
|
|
424
|
-
var a = t.childNodes;
|
|
425
|
-
if (a.length > 0)
|
|
426
|
-
for (var n = 0; n < a.length; n++) translate.element.whileNodes(e, a[n]);
|
|
427
|
-
else translate.element.findNode(e, t)
|
|
428
|
-
}
|
|
429
|
-
},
|
|
430
|
-
findNode: function (e, t) {
|
|
431
|
-
if (null != t && void 0 !== t && null != t.parentNode) {
|
|
432
|
-
var a = translate.element.getNodeName(t.parentNode);
|
|
433
|
-
if ("" != a && !(translate.ignore.tag.indexOf(a.toLowerCase()) > -1)) {
|
|
434
|
-
for (var n = !1, l = t.parentNode; t != l && null != l;) null != l.className && translate.ignore
|
|
435
|
-
.class.indexOf(l.className) > -1 && (n = !0), l = l.parentNode;
|
|
436
|
-
if (!n && !translate.ignore.isIgnore(t)) {
|
|
437
|
-
var r = translate.element.nodeAnalyse.get(t);
|
|
438
|
-
r.text.length > 0 && translate.addNodeToQueue(e, r.node, r.text)
|
|
439
|
-
}
|
|
930
|
+
}
|
|
931
|
+
if (originalText.substr(originalText.length - 1, 1) === ' ') {
|
|
932
|
+
//console.log('最后一个字符是空格');
|
|
933
|
+
if (resultText.substr(0, 1) != ' ') {
|
|
934
|
+
//翻译结果的最后一个字符不是空格,那么补上
|
|
935
|
+
resultText = resultText + ' ';
|
|
440
936
|
}
|
|
441
937
|
}
|
|
938
|
+
//v2.3.3 增加 -- 结束
|
|
939
|
+
|
|
940
|
+
task['originalText'] = originalText;
|
|
941
|
+
task['resultText'] = resultText;
|
|
942
|
+
task['attribute'] = attribute;
|
|
943
|
+
|
|
944
|
+
//console.log(task);
|
|
945
|
+
tasks.push(task);
|
|
946
|
+
this.taskQueue[hash] = tasks;
|
|
947
|
+
/****** 加入翻译的任务队列 end */
|
|
442
948
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
if (
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
949
|
+
//进行替换渲染任务,对页面进行渲染替换翻译
|
|
950
|
+
execute() {
|
|
951
|
+
//先对tasks任务队列的替换词进行排序,将同一个node的替换词有大到小排列,避免先替换了小的,大的替换时找不到
|
|
952
|
+
for (var hash in this.taskQueue) {
|
|
953
|
+
var tasks = this.taskQueue[hash];
|
|
954
|
+
if (typeof (tasks) == 'function') {
|
|
955
|
+
//进行异常的预处理调出
|
|
956
|
+
continue;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
//进行排序,将原字符串长的放前面,避免造成有部分不翻译的情况(bug是先翻译了短的,导致长的被打断而无法进行适配)
|
|
960
|
+
tasks.sort((a, b) => b.originalText.length - a.originalText.length);
|
|
961
|
+
|
|
962
|
+
this.taskQueue[hash] = tasks;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
//console.log('===========task=========');
|
|
966
|
+
//console.log(this.taskQueue);
|
|
967
|
+
//console.log(this.nodes);
|
|
968
|
+
//console.log('===========task======end===');
|
|
969
|
+
|
|
970
|
+
//对nodeQueue进行翻译
|
|
971
|
+
for (var hash in this.nodes) {
|
|
972
|
+
var tasks = this.taskQueue[hash]; //取出当前node元素对应的替换任务
|
|
973
|
+
//var tagName = this.nodes[hash][0].nodeName; //以下节点的tag name
|
|
974
|
+
//console.log(tasks);
|
|
975
|
+
for (var node_index = 0; node_index < this.nodes[hash].length; node_index++) {
|
|
976
|
+
//对这个node元素进行替换翻译字符
|
|
977
|
+
for (var task_index = 0; task_index < tasks.length; task_index++) {
|
|
978
|
+
var task = tasks[task_index];
|
|
979
|
+
if (typeof (tasks) == 'function') {
|
|
980
|
+
//进行异常的预处理调出
|
|
981
|
+
continue;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
//console.log(this.nodes[hash][task_index]);
|
|
985
|
+
translate.element.nodeAnalyse.set(this.nodes[hash][task_index], task.originalText, task.resultText, task['attribute']);
|
|
986
|
+
/*
|
|
987
|
+
//var tagName = translate.element.getTagNameByNode(this.nodes[hash][task_index]);//节点的tag name
|
|
988
|
+
//console.log(tagName)
|
|
989
|
+
//console.log(this.nodes[hash][task_index])
|
|
990
|
+
//var tagName = this.nodes[hash][task_index].nodeName; //节点的tag name
|
|
991
|
+
var nodename = translate.element.getNodeName(this.nodes[hash][task_index]);
|
|
992
|
+
|
|
993
|
+
//console.log(this.nodes[hash][task_index]+', '+task.originalText+', '+task.resultText+', tagName:'+tagName);
|
|
994
|
+
if(nodename == 'META'){
|
|
995
|
+
if(typeof(this.nodes[hash][task_index].name) != 'undefined' && this.nodes[hash][task_index].name != null){
|
|
996
|
+
//var nodeName = this.nodes[hash][task_index].name.toLowerCase(); //取meta 标签的name 属性
|
|
997
|
+
|
|
998
|
+
this.nodes[hash][task_index].content = this.nodes[hash][task_index].content.replace(new RegExp(translate.util.regExp.pattern(task.originalText),'g'), translate.util.regExp.resultText(task.resultText));
|
|
999
|
+
}
|
|
1000
|
+
}else if(nodename == 'IMG'){
|
|
1001
|
+
this.nodes[hash][task_index].alt = this.nodes[hash][task_index].alt.replace(new RegExp(translate.util.regExp.pattern(task.originalText),'g'), translate.util.regExp.resultText(task.resultText));
|
|
1002
|
+
}else{
|
|
1003
|
+
//普通的
|
|
1004
|
+
//console.log('task.originalText : '+task.originalText);
|
|
1005
|
+
//console.log(translate.util.regExp.pattern(task.originalText))
|
|
1006
|
+
//console.log('task.resultText : '+task.resultText);
|
|
1007
|
+
this.nodes[hash][task_index].nodeValue = this.nodes[hash][task_index].nodeValue.replace(new RegExp(translate.util.regExp.pattern(task.originalText),'g'), translate.util.regExp.resultText(task.resultText));
|
|
1008
|
+
}
|
|
1009
|
+
*/
|
|
472
1010
|
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
//监听
|
|
1015
|
+
if (typeof (this.taskQueue) != 'undefined' && this.taskQueue.length > 0) {
|
|
1016
|
+
translate.listener.renderTaskFinish(this);
|
|
473
1017
|
}
|
|
474
1018
|
}
|
|
475
1019
|
},
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
.autoRecognitionLocalLanguage(), translate.language.local
|
|
484
|
-
},
|
|
485
|
-
autoRecognitionLocalLanguage: function () {
|
|
486
|
-
if (!(null != translate.language.local && translate.language.local.length > 2)) {
|
|
487
|
-
var e = document.body.outerText;
|
|
488
|
-
if (null == e || void 0 === e || e.length < 1) translate.language.local = "chinese_simplified";
|
|
489
|
-
else {
|
|
490
|
-
e = e.replace(/\n|\t|\r/g, "");
|
|
491
|
-
for (var t = new Array, a = 0; a < e.length; a++) {
|
|
492
|
-
var n = e.charAt(a),
|
|
493
|
-
l = translate.language.getCharLanguage(n);
|
|
494
|
-
"" == l && (l = "unidentification"), t.push(l)
|
|
495
|
-
}
|
|
496
|
-
var r = translate.util.arrayFindMaxNumber(t),
|
|
497
|
-
s = r.indexOf("specialCharacter");
|
|
498
|
-
s > -1 && r.splice(s, 1), r.length > 0 ? translate.language.local = r[0] : translate.language
|
|
499
|
-
.local = "chinese_simplified"
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
},
|
|
503
|
-
get: function (e) {
|
|
504
|
-
for (var t = new Array, a = new Array, n = [], l = [], r = 0; r < e.length; r++) {
|
|
505
|
-
var s = e.charAt(r),
|
|
506
|
-
o = translate.language.getCharLanguage(s);
|
|
507
|
-
"" == o && (o = "unidentification");
|
|
508
|
-
var u = translate.language.analyse(o, a, n, l, s);
|
|
509
|
-
a = u.langStrs, void 0 !== n.language && (l.language = n.language, l.charstr = n.charstr, l.storage_language =
|
|
510
|
-
n.storage_language), n.language = u.storage_language, n.charstr = s, n.storage_language =
|
|
511
|
-
u.storage_language, t.push(o)
|
|
512
|
-
}
|
|
513
|
-
return void 0 !== a.unidentification && delete a.unidentification, void 0 !== a.specialCharacter &&
|
|
514
|
-
delete a.specialCharacter, void 0 !== a.number && delete a.number, a
|
|
515
|
-
},
|
|
516
|
-
getCharLanguage: function (e) {
|
|
517
|
-
return null == e || void 0 === e ? "" : this.english(e) ? "english" : this.specialCharacter(e) ?
|
|
518
|
-
"specialCharacter" : this.number(e) ? "number" : this.chinese_simplified(e) ?
|
|
519
|
-
"chinese_simplified" : this.japanese(e) ? "japanese" : this.korean(e) ? "korean" : (console.log(
|
|
520
|
-
"not find is language , char : " + e + ", unicode: " + e.charCodeAt(0).toString(16)),
|
|
521
|
-
"")
|
|
522
|
-
},
|
|
523
|
-
analyse: function (e, t, a, n, l) {
|
|
524
|
-
void 0 === t[e] && (t[e] = new Array);
|
|
525
|
-
var r = 0;
|
|
526
|
-
void 0 === a.storage_language || (translate.language.connector(l) && (e = a.storage_language), r =
|
|
527
|
-
a.storage_language == e ? t[e].length - 1 : t[e].length), void 0 === t[e][r] && (t[e][r] =
|
|
528
|
-
new Array, t[e][r].beforeText = "", t[e][r].afterText = "", t[e][r].text = ""), t[e][r].text =
|
|
529
|
-
t[e][r].text + l, "english" != translate.language.getLocal() && "english" == translate.to &&
|
|
530
|
-
null != a.storage_language && void 0 !== a.storage_language && a.storage_language.length > 0 &&
|
|
531
|
-
"specialCharacter" != a.storage_language && ("english" != a.storage_language && "english" == e ?
|
|
532
|
-
t[a.storage_language][t[a.storage_language].length - 1].afterText = " " : "english" == a.storage_language &&
|
|
533
|
-
"english" != e && (t[e][r].beforeText = " "));
|
|
534
|
-
var s = new Array;
|
|
535
|
-
return s.langStrs = t, s.storage_language = e, s
|
|
536
|
-
},
|
|
537
|
-
connector: function (e) {
|
|
538
|
-
return !!/.*[\u0020\u00A0\u202F\u205F\u3000]+.*$/.test(e) || (!!/.*[\u0030-\u0039]+.*$/.test(e) ||
|
|
539
|
-
(!!
|
|
540
|
-
/.*[\u0021\u0022\u0023\u0024\u0025\u0026\u0027\u002C\u002D\u002E\u003A\u003B\u003F\u0040]+.*$/
|
|
541
|
-
.test(e) || !!
|
|
542
|
-
/.*[\u3002\uFF1F\uFF01\uFF0C\u3001\uFF1B\uFF1A\u300C\u300D\u300E\u300F\u2018\u2019\u201C\u201D\uFF08\uFF09\u3014\u3015\u3010\u3011\u2014\u2026\u2013\uFF0E\u300A\u300B\u3008\u3009\u00b7]+.*$/
|
|
543
|
-
.test(e)))
|
|
544
|
-
},
|
|
545
|
-
chinese_simplified: function (e) {
|
|
546
|
-
return !!/.*[\u4e00-\u9fa5]+.*$/.test(e)
|
|
547
|
-
},
|
|
548
|
-
english: function (e) {
|
|
549
|
-
return !!/.*[\u0041-\u005a]+.*$/.test(e) || !!/.*[\u0061-\u007a]+.*$/.test(e)
|
|
550
|
-
},
|
|
551
|
-
japanese: function (e) {
|
|
552
|
-
return !!/.*[\u0800-\u4e00]+.*$/.test(e)
|
|
553
|
-
},
|
|
554
|
-
korean: function (e) {
|
|
555
|
-
return !!/.*[\uAC00-\uD7AF]+.*$/.test(e)
|
|
556
|
-
},
|
|
557
|
-
number: function (e) {
|
|
558
|
-
return !!/.*[\u0030-\u0039]+.*$/.test(e)
|
|
559
|
-
},
|
|
560
|
-
specialCharacter: function (e) {
|
|
561
|
-
return !!/.*[\u2460-\u24E9]+.*$/.test(e) || (!!/.*[\u2500-\u25FF]+.*$/.test(e) || (!!
|
|
562
|
-
/.*[\u3200-\u33FF]+.*$/.test(e) || (!!/.*[\uFF00-\uFF5E]+.*$/.test(e) || (!!
|
|
563
|
-
/.*[\u2000-\u22FF]+.*$/.test(e) || (!!/.*[\u3001-\u3036]+.*$/.test(e) || (!!
|
|
564
|
-
/.*[\u0020-\u002F]+.*$/.test(e) || (!!/.*[\u003A-\u007E]+.*$/.test(e) ||
|
|
565
|
-
(!!
|
|
566
|
-
/.*[\u0009\u000a\u0020\u00A0\u1680\u180E\u202F\u205F\u3000\uFEFF]+.*$/
|
|
567
|
-
.test(e) || (!!/.*[\u2000-\u200B]+.*$/.test(e) || (!!
|
|
568
|
-
/.*[\u00A1-\u0105]+.*$/.test(e) || !!
|
|
569
|
-
/.*[\u2C60-\u2C77]+.*$/.test(e)))))))))))
|
|
1020
|
+
|
|
1021
|
+
//执行翻译操作。翻译的是 nodeQueue 中的
|
|
1022
|
+
//docs 如果传入,那么翻译的只是传入的这个docs的。传入如 [document.getElementById('xxx'),document.getElementById('xxx'),...]
|
|
1023
|
+
execute: function (docs) {
|
|
1024
|
+
if (typeof (doc) != 'undefined') {
|
|
1025
|
+
//execute传入参数,只有v2版本才支持
|
|
1026
|
+
translate.useVersion = 'v2';
|
|
570
1027
|
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
var
|
|
602
|
-
if (
|
|
603
|
-
|
|
604
|
-
return a + ""
|
|
605
|
-
},
|
|
606
|
-
charReplace: function (e) {
|
|
607
|
-
return null == e ? "" : e = (e = e.trim()).replace(/\t|\n|\v|\r|\f/g, "")
|
|
608
|
-
},
|
|
609
|
-
regExp: {
|
|
610
|
-
pattern: function (e) {
|
|
611
|
-
return e = (e = e.replace(/\"/g, '\\"')).replace(/\?/g, "\\?")
|
|
612
|
-
},
|
|
613
|
-
resultText: function (e) {
|
|
614
|
-
return e
|
|
1028
|
+
|
|
1029
|
+
if (translate.useVersion == 'v1') {
|
|
1030
|
+
//if(this.to == null || this.to == ''){
|
|
1031
|
+
//采用1.x版本的翻译,使用google翻译
|
|
1032
|
+
//translate.execute_v1();
|
|
1033
|
+
//return;
|
|
1034
|
+
//v2.5.1增加
|
|
1035
|
+
console.log('提示:https://github.com/xnx3/translate 在 v2.5 版本之后,由于谷歌翻译调整,免费翻译通道不再支持,所以v1版本的翻译接口不再被支持,v1全线下架。考虑到v1已不能使用,当前已自动切换到v2版本。如果您使用中发现什么异常,请针对v2版本进行适配。');
|
|
1036
|
+
translate.useVersion = 'v2';
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
/****** 采用 2.x 版本的翻译,使用自有翻译算法 */
|
|
1040
|
+
|
|
1041
|
+
|
|
1042
|
+
//每次执行execute,都会生成一个唯一uuid,也可以叫做队列的唯一标识,每一次执行execute都会创建一个独立的翻译执行队列
|
|
1043
|
+
var uuid = translate.util.uuid();
|
|
1044
|
+
//console.log('=====')
|
|
1045
|
+
//console.log(translate.nodeQueue);
|
|
1046
|
+
|
|
1047
|
+
/* v2.4.3 将初始化放到了 translate.element.whileNodes 中,如果uuid对应的没有,则自动创建
|
|
1048
|
+
|
|
1049
|
+
translate.nodeQueue[uuid] = new Array(); //创建
|
|
1050
|
+
translate.nodeQueue[uuid]['expireTime'] = Date.now() + 120*1000; //删除时间,10分钟后删除
|
|
1051
|
+
translate.nodeQueue[uuid]['list'] = new Array();
|
|
1052
|
+
*/
|
|
1053
|
+
//console.log(translate.nodeQueue);
|
|
1054
|
+
//console.log('=====end')
|
|
1055
|
+
|
|
1056
|
+
//如果页面打开第一次使用,先判断缓存中有没有上次使用的语种,从缓存中取出
|
|
1057
|
+
if (translate.to == null || translate.to == '') {
|
|
1058
|
+
var to_storage = translate.storage.get('to');
|
|
1059
|
+
if (to_storage != null && typeof (to_storage) != 'undefined' && to_storage.length > 0) {
|
|
1060
|
+
translate.to = to_storage;
|
|
615
1061
|
}
|
|
616
1062
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
send: function (e, t, a, n, l, r, s) {
|
|
631
|
-
var o = "";
|
|
632
|
-
if (null != t)
|
|
633
|
-
for (var u in t) o.length > 0 && (o += "&"), o = o + u + "=" + t[u];
|
|
634
|
-
var i = null;
|
|
635
|
-
try {
|
|
636
|
-
i = new XMLHttpRequest
|
|
637
|
-
} catch (e) {
|
|
638
|
-
i = new ActiveXObject("Microsoft.XMLHTTP")
|
|
639
|
-
}
|
|
640
|
-
if (i.open(n, e, l), null != r)
|
|
641
|
-
for (var u in r) i.setRequestHeader(u, r[u]);
|
|
642
|
-
i.send(o), i.onreadystatechange = function () {
|
|
643
|
-
if (4 == i.readyState)
|
|
644
|
-
if (200 == i.status) {
|
|
645
|
-
var e = null;
|
|
646
|
-
try {
|
|
647
|
-
e = JSON.parse(i.responseText)
|
|
648
|
-
} catch (e) {
|
|
649
|
-
console.log(e)
|
|
650
|
-
}
|
|
651
|
-
a(null == e ? i.responseText : e)
|
|
652
|
-
} else null != s && s(i)
|
|
1063
|
+
|
|
1064
|
+
//渲染select选择语言
|
|
1065
|
+
try {
|
|
1066
|
+
translate.selectLanguageTag.render();
|
|
1067
|
+
} catch (e) {
|
|
1068
|
+
console.log(e);
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
//判断是否还未指定翻译的目标语言
|
|
1072
|
+
if (translate.to == null || typeof (translate.to) == 'undefined' || translate.to.length == 0) {
|
|
1073
|
+
//未指定,判断如果指定了自动获取用户本国语种了,那么进行获取
|
|
1074
|
+
if (translate.autoDiscriminateLocalLanguage) {
|
|
1075
|
+
translate.executeByLocalLanguage();
|
|
653
1076
|
}
|
|
1077
|
+
|
|
1078
|
+
//没有指定翻译目标语言、又没自动获取用户本国语种,则不翻译
|
|
1079
|
+
return;
|
|
654
1080
|
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
},
|
|
660
|
-
get: function (e) {
|
|
661
|
-
return localStorage.getItem(e)
|
|
1081
|
+
|
|
1082
|
+
//判断本地语种跟要翻译的目标语种是否一样,如果是一样,那就不需要进行任何翻译
|
|
1083
|
+
if (translate.to == translate.language.getLocal()) {
|
|
1084
|
+
return;
|
|
662
1085
|
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
1086
|
+
|
|
1087
|
+
/********** 翻译进行 */
|
|
1088
|
+
|
|
1089
|
+
//先进行图片的翻译替换,毕竟图片还有加载的过程
|
|
1090
|
+
translate.images.execute();
|
|
1091
|
+
|
|
1092
|
+
/*
|
|
1093
|
+
进行翻译指定的node操作。优先级为:
|
|
1094
|
+
1. 这个方法已经指定的翻译 nodes
|
|
1095
|
+
2. setDocuments 指定的
|
|
1096
|
+
3. 整个网页
|
|
1097
|
+
其实2、3都是通过 getDocuments() 取,在getDocuments() 就对2、3进行了判断
|
|
1098
|
+
*/
|
|
1099
|
+
var all;
|
|
1100
|
+
if (typeof (docs) != 'undefined') {
|
|
1101
|
+
//1. 这个方法已经指定的翻译 nodes
|
|
1102
|
+
|
|
1103
|
+
if (docs == null) {
|
|
1104
|
+
//要翻译的目标区域不存在
|
|
1105
|
+
console.log('translate.execute(...) 中传入的要翻译的目标区域不存在。');
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
if (typeof (docs.length) == 'undefined') {
|
|
1110
|
+
//不是数组,是单个元素
|
|
1111
|
+
all = new Array();
|
|
1112
|
+
all[0] = docs;
|
|
1113
|
+
} else {
|
|
1114
|
+
//是数组,直接赋予
|
|
1115
|
+
all = docs;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
} else {
|
|
1119
|
+
//2、3
|
|
1120
|
+
all = translate.getDocuments();
|
|
1121
|
+
}
|
|
1122
|
+
//console.log('----要翻译的目标元素-----');
|
|
1123
|
+
//console.log(all)
|
|
1124
|
+
|
|
1125
|
+
//检索目标内的node元素
|
|
1126
|
+
for (var i = 0; i < all.length & i < 20; i++) {
|
|
1127
|
+
var node = all[i];
|
|
1128
|
+
translate.element.whileNodes(uuid, node);
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
//console.log('-----待翻译:----');
|
|
1132
|
+
//console.log(translate.nodeQueue);
|
|
1133
|
+
|
|
1134
|
+
//translateTextArray[lang][0]
|
|
1135
|
+
var translateTextArray = {}; //要翻译的文本的数组,格式如 ["你好","欢迎"]
|
|
1136
|
+
var translateHashArray = {}; //要翻译的文本的hash,跟上面的index是一致的,只不过上面是存要翻译的文本,这个存hash值
|
|
1137
|
+
|
|
1138
|
+
for (var lang in translate.nodeQueue[uuid]['list']) { //二维数组中,取语言
|
|
1139
|
+
//console.log('lang:'+lang); //lang为english这种语言标识
|
|
1140
|
+
if (lang == null || typeof (lang) == 'undefined' || lang.length == 0 || lang == 'undefined') {
|
|
1141
|
+
//console.log('lang is null : '+lang);
|
|
1142
|
+
continue;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
translateTextArray[lang] = [];
|
|
1146
|
+
translateHashArray[lang] = [];
|
|
1147
|
+
|
|
1148
|
+
let task = new translate.renderTask();
|
|
1149
|
+
//console.log(translate.nodeQueue);
|
|
1150
|
+
//二维数组,取hash、value
|
|
1151
|
+
for (var hash in translate.nodeQueue[uuid]['list'][lang]) {
|
|
1152
|
+
if (typeof (translate.nodeQueue[uuid]['list'][lang][hash]) == 'function') {
|
|
1153
|
+
//跳出,增加容错率。 正常情况下应该不会这样
|
|
1154
|
+
continue;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
//取原始的词,还未经过翻译的,需要进行翻译的词
|
|
1158
|
+
//var originalWord = translate.nodeQueue[uuid]['list'][lang][hash]['original'];
|
|
1159
|
+
|
|
1160
|
+
//原始的node中的词
|
|
1161
|
+
var originalWord = translate.nodeQueue[uuid]['list'][lang][hash]['original'];
|
|
1162
|
+
//要翻译的词
|
|
1163
|
+
var translateText = translate.nodeQueue[uuid]['list'][lang][hash]['translateText'];
|
|
1164
|
+
|
|
1165
|
+
/*
|
|
1166
|
+
//自定义术语后的。如果
|
|
1167
|
+
var nomenclatureOriginalWord = translate.nomenclature.dispose(cache);
|
|
1168
|
+
if(nomenclatureOriginalWord != originalWord){
|
|
1169
|
+
has
|
|
1170
|
+
}
|
|
1171
|
+
*/
|
|
1172
|
+
//console.log(originalWord == translateText ? '1':'xin:'+translateText);
|
|
1173
|
+
//根据hash,判断本地是否有缓存了
|
|
1174
|
+
var cacheHash = originalWord == translateText ? hash : translate.util.hash(translateText); //如果匹配到了自定义术语库,那翻译前的hash是被改变了
|
|
1175
|
+
translate.nodeQueue[uuid]['list'][lang][hash]['cacheHash'] = cacheHash; //缓存的hash。 缓存时,其hash跟翻译的语言是完全对应的,缓存的hash就是翻译的语言转换来的
|
|
1176
|
+
var cache = translate.storage.get('hash_' + translate.to + '_' + cacheHash);
|
|
1177
|
+
//console.log(key+', '+cache);
|
|
1178
|
+
if (cache != null && cache.length > 0) {
|
|
1179
|
+
//有缓存了
|
|
1180
|
+
//console.log('find cache:'+cache);
|
|
1181
|
+
//console.log(this.nodeQueue[lang][hash]['nodes']);
|
|
1182
|
+
//直接将缓存赋予
|
|
1183
|
+
//for(var index = 0; index < this.nodeQueue[lang][hash].length; index++){
|
|
1184
|
+
//this.nodeQueue[lang][hash][index].nodeValue = cache;
|
|
1185
|
+
|
|
1186
|
+
for (var node_index = 0; node_index < translate.nodeQueue[uuid]['list'][lang][hash]['nodes'].length; node_index++) {
|
|
1187
|
+
//this.nodeQueue[lang][hash]['nodes'][node_index].nodeValue = cache;
|
|
1188
|
+
//console.log(originalWord);
|
|
1189
|
+
task.add(translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][node_index]['node'], originalWord, translate.nodeQueue[uuid]['list'][lang][hash]['beforeText'] + cache + translate.nodeQueue[uuid]['list'][lang][hash]['afterText'], translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][node_index]['attribute']);
|
|
1190
|
+
//this.nodeQueue[lang][hash]['nodes'][node_index].nodeValue = this.nodeQueue[lang][hash]['nodes'][node_index].nodeValue.replace(new RegExp(originalWord,'g'), cache);
|
|
1191
|
+
}
|
|
1192
|
+
//}
|
|
1193
|
+
|
|
1194
|
+
continue; //跳出,不用在传入下面的翻译接口了
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
/*
|
|
1198
|
+
//取出数组
|
|
1199
|
+
var queueNodes = this.nodeQueue[lang][hash];
|
|
1200
|
+
if(queueNodes.length > 0){
|
|
1201
|
+
//因为在这个数组中的值都是一样的,那么只需要取出第一个就行了
|
|
1202
|
+
var valueStr = queueNodes[0].nodeValue;
|
|
1203
|
+
valueStr = this.util.charReplace(valueStr);
|
|
1204
|
+
|
|
1205
|
+
translateTextArray[lang].push(valueStr);
|
|
1206
|
+
translateHashArray[lang].push(hash);
|
|
1207
|
+
}
|
|
1208
|
+
*/
|
|
1209
|
+
|
|
1210
|
+
//加入待翻译数组
|
|
1211
|
+
translateTextArray[lang].push(translateText);
|
|
1212
|
+
translateHashArray[lang].push(hash); //这里存入的依旧还是用原始hash,未使用自定义术语库前的hash,目的是不破坏 nodeQueue 的 key
|
|
1213
|
+
}
|
|
1214
|
+
task.execute(); //执行渲染任务
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
//window.translateHashArray = translateHashArray;
|
|
1218
|
+
|
|
1219
|
+
//统计出要翻译哪些语种 ,这里面的语种会调用接口进行翻译。其内格式如 english
|
|
1220
|
+
var fanyiLangs = [];
|
|
1221
|
+
for (var lang in translate.nodeQueue[uuid]['list']) { //二维数组中取语言
|
|
1222
|
+
if (translateTextArray[lang].length < 1) {
|
|
1223
|
+
continue;
|
|
1224
|
+
}
|
|
1225
|
+
fanyiLangs.push(lang);
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
/******* 用以记录当前是否进行完第一次翻译了 *******/
|
|
1229
|
+
if (!translate.listener.isExecuteFinish) {
|
|
1230
|
+
translate.temp_executeFinishNumber = 0; //下面请求接口渲染,翻译执行完成的次数
|
|
1231
|
+
//判断是否是执行完一次了
|
|
1232
|
+
translate.temp_executeFinishInterval = setInterval(function () {
|
|
1233
|
+
if (translate.temp_executeFinishNumber == fanyiLangs.length) {
|
|
1234
|
+
translate.listener.isExecuteFinish = true; //记录当前已执行完第一次了
|
|
1235
|
+
clearInterval(translate.temp_executeFinishInterval);//停止
|
|
1236
|
+
//console.log('translate.execute() Finish!');
|
|
1237
|
+
}
|
|
1238
|
+
}, 50);
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
if (fanyiLangs.length == 0) {
|
|
1242
|
+
//没有需要翻译的,直接退出
|
|
1243
|
+
return;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
//进行掉接口翻译
|
|
1247
|
+
for (var lang_index in fanyiLangs) { //一维数组,取语言
|
|
1248
|
+
var lang = fanyiLangs[lang_index];
|
|
1249
|
+
//console.log(typeof(translateTextArray[lang]))
|
|
1250
|
+
|
|
1251
|
+
if (typeof (translateTextArray[lang]) == 'undefined' || translateTextArray[lang].length < 1) {
|
|
1252
|
+
return;
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
//自定义术语
|
|
1256
|
+
/*var nomenclatureCache = translate.nomenclature.dispose(cache);
|
|
1257
|
+
for(var ttr_index = 0; ttr_index<translateTextArray[lang].length; ttr_index++){
|
|
1258
|
+
console.log(translateTextArray[lang][ttr_index])
|
|
1259
|
+
}*/
|
|
1260
|
+
|
|
1261
|
+
/*** 翻译开始 ***/
|
|
1262
|
+
var url = translate.request.api.host + translate.request.api.translate + '?v=' + translate.version;
|
|
1263
|
+
var data = {
|
|
1264
|
+
from: lang,
|
|
1265
|
+
to: translate.to,
|
|
1266
|
+
//text:JSON.stringify(translateTextArray[lang])
|
|
1267
|
+
text: encodeURIComponent(JSON.stringify(translateTextArray[lang]))
|
|
1268
|
+
};
|
|
1269
|
+
translate.request.post(url, data, function (data) {
|
|
1270
|
+
//console.log(data);
|
|
1271
|
+
if (data.result == 0) {
|
|
1272
|
+
console.log('=======ERROR START=======');
|
|
1273
|
+
console.log(translateTextArray[data.from]);
|
|
1274
|
+
//console.log(encodeURIComponent(JSON.stringify(translateTextArray[data.from])));
|
|
1275
|
+
|
|
1276
|
+
console.log('response : ' + data.info);
|
|
1277
|
+
console.log('=======ERROR END =======');
|
|
1278
|
+
translate.temp_executeFinishNumber++; //记录执行完的次数
|
|
1279
|
+
return;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
//console.log('-----待翻译3:----');
|
|
1283
|
+
//console.log(translate.nodeQueue);
|
|
1284
|
+
|
|
1285
|
+
//console.log('response:'+uuid);
|
|
1286
|
+
let task = new translate.renderTask();
|
|
1287
|
+
//遍历 translateHashArray
|
|
1288
|
+
for (var i = 0; i < translateHashArray[data.from].length; i++) {
|
|
1289
|
+
//翻译前的语种,如 english
|
|
1290
|
+
var lang = data.from;
|
|
1291
|
+
//翻译后的内容
|
|
1292
|
+
var text = data.text[i];
|
|
1293
|
+
//翻译前的hash对应下标
|
|
1294
|
+
var hash = translateHashArray[data.from][i];
|
|
1295
|
+
var cacheHash = translate.nodeQueue[uuid]['list'][lang][hash]['cacheHash'];
|
|
1296
|
+
|
|
1297
|
+
|
|
1298
|
+
|
|
1299
|
+
//取原始的词,还未经过翻译的,需要进行翻译的词
|
|
1300
|
+
var originalWord = '';
|
|
1301
|
+
try {
|
|
1302
|
+
originalWord = translate.nodeQueue[uuid]['list'][lang][hash]['original'];
|
|
1303
|
+
//console.log('bef:'+translate.nodeQueue[uuid]['list'][lang][hash]['beforeText']);
|
|
1304
|
+
} catch (e) {
|
|
1305
|
+
console.log('uuid:' + uuid + ', originalWord:' + originalWord + ', lang:' + lang + ', hash:' + hash + ', text:' + text + ', queue:' + translate.nodeQueue[uuid]);
|
|
1306
|
+
console.log(e);
|
|
1307
|
+
continue;
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
//for(var index = 0; index < translate.nodeQueue[lang][hash].length; index++){
|
|
1311
|
+
for (var node_index = 0; node_index < translate.nodeQueue[uuid]['list'][lang][hash]['nodes'].length; node_index++) {
|
|
1312
|
+
//translate.nodeQueue[lang][hash]['nodes'][node_index].nodeValue = translate.nodeQueue[lang][hash]['nodes'][node_index].nodeValue.replace(new RegExp(originalWord,'g'), text);
|
|
1313
|
+
//加入任务
|
|
1314
|
+
task.add(translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][node_index]['node'], originalWord, translate.nodeQueue[uuid]['list'][lang][hash]['beforeText'] + text + translate.nodeQueue[uuid]['list'][lang][hash]['afterText'], translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][node_index]['attribute']);
|
|
1315
|
+
}
|
|
1316
|
+
//}
|
|
1317
|
+
/*
|
|
1318
|
+
for(var index = 0; index < translate.nodeQueue[data.from][hash].length; index++){
|
|
1319
|
+
translate.nodeQueue[data.from][hash][index].nodeValue = text;
|
|
1320
|
+
}
|
|
1321
|
+
*/
|
|
1322
|
+
|
|
1323
|
+
//将翻译结果以 key:hash value翻译结果的形式缓存
|
|
1324
|
+
translate.storage.set('hash_' + data.to + '_' + cacheHash, text);
|
|
1325
|
+
}
|
|
1326
|
+
task.execute(); //执行渲染任务
|
|
1327
|
+
translate.temp_executeFinishNumber++; //记录执行完的次数
|
|
1328
|
+
|
|
1329
|
+
});
|
|
1330
|
+
/*** 翻译end ***/
|
|
1331
|
+
|
|
1332
|
+
|
|
1333
|
+
}
|
|
1334
|
+
},
|
|
1335
|
+
element: {
|
|
1336
|
+
//对翻译前后的node元素的分析(翻以前)及渲染(翻译后)
|
|
1337
|
+
nodeAnalyse: {
|
|
1338
|
+
/*
|
|
1339
|
+
获取node中的要进行翻译的文本内容、以及要操作的实际node对象(这个node对象很可能是传入的node中的某个子node)
|
|
1340
|
+
node
|
|
1341
|
+
attribute 要获取的是某个属性的值,还是node本身的值。比如 a标签的title属性的值,则传入 title。 如果是直接获取node.nodeValue ,那这个没有
|
|
1342
|
+
|
|
1343
|
+
返回结果是一个数组。其中:
|
|
1344
|
+
['text']:要进行翻译的text内容文本
|
|
1345
|
+
['node']:要进行翻译的目标node
|
|
1346
|
+
|
|
1347
|
+
*/
|
|
1348
|
+
get: function (node, attribute) {
|
|
1349
|
+
return translate.element.nodeAnalyse.analyse(node, '', '', attribute);
|
|
1350
|
+
},
|
|
1351
|
+
/*
|
|
1352
|
+
进行翻译之后的渲染显示
|
|
1353
|
+
参数:
|
|
1354
|
+
node 当前翻译的node元素
|
|
1355
|
+
originalText 翻译之前的内容文本
|
|
1356
|
+
resultText 翻译之后的内容文本
|
|
1357
|
+
attribute 存放要替换的属性,比如 a标签的title属性。 如果是直接替换node.nodeValue ,那这个没有
|
|
1358
|
+
*/
|
|
1359
|
+
set: function (node, originalText, resultText, attribute) {
|
|
1360
|
+
translate.element.nodeAnalyse.analyse(node, originalText, resultText, attribute);
|
|
1361
|
+
},
|
|
1362
|
+
/*
|
|
1363
|
+
|
|
1364
|
+
注意,这个不使用,只是服务于上面的get、set使用。具体使用用上面的get、set
|
|
1365
|
+
|
|
1366
|
+
1. 只传入 node:
|
|
1367
|
+
获取node中的要进行翻译的文本内容、以及要操作的实际node对象(这个node对象很可能是传入的node中的某个子node)
|
|
1368
|
+
返回结果是一个数组。其中:
|
|
1369
|
+
['text']:要进行翻译的text内容文本
|
|
1370
|
+
['node']:要进行翻译的目标node
|
|
1371
|
+
2. 传入 node、originalText、 resultText
|
|
1372
|
+
则是进行翻译之后的渲染显示
|
|
1373
|
+
|
|
1374
|
+
attribute : 进行替换渲染时使用,存放要替换的属性,比如 a标签的title属性。 如果是直接替换node.nodeValue ,那这个没有
|
|
1375
|
+
*/
|
|
1376
|
+
analyse: function (node, originalText, resultText, attribute) {
|
|
1377
|
+
var result = new Array(); //返回的结果
|
|
1378
|
+
result['node'] = node;
|
|
1379
|
+
result['text'] = '';
|
|
1380
|
+
|
|
1381
|
+
var nodename = translate.element.getNodeName(node);
|
|
1382
|
+
|
|
1383
|
+
if (attribute != null && typeof (attribute) == 'string' && attribute.length > 0) {
|
|
1384
|
+
//这个node有属性,替换的是node的属性,而不是nodeValue
|
|
1385
|
+
result['text'] = node[attribute];
|
|
1386
|
+
|
|
1387
|
+
//替换渲染
|
|
1388
|
+
if (typeof (originalText) != 'undefined' && originalText.length > 0) {
|
|
1389
|
+
if (typeof (node[attribute]) != 'undefined') {
|
|
1390
|
+
node[attribute] = node[attribute].replace(new RegExp(translate.util.regExp.pattern(originalText), 'g'), translate.util.regExp.resultText(resultText));
|
|
1391
|
+
} else {
|
|
1392
|
+
console.log(node);
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
}
|
|
1396
|
+
return result;
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
//正常的node ,typeof 都是 object
|
|
1400
|
+
|
|
1401
|
+
//console.log(typeof(node)+node);
|
|
1402
|
+
if (nodename == '#text') {
|
|
1403
|
+
//如果是普通文本,判断一下上层是否是包含在textarea标签中
|
|
1404
|
+
if (typeof (node.parentNode) != 'undefined') {
|
|
1405
|
+
var parentNodename = translate.element.getNodeName(node.parentNode);
|
|
1406
|
+
//console.log(parentNodename)
|
|
1407
|
+
if (parentNodename == 'TEXTAREA') {
|
|
1408
|
+
//是textarea标签,那将nodename 纳入 textarea的判断中,同时将判断对象交于上级,也就是textarea标签
|
|
1409
|
+
nodename = 'TEXTAREA';
|
|
1410
|
+
node = node.parentNode;
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
//console.log(nodename)
|
|
1418
|
+
//console.log(translate.element.getNodeName(node.parentNode))
|
|
1419
|
+
//console.log(node)
|
|
1420
|
+
if (nodename == 'INPUT' || nodename == 'TEXTAREA') {
|
|
1421
|
+
//console.log(node.attributes)
|
|
1422
|
+
/*
|
|
1423
|
+
1. input、textarea 输入框,要对 placeholder 做翻译
|
|
1424
|
+
2. input 要对 type=button 的情况进行翻译
|
|
1425
|
+
*/
|
|
1426
|
+
if (node.attributes == null || typeof (node.attributes) == 'undefined') {
|
|
1427
|
+
result['text'] = '';
|
|
1428
|
+
return result;
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
//input,要对 type=button、submit 的情况进行翻译
|
|
1432
|
+
if (nodename == 'INPUT') {
|
|
1433
|
+
if (typeof (node.attributes.type) != 'undefined' && typeof (node.attributes.type.nodeValue) != null && (node.attributes.type.nodeValue.toLowerCase() == 'button' || node.attributes.type.nodeValue.toLowerCase() == 'submit')) {
|
|
1434
|
+
//console.log('----是 <input type="button"');
|
|
1435
|
+
//取它的value
|
|
1436
|
+
var input_value_node = node.attributes.value;
|
|
1437
|
+
if (input_value_node != null && typeof (input_value_node) != 'undefined' && typeof (input_value_node.nodeValue) != 'undefined' && input_value_node.nodeValue.length > 0) {
|
|
1438
|
+
//替换渲染
|
|
1439
|
+
if (typeof (originalText) != 'undefined' && originalText.length > 0) {
|
|
1440
|
+
//this.nodes[hash][task_index].nodeValue = this.nodes[hash][task_index].nodeValue.replace(new RegExp(translate.util.regExp.pattern(task.originalText),'g'), translate.util.regExp.resultText(task.resultText));
|
|
1441
|
+
input_value_node.nodeValue = input_value_node.nodeValue.replace(new RegExp(translate.util.regExp.pattern(originalText), 'g'), translate.util.regExp.resultText(resultText));
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
result['text'] = input_value_node.nodeValue;
|
|
1445
|
+
result['node'] = input_value_node;
|
|
1446
|
+
return result;
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
//console.log(node)
|
|
1451
|
+
|
|
1452
|
+
//input textarea 的 placeholder 情况
|
|
1453
|
+
if (typeof (node.attributes['placeholder']) != 'undefined') {
|
|
1454
|
+
//console.log(node);
|
|
1455
|
+
//替换渲染
|
|
1456
|
+
if (typeof (originalText) != 'undefined' && originalText.length > 0) {
|
|
1457
|
+
//this.nodes[hash][task_index].nodeValue = this.nodes[hash][task_index].nodeValue.replace(new RegExp(translate.util.regExp.pattern(task.originalText),'g'), translate.util.regExp.resultText(task.resultText));
|
|
1458
|
+
node.attributes['placeholder'].nodeValue = node.attributes['placeholder'].nodeValue.replace(new RegExp(translate.util.regExp.pattern(originalText), 'g'), translate.util.regExp.resultText(resultText));
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
result['text'] = node.attributes['placeholder'].nodeValue;
|
|
1462
|
+
result['node'] = node.attributes['placeholder'];
|
|
1463
|
+
return result;
|
|
1464
|
+
//return node.attributes['placeholder'].nodeValue;
|
|
1465
|
+
}
|
|
1466
|
+
//console.log(node)
|
|
1467
|
+
result['text'] = '';
|
|
1468
|
+
return result;
|
|
1469
|
+
}
|
|
1470
|
+
if (nodename == 'META') {
|
|
1471
|
+
//meta标签,如是关键词、描述等
|
|
1472
|
+
if (typeof (node.name) != 'undefined' && node.name != null) {
|
|
1473
|
+
var nodeAttributeName = node.name.toLowerCase(); //取meta 标签的name 属性
|
|
1474
|
+
if (nodeAttributeName == 'keywords' || nodeAttributeName == 'description') {
|
|
1475
|
+
//替换渲染
|
|
1476
|
+
if (typeof (originalText) != 'undefined' && originalText.length > 0) {
|
|
1477
|
+
//this.nodes[hash][task_index].nodeValue = this.nodes[hash][task_index].nodeValue.replace(new RegExp(translate.util.regExp.pattern(task.originalText),'g'), translate.util.regExp.resultText(task.resultText));
|
|
1478
|
+
node.content = node.content.replace(new RegExp(translate.util.regExp.pattern(originalText), 'g'), translate.util.regExp.resultText(resultText));
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
result['text'] = node.content;
|
|
1482
|
+
return result;
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
result['text'] = '';
|
|
1487
|
+
return result;
|
|
1488
|
+
}
|
|
1489
|
+
if (nodename == 'IMG') {
|
|
1490
|
+
if (typeof (node.alt) == 'undefined' || node.alt == null) {
|
|
1491
|
+
result['text'] = '';
|
|
1492
|
+
return result;
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
//替换渲染
|
|
1496
|
+
if (typeof (originalText) != 'undefined' && originalText.length > 0) {
|
|
1497
|
+
//this.nodes[hash][task_index].nodeValue = this.nodes[hash][task_index].nodeValue.replace(new RegExp(translate.util.regExp.pattern(task.originalText),'g'), translate.util.regExp.resultText(task.resultText));
|
|
1498
|
+
node.alt = node.alt.replace(new RegExp(translate.util.regExp.pattern(originalText), 'g'), translate.util.regExp.resultText(resultText));
|
|
1499
|
+
}
|
|
1500
|
+
result['text'] = node.alt;
|
|
1501
|
+
return result;
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
|
|
1505
|
+
//其他的
|
|
1506
|
+
if (node.nodeValue == null || typeof (node.nodeValue) == 'undefined') {
|
|
1507
|
+
result['text'] = '';
|
|
1508
|
+
} else if (node.nodeValue.trim().length == 0) {
|
|
1509
|
+
//避免就是单纯的空格或者换行
|
|
1510
|
+
result['text'] = '';
|
|
1511
|
+
} else {
|
|
1512
|
+
//替换渲染
|
|
1513
|
+
if (typeof (originalText) != 'undefined' && originalText.length > 0) {
|
|
1514
|
+
//this.nodes[hash][task_index].nodeValue = this.nodes[hash][task_index].nodeValue.replace(new RegExp(translate.util.regExp.pattern(task.originalText),'g'), translate.util.regExp.resultText(task.resultText));
|
|
1515
|
+
node.nodeValue = node.nodeValue.replace(new RegExp(translate.util.regExp.pattern(originalText), 'g'), translate.util.regExp.resultText(resultText));
|
|
1516
|
+
}
|
|
1517
|
+
result['text'] = node.nodeValue;
|
|
1518
|
+
}
|
|
1519
|
+
return result;
|
|
1520
|
+
}
|
|
1521
|
+
},
|
|
1522
|
+
//获取这个node元素的node name ,如果未发现,则返回''空字符串
|
|
1523
|
+
getNodeName: function (node) {
|
|
1524
|
+
if (node == null || typeof (node) == 'undefined') {
|
|
1525
|
+
return '';
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
if (node.nodeName == null || typeof (node.nodeName) == 'undefined') {
|
|
1529
|
+
return '';
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
var nodename = node.nodeName;
|
|
1533
|
+
//console.log('nodename:'+nodename+', node:'+node);
|
|
1534
|
+
return nodename;
|
|
1535
|
+
},
|
|
1536
|
+
//向下遍历node
|
|
1537
|
+
whileNodes: function (uuid, node) {
|
|
1538
|
+
if (node == null || typeof (node) == 'undefined') {
|
|
1539
|
+
return;
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
//如果这个uuid没有,则创建
|
|
1543
|
+
if (typeof (translate.nodeQueue[uuid]) == 'undefined' || translate.nodeQueue[uuid] == null) {
|
|
1544
|
+
translate.nodeQueue[uuid] = new Array(); //创建
|
|
1545
|
+
translate.nodeQueue[uuid]['expireTime'] = Date.now() + 120 * 1000; //删除时间,10分钟后删除
|
|
1546
|
+
translate.nodeQueue[uuid]['list'] = new Array();
|
|
1547
|
+
//console.log('创建 --- ');
|
|
1548
|
+
//console.log(uuid)
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
//console.log('---'+typeof(node)+', ');
|
|
1552
|
+
//判断是否是有title属性,title属性也要翻译
|
|
1553
|
+
if (typeof (node) == 'object' && typeof (node['title']) == 'string' && node['title'].length > 0) {
|
|
1554
|
+
//将title加入翻译队列
|
|
1555
|
+
//console.log('---'+node.title+'\t'+node.tagName);
|
|
1556
|
+
//console.log(node)
|
|
1557
|
+
//console.log('------------');
|
|
1558
|
+
|
|
1559
|
+
//判断当前元素是否在ignore忽略的tag、id、class name中
|
|
1560
|
+
if (!translate.ignore.isIgnore(node)) {
|
|
1561
|
+
//不在忽略的里面,才会加入翻译
|
|
1562
|
+
translate.addNodeToQueue(uuid, node, node['title'], 'title');
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
var childNodes = node.childNodes;
|
|
1567
|
+
if (childNodes.length > 0) {
|
|
1568
|
+
for (var i = 0; i < childNodes.length; i++) {
|
|
1569
|
+
translate.element.whileNodes(uuid, childNodes[i]);
|
|
1570
|
+
}
|
|
1571
|
+
} else {
|
|
1572
|
+
//单个了
|
|
1573
|
+
translate.element.findNode(uuid, node);
|
|
1574
|
+
}
|
|
1575
|
+
},
|
|
1576
|
+
findNode: function (uuid, node) {
|
|
1577
|
+
if (node == null || typeof (node) == 'undefined') {
|
|
1578
|
+
return;
|
|
1579
|
+
}
|
|
1580
|
+
//console.log(node)
|
|
1581
|
+
if (node.parentNode == null) {
|
|
1582
|
+
return;
|
|
1583
|
+
}
|
|
1584
|
+
//console.log('-----parent')
|
|
1585
|
+
var parentNodeName = translate.element.getNodeName(node.parentNode);
|
|
1586
|
+
//node.parentNode.nodeName;
|
|
1587
|
+
if (parentNodeName == '') {
|
|
1588
|
+
return;
|
|
1589
|
+
}
|
|
1590
|
+
if (translate.ignore.tag.indexOf(parentNodeName.toLowerCase()) > -1) {
|
|
1591
|
+
//忽略tag
|
|
1592
|
+
//console.log('忽略tag:'+parentNodeName);
|
|
1593
|
+
return;
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
/****** 判断忽略的class ******/
|
|
1597
|
+
/*
|
|
1598
|
+
这段理论上不需要了,因为在 translate.ignore.isIgnore 判断了
|
|
1599
|
+
var ignoreClass = false; //是否是被忽略的class,true是
|
|
1600
|
+
var parentNode = node.parentNode;
|
|
1601
|
+
while(node != parentNode && parentNode != null){
|
|
1602
|
+
//console.log('node:'+node+', parentNode:'+parentNode);
|
|
1603
|
+
if(parentNode.className != null){
|
|
1604
|
+
if(translate.ignore.class.indexOf(parentNode.className) > -1){
|
|
1605
|
+
//发现ignore.class 当前是处于被忽略的 class
|
|
1606
|
+
ignoreClass = true;
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
parentNode = parentNode.parentNode;
|
|
1611
|
+
}
|
|
1612
|
+
if(ignoreClass){
|
|
1613
|
+
//console.log('ignore class : node:'+node.nodeValue);
|
|
1614
|
+
return;
|
|
1615
|
+
}
|
|
1616
|
+
*/
|
|
1617
|
+
/**** 判断忽略的class结束 ******/
|
|
1618
|
+
|
|
1619
|
+
|
|
1620
|
+
|
|
1621
|
+
/**** 避免中途局部翻译,在判断一下 ****/
|
|
1622
|
+
//判断当前元素是否在ignore忽略的tag、id、class name中
|
|
1623
|
+
if (translate.ignore.isIgnore(node)) {
|
|
1624
|
+
//console.log('node包含在要忽略的元素中:');
|
|
1625
|
+
//console.log(node);
|
|
1626
|
+
return;
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
//node分析
|
|
1630
|
+
var nodeAnaly = translate.element.nodeAnalyse.get(node);
|
|
1631
|
+
if (nodeAnaly['text'].length > 0) {
|
|
1632
|
+
//有要翻译的目标内容,加入翻译队列
|
|
1633
|
+
//console.log('addNodeToQueue -- '+nodeAnaly['node']+', text:' + nodeAnaly['text']);
|
|
1634
|
+
translate.addNodeToQueue(uuid, nodeAnaly['node'], nodeAnaly['text']);
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
/*
|
|
1638
|
+
//console.log(node.nodeName+', type:'+node.nodeType+', '+node.nodeValue);
|
|
1639
|
+
var nodename = translate.element.getNodeName(node);
|
|
1640
|
+
if(nodename == 'INPUT' || nodename == 'TEXTAREA'){
|
|
1641
|
+
//input 输入框,要对 placeholder 做翻译
|
|
1642
|
+
console.log('input---'+node.attributes);
|
|
1643
|
+
if(node.attributes == null || typeof(node.attributes) == 'undefined'){
|
|
1644
|
+
return;
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
if(typeof(node.attributes['placeholder']) != 'undefined'){
|
|
1648
|
+
//console.log(node.attributes['placeholder'].nodeValue);
|
|
1649
|
+
//加入要翻译的node队列
|
|
1650
|
+
//translate.nodeQueue[translate.hash(node.nodeValue)] = node.attributes['placeholder'];
|
|
1651
|
+
//加入要翻译的node队列
|
|
1652
|
+
//translate.addNodeToQueue(translate.hash(node.attributes['placeholder'].nodeValue), node.attributes['placeholder']);
|
|
1653
|
+
translate.addNodeToQueue(uuid, node.attributes['placeholder'], node.attributes['placeholder'].nodeValue);
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
//console.log(node.getAttribute("placeholder"));
|
|
1657
|
+
}else if(nodename == 'META'){
|
|
1658
|
+
//meta标签,如是关键词、描述等
|
|
1659
|
+
if(typeof(node.name) != 'undefined' && node.name != null){
|
|
1660
|
+
var nodeAttributeName = node.name.toLowerCase(); //取meta 标签的name 属性
|
|
1661
|
+
//console.log(nodeName);
|
|
1662
|
+
if(nodeAttributeName == 'keywords' || nodeAttributeName == 'description'){
|
|
1663
|
+
//关键词、描述
|
|
1664
|
+
translate.addNodeToQueue(uuid, node, node.content);
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
//console.log(node.name)
|
|
1668
|
+
}else if(nodename == 'IMG'){
|
|
1669
|
+
//console.log('-------'+node.alt);
|
|
1670
|
+
translate.addNodeToQueue(uuid, node, node.alt);
|
|
1671
|
+
}else if(node.nodeValue != null && node.nodeValue.trim().length > 0){
|
|
1672
|
+
|
|
1673
|
+
//过滤掉无效的值
|
|
1674
|
+
if(node.nodeValue != null && typeof(node.nodeValue) == 'string' && node.nodeValue.length > 0){
|
|
1675
|
+
}else{
|
|
1676
|
+
return;
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
//console.log(node.nodeValue+' --- ' + translate.language.get(node.nodeValue));
|
|
1680
|
+
|
|
1681
|
+
//console.log(node.nodeName);
|
|
1682
|
+
//console.log(node.parentNode.nodeName);
|
|
1683
|
+
//console.log(node.nodeValue);
|
|
1684
|
+
//加入要翻译的node队列
|
|
1685
|
+
translate.addNodeToQueue(uuid, node, node.nodeValue);
|
|
1686
|
+
//translate.addNodeToQueue(translate.hash(node.nodeValue), node);
|
|
1687
|
+
//translate.nodeQueue[translate.hash(node.nodeValue)] = node;
|
|
1688
|
+
//translate.nodeQueue[translate.hash(node.nodeValue)] = node.nodeValue;
|
|
1689
|
+
//node.nodeValue = node.nodeValue+'|';
|
|
1690
|
+
|
|
1691
|
+
}
|
|
1692
|
+
*/
|
|
1693
|
+
|
|
1694
|
+
},
|
|
1695
|
+
},
|
|
1696
|
+
|
|
1697
|
+
|
|
1698
|
+
|
|
1699
|
+
|
|
1700
|
+
|
|
1701
|
+
/*
|
|
1702
|
+
* 将发现的元素节点加入待翻译队列
|
|
1703
|
+
* uuid execute方法执行的唯一id
|
|
1704
|
+
* node 当前text所在的node
|
|
1705
|
+
* text 当前要翻译的目标文本
|
|
1706
|
+
* attribute 是否是元素的某个属性。比如 a标签中的title属性, a.title 再以node参数传入时是string类型的,本身并不是node类型,所以就要传入这个 attribute=title 来代表这是a标签的title属性。同样第二个参数node传入的也不能是a.title,而是传入a这个node元素
|
|
1707
|
+
*/
|
|
1708
|
+
addNodeToQueue: function (uuid, node, text, attribute) {
|
|
1709
|
+
if (node == null || text == null || text.length == 0) {
|
|
1710
|
+
return;
|
|
1711
|
+
}
|
|
1712
|
+
//console.log('find tag ignore : '+node.nodeValue+', '+node.nodeName+", "+node.nodeType+", "+node.tagName);
|
|
1713
|
+
//console.log('addNodeToQueue into -- node:'+node+', text:'+text+', attribute:'+attribute);
|
|
1714
|
+
var nodename = translate.element.getNodeName(node);
|
|
1715
|
+
|
|
1716
|
+
//判断如果是被 <!-- --> 注释的区域,不进行翻译
|
|
1717
|
+
if (nodename.toLowerCase() == '#comment') {
|
|
1718
|
+
return;
|
|
1719
|
+
}
|
|
1720
|
+
//console.log('\t\t'+text);
|
|
1721
|
+
//取要翻译字符的hash
|
|
1722
|
+
var key = translate.util.hash(text);
|
|
1723
|
+
/*
|
|
1724
|
+
如果是input 的 placeholder ,就会出现这个情况
|
|
1725
|
+
if(node.parentNode == null){
|
|
1726
|
+
console.log('node.parentNode == null');
|
|
1727
|
+
return;
|
|
1728
|
+
}
|
|
1729
|
+
*/
|
|
1730
|
+
|
|
1731
|
+
//console.log(node.parentNode);
|
|
1732
|
+
//console.log(node.parentNode.nodeName);
|
|
1733
|
+
|
|
1734
|
+
if (translate.util.findTag(text)) {
|
|
1735
|
+
//console.log('find tag ignore : '+node.nodeValue+', '+node.nodeName+", "+node.nodeType+", "+node.tagName);
|
|
1736
|
+
//console.log(node.parentNode.nodeName);
|
|
1737
|
+
|
|
1738
|
+
//获取到当前文本是属于那个tag标签中的,如果是script、style 这样的标签中,那也会忽略掉它,不进行翻译
|
|
1739
|
+
if (node.parentNode == null) {
|
|
1740
|
+
//没有上级了,或是没获取到上级,忽略
|
|
1741
|
+
return;
|
|
1742
|
+
}
|
|
1743
|
+
//去上级的tag name
|
|
1744
|
+
var parentNodeName = translate.element.getNodeName(node.parentNode);
|
|
1745
|
+
//node.parentNode.nodeName;
|
|
1746
|
+
if (parentNodeName == 'SCRIPT' || parentNodeName == 'STYLE') {
|
|
1747
|
+
//如果是script、style中发现的,那也忽略
|
|
1748
|
+
return;
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
//console.log(node.nodeValue);
|
|
1752
|
+
|
|
1753
|
+
//获取当前是什么语种
|
|
1754
|
+
var langs = translate.language.get(text);
|
|
1755
|
+
//console.log('langs');
|
|
1756
|
+
//console.log(langs);
|
|
1757
|
+
|
|
1758
|
+
//过滤掉要转换为的目标语种,比如要转为英语,那就将本来是英语的部分过滤掉,不用再翻译了
|
|
1759
|
+
if (typeof (langs[translate.to]) != 'undefined') {
|
|
1760
|
+
delete langs[translate.to];
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
/* if(this.nodeQueue[lang] == null || typeof(this.nodeQueue[lang]) == 'undefined'){
|
|
1764
|
+
this.nodeQueue[lang] = new Array();
|
|
1765
|
+
}
|
|
1766
|
+
//创建二维数组
|
|
1767
|
+
if(this.nodeQueue[lang][key] == null || typeof(this.nodeQueue[lang][key]) == 'undefined'){
|
|
1768
|
+
this.nodeQueue[lang][key] = new Array();
|
|
1769
|
+
}
|
|
1770
|
+
*/
|
|
1771
|
+
//console.log(langs);
|
|
1772
|
+
|
|
1773
|
+
for (var lang in langs) {
|
|
1774
|
+
//创建二维数组, key为语种,如 english
|
|
1775
|
+
if (translate.nodeQueue[uuid]['list'][lang] == null || typeof (translate.nodeQueue[uuid]['list'][lang]) == 'undefined') {
|
|
1776
|
+
translate.nodeQueue[uuid]['list'][lang] = new Array();
|
|
1777
|
+
}
|
|
1778
|
+
//console.log('|'+langs[lang].length);
|
|
1779
|
+
//遍历出该语种下有哪些词需要翻译
|
|
1780
|
+
for (var word_index = 0; word_index < langs[lang].length; word_index++) {
|
|
1781
|
+
//console.log('start:'+word_index)
|
|
1782
|
+
//console.log(langs[lang][word_index]);
|
|
1783
|
+
if (typeof (langs[lang][word_index]) == 'undefined' || typeof (langs[lang][word_index]['text']) == 'undefined') {
|
|
1784
|
+
//理论上应该不会,但多加个判断
|
|
1785
|
+
continue;
|
|
1786
|
+
}
|
|
1787
|
+
var word = langs[lang][word_index]['text']; //要翻译的词
|
|
1788
|
+
var beforeText = langs[lang][word_index]['beforeText'];
|
|
1789
|
+
var afterText = langs[lang][word_index]['afterText'];
|
|
1790
|
+
|
|
1791
|
+
//console.log("word:"+word+', bef:'+beforeText+', after:'+afterText)
|
|
1792
|
+
var hash = translate.util.hash(word); //要翻译的词的hash
|
|
1793
|
+
//console.log(hash);
|
|
1794
|
+
|
|
1795
|
+
//创建三维数组, key为要通过接口翻译的文本词或句子的 hash (注意并不是node的文本,而是node拆分后的文本)
|
|
1796
|
+
if (translate.nodeQueue[uuid]['list'][lang][hash] == null || typeof (translate.nodeQueue[uuid]['list'][lang][hash]) == 'undefined') {
|
|
1797
|
+
translate.nodeQueue[uuid]['list'][lang][hash] = new Array();
|
|
1798
|
+
|
|
1799
|
+
/*
|
|
1800
|
+
* 创建四维数组,存放具体数据
|
|
1801
|
+
* key: nodes 包含了这个hash的node元素的数组集合,array 多个。其中
|
|
1802
|
+
nodes[index]['node'] 存放当前的node元素
|
|
1803
|
+
nodes[index]['attribute'] 存放当前hash,也就是翻译文本针对的是什么,是node本身(nodeValue),还是 node 的某个属性,比如title属性。如果这里不为空,那就是针对的属性操作的
|
|
1804
|
+
* key: original 原始的要翻译的词或句子,html加载完成但还没翻译前的文本,用于支持当前页面多次语种翻译切换而无需跳转
|
|
1805
|
+
* beforeText、afterText:见 translate.nodeQueue 的说明
|
|
1806
|
+
*/
|
|
1807
|
+
translate.nodeQueue[uuid]['list'][lang][hash]['nodes'] = new Array();
|
|
1808
|
+
translate.nodeQueue[uuid]['list'][lang][hash]['original'] = word;
|
|
1809
|
+
translate.nodeQueue[uuid]['list'][lang][hash]['translateText'] = translate.nomenclature.dispose(word); //自定义术语处理
|
|
1810
|
+
translate.nodeQueue[uuid]['list'][lang][hash]['beforeText'] = beforeText;
|
|
1811
|
+
translate.nodeQueue[uuid]['list'][lang][hash]['afterText'] = afterText;
|
|
1812
|
+
//translate.nodeQueue[uuid]['list'][lang][hash]['attribute'] = attribute; //放入 nodes[index][attribute] 元素中
|
|
1813
|
+
|
|
1814
|
+
//其中key: nodes 是第四维数组,里面存放具体的node元素对象
|
|
1815
|
+
|
|
1816
|
+
|
|
1817
|
+
//console.log(translate.nodeQueue[uuid]['list'][lang][hash]);
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
if (typeof (node.isSameNode) != 'undefined') { //支持 isSameNode 方法判断对象是否相等
|
|
1821
|
+
for (var node_index = 0; node_index < translate.nodeQueue[uuid]['list'][lang][hash]['nodes'].length; node_index++) {
|
|
1822
|
+
if (node.isSameNode(translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][node_index]['node'])) {
|
|
1823
|
+
//相同,那就不用在存入了
|
|
1824
|
+
//console.log('相同,那就不用在存入了')
|
|
1825
|
+
//console.log(node)
|
|
1826
|
+
continue;
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
//往五维数组nodes中追加node元素
|
|
1832
|
+
var nodesIndex = translate.nodeQueue[uuid]['list'][lang][hash]['nodes'].length;
|
|
1833
|
+
translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][nodesIndex] = new Array();
|
|
1834
|
+
translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][nodesIndex]['node'] = node;
|
|
1835
|
+
translate.nodeQueue[uuid]['list'][lang][hash]['nodes'][nodesIndex]['attribute'] = attribute;
|
|
1836
|
+
//console.log('end:'+word_index)
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
|
|
1842
|
+
|
|
1843
|
+
//this.nodeQueue[lang][key][this.nodeQueue[lang][key].length]=node; //往数组中追加
|
|
1844
|
+
},
|
|
1845
|
+
|
|
1846
|
+
language: {
|
|
1847
|
+
//当前本地语种,本地语言,默认是简体中文。设置请使用 translate.language.setLocal(...)。不可直接使用,使用需用 getLocal()
|
|
1848
|
+
local: '',
|
|
1849
|
+
//传入语种。具体可传入哪些参考: http://api.translate.zvo.cn/doc/language.json.html
|
|
1850
|
+
setLocal: function (languageName) {
|
|
1851
|
+
translate.setUseVersion2(); //Set to use v2.x version
|
|
1852
|
+
translate.language.local = languageName;
|
|
1853
|
+
},
|
|
1854
|
+
//获取当前本地语种,本地语言,默认是简体中文。设置请使用 translate.language.setLocal(...)
|
|
1855
|
+
getLocal: function () {
|
|
1856
|
+
//判断是否设置了本地语种,如果没设置,自动给其设置
|
|
1857
|
+
if (translate.language.local == null || translate.language.local.length < 1) {
|
|
1858
|
+
translate.language.autoRecognitionLocalLanguage();
|
|
1859
|
+
}
|
|
1860
|
+
return translate.language.local;
|
|
1861
|
+
},
|
|
1862
|
+
/*
|
|
1863
|
+
获取当前语种。
|
|
1864
|
+
比如当前设置的本地语种是简体中文,用户并未切换其他语种,那么这个方法将返回本地当前的语种,也就是等同于 translate.language.getLocal()
|
|
1865
|
+
如果用户切换为英语进行浏览,那么这个方法将返回翻译的目标语种,也就是 english
|
|
1866
|
+
*/
|
|
1867
|
+
getCurrent: function () {
|
|
1868
|
+
var to_storage = translate.storage.get('to');
|
|
1869
|
+
if (to_storage != null && typeof (to_storage) != 'undefined' && to_storage.length > 0) {
|
|
1870
|
+
//之前有过使用,并且主动设置过目标语种
|
|
1871
|
+
return to_storage;
|
|
1872
|
+
}
|
|
1873
|
+
return translate.language.getLocal();
|
|
1874
|
+
},
|
|
1875
|
+
//如果第一次用,默认以什么语种显示。
|
|
1876
|
+
//比如本地当前语种是简体中文,这里设置为english,那么用户第一次使用时,会自动翻译为english进行显示。如果用户手动切换为其他语种比如韩语,那么就遵循用户手动切换的为主,显示韩语。
|
|
1877
|
+
setDefaultTo: function (languageName) {
|
|
1878
|
+
var to_storage = translate.storage.get('to');
|
|
1879
|
+
if (to_storage != null && typeof (to_storage) != 'undefined' && to_storage.length > 0) {
|
|
1880
|
+
//之前有过使用,并且主动设置过目标语种,那么不进行处理
|
|
1881
|
+
} else {
|
|
1882
|
+
//没有设置过,进行处理
|
|
1883
|
+
translate.storage.set('to', languageName);
|
|
1884
|
+
translate.to = languageName;
|
|
1885
|
+
}
|
|
1886
|
+
},
|
|
1887
|
+
//根据URL传参控制以何种语种显示
|
|
1888
|
+
//设置可以根据当前访问url的某个get参数来控制使用哪种语言显示。
|
|
1889
|
+
//比如当前语种是简体中文,网页url是http://translate.zvo.cn/index.html ,那么可以通过在url后面增加 language 参数指定翻译语种,来使网页内容以英文形态显示 http://translate.zvo.cn/index.html?language=english
|
|
1890
|
+
setUrlParamControl: function (paramName) {
|
|
1891
|
+
if (typeof (paramName) == 'undefined' || paramName.length < 1) {
|
|
1892
|
+
paramName = 'language';
|
|
1893
|
+
}
|
|
1894
|
+
var paramValue = translate.util.getUrlParam(paramName);
|
|
1895
|
+
if (typeof (paramValue) == 'undefined') {
|
|
1896
|
+
return;
|
|
1897
|
+
}
|
|
1898
|
+
if (paramValue == '' || paramValue == 'null' || paramValue == 'undefined') {
|
|
1899
|
+
return;
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
translate.storage.set('to', paramValue);
|
|
1903
|
+
translate.to = paramValue;
|
|
1904
|
+
},
|
|
1905
|
+
//自动识别当前页面是什么语种
|
|
1906
|
+
autoRecognitionLocalLanguage: function () {
|
|
1907
|
+
if (translate.language.local != null && translate.language.local.length > 2) {
|
|
1908
|
+
//已设置过了,不需要再设置
|
|
1909
|
+
return;
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1912
|
+
var bodyText = document.body.outerText;
|
|
1913
|
+
if (bodyText == null || typeof (bodyText) == 'undefined' || bodyText.length < 1) {
|
|
1914
|
+
//未取到,默认赋予简体中文
|
|
1915
|
+
translate.language.local = 'chinese_simplified';
|
|
1916
|
+
return;
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1919
|
+
bodyText = bodyText.replace(/\n|\t|\r/g, ''); //将回车换行等去掉
|
|
1920
|
+
|
|
1921
|
+
var langs = new Array(); //上一个字符的语种是什么,当前字符向上数第一个字符。格式如 ['language']='english', ['chatstr']='a', ['storage_language']='english' 这里面有3个参数,分别代表这个字符属于那个语种,其字符是什么、存入了哪种语种的队列。因为像是逗号,句号,一般是存入本身语种中,而不是存入特殊符号中。
|
|
1922
|
+
for (var i = 0; i < bodyText.length; i++) {
|
|
1923
|
+
var charstr = bodyText.charAt(i);
|
|
1924
|
+
var lang = translate.language.getCharLanguage(charstr);
|
|
1925
|
+
if (lang == '') {
|
|
1926
|
+
//未获取到,未发现是什么语言
|
|
1927
|
+
//continue;
|
|
1928
|
+
lang = 'unidentification';
|
|
1929
|
+
}
|
|
1930
|
+
langs.push(lang);
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1933
|
+
//从数组中取出现频率最高的
|
|
1934
|
+
var newLangs = translate.util.arrayFindMaxNumber(langs);
|
|
1935
|
+
|
|
1936
|
+
//移除数组中的特殊字符
|
|
1937
|
+
var index = newLangs.indexOf('specialCharacter');
|
|
1938
|
+
if (index > -1) {
|
|
1939
|
+
newLangs.splice(index, 1); //移除数组中的特殊字符
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1942
|
+
if (newLangs.length > 0) {
|
|
1943
|
+
//找到排序出现频率最多的
|
|
1944
|
+
translate.language.local = newLangs[0];
|
|
1945
|
+
} else {
|
|
1946
|
+
//没有,默认赋予简体中文
|
|
1947
|
+
translate.language.local = 'chinese_simplified';
|
|
1948
|
+
}
|
|
1949
|
+
},
|
|
1950
|
+
|
|
1951
|
+
/*
|
|
1952
|
+
* 获取当前字符是什么语种。返回值是一个语言标识,有 chinese_simplified简体中文、japanese日语、korean韩语、
|
|
1953
|
+
* str : node.nodeValue 或 图片的 node.alt 等
|
|
1954
|
+
* 如果语句长,会全句翻译,以保证翻译的准确性,提高可读性。
|
|
1955
|
+
* 如果语句短,会自动将特殊字符、要翻译的目标语种给过滤掉,只取出具体的要翻译的目标语种文本
|
|
1956
|
+
*/
|
|
1957
|
+
get: function (str) {
|
|
1958
|
+
//将str拆分为单个char进行判断
|
|
1959
|
+
|
|
1960
|
+
var langs = new Array(); //当前字符串包含哪些语言的数组,其内如 english
|
|
1961
|
+
var langStrs = new Array(); //存放不同语言的文本,格式如 ['english'][0] = 'hello'
|
|
1962
|
+
var upLangs = []; //上一个字符的语种是什么,当前字符向上数第一个字符。格式如 ['language']='english', ['chatstr']='a', ['storage_language']='english' 这里面有3个参数,分别代表这个字符属于那个语种,其字符是什么、存入了哪种语种的队列。因为像是逗号,句号,一般是存入本身语种中,而不是存入特殊符号中。
|
|
1963
|
+
var upLangsTwo = []; //上二个字符的语种是什么 ,当前字符向上数第二个字符。 格式如 ['language']='english', ['chatstr']='a', ['storage_language']='english' 这里面有3个参数,分别代表这个字符属于那个语种,其字符是什么、存入了哪种语种的队列。因为像是逗号,句号,一般是存入本身语种中,而不是存入特殊符号中。
|
|
1964
|
+
|
|
1965
|
+
//var upLangs = ''; //上一个字符的语种是什么,格式如 english
|
|
1966
|
+
for (var i = 0; i < str.length; i++) {
|
|
1967
|
+
var charstr = str.charAt(i);
|
|
1968
|
+
//console.log('charstr:'+charstr)
|
|
1969
|
+
var lang = translate.language.getCharLanguage(charstr);
|
|
1970
|
+
if (lang == '') {
|
|
1971
|
+
//未获取到,未发现是什么语言
|
|
1972
|
+
//continue;
|
|
1973
|
+
lang = 'unidentification';
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
var result = translate.language.analyse(lang, langStrs, upLangs, upLangsTwo, charstr);
|
|
1977
|
+
//console.log(result)
|
|
1978
|
+
langStrs = result['langStrs'];
|
|
1979
|
+
//记录上几个字符
|
|
1980
|
+
if (typeof (upLangs['language']) != 'undefined') {
|
|
1981
|
+
upLangsTwo['language'] = upLangs['language'];
|
|
1982
|
+
upLangsTwo['charstr'] = upLangs['charstr'];
|
|
1983
|
+
upLangsTwo['storage_language'] = upLangs['storage_language'];
|
|
1984
|
+
}
|
|
1985
|
+
//upLangs['language'] = lang;
|
|
1986
|
+
upLangs['language'] = result['storage_language'];
|
|
1987
|
+
upLangs['charstr'] = charstr;
|
|
1988
|
+
upLangs['storage_language'] = result['storage_language'];
|
|
1989
|
+
//console.log(result['storage_language'])
|
|
1990
|
+
//console.log(upLangs['language']);
|
|
1991
|
+
langs.push(lang);
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
//console.log(langStrs);
|
|
1995
|
+
|
|
1996
|
+
//console.log(langs);
|
|
1997
|
+
//console.log(langStrs);
|
|
1998
|
+
|
|
1999
|
+
/*
|
|
2000
|
+
//从数组中取出现频率最高的
|
|
2001
|
+
var newLangs = translate.util.arrayFindMaxNumber(langs);
|
|
2002
|
+
|
|
2003
|
+
//移除当前翻译目标的语言。因为已经是目标预言了,不需要翻译了
|
|
2004
|
+
var index = newLangs.indexOf(translate.to);
|
|
2005
|
+
if(index > -1){
|
|
2006
|
+
newLangs.splice(index,1); //移除
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
//移除特殊字符
|
|
2010
|
+
var index = newLangs.indexOf('specialCharacter');
|
|
2011
|
+
if(index > -1){
|
|
2012
|
+
newLangs.splice(index,1); //移除数组中的特殊字符
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
if(newLangs.length > 0){
|
|
2016
|
+
//还剩一个或多个,(如果是多个,那应该是这几个出现的频率一样,所以取频率最高的时返回了多个)
|
|
2017
|
+
return newLangs[0];
|
|
2018
|
+
}else{
|
|
2019
|
+
//没找到,直接返回空字符串
|
|
2020
|
+
return '';
|
|
2021
|
+
}
|
|
2022
|
+
*/
|
|
2023
|
+
|
|
2024
|
+
|
|
2025
|
+
//去除特殊符号
|
|
2026
|
+
//for(var i = 0; i<langStrs.length; i++){
|
|
2027
|
+
/*
|
|
2028
|
+
var i = 0;
|
|
2029
|
+
for(var item in langStrs) {
|
|
2030
|
+
if(item == 'unidentification' || item == 'specialCharacter'){
|
|
2031
|
+
//langStrs.splice(i,1); //移除
|
|
2032
|
+
delete langStrs[item];
|
|
2033
|
+
}
|
|
2034
|
+
console.log(item);
|
|
2035
|
+
i++;
|
|
2036
|
+
}
|
|
2037
|
+
*/
|
|
2038
|
+
|
|
2039
|
+
//console.log(langStrs);
|
|
2040
|
+
if (typeof (langStrs['unidentification']) != 'undefined') {
|
|
2041
|
+
delete langStrs['unidentification'];
|
|
2042
|
+
}
|
|
2043
|
+
if (typeof (langStrs['specialCharacter']) != 'undefined') {
|
|
2044
|
+
delete langStrs['specialCharacter'];
|
|
2045
|
+
}
|
|
2046
|
+
if (typeof (langStrs['number']) != 'undefined') {
|
|
2047
|
+
delete langStrs['number'];
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
|
|
2051
|
+
//console.log('get end');
|
|
2052
|
+
return langStrs;
|
|
2053
|
+
},
|
|
2054
|
+
// 传入一个char,返回这个char属于什么语种,返回如 chinese_simplified、english 如果返回空字符串,那么表示未获取到是什么语种
|
|
2055
|
+
getCharLanguage: function (charstr) {
|
|
2056
|
+
if (charstr == null || typeof (charstr) == 'undefined') {
|
|
2057
|
+
return '';
|
|
2058
|
+
}
|
|
2059
|
+
|
|
2060
|
+
if (this.english(charstr)) {
|
|
2061
|
+
return 'english';
|
|
2062
|
+
} else if (this.specialCharacter(charstr)) {
|
|
2063
|
+
return 'specialCharacter';
|
|
2064
|
+
} else if (this.number(charstr)) {
|
|
2065
|
+
return 'number';
|
|
2066
|
+
} else if (this.chinese_simplified(charstr)) {
|
|
2067
|
+
return 'chinese_simplified';
|
|
2068
|
+
} else if (this.japanese(charstr)) {
|
|
2069
|
+
return 'japanese';
|
|
2070
|
+
} else if (this.korean(charstr)) {
|
|
2071
|
+
return 'korean';
|
|
2072
|
+
} else {
|
|
2073
|
+
console.log('not find is language , char : ' + charstr + ', unicode: ' + charstr.charCodeAt(0).toString(16));
|
|
2074
|
+
return '';
|
|
2075
|
+
}
|
|
2076
|
+
},
|
|
2077
|
+
/*
|
|
2078
|
+
* 对字符串进行分析,分析字符串是有哪几种语言组成。
|
|
2079
|
+
* language : 当前字符的语种,传入如 english
|
|
2080
|
+
* langStrs : 操作的,如 langStrs['english'][0] = '你好'
|
|
2081
|
+
* upLangs : 当前字符之前的上一个字符的语种是什么,当前字符向上数第一个字符。格式如 ['language']='english', ['chatstr']='a', ['storage_language']='english' 这里面有3个参数,分别代表这个字符属于那个语种,其字符是什么、存入了哪种语种的队列。因为像是逗号,句号,一般是存入本身语种中,而不是存入特殊符号中。
|
|
2082
|
+
* upLangsTwo : 当前字符之前的上二个字符的语种是什么 ,当前字符向上数第二个字符。 格式如 ['language']='english', ['chatstr']='a', ['storage_language']='english' 这里面有3个参数,分别代表这个字符属于那个语种,其字符是什么、存入了哪种语种的队列。因为像是逗号,句号,一般是存入本身语种中,而不是存入特殊符号中。
|
|
2083
|
+
* chatstr : 当前字符,如 h
|
|
2084
|
+
*/
|
|
2085
|
+
analyse: function (language, langStrs, upLangs, upLangsTwo, charstr) {
|
|
2086
|
+
if (typeof (langStrs[language]) == 'undefined') {
|
|
2087
|
+
langStrs[language] = new Array();
|
|
2088
|
+
}
|
|
2089
|
+
var index = 0; //当前要存入的数组下标
|
|
2090
|
+
if (typeof (upLangs['storage_language']) == 'undefined') {
|
|
2091
|
+
//第一次,那么还没存入值,index肯定为0
|
|
2092
|
+
//console.log('第一次,那么还没存入值,index肯定为0')
|
|
2093
|
+
//console.log(upLangs['language'])
|
|
2094
|
+
} else {
|
|
2095
|
+
//console.log('analyse, charstr : '+charstr+', upLangs :');
|
|
2096
|
+
//console.log(upLangs);
|
|
2097
|
+
//var isEqual = upLangs['storage_language'] == language; //上次跟当前字符是否都是同一个语种(这个字符跟这个字符前一个字符)
|
|
2098
|
+
|
|
2099
|
+
/*
|
|
2100
|
+
英语每个单词之间都会有空格分割. 如果是英文的话,英文跟特殊字符还要单独判断一下,避免拆开,造成翻译不准,单个单词翻译的情况
|
|
2101
|
+
所以如果上次的字符是英文或特殊符号,当前字符是特殊符号(逗号、句号、空格,然后直接笼统就吧特殊符号都算上吧),那么也将当次的特殊符号变为英文来进行适配
|
|
2102
|
+
示例
|
|
2103
|
+
hello word 的 "o w"
|
|
2104
|
+
hello word 的 " w"
|
|
2105
|
+
hello word 的 "w "
|
|
2106
|
+
this is a dog 的 " a "
|
|
2107
|
+
*/
|
|
2108
|
+
//console.log(language == 'specialCharacter');
|
|
2109
|
+
//如果两个字符类型不一致,但当前字符是英文或连接符时,进行判断
|
|
2110
|
+
/*
|
|
2111
|
+
if(!isEqual){
|
|
2112
|
+
if(language == 'english' || translate.language.connector(charstr)){
|
|
2113
|
+
console.log('1.'+(language == 'english' || translate.language.connector(charstr))+', upLangs str:'+upLangs['charstr']);
|
|
2114
|
+
//上一个字符是英文或连接符
|
|
2115
|
+
//console.log('teshu:'+translate.language.connector(upLangs['charstr'])+', str:'+upLangs['charstr']);
|
|
2116
|
+
if(upLangs['language'] == 'english' || translate.language.connector(upLangs['charstr'])) {
|
|
2117
|
+
console.log('2');
|
|
2118
|
+
//如果上二个字符不存在,那么刚开始,不再上面几种情况之中,直接不用考虑
|
|
2119
|
+
if(typeof(upLangsTwo['language']) != 'undefined'){
|
|
2120
|
+
console.log('3')
|
|
2121
|
+
//上二个字符是空(字符串刚开始),或者是英文
|
|
2122
|
+
if(upLangsTwo['language'] == 'english' || translate.language.connector(upLangsTwo['charstr'])){
|
|
2123
|
+
//满足这三个条件,那就将这三个拼接到一起
|
|
2124
|
+
console.log('4/5: '+', two lang:'+upLangsTwo['language']+', str:'+upLangsTwo['charstr'])
|
|
2125
|
+
isEqual = true;
|
|
2126
|
+
if(language == 'specialCharacter' && upLangs['language'] == 'specialCharacter' && upLangsTwo['language'] == 'specialCharacter'){
|
|
2127
|
+
//如果三个都是特殊字符,或后两个是特殊字符,第一个是空(刚开始),那就归入特殊字符
|
|
2128
|
+
language = 'specialCharacter';
|
|
2129
|
+
//console.log('4')
|
|
2130
|
+
}else{
|
|
2131
|
+
//不然就都归于英文中。
|
|
2132
|
+
//这里更改是为了让下面能将特殊字符(像是空格逗号等)也一起存入数组
|
|
2133
|
+
language = 'english';
|
|
2134
|
+
console.log(5)
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
*/
|
|
2142
|
+
|
|
2143
|
+
/*
|
|
2144
|
+
不判断当前字符,而判断上个字符,是因为当前字符没法获取未知的下个字符。
|
|
2145
|
+
*/
|
|
2146
|
+
//if(!isEqual){
|
|
2147
|
+
|
|
2148
|
+
//如果当前字符是连接符
|
|
2149
|
+
if (translate.language.connector(charstr)) {
|
|
2150
|
+
language = upLangs['storage_language'];
|
|
2151
|
+
/*
|
|
2152
|
+
//判断上个字符是否存入了待翻译字符,如要将中文翻译为英文,而上个字符是中文,待翻译,那将连接符一并加入待翻译字符中去,保持句子完整性
|
|
2153
|
+
//判断依据是上个字符存储至的翻译字符语种序列,不是特殊字符,而且也不是要翻译的目标语种,那肯定就是待翻译的,将连接符加入待翻译中一起进行翻译
|
|
2154
|
+
if(upLangs['storage_language'] != 'specialCharacter' && upLangs['storage_language'] != translate.to){
|
|
2155
|
+
|
|
2156
|
+
language = upLangs['storage_language'];
|
|
2157
|
+
console.log('teshu:'+charstr+', 当前字符并入上个字符存储翻译语种:'+upLangs['storage_language']);
|
|
2158
|
+
}
|
|
2159
|
+
*/
|
|
2160
|
+
}
|
|
2161
|
+
//}
|
|
2162
|
+
|
|
2163
|
+
//console.log('isEqual:'+isEqual);
|
|
2164
|
+
/*
|
|
2165
|
+
if(isEqual){
|
|
2166
|
+
//跟上次语言一样,那么直接拼接
|
|
2167
|
+
index = langStrs[language].length-1;
|
|
2168
|
+
//但是还有别的特殊情况,v2.1针对英文翻译准确度的适配,会有特殊字符的问题
|
|
2169
|
+
if(typeof(upLangs['storage_language']) != 'undefined' && upLangs['storage_language'] != language){
|
|
2170
|
+
//如果上个字符存入的翻译队列跟当前这个要存入的队列不一个的话,那应该是特殊字符像是逗号句号等导致的,那样还要额外一个数组,不能在存入之前的数组了
|
|
2171
|
+
index = langStrs[language].length;
|
|
2172
|
+
}
|
|
2173
|
+
}else{
|
|
2174
|
+
//console.log('新开');
|
|
2175
|
+
//当前字符跟上次语言不样,那么新开一个数组
|
|
2176
|
+
index = langStrs[language].length;
|
|
2177
|
+
//console.log('++, inde:'+index+',lang:'+language+', length:'+langStrs[language].length)
|
|
2178
|
+
}
|
|
2179
|
+
*/
|
|
2180
|
+
|
|
2181
|
+
//当前要翻译的语种跟上个字符要翻译的语种一样,那么直接拼接
|
|
2182
|
+
if (upLangs['storage_language'] == language) {
|
|
2183
|
+
index = langStrs[language].length - 1;
|
|
2184
|
+
} else {
|
|
2185
|
+
//console.log('新开');
|
|
2186
|
+
//当前字符跟上次语言不样,那么新开一个数组
|
|
2187
|
+
index = langStrs[language].length;
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
if (typeof (langStrs[language][index]) == 'undefined') {
|
|
2191
|
+
langStrs[language][index] = new Array();
|
|
2192
|
+
langStrs[language][index]['beforeText'] = '';
|
|
2193
|
+
langStrs[language][index]['afterText'] = '';
|
|
2194
|
+
langStrs[language][index]['text'] = '';
|
|
2195
|
+
}
|
|
2196
|
+
langStrs[language][index]['text'] = langStrs[language][index]['text'] + charstr;
|
|
2197
|
+
/*
|
|
2198
|
+
中文英文混合时,当中文+英文并没有空格间隔,翻译为英文时,会使中文翻译英文的结果跟原本的英文单词连到一块。这里就是解决这种情况
|
|
2199
|
+
针对当前非英文(不需要空格分隔符,像是中文、韩语),但要翻译为英文(需要空格作为分割符号,像是法语等)时的情况进行判断
|
|
2200
|
+
*/
|
|
2201
|
+
//if(translate.language.getLocal() != 'english' && translate.to == 'english'){
|
|
2202
|
+
//当前本地语种的语言是连续的,但翻译的目标语言不是连续的(空格间隔)
|
|
2203
|
+
if (translate.language.wordBlankConnector(translate.language.getLocal()) == false && translate.language.wordBlankConnector(translate.to)) {
|
|
2204
|
+
if ((upLangs['storage_language'] != null && typeof (upLangs['storage_language']) != 'undefined' && upLangs['storage_language'].length > 0)) {
|
|
2205
|
+
//上个字符存在
|
|
2206
|
+
//console.log(upLangs['storage_language']);
|
|
2207
|
+
if (upLangs['storage_language'] != 'specialCharacter') {
|
|
2208
|
+
//上个字符不是特殊字符 (是正常语种。且不会是连接符,连接符都并入了正常语种)
|
|
2209
|
+
|
|
2210
|
+
//if( upLangs['storage_language'] != 'english' && language == 'english'){
|
|
2211
|
+
//上个字符的语言是连续的,但当前字符的语言不是连续的(空格间隔)
|
|
2212
|
+
if (translate.language.wordBlankConnector(upLangs['storage_language']) == false && translate.language.wordBlankConnector(language)) {
|
|
2213
|
+
//上个字符不是英语,当前字符是英语,这种情况要在上个字符后面追加空格,因为当前字符是英文,就不会在执行翻译操作了
|
|
2214
|
+
//console.log(upLangs['language']);
|
|
2215
|
+
langStrs[upLangs['storage_language']][langStrs[upLangs['storage_language']].length - 1]['afterText'] = ' ';
|
|
2216
|
+
} else if (upLangs['storage_language'] == 'english' && language != 'english') {
|
|
2217
|
+
//上个字符是英语,当前字符不是英语,直接在当前字符前面追加空格
|
|
2218
|
+
langStrs[language][index]['beforeText'] = ' ';
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
var result = new Array();
|
|
2227
|
+
result['langStrs'] = langStrs;
|
|
2228
|
+
result['storage_language'] = language; //实际存入了哪种语种队列
|
|
2229
|
+
//console.log(result);
|
|
2230
|
+
//console.log(langStrs)
|
|
2231
|
+
//console.log(charstr);
|
|
2232
|
+
return result;
|
|
2233
|
+
},
|
|
2234
|
+
|
|
2235
|
+
/*
|
|
2236
|
+
* 不同于语言,这个只是单纯的连接符。比如英文单词之间有逗号、句号、空格, 汉字之间有逗号句号书名号的。避免一行完整的句子被分割,导致翻译不准确
|
|
2237
|
+
* 单独拿他出来,目的是为了更好的判断计算,提高翻译的准确率
|
|
2238
|
+
*/
|
|
2239
|
+
connector: function (str) {
|
|
2240
|
+
|
|
2241
|
+
/*
|
|
2242
|
+
通用的有 空格、阿拉伯数字
|
|
2243
|
+
1.不间断空格\u00A0,主要用在office中,让一个单词在结尾处不会换行显示,快捷键ctrl+shift+space ;
|
|
2244
|
+
2.半角空格(英文符号)\u0020,代码中常用的;
|
|
2245
|
+
3.全角空格(中文符号)\u3000,中文文章中使用;
|
|
2246
|
+
*/
|
|
2247
|
+
if (/.*[\u0020\u00A0\u202F\u205F\u3000]+.*$/.test(str)) {
|
|
2248
|
+
return true;
|
|
2249
|
+
}
|
|
2250
|
+
/*
|
|
2251
|
+
U+0030 0 数字 0
|
|
2252
|
+
U+0031 1 数字 1
|
|
2253
|
+
U+0032 2 数字 2
|
|
2254
|
+
U+0033 3 数字 3
|
|
2255
|
+
U+0034 4 数字 4
|
|
2256
|
+
U+0035 5 数字 5
|
|
2257
|
+
U+0036 6 数字 6
|
|
2258
|
+
U+0037 7 数字 7
|
|
2259
|
+
U+0038 8 数字 8
|
|
2260
|
+
U+0039 9 数字 9
|
|
2261
|
+
*/
|
|
2262
|
+
if (/.*[\u0030-\u0039]+.*$/.test(str)) {
|
|
2263
|
+
return true
|
|
2264
|
+
}
|
|
2265
|
+
|
|
2266
|
+
|
|
2267
|
+
/*
|
|
2268
|
+
英文场景
|
|
2269
|
+
英文逗号、句号
|
|
2270
|
+
这里不包括() 因为这里面的基本属于补充,对语句前后并无强依赖关系
|
|
2271
|
+
|
|
2272
|
+
U+0021 ! 叹号
|
|
2273
|
+
U+0022 " 双引号
|
|
2274
|
+
U+0023 # 井号
|
|
2275
|
+
U+0024 $ 价钱/货币符号
|
|
2276
|
+
U+0025 % 百分比符号
|
|
2277
|
+
U+0026 & 英文“and”的简写符号
|
|
2278
|
+
U+0027 ' 引号
|
|
2279
|
+
U+002C , 逗号
|
|
2280
|
+
U+002D - 连字号/减号
|
|
2281
|
+
U+002E . 句号
|
|
2282
|
+
U+003A : 冒号
|
|
2283
|
+
U+003B ; 分号
|
|
2284
|
+
U+003F ? 问号
|
|
2285
|
+
U+0040 @ 英文“at”的简写符号
|
|
2286
|
+
|
|
2287
|
+
|
|
2288
|
+
*/
|
|
2289
|
+
if (/.*[\u0021\u0022\u0023\u0024\u0025\u0026\u0027\u002C\u002D\u002E\u003A\u003B\u003F\u0040]+.*$/.test(str)) {
|
|
2290
|
+
return true;
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2293
|
+
/*
|
|
2294
|
+
中文标点符号
|
|
2295
|
+
名称 Unicode 符号
|
|
2296
|
+
句号 3002 。
|
|
2297
|
+
问号 FF1F ?
|
|
2298
|
+
叹号 FF01 !
|
|
2299
|
+
逗号 FF0C ,
|
|
2300
|
+
顿号 3001 、
|
|
2301
|
+
分号 FF1B ;
|
|
2302
|
+
冒号 FF1A :
|
|
2303
|
+
引号 300C 「
|
|
2304
|
+
300D 」
|
|
2305
|
+
引号 300E 『
|
|
2306
|
+
300F 』
|
|
2307
|
+
引号 2018 ‘
|
|
2308
|
+
2019 ’
|
|
2309
|
+
引号 201C “
|
|
2310
|
+
201D ”
|
|
2311
|
+
括号 FF08 (
|
|
2312
|
+
FF09 )
|
|
2313
|
+
括号 3014 〔
|
|
2314
|
+
3015 〕
|
|
2315
|
+
括号 3010 【
|
|
2316
|
+
3011 】
|
|
2317
|
+
破折号 2014 —
|
|
2318
|
+
省略号 2026 …
|
|
2319
|
+
连接号 2013 –
|
|
2320
|
+
间隔号 FF0E .
|
|
2321
|
+
书名号 300A 《
|
|
2322
|
+
300B 》
|
|
2323
|
+
书名号 3008 〈
|
|
2324
|
+
3009 〉
|
|
2325
|
+
键盘123前面的那个符号 · 00b7
|
|
2326
|
+
*/
|
|
2327
|
+
if (/.*[\u3002\uFF1F\uFF01\uFF0C\u3001\uFF1B\uFF1A\u300C\u300D\u300E\u300F\u2018\u2019\u201C\u201D\uFF08\uFF09\u3014\u3015\u3010\u3011\u2014\u2026\u2013\uFF0E\u300A\u300B\u3008\u3009\u00b7]+.*$/.test(str)) {
|
|
2328
|
+
return true;
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
|
|
2332
|
+
|
|
2333
|
+
|
|
2334
|
+
//不是,返回false
|
|
2335
|
+
return false;
|
|
2336
|
+
},
|
|
2337
|
+
//语种的单词连接符是否需要空格,比如中文、韩文、日语都不需要空格,则返回false, 但是像是英文的单词间需要空格进行隔开,则返回true
|
|
2338
|
+
//如果未匹配到,默认返回true
|
|
2339
|
+
//language:语种,传入如 english
|
|
2340
|
+
wordBlankConnector: function (language) {
|
|
2341
|
+
if (language == null || typeof (language) == 'undefined') {
|
|
2342
|
+
return true;
|
|
2343
|
+
}
|
|
2344
|
+
switch (language.trim().toLowerCase()) {
|
|
2345
|
+
case 'chinese_simplified':
|
|
2346
|
+
return false;
|
|
2347
|
+
case 'chinese_traditional':
|
|
2348
|
+
return false;
|
|
2349
|
+
case 'korean':
|
|
2350
|
+
return false;
|
|
2351
|
+
case 'japanese':
|
|
2352
|
+
return false;
|
|
2353
|
+
}
|
|
2354
|
+
//其他情况则返回true
|
|
2355
|
+
return true;
|
|
2356
|
+
},
|
|
2357
|
+
//是否包含中文,true:包含
|
|
2358
|
+
chinese_simplified: function (str) {
|
|
2359
|
+
if (/.*[\u4e00-\u9fa5]+.*$/.test(str)) {
|
|
2360
|
+
return true
|
|
2361
|
+
} else {
|
|
2362
|
+
return false;
|
|
2363
|
+
}
|
|
2364
|
+
},
|
|
2365
|
+
//是否包含英文,true:包含
|
|
2366
|
+
english: function (str) {
|
|
2367
|
+
if (/.*[\u0041-\u005a]+.*$/.test(str)) {
|
|
2368
|
+
return true;
|
|
2369
|
+
} else if (/.*[\u0061-\u007a]+.*$/.test(str)) {
|
|
2370
|
+
return true;
|
|
2371
|
+
} else {
|
|
2372
|
+
return false;
|
|
2373
|
+
}
|
|
2374
|
+
},
|
|
2375
|
+
//是否包含日语,true:包含
|
|
2376
|
+
japanese: function (str) {
|
|
2377
|
+
if (/.*[\u0800-\u4e00]+.*$/.test(str)) {
|
|
2378
|
+
return true
|
|
2379
|
+
} else {
|
|
2380
|
+
return false;
|
|
2381
|
+
}
|
|
2382
|
+
},
|
|
2383
|
+
//是否包含韩语,true:包含
|
|
2384
|
+
korean: function (str) {
|
|
2385
|
+
if (/.*[\uAC00-\uD7AF]+.*$/.test(str)) {
|
|
2386
|
+
return true
|
|
2387
|
+
} else {
|
|
2388
|
+
return false;
|
|
2389
|
+
}
|
|
2390
|
+
},
|
|
2391
|
+
//0-9 阿拉伯数字
|
|
2392
|
+
number: function (str) {
|
|
2393
|
+
if (/.*[\u0030-\u0039]+.*$/.test(str)) {
|
|
2394
|
+
return true;
|
|
2395
|
+
}
|
|
2396
|
+
return false;
|
|
2397
|
+
},
|
|
2398
|
+
//是否包含特殊字符
|
|
2399
|
+
specialCharacter: function (str) {
|
|
2400
|
+
//如:① ⑴ ⒈
|
|
2401
|
+
if (/.*[\u2460-\u24E9]+.*$/.test(str)) {
|
|
2402
|
+
return true
|
|
2403
|
+
}
|
|
2404
|
+
|
|
2405
|
+
//如:┊┌┍ ▃ ▄ ▅
|
|
2406
|
+
if (/.*[\u2500-\u25FF]+.*$/.test(str)) {
|
|
2407
|
+
return true
|
|
2408
|
+
}
|
|
2409
|
+
|
|
2410
|
+
//如:㈠ ㎎ ㎏ ㎡
|
|
2411
|
+
if (/.*[\u3200-\u33FF]+.*$/.test(str)) {
|
|
2412
|
+
return true
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
//如:与ANSI对应的全角字符
|
|
2416
|
+
if (/.*[\uFF00-\uFF5E]+.*$/.test(str)) {
|
|
2417
|
+
return true
|
|
2418
|
+
}
|
|
2419
|
+
|
|
2420
|
+
//其它特殊符号
|
|
2421
|
+
if (/.*[\u2000-\u22FF]+.*$/.test(str)) {
|
|
2422
|
+
return true
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2425
|
+
// 、><等符号
|
|
2426
|
+
if (/.*[\u3001-\u3036]+.*$/.test(str)) {
|
|
2427
|
+
return true;
|
|
2428
|
+
}
|
|
2429
|
+
|
|
2430
|
+
/*
|
|
2431
|
+
//阿拉伯数字 0-9
|
|
2432
|
+
if(/.*[\u0030-\u0039]+.*$/.test(str)){
|
|
2433
|
+
return true;
|
|
2434
|
+
}
|
|
2435
|
+
*/
|
|
2436
|
+
|
|
2437
|
+
/*
|
|
2438
|
+
U+0020 空格
|
|
2439
|
+
U+0021 ! 叹号
|
|
2440
|
+
U+0022 " 双引号
|
|
2441
|
+
U+0023 # 井号
|
|
2442
|
+
U+0024 $ 价钱/货币符号
|
|
2443
|
+
U+0025 % 百分比符号
|
|
2444
|
+
U+0026 & 英文“and”的简写符号
|
|
2445
|
+
U+0027 ' 引号
|
|
2446
|
+
U+0028 ( 开 左圆括号
|
|
2447
|
+
U+0029 ) 关 右圆括号
|
|
2448
|
+
U+002A * 星号
|
|
2449
|
+
U+002B + 加号
|
|
2450
|
+
U+002C , 逗号
|
|
2451
|
+
U+002D - 连字号/减号
|
|
2452
|
+
U+002E . 句号
|
|
2453
|
+
U+002F / 左斜杠
|
|
2454
|
+
*/
|
|
2455
|
+
if (/.*[\u0020-\u002F]+.*$/.test(str)) {
|
|
2456
|
+
return true;
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
/*
|
|
2460
|
+
U+003A : 冒号
|
|
2461
|
+
U+003B ; 分号
|
|
2462
|
+
U+003C < 小于符号
|
|
2463
|
+
U+003D = 等于号
|
|
2464
|
+
U+003E > 大于符号
|
|
2465
|
+
U+003F ? 问号
|
|
2466
|
+
U+0040 @ 英文“at”的简写符号
|
|
2467
|
+
U+0041 A 拉丁字母 A
|
|
2468
|
+
U+0042 B 拉丁字母 B
|
|
2469
|
+
U+0043 C 拉丁字母 C
|
|
2470
|
+
U+0044 D 拉丁字母 D
|
|
2471
|
+
U+0045 E 拉丁字母 E
|
|
2472
|
+
U+0046 F 拉丁字母 F
|
|
2473
|
+
U+0047 G 拉丁字母 G
|
|
2474
|
+
U+0048 H 拉丁字母 H
|
|
2475
|
+
U+0049 I 拉丁字母 I
|
|
2476
|
+
U+004A J 拉丁字母 J
|
|
2477
|
+
U+004B K 拉丁字母 K
|
|
2478
|
+
U+004C L 拉丁字母 L
|
|
2479
|
+
U+004D M 拉丁字母 M
|
|
2480
|
+
U+004E N 拉丁字母 N
|
|
2481
|
+
U+004F O 拉丁字母 O
|
|
2482
|
+
U+0050 P 拉丁字母 P
|
|
2483
|
+
U+0051 Q 拉丁字母 Q
|
|
2484
|
+
U+0052 R 拉丁字母 R
|
|
2485
|
+
U+0053 S 拉丁字母 S
|
|
2486
|
+
U+0054 T 拉丁字母 T
|
|
2487
|
+
U+0055 U 拉丁字母 U
|
|
2488
|
+
U+0056 V 拉丁字母 V
|
|
2489
|
+
U+0057 W 拉丁字母 W
|
|
2490
|
+
U+0058 X 拉丁字母 X
|
|
2491
|
+
U+0059 Y 拉丁字母 Y
|
|
2492
|
+
U+005A Z 拉丁字母 Z
|
|
2493
|
+
U+005B [ 开 方括号
|
|
2494
|
+
U+005C \ 右斜杠
|
|
2495
|
+
U+005D ] 关 方括号
|
|
2496
|
+
U+005E ^ 抑扬(重音)符号
|
|
2497
|
+
U+005F _ 底线
|
|
2498
|
+
U+0060 ` 重音符
|
|
2499
|
+
U+0061 a 拉丁字母 a
|
|
2500
|
+
U+0062 b 拉丁字母 b
|
|
2501
|
+
U+0063 c 拉丁字母 c
|
|
2502
|
+
U+0064 d 拉丁字母 d
|
|
2503
|
+
U+0065 e 拉丁字母 e
|
|
2504
|
+
U+0066 f 拉丁字母 f
|
|
2505
|
+
U+0067 g 拉丁字母 g
|
|
2506
|
+
U+0068 h 拉丁字母 h
|
|
2507
|
+
U+0069 i 拉丁字母 i
|
|
2508
|
+
U+006A j 拉丁字母 j
|
|
2509
|
+
U+006B k 拉丁字母 k
|
|
2510
|
+
U+006C l 拉丁字母 l(L的小写)
|
|
2511
|
+
U+006D m 拉丁字母 m
|
|
2512
|
+
U+006E n 拉丁字母 n
|
|
2513
|
+
U+006F o 拉丁字母 o
|
|
2514
|
+
U+0070 p 拉丁字母 p
|
|
2515
|
+
U+0071 q 拉丁字母 q
|
|
2516
|
+
U+0072 r 拉丁字母 r
|
|
2517
|
+
U+0073 s 拉丁字母 s
|
|
2518
|
+
U+0074 t 拉丁字母 t
|
|
2519
|
+
U+0075 u 拉丁字母 u
|
|
2520
|
+
U+0076 v 拉丁字母 v
|
|
2521
|
+
U+0077 w 拉丁字母 w
|
|
2522
|
+
U+0078 x 拉丁字母 x
|
|
2523
|
+
U+0079 y 拉丁字母 y
|
|
2524
|
+
U+007A z 拉丁字母 z
|
|
2525
|
+
U+007B { 开 左花括号
|
|
2526
|
+
U+007C | 直线
|
|
2527
|
+
U+007D } 关 右花括号
|
|
2528
|
+
U+007E ~ 波浪纹
|
|
2529
|
+
*/
|
|
2530
|
+
if (/.*[\u003A-\u007E]+.*$/.test(str)) {
|
|
2531
|
+
return true;
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
//空白字符,\u0009\u000a + https://cloud.tencent.com/developer/article/2128593
|
|
2535
|
+
if (/.*[\u0009\u000a\u0020\u00A0\u1680\u180E\u202F\u205F\u3000\uFEFF]+.*$/.test(str)) {
|
|
2536
|
+
return true;
|
|
2537
|
+
}
|
|
2538
|
+
if (/.*[\u2000-\u200B]+.*$/.test(str)) {
|
|
2539
|
+
return true;
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2542
|
+
/*
|
|
2543
|
+
拉丁字母
|
|
2544
|
+
代码 显示 描述
|
|
2545
|
+
U+00A1 ¡ 倒转的叹号
|
|
2546
|
+
U+00A2 ¢ (货币单位)分钱、毫子
|
|
2547
|
+
U+00A3 £ (货币)英镑
|
|
2548
|
+
U+00A4 ¤ (货币)当货币未有符号时以此替代
|
|
2549
|
+
U+00A5 ¥ (货币)日元
|
|
2550
|
+
U+00A6 ¦ 两条断开的直线
|
|
2551
|
+
U+00A7 § 文件分不同部分
|
|
2552
|
+
U+00A8 ¨ (语言)分音
|
|
2553
|
+
U+00A9 © 版权符
|
|
2554
|
+
U+00AA ª (意大利文、葡萄牙文、西班牙文)阴性序数
|
|
2555
|
+
U+00AB « 双重角形引号
|
|
2556
|
+
U+00AC ¬ 逻辑非
|
|
2557
|
+
U+00AE ® 商标
|
|
2558
|
+
U+00AF ¯ 长音
|
|
2559
|
+
U+00B0 ° 角度
|
|
2560
|
+
U+00B1 ± 正负号
|
|
2561
|
+
U+00B2 ² 二次方
|
|
2562
|
+
U+00B3 ³ 三次方
|
|
2563
|
+
U+00B4 ´ 锐音符
|
|
2564
|
+
U+00B5 µ 百万分之一,10?6
|
|
2565
|
+
U+00B6 ¶ 文章分段
|
|
2566
|
+
U+00B7 · 间隔号
|
|
2567
|
+
U+00B8 ¸ 软音符
|
|
2568
|
+
U+00B9 ¹ 一次方
|
|
2569
|
+
U+00BA º (意大利文、葡萄牙文、西班牙文)阳性序数
|
|
2570
|
+
U+00BB » 指向右的双箭头
|
|
2571
|
+
U+00BC ¼ 四分之一
|
|
2572
|
+
U+00BD ½ 二分之一
|
|
2573
|
+
U+00BE ¾ 四分之三
|
|
2574
|
+
U+00BF ¿ 倒转的问号
|
|
2575
|
+
U+00C1 Á 在拉丁字母 A 上加锐音符
|
|
2576
|
+
U+00C2 Â 在拉丁字母 A 上加抑扬符“^”
|
|
2577
|
+
U+00C3 Ã 在拉丁字母 A 上加“~”
|
|
2578
|
+
U+00C4 Ä 在拉丁字母 A 上加分音符“..”
|
|
2579
|
+
U+00C5 Å 在拉丁字母 A 上加角度符“°”
|
|
2580
|
+
U+00C6 Æ 拉丁字母 A、E 的混合
|
|
2581
|
+
U+00C7 Ç 在拉丁字母 C 下加软音符
|
|
2582
|
+
U+00C8 È 在拉丁字母 E 上加重音符
|
|
2583
|
+
U+00C9 É 在拉丁字母 E 上加锐音符
|
|
2584
|
+
U+00CA Ê 在拉丁字母 E 上加抑扬符
|
|
2585
|
+
U+00CB Ë 在拉丁字母 E 上加分音符
|
|
2586
|
+
U+00CC Ì 在拉丁字母 I 上加重音符
|
|
2587
|
+
U+00CD Í 在拉丁字母 I 上加锐音符
|
|
2588
|
+
U+00CE Î 在拉丁字母 I 上加抑扬符
|
|
2589
|
+
U+00CF Ï 在拉丁字母 I 上加分音符
|
|
2590
|
+
U+00D0 Ð 古拉丁字母,现只有法罗文和冰岛文和越南语使用
|
|
2591
|
+
U+00D1 Ñ 在拉丁字母 N 上加波浪纹“~”
|
|
2592
|
+
U+00D2 Ò 在拉丁字母 O 上加重音符
|
|
2593
|
+
U+00D3 Ó 在拉丁字母 O 上加锐音符
|
|
2594
|
+
U+00D4 Ô 在拉丁字母 O 上加抑扬符
|
|
2595
|
+
U+00D5 Õ 在拉丁字母 O 上加波浪纹“~”
|
|
2596
|
+
U+00D6 Ö 在拉丁字母 O 上加分音符
|
|
2597
|
+
U+00D7 × 乘号,亦可拖按“Alt”键,同时按“41425”五键
|
|
2598
|
+
U+00D8 Ø 在拉丁字母 O 由右上至左下加对角斜线“/”
|
|
2599
|
+
U+00D9 Ù 在拉丁字母 U 上加重音符
|
|
2600
|
+
U+00DA Ú 在拉丁字母 U 上加锐音符
|
|
2601
|
+
U+00DB Û 在拉丁字母 U 上加抑扬符
|
|
2602
|
+
U+00DC Ü 在拉丁字母 U 上加分音符
|
|
2603
|
+
U+00DD Ý 在拉丁字母 Y 上加锐音符
|
|
2604
|
+
U+00DE Þ 古拉丁字母,现已被“Th”取替
|
|
2605
|
+
U+00DF ß 德文字母
|
|
2606
|
+
U+00E0 à 在拉丁字母 a 上加重音符
|
|
2607
|
+
U+00E1 á 在拉丁字母 a 上加锐音符
|
|
2608
|
+
U+00E2 â 在拉丁字母 a 上加抑扬符
|
|
2609
|
+
U+00E3 ã 在拉丁字母 a 上加波浪纹“~”
|
|
2610
|
+
U+00E4 ä 在拉丁字母 a 上加分音符
|
|
2611
|
+
U+00E5 å 在拉丁字母 a 上加角度符“°”
|
|
2612
|
+
U+00E6 æ 拉丁字母 a、e 的混合
|
|
2613
|
+
U+00E7 ç 在拉丁字母 c 下加软音符
|
|
2614
|
+
U+00E8 è 在拉丁字母 e 上加锐音符
|
|
2615
|
+
U+00E9 é 在拉丁字母 e 上加重音符
|
|
2616
|
+
U+00EA ê 在拉丁字母 e 上加抑扬符
|
|
2617
|
+
U+00EB ë 在拉丁字母 e 上加分音符
|
|
2618
|
+
U+00EC ì 在拉丁字母 i 上加重音符
|
|
2619
|
+
U+00ED í 在拉丁字母 i 上加锐音符
|
|
2620
|
+
U+00EE î 在拉丁字母 i 上加抑扬符
|
|
2621
|
+
U+00EF ï 在拉丁字母 i 上加分音符
|
|
2622
|
+
U+00F0 ð 古拉丁字母
|
|
2623
|
+
U+00F1 ñ 在拉丁字母 n 上加波浪纹“~”
|
|
2624
|
+
U+00F2 ò 在拉丁字母 o 上加重音符
|
|
2625
|
+
U+00F3 ó 在拉丁字母 o 上加锐音符
|
|
2626
|
+
U+00F4 ô 在拉丁字母 o 上加抑扬符
|
|
2627
|
+
U+00F5 õ 在拉丁字母 o 上加波浪纹“~”
|
|
2628
|
+
U+00F6 ö 在拉丁字母 o 上加分音符
|
|
2629
|
+
U+00F7 ÷ 除号,亦可拖按“Alt”键,同时按“41426”五键
|
|
2630
|
+
U+00F8 ø 在拉丁字母 o 由右上至左下加对角斜线“/”
|
|
2631
|
+
U+00F9 ù 在拉丁字母 u 上加重音符
|
|
2632
|
+
U+00FA ú 在拉丁字母 u 上加锐音符
|
|
2633
|
+
U+00FB ? 在拉丁字母 u 上加抑扬符
|
|
2634
|
+
U+00FC ü 在拉丁字母 u 上加分音符
|
|
2635
|
+
U+00FD ý 在拉丁字母 y 上加锐音符
|
|
2636
|
+
U+00FE þ 古拉丁字母,现已被“th”取替
|
|
2637
|
+
U+00FF ü 在拉丁字母 u 上加分音符
|
|
2638
|
+
拉丁字母(扩展 A)
|
|
2639
|
+
代码 显示 描述
|
|
2640
|
+
U+0100 Ā 在拉丁字母 A 上加长音符
|
|
2641
|
+
U+0101 ā 在拉丁字母 a 上加长音符
|
|
2642
|
+
U+0102 Ă 在拉丁字母 A 上加短音符
|
|
2643
|
+
U+0103 ă 在拉丁字母 a 上加短音符
|
|
2644
|
+
U+0104 Ą 在拉丁字母 A 上加反尾形符
|
|
2645
|
+
U+0105 ą 在拉丁字母 a 上加反尾形符
|
|
2646
|
+
拉丁字母(扩展 C)
|
|
2647
|
+
代码 显示 描述
|
|
2648
|
+
U+2C60 Ⱡ 在拉丁字母“L”中间加两条横线“=”
|
|
2649
|
+
U+2C61 ⱡ 在拉丁字母“l”(L 的小写)中间加两条横线“=”
|
|
2650
|
+
U+2C62 Ɫ 在拉丁字母“L”(大写)中间加一条波浪线“~”
|
|
2651
|
+
U+2C63 Ᵽ 在拉丁字母“P”中间加一条横线“-”
|
|
2652
|
+
U+2C64 Ɽ 在拉丁字母“R”下加一条尾巴
|
|
2653
|
+
U+2C65 ⱥ 在拉丁字母“a”上加一条对角斜线“/”
|
|
2654
|
+
U+2C66 ⱦ 在拉丁字母“t”上加一条对角斜线“/”
|
|
2655
|
+
U+2C67 Ⱨ 在拉丁字母“H”下加一条尾巴
|
|
2656
|
+
U+2C68 ⱨ 在拉丁字母“h”下加一条尾巴
|
|
2657
|
+
U+2C69 Ⱪ 在拉丁字母“K”下加一条尾巴
|
|
2658
|
+
U+2C6A ⱪ 在拉丁字母“k”下加一条尾巴
|
|
2659
|
+
U+2C6B Ⱬ 在拉丁字母“Z”下加一条尾巴
|
|
2660
|
+
U+2C6C ⱬ 在拉丁字母“z”下加一条尾巴
|
|
2661
|
+
U+2C74 ⱴ 在拉丁字母“v”的起笔加一个弯勾
|
|
2662
|
+
U+2C75 Ⱶ 拉丁字母“H”的左半部
|
|
2663
|
+
U+2C76 ⱶ 拉丁字母“h”的左半部
|
|
2664
|
+
U+2C77 ⱷ 希腊字母“φ”的上半部
|
|
2665
|
+
*/
|
|
2666
|
+
if (/.*[\u00A1-\u0105]+.*$/.test(str)) {
|
|
2667
|
+
return true;
|
|
2668
|
+
}
|
|
2669
|
+
if (/.*[\u2C60-\u2C77]+.*$/.test(str)) {
|
|
2670
|
+
return true;
|
|
2671
|
+
}
|
|
2672
|
+
|
|
2673
|
+
|
|
2674
|
+
return false;
|
|
2675
|
+
}
|
|
2676
|
+
},
|
|
2677
|
+
//用户第一次打开网页时,自动判断当前用户所在国家使用的是哪种语言,来自动进行切换为用户所在国家的语种。
|
|
2678
|
+
//如果使用后,第二次在用,那就优先以用户所选择的为主
|
|
2679
|
+
executeByLocalLanguage: function () {
|
|
2680
|
+
translate.request.post(translate.request.api.host + translate.request.api.ip + '?v=' + translate.version, {}, function (data) {
|
|
2681
|
+
//console.log(data);
|
|
2682
|
+
if (data.result == 0) {
|
|
2683
|
+
console.log('==== ERROR 获取当前用户所在区域异常 ====');
|
|
2684
|
+
console.log(data.info);
|
|
2685
|
+
console.log('==== ERROR END ====');
|
|
2686
|
+
} else {
|
|
2687
|
+
translate.setUseVersion2();
|
|
2688
|
+
translate.storage.set('to', data.language); //设置目标翻译语言
|
|
2689
|
+
translate.to = data.language; //设置目标语言
|
|
2690
|
+
translate.selectLanguageTag
|
|
2691
|
+
translate.execute(); //执行翻译
|
|
2692
|
+
}
|
|
2693
|
+
});
|
|
2694
|
+
},
|
|
2695
|
+
|
|
2696
|
+
util: {
|
|
2697
|
+
/* 生成一个随机UUID,复制于 https://gitee.com/mail_osc/kefu.js */
|
|
2698
|
+
uuid: function () {
|
|
2699
|
+
var d = new Date().getTime();
|
|
2700
|
+
if (window.performance && typeof window.performance.now === "function") {
|
|
2701
|
+
d += performance.now(); //use high-precision timer if available
|
|
2702
|
+
}
|
|
2703
|
+
var uuid = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
2704
|
+
var r = (d + Math.random() * 16) % 16 | 0;
|
|
2705
|
+
d = Math.floor(d / 16);
|
|
2706
|
+
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
|
|
2707
|
+
});
|
|
2708
|
+
return uuid;
|
|
2709
|
+
},
|
|
2710
|
+
|
|
2711
|
+
//判断字符串中是否存在tag标签。 true存在
|
|
2712
|
+
findTag: function (str) {
|
|
2713
|
+
var reg = /<[^>]+>/g;
|
|
2714
|
+
return reg.test(str);
|
|
2715
|
+
},
|
|
2716
|
+
//传入一个数组,从数组中找出现频率最多的一个返回。 如果多个频率出现的次数一样,那会返回多个
|
|
2717
|
+
arrayFindMaxNumber: function (arr) {
|
|
2718
|
+
|
|
2719
|
+
// 储存每个元素出现的次数
|
|
2720
|
+
var numbers = {}
|
|
2721
|
+
|
|
2722
|
+
// 储存出现最多次的元素
|
|
2723
|
+
var maxStr = []
|
|
2724
|
+
|
|
2725
|
+
// 储存最多出现的元素次数
|
|
2726
|
+
var maxNum = 0
|
|
2727
|
+
|
|
2728
|
+
for (var i = 0, len = arr.length; i < len; i++) {
|
|
2729
|
+
if (!numbers[arr[i]]) {
|
|
2730
|
+
numbers[arr[i]] = 1
|
|
2731
|
+
} else {
|
|
2732
|
+
numbers[arr[i]]++
|
|
2733
|
+
}
|
|
2734
|
+
|
|
2735
|
+
if (numbers[arr[i]] > maxNum) {
|
|
2736
|
+
maxNum = numbers[arr[i]]
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
|
|
2740
|
+
for (var item in numbers) {
|
|
2741
|
+
if (numbers[item] === maxNum) {
|
|
2742
|
+
maxStr.push(item)
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2746
|
+
return maxStr;
|
|
2747
|
+
},
|
|
2748
|
+
//对字符串进行hash化,目的取唯一值进行标识
|
|
2749
|
+
hash: function (str) {
|
|
2750
|
+
if (str == null || typeof (str) == 'undefined') {
|
|
2751
|
+
return str;
|
|
2752
|
+
}
|
|
2753
|
+
var hash = 0, i, chr;
|
|
2754
|
+
if (str.length === 0) {
|
|
2755
|
+
return hash;
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2758
|
+
for (i = 0; i < str.length; i++) {
|
|
2759
|
+
chr = str.charCodeAt(i);
|
|
2760
|
+
hash = ((hash << 5) - hash) + chr;
|
|
2761
|
+
hash |= 0; // Convert to 32bit integer
|
|
2762
|
+
}
|
|
2763
|
+
return hash + '';
|
|
2764
|
+
},
|
|
2765
|
+
//去除一些指定字符,如换行符。 如果传入的是null,则返回空字符串
|
|
2766
|
+
charReplace: function (str) {
|
|
2767
|
+
|
|
2768
|
+
if (str == null) {
|
|
2769
|
+
return '';
|
|
2770
|
+
}
|
|
2771
|
+
str = str.trim();
|
|
2772
|
+
str = str.replace(/\t|\n|\v|\r|\f/g, ''); //去除换行符等
|
|
2773
|
+
//str = str.replace(/&/g, "%26"); //因为在提交时已经进行了url编码了
|
|
2774
|
+
return str;
|
|
2775
|
+
},
|
|
2776
|
+
//RegExp相关
|
|
2777
|
+
regExp: {
|
|
2778
|
+
// new RegExp(pattern, resultText); 中的 pattern 字符串的预处理
|
|
2779
|
+
pattern: function (str) {
|
|
2780
|
+
//str = str.replace(/'/g,'\\\'');
|
|
2781
|
+
str = str.replace(/\"/g, '\\\"');
|
|
2782
|
+
//str = str.replace(/./g,'\\\.');
|
|
2783
|
+
str = str.replace(/\?/g, '\\\?');
|
|
2784
|
+
str = str.replace(/\$/g, '\\\$');
|
|
2785
|
+
return str;
|
|
2786
|
+
},
|
|
2787
|
+
// new RegExp(pattern, resultText); 中的 resultText 字符串的预处理
|
|
2788
|
+
resultText: function (str) {
|
|
2789
|
+
//str = str.replace(/"/g,"\"");
|
|
2790
|
+
//str = str.replace(/'/g,"\\\'");
|
|
2791
|
+
//str = str.replace(/"/g,"\\\"");
|
|
2792
|
+
return str;
|
|
2793
|
+
}
|
|
2794
|
+
},
|
|
2795
|
+
//获取URL的GET参数。若没有,返回""
|
|
2796
|
+
getUrlParam: function (name) {
|
|
2797
|
+
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
|
|
2798
|
+
var r = window.location.search.substr(1).match(reg);
|
|
2799
|
+
if (r != null) return unescape(r[2]); return "";
|
|
2800
|
+
},
|
|
2801
|
+
/**
|
|
2802
|
+
* 同步加载JS,加载过程中会阻塞,加载完毕后继续执行后面的。
|
|
2803
|
+
* url: 要加载的js的url
|
|
2804
|
+
*/
|
|
2805
|
+
synchronizesLoadJs: function (url) {
|
|
2806
|
+
var xmlHttp = null;
|
|
2807
|
+
if (window.ActiveXObject) {//IE
|
|
2808
|
+
try {
|
|
2809
|
+
//IE6以及以后版本中可以使用
|
|
2810
|
+
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
|
|
2811
|
+
} catch (e) {
|
|
2812
|
+
//IE5.5以及以后版本可以使用
|
|
2813
|
+
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
|
|
2814
|
+
}
|
|
2815
|
+
} else if (window.XMLHttpRequest) {
|
|
2816
|
+
//Firefox,Opera 8.0+,Safari,Chrome
|
|
2817
|
+
xmlHttp = new XMLHttpRequest();
|
|
2818
|
+
}
|
|
2819
|
+
//采用同步加载
|
|
2820
|
+
xmlHttp.open("GET", url, false);
|
|
2821
|
+
//发送同步请求,如果浏览器为Chrome或Opera,必须发布后才能运行,不然会报错
|
|
2822
|
+
xmlHttp.send(null);
|
|
2823
|
+
//4代表数据发送完毕
|
|
2824
|
+
if (xmlHttp.readyState == 4) {
|
|
2825
|
+
//0为访问的本地,200到300代表访问服务器成功,304代表没做修改访问的是缓存
|
|
2826
|
+
if ((xmlHttp.status >= 200 && xmlHttp.status < 300) || xmlHttp.status == 0 || xmlHttp.status == 304) {
|
|
2827
|
+
var myBody = document.getElementsByTagName("HTML")[0];
|
|
2828
|
+
var myScript = document.createElement("script");
|
|
2829
|
+
myScript.language = "javascript";
|
|
2830
|
+
myScript.type = "text/javascript";
|
|
2831
|
+
try {
|
|
2832
|
+
//IE8以及以下不支持这种方式,需要通过text属性来设置
|
|
2833
|
+
myScript.appendChild(document.createTextNode(xmlHttp.responseText));
|
|
2834
|
+
} catch (ex) {
|
|
2835
|
+
myScript.text = xmlHttp.responseText;
|
|
2836
|
+
}
|
|
2837
|
+
myBody.appendChild(myScript);
|
|
2838
|
+
return true;
|
|
2839
|
+
} else {
|
|
2840
|
+
return false;
|
|
2841
|
+
}
|
|
2842
|
+
} else {
|
|
2843
|
+
return false;
|
|
2844
|
+
}
|
|
2845
|
+
},
|
|
2846
|
+
//加载 msg.js
|
|
2847
|
+
loadMsgJs: function () {
|
|
2848
|
+
if (typeof (msg) != 'undefined') {
|
|
2849
|
+
return;
|
|
2850
|
+
}
|
|
2851
|
+
translate.util.synchronizesLoadJs('http://res.zvo.cn/msg/msg.js');
|
|
2852
|
+
},
|
|
2853
|
+
/*
|
|
2854
|
+
对一个对象,按照对象的key的长度进行排序,越长越在前面
|
|
2855
|
+
*/
|
|
2856
|
+
objSort: function (obj) {
|
|
2857
|
+
// 获取对象数组的所有 key,并转换为普通数组
|
|
2858
|
+
var keys = Array.from(Object.keys(obj));
|
|
2859
|
+
|
|
2860
|
+
// 对 key 数组进行排序
|
|
2861
|
+
keys.sort(function (a, b) {
|
|
2862
|
+
return b.length - a.length;
|
|
2863
|
+
});
|
|
2864
|
+
|
|
2865
|
+
// 定义一个新的对象数组,用来存储排序后的结果
|
|
2866
|
+
var sortedObj = new Array();
|
|
2867
|
+
|
|
2868
|
+
// 遍历排序后的 key 数组,将对应的值复制到新的对象数组中,并删除原来的对象数组中的键值对
|
|
2869
|
+
for (var key of keys) {
|
|
2870
|
+
sortedObj[key] = obj[key];
|
|
2871
|
+
}
|
|
2872
|
+
return sortedObj;
|
|
2873
|
+
}
|
|
2874
|
+
},
|
|
2875
|
+
//request请求来源于 https://github.com/xnx3/request
|
|
2876
|
+
request: {
|
|
2877
|
+
//相关API接口方面
|
|
2878
|
+
api: {
|
|
2879
|
+
/**
|
|
2880
|
+
* 翻译接口请求的域名主机 host
|
|
2881
|
+
* 格式注意前面要带上协议如 https:// 域名后要加 /
|
|
2882
|
+
*/
|
|
2883
|
+
host: 'https://api.translate.zvo.cn/',
|
|
2884
|
+
language: 'language.json', //获取支持的语种列表接口
|
|
2885
|
+
translate: 'translate.json', //翻译接口
|
|
2886
|
+
ip: 'ip.json' //根据用户当前ip获取其所在地的语种
|
|
2887
|
+
},
|
|
2888
|
+
/**
|
|
2889
|
+
* post请求
|
|
2890
|
+
* @param url 请求的接口URL,传入如 http://www.xxx.com/a.php
|
|
2891
|
+
* @param data 请求的参数数据,传入如 {"goodsid":"1", "author":"管雷鸣"}
|
|
2892
|
+
* @param func 请求完成的回调,传入如 function(data){ console.log(data); }
|
|
2893
|
+
*/
|
|
2894
|
+
post: function (url, data, func) {
|
|
2895
|
+
var headers = {
|
|
2896
|
+
'content-type': 'application/x-www-form-urlencoded',
|
|
2897
|
+
};
|
|
2898
|
+
this.send(url, data, func, 'post', true, headers, null);
|
|
2899
|
+
},
|
|
2900
|
+
/**
|
|
2901
|
+
* 发送请求
|
|
2902
|
+
* url 请求的url
|
|
2903
|
+
* data 请求的数据,如 {"author":"管雷鸣",'site':'www.guanleiming.com'}
|
|
2904
|
+
* func 请求完成的回调,传入如 function(data){}
|
|
2905
|
+
* method 请求方式,可传入 post、get
|
|
2906
|
+
* isAsynchronize 是否是异步请求, 传入 true 是异步请求,传入false 是同步请求
|
|
2907
|
+
* headers 设置请求的header,传入如 {'content-type':'application/x-www-form-urlencoded'};
|
|
2908
|
+
* abnormalFunc 响应异常所执行的方法,响应码不是200就会执行这个方法 ,传入如 function(xhr){}
|
|
2909
|
+
*/
|
|
2910
|
+
send: function (url, data, func, method, isAsynchronize, headers, abnormalFunc) {
|
|
2911
|
+
//post提交的参数
|
|
2912
|
+
var params = '';
|
|
2913
|
+
if (data != null) {
|
|
2914
|
+
for (var index in data) {
|
|
2915
|
+
if (params.length > 0) {
|
|
2916
|
+
params = params + '&';
|
|
2917
|
+
}
|
|
2918
|
+
params = params + index + '=' + data[index];
|
|
2919
|
+
}
|
|
2920
|
+
}
|
|
2921
|
+
|
|
2922
|
+
var xhr = null;
|
|
2923
|
+
try {
|
|
2924
|
+
xhr = new XMLHttpRequest();
|
|
2925
|
+
} catch (e) {
|
|
2926
|
+
xhr = new ActiveXObject("Microsoft.XMLHTTP");
|
|
2927
|
+
}
|
|
2928
|
+
//2.调用open方法(true----异步)
|
|
2929
|
+
xhr.open(method, url, isAsynchronize);
|
|
2930
|
+
//设置headers
|
|
2931
|
+
if (headers != null) {
|
|
2932
|
+
for (var index in headers) {
|
|
2933
|
+
xhr.setRequestHeader(index, headers[index]);
|
|
2934
|
+
}
|
|
2935
|
+
}
|
|
2936
|
+
xhr.send(params);
|
|
2937
|
+
//4.请求状态改变事件
|
|
2938
|
+
xhr.onreadystatechange = function () {
|
|
2939
|
+
if (xhr.readyState == 4) {
|
|
2940
|
+
if (xhr.status == 200) {
|
|
2941
|
+
//请求正常,响应码 200
|
|
2942
|
+
var json = null;
|
|
2943
|
+
try {
|
|
2944
|
+
json = JSON.parse(xhr.responseText);
|
|
2945
|
+
} catch (e) {
|
|
2946
|
+
console.log(e);
|
|
2947
|
+
}
|
|
2948
|
+
if (json == null) {
|
|
2949
|
+
func(xhr.responseText);
|
|
2950
|
+
} else {
|
|
2951
|
+
func(json);
|
|
2952
|
+
}
|
|
2953
|
+
} else {
|
|
2954
|
+
if (abnormalFunc != null) {
|
|
2955
|
+
abnormalFunc(xhr);
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
}
|
|
2959
|
+
}
|
|
2960
|
+
}
|
|
2961
|
+
},
|
|
2962
|
+
//存储,本地缓存
|
|
2963
|
+
storage: {
|
|
2964
|
+
set: function (key, value) {
|
|
2965
|
+
localStorage.setItem(key, value);
|
|
2966
|
+
},
|
|
2967
|
+
get: function (key) {
|
|
2968
|
+
return localStorage.getItem(key);
|
|
2969
|
+
}
|
|
2970
|
+
},
|
|
2971
|
+
//针对图片进行相关的语种图片替换
|
|
2972
|
+
images: {
|
|
2973
|
+
/* 要替换的图片队列,数组形态,其中某个数组的:
|
|
2974
|
+
key:"/uploads/allimg/160721/2-160H11URA25-lp.jpg"; //旧图片,也就是原网站本身的图片。也可以绝对路径,会自动匹配 img src 的值,匹配时会进行完全匹配
|
|
2975
|
+
value:"https://xxx.com/abc_{language}.jpg" //新图片,要被替换为的新图片。新图片路径需要为绝对路径,能直接访问到的。其中 {language} 会自动替换为当前要显示的语种。比如你要将你中文网站翻译为繁体中文,那这里会自动替换为:https://xxx.com/abc_chinese_traditional.jpg 有关{language}的取值,可查阅 http://api.translate.zvo.cn/doc/language.json.html 其中的语言标识id便是
|
|
2976
|
+
*/
|
|
2977
|
+
queues: [],
|
|
2978
|
+
|
|
2979
|
+
/*
|
|
2980
|
+
向图片替换队列中追加要替换的图片
|
|
2981
|
+
传入格式如:
|
|
2982
|
+
|
|
2983
|
+
translate.images.add({
|
|
2984
|
+
"/uploads/a.jpg":"https://www.zvo.cn/a_{language}.jpg",
|
|
2985
|
+
"/uploads/b.jpg":"https://www.zvo.cn/b_{language}.jpg",
|
|
2986
|
+
});
|
|
2987
|
+
|
|
2988
|
+
参数说明:
|
|
2989
|
+
key //旧图片,也就是原网站本身的图片。也可以绝对路径,会自动匹配 img src 的值,匹配时会进行完全匹配
|
|
2990
|
+
value //新图片,要被替换为的新图片。新图片路径需要为绝对路径,能直接访问到的。其中 {language} 会自动替换为当前要显示的语种。比如你要将你中文网站翻译为繁体中文,那这里会自动替换为:https://xxx.com/abc_chinese_traditional.jpg 有关{language}的取值,可查阅 http://api.translate.zvo.cn/doc/language.json.html 其中的语言标识id便是
|
|
2991
|
+
*/
|
|
2992
|
+
add: function (queueArray) {
|
|
2993
|
+
/*
|
|
2994
|
+
translate.images.queues[translate.images.queues.length] = {
|
|
2995
|
+
old:oldImage,
|
|
2996
|
+
new:newImage
|
|
2997
|
+
}
|
|
2998
|
+
*/
|
|
2999
|
+
for (var key in queueArray) {
|
|
3000
|
+
translate.images.queues[key] = queueArray[key];
|
|
3001
|
+
}
|
|
3002
|
+
},
|
|
3003
|
+
//执行图片替换操作,将原本的图片替换为跟翻译语种一样的图片
|
|
3004
|
+
execute: function () {
|
|
3005
|
+
if (Object.keys(translate.images.queues).length < 1) {
|
|
3006
|
+
//如果没有,那么直接取消图片的替换扫描
|
|
3007
|
+
return;
|
|
3008
|
+
}
|
|
3009
|
+
|
|
3010
|
+
var imgs = document.getElementsByTagName('img');
|
|
3011
|
+
for (var i = 0; i < imgs.length; i++) {
|
|
3012
|
+
var img = imgs[i];
|
|
3013
|
+
if (typeof (img.src) == 'undefined' || img.src == null || img.src.length == 0) {
|
|
3014
|
+
continue;
|
|
3015
|
+
}
|
|
3016
|
+
|
|
3017
|
+
for (var key in translate.images.queues) {
|
|
3018
|
+
var oldImage = key; //原本的图片src
|
|
3019
|
+
var newImage = translate.images.queues[key]; //新的图片src,要替换为的
|
|
3020
|
+
//console.log('queue+'+oldImage);
|
|
3021
|
+
if (oldImage == img.src) {
|
|
3022
|
+
//console.log('发现匹配图片:'+img.src);
|
|
3023
|
+
/*
|
|
3024
|
+
//判断当前元素是否在ignore忽略的tag、id、class name中
|
|
3025
|
+
if(translate.ignore.isIgnore(node)){
|
|
3026
|
+
console.log('node包含在要忽略的元素中:');
|
|
3027
|
+
console.log(node);
|
|
3028
|
+
continue;
|
|
3029
|
+
}
|
|
3030
|
+
*/
|
|
3031
|
+
|
|
3032
|
+
//没在忽略元素里,可以替换
|
|
3033
|
+
img.src = newImage.replace(new RegExp('{language}', 'g'), translate.to);
|
|
3034
|
+
}
|
|
3035
|
+
}
|
|
3036
|
+
|
|
3037
|
+
}
|
|
3038
|
+
|
|
3039
|
+
|
|
3040
|
+
/********** 还要替换style中的背景图 */
|
|
3041
|
+
/*
|
|
3042
|
+
|
|
3043
|
+
var elements = document.querySelectorAll('[style*="background-image"], [style*="background"]');
|
|
3044
|
+
for (var i = 0; i < elements.length; i++) {
|
|
3045
|
+
var style = window.getComputedStyle(elements[i]);
|
|
3046
|
+
var backgroundImage = style.getPropertyValue('background-image');
|
|
3047
|
+
if (backgroundImage !== 'none') {
|
|
3048
|
+
console.log(backgroundImage);
|
|
3049
|
+
}
|
|
3050
|
+
}
|
|
3051
|
+
|
|
3052
|
+
*/
|
|
3053
|
+
|
|
3054
|
+
}
|
|
3055
|
+
},
|
|
3056
|
+
|
|
3057
|
+
/*
|
|
3058
|
+
划词翻译,鼠标在网页中选中一段文字,会自动出现对应翻译后的文本
|
|
3059
|
+
有网友 https://gitee.com/huangguishen 提供。
|
|
3060
|
+
详细使用说明参见:http://translate.zvo.cn/41557.html
|
|
3061
|
+
*/
|
|
3062
|
+
selectionTranslate: {
|
|
3063
|
+
selectionX: 0,
|
|
3064
|
+
selectionY: 0,
|
|
3065
|
+
callTranslate: function (event) {
|
|
3066
|
+
let curSelection = window.getSelection();
|
|
3067
|
+
//相等认为没有划词
|
|
3068
|
+
if (curSelection.anchorOffset == curSelection.focusOffset) return;
|
|
3069
|
+
let translateText = window.getSelection().toString();
|
|
3070
|
+
|
|
3071
|
+
//简单Copy原有代码了
|
|
3072
|
+
var url = translate.request.api.host + translate.request.api.translate + '?v=' + translate.version;
|
|
3073
|
+
var data = {
|
|
3074
|
+
from: translate.language.getLocal(),
|
|
3075
|
+
to: translate.to,
|
|
3076
|
+
text: encodeURIComponent(JSON.stringify([translateText]))
|
|
3077
|
+
};
|
|
3078
|
+
translate.request.post(url, data, function (data) {
|
|
3079
|
+
if (data.result == 0) return;
|
|
3080
|
+
let curTooltipEle = document.querySelector('#translateTooltip')
|
|
3081
|
+
curTooltipEle.innerText = data.text[0];
|
|
3082
|
+
curTooltipEle.style.top = selectionY + 20 + "px";
|
|
3083
|
+
curTooltipEle.style.left = selectionX + 50 + "px";
|
|
3084
|
+
curTooltipEle.style.display = "";
|
|
3085
|
+
});
|
|
3086
|
+
},
|
|
3087
|
+
start: function () {
|
|
3088
|
+
//新建一个tooltip元素节点用于显示翻译
|
|
3089
|
+
let tooltipEle = document.createElement('span');
|
|
3090
|
+
tooltipEle.innerText = '';
|
|
3091
|
+
tooltipEle.setAttribute('id', 'translateTooltip');
|
|
3092
|
+
tooltipEle.setAttribute('style', 'background-color:black;color:#fff;text-align:center;border-radius:6px;padding:5px;position:absolute;z-index:999;top:150%;left:50%; ');
|
|
3093
|
+
//把元素节点添加到body元素节点中成为其子节点,放在body的现有子节点的最后
|
|
3094
|
+
document.body.appendChild(tooltipEle);
|
|
3095
|
+
//监听鼠标按下事件,点击起始点位置作为显示翻译的位置点
|
|
3096
|
+
document.addEventListener('mousedown', (event) => { selectionX = event.pageX; selectionY = event.pageY; }, false);
|
|
3097
|
+
//监听鼠标弹起事件,便于判断是否处于划词
|
|
3098
|
+
document.addEventListener('mouseup', translate.selectionTranslate.callTranslate, false);
|
|
3099
|
+
//监听鼠标点击事件,隐藏tooltip,此处可优化
|
|
3100
|
+
document.addEventListener('click', (event) => { document.querySelector('#translateTooltip').style.display = "none" }, false);
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
|
|
3104
|
+
|
|
3105
|
+
|
|
3106
|
+
/**************************** v2.0 end */
|
|
3107
|
+
|
|
669
3108
|
}
|
|
3109
|
+
console.log('Two lines of js html automatic translation, page without change, no language configuration file, no API Key, SEO friendly! Open warehouse : https://github.com/xnx3/translate');
|
|
3110
|
+
|
|
3111
|
+
//这个只是v1使用到
|
|
3112
|
+
try {
|
|
3113
|
+
translate.init();
|
|
3114
|
+
//translate.execute();
|
|
3115
|
+
} catch (e) { console.log(e); }
|
|
670
3116
|
|
|
671
3117
|
export default translate
|