* @param {AST.RegularElement | AST.SvelteElement | AST.SvelteComponent | AST.Component | AST.SlotElement | AST.SvelteFragment} node * @param {AST.SvelteNode[]} path * @param {State} state
(node, path, state)
| 1420 | * @param {State} state |
| 1421 | */ |
| 1422 | function migrate_slot_usage(node, path, state) { |
| 1423 | const parent = path.at(-2); |
| 1424 | // Bail on custom element slot usage |
| 1425 | if ( |
| 1426 | parent?.type !== 'Component' && |
| 1427 | parent?.type !== 'SvelteComponent' && |
| 1428 | node.type !== 'Component' && |
| 1429 | node.type !== 'SvelteComponent' |
| 1430 | ) { |
| 1431 | return; |
| 1432 | } |
| 1433 | |
| 1434 | let snippet_name = 'children'; |
| 1435 | let snippet_props = []; |
| 1436 | |
| 1437 | // if we stop the transform because the name is not correct we don't want to |
| 1438 | // remove the let directive and they could come before the name |
| 1439 | let removal_queue = []; |
| 1440 | |
| 1441 | for (let attribute of node.attributes) { |
| 1442 | if ( |
| 1443 | attribute.type === 'Attribute' && |
| 1444 | attribute.name === 'slot' && |
| 1445 | is_text_attribute(attribute) |
| 1446 | ) { |
| 1447 | snippet_name = attribute.value[0].data; |
| 1448 | // the default slot in svelte 4 if what the children slot is for svelte 5 |
| 1449 | if (snippet_name === 'default') { |
| 1450 | snippet_name = 'children'; |
| 1451 | } |
| 1452 | if (!regex_is_valid_identifier.test(snippet_name) || is_reserved(snippet_name)) { |
| 1453 | has_migration_task = true; |
| 1454 | state.str.appendLeft( |
| 1455 | node.start, |
| 1456 | `<!-- @migration-task: migrate this slot by hand, \`${snippet_name}\` is an invalid identifier -->\n${state.indent}` |
| 1457 | ); |
| 1458 | return; |
| 1459 | } |
| 1460 | if (parent?.type === 'Component' || parent?.type === 'SvelteComponent') { |
| 1461 | for (let attribute of parent.attributes) { |
| 1462 | if (attribute.type === 'Attribute' || attribute.type === 'BindDirective') { |
| 1463 | if (attribute.name === snippet_name) { |
| 1464 | state.str.appendLeft( |
| 1465 | node.start, |
| 1466 | `<!-- @migration-task: migrate this slot by hand, \`${snippet_name}\` would shadow a prop on the parent component -->\n${state.indent}` |
| 1467 | ); |
| 1468 | return; |
| 1469 | } |
| 1470 | } |
| 1471 | } |
| 1472 | } |
| 1473 | // flush the queue after we found the name |
| 1474 | for (let remove_let of removal_queue) { |
| 1475 | remove_let(); |
| 1476 | } |
| 1477 | state.str.remove(attribute.start, attribute.end); |
| 1478 | } |
| 1479 | if (attribute.type === 'LetDirective') { |
no test coverage detected