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.
|
|
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.
|
|
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
|
-
|
|
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
|
|
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 = [
|
|
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
|
|
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 = [
|
|
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 = [
|
|
72
|
-
|
|
73
|
-
<svg
|
|
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(
|
|
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:
|
|
103
|
-
{ x:
|
|
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 = [
|
|
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
|
-
|
|
207
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
});
|