3 * Handles the JavaScript side of translating strings
4 * in a way which fits with Laravel.
9 this.store = new Map();
10 this.parseTranslations();
14 * Parse translations out of the page and place into the store.
17 const translationMetaTags = document.querySelectorAll('meta[name="translation"]');
18 for (const tag of translationMetaTags) {
19 const key = tag.getAttribute('key');
20 const value = tag.getAttribute('value');
21 this.store.set(key, value);
26 * Get a translation, Same format as Laravel's 'trans' helper
31 get(key, replacements) {
32 const text = this.getTransText(key);
33 return this.performReplacements(text, replacements);
37 * Get pluralised text, Dependent on the given count.
38 * Same format at Laravel's 'trans_choice' helper.
44 getPlural(key, count, replacements) {
45 const text = this.getTransText(key);
46 return this.parsePlural(text, count, replacements);
50 * Parse the given translation and find the correct plural option
51 * to use. Similar format at Laravel's 'trans_choice' helper.
52 * @param {String} translation
53 * @param {Number} count
54 * @param {Object} replacements
57 parsePlural(translation, count, replacements) {
58 const splitText = translation.split('|');
59 const exactCountRegex = /^{([0-9]+)}/;
60 const rangeRegex = /^\[([0-9]+),([0-9*]+)]/;
63 for (const t of splitText) {
64 // Parse exact matches
65 const exactMatches = t.match(exactCountRegex);
66 if (exactMatches !== null && Number(exactMatches[1]) === count) {
67 result = t.replace(exactCountRegex, '').trim();
71 // Parse range matches
72 const rangeMatches = t.match(rangeRegex);
73 if (rangeMatches !== null) {
74 const rangeStart = Number(rangeMatches[1]);
75 if (rangeStart <= count && (rangeMatches[2] === '*' || Number(rangeMatches[2]) >= count)) {
76 result = t.replace(rangeRegex, '').trim();
82 if (result === null && splitText.length > 1) {
83 result = (count === 1) ? splitText[0] : splitText[1];
86 if (result === null) {
87 result = splitText[0];
90 return this.performReplacements(result, replacements);
94 * Fetched translation text from the store for the given key.
96 * @returns {String|Object}
99 const value = this.store.get(key);
101 if (value === undefined) {
102 console.warn(`Translation with key "${key}" does not exist`);
109 * Perform replacements on a string.
110 * @param {String} string
111 * @param {Object} replacements
114 performReplacements(string, replacements) {
115 if (!replacements) return string;
116 const replaceMatches = string.match(/:(\S+)/g);
117 if (replaceMatches === null) return string;
118 let updatedString = string;
120 replaceMatches.forEach(match => {
121 const key = match.substring(1);
122 if (typeof replacements[key] === 'undefined') return;
123 updatedString = updatedString.replace(match, replacements[key]);
126 return updatedString;
131 export default Translator;