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); }); });