/
LanguageControl.ts
97 lines (85 loc) · 2.87 KB
/
LanguageControl.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import getLanguageField from './getLanguageField';
import localizeTextField from './localizeTextField';
import Base from '../Base/Base';
const SUPPORTED_LANGUAGES = [
'en',
'es',
'fr',
'de',
'ru',
'zh',
'pt',
'ar',
'ja',
'ko',
'mul',
];
interface LanguageControlOptions {
/** (supported languages)[https://docs.mapbox.com/help/troubleshooting/change-language/] */
supportedLanguages?: string[];
/** one of the supported languages to apply */
language?: string;
/** Accepts language and returns language field. By default fields are `name_LANGUAGE` and `name` for multi language (mul) */
getLanguageField?: (language: string) => string;
/** Array of layer id to exclude from localization */
excludedLayerIds?: string[];
}
export default class LanguageControl extends Base {
supportedLanguages: string[];
language: string;
getLanguageField: (language: string) => string;
excludedLayerIds: string[];
constructor(options?: LanguageControlOptions) {
super();
this.supportedLanguages = SUPPORTED_LANGUAGES;
this.getLanguageField = getLanguageField;
this.excludedLayerIds = [];
this.language = options?.language;
if (options?.supportedLanguages) {
this.supportedLanguages = options.supportedLanguages;
}
if (options?.getLanguageField) {
this.getLanguageField = options.getLanguageField;
}
if (options?.excludedLayerIds) {
this.excludedLayerIds = options.excludedLayerIds;
}
this.styleChangeListener = this.styleChangeListener.bind(this);
}
onAddControl() {
this.map.on('styledata', this.styleChangeListener);
}
onRemoveControl() {
this.map.off('styledata', this.styleChangeListener);
}
styleChangeListener() {
this.map.off('styledata', this.styleChangeListener);
this.setLanguage(this.language);
}
setLanguage(lang = this.browserLanguage()) {
const language = this.supportedLanguages.indexOf(lang) < 0 ? 'mul' : lang;
const style = this.map.getStyle();
const languageField = this.getLanguageField(language);
const layers = style.layers.map((layer) => {
if (layer.type !== 'symbol') return layer;
if (!layer.layout || !layer.layout['text-field']) return layer;
if (this.excludedLayerIds.indexOf(layer.id) !== -1) return layer;
const textField = layer.layout['text-field'];
const textFieldLocalized = localizeTextField(textField, languageField);
return {
...layer,
layout: { ...layer.layout, 'text-field': textFieldLocalized },
};
});
this.map.setStyle({ ...style, layers });
}
browserLanguage() {
const language = navigator.languages
? navigator.languages[0]
: navigator.language;
const parts = language.split('-');
const languageCode = parts.length > 1 ? parts[0] : language;
if (this.supportedLanguages.indexOf(languageCode) > -1) return languageCode;
return 'mul';
}
}