i18n-jsautotranslate 3.18.63 → 3.18.71
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/ArcoDesign/Vue3/LanguageSelect.vue +17 -28
- package/index.js +568 -275
- package/package.json +1 -1
- package/vue/vue3/translateVue3TS.ts +19 -19
package/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var translate = {
|
|
|
14
14
|
* 格式:major.minor.patch.date
|
|
15
15
|
*/
|
|
16
16
|
// AUTO_VERSION_START
|
|
17
|
-
version: '3.18.
|
|
17
|
+
version: '3.18.71.20251010',
|
|
18
18
|
// AUTO_VERSION_END
|
|
19
19
|
/*
|
|
20
20
|
当前使用的版本,默认使用v2. 可使用 setUseVersion2();
|
|
@@ -73,6 +73,11 @@ var translate = {
|
|
|
73
73
|
*/
|
|
74
74
|
languages:'',
|
|
75
75
|
alreadyRender:false, //当前是否已渲染过了 true为是 v2.2增加
|
|
76
|
+
|
|
77
|
+
changeLanguageBeforeLoadOfflineFile: function(path){
|
|
78
|
+
|
|
79
|
+
},
|
|
80
|
+
|
|
76
81
|
selectOnChange:function(event){
|
|
77
82
|
var language = event.target.value;
|
|
78
83
|
translate.changeLanguage(language);
|
|
@@ -518,6 +523,12 @@ var translate = {
|
|
|
518
523
|
if(ele == null || typeof(ele) == 'undefined'){
|
|
519
524
|
return false;
|
|
520
525
|
}
|
|
526
|
+
if(ele.nodeType === 2){ //是属性,将其转为元素判断,因为当前忽略配置,是针对元素配置的
|
|
527
|
+
ele = ele.ownerElement;
|
|
528
|
+
}else if(ele.nodeType === 3){
|
|
529
|
+
//文本节点,转为元素
|
|
530
|
+
ele = ele.parentNode;
|
|
531
|
+
}
|
|
521
532
|
|
|
522
533
|
var parentNode = ele;
|
|
523
534
|
var maxnumber = 100; //最大循环次数,避免死循环
|
|
@@ -765,8 +776,7 @@ var translate = {
|
|
|
765
776
|
* 如果传入 null,则不进行任何替换操作
|
|
766
777
|
* 如果传入具体的值,则是:
|
|
767
778
|
* {
|
|
768
|
-
* node: node节点
|
|
769
|
-
* attribute: 要替换的node的attribute名称。如果传入 null,则是直接对 nodeValue 生效
|
|
779
|
+
* node: node节点 ,要改动的文字所在的node节点。 如果改动的文字比如是 div 的title中,那么这里传入的node应该是 title 的node,而不是 div 的node
|
|
770
780
|
* }
|
|
771
781
|
*
|
|
772
782
|
* @returns {
|
|
@@ -899,8 +909,7 @@ var translate = {
|
|
|
899
909
|
如果传入 null,则不进行任何替换操作
|
|
900
910
|
如果传入具体的值,则是:
|
|
901
911
|
{
|
|
902
|
-
node: node节点
|
|
903
|
-
attribute: 要替换的node的attribute名称。如果传入 null,则是直接对 nodeValue 生效
|
|
912
|
+
node: node节点 ,要改动的文字所在的node节点。 如果改动的文字比如是 div 的title中,那么这里传入的node应该是 title 的node,而不是 div 的node
|
|
904
913
|
}
|
|
905
914
|
|
|
906
915
|
|
|
@@ -946,7 +955,22 @@ var translate = {
|
|
|
946
955
|
},
|
|
947
956
|
},
|
|
948
957
|
|
|
958
|
+
//已转为 offline ,这个是对旧版做兼容
|
|
949
959
|
office:{
|
|
960
|
+
export:function(){
|
|
961
|
+
console.log('请使用最新版本的 translate.offline.export , 而不是 translate.office.export');
|
|
962
|
+
},
|
|
963
|
+
showPanel:function(){
|
|
964
|
+
console.log('请使用最新版本的 translate.offline.showPanel , 而不是 translate.office.export');
|
|
965
|
+
},
|
|
966
|
+
append:function(to, properties){
|
|
967
|
+
translate.offline.append(to, properties);
|
|
968
|
+
},
|
|
969
|
+
fullExtract:{
|
|
970
|
+
isUse:false
|
|
971
|
+
}
|
|
972
|
+
},
|
|
973
|
+
offline:{
|
|
950
974
|
/*
|
|
951
975
|
网页上翻译之后,自动导出当前页面的术语库
|
|
952
976
|
|
|
@@ -992,7 +1016,7 @@ var translate = {
|
|
|
992
1016
|
|
|
993
1017
|
if(text.length > 0){
|
|
994
1018
|
//有内容
|
|
995
|
-
text = 'translate.
|
|
1019
|
+
text = 'translate.offline.append(\''+translate.language.getCurrent()+'\',`'+text+'\n`);';
|
|
996
1020
|
//console.log(text);
|
|
997
1021
|
translate.util.loadMsgJs();
|
|
998
1022
|
msg.popups({
|
|
@@ -1017,7 +1041,7 @@ var translate = {
|
|
|
1017
1041
|
//导出按钮
|
|
1018
1042
|
let button = document.createElement('button');
|
|
1019
1043
|
button.onclick = function() {
|
|
1020
|
-
translate.
|
|
1044
|
+
translate.offline.export();
|
|
1021
1045
|
};
|
|
1022
1046
|
button.innerHTML = '导出配置信息';
|
|
1023
1047
|
button.setAttribute('style', 'margin-left: 72px; margin-top: 30px; margin-bottom: 20px; font-size: 25px; background-color: blue; padding: 15px; padding-top: 3px; padding-bottom: 3px; border-radius: 3px;');
|
|
@@ -1080,7 +1104,7 @@ var translate = {
|
|
|
1080
1104
|
|
|
1081
1105
|
//全部提取能力(整站的离线翻译数据提取)
|
|
1082
1106
|
fullExtract:{
|
|
1083
|
-
/*js translate.
|
|
1107
|
+
/*js translate.offline.fullExtract.set start*/
|
|
1084
1108
|
/*
|
|
1085
1109
|
将翻译的结果加入
|
|
1086
1110
|
hash: 翻译前的文本的hash
|
|
@@ -1102,9 +1126,9 @@ var translate = {
|
|
|
1102
1126
|
obj[toLanguage] = translateText;
|
|
1103
1127
|
await translate.storage.IndexedDB.set('hash_'+hash, obj);
|
|
1104
1128
|
},
|
|
1105
|
-
/*js translate.
|
|
1129
|
+
/*js translate.offline.fullExtract.set end*/
|
|
1106
1130
|
|
|
1107
|
-
/*js translate.
|
|
1131
|
+
/*js translate.offline.fullExtract.export start*/
|
|
1108
1132
|
/*
|
|
1109
1133
|
将存储的数据导出为 txt 文件下载下来
|
|
1110
1134
|
*/
|
|
@@ -1117,7 +1141,7 @@ var translate = {
|
|
|
1117
1141
|
translate.log('error : to param not find, example: "english"');
|
|
1118
1142
|
return;
|
|
1119
1143
|
}
|
|
1120
|
-
var text = 'translate.
|
|
1144
|
+
var text = 'translate.offline.append(\''+to+'\',`';
|
|
1121
1145
|
|
|
1122
1146
|
var data = await translate.storage.IndexedDB.list('hash_*');
|
|
1123
1147
|
for(var i in data){
|
|
@@ -1137,7 +1161,7 @@ var translate = {
|
|
|
1137
1161
|
link.click();
|
|
1138
1162
|
URL.revokeObjectURL(url);
|
|
1139
1163
|
},
|
|
1140
|
-
/*js translate.
|
|
1164
|
+
/*js translate.offline.fullExtract.export end*/
|
|
1141
1165
|
|
|
1142
1166
|
/*
|
|
1143
1167
|
是否启用全部提取的能力
|
|
@@ -1309,6 +1333,54 @@ var translate = {
|
|
|
1309
1333
|
//console.log('refresh ignore finish: '+Object.keys(translate.listener.ignoreNode).length);
|
|
1310
1334
|
},
|
|
1311
1335
|
|
|
1336
|
+
/*
|
|
1337
|
+
用于监听发生改变的这个 node 是否有正常需要翻译的内容、以及是否是非translate.js触发的需要被翻译。
|
|
1338
|
+
注意,传入进行判断的node中的文本必须是 node.nodeValue ,也就是这个必须是 node.nodeType == 2(某个元素的属性,比如 input 的 placeholder) 或 3(文本节点), 这样他们才会有正常的 node.nodeValue,而且文本也存在于 node.nodeValue 中
|
|
1339
|
+
比如 div title="你好" ,要对 title 的 你好 这个值进行判定,传入的node必须是 title 的 node,而非 div 的 node
|
|
1340
|
+
它主要是为了给 translate.listener.addListener 中的动态监听node改变所服务的
|
|
1341
|
+
|
|
1342
|
+
@param node 要判断的这个是否需要触发翻译的node
|
|
1343
|
+
@return boolean true:需要触发 translate.execute(node) 进行翻译
|
|
1344
|
+
*/
|
|
1345
|
+
nodeValueChangeNeedTranslate: function(node){
|
|
1346
|
+
//是否是要加入翻译扫描触发执行,是则是true
|
|
1347
|
+
var addTranslateExecute = true;
|
|
1348
|
+
|
|
1349
|
+
/*
|
|
1350
|
+
不会进入翻译的情况 -
|
|
1351
|
+
1. 认为是有 translate.js 本身翻译导致的改变,不进行翻译
|
|
1352
|
+
取 translate.node.data 中的数据,当改变的node节点在其中找到了对应的数据后,进行判定
|
|
1353
|
+
1. 是整体翻译,且当前node改变后的内容,跟上次翻译后的结果一样,那说明当前node改变事件
|
|
1354
|
+
2. 不是整体翻译,可能是触发自定义术语、或直接没启用整体翻译能力,那就要根据最后翻译时间这个来判定了。如果这个node元素,已经被翻译过了,最后一次翻译渲染时间,距离当前时间不超过500毫秒
|
|
1355
|
+
2. 其他的情况如果后续发现有遗漏,再加入,当前没有这种考虑
|
|
1356
|
+
*/
|
|
1357
|
+
if(translate.node.get(node) != null){
|
|
1358
|
+
if(typeof(translate.node.get(node).whole) !== 'undefined' && translate.node.get(node).whole == true){
|
|
1359
|
+
//整体翻译
|
|
1360
|
+
if(typeof(translate.node.get(node).resultText) !== 'undefined' && translate.node.get(node).resultText === node.nodeValue){
|
|
1361
|
+
//当前改变后的内容,跟上次翻译后的结果一样,那说明当前node改变事件,是有translate.js 本身翻译导致的,不进行翻译
|
|
1362
|
+
addTranslateExecute = false;
|
|
1363
|
+
}
|
|
1364
|
+
}else{
|
|
1365
|
+
//不是整体翻译,可能是触发自定义术语、或直接没启用整体翻译能力
|
|
1366
|
+
//这就要根据最后翻译时间这个来判定了
|
|
1367
|
+
if(typeof(translate.node.get(node).lastTranslateRenderTime) == 'number' && translate.node.get(node).lastTranslateRenderTime + 500 > Date.now()){
|
|
1368
|
+
//如果这个node元素,已经被翻译过了,最后一次翻译渲染时间,距离当前时间不超过500毫秒,那认为这个元素动态改变,是有translate.js 本身引起的,将不做任何动作
|
|
1369
|
+
addTranslateExecute = false;
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
//如果新的里面没有非空白字符的值,那也不再触发翻译
|
|
1375
|
+
if(addTranslateExecute === true){
|
|
1376
|
+
if(node.nodeValue.trim().length === 0){
|
|
1377
|
+
addTranslateExecute = false;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
return addTranslateExecute;
|
|
1382
|
+
},
|
|
1383
|
+
|
|
1312
1384
|
|
|
1313
1385
|
//增加监听,开始监听。这个不要直接调用,需要使用上面的 start() 开启
|
|
1314
1386
|
addListener:function(){
|
|
@@ -1345,61 +1417,47 @@ var translate = {
|
|
|
1345
1417
|
}
|
|
1346
1418
|
}
|
|
1347
1419
|
}else if (mutation.type === 'attributes') {
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
//如果是class,不做任何改变,直接跳出
|
|
1420
|
+
if(mutation.attributeName === 'class' || mutation.attributeName === 'style'){
|
|
1421
|
+
//如果是class/ style 这种常见的,不做任何改变,直接跳出
|
|
1351
1422
|
continue;
|
|
1352
1423
|
}
|
|
1353
|
-
//console.log('listener attributes change --> ' + mutation.target.nodeName+'['+ mutation.attributeName + '] oldValue :'+mutation.oldValue);
|
|
1354
1424
|
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1425
|
+
/*
|
|
1426
|
+
这里要判断一些允许翻译的属性
|
|
1427
|
+
input 的 placeholder 属性 ,直接判断 placeholder 就行了,也就 input、textarea 有这个属性
|
|
1428
|
+
img 的 alt 属性
|
|
1429
|
+
所有标签的 title 属性
|
|
1430
|
+
*/
|
|
1431
|
+
|
|
1432
|
+
if(mutation.attributeName === 'placeholder' || mutation.attributeName === 'alt' || mutation.attributeName === 'title'){
|
|
1433
|
+
//允许翻译
|
|
1434
|
+
}else{
|
|
1435
|
+
//判断是否是 translate.element.tagAttribute 自定义翻译属性的
|
|
1436
|
+
var divTagAttribute = translate.element.tagAttribute[mutation.target.nodeName.toLowerCase()];
|
|
1437
|
+
if(typeof(divTagAttribute) !== 'undefined' && divTagAttribute.attribute.indexOf(mutation.attributeName) > -1 && divTagAttribute.condition(mutation.target)){
|
|
1438
|
+
//是自定义翻译这个属性的,以及判定是否达到翻译条件
|
|
1439
|
+
//条件满足,允许翻译
|
|
1359
1440
|
}else{
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
//console.log(translate.node.get(mutation.target)[nodeAttribute.key])
|
|
1363
|
-
if(typeof(translate.node.get(mutation.target)[nodeAttribute.key]) != 'undefined'){
|
|
1364
|
-
//从翻译历史中删掉,使这个属性还能继续被翻译
|
|
1365
|
-
//console.log('delete translate.node.get(mutation.target)[nodeAttribute.key] -> '+mutation.attributeName);
|
|
1366
|
-
delete translate.node.get(mutation.target)[nodeAttribute.key];
|
|
1367
|
-
}
|
|
1441
|
+
//条件不满足,不在翻译的属性范围
|
|
1442
|
+
continue;
|
|
1368
1443
|
}
|
|
1369
1444
|
}
|
|
1370
1445
|
|
|
1371
|
-
|
|
1372
|
-
|
|
1446
|
+
//这里出现的 mutation.target 是定位到了元素上面,而不是变化的这个 attributes 属性上,需要用 mutation.attributeName 获取到这个属性的node
|
|
1447
|
+
var node = mutation.target.getAttributeNode(mutation.attributeName);
|
|
1448
|
+
|
|
1449
|
+
//是否是要加入翻译扫描触发执行,是则是true
|
|
1450
|
+
var addTranslateExecute = translate.listener.nodeValueChangeNeedTranslate(node);
|
|
1451
|
+
if(addTranslateExecute){ //不是 translate.js 翻译引起的改变,那么
|
|
1452
|
+
//console.log('listener attributes change ' + mutation.target.nodeName+'['+ mutation.attributeName + '] '+mutation.oldValue+' --> '+node.nodeValue);
|
|
1453
|
+
translate.node.delete(node);
|
|
1454
|
+
addNodes = [node]; //将这个属性转为的node加入待翻译
|
|
1455
|
+
}
|
|
1373
1456
|
}else if(mutation.type === 'characterData'){
|
|
1374
1457
|
//内容改变
|
|
1375
1458
|
|
|
1376
1459
|
//是否是要加入翻译扫描触发执行,是则是true
|
|
1377
|
-
var addTranslateExecute =
|
|
1378
|
-
|
|
1379
|
-
/*
|
|
1380
|
-
不会进入翻译的情况 -
|
|
1381
|
-
1. 认为是有 translate.js 本身翻译导致的改变,不进行翻译
|
|
1382
|
-
取 translate.node.data 中的数据,当改变的node节点在其中找到了对应的数据后,进行判定
|
|
1383
|
-
1. 是整体翻译,且当前node改变后的内容,跟上次翻译后的结果一样,那说明当前node改变事件
|
|
1384
|
-
2. 不是整体翻译,可能是触发自定义术语、或直接没启用整体翻译能力,那就要根据最后翻译时间这个来判定了。如果这个node元素,已经被翻译过了,最后一次翻译渲染时间,距离当前时间不超过500毫秒
|
|
1385
|
-
2. 其他的情况如果后续发现有遗漏,再加入,当前没有这种考虑
|
|
1386
|
-
*/
|
|
1387
|
-
if(translate.node.get(mutation.target) != null && typeof(translate.node.get(mutation.target).translate_default_value) != 'undefined'){
|
|
1388
|
-
if(typeof(translate.node.get(mutation.target).translate_default_value.whole) != 'undefined' && translate.node.get(mutation.target).translate_default_value.whole == true){
|
|
1389
|
-
//整体翻译
|
|
1390
|
-
if(typeof(translate.node.get(mutation.target).translate_default_value.resultText) != 'undefined' && translate.node.get(mutation.target).translate_default_value.resultText === mutation.target.nodeValue){
|
|
1391
|
-
//当前改变后的内容,跟上次翻译后的结果一样,那说明当前node改变事件,是有translate.js 本身翻译导致的,不进行翻译
|
|
1392
|
-
addTranslateExecute = false;
|
|
1393
|
-
}
|
|
1394
|
-
}else{
|
|
1395
|
-
//不是整体翻译,可能是触发自定义术语、或直接没启用整体翻译能力
|
|
1396
|
-
//这就要根据最后翻译时间这个来判定了
|
|
1397
|
-
if(typeof(translate.node.get(mutation.target).lastTranslateRenderTime) == 'number' && translate.node.get(mutation.target).lastTranslateRenderTime + 500 > Date.now()){
|
|
1398
|
-
//如果这个node元素,已经被翻译过了,最后一次翻译渲染时间,距离当前时间不超过500毫秒,那认为这个元素动态改变,是有translate.js 本身引起的,将不做任何动作
|
|
1399
|
-
addTranslateExecute = false;
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1460
|
+
var addTranslateExecute = translate.listener.nodeValueChangeNeedTranslate(mutation.target);
|
|
1403
1461
|
|
|
1404
1462
|
if(addTranslateExecute){ //不是 translate.js 翻译引起的改变,那么
|
|
1405
1463
|
translate.node.delete(mutation.target);
|
|
@@ -1428,10 +1486,8 @@ var translate = {
|
|
|
1428
1486
|
}
|
|
1429
1487
|
}
|
|
1430
1488
|
|
|
1431
|
-
//console.log(documents.length);
|
|
1432
1489
|
if(documents.length > 0){
|
|
1433
1490
|
//有变动,需要看看是否需要翻译,延迟10毫秒执行
|
|
1434
|
-
|
|
1435
1491
|
translate.time.log('监听到元素发生变化,'+documents.length+'个元素');
|
|
1436
1492
|
|
|
1437
1493
|
//判断是否属于在正在翻译的节点,重新组合出新的要翻译的node集合
|
|
@@ -1473,7 +1529,7 @@ var translate = {
|
|
|
1473
1529
|
//console.log('translateNodeslength: '+translateNodes.length);
|
|
1474
1530
|
|
|
1475
1531
|
translate.time.log('将监听到的发生变化的元素进行整理,得到'+translateNodes.length+'个元素,对其进行翻译');
|
|
1476
|
-
//console.log(translateNodes
|
|
1532
|
+
//console.log(translateNodes);
|
|
1477
1533
|
|
|
1478
1534
|
translate.execute(translateNodes);
|
|
1479
1535
|
//setTimeout(function() {
|
|
@@ -1694,12 +1750,25 @@ var translate = {
|
|
|
1694
1750
|
|
|
1695
1751
|
|
|
1696
1752
|
// translate.node 记录
|
|
1697
|
-
|
|
1698
|
-
|
|
1753
|
+
|
|
1754
|
+
var translateNode; //当前操作的,要记录入 translate.node 中的,进行翻译的node
|
|
1755
|
+
var translateNode_attribute = ''; //当前操作的是node中的哪个attribute,如果没有是node本身则是空字符串
|
|
1756
|
+
if(typeof(task['attribute']) === 'string' && task['attribute'].length > 0){
|
|
1757
|
+
//当前渲染任务是针对的元素的某个属性,这是要取出这个元素的具体属性,作为一个目的 node 来进行加入 translate.node
|
|
1758
|
+
//是操作的元素的某个属性
|
|
1759
|
+
translateNode = this.nodes[hash][node_index].getAttributeNode(task['attribute']);
|
|
1760
|
+
translateNode_attribute = task['attribute'];
|
|
1761
|
+
}else{
|
|
1762
|
+
//操作的就是node本身
|
|
1763
|
+
translateNode = this.nodes[hash][node_index];
|
|
1764
|
+
}
|
|
1765
|
+
//console.log(translateNode)
|
|
1766
|
+
//var nodeAttribute = translate.node.getAttribute(task['attribute']);
|
|
1767
|
+
if(translate.node.data.get(translateNode) != null){
|
|
1699
1768
|
// 记录当前有 translate.js 所触发翻译之后渲染到dom界面显示的时间,13位时间戳
|
|
1700
|
-
translate.node.get(
|
|
1769
|
+
translate.node.get(translateNode).lastTranslateRenderTime = Date.now();
|
|
1701
1770
|
}else{
|
|
1702
|
-
translate.log('执行异常,渲染时,node未在
|
|
1771
|
+
translate.log('执行异常,渲染时,node 未在 translate.node 中找到, 这个理论上是不应该存在的,当前异常已被容错。 node:'+translateNode);
|
|
1703
1772
|
translate.log(this.nodes[hash][task_index]);
|
|
1704
1773
|
}
|
|
1705
1774
|
|
|
@@ -1708,22 +1777,14 @@ var translate = {
|
|
|
1708
1777
|
var analyseSet = translate.element.nodeAnalyse.set(this.nodes[hash][task_index], task.originalText, task.resultText, task['attribute']);
|
|
1709
1778
|
//console.log(analyseSet);
|
|
1710
1779
|
|
|
1711
|
-
if(translate.node.data.get(
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
//将具体通过文本翻译接口进行翻译的文本记录到 translate.node.data
|
|
1717
|
-
translate.node.get(this.nodes[hash][task_index])[nodeAttribute.key].translateTexts[task.originalText] = task.resultText;
|
|
1718
|
-
//将翻译完成后要显示出的文本进行记录
|
|
1719
|
-
translate.node.get(this.nodes[hash][task_index])[nodeAttribute.key].resultText = analyseSet.resultText;
|
|
1780
|
+
if(translate.node.data.get(translateNode) != null){
|
|
1781
|
+
//将具体通过文本翻译接口进行翻译的文本记录到 translate.node.data
|
|
1782
|
+
translate.node.get(translateNode).translateTexts[task.originalText] = task.resultText;
|
|
1783
|
+
//将翻译完成后要显示出的文本进行记录
|
|
1784
|
+
translate.node.get(translateNode).resultText = analyseSet.resultText;
|
|
1720
1785
|
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
}
|
|
1724
|
-
}else{
|
|
1725
|
-
translate.log('执行异常,渲染时,node未在 nodeHistory 中找到, 这个理论上是不应该存在的,当前异常已被容错。 node:'+this.nodes[hash][task_index]);
|
|
1726
|
-
translate.log(this.nodes[hash][task_index]);
|
|
1786
|
+
//将其加入 translate.history.translateTexts
|
|
1787
|
+
translate.history.translateText.add(translate.node.get(translateNode).originalText ,analyseSet.resultText);
|
|
1727
1788
|
}
|
|
1728
1789
|
|
|
1729
1790
|
//加入 translate.listener.ignoreNode
|
|
@@ -1856,12 +1917,14 @@ var translate = {
|
|
|
1856
1917
|
translate.listener.execute.renderFinishByApiRun(uuid, from, to);
|
|
1857
1918
|
|
|
1858
1919
|
//通过 uuid、from 取得本次翻译相关的 texts、nodes , 触发 translateNetworkAfter_Trigger 钩子
|
|
1920
|
+
//获取请求日志
|
|
1921
|
+
var requestData = translate.request.data[uuid].list[from][to];
|
|
1859
1922
|
translate.lifecycle.execute.translateNetworkAfter_Trigger({
|
|
1860
1923
|
uuid: uuid,
|
|
1861
1924
|
from: from,
|
|
1862
1925
|
to: to,
|
|
1863
|
-
texts:
|
|
1864
|
-
nodes:
|
|
1926
|
+
texts: requestData.texts,
|
|
1927
|
+
nodes: requestData.nodes,
|
|
1865
1928
|
result: result,
|
|
1866
1929
|
info: info
|
|
1867
1930
|
});
|
|
@@ -2229,8 +2292,8 @@ var translate = {
|
|
|
2229
2292
|
if(sliceDoc[di].getAttribute('class') != null && typeof(sliceDoc[di].getAttribute('class')) == 'string' && sliceDoc[di].getAttribute('class').length > 0){
|
|
2230
2293
|
sliceDocString = sliceDocString + " class="+sliceDoc[di].getAttribute('class');
|
|
2231
2294
|
}
|
|
2232
|
-
}else if(sliceDoc[di].nodeType === 3){
|
|
2233
|
-
//
|
|
2295
|
+
}else if(sliceDoc[di].nodeType === 2 || sliceDoc[di].nodeType === 3){
|
|
2296
|
+
//2属性 或 3文本节点
|
|
2234
2297
|
sliceDocString = sliceDocString + sliceDoc[di].nodeValue.replaceAll(/\r?\n/g, '[换行符]');
|
|
2235
2298
|
}
|
|
2236
2299
|
}
|
|
@@ -2239,7 +2302,6 @@ var translate = {
|
|
|
2239
2302
|
|
|
2240
2303
|
|
|
2241
2304
|
translate.log('当前翻译未完结,新翻译任务已加入等待翻译队列,待上个翻译任务结束后便会执行当前翻译任务'+sliceDocString);
|
|
2242
|
-
//console.log(docs);
|
|
2243
2305
|
translate.waitingExecute.add(docs);
|
|
2244
2306
|
|
|
2245
2307
|
//钩子
|
|
@@ -2371,7 +2433,7 @@ var translate = {
|
|
|
2371
2433
|
|
|
2372
2434
|
if(all.length > 500){
|
|
2373
2435
|
translate.log('------tip------');
|
|
2374
|
-
translate.log('translate.execute( docs ) 传入的docs.length 过大,超过
|
|
2436
|
+
translate.log('translate.execute( docs ) 传入的docs.length 过大,超过1500,这很不正常,当前 docs.length : '+all.length+' ,如果你感觉真的没问题,请联系作者 http://translate.zvo.cn/43006.html 说明情况,根据你的情况进行分析。 当前只取前1500个元素进行翻译');
|
|
2375
2437
|
}
|
|
2376
2438
|
|
|
2377
2439
|
//初始化 translate.element.tagAttribute ,主要针对 v3.17.10 版本的适配调整,对 translate.element.tagAttribute 的设置做了改变,做旧版本的适配
|
|
@@ -2397,7 +2459,7 @@ var translate = {
|
|
|
2397
2459
|
|
|
2398
2460
|
translate.time.log('开始扫描要翻译区域的元素');
|
|
2399
2461
|
//检索目标内的node元素
|
|
2400
|
-
for(var i = 0; i< all.length & i <
|
|
2462
|
+
for(var i = 0; i< all.length & i < 1500; i++){
|
|
2401
2463
|
var node = all[i];
|
|
2402
2464
|
translate.element.whileNodes(uuid, node);
|
|
2403
2465
|
}
|
|
@@ -2928,6 +2990,11 @@ var translate = {
|
|
|
2928
2990
|
将翻译请求的信息记录到 translate.js 本身中
|
|
2929
2991
|
uuid 每次 translate.execute() 触发生成的uuid
|
|
2930
2992
|
time: 触发后加入到 data 中的时间,13位时间戳
|
|
2993
|
+
list: 记录当前uuid下发起的网络请求
|
|
2994
|
+
from: 从什么语种进行的翻译,如: chinese_simplified
|
|
2995
|
+
to: 翻译为什么语种,如 : english
|
|
2996
|
+
nodes: 当前网络请求有哪些node节点,值为 [node1, node2, ...]
|
|
2997
|
+
texts: 当前网络请求有哪些文本进行翻译,值为 [text1, text2, ...]
|
|
2931
2998
|
|
|
2932
2999
|
*/
|
|
2933
3000
|
translate.request.data[uuid] = {
|
|
@@ -2998,8 +3065,10 @@ var translate = {
|
|
|
2998
3065
|
});
|
|
2999
3066
|
|
|
3000
3067
|
//记入请求日志
|
|
3001
|
-
translate.request.data[uuid].list[lang]
|
|
3002
|
-
|
|
3068
|
+
if(typeof(translate.request.data[uuid].list[lang]) === 'undefined'){
|
|
3069
|
+
translate.request.data[uuid].list[lang] = {};
|
|
3070
|
+
}
|
|
3071
|
+
translate.request.data[uuid].list[lang][translate.to] = {
|
|
3003
3072
|
texts: translateTextArray[lang],
|
|
3004
3073
|
nodes: translateTextNodes,
|
|
3005
3074
|
};
|
|
@@ -3113,8 +3182,8 @@ var translate = {
|
|
|
3113
3182
|
//将翻译结果以 key:hash value翻译结果的形式缓存
|
|
3114
3183
|
translate.storage.set('hash_'+data.to+'_'+cacheHash,text);
|
|
3115
3184
|
//如果离线翻译启用了全部提取,那么还要存入离线翻译指定存储
|
|
3116
|
-
if(translate.
|
|
3117
|
-
translate.
|
|
3185
|
+
if(translate.offline.fullExtract.isUse){
|
|
3186
|
+
translate.offline.fullExtract.set(hash, originalWord, data.to, text);
|
|
3118
3187
|
}
|
|
3119
3188
|
}
|
|
3120
3189
|
task.execute(); //执行渲染任务
|
|
@@ -3193,7 +3262,7 @@ var translate = {
|
|
|
3193
3262
|
将已扫描的节点进行记录,这里是只要进行扫描到了,也就是在加入 translate.nodeQueue 时就也要加入到这里。
|
|
3194
3263
|
这是一个map,为了兼容es5,这里设置为null,在 translate.execute 中在进行初始化
|
|
3195
3264
|
|
|
3196
|
-
key: node
|
|
3265
|
+
key: node ,进行翻译的文本的node, 如果是 div 的 title属性进行的翻译,那这个node是定位在 title 上的node,而不是 div 这个依附的元素
|
|
3197
3266
|
value: 这是一个对像
|
|
3198
3267
|
其中,key的取值有这几种:
|
|
3199
3268
|
translate_default_value: 如果当前翻译的是元素本身的值或node节点本身的值(nodeValue),那么这里的key就是固定的 translate_default_value
|
|
@@ -3246,7 +3315,7 @@ var translate = {
|
|
|
3246
3315
|
key: translate.node 中 translate.node.get(node)[attribute] 所使用的 attribute 的字符串,如 attribute_title 、translate_default_value
|
|
3247
3316
|
attribute: 这里是attribute具体的内容,比如 key 是 attribute_title 那么这里就是 title , key 是 translate_default_value 这里就是 '' 空字符串
|
|
3248
3317
|
}
|
|
3249
|
-
|
|
3318
|
+
|
|
3250
3319
|
getAttribute:function(attribute){
|
|
3251
3320
|
var history_attribute;
|
|
3252
3321
|
if(typeof(attribute) != 'undefined' && attribute.length > 0){
|
|
@@ -3262,6 +3331,7 @@ var translate = {
|
|
|
3262
3331
|
attribute:attribute
|
|
3263
3332
|
}
|
|
3264
3333
|
},
|
|
3334
|
+
*/
|
|
3265
3335
|
/*
|
|
3266
3336
|
刷新 translate.node.data 中的数据,剔除过时的(node已经不存在于dom的)
|
|
3267
3337
|
*/
|
|
@@ -3360,6 +3430,147 @@ var translate = {
|
|
|
3360
3430
|
get:function(node, attribute){
|
|
3361
3431
|
return translate.element.nodeAnalyse.analyse(node,'','', attribute);
|
|
3362
3432
|
},
|
|
3433
|
+
/*
|
|
3434
|
+
同上,只不过这个是扫描 element/node 下的所有可翻译的子节点(下层节点),返回数组形态。
|
|
3435
|
+
这里面的数组,已经经过判断, text 必然是有不为空的值的。
|
|
3436
|
+
所以它的返回值,有可能是一个空的数组
|
|
3437
|
+
|
|
3438
|
+
[
|
|
3439
|
+
{
|
|
3440
|
+
node: 当前扫描出的node (传入的node、或下层node)
|
|
3441
|
+
attribute: 是否是下层属性,比如 alt、placeholder , 如果是传入的node本身,不是任何下层属性,则这里是空白字符串 ''
|
|
3442
|
+
text: 可进行翻译的文本,也就是当前数组中 node 的值的文本
|
|
3443
|
+
},
|
|
3444
|
+
...
|
|
3445
|
+
]
|
|
3446
|
+
*/
|
|
3447
|
+
gets:function(node){
|
|
3448
|
+
var resultArray = [];
|
|
3449
|
+
|
|
3450
|
+
var nodename = translate.element.getNodeName(node).toUpperCase();
|
|
3451
|
+
switch (nodename) {
|
|
3452
|
+
case 'META': //meta标签,如是关键词、描述等
|
|
3453
|
+
var nodeAttributeName = node.name.toLowerCase(); //取meta 标签的name 属性
|
|
3454
|
+
var nodeAttributePropertyOri = node.getAttribute('property'); //取 property的值
|
|
3455
|
+
var nodeAttributeProperty = '';
|
|
3456
|
+
if(typeof(nodeAttributePropertyOri) === 'string' && nodeAttributePropertyOri.length > 0){
|
|
3457
|
+
nodeAttributeProperty = nodeAttributePropertyOri.toLowerCase();
|
|
3458
|
+
}
|
|
3459
|
+
|
|
3460
|
+
if(nodeAttributeName == 'keywords' || nodeAttributeName == 'description' || nodeAttributeName == 'sharetitle' || nodeAttributeProperty == 'og:title' || nodeAttributeProperty == 'og:description' || nodeAttributeProperty == 'og:site_name' || nodeAttributeProperty == 'og:novel:latest_chapter_name'){
|
|
3461
|
+
if(typeof(node.content) === 'string' && node.content.trim().length > 0){
|
|
3462
|
+
resultArray.push({
|
|
3463
|
+
text: node.content,
|
|
3464
|
+
attribute: 'content',
|
|
3465
|
+
node: node.getAttributeNode('content')
|
|
3466
|
+
});
|
|
3467
|
+
}
|
|
3468
|
+
}
|
|
3469
|
+
break;
|
|
3470
|
+
case 'IMG':
|
|
3471
|
+
if(typeof(node.alt) === 'string' && node.alt.trim().length > 0){
|
|
3472
|
+
resultArray.push({
|
|
3473
|
+
text: node.alt,
|
|
3474
|
+
attribute: 'alt',
|
|
3475
|
+
node: node.getAttributeNode('alt')
|
|
3476
|
+
});
|
|
3477
|
+
}
|
|
3478
|
+
break;
|
|
3479
|
+
case 'INPUT':
|
|
3480
|
+
/*
|
|
3481
|
+
input,要对以下情况进行翻译
|
|
3482
|
+
placeholder
|
|
3483
|
+
type=button、submit 的情况下的 value
|
|
3484
|
+
*/
|
|
3485
|
+
|
|
3486
|
+
//针对 type=button、submit 的情况下的 value
|
|
3487
|
+
if(typeof(node.attributes.type) !== 'undefined' && node.attributes.type !== null && typeof(node.attributes.type.nodeValue) === 'string' && (node.attributes.type.nodeValue.toLowerCase() == 'button' || node.attributes.type.nodeValue.toLowerCase() == 'submit')){
|
|
3488
|
+
//取它的value
|
|
3489
|
+
var input_value_node = node.attributes.value;
|
|
3490
|
+
if(typeof(input_value_node) !== 'undefined' && input_value_node !== null && typeof(input_value_node.nodeValue) === 'string' && input_value_node.nodeValue.trim().length > 0){
|
|
3491
|
+
resultArray.push({
|
|
3492
|
+
text: input_value_node.nodeValue,
|
|
3493
|
+
attribute: 'value',
|
|
3494
|
+
node: input_value_node
|
|
3495
|
+
});
|
|
3496
|
+
}
|
|
3497
|
+
}
|
|
3498
|
+
|
|
3499
|
+
//针对 placeholder
|
|
3500
|
+
if(typeof(node.attributes['placeholder']) !== 'undefined' && typeof(node.attributes['placeholder'].nodeValue) === 'string' && node.attributes['placeholder'].nodeValue.trim().length > 0){
|
|
3501
|
+
resultArray.push({
|
|
3502
|
+
text: node.attributes['placeholder'].nodeValue,
|
|
3503
|
+
attribute: 'placeholder',
|
|
3504
|
+
node: node.attributes['placeholder']
|
|
3505
|
+
});
|
|
3506
|
+
}
|
|
3507
|
+
break;
|
|
3508
|
+
case 'TEXTAREA':
|
|
3509
|
+
//针对 placeholder
|
|
3510
|
+
if(typeof(node.attributes['placeholder']) !== 'undefined' && typeof(node.attributes['placeholder'].nodeValue) === 'string' && node.attributes['placeholder'].nodeValue.trim().length > 0){
|
|
3511
|
+
resultArray.push({
|
|
3512
|
+
text: node.attributes['placeholder'].nodeValue,
|
|
3513
|
+
attribute: 'placeholder',
|
|
3514
|
+
node: node.attributes['placeholder']
|
|
3515
|
+
});
|
|
3516
|
+
}
|
|
3517
|
+
break;
|
|
3518
|
+
}
|
|
3519
|
+
|
|
3520
|
+
//判断是否是 translate.element.tagAttribute 自定义翻译属性的
|
|
3521
|
+
var divTagAttribute = translate.element.tagAttribute[nodename.toLowerCase()];
|
|
3522
|
+
if(typeof(divTagAttribute) !== 'undefined'){
|
|
3523
|
+
//有这个标签的自定义翻译某个属性
|
|
3524
|
+
for(var ai = 0; ai<node.attributes.length; ai++){
|
|
3525
|
+
var arrtibuteNodeName = translate.element.getNodeName(node.attributes[ai]).toLowerCase();
|
|
3526
|
+
if(divTagAttribute.attribute.indexOf(arrtibuteNodeName) > -1 && divTagAttribute.condition(node)){
|
|
3527
|
+
//包含这个属性,且自定义判断条件满足,允许翻译
|
|
3528
|
+
//判定一下是否已经加入过了,如果没有加入过,才会加入。这里主要是针对input 标签进行判断,比如 input type="submit" 的,value值如果也被用户自定义翻译,那上面的value就已经加上了,不需要在加了
|
|
3529
|
+
var isAlreadyAdd = false; //true已经加入过了
|
|
3530
|
+
for(var ri = 0; ri < resultArray.length; ri++){
|
|
3531
|
+
if(resultArray[ri].node === node.attributes[ai]){
|
|
3532
|
+
//相同,则不在加入了
|
|
3533
|
+
isAlreadyAdd = true;
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3536
|
+
if(!isAlreadyAdd){
|
|
3537
|
+
resultArray.push({
|
|
3538
|
+
text: node.attributes[ai].nodeValue,
|
|
3539
|
+
attribute: arrtibuteNodeName,
|
|
3540
|
+
node: node.attributes[ai]
|
|
3541
|
+
});
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3544
|
+
}
|
|
3545
|
+
}else{
|
|
3546
|
+
//条件不满足,不在翻译的属性范围
|
|
3547
|
+
}
|
|
3548
|
+
|
|
3549
|
+
|
|
3550
|
+
//所有元素都要判定的属性 - title 属性
|
|
3551
|
+
if(typeof(node['title']) === 'string' && node['title'].trim().length > 0){
|
|
3552
|
+
var titleNode = node.getAttributeNode('title');
|
|
3553
|
+
resultArray.push({
|
|
3554
|
+
text: titleNode.nodeValue,
|
|
3555
|
+
attribute: 'title',
|
|
3556
|
+
node: titleNode
|
|
3557
|
+
});
|
|
3558
|
+
}
|
|
3559
|
+
|
|
3560
|
+
|
|
3561
|
+
//最后判定 node 本身
|
|
3562
|
+
if(typeof(node.nodeValue) === 'string' && node.nodeValue.trim().length > 0){
|
|
3563
|
+
//返回传入的node本身
|
|
3564
|
+
resultArray.push({
|
|
3565
|
+
text: node.nodeValue,
|
|
3566
|
+
attribute: '',
|
|
3567
|
+
node: node
|
|
3568
|
+
});
|
|
3569
|
+
}
|
|
3570
|
+
|
|
3571
|
+
|
|
3572
|
+
return resultArray;
|
|
3573
|
+
},
|
|
3363
3574
|
/*
|
|
3364
3575
|
进行翻译之后的渲染显示
|
|
3365
3576
|
注意,它会对node本身进行扫描的,需要进行通过文本翻译接口进行翻译的文本进行识别,比如 这个 node 其内容为:
|
|
@@ -3467,6 +3678,7 @@ var translate = {
|
|
|
3467
3678
|
|
|
3468
3679
|
//正常的node ,typeof 都是 object
|
|
3469
3680
|
|
|
3681
|
+
/* 这里是通用方法,不应该有限制
|
|
3470
3682
|
//console.log(typeof(node)+node);
|
|
3471
3683
|
if(nodename == '#text'){
|
|
3472
3684
|
//如果是普通文本,判断一下上层是否是包含在textarea标签中
|
|
@@ -3480,7 +3692,7 @@ var translate = {
|
|
|
3480
3692
|
}
|
|
3481
3693
|
}
|
|
3482
3694
|
}
|
|
3483
|
-
|
|
3695
|
+
*/
|
|
3484
3696
|
|
|
3485
3697
|
|
|
3486
3698
|
//console.log(nodename)
|
|
@@ -3639,11 +3851,23 @@ var translate = {
|
|
|
3639
3851
|
resultShowText: translate.element.nodeAnalyse.analyse 进行设置翻译后的文本渲染时,提前计算好这个node显示的所有文本,然后在赋予 dom,这里是计算好的node要整体显示的文本
|
|
3640
3852
|
*/
|
|
3641
3853
|
analyseReplaceBefore_DateToTranslateNode:function(node, attribute, resultShowText){
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3854
|
+
var translateNode; //当前操作的,要记录入 translate.node 中的,进行翻译的node
|
|
3855
|
+
var translateNode_attribute = ''; //当前操作的是node中的哪个attribute,如果没有是node本身则是空字符串
|
|
3856
|
+
|
|
3857
|
+
if(typeof(attribute) === 'string' && attribute.length > 0){
|
|
3858
|
+
//是操作的元素的某个属性
|
|
3859
|
+
translateNode = node.getAttributeNode(attribute);
|
|
3860
|
+
translateNode_attribute = attribute;
|
|
3861
|
+
}else{
|
|
3862
|
+
//操作的就是node本身
|
|
3863
|
+
translateNode = node;
|
|
3864
|
+
}
|
|
3865
|
+
|
|
3866
|
+
if(translate.node.find(translateNode)){
|
|
3867
|
+
if(typeof(translate.node.get(translateNode).translateResults) == 'undefined'){
|
|
3868
|
+
translate.node.get(translateNode).translateResults = {};
|
|
3645
3869
|
}
|
|
3646
|
-
translate.node.get(
|
|
3870
|
+
translate.node.get(translateNode).translateResults[resultShowText] = 1;
|
|
3647
3871
|
}else{
|
|
3648
3872
|
//翻译过程中,会有时间差,比如通过文本翻译api请求,这时node元素本身被其他js改变了,导致翻译完成后,原本的node不存在了
|
|
3649
3873
|
//console.log('[debug] 数据异常,analyse - set 中发现 translate.node 中的 node 不存在,理论上应该只要被扫描了,被翻译了,到这里就一定会存在的,不存在怎么会扫描到交给去翻译呢');
|
|
@@ -3690,7 +3914,7 @@ var translate = {
|
|
|
3690
3914
|
|
|
3691
3915
|
//console.log('---'+typeof(node)+', ');
|
|
3692
3916
|
//判断是否是有title属性,title属性也要翻译
|
|
3693
|
-
if(typeof(node) == 'object' && typeof(node['title']) == 'string' && node['title'].length > 0){
|
|
3917
|
+
if(typeof(node) == 'object' && typeof(node['title']) == 'string' && node['title'].trim().length > 0){
|
|
3694
3918
|
//将title加入翻译队列
|
|
3695
3919
|
//console.log('---'+node.title+'\t'+node.tagName);
|
|
3696
3920
|
//console.log(node)
|
|
@@ -3699,7 +3923,8 @@ var translate = {
|
|
|
3699
3923
|
//判断当前元素是否在ignore忽略的tag、id、class name中
|
|
3700
3924
|
if(!translate.ignore.isIgnore(node)){
|
|
3701
3925
|
//不在忽略的里面,才会加入翻译
|
|
3702
|
-
translate.addNodeToQueue(uuid, node, node['title'], 'title');
|
|
3926
|
+
//translate.addNodeToQueue(uuid, node, node['title'], 'title');
|
|
3927
|
+
translate.addNodeToQueue(uuid, node.getAttributeNode('title'), node['title'], '');
|
|
3703
3928
|
}
|
|
3704
3929
|
}
|
|
3705
3930
|
|
|
@@ -3753,7 +3978,7 @@ var translate = {
|
|
|
3753
3978
|
//判断当前元素是否在ignore忽略的tag、id、class name中 v3.15.7 增加
|
|
3754
3979
|
if(!translate.ignore.isIgnore(node)){
|
|
3755
3980
|
//加入翻译
|
|
3756
|
-
translate.addNodeToQueue(uuid, node, attributeValue,
|
|
3981
|
+
translate.addNodeToQueue(uuid, node.getAttributeNode(attributeName), attributeValue, '');
|
|
3757
3982
|
}
|
|
3758
3983
|
}
|
|
3759
3984
|
}
|
|
@@ -3776,22 +4001,16 @@ var translate = {
|
|
|
3776
4001
|
if(node == null || typeof(node) == 'undefined'){
|
|
3777
4002
|
return;
|
|
3778
4003
|
}
|
|
3779
|
-
if(node.
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
return;
|
|
3788
|
-
}
|
|
3789
|
-
if(translate.ignore.tag.indexOf(parentNodeName.toLowerCase()) > -1){
|
|
3790
|
-
//忽略tag
|
|
3791
|
-
//console.log('忽略tag:'+parentNodeName);
|
|
3792
|
-
return;
|
|
4004
|
+
if(node.nodeType === 2){ //是属性node,比如 div 的 title 属性的 node
|
|
4005
|
+
if(node.ownerElement == null){
|
|
4006
|
+
return;
|
|
4007
|
+
}
|
|
4008
|
+
}else{ //是元素了
|
|
4009
|
+
if(node.parentNode == null){
|
|
4010
|
+
return;
|
|
4011
|
+
}
|
|
3793
4012
|
}
|
|
3794
|
-
|
|
4013
|
+
|
|
3795
4014
|
/****** 判断忽略的class ******/
|
|
3796
4015
|
/*
|
|
3797
4016
|
这段理论上不需要了,因为在 translate.ignore.isIgnore 判断了
|
|
@@ -3825,13 +4044,21 @@ var translate = {
|
|
|
3825
4044
|
return;
|
|
3826
4045
|
}
|
|
3827
4046
|
|
|
3828
|
-
//node
|
|
4047
|
+
//node分析,分析这个node的所有可翻译属性(包含自定义翻译属性 translate.element.tagAttribute )
|
|
4048
|
+
var nodeAnalyChild = translate.element.nodeAnalyse.gets(node);
|
|
4049
|
+
//console.log(nodeAnalyChild);
|
|
4050
|
+
for(var nci = 0; nci < nodeAnalyChild.length; nci++){
|
|
4051
|
+
translate.addNodeToQueue(uuid, nodeAnalyChild[nci].node, nodeAnalyChild[nci].text, '');
|
|
4052
|
+
}
|
|
4053
|
+
/*
|
|
3829
4054
|
var nodeAnaly = translate.element.nodeAnalyse.get(node);
|
|
3830
4055
|
if(nodeAnaly['text'].length > 0){
|
|
3831
4056
|
//有要翻译的目标内容,加入翻译队列
|
|
3832
|
-
|
|
3833
|
-
|
|
4057
|
+
console.log(nodeAnaly)
|
|
4058
|
+
console.log('addNodeToQueue -- '+nodeAnaly['node']+', text:' + nodeAnaly['text']);
|
|
4059
|
+
translate.addNodeToQueue(uuid, nodeAnaly['node'], nodeAnaly['text'], '');
|
|
3834
4060
|
}
|
|
4061
|
+
*/
|
|
3835
4062
|
|
|
3836
4063
|
//console.log(nodeAnaly);
|
|
3837
4064
|
/*
|
|
@@ -3892,6 +4119,56 @@ var translate = {
|
|
|
3892
4119
|
*/
|
|
3893
4120
|
|
|
3894
4121
|
},
|
|
4122
|
+
/*
|
|
4123
|
+
将node转为element输出。
|
|
4124
|
+
如果node是文本元素,则转化为这个文本元素所在的element元素
|
|
4125
|
+
如果node是属性,则转化为这个属性所在的element元素
|
|
4126
|
+
如果node本身就是元素标签,那就还是这样返回。
|
|
4127
|
+
|
|
4128
|
+
|
|
4129
|
+
nodes: node数组,传入如 [node1,node2, ...] 它里面可能包含 node.nodeType 1\2\3 等值
|
|
4130
|
+
|
|
4131
|
+
返回这些node转化为所在元素后的数组,返回如 [element1, element2, ...]
|
|
4132
|
+
注意的是
|
|
4133
|
+
1. 输出的一定是 element 元素,也就是 node.nodeType 一定等于1
|
|
4134
|
+
2. 输出的元素数组不一定等于传入的nodes数组,也就是他们的数量跟下标并不是对应相等的
|
|
4135
|
+
|
|
4136
|
+
*/
|
|
4137
|
+
nodeToElement: function(nodes){
|
|
4138
|
+
var elements = new Array(); //要改动的元素
|
|
4139
|
+
|
|
4140
|
+
//遍历所有node组合到 nodes. 这个不单纯只是遍历组合,它会判断如果是文本节点,则取它的父级元素。它组合的结果是元素的集合
|
|
4141
|
+
for(var r = 0; r<nodes.length; r++){
|
|
4142
|
+
var node = nodes[r];
|
|
4143
|
+
if(typeof(node) == 'undefined' || typeof(node.parentNode) == 'undefined'){
|
|
4144
|
+
continue;
|
|
4145
|
+
}
|
|
4146
|
+
if(node.nodeType === 2){
|
|
4147
|
+
//是属性节点,可能是input、textarea 的 placeholder ,获取它的父元素
|
|
4148
|
+
var nodeParentElement = node.ownerElement;
|
|
4149
|
+
if(nodeParentElement == null){
|
|
4150
|
+
continue;
|
|
4151
|
+
}
|
|
4152
|
+
elements.push(nodeParentElement);
|
|
4153
|
+
}else if(node.nodeType === 3){
|
|
4154
|
+
//是文本节点
|
|
4155
|
+
var nodeParentElement = node.parentNode;
|
|
4156
|
+
if(nodeParentElement == null){
|
|
4157
|
+
continue;
|
|
4158
|
+
}
|
|
4159
|
+
elements.push(nodeParentElement);
|
|
4160
|
+
}else if(node.nodeType === 1){
|
|
4161
|
+
//元素节点了,直接加入
|
|
4162
|
+
elements.push(node);
|
|
4163
|
+
}else{
|
|
4164
|
+
//1\2\3 都不是,这不应该是 translate.js 中应该出现的
|
|
4165
|
+
translate.log('translate.element.nodeToElement 中,发现传入的node.nodeType 类型有异常,理论上不应该存在, node.nodeType:'+node.nodeType);
|
|
4166
|
+
translate.log(node);
|
|
4167
|
+
}
|
|
4168
|
+
}
|
|
4169
|
+
|
|
4170
|
+
return elements;
|
|
4171
|
+
}
|
|
3895
4172
|
},
|
|
3896
4173
|
|
|
3897
4174
|
|
|
@@ -3957,27 +4234,34 @@ var translate = {
|
|
|
3957
4234
|
|
|
3958
4235
|
|
|
3959
4236
|
/***** 记录这个node 到 translate.node.data,这也是node进入 translate.node.data 记录的第一入口 *****/
|
|
3960
|
-
|
|
3961
|
-
|
|
4237
|
+
var translateNode; //当前操作的,要记录入 translate.node 中的,进行翻译的node
|
|
4238
|
+
var translateNode_attribute = ''; //当前操作的是node中的哪个attribute,如果没有是node本身则是空字符串
|
|
4239
|
+
if(typeof(attribute) === 'string' && attribute.length > 0){
|
|
4240
|
+
//是操作的元素的某个属性
|
|
4241
|
+
translateNode = node.getAttributeNode(attribute);
|
|
4242
|
+
translateNode_attribute = attribute;
|
|
4243
|
+
}else{
|
|
4244
|
+
//操作的就是node本身
|
|
4245
|
+
translateNode = node;
|
|
3962
4246
|
}
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
4247
|
+
if(translate.node.get(translateNode) == null){
|
|
4248
|
+
translate.node.set(translateNode, {});
|
|
4249
|
+
}
|
|
4250
|
+
|
|
4251
|
+
//var nodeAttribute = translate.node.getAttribute(attribute);
|
|
3966
4252
|
//console.log(text+'-----:');
|
|
3967
4253
|
//console.log(nodeAttribute);
|
|
3968
|
-
if(typeof(translate.node.get(
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
translate.node.get(
|
|
3973
|
-
if(typeof(translate.node.get(node)[nodeAttribute.key].originalText) == 'string'){
|
|
4254
|
+
//if(typeof(translate.node.get(translateNode)[nodeAttribute.key]) == 'undefined'){
|
|
4255
|
+
// translate.node.get(node)[nodeAttribute.key] = {};
|
|
4256
|
+
//}
|
|
4257
|
+
translate.node.get(translateNode).attribute = translateNode_attribute;
|
|
4258
|
+
if(typeof(translate.node.get(translateNode).originalText) === 'string'){
|
|
3974
4259
|
//这个节点有过记录原始显示的文本了,那么不再对其进行后续的扫描,除非它有被触发过动态监听元素改变, --- 至于它有被触发过动态监听元素改变--后续想怎么判定
|
|
3975
4260
|
//console.log(translate.node.get(node)[nodeAttribute.key].originalText+'\t又过了,不在翻译');
|
|
3976
4261
|
return;
|
|
3977
4262
|
}else{
|
|
3978
4263
|
//没有过,是第一次,那么赋予值
|
|
3979
|
-
translate.node.get(
|
|
3980
|
-
//console.log(translate.node.get(node));
|
|
4264
|
+
translate.node.get(translateNode).originalText = text;
|
|
3981
4265
|
}
|
|
3982
4266
|
//console.log(translate.node.get(node)[nodeAttribute.key]);
|
|
3983
4267
|
/*
|
|
@@ -4007,13 +4291,12 @@ var translate = {
|
|
|
4007
4291
|
return;
|
|
4008
4292
|
}
|
|
4009
4293
|
*/
|
|
4010
|
-
if(typeof(translate.node.get(
|
|
4011
|
-
translate.node.get(
|
|
4294
|
+
if(typeof(translate.node.get(translateNode).translateTexts) === 'undefined'){
|
|
4295
|
+
translate.node.get(translateNode).translateTexts = {};
|
|
4012
4296
|
}
|
|
4013
4297
|
/***** 自检完毕,准备进行翻译了 *****/
|
|
4014
4298
|
|
|
4015
4299
|
|
|
4016
|
-
|
|
4017
4300
|
//原本传入的text会被切割为多个小块
|
|
4018
4301
|
var textArray = new Array();
|
|
4019
4302
|
textArray.push(text); //先将主 text 赋予 ,后面如果对主text进行加工分割,分割后会将主text给删除掉
|
|
@@ -4053,8 +4336,8 @@ var translate = {
|
|
|
4053
4336
|
|
|
4054
4337
|
//console.log(textArray);
|
|
4055
4338
|
textArray = translate.nomenclature.dispose(textArray, temporaryIgnoreTexts[ti], temporaryIgnoreTexts[ti], {
|
|
4056
|
-
node:
|
|
4057
|
-
attribute:
|
|
4339
|
+
node:translateNode,
|
|
4340
|
+
attribute:''
|
|
4058
4341
|
}).texts;
|
|
4059
4342
|
//console.log(textArray);
|
|
4060
4343
|
}
|
|
@@ -4082,8 +4365,8 @@ var translate = {
|
|
|
4082
4365
|
//console.log('----translate.nomenclature.dispose---');
|
|
4083
4366
|
//console.log(textArray);
|
|
4084
4367
|
var nomenclatureDispose = translate.nomenclature.dispose(textArray, nomenclatureKey, nomenclatureValue, {
|
|
4085
|
-
node:
|
|
4086
|
-
attribute:
|
|
4368
|
+
node:translateNode,
|
|
4369
|
+
attribute:''
|
|
4087
4370
|
});
|
|
4088
4371
|
|
|
4089
4372
|
textArray = nomenclatureDispose.texts;
|
|
@@ -4107,10 +4390,10 @@ var translate = {
|
|
|
4107
4390
|
|
|
4108
4391
|
//记录 nodeHistory - 判断text是否已经被拆分了
|
|
4109
4392
|
if(textArray.length > 0 && textArray[0] != text){ //主要是后面的是否相等,前面的>0只是避免代码报错
|
|
4110
|
-
translate.node.get(
|
|
4393
|
+
translate.node.get(translateNode).whole = false; //已经被拆分了,不是整体翻译了
|
|
4111
4394
|
//这时,也默认给其赋值操作,将自定义术语匹配后的结果进行赋予
|
|
4112
4395
|
}else{
|
|
4113
|
-
translate.node.get(
|
|
4396
|
+
translate.node.get(translateNode).whole = true; //未拆分,是整体翻译
|
|
4114
4397
|
}
|
|
4115
4398
|
//成功加入到 nodeQueue 的对象。 如果长度为0,那就是还没有加入到 translate.nodeQueue 中,可能全被自定义术语命中了
|
|
4116
4399
|
var addQueueObjectArray = [];
|
|
@@ -4151,14 +4434,14 @@ var translate = {
|
|
|
4151
4434
|
// translate.node 记录
|
|
4152
4435
|
|
|
4153
4436
|
// 记录当前有 translate.js 所触发翻译之后渲染到dom界面显示的时间,13位时间戳
|
|
4154
|
-
translate.node.get(
|
|
4437
|
+
translate.node.get(translateNode).lastTranslateRenderTime = Date.now();
|
|
4155
4438
|
//将具体通过文本翻译接口进行翻译的文本记录到 translate.node.data
|
|
4156
|
-
translate.node.get(
|
|
4439
|
+
translate.node.get(translateNode).translateTexts = {}; //这里全部命中了,所以根本没有走翻译接口的文本
|
|
4157
4440
|
//将翻译完成后要显示出的文本进行记录
|
|
4158
|
-
translate.node.get(
|
|
4441
|
+
translate.node.get(translateNode).resultText = translate.element.nodeAnalyse.get(node, attribute).text; //直接获取当前node显示出来的文本作为最后的结果的文本
|
|
4159
4442
|
|
|
4160
4443
|
//将其加入 translate.history.translateTexts 中
|
|
4161
|
-
translate.history.translateText.add(translate.node.get(
|
|
4444
|
+
translate.history.translateText.add(translate.node.get(translateNode).originalText, translate.node.get(translateNode).resultText);
|
|
4162
4445
|
}
|
|
4163
4446
|
|
|
4164
4447
|
},
|
|
@@ -7875,8 +8158,8 @@ var translate = {
|
|
|
7875
8158
|
var hash = translate.util.hash(apiTranslateText[i]);
|
|
7876
8159
|
translate.storage.set('hash_'+to+'_'+hash, resultData.text[i]);
|
|
7877
8160
|
//如果离线翻译启用了全部提取,那么还要存入离线翻译指定存储
|
|
7878
|
-
if(translate.
|
|
7879
|
-
translate.
|
|
8161
|
+
if(translate.offline.fullExtract.isUse){
|
|
8162
|
+
translate.offline.fullExtract.set(hash, apiTranslateText[i], data.to, resultData.text[i]);
|
|
7880
8163
|
}
|
|
7881
8164
|
|
|
7882
8165
|
//进行组合数据到 translateResultArray
|
|
@@ -8341,24 +8624,7 @@ var translate = {
|
|
|
8341
8624
|
config.notTranslateTip = true;
|
|
8342
8625
|
}
|
|
8343
8626
|
|
|
8344
|
-
|
|
8345
|
-
|
|
8346
|
-
var lastUuid = ''; //最后一次的uuid
|
|
8347
|
-
for(var queue in translate.nodeQueue){
|
|
8348
|
-
if (!translate.nodeQueue.hasOwnProperty(queue)) {
|
|
8349
|
-
continue;
|
|
8350
|
-
}
|
|
8351
|
-
lastUuid = queue;
|
|
8352
|
-
}
|
|
8353
|
-
//console.log(queue);
|
|
8354
|
-
|
|
8355
|
-
if(lastUuid == ''){
|
|
8356
|
-
if(config.selectLanguageRefreshRender){
|
|
8357
|
-
translate.log('提示,当前还未执行过翻译,所以 translate.reset(); 还原至翻译前的执行指令忽略');
|
|
8358
|
-
}
|
|
8359
|
-
return;
|
|
8360
|
-
}
|
|
8361
|
-
|
|
8627
|
+
|
|
8362
8628
|
/*
|
|
8363
8629
|
for(var lang in translate.nodeQueue[lastUuid].list){
|
|
8364
8630
|
if (!translate.nodeQueue[lastUuid].list.hasOwnProperty(lang)) {
|
|
@@ -8419,16 +8685,20 @@ var translate = {
|
|
|
8419
8685
|
if (!translate.node.get(key) == null) {
|
|
8420
8686
|
continue;
|
|
8421
8687
|
}
|
|
8422
|
-
for(var attr in translate.node.get(key)){
|
|
8423
|
-
if (!translate.node.get(key).hasOwnProperty(attr)) {
|
|
8424
|
-
|
|
8425
|
-
}
|
|
8426
|
-
|
|
8427
|
-
|
|
8688
|
+
//for(var attr in translate.node.get(key)){
|
|
8689
|
+
//if (!translate.node.get(key).hasOwnProperty(attr)) {
|
|
8690
|
+
// continue;
|
|
8691
|
+
//}
|
|
8692
|
+
|
|
8693
|
+
//var analyse = translate.element.nodeAnalyse.get(key,translate.node.get(key).attribute);
|
|
8694
|
+
if(typeof(translate.node.get(key).originalText) !== 'string'){
|
|
8428
8695
|
continue;
|
|
8429
8696
|
}
|
|
8430
|
-
translate.element.nodeAnalyse.analyse(key, analyse.text, translate.node.get(key)
|
|
8431
|
-
|
|
8697
|
+
//translate.element.nodeAnalyse.analyse(key, analyse.text, translate.node.get(key).originalText, translate.node.get(key).attribute);
|
|
8698
|
+
|
|
8699
|
+
//标注此次改动是有 translate.js 导致的 -- 这里就不用标记了,因为先已经移除了 translate.listener.observer 监听,所以不会再监听到还原的操作了
|
|
8700
|
+
key.nodeValue = translate.node.get(key).originalText;
|
|
8701
|
+
//}
|
|
8432
8702
|
}
|
|
8433
8703
|
|
|
8434
8704
|
|
|
@@ -8449,6 +8719,15 @@ var translate = {
|
|
|
8449
8719
|
translate.storage.set('to', '');
|
|
8450
8720
|
translate.to = null;
|
|
8451
8721
|
|
|
8722
|
+
//清除文本翻译记录
|
|
8723
|
+
if(translate.history.translateText.originalMap !== null){
|
|
8724
|
+
translate.history.translateText.originalMap.clear();
|
|
8725
|
+
}
|
|
8726
|
+
if(translate.history.translateText.resultMap !== null){
|
|
8727
|
+
translate.history.translateText.resultMap.clear();
|
|
8728
|
+
}
|
|
8729
|
+
|
|
8730
|
+
|
|
8452
8731
|
//重新绘制 select 选择语言
|
|
8453
8732
|
if(config.selectLanguageRefreshRender){
|
|
8454
8733
|
translate.selectLanguageTag.refreshRender();
|
|
@@ -8677,7 +8956,7 @@ var translate = {
|
|
|
8677
8956
|
if(typeof(translatejsTextElementHidden) == 'undefined' || translatejsTextElementHidden == null){
|
|
8678
8957
|
const style = document.createElement('style');
|
|
8679
8958
|
// 设置 style 元素的文本内容为要添加的 CSS 规则
|
|
8680
|
-
style.textContent = ' .translatejs-text-element-hidden{color: transparent !important; text-shadow: none !important;}';
|
|
8959
|
+
style.textContent = ' .translatejs-text-element-hidden, .translatejs-text-element-hidden[type="text"]::placeholder{color: transparent !important; -webkit-text-fill-color: transparent !important; text-shadow: none !important;} ';
|
|
8681
8960
|
style.id = 'translatejs-text-element-hidden';
|
|
8682
8961
|
// 将 style 元素插入到 head 元素中
|
|
8683
8962
|
document.head.appendChild(style);
|
|
@@ -8698,38 +8977,16 @@ var translate = {
|
|
|
8698
8977
|
if(translate.progress.api.isTip){
|
|
8699
8978
|
//translate.listener.execute.renderStartByApi.push(function(uuid, from, to){
|
|
8700
8979
|
translate.lifecycle.execute.translateNetworkBefore.push(function(data){
|
|
8701
|
-
|
|
8702
|
-
|
|
8703
|
-
|
|
8704
|
-
for(var r = 0; r<data.nodes.length; r++){
|
|
8705
|
-
var node = data.nodes[r];
|
|
8706
|
-
if(typeof(node) == 'undefined' || typeof(node.parentNode) == 'undefined'){
|
|
8707
|
-
continue;
|
|
8708
|
-
}
|
|
8709
|
-
nodes.push(node);
|
|
8710
|
-
}
|
|
8980
|
+
//取出当前变动的node,对应的元素
|
|
8981
|
+
var elements = translate.element.nodeToElement(data.nodes);
|
|
8982
|
+
//console.log(elements)
|
|
8711
8983
|
|
|
8712
8984
|
//隐藏所有node的文本
|
|
8713
|
-
for(var r = 0; r<
|
|
8714
|
-
|
|
8715
|
-
nodes[r].className = nodes[r].className+' translatejs-text-element-hidden';
|
|
8716
|
-
}else{
|
|
8717
|
-
//不是元素,那么就取父级了 -- 这里即使翻译的属性,也要进行,比如 value 的 placeholder
|
|
8718
|
-
var nodeParent = nodes[r].parentNode;
|
|
8719
|
-
if(nodeParent == null){
|
|
8720
|
-
continue;
|
|
8721
|
-
}
|
|
8722
|
-
if(typeof(nodeParent.className) != 'undefined' && nodeParent.className != null && nodeParent.className.indexOf('translatejs-text-element-hidden') > -1){
|
|
8723
|
-
//父有了,那么子就不需要再加了
|
|
8724
|
-
continue;
|
|
8725
|
-
}else{
|
|
8726
|
-
//没有,添加
|
|
8727
|
-
nodeParent.className = nodeParent.className+' translatejs-text-element-hidden';
|
|
8728
|
-
}
|
|
8729
|
-
}
|
|
8985
|
+
for(var r = 0; r<elements.length; r++){
|
|
8986
|
+
elements[r].className = elements[r].className+' translatejs-text-element-hidden';
|
|
8730
8987
|
}
|
|
8731
8988
|
|
|
8732
|
-
var rects = translate.visual.getRects(
|
|
8989
|
+
var rects = translate.visual.getRects(elements);
|
|
8733
8990
|
//console.log(rects)
|
|
8734
8991
|
var rectsOneArray = translate.visual.rectsToOneArray(rects);
|
|
8735
8992
|
|
|
@@ -8743,70 +9000,29 @@ var translate = {
|
|
|
8743
9000
|
|
|
8744
9001
|
var rectLineSplit = translate.visual.filterRectsByLineInterval(rectsOneArray, 2);
|
|
8745
9002
|
for(var r = 0; r<rectLineSplit.length; r++){
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
if(nodeParent == null){
|
|
8752
|
-
continue;
|
|
8753
|
-
}
|
|
8754
|
-
if(typeof(nodeParent.className) != 'undefined' && nodeParent.className != null && nodeParent.className.indexOf('translate_api_in_progress') > -1){
|
|
8755
|
-
//父有了,那么子就不需要再加了
|
|
8756
|
-
continue;
|
|
8757
|
-
}else{
|
|
8758
|
-
//没有,添加
|
|
8759
|
-
nodeParent.className = nodeParent.className+' translate_api_in_progress';
|
|
8760
|
-
}
|
|
8761
|
-
}
|
|
9003
|
+
if(typeof(rectLineSplit[r].node.className) === 'string' && rectLineSplit[r].node.className.indexOf('translate_api_in_progress') > -1){
|
|
9004
|
+
//已经存在了,就不继续加了
|
|
9005
|
+
}else{
|
|
9006
|
+
rectLineSplit[r].node.className = rectLineSplit[r].node.className+' translate_api_in_progress';
|
|
9007
|
+
}
|
|
8762
9008
|
}
|
|
8763
|
-
|
|
8764
9009
|
});
|
|
8765
9010
|
|
|
8766
|
-
translate.
|
|
8767
|
-
|
|
8768
|
-
|
|
8769
|
-
|
|
8770
|
-
|
|
8771
|
-
|
|
8772
|
-
|
|
8773
|
-
|
|
8774
|
-
|
|
8775
|
-
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
var node = translate.nodeQueue[uuid].list[from][hash].nodes[nodeindex].node;
|
|
8779
|
-
|
|
8780
|
-
var operationNode;
|
|
8781
|
-
if(node.nodeType === 1){
|
|
8782
|
-
//是元素
|
|
8783
|
-
operationNode = node;
|
|
8784
|
-
}else{
|
|
8785
|
-
//节点,如 #text
|
|
8786
|
-
operationNode = node.parentNode;
|
|
8787
|
-
if(operationNode == null){
|
|
8788
|
-
continue;
|
|
8789
|
-
}
|
|
8790
|
-
}
|
|
8791
|
-
|
|
8792
|
-
|
|
8793
|
-
|
|
8794
|
-
|
|
8795
|
-
if(typeof(operationNode.className) != 'undefined' && operationNode.className != null){
|
|
8796
|
-
|
|
8797
|
-
if(operationNode.className.indexOf('translatejs-text-element-hidden') > -1){
|
|
8798
|
-
operationNode.className = operationNode.className.replace(/translatejs-text-element-hidden/g, '');
|
|
8799
|
-
}
|
|
8800
|
-
if(operationNode.className.indexOf('translate_api_in_progress') > -1){
|
|
8801
|
-
operationNode.className = operationNode.className.replace(/translate_api_in_progress/g, '');
|
|
8802
|
-
}
|
|
9011
|
+
translate.lifecycle.execute.translateNetworkAfter.push(function(data){
|
|
9012
|
+
//取出当前变动的node,对应的元素
|
|
9013
|
+
var elements = translate.element.nodeToElement(data.nodes);
|
|
9014
|
+
|
|
9015
|
+
for(var r = 0; r<elements.length; r++){
|
|
9016
|
+
if(typeof(elements[r].className) === 'string'){
|
|
9017
|
+
if(elements[r].className.indexOf('translatejs-text-element-hidden') > -1){
|
|
9018
|
+
elements[r].className = elements[r].className.replace(/translatejs-text-element-hidden/g, '');
|
|
9019
|
+
}
|
|
9020
|
+
if(elements[r].className.indexOf('translate_api_in_progress') > -1){
|
|
9021
|
+
elements[r].className = elements[r].className.replace(/translate_api_in_progress/g, '');
|
|
8803
9022
|
}
|
|
8804
|
-
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
|
|
8808
|
-
}
|
|
8809
|
-
}
|
|
9023
|
+
}
|
|
9024
|
+
}
|
|
9025
|
+
|
|
8810
9026
|
|
|
8811
9027
|
});
|
|
8812
9028
|
|
|
@@ -9119,20 +9335,99 @@ var translate = {
|
|
|
9119
9335
|
|
|
9120
9336
|
obj: js对象
|
|
9121
9337
|
formatSupplementaryCharLength: 对这个js对象进行格式化自动补充字符的长度,比如 2、 4
|
|
9338
|
+
|
|
9339
|
+
2025.10.10 优化传入参数
|
|
9340
|
+
obj:{
|
|
9341
|
+
jsObject: 原本的obj参数, 也就是js对象
|
|
9342
|
+
formatSupplementaryCharLength: 对这个js对象进行格式化自动补充字符的长度,比如 2、 4 ,默认不设置则是4
|
|
9343
|
+
functionBodyHandle: 针对值是function函数类型时,可以自定义对函数体的源码进行处理,它是传入 function 类型的,比如:
|
|
9344
|
+
functionBodyHandle: function(functionBody){
|
|
9345
|
+
functionBody = functionBody+'123';
|
|
9346
|
+
return functionBody;
|
|
9347
|
+
}
|
|
9348
|
+
传入值是函数体的string类型的源码内容
|
|
9349
|
+
返回值是修改过后最新的函数体的string类型的源码内容
|
|
9350
|
+
这是 2025.10.10 新增参数,应对layui的 i18n 全自动翻译函数体中的字符串文本
|
|
9351
|
+
}
|
|
9122
9352
|
*/
|
|
9123
9353
|
objToString:function(obj, formatSupplementaryCharLength){
|
|
9354
|
+
if(typeof(obj) === 'object'){
|
|
9355
|
+
if(typeof(obj.jsObject) === 'object'){
|
|
9356
|
+
//是 2025.10.10 以后的新版本
|
|
9357
|
+
}else{
|
|
9358
|
+
//是 2025.10.10 以前的旧版本
|
|
9359
|
+
var newObj = {
|
|
9360
|
+
jsObject: obj
|
|
9361
|
+
}
|
|
9362
|
+
obj = newObj;
|
|
9363
|
+
}
|
|
9364
|
+
}else{
|
|
9365
|
+
obj = {};
|
|
9366
|
+
}
|
|
9367
|
+
if(typeof(formatSupplementaryCharLength) === 'number'){
|
|
9368
|
+
obj.formatSupplementaryCharLength = formatSupplementaryCharLength;
|
|
9369
|
+
}
|
|
9370
|
+
//未设置,就赋予默认值4
|
|
9371
|
+
if(typeof(obj.formatSupplementaryCharLength) !== 'number'){
|
|
9372
|
+
obj.formatSupplementaryCharLength = 4;
|
|
9373
|
+
}
|
|
9374
|
+
|
|
9124
9375
|
// 自定义replacer函数,将函数转换为字符串
|
|
9125
|
-
|
|
9376
|
+
let jsonStr = JSON.stringify(obj.jsObject, (key, value) => {
|
|
9126
9377
|
if (typeof value === 'function') {
|
|
9127
9378
|
// 将函数转换为其源代码字符串
|
|
9128
|
-
|
|
9379
|
+
var funcString = value.toString();
|
|
9380
|
+
if(typeof(funcString) === 'string' && funcString.length > 0){
|
|
9381
|
+
funcString = funcString.replace(/\n/g, '___TRANSLATEJS_LINE_BREAK___');
|
|
9382
|
+
}
|
|
9383
|
+
return funcString;
|
|
9384
|
+
}else{
|
|
9385
|
+
return value;
|
|
9129
9386
|
}
|
|
9130
|
-
return value;
|
|
9131
|
-
}, formatSupplementaryCharLength);
|
|
9132
9387
|
|
|
9133
|
-
|
|
9134
|
-
|
|
9135
|
-
|
|
9388
|
+
return result;
|
|
9389
|
+
}, obj.formatSupplementaryCharLength);
|
|
9390
|
+
|
|
9391
|
+
|
|
9392
|
+
//对 function 的函数体进行处理
|
|
9393
|
+
// 将转义的\n替换为实际的换行符 -- 20251009 优化,去掉换行符替换,layui 工具中发现这样会将原本文本中的换行符替换掉,而是调整为仅仅针对function方法进行针对替换
|
|
9394
|
+
// 逐行判断,判断其中哪一行的value是function,要将function的字符串格式变为function函数格式
|
|
9395
|
+
if(jsonStr.indexOf('___TRANSLATEJS_LINE_BREAK___') > -1){
|
|
9396
|
+
const lines = jsonStr.split('\n');
|
|
9397
|
+
for(var li = 0; li<lines.length; li++){
|
|
9398
|
+
// 检查当前行是否包含特定标记
|
|
9399
|
+
if (lines[li].includes('___TRANSLATEJS_LINE_BREAK___')) {
|
|
9400
|
+
lines[li] = lines[li].replace(/___TRANSLATEJS_LINE_BREAK___/g, '\n'); //将其替换为原本的换行符
|
|
9401
|
+
|
|
9402
|
+
// 查找值部分(假设格式是 "key": "function...")
|
|
9403
|
+
const valueMatch = lines[li].match(/"[^"]+":\s*"([^"]+)"/);
|
|
9404
|
+
if (valueMatch && valueMatch[1]) {
|
|
9405
|
+
// 替换换行标记为实际换行
|
|
9406
|
+
let functionStr = valueMatch[1].replace(/___TRANSLATEJS_LINE_BREAK___/g, '\n');
|
|
9407
|
+
|
|
9408
|
+
// 将函数字符串转换为实际函数
|
|
9409
|
+
try {
|
|
9410
|
+
// 使用Function构造函数创建函数更安全一些
|
|
9411
|
+
const functionParts = functionStr.match(/function\s*([^\(]*)\(([^)]*)\)\s*\{([\s\S]*)\}/);
|
|
9412
|
+
|
|
9413
|
+
if (functionParts) {
|
|
9414
|
+
var [, name, params, body] = functionParts;
|
|
9415
|
+
if(typeof(obj.functionBodyHandle) === 'function'){
|
|
9416
|
+
body = obj.functionBodyHandle(body);
|
|
9417
|
+
}
|
|
9418
|
+
// 替换原行中的字符串为函数表达式
|
|
9419
|
+
lines[li] = lines[li].replace(`"${valueMatch[1]}"`, `function${name}(${params}){${body}}`);
|
|
9420
|
+
}
|
|
9421
|
+
} catch (e) {
|
|
9422
|
+
console.error('转换函数时出错:', e);
|
|
9423
|
+
}
|
|
9424
|
+
}
|
|
9425
|
+
}
|
|
9426
|
+
}
|
|
9427
|
+
jsonStr = lines.join('\n');
|
|
9428
|
+
}
|
|
9429
|
+
|
|
9430
|
+
return jsonStr;
|
|
9136
9431
|
}
|
|
9137
9432
|
},
|
|
9138
9433
|
/*js dispose end*/
|
|
@@ -10455,13 +10750,11 @@ var translate = {
|
|
|
10455
10750
|
});
|
|
10456
10751
|
//将其记录到 translate.node.data
|
|
10457
10752
|
translate.node.set(textNode,{
|
|
10458
|
-
|
|
10459
|
-
|
|
10460
|
-
|
|
10461
|
-
|
|
10462
|
-
|
|
10463
|
-
whole: true
|
|
10464
|
-
},
|
|
10753
|
+
attribute:"",
|
|
10754
|
+
originalText: originalText,
|
|
10755
|
+
resultText: text,
|
|
10756
|
+
translateTexts: {}, //这里因为直接从缓存中取的,没有走网络接口,所以这里直接空
|
|
10757
|
+
whole: true,
|
|
10465
10758
|
translateResults: {
|
|
10466
10759
|
[originalText]:1
|
|
10467
10760
|
},
|
|
@@ -10743,7 +11036,7 @@ var nodeuuid = {
|
|
|
10743
11036
|
//延迟触发,方便拦截自定义
|
|
10744
11037
|
setTimeout(function(){
|
|
10745
11038
|
translate.log('------ translate.js ------\nTwo 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 \n两行js实现html全自动翻译。 无需改动页面、无语言配置文件、无API Key、对SEO友好!完全开源,代码仓库:https://gitee.com/mail_osc/translate');
|
|
10746
|
-
},
|
|
11039
|
+
}, 3000);
|
|
10747
11040
|
/*js copyright-notice end*/
|
|
10748
11041
|
|
|
10749
11042
|
//初始化
|