From 14ea7fa52465810d513ac8e9bcf1185ad554ea4d Mon Sep 17 00:00:00 2001 From: Tim Londschien Date: Tue, 18 Nov 2025 14:29:37 +0100 Subject: [PATCH 1/3] add attribute comments --- .../compiler/phases/1-parse/state/element.js | 22 ++++++++++++++++- .../html-attribute-comment/input.svelte | 3 +++ .../html-attribute-comment/output.json | 24 +++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 packages/svelte/tests/parser-modern/samples/html-attribute-comment/input.svelte create mode 100644 packages/svelte/tests/parser-modern/samples/html-attribute-comment/output.json diff --git a/packages/svelte/src/compiler/phases/1-parse/state/element.js b/packages/svelte/src/compiler/phases/1-parse/state/element.js index 9167888e37d3..73523f5edb56 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/element.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/element.js @@ -215,8 +215,15 @@ export default function element(parser) { const read = is_top_level_script_or_style ? read_static_attribute : read_attribute; + /** @type {ReturnType} */ let attribute; while ((attribute = read(parser))) { + // {/* comment */} + if (attribute.type === 'Comment') { + parser.allow_whitespace(); + continue; + } + // animate and transition can only be specified once per element so no need // to check here, use can be used multiple times, same for the on directive // finally let already has error handling in case of duplicate variable names @@ -490,7 +497,7 @@ function read_static_attribute(parser) { /** * @param {Parser} parser - * @returns {AST.Attribute | AST.SpreadAttribute | AST.Directive | AST.AttachTag | null} + * @returns {AST.Attribute | AST.SpreadAttribute | AST.Directive | AST.AttachTag | AST.Comment | null} */ function read_attribute(parser) { const start = parser.index; @@ -537,6 +544,19 @@ function read_attribute(parser) { }; return spread; + } else if (parser.eat('/*')) { + const data = parser.read_until(/\*\/\}/); + parser.eat('*/}', true); + + /** @type {AST.Comment} */ + const comment = { + type: 'Comment', + data: data, + start, + end: parser.index + }; + + return comment; } else { const value_start = parser.index; let name = parser.read_identifier(); diff --git a/packages/svelte/tests/parser-modern/samples/html-attribute-comment/input.svelte b/packages/svelte/tests/parser-modern/samples/html-attribute-comment/input.svelte new file mode 100644 index 000000000000..5d82ddd2c10c --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/html-attribute-comment/input.svelte @@ -0,0 +1,3 @@ +
diff --git a/packages/svelte/tests/parser-modern/samples/html-attribute-comment/output.json b/packages/svelte/tests/parser-modern/samples/html-attribute-comment/output.json new file mode 100644 index 000000000000..804dc0fc7d83 --- /dev/null +++ b/packages/svelte/tests/parser-modern/samples/html-attribute-comment/output.json @@ -0,0 +1,24 @@ +{ + "css": null, + "js": [], + "start": 0, + "end": 62, + "type": "Root", + "fragment": { + "type": "Fragment", + "nodes": [ + { + "type": "RegularElement", + "start": 0, + "end": 62, + "name": "div", + "attributes": [], + "fragment": { + "type": "Fragment", + "nodes": [] + } + } + ] + }, + "options": null +} From a3d76300946bfb10952c89ee78aebd678be71413 Mon Sep 17 00:00:00 2001 From: Tim Londschien Date: Tue, 18 Nov 2025 14:52:57 +0100 Subject: [PATCH 2/3] change from using `AST.Comment` to its own `AST.CommentAttribute` --- .../svelte/src/compiler/phases/1-parse/state/element.js | 8 ++++---- packages/svelte/src/compiler/types/template.d.ts | 8 ++++++++ packages/svelte/types/index.d.ts | 8 ++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/svelte/src/compiler/phases/1-parse/state/element.js b/packages/svelte/src/compiler/phases/1-parse/state/element.js index 73523f5edb56..2179c8901b15 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/element.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/element.js @@ -219,7 +219,7 @@ export default function element(parser) { let attribute; while ((attribute = read(parser))) { // {/* comment */} - if (attribute.type === 'Comment') { + if (attribute.type === 'CommentAttribute') { parser.allow_whitespace(); continue; } @@ -497,7 +497,7 @@ function read_static_attribute(parser) { /** * @param {Parser} parser - * @returns {AST.Attribute | AST.SpreadAttribute | AST.Directive | AST.AttachTag | AST.Comment | null} + * @returns {AST.Attribute | AST.SpreadAttribute | AST.Directive | AST.AttachTag | AST.CommentAttribute | null} */ function read_attribute(parser) { const start = parser.index; @@ -548,9 +548,9 @@ function read_attribute(parser) { const data = parser.read_until(/\*\/\}/); parser.eat('*/}', true); - /** @type {AST.Comment} */ + /** @type {AST.CommentAttribute} */ const comment = { - type: 'Comment', + type: 'CommentAttribute', data: data, start, end: parser.index diff --git a/packages/svelte/src/compiler/types/template.d.ts b/packages/svelte/src/compiler/types/template.d.ts index fd664f107c0e..fa3361a1ae3c 100644 --- a/packages/svelte/src/compiler/types/template.d.ts +++ b/packages/svelte/src/compiler/types/template.d.ts @@ -143,6 +143,13 @@ export namespace AST { data: string; } + /** An Attribute comment `{/* ... *​/}` */ + export interface CommentAttribute extends BaseNode { + type: 'CommentAttribute'; + /** the contents of the comment */ + data: string; + } + /** A `{@const ...}` tag */ export interface ConstTag extends BaseNode { type: 'ConstTag'; @@ -613,6 +620,7 @@ export namespace AST { | Directive | AST.AttachTag | AST.Comment + | AST.CommentAttribute | Block; export type SvelteNode = Node | TemplateNode | AST.Fragment | _CSS.Node | Script; diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 5e3ca77eb5cd..7e066c770960 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -1273,6 +1273,13 @@ declare module 'svelte/compiler' { data: string; } + /** An Attribute comment `{/* ... *​/}` */ + export interface CommentAttribute extends BaseNode { + type: 'CommentAttribute'; + /** the contents of the comment */ + data: string; + } + /** A `{@const ...}` tag */ export interface ConstTag extends BaseNode { type: 'ConstTag'; @@ -1601,6 +1608,7 @@ declare module 'svelte/compiler' { | Directive | AST.AttachTag | AST.Comment + | AST.CommentAttribute | Block; export type SvelteNode = Node | TemplateNode | AST.Fragment | _CSS.Node | Script; From 85242fc0017bbb3609560d74a5dfdca1b7458a54 Mon Sep 17 00:00:00 2001 From: Tim Londschien Date: Tue, 18 Nov 2025 15:02:59 +0100 Subject: [PATCH 3/3] add changeset --- .changeset/salty-plants-pump.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/salty-plants-pump.md diff --git a/.changeset/salty-plants-pump.md b/.changeset/salty-plants-pump.md new file mode 100644 index 000000000000..6d863c2a9b9b --- /dev/null +++ b/.changeset/salty-plants-pump.md @@ -0,0 +1,5 @@ +--- +'svelte': minor +--- + +Add ability to comment out attributes [RFC](https://github.com/sveltejs/rfcs/pull/43)