mirror of
https://github.com/element-hq/element-web
synced 2024-11-22 17:25:50 +03:00
Iterate over all instances of variable/tag for _t substitutions
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
efe8254985
commit
b5daba9026
2 changed files with 57 additions and 32 deletions
|
@ -179,12 +179,12 @@ export function replaceByRegexes(text, mapping) {
|
||||||
|
|
||||||
for (const regexpString in mapping) {
|
for (const regexpString in mapping) {
|
||||||
// TODO: Cache regexps
|
// TODO: Cache regexps
|
||||||
const regexp = new RegExp(regexpString);
|
const regexp = new RegExp(regexpString, "g");
|
||||||
|
|
||||||
// Loop over what output we have so far and perform replacements
|
// Loop over what output we have so far and perform replacements
|
||||||
// We look for matches: if we find one, we get three parts: everything before the match, the replaced part,
|
// We look for matches: if we find one, we get three parts: everything before the match, the replaced part,
|
||||||
// and everything after the match. Insert all three into the output. We need to do this because we can insert objects.
|
// and everything after the match. Insert all three into the output. We need to do this because we can insert objects.
|
||||||
// Otherwise there would be no need for the splitting and we could do simple replcement.
|
// Otherwise there would be no need for the splitting and we could do simple replacement.
|
||||||
let matchFoundSomewhere = false; // If we don't find a match anywhere we want to log it
|
let matchFoundSomewhere = false; // If we don't find a match anywhere we want to log it
|
||||||
for (const outputIndex in output) {
|
for (const outputIndex in output) {
|
||||||
const inputText = output[outputIndex];
|
const inputText = output[outputIndex];
|
||||||
|
@ -192,44 +192,58 @@ export function replaceByRegexes(text, mapping) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const match = inputText.match(regexp);
|
// process every match in the string
|
||||||
if (!match) {
|
// starting with the first
|
||||||
continue;
|
let match = regexp.exec(inputText);
|
||||||
}
|
|
||||||
|
if (!match) continue;
|
||||||
matchFoundSomewhere = true;
|
matchFoundSomewhere = true;
|
||||||
|
|
||||||
const capturedGroups = match.slice(2);
|
// The textual part before the first match
|
||||||
|
|
||||||
// The textual part before the match
|
|
||||||
const head = inputText.substr(0, match.index);
|
const head = inputText.substr(0, match.index);
|
||||||
|
|
||||||
// The textual part after the match
|
const parts = [];
|
||||||
const tail = inputText.substr(match.index + match[0].length);
|
// keep track of prevMatch
|
||||||
|
let prevMatch;
|
||||||
|
while (match) {
|
||||||
|
// store prevMatch
|
||||||
|
prevMatch = match;
|
||||||
|
const capturedGroups = match.slice(2);
|
||||||
|
|
||||||
let replaced;
|
let replaced;
|
||||||
// If substitution is a function, call it
|
// If substitution is a function, call it
|
||||||
if (mapping[regexpString] instanceof Function) {
|
if (mapping[regexpString] instanceof Function) {
|
||||||
replaced = mapping[regexpString].apply(null, capturedGroups);
|
replaced = mapping[regexpString].apply(null, capturedGroups);
|
||||||
} else {
|
} else {
|
||||||
replaced = mapping[regexpString];
|
replaced = mapping[regexpString];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof replaced === 'object') {
|
||||||
|
shouldWrapInSpan = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here we also need to check that it actually is a string before comparing against one
|
||||||
|
// The head and tail are always strings
|
||||||
|
if (typeof replaced !== 'string' || replaced !== '') {
|
||||||
|
parts.push(replaced);
|
||||||
|
}
|
||||||
|
|
||||||
|
// try the next match
|
||||||
|
match = regexp.exec(inputText);
|
||||||
|
|
||||||
|
// add the text between prevMatch and this one
|
||||||
|
// or the end of the string if prevMatch is the last match
|
||||||
|
if (match) {
|
||||||
|
const startIndex = prevMatch.index + prevMatch[0].length;
|
||||||
|
parts.push(inputText.substr(startIndex, match.index - startIndex));
|
||||||
|
} else {
|
||||||
|
parts.push(inputText.substr(prevMatch.index + prevMatch[0].length));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof replaced === 'object') {
|
|
||||||
shouldWrapInSpan = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
output.splice(outputIndex, 1); // Remove old element
|
|
||||||
|
|
||||||
// Insert in reverse order as splice does insert-before and this way we get the final order correct
|
// Insert in reverse order as splice does insert-before and this way we get the final order correct
|
||||||
if (tail !== '') {
|
// remove the old element at the same time
|
||||||
output.splice(outputIndex, 0, tail);
|
output.splice(outputIndex, 1, ...parts);
|
||||||
}
|
|
||||||
|
|
||||||
// Here we also need to check that it actually is a string before comparing against one
|
|
||||||
// The head and tail are always strings
|
|
||||||
if (typeof replaced !== 'string' || replaced !== '') {
|
|
||||||
output.splice(outputIndex, 0, replaced);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (head !== '') { // Don't push empty nodes, they are of no use
|
if (head !== '') { // Don't push empty nodes, they are of no use
|
||||||
output.splice(outputIndex, 0, head);
|
output.splice(outputIndex, 0, head);
|
||||||
|
|
|
@ -70,4 +70,15 @@ describe('languageHandler', function() {
|
||||||
const text = '%(var1)s %(var2)s';
|
const text = '%(var1)s %(var2)s';
|
||||||
expect(languageHandler._t(text, { var2: 'val2', var1: 'val1' })).toBe('val1 val2');
|
expect(languageHandler._t(text, { var2: 'val2', var1: 'val1' })).toBe('val1 val2');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('multiple replacements of the same variable', function() {
|
||||||
|
const text = '%(var1)s %(var1)s';
|
||||||
|
expect(languageHandler._t(text, { var1: 'val1' })).toBe('val1 val1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('multiple replacements of the same tag', function() {
|
||||||
|
const text = '<a>Click here</a> to join the discussion! <a>or here</a>';
|
||||||
|
expect(languageHandler._t(text, {}, { 'a': (sub) => `x${sub}x` }))
|
||||||
|
.toBe('xClick herex to join the discussion! xor herex');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue