const translator = {
"output_1": {
"a quick brown fox jumps over a lazy dog": "a fast brown fox jumps ovew a wazy good boy",
"Hello there": "Ello There",
"n": "\ud83d\udc68\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c\udffd"
},
"output_2": {
"a quick brown fox jumps over a lazy dog": "new fox",
"Hello there": "Hey There",
"n": "no"
}
};
document.querySelector("#input_1").addEventListener("input", (e) => {
for (const output of Object.keys(translator)) {
document.querySelector(`#${output}`).value = translate(e.target, output);
}
});
function translate(input, outputSelector) {
const text = input.value;
const currentTranslator = translator[outputSelector];
const translated = replaceOnceUsingDictionary(currentTranslator, text, function(key, dictionary) {
return dictionary[key];
});
return translated;
}
/*
* @description Replaces phrases in a string, based on keys in a given dictionary.
* Each key is used only once, and the replacements are case-insensitive
* @param Object dictionary {key: phrase, ...}
* @param String content
* @param Function replacehandler
* @returns Modified string
*/
function replaceOnceUsingDictionary(dictionary, content, replacehandler) {
if (typeof replacehandler != "function") {
// Default replacehandler function.
replacehandler = function(key, dictionary) {
return dictionary[key];
}
}
var patterns = [], // \b is used to mark boundaries "foo" doesn't match food
patternHash = {},
oldkey, key, index = 0,
output = [];
for (key in dictionary) {
// Case-insensitivity:
key = (oldkey = key).toLowerCase();
dictionary[key] = dictionary[oldkey];
// Sanitize the key, and push it in the list
patterns.push('\\b(?:' + key.replace(/([[^$.|?*+(){}])/g, '\\$1') + ')\\b');
// Add entry to hash variable, for an optimized backtracking at the next loop
patternHash[key] = index++;
}
var pattern = new RegExp(patterns.join('|'), 'gi'),
lastIndex = 0;
// We should actually test using !== null, but for foolproofness,
// we also reject empty strings
while (key = pattern.exec(content)) {
// Case-insensitivity
key = key[0].toLowerCase();
// Add to output buffer
output.push(content.substring(lastIndex, pattern.lastIndex - key.length));
// The next line is the actual replacement method
output.push(replacehandler(key, dictionary));
// Update lastIndex variable
lastIndex = pattern.lastIndex;
// Don't match again by removing the matched word, create new pattern
patterns[patternHash[key]] = '^';
pattern = new RegExp(patterns.join('|'), 'gi');
// IMPORTANT: Update lastIndex property. Otherwise, enjoy an infinite loop
pattern.lastIndex = lastIndex;
}
output.push(content.substring(lastIndex, content.length));
return output.join('');
}
<input id="input_1" class="text-area-main input_mainn" type="text" placeholder="Input Goes Here">
<textarea id="output_1" class="text-area-main"></textarea>
<textarea id="output_2" class="text-area-main"></textarea>