@saykit/transform-jsx 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/parser.mjs +54 -39
- package/package.json +3 -3
package/dist/parser.mjs
CHANGED
|
@@ -14,21 +14,7 @@ function parseJSXContainerElement(element) {
|
|
|
14
14
|
const processed = processJSXOpeningElement(element.openingElement);
|
|
15
15
|
if (!processed) return null;
|
|
16
16
|
const [accessor] = processed;
|
|
17
|
-
const children = element
|
|
18
|
-
if (t.isJSXText(c)) {
|
|
19
|
-
const text = normalizeJSXText(c.value, i === 0, i === a.length - 1);
|
|
20
|
-
if (text) p.push(new LiteralMessage(text));
|
|
21
|
-
}
|
|
22
|
-
if (t.isJSXElement(c)) p.push(parseJSXElement(c, true));
|
|
23
|
-
else if (t.isJSXFragment(c)) p.push(new ElementMessage(AUTO_INCREMENT_IDENTIFIER, [], c));
|
|
24
|
-
else if (t.isJSXExpressionContainer(c)) {
|
|
25
|
-
if (t.isExpression(c.expression)) {
|
|
26
|
-
const [identifier, value] = unwrapPlaceholder(c.expression);
|
|
27
|
-
p.push(new ArgumentMessage(identifier, value));
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return p;
|
|
31
|
-
}, []);
|
|
17
|
+
const children = buildMessageChildren(element);
|
|
32
18
|
const descriptorId = findAttributeValueIfStringLiteralAsString(element.openingElement.attributes, "id");
|
|
33
19
|
const descriptorContext = findAttributeValueIfStringLiteralAsString(element.openingElement.attributes, "context");
|
|
34
20
|
const whitespace = findAttributeValueAsBoolean(element.openingElement.attributes, "whitespace");
|
|
@@ -69,11 +55,13 @@ function parseJSXOpeningElement(element) {
|
|
|
69
55
|
identifier,
|
|
70
56
|
value: parseJSXElement(a.value.expression, true)
|
|
71
57
|
});
|
|
72
|
-
else if (t.isJSXFragment(a.value.expression))
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
58
|
+
else if (t.isJSXFragment(a.value.expression)) {
|
|
59
|
+
const fragment = a.value.expression;
|
|
60
|
+
b.push({
|
|
61
|
+
identifier,
|
|
62
|
+
value: new CompositeMessage({}, [], [], buildMessageChildren(fragment), fragment)
|
|
63
|
+
});
|
|
64
|
+
} else if (t.isExpression(a.value.expression)) {
|
|
77
65
|
const [name, value] = unwrapPlaceholder(a.value.expression);
|
|
78
66
|
b.push({
|
|
79
67
|
identifier,
|
|
@@ -119,29 +107,56 @@ function findPluralOffset(attributes) {
|
|
|
119
107
|
}
|
|
120
108
|
}
|
|
121
109
|
/**
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
110
|
+
* The children the JSX transform itself would compile, so a message extracts as
|
|
111
|
+
* the text that renders. Text children come back with their whitespace
|
|
112
|
+
* collapsed the way JSX collapses it — a line break and the indentation around
|
|
113
|
+
* it are layout and disappear, while two lines that both hold text rejoin with
|
|
114
|
+
* the single space that separated the words — every expression container comes
|
|
115
|
+
* back unwrapped, and a comment child comes back as nothing.
|
|
125
116
|
*/
|
|
126
|
-
|
|
117
|
+
function buildMessageChildren(element, into = []) {
|
|
118
|
+
return t.react.buildChildren(element).reduce((p, c) => {
|
|
119
|
+
const literal = getExpressionAsLiteralText(c);
|
|
120
|
+
if (literal !== void 0) pushLiteral(p, literal);
|
|
121
|
+
else if (t.isJSXElement(c)) p.push(parseJSXElement(c, true));
|
|
122
|
+
else if (t.isJSXFragment(c)) buildMessageChildren(c, p);
|
|
123
|
+
else if (t.isExpression(c)) {
|
|
124
|
+
const [identifier, value] = unwrapPlaceholder(c);
|
|
125
|
+
p.push(new ArgumentMessage(identifier, value));
|
|
126
|
+
}
|
|
127
|
+
return p;
|
|
128
|
+
}, into);
|
|
129
|
+
}
|
|
127
130
|
/**
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
* Add text to the message, folding it into the literal in front of it when
|
|
132
|
+
* there is one, so `Hello{' '}world` is three children in the source and one
|
|
133
|
+
* run of text in the catalogue.
|
|
134
|
+
*/
|
|
135
|
+
function pushLiteral(messages, text) {
|
|
136
|
+
if (!text) return;
|
|
137
|
+
const last = messages.at(-1);
|
|
138
|
+
if (last instanceof LiteralMessage) messages[messages.length - 1] = new LiteralMessage(last.text + text);
|
|
139
|
+
else messages.push(new LiteralMessage(text));
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* The text a child renders as, when that is knowable at build time — a text
|
|
143
|
+
* child, which `buildChildren` has already collapsed into a string, or an
|
|
144
|
+
* expression holding a literal with nothing interpolated into it.
|
|
134
145
|
*
|
|
135
|
-
* The
|
|
136
|
-
*
|
|
137
|
-
*
|
|
146
|
+
* The second is what makes `{' '}` the way to write whitespace that has to
|
|
147
|
+
* survive a line break: it extracts as the space it renders as, rather than as
|
|
148
|
+
* a placeholder a translator can neither see nor move.
|
|
138
149
|
*/
|
|
139
|
-
function
|
|
140
|
-
|
|
141
|
-
if (
|
|
142
|
-
|
|
143
|
-
if (
|
|
144
|
-
|
|
150
|
+
function getExpressionAsLiteralText(expression) {
|
|
151
|
+
if (t.isStringLiteral(expression)) return expression.value;
|
|
152
|
+
if (t.isNumericLiteral(expression)) return String(expression.value);
|
|
153
|
+
if (t.isUnaryExpression(expression) && (expression.operator === "-" || expression.operator === "+") && t.isNumericLiteral(expression.argument)) return String(expression.operator === "-" ? -expression.argument.value : expression.argument.value);
|
|
154
|
+
if (t.isBooleanLiteral(expression) || t.isNullLiteral(expression)) return "";
|
|
155
|
+
if (t.isTemplateLiteral(expression) && expression.expressions.length === 0) {
|
|
156
|
+
const [chunk] = expression.quasis;
|
|
157
|
+
/* v8 ignore next */
|
|
158
|
+
return chunk?.value.cooked ?? "";
|
|
159
|
+
}
|
|
145
160
|
}
|
|
146
161
|
function processJSXOpeningElement(element) {
|
|
147
162
|
if (t.isJSXIdentifier(element.name) && element.name.name === "Say") return [element.name, null];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saykit/transform-jsx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "JSX and TSX source transformer for SayKit",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"i18n",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"@babel/parser": "^7.29.7",
|
|
48
48
|
"@babel/traverse": "^7.29.7",
|
|
49
49
|
"@babel/types": "^7.29.7",
|
|
50
|
-
"@saykit/config": "^0.
|
|
51
|
-
"@saykit/transform-js": "^0.
|
|
50
|
+
"@saykit/config": "^0.8.0",
|
|
51
|
+
"@saykit/transform-js": "^0.8.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@babel/core": "^7.29.7",
|