i18n-jsautotranslate 3.13.1 → 3.13.6

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.
Files changed (2) hide show
  1. package/index.js +211 -28
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -3,8 +3,10 @@
3
3
  国际化,网页自动翻译。
4
4
  作者:管雷鸣
5
5
  开原仓库:https://github.com/xnx3/translate
6
-
7
6
  */
7
+ if(typeof(translate) == 'object' && typeof(translate.version) == 'string'){
8
+ throw new Error('translate.js 已经加载过一次了,当前是重复加载,避免你的翻译出现异常,已帮你拦截此次加载。本信息只是给你一个提示,你可以检查一下你的项目中是否出现了重复引入 translate.js ,当然,这个异常并不会影响到你的具体使用,它已经自动帮你处理拦截了这个异常,只不过提示出来是让你知道,你的代码里出现了重复引入的情况。');
9
+ }
8
10
  var translate = {
9
11
  /**
10
12
  * 当前的版本
@@ -12,7 +14,7 @@ var translate = {
12
14
  * 格式:major.minor.patch.date
13
15
  */
14
16
  // AUTO_VERSION_START
15
- version: '3.13.1.20250207',
17
+ version: '3.13.6.20250217',
16
18
  // AUTO_VERSION_END
17
19
  /*
18
20
  当前使用的版本,默认使用v2. 可使用 setUseVersion2();
@@ -606,7 +608,7 @@ var translate = {
606
608
  //console.log('beforeChar:'+beforeChar+', str:'+str)
607
609
  var lang = translate.language.getCharLanguage(beforeChar);
608
610
  //console.log(lang);
609
- if(lang == 'english'){
611
+ if(lang == 'english' || lang == 'romance'){
610
612
  //调出,不能强拆
611
613
  continue;
612
614
  }
@@ -621,7 +623,7 @@ var translate = {
621
623
  //后面有别的字符,判断是什么字符,如果是英文,那么这个是不能被拆分的,要忽略
622
624
  afterChar = str.substr(index+originalText.length,1);
623
625
  var lang = translate.language.getCharLanguage(afterChar);
624
- if(lang == 'english'){
626
+ if(lang == 'english' || lang == 'romance'){
625
627
  //跳出,不能强拆
626
628
  continue;
627
629
  }
@@ -865,6 +867,18 @@ var translate = {
865
867
  if(document.readyState == 'complete'){
866
868
  //dom加载完成,进行启动
867
869
  clearInterval(translate.temp_linstenerStartInterval);//停止
870
+
871
+ //如果不需要翻译的情况,是不需要进行监听的
872
+ if(translate.language.getCurrent() == translate.language.getLocal()){
873
+ if(translate.language.translateLocal){
874
+ //本地语种也要强制翻译跟本地语种不一致的语种
875
+ }else{
876
+ //console.log('本地语种跟目标语种一致,不进行翻译操作,无需监听。');
877
+ return;
878
+ }
879
+ }
880
+
881
+ //console.log('进行监听。。');
868
882
  translate.listener.addListener();
869
883
  }
870
884
 
@@ -1757,7 +1771,7 @@ var translate = {
1757
1771
  //console.log(translate.nodeQueue[uuid]['list'][lang]);
1758
1772
  //console.log(firstScan);
1759
1773
  for(var ti=0; ti<twoScan.length; ti++){
1760
- twoHash = twoScan[ti];
1774
+ var twoHash = twoScan[ti];
1761
1775
  //console.log(twoHash + '-- '+firstScan.indexOf(twoHash));
1762
1776
  if(firstScan.indexOf(twoHash) == -1){
1763
1777
  //需要追加了
@@ -3316,8 +3330,8 @@ var translate = {
3316
3330
  ]
3317
3331
  ]
3318
3332
  }
3319
- languageName 是当前字符串是什么语种。它的识别有以下特点:
3320
- 1. 如果出现英语跟中文、法语、德语等混合的情况,也就是不纯粹英语的情况,那么会以其他语种为准,而不是识别为英语。不论英语字符出现的比例占多少。
3333
+ languageName 是当前字符串最终判定结果是什么语种。它的识别有以下特点:
3334
+ 1. 如果出现英语跟中文、罗曼语族、德语等混合的情况,也就是不纯粹英语的情况,那么会以其他语种为准,而不是识别为英语。不论英语字符出现的比例占多少。
3321
3335
  2. 如果出现简体中文跟繁体中文混合的情况,那么识别为繁体中文。不论简体中文字符出现的比例占多少。
3322
3336
  3. 除了以上两种规则外,如果出现了多个语种,那么会识别为出现字符数量最多的语种当做当前句子的语种。(注意是字符数,而不是语种的数组数)
3323
3337
  languageArray 对传入字符串进行分析,识别出都有哪些语种,每个语种的字符是什么
@@ -3346,16 +3360,28 @@ var translate = {
3346
3360
  //过滤 语种的字符数小于总字符数 百分之五的,低于这个数,将忽略
3347
3361
  var langkeys = [];
3348
3362
  for(var lang in langsNumber){
3349
- if(langsNumber[lang]/allNumber > 0.05){
3363
+ if(langsNumber[lang]/allNumber > 0.01){
3350
3364
  langkeys[langkeys.length] = lang+'';
3351
3365
  }
3352
3366
  }
3353
3367
 
3354
-
3355
3368
  if(langkeys.length > 1 && langkeys.indexOf('english') > -1){
3356
- //console.log('出现了english, 并且english跟其他语种一起出现,那么删除english,因为什么法语德语乱七八糟的都有英语。而且中文跟英文一起,如果认为是英文的话,有时候中文会不被翻译');
3357
- //langkeys.splice(langkeys.indexOf('english'), 1);
3358
- langsNumber['english'] = 0;
3369
+ //console.log('出现了english, 并且english跟其他语种一起出现那么删除english,因为什么法语德语乱七八糟的都有英语。而且中文跟英文一起,如果认为是英文的话,有时候中文会不被翻译');
3370
+ //这里先判断一下是否有发现了 罗曼语族
3371
+ if(langkeys.indexOf('romance') > -1){
3372
+ //发现了,那么判断一下到底是 法语、西班牙语、葡萄牙语、意大利语 中的哪一种呢
3373
+ var romanceSentenceLanguage = translate.language.romanceSentenceAnaly(str);
3374
+ if(romanceSentenceLanguage.length == 0){
3375
+ console.log('语种识别异常,应该是 法语、西班牙语、葡萄牙语、意大利语 中的一种才是,除非是除了这四种语种之外的别的 罗曼语族 中的语种,当前已将 '+ str +'识别为英语。 你可以联系我们求助 https://translate.zvo.cn/4030.html');
3376
+ }else{
3377
+ //console.log(langsNumber);
3378
+ langsNumber[romanceSentenceLanguage] = langsNumber['romance']+langsNumber['english'];
3379
+ //console.log('set romance to '+romanceSentenceLanguage+' : \t'+str);
3380
+ langsNumber['english'] = 0;
3381
+ }
3382
+ }else{
3383
+ langsNumber['english'] = 0;
3384
+ }
3359
3385
  }
3360
3386
 
3361
3387
  if(langkeys.indexOf('chinese_simplified') > -1 && langkeys.indexOf('chinese_traditional') > -1){
@@ -3401,7 +3427,18 @@ var translate = {
3401
3427
 
3402
3428
  return result;
3403
3429
  },
3404
- // 传入一个char,返回这个char属于什么语种,返回如 chinese_simplified、english 如果返回空字符串,那么表示未获取到是什么语种
3430
+ /*
3431
+ 传入一个char,返回这个char属于什么语种,返回如 如果返回空字符串,那么表示未获取到是什么语种
3432
+ chinese_simplified 简体中文
3433
+ chinese_traditional 繁体中文
3434
+ russian 俄罗斯语
3435
+ english 英语
3436
+ romance 罗曼语族,它是 法语、西班牙语、意大利语、葡萄牙語 的集合,并不是单个语言
3437
+ specialCharacter 特殊字符,符号
3438
+ number 阿拉伯数字
3439
+ japanese 日语
3440
+ korean 韩语
3441
+ */
3405
3442
  getCharLanguage:function(charstr){
3406
3443
  if(charstr == null || typeof(charstr) == 'undefined'){
3407
3444
  return '';
@@ -3413,6 +3450,9 @@ var translate = {
3413
3450
  if(this.english(charstr)){
3414
3451
  return 'english';
3415
3452
  }
3453
+ if(this.romance(charstr)){
3454
+ return 'romance';
3455
+ }
3416
3456
  if(this.specialCharacter(charstr)){
3417
3457
  return 'specialCharacter';
3418
3458
  }
@@ -3740,16 +3780,6 @@ var translate = {
3740
3780
  return '';
3741
3781
  }
3742
3782
  },
3743
- //是否包含英文,true:包含
3744
- english:function(str){
3745
- if(/.*[\u0041-\u005a]+.*$/.test(str)){
3746
- return true;
3747
- } else if(/.*[\u0061-\u007a]+.*$/.test(str)){
3748
- return true;
3749
- } else {
3750
- return false;
3751
- }
3752
- },
3753
3783
  //是否包含日语,true:包含
3754
3784
  japanese:function(str){
3755
3785
  if(/.*[\u3040-\u309F\u30A0-\u30FF]+.*$/.test(str)){
@@ -3782,7 +3812,73 @@ var translate = {
3782
3812
  }
3783
3813
  return false;
3784
3814
  },
3785
-
3815
+ //是否包含英文,true:包含
3816
+ english:function(str){
3817
+ if(/.*[\u0041-\u005a]+.*$/.test(str)){
3818
+ return true;
3819
+ } else if(/.*[\u0061-\u007a]+.*$/.test(str)){
3820
+ return true;
3821
+ } else {
3822
+ return false;
3823
+ }
3824
+ },
3825
+ //是否包含 罗曼语族 的特殊字符,因为 法语、西班牙语、意大利语、葡萄牙語 都属于这个语族,单纯判断特殊字符已经不能判断出到底属于哪个语种了
3826
+ romance_dict:['é','è','ê','à','ç','œ','ñ','á','ó','ò','ì','ã','õ'],
3827
+ romance:function(str){
3828
+ if(this.romance_dict.indexOf(str) > -1){
3829
+ return true;
3830
+ } else {
3831
+ return false;
3832
+ }
3833
+ },
3834
+ //对 罗曼语族 的句子进行分析,看它是属于 法语、西班牙语、意大利语、葡萄牙語 的哪个。注意这个是传入的整体的句子,不是传入的单个字符
3835
+ //返回识别的语种: french、spanish、italian、portuguese 如果都没有识别出来,则返回空字符串
3836
+ romanceSentenceAnaly:function(text) {
3837
+ // 定义各语言的典型字母/符号权重 (可调整)
3838
+ const langFeatures = {
3839
+ 'french': { score:0 , chars: ['é','è','ê','à','ç','œ'] },
3840
+ 'spanish': { score:0 , chars: ['ñ','á','ó'], pairs: ['ll'] },
3841
+ 'italian': { score:0 , chars: ['ò','ì'], pairs: ['cc', 'ss'] },
3842
+ 'portuguese': { score:0 , chars: ['ã', 'õ'] }
3843
+ };
3844
+
3845
+ // 逐字扫描 + 相邻配对检测
3846
+ for (let i=0; i<text.length; i++) {
3847
+ const char = text[i].toLowerCase();
3848
+
3849
+ // 单字匹配
3850
+ Object.keys(langFeatures).forEach(lang => {
3851
+ if (langFeatures[lang].chars.includes(char)) {
3852
+ langFeatures[lang].score +=1;
3853
+ }
3854
+ });
3855
+
3856
+ // 双字配对检测 (如 ll)
3857
+ if(i < text.length -1) {
3858
+ const pair = text.slice(i,i+2).toLowerCase();
3859
+ Object.keys(langFeatures).forEach(lang => {
3860
+ const pairs = langFeatures[lang].pairs;
3861
+ if (pairs && pairs.includes(pair)) {
3862
+ langFeatures[lang].score += 2; // pair权重大于单字
3863
+ }
3864
+ });
3865
+ }
3866
+ }
3867
+
3868
+ // 结果判定 (取最高分)
3869
+ let maxLang = '';
3870
+ let maxScore = -1;
3871
+
3872
+ Object.keys(langFeatures).forEach(lang =>{
3873
+ if(langFeatures[lang].score > maxScore){
3874
+ maxScore = langFeatures[lang].score;
3875
+ maxLang = lang;
3876
+ }
3877
+ });
3878
+
3879
+ return maxLang || '';
3880
+ },
3881
+
3786
3882
  //是否包含特殊字符,包含,则是true
3787
3883
  specialCharacter:function(str){
3788
3884
  //如:① ⑴ ⒈
@@ -4251,6 +4347,7 @@ var translate = {
4251
4347
  * @author 刘晓腾
4252
4348
  */
4253
4349
  split:function(array, size, maxSize) {
4350
+ let orgsize = size;
4254
4351
  let list = [];
4255
4352
  // 数组长度小于size,直接进行返回
4256
4353
  if(JSON.stringify(array).length <= size) {
@@ -4308,10 +4405,10 @@ var translate = {
4308
4405
  // 看看是否以引号开头,如果不是,需要拼两个引号
4309
4406
  if (s.startsWith("\"")) {
4310
4407
  // 拼一个引号,-1
4311
- endIndex = s.length() - 1;
4408
+ endIndex = s.length - 1;
4312
4409
  } else {
4313
4410
  // 拼两个引号,-2
4314
- endIndex = s.length() - 2;
4411
+ endIndex = s.length - 2;
4315
4412
  }
4316
4413
  if (!s.endsWith("\"")) {
4317
4414
  // 开始不是逗号了,不能-1
@@ -4348,8 +4445,94 @@ var translate = {
4348
4445
  }
4349
4446
  }
4350
4447
  }
4448
+ // 设置了maxSize,进行处理
4449
+ if (maxSize && maxSize > 0) {
4450
+ list = translate.util._splitMaxSize(list, orgsize, maxSize);
4451
+ }
4351
4452
  return list;
4352
4453
  },
4454
+ /**
4455
+ * 针对split函数中maxSize的处理
4456
+ * private
4457
+ * @param array 已拆分的二维数组
4458
+ * @param size 拆分的长度
4459
+ * @param maxSize 元素数量
4460
+ * @author 刘晓腾
4461
+ */
4462
+ _splitMaxSize:function(array, size, maxSize) {
4463
+ // console.log("------ splitMaxSize run ------")
4464
+
4465
+ // 返回的数据
4466
+ let list = [];
4467
+ // 暂存的数组,用来存储每次遍历时超出的数据
4468
+ let tmp = [];
4469
+
4470
+ // 遍历二维数组
4471
+ array.forEach(function(arr, index) {
4472
+ // 累加数组
4473
+ arr = tmp.concat(arr);
4474
+ // 计算元素数量
4475
+ let length = arr.length;
4476
+ // 数组中元素数量大于maxSize,对多余的元素进行移除
4477
+ if (length > maxSize) {
4478
+ // 第一个数组,包含前N个元素
4479
+ let firstArray = arr.slice(0, maxSize);
4480
+ // 第二个数组,包含剩下的元素
4481
+ let secondArray = arr.slice(maxSize);
4482
+
4483
+ // 处理长度
4484
+ let len = 1;
4485
+ while (JSON.stringify(firstArray).length > size) {
4486
+ // 长度超过限制,进行处理
4487
+ firstArray = arr.slice(0, maxSize - len);
4488
+ secondArray = arr.slice(maxSize - len);
4489
+ len++;
4490
+ if (len >= arr.length+1) {
4491
+ break;
4492
+ }
4493
+ }
4494
+
4495
+ // 第一个数组记录
4496
+ list.push(firstArray);
4497
+ // 第二个数组暂存
4498
+ tmp.length = 0;
4499
+ tmp = secondArray;
4500
+ } else {
4501
+ // 没超,只处理长度
4502
+ // 处理长度
4503
+ let firstArray = arr;
4504
+ let secondArray = [];
4505
+ let len = 1;
4506
+ while (JSON.stringify(firstArray).length > size) {
4507
+ // 长度超过限制,进行处理
4508
+ firstArray = arr.slice(0, maxSize - len);
4509
+ secondArray = arr.slice(maxSize - len);
4510
+ len++;
4511
+ if (len >= arr.length+1) {
4512
+ break;
4513
+ }
4514
+ }
4515
+
4516
+ // 第一个数组记录
4517
+ list.push(firstArray);
4518
+ // 第二个数组暂存
4519
+ tmp.length = 0;
4520
+ tmp = secondArray;
4521
+ }
4522
+
4523
+ });
4524
+
4525
+ // 临时数组中还有元素,也要进行处理
4526
+ if (tmp.length > 0) {
4527
+ let tmpl = [];
4528
+ tmpl.push(tmp);
4529
+ // 递归处理
4530
+ let l = translate.util._splitMaxSize(tmpl, size, maxSize);
4531
+ list = list.concat(l);
4532
+ }
4533
+
4534
+ return list;
4535
+ },
4353
4536
  /*
4354
4537
  浏览器的语种标识跟translate.js的语种标识的对应
4355
4538
  key: 浏览器的语种标识
@@ -4553,7 +4736,7 @@ var translate = {
4553
4736
  */
4554
4737
  translate:function(path, data, func, abnormalFunc){
4555
4738
  var textArray = JSON.parse(decodeURIComponent(data.text));
4556
- let translateTextArray = translate.util.split(textArray, 38000, 0);
4739
+ let translateTextArray = translate.util.split(textArray, 40000, 900);
4557
4740
 
4558
4741
  translate.request.send(translate.service.edge.api.auth, {}, function(auth){
4559
4742
  var from = translate.service.edge.language.getMap()[data.from];
@@ -5120,7 +5303,7 @@ var translate = {
5120
5303
 
5121
5304
  if(typeof(obj) == 'string'){
5122
5305
  //案例一的场景,传入单个字符串
5123
- texts[0] = [obj];
5306
+ texts[0] = obj;
5124
5307
  }else{
5125
5308
  //不是字符串了,而是对象了,判断是案例二还是案例三
5126
5309
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "i18n-jsautotranslate",
3
- "version": "3.13.1",
3
+ "version": "3.13.6",
4
4
  "description": "Two lines of js realize automatic html translation. No need to change the page, no language configuration file, no API key, SEO friendly!",
5
5
  "main": "index.js",
6
6
  "scripts": {