From f4355efb305644335c619fd8e10f94354927e392 Mon Sep 17 00:00:00 2001
From: Peter Jaszkowiak
Date: Sat, 14 Oct 2017 13:47:05 -0600
Subject: [PATCH] Optimize translator
- Use `slice` less
- Skip iterations with `indexOf`
---
public/src/modules/translator.js | 202 ++++++++++++++++---------------
1 file changed, 102 insertions(+), 100 deletions(-)
diff --git a/public/src/modules/translator.js b/public/src/modules/translator.js
index 465a240e4e..c71158c2e2 100644
--- a/public/src/modules/translator.js
+++ b/public/src/modules/translator.js
@@ -111,10 +111,10 @@
var level = 0;
while (i + 2 <= len) {
- if (text.slice(i, i + 2) === '[[') {
+ if (text[i] === '[' && text[i + 1] === '[') {
level += 1;
i += 1;
- } else if (text.slice(i, i + 2) === ']]') {
+ } else if (text[i] === ']' && text[i + 1] === ']') {
level -= 1;
i += 1;
} else if (level === 0 && text[i] === ',' && text[i - 1] !== '\\') {
@@ -128,111 +128,113 @@
return arr;
}
+ // move to the first [[
+ cursor = str.indexOf('[[', cursor);
+
// the loooop, we'll go to where the cursor
// is equal to the length of the string since
// slice doesn't include the ending index
- while (cursor + 2 <= len) {
- // if the current position in the string looks
- // like the beginning of a translation string
- if (str.slice(cursor, cursor + 2) === '[[') {
- // split the string from the last break
- // to the character before the cursor
- // add that to the result array
- toTranslate.push(str.slice(lastBreak, cursor));
- // set the cursor position past the beginning
- // brackets of the translation string
- cursor += 2;
- // set the last break to our current
- // spot since we just broke the string
- lastBreak = cursor;
- // we're in a token now
- inToken = true;
-
- // the current level of nesting of the translation strings
- var level = 0;
- var sliced;
- // validating the current string is actually a translation
- var textBeforeColonFound = false;
- var colonFound = false;
- var textAfterColonFound = false;
- var commaAfterNameFound = false;
-
- while (cursor + 2 <= len) {
- sliced = str.slice(cursor, cursor + 2);
- // found some text after the double bracket,
- // so this is probably a translation string
- if (!textBeforeColonFound && validTextRegex.test(sliced[0])) {
- textBeforeColonFound = true;
- cursor += 1;
- // found a colon, so this is probably a translation string
- } else if (textBeforeColonFound && !colonFound && sliced[0] === ':') {
- colonFound = true;
- cursor += 1;
- // found some text after the colon,
- // so this is probably a translation string
- } else if (colonFound && !textAfterColonFound && validTextRegex.test(sliced[0])) {
- textAfterColonFound = true;
- cursor += 1;
- } else if (textAfterColonFound && !commaAfterNameFound && sliced[0] === ',') {
- commaAfterNameFound = true;
- cursor += 1;
- // a space or comma was found before the name
- // this isn't a translation string, so back out
- } else if (!(textBeforeColonFound && colonFound && textAfterColonFound && commaAfterNameFound) &&
- invalidTextRegex.test(sliced[0])) {
- cursor += 1;
- lastBreak -= 2;
- // no longer in a token
- inToken = false;
- if (level > 0) {
- level -= 1;
- } else {
- break;
- }
- // if we're at the beginning of another translation string,
- // we're nested, so add to our level
- } else if (sliced === '[[') {
- level += 1;
- cursor += 2;
- // if we're at the end of a translation string
- } else if (sliced === ']]') {
- // if we're at the base level, then this is the end
- if (level === 0) {
- // so grab the name and args
- var currentSlice = str.slice(lastBreak, cursor);
- var result = split(currentSlice);
- var name = result[0];
- var args = result.slice(1);
-
- // make a backup based on the raw string of the token
- // if there are arguments to the token
- var backup = '';
- if (args && args.length) {
- backup = this.translate(currentSlice);
- }
- // add the translation promise to the array
- toTranslate.push(this.translateKey(name, args, backup));
- // skip past the ending brackets
- cursor += 2;
- // set this as our last break
- lastBreak = cursor;
- // and we're no longer in a translation string,
- // so continue with the main loop
- inToken = false;
- break;
- }
- // otherwise we lower the level
+ while (cursor + 2 <= len && cursor !== -1) {
+ // split the string from the last break
+ // to the character before the cursor
+ // add that to the result array
+ toTranslate.push(str.slice(lastBreak, cursor));
+ // set the cursor position past the beginning
+ // brackets of the translation string
+ cursor += 2;
+ // set the last break to our current
+ // spot since we just broke the string
+ lastBreak = cursor;
+ // we're in a token now
+ inToken = true;
+
+ // the current level of nesting of the translation strings
+ var level = 0;
+ var char0;
+ var char1;
+ // validating the current string is actually a translation
+ var textBeforeColonFound = false;
+ var colonFound = false;
+ var textAfterColonFound = false;
+ var commaAfterNameFound = false;
+
+ while (cursor + 2 <= len) {
+ char0 = str[cursor];
+ char1 = str[cursor + 1];
+ // found some text after the double bracket,
+ // so this is probably a translation string
+ if (!textBeforeColonFound && validTextRegex.test(char0)) {
+ textBeforeColonFound = true;
+ cursor += 1;
+ // found a colon, so this is probably a translation string
+ } else if (textBeforeColonFound && !colonFound && char0 === ':') {
+ colonFound = true;
+ cursor += 1;
+ // found some text after the colon,
+ // so this is probably a translation string
+ } else if (colonFound && !textAfterColonFound && validTextRegex.test(char0)) {
+ textAfterColonFound = true;
+ cursor += 1;
+ } else if (textAfterColonFound && !commaAfterNameFound && char0 === ',') {
+ commaAfterNameFound = true;
+ cursor += 1;
+ // a space or comma was found before the name
+ // this isn't a translation string, so back out
+ } else if (!(textBeforeColonFound && colonFound && textAfterColonFound && commaAfterNameFound) &&
+ invalidTextRegex.test(char0)) {
+ cursor += 1;
+ lastBreak -= 2;
+ // no longer in a token
+ inToken = false;
+ if (level > 0) {
level -= 1;
- // and skip past the ending brackets
- cursor += 2;
} else {
- // otherwise just move to the next character
- cursor += 1;
+ break;
}
+ // if we're at the beginning of another translation string,
+ // we're nested, so add to our level
+ } else if (char0 === '[' && char1 === '[') {
+ level += 1;
+ cursor += 2;
+ // if we're at the end of a translation string
+ } else if (char0 === ']' && char1 === ']') {
+ // if we're at the base level, then this is the end
+ if (level === 0) {
+ // so grab the name and args
+ var currentSlice = str.slice(lastBreak, cursor);
+ var result = split(currentSlice);
+ var name = result[0];
+ var args = result.slice(1);
+
+ // make a backup based on the raw string of the token
+ // if there are arguments to the token
+ var backup = '';
+ if (args && args.length) {
+ backup = this.translate(currentSlice);
+ }
+ // add the translation promise to the array
+ toTranslate.push(this.translateKey(name, args, backup));
+ // skip past the ending brackets
+ cursor += 2;
+ // set this as our last break
+ lastBreak = cursor;
+ // and we're no longer in a translation string,
+ // so continue with the main loop
+ inToken = false;
+ break;
+ }
+ // otherwise we lower the level
+ level -= 1;
+ // and skip past the ending brackets
+ cursor += 2;
+ } else {
+ // otherwise just move to the next character
+ cursor += 1;
}
}
- // move to the next character
- cursor += 1;
+
+ // skip to the next [[
+ cursor = str.indexOf('[[', cursor);
}
// ending string of source
@@ -304,7 +306,7 @@
* Load translation file (or use a cached version), and optionally return the translation of a certain key
* @param {string} namespace - The file name of the translation namespace
* @param {string} [key] - The key of the specific translation to getJSON
- * @returns {Promise<{ [key: string]: string }>|Promise}
+ * @returns {Promise<{ [key: string]: string } | string>}
*/
Translator.prototype.getTranslation = function getTranslation(namespace, key) {
var translation;