UNPKG

2.73 kBJavaScriptView Raw
1/*
2 *
3 * Message Translation and Bundling
4 *
5 */
6
7import traverse from 'babel-traverse';
8
9import {
10 convertNamespacedNameToIdAttribute,
11 idOrComponentName,
12 isElement,
13 isElementMarker,
14 removeIdAttribute
15} from './ast';
16import generate from './generation';
17import freeVariablesInMessage from './free-variables';
18import {options} from './options';
19import parsing from './parsing';
20import {validateTranslation, sanitizedAttributesOf, validateMessage} from './validation';
21
22
23export default function translatedRendererFor(markerNode, translatedMessage, originalMessage) {
24 try {
25 let unprintedTranslation;
26 let freeVars = [];
27 if (isElement(markerNode)) {
28 const translated = parsing.parse(
29 `<${options.elementMarker}>${translatedMessage}</${options.elementMarker}>
30 `);
31 freeVars = freeVariablesInMessage(markerNode);
32 validateTranslation(markerNode, translated.program.body[0].expression);
33 const reconstituted = reconstitute(markerNode, translated);
34 unprintedTranslation = generate(reconstituted, undefined, translatedMessage);
35 } else {
36 unprintedTranslation = JSON.stringify(translatedMessage) + ';';
37 }
38 return renderer(freeVars, unprintedTranslation);
39 } catch(exc) {
40 if (process.env.NODE_ENV === 'test') {
41 throw exc;
42 }
43 return errorRenderer(originalMessage, translatedMessage, exc);
44 }
45}
46
47function reconstitute(original, translated) {
48 traverse(original, {
49 noScope: true,
50 JSXElement({node}) {
51 convertNamespacedNameToIdAttribute(node);
52 }
53 });
54 const sanitized = sanitizedAttributesOf(original);
55 traverse(translated, {
56 JSXElement({node}) {
57 if (isElementMarker(node)) {
58 validateMessage(node);
59 node.openingElement.name.name = 'span';
60 node.closingElement.name.name = 'span';
61 }
62 convertNamespacedNameToIdAttribute(node);
63 const id = idOrComponentName(node);
64 if (id && sanitized[id]) {
65 sanitized[id].forEach(a => {
66 node.openingElement.attributes.push(a);
67 });
68 }
69 removeIdAttribute(node);
70 },
71 });
72 return translated;
73}
74
75function renderer(freeVariables, translation) {
76 return (
77`function(${freeVariables.join(', ')}) { return ${translation} }`
78 );
79}
80
81function errorRenderer(message, translation, exception) {
82 return (
83`function() {
84return <span class="error">Error for translation "${translation}" of "${message}":
85<pre>
86${exception}
87${exception.stack}
88</pre></span>;
89}`
90 );
91}