From 1f8ef629e6e8c0c8be6c9fc119c6a2e826fbad46 Mon Sep 17 00:00:00 2001
From: Peter Jaszkowiak
Date: Wed, 17 May 2017 15:59:55 -0600
Subject: [PATCH] Extract in-place translation from bootbox wrapper for use
anywhere
---
public/src/modules/translator.js | 66 +++++++++++++++++++++++++++++++-
public/vendor/bootbox/wrapper.js | 61 ++++-------------------------
2 files changed, 72 insertions(+), 55 deletions(-)
diff --git a/public/src/modules/translator.js b/public/src/modules/translator.js
index afd64317ef..5296e1eef4 100644
--- a/public/src/modules/translator.js
+++ b/public/src/modules/translator.js
@@ -304,7 +304,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|Promise}
+ * @returns {Promise<{ [key: string]: string }>|Promise}
*/
Translator.prototype.getTranslation = function getTranslation(namespace, key) {
var translation;
@@ -324,6 +324,70 @@
return translation;
};
+ /**
+ * @param {Node} node
+ * @returns {Node[]}
+ */
+ function descendantTextNodes(node) {
+ var textNodes = [];
+
+ function helper(node) {
+ if (node.nodeType === 3) {
+ textNodes.push(node);
+ } else {
+ for (var i = 0, c = node.childNodes, l = c.length; i < l; i += 1) {
+ helper(c[i]);
+ }
+ }
+ }
+
+ helper(node);
+ return textNodes;
+ }
+
+ /**
+ * Recursively translate a DOM element in place
+ * @param {Element} element - Root element to translate
+ * @param {string[]} [attributes] - Array of node attributes to translate
+ * @returns {Promise}
+ */
+ Translator.prototype.translateInPlace = function translateInPlace(element, attributes) {
+ attributes = attributes || ['placeholder', 'title'];
+
+ var nodes = descendantTextNodes(element);
+ var text = nodes.map(function (node) {
+ return node.nodeValue;
+ }).join(' || ');
+
+ var attrNodes = attributes.reduce(function (prev, attr) {
+ var tuples = Array.prototype.map.call(element.querySelectorAll('[' + attr + '*="[["]'), function (el) {
+ return [attr, el];
+ });
+ return prev.concat(tuples);
+ }, []);
+ var attrText = attrNodes.map(function (node) {
+ return node[1].getAttribute(node[0]);
+ }).join(' || ');
+
+ return Promise.all([
+ this.translate(text),
+ this.translate(attrText),
+ ]).then(function (ref) {
+ var translated = ref[0];
+ var translatedAttrs = ref[1];
+ if (translated) {
+ translated.split(' || ').forEach(function (html, i) {
+ $(nodes[i]).replaceWith(html);
+ });
+ }
+ if (translatedAttrs) {
+ translatedAttrs.split(' || ').forEach(function (text, i) {
+ attrNodes[i][1].setAttribute(attrNodes[i][0], text);
+ });
+ }
+ });
+ };
+
/**
* Get the language of the current environment, falling back to defaults
* @returns {string}
diff --git a/public/vendor/bootbox/wrapper.js b/public/vendor/bootbox/wrapper.js
index 505b42788f..35efdd8305 100644
--- a/public/vendor/bootbox/wrapper.js
+++ b/public/vendor/bootbox/wrapper.js
@@ -1,67 +1,20 @@
/* global bootbox */
require(['translator'], function (shim) {
- "use strict";
-
- function descendantTextNodes(node) {
- var textNodes = [];
-
- function helper(node) {
- if (node.nodeType === 3) {
- textNodes.push(node);
- } else {
- for (var i = 0, c = node.childNodes, l = c.length; i < l; i += 1) {
- helper(c[i]);
- }
- }
- }
-
- helper(node);
- return textNodes;
- }
+ 'use strict';
var translator = shim.Translator.create();
var dialog = bootbox.dialog;
var attrsToTranslate = ['placeholder', 'title', 'value'];
bootbox.dialog = function (options) {
- var show, $elem, nodes, text, attrNodes, attrText;
-
- show = options.show !== false;
+ var show = options.show !== false;
options.show = false;
- $elem = dialog.call(bootbox, options);
+ var $elem = dialog.call(bootbox, options);
+ var element = $elem[0];
- if (/\[\[.+\]\]/.test($elem[0].outerHTML)) {
- nodes = descendantTextNodes($elem[0]);
- text = nodes.map(function (node) {
- return node.nodeValue;
- }).join(' || ');
-
- attrNodes = attrsToTranslate.reduce(function (prev, attr) {
- return prev.concat(nodes.map.call($elem.find('[' + attr + '*="[["]'), function (el) {
- return [attr, el];
- }));
- }, []);
- attrText = attrNodes.map(function (node) {
- return node[1].getAttribute(node[0]);
- }).join(' || ');
-
- Promise.all([
- translator.translate(text),
- translator.translate(attrText),
- ]).then(function (ref) {
- var translated = ref[0];
- var translatedAttrs = ref[1];
- if (translated) {
- translated.split(' || ').forEach(function (html, i) {
- $(nodes[i]).replaceWith(html);
- });
- }
- if (translatedAttrs) {
- translatedAttrs.split(' || ').forEach(function (text, i) {
- attrNodes[i][1].setAttribute(attrNodes[i][0], text);
- });
- }
+ if (/\[\[.+\]\]/.test(element.outerHTML)) {
+ translator.translateInPlace(element, attrsToTranslate).then(function () {
if (show) {
$elem.modal('show');
}
@@ -84,7 +37,7 @@ require(['translator'], function (shim) {
CANCEL: translations[1],
CONFIRM: translations[2],
});
-
+
bootbox.setLocale(lang);
});
});