3 * Handles the JavaScript side of translating strings
4 * in a way which fits with Laravel.
9 * Create an instance, Passing in the required translations
12 constructor(translations) {
13 this.store = new Map();
14 this.parseTranslations();
18 * Parse translations out of the page and place into the store.
21 const translationMetaTags = document.querySelectorAll('meta[name="translation"]');
22 for (let tag of translationMetaTags) {
23 const key = tag.getAttribute('key');
24 const value = tag.getAttribute('value');
25 this.store.set(key, value);
30 * Get a translation, Same format as laravel's 'trans' helper
35 get(key, replacements) {
36 const text = this.getTransText(key);
37 return this.performReplacements(text, replacements);
41 * Get pluralised text, Dependant on the given count.
42 * Same format at laravel's 'trans_choice' helper.
48 getPlural(key, count, replacements) {
49 const text = this.getTransText(key);
50 return this.parsePlural(text, count, replacements);
54 * Parse the given translation and find the correct plural option
55 * to use. Similar format at laravel's 'trans_choice' helper.
56 * @param {String} translation
57 * @param {Number} count
58 * @param {Object} replacements
61 parsePlural(translation, count, replacements) {
62 const splitText = translation.split('|');
63 const exactCountRegex = /^{([0-9]+)}/;
64 const rangeRegex = /^\[([0-9]+),([0-9*]+)]/;
67 for (let t of splitText) {
68 // Parse exact matches
69 const exactMatches = t.match(exactCountRegex);
70 if (exactMatches !== null && Number(exactMatches[1]) === count) {
71 result = t.replace(exactCountRegex, '').trim();
75 // Parse range matches
76 const rangeMatches = t.match(rangeRegex);
77 if (rangeMatches !== null) {
78 const rangeStart = Number(rangeMatches[1]);
79 if (rangeStart <= count && (rangeMatches[2] === '*' || Number(rangeMatches[2]) >= count)) {
80 result = t.replace(rangeRegex, '').trim();
86 if (result === null && splitText.length > 1) {
87 result = (count === 1) ? splitText[0] : splitText[1];
90 if (result === null) {
91 result = splitText[0];
94 return this.performReplacements(result, replacements);
98 * Fetched translation text from the store for the given key.
100 * @returns {String|Object}
103 const value = this.store.get(key);
105 if (value === undefined) {
106 console.warn(`Translation with key "${key}" does not exist`);
113 * Perform replacements on a string.
114 * @param {String} string
115 * @param {Object} replacements
118 performReplacements(string, replacements) {
119 if (!replacements) return string;
120 const replaceMatches = string.match(/:([\S]+)/g);
121 if (replaceMatches === null) return string;
122 replaceMatches.forEach(match => {
123 const key = match.substring(1);
124 if (typeof replacements[key] === 'undefined') return;
125 string = string.replace(match, replacements[key]);
132 export default Translator;