UNPKG

1.82 kBJavaScriptView Raw
1const template = require('babel-template');
2import traverse from 'babel-traverse';
3const types = require('babel-types');
4
5import {isElementMarker, stripI18nId} from './ast';
6import {extractElementMessageWithoutSideEffects} from './extract';
7import freeVariablesInMessage from './free-variables';
8import {options} from './options';
9
10
11const transformElementMarker = template(`
12 <${options.elementMarker} message={MESSAGE} context={this} args={ARGS} fallback={function() { return FALLBACK; }}/>
13`, {plugins: ['jsx']});
14
15
16export default {
17 transformMarker(node) {
18 if (isElementMarker(node)) {
19 return this.transformElementMarker(node);
20 } else {
21 return node;
22 }
23 },
24
25 transformElementMarker(node) {
26 const vars = freeVariablesInMessage(node);
27 const message = extractElementMessageWithoutSideEffects(node);
28 const fallback = this.makeFallback(node);
29 const transformed = transformElementMarker({
30 MESSAGE: types.stringLiteral(message),
31 ARGS: types.arrayExpression(
32 vars.map(v => types.identifier(v))
33 ),
34 FALLBACK: fallback,
35 });
36 return transformed;
37 },
38
39 makeFallback(node) {
40 node.openingElement.name.name = 'span';
41 node.closingElement.name.name = 'span';
42 traverse(node, {
43 noScope: true,
44 JSXElement({node}) {
45 stripI18nId(node);
46 }
47 });
48 return node;
49 },
50
51 needsTransformation(node) {
52 // Babel will re-visit the node after replacement, so we must check to
53 // see if a node has already been processed. Since we transform to a
54 // self-closing tag, the absence of children signifies completion.
55 return node.children.length;
56 },
57};