]>
git.proxmox.com Git - mirror_novnc.git/blob - app/localization.js
2 * noVNC: HTML5 VNC client
3 * Copyright (C) 2012 Joel Martin
4 * Licensed under MPL 2.0 (see LICENSE.txt)
6 * See README.md for usage and integration instructions.
10 * Localization Utilities
13 export function Localizer() {
14 // Currently configured language
17 // Current dictionary of translations
18 this.dictionary
= undefined;
21 Localizer
.prototype = {
22 // Configure suitable language based on user preferences
23 setup: function (supportedLanguages
) {
26 this.language
= 'en'; // Default: US English
29 * Navigator.languages only available in Chrome (32+) and FireFox (32+)
30 * Fall back to navigator.language for other browsers
32 if (typeof window
.navigator
.languages
== 'object') {
33 userLanguages
= window
.navigator
.languages
;
35 userLanguages
= [navigator
.language
|| navigator
.userLanguage
];
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("-");
45 if ((userLang
[0] === 'en') &&
46 ((userLang
[1] === undefined) || (userLang
[1] === 'us'))) {
50 // First pass: perfect match
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("-");
58 if (userLang
[0] !== supLang
[0])
60 if (userLang
[1] !== supLang
[1])
63 this.language
= supportedLanguages
[j
];
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("-");
74 if (userLang
[0] !== supLang
[0])
76 if (supLang
[1] !== undefined)
79 this.language
= supportedLanguages
[j
];
85 // Retrieve localised text
87 if (typeof this.dictionary
!== 'undefined' && this.dictionary
[id
]) {
88 return this.dictionary
[id
];
94 // Traverses the DOM and translates relevant fields
95 // See https://html.spec.whatwg.org/multipage/dom.html#attr-translate
96 translateDOM: function () {
98 function process(elem
, enabled
) {
99 function isAnyOf(searchElement
, items
) {
100 return items
.indexOf(searchElement
) !== -1;
103 function translateAttribute(elem
, attr
) {
104 var str
= elem
.getAttribute(attr
);
106 elem
.setAttribute(attr
, str
);
109 function translateTextNode(node
) {
110 var str
= node
.data
.trim();
115 if (elem
.hasAttribute("translate")) {
116 if (isAnyOf(elem
.getAttribute("translate"), ["", "yes"])) {
118 } else if (isAnyOf(elem
.getAttribute("translate"), ["no"])) {
124 if (elem
.hasAttribute("abbr") &&
125 elem
.tagName
=== "TH") {
126 translateAttribute(elem
, "abbr");
128 if (elem
.hasAttribute("alt") &&
129 isAnyOf(elem
.tagName
, ["AREA", "IMG", "INPUT"])) {
130 translateAttribute(elem
, "alt");
132 if (elem
.hasAttribute("download") &&
133 isAnyOf(elem
.tagName
, ["A", "AREA"])) {
134 translateAttribute(elem
, "download");
136 if (elem
.hasAttribute("label") &&
137 isAnyOf(elem
.tagName
, ["MENUITEM", "MENU", "OPTGROUP",
138 "OPTION", "TRACK"])) {
139 translateAttribute(elem
, "label");
141 // FIXME: Should update "lang"
142 if (elem
.hasAttribute("placeholder") &&
143 isAnyOf(elem
.tagName
, ["INPUT", "TEXTAREA"])) {
144 translateAttribute(elem
, "placeholder");
146 if (elem
.hasAttribute("title")) {
147 translateAttribute(elem
, "title");
149 if (elem
.hasAttribute("value") &&
150 elem
.tagName
=== "INPUT" &&
151 isAnyOf(elem
.getAttribute("type"), ["reset", "button", "submit"])) {
152 translateAttribute(elem
, "value");
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
);
166 process(document
.body
, true);
170 export var l10n
= new Localizer();
171 export default l10n
.get.bind(l10n
);