]> git.proxmox.com Git - mirror_novnc.git/blob - app/localization.js
Add eslint and fix reported issues
[mirror_novnc.git] / app / localization.js
1 /*
2 * noVNC: HTML5 VNC client
3 * Copyright (C) 2012 Joel Martin
4 * Licensed under MPL 2.0 (see LICENSE.txt)
5 *
6 * See README.md for usage and integration instructions.
7 */
8
9 /*
10 * Localization Utilities
11 */
12
13 export function Localizer() {
14 // Currently configured language
15 this.language = 'en';
16
17 // Current dictionary of translations
18 this.dictionary = undefined;
19 }
20
21 Localizer.prototype = {
22 // Configure suitable language based on user preferences
23 setup: function (supportedLanguages) {
24 var userLanguages;
25
26 this.language = 'en'; // Default: US English
27
28 /*
29 * Navigator.languages only available in Chrome (32+) and FireFox (32+)
30 * Fall back to navigator.language for other browsers
31 */
32 if (typeof window.navigator.languages == 'object') {
33 userLanguages = window.navigator.languages;
34 } else {
35 userLanguages = [navigator.language || navigator.userLanguage];
36 }
37
38 for (var i = 0;i < userLanguages.length;i++) {
39 var userLang = userLanguages[i];
40 userLang = userLang.toLowerCase();
41 userLang = userLang.replace("_", "-");
42 userLang = userLang.split("-");
43
44 // Built-in default?
45 if ((userLang[0] === 'en') &&
46 ((userLang[1] === undefined) || (userLang[1] === 'us'))) {
47 return;
48 }
49
50 // First pass: perfect match
51 var j;
52 for (j = 0; j < supportedLanguages.length; j++) {
53 var supLang = supportedLanguages[j];
54 supLang = supLang.toLowerCase();
55 supLang = supLang.replace("_", "-");
56 supLang = supLang.split("-");
57
58 if (userLang[0] !== supLang[0])
59 continue;
60 if (userLang[1] !== supLang[1])
61 continue;
62
63 this.language = supportedLanguages[j];
64 return;
65 }
66
67 // Second pass: fallback
68 for (j = 0;j < supportedLanguages.length;j++) {
69 supLang = supportedLanguages[j];
70 supLang = supLang.toLowerCase();
71 supLang = supLang.replace("_", "-");
72 supLang = supLang.split("-");
73
74 if (userLang[0] !== supLang[0])
75 continue;
76 if (supLang[1] !== undefined)
77 continue;
78
79 this.language = supportedLanguages[j];
80 return;
81 }
82 }
83 },
84
85 // Retrieve localised text
86 get: function (id) {
87 if (typeof this.dictionary !== 'undefined' && this.dictionary[id]) {
88 return this.dictionary[id];
89 } else {
90 return id;
91 }
92 },
93
94 // Traverses the DOM and translates relevant fields
95 // See https://html.spec.whatwg.org/multipage/dom.html#attr-translate
96 translateDOM: function () {
97 var self = this;
98 function process(elem, enabled) {
99 function isAnyOf(searchElement, items) {
100 return items.indexOf(searchElement) !== -1;
101 }
102
103 function translateAttribute(elem, attr) {
104 var str = elem.getAttribute(attr);
105 str = self.get(str);
106 elem.setAttribute(attr, str);
107 }
108
109 function translateTextNode(node) {
110 var str = node.data.trim();
111 str = self.get(str);
112 node.data = str;
113 }
114
115 if (elem.hasAttribute("translate")) {
116 if (isAnyOf(elem.getAttribute("translate"), ["", "yes"])) {
117 enabled = true;
118 } else if (isAnyOf(elem.getAttribute("translate"), ["no"])) {
119 enabled = false;
120 }
121 }
122
123 if (enabled) {
124 if (elem.hasAttribute("abbr") &&
125 elem.tagName === "TH") {
126 translateAttribute(elem, "abbr");
127 }
128 if (elem.hasAttribute("alt") &&
129 isAnyOf(elem.tagName, ["AREA", "IMG", "INPUT"])) {
130 translateAttribute(elem, "alt");
131 }
132 if (elem.hasAttribute("download") &&
133 isAnyOf(elem.tagName, ["A", "AREA"])) {
134 translateAttribute(elem, "download");
135 }
136 if (elem.hasAttribute("label") &&
137 isAnyOf(elem.tagName, ["MENUITEM", "MENU", "OPTGROUP",
138 "OPTION", "TRACK"])) {
139 translateAttribute(elem, "label");
140 }
141 // FIXME: Should update "lang"
142 if (elem.hasAttribute("placeholder") &&
143 isAnyOf(elem.tagName, ["INPUT", "TEXTAREA"])) {
144 translateAttribute(elem, "placeholder");
145 }
146 if (elem.hasAttribute("title")) {
147 translateAttribute(elem, "title");
148 }
149 if (elem.hasAttribute("value") &&
150 elem.tagName === "INPUT" &&
151 isAnyOf(elem.getAttribute("type"), ["reset", "button", "submit"])) {
152 translateAttribute(elem, "value");
153 }
154 }
155
156 for (var i = 0;i < elem.childNodes.length;i++) {
157 var node = elem.childNodes[i];
158 if (node.nodeType === node.ELEMENT_NODE) {
159 process(node, enabled);
160 } else if (node.nodeType === node.TEXT_NODE && enabled) {
161 translateTextNode(node);
162 }
163 }
164 }
165
166 process(document.body, true);
167 },
168 };
169
170 export var l10n = new Localizer();
171 export default l10n.get.bind(l10n);