ripple 0.2.4 → 0.2.6

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.
@@ -2,6 +2,41 @@ import { walk } from 'zimmerframe';
2
2
 
3
3
  const seen = new Set();
4
4
  const regex_backslash_and_following_character = /\\(.)/g;
5
+ const FORWARD = 0;
6
+ const BACKWARD = 1;
7
+
8
+ // CSS selector constants
9
+ const descendant_combinator = { name: ' ', type: 'Combinator' };
10
+ const nesting_selector = {
11
+ type: 'NestingSelector',
12
+ name: '&',
13
+ selectors: [],
14
+ metadata: { scoped: false }
15
+ };
16
+ const any_selector = {
17
+ type: 'RelativeSelector',
18
+ selectors: [{ type: 'TypeSelector', name: '*' }],
19
+ combinator: null,
20
+ metadata: { scoped: false }
21
+ };
22
+
23
+ // Whitelist for attribute selectors on specific elements
24
+ const whitelist_attribute_selector = new Map([
25
+ ['details', ['open']],
26
+ ['dialog', ['open']],
27
+ ['form', ['novalidate']],
28
+ ['iframe', ['allow', 'allowfullscreen', 'allowpaymentrequest', 'loading', 'referrerpolicy']],
29
+ ['img', ['loading']],
30
+ ['input', ['accept', 'autocomplete', 'capture', 'checked', 'disabled', 'max', 'maxlength', 'min', 'minlength', 'multiple', 'pattern', 'placeholder', 'readonly', 'required', 'size', 'step']],
31
+ ['object', ['typemustmatch']],
32
+ ['ol', ['reversed', 'start', 'type']],
33
+ ['optgroup', ['disabled']],
34
+ ['option', ['disabled', 'selected']],
35
+ ['script', ['async', 'defer', 'nomodule', 'type']],
36
+ ['select', ['disabled', 'multiple', 'required', 'size']],
37
+ ['textarea', ['autocomplete', 'disabled', 'maxlength', 'minlength', 'placeholder', 'readonly', 'required', 'rows', 'wrap']],
38
+ ['video', ['autoplay', 'controls', 'loop', 'muted', 'playsinline']]
39
+ ]);
5
40
 
6
41
  function get_relative_selectors(node) {
7
42
  const selectors = truncate(node);
@@ -62,14 +97,14 @@ function truncate(node) {
62
97
  });
63
98
  }
64
99
 
65
- function apply_selector(relative_selectors, rule, element) {
66
- const parent_selectors = relative_selectors.slice();
67
- const relative_selector = parent_selectors.pop();
100
+ function apply_selector(relative_selectors, rule, element, direction) {
101
+ const rest_selectors = relative_selectors.slice();
102
+ const relative_selector = direction === FORWARD ? rest_selectors.shift() : rest_selectors.pop();
68
103
 
69
104
  const matched =
70
105
  !!relative_selector &&
71
- relative_selector_might_apply_to_node(relative_selector, rule, element) &&
72
- apply_combinator(relative_selector, parent_selectors, rule, element);
106
+ relative_selector_might_apply_to_node(relative_selector, rule, element, direction) &&
107
+ apply_combinator(relative_selector, rest_selectors, rule, element, direction);
73
108
 
74
109
  if (matched) {
75
110
  if (!is_outer_global(relative_selector)) {
@@ -82,55 +117,163 @@ function apply_selector(relative_selectors, rule, element) {
82
117
  return matched;
83
118
  }
84
119
 
85
- function apply_combinator(relative_selector, parent_selectors, rule, node) {
86
- if (!relative_selector.combinator) return true;
120
+ function get_ancestor_elements(node, adjacent_only, seen = new Set()) {
121
+ const ancestors = [];
87
122
 
88
- const name = relative_selector.combinator.name;
123
+ const path = node.metadata.path;
124
+ let i = path.length;
89
125
 
90
- switch (name) {
91
- case ' ':
92
- case '>': {
93
- let parent_matched = false;
126
+ while (i--) {
127
+ const parent = path[i];
94
128
 
95
- const path = node.metadata.path;
96
- let i = path.length;
129
+ if (parent.type === 'Element') {
130
+ ancestors.push(parent);
131
+ if (adjacent_only) {
132
+ break;
133
+ }
134
+ }
135
+ }
97
136
 
98
- while (i--) {
99
- const parent = path[i];
137
+ return ancestors;
138
+ }
100
139
 
101
- if (parent.type === 'Element') {
102
- if (apply_selector(parent_selectors, rule, parent)) {
103
- parent_matched = true;
104
- }
140
+ function get_descendant_elements(node, adjacent_only) {
141
+ const descendants = [];
142
+
143
+ function visit(current_node, depth = 0) {
144
+ if (current_node.type === 'Element' && current_node !== node) {
145
+ descendants.push(current_node);
146
+ if (adjacent_only) return; // Only direct children for '>' combinator
147
+ }
148
+
149
+ // Visit children based on Ripple's AST structure
150
+ if (current_node.children) {
151
+ for (const child of current_node.children) {
152
+ visit(child, depth + 1);
153
+ }
154
+ }
155
+
156
+ if (current_node.body) {
157
+ for (const child of current_node.body) {
158
+ visit(child, depth + 1);
159
+ }
160
+ }
161
+
162
+ // For template nodes and text interpolations
163
+ if (current_node.expression && typeof current_node.expression === 'object') {
164
+ visit(current_node.expression, depth + 1);
165
+ }
166
+ }
167
+
168
+ // Start from node's children
169
+ if (node.children) {
170
+ for (const child of node.children) {
171
+ visit(child);
172
+ }
173
+ }
174
+
175
+ if (node.body) {
176
+ for (const child of node.body) {
177
+ visit(child);
178
+ }
179
+ }
105
180
 
106
- if (name === '>') return parent_matched;
181
+ return descendants;
182
+ }
183
+
184
+ function get_possible_element_siblings(node, direction, adjacent_only) {
185
+ const siblings = new Map();
186
+ const parent = get_element_parent(node);
187
+
188
+ if (!parent) {
189
+ return siblings;
190
+ }
191
+
192
+ // Get the container that holds the siblings
193
+ const container = parent.children || parent.body || [];
194
+ const node_index = container.indexOf(node);
195
+
196
+ if (node_index === -1) return siblings;
197
+
198
+ // Determine which siblings to check based on direction
199
+ let start, end, step;
200
+ if (direction === FORWARD) {
201
+ start = node_index + 1;
202
+ end = container.length;
203
+ step = 1;
204
+ } else {
205
+ start = node_index - 1;
206
+ end = -1;
207
+ step = -1;
208
+ }
209
+
210
+ // Collect siblings
211
+ for (let i = start; i !== end; i += step) {
212
+ const sibling = container[i];
213
+
214
+ if (sibling.type === 'Element' || sibling.type === 'Component') {
215
+ siblings.set(sibling, true);
216
+ if (adjacent_only) break; // Only immediate sibling for '+' combinator
217
+ }
218
+ // Stop at non-whitespace text nodes for adjacent selectors
219
+ else if (adjacent_only && sibling.type === 'Text' && sibling.value?.trim()) {
220
+ break;
221
+ }
222
+ }
223
+
224
+ return siblings;
225
+ }
226
+
227
+ function apply_combinator(relative_selector, rest_selectors, rule, node, direction) {
228
+ const combinator =
229
+ direction == FORWARD ? rest_selectors[0]?.combinator : relative_selector.combinator;
230
+ if (!combinator) return true;
231
+
232
+ switch (combinator.name) {
233
+ case ' ':
234
+ case '>': {
235
+ const is_adjacent = combinator.name === '>';
236
+ const parents =
237
+ direction === FORWARD
238
+ ? get_descendant_elements(node, is_adjacent)
239
+ : get_ancestor_elements(node, is_adjacent);
240
+ let parent_matched = false;
241
+
242
+ for (const parent of parents) {
243
+ if (apply_selector(rest_selectors, rule, parent, direction)) {
244
+ parent_matched = true;
107
245
  }
108
246
  }
109
247
 
110
- return parent_matched || parent_selectors.every((selector) => is_global(selector, rule));
248
+ return (
249
+ parent_matched ||
250
+ (direction === BACKWARD &&
251
+ (!is_adjacent || parents.length === 0) &&
252
+ rest_selectors.every((selector) => is_global(selector, rule)))
253
+ );
111
254
  }
112
255
 
113
256
  case '+':
114
257
  case '~': {
115
- const siblings = get_possible_element_siblings(node, name === '+');
258
+ const siblings = get_possible_element_siblings(node, direction, combinator.name === '+');
116
259
 
117
260
  let sibling_matched = false;
118
261
 
119
262
  for (const possible_sibling of siblings.keys()) {
120
- if (possible_sibling.type === 'RenderTag' || possible_sibling.type === 'SlotElement') {
121
- // `{@render foo()}<p>foo</p>` with `:global(.x) + p` is a match
122
- if (parent_selectors.length === 1 && parent_selectors[0].metadata.is_global) {
263
+ if (possible_sibling.type === 'Component') {
264
+ if (rest_selectors.length === 1 && rest_selectors[0].metadata.is_global) {
123
265
  sibling_matched = true;
124
266
  }
125
- } else if (apply_selector(parent_selectors, rule, possible_sibling)) {
267
+ } else if (apply_selector(rest_selectors, rule, possible_sibling, direction)) {
126
268
  sibling_matched = true;
127
269
  }
128
270
  }
129
271
 
130
272
  return (
131
273
  sibling_matched ||
132
- (get_element_parent(node) === null &&
133
- parent_selectors.every((selector) => is_global(selector, rule)))
274
+ (direction === BACKWARD &&
275
+ get_element_parent(node) === null &&
276
+ rest_selectors.every((selector) => is_global(selector, rule)))
134
277
  );
135
278
  }
136
279
 
@@ -141,13 +284,18 @@ function apply_combinator(relative_selector, parent_selectors, rule, node) {
141
284
  }
142
285
 
143
286
  function get_element_parent(node) {
287
+ // Check if metadata and path exist
288
+ if (!node.metadata || !node.metadata.path) {
289
+ return null;
290
+ }
291
+
144
292
  let path = node.metadata.path;
145
293
  let i = path.length;
146
294
 
147
295
  while (i--) {
148
296
  const parent = path[i];
149
297
 
150
- if (parent.type === 'RegularElement' || parent.type === 'SvelteElement') {
298
+ if (parent.type === 'Element') {
151
299
  return parent;
152
300
  }
153
301
  }
@@ -252,7 +400,7 @@ function is_outer_global(relative_selector) {
252
400
  );
253
401
  }
254
402
 
255
- function relative_selector_might_apply_to_node(relative_selector, rule, element) {
403
+ function relative_selector_might_apply_to_node(relative_selector, rule, element, direction) {
256
404
  // Sort :has(...) selectors in one bucket and everything else into another
257
405
  const has_selectors = [];
258
406
  const other_selectors = [];
@@ -268,13 +416,6 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
268
416
  // If we're called recursively from a :has(...) selector, we're on the way of checking if the other selectors match.
269
417
  // In that case ignore this check (because we just came from this) to avoid an infinite loop.
270
418
  if (has_selectors.length > 0) {
271
- /** @type {Array<Compiler.AST.RegularElement | Compiler.AST.SvelteElement>} */
272
- const child_elements = [];
273
- /** @type {Array<Compiler.AST.RegularElement | Compiler.AST.SvelteElement>} */
274
- const descendant_elements = [];
275
- /** @type {Array<Compiler.AST.RegularElement | Compiler.AST.SvelteElement>} */
276
- let sibling_elements; // do them lazy because it's rarely used and expensive to calculate
277
-
278
419
  // If this is a :has inside a global selector, we gotta include the element itself, too,
279
420
  // because the global selector might be for an element that's outside the component,
280
421
  // e.g. :root:has(.scoped), :global(.foo):has(.scoped), or :root { &:has(.scoped) {} }
@@ -290,37 +431,6 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
290
431
  )
291
432
  )
292
433
  );
293
- if (include_self) {
294
- child_elements.push(element);
295
- descendant_elements.push(element);
296
- }
297
-
298
- /**
299
- * @param {Compiler.AST.SvelteNode} node
300
- * @param {{ is_child: boolean }} state
301
- */
302
- function walk_children(node, state) {
303
- walk(node, state, {
304
- _(node, context) {
305
- if (node.type === 'Element') {
306
- descendant_elements.push(node);
307
-
308
- if (context.state.is_child) {
309
- child_elements.push(node);
310
- context.state.is_child = false;
311
- context.next();
312
- context.state.is_child = true;
313
- } else {
314
- context.next();
315
- }
316
- } else {
317
- context.next();
318
- }
319
- }
320
- });
321
- }
322
-
323
- walk_children(element.fragment, { is_child: true });
324
434
 
325
435
  // :has(...) is special in that it means "look downwards in the CSS tree". Since our matching algorithm goes
326
436
  // upwards and back-to-front, we need to first check the selectors inside :has(...), then check the rest of the
@@ -331,37 +441,34 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
331
441
  let matched = false;
332
442
 
333
443
  for (const complex_selector of complex_selectors) {
334
- const selectors = truncate(complex_selector);
335
- const left_most_combinator = selectors[0]?.combinator ?? descendant_combinator;
336
- // In .x:has(> y), we want to search for y, ignoring the left-most combinator
337
- // (else it would try to walk further up and fail because there are no selectors left)
338
- if (selectors.length > 0) {
339
- selectors[0] = {
340
- ...selectors[0],
341
- combinator: null
342
- };
444
+ const [first, ...rest] = truncate(complex_selector);
445
+ // if it was just a :global(...)
446
+ if (!first) {
447
+ complex_selector.metadata.used = true;
448
+ matched = true;
449
+ continue;
343
450
  }
344
451
 
345
- const descendants =
346
- left_most_combinator.name === '+' || left_most_combinator.name === '~'
347
- ? (sibling_elements ??= get_following_sibling_elements(element, include_self))
348
- : left_most_combinator.name === '>'
349
- ? child_elements
350
- : descendant_elements;
351
-
352
- let selector_matched = false;
353
-
354
- // Iterate over all descendant elements and check if the selector inside :has matches
355
- for (const element of descendants) {
356
- if (
357
- selectors.length === 0 /* is :global(...) */ ||
358
- (element.metadata.scoped && selector_matched) ||
359
- apply_selector(selectors, rule, element)
360
- ) {
452
+ if (include_self) {
453
+ const selector_including_self = [
454
+ first.combinator ? { ...first, combinator: null } : first,
455
+ ...rest
456
+ ];
457
+ if (apply_selector(selector_including_self, rule, element, FORWARD)) {
361
458
  complex_selector.metadata.used = true;
362
- selector_matched = matched = true;
459
+ matched = true;
363
460
  }
364
461
  }
462
+
463
+ const selector_excluding_self = [
464
+ any_selector,
465
+ first.combinator ? first : { ...first, combinator: descendant_combinator },
466
+ ...rest
467
+ ];
468
+ if (apply_selector(selector_excluding_self, rule, element, FORWARD)) {
469
+ complex_selector.metadata.used = true;
470
+ matched = true;
471
+ }
365
472
  }
366
473
 
367
474
  if (!matched) {
@@ -386,7 +493,7 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
386
493
  ) {
387
494
  const args = selector.args;
388
495
  const complex_selector = args.children[0];
389
- return apply_selector(complex_selector.children, rule, element);
496
+ return apply_selector(complex_selector.children, rule, element, BACKWARD);
390
497
  }
391
498
 
392
499
  // We came across a :global, everything beyond it is global and therefore a potential match
@@ -413,7 +520,6 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
413
520
  selector.metadata.scoped = true;
414
521
  }
415
522
 
416
- /** @type {Compiler.AST.RegularElement | Compiler.AST.SvelteElement | null} */
417
523
  let el = element;
418
524
  while (el) {
419
525
  el.metadata.scoped = true;
@@ -435,7 +541,7 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
435
541
  if (is_global) {
436
542
  complex_selector.metadata.used = true;
437
543
  matched = true;
438
- } else if (apply_selector(relative, rule, element)) {
544
+ } else if (apply_selector(relative, rule, element, BACKWARD)) {
439
545
  complex_selector.metadata.used = true;
440
546
  matched = true;
441
547
  } else if (complex_selector.children.length > 1 && (name == 'is' || name == 'where')) {
@@ -465,7 +571,7 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
465
571
  case 'AttributeSelector': {
466
572
  const whitelisted = whitelist_attribute_selector.get(element.id.name.toLowerCase());
467
573
  if (
468
- !whitelisted?.includes(selector.id.name.toLowerCase()) &&
574
+ !whitelisted?.includes(selector.name.toLowerCase()) &&
469
575
  !attribute_matches(
470
576
  element,
471
577
  selector.name,
@@ -480,12 +586,7 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
480
586
  }
481
587
 
482
588
  case 'ClassSelector': {
483
- if (
484
- !attribute_matches(element, 'class', name, '~=', false) &&
485
- !element.attributes.some(
486
- (attribute) => attribute.type === 'ClassDirective' && attribute.name === name
487
- )
488
- ) {
589
+ if (!attribute_matches(element, 'class', name, '~=', false)) {
489
590
  return false;
490
591
  }
491
592
 
@@ -502,9 +603,9 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
502
603
 
503
604
  case 'TypeSelector': {
504
605
  if (
606
+ element.id.type === 'Identifier' &&
505
607
  element.id.name.toLowerCase() !== name.toLowerCase() &&
506
- name !== '*' &&
507
- element.id.name[0].toLowerCase() === element.id.name[0]
608
+ name !== '*'
508
609
  ) {
509
610
  return false;
510
611
  }
@@ -519,7 +620,7 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
519
620
 
520
621
  for (const complex_selector of parent.prelude.children) {
521
622
  if (
522
- apply_selector(get_relative_selectors(complex_selector), parent, element) ||
623
+ apply_selector(get_relative_selectors(complex_selector), parent, element, direction) ||
523
624
  complex_selector.children.every((s) => is_global(s, parent))
524
625
  ) {
525
626
  complex_selector.metadata.used = true;
@@ -540,6 +641,27 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element)
540
641
  return true;
541
642
  }
542
643
 
644
+ // Utility functions for parsing CSS values
645
+ function unquote(str) {
646
+ if ((str[0] === '"' && str[str.length - 1] === '"') ||
647
+ (str[0] === "'" && str[str.length - 1] === "'")) {
648
+ return str.slice(1, -1);
649
+ }
650
+ return str;
651
+ }
652
+
653
+ function get_parent_rules(rule) {
654
+ const rules = [rule];
655
+ let current = rule;
656
+
657
+ while (current.metadata.parent_rule) {
658
+ current = current.metadata.parent_rule;
659
+ rules.unshift(current);
660
+ }
661
+
662
+ return rules;
663
+ }
664
+
543
665
  export function prune_css(css, element) {
544
666
  walk(css, null, {
545
667
  Rule(node, context) {
@@ -558,7 +680,8 @@ export function prune_css(css, element) {
558
680
  apply_selector(
559
681
  selectors,
560
682
  /** @type {Compiler.AST.CSS.Rule} */ (node.metadata.rule),
561
- element
683
+ element,
684
+ BACKWARD
562
685
  )
563
686
  ) {
564
687
  node.metadata.used = true;
@@ -32,6 +32,12 @@ function visit_function(node, context) {
32
32
  const metadata = node.metadata;
33
33
  const state = context.state;
34
34
 
35
+ delete node.returnType;
36
+
37
+ for (const param of node.params) {
38
+ delete param.typeAnnotation;
39
+ }
40
+
35
41
  if (metadata?.hoisted === true) {
36
42
  const params = build_hoisted_params(node, context);
37
43
 
@@ -497,6 +503,9 @@ const visitors = {
497
503
  }
498
504
  } else if (attr.type === 'SpreadAttribute') {
499
505
  spread_attributes.push(b.spread(b.call('$.spread_object', visit(attr.argument, state))));
506
+ } else if (attr.type === 'UseAttribute') {
507
+ const id = state.flush_node();
508
+ state.init.push(b.stmt(b.call('$.use', id, b.thunk(visit(attr.argument, state)))));
500
509
  }
501
510
  }
502
511
 
@@ -581,6 +590,8 @@ const visitors = {
581
590
  )
582
591
  )
583
592
  );
593
+ } else if (attr.type === 'UseAttribute') {
594
+ props.push(b.prop('init', b.call('$.use_prop'), visit(attr.argument, state), true));
584
595
  } else {
585
596
  throw new Error('TODO');
586
597
  }
@@ -1184,23 +1195,42 @@ function transform_ts_child(node, context) {
1184
1195
  const type = node.id.name;
1185
1196
  const children = [];
1186
1197
  let has_children_props = false;
1198
+
1199
+ // Filter out UseAttributes and handle them separately
1200
+ const use_attributes = [];
1201
+ const attributes = node.attributes
1202
+ .filter((attr) => {
1203
+ if (attr.type === 'UseAttribute') {
1204
+ use_attributes.push(attr);
1205
+ return false; // Filter out from JSX attributes
1206
+ }
1207
+ return true;
1208
+ })
1209
+ .map((attr) => {
1210
+ if (attr.type === 'Attribute') {
1211
+ const metadata = { await: false };
1212
+ const name = visit(attr.name, { ...state, metadata });
1213
+ const value = visit(attr.value, { ...state, metadata });
1214
+ const jsx_name = b.jsx_id(name.name);
1215
+ if (name.name === '$children') {
1216
+ has_children_props = true;
1217
+ }
1218
+ jsx_name.loc = name.loc;
1187
1219
 
1188
- const attributes = node.attributes.map((attr) => {
1189
- if (attr.type === 'Attribute') {
1190
- const metadata = { await: false };
1191
- const name = visit(attr.name, { ...state, metadata });
1192
- const value = visit(attr.value, { ...state, metadata });
1193
- const jsx_name = b.jsx_id(name.name);
1194
- if (name.name === '$children') {
1195
- has_children_props = true;
1220
+ return b.jsx_attribute(jsx_name, b.jsx_expression_container(value));
1221
+ } else if (attr.type === 'SpreadAttribute') {
1222
+ const metadata = { await: false };
1223
+ const argument = visit(attr.argument, { ...state, metadata });
1224
+ return b.jsx_spread_attribute(argument);
1196
1225
  }
1197
- jsx_name.loc = name.loc;
1226
+ });
1198
1227
 
1199
- return b.jsx_attribute(jsx_name, b.jsx_expression_container(value));
1200
- } else {
1201
- debugger;
1202
- }
1203
- });
1228
+ // Add UseAttribute references separately for sourcemap purposes
1229
+ for (const use_attr of use_attributes) {
1230
+ const metadata = { await: false };
1231
+ const argument = visit(use_attr.argument, { ...state, metadata });
1232
+ state.init.push(b.stmt(argument));
1233
+ }
1204
1234
 
1205
1235
  if (!node.selfClosing && !has_children_props && node.children.length > 0) {
1206
1236
  const is_dom_element = type[0].toLowerCase() === type[0] && type[0] !== '$';
@@ -1,6 +1,6 @@
1
1
  import { decode } from '@jridgewell/sourcemap-codec';
2
2
 
3
- export const defaultMappingData = {
3
+ export const mapping_data = {
4
4
  verification: true,
5
5
  completion: true,
6
6
  semantic: true,
@@ -8,12 +8,11 @@ export const defaultMappingData = {
8
8
  };
9
9
 
10
10
  /**
11
- * Convert esrap SourceMap to Volar mappings using Svelte's approach
12
- * Based on: https://github.com/volarjs/svelte-language-tools/blob/master/packages/language-server/src/language.ts#L45-L88
13
- * @param {object} source_map - esrap SourceMap object
14
- * @param {string} source - Original Ripple source
15
- * @param {string} generated_code - Generated TypeScript code
16
- * @returns {object} Object with code and mappings for Volar
11
+ * Convert esrap SourceMap to Volar mappings
12
+ * @param {object} source_map
13
+ * @param {string} source
14
+ * @param {string} generated_code
15
+ * @returns {object}
17
16
  */
18
17
  export function convert_source_map_to_mappings(source_map, source, generated_code) {
19
18
  const mappings = [];
@@ -57,6 +56,11 @@ export function convert_source_map_to_mappings(source_map, source, generated_cod
57
56
  const generated_content = generated_code.substring(current_generated_offset, current_generated_offset + segment_length);
58
57
  const source_content = source.substring(source_offset, source_offset + segment_length);
59
58
 
59
+ // Skip mappings for UseAttribute syntax to avoid overlapping sourcemaps
60
+ if (source_content.includes('{@use ') || source_content.match(/\{\s*@use\s+/)) {
61
+ continue;
62
+ }
63
+
60
64
  // Fix for $children mapping: when generated content is "$children",
61
65
  // it should only map to the component name in the source, not include attributes
62
66
  if (generated_content === '$children') {
@@ -68,12 +72,11 @@ export function convert_source_map_to_mappings(source_map, source, generated_cod
68
72
  }
69
73
  }
70
74
 
71
- // Create Volar mapping with default mapping data
72
75
  mappings.push({
73
76
  sourceOffsets: [source_offset],
74
77
  generatedOffsets: [current_generated_offset],
75
78
  lengths: [segment_length],
76
- data: defaultMappingData
79
+ data: mapping_data
77
80
  });
78
81
  }
79
82