Skip to content

Commit 88c2d6e

Browse files
fix: Allow unquoted slash in attributes (#14615)
* test: add sample for unquoted attributes * fix: handle unquoted slash in attributes * docs: allow unquoted slash in attributes * test: add additional sample for unquoted href attributes * fix: improve handling of self-closing tags with unquoted attributes * Update .changeset/long-boxes-flow.md --------- Co-authored-by: Rich Harris <[email protected]>
1 parent 65db409 commit 88c2d6e

File tree

4 files changed

+105
-4
lines changed

4 files changed

+105
-4
lines changed

.changeset/long-boxes-flow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: allow unquoted slash in attributes

packages/svelte/src/compiler/phases/1-parse/state/element.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,8 +504,24 @@ function read_attribute(parser) {
504504
let value = true;
505505
if (parser.eat('=')) {
506506
parser.allow_whitespace();
507-
value = read_attribute_value(parser);
508-
end = parser.index;
507+
508+
if (parser.template[parser.index] === '/' && parser.template[parser.index + 1] === '>') {
509+
const char_start = parser.index;
510+
parser.index++; // consume '/'
511+
value = [
512+
{
513+
start: char_start,
514+
end: char_start + 1,
515+
type: 'Text',
516+
raw: '/',
517+
data: '/'
518+
}
519+
];
520+
end = parser.index;
521+
} else {
522+
value = read_attribute_value(parser);
523+
end = parser.index;
524+
}
509525
} else if (parser.match_regex(regex_starts_with_quote_characters)) {
510526
e.expected_token(parser.index, '=');
511527
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
<div class=foo></div>
1+
<div class=foo></div>
2+
<a href=/>home</a>
3+
<a href=/foo>home</a>

packages/svelte/tests/parser-legacy/samples/attribute-unquoted/output.json

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"html": {
33
"type": "Fragment",
44
"start": 0,
5-
"end": 21,
5+
"end": 62,
66
"children": [
77
{
88
"type": "Element",
@@ -27,6 +27,84 @@
2727
}
2828
],
2929
"children": []
30+
},
31+
{
32+
"type": "Text",
33+
"start": 21,
34+
"end": 22,
35+
"raw": "\n",
36+
"data": "\n"
37+
},
38+
{
39+
"type": "Element",
40+
"start": 22,
41+
"end": 40,
42+
"name": "a",
43+
"attributes": [
44+
{
45+
"type": "Attribute",
46+
"start": 25,
47+
"end": 31,
48+
"name": "href",
49+
"value": [
50+
{
51+
"start": 30,
52+
"end": 31,
53+
"type": "Text",
54+
"raw": "/",
55+
"data": "/"
56+
}
57+
]
58+
}
59+
],
60+
"children": [
61+
{
62+
"type": "Text",
63+
"start": 32,
64+
"end": 36,
65+
"raw": "home",
66+
"data": "home"
67+
}
68+
]
69+
},
70+
{
71+
"type": "Text",
72+
"start": 40,
73+
"end": 41,
74+
"raw": "\n",
75+
"data": "\n"
76+
},
77+
{
78+
"type": "Element",
79+
"start": 41,
80+
"end": 62,
81+
"name": "a",
82+
"attributes": [
83+
{
84+
"type": "Attribute",
85+
"start": 44,
86+
"end": 53,
87+
"name": "href",
88+
"value": [
89+
{
90+
"start": 49,
91+
"end": 53,
92+
"type": "Text",
93+
"raw": "/foo",
94+
"data": "/foo"
95+
}
96+
]
97+
}
98+
],
99+
"children": [
100+
{
101+
"type": "Text",
102+
"start": 54,
103+
"end": 58,
104+
"raw": "home",
105+
"data": "home"
106+
}
107+
]
30108
}
31109
]
32110
}

0 commit comments

Comments
 (0)