]> git.proxmox.com Git - mirror_novnc.git/blob - app/localization.js
Add Spanish translation
[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 for (var j = 0;j < supportedLanguages.length;j++) {
52 var supLang = supportedLanguages[j];
53 supLang = supLang.toLowerCase();
54 supLang = supLang.replace("_", "-");
55 supLang = supLang.split("-");
56
57 if (userLang[0] !== supLang[0])
58 continue;
59 if (userLang[1] !== supLang[1])
60 continue;
61
62 this.language = supportedLanguages[j];
63 return;
64 }
65
66 // Second pass: fallback
67 for (var j = 0;j < supportedLanguages.length;j++) {
68 supLang = supportedLanguages[j];
69 supLang = supLang.toLowerCase();
70 supLang = supLang.replace("_", "-");
71 supLang = supLang.split("-");
72
73 if (userLang[0] !== supLang[0])
74 continue;
75 if (supLang[1] !== undefined)
76 continue;
77
78 this.language = supportedLanguages[j];
79 return;
80 }
81 }
82 },
83
84 // Retrieve localised text
85 get: function (id) {
86 if (typeof this.dictionary !== 'undefined' && this.dictionary[id]) {
87 return this.dictionary[id];
88 } else {
89 return id;
90 }
91 },
92
93 // Traverses the DOM and translates relevant fields
94 // See https://html.spec.whatwg.org/multipage/dom.html#attr-translate
95 translateDOM: function () {
96 var self = this;
97 function process(elem, enabled) {
98 function isAnyOf(searchElement, items) {
99 return items.indexOf(searchElement) !== -1;
100 }
101
102 function translateAttribute(elem, attr) {
103 var str = elem.getAttribute(attr);
104 str = self.get(str);
105 elem.setAttribute(attr, str);
106 }
107
108 function translateTextNode(node) {
109 var str = node.data.trim();
110 str = self.get(str);
111 node.data = str;
112 }
113
114 if (elem.hasAttribute("translate")) {
115 if (isAnyOf(elem.getAttribute("translate"), ["", "yes"])) {
116 enabled = true;
117 } else if (isAnyOf(elem.getAttribute("translate"), ["no"])) {
118 enabled = false;
119 }
120 }
121
122 if (enabled) {
123 if (elem.hasAttribute("abbr") &&
124 elem.tagName === "TH") {
125 translateAttribute(elem, "abbr");
126 }
127 if (elem.hasAttribute("alt") &&
128 isAnyOf(elem.tagName, ["AREA", "IMG", "INPUT"])) {
129 translateAttribute(elem, "alt");
130 }
131 if (elem.hasAttribute("download") &&
132 isAnyOf(elem.tagName, ["A", "AREA"])) {
133 translateAttribute(elem, "download");
134 }
135 if (elem.hasAttribute("label") &&
136 isAnyOf(elem.tagName, ["MENUITEM", "MENU", "OPTGROUP",
137 "OPTION", "TRACK"])) {
138 translateAttribute(elem, "label");
139 }
140 // FIXME: Should update "lang"
141 if (elem.hasAttribute("placeholder") &&
142 isAnyOf(elem.tagName, ["INPUT", "TEXTAREA"])) {
143 translateAttribute(elem, "placeholder");
144 }
145 if (elem.hasAttribute("title")) {
146 translateAttribute(elem, "title");
147 }
148 if (elem.hasAttribute("value") &&
149 elem.tagName === "INPUT" &&
150 isAnyOf(elem.getAttribute("type"), ["reset", "button", "submit"])) {
151 translateAttribute(elem, "value");
152 }
153 }
154
155 for (var i = 0;i < elem.childNodes.length;i++) {
156 var node = elem.childNodes[i];
157 if (node.nodeType === node.ELEMENT_NODE) {
158 process(node, enabled);
159 } else if (node.nodeType === node.TEXT_NODE && enabled) {
160 translateTextNode(node);
161 }
162 }
163 }
164
165 process(document.body, true);
166 },
167 };
168
169 export var l10n = new Localizer();
170 export default l10n.get.bind(l10n);