i18n-jsautotranslate 3.17.0 → 3.18.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/README.md +94 -92
- package/index.js +589 -173
- package/package.json +1 -1
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.
|
|
17
|
+
version: '3.18.0.20250816',
|
|
18
18
|
// AUTO_VERSION_END
|
|
19
19
|
/*
|
|
20
20
|
当前使用的版本,默认使用v2. 可使用 setUseVersion2();
|
|
@@ -178,18 +178,20 @@ var translate = {
|
|
|
178
178
|
|
|
179
179
|
//从服务器加载支持的语言库
|
|
180
180
|
if(typeof(translate.request.api.language) == 'string' && translate.request.api.language.length > 0){
|
|
181
|
+
//从接口加载语种
|
|
181
182
|
translate.request.post(translate.request.api.language, {}, function(data){
|
|
182
183
|
if(data.result == 0){
|
|
183
184
|
console.log('load language list error : '+data.info);
|
|
184
185
|
return;
|
|
185
186
|
}
|
|
186
|
-
|
|
187
|
+
//console.log(data.list);
|
|
187
188
|
translate.selectLanguageTag.customUI(data.list);
|
|
188
189
|
}, null);
|
|
190
|
+
}else if(typeof(translate.request.api.language) == 'object'){
|
|
191
|
+
//无网络环境下,自定义显示语种
|
|
192
|
+
translate.selectLanguageTag.customUI(translate.request.api.language);
|
|
189
193
|
}
|
|
190
194
|
|
|
191
|
-
|
|
192
|
-
|
|
193
195
|
}
|
|
194
196
|
},
|
|
195
197
|
|
|
@@ -365,7 +367,10 @@ var translate = {
|
|
|
365
367
|
if(window.self !== window.top){
|
|
366
368
|
if(typeof(window.parent.translate) == 'object' && typeof(window.parent.translate.version) == 'string'){
|
|
367
369
|
//iframe页面中存在 translate,那么也控制iframe中的进行翻译
|
|
368
|
-
window.parent.translate.
|
|
370
|
+
if(window.parent.translate.language.getCurrent() != languageName){
|
|
371
|
+
//如果父页面当前的语种不是需要翻译的语种,对其进行翻译
|
|
372
|
+
window.parent.translate.changeLanguage(languageName);
|
|
373
|
+
}
|
|
369
374
|
}
|
|
370
375
|
}
|
|
371
376
|
}catch(e){
|
|
@@ -403,7 +408,9 @@ var translate = {
|
|
|
403
408
|
|
|
404
409
|
//当用户代码设置里启用了 translate.listener.start() 然后用户加载页面后并没有翻译(这时listener是不启动的只是把listener.use标记为true),然后手动点击翻译按钮翻译为其他语种(这是不会刷新页面),翻译后也要跟着启动监听
|
|
405
410
|
if(translate.listener.use == true && translate.listener.isStart == false){
|
|
406
|
-
translate.listener.start
|
|
411
|
+
if(typeof(translate.listener.start) != 'undefined'){
|
|
412
|
+
translate.listener.start();
|
|
413
|
+
}
|
|
407
414
|
}
|
|
408
415
|
},
|
|
409
416
|
|
|
@@ -549,7 +556,9 @@ var translate = {
|
|
|
549
556
|
throw new Error('第' + i + '项不是RegExp对象');
|
|
550
557
|
}
|
|
551
558
|
}
|
|
552
|
-
this.textRegex = [...this.textRegex, ...arr];
|
|
559
|
+
//this.textRegex = [...this.textRegex, ...arr];
|
|
560
|
+
//改为兼容 es5 的方式,提供更多兼容
|
|
561
|
+
this.textRegex = this.textRegex.concat(arr);
|
|
553
562
|
},
|
|
554
563
|
},
|
|
555
564
|
//刷新页面,你可以自定义刷新页面的方式,比如在 uniapp 打包生成 apk 时,apk中的刷新页面就不是h5的这个刷新,而是app的刷新方式,就需要自己进行重写这个刷新页面的方法了
|
|
@@ -1213,11 +1222,10 @@ var translate = {
|
|
|
1213
1222
|
}
|
|
1214
1223
|
//console.log('translateNodeslength: '+translateNodes.length);
|
|
1215
1224
|
|
|
1216
|
-
|
|
1217
|
-
setTimeout(function() {
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
}, 10); //这个要比 task.execute() 中的 settimeout 延迟执行删除 translate.inpr.....nodes 的时间要小,目的是前一个发生变动后,记入 inpr...nodes 然后翻译完成后节点发生变化又触发了listener,此时 inpr....nodes 还有,那么这个变化将不做处理,然后 inp.....nodes 再删除这个标记
|
|
1225
|
+
translate.execute(translateNodes);
|
|
1226
|
+
//setTimeout(function() {
|
|
1227
|
+
// translate.execute(translateNodes); //指定要翻译的元素的集合,可传入一个或多个元素。如果不设置,默认翻译整个网页
|
|
1228
|
+
//}, 10); //这个要比 task.execute() 中的 settimeout 延迟执行删除 translate.inpr.....nodes 的时间要小,目的是前一个发生变动后,记入 inpr...nodes 然后翻译完成后节点发生变化又触发了listener,此时 inpr....nodes 还有,那么这个变化将不做处理,然后 inp.....nodes 再删除这个标记
|
|
1221
1229
|
}
|
|
1222
1230
|
};
|
|
1223
1231
|
// 创建一个观察器实例并传入回调函数
|
|
@@ -1646,15 +1654,33 @@ var translate = {
|
|
|
1646
1654
|
executeNumber:0,
|
|
1647
1655
|
|
|
1648
1656
|
lifecycle:{
|
|
1657
|
+
|
|
1658
|
+
/*
|
|
1659
|
+
translate.execute() 执行相关
|
|
1660
|
+
*/
|
|
1649
1661
|
execute:{
|
|
1650
1662
|
/*
|
|
1651
|
-
每当触发执行 translate.execute()
|
|
1652
|
-
|
|
1663
|
+
每当触发执行 translate.execute() 时,会先进行当前是否可以正常进行翻译的判定,比如 当前语种是否就已经是翻译之后的语种了是否没必要翻译了等。(这些初始判定可以理解成它的耗时小于1毫秒,几乎没有耗时)
|
|
1664
|
+
经过初始的判断后,发现允许被翻译,那么在向后执行之前,先触发此。
|
|
1665
|
+
也就是在进行翻译之前,触发此。
|
|
1666
|
+
|
|
1653
1667
|
@param uuid:translate.nodeQueue[uuid] 这里的
|
|
1654
|
-
@param from 来源语种,翻译前的语种
|
|
1655
1668
|
@param to 翻译为的语种
|
|
1656
1669
|
*/
|
|
1657
1670
|
start : [],
|
|
1671
|
+
start_Trigger:function(uuid, to){
|
|
1672
|
+
for(var i = 0; i < translate.lifecycle.execute.start.length; i++){
|
|
1673
|
+
try{
|
|
1674
|
+
translate.lifecycle.execute.start[i](uuid, to);
|
|
1675
|
+
}catch(e){
|
|
1676
|
+
console.log(e);
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
},
|
|
1680
|
+
|
|
1681
|
+
|
|
1682
|
+
//待整理
|
|
1683
|
+
start_old : [],
|
|
1658
1684
|
startRun:function(uuid, from, to){
|
|
1659
1685
|
//console.log(translate.nodeQueue[uuid]);
|
|
1660
1686
|
for(var i = 0; i < translate.listener.execute.renderStartByApi.length; i++){
|
|
@@ -1668,20 +1694,40 @@ var translate = {
|
|
|
1668
1694
|
|
|
1669
1695
|
/*
|
|
1670
1696
|
当扫描整个节点完成,进行翻译(1. 命中本地缓存、 2.进行网络翻译请求)之前,触发
|
|
1697
|
+
待整理
|
|
1671
1698
|
*/
|
|
1672
1699
|
scanNodesFinsh: [],
|
|
1673
1700
|
|
|
1701
|
+
|
|
1674
1702
|
/*
|
|
1675
|
-
|
|
1676
|
-
|
|
1703
|
+
每当触发执行 translate.execute() 时,当缓存中未发现,需要请求翻译API进行翻译时,在发送API请求前,触发此
|
|
1704
|
+
|
|
1705
|
+
@param uuid:translate.nodeQueue[uuid] 这里的
|
|
1706
|
+
@param from 来源语种,翻译前的语种
|
|
1707
|
+
@param to 翻译为的语种
|
|
1708
|
+
@param texts 要翻译的文本,它是一个数组形态,是要进行通过API翻译接口进行翻译的文本,格式如 ['你好','世界']
|
|
1709
|
+
*/
|
|
1677
1710
|
translateNetworkBefore:[],
|
|
1711
|
+
translateNetworkBefore_Trigger:function(uuid, from, to, texts){
|
|
1712
|
+
for(var i = 0; i < translate.lifecycle.execute.translateNetworkBefore.length; i++){
|
|
1713
|
+
try{
|
|
1714
|
+
translate.lifecycle.execute.translateNetworkBefore[i](uuid,from, to, texts);
|
|
1715
|
+
}catch(e){
|
|
1716
|
+
console.log(e);
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
},
|
|
1678
1720
|
|
|
1679
1721
|
/*
|
|
1680
1722
|
当 translate.execute() 触发网络翻译请求完毕(不管成功还是失败),并将翻译结果渲染到页面完毕后,触发此。
|
|
1681
1723
|
@param uuid translate.nodeQueue 的uuid
|
|
1724
|
+
@param from
|
|
1682
1725
|
@param to 当前是执行的翻译为什么语种
|
|
1726
|
+
@param text 网络请求翻译的文本/节点/。。。待定
|
|
1683
1727
|
*/
|
|
1684
|
-
|
|
1728
|
+
translateNetworkAfter:[], //已废弃
|
|
1729
|
+
/*
|
|
1730
|
+
|
|
1685
1731
|
translateNetworkAfter_Trigger:function(uuid, to){
|
|
1686
1732
|
for(var i = 0; i < translate.lifecycle.execute.translateNetworkAfter.length; i++){
|
|
1687
1733
|
try{
|
|
@@ -1691,6 +1737,7 @@ var translate = {
|
|
|
1691
1737
|
}
|
|
1692
1738
|
}
|
|
1693
1739
|
},
|
|
1740
|
+
*/
|
|
1694
1741
|
|
|
1695
1742
|
/*
|
|
1696
1743
|
translate.execute() 的翻译渲染完毕触发
|
|
@@ -1700,7 +1747,9 @@ var translate = {
|
|
|
1700
1747
|
@param to 当前是执行的翻译为什么语种
|
|
1701
1748
|
*/
|
|
1702
1749
|
renderFinish:[function(uuid, to){ //这里默认带着一个触发翻译为英文后,自动对英文进行元素视觉处理,追加空格的
|
|
1703
|
-
translate.visual
|
|
1750
|
+
if(typeof(translate.visual) != 'undefined'){
|
|
1751
|
+
translate.visual.adjustTranslationSpacesByNodequeueUuid(uuid);
|
|
1752
|
+
}
|
|
1704
1753
|
}],
|
|
1705
1754
|
renderFinish_Trigger:function(uuid, to){
|
|
1706
1755
|
for(var i = 0; i < translate.lifecycle.execute.renderFinish.length; i++){
|
|
@@ -1788,11 +1837,11 @@ var translate = {
|
|
|
1788
1837
|
//未指定,判断如果指定了自动获取用户本国语种了,那么进行获取
|
|
1789
1838
|
if(translate.autoDiscriminateLocalLanguage){
|
|
1790
1839
|
translate.executeByLocalLanguage();
|
|
1840
|
+
}else{
|
|
1841
|
+
//没有指定翻译目标语言、又没自动获取用户本国语种,则不翻译
|
|
1842
|
+
translate.state = 0;
|
|
1843
|
+
return;
|
|
1791
1844
|
}
|
|
1792
|
-
|
|
1793
|
-
//没有指定翻译目标语言、又没自动获取用户本国语种,则不翻译
|
|
1794
|
-
translate.state = 0;
|
|
1795
|
-
return;
|
|
1796
1845
|
}
|
|
1797
1846
|
|
|
1798
1847
|
//判断本地语种跟要翻译的目标语种是否一样,如果是一样,那就不需要进行任何翻译
|
|
@@ -1808,6 +1857,10 @@ var translate = {
|
|
|
1808
1857
|
|
|
1809
1858
|
|
|
1810
1859
|
/********** 翻译进行 */
|
|
1860
|
+
|
|
1861
|
+
//生命周期-触发翻译进行之前,用户自定义的钩子
|
|
1862
|
+
translate.lifecycle.execute.start_Trigger(uuid, translate.to);
|
|
1863
|
+
|
|
1811
1864
|
|
|
1812
1865
|
//先进行图片的翻译替换,毕竟图片还有加载的过程
|
|
1813
1866
|
translate.images.execute();
|
|
@@ -1853,6 +1906,27 @@ var translate = {
|
|
|
1853
1906
|
console.log('translate.execute( docs ) 传入的docs.length 过大,超过500,这很不正常,当前 docs.length : '+all.length+' ,如果你感觉真的没问题,请联系作者 http://translate.zvo.cn/43006.html 说明情况,根据你的情况进行分析。 当前只取前500个元素进行翻译');
|
|
1854
1907
|
}
|
|
1855
1908
|
|
|
1909
|
+
//初始化 translate.element.tagAttribute ,主要针对 v3.17.10 版本的适配调整,对 translate.element.tagAttribute 的设置做了改变,做旧版本的适配
|
|
1910
|
+
try{
|
|
1911
|
+
for(var te_tag in translate.element.tagAttribute){
|
|
1912
|
+
if (!translate.element.tagAttribute.hasOwnProperty(te_tag)) {
|
|
1913
|
+
continue;
|
|
1914
|
+
}
|
|
1915
|
+
if(translate.element.tagAttribute[te_tag] instanceof Array){
|
|
1916
|
+
//是 v3.17.10 之前版本的设置方式,要进行对旧版本的适配
|
|
1917
|
+
var tArray = translate.element.tagAttribute[te_tag];
|
|
1918
|
+
translate.element.tagAttribute[te_tag] = {
|
|
1919
|
+
attribute: tArray,
|
|
1920
|
+
condition: function(element){
|
|
1921
|
+
return true;
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
}catch(e){
|
|
1927
|
+
console.log(e);
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1856
1930
|
//检索目标内的node元素
|
|
1857
1931
|
for(var i = 0; i< all.length & i < 500; i++){
|
|
1858
1932
|
var node = all[i];
|
|
@@ -2134,6 +2208,19 @@ var translate = {
|
|
|
2134
2208
|
//console.log('cacheScanNodes:');
|
|
2135
2209
|
//console.log(cacheScanNodes);
|
|
2136
2210
|
|
|
2211
|
+
|
|
2212
|
+
if(typeof(translate.request.api.translate) != 'string' || translate.request.api.translate == null || translate.request.api.translate.length < 1){
|
|
2213
|
+
//用户已经设置了不掉翻译接口进行翻译
|
|
2214
|
+
translate.state = 0;
|
|
2215
|
+
|
|
2216
|
+
//生命周期触发事件
|
|
2217
|
+
translate.lifecycle.execute.renderFinish_Trigger(uuid, translate.to);
|
|
2218
|
+
translate.executeNumber++;
|
|
2219
|
+
return;
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
|
|
2223
|
+
|
|
2137
2224
|
/******* 进行第二次扫描、追加入翻译队列。目的是防止缓存打散扫描的待翻译文本 ********/
|
|
2138
2225
|
for(var lang in twoScanNodes){
|
|
2139
2226
|
if (!twoScanNodes.hasOwnProperty(lang)) {
|
|
@@ -2360,7 +2447,8 @@ var translate = {
|
|
|
2360
2447
|
|
|
2361
2448
|
//listener
|
|
2362
2449
|
translate.listener.execute.renderStartByApiRun(uuid, lang, translate.to);
|
|
2363
|
-
|
|
2450
|
+
translate.lifecycle.execute.translateNetworkBefore_Trigger(uuid, lang, translate.to, translateTextArray[lang]);
|
|
2451
|
+
|
|
2364
2452
|
/*** 翻译开始 ***/
|
|
2365
2453
|
var url = translate.request.api.translate;
|
|
2366
2454
|
var data = {
|
|
@@ -2538,6 +2626,32 @@ var translate = {
|
|
|
2538
2626
|
有几个要翻译的属性,就写上几个。
|
|
2539
2627
|
同样,有几个要额外翻译的tag,就加上几行。
|
|
2540
2628
|
详细文档参考: http://translate.zvo.cn/231504.html
|
|
2629
|
+
|
|
2630
|
+
|
|
2631
|
+
//针对宁德时代提出的需求,需要对 标签本身进行一个判定,是否符合条件符合条件才会翻译,不符合条件则不要进行翻译
|
|
2632
|
+
//比如标签带有 disabled 的才会被翻译,所以要增加一个自定义入参的 function ,返回 true、false
|
|
2633
|
+
translate.element.tagAttribute['input']={
|
|
2634
|
+
//要被翻译的tag的属性,这里是要翻译 input 的 value 、 data-value 这两个属性。
|
|
2635
|
+
//数组格式,可以一个或多个属性
|
|
2636
|
+
attribute:['value','data-value'],
|
|
2637
|
+
//条件,传入一个function,返回一个布尔值。
|
|
2638
|
+
//只有当返回的布尔值是true时,才会对上面设置的 attribute 进行翻译,否则并不会对当前设定标签的 attribute 进行任何翻译操作。
|
|
2639
|
+
condition:function(element){
|
|
2640
|
+
// element 便是当前的元素,
|
|
2641
|
+
// 比如这里是 translate.element.tagAttribute['input'] 那这个 element 参数便是扫描到的具体的 input 元素
|
|
2642
|
+
// 可以针对 element 这个当前元素本身来进行判定,来决定是否进行翻译。
|
|
2643
|
+
// 返回值是布尔值 true、false
|
|
2644
|
+
// return true; //要对 attribute中设置的 ['value','data-value'] 这两个input 的属性的值进行翻译。
|
|
2645
|
+
// 如果不设置或传入 condition ,比如单纯这样设置:
|
|
2646
|
+
// translate.element.tagAttribute['input']={
|
|
2647
|
+
// attribute:['value','data-value']
|
|
2648
|
+
// }
|
|
2649
|
+
// 那么这里默认就是 return true;
|
|
2650
|
+
// return false; //不对 attribute中设置的 ['value','data-value'] 这两个input 的属性的值进行任何操作
|
|
2651
|
+
return true;
|
|
2652
|
+
}
|
|
2653
|
+
};
|
|
2654
|
+
|
|
2541
2655
|
*/
|
|
2542
2656
|
tagAttribute : {},
|
|
2543
2657
|
|
|
@@ -2598,14 +2712,29 @@ var translate = {
|
|
|
2598
2712
|
|
|
2599
2713
|
if(attribute != null && typeof(attribute) == 'string' && attribute.length > 0){
|
|
2600
2714
|
//这个node有属性,替换的是node的属性,而不是nodeValue
|
|
2601
|
-
|
|
2715
|
+
|
|
2716
|
+
var nodeAttributeValue; //这个 attribute 属性的值
|
|
2717
|
+
if(nodename == 'INPUT' && attribute.toLowerCase() == 'value'){
|
|
2718
|
+
//如果是input 的value属性,那么要直接获取,而非通过 attribute ,不然用户自己输入的通过 attribute 是获取不到的 -- catl 赵阳 提出
|
|
2719
|
+
|
|
2720
|
+
nodeAttributeValue = node.value;
|
|
2721
|
+
}else{
|
|
2722
|
+
nodeAttributeValue = node[attribute];
|
|
2723
|
+
}
|
|
2724
|
+
result['text'] = nodeAttributeValue;
|
|
2725
|
+
|
|
2602
2726
|
|
|
2603
2727
|
//替换渲染
|
|
2604
2728
|
if(typeof(originalText) != 'undefined' && originalText.length > 0){
|
|
2605
|
-
if(typeof(
|
|
2729
|
+
if(typeof(nodeAttributeValue) != 'undefined'){
|
|
2606
2730
|
//这种是主流框架,像是vue、element、react 都是用这种 DOM Property 的方式,更快
|
|
2607
|
-
var resultShowText = translate.util.textReplace(
|
|
2608
|
-
|
|
2731
|
+
var resultShowText = translate.util.textReplace(nodeAttributeValue, originalText, resultText, translate.to);
|
|
2732
|
+
if(nodename == 'INPUT' && attribute.toLowerCase() == 'value'){
|
|
2733
|
+
//input 的value 对于用户输入的必须用 .value 操作
|
|
2734
|
+
node.value = resultShowText;
|
|
2735
|
+
}else{
|
|
2736
|
+
node[attribute] = resultShowText; //2025.4.26 变更为此方式
|
|
2737
|
+
}
|
|
2609
2738
|
if(resultShowText.indexOf(resultText) > -1){
|
|
2610
2739
|
result['resultText'] = resultShowText;
|
|
2611
2740
|
}else{
|
|
@@ -2843,37 +2972,47 @@ var translate = {
|
|
|
2843
2972
|
//console.log('find:'+nodeNameLowerCase);
|
|
2844
2973
|
//console.log(translate.element.tagAttribute[nodeNameLowerCase]);
|
|
2845
2974
|
|
|
2846
|
-
for(var attributeName_index in translate.element.tagAttribute[nodeNameLowerCase]){
|
|
2847
|
-
if (!translate.element.tagAttribute[nodeNameLowerCase].hasOwnProperty(attributeName_index)) {
|
|
2975
|
+
for(var attributeName_index in translate.element.tagAttribute[nodeNameLowerCase].attribute){
|
|
2976
|
+
if (!translate.element.tagAttribute[nodeNameLowerCase].attribute.hasOwnProperty(attributeName_index)) {
|
|
2977
|
+
continue;
|
|
2978
|
+
}
|
|
2979
|
+
if(typeof(translate.element.tagAttribute[nodeNameLowerCase].condition) !='undefined' && !translate.element.tagAttribute[nodeNameLowerCase].condition(node)){
|
|
2848
2980
|
continue;
|
|
2849
2981
|
}
|
|
2850
2982
|
|
|
2851
|
-
var attributeName = translate.element.tagAttribute[nodeNameLowerCase][attributeName_index];
|
|
2983
|
+
var attributeName = translate.element.tagAttribute[nodeNameLowerCase].attribute[attributeName_index];
|
|
2852
2984
|
//console.log(attributeName);
|
|
2853
2985
|
//console.log(node.getAttribute(attributeName));
|
|
2854
2986
|
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
*/
|
|
2860
|
-
var DOMPropOrHTMLAttr = 'HTMLAtrribute';
|
|
2861
|
-
var attributeValue = node.getAttribute(attributeName);
|
|
2862
|
-
if(typeof(attributeValue) == 'undefined' || attributeValue == null){
|
|
2863
|
-
//vue、element、react 中的一些动态赋值,比如 element 中的 el-select 选中后赋予显示出来的文本,getAttribute 就取不到,因为是改动的 DOM属性,所以要用这种方式才能取出来
|
|
2864
|
-
attributeValue = node[attributeName];
|
|
2987
|
+
|
|
2988
|
+
if(nodeNameLowerCase == 'input' && attributeName.toLowerCase() == 'value'){
|
|
2989
|
+
//如果是input 的value属性,那么要直接获取,而非通过 attribute ,不然用户自己输入的通过 attribute 是获取不到的 - catl 赵阳 提出
|
|
2990
|
+
attributeValue = node.value;
|
|
2865
2991
|
DOMPropOrHTMLAttr = 'DOMProperty';
|
|
2992
|
+
}else{
|
|
2993
|
+
/*
|
|
2994
|
+
* 默认是 HtmlAtrribute 也就是 HTML特性。取值有两个:
|
|
2995
|
+
* HTMLAtrribute : HTML特性
|
|
2996
|
+
* DOMProperty : DOM属性
|
|
2997
|
+
*/
|
|
2998
|
+
var DOMPropOrHTMLAttr = 'HTMLAtrribute';
|
|
2999
|
+
var attributeValue = node.getAttribute(attributeName);
|
|
3000
|
+
if(typeof(attributeValue) == 'undefined' || attributeValue == null){
|
|
3001
|
+
//vue、element、react 中的一些动态赋值,比如 element 中的 el-select 选中后赋予显示出来的文本,getAttribute 就取不到,因为是改动的 DOM属性,所以要用这种方式才能取出来
|
|
3002
|
+
attributeValue = node[attributeName];
|
|
3003
|
+
DOMPropOrHTMLAttr = 'DOMProperty';
|
|
3004
|
+
}
|
|
3005
|
+
if(typeof(attributeValue) == 'undefined' || attributeValue == null){
|
|
3006
|
+
//这个tag标签没有这个属性,忽略
|
|
3007
|
+
continue;
|
|
3008
|
+
}
|
|
2866
3009
|
}
|
|
2867
|
-
|
|
2868
|
-
//这个tag标签没有这个属性,忽略
|
|
2869
|
-
continue;
|
|
2870
|
-
}
|
|
3010
|
+
|
|
2871
3011
|
|
|
2872
3012
|
//if(typeof(node.getAttribute(attributeName)) == 'undefined' && typeof(node[attributeName]) == 'undefined'){
|
|
2873
3013
|
// //这个tag标签没有这个 attribute,忽略
|
|
2874
3014
|
// continue
|
|
2875
3015
|
//}
|
|
2876
|
-
|
|
2877
3016
|
//判断当前元素是否在ignore忽略的tag、id、class name中 v3.15.7 增加
|
|
2878
3017
|
if(!translate.ignore.isIgnore(node)){
|
|
2879
3018
|
//加入翻译
|
|
@@ -2952,6 +3091,7 @@ var translate = {
|
|
|
2952
3091
|
|
|
2953
3092
|
//node分析
|
|
2954
3093
|
var nodeAnaly = translate.element.nodeAnalyse.get(node);
|
|
3094
|
+
//console.log(nodeAnaly)
|
|
2955
3095
|
if(nodeAnaly['text'].length > 0){
|
|
2956
3096
|
//有要翻译的目标内容,加入翻译队列
|
|
2957
3097
|
//console.log('addNodeToQueue -- '+nodeAnaly['node']+', text:' + nodeAnaly['text']);
|
|
@@ -3608,11 +3748,10 @@ var translate = {
|
|
|
3608
3748
|
language:{
|
|
3609
3749
|
/*
|
|
3610
3750
|
英语的变种语种,也就是在英语26个字母的基础上加了点别的特殊字母另成的一种语言,而这些语言是没法直接通过识别字符来判断出是哪种语种的
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
法语、意大利语、德语
|
|
3751
|
+
|
|
3752
|
+
法语、意大利语、德语、葡萄牙语
|
|
3614
3753
|
*/
|
|
3615
|
-
englishVarietys : ['french','italian','deutsch'],
|
|
3754
|
+
englishVarietys : ['french','italian','deutsch', 'portuguese'],
|
|
3616
3755
|
|
|
3617
3756
|
//当前本地语种,本地语言,默认是简体中文。设置请使用 translate.language.setLocal(...)。不可直接使用,使用需用 getLocal()
|
|
3618
3757
|
local:'',
|
|
@@ -3674,6 +3813,14 @@ var translate = {
|
|
|
3674
3813
|
清除历史翻译语种的缓存
|
|
3675
3814
|
*/
|
|
3676
3815
|
clearCacheLanguage:function(){
|
|
3816
|
+
if(typeof(translate.language.setUrlParamControl_use) != 'undefined'){
|
|
3817
|
+
if(translate.language.setUrlParamControl_use){
|
|
3818
|
+
console.log('使用提示:')
|
|
3819
|
+
console.log('translate.language.setUrlParamControl(...) 的作用是 可以通过URL传一个语种,来指定当前页面以什么语种显示。 参考文档: http://translate.zvo.cn/4075.html');
|
|
3820
|
+
console.log('translate.language.clearCacheLanguage() 是清除历史翻译语种缓存,也就是清除之前指定翻译为什么语种。 参考文档:http://translate.zvo.cn/4080.html')
|
|
3821
|
+
console.log('如果你执行了 translate.language.setUrlParamControl(...) 那么是要根据url传参来切换语种的,但是后面又出现了 translate.language.clearCacheLanguage() 它会阻止 translate.language.setUrlParamControl(...) 它的设置,即使有url传递翻译为什么语言,也会因为 translate.language.clearCacheLanguage() 给清除掉,使URL传参的语种不起任何作用。')
|
|
3822
|
+
}
|
|
3823
|
+
}
|
|
3677
3824
|
translate.to = '';
|
|
3678
3825
|
translate.storage.set('to','');
|
|
3679
3826
|
},
|
|
@@ -3681,6 +3828,7 @@ var translate = {
|
|
|
3681
3828
|
//设置可以根据当前访问url的某个get参数来控制使用哪种语言显示。
|
|
3682
3829
|
//比如当前语种是简体中文,网页url是http://translate.zvo.cn/index.html ,那么可以通过在url后面增加 language 参数指定翻译语种,来使网页内容以英文形态显示 http://translate.zvo.cn/index.html?language=english
|
|
3683
3830
|
setUrlParamControl:function(paramName){
|
|
3831
|
+
translate.language.setUrlParamControl_use = true; //标记已执行了 translate.language.setUrlParamControl ,仅仅只是标记,无其他作用
|
|
3684
3832
|
if(typeof(paramName) == 'undefined' || paramName.length < 1){
|
|
3685
3833
|
paramName = 'language';
|
|
3686
3834
|
}
|
|
@@ -3695,36 +3843,85 @@ var translate = {
|
|
|
3695
3843
|
translate.storage.set('to', paramValue);
|
|
3696
3844
|
translate.to = paramValue;
|
|
3697
3845
|
},
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3846
|
+
/*
|
|
3847
|
+
获取翻译区域的原始文本,翻译前的文本。 这里会把空白符等过滤掉,只返回纯显示的文本
|
|
3848
|
+
也就是获取 translate.setDocument(...) 定义的翻译区域中,翻译前,要参与翻译的文本。
|
|
3849
|
+
其中像是 translate.ignore.tag 这种忽略翻译的标签,这里也不会获取的,这里只是获取实际要参与翻译的文本。
|
|
3850
|
+
*/
|
|
3851
|
+
getTranslateAreaText:function(){
|
|
3705
3852
|
//v3.16.1 优化,获取本地语种,针对开源中国只对 readme 部分进行翻译的场景,将针对设置的 translate.setDocument() 区域的元素的显示文本进行判定语种
|
|
3706
3853
|
var translateAreaText = ''; //翻译区域内当前的文本
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3854
|
+
|
|
3855
|
+
/** 构建虚拟容器,将要翻译的区域放入虚拟容器,以便后续处理 **/
|
|
3856
|
+
var virtualContainer = document.createElement('div'); // 创建虚拟容器,处理、判断也都是针对这个虚拟容器
|
|
3857
|
+
if(translate.documents != null && typeof(translate.documents) != 'undefined' && translate.documents.length > 0){
|
|
3858
|
+
// setDocuments 指定的
|
|
3859
|
+
for(var docs_index = 0; docs_index < translate.documents.length; docs_index++){
|
|
3860
|
+
var doc = translate.documents[docs_index];
|
|
3861
|
+
if(typeof(doc) != 'undefined' && doc != null && typeof(doc.innerText) != 'undefined' && doc.innerText != null && doc.innerText.length > 0){
|
|
3862
|
+
virtualContainer.appendChild(doc.cloneNode(true));
|
|
3863
|
+
}
|
|
3712
3864
|
}
|
|
3713
|
-
}
|
|
3865
|
+
}else{
|
|
3866
|
+
//未使用 setDocuments指定,那就是整个网页了
|
|
3867
|
+
//return document.all; //翻译所有的 这是 v3.5.0之前的
|
|
3868
|
+
//v3.5.0 之后采用 拿 html的最上层的demo,而不是 document.all 拿到可能几千个dom
|
|
3869
|
+
if(typeof(document.head) != 'undefined'){
|
|
3870
|
+
virtualContainer.appendChild(document.head.cloneNode(true));
|
|
3871
|
+
}
|
|
3872
|
+
if(typeof(document.body) != 'undefined'){
|
|
3873
|
+
virtualContainer.appendChild(document.body.cloneNode(true));
|
|
3874
|
+
}
|
|
3875
|
+
}
|
|
3876
|
+
//console.log(virtualContainer);
|
|
3877
|
+
|
|
3878
|
+
|
|
3879
|
+
/** 对虚拟容器中的元素进行处理,移除忽略的 tag (这里暂时就只是移除忽略的tag, 其他忽略的后续再加) **/
|
|
3880
|
+
// 遍历标签列表
|
|
3881
|
+
//console.log('---- remove element');
|
|
3882
|
+
for (var i = 0; i < translate.ignore.tag.length; i++) {
|
|
3883
|
+
var tagName = translate.ignore.tag[i];
|
|
3884
|
+
var elements = virtualContainer.querySelectorAll(tagName);
|
|
3885
|
+
// 将 NodeList 转换为数组
|
|
3886
|
+
var elementArray = Array.prototype.slice.call(elements);
|
|
3887
|
+
// 遍历并移除每个匹配的元素
|
|
3888
|
+
for (var j = 0; j < elementArray.length; j++) {
|
|
3889
|
+
var element = elementArray[j];
|
|
3890
|
+
if (element.parentNode) {
|
|
3891
|
+
//console.log(element);
|
|
3892
|
+
element.parentNode.removeChild(element);
|
|
3893
|
+
}
|
|
3894
|
+
}
|
|
3895
|
+
}
|
|
3896
|
+
//console.log('---- remove element end');
|
|
3714
3897
|
|
|
3715
|
-
|
|
3716
|
-
|
|
3898
|
+
|
|
3899
|
+
/*** 取过滤完后的文本字符 ***/
|
|
3900
|
+
translateAreaText = virtualContainer.innerText;
|
|
3717
3901
|
if(translateAreaText == null || typeof(translateAreaText) == 'undefined' || translateAreaText.length < 1){
|
|
3718
3902
|
//未取到,默认赋予简体中文
|
|
3719
3903
|
translate.language.local = 'chinese_simplified';
|
|
3720
3904
|
return;
|
|
3721
3905
|
}
|
|
3906
|
+
// 移除所有空白字符(包括空格、制表符、换行符等)
|
|
3907
|
+
translateAreaText = translateAreaText.replace(/\s/g, '');
|
|
3722
3908
|
|
|
3723
|
-
|
|
3909
|
+
//console.log('translateAreaText:\n'+translateAreaText);
|
|
3910
|
+
return translateAreaText;
|
|
3911
|
+
},
|
|
3912
|
+
//自动识别当前页面是什么语种
|
|
3913
|
+
autoRecognitionLocalLanguage:function(){
|
|
3914
|
+
if(translate.language.local != null && translate.language.local.length > 2){
|
|
3915
|
+
//已设置过了,不需要再设置
|
|
3916
|
+
return translate.language.local;
|
|
3917
|
+
}
|
|
3918
|
+
|
|
3919
|
+
var translateAreaText = translate.language.getTranslateAreaText();
|
|
3724
3920
|
|
|
3725
3921
|
//默认赋予简体中文
|
|
3726
3922
|
translate.language.local = 'chinese_simplified';
|
|
3727
3923
|
var recognition = translate.language.recognition(translateAreaText);
|
|
3924
|
+
//console.log(recognition);
|
|
3728
3925
|
translate.language.local = recognition.languageName;
|
|
3729
3926
|
return translate.language.local;
|
|
3730
3927
|
/* v3.1优化
|
|
@@ -3874,6 +4071,109 @@ var translate = {
|
|
|
3874
4071
|
//console.log('get end');
|
|
3875
4072
|
return langStrs;
|
|
3876
4073
|
},
|
|
4074
|
+
/*
|
|
4075
|
+
语种识别策略
|
|
4076
|
+
|
|
4077
|
+
str 要识别的字符串
|
|
4078
|
+
data 对于str字符串识别的结果,格式如:
|
|
4079
|
+
{
|
|
4080
|
+
languageName: 'english',
|
|
4081
|
+
languageArray:[
|
|
4082
|
+
english:[
|
|
4083
|
+
list[
|
|
4084
|
+
{beforeText: ' ', afterText: ' ', text: 'hello word'},
|
|
4085
|
+
{beforeText: ' ', afterText: ' ', text: 'who?'},
|
|
4086
|
+
],
|
|
4087
|
+
number:12
|
|
4088
|
+
],
|
|
4089
|
+
japanese:[
|
|
4090
|
+
......
|
|
4091
|
+
]
|
|
4092
|
+
]
|
|
4093
|
+
}
|
|
4094
|
+
有关这里面具体参数的说明,参考 translate.language.recognition 的说明
|
|
4095
|
+
languagesSize key:语言名, value:语言字符数
|
|
4096
|
+
allSize 当前所有发现的语种,加起来的总字符数,也就是 languagesSize 遍历所有的value相加的数
|
|
4097
|
+
|
|
4098
|
+
最后,要 return data;
|
|
4099
|
+
*/
|
|
4100
|
+
recognitionAlgorithm:function(str, data, languagesSize, allSize){
|
|
4101
|
+
|
|
4102
|
+
/*
|
|
4103
|
+
如果英语跟罗曼语族(法语意大利语等多个语言)一起出现,且当前 data.languageName 认定是英语(也就是英文字符占比最大),那么要判定一下:
|
|
4104
|
+
如果 罗曼语族的字符数/英文的字符数 > 0.008 , 那么认为当前是罗曼语族的中的某个语种, 在对其判定出具体是罗曼语族中的哪个语种赋予最终结果。
|
|
4105
|
+
*/
|
|
4106
|
+
if(typeof(languagesSize['english']) != 'undefined' && typeof(languagesSize['romance']) != 'undefined' && data.languageName == 'english'){
|
|
4107
|
+
if(languagesSize['romance']/languagesSize['english'] > 0.008){
|
|
4108
|
+
//排定是罗曼语族了,那么判断一下到底是 法语、西班牙语、葡萄牙语、意大利语 中的哪一种呢
|
|
4109
|
+
|
|
4110
|
+
//先判定是否有设置本地语种是罗曼语族中其中的某一个
|
|
4111
|
+
if(typeof(translate.language.local) != 'undefined' && translate.language.local.length > 1){
|
|
4112
|
+
if(translate.language.englishVarietys.indexOf(translate.language.local) > -1){
|
|
4113
|
+
//发现当前设置的是小语种,那么将当前识别的语种识别为 本地设置的这个小语种。
|
|
4114
|
+
data.languageName = translate.language.local;
|
|
4115
|
+
}
|
|
4116
|
+
}
|
|
4117
|
+
|
|
4118
|
+
if(data.languageName == 'english'){
|
|
4119
|
+
//还是英语,那就是没有经过上面本地语种的判定,那进行罗曼语的具体语种识别
|
|
4120
|
+
|
|
4121
|
+
var romanceSentenceLanguage = translate.language.romanceSentenceAnaly(str);
|
|
4122
|
+
if(romanceSentenceLanguage.length == 0){
|
|
4123
|
+
console.log('语种识别异常,应该是 法语、西班牙语、葡萄牙语、意大利语 中的一种才是,除非是除了这四种语种之外的别的 罗曼语族 中的语种,当前已将 '+ str +'识别为英语。 你可以联系我们求助 https://translate.zvo.cn/4030.html');
|
|
4124
|
+
}else{
|
|
4125
|
+
data.languageName = romanceSentenceLanguage;
|
|
4126
|
+
}
|
|
4127
|
+
}
|
|
4128
|
+
}
|
|
4129
|
+
}
|
|
4130
|
+
|
|
4131
|
+
|
|
4132
|
+
/*
|
|
4133
|
+
日语判定
|
|
4134
|
+
如果发现日语存在,且当前 data.languageName 认定不是日语,那么要判定一下:
|
|
4135
|
+
如果 日语的字符数/所有字符数 的字符数 > 0.08 , 那么认为当前是日语的
|
|
4136
|
+
*/
|
|
4137
|
+
if( typeof(languagesSize['japanese']) != 'undefined' && data.languageName != 'japanese'){
|
|
4138
|
+
if(languagesSize['japanese']/allSize > 0.08){
|
|
4139
|
+
data.languageName = 'japanese'
|
|
4140
|
+
}
|
|
4141
|
+
}
|
|
4142
|
+
|
|
4143
|
+
/*
|
|
4144
|
+
如果发现英语、简体中文或繁体中文 一起存在,且当前 data.languageName 认定是英语时,那么要判定一下:
|
|
4145
|
+
如果 (简体中文+繁体中文)的字符数/英语 > 0.05 , 那么认为当前是简体中文(不认为是繁体中文,因为下面还有 简体中文跟繁体中文的判定)
|
|
4146
|
+
*/
|
|
4147
|
+
if( (typeof(languagesSize['chinese_simplified']) != 'undefined' || typeof(languagesSize['chinese_traditional']) != 'undefined' ) && typeof(languagesSize['english']) != 'undefined' && data.languageName == 'english'){
|
|
4148
|
+
var size = 0;
|
|
4149
|
+
if(typeof(languagesSize['chinese_simplified']) != 'undefined'){
|
|
4150
|
+
size = size + languagesSize['chinese_simplified'];
|
|
4151
|
+
}
|
|
4152
|
+
if(typeof(languagesSize['chinese_traditional']) != 'undefined'){
|
|
4153
|
+
size = size + languagesSize['chinese_traditional'];
|
|
4154
|
+
}
|
|
4155
|
+
if(size/languagesSize['english'] > 0.05){
|
|
4156
|
+
data.languageName = 'chinese_simplified'
|
|
4157
|
+
}
|
|
4158
|
+
}
|
|
4159
|
+
|
|
4160
|
+
|
|
4161
|
+
/*
|
|
4162
|
+
如果简体中文跟繁体中文一起出现,且当前 data.languageName 认定是简体中文(也就是简体中文字符占比最大),那么要判定一下繁体中文:
|
|
4163
|
+
如果 繁体中文的字符数/简体中文的字符数 > 0.08 , 那么认为当前是繁体中文的
|
|
4164
|
+
*/
|
|
4165
|
+
if(typeof(languagesSize['chinese_simplified']) != 'undefined' && typeof(languagesSize['chinese_traditional']) != 'undefined' && data.languageName == 'chinese_simplified'){
|
|
4166
|
+
if(languagesSize['chinese_traditional']/languagesSize['chinese_simplified'] > 0.03){
|
|
4167
|
+
data.languageName = 'chinese_traditional'
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
/* if(langkeys.indexOf('chinese_simplified') > -1 && langkeys.indexOf('chinese_traditional') > -1){
|
|
4171
|
+
langsNumber['chinese_simplified'] = 0;
|
|
4172
|
+
} */
|
|
4173
|
+
|
|
4174
|
+
|
|
4175
|
+
return data;
|
|
4176
|
+
},
|
|
3877
4177
|
|
|
3878
4178
|
/*
|
|
3879
4179
|
* 识别字符串是什么语种。它是 get() 的扩展,以代替get返回更多
|
|
@@ -3884,12 +4184,14 @@ var translate = {
|
|
|
3884
4184
|
{
|
|
3885
4185
|
languageName: 'english',
|
|
3886
4186
|
languageArray:[
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
4187
|
+
english:[
|
|
4188
|
+
list[
|
|
4189
|
+
{beforeText: ' ', afterText: ' ', text: 'hello word'},
|
|
4190
|
+
{beforeText: ' ', afterText: ' ', text: 'who?'},
|
|
4191
|
+
],
|
|
4192
|
+
number:12
|
|
3890
4193
|
],
|
|
3891
|
-
|
|
3892
|
-
{beforeText: ' ', afterText: ' ', text: 'ẽ '},
|
|
4194
|
+
japanese:[
|
|
3893
4195
|
......
|
|
3894
4196
|
]
|
|
3895
4197
|
]
|
|
@@ -3909,6 +4211,8 @@ var translate = {
|
|
|
3909
4211
|
var langsNumber = []; //key 语言名, value 语言字符数
|
|
3910
4212
|
var langsNumberOriginal = []; //同上,只不过这个不会进行清空字符数
|
|
3911
4213
|
var allNumber = 0;//总字数
|
|
4214
|
+
|
|
4215
|
+
/** 进行字数统计相关 - start **/
|
|
3912
4216
|
for(var key in langs){
|
|
3913
4217
|
if (!langs.hasOwnProperty(key)) {
|
|
3914
4218
|
continue;
|
|
@@ -3924,52 +4228,10 @@ var translate = {
|
|
|
3924
4228
|
langsNumber[key] = langStrLength;
|
|
3925
4229
|
langsNumberOriginal[key] = langStrLength;
|
|
3926
4230
|
}
|
|
4231
|
+
/** 进行字数统计相关 - end **/
|
|
3927
4232
|
|
|
3928
|
-
//过滤 语种的字符数小于总字符数 百分之五的,低于这个数,将忽略
|
|
3929
|
-
var langkeys = [];
|
|
3930
|
-
for(var lang in langsNumber){
|
|
3931
|
-
if (!langsNumber.hasOwnProperty(lang)) {
|
|
3932
|
-
continue;
|
|
3933
|
-
}
|
|
3934
|
-
if(langsNumber[lang]/allNumber > 0.01){
|
|
3935
|
-
langkeys[langkeys.length] = lang+'';
|
|
3936
|
-
}
|
|
3937
|
-
}
|
|
3938
|
-
|
|
3939
|
-
if(langkeys.length > 1 && langkeys.indexOf('english') > -1){
|
|
3940
|
-
//console.log('出现了english, 并且english跟其他语种一起出现那么删除english,因为什么法语德语乱七八糟的都有英语。而且中文跟英文一起,如果认为是英文的话,有时候中文会不被翻译');
|
|
3941
|
-
//这里先判断一下是否有发现了 罗曼语族
|
|
3942
|
-
if(langkeys.indexOf('romance') > -1){
|
|
3943
|
-
//发现了,那么判断一下到底是 法语、西班牙语、葡萄牙语、意大利语 中的哪一种呢
|
|
3944
|
-
var romanceSentenceLanguage = translate.language.romanceSentenceAnaly(str);
|
|
3945
|
-
if(romanceSentenceLanguage.length == 0){
|
|
3946
|
-
console.log('语种识别异常,应该是 法语、西班牙语、葡萄牙语、意大利语 中的一种才是,除非是除了这四种语种之外的别的 罗曼语族 中的语种,当前已将 '+ str +'识别为英语。 你可以联系我们求助 https://translate.zvo.cn/4030.html');
|
|
3947
|
-
}else{
|
|
3948
|
-
//console.log(langsNumber);
|
|
3949
|
-
langsNumber[romanceSentenceLanguage] = langsNumber['romance']+langsNumber['english'];
|
|
3950
|
-
//console.log('set romance to '+romanceSentenceLanguage+' : \t'+str);
|
|
3951
|
-
langsNumber['english'] = 0;
|
|
3952
|
-
}
|
|
3953
|
-
}else{
|
|
3954
|
-
langsNumber['english'] = 0;
|
|
3955
|
-
}
|
|
3956
|
-
}
|
|
3957
|
-
|
|
3958
|
-
//如果简体中文跟繁体中文一起出现,那么会判断当前句子为繁体中文,将简体中文字符数置0
|
|
3959
|
-
if(langkeys.indexOf('chinese_simplified') > -1 && langkeys.indexOf('chinese_traditional') > -1){
|
|
3960
|
-
//langkeys.splice(langkeys.indexOf('chinese_simplified'), 1);
|
|
3961
|
-
langsNumber['chinese_simplified'] = 0;
|
|
3962
|
-
}
|
|
3963
4233
|
|
|
3964
4234
|
|
|
3965
|
-
//如果发现日语字符,那么将发现的简体中文、繁体中文字符数量置零
|
|
3966
|
-
if(langkeys.length > 1 && langkeys.indexOf('japanese') > -1){
|
|
3967
|
-
langsNumber['chinese_simplified'] = 0;
|
|
3968
|
-
langsNumber['chinese_traditional'] = 0;
|
|
3969
|
-
}
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
4235
|
//从 langsNumber 中找出字数最多的来
|
|
3974
4236
|
var maxLang = ''; //字数最多的语种
|
|
3975
4237
|
var maxNumber = 0;
|
|
@@ -3998,19 +4260,9 @@ var translate = {
|
|
|
3998
4260
|
languageName: maxLang,
|
|
3999
4261
|
languageArray: languageArray
|
|
4000
4262
|
};
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
//如果识别的语种是英语,那便不仅仅是英语,因为法语、德语、意大利语也是在英语里面,还要判断一下是否用户自己设置了具体语种是否是英语延伸的小语种
|
|
4005
|
-
|
|
4006
|
-
var localLang = translate.language.getLocal(); //本地语种
|
|
4007
|
-
if(translate.language.englishVarietys.indexOf(localLang) > -1){
|
|
4008
|
-
//发现当前设置的是小语种,那么将当前识别的语种识别为 本地设置的这个小语种。
|
|
4009
|
-
result.languageName = localLang;
|
|
4010
|
-
}
|
|
4011
|
-
}
|
|
4012
|
-
|
|
4013
|
-
return result;
|
|
4263
|
+
|
|
4264
|
+
//最后进行一层简单的算法处理
|
|
4265
|
+
return translate.language.recognitionAlgorithm(str, result, langsNumber, allNumber);
|
|
4014
4266
|
},
|
|
4015
4267
|
/*
|
|
4016
4268
|
传入一个char,返回这个char属于什么语种,返回如 如果返回空字符串,那么表示未获取到是什么语种
|
|
@@ -4731,7 +4983,7 @@ var translate = {
|
|
|
4731
4983
|
|
|
4732
4984
|
//判断它后面是否还有文本
|
|
4733
4985
|
if(originalIndex+1 < text.length){
|
|
4734
|
-
|
|
4986
|
+
let char = text.charAt(originalIndex+translateOriginal.length);
|
|
4735
4987
|
//console.log(char);
|
|
4736
4988
|
if(/。/.test(char)){
|
|
4737
4989
|
replaceResultText = replaceResultText + '. ';
|
|
@@ -4745,9 +4997,12 @@ var translate = {
|
|
|
4745
4997
|
}else if([' ', '\n','\t',']','|', '_','-','/'].indexOf(char) !== -1){
|
|
4746
4998
|
// 如果后面的字符是 这些字符,那么不用添加空格隔开
|
|
4747
4999
|
}else{
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
5000
|
+
//补充上一个空格,用于将两个单词隔开。 不过 ,如果当前 replaceResultText 的最后一个字符也是空格,那就不需要再加空格了。 这里就只判断空格就好了,至于其他的换行等基本不会出现这个情况,所以不考虑
|
|
5001
|
+
if(replaceResultText.length > 0 && replaceResultText.charAt(replaceResultText.length-1) == ' '){
|
|
5002
|
+
//replaceResultText 本身有值,且最后一个字符就是空格,就不需要再追加空格进行隔开了
|
|
5003
|
+
}else{
|
|
5004
|
+
replaceResultText = replaceResultText + ' ';
|
|
5005
|
+
}
|
|
4751
5006
|
}
|
|
4752
5007
|
|
|
4753
5008
|
}
|
|
@@ -4768,10 +5023,14 @@ var translate = {
|
|
|
4768
5023
|
replaceOriginalText = ':'+replaceOriginalText;
|
|
4769
5024
|
}else if([' ', '\n','\t','[', '|', '_','-','/'].indexOf(char) !== -1){
|
|
4770
5025
|
// 如果前面的字符是 这些字符,那么不用添加空格隔开
|
|
5026
|
+
//console.log('不需要空格隔开的');
|
|
4771
5027
|
}else{
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
5028
|
+
//补充上一个空格,用于将两个单词隔开。 不过 ,如果当前 replaceResultText 的第一个字符也是空格,那就不需要再加空格了。 这里就只判断空格就好了,至于其他的换行等基本不会出现这个情况,所以不考虑
|
|
5029
|
+
if(replaceResultText.length > 0 && replaceResultText.charAt(0) == ' '){
|
|
5030
|
+
//replaceResultText 本身有值,且最后一个字符就是空格,就不需要再追加空格进行隔开了
|
|
5031
|
+
}else{
|
|
5032
|
+
replaceResultText = ' '+replaceResultText;
|
|
5033
|
+
}
|
|
4775
5034
|
//console.log('before add space : '+replaceResultText);
|
|
4776
5035
|
}
|
|
4777
5036
|
}
|
|
@@ -4779,6 +5038,8 @@ var translate = {
|
|
|
4779
5038
|
//如果是其他语种比如英语法语翻译为中文、日文,那么标点符号也要判断的,这个因为目前这个场景还没咋遇到,就不判断了,遇到了在加。
|
|
4780
5039
|
|
|
4781
5040
|
}
|
|
5041
|
+
//console.log(replaceResultText)
|
|
5042
|
+
//console.log(replaceResultText.length)
|
|
4782
5043
|
|
|
4783
5044
|
let replaceResult = translate.util.replaceFromIndex(text, currentReplaceEndIndex, replaceOriginalText, replaceResultText);
|
|
4784
5045
|
if(replaceResult.replaceEndIndex < 1){
|
|
@@ -5244,6 +5505,7 @@ var translate = {
|
|
|
5244
5505
|
value: translate.js 的语种标识
|
|
5245
5506
|
*/
|
|
5246
5507
|
browserLanguage:{
|
|
5508
|
+
'zh':'chinese_simplified',
|
|
5247
5509
|
'zh-CN':'chinese_simplified',
|
|
5248
5510
|
'zh-TW':'chinese_traditional',
|
|
5249
5511
|
'zh-HK':'chinese_traditional',
|
|
@@ -5443,15 +5705,15 @@ var translate = {
|
|
|
5443
5705
|
const endX = startX + width;
|
|
5444
5706
|
const endY = startY + height;
|
|
5445
5707
|
|
|
5446
|
-
//
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5708
|
+
// 返回包含所有信息的对象(使用ES5兼容语法)
|
|
5709
|
+
return {
|
|
5710
|
+
startX: startX,
|
|
5711
|
+
startY: startY,
|
|
5712
|
+
endX: endX,
|
|
5713
|
+
endY: endY,
|
|
5714
|
+
width: width,
|
|
5715
|
+
height: height
|
|
5716
|
+
};
|
|
5455
5717
|
}
|
|
5456
5718
|
/*js translate.util.getElementPosition end*/
|
|
5457
5719
|
},
|
|
@@ -5482,6 +5744,9 @@ var translate = {
|
|
|
5482
5744
|
if(typeof(serviceName) == 'string'){
|
|
5483
5745
|
translate.service.name = serviceName;
|
|
5484
5746
|
if(serviceName != 'translate.service'){
|
|
5747
|
+
//增加元素整体翻译能力
|
|
5748
|
+
translate.whole.enableAll();
|
|
5749
|
+
|
|
5485
5750
|
if(serviceName.toLowerCase() == 'giteeai'){
|
|
5486
5751
|
//设定翻译接口为GiteeAI的
|
|
5487
5752
|
translate.request.api.host=['https://giteeai.zvo.cn/','https://deutsch.enterprise.api.translate.zvo.cn:1000/','https://api.translate.zvo.cn:1000/'];
|
|
@@ -5492,9 +5757,6 @@ var translate = {
|
|
|
5492
5757
|
translate.request.api.host=['https://siliconflow.zvo.cn/','https://america.api.translate.zvo.cn:1414/','https://deutsch.enterprise.api.translate.zvo.cn:1414/'];
|
|
5493
5758
|
return;
|
|
5494
5759
|
}
|
|
5495
|
-
|
|
5496
|
-
//增加元素整体翻译能力
|
|
5497
|
-
translate.whole.enableAll();
|
|
5498
5760
|
}
|
|
5499
5761
|
}
|
|
5500
5762
|
},
|
|
@@ -5509,6 +5771,7 @@ var translate = {
|
|
|
5509
5771
|
},
|
|
5510
5772
|
|
|
5511
5773
|
language:{
|
|
5774
|
+
|
|
5512
5775
|
json:[{"id":"ukrainian","name":"Україна","serviceId":"uk"},{"id":"norwegian","name":"Norge","serviceId":"no"},{"id":"welsh","name":"Iaith Weleg","serviceId":"cy"},{"id":"dutch","name":"nederlands","serviceId":"nl"},{"id":"japanese","name":"日本語","serviceId":"ja"},{"id":"filipino","name":"Pilipino","serviceId":"fil"},{"id":"english","name":"English","serviceId":"en"},{"id":"lao","name":"ກະຣຸນາ","serviceId":"lo"},{"id":"telugu","name":"తెలుగుName","serviceId":"te"},{"id":"romanian","name":"Română","serviceId":"ro"},{"id":"nepali","name":"नेपालीName","serviceId":"ne"},{"id":"french","name":"Français","serviceId":"fr"},{"id":"haitian_creole","name":"Kreyòl ayisyen","serviceId":"ht"},{"id":"czech","name":"český","serviceId":"cs"},{"id":"swedish","name":"Svenska","serviceId":"sv"},{"id":"russian","name":"Русский язык","serviceId":"ru"},{"id":"malagasy","name":"Malagasy","serviceId":"mg"},{"id":"burmese","name":"ဗာရမ်","serviceId":"my"},{"id":"pashto","name":"پښتوName","serviceId":"ps"},{"id":"thai","name":"คนไทย","serviceId":"th"},{"id":"armenian","name":"Արմենյան","serviceId":"hy"},{"id":"chinese_simplified","name":"简体中文","serviceId":"zh-CHS"},{"id":"persian","name":"Persian","serviceId":"fa"},{"id":"chinese_traditional","name":"繁體中文","serviceId":"zh-CHT"},{"id":"kurdish","name":"Kurdî","serviceId":"ku"},{"id":"turkish","name":"Türkçe","serviceId":"tr"},{"id":"hindi","name":"हिन्दी","serviceId":"hi"},{"id":"bulgarian","name":"български","serviceId":"bg"},{"id":"malay","name":"Malay","serviceId":"ms"},{"id":"swahili","name":"Kiswahili","serviceId":"sw"},{"id":"oriya","name":"ଓଡିଆ","serviceId":"or"},{"id":"icelandic","name":"ÍslandName","serviceId":"is"},{"id":"irish","name":"Íris","serviceId":"ga"},{"id":"khmer","name":"ភាសាខ្មែរName","serviceId":"km"},{"id":"gujarati","name":"ગુજરાતી","serviceId":"gu"},{"id":"slovak","name":"Slovenská","serviceId":"sk"},{"id":"kannada","name":"ಕನ್ನಡ್Name","serviceId":"kn"},{"id":"hebrew","name":"היברית","serviceId":"he"},{"id":"hungarian","name":"magyar","serviceId":"hu"},{"id":"marathi","name":"मराठीName","serviceId":"mr"},{"id":"tamil","name":"தாமில்","serviceId":"ta"},{"id":"estonian","name":"eesti keel","serviceId":"et"},{"id":"malayalam","name":"മലമാലം","serviceId":"ml"},{"id":"inuktitut","name":"ᐃᓄᒃᑎᑐᑦ","serviceId":"iu"},{"id":"arabic","name":"بالعربية","serviceId":"ar"},{"id":"deutsch","name":"Deutsch","serviceId":"de"},{"id":"slovene","name":"slovenščina","serviceId":"sl"},{"id":"bengali","name":"বেঙ্গালী","serviceId":"bn"},{"id":"urdu","name":"اوردو","serviceId":"ur"},{"id":"azerbaijani","name":"azerbaijani","serviceId":"az"},{"id":"portuguese","name":"português","serviceId":"pt"},{"id":"samoan","name":"lifiava","serviceId":"sm"},{"id":"afrikaans","name":"afrikaans","serviceId":"af"},{"id":"tongan","name":"汤加语","serviceId":"to"},{"id":"greek","name":"ελληνικά","serviceId":"el"},{"id":"indonesian","name":"IndonesiaName","serviceId":"id"},{"id":"spanish","name":"Español","serviceId":"es"},{"id":"danish","name":"dansk","serviceId":"da"},{"id":"amharic","name":"amharic","serviceId":"am"},{"id":"punjabi","name":"ਪੰਜਾਬੀName","serviceId":"pa"},{"id":"albanian","name":"albanian","serviceId":"sq"},{"id":"lithuanian","name":"Lietuva","serviceId":"lt"},{"id":"italian","name":"italiano","serviceId":"it"},{"id":"vietnamese","name":"Tiếng Việt","serviceId":"vi"},{"id":"korean","name":"한국어","serviceId":"ko"},{"id":"maltese","name":"Malti","serviceId":"mt"},{"id":"finnish","name":"suomi","serviceId":"fi"},{"id":"catalan","name":"català","serviceId":"ca"},{"id":"croatian","name":"hrvatski","serviceId":"hr"},{"id":"bosnian","name":"bosnian","serviceId":"bs-Latn"},{"id":"polish","name":"Polski","serviceId":"pl"},{"id":"latvian","name":"latviešu","serviceId":"lv"},{"id":"maori","name":"Maori","serviceId":"mi"}],
|
|
5513
5776
|
/*
|
|
5514
5777
|
获取map形式的语言列表
|
|
@@ -5537,11 +5800,22 @@ var translate = {
|
|
|
5537
5800
|
var textArray = JSON.parse(decodeURIComponent(data.text));
|
|
5538
5801
|
let translateTextArray = translate.util.split(textArray, 40000, 900);
|
|
5539
5802
|
|
|
5540
|
-
translate.request.send(translate.service.edge.api.auth, {}, function(auth){
|
|
5803
|
+
translate.request.send(translate.service.edge.api.auth, {},{}, function(auth){
|
|
5804
|
+
var appendXhrData = {
|
|
5805
|
+
"from":data.from+'',
|
|
5806
|
+
"to":data.to,
|
|
5807
|
+
"text":data.text
|
|
5808
|
+
};
|
|
5541
5809
|
var from = data.from;
|
|
5542
5810
|
if(from != 'auto'){
|
|
5543
|
-
from
|
|
5811
|
+
if(from == 'romance'){
|
|
5812
|
+
//这里额外加了一个罗曼语族(romance)会自动认为是法语(fr)
|
|
5813
|
+
from = 'fr';
|
|
5814
|
+
}else{
|
|
5815
|
+
from = translate.service.edge.language.getMap()[data.from];
|
|
5816
|
+
}
|
|
5544
5817
|
}
|
|
5818
|
+
|
|
5545
5819
|
var to = translate.service.edge.language.getMap()[data.to];
|
|
5546
5820
|
var transUrl = translate.service.edge.api.translate.replace('{from}',from).replace('{to}',to);
|
|
5547
5821
|
|
|
@@ -5552,7 +5826,7 @@ var translate = {
|
|
|
5552
5826
|
json.push({"Text":translateTextArray[tai][i]});
|
|
5553
5827
|
}
|
|
5554
5828
|
|
|
5555
|
-
translate.request.send(transUrl, JSON.stringify(json), function(result){
|
|
5829
|
+
translate.request.send(transUrl, JSON.stringify(json), appendXhrData, function(result){
|
|
5556
5830
|
var d = {};
|
|
5557
5831
|
d.info = 'SUCCESS';
|
|
5558
5832
|
d.result = 1;
|
|
@@ -5850,6 +6124,7 @@ var translate = {
|
|
|
5850
6124
|
translate.request.send(
|
|
5851
6125
|
host+translate.request.api.connectTest,
|
|
5852
6126
|
{host:host},
|
|
6127
|
+
{host:host},
|
|
5853
6128
|
function(data){
|
|
5854
6129
|
var host = data.info;
|
|
5855
6130
|
var map = translate.request.speedDetectionControl.checkHostQueueMap[host];
|
|
@@ -5986,12 +6261,13 @@ var translate = {
|
|
|
5986
6261
|
}
|
|
5987
6262
|
// ------- edge end --------
|
|
5988
6263
|
|
|
5989
|
-
this.send(path, data, func, 'post', true, headers, abnormalFunc, true);
|
|
6264
|
+
this.send(path, data, data, func, 'post', true, headers, abnormalFunc, true);
|
|
5990
6265
|
},
|
|
5991
6266
|
/**
|
|
5992
6267
|
* 发送请求
|
|
5993
6268
|
* url 请求的url或者path(path,传入的是translate.request.api.translate 这种的,需要使用 getUrl 来组合真正请求的url )
|
|
5994
6269
|
* data 请求的数据,如 {"author":"管雷鸣",'site':'www.guanleiming.com'}
|
|
6270
|
+
* appendXhrData 附加到 xhr.data 中的对象数据,传入比如 {"from":"english","to":"japanese"} ,他会直接赋予 xhr.data
|
|
5995
6271
|
* func 请求完成的回调,传入如 function(data){}
|
|
5996
6272
|
* method 请求方式,可传入 post、get
|
|
5997
6273
|
* isAsynchronize 是否是异步请求, 传入 true 是异步请求,传入false 是同步请求。 如果传入false,则本方法返回xhr
|
|
@@ -5999,7 +6275,7 @@ var translate = {
|
|
|
5999
6275
|
* abnormalFunc 响应异常所执行的方法,响应码不是200就会执行这个方法 ,传入如 function(xhr){} 另外这里的 xhr 会额外有个参数 xhr.requestURL 返回当前请求失败的url
|
|
6000
6276
|
* showErrorLog 是否控制台打印出来错误日志,true打印, false 不打印
|
|
6001
6277
|
*/
|
|
6002
|
-
send:function(url, data, func, method, isAsynchronize, headers, abnormalFunc, showErrorLog){
|
|
6278
|
+
send:function(url, data, appendXhrData, func, method, isAsynchronize, headers, abnormalFunc, showErrorLog){
|
|
6003
6279
|
//post提交的参数
|
|
6004
6280
|
var params = '';
|
|
6005
6281
|
|
|
@@ -6008,7 +6284,7 @@ var translate = {
|
|
|
6008
6284
|
}
|
|
6009
6285
|
|
|
6010
6286
|
if(typeof(data) == 'string'){
|
|
6011
|
-
params = data; //payload 方式
|
|
6287
|
+
params = data; //payload 方式 , edge 的方式
|
|
6012
6288
|
}else{
|
|
6013
6289
|
//表单提交方式
|
|
6014
6290
|
|
|
@@ -6055,7 +6331,7 @@ var translate = {
|
|
|
6055
6331
|
}catch(e){
|
|
6056
6332
|
xhr=new ActiveXObject("Microsoft.XMLHTTP");
|
|
6057
6333
|
}
|
|
6058
|
-
xhr.data=
|
|
6334
|
+
xhr.data=appendXhrData;
|
|
6059
6335
|
//2.调用open方法(true----异步)
|
|
6060
6336
|
xhr.open(method,url,isAsynchronize);
|
|
6061
6337
|
//设置headers
|
|
@@ -6209,41 +6485,83 @@ var translate = {
|
|
|
6209
6485
|
return;
|
|
6210
6486
|
}
|
|
6211
6487
|
}
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
console.log(texts[i]);
|
|
6488
|
+
//console.log(obj);
|
|
6489
|
+
//返回的翻译结果,下标跟 obj.texts 一一对应的
|
|
6490
|
+
var translateResultArray = new Array();
|
|
6216
6491
|
|
|
6492
|
+
// 筛选需要翻译的文本及其原始索引
|
|
6493
|
+
var apiTranslateText = [];
|
|
6494
|
+
var apiTranslateArray = {};
|
|
6495
|
+
for(var i = 0; i < texts.length; i++){
|
|
6217
6496
|
//判断是否在浏览器缓存中出现了
|
|
6218
|
-
var
|
|
6219
|
-
var cache = translate.storage.get('hash_'+
|
|
6497
|
+
var hash = translate.util.hash(texts[i]);
|
|
6498
|
+
var cache = translate.storage.get('hash_'+to+'_'+hash);
|
|
6499
|
+
//console.log(hash+'\t'+texts[i]+'\t'+cache);
|
|
6220
6500
|
if(cache != null && cache.length > 0){
|
|
6221
6501
|
//缓存中发现了这个得结果,那这个就不需要再进行翻译了
|
|
6222
|
-
|
|
6502
|
+
translateResultArray[i] = cache;
|
|
6503
|
+
}else{
|
|
6504
|
+
translateResultArray[i] = '';
|
|
6505
|
+
apiTranslateText.push(texts[i]);
|
|
6506
|
+
apiTranslateArray[hash] = i;
|
|
6507
|
+
}
|
|
6508
|
+
}
|
|
6509
|
+
if (apiTranslateText.length == 0) {
|
|
6510
|
+
//没有需要进行通过网络API翻译的任务了,全部命中缓存,那么直接返回
|
|
6511
|
+
var data = {
|
|
6512
|
+
from:from,
|
|
6513
|
+
to: to,
|
|
6514
|
+
text:translateResultArray,
|
|
6515
|
+
result:1
|
|
6516
|
+
};
|
|
6517
|
+
//console.log(data);
|
|
6518
|
+
func(data);
|
|
6519
|
+
return;
|
|
6520
|
+
}
|
|
6521
|
+
|
|
6522
|
+
|
|
6523
|
+
|
|
6524
|
+
//还有需要进行通过API接口进行翻译的文本,需要调用翻译接口
|
|
6525
|
+
if(typeof(translate.request.api.translate) != 'string' || translate.request.api.translate == null || translate.request.api.translate.length < 1){
|
|
6526
|
+
//用户已经设置了不掉翻译接口进行翻译
|
|
6527
|
+
return;
|
|
6223
6528
|
}
|
|
6224
|
-
*/
|
|
6225
|
-
|
|
6226
6529
|
|
|
6227
6530
|
var url = translate.request.api.translate;
|
|
6228
6531
|
var data = {
|
|
6229
6532
|
from:from,
|
|
6230
6533
|
to: to,
|
|
6231
|
-
text:encodeURIComponent(JSON.stringify(
|
|
6534
|
+
text:encodeURIComponent(JSON.stringify(apiTranslateText))
|
|
6232
6535
|
};
|
|
6233
|
-
//console.log(
|
|
6234
|
-
translate.request.post(url, data, function(
|
|
6536
|
+
//console.log(apiTranslateText);
|
|
6537
|
+
translate.request.post(url, data, function(resultData){
|
|
6538
|
+
//console.log(resultData);
|
|
6235
6539
|
//console.log(data);
|
|
6236
|
-
if(
|
|
6540
|
+
if(resultData.result == 0){
|
|
6237
6541
|
console.log('=======ERROR START=======');
|
|
6238
|
-
console.log('from : '+
|
|
6239
|
-
console.log('to : '+
|
|
6542
|
+
console.log('from : '+resultData.from);
|
|
6543
|
+
console.log('to : '+resultData.to);
|
|
6240
6544
|
console.log('translate text array : '+texts);
|
|
6241
|
-
console.log('response : '+
|
|
6545
|
+
console.log('response : '+resultData.info);
|
|
6242
6546
|
console.log('=======ERROR END =======');
|
|
6243
6547
|
//return;
|
|
6244
6548
|
}
|
|
6245
6549
|
|
|
6246
|
-
|
|
6550
|
+
for(var i = 0; i < resultData.text.length; i++){
|
|
6551
|
+
//将翻译结果以 key:hash value翻译结果的形式缓存
|
|
6552
|
+
var hash = translate.util.hash(apiTranslateText[i]);
|
|
6553
|
+
translate.storage.set('hash_'+to+'_'+hash, resultData.text[i]);
|
|
6554
|
+
//如果离线翻译启用了全部提取,那么还要存入离线翻译指定存储
|
|
6555
|
+
if(translate.office.fullExtract.isUse){
|
|
6556
|
+
translate.office.fullExtract.set(hash, apiTranslateText[i], data.to, resultData.text[i]);
|
|
6557
|
+
}
|
|
6558
|
+
|
|
6559
|
+
//进行组合数据到 translateResultArray
|
|
6560
|
+
translateResultArray[apiTranslateArray[hash]] = resultData.text[i];
|
|
6561
|
+
}
|
|
6562
|
+
resultData.text = translateResultArray;
|
|
6563
|
+
|
|
6564
|
+
func(resultData);
|
|
6247
6565
|
}, null);
|
|
6248
6566
|
},
|
|
6249
6567
|
listener:{
|
|
@@ -6302,6 +6620,8 @@ var translate = {
|
|
|
6302
6620
|
trigger:function(url){
|
|
6303
6621
|
return true;
|
|
6304
6622
|
},
|
|
6623
|
+
|
|
6624
|
+
/*js translate.request.listener.start start*/
|
|
6305
6625
|
/*
|
|
6306
6626
|
启动根据ajax请求来自动触发执行翻译,避免有时候有的框架存在漏翻译的情况。
|
|
6307
6627
|
这个只需要执行一次即可,如果执行多次,只有第一次会生效
|
|
@@ -6417,6 +6737,7 @@ var translate = {
|
|
|
6417
6737
|
}
|
|
6418
6738
|
|
|
6419
6739
|
}
|
|
6740
|
+
/*js translate.request.listener.start end*/
|
|
6420
6741
|
}
|
|
6421
6742
|
},
|
|
6422
6743
|
//存储,本地缓存
|
|
@@ -6760,6 +7081,13 @@ var translate = {
|
|
|
6760
7081
|
if (curSelection.anchorOffset == curSelection.focusOffset) return;
|
|
6761
7082
|
let translateText = window.getSelection().toString();
|
|
6762
7083
|
|
|
7084
|
+
//还有需要进行通过API接口进行翻译的文本,需要调用翻译接口
|
|
7085
|
+
if(typeof(translate.request.api.translate) != 'string' || translate.request.api.translate == null || translate.request.api.translate.length < 1){
|
|
7086
|
+
//用户已经设置了不掉翻译接口进行翻译
|
|
7087
|
+
console.log('已设置了不使用 translate 翻译接口,翻译请求被阻止');
|
|
7088
|
+
return;
|
|
7089
|
+
}
|
|
7090
|
+
|
|
6763
7091
|
//简单Copy原有代码了
|
|
6764
7092
|
var url = translate.request.api.translate
|
|
6765
7093
|
var data = {
|
|
@@ -6868,6 +7196,7 @@ var translate = {
|
|
|
6868
7196
|
translate.request.send(
|
|
6869
7197
|
translate.request.api.init,
|
|
6870
7198
|
{},
|
|
7199
|
+
{},
|
|
6871
7200
|
function(data){
|
|
6872
7201
|
if (data.result == 0){
|
|
6873
7202
|
console.log('translate.js init 初始化异常:'+data.info);
|
|
@@ -6881,8 +7210,6 @@ var translate = {
|
|
|
6881
7210
|
if(newVersion > currentVersion){
|
|
6882
7211
|
console.log('Tip : translate.js find new version : '+data.version);
|
|
6883
7212
|
}
|
|
6884
|
-
}else{
|
|
6885
|
-
eval(data.info);
|
|
6886
7213
|
}
|
|
6887
7214
|
},
|
|
6888
7215
|
'post',
|
|
@@ -7937,8 +8264,96 @@ var translate = {
|
|
|
7937
8264
|
if(typeof(uuid) == 'string' && uuid.length > 1){
|
|
7938
8265
|
translate.visual.adjustTranslationSpacesByNodequeueUuid(uuid);
|
|
7939
8266
|
}
|
|
8267
|
+
},
|
|
8268
|
+
|
|
8269
|
+
/**
|
|
8270
|
+
* 隐藏当前网页的所有文本
|
|
8271
|
+
*
|
|
8272
|
+
*/
|
|
8273
|
+
hideText:{
|
|
8274
|
+
style:`
|
|
8275
|
+
/* 文本隐藏核心样式 - 仅隐藏文本内容 */
|
|
8276
|
+
html.translatejs-text-hidden p, html.translatejs-text-hidden div,
|
|
8277
|
+
html.translatejs-text-hidden h1, html.translatejs-text-hidden h2, html.translatejs-text-hidden h3,
|
|
8278
|
+
html.translatejs-text-hidden h4, html.translatejs-text-hidden h5, html.translatejs-text-hidden h6,
|
|
8279
|
+
html.translatejs-text-hidden span, html.translatejs-text-hidden a, html.translatejs-text-hidden b,
|
|
8280
|
+
html.translatejs-text-hidden strong, html.translatejs-text-hidden i, html.translatejs-text-hidden em,
|
|
8281
|
+
html.translatejs-text-hidden mark,
|
|
8282
|
+
html.translatejs-text-hidden blockquote, html.translatejs-text-hidden ul, html.translatejs-text-hidden ol,
|
|
8283
|
+
html.translatejs-text-hidden li, html.translatejs-text-hidden table, html.translatejs-text-hidden th,
|
|
8284
|
+
html.translatejs-text-hidden td, html.translatejs-text-hidden label, html.translatejs-text-hidden button,
|
|
8285
|
+
html.translatejs-text-hidden input, html.translatejs-text-hidden select, html.translatejs-text-hidden textarea {
|
|
8286
|
+
color: transparent !important;
|
|
8287
|
+
text-shadow: none !important;
|
|
8288
|
+
}
|
|
8289
|
+
|
|
8290
|
+
/* 隐藏占位符文字 */
|
|
8291
|
+
html.translatejs-text-hidden ::placeholder {
|
|
8292
|
+
color: transparent !important;
|
|
8293
|
+
}
|
|
8294
|
+
|
|
8295
|
+
/* 确保媒体元素不受影响 */
|
|
8296
|
+
img, video, iframe, canvas, svg,
|
|
8297
|
+
object, embed, picture, source {
|
|
8298
|
+
color: initial !important;
|
|
8299
|
+
}
|
|
8300
|
+
|
|
8301
|
+
/* 忽略隐藏的元素保持可见 */
|
|
8302
|
+
.ignore-hidden {
|
|
8303
|
+
color: inherit !important;
|
|
8304
|
+
}
|
|
8305
|
+
`,
|
|
8306
|
+
|
|
8307
|
+
/**
|
|
8308
|
+
* 当点击切换语言按钮后,会刷新当前页面,然后再进行翻译。
|
|
8309
|
+
* 这时会出现刷新当前页面后,会先显示原本的文本,然后再翻译为切换为的语种,体验效果有点欠缺。
|
|
8310
|
+
* 这个得作用就是增强用户视觉的体验效果,在页面初始化加载时,如果判定需要翻译,那么会隐藏所有网页中的文本 。
|
|
8311
|
+
* 这个需要在body标签之前执行,需要在head标签中执行此。也就是加载 translate.js 以及触发此都要放到head标签中
|
|
8312
|
+
*/
|
|
8313
|
+
hide:function(){
|
|
8314
|
+
const style = document.createElement('style');
|
|
8315
|
+
style.textContent = translate.visual.hideText.style;
|
|
8316
|
+
document.head.appendChild(style);
|
|
8317
|
+
document.documentElement.classList.add('translatejs-text-hidden');
|
|
8318
|
+
},
|
|
8319
|
+
/**
|
|
8320
|
+
* 撤销隐藏状态,将原本的文本正常显示出来
|
|
8321
|
+
*
|
|
8322
|
+
*/
|
|
8323
|
+
show:function(){
|
|
8324
|
+
document.documentElement.classList.remove('translatejs-text-hidden');
|
|
8325
|
+
}
|
|
8326
|
+
},
|
|
8327
|
+
|
|
8328
|
+
/**
|
|
8329
|
+
* 网页加载,且要进行翻译时,翻译之前,隐藏当前网页的文本。
|
|
8330
|
+
* 当点击切换语言按钮后,会刷新当前页面,然后再进行翻译。
|
|
8331
|
+
* 这时会出现刷新当前页面后,会先显示原本的文本,然后再翻译为切换为的语种,体验效果有点欠缺。
|
|
8332
|
+
* 这个得作用就是增强用户视觉的体验效果,在页面初始化加载时,如果判定需要翻译,那么会隐藏所有网页中的文本 。
|
|
8333
|
+
* 这个需要在body标签之前执行,需要在head标签中执行此。也就是加载 translate.js 以及触发此都要放到head标签中
|
|
8334
|
+
*/
|
|
8335
|
+
webPageLoadTranslateBeforeHiddenText:function(){
|
|
8336
|
+
if(typeof(document.body) == 'undefined' || document.body == null){
|
|
8337
|
+
//正常,body还没加载
|
|
8338
|
+
}else{
|
|
8339
|
+
console.log('错误警告: translate.visual.webPageLoadTranslateBeforeHiddenText() 要在 head 标签中触发才能达到最好的效果!');
|
|
8340
|
+
}
|
|
8341
|
+
if(translate.language.local == ''){
|
|
8342
|
+
console.log('错误警告:在使用 translate.visual.webPageLoadTranslateBeforeHiddenText() 之前,请先手动设置你的本地语种,参考: http://translate.zvo.cn/4066.html 如果你不设置,则不管你是否有切换语言,网页打开后都会先短暂的不显示文字');
|
|
8343
|
+
}
|
|
8344
|
+
|
|
8345
|
+
if(translate.language.local == '' || translate.language.local != translate.language.getCurrent()){
|
|
8346
|
+
translate.visual.hideText.hide();
|
|
8347
|
+
|
|
8348
|
+
//设置翻译完成后,移除隐藏文本的css 的class name
|
|
8349
|
+
translate.lifecycle.execute.renderFinish.push(function(uuid, to){
|
|
8350
|
+
translate.visual.hideText.show();
|
|
8351
|
+
});
|
|
8352
|
+
}
|
|
7940
8353
|
}
|
|
7941
8354
|
|
|
8355
|
+
|
|
8356
|
+
|
|
7942
8357
|
|
|
7943
8358
|
|
|
7944
8359
|
}
|
|
@@ -8004,13 +8419,14 @@ var nodeuuid = {
|
|
|
8004
8419
|
console.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');
|
|
8005
8420
|
/*js copyright-notice end*/
|
|
8006
8421
|
|
|
8422
|
+
|
|
8007
8423
|
/*js amd-cmd-commonjs start*/
|
|
8008
8424
|
/*兼容 AMD、CMD、CommonJS 规范 - start*/
|
|
8009
8425
|
/**
|
|
8010
8426
|
* 兼容 AMD、CMD、CommonJS 规范
|
|
8011
8427
|
* node 环境使用:`npm i i18n-jsautotranslate` 安装包
|
|
8012
8428
|
*/
|
|
8013
|
-
(function (root, factory) {
|
|
8429
|
+
;(function (root, factory) {
|
|
8014
8430
|
if (typeof define === 'function' && define.amd) {
|
|
8015
8431
|
define([], () => factory());
|
|
8016
8432
|
} else if (typeof module === 'object' && module.exports) {
|