diff --git a/.changeset/long-boxes-flow.md b/.changeset/long-boxes-flow.md new file mode 100644 index 0000000000..d249354b67 --- /dev/null +++ b/.changeset/long-boxes-flow.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: allow unquoted slash in attributes 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 45350bb1ae..cd5cdd3e6e 100644 --- a/packages/svelte/src/compiler/phases/1-parse/state/element.js +++ b/packages/svelte/src/compiler/phases/1-parse/state/element.js @@ -504,8 +504,24 @@ function read_attribute(parser) { let value = true; if (parser.eat('=')) { parser.allow_whitespace(); - value = read_attribute_value(parser); - end = parser.index; + + if (parser.template[parser.index] === '/' && parser.template[parser.index + 1] === '>') { + const char_start = parser.index; + parser.index++; // consume '/' + value = [ + { + start: char_start, + end: char_start + 1, + type: 'Text', + raw: '/', + data: '/' + } + ]; + end = parser.index; + } else { + value = read_attribute_value(parser); + end = parser.index; + } } else if (parser.match_regex(regex_starts_with_quote_characters)) { e.expected_token(parser.index, '='); } diff --git a/packages/svelte/tests/parser-legacy/samples/attribute-unquoted/input.svelte b/packages/svelte/tests/parser-legacy/samples/attribute-unquoted/input.svelte index 4bab0df72f..527d6eebf1 100644 --- a/packages/svelte/tests/parser-legacy/samples/attribute-unquoted/input.svelte +++ b/packages/svelte/tests/parser-legacy/samples/attribute-unquoted/input.svelte @@ -1 +1,3 @@ -
\ No newline at end of file +
+home +home \ No newline at end of file diff --git a/packages/svelte/tests/parser-legacy/samples/attribute-unquoted/output.json b/packages/svelte/tests/parser-legacy/samples/attribute-unquoted/output.json index 5df4d66ab6..ab2912a2c0 100644 --- a/packages/svelte/tests/parser-legacy/samples/attribute-unquoted/output.json +++ b/packages/svelte/tests/parser-legacy/samples/attribute-unquoted/output.json @@ -2,7 +2,7 @@ "html": { "type": "Fragment", "start": 0, - "end": 21, + "end": 62, "children": [ { "type": "Element", @@ -27,6 +27,84 @@ } ], "children": [] + }, + { + "type": "Text", + "start": 21, + "end": 22, + "raw": "\n", + "data": "\n" + }, + { + "type": "Element", + "start": 22, + "end": 40, + "name": "a", + "attributes": [ + { + "type": "Attribute", + "start": 25, + "end": 31, + "name": "href", + "value": [ + { + "start": 30, + "end": 31, + "type": "Text", + "raw": "/", + "data": "/" + } + ] + } + ], + "children": [ + { + "type": "Text", + "start": 32, + "end": 36, + "raw": "home", + "data": "home" + } + ] + }, + { + "type": "Text", + "start": 40, + "end": 41, + "raw": "\n", + "data": "\n" + }, + { + "type": "Element", + "start": 41, + "end": 62, + "name": "a", + "attributes": [ + { + "type": "Attribute", + "start": 44, + "end": 53, + "name": "href", + "value": [ + { + "start": 49, + "end": 53, + "type": "Text", + "raw": "/foo", + "data": "/foo" + } + ] + } + ], + "children": [ + { + "type": "Text", + "start": 54, + "end": 58, + "raw": "home", + "data": "home" + } + ] } ] }