i18n-jsautotranslate 3.13.1 → 3.13.12
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 +68 -82
- package/index.js +554 -52
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
translate.js
|
|
4
4
|
</h1>
|
|
5
5
|
<h4 align="center">
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
AI i18n,两行js实现html全自动翻译。 <br/>
|
|
7
|
+
交给AI,无需改动页面、无语言配置文件、无API Key、对SEO友好!
|
|
8
8
|
</h4>
|
|
9
9
|
<h4 align="center">
|
|
10
10
|
简体中文 |
|
|
@@ -16,27 +16,55 @@
|
|
|
16
16
|
<a href="http://translate.zvo.cn/4019.html?language=french">Français</a>
|
|
17
17
|
</h4>
|
|
18
18
|
|
|
19
|
-
# 寻找合作
|
|
20
|
-
寻找合作伙伴探讨盈利方式 - 以下全自有技术研发
|
|
21
|
-
|
|
22
|
-
1. html源码翻译开放API http://doc.zvo.cn/tcdn/api/doc.html
|
|
23
|
-
2. 企业级翻译通道代理 http://translate.zvo.cn/43262.html
|
|
24
|
-
3. TCDN全自动网站源码级翻译,适合翻译后语种的SEO优化 http://translate.zvo.cn/236896.html
|
|
25
|
-
|
|
26
|
-
联系:17076012262(微信同号) 我们是纯技术团队,欢迎联系,希望能跟你探讨合作盈利商机,我们专心技术,您来拓展商务销售
|
|
27
|
-
|
|
28
|
-
|
|
29
19
|
# 特性说明
|
|
30
|
-
* **使用极其简单。**
|
|
31
|
-
* **不增加工作量。**
|
|
32
|
-
* **极其灵活扩展。** 您可指定它[
|
|
33
|
-
* [
|
|
34
|
-
* [
|
|
35
|
-
* [
|
|
36
|
-
* **搜索引擎友好。** 完全不影响你本身网站搜索引擎的收录。爬虫所爬取的网页源代码,它不会对其进行任何改动,你可完全放心。
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
|
|
20
|
+
* **使用极其简单。** 直接加入几行 JavaScript 代码即可让其拥有上百种语言切换能力。
|
|
21
|
+
* **不增加工作量。** 无需改造页面本身植入大量垃圾代码变得臃肿,也不需要配置各种语种的语言文件,因为它会直接扫描你的DOM自动识别并翻译显示,它不需要你到某某网站登录去申请什么key,它是开源开放的,拿来就能用。
|
|
22
|
+
* **极其灵活扩展。** 您可指定它[只翻译某些指定区域的元素](http://translate.zvo.cn/4063.html)、[自定义切换语言方式及美化](http://translate.zvo.cn/4056.html)、[某些id、class、tag不被翻译](https://translate.zvo.cn/4061.html)、[自定义翻译术语](https://translate.zvo.cn/4070.html) ...... 只要你想的,它都能做到。做不到的,你找我我来让它做到!
|
|
23
|
+
* **自动切换语种。** [自动根据用户的语言喜好及所在的国家切换到这个语种进行浏览](http://translate.zvo.cn/4065.html)
|
|
24
|
+
* **极速翻译能力。** [内置三层缓存、预加载机制,毫秒级瞬间翻译的能力。它并不是你理解的大模型蜗牛似的逐个字往外出的那样](http://translate.zvo.cn/4026.html)
|
|
25
|
+
* [**永久开源免费。** 采用Apache-2.0开源协议,您可永久免费使用](https://github.com/xnx3/translate/blob/master/LICENSE)。[另外你可以用它来做某些系统的三方插件直接售卖盈利](http://translate.zvo.cn/4036.html)、或者你是建站公司用它来做为一项高级功能盈利,我们都是完全认可并支持的,并不需要给我们任何费用!
|
|
26
|
+
* **搜索引擎友好。** 完全不影响你本身网站搜索引擎的收录。爬虫所爬取的网页源代码,它不会对其进行任何改动,你可完全放心。[另外我们还有高级版本让你翻译之后的页面也能被搜索引擎收录](http://translate.zvo.cn/236896.html)
|
|
27
|
+
* **支持私有部署。** [在某些政府机关及大集团内部项目中,对数据隐私及安全保密有强要求场景、或者完全不通外网的场景,可以自行私有部署翻译API服务](http://translate.zvo.cn/4052.html)
|
|
28
|
+
* **全球网络节点**。美洲、亚洲、欧洲 ... 都有网络节点,它能自动适配最快节点,每间隔1分钟自动获取一次延迟最小的节点进行接入使用,使全球范围使用都可高效稳定。
|
|
29
|
+
* **HTML整体翻译**。[提供开放API接口,传入html文件(html源代码)及要翻译为的语言即可拿到翻译后的html源码。完美支持识别各种复杂及不规范html代码,
|
|
30
|
+
支持翻译前的微调,比如不翻译某个区域、图片翻译、js语法操作html文件中的元素进行增删改等。](https://translate.zvo.cn/4022.html)
|
|
31
|
+
* **源站翻译及域名分发**。[将您现有的网站,翻译成全新的小语种网站,小语种网站可以分别绑定域名并支持搜索引擎收录和排名。而您的源站无需任何改动。也就是你可以将你朋友的网站,翻译为小语种网站,绑定上自己的域名,提供对外访问。而你无需向你朋友取得任何的如账号等相关权限](https://translate.zvo.cn/236896.html)
|
|
32
|
+
* **浏览器翻译插件**。[提供整体的浏览器翻译插件的全套方案,您如果是开发者,完全可以拿去将界面美化包装一下,而后直接提交应用市场进行售卖盈利](https://translate.zvo.cn/4037.html)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# 微调指令
|
|
37
|
+
* **[设置默认翻译为的语种](http://translate.zvo.cn/4071.html)**,用户第一次打开时,默认以什么语种显示。
|
|
38
|
+
* **[自定义翻译术语](http://translate.zvo.cn/41555.html)**,如果你感觉某些翻译不太符合你的预期,可进行针对性的定义某些词或句子的翻译结果,进行自定义术语库
|
|
39
|
+
* **[翻译完后自动触发执行](http://translate.zvo.cn/4069.html)**,当翻译完成后会自动触发执行您的某个方法,以便您来做自定义扩展。
|
|
40
|
+
* **[指定翻译服务接口](http://translate.zvo.cn/4068.html)**,如果你不想用我们开源免费的翻译服务接口,使用您自己私有部署的、或者您自己二次开发对接的某个翻译服务,可通过此来指定自己的翻译接口。
|
|
41
|
+
* **[监控页面动态渲染的文本进行自动翻译](http://translate.zvo.cn/4067.html)**,如果页面用 JavaScript 的地方比较多,内容都是随时用JS来控制显示的,比如 VUE、React 等框架做的应用,它可以实时监控DOM中文字的变动,当发生变动后立即识别并进行翻译。
|
|
42
|
+
* **[设置本地语种(当前网页的语种)](http://translate.zvo.cn/4066.html)**,手动指定当前页面的语言。如果不设置,它会自动识别当前网页的文本,取当前网页文本中,出现频率最高的语种为默认语种。
|
|
43
|
+
* **[自动切换为用户所使用的语种](http://translate.zvo.cn/4065.html)**,用户第一次打开网页时,自动判断当前用户所使用的语种、以及所在的国家,来自动进行切换为这个语种。
|
|
44
|
+
* **[主动进行语言切换](http://translate.zvo.cn/4064.html)**,开放一个方法提供程序调用,只需传入翻译的目标语言,即可快速切换到指定语种
|
|
45
|
+
* **[只翻译指定的元素](http://translate.zvo.cn/4063.html)**,指定要翻译的元素的集合,可传入一个或多个元素。如果不设置此,默认翻译整个网页。
|
|
46
|
+
* **[翻译时忽略指定的id](http://translate.zvo.cn/4062.html)**,翻译时追加上自己想忽略不进行翻译的id的值,凡是在这里面的,都不进行翻译,也就是当前元素以及其子元素都不会被翻译。
|
|
47
|
+
* **[翻译时忽略指定的class属性](http://translate.zvo.cn/4061.html)**,翻译时追加上自己想忽略不进行翻译的class标签,凡是在这里面的,都不进行翻译,也就是当前元素以及其子元素都不会被翻译。
|
|
48
|
+
* **[翻译时忽略指定的tag标签](http://translate.zvo.cn/4060.html)**,翻译时追加上自己想忽略不进行翻译的tag标签,凡是在这里面的,都不进行翻译,也就是当前元素以及其子元素都不会被翻译。
|
|
49
|
+
* **[翻译时忽略指定的文字不翻译](http://translate.zvo.cn/283381.html)**,翻译时追加上自己想忽略不进行翻译的文字,凡是在这里面的,都不进行翻译。
|
|
50
|
+
* **[对网页中图片进行翻译](http://translate.zvo.cn/4055.html)**,在进行翻译时,对其中的图片也会一起进行翻译。
|
|
51
|
+
* **[鼠标划词翻译](http://translate.zvo.cn/4072.html)**,鼠标在网页中选中一段文字,会自动出现对应翻译后的文本
|
|
52
|
+
* **[获取当前显示的是什么语种](http://translate.zvo.cn/4074.html)**,如果用户切换为英语进行浏览,那么这个方法将返回翻译的目标语种。
|
|
53
|
+
* **[根据URL传参控制以何种语种显示](http://translate.zvo.cn/41929.html)**,设置可以根据当前访问url的某个get参数来控制使用哪种语言显示。
|
|
54
|
+
* **[离线翻译及自动生成配置](http://translate.zvo.cn/4076.html)**,其实它也就是传统 i18n 的能力,有语言配置文件提供翻译结果。
|
|
55
|
+
* **[手动调用接口进行翻译操作](http://translate.zvo.cn/4077.html)**,通过JavaScript调用一个方法,传入翻译文本进行翻译,并获得翻译结果
|
|
56
|
+
* **[元素的内容整体翻译能力配置](http://translate.zvo.cn/4078.html)**,对node节点的文本拿来进行整体翻译处理,而不再拆分具体语种,提高翻译语句阅读通顺程度
|
|
57
|
+
* **[翻译接口响应捕获处理](http://translate.zvo.cn/4079.html)**,对翻译API接口的响应进行捕获,进行一些自定义扩展
|
|
58
|
+
* **[清除历史翻译语种的缓存](http://translate.zvo.cn/4080.html)**,清除掉你上个页面所记忆的翻译语种,从而达到切换页面时不会按照上个页面翻译语种自动进行翻译的目的。
|
|
59
|
+
* **[网页ajax请求触发自动翻译](http://translate.zvo.cn/4086.html)**,监听当前网页中所有的ajax请求,当请求结束后,自动触发翻译
|
|
60
|
+
* **[设置只对指定语种进行翻译](http://translate.zvo.cn/4085.html)**,翻译时只会翻译在这里设置的语种,未在里面的语种将不会被翻译。
|
|
61
|
+
* **[识别字符串语种及分析](http://translate.zvo.cn/43128.html)**,对字符串进行分析,识别出都有哪些语种,每个语种的字符是什么、每个语种包含的字符数是多少
|
|
62
|
+
* **[重写一级缓存(浏览器缓存)](http://translate.zvo.cn/4082.html)**,你如果不想使用默认的 localStorage 的缓存,您完全可以对其重写,设置自己想使用的缓存方式
|
|
63
|
+
* **[设置使用的翻译服务 translate.service.use](http://translate.zvo.cn/4081.html)**,目前有自有的服务器提供翻译API方式、无自己服务器API的方式两种。
|
|
64
|
+
* **[启用企业级稳定翻译](http://translate.zvo.cn/4087.html)**,独立于开源版本的翻译通道之外,仅对少数用户开放,提供企业级的稳定、高速、以及更多网络分发节点。
|
|
65
|
+
* **[增加对指定标签的属性进行翻译](http://translate.zvo.cn/231504.html)**,可以增加对指定html标签的某个或某些属性进行翻译。比如element、vue 等框架,有些自定义的标签属性,想让其也正常翻译
|
|
66
|
+
* **[本地语种也进行强制翻译](http://translate.zvo.cn/289574.html)**,切换为中文时,即使本地语种设置的是中文,网页中只要不是中文的元素,都会被翻译为要显示的语种
|
|
67
|
+
* **[自定义通过翻译API进行时的监听事件](http://translate.zvo.cn/379207.html)**,当通过翻译API进行文本翻译时的整个过程进行监听,做一些自定义处理,比如翻译API请求前要做些什么、请求翻译API完成并在DOM渲染完毕后触发些什么。
|
|
40
68
|
|
|
41
69
|
# 在线体验
|
|
42
70
|
http://res.zvo.cn/translate/demo.html
|
|
@@ -65,42 +93,6 @@ translate.execute();//进行翻译
|
|
|
65
93
|
</script>
|
|
66
94
|
````
|
|
67
95
|
|
|
68
|
-
# 详细使用
|
|
69
|
-
* [设置默认翻译为的语种](http://translate.zvo.cn/41556.html)
|
|
70
|
-
* [自定义翻译术语](http://translate.zvo.cn/41555.html)
|
|
71
|
-
* [翻译完后自动执行](http://translate.zvo.cn/41554.html)
|
|
72
|
-
* [指定翻译服务接口](http://translate.zvo.cn/41553.html)
|
|
73
|
-
* [监控页面动态渲染的文本进行自动翻译](http://translate.zvo.cn/41552.html)
|
|
74
|
-
* [设置本地语种(当前网页的语种)](http://translate.zvo.cn/41551.html)
|
|
75
|
-
* [自动根据用户所在的国家切换其语种](http://translate.zvo.cn/41550.html)
|
|
76
|
-
* [主动进行语言切换](http://translate.zvo.cn/41549.html)
|
|
77
|
-
* [只翻译指定的元素](http://translate.zvo.cn/41548.html)
|
|
78
|
-
* [翻译时忽略指定的id](http://translate.zvo.cn/41547.html)
|
|
79
|
-
* [翻译时忽略指定的class属性](http://translate.zvo.cn/41546.html)
|
|
80
|
-
* [翻译时忽略指定的tag标签](http://translate.zvo.cn/41545.html)
|
|
81
|
-
* [翻译时忽略指定的文字不翻译](http://translate.zvo.cn/283381.html)
|
|
82
|
-
* [对网页中图片进行翻译](http://translate.zvo.cn/41538.html)
|
|
83
|
-
* [设定切换语言所支持的语种](http://translate.zvo.cn/41544.html)
|
|
84
|
-
* [设定是否自动出现 select 切换语言](http://translate.zvo.cn/41543.html)
|
|
85
|
-
* [CSS美化切换语言按钮](http://translate.zvo.cn/41542.html)
|
|
86
|
-
* [指定切换语言选择框在代码中的位置](http://translate.zvo.cn/41541.html)
|
|
87
|
-
* [对网页中图片进行翻译](http://translate.zvo.cn/41538.html)
|
|
88
|
-
* [鼠标划词翻译](http://translate.zvo.cn/41557.html)
|
|
89
|
-
* [获取当前显示的是什么语种](http://translate.zvo.cn/41761.html)
|
|
90
|
-
* [根据URL传参控制以何种语种显示](http://translate.zvo.cn/41929.html)
|
|
91
|
-
* [离线翻译及自动生成配置](http://translate.zvo.cn/41936.html)
|
|
92
|
-
* [手动调用接口进行翻译操作](http://translate.zvo.cn/41961.html)
|
|
93
|
-
* [元素的内容整体翻译能力配置](http://translate.zvo.cn/42563.html)
|
|
94
|
-
* [翻译接口响应捕获处理](http://translate.zvo.cn/42678.html)
|
|
95
|
-
* [清除历史翻译语种的缓存](http://translate.zvo.cn/43070.html)
|
|
96
|
-
* [网页ajax请求触发自动翻译](http://translate.zvo.cn/43170.html)
|
|
97
|
-
* [设置只对指定语种进行翻译](http://translate.zvo.cn/43133.html)
|
|
98
|
-
* [重新绘制 select 语种下拉选择](http://translate.zvo.cn/43129.html)
|
|
99
|
-
* [识别字符串语种及分析](http://translate.zvo.cn/43128.html)
|
|
100
|
-
* [重写一级缓存(浏览器缓存)](http://translate.zvo.cn/43114.html)
|
|
101
|
-
* [设置使用的翻译服务 translate.service.use](http://translate.zvo.cn/43086.html)
|
|
102
|
-
* [启用企业级稳定翻译](http://translate.zvo.cn/43262.html)
|
|
103
|
-
* [增加对指定标签的属性进行翻译](http://translate.zvo.cn/231504.html)
|
|
104
96
|
|
|
105
97
|
|
|
106
98
|
# 使用示例
|
|
@@ -150,6 +142,8 @@ translate.execute();//进行翻译
|
|
|
150
142
|
# 谁在使用
|
|
151
143
|
|
|
152
144
|
开源项目:
|
|
145
|
+
* [DzzOffice](http://www.dzzoffice.com/index.php?mod=dzzmarket&op=view&mid=58) 开源办公套件,搭建自己的类似“Google企业应用套件”、“微软Office365”的企业协同办公平台
|
|
146
|
+
* [ModStart](https://modstart.com/m/WebTranslate) 基于 Laravel 的模块化全栈开发框架
|
|
153
147
|
* [管伊佳ERP](https://gitee.com/jishenghua/JSH_ERP) 国产开源ERP系统关注度第一,专注进销存、生产、总账
|
|
154
148
|
* [FixIt](https://github.com/hugo-fixit/cmpt-translate) 一款简洁、优雅且先进的Hugo 博客主题
|
|
155
149
|
* [Z-Blog](https://app.zblogcn.com/?id=49226) 易用的博客程序,功能丰富,模板多样,助轻松搭建个性博客。
|
|
@@ -182,16 +176,6 @@ translate.execute();//进行翻译
|
|
|
182
176
|
如果您有开源项目,比如文档、cms、UI 框架、后台管理框架、等等,需要采用此进行多语言切换,欢迎喊我,无偿提供全程接入讨论及遇到的问题跟随优化,希望我们的开源项目能互相产生作用一起越来越好。如果你的项目在这个列表中没有,欢迎联系我说明,我给加入进去。如果您不想出现在这里,也联系我,我给隐去。
|
|
183
177
|
|
|
184
178
|
|
|
185
|
-
# 哪些能力
|
|
186
|
-
#### 能力一:前端翻译
|
|
187
|
-
加入一个js文件及两行js代码,即可让你现有页面具有几百种语种切换能力。零门槛!详细参见 [translate.js](http://translate.zvo.cn/4019.html)
|
|
188
|
-
#### 能力二:翻译html的能力
|
|
189
|
-
传入html源码,指定要范围为什么语种,能将翻译之后的html源码返回。详细参见 [translate.api](http://translate.zvo.cn/41165.html)
|
|
190
|
-
#### 能力三:整站翻译及独立绑定域名
|
|
191
|
-
将您现有的网站,翻译成全新的小语种网站,可以绑定域名并支持搜索引擎收录和排名。基于现有网站,无需改动源站,翻译全站网页,绑定独立域名,保证搜索收录。
|
|
192
|
-
翻译是基于您现有的网站内容,不需要重新建设多语种网站,只需要解析域名到您私有部署的服务器,就可以完成全站翻译。
|
|
193
|
-
详细参见 [TCDN](http://translate.zvo.cn/41159.html)
|
|
194
|
-
|
|
195
179
|
# TCDN部署
|
|
196
180
|
tcdn是translate.js 的高级版本,它的能力是让你原本的网站可以用不同的域名访问到不同的语种。而不同的语种,都可以被收录!它可以免费部署到服务器进行使用。注意,它需要使用个1核2G的服务器进行部署的。
|
|
197
181
|
部署方式有两种:
|
|
@@ -275,27 +259,29 @@ tcdn是translate.js 的高级版本,它的能力是让你原本的网站可以
|
|
|
275
259
|
如果您在使用过程中遇到任何异常情况,请详细说一下您遇到的问题。如果可以,请写下您的网站,以便我们可以更全面地测试,以便快速找到问题所在
|
|
276
260
|
作者微信:xnx3com(使用交流可加QQ群进行,我看微信很不及时)
|
|
277
261
|
Telegram : [untran](https://t.me/untran)
|
|
278
|
-
交流QQ群:240567964
|
|
279
262
|
交流QQ群:181781514 (已满)
|
|
280
263
|
交流QQ群:641047127 (已满)
|
|
264
|
+
交流QQ群:240567964 (快满)
|
|
265
|
+
交流QQ群:1034085260
|
|
281
266
|
微信公众号:wangmarket
|
|
282
267
|
github: [https://github.com/xnx3/translate](https://github.com/xnx3/translate)
|
|
283
268
|
gitee: [https://gitee.com/mail_osc/translate](https://gitee.com/mail_osc/translate)
|
|
284
269
|
|
|
285
|
-
# 有偿帮助
|
|
286
|
-
我们位于三线城市,各方面开发成本相对较低,如果您有临时需要技术人员帮助,欢迎联系我们,也算对我们的支持,让我们能持续下去。
|
|
287
|
-
* Java开发,5年以上经验,65元每小时
|
|
288
|
-
* Java开发,半年经验(主要处理琐碎杂事),25元每小时
|
|
289
|
-
* 前端开发,3年经验(vue、uniapp、微信小程序等都可以),50元每小时
|
|
290
|
-
* Android开发,7年经验,65元每小时
|
|
291
270
|
|
|
292
|
-
|
|
271
|
+
# 寻找合作
|
|
272
|
+
寻找合作伙伴探讨盈利方式 - 以下全自有技术研发
|
|
273
|
+
|
|
274
|
+
1. html源码翻译开放API http://doc.zvo.cn/tcdn/api/doc.html
|
|
275
|
+
2. TCDN全自动网站源码级翻译,适合翻译后语种分别分配域名、进行SEO优化 http://translate.zvo.cn/236896.html
|
|
276
|
+
|
|
277
|
+
联系:17076012262(微信同号) 我们是纯技术团队,欢迎联系,希望能跟你探讨合作盈利商机,我们专心技术,您来拓展商务销售
|
|
293
278
|
|
|
294
279
|
|
|
295
|
-
#
|
|
296
|
-
* [指点云](https://www.zhidianyun.cn/?i125cc1) 赞助服务器,用于开放公共、免费API给大家使用。指点云服务器便宜,性能很不错。
|
|
297
|
-
* AO3读者们,赞助美国服务器,部署全球网络加速节点
|
|
298
|
-
* 微软 提供 client.edge 方式的翻译通道
|
|
299
|
-
* [小牛翻译](https://niutrans.com/register?userSource=translate-js) 赞助在线翻译接口,小牛翻译提供三百八十多种语种翻译能力,需要的语种,它基本都包含了!
|
|
300
|
-
* [如果您想参与赞助,可点此查看更多](https://gitee.com/mail_osc/translate/issues/I7OXEQ),如果有没列出来的,您感觉可以对本项目有帮助的,也欢迎联系我的,感谢大家的支持
|
|
280
|
+
# 商业化声明
|
|
301
281
|
|
|
282
|
+
我完全允许你拿我的开源项目进行商业化包装盈利,而无需给我支付任何费用!
|
|
283
|
+
你能拿来赚钱,那是你的本事。
|
|
284
|
+
而我的开源项目能帮你赚钱,我会很荣幸,我能造福社会。
|
|
285
|
+
你在用它进行商业化盈利的时候,遇到问题也完全可以大方的向我求助,用它赚钱并不是什么偷偷摸摸的事情,技术能用来养家糊口改善生活是值得点赞的。
|
|
286
|
+
而且如果你不放心,我还可以白纸黑字盖章,送你一个定心丸。
|
|
287
|
+
说这么多,是体现一个态度,开源就是开源,我不会想法绑架你。我们可以在一起以最纯粹的状态交流,让生活更美好。
|
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.
|
|
17
|
+
version: '3.13.12.20250307',
|
|
16
18
|
// AUTO_VERSION_END
|
|
17
19
|
/*
|
|
18
20
|
当前使用的版本,默认使用v2. 可使用 setUseVersion2();
|
|
@@ -89,6 +91,7 @@ var translate = {
|
|
|
89
91
|
var selectLanguage = document.createElement("select");
|
|
90
92
|
selectLanguage.id = translate.selectLanguageTag.documentId+'SelectLanguage';
|
|
91
93
|
selectLanguage.className = translate.selectLanguageTag.documentId+'SelectLanguage';
|
|
94
|
+
var to = translate.language.getCurrent();
|
|
92
95
|
for(var i = 0; i<languageList.length; i++){
|
|
93
96
|
var option = document.createElement("option");
|
|
94
97
|
option.setAttribute("value",languageList[i].id);
|
|
@@ -108,10 +111,10 @@ var translate = {
|
|
|
108
111
|
}
|
|
109
112
|
|
|
110
113
|
/*判断默认要选中哪个语言*/
|
|
111
|
-
|
|
114
|
+
|
|
115
|
+
if(to != null && typeof(to) != 'undefined' && to.length > 0){
|
|
112
116
|
//设置了目标语言,那就进行判断显示目标语言
|
|
113
|
-
|
|
114
|
-
if(translate.to == languageList[i].id){
|
|
117
|
+
if(to == languageList[i].id){
|
|
115
118
|
option.setAttribute("selected",'selected');
|
|
116
119
|
}
|
|
117
120
|
}else{
|
|
@@ -339,6 +342,18 @@ var translate = {
|
|
|
339
342
|
}else{
|
|
340
343
|
//不用刷新,直接翻译
|
|
341
344
|
translate.execute(); //翻译
|
|
345
|
+
|
|
346
|
+
//检测是否有iframe中的子页面,如果有,也对子页面下发翻译命令。这个是针对 LayuiAdmin 框架的场景适配,它的主体区域是在 iframe 中的,不能点击切换语言后,只翻译外面的大框,而iframe中的不翻译
|
|
347
|
+
const iframes = document.querySelectorAll('iframe');
|
|
348
|
+
for (let i = 0; i < iframes.length; i++) {
|
|
349
|
+
const iframe = iframes[i];
|
|
350
|
+
// 获取 iframe 的 window 对象
|
|
351
|
+
const iframeWindow = iframe.contentWindow;
|
|
352
|
+
if(typeof(iframeWindow.translate) == 'object' && typeof(iframeWindow.translate.version) == 'string'){
|
|
353
|
+
//iframe页面中存在 translate,那么也控制iframe中的进行翻译
|
|
354
|
+
iframeWindow.translate.execute();
|
|
355
|
+
}
|
|
356
|
+
}
|
|
342
357
|
}
|
|
343
358
|
},
|
|
344
359
|
|
|
@@ -606,7 +621,7 @@ var translate = {
|
|
|
606
621
|
//console.log('beforeChar:'+beforeChar+', str:'+str)
|
|
607
622
|
var lang = translate.language.getCharLanguage(beforeChar);
|
|
608
623
|
//console.log(lang);
|
|
609
|
-
if(lang == 'english'){
|
|
624
|
+
if(lang == 'english' || lang == 'romance'){
|
|
610
625
|
//调出,不能强拆
|
|
611
626
|
continue;
|
|
612
627
|
}
|
|
@@ -621,7 +636,7 @@ var translate = {
|
|
|
621
636
|
//后面有别的字符,判断是什么字符,如果是英文,那么这个是不能被拆分的,要忽略
|
|
622
637
|
afterChar = str.substr(index+originalText.length,1);
|
|
623
638
|
var lang = translate.language.getCharLanguage(afterChar);
|
|
624
|
-
if(lang == 'english'){
|
|
639
|
+
if(lang == 'english' || lang == 'romance'){
|
|
625
640
|
//跳出,不能强拆
|
|
626
641
|
continue;
|
|
627
642
|
}
|
|
@@ -799,13 +814,13 @@ var translate = {
|
|
|
799
814
|
k/v
|
|
800
815
|
二维:对象形态,具体有:
|
|
801
816
|
key:expireTime 当前一维数组key的过期时间,到达过期时间会自动删除掉这个一维数组。如果<0则代表永不删除,常驻内存
|
|
802
|
-
value:list
|
|
817
|
+
value:list 从DOM中自动识别出的语言文本及节点数据,按照语种进行了划分,每个语种便是其中的一项。
|
|
803
818
|
三维:针对二维的value, key:english、chinese_simplified等语种,这里的key便是对value的判断,取value中的要翻译的词是什么语种,对其进行了语种分类 value: k/v
|
|
804
819
|
四维:针对三维的value, key:要翻译的词(经过语种分割的)的hash, value: node数组
|
|
805
820
|
五维:针对四维的value, 这是个对象, 其中
|
|
806
|
-
original: 是三维的key的hash
|
|
821
|
+
original: 是三维的key的hash的原始文字, node 元素中的原始文字(可能是node元素整个内容,也可能是被分割出的某一块内容,比如中英文混合时单独提取中文)
|
|
807
822
|
cacheHash: 如果翻译时匹配到了自定义术语库中的词,那么翻译完后存入到缓存中时,其缓存的翻译前字符串已经不是original,而是匹配完术语库后的文本的hash了。所以这里额外多增加了这个属性。如果匹配了术语库,那这里就是要进行缓存的翻译前文本的hash,如果未使用术语库,这里就跟其key-hash 相同。
|
|
808
|
-
translateText: 针对 original
|
|
823
|
+
translateText: 针对 original 的经过加工过的文字,比如经过自定义术语、以及其他处理操作后的,待进行文本翻译的文字。
|
|
809
824
|
nodes: 有哪些node元素中包含了这个词,都会在这里记录
|
|
810
825
|
六维:针对五维的 nodes,将各个具体的 node 以及 其操作的 attribute 以数组形式列出
|
|
811
826
|
七维:针对六维列出的nodes数组,其中包含:
|
|
@@ -865,6 +880,18 @@ var translate = {
|
|
|
865
880
|
if(document.readyState == 'complete'){
|
|
866
881
|
//dom加载完成,进行启动
|
|
867
882
|
clearInterval(translate.temp_linstenerStartInterval);//停止
|
|
883
|
+
|
|
884
|
+
//如果不需要翻译的情况,是不需要进行监听的
|
|
885
|
+
if(translate.language.getCurrent() == translate.language.getLocal()){
|
|
886
|
+
if(translate.language.translateLocal){
|
|
887
|
+
//本地语种也要强制翻译跟本地语种不一致的语种
|
|
888
|
+
}else{
|
|
889
|
+
//console.log('本地语种跟目标语种一致,不进行翻译操作,无需监听。');
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
//console.log('进行监听。。');
|
|
868
895
|
translate.listener.addListener();
|
|
869
896
|
}
|
|
870
897
|
|
|
@@ -880,6 +907,53 @@ var translate = {
|
|
|
880
907
|
|
|
881
908
|
|
|
882
909
|
},
|
|
910
|
+
/*
|
|
911
|
+
key: nodeid node的唯一标识,格式如 HTML1_BODY1_DIV2_#text1 ,它是使用 nodeuuid.uuid(node) 获得的
|
|
912
|
+
注意,document.getElementById 获得的并不是,需要这样获得 document.getElementById('xx').childNodes[0] 因为它是要给监听dom改动那里用的,监听到的改动的是里面具体的node
|
|
913
|
+
value:13位时间戳
|
|
914
|
+
*/
|
|
915
|
+
ignoreNode:[],
|
|
916
|
+
/*
|
|
917
|
+
通过 translate.execute() 触发的翻译,来使node发生的改动,这种改动加入到 ignoreNode 的过期时间是多少。
|
|
918
|
+
单位是毫秒
|
|
919
|
+
*/
|
|
920
|
+
translateExecuteNodeIgnoreExpireTime:1000,
|
|
921
|
+
/*
|
|
922
|
+
增加一个被listener忽略的节点
|
|
923
|
+
这里通常是用于被 translate.js 本身翻译更改的节点、以及像是 Layui 被翻译后触发了渲染改动了dom , 这几种场景都是翻译本身自己触发的,是不需要再被listener触发,不然就形成死循环了
|
|
924
|
+
node 是哪个节点被listener扫描到改动后忽略。
|
|
925
|
+
可传入 node、也可以传入node的uuid字符串
|
|
926
|
+
expireTime 过期时间,也就是执行当前方法将 node 加入后,过多长时间失效,这里是毫秒,比如传入 500 则这个node在当前时间往后的500毫秒内,如果被listener监听到改动,是直接被忽略的,不会触发任何翻译操作
|
|
927
|
+
*/
|
|
928
|
+
addIgnore:function(node, expireTime){
|
|
929
|
+
let nodeid = '';
|
|
930
|
+
if(typeof(node) == 'string'){
|
|
931
|
+
nodeid = node;
|
|
932
|
+
}else{
|
|
933
|
+
nodeid = nodeuuid.uuid(node);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
translate.listener.ignoreNode[nodeid] = Date.now()+expireTime;
|
|
937
|
+
|
|
938
|
+
//translate.listener.renderTaskFinish();
|
|
939
|
+
},
|
|
940
|
+
/*
|
|
941
|
+
刷新 ignoreNode 中的元素,也就是查找其中 expireTime 过期的,删掉
|
|
942
|
+
*/
|
|
943
|
+
refreshIgnoreNode:function(){
|
|
944
|
+
//console.log('refresh ignore ,current: '+Object.keys(translate.listener.ignoreNode).length);
|
|
945
|
+
var currentTime = Date.now();
|
|
946
|
+
for (const node in translate.listener.ignoreNode) {
|
|
947
|
+
if(translate.listener.ignoreNode[node] < currentTime){
|
|
948
|
+
//console.log('delete : ');
|
|
949
|
+
//console.log(node);
|
|
950
|
+
delete translate.listener.ignoreNode[node];
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
//console.log('refresh ignore finish: '+Object.keys(translate.listener.ignoreNode).length);
|
|
954
|
+
},
|
|
955
|
+
|
|
956
|
+
|
|
883
957
|
//增加监听,开始监听。这个不要直接调用,需要使用上面的 start() 开启
|
|
884
958
|
addListener:function(){
|
|
885
959
|
translate.listener.isStart = true; //记录已执行过启动方法了
|
|
@@ -939,12 +1013,12 @@ var translate = {
|
|
|
939
1013
|
//判断是否属于在正在翻译的节点,重新组合出新的要翻译的node集合
|
|
940
1014
|
var translateNodes = [];
|
|
941
1015
|
//console.log(translate.inProgressNodes.length);
|
|
942
|
-
for(let
|
|
943
|
-
//console.log('---type:'+
|
|
1016
|
+
for(let node of documents){
|
|
1017
|
+
//console.log('---type:'+node.nodeType);
|
|
944
1018
|
|
|
945
1019
|
var find = false;
|
|
946
1020
|
for(var ini = 0; ini < translate.inProgressNodes.length; ini++){
|
|
947
|
-
if(translate.inProgressNodes[ini].node.isSameNode(
|
|
1021
|
+
if(translate.inProgressNodes[ini].node.isSameNode(node)){
|
|
948
1022
|
//有记录了,那么忽略这个node,这个node是因为翻译才导致的变动
|
|
949
1023
|
//console.log('发现相同');
|
|
950
1024
|
find = true;
|
|
@@ -955,10 +1029,19 @@ var translate = {
|
|
|
955
1029
|
continue;
|
|
956
1030
|
}
|
|
957
1031
|
|
|
1032
|
+
//console.log(node);
|
|
1033
|
+
let nodeid = nodeuuid.uuid(node);
|
|
1034
|
+
if(typeof(translate.listener.ignoreNode[nodeid]) == 'number'){
|
|
1035
|
+
if(translate.listener.ignoreNode[nodeid] > Date.now()){
|
|
1036
|
+
//console.log('node 未过忽略期,listener扫描后忽略:'+nodeid);
|
|
1037
|
+
continue;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
|
|
958
1041
|
//不相同,才追加到新的 translateNodes
|
|
959
|
-
translateNodes.push(
|
|
960
|
-
//console.log('listener ++ '+
|
|
961
|
-
//console.log(
|
|
1042
|
+
translateNodes.push(node);
|
|
1043
|
+
//console.log('listener ++ '+node.nodeValue);
|
|
1044
|
+
//console.log(node);
|
|
962
1045
|
}
|
|
963
1046
|
if(translateNodes.length < 1){
|
|
964
1047
|
return;
|
|
@@ -990,7 +1073,45 @@ var translate = {
|
|
|
990
1073
|
*/
|
|
991
1074
|
renderTaskFinish:function(renderTask){
|
|
992
1075
|
//console.log(renderTask);
|
|
993
|
-
}
|
|
1076
|
+
},
|
|
1077
|
+
|
|
1078
|
+
/*
|
|
1079
|
+
翻译执行过程中,相关的监控
|
|
1080
|
+
*/
|
|
1081
|
+
execute:{
|
|
1082
|
+
|
|
1083
|
+
/*
|
|
1084
|
+
每当触发执行 translate.execute() 时,当缓存中未发现,需要请求翻译API进行翻译时,在发送API请求前,触发此
|
|
1085
|
+
*/
|
|
1086
|
+
renderStartByApi : [],
|
|
1087
|
+
renderStartByApiRun:function(uuid){
|
|
1088
|
+
//console.log(translate.nodeQueue[uuid]);
|
|
1089
|
+
for(var i = 0; i < translate.listener.execute.renderStartByApi.length; i++){
|
|
1090
|
+
try{
|
|
1091
|
+
translate.listener.execute.renderStartByApi[i](uuid);
|
|
1092
|
+
}catch(e){
|
|
1093
|
+
console.log(e);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
},
|
|
1097
|
+
|
|
1098
|
+
/*
|
|
1099
|
+
每当 translate.execute() 执行完毕(前提是采用API翻译的,API将翻译结果返回,并且界面上的翻译结果也已经渲染完毕)后,触发此方法。
|
|
1100
|
+
uuid:translate.nodeQueue[uuid] 这里的
|
|
1101
|
+
*/
|
|
1102
|
+
renderFinishByApi : [],
|
|
1103
|
+
renderFinishByApiRun:function(uuid){
|
|
1104
|
+
//console.log(translate.nodeQueue[uuid]);
|
|
1105
|
+
for(var i = 0; i < translate.listener.execute.renderFinishByApi.length; i++){
|
|
1106
|
+
try{
|
|
1107
|
+
translate.listener.execute.renderFinishByApi[i](uuid);
|
|
1108
|
+
}catch(e){
|
|
1109
|
+
console.log(e);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
|
|
994
1115
|
},
|
|
995
1116
|
//对翻译结果进行替换渲染的任务,将待翻译内容替换为翻译内容的过程
|
|
996
1117
|
renderTask:class{
|
|
@@ -1090,6 +1211,9 @@ var translate = {
|
|
|
1090
1211
|
//console.log(this.nodes);
|
|
1091
1212
|
//console.log('===========task======end===');
|
|
1092
1213
|
|
|
1214
|
+
//进行翻译前,先刷新一下 dom监听的忽略node,将过期的node剔除,降低listener的压力
|
|
1215
|
+
translate.listener.refreshIgnoreNode();
|
|
1216
|
+
|
|
1093
1217
|
//对nodeQueue进行翻译
|
|
1094
1218
|
for(var hash in this.nodes){
|
|
1095
1219
|
var tasks = this.taskQueue[hash]; //取出当前node元素对应的替换任务
|
|
@@ -1127,6 +1251,8 @@ var translate = {
|
|
|
1127
1251
|
|
|
1128
1252
|
}, 50, ipnode);
|
|
1129
1253
|
|
|
1254
|
+
//加入 translate.listener.ignoreNode
|
|
1255
|
+
translate.listener.addIgnore(this.nodes[hash][task_index], translate.listener.translateExecuteNodeIgnoreExpireTime);
|
|
1130
1256
|
translate.element.nodeAnalyse.set(this.nodes[hash][task_index], task.originalText, task.resultText, task['attribute']);
|
|
1131
1257
|
|
|
1132
1258
|
|
|
@@ -1277,7 +1403,6 @@ var translate = {
|
|
|
1277
1403
|
},
|
|
1278
1404
|
//当前 translate.translateRequest[uuid] 的是否已经全部执行完毕,这里单纯只是对 translate.translateRequest[uuid] 的进行判断,这里要在 translate.json 接口触发完并渲染完毕后触发,当然接口失败时也要触发
|
|
1279
1405
|
isAllExecuteFinish:function(uuid){
|
|
1280
|
-
|
|
1281
1406
|
for(var lang in translate.translateRequest[uuid]){
|
|
1282
1407
|
for(var i = 0; i<translate.translateRequest[uuid][lang].length; i++){
|
|
1283
1408
|
if(translate.translateRequest[uuid][lang][i].executeFinish == 0){
|
|
@@ -1294,6 +1419,8 @@ var translate = {
|
|
|
1294
1419
|
//都执行完了,那么设置完毕
|
|
1295
1420
|
translate.state = 0;
|
|
1296
1421
|
translate.executeNumber++;
|
|
1422
|
+
|
|
1423
|
+
translate.listener.execute.renderFinishByApiRun(uuid);
|
|
1297
1424
|
}
|
|
1298
1425
|
|
|
1299
1426
|
},
|
|
@@ -1757,7 +1884,7 @@ var translate = {
|
|
|
1757
1884
|
//console.log(translate.nodeQueue[uuid]['list'][lang]);
|
|
1758
1885
|
//console.log(firstScan);
|
|
1759
1886
|
for(var ti=0; ti<twoScan.length; ti++){
|
|
1760
|
-
twoHash = twoScan[ti];
|
|
1887
|
+
var twoHash = twoScan[ti];
|
|
1761
1888
|
//console.log(twoHash + '-- '+firstScan.indexOf(twoHash));
|
|
1762
1889
|
if(firstScan.indexOf(twoHash) == -1){
|
|
1763
1890
|
//需要追加了
|
|
@@ -1867,7 +1994,8 @@ var translate = {
|
|
|
1867
1994
|
//状态
|
|
1868
1995
|
translate.state = 20;
|
|
1869
1996
|
|
|
1870
|
-
|
|
1997
|
+
//listener
|
|
1998
|
+
translate.listener.execute.renderStartByApiRun(uuid);
|
|
1871
1999
|
|
|
1872
2000
|
//进行掉接口翻译
|
|
1873
2001
|
for(var lang_index in fanyiLangs){ //一维数组,取语言
|
|
@@ -1901,7 +2029,7 @@ var translate = {
|
|
|
1901
2029
|
var data = {
|
|
1902
2030
|
from:lang,
|
|
1903
2031
|
to:translate.to,
|
|
1904
|
-
lowercase:translate.whole.isEnableAll? '0':'1', //首字母大写
|
|
2032
|
+
//lowercase:translate.whole.isEnableAll? '0':'1', //首字母大写
|
|
1905
2033
|
//text:JSON.stringify(translateTextArray[lang])
|
|
1906
2034
|
text:encodeURIComponent(JSON.stringify(translateTextArray[lang]))
|
|
1907
2035
|
};
|
|
@@ -1913,7 +2041,7 @@ var translate = {
|
|
|
1913
2041
|
translate.translateRequest[uuid][lang].result = 2;
|
|
1914
2042
|
translate.translateRequest[uuid][lang].executeFinish = 1; //1是执行完毕
|
|
1915
2043
|
translate.translateRequest[uuid][lang].stoptime = Math.floor(Date.now() / 1000);
|
|
1916
|
-
translate.waitingExecute.isAllExecuteFinish();
|
|
2044
|
+
translate.waitingExecute.isAllExecuteFinish(uuid);
|
|
1917
2045
|
console.log('=======ERROR START=======');
|
|
1918
2046
|
console.log(translateTextArray[data.from]);
|
|
1919
2047
|
//console.log(encodeURIComponent(JSON.stringify(translateTextArray[data.from])));
|
|
@@ -1993,12 +2121,14 @@ var translate = {
|
|
|
1993
2121
|
translate.translateRequest[uuid][lang].result = 1;
|
|
1994
2122
|
translate.translateRequest[uuid][lang].executeFinish = 1; //1是执行完毕
|
|
1995
2123
|
translate.translateRequest[uuid][lang].stoptime = Math.floor(Date.now() / 1000);
|
|
1996
|
-
|
|
2124
|
+
setTimeout(function(){
|
|
2125
|
+
translate.waitingExecute.isAllExecuteFinish(uuid);
|
|
2126
|
+
},10);
|
|
1997
2127
|
}, function(xhr){
|
|
1998
2128
|
translate.translateRequest[uuid][lang].executeFinish = 1; //1是执行完毕
|
|
1999
2129
|
translate.translateRequest[uuid][lang].stoptime = Math.floor(Date.now() / 1000);
|
|
2000
2130
|
translate.translateRequest[uuid][lang].result = 3;
|
|
2001
|
-
translate.waitingExecute.isAllExecuteFinish();
|
|
2131
|
+
translate.waitingExecute.isAllExecuteFinish(uuid);
|
|
2002
2132
|
});
|
|
2003
2133
|
/*** 翻译end ***/
|
|
2004
2134
|
}
|
|
@@ -3316,8 +3446,8 @@ var translate = {
|
|
|
3316
3446
|
]
|
|
3317
3447
|
]
|
|
3318
3448
|
}
|
|
3319
|
-
languageName
|
|
3320
|
-
1.
|
|
3449
|
+
languageName 是当前字符串最终判定结果是什么语种。它的识别有以下特点:
|
|
3450
|
+
1. 如果出现英语跟中文、罗曼语族、德语等混合的情况,也就是不纯粹英语的情况,那么会以其他语种为准,而不是识别为英语。不论英语字符出现的比例占多少。
|
|
3321
3451
|
2. 如果出现简体中文跟繁体中文混合的情况,那么识别为繁体中文。不论简体中文字符出现的比例占多少。
|
|
3322
3452
|
3. 除了以上两种规则外,如果出现了多个语种,那么会识别为出现字符数量最多的语种当做当前句子的语种。(注意是字符数,而不是语种的数组数)
|
|
3323
3453
|
languageArray 对传入字符串进行分析,识别出都有哪些语种,每个语种的字符是什么
|
|
@@ -3346,16 +3476,28 @@ var translate = {
|
|
|
3346
3476
|
//过滤 语种的字符数小于总字符数 百分之五的,低于这个数,将忽略
|
|
3347
3477
|
var langkeys = [];
|
|
3348
3478
|
for(var lang in langsNumber){
|
|
3349
|
-
if(langsNumber[lang]/allNumber > 0.
|
|
3479
|
+
if(langsNumber[lang]/allNumber > 0.01){
|
|
3350
3480
|
langkeys[langkeys.length] = lang+'';
|
|
3351
3481
|
}
|
|
3352
3482
|
}
|
|
3353
3483
|
|
|
3354
|
-
|
|
3355
3484
|
if(langkeys.length > 1 && langkeys.indexOf('english') > -1){
|
|
3356
|
-
//console.log('出现了english, 并且english
|
|
3357
|
-
|
|
3358
|
-
|
|
3485
|
+
//console.log('出现了english, 并且english跟其他语种一起出现那么删除english,因为什么法语德语乱七八糟的都有英语。而且中文跟英文一起,如果认为是英文的话,有时候中文会不被翻译');
|
|
3486
|
+
//这里先判断一下是否有发现了 罗曼语族
|
|
3487
|
+
if(langkeys.indexOf('romance') > -1){
|
|
3488
|
+
//发现了,那么判断一下到底是 法语、西班牙语、葡萄牙语、意大利语 中的哪一种呢
|
|
3489
|
+
var romanceSentenceLanguage = translate.language.romanceSentenceAnaly(str);
|
|
3490
|
+
if(romanceSentenceLanguage.length == 0){
|
|
3491
|
+
console.log('语种识别异常,应该是 法语、西班牙语、葡萄牙语、意大利语 中的一种才是,除非是除了这四种语种之外的别的 罗曼语族 中的语种,当前已将 '+ str +'识别为英语。 你可以联系我们求助 https://translate.zvo.cn/4030.html');
|
|
3492
|
+
}else{
|
|
3493
|
+
//console.log(langsNumber);
|
|
3494
|
+
langsNumber[romanceSentenceLanguage] = langsNumber['romance']+langsNumber['english'];
|
|
3495
|
+
//console.log('set romance to '+romanceSentenceLanguage+' : \t'+str);
|
|
3496
|
+
langsNumber['english'] = 0;
|
|
3497
|
+
}
|
|
3498
|
+
}else{
|
|
3499
|
+
langsNumber['english'] = 0;
|
|
3500
|
+
}
|
|
3359
3501
|
}
|
|
3360
3502
|
|
|
3361
3503
|
if(langkeys.indexOf('chinese_simplified') > -1 && langkeys.indexOf('chinese_traditional') > -1){
|
|
@@ -3401,7 +3543,18 @@ var translate = {
|
|
|
3401
3543
|
|
|
3402
3544
|
return result;
|
|
3403
3545
|
},
|
|
3404
|
-
|
|
3546
|
+
/*
|
|
3547
|
+
传入一个char,返回这个char属于什么语种,返回如 如果返回空字符串,那么表示未获取到是什么语种
|
|
3548
|
+
chinese_simplified 简体中文
|
|
3549
|
+
chinese_traditional 繁体中文
|
|
3550
|
+
russian 俄罗斯语
|
|
3551
|
+
english 英语
|
|
3552
|
+
romance 罗曼语族,它是 法语、西班牙语、意大利语、葡萄牙語 的集合,并不是单个语言
|
|
3553
|
+
specialCharacter 特殊字符,符号
|
|
3554
|
+
number 阿拉伯数字
|
|
3555
|
+
japanese 日语
|
|
3556
|
+
korean 韩语
|
|
3557
|
+
*/
|
|
3405
3558
|
getCharLanguage:function(charstr){
|
|
3406
3559
|
if(charstr == null || typeof(charstr) == 'undefined'){
|
|
3407
3560
|
return '';
|
|
@@ -3413,6 +3566,9 @@ var translate = {
|
|
|
3413
3566
|
if(this.english(charstr)){
|
|
3414
3567
|
return 'english';
|
|
3415
3568
|
}
|
|
3569
|
+
if(this.romance(charstr)){
|
|
3570
|
+
return 'romance';
|
|
3571
|
+
}
|
|
3416
3572
|
if(this.specialCharacter(charstr)){
|
|
3417
3573
|
return 'specialCharacter';
|
|
3418
3574
|
}
|
|
@@ -3740,16 +3896,6 @@ var translate = {
|
|
|
3740
3896
|
return '';
|
|
3741
3897
|
}
|
|
3742
3898
|
},
|
|
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
3899
|
//是否包含日语,true:包含
|
|
3754
3900
|
japanese:function(str){
|
|
3755
3901
|
if(/.*[\u3040-\u309F\u30A0-\u30FF]+.*$/.test(str)){
|
|
@@ -3782,7 +3928,73 @@ var translate = {
|
|
|
3782
3928
|
}
|
|
3783
3929
|
return false;
|
|
3784
3930
|
},
|
|
3785
|
-
|
|
3931
|
+
//是否包含英文,true:包含
|
|
3932
|
+
english:function(str){
|
|
3933
|
+
if(/.*[\u0041-\u005a]+.*$/.test(str)){
|
|
3934
|
+
return true;
|
|
3935
|
+
} else if(/.*[\u0061-\u007a]+.*$/.test(str)){
|
|
3936
|
+
return true;
|
|
3937
|
+
} else {
|
|
3938
|
+
return false;
|
|
3939
|
+
}
|
|
3940
|
+
},
|
|
3941
|
+
//是否包含 罗曼语族 的特殊字符,因为 法语、西班牙语、意大利语、葡萄牙語 都属于这个语族,单纯判断特殊字符已经不能判断出到底属于哪个语种了
|
|
3942
|
+
romance_dict:['é','è','ê','à','ç','œ','ñ','á','ó','ò','ì','ã','õ'],
|
|
3943
|
+
romance:function(str){
|
|
3944
|
+
if(this.romance_dict.indexOf(str) > -1){
|
|
3945
|
+
return true;
|
|
3946
|
+
} else {
|
|
3947
|
+
return false;
|
|
3948
|
+
}
|
|
3949
|
+
},
|
|
3950
|
+
//对 罗曼语族 的句子进行分析,看它是属于 法语、西班牙语、意大利语、葡萄牙語 的哪个。注意这个是传入的整体的句子,不是传入的单个字符
|
|
3951
|
+
//返回识别的语种: french、spanish、italian、portuguese 如果都没有识别出来,则返回空字符串
|
|
3952
|
+
romanceSentenceAnaly:function(text) {
|
|
3953
|
+
// 定义各语言的典型字母/符号权重 (可调整)
|
|
3954
|
+
const langFeatures = {
|
|
3955
|
+
'french': { score:0 , chars: ['é','è','ê','à','ç','œ'] },
|
|
3956
|
+
'spanish': { score:0 , chars: ['ñ','á','ó'], pairs: ['ll'] },
|
|
3957
|
+
'italian': { score:0 , chars: ['ò','ì'], pairs: ['cc', 'ss'] },
|
|
3958
|
+
'portuguese': { score:0 , chars: ['ã', 'õ'] }
|
|
3959
|
+
};
|
|
3960
|
+
|
|
3961
|
+
// 逐字扫描 + 相邻配对检测
|
|
3962
|
+
for (let i=0; i<text.length; i++) {
|
|
3963
|
+
const char = text[i].toLowerCase();
|
|
3964
|
+
|
|
3965
|
+
// 单字匹配
|
|
3966
|
+
Object.keys(langFeatures).forEach(lang => {
|
|
3967
|
+
if (langFeatures[lang].chars.includes(char)) {
|
|
3968
|
+
langFeatures[lang].score +=1;
|
|
3969
|
+
}
|
|
3970
|
+
});
|
|
3971
|
+
|
|
3972
|
+
// 双字配对检测 (如 ll)
|
|
3973
|
+
if(i < text.length -1) {
|
|
3974
|
+
const pair = text.slice(i,i+2).toLowerCase();
|
|
3975
|
+
Object.keys(langFeatures).forEach(lang => {
|
|
3976
|
+
const pairs = langFeatures[lang].pairs;
|
|
3977
|
+
if (pairs && pairs.includes(pair)) {
|
|
3978
|
+
langFeatures[lang].score += 2; // pair权重大于单字
|
|
3979
|
+
}
|
|
3980
|
+
});
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
|
|
3984
|
+
// 结果判定 (取最高分)
|
|
3985
|
+
let maxLang = '';
|
|
3986
|
+
let maxScore = -1;
|
|
3987
|
+
|
|
3988
|
+
Object.keys(langFeatures).forEach(lang =>{
|
|
3989
|
+
if(langFeatures[lang].score > maxScore){
|
|
3990
|
+
maxScore = langFeatures[lang].score;
|
|
3991
|
+
maxLang = lang;
|
|
3992
|
+
}
|
|
3993
|
+
});
|
|
3994
|
+
|
|
3995
|
+
return maxLang || '';
|
|
3996
|
+
},
|
|
3997
|
+
|
|
3786
3998
|
//是否包含特殊字符,包含,则是true
|
|
3787
3999
|
specialCharacter:function(str){
|
|
3788
4000
|
//如:① ⑴ ⒈
|
|
@@ -4251,6 +4463,7 @@ var translate = {
|
|
|
4251
4463
|
* @author 刘晓腾
|
|
4252
4464
|
*/
|
|
4253
4465
|
split:function(array, size, maxSize) {
|
|
4466
|
+
let orgsize = size;
|
|
4254
4467
|
let list = [];
|
|
4255
4468
|
// 数组长度小于size,直接进行返回
|
|
4256
4469
|
if(JSON.stringify(array).length <= size) {
|
|
@@ -4308,10 +4521,10 @@ var translate = {
|
|
|
4308
4521
|
// 看看是否以引号开头,如果不是,需要拼两个引号
|
|
4309
4522
|
if (s.startsWith("\"")) {
|
|
4310
4523
|
// 拼一个引号,-1
|
|
4311
|
-
endIndex = s.length
|
|
4524
|
+
endIndex = s.length - 1;
|
|
4312
4525
|
} else {
|
|
4313
4526
|
// 拼两个引号,-2
|
|
4314
|
-
endIndex = s.length
|
|
4527
|
+
endIndex = s.length - 2;
|
|
4315
4528
|
}
|
|
4316
4529
|
if (!s.endsWith("\"")) {
|
|
4317
4530
|
// 开始不是逗号了,不能-1
|
|
@@ -4348,8 +4561,94 @@ var translate = {
|
|
|
4348
4561
|
}
|
|
4349
4562
|
}
|
|
4350
4563
|
}
|
|
4564
|
+
// 设置了maxSize,进行处理
|
|
4565
|
+
if (maxSize && maxSize > 0) {
|
|
4566
|
+
list = translate.util._splitMaxSize(list, orgsize, maxSize);
|
|
4567
|
+
}
|
|
4351
4568
|
return list;
|
|
4352
4569
|
},
|
|
4570
|
+
/**
|
|
4571
|
+
* 针对split函数中maxSize的处理
|
|
4572
|
+
* private
|
|
4573
|
+
* @param array 已拆分的二维数组
|
|
4574
|
+
* @param size 拆分的长度
|
|
4575
|
+
* @param maxSize 元素数量
|
|
4576
|
+
* @author 刘晓腾
|
|
4577
|
+
*/
|
|
4578
|
+
_splitMaxSize:function(array, size, maxSize) {
|
|
4579
|
+
// console.log("------ splitMaxSize run ------")
|
|
4580
|
+
|
|
4581
|
+
// 返回的数据
|
|
4582
|
+
let list = [];
|
|
4583
|
+
// 暂存的数组,用来存储每次遍历时超出的数据
|
|
4584
|
+
let tmp = [];
|
|
4585
|
+
|
|
4586
|
+
// 遍历二维数组
|
|
4587
|
+
array.forEach(function(arr, index) {
|
|
4588
|
+
// 累加数组
|
|
4589
|
+
arr = tmp.concat(arr);
|
|
4590
|
+
// 计算元素数量
|
|
4591
|
+
let length = arr.length;
|
|
4592
|
+
// 数组中元素数量大于maxSize,对多余的元素进行移除
|
|
4593
|
+
if (length > maxSize) {
|
|
4594
|
+
// 第一个数组,包含前N个元素
|
|
4595
|
+
let firstArray = arr.slice(0, maxSize);
|
|
4596
|
+
// 第二个数组,包含剩下的元素
|
|
4597
|
+
let secondArray = arr.slice(maxSize);
|
|
4598
|
+
|
|
4599
|
+
// 处理长度
|
|
4600
|
+
let len = 1;
|
|
4601
|
+
while (JSON.stringify(firstArray).length > size) {
|
|
4602
|
+
// 长度超过限制,进行处理
|
|
4603
|
+
firstArray = arr.slice(0, maxSize - len);
|
|
4604
|
+
secondArray = arr.slice(maxSize - len);
|
|
4605
|
+
len++;
|
|
4606
|
+
if (len >= arr.length+1) {
|
|
4607
|
+
break;
|
|
4608
|
+
}
|
|
4609
|
+
}
|
|
4610
|
+
|
|
4611
|
+
// 第一个数组记录
|
|
4612
|
+
list.push(firstArray);
|
|
4613
|
+
// 第二个数组暂存
|
|
4614
|
+
tmp.length = 0;
|
|
4615
|
+
tmp = secondArray;
|
|
4616
|
+
} else {
|
|
4617
|
+
// 没超,只处理长度
|
|
4618
|
+
// 处理长度
|
|
4619
|
+
let firstArray = arr;
|
|
4620
|
+
let secondArray = [];
|
|
4621
|
+
let len = 1;
|
|
4622
|
+
while (JSON.stringify(firstArray).length > size) {
|
|
4623
|
+
// 长度超过限制,进行处理
|
|
4624
|
+
firstArray = arr.slice(0, maxSize - len);
|
|
4625
|
+
secondArray = arr.slice(maxSize - len);
|
|
4626
|
+
len++;
|
|
4627
|
+
if (len >= arr.length+1) {
|
|
4628
|
+
break;
|
|
4629
|
+
}
|
|
4630
|
+
}
|
|
4631
|
+
|
|
4632
|
+
// 第一个数组记录
|
|
4633
|
+
list.push(firstArray);
|
|
4634
|
+
// 第二个数组暂存
|
|
4635
|
+
tmp.length = 0;
|
|
4636
|
+
tmp = secondArray;
|
|
4637
|
+
}
|
|
4638
|
+
|
|
4639
|
+
});
|
|
4640
|
+
|
|
4641
|
+
// 临时数组中还有元素,也要进行处理
|
|
4642
|
+
if (tmp.length > 0) {
|
|
4643
|
+
let tmpl = [];
|
|
4644
|
+
tmpl.push(tmp);
|
|
4645
|
+
// 递归处理
|
|
4646
|
+
let l = translate.util._splitMaxSize(tmpl, size, maxSize);
|
|
4647
|
+
list = list.concat(l);
|
|
4648
|
+
}
|
|
4649
|
+
|
|
4650
|
+
return list;
|
|
4651
|
+
},
|
|
4353
4652
|
/*
|
|
4354
4653
|
浏览器的语种标识跟translate.js的语种标识的对应
|
|
4355
4654
|
key: 浏览器的语种标识
|
|
@@ -4553,7 +4852,7 @@ var translate = {
|
|
|
4553
4852
|
*/
|
|
4554
4853
|
translate:function(path, data, func, abnormalFunc){
|
|
4555
4854
|
var textArray = JSON.parse(decodeURIComponent(data.text));
|
|
4556
|
-
let translateTextArray = translate.util.split(textArray,
|
|
4855
|
+
let translateTextArray = translate.util.split(textArray, 40000, 900);
|
|
4557
4856
|
|
|
4558
4857
|
translate.request.send(translate.service.edge.api.auth, {}, function(auth){
|
|
4559
4858
|
var from = translate.service.edge.language.getMap()[data.from];
|
|
@@ -4732,14 +5031,13 @@ var translate = {
|
|
|
4732
5031
|
if(storage_hostQueue == null || typeof(storage_hostQueue) == 'undefined'){
|
|
4733
5032
|
//本地存储中没有,也就是之前没设置过,是第一次用,那么直接讲 translate.request.api.host 赋予之
|
|
4734
5033
|
//translate.request.api.host
|
|
4735
|
-
|
|
5034
|
+
|
|
4736
5035
|
if(typeof(translate.request.api.host) == 'string'){
|
|
4737
5036
|
//单个,那么赋予数组形式
|
|
4738
5037
|
//translate.request.speedDetectionControl.hostQueue = [{"host":translate.request.api.host, time:0 }];
|
|
4739
5038
|
translate.request.api.host = [''+translate.request.api.host];
|
|
4740
5039
|
}
|
|
4741
5040
|
|
|
4742
|
-
//console.log(translate.request.api.host)
|
|
4743
5041
|
//数组形态,多个,v2.8.2 增加多个,根据优先级返回
|
|
4744
5042
|
translate.request.speedDetectionControl.hostQueue = [];
|
|
4745
5043
|
for(var i = 0; i<translate.request.api.host.length; i++){
|
|
@@ -5120,7 +5418,7 @@ var translate = {
|
|
|
5120
5418
|
|
|
5121
5419
|
if(typeof(obj) == 'string'){
|
|
5122
5420
|
//案例一的场景,传入单个字符串
|
|
5123
|
-
texts[0] =
|
|
5421
|
+
texts[0] = obj;
|
|
5124
5422
|
}else{
|
|
5125
5423
|
//不是字符串了,而是对象了,判断是案例二还是案例三
|
|
5126
5424
|
|
|
@@ -5607,7 +5905,6 @@ var translate = {
|
|
|
5607
5905
|
return;
|
|
5608
5906
|
}
|
|
5609
5907
|
translate.init_execute = '已进行';
|
|
5610
|
-
|
|
5611
5908
|
try{
|
|
5612
5909
|
translate.request.send(
|
|
5613
5910
|
translate.request.api.init,
|
|
@@ -5639,6 +5936,212 @@ var translate = {
|
|
|
5639
5936
|
);
|
|
5640
5937
|
}catch(e){
|
|
5641
5938
|
}
|
|
5939
|
+
},
|
|
5940
|
+
|
|
5941
|
+
/*
|
|
5942
|
+
翻译执行的进展相关
|
|
5943
|
+
*/
|
|
5944
|
+
progress:{
|
|
5945
|
+
/*
|
|
5946
|
+
通过文本翻译API进行的
|
|
5947
|
+
*/
|
|
5948
|
+
api:{
|
|
5949
|
+
isTip:true,//是否显示ui的提示,true显示,false不显示
|
|
5950
|
+
setUITip:function(tip){
|
|
5951
|
+
translate.progress.api.isTip = tip;
|
|
5952
|
+
},
|
|
5953
|
+
startUITip:function(){
|
|
5954
|
+
// 创建一个 style 元素
|
|
5955
|
+
const style = document.createElement('style');
|
|
5956
|
+
// 设置 style 元素的文本内容为要添加的 CSS 规则
|
|
5957
|
+
style.textContent = `
|
|
5958
|
+
/* CSS部分 */
|
|
5959
|
+
/* 灰色水平加载动画 */
|
|
5960
|
+
.translate_api_in_progress {
|
|
5961
|
+
position: relative;
|
|
5962
|
+
overflow: hidden; /* 隐藏超出部分的动画 */
|
|
5963
|
+
}
|
|
5964
|
+
|
|
5965
|
+
/* 蒙版层 */
|
|
5966
|
+
.translate_api_in_progress::after {
|
|
5967
|
+
content: '';
|
|
5968
|
+
position: absolute;
|
|
5969
|
+
top: 0;
|
|
5970
|
+
left: 0;
|
|
5971
|
+
width: 100%;
|
|
5972
|
+
height: 100%;
|
|
5973
|
+
background: rgba(255, 255, 255, 1); /* 半透明白色遮罩 */
|
|
5974
|
+
z-index: 2;
|
|
5975
|
+
}
|
|
5976
|
+
|
|
5977
|
+
/* 水平加载条动画 */
|
|
5978
|
+
.translate_api_in_progress::before {
|
|
5979
|
+
content: '';
|
|
5980
|
+
position: absolute;
|
|
5981
|
+
top: 50%;
|
|
5982
|
+
left: 0;
|
|
5983
|
+
width: 100%;
|
|
5984
|
+
height:100%; /* 细线高度 */
|
|
5985
|
+
background: linear-gradient(
|
|
5986
|
+
90deg,
|
|
5987
|
+
transparent 0%,
|
|
5988
|
+
#e8e8e8 25%, /* 浅灰色 */
|
|
5989
|
+
#d0d0d0 50%, /* 中灰色 */
|
|
5990
|
+
#e8e8e8 75%, /* 浅灰色 */
|
|
5991
|
+
transparent 100%
|
|
5992
|
+
);
|
|
5993
|
+
background-size: 200% 100%;
|
|
5994
|
+
animation: translate_api_in_progress_horizontal-loader 3.5s linear infinite;
|
|
5995
|
+
z-index: 3;
|
|
5996
|
+
transform: translateY(-50%);
|
|
5997
|
+
}
|
|
5998
|
+
|
|
5999
|
+
@keyframes translate_api_in_progress_horizontal-loader {
|
|
6000
|
+
0% {
|
|
6001
|
+
background-position: 200% 0;
|
|
6002
|
+
}
|
|
6003
|
+
100% {
|
|
6004
|
+
background-position: -200% 0;
|
|
6005
|
+
}
|
|
6006
|
+
}
|
|
6007
|
+
`;
|
|
6008
|
+
// 将 style 元素插入到 head 元素中
|
|
6009
|
+
document.head.appendChild(style);
|
|
6010
|
+
|
|
6011
|
+
|
|
6012
|
+
if(translate.progress.api.isTip){
|
|
6013
|
+
translate.listener.execute.renderStartByApi.push(function(uuid){
|
|
6014
|
+
for(var lang in translate.nodeQueue[uuid].list){
|
|
6015
|
+
if(translate.language.getCurrent() == lang){
|
|
6016
|
+
//忽略这个语种
|
|
6017
|
+
continue;
|
|
6018
|
+
}
|
|
6019
|
+
for(var hash in translate.nodeQueue[uuid].list[lang]){
|
|
6020
|
+
for(var nodeindex in translate.nodeQueue[uuid].list[lang][hash].nodes){
|
|
6021
|
+
var node = translate.nodeQueue[uuid].list[lang][hash].nodes[nodeindex].node;
|
|
6022
|
+
var nodeParent = node.parentNode;
|
|
6023
|
+
if(nodeParent == null){
|
|
6024
|
+
continue;
|
|
6025
|
+
}
|
|
6026
|
+
if(nodeParent.childNodes.length != 1){
|
|
6027
|
+
continue;
|
|
6028
|
+
}
|
|
6029
|
+
|
|
6030
|
+
if(typeof(nodeParent.className) == 'undefined' || nodeParent.className == null || nodeParent.className == ''){
|
|
6031
|
+
nodeParent.className = ' translate_api_in_progress';
|
|
6032
|
+
}else{
|
|
6033
|
+
//这个元素本身有class了,那就追加
|
|
6034
|
+
|
|
6035
|
+
if(nodeParent.className.indexOf('translate_api_in_progress') > -1){
|
|
6036
|
+
continue;
|
|
6037
|
+
}
|
|
6038
|
+
|
|
6039
|
+
nodeParent.className = nodeParent.className+' translate_api_in_progress';
|
|
6040
|
+
}
|
|
6041
|
+
|
|
6042
|
+
}
|
|
6043
|
+
}
|
|
6044
|
+
}
|
|
6045
|
+
});
|
|
6046
|
+
translate.listener.execute.renderFinishByApi.push(function(uuid){
|
|
6047
|
+
for(var lang in translate.nodeQueue[uuid].list){
|
|
6048
|
+
if(translate.language.getCurrent() == lang){
|
|
6049
|
+
//忽略这个语种
|
|
6050
|
+
continue;
|
|
6051
|
+
}
|
|
6052
|
+
for(var hash in translate.nodeQueue[uuid].list[lang]){
|
|
6053
|
+
for(var nodeindex in translate.nodeQueue[uuid].list[lang][hash].nodes){
|
|
6054
|
+
var node = translate.nodeQueue[uuid].list[lang][hash].nodes[nodeindex].node;
|
|
6055
|
+
var nodeParent = node.parentNode;
|
|
6056
|
+
if(nodeParent == null){
|
|
6057
|
+
continue;
|
|
6058
|
+
}
|
|
6059
|
+
|
|
6060
|
+
/*
|
|
6061
|
+
注释这个,因为可能是给这个元素动态追加删除导致其子元素不是11
|
|
6062
|
+
if(nodeParent.childNodes.length != 1){
|
|
6063
|
+
continue;
|
|
6064
|
+
}
|
|
6065
|
+
*/
|
|
6066
|
+
|
|
6067
|
+
var parentClassName = nodeParent.className;
|
|
6068
|
+
if(typeof(parentClassName) == 'undefined' || parentClassName == null || parentClassName == ''){
|
|
6069
|
+
continue;
|
|
6070
|
+
}
|
|
6071
|
+
if(parentClassName.indexOf('translate_api_in_progress') < -1){
|
|
6072
|
+
continue;
|
|
6073
|
+
}
|
|
6074
|
+
|
|
6075
|
+
nodeParent.className = parentClassName.replace(/translate_api_in_progress/g, '');
|
|
6076
|
+
//nodeParent.className = parentClassName.replace(/loading/g, '');
|
|
6077
|
+
}
|
|
6078
|
+
}
|
|
6079
|
+
}
|
|
6080
|
+
});
|
|
6081
|
+
|
|
6082
|
+
}
|
|
6083
|
+
}
|
|
6084
|
+
}
|
|
6085
|
+
},
|
|
6086
|
+
/*
|
|
6087
|
+
对js对象进行翻译
|
|
6088
|
+
obj: 可以是JS定义的 对象、数组、甚至是单个具体的值
|
|
6089
|
+
*/
|
|
6090
|
+
jsObject:function (obj, parentKey = '') {
|
|
6091
|
+
/*
|
|
6092
|
+
存放扫描的结果
|
|
6093
|
+
key 存放要被翻译的文本,也就是对象里面某个具体属性的值
|
|
6094
|
+
value 存放 obj 中的 key (的调取路径),比如 series[0].data[0].name 这个是个数组形态,因为同一个翻译的文本内容有可能会在obj中出现多次
|
|
6095
|
+
*/
|
|
6096
|
+
var kvs = {};
|
|
6097
|
+
|
|
6098
|
+
if (typeof obj === 'object' && obj!== null) {
|
|
6099
|
+
if (Array.isArray(obj)) {
|
|
6100
|
+
// 处理数组
|
|
6101
|
+
obj.forEach((item, index) => {
|
|
6102
|
+
const currentKey = parentKey? `${parentKey}[${index}]` : `[${index}]`;
|
|
6103
|
+
translate.jsObject(item, currentKey);
|
|
6104
|
+
});
|
|
6105
|
+
} else {
|
|
6106
|
+
// 处理普通对象
|
|
6107
|
+
for (const key in obj) {
|
|
6108
|
+
const currentKey = parentKey? `${parentKey}.${key}` : key;
|
|
6109
|
+
if (typeof obj[key] === 'object' && obj[key]!== null) {
|
|
6110
|
+
// 如果值是对象,递归调用函数
|
|
6111
|
+
translate.jsObject(obj[key], currentKey);
|
|
6112
|
+
} else {
|
|
6113
|
+
// 打印键值对
|
|
6114
|
+
|
|
6115
|
+
if(typeof(obj[key]) == 'string'){
|
|
6116
|
+
//console.log(`${currentKey}: ${obj[key]}`);
|
|
6117
|
+
//console.log(obj[key]);
|
|
6118
|
+
//console.log(typeof(kvs[obj[key]]));
|
|
6119
|
+
if(typeof(kvs[obj[key]]) == 'undefined'){
|
|
6120
|
+
kvs[obj[key]] = new Array();
|
|
6121
|
+
}
|
|
6122
|
+
//kvs[obj[key].push(currentKey);
|
|
6123
|
+
}
|
|
6124
|
+
|
|
6125
|
+
}
|
|
6126
|
+
}
|
|
6127
|
+
}
|
|
6128
|
+
} else {
|
|
6129
|
+
// 如果不是对象,直接打印
|
|
6130
|
+
if(typeof(obj) == 'string'){
|
|
6131
|
+
|
|
6132
|
+
if(typeof(obj) == 'string'){
|
|
6133
|
+
//console.log(`${parentKey}: ${obj}`);
|
|
6134
|
+
if(typeof(kvs[obj]) == 'undefined'){
|
|
6135
|
+
kvs[obj] = new Array();
|
|
6136
|
+
}
|
|
6137
|
+
kvs[obj].push('not key');
|
|
6138
|
+
}
|
|
6139
|
+
|
|
6140
|
+
|
|
6141
|
+
}
|
|
6142
|
+
}
|
|
6143
|
+
|
|
6144
|
+
return kvs;
|
|
5642
6145
|
}
|
|
5643
6146
|
|
|
5644
6147
|
|
|
@@ -5710,8 +6213,7 @@ var nodeuuid = {
|
|
|
5710
6213
|
待同事实现
|
|
5711
6214
|
*/
|
|
5712
6215
|
|
|
5713
|
-
}
|
|
5714
|
-
|
|
6216
|
+
},
|
|
5715
6217
|
|
|
5716
6218
|
}
|
|
5717
6219
|
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');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "i18n-jsautotranslate",
|
|
3
|
-
"version": "3.13.
|
|
3
|
+
"version": "3.13.12",
|
|
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": {
|