Repository: sveltejs/svelte (JavaScript)
Date: 2021-07-18 14:20:19+00:00
Task type: Bug Fix

Issue:
Parser Attribute value undefined for empty string
https://astexplorer.net/#/gist/30071e5e2620f2d0e2e38f54cb7350b8/a5398ab81434679120e3d97c516bba48143bc3c5
```svelte
<input foo="" />
```
```json
{
  "start": 7,
  "end": 13,
  "type": "Attribute",
  "name": "foo",
  "value": []
}
```
Unexpected : `value` is undefined

Expected 
```json
"value": [
  {
    "start": 12,
    "end": 12,
    "type": "Text",
    "raw": "",
    "data": ""
  }
]
```


Issue discussion:

Solution patch:
diff --git a/src/compiler/parse/state/tag.ts b/src/compiler/parse/state/tag.ts
--- a/src/compiler/parse/state/tag.ts
+++ b/src/compiler/parse/state/tag.ts
@@ -465,6 +465,15 @@ function get_directive_type(name: string): DirectiveType {
 
 function read_attribute_value(parser: Parser) {
 	const quote_mark = parser.eat("'") ? "'" : parser.eat('"') ? '"' : null;
+	if (quote_mark && parser.eat(quote_mark)) {
+		return [{
+			start: parser.index - 1,
+			end: parser.index - 1,
+			type: 'Text',
+			raw: '',
+			data: ''
+		}];
+	}
 
 	const regex = (
 		quote_mark === "'" ? /'/ :


Test patch:
diff --git a/test/parser/samples/element-with-attribute-empty-string/input.svelte b/test/parser/samples/element-with-attribute-empty-string/input.svelte
new file mode 100644
--- /dev/null
+++ b/test/parser/samples/element-with-attribute-empty-string/input.svelte
@@ -0,0 +1,2 @@
+<span attr=""></span>
+<span attr=''></span>
diff --git a/test/parser/samples/element-with-attribute-empty-string/output.json b/test/parser/samples/element-with-attribute-empty-string/output.json
new file mode 100644
--- /dev/null
+++ b/test/parser/samples/element-with-attribute-empty-string/output.json
@@ -0,0 +1,64 @@
+{
+	"html": {
+		"start": 0,
+		"end": 43,
+		"type": "Fragment",
+		"children": [
+			{
+				"start": 0,
+				"end": 21,
+				"type": "Element",
+				"name": "span",
+				"attributes": [
+					{
+						"start": 6,
+						"end": 13,
+						"type": "Attribute",
+						"name": "attr",
+						"value": [
+							{
+								"start": 12,
+								"end": 12,
+								"type": "Text",
+								"raw": "",
+								"data": ""
+							}
+						]
+					}
+				],
+				"children": []
+			},
+			{
+				"start": 21,
+				"end": 22,
+				"type": "Text",
+				"raw": "\n",
+				"data": "\n"
+			},
+			{
+				"start": 22,
+				"end": 43,
+				"type": "Element",
+				"name": "span",
+				"attributes": [
+					{
+						"start": 28,
+						"end": 35,
+						"type": "Attribute",
+						"name": "attr",
+						"value": [
+							{
+								"start": 34,
+								"end": 34,
+								"type": "Text",
+								"raw": "",
+								"data": ""
+							}
+						]
+					}
+				],
+				"children": []
+			}
+		]
+	}
+}
diff --git a/test/parser/samples/element-with-attribute/input.svelte b/test/parser/samples/element-with-attribute/input.svelte
new file mode 100644
--- /dev/null
+++ b/test/parser/samples/element-with-attribute/input.svelte
@@ -0,0 +1,2 @@
+<span attr="foo"></span>
+<span attr='bar'></span>
diff --git a/test/parser/samples/element-with-attribute/output.json b/test/parser/samples/element-with-attribute/output.json
new file mode 100644
--- /dev/null
+++ b/test/parser/samples/element-with-attribute/output.json
@@ -0,0 +1,64 @@
+{
+	"html": {
+		"start": 0,
+		"end": 49,
+		"type": "Fragment",
+		"children": [
+			{
+				"start": 0,
+				"end": 24,
+				"type": "Element",
+				"name": "span",
+				"attributes": [
+					{
+						"start": 6,
+						"end": 16,
+						"type": "Attribute",
+						"name": "attr",
+						"value": [
+							{
+								"start": 12,
+								"end": 15,
+								"type": "Text",
+								"raw": "foo",
+								"data": "foo"
+							}
+						]
+					}
+				],
+				"children": []
+			},
+			{
+				"start": 24,
+				"end": 25,
+				"type": "Text",
+				"raw": "\n",
+				"data": "\n"
+			},
+			{
+				"start": 25,
+				"end": 49,
+				"type": "Element",
+				"name": "span",
+				"attributes": [
+					{
+						"start": 31,
+						"end": 41,
+						"type": "Attribute",
+						"name": "attr",
+						"value": [
+							{
+								"start": 37,
+								"end": 40,
+								"type": "Text",
+								"raw": "bar",
+								"data": "bar"
+							}
+						]
+					}
+				],
+				"children": []
+			}
+		]
+	}
+}