ripple 0.2.146 → 0.2.147

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Ripple is an elegant TypeScript UI framework",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.2.146",
6
+ "version": "0.2.147",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index-client.js",
9
9
  "main": "src/runtime/index-client.js",
@@ -81,6 +81,6 @@
81
81
  "typescript": "^5.9.2"
82
82
  },
83
83
  "peerDependencies": {
84
- "ripple": "0.2.146"
84
+ "ripple": "0.2.147"
85
85
  }
86
86
  }
@@ -976,6 +976,15 @@ function RipplePlugin(config) {
976
976
  return this.finishNode(node, 'JSXExpressionContainer');
977
977
  }
978
978
 
979
+ jsx_parseEmptyExpression() {
980
+ // Override to properly handle the range for JSXEmptyExpression
981
+ // The range should be from after { to before }
982
+ const node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc);
983
+ node.end = this.start;
984
+ node.loc.end = this.startLoc;
985
+ return this.finishNodeAt(node, 'JSXEmptyExpression', this.start, this.startLoc);
986
+ }
987
+
979
988
  jsx_parseTupleContainer() {
980
989
  var t = this.startNode();
981
990
  return (
@@ -1588,9 +1597,7 @@ function RipplePlugin(config) {
1588
1597
  const node = this.jsx_parseExpressionContainer();
1589
1598
  node.type = node.html ? 'Html' : 'Text';
1590
1599
  delete node.html;
1591
- if (node.expression.type !== 'JSXEmptyExpression') {
1592
- body.push(node);
1593
- }
1600
+ body.push(node);
1594
1601
  } else if (this.type.label === '}') {
1595
1602
  return;
1596
1603
  } else if (this.type.label === 'jsxTagStart') {
@@ -1915,6 +1922,17 @@ function get_comment_handlers(source, comments, index = 0) {
1915
1922
  return;
1916
1923
  }
1917
1924
  }
1925
+ // Handle JSXEmptyExpression - these represent {/* comment */} in JSX
1926
+ if (node.type === 'JSXEmptyExpression') {
1927
+ // Collect all comments that fall within this JSXEmptyExpression
1928
+ while (comments[0] && comments[0].start >= node.start && comments[0].end <= node.end) {
1929
+ comment = /** @type {CommentWithLocation} */ (comments.shift());
1930
+ (node.innerComments ||= []).push(comment);
1931
+ }
1932
+ if (node.innerComments && node.innerComments.length > 0) {
1933
+ return;
1934
+ }
1935
+ }
1918
1936
  // Handle empty Element nodes the same way as empty BlockStatements
1919
1937
  if (node.type === 'Element' && (!node.children || node.children.length === 0)) {
1920
1938
  if (comments[0].start < node.end && comments[0].end < node.end) {
@@ -1,7 +1,13 @@
1
1
  describe('SVG namespace handling', () => {
2
2
  it('should render static SVG elements with correct namespace', () => {
3
3
  component App() {
4
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor">
4
+ <svg
5
+ xmlns="http://www.w3.org/2000/svg"
6
+ width="24"
7
+ height="24"
8
+ fill="none"
9
+ stroke="currentColor"
10
+ >
5
11
  <path d="m14 12 4 4 4-4" />
6
12
  <circle cx="12" cy="12" r="4" />
7
13
  <rect x="4" y="4" width="16" height="16" />
@@ -32,9 +38,20 @@ describe('SVG namespace handling', () => {
32
38
 
33
39
  it('should render dynamic SVG paths with for loop (original issue)', () => {
34
40
  component App() {
35
- const d = ["m14 12 4 4 4-4", "M18 16V7", "m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16", "M3.304 13h6.392"];
41
+ const d = [
42
+ 'm14 12 4 4 4-4',
43
+ 'M18 16V7',
44
+ 'm2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16',
45
+ 'M3.304 13h6.392',
46
+ ];
36
47
 
37
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor">
48
+ <svg
49
+ xmlns="http://www.w3.org/2000/svg"
50
+ width="24"
51
+ height="24"
52
+ fill="none"
53
+ stroke="currentColor"
54
+ >
38
55
  for (const pathData of d) {
39
56
  <path d={pathData} />
40
57
  }
@@ -52,7 +69,12 @@ describe('SVG namespace handling', () => {
52
69
 
53
70
  // Critical test: dynamic paths should have correct SVG namespace
54
71
  expect(paths.length).toBe(4);
55
- const expectedPaths = ["m14 12 4 4 4-4", "M18 16V7", "m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16", "M3.304 13h6.392"];
72
+ const expectedPaths = [
73
+ 'm14 12 4 4 4-4',
74
+ 'M18 16V7',
75
+ 'm2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16',
76
+ 'M3.304 13h6.392',
77
+ ];
56
78
  paths.forEach((path, i) => {
57
79
  expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
58
80
  expect(path.getAttribute('d')).toBe(expectedPaths[i]);
@@ -60,7 +82,7 @@ describe('SVG namespace handling', () => {
60
82
 
61
83
  // Verify paths are actually SVG elements (should have getBBox method)
62
84
  // Note: getBBox might not work in test environment, so just check namespace
63
- paths.forEach(path => {
85
+ paths.forEach((path) => {
64
86
  expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
65
87
  expect(path.tagName.toLowerCase()).toBe('path');
66
88
  });
@@ -68,9 +90,15 @@ describe('SVG namespace handling', () => {
68
90
 
69
91
  it('should handle mixed static and dynamic SVG elements', () => {
70
92
  component App() {
71
- const dynamicPaths = ["M12 2L2 7v10c0 5.55 3.84 10 9 11 5.16-1 9-5.45 9-11V7l-10-5z"];
72
-
73
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor">
93
+ const dynamicPaths = ['M12 2L2 7v10c0 5.55 3.84 10 9 11 5.16-1 9-5.45 9-11V7l-10-5z'];
94
+
95
+ <svg
96
+ xmlns="http://www.w3.org/2000/svg"
97
+ width="24"
98
+ height="24"
99
+ fill="none"
100
+ stroke="currentColor"
101
+ >
74
102
  <circle cx="12" cy="12" r="10" />
75
103
  for (const pathData of dynamicPaths) {
76
104
  <path d={pathData} />
@@ -93,14 +121,16 @@ describe('SVG namespace handling', () => {
93
121
  expect(rect.namespaceURI).toBe('http://www.w3.org/2000/svg');
94
122
 
95
123
  // Verify content
96
- expect(path.getAttribute('d')).toBe('M12 2L2 7v10c0 5.55 3.84 10 9 11 5.16-1 9-5.45 9-11V7l-10-5z');
124
+ expect(path.getAttribute('d')).toBe(
125
+ 'M12 2L2 7v10c0 5.55 3.84 10 9 11 5.16-1 9-5.45 9-11V7l-10-5z',
126
+ );
97
127
  });
98
128
 
99
129
  it('should handle nested SVG groups with for loops', () => {
100
130
  component App() {
101
131
  const items = [
102
- { x: "10", y: "10", width: "20", height: "20" },
103
- { x: "40", y: "40", width: "20", height: "20" }
132
+ { x: '10', y: '10', width: '20', height: '20' },
133
+ { x: '40', y: '40', width: '20', height: '20' },
104
134
  ];
105
135
 
106
136
  <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
@@ -123,7 +153,7 @@ describe('SVG namespace handling', () => {
123
153
  expect(g.namespaceURI).toBe('http://www.w3.org/2000/svg');
124
154
  expect(rects.length).toBe(2);
125
155
 
126
- rects.forEach(rect => {
156
+ rects.forEach((rect) => {
127
157
  expect(rect.namespaceURI).toBe('http://www.w3.org/2000/svg');
128
158
  });
129
159
 
@@ -200,22 +230,39 @@ describe('SVG namespace handling', () => {
200
230
 
201
231
  it('should compare static vs dynamic SVG rendering (original problem case)', () => {
202
232
  component App() {
203
- const d = ["m14 12 4 4 4-4", "M18 16V7", "m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16", "M3.304 13h6.392"];
233
+ const d = [
234
+ 'm14 12 4 4 4-4',
235
+ 'M18 16V7',
236
+ 'm2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16',
237
+ 'M3.304 13h6.392',
238
+ ];
204
239
 
205
240
  <div class="container">
206
- {/* Dynamic SVG - the original problem case */}
207
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" class="dynamic-svg">
241
+ <svg
242
+ xmlns="http://www.w3.org/2000/svg"
243
+ width="24"
244
+ height="24"
245
+ fill="none"
246
+ stroke="currentColor"
247
+ class="dynamic-svg"
248
+ >
208
249
  for (const path of d) {
209
250
  <path d={path} />
210
251
  }
211
252
  </svg>
212
253
 
213
- {/* Static SVG - always worked */}
214
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" class="static-svg">
215
- <path d="m14 12 4 4 4-4"></path>
216
- <path d="M18 16V7"></path>
217
- <path d="m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16"></path>
218
- <path d="M3.304 13h6.392"></path>
254
+ <svg
255
+ xmlns="http://www.w3.org/2000/svg"
256
+ width="24"
257
+ height="24"
258
+ fill="none"
259
+ stroke="currentColor"
260
+ class="static-svg"
261
+ >
262
+ <path d="m14 12 4 4 4-4" />
263
+ <path d="M18 16V7" />
264
+ <path d="m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16" />
265
+ <path d="M3.304 13h6.392" />
219
266
  </svg>
220
267
  </div>
221
268
  }
@@ -236,10 +283,10 @@ describe('SVG namespace handling', () => {
236
283
  expect(staticPaths.length).toBe(4);
237
284
 
238
285
  // All paths should have SVG namespace
239
- dynamicPaths.forEach(path => {
286
+ dynamicPaths.forEach((path) => {
240
287
  expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
241
288
  });
242
- staticPaths.forEach(path => {
289
+ staticPaths.forEach((path) => {
243
290
  expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
244
291
  });
245
292
 
@@ -249,11 +296,11 @@ describe('SVG namespace handling', () => {
249
296
  });
250
297
 
251
298
  // Critical test: all paths should be proper SVG elements
252
- dynamicPaths.forEach(path => {
299
+ dynamicPaths.forEach((path) => {
253
300
  expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
254
301
  expect(path.tagName.toLowerCase()).toBe('path');
255
302
  });
256
- staticPaths.forEach(path => {
303
+ staticPaths.forEach((path) => {
257
304
  expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
258
305
  expect(path.tagName.toLowerCase()).toBe('path');
259
306
  });