gtx-cli 2.4.9 → 2.4.11

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # gtx-cli
2
2
 
3
+ ## 2.4.11
4
+
5
+ ### Patch Changes
6
+
7
+ - [#780](https://github.com/generaltranslation/gt/pull/780) [`c048320`](https://github.com/generaltranslation/gt/commit/c048320ae0daf91bebf65145aba6fb15c2f3612d) Thanks [@ErnestM1234](https://github.com/ErnestM1234)! - Fix CLI parsing for nbsp characters
8
+
9
+ ## 2.4.10
10
+
11
+ ### Patch Changes
12
+
13
+ - [#778](https://github.com/generaltranslation/gt/pull/778) [`0d8f414`](https://github.com/generaltranslation/gt/commit/0d8f4144696873b15f0aaa6744bdb7390d472279) Thanks [@SamEggert](https://github.com/SamEggert)! - skip dynamic expressions for HTML content props in parseJSX
14
+
3
15
  ## 2.4.9
4
16
 
5
17
  ### Patch Changes
@@ -1,14 +1,41 @@
1
1
  import { isAcceptedPluralForm } from 'generaltranslation/internal';
2
+ // JSX whitespace characters (space, tab, newline, carriage return)
3
+ // Does NOT include non-breaking space (U+00A0) which should be preserved
4
+ const isJsxWhitespace = (char) => {
5
+ return char === ' ' || char === '\t' || char === '\n' || char === '\r';
6
+ };
7
+ const trimJsxWhitespace = (str, side = 'both') => {
8
+ let start = 0;
9
+ let end = str.length;
10
+ if (side === 'start' || side === 'both') {
11
+ while (start < end && isJsxWhitespace(str[start])) {
12
+ start++;
13
+ }
14
+ }
15
+ if (side === 'end' || side === 'both') {
16
+ while (end > start && isJsxWhitespace(str[end - 1])) {
17
+ end--;
18
+ }
19
+ }
20
+ return str.slice(start, end);
21
+ };
22
+ const hasNonJsxWhitespace = (str) => {
23
+ for (const char of str) {
24
+ if (!isJsxWhitespace(char))
25
+ return true;
26
+ }
27
+ return false;
28
+ };
2
29
  export function trimJsxStringChild(child, index, childrenTypes) {
3
30
  // Normalize line endings to \n for consistency across platforms
4
31
  let result = child.replace(/\r\n|\r/g, '\n');
5
- // Collapse multiple spaces/tabs into a single space
32
+ // Collapse multiple spaces/tabs into a single space (but not nbsp)
6
33
  result = result.replace(/[\t ]+/g, ' ');
7
34
  let newResult = '';
8
35
  let newline = false;
9
36
  for (const char of result) {
10
37
  if (char === '\n') {
11
- if (newResult.trim())
38
+ if (hasNonJsxWhitespace(newResult))
12
39
  newResult += ' ';
13
40
  else
14
41
  newResult = '';
@@ -19,15 +46,15 @@ export function trimJsxStringChild(child, index, childrenTypes) {
19
46
  newResult += char;
20
47
  continue;
21
48
  }
22
- if (char.trim() === '')
49
+ if (isJsxWhitespace(char))
23
50
  continue;
24
51
  newResult += char;
25
52
  newline = false;
26
53
  }
27
54
  if (newline)
28
- newResult = newResult.trimEnd();
55
+ newResult = trimJsxWhitespace(newResult, 'end');
29
56
  result = newResult;
30
- // Collapse multiple spaces/tabs into a single space
57
+ // Collapse multiple spaces/tabs into a single space (but not nbsp)
31
58
  result = result.replace(/[\t ]+/g, ' ');
32
59
  return result;
33
60
  }
@@ -8,6 +8,7 @@ import { isAcceptedPluralForm } from 'generaltranslation/internal';
8
8
  import { handleChildrenWhitespace } from '../trimJsxStringChildren.js';
9
9
  import { isStaticExpression } from '../evaluateJsx.js';
10
10
  import { GT_ATTRIBUTES, mapAttributeName, VARIABLE_COMPONENTS, } from './constants.js';
11
+ import { HTML_CONTENT_PROPS } from 'generaltranslation/types';
11
12
  /**
12
13
  * Builds a JSX tree from a given node, recursively handling children.
13
14
  * @param node - The node to build the tree from
@@ -80,15 +81,29 @@ export function buildJSXTree(importAliases, node, unwrappedExpressions, updates,
80
81
  attrValue = attr.value.value;
81
82
  }
82
83
  else if (t.isJSXExpressionContainer(attr.value)) {
83
- if ((elementIsPlural && isAcceptedPluralForm(attrName)) ||
84
- (elementIsBranch && attrName !== 'branch')) {
85
- // Make sure that variable strings like {`I have ${count} book`} are invalid!
86
- if (t.isTemplateLiteral(attr.value.expression) &&
87
- !isStaticExpression(attr.value.expression).isStatic) {
88
- unwrappedExpressions.push(generate(attr.value).code);
84
+ // Check if this is an HTML content prop (title, placeholder, alt, etc.)
85
+ const isHtmlContentProp = Object.values(HTML_CONTENT_PROPS).includes(attrName);
86
+ if (isHtmlContentProp) {
87
+ // For HTML content props, only accept static string expressions
88
+ const staticAnalysis = isStaticExpression(attr.value.expression);
89
+ if (staticAnalysis.isStatic &&
90
+ staticAnalysis.value !== undefined) {
91
+ attrValue = staticAnalysis.value;
89
92
  }
93
+ // Otherwise attrValue stays null and won't be included
94
+ }
95
+ else {
96
+ // For non-HTML-content props, validate plural/branch then build tree
97
+ if ((elementIsPlural && isAcceptedPluralForm(attrName)) ||
98
+ (elementIsBranch && attrName !== 'branch')) {
99
+ // Make sure that variable strings like {`I have ${count} book`} are invalid!
100
+ if (t.isTemplateLiteral(attr.value.expression) &&
101
+ !isStaticExpression(attr.value.expression).isStatic) {
102
+ unwrappedExpressions.push(generate(attr.value).code);
103
+ }
104
+ }
105
+ attrValue = buildJSXTree(importAliases, attr.value.expression, unwrappedExpressions, updates, errors, warnings, file, true);
90
106
  }
91
- attrValue = buildJSXTree(importAliases, attr.value.expression, unwrappedExpressions, updates, errors, warnings, file, true);
92
107
  }
93
108
  }
94
109
  props[attrName] = attrValue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gtx-cli",
3
- "version": "2.4.9",
3
+ "version": "2.4.11",
4
4
  "main": "dist/index.js",
5
5
  "bin": "dist/main.js",
6
6
  "files": [