@tilde-nlp/website-translator 7.1.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.
@@ -0,0 +1,3 @@
1
+ /*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
2
+
3
+ /*! WTW version: v0.0.0 */
@@ -0,0 +1,32 @@
1
+ // Configure your personal API key
2
+ WebsiteTranslator.Options.api.clientId = 'x-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
3
+
4
+ // Step #1: Specify embedded languages of your webpage that has translation already
5
+ WebsiteTranslator.Options.translation.thirdPartyTranslationLanguages = ['en', 'fr']
6
+ // Step #2: Set language of the webpage that is currently rendered
7
+ WebsiteTranslator.Options.currentLanguage = document.documentElement.getAttribute('lang')
8
+ console.log('Current document language: ' + WebsiteTranslator.Options.currentLanguage)
9
+ // Step #3: Add custom logic to use embedded translations instead of machine translation
10
+ WebsiteTranslator.Options.translation.onLanguageSelected = function (selectedLanguage) {
11
+ return new Promise(function (resolve) {
12
+ let translationHandled = false
13
+ console.info('Language selected: ' + selectedLanguage)
14
+ // Check if custom action must be perform to open embedded translation bypassing machine translation process
15
+ if (WebsiteTranslator.Options.translation.thirdPartyTranslationLanguages.includes(selectedLanguage)) {
16
+ translationHandled = true
17
+ if (WebsiteTranslator.Options.currentLanguage !== selectedLanguage) {
18
+ console.info('Redirecting to embedded language version of the page')
19
+ // Add your own logic on how to transform URL of current language to URL of selected target language
20
+ // or other necessary actions.
21
+ // Note. This replacement logic is to transform http://example.com/page_en.html to http://example.com/page_de.html
22
+ // and vice versa.
23
+ window.location.href = window.location.href.replace(/page_\w+/, 'page_' + selectedLanguage)
24
+ // For example, for page https://example.com/en/news to transform to https://example.com/de/news
25
+ // window.location.href = window.location.href.replace(/example.com\/\w+/, "/example.com/" + selectedLanguage)
26
+ }
27
+ }
28
+ resolve(translationHandled)
29
+ })
30
+ }
31
+
32
+ WebsiteTranslator.Initialize()
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html lang="de">
3
+ <head>
4
+ <script src="widget.js"></script>
5
+ </head>
6
+ <body>
7
+ <p>
8
+ Text zur Übersetzung
9
+ </p>
10
+
11
+ <div class="website-translator"></div>
12
+
13
+ <p>
14
+ Text zur Übersetzung
15
+ </p>
16
+
17
+ <script src="main.js"></script>
18
+ </body>
19
+ </html>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <script src="widget.js"></script>
5
+ </head>
6
+ <body>
7
+ <p>According to the United Nations <a href="/wiki/World_Food_Programme" title="World Food Programme">World Food Programme</a>, famine is declared when malnutrition is widespread, and when people have started dying of starvation through lack of access to sufficient,&nbsp;nutritious food.<sup id="cite_ref-3" class="reference"><a href="#cite_note-3">[3]</a></sup> The <a href="/wiki/Integrated_Food_Security_Phase_Classification" title="Integrated Food Security Phase Classification">Integrated Food Security Phase Classification</a> criteria define <i>Phase 5 famine</i> of acute food insecurity as occurring when:<sup id="cite_ref-4" class="reference"><a href="#cite_note-4">[4]</a></sup><sup id="cite_ref-IPC_famine_5-0" class="reference"><a href="#cite_note-IPC_famine-5">[5]</a></sup>
8
+ </p>
9
+
10
+ <div class="website-translator"></div>
11
+
12
+ <script src="main.js"></script>
13
+ </body>
14
+ </html>
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <script src="widget.js"></script>
5
+ </head>
6
+ <body>
7
+ <p>
8
+ Custom content FR
9
+ </p>
10
+
11
+ <div class="website-translator"></div>
12
+
13
+ <script src="main.js"></script>
14
+ </body>
15
+ </html>
@@ -0,0 +1,96 @@
1
+ <!DOCTYPE html>
2
+ <head>
3
+ <!-- Enter correct source code path -->
4
+ <script src="widget.js"></script>
5
+ <style>
6
+ [translate="yes"]{
7
+ color:green;
8
+ }
9
+ [translate="no"]{
10
+ color:crimson;
11
+ }
12
+ </style>
13
+ </head>
14
+ <body>
15
+ <div class="website-translator"></div>
16
+
17
+ <button onclick="translateToLV()">
18
+ Click this button to start translation to Latvian.
19
+ </button><br>
20
+
21
+ <button onclick="translateToLT()">
22
+ Click this button to start translation to Lithuanian.
23
+ </button><br>
24
+
25
+ <button onclick="restoreTranslation()">
26
+ Click this button to stop translation and return page to original state
27
+ </button><br>
28
+
29
+
30
+
31
+ This text will not be translated because of
32
+ <code>
33
+ WebsiteTranslator.Options.translation.translateOnlyAllowedTags = true
34
+ </code>
35
+
36
+ <div translate="yes">
37
+ You can define elements to translate with translate attribute
38
+
39
+ <div translate="no">
40
+ Excluded elements can be child of translatable elements
41
+ <div translate="yes">
42
+ Multiple levels of translate attribute can be processed
43
+ <div translate="no">
44
+ This element will not be translated because of translate attribute
45
+ </div>
46
+ </div>
47
+ </div>
48
+ </div>
49
+
50
+ </body>
51
+
52
+ <footer>
53
+ <script>
54
+ var translatorIsInitialized = false;
55
+ // Configure plugin
56
+ WebsiteTranslator.Options.translation.translateOnlyAllowedTags = true
57
+ WebsiteTranslator.Options.translation.autoTranslate = false
58
+ WebsiteTranslator.Options.debug = true
59
+
60
+ WebsiteTranslator.Options.api.clientId = 'x-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
61
+
62
+ WebsiteTranslator.Initialize().then(function(){
63
+ translatorIsInitialized = true;
64
+ })
65
+ function translateToLV(){
66
+ if(translatorIsInitialized){
67
+ var translationFinish = null
68
+
69
+ // You should always await for translation start
70
+ translationFinish = WebsiteTranslator.Translate("lv").then(function(translationFinish){
71
+ console.log("Translation is started")
72
+ })
73
+ }
74
+ }
75
+
76
+ function translateToLT(){
77
+ if(translatorIsInitialized){
78
+ // But you can call next translation even when previous is not finished
79
+ WebsiteTranslator.Translate("lt").then(function(translationFinish){
80
+ // Or you can await when page is translated
81
+ Promise.all(translationFinish).then(function(){
82
+ console.log("Translation is complete")
83
+ })
84
+ })
85
+ }
86
+ }
87
+
88
+ function restoreTranslation(){
89
+ if(translatorIsInitialized){
90
+ // To restore page in original state
91
+ WebsiteTranslator.CancelAndRestore()
92
+ }
93
+ }
94
+ </script>
95
+ </footer>
96
+ </html>
@@ -0,0 +1,71 @@
1
+ <!DOCTYPE html>
2
+ <head>
3
+ <!-- Enter correct source code path -->
4
+ <script src="widget.js"></script>
5
+ <style>
6
+ [translate="yes"]{
7
+ color:green;
8
+ }
9
+ [translate="no"]{
10
+ color:crimson;
11
+ }
12
+ .website-translator{
13
+ background:ghostwhite;
14
+ }
15
+ </style>
16
+ </head>
17
+ <body>
18
+ <div class="website-translator"></div>
19
+
20
+ <div translate="yes">
21
+ You can define elements to translate with translate attribute
22
+
23
+ <div translate="no">
24
+ Excluded elements can be child of translatable elements
25
+ <div translate="yes">
26
+ Multiple levels of translate attribute can be processed
27
+ <div translate="no">
28
+ This element will not be translated because of translate attribute
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </div>
33
+
34
+ </body>
35
+
36
+ <footer>
37
+ <script>
38
+ // Configure
39
+ WebsiteTranslator.Options.ui.toolbarPosition = "top"
40
+
41
+ WebsiteTranslator.Options.api.clientId = 'x-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
42
+
43
+ var params = new URLSearchParams(window.location.search);
44
+
45
+ // Languages which are already pretranslated and don't need to be machine translated
46
+ var thirdPartyLanguages = ["de", "fr", "sv"];
47
+ WebsiteTranslator.Options.translation.thirdPartyTranslationLanguages = thirdPartyLanguages;
48
+ WebsiteTranslator.Options.translation.onLanguageSelected = function(selectedLanguage) {
49
+ return new Promise(function(resolve) {
50
+ var translationHandled = false;
51
+
52
+ console.info("Selecting language", selectedLanguage);
53
+ if (thirdPartyLanguages.includes(selectedLanguage)) {
54
+ console.info("Switching to third-party language with external code");
55
+ translationHandled = true;
56
+ // Third party translation
57
+
58
+ var newUrl = new URL(window.location.href)
59
+ newUrl.searchParams.set("lang", selectedLanguage)
60
+ window.location.href = newUrl.href
61
+ }
62
+
63
+ resolve(translationHandled);
64
+ });
65
+ };
66
+
67
+ // Initialize and run translations
68
+ WebsiteTranslator.Initialize()
69
+ </script>
70
+ </footer>
71
+ </html>
@@ -0,0 +1,22 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en-US">
3
+ <head>
4
+ <!-- Enter correct source code path -->
5
+ <script src="widget.js" async defer onload="InitWebsiteTranslation()"></script>
6
+ </head>
7
+ <body>
8
+ <div class="website-translator"></div>
9
+
10
+ <script>
11
+ function InitWebsiteTranslation(){
12
+ // Configure
13
+ WebsiteTranslator.Options.api.clientId = 'x-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
14
+
15
+ // ...
16
+
17
+ // Initialize and run translations
18
+ WebsiteTranslator.Initialize()
19
+ }
20
+ </script>
21
+ </body>
22
+ </html>
@@ -0,0 +1,22 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en-US">
3
+ <head>
4
+ <!-- Enter correct source code path -->
5
+ <script src="widget.js" defer></script>
6
+ </head>
7
+ <body>
8
+ <div class="website-translator"></div>
9
+
10
+ <script>
11
+ window.onload = function(){
12
+ // Configure
13
+ WebsiteTranslator.Options.api.clientId = 'x-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
14
+
15
+ // ...
16
+
17
+ // Initialize and run translations
18
+ WebsiteTranslator.Initialize()
19
+ }
20
+ </script>
21
+ </body>
22
+ </html>
package/package.json ADDED
@@ -0,0 +1,87 @@
1
+ {
2
+ "name": "@tilde-nlp/website-translator",
3
+ "description": "Widget to integrate in to another website to translate it",
4
+ "version": "7.1.0",
5
+ "main": "dist/widget.js",
6
+ "directories": {
7
+ "doc": "docs",
8
+ "lib": "dist",
9
+ "example": "example"
10
+ },
11
+ "author": {
12
+ "name": "Tilde, SIA",
13
+ "url": "https://tilde.com"
14
+ },
15
+ "keywords": [
16
+ "translate",
17
+ "translator",
18
+ "html",
19
+ "tilde",
20
+ "webpage",
21
+ "website"
22
+ ],
23
+ "license": "Apache-2.0",
24
+ "scripts": {
25
+ "lint": "standardx --parser @typescript-eslint/parser --plugin @typescript-eslint/eslint-plugin **/*.ts",
26
+ "lint:fix": "standardx --parser @typescript-eslint/parser --plugin @typescript-eslint/eslint-plugin **/*.ts --fix",
27
+ "patch-version": "@powershell -NoProfile -Command ./auto_version_patch.ps1",
28
+ "publish-public-latest": "@powershell -NoProfile -Command ./publish_public_npm.ps1",
29
+ "build:prod": "webpack --mode production",
30
+ "build:dev": "webpack --mode development",
31
+ "start": "webpack serve --progress --mode development"
32
+ },
33
+ "devDependencies": {
34
+ "@typescript-eslint/eslint-plugin": "^5.14.0",
35
+ "@typescript-eslint/parser": "^5.14.0",
36
+ "css-loader": "^6.7.1",
37
+ "ifdef-loader": "^2.3.2",
38
+ "node-sass": "^7.0.1",
39
+ "sass-loader": "^12.6.0",
40
+ "standardx": "^7.0.0",
41
+ "style-loader": "^3.3.1",
42
+ "ts-loader": "^9.2.8",
43
+ "typescript": "^4.6.2",
44
+ "url-loader": "^4.1.1",
45
+ "webpack": "^5.70.0",
46
+ "webpack-cli": "^4.9.2",
47
+ "webpack-dev-server": "^4.7.4"
48
+ },
49
+ "dependencies": {
50
+ "@babel/polyfill": "^7.12.1",
51
+ "axios": "^0.25.0",
52
+ "core-js": "^3.21.1",
53
+ "rxjs": "^7.5.5"
54
+ },
55
+ "eslintConfig": {
56
+ "rules": {
57
+ "object-property-newline": [
58
+ "error",
59
+ {
60
+ "allowAllPropertiesOnSameLine": false
61
+ }
62
+ ],
63
+ "no-var": "error",
64
+ "no-console": "error",
65
+ "brace-style": [
66
+ "error",
67
+ "stroustrup"
68
+ ],
69
+ "no-unused-vars": "off",
70
+ "@typescript-eslint/no-unused-vars": "warn"
71
+ },
72
+ "globals": {
73
+ "EventListenerOrEventListenerObject": "readonly",
74
+ "MutationObserverInit": "readonly"
75
+ },
76
+ "env": {
77
+ "browser": true,
78
+ "node": true
79
+ }
80
+ },
81
+ "standardx": {
82
+ "parser": "@typescript-eslint/parser",
83
+ "plugins": [
84
+ "@typescript-eslint/eslint-plugin"
85
+ ]
86
+ }
87
+ }
@@ -0,0 +1,4 @@
1
+ export enum PluginUILanguageType{
2
+ SOURCE = 'source',
3
+ TARGET = 'target'
4
+ }
@@ -0,0 +1,4 @@
1
+ export enum PluginToolbarPositionType{
2
+ TOP = 'top',
3
+ BOTTOM = 'bottom'
4
+ }
@@ -0,0 +1,149 @@
1
+ // TODO: convert some of the types to enums
2
+
3
+ import { PluginUILanguageType } from '../enums/PluginUILanguageType'
4
+ import { PluginToolbarPositionType } from '../enums/ToolbarPositionType'
5
+
6
+ export interface IPluginOptions{
7
+ /**
8
+ * Source language for machine translation
9
+ * @recomended "en"
10
+ * @required
11
+ */
12
+ sourceLanguage: string,
13
+ /**
14
+ * Current web page language (if the web page is already pre-translated).
15
+ * The language in which the website has been translated.
16
+ * When {currentLanguage} is not equal to {sourceLanguage}, selecting language to translate, plugin will try to get page in {sourceLanguage} by calling {translation.onLanguageSelected({sourceLanguage})}
17
+ * @optional
18
+ * @default null
19
+ */
20
+ currentLanguage: string,
21
+ /**
22
+ * Where is the plugin api and how it connects to it
23
+ */
24
+ api: {
25
+ /**
26
+ * Authorization key which allows plugin to access translation api
27
+ * @required
28
+ */
29
+ clientId: string,
30
+ /**
31
+ * Translation service Uri.
32
+ * @required
33
+ */
34
+ url: string,
35
+ /**
36
+ * API version
37
+ * 1 - older version
38
+ * 2 - version with seperate API endpoint for configuration
39
+ */
40
+ version: number
41
+ },
42
+ /**
43
+ * How plugin translates
44
+ */
45
+ translation: {
46
+ /**
47
+ * Save last translation {target language} and on next page load, automatically translate to it.
48
+ */
49
+ autoTranslate: boolean,
50
+
51
+ targetLanguages:Array<string>
52
+ /**
53
+ * Translate only tags and their children which have [translate="yes"] attribute
54
+ */
55
+ translateOnlyAllowedTags: boolean,
56
+ /**
57
+ * Translate HTML attributes
58
+ */
59
+ translateAttributes: boolean,
60
+ /**
61
+ * Custom actions on selecting languages.
62
+ * If webpage is pre-translated by third-party, then you should handle {sourceLanguage} here too
63
+ * @returns {boolean} Language should be Translated with this Translation plugin
64
+ * Please dont use this, this was requirement, but it is not desired way. Please use your own language menu.
65
+ */
66
+ onLanguageSelected: any,
67
+ /**
68
+ * Define languages which are supposed to be translated with third party
69
+ */
70
+ thirdPartyTranslationLanguages: Array<string>
71
+ },
72
+ /**
73
+ * How plugin looks
74
+ */
75
+ ui: {
76
+ /**
77
+ * Hide MT toolbar with translation progress.
78
+ */
79
+ headless: boolean
80
+ /**
81
+ * Show sign in link for WTW
82
+ */
83
+ showSignInLink: boolean
84
+ /**
85
+ * Translate plugin ui, values can be:
86
+ * source - Show plugin ui in source language
87
+ * target - Show plugin ui in target language
88
+ */
89
+ translate: PluginUILanguageType
90
+ /**
91
+ * Show or hide "restore" and "cancel" translation buttons on Translation Plugin UI
92
+ */
93
+ showTranslationControls: boolean
94
+ /**
95
+ * Change display mode of the language selection in UI, values can be:
96
+ * "menu" - Show available languages in select
97
+ * "list" - Show available languages as list items
98
+ * null - Hide language menu
99
+ * If you wish to add more functionality, please consider use your own language menu?
100
+ */
101
+ layout: string,
102
+ /**
103
+ * How much time to wait after user is started to hover translation to show suggestion popup (in ms)
104
+ */
105
+ tooltipShowDelay: number,
106
+ /**
107
+ * Where toolbar is positioned.
108
+ */
109
+ toolbarPosition: PluginToolbarPositionType,
110
+ /**
111
+ * Main container [HTMLElement] for web page that contains all scrollable content
112
+ */
113
+ mainContentElement: HTMLElement,
114
+ /**
115
+ * Show original text even if public suggestions are set to false
116
+ */
117
+ alwaysShowOriginalTextInPopup: boolean,
118
+ /**
119
+ * Show notification about what service is providing translation.
120
+ */
121
+ showPopupTranslationProvider: boolean,
122
+ /**
123
+ * Show or hide translation popup.
124
+ */
125
+ showPopup: boolean
126
+ /**
127
+ * Show languages in native language for example in Language Menu
128
+ */
129
+ showLanguagesInNativeLanguage: boolean,
130
+ branding:{
131
+ /**
132
+ * Name of provider that provides MT
133
+ */
134
+ name:string,
135
+ /**
136
+ * URL which is used for links to MT
137
+ */
138
+ url:string
139
+ }
140
+ },
141
+ /**
142
+ * Enable verbose logging in console
143
+ */
144
+ debug: boolean,
145
+ /**
146
+ * App id, this is usefull to make seperate statistics
147
+ */
148
+ appID: string
149
+ }
@@ -0,0 +1,6 @@
1
+ $zIndex: 100000;
2
+ $defaultFontFamily: Roboto;
3
+ $iconDefaultColor: invert(59%) sepia(0%) saturate(0%) hue-rotate(117deg) brightness(81%) contrast(82%);
4
+ $defaultFontSize: 14px;
5
+ $defaultTextColor: #000000;
6
+ $defaultAccentColor: #005693;