Skip to content

Commit 855af3b

Browse files
authored
feat: support {@Attach ...} (#714)
1 parent 10fc353 commit 855af3b

33 files changed

+49078
-2
lines changed

.changeset/public-sheep-speak.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte-eslint-parser": minor
3+
---
4+
5+
feat: support `{@attach ...}`

docs/AST.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ interface SvelteStartTag extends Node {
169169
| SvelteAttribute
170170
| SvelteShorthandAttribute
171171
| SvelteSpreadAttribute
172+
| SvelteAttachTag
172173
| SvelteDirective
173174
| SvelteStyleDirective
174175
| SvelteSpecialDirective
@@ -451,6 +452,18 @@ interface SvelteRenderTag extends Node {
451452
}
452453
```
453454

455+
### SvelteAttachTag
456+
457+
This is `{@attach}` tag node.
458+
459+
```ts
460+
export interface SvelteAttachTag extends BaseNode {
461+
type: "SvelteAttachTag";
462+
expression: ESTree.Expression;
463+
parent: SvelteStartTag;
464+
}
465+
```
466+
454467
### SvelteIfBlock
455468

456469
This is the `{#if}` tag node. `{:else if}` is also included in this node.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
"prettier-plugin-svelte": "^3.3.3",
106106
"rimraf": "^6.0.1",
107107
"semver": "^7.7.1",
108-
"svelte": "^5.25.3",
108+
"svelte": "^5.30.1",
109109
"svelte2tsx": "^0.7.35",
110110
"tsx": "^4.19.3",
111111
"typescript": "~5.8.2",

src/ast/html.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export type SvelteHTMLNode =
3131
| SvelteAttribute
3232
| SvelteShorthandAttribute
3333
| SvelteSpreadAttribute
34+
| SvelteAttachTag
3435
| SvelteDirective
3536
| SvelteStyleDirective
3637
| SvelteSpecialDirective
@@ -142,6 +143,7 @@ export interface SvelteStartTag extends BaseNode {
142143
| SvelteAttribute
143144
| SvelteShorthandAttribute
144145
| SvelteSpreadAttribute
146+
| SvelteAttachTag
145147
| SvelteDirective
146148
| SvelteStyleDirective
147149
| SvelteSpecialDirective
@@ -541,6 +543,12 @@ export interface SvelteSpreadAttribute extends BaseNode {
541543
parent: SvelteStartTag;
542544
}
543545

546+
export interface SvelteAttachTag extends BaseNode {
547+
type: "SvelteAttachTag";
548+
expression: ESTree.Expression;
549+
parent: SvelteStartTag;
550+
}
551+
544552
/** Node of directive. e.g. `<input bind:value />` */
545553
export type SvelteDirective =
546554
| SvelteActionDirective

src/parser/converts/attr.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
SvelteAnimationDirective,
44
SvelteAttribute,
55
SvelteShorthandAttribute,
6+
SvelteAttachTag,
67
SvelteBindingDirective,
78
SvelteClassDirective,
89
SvelteDirective,
@@ -48,6 +49,7 @@ export function* convertAttributes(
4849
| SvAST.AttributeOrDirective
4950
| Compiler.Attribute
5051
| Compiler.SpreadAttribute
52+
| Compiler.AttachTag
5153
| Compiler.Directive
5254
)[],
5355
parent: SvelteStartTag,
@@ -56,6 +58,7 @@ export function* convertAttributes(
5658
| SvelteAttribute
5759
| SvelteShorthandAttribute
5860
| SvelteSpreadAttribute
61+
| SvelteAttachTag
5962
| SvelteDirective
6063
| SvelteStyleDirective
6164
> {
@@ -68,6 +71,10 @@ export function* convertAttributes(
6871
yield convertSpreadAttribute(attr, parent, ctx);
6972
continue;
7073
}
74+
if (attr.type === "AttachTag") {
75+
yield convertAttachTag(attr, parent, ctx);
76+
continue;
77+
}
7178
if (attr.type === "BindDirective" || attr.type === "Binding") {
7279
yield convertBindingDirective(attr, parent, ctx);
7380
continue;
@@ -344,6 +351,31 @@ function convertSpreadAttribute(
344351
return attribute;
345352
}
346353

354+
function convertAttachTag(
355+
node: Compiler.AttachTag,
356+
parent: SvelteAttachTag["parent"],
357+
ctx: Context,
358+
): SvelteAttachTag {
359+
const attachTag: SvelteAttachTag = {
360+
type: "SvelteAttachTag",
361+
expression: node.expression,
362+
parent,
363+
...ctx.getConvertLocation(node),
364+
};
365+
366+
ctx.scriptLet.addExpression(node.expression, attachTag, null, (es) => {
367+
attachTag.expression = es;
368+
});
369+
370+
const atAttachStart = ctx.code.indexOf("@attach", attachTag.range[0]);
371+
ctx.addToken("MustacheKeyword", {
372+
start: atAttachStart,
373+
end: atAttachStart + 7,
374+
});
375+
376+
return attachTag;
377+
}
378+
347379
/** Convert for Binding Directive */
348380
function convertBindingDirective(
349381
node: SvAST.DirectiveForExpression | Compiler.BindDirective,

src/parser/converts/element.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,13 +223,19 @@ export function* convertChildren(
223223
function extractLetDirectives(fragment: {
224224
attributes:
225225
| SvAST.AttributeOrDirective[]
226-
| (Compiler.Attribute | Compiler.SpreadAttribute | Compiler.Directive)[];
226+
| (
227+
| Compiler.Attribute
228+
| Compiler.SpreadAttribute
229+
| Compiler.AttachTag
230+
| Compiler.Directive
231+
)[];
227232
}): {
228233
letDirectives: (SvAST.LetDirective | Compiler.LetDirective)[];
229234
attributes: Exclude<
230235
| SvAST.AttributeOrDirective
231236
| Compiler.Attribute
232237
| Compiler.SpreadAttribute
238+
| Compiler.AttachTag
233239
| Compiler.Directive,
234240
SvAST.LetDirective | Compiler.LetDirective
235241
>[];
@@ -239,6 +245,7 @@ function extractLetDirectives(fragment: {
239245
| SvAST.AttributeOrDirective
240246
| Compiler.Attribute
241247
| Compiler.SpreadAttribute
248+
| Compiler.AttachTag
242249
| Compiler.Directive,
243250
SvAST.LetDirective | Compiler.LetDirective
244251
>[] = [];

src/parser/svelte-ast-types-for-v5.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export type SnippetBlock = AST.SnippetBlock;
3737
export type Comment = AST.Comment;
3838
export type Attribute = AST.Attribute;
3939
export type SpreadAttribute = AST.SpreadAttribute;
40+
export type AttachTag = AST.AttachTag;
4041
export type AnimateDirective = AST.AnimateDirective;
4142
export type BindDirective = AST.BindDirective;
4243
export type ClassDirective = AST.ClassDirective;

src/visitor-keys.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const svelteKeys: SvelteKeysType = {
4242
SvelteAttribute: ["key", "value"],
4343
SvelteShorthandAttribute: ["key", "value"],
4444
SvelteSpreadAttribute: ["argument"],
45+
SvelteAttachTag: ["expression"],
4546
SvelteDirective: ["key", "expression"],
4647
SvelteStyleDirective: ["key", "value"],
4748
SvelteSpecialDirective: ["key", "expression"],
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script lang="ts">
2+
import type { Attachment } from 'svelte/attachments';
3+
4+
5+
const myAttachment: Attachment = (element) => {
6+
console.log(element.nodeName); // 'DIV'
7+
8+
return () => {
9+
console.log('cleaning up');
10+
};
11+
};
12+
</script>
13+
14+
<div {@attach myAttachment}>...</div>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy