--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`parser/parse invalid html 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 1,
+ "line": 3,
+ "offset": 13,
+ },
+ "source": "<span>
+",
+ "start": Object {
+ "column": 1,
+ "line": 2,
+ "offset": 6,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "span",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 7,
+ "line": 3,
+ "offset": 19,
+ },
+ "source": "<div>
+<span>
+</div>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 8,
+ "line": 4,
+ "offset": 27,
+ },
+ "source": "<div>
+<span>
+</div>
+</span>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option ABRUPT_CLOSING_OF_EMPTY_COMMENT <template><!--></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "",
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "<!-->",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "<template><!--></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "<template><!--></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option ABRUPT_CLOSING_OF_EMPTY_COMMENT <template><!---></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "",
+ "loc": Object {
+ "end": Object {
+ "column": 17,
+ "line": 1,
+ "offset": 16,
+ },
+ "source": "<!--->",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<template><!---></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<template><!---></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option ABRUPT_CLOSING_OF_EMPTY_COMMENT <template><!----></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "",
+ "loc": Object {
+ "end": Object {
+ "column": 18,
+ "line": 1,
+ "offset": 17,
+ },
+ "source": "<!---->",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 29,
+ "line": 1,
+ "offset": 28,
+ },
+ "source": "<template><!----></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 29,
+ "line": 1,
+ "offset": 28,
+ },
+ "source": "<template><!----></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template attr="c"></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 35,
+ "line": 1,
+ "offset": 34,
+ },
+ "source": "<template attr=\\"c\\"></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "attr=\\"c\\"",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "name": "attr",
+ "type": 3,
+ "value": Object {
+ "content": "c",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "\\"c\\"",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 35,
+ "line": 1,
+ "offset": 34,
+ },
+ "source": "<template attr=\\"c\\"></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template attr="&#a;"></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": "<template attr=\\"&#a;\\"></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ "source": "attr=\\"&#a;\\"",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "name": "attr",
+ "type": 3,
+ "value": Object {
+ "content": "&#a;",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ "source": "\\"&#a;\\"",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": "<template attr=\\"&#a;\\"></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template attr="ÿ"></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 36,
+ "line": 1,
+ "offset": 35,
+ },
+ "source": "<template attr=\\"ÿ\\"></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "attr=\\"ÿ\\"",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "name": "attr",
+ "type": 3,
+ "value": Object {
+ "content": "ÿ",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "\\"ÿ\\"",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 36,
+ "line": 1,
+ "offset": 35,
+ },
+ "source": "<template attr=\\"ÿ\\"></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template attr="&#xg;"></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 35,
+ "line": 1,
+ "offset": 34,
+ },
+ "source": "<template attr=\\"&#xg;\\"></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "attr=\\"&#xg;\\"",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "name": "attr",
+ "type": 3,
+ "value": Object {
+ "content": "&#xg;",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "\\"&#xg;\\"",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 35,
+ "line": 1,
+ "offset": 34,
+ },
+ "source": "<template attr=\\"&#xg;\\"></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template>c</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "c",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "c",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "<template>c</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "<template>c</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template>&#a;</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "&#a;",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 15,
+ "line": 1,
+ "offset": 14,
+ },
+ "source": "&#a;",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 26,
+ "line": 1,
+ "offset": 25,
+ },
+ "source": "<template>&#a;</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 26,
+ "line": 1,
+ "offset": 25,
+ },
+ "source": "<template>&#a;</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template>ÿ</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "ÿ",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 17,
+ "line": 1,
+ "offset": 16,
+ },
+ "source": "ÿ",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<template>ÿ</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<template>ÿ</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template>&#xg;</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "&#xg;",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "&#xg;",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "<template>&#xg;</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "<template>&#xg;</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option CDATA_IN_HTML_CONTENT <template><![CDATA[cdata]]></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "[CDATA[cdata]]",
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<![CDATA[cdata]]>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 39,
+ "line": 1,
+ "offset": 38,
+ },
+ "source": "<template><![CDATA[cdata]]></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 39,
+ "line": 1,
+ "offset": 38,
+ },
+ "source": "<template><![CDATA[cdata]]></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option CDATA_IN_HTML_CONTENT <template><svg><![CDATA[cdata]]></svg></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "cdata",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "cdata",
+ "start": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 39,
+ "line": 1,
+ "offset": 38,
+ },
+ "source": "<svg><![CDATA[cdata]]></svg>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 1,
+ "props": Array [],
+ "tag": "svg",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 50,
+ "line": 1,
+ "offset": 49,
+ },
+ "source": "<template><svg><![CDATA[cdata]]></svg></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 50,
+ "line": 1,
+ "offset": 49,
+ },
+ "source": "<template><svg><![CDATA[cdata]]></svg></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option CHARACTER_REFERENCE_OUTSIDE_UNICODE_RANGE <template>�</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "�",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 21,
+ "line": 1,
+ "offset": 20,
+ },
+ "source": "�",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 32,
+ "line": 1,
+ "offset": 31,
+ },
+ "source": "<template>�</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 32,
+ "line": 1,
+ "offset": 31,
+ },
+ "source": "<template>�</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option CONTROL_CHARACTER_REFERENCE <template></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "\ 3",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 18,
+ "line": 1,
+ "offset": 17,
+ },
+ "source": "",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 29,
+ "line": 1,
+ "offset": 28,
+ },
+ "source": "<template></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 29,
+ "line": 1,
+ "offset": 28,
+ },
+ "source": "<template></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option CONTROL_CHARACTER_REFERENCE <template></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "\7f",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 17,
+ "line": 1,
+ "offset": 16,
+ },
+ "source": "",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<template></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<template></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option DUPLICATE_ATTRIBUTE <template><div id="" id=""></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": "<div id=\\"\\" id=\\"\\"></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 21,
+ "line": 1,
+ "offset": 20,
+ },
+ "source": "id=\\"\\"",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": Object {
+ "content": "",
+ "isEmpty": true,
+ "loc": Object {
+ "end": Object {
+ "column": 21,
+ "line": 1,
+ "offset": 20,
+ },
+ "source": "\\"\\"",
+ "start": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ },
+ "type": 0,
+ },
+ },
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "id=\\"\\"",
+ "start": Object {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": Object {
+ "content": "",
+ "isEmpty": true,
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "\\"\\"",
+ "start": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 45,
+ "line": 1,
+ "offset": 44,
+ },
+ "source": "<template><div id=\\"\\" id=\\"\\"></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 45,
+ "line": 1,
+ "offset": 44,
+ },
+ "source": "<template><div id=\\"\\" id=\\"\\"></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option END_TAG_WITH_ATTRIBUTES <template><div></div id=""></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<div></div id=\\"\\">",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 39,
+ "line": 1,
+ "offset": 38,
+ },
+ "source": "<template><div></div id=\\"\\"></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 39,
+ "line": 1,
+ "offset": 38,
+ },
+ "source": "<template><div></div id=\\"\\"></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option END_TAG_WITH_TRAILING_SOLIDUS <template><div></div/></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "<div></div/>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": "<template><div></div/></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": "<template><div></div/></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_BEFORE_TAG_NAME <template>< 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "<",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 12,
+ "line": 1,
+ "offset": 11,
+ },
+ "source": "<",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 12,
+ "line": 1,
+ "offset": 11,
+ },
+ "source": "<template><",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 12,
+ "line": 1,
+ "offset": 11,
+ },
+ "source": "<template><",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_BEFORE_TAG_NAME <template></ 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "</",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 13,
+ "line": 1,
+ "offset": 12,
+ },
+ "source": "</",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 13,
+ "line": 1,
+ "offset": 12,
+ },
+ "source": "<template></",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 13,
+ "line": 1,
+ "offset": 12,
+ },
+ "source": "<template></",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_CDATA <template><svg><![CDATA[ 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<svg><![CDATA[",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 1,
+ "props": Array [],
+ "tag": "svg",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<template><svg><![CDATA[",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<template><svg><![CDATA[",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_CDATA <template><svg><![CDATA[cdata 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "cdata",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "cdata",
+ "start": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "<svg><![CDATA[cdata",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 1,
+ "props": Array [],
+ "tag": "svg",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "<template><svg><![CDATA[cdata",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "<template><svg><![CDATA[cdata",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_COMMENT <template><! 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "",
+ "loc": Object {
+ "end": Object {
+ "column": 13,
+ "line": 1,
+ "offset": 12,
+ },
+ "source": "<!",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 13,
+ "line": 1,
+ "offset": 12,
+ },
+ "source": "<template><!",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 13,
+ "line": 1,
+ "offset": 12,
+ },
+ "source": "<template><!",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_COMMENT <template><!- 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "-",
+ "loc": Object {
+ "end": Object {
+ "column": 14,
+ "line": 1,
+ "offset": 13,
+ },
+ "source": "<!-",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 14,
+ "line": 1,
+ "offset": 13,
+ },
+ "source": "<template><!-",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 14,
+ "line": 1,
+ "offset": 13,
+ },
+ "source": "<template><!-",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_COMMENT <template><!-- 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "",
+ "loc": Object {
+ "end": Object {
+ "column": 15,
+ "line": 1,
+ "offset": 14,
+ },
+ "source": "<!--",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 15,
+ "line": 1,
+ "offset": 14,
+ },
+ "source": "<template><!--",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 15,
+ "line": 1,
+ "offset": 14,
+ },
+ "source": "<template><!--",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_COMMENT <template><!--comment 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "comment",
+ "loc": Object {
+ "end": Object {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ "source": "<!--comment",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ "source": "<template><!--comment",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ "source": "<template><!--comment",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_COMMENT <template><!abc 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "abc",
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "<!abc",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "<template><!abc",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "<template><!abc",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT <script><!--console.log('hello') 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "<!--console.log('hello')",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 33,
+ "line": 1,
+ "offset": 32,
+ },
+ "source": "<!--console.log('hello')",
+ "start": Object {
+ "column": 9,
+ "line": 1,
+ "offset": 8,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 33,
+ "line": 1,
+ "offset": 32,
+ },
+ "source": "<script><!--console.log('hello')",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "script",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 33,
+ "line": 1,
+ "offset": 32,
+ },
+ "source": "<script><!--console.log('hello')",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT <script>console.log('hello') 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "console.log('hello')",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 29,
+ "line": 1,
+ "offset": 28,
+ },
+ "source": "console.log('hello')",
+ "start": Object {
+ "column": 9,
+ "line": 1,
+ "offset": 8,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 29,
+ "line": 1,
+ "offset": 28,
+ },
+ "source": "<script>console.log('hello')",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "script",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 29,
+ "line": 1,
+ "offset": 28,
+ },
+ "source": "<script>console.log('hello')",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_TAG <template><div 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "<div ",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "<template><div ",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "<template><div ",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_TAG <template><div 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 15,
+ "line": 1,
+ "offset": 14,
+ },
+ "source": "<div",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 15,
+ "line": 1,
+ "offset": 14,
+ },
+ "source": "<template><div",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 15,
+ "line": 1,
+ "offset": 14,
+ },
+ "source": "<template><div",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_TAG <template><div id 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ "source": "<div id ",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 18,
+ "line": 1,
+ "offset": 17,
+ },
+ "source": "id",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": undefined,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ "source": "<template><div id ",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ "source": "<template><div id ",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_TAG <template><div id = 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ "source": "<div id =",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ "source": "id =",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": undefined,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ "source": "<template><div id =",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ "source": "<template><div id =",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_TAG <template><div id 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 18,
+ "line": 1,
+ "offset": 17,
+ },
+ "source": "<div id",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 18,
+ "line": 1,
+ "offset": 17,
+ },
+ "source": "id",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": undefined,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 18,
+ "line": 1,
+ "offset": 17,
+ },
+ "source": "<template><div id",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 18,
+ "line": 1,
+ "offset": 17,
+ },
+ "source": "<template><div id",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_TAG <template><div id="abc 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "<div id=\\"abc",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "id=\\"abc",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": Object {
+ "content": "abc",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "\\"abc",
+ "start": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "<template><div id=\\"abc",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "<template><div id=\\"abc",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_TAG <template><div id="abc" 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "<div id=\\"abc\\"",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "id=\\"abc\\"",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": Object {
+ "content": "abc",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "\\"abc\\"",
+ "start": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "<template><div id=\\"abc\\"",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "<template><div id=\\"abc\\"",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_TAG <template><div id="abc"/ 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<div id=\\"abc\\"/",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "id=\\"abc\\"",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": Object {
+ "content": "abc",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "\\"abc\\"",
+ "start": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<template><div id=\\"abc\\"/",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<template><div id=\\"abc\\"/",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_TAG <template><div id='abc 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "<div id='abc",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "id='abc",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": Object {
+ "content": "abc",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "'abc",
+ "start": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "<template><div id='abc",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "<template><div id='abc",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_TAG <template><div id='abc' 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "<div id='abc'",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "id='abc'",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": Object {
+ "content": "abc",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "'abc'",
+ "start": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "<template><div id='abc'",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "<template><div id='abc'",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_TAG <template><div id='abc'/ 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<div id='abc'/",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "id='abc'",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": Object {
+ "content": "abc",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "'abc'",
+ "start": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<template><div id='abc'/",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<template><div id='abc'/",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_TAG <template><div id=abc / 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "<div id=abc /",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ "source": "id=abc",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": Object {
+ "content": "abc",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ "source": "abc",
+ "start": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "<template><div id=abc /",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "<template><div id=abc /",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option EOF_IN_TAG <template><div id=abc 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ "source": "<div id=abc",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ "source": "id=abc",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": Object {
+ "content": "abc",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ "source": "abc",
+ "start": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ "source": "<template><div id=abc",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 22,
+ "line": 1,
+ "offset": 21,
+ },
+ "source": "<template><div id=abc",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option INCORRECTLY_CLOSED_COMMENT <template><!--comment--!></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "comment",
+ "loc": Object {
+ "end": Object {
+ "column": 26,
+ "line": 1,
+ "offset": 25,
+ },
+ "source": "<!--comment--!>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 37,
+ "line": 1,
+ "offset": 36,
+ },
+ "source": "<template><!--comment--!></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 37,
+ "line": 1,
+ "offset": 36,
+ },
+ "source": "<template><!--comment--!></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option INCORRECTLY_OPENED_COMMENT <!DOCTYPE html> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "content": "DOCTYPE html",
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "<!DOCTYPE html>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "<!DOCTYPE html>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option INCORRECTLY_OPENED_COMMENT <template><!></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "",
+ "loc": Object {
+ "end": Object {
+ "column": 14,
+ "line": 1,
+ "offset": 13,
+ },
+ "source": "<!>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<template><!></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<template><!></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option INCORRECTLY_OPENED_COMMENT <template><!-></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "-",
+ "loc": Object {
+ "end": Object {
+ "column": 15,
+ "line": 1,
+ "offset": 14,
+ },
+ "source": "<!->",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 26,
+ "line": 1,
+ "offset": 25,
+ },
+ "source": "<template><!-></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 26,
+ "line": 1,
+ "offset": 25,
+ },
+ "source": "<template><!-></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option INCORRECTLY_OPENED_COMMENT <template><!ELEMENT br EMPTY></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "ELEMENT br EMPTY",
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "<!ELEMENT br EMPTY>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 41,
+ "line": 1,
+ "offset": 40,
+ },
+ "source": "<template><!ELEMENT br EMPTY></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 41,
+ "line": 1,
+ "offset": 40,
+ },
+ "source": "<template><!ELEMENT br EMPTY></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template></�></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "�",
+ "loc": Object {
+ "end": Object {
+ "column": 15,
+ "line": 1,
+ "offset": 14,
+ },
+ "source": "</�>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 26,
+ "line": 1,
+ "offset": 25,
+ },
+ "source": "<template></�></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 26,
+ "line": 1,
+ "offset": 25,
+ },
+ "source": "<template></�></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template><�></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "<�>",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 14,
+ "line": 1,
+ "offset": 13,
+ },
+ "source": "<�>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<template><�></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<template><�></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template>{{a < b}}</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "a < b",
+ "isStatic": false,
+ "loc": Object {
+ "end": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ "source": "{{a < b}}",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 4,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 31,
+ "line": 1,
+ "offset": 30,
+ },
+ "source": "<template>{{a < b}}</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 31,
+ "line": 1,
+ "offset": 30,
+ },
+ "source": "<template>{{a < b}}</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template>a < b</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "a < b",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "a < b",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "<template>a < b</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "<template>a < b</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template>a </ b</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "a ",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 13,
+ "line": 1,
+ "offset": 12,
+ },
+ "source": "a ",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ Object {
+ "content": " b</template",
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "</ b</template>",
+ "start": Object {
+ "column": 13,
+ "line": 1,
+ "offset": 12,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<template>a </ b</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<template>a </ b</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option MISSING_ATTRIBUTE_VALUE <template><div id= /></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<div id= /></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 21,
+ "line": 1,
+ "offset": 20,
+ },
+ "source": "id= /",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": Object {
+ "content": "/",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 21,
+ "line": 1,
+ "offset": 20,
+ },
+ "source": "/",
+ "start": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 39,
+ "line": 1,
+ "offset": 38,
+ },
+ "source": "<template><div id= /></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 39,
+ "line": 1,
+ "offset": 38,
+ },
+ "source": "<template><div id= /></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option MISSING_ATTRIBUTE_VALUE <template><div id= ></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "<div id= ></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ "source": "id= ",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": undefined,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 38,
+ "line": 1,
+ "offset": 37,
+ },
+ "source": "<template><div id= ></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 38,
+ "line": 1,
+ "offset": 37,
+ },
+ "source": "<template><div id= ></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option MISSING_ATTRIBUTE_VALUE <template><div id=></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 26,
+ "line": 1,
+ "offset": 25,
+ },
+ "source": "<div id=></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ "source": "id=",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": undefined,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 37,
+ "line": 1,
+ "offset": 36,
+ },
+ "source": "<template><div id=></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 37,
+ "line": 1,
+ "offset": 36,
+ },
+ "source": "<template><div id=></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option MISSING_END_TAG_NAME <template></></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<template></></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<template></></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE <template>(</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "(",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 15,
+ "line": 1,
+ "offset": 14,
+ },
+ "source": "(",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 26,
+ "line": 1,
+ "offset": 25,
+ },
+ "source": "<template>(</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 26,
+ "line": 1,
+ "offset": 25,
+ },
+ "source": "<template>(</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE <template>@</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "@",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "@",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "<template>@</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "<template>@</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE <template>&</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "&",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 15,
+ "line": 1,
+ "offset": 14,
+ },
+ "source": "&",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 26,
+ "line": 1,
+ "offset": 25,
+ },
+ "source": "<template>&</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 26,
+ "line": 1,
+ "offset": 25,
+ },
+ "source": "<template>&</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option MISSING_WHITESPACE_BETWEEN_ATTRIBUTES <template><div id="foo"\\x0d;\\x0a;class="bar"></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 19,
+ "line": 2,
+ "offset": 43,
+ },
+ "source": "<div id=\\"foo\\"
+class=\\"bar\\"></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "id=\\"foo\\"",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": Object {
+ "content": "foo",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "\\"foo\\"",
+ "start": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ },
+ "type": 0,
+ },
+ },
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 12,
+ "line": 2,
+ "offset": 36,
+ },
+ "source": "class=\\"bar\\"",
+ "start": Object {
+ "column": 1,
+ "line": 2,
+ "offset": 25,
+ },
+ },
+ "name": "class",
+ "type": 3,
+ "value": Object {
+ "content": "bar",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 12,
+ "line": 2,
+ "offset": 36,
+ },
+ "source": "\\"bar\\"",
+ "start": Object {
+ "column": 7,
+ "line": 2,
+ "offset": 31,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 2,
+ "offset": 54,
+ },
+ "source": "<template><div id=\\"foo\\"
+class=\\"bar\\"></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 2,
+ "offset": 54,
+ },
+ "source": "<template><div id=\\"foo\\"
+class=\\"bar\\"></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option MISSING_WHITESPACE_BETWEEN_ATTRIBUTES <template><div id="foo"class="bar"></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 42,
+ "line": 1,
+ "offset": 41,
+ },
+ "source": "<div id=\\"foo\\"class=\\"bar\\"></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "id=\\"foo\\"",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "id",
+ "type": 3,
+ "value": Object {
+ "content": "foo",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "\\"foo\\"",
+ "start": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ },
+ "type": 0,
+ },
+ },
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 35,
+ "line": 1,
+ "offset": 34,
+ },
+ "source": "class=\\"bar\\"",
+ "start": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ },
+ "name": "class",
+ "type": 3,
+ "value": Object {
+ "content": "bar",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 35,
+ "line": 1,
+ "offset": 34,
+ },
+ "source": "\\"bar\\"",
+ "start": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 53,
+ "line": 1,
+ "offset": 52,
+ },
+ "source": "<template><div id=\\"foo\\"class=\\"bar\\"></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 53,
+ "line": 1,
+ "offset": 52,
+ },
+ "source": "<template><div id=\\"foo\\"class=\\"bar\\"></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option NESTED_COMMENT <template><!--a<!-- 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "a<!--",
+ "loc": Object {
+ "end": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ "source": "<!--a<!--",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ "source": "<template><!--a<!--",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ "source": "<template><!--a<!--",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option NESTED_COMMENT <template><!--a<!--></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "a<!",
+ "loc": Object {
+ "end": Object {
+ "column": 21,
+ "line": 1,
+ "offset": 20,
+ },
+ "source": "<!--a<!-->",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 32,
+ "line": 1,
+ "offset": 31,
+ },
+ "source": "<template><!--a<!--></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 32,
+ "line": 1,
+ "offset": 31,
+ },
+ "source": "<template><!--a<!--></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option NESTED_COMMENT <template><!--a<!--b<!--c--></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "a<!--b<!--c",
+ "loc": Object {
+ "end": Object {
+ "column": 29,
+ "line": 1,
+ "offset": 28,
+ },
+ "source": "<!--a<!--b<!--c-->",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 40,
+ "line": 1,
+ "offset": 39,
+ },
+ "source": "<template><!--a<!--b<!--c--></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 40,
+ "line": 1,
+ "offset": 39,
+ },
+ "source": "<template><!--a<!--b<!--c--></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option NESTED_COMMENT <template><!--a<!--b--></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "a<!--b",
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "<!--a<!--b-->",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 35,
+ "line": 1,
+ "offset": 34,
+ },
+ "source": "<template><!--a<!--b--></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 35,
+ "line": 1,
+ "offset": 34,
+ },
+ "source": "<template><!--a<!--b--></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option NONCHARACTER_CHARACTER_REFERENCE <template></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ "source": "",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 31,
+ "line": 1,
+ "offset": 30,
+ },
+ "source": "<template></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 31,
+ "line": 1,
+ "offset": 30,
+ },
+ "source": "<template></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option NONCHARACTER_CHARACTER_REFERENCE <template></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ "source": "",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "<template></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "<template></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option NULL_CHARACTER_REFERENCE <template>�</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "�",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 18,
+ "line": 1,
+ "offset": 17,
+ },
+ "source": "�",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 29,
+ "line": 1,
+ "offset": 28,
+ },
+ "source": "<template>�</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 29,
+ "line": 1,
+ "offset": 28,
+ },
+ "source": "<template>�</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option SURROGATE_CHARACTER_REFERENCE <template>�</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "�",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ "source": "�",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "<template>�</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "<template>�</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME <template><div a"bc=''></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "<div a\\"bc=''></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "a\\"bc=''",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "a\\"bc",
+ "type": 3,
+ "value": Object {
+ "content": "",
+ "isEmpty": true,
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "''",
+ "start": Object {
+ "column": 21,
+ "line": 1,
+ "offset": 20,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 41,
+ "line": 1,
+ "offset": 40,
+ },
+ "source": "<template><div a\\"bc=''></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 41,
+ "line": 1,
+ "offset": 40,
+ },
+ "source": "<template><div a\\"bc=''></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME <template><div a'bc=''></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "<div a'bc=''></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "a'bc=''",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "a'bc",
+ "type": 3,
+ "value": Object {
+ "content": "",
+ "isEmpty": true,
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "''",
+ "start": Object {
+ "column": 21,
+ "line": 1,
+ "offset": 20,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 41,
+ "line": 1,
+ "offset": 40,
+ },
+ "source": "<template><div a'bc=''></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 41,
+ "line": 1,
+ "offset": 40,
+ },
+ "source": "<template><div a'bc=''></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME <template><div a<bc=''></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "<div a<bc=''></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "a<bc=''",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "a<bc",
+ "type": 3,
+ "value": Object {
+ "content": "",
+ "isEmpty": true,
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "''",
+ "start": Object {
+ "column": 21,
+ "line": 1,
+ "offset": 20,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 41,
+ "line": 1,
+ "offset": 40,
+ },
+ "source": "<template><div a<bc=''></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 41,
+ "line": 1,
+ "offset": 40,
+ },
+ "source": "<template><div a<bc=''></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar"></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 31,
+ "line": 1,
+ "offset": 30,
+ },
+ "source": "<div foo=bar\\"></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "foo=bar\\"",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "foo",
+ "type": 3,
+ "value": Object {
+ "content": "bar\\"",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "bar\\"",
+ "start": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 42,
+ "line": 1,
+ "offset": 41,
+ },
+ "source": "<template><div foo=bar\\"></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 42,
+ "line": 1,
+ "offset": 41,
+ },
+ "source": "<template><div foo=bar\\"></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar'></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 31,
+ "line": 1,
+ "offset": 30,
+ },
+ "source": "<div foo=bar'></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "foo=bar'",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "foo",
+ "type": 3,
+ "value": Object {
+ "content": "bar'",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "bar'",
+ "start": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 42,
+ "line": 1,
+ "offset": 41,
+ },
+ "source": "<template><div foo=bar'></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 42,
+ "line": 1,
+ "offset": 41,
+ },
+ "source": "<template><div foo=bar'></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar<div></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": "<div foo=bar<div></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "foo=bar<div",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "foo",
+ "type": 3,
+ "value": Object {
+ "content": "bar<div",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "bar<div",
+ "start": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 45,
+ "line": 1,
+ "offset": 44,
+ },
+ "source": "<template><div foo=bar<div></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 45,
+ "line": 1,
+ "offset": 44,
+ },
+ "source": "<template><div foo=bar<div></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar=baz></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": "<div foo=bar=baz></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "foo=bar=baz",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "foo",
+ "type": 3,
+ "value": Object {
+ "content": "bar=baz",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "bar=baz",
+ "start": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 45,
+ "line": 1,
+ "offset": 44,
+ },
+ "source": "<template><div foo=bar=baz></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 45,
+ "line": 1,
+ "offset": 44,
+ },
+ "source": "<template><div foo=bar=baz></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar\`></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 31,
+ "line": 1,
+ "offset": 30,
+ },
+ "source": "<div foo=bar\`></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "foo=bar\`",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "foo",
+ "type": 3,
+ "value": Object {
+ "content": "bar\`",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "bar\`",
+ "start": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 42,
+ "line": 1,
+ "offset": 41,
+ },
+ "source": "<template><div foo=bar\`></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 42,
+ "line": 1,
+ "offset": 41,
+ },
+ "source": "<template><div foo=bar\`></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME <template><div =></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "<div =></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 17,
+ "line": 1,
+ "offset": 16,
+ },
+ "source": "=",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "=",
+ "type": 3,
+ "value": undefined,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 35,
+ "line": 1,
+ "offset": 34,
+ },
+ "source": "<template><div =></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 35,
+ "line": 1,
+ "offset": 34,
+ },
+ "source": "<template><div =></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME <template><div =foo=bar></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 31,
+ "line": 1,
+ "offset": 30,
+ },
+ "source": "<div =foo=bar></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "=foo=bar",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "=foo",
+ "type": 3,
+ "value": Object {
+ "content": "bar",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 24,
+ "line": 1,
+ "offset": 23,
+ },
+ "source": "bar",
+ "start": Object {
+ "column": 21,
+ "line": 1,
+ "offset": 20,
+ },
+ },
+ "type": 0,
+ },
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 42,
+ "line": 1,
+ "offset": 41,
+ },
+ "source": "<template><div =foo=bar></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 42,
+ "line": 1,
+ "offset": 41,
+ },
+ "source": "<template><div =foo=bar></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME <template><?xml?></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "?xml?",
+ "loc": Object {
+ "end": Object {
+ "column": 18,
+ "line": 1,
+ "offset": 17,
+ },
+ "source": "<?xml?>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 29,
+ "line": 1,
+ "offset": 28,
+ },
+ "source": "<template><?xml?></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 29,
+ "line": 1,
+ "offset": 28,
+ },
+ "source": "<template><?xml?></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option UNEXPECTED_SOLIDUS_IN_TAG <template><div a/b></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 26,
+ "line": 1,
+ "offset": 25,
+ },
+ "source": "<div a/b></div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 17,
+ "line": 1,
+ "offset": 16,
+ },
+ "source": "a",
+ "start": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ },
+ "name": "a",
+ "type": 3,
+ "value": undefined,
+ },
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ "source": "b",
+ "start": Object {
+ "column": 18,
+ "line": 1,
+ "offset": 17,
+ },
+ },
+ "name": "b",
+ "type": 3,
+ "value": undefined,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 37,
+ "line": 1,
+ "offset": 36,
+ },
+ "source": "<template><div a/b></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 37,
+ "line": 1,
+ "offset": 36,
+ },
+ "source": "<template><div a/b></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option UNKNOWN_NAMED_CHARACTER_REFERENCE <template>&unknown;</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "&unknown;",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 20,
+ "line": 1,
+ "offset": 19,
+ },
+ "source": "&unknown;",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 31,
+ "line": 1,
+ "offset": 30,
+ },
+ "source": "<template>&unknown;</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 31,
+ "line": 1,
+ "offset": 30,
+ },
+ "source": "<template>&unknown;</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option X_INVALID_END_TAG <svg><![CDATA[</div>]]></svg> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "</div>",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 21,
+ "line": 1,
+ "offset": 20,
+ },
+ "source": "</div>",
+ "start": Object {
+ "column": 15,
+ "line": 1,
+ "offset": 14,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "<svg><![CDATA[</div>]]></svg>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 1,
+ "props": Array [],
+ "tag": "svg",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 30,
+ "line": 1,
+ "offset": 29,
+ },
+ "source": "<svg><![CDATA[</div>]]></svg>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option X_INVALID_END_TAG <svg><!--</div>--></svg> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "</div>",
+ "loc": Object {
+ "end": Object {
+ "column": 19,
+ "line": 1,
+ "offset": 18,
+ },
+ "source": "<!--</div>-->",
+ "start": Object {
+ "column": 6,
+ "line": 1,
+ "offset": 5,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<svg><!--</div>--></svg>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 1,
+ "props": Array [],
+ "tag": "svg",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 25,
+ "line": 1,
+ "offset": 24,
+ },
+ "source": "<svg><!--</div>--></svg>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option X_INVALID_END_TAG <template></div></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": "<template></div></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": "<template></div></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option X_INVALID_END_TAG <template></div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<template></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<template></div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option X_INVALID_END_TAG <template>{{'</div>'}}</template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "'</div>'",
+ "isStatic": false,
+ "loc": Object {
+ "end": Object {
+ "column": 23,
+ "line": 1,
+ "offset": 22,
+ },
+ "source": "{{'</div>'}}",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 4,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": "<template>{{'</div>'}}</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": "<template>{{'</div>'}}</template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option X_INVALID_END_TAG <textarea></div></textarea> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "content": "</div>",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 17,
+ "line": 1,
+ "offset": 16,
+ },
+ "source": "</div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<textarea></div></textarea>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "textarea",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 28,
+ "line": 1,
+ "offset": 27,
+ },
+ "source": "<textarea></div></textarea>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option X_MISSING_END_TAG <template><div> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "<div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "<template><div>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "<template><div>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option X_MISSING_END_TAG <template><div></template> 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 1,
+ "offset": 15,
+ },
+ "source": "<div>",
+ "start": Object {
+ "column": 11,
+ "line": 1,
+ "offset": 10,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "<template><div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [],
+ "tag": "template",
+ "tagType": 3,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 27,
+ "line": 1,
+ "offset": 26,
+ },
+ "source": "<template><div></template>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option X_MISSING_INTERPOLATION_END {{ 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "content": "{{",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 3,
+ "line": 1,
+ "offset": 2,
+ },
+ "source": "{{",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 3,
+ "line": 1,
+ "offset": 2,
+ },
+ "source": "{{",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option X_MISSING_INTERPOLATION_END {{ foo 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "content": "{{ foo",
+ "isEmpty": false,
+ "loc": Object {
+ "end": Object {
+ "column": 7,
+ "line": 1,
+ "offset": 6,
+ },
+ "source": "{{ foo",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 0,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 7,
+ "line": 1,
+ "offset": 6,
+ },
+ "source": "{{ foo",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse onError option X_MISSING_INTERPOLATION_END {{}} 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "content": "",
+ "isStatic": true,
+ "loc": Object {
+ "end": Object {
+ "column": 5,
+ "line": 1,
+ "offset": 4,
+ },
+ "source": "{{}}",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 4,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 5,
+ "line": 1,
+ "offset": 4,
+ },
+ "source": "{{}}",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse self closing multiple tag 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": true,
+ "loc": Object {
+ "end": Object {
+ "column": 37,
+ "line": 1,
+ "offset": 36,
+ },
+ "source": "<div :class=\\"{ some: condition }\\" />",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "arg": Object {
+ "content": "class",
+ "isStatic": true,
+ "loc": Object {
+ "end": Object {
+ "column": 12,
+ "line": 1,
+ "offset": 11,
+ },
+ "source": "class",
+ "start": Object {
+ "column": 7,
+ "line": 1,
+ "offset": 6,
+ },
+ },
+ "type": 4,
+ },
+ "exp": Object {
+ "content": "{ some: condition }",
+ "isStatic": false,
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": "\\"{ some: condition }\\"",
+ "start": Object {
+ "column": 13,
+ "line": 1,
+ "offset": 12,
+ },
+ },
+ "type": 4,
+ },
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": ":class=\\"{ some: condition }\\"",
+ "start": Object {
+ "column": 6,
+ "line": 1,
+ "offset": 5,
+ },
+ },
+ "modifiers": Array [],
+ "name": "bind",
+ "type": 5,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ Object {
+ "children": Array [],
+ "isSelfClosing": true,
+ "loc": Object {
+ "end": Object {
+ "column": 37,
+ "line": 2,
+ "offset": 73,
+ },
+ "source": "<p v-bind:style=\\"{ color: 'red' }\\"/>",
+ "start": Object {
+ "column": 1,
+ "line": 2,
+ "offset": 37,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "arg": Object {
+ "content": "style",
+ "isStatic": true,
+ "loc": Object {
+ "end": Object {
+ "column": 16,
+ "line": 2,
+ "offset": 52,
+ },
+ "source": "style",
+ "start": Object {
+ "column": 11,
+ "line": 2,
+ "offset": 47,
+ },
+ },
+ "type": 4,
+ },
+ "exp": Object {
+ "content": "{ color: 'red' }",
+ "isStatic": false,
+ "loc": Object {
+ "end": Object {
+ "column": 35,
+ "line": 2,
+ "offset": 71,
+ },
+ "source": "\\"{ color: 'red' }\\"",
+ "start": Object {
+ "column": 17,
+ "line": 2,
+ "offset": 53,
+ },
+ },
+ "type": 4,
+ },
+ "loc": Object {
+ "end": Object {
+ "column": 35,
+ "line": 2,
+ "offset": 71,
+ },
+ "source": "v-bind:style=\\"{ color: 'red' }\\"",
+ "start": Object {
+ "column": 4,
+ "line": 2,
+ "offset": 40,
+ },
+ },
+ "modifiers": Array [],
+ "name": "bind",
+ "type": 5,
+ },
+ ],
+ "tag": "p",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 37,
+ "line": 2,
+ "offset": 73,
+ },
+ "source": "<div :class=\\"{ some: condition }\\" />
+<p v-bind:style=\\"{ color: 'red' }\\"/>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
+
+exports[`parser/parse valid html 1`] = `
+Object {
+ "children": Array [
+ Object {
+ "children": Array [
+ Object {
+ "children": Array [],
+ "isSelfClosing": true,
+ "loc": Object {
+ "end": Object {
+ "column": 38,
+ "line": 2,
+ "offset": 73,
+ },
+ "source": "<p v-bind:style=\\"{ color: 'red' }\\"/>",
+ "start": Object {
+ "column": 2,
+ "line": 2,
+ "offset": 37,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "arg": Object {
+ "content": "style",
+ "isStatic": true,
+ "loc": Object {
+ "end": Object {
+ "column": 17,
+ "line": 2,
+ "offset": 52,
+ },
+ "source": "style",
+ "start": Object {
+ "column": 12,
+ "line": 2,
+ "offset": 47,
+ },
+ },
+ "type": 4,
+ },
+ "exp": Object {
+ "content": "{ color: 'red' }",
+ "isStatic": false,
+ "loc": Object {
+ "end": Object {
+ "column": 36,
+ "line": 2,
+ "offset": 71,
+ },
+ "source": "\\"{ color: 'red' }\\"",
+ "start": Object {
+ "column": 18,
+ "line": 2,
+ "offset": 53,
+ },
+ },
+ "type": 4,
+ },
+ "loc": Object {
+ "end": Object {
+ "column": 36,
+ "line": 2,
+ "offset": 71,
+ },
+ "source": "v-bind:style=\\"{ color: 'red' }\\"",
+ "start": Object {
+ "column": 5,
+ "line": 2,
+ "offset": 40,
+ },
+ },
+ "modifiers": Array [],
+ "name": "bind",
+ "type": 5,
+ },
+ ],
+ "tag": "p",
+ "tagType": 0,
+ "type": 2,
+ },
+ Object {
+ "content": " a comment with <html> inside it ",
+ "loc": Object {
+ "end": Object {
+ "column": 42,
+ "line": 3,
+ "offset": 116,
+ },
+ "source": "<!-- a comment with <html> inside it -->",
+ "start": Object {
+ "column": 2,
+ "line": 3,
+ "offset": 76,
+ },
+ },
+ "type": 1,
+ },
+ ],
+ "isSelfClosing": false,
+ "loc": Object {
+ "end": Object {
+ "column": 7,
+ "line": 4,
+ "offset": 123,
+ },
+ "source": "<div :class=\\"{ some: condition }\\">
+ <p v-bind:style=\\"{ color: 'red' }\\"/>
+ <!-- a comment with <html> inside it -->
+</div>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": Array [
+ Object {
+ "arg": Object {
+ "content": "class",
+ "isStatic": true,
+ "loc": Object {
+ "end": Object {
+ "column": 12,
+ "line": 1,
+ "offset": 11,
+ },
+ "source": "class",
+ "start": Object {
+ "column": 7,
+ "line": 1,
+ "offset": 6,
+ },
+ },
+ "type": 4,
+ },
+ "exp": Object {
+ "content": "{ some: condition }",
+ "isStatic": false,
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": "\\"{ some: condition }\\"",
+ "start": Object {
+ "column": 13,
+ "line": 1,
+ "offset": 12,
+ },
+ },
+ "type": 4,
+ },
+ "loc": Object {
+ "end": Object {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": ":class=\\"{ some: condition }\\"",
+ "start": Object {
+ "column": 6,
+ "line": 1,
+ "offset": 5,
+ },
+ },
+ "modifiers": Array [],
+ "name": "bind",
+ "type": 5,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 2,
+ },
+ ],
+ "loc": Object {
+ "end": Object {
+ "column": 7,
+ "line": 4,
+ "offset": 123,
+ },
+ "source": "<div :class=\\"{ some: condition }\\">
+ <p v-bind:style=\\"{ color: 'red' }\\"/>
+ <!-- a comment with <html> inside it -->
+</div>",
+ "start": Object {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "type": 6,
+}
+`;
--- /dev/null
+import { parse, ParserOptions } from '../src/parser'
+import {
+ AttributeNode,
+ CommentNode,
+ DirectiveNode,
+ ElementNode,
+ ElementTypes,
+ ExpressionNode,
+ Namespaces,
+ NodeTypes,
+ Position,
+ TextNode
+} from '../src/ast'
+import { ParserErrorTypes } from '../src/errorTypes'
+import { parserOptionsMinimal as parserOptions } from '../src/parserOptionsMinimal'
+
+describe('parser/parse', () => {
+ describe('Text', () => {
+ test('simple text', () => {
+ const ast = parse('some text', parserOptions)
+ const text = ast.children[0] as TextNode
+
+ expect(text).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: 'some text',
+ isEmpty: false,
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 9, line: 1, column: 10 },
+ source: 'some text'
+ }
+ })
+ })
+
+ test('simple text with invalid end tag', () => {
+ const ast = parse('some text</div>', {
+ ...parserOptions,
+ onError: () => {}
+ })
+ const text = ast.children[0] as TextNode
+
+ expect(text).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: 'some text',
+ isEmpty: false,
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 9, line: 1, column: 10 },
+ source: 'some text'
+ }
+ })
+ })
+
+ test('text with interpolation', () => {
+ const ast = parse('some {{ foo + bar }} text', parserOptions)
+ const text1 = ast.children[0] as TextNode
+ const text2 = ast.children[2] as TextNode
+
+ expect(text1).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: 'some ',
+ isEmpty: false,
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 5, line: 1, column: 6 },
+ source: 'some '
+ }
+ })
+ expect(text2).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: ' text',
+ isEmpty: false,
+ loc: {
+ start: { offset: 20, line: 1, column: 21 },
+ end: { offset: 25, line: 1, column: 26 },
+ source: ' text'
+ }
+ })
+ })
+
+ test('text with interpolation which has `<`', () => {
+ const ast = parse('some {{ a<b && c>d }} text', parserOptions)
+ const text1 = ast.children[0] as TextNode
+ const text2 = ast.children[2] as TextNode
+
+ expect(text1).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: 'some ',
+ isEmpty: false,
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 5, line: 1, column: 6 },
+ source: 'some '
+ }
+ })
+ expect(text2).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: ' text',
+ isEmpty: false,
+ loc: {
+ start: { offset: 21, line: 1, column: 22 },
+ end: { offset: 26, line: 1, column: 27 },
+ source: ' text'
+ }
+ })
+ })
+
+ test('text with mix of tags and interpolations', () => {
+ const ast = parse(
+ 'some <span>{{ foo < bar + foo }} text</span>',
+ parserOptions
+ )
+ const text1 = ast.children[0] as TextNode
+ const text2 = (ast.children[1] as ElementNode).children![1] as TextNode
+
+ expect(text1).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: 'some ',
+ isEmpty: false,
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 5, line: 1, column: 6 },
+ source: 'some '
+ }
+ })
+ expect(text2).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: ' text',
+ isEmpty: false,
+ loc: {
+ start: { offset: 32, line: 1, column: 33 },
+ end: { offset: 37, line: 1, column: 38 },
+ source: ' text'
+ }
+ })
+ })
+
+ test('CDATA', () => {
+ const ast = parse('<svg><![CDATA[some text]]></svg>', parserOptions)
+ const text = (ast.children[0] as ElementNode).children![0] as TextNode
+
+ expect(text).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: 'some text',
+ isEmpty: false,
+ loc: {
+ start: { offset: 14, line: 1, column: 15 },
+ end: { offset: 23, line: 1, column: 24 },
+ source: 'some text'
+ }
+ })
+ })
+
+ test('lonly "<" don\'t separate nodes', () => {
+ const ast = parse('a < b', {
+ ...parserOptions,
+ onError: errorCode => {
+ if (
+ errorCode !== ParserErrorTypes.INVALID_FIRST_CHARACTER_OF_TAG_NAME
+ ) {
+ throw new Error(`${errorCode}`)
+ }
+ }
+ })
+ const text = ast.children[0] as TextNode
+
+ expect(text).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: 'a < b',
+ isEmpty: false,
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 5, line: 1, column: 6 },
+ source: 'a < b'
+ }
+ })
+ })
+
+ test('lonly "{{" don\'t separate nodes', () => {
+ const ast = parse('a {{ b', {
+ ...parserOptions,
+ onError: errorCode => {
+ if (errorCode !== ParserErrorTypes.X_MISSING_INTERPOLATION_END) {
+ throw new Error(`${errorCode}`)
+ }
+ }
+ })
+ const text = ast.children[0] as TextNode
+
+ expect(text).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: 'a {{ b',
+ isEmpty: false,
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 6, line: 1, column: 7 },
+ source: 'a {{ b'
+ }
+ })
+ })
+
+ test('textarea handles comments/elements as just a text', () => {
+ const ast = parse(
+ '<textarea>some<div>text</div>and<!--comment--></textarea>',
+ parserOptions
+ )
+ const element = ast.children[0] as ElementNode
+ const text = element.children[0] as TextNode
+
+ expect(text).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: 'some<div>text</div>and<!--comment-->',
+ isEmpty: false,
+ loc: {
+ start: { offset: 10, line: 1, column: 11 },
+ end: { offset: 46, line: 1, column: 47 },
+ source: 'some<div>text</div>and<!--comment-->'
+ }
+ })
+ })
+
+ test('textarea handles character references', () => {
+ const ast = parse('<textarea>&</textarea>', parserOptions)
+ const element = ast.children[0] as ElementNode
+ const text = element.children[0] as TextNode
+
+ expect(text).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: '&',
+ isEmpty: false,
+ loc: {
+ start: { offset: 10, line: 1, column: 11 },
+ end: { offset: 15, line: 1, column: 16 },
+ source: '&'
+ }
+ })
+ })
+
+ test('style handles comments/elements as just a text', () => {
+ const ast = parse(
+ '<style>some<div>text</div>and<!--comment--></style>',
+ parserOptions
+ )
+ const element = ast.children[0] as ElementNode
+ const text = element.children[0] as TextNode
+
+ expect(text).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: 'some<div>text</div>and<!--comment-->',
+ isEmpty: false,
+ loc: {
+ start: { offset: 7, line: 1, column: 8 },
+ end: { offset: 43, line: 1, column: 44 },
+ source: 'some<div>text</div>and<!--comment-->'
+ }
+ })
+ })
+
+ test("style doesn't handle character references", () => {
+ const ast = parse('<style>&</style>', parserOptions)
+ const element = ast.children[0] as ElementNode
+ const text = element.children[0] as TextNode
+
+ expect(text).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: '&',
+ isEmpty: false,
+ loc: {
+ start: { offset: 7, line: 1, column: 8 },
+ end: { offset: 12, line: 1, column: 13 },
+ source: '&'
+ }
+ })
+ })
+
+ test('HTML entities compatibility in text (https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state).', () => {
+ const spy = jest.fn()
+ const ast = parse('&ersand;', {
+ ...parserOptions,
+ namedCharacterReferences: { amp: '&' },
+ onError: spy
+ })
+ const text = ast.children[0] as TextNode
+
+ expect(text).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: '&ersand;',
+ isEmpty: false,
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 11, line: 1, column: 12 },
+ source: '&ersand;'
+ }
+ })
+ expect(spy.mock.calls).toEqual([
+ [
+ ParserErrorTypes.MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE,
+ { offset: 4, line: 1, column: 5 }
+ ]
+ ])
+ })
+
+ test('HTML entities compatibility in attribute (https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state).', () => {
+ const spy = jest.fn()
+ const ast = parse(
+ '<div a="&ersand;" b="&ersand;" c="&!"></div>',
+ {
+ ...parserOptions,
+ namedCharacterReferences: { amp: '&', 'amp;': '&' },
+ onError: spy
+ }
+ )
+ const element = ast.children[0] as ElementNode
+ const text1 = (element.props[0] as AttributeNode).value
+ const text2 = (element.props[1] as AttributeNode).value
+ const text3 = (element.props[2] as AttributeNode).value
+
+ expect(text1).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: '&ersand;',
+ isEmpty: false,
+ loc: {
+ start: { offset: 7, line: 1, column: 8 },
+ end: { offset: 20, line: 1, column: 21 },
+ source: '"&ersand;"'
+ }
+ })
+ expect(text2).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: '&ersand;',
+ isEmpty: false,
+ loc: {
+ start: { offset: 23, line: 1, column: 24 },
+ end: { offset: 37, line: 1, column: 38 },
+ source: '"&ersand;"'
+ }
+ })
+ expect(text3).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: '&!',
+ isEmpty: false,
+ loc: {
+ start: { offset: 40, line: 1, column: 41 },
+ end: { offset: 47, line: 1, column: 48 },
+ source: '"&!"'
+ }
+ })
+ expect(spy.mock.calls).toEqual([
+ [
+ ParserErrorTypes.MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE,
+ { offset: 45, line: 1, column: 46 }
+ ]
+ ])
+ })
+
+ test('Some control character reference should be replaced.', () => {
+ const spy = jest.fn()
+ const ast = parse('†', { ...parserOptions, onError: spy })
+ const text = ast.children[0] as TextNode
+
+ expect(text).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: '†',
+ isEmpty: false,
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 6, line: 1, column: 7 },
+ source: '†'
+ }
+ })
+ expect(spy.mock.calls).toEqual([
+ [
+ ParserErrorTypes.CONTROL_CHARACTER_REFERENCE,
+ { offset: 0, line: 1, column: 1 }
+ ]
+ ])
+ })
+ })
+
+ describe('Interpolation', () => {
+ test('simple interpolation', () => {
+ const ast = parse('{{message}}', parserOptions)
+ const interpolation = ast.children[0] as ExpressionNode
+
+ expect(interpolation).toStrictEqual({
+ type: NodeTypes.EXPRESSION,
+ content: 'message',
+ isStatic: false,
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 11, line: 1, column: 12 },
+ source: '{{message}}'
+ }
+ })
+ })
+
+ test('it can have tag-like notation', () => {
+ const ast = parse('{{ a<b }}', parserOptions)
+ const interpolation = ast.children[0] as ExpressionNode
+
+ expect(interpolation).toStrictEqual({
+ type: NodeTypes.EXPRESSION,
+ content: 'a<b',
+ isStatic: false,
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 9, line: 1, column: 10 },
+ source: '{{ a<b }}'
+ }
+ })
+ })
+
+ test('it can have tag-like notation (2)', () => {
+ const ast = parse('{{ a<b }}{{ c>d }}', parserOptions)
+ const interpolation1 = ast.children[0] as ExpressionNode
+ const interpolation2 = ast.children[1] as ExpressionNode
+
+ expect(interpolation1).toStrictEqual({
+ type: NodeTypes.EXPRESSION,
+ content: 'a<b',
+ isStatic: false,
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 9, line: 1, column: 10 },
+ source: '{{ a<b }}'
+ }
+ })
+ expect(interpolation2).toStrictEqual({
+ type: NodeTypes.EXPRESSION,
+ content: 'c>d',
+ isStatic: false,
+ loc: {
+ start: { offset: 9, line: 1, column: 10 },
+ end: { offset: 18, line: 1, column: 19 },
+ source: '{{ c>d }}'
+ }
+ })
+ })
+
+ test('it can have tag-like notation (3)', () => {
+ const ast = parse('<div>{{ "</div>" }}</div>', parserOptions)
+ const element = ast.children[0] as ElementNode
+ const interpolation = element.children[0] as ExpressionNode
+
+ expect(interpolation).toStrictEqual({
+ type: NodeTypes.EXPRESSION,
+ content: '"</div>"',
+ isStatic: false,
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 19, line: 1, column: 20 },
+ source: '{{ "</div>" }}'
+ }
+ })
+ })
+
+ test('HTML entities in interpolation should be translated for backward compatibility.', () => {
+ const ast = parse('<div>{{ a < b }}</div>', parserOptions)
+ const element = ast.children[0] as ElementNode
+ const interpolation = element.children[0] as ExpressionNode
+
+ expect(interpolation).toStrictEqual({
+ type: NodeTypes.EXPRESSION,
+ content: 'a < b',
+ isStatic: false,
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 19, line: 1, column: 20 },
+ source: '{{ a < b }}'
+ }
+ })
+ })
+ })
+
+ describe('Comment', () => {
+ test('empty comment', () => {
+ const ast = parse('<!---->', parserOptions)
+ const comment = ast.children[0] as CommentNode
+
+ expect(comment).toStrictEqual({
+ type: NodeTypes.COMMENT,
+ content: '',
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 7, line: 1, column: 8 },
+ source: '<!---->'
+ }
+ })
+ })
+
+ test('simple comment', () => {
+ const ast = parse('<!--abc-->', parserOptions)
+ const comment = ast.children[0] as CommentNode
+
+ expect(comment).toStrictEqual({
+ type: NodeTypes.COMMENT,
+ content: 'abc',
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 10, line: 1, column: 11 },
+ source: '<!--abc-->'
+ }
+ })
+ })
+
+ test('two comments', () => {
+ const ast = parse('<!--abc--><!--def-->', parserOptions)
+ const comment1 = ast.children[0] as CommentNode
+ const comment2 = ast.children[1] as CommentNode
+
+ expect(comment1).toStrictEqual({
+ type: NodeTypes.COMMENT,
+ content: 'abc',
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 10, line: 1, column: 11 },
+ source: '<!--abc-->'
+ }
+ })
+ expect(comment2).toStrictEqual({
+ type: NodeTypes.COMMENT,
+ content: 'def',
+ loc: {
+ start: { offset: 10, line: 1, column: 11 },
+ end: { offset: 20, line: 1, column: 21 },
+ source: '<!--def-->'
+ }
+ })
+ })
+ })
+
+ describe('Element', () => {
+ test('simple div', () => {
+ const ast = parse('<div>hello</div>', parserOptions)
+ const element = ast.children[0] as ElementNode
+
+ expect(element).toStrictEqual({
+ type: NodeTypes.ELEMENT,
+ ns: Namespaces.HTML,
+ tag: 'div',
+ tagType: ElementTypes.ELEMENT,
+ props: [],
+ isSelfClosing: false,
+ children: [
+ {
+ type: NodeTypes.TEXT,
+ content: 'hello',
+ isEmpty: false,
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 10, line: 1, column: 11 },
+ source: 'hello'
+ }
+ }
+ ],
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 16, line: 1, column: 17 },
+ source: '<div>hello</div>'
+ }
+ })
+ })
+
+ test('empty', () => {
+ const ast = parse('<div></div>', parserOptions)
+ const element = ast.children[0] as ElementNode
+
+ expect(element).toStrictEqual({
+ type: NodeTypes.ELEMENT,
+ ns: Namespaces.HTML,
+ tag: 'div',
+ tagType: ElementTypes.ELEMENT,
+ props: [],
+ isSelfClosing: false,
+ children: [],
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 11, line: 1, column: 12 },
+ source: '<div></div>'
+ }
+ })
+ })
+
+ test('self closing', () => {
+ const ast = parse('<div/>after', parserOptions)
+ const element = ast.children[0] as ElementNode
+
+ expect(element).toStrictEqual({
+ type: NodeTypes.ELEMENT,
+ ns: Namespaces.HTML,
+ tag: 'div',
+ tagType: ElementTypes.ELEMENT,
+ props: [],
+ isSelfClosing: true,
+ children: [],
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 6, line: 1, column: 7 },
+ source: '<div/>'
+ }
+ })
+ })
+
+ test('void element', () => {
+ const ast = parse('<img>after', parserOptions)
+ const element = ast.children[0] as ElementNode
+
+ expect(element).toStrictEqual({
+ type: NodeTypes.ELEMENT,
+ ns: Namespaces.HTML,
+ tag: 'img',
+ tagType: ElementTypes.ELEMENT,
+ props: [],
+ isSelfClosing: false,
+ children: [],
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 5, line: 1, column: 6 },
+ source: '<img>'
+ }
+ })
+ })
+
+ test('attribute with no value', () => {
+ const ast = parse('<div id></div>', parserOptions)
+ const element = ast.children[0] as ElementNode
+
+ expect(element).toStrictEqual({
+ type: NodeTypes.ELEMENT,
+ ns: Namespaces.HTML,
+ tag: 'div',
+ tagType: ElementTypes.ELEMENT,
+ props: [
+ {
+ type: NodeTypes.ATTRIBUTE,
+ name: 'id',
+ value: undefined,
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 7, line: 1, column: 8 },
+ source: 'id'
+ }
+ }
+ ],
+ isSelfClosing: false,
+ children: [],
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 14, line: 1, column: 15 },
+ source: '<div id></div>'
+ }
+ })
+ })
+
+ test('attribute with empty value, double quote', () => {
+ const ast = parse('<div id=""></div>', parserOptions)
+ const element = ast.children[0] as ElementNode
+
+ expect(element).toStrictEqual({
+ type: NodeTypes.ELEMENT,
+ ns: Namespaces.HTML,
+ tag: 'div',
+ tagType: ElementTypes.ELEMENT,
+ props: [
+ {
+ type: NodeTypes.ATTRIBUTE,
+ name: 'id',
+ value: {
+ type: NodeTypes.TEXT,
+ content: '',
+ isEmpty: true,
+ loc: {
+ start: { offset: 8, line: 1, column: 9 },
+ end: { offset: 10, line: 1, column: 11 },
+ source: '""'
+ }
+ },
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 10, line: 1, column: 11 },
+ source: 'id=""'
+ }
+ }
+ ],
+ isSelfClosing: false,
+ children: [],
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 17, line: 1, column: 18 },
+ source: '<div id=""></div>'
+ }
+ })
+ })
+
+ test('attribute with empty value, single quote', () => {
+ const ast = parse("<div id=''></div>", parserOptions)
+ const element = ast.children[0] as ElementNode
+
+ expect(element).toStrictEqual({
+ type: NodeTypes.ELEMENT,
+ ns: Namespaces.HTML,
+ tag: 'div',
+ tagType: ElementTypes.ELEMENT,
+ props: [
+ {
+ type: NodeTypes.ATTRIBUTE,
+ name: 'id',
+ value: {
+ type: NodeTypes.TEXT,
+ content: '',
+ isEmpty: true,
+ loc: {
+ start: { offset: 8, line: 1, column: 9 },
+ end: { offset: 10, line: 1, column: 11 },
+ source: "''"
+ }
+ },
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 10, line: 1, column: 11 },
+ source: "id=''"
+ }
+ }
+ ],
+ isSelfClosing: false,
+ children: [],
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 17, line: 1, column: 18 },
+ source: "<div id=''></div>"
+ }
+ })
+ })
+
+ test('attribute with value, double quote', () => {
+ const ast = parse('<div id=">\'"></div>', parserOptions)
+ const element = ast.children[0] as ElementNode
+
+ expect(element).toStrictEqual({
+ type: NodeTypes.ELEMENT,
+ ns: Namespaces.HTML,
+ tag: 'div',
+ tagType: ElementTypes.ELEMENT,
+ props: [
+ {
+ type: NodeTypes.ATTRIBUTE,
+ name: 'id',
+ value: {
+ type: NodeTypes.TEXT,
+ content: ">'",
+ isEmpty: false,
+ loc: {
+ start: { offset: 8, line: 1, column: 9 },
+ end: { offset: 12, line: 1, column: 13 },
+ source: '">\'"'
+ }
+ },
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 12, line: 1, column: 13 },
+ source: 'id=">\'"'
+ }
+ }
+ ],
+ isSelfClosing: false,
+ children: [],
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 19, line: 1, column: 20 },
+ source: '<div id=">\'"></div>'
+ }
+ })
+ })
+
+ test('attribute with value, single quote', () => {
+ const ast = parse("<div id='>\"'></div>", parserOptions)
+ const element = ast.children[0] as ElementNode
+
+ expect(element).toStrictEqual({
+ type: NodeTypes.ELEMENT,
+ ns: Namespaces.HTML,
+ tag: 'div',
+ tagType: ElementTypes.ELEMENT,
+ props: [
+ {
+ type: NodeTypes.ATTRIBUTE,
+ name: 'id',
+ value: {
+ type: NodeTypes.TEXT,
+ content: '>"',
+ isEmpty: false,
+ loc: {
+ start: { offset: 8, line: 1, column: 9 },
+ end: { offset: 12, line: 1, column: 13 },
+ source: "'>\"'"
+ }
+ },
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 12, line: 1, column: 13 },
+ source: "id='>\"'"
+ }
+ }
+ ],
+ isSelfClosing: false,
+ children: [],
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 19, line: 1, column: 20 },
+ source: "<div id='>\"'></div>"
+ }
+ })
+ })
+
+ test('attribute with value, unquoted', () => {
+ const ast = parse('<div id=a/></div>', parserOptions)
+ const element = ast.children[0] as ElementNode
+
+ expect(element).toStrictEqual({
+ type: NodeTypes.ELEMENT,
+ ns: Namespaces.HTML,
+ tag: 'div',
+ tagType: ElementTypes.ELEMENT,
+ props: [
+ {
+ type: NodeTypes.ATTRIBUTE,
+ name: 'id',
+ value: {
+ type: NodeTypes.TEXT,
+ content: 'a/',
+ isEmpty: false,
+ loc: {
+ start: { offset: 8, line: 1, column: 9 },
+ end: { offset: 10, line: 1, column: 11 },
+ source: 'a/'
+ }
+ },
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 10, line: 1, column: 11 },
+ source: 'id=a/'
+ }
+ }
+ ],
+ isSelfClosing: false,
+ children: [],
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 17, line: 1, column: 18 },
+ source: '<div id=a/></div>'
+ }
+ })
+ })
+
+ test('multiple attributes', () => {
+ const ast = parse(
+ '<div id=a class="c" inert style=\'\'></div>',
+ parserOptions
+ )
+ const element = ast.children[0] as ElementNode
+
+ expect(element).toStrictEqual({
+ type: NodeTypes.ELEMENT,
+ ns: Namespaces.HTML,
+ tag: 'div',
+ tagType: ElementTypes.ELEMENT,
+ props: [
+ {
+ type: NodeTypes.ATTRIBUTE,
+ name: 'id',
+ value: {
+ type: NodeTypes.TEXT,
+ content: 'a',
+ isEmpty: false,
+ loc: {
+ start: { offset: 8, line: 1, column: 9 },
+ end: { offset: 9, line: 1, column: 10 },
+ source: 'a'
+ }
+ },
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 9, line: 1, column: 10 },
+ source: 'id=a'
+ }
+ },
+ {
+ type: NodeTypes.ATTRIBUTE,
+ name: 'class',
+ value: {
+ type: NodeTypes.TEXT,
+ content: 'c',
+ isEmpty: false,
+ loc: {
+ start: { offset: 16, line: 1, column: 17 },
+ end: { offset: 19, line: 1, column: 20 },
+ source: '"c"'
+ }
+ },
+ loc: {
+ start: { offset: 10, line: 1, column: 11 },
+ end: { offset: 19, line: 1, column: 20 },
+ source: 'class="c"'
+ }
+ },
+ {
+ type: NodeTypes.ATTRIBUTE,
+ name: 'inert',
+ value: undefined,
+ loc: {
+ start: { offset: 20, line: 1, column: 21 },
+ end: { offset: 25, line: 1, column: 26 },
+ source: 'inert'
+ }
+ },
+ {
+ type: NodeTypes.ATTRIBUTE,
+ name: 'style',
+ value: {
+ type: NodeTypes.TEXT,
+ content: '',
+ isEmpty: true,
+ loc: {
+ start: { offset: 32, line: 1, column: 33 },
+ end: { offset: 34, line: 1, column: 35 },
+ source: "''"
+ }
+ },
+ loc: {
+ start: { offset: 26, line: 1, column: 27 },
+ end: { offset: 34, line: 1, column: 35 },
+ source: "style=''"
+ }
+ }
+ ],
+ isSelfClosing: false,
+ children: [],
+ loc: {
+ start: { offset: 0, line: 1, column: 1 },
+ end: { offset: 41, line: 1, column: 42 },
+ source: '<div id=a class="c" inert style=\'\'></div>'
+ }
+ })
+ })
+
+ test('directive with no value', () => {
+ const ast = parse('<div v-if/>', parserOptions)
+ const directive = (ast.children[0] as ElementNode)
+ .props[0] as DirectiveNode
+
+ expect(directive).toStrictEqual({
+ type: NodeTypes.DIRECTIVE,
+ name: 'if',
+ arg: undefined,
+ modifiers: [],
+ exp: undefined,
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 9, line: 1, column: 10 },
+ source: 'v-if'
+ }
+ })
+ })
+
+ test('directive with value', () => {
+ const ast = parse('<div v-if="a"/>', parserOptions)
+ const directive = (ast.children[0] as ElementNode)
+ .props[0] as DirectiveNode
+
+ expect(directive).toStrictEqual({
+ type: NodeTypes.DIRECTIVE,
+ name: 'if',
+ arg: undefined,
+ modifiers: [],
+ exp: {
+ type: NodeTypes.EXPRESSION,
+ content: 'a',
+ isStatic: false,
+ loc: {
+ start: { offset: 10, line: 1, column: 11 },
+ end: { offset: 13, line: 1, column: 14 },
+ source: '"a"'
+ }
+ },
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 13, line: 1, column: 14 },
+ source: 'v-if="a"'
+ }
+ })
+ })
+
+ test('directive with argument', () => {
+ const ast = parse('<div v-on:click/>', parserOptions)
+ const directive = (ast.children[0] as ElementNode)
+ .props[0] as DirectiveNode
+
+ expect(directive).toStrictEqual({
+ type: NodeTypes.DIRECTIVE,
+ name: 'on',
+ arg: {
+ type: 4,
+ content: 'click',
+ isStatic: true,
+ loc: {
+ source: 'click',
+ start: {
+ column: 11,
+ line: 1,
+ offset: 10
+ },
+ end: {
+ column: 16,
+ line: 1,
+ offset: 15
+ }
+ }
+ },
+ modifiers: [],
+ exp: undefined,
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 15, line: 1, column: 16 },
+ source: 'v-on:click'
+ }
+ })
+ })
+
+ test('directive with a modifier', () => {
+ const ast = parse('<div v-on.enter/>', parserOptions)
+ const directive = (ast.children[0] as ElementNode)
+ .props[0] as DirectiveNode
+
+ expect(directive).toStrictEqual({
+ type: NodeTypes.DIRECTIVE,
+ name: 'on',
+ arg: undefined,
+ modifiers: ['enter'],
+ exp: undefined,
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 15, line: 1, column: 16 },
+ source: 'v-on.enter'
+ }
+ })
+ })
+
+ test('directive with two modifiers', () => {
+ const ast = parse('<div v-on.enter.exact/>', parserOptions)
+ const directive = (ast.children[0] as ElementNode)
+ .props[0] as DirectiveNode
+
+ expect(directive).toStrictEqual({
+ type: NodeTypes.DIRECTIVE,
+ name: 'on',
+ arg: undefined,
+ modifiers: ['enter', 'exact'],
+ exp: undefined,
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 21, line: 1, column: 22 },
+ source: 'v-on.enter.exact'
+ }
+ })
+ })
+
+ test('directive with argument and modifiers', () => {
+ const ast = parse('<div v-on:click.enter.exact/>', parserOptions)
+ const directive = (ast.children[0] as ElementNode)
+ .props[0] as DirectiveNode
+
+ expect(directive).toStrictEqual({
+ type: NodeTypes.DIRECTIVE,
+ name: 'on',
+ arg: {
+ type: 4,
+ content: 'click',
+ isStatic: true,
+ loc: {
+ source: 'click',
+ start: {
+ column: 11,
+ line: 1,
+ offset: 10
+ },
+ end: {
+ column: 16,
+ line: 1,
+ offset: 15
+ }
+ }
+ },
+ modifiers: ['enter', 'exact'],
+ exp: undefined,
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 27, line: 1, column: 28 },
+ source: 'v-on:click.enter.exact'
+ }
+ })
+ })
+
+ test('v-bind shorthand', () => {
+ const ast = parse('<div :a=b />', parserOptions)
+ const directive = (ast.children[0] as ElementNode)
+ .props[0] as DirectiveNode
+
+ expect(directive).toStrictEqual({
+ type: NodeTypes.DIRECTIVE,
+ name: 'bind',
+ arg: {
+ type: 4,
+ content: 'a',
+ isStatic: true,
+ loc: {
+ source: 'a',
+ start: {
+ column: 7,
+ line: 1,
+ offset: 6
+ },
+ end: {
+ column: 8,
+ line: 1,
+ offset: 7
+ }
+ }
+ },
+ modifiers: [],
+ exp: {
+ type: NodeTypes.EXPRESSION,
+ content: 'b',
+ isStatic: false,
+ loc: {
+ start: { offset: 8, line: 1, column: 9 },
+ end: { offset: 9, line: 1, column: 10 },
+ source: 'b'
+ }
+ },
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 9, line: 1, column: 10 },
+ source: ':a=b'
+ }
+ })
+ })
+
+ test('v-bind shorthand with modifier', () => {
+ const ast = parse('<div :a.sync=b />', parserOptions)
+ const directive = (ast.children[0] as ElementNode)
+ .props[0] as DirectiveNode
+
+ expect(directive).toStrictEqual({
+ type: NodeTypes.DIRECTIVE,
+ name: 'bind',
+ arg: {
+ type: 4,
+ content: 'a',
+ isStatic: true,
+ loc: {
+ source: 'a',
+ start: {
+ column: 7,
+ line: 1,
+ offset: 6
+ },
+ end: {
+ column: 8,
+ line: 1,
+ offset: 7
+ }
+ }
+ },
+ modifiers: ['sync'],
+ exp: {
+ type: NodeTypes.EXPRESSION,
+ content: 'b',
+ isStatic: false,
+ loc: {
+ start: { offset: 13, line: 1, column: 14 },
+ end: { offset: 14, line: 1, column: 15 },
+ source: 'b'
+ }
+ },
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 14, line: 1, column: 15 },
+ source: ':a.sync=b'
+ }
+ })
+ })
+
+ test('v-on shorthand', () => {
+ const ast = parse('<div @a=b />', parserOptions)
+ const directive = (ast.children[0] as ElementNode)
+ .props[0] as DirectiveNode
+
+ expect(directive).toStrictEqual({
+ type: NodeTypes.DIRECTIVE,
+ name: 'on',
+ arg: {
+ type: 4,
+ content: 'a',
+ isStatic: true,
+ loc: {
+ source: 'a',
+ start: {
+ column: 7,
+ line: 1,
+ offset: 6
+ },
+ end: {
+ column: 8,
+ line: 1,
+ offset: 7
+ }
+ }
+ },
+ modifiers: [],
+ exp: {
+ type: NodeTypes.EXPRESSION,
+ content: 'b',
+ isStatic: false,
+ loc: {
+ start: { offset: 8, line: 1, column: 9 },
+ end: { offset: 9, line: 1, column: 10 },
+ source: 'b'
+ }
+ },
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 9, line: 1, column: 10 },
+ source: '@a=b'
+ }
+ })
+ })
+
+ test('v-on shorthand with modifier', () => {
+ const ast = parse('<div @a.enter=b />', parserOptions)
+ const directive = (ast.children[0] as ElementNode)
+ .props[0] as DirectiveNode
+
+ expect(directive).toStrictEqual({
+ type: NodeTypes.DIRECTIVE,
+ name: 'on',
+ arg: {
+ type: 4,
+ content: 'a',
+ isStatic: true,
+ loc: {
+ source: 'a',
+ start: {
+ column: 7,
+ line: 1,
+ offset: 6
+ },
+ end: {
+ column: 8,
+ line: 1,
+ offset: 7
+ }
+ }
+ },
+ modifiers: ['enter'],
+ exp: {
+ type: NodeTypes.EXPRESSION,
+ content: 'b',
+ isStatic: false,
+ loc: {
+ start: { offset: 14, line: 1, column: 15 },
+ end: { offset: 15, line: 1, column: 16 },
+ source: 'b'
+ }
+ },
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 15, line: 1, column: 16 },
+ source: '@a.enter=b'
+ }
+ })
+ })
+
+ test('end tags are case-insensitive.', () => {
+ const ast = parse('<div>hello</DIV>after', parserOptions)
+ const element = ast.children[0] as ElementNode
+ const text = element.children[0] as TextNode
+
+ expect(text).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: 'hello',
+ isEmpty: false,
+ loc: {
+ start: { offset: 5, line: 1, column: 6 },
+ end: { offset: 10, line: 1, column: 11 },
+ source: 'hello'
+ }
+ })
+ })
+
+ test('Strict end tag detection.', () => {
+ const ast = parse(
+ '<textarea>hello</textarea</textarea0></texTArea a="<>">',
+ {
+ ...parserOptions,
+ onError: type => {
+ if (type !== ParserErrorTypes.END_TAG_WITH_ATTRIBUTES) {
+ throw new Error(String(type))
+ }
+ }
+ }
+ )
+ const element = ast.children[0] as ElementNode
+ const text = element.children[0] as TextNode
+
+ expect(ast.children.length).toBe(1)
+ expect(text).toStrictEqual({
+ type: NodeTypes.TEXT,
+ content: 'hello</textarea</textarea0>',
+ isEmpty: false,
+ loc: {
+ start: { offset: 10, line: 1, column: 11 },
+ end: { offset: 37, line: 1, column: 38 },
+ source: 'hello</textarea</textarea0>'
+ }
+ })
+ })
+ })
+
+ test('self closing single tag', () => {
+ const ast = parse('<div :class="{ some: condition }" />', parserOptions)
+
+ expect(ast.children).toHaveLength(1)
+ expect(ast.children[0]).toMatchObject({ tag: 'div' })
+ })
+
+ test('self closing multiple tag', () => {
+ const ast = parse(
+ `<div :class="{ some: condition }" />\n` +
+ `<p v-bind:style="{ color: 'red' }"/>`,
+ parserOptions
+ )
+
+ expect(ast).toMatchSnapshot()
+
+ expect(ast.children).toHaveLength(2)
+ expect(ast.children[0]).toMatchObject({ tag: 'div' })
+ expect(ast.children[1]).toMatchObject({ tag: 'p' })
+ })
+
+ test('valid html', () => {
+ const ast = parse(
+ `<div :class="{ some: condition }">\n` +
+ ` <p v-bind:style="{ color: 'red' }"/>\n` +
+ ` <!-- a comment with <html> inside it -->\n` +
+ `</div>`,
+ parserOptions
+ )
+
+ expect(ast).toMatchSnapshot()
+
+ expect(ast.children).toHaveLength(1)
+ const el = ast.children[0] as any
+ expect(el).toMatchObject({
+ tag: 'div'
+ })
+ expect(el.children).toHaveLength(2)
+ expect(el.children[0]).toMatchObject({
+ tag: 'p'
+ })
+ expect(el.children[1]).toMatchObject({
+ type: NodeTypes.COMMENT
+ })
+ })
+
+ test('invalid html', () => {
+ expect(() => {
+ parse(`<div>\n<span>\n</div>\n</span>`, parserOptions)
+ }).toThrow('End tag was not found. (3:1)')
+
+ const spy = jest.fn()
+ const ast = parse(`<div>\n<span>\n</div>\n</span>`, {
+ ...parserOptions,
+ onError: spy
+ })
+
+ expect(spy).toBeCalledWith(ParserErrorTypes.X_MISSING_END_TAG, {
+ offset: 13,
+ line: 3,
+ column: 1
+ })
+ expect(spy).toBeCalledWith(ParserErrorTypes.X_INVALID_END_TAG, {
+ offset: 20,
+ line: 4,
+ column: 1
+ })
+ expect(ast).toMatchSnapshot()
+ })
+
+ test('parse with correct location info', () => {
+ const [foo, bar, but, baz] = parse(
+ 'foo \n is {{ bar }} but {{ baz }}',
+ parserOptions
+ ).children
+
+ let offset = 0
+ expect(foo.loc.start).toEqual({ line: 1, column: 1, offset })
+ offset += foo.loc.source.length
+ expect(foo.loc.end).toEqual({ line: 2, column: 4, offset })
+
+ expect(bar.loc.start).toEqual({ line: 2, column: 4, offset })
+ offset += bar.loc.source.length
+ expect(bar.loc.end).toEqual({ line: 2, column: 13, offset })
+
+ expect(but.loc.start).toEqual({ line: 2, column: 13, offset })
+ offset += but.loc.source.length
+ expect(but.loc.end).toEqual({ line: 2, column: 18, offset })
+
+ expect(baz.loc.start).toEqual({ line: 2, column: 18, offset })
+ offset += baz.loc.source.length
+ expect(baz.loc.end).toEqual({ line: 2, column: 27, offset })
+ })
+
+ describe('namedCharacterReferences option', () => {
+ test('use the given map', () => {
+ const ast: any = parse('&∪︀', {
+ ...parserOptions,
+ namedCharacterReferences: {
+ 'cups;': '\u222A\uFE00' // UNION with serifs
+ },
+ onError: () => {} // Ignore errors
+ })
+
+ expect(ast.children.length).toBe(1)
+ expect(ast.children[0].type).toBe(NodeTypes.TEXT)
+ expect(ast.children[0].content).toBe('&\u222A\uFE00')
+ })
+ })
+
+ describe('onError option', () => {
+ const patterns: {
+ [key: string]: Array<{
+ code: string
+ errors: Array<{ type: ParserErrorTypes; loc: Position }>
+ options?: Partial<ParserOptions>
+ }>
+ } = {
+ ABRUPT_CLOSING_OF_EMPTY_COMMENT: [
+ {
+ code: '<template><!--></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.ABRUPT_CLOSING_OF_EMPTY_COMMENT,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ },
+ {
+ code: '<template><!---></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.ABRUPT_CLOSING_OF_EMPTY_COMMENT,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ },
+ {
+ code: '<template><!----></template>',
+ errors: []
+ }
+ ],
+ ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE: [
+ {
+ code: '<template>&#a;</template>',
+ errors: [
+ {
+ type:
+ ParserErrorTypes.ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ },
+ {
+ code: '<template>&#xg;</template>',
+ errors: [
+ {
+ type:
+ ParserErrorTypes.ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ },
+ {
+ code: '<template>c</template>',
+ errors: []
+ },
+ {
+ code: '<template>ÿ</template>',
+ errors: []
+ },
+ {
+ code: '<template attr="&#a;"></template>',
+ errors: [
+ {
+ type:
+ ParserErrorTypes.ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE,
+ loc: { offset: 16, line: 1, column: 17 }
+ }
+ ]
+ },
+ {
+ code: '<template attr="&#xg;"></template>',
+ errors: [
+ {
+ type:
+ ParserErrorTypes.ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE,
+ loc: { offset: 16, line: 1, column: 17 }
+ }
+ ]
+ },
+ {
+ code: '<template attr="c"></template>',
+ errors: []
+ },
+ {
+ code: '<template attr="ÿ"></template>',
+ errors: []
+ }
+ ],
+ CDATA_IN_HTML_CONTENT: [
+ {
+ code: '<template><![CDATA[cdata]]></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.CDATA_IN_HTML_CONTENT,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ },
+ {
+ code: '<template><svg><![CDATA[cdata]]></svg></template>',
+ errors: []
+ }
+ ],
+ CHARACTER_REFERENCE_OUTSIDE_UNICODE_RANGE: [
+ {
+ code: '<template>�</template>',
+ errors: [
+ {
+ type: ParserErrorTypes.CHARACTER_REFERENCE_OUTSIDE_UNICODE_RANGE,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ }
+ ],
+ CONTROL_CHARACTER_REFERENCE: [
+ {
+ code: '<template></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.CONTROL_CHARACTER_REFERENCE,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ },
+ {
+ code: '<template></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.CONTROL_CHARACTER_REFERENCE,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ }
+ ],
+ DUPLICATE_ATTRIBUTE: [
+ {
+ code: '<template><div id="" id=""></div></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.DUPLICATE_ATTRIBUTE,
+ loc: { offset: 21, line: 1, column: 22 }
+ }
+ ]
+ }
+ ],
+ END_TAG_WITH_ATTRIBUTES: [
+ {
+ code: '<template><div></div id=""></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.END_TAG_WITH_ATTRIBUTES,
+ loc: { offset: 21, line: 1, column: 22 }
+ }
+ ]
+ }
+ ],
+ END_TAG_WITH_TRAILING_SOLIDUS: [
+ {
+ code: '<template><div></div/></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.END_TAG_WITH_TRAILING_SOLIDUS,
+ loc: { offset: 20, line: 1, column: 21 }
+ }
+ ]
+ }
+ ],
+ EOF_BEFORE_TAG_NAME: [
+ {
+ code: '<template><',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_BEFORE_TAG_NAME,
+ loc: { offset: 11, line: 1, column: 12 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 11, line: 1, column: 12 }
+ }
+ ]
+ },
+ {
+ code: '<template></',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_BEFORE_TAG_NAME,
+ loc: { offset: 12, line: 1, column: 13 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 12, line: 1, column: 13 }
+ }
+ ]
+ }
+ ],
+ EOF_IN_CDATA: [
+ {
+ code: '<template><svg><![CDATA[cdata',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_CDATA,
+ loc: { offset: 29, line: 1, column: 30 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 29, line: 1, column: 30 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 29, line: 1, column: 30 }
+ }
+ ]
+ },
+ {
+ code: '<template><svg><![CDATA[',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_CDATA,
+ loc: { offset: 24, line: 1, column: 25 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 24, line: 1, column: 25 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 24, line: 1, column: 25 }
+ }
+ ]
+ }
+ ],
+ EOF_IN_COMMENT: [
+ {
+ code: '<template><!--comment',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_COMMENT,
+ loc: { offset: 21, line: 1, column: 22 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 21, line: 1, column: 22 }
+ }
+ ]
+ },
+ {
+ code: '<template><!--',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_COMMENT,
+ loc: { offset: 14, line: 1, column: 15 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 14, line: 1, column: 15 }
+ }
+ ]
+ },
+ // Bogus comments don't throw eof-in-comment error.
+ // https://html.spec.whatwg.org/multipage/parsing.html#bogus-comment-state
+ {
+ code: '<template><!',
+ errors: [
+ {
+ type: ParserErrorTypes.INCORRECTLY_OPENED_COMMENT,
+ loc: { offset: 10, line: 1, column: 11 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 12, line: 1, column: 13 }
+ }
+ ]
+ },
+ {
+ code: '<template><!-',
+ errors: [
+ {
+ type: ParserErrorTypes.INCORRECTLY_OPENED_COMMENT,
+ loc: { offset: 10, line: 1, column: 11 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 13, line: 1, column: 14 }
+ }
+ ]
+ },
+ {
+ code: '<template><!abc',
+ errors: [
+ {
+ type: ParserErrorTypes.INCORRECTLY_OPENED_COMMENT,
+ loc: { offset: 10, line: 1, column: 11 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 15, line: 1, column: 16 }
+ }
+ ]
+ }
+ ],
+ EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT: [
+ {
+ code: "<script><!--console.log('hello')",
+ errors: [
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 32, line: 1, column: 33 }
+ },
+ {
+ type: ParserErrorTypes.EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT,
+ loc: { offset: 32, line: 1, column: 33 }
+ }
+ ]
+ },
+ {
+ code: "<script>console.log('hello')",
+ errors: [
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 28, line: 1, column: 29 }
+ }
+ ]
+ }
+ ],
+ EOF_IN_TAG: [
+ {
+ code: '<template><div',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_TAG,
+ loc: { offset: 14, line: 1, column: 15 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 14, line: 1, column: 15 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 14, line: 1, column: 15 }
+ }
+ ]
+ },
+ {
+ code: '<template><div ',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_TAG,
+ loc: { offset: 15, line: 1, column: 16 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 15, line: 1, column: 16 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 15, line: 1, column: 16 }
+ }
+ ]
+ },
+ {
+ code: '<template><div id',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_TAG,
+ loc: { offset: 17, line: 1, column: 18 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 17, line: 1, column: 18 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 17, line: 1, column: 18 }
+ }
+ ]
+ },
+ {
+ code: '<template><div id ',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_TAG,
+ loc: { offset: 18, line: 1, column: 19 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 18, line: 1, column: 19 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 18, line: 1, column: 19 }
+ }
+ ]
+ },
+ {
+ code: '<template><div id =',
+ errors: [
+ {
+ type: ParserErrorTypes.MISSING_ATTRIBUTE_VALUE,
+ loc: { offset: 19, line: 1, column: 20 }
+ },
+ {
+ type: ParserErrorTypes.EOF_IN_TAG,
+ loc: { offset: 19, line: 1, column: 20 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 19, line: 1, column: 20 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 19, line: 1, column: 20 }
+ }
+ ]
+ },
+ {
+ code: "<template><div id='abc",
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_TAG,
+ loc: { offset: 22, line: 1, column: 23 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 22, line: 1, column: 23 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 22, line: 1, column: 23 }
+ }
+ ]
+ },
+ {
+ code: '<template><div id="abc',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_TAG,
+ loc: { offset: 22, line: 1, column: 23 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 22, line: 1, column: 23 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 22, line: 1, column: 23 }
+ }
+ ]
+ },
+ {
+ code: "<template><div id='abc'",
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_TAG,
+ loc: { offset: 23, line: 1, column: 24 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 23, line: 1, column: 24 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 23, line: 1, column: 24 }
+ }
+ ]
+ },
+ {
+ code: '<template><div id="abc"',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_TAG,
+ loc: { offset: 23, line: 1, column: 24 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 23, line: 1, column: 24 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 23, line: 1, column: 24 }
+ }
+ ]
+ },
+ {
+ code: '<template><div id=abc',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_TAG,
+ loc: { offset: 21, line: 1, column: 22 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 21, line: 1, column: 22 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 21, line: 1, column: 22 }
+ }
+ ]
+ },
+ {
+ code: "<template><div id='abc'/",
+ errors: [
+ {
+ type: ParserErrorTypes.UNEXPECTED_SOLIDUS_IN_TAG,
+ loc: { offset: 23, line: 1, column: 24 }
+ },
+ {
+ type: ParserErrorTypes.EOF_IN_TAG,
+ loc: { offset: 24, line: 1, column: 25 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 24, line: 1, column: 25 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 24, line: 1, column: 25 }
+ }
+ ]
+ },
+ {
+ code: '<template><div id="abc"/',
+ errors: [
+ {
+ type: ParserErrorTypes.UNEXPECTED_SOLIDUS_IN_TAG,
+ loc: { offset: 23, line: 1, column: 24 }
+ },
+ {
+ type: ParserErrorTypes.EOF_IN_TAG,
+ loc: { offset: 24, line: 1, column: 25 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 24, line: 1, column: 25 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 24, line: 1, column: 25 }
+ }
+ ]
+ },
+ {
+ code: '<template><div id=abc /',
+ errors: [
+ {
+ type: ParserErrorTypes.UNEXPECTED_SOLIDUS_IN_TAG,
+ loc: { offset: 22, line: 1, column: 23 }
+ },
+ {
+ type: ParserErrorTypes.EOF_IN_TAG,
+ loc: { offset: 23, line: 1, column: 24 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 23, line: 1, column: 24 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 23, line: 1, column: 24 }
+ }
+ ]
+ }
+ ],
+ INCORRECTLY_CLOSED_COMMENT: [
+ {
+ code: '<template><!--comment--!></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.INCORRECTLY_CLOSED_COMMENT,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ }
+ ],
+ INCORRECTLY_OPENED_COMMENT: [
+ {
+ code: '<template><!></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.INCORRECTLY_OPENED_COMMENT,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ },
+ {
+ code: '<template><!-></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.INCORRECTLY_OPENED_COMMENT,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ },
+ {
+ code: '<template><!ELEMENT br EMPTY></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.INCORRECTLY_OPENED_COMMENT,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ },
+ // Just ignore doctype.
+ {
+ code: '<!DOCTYPE html>',
+ errors: []
+ }
+ ],
+ INVALID_FIRST_CHARACTER_OF_TAG_NAME: [
+ {
+ code: '<template>a < b</template>',
+ errors: [
+ {
+ type: ParserErrorTypes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
+ loc: { offset: 13, line: 1, column: 14 }
+ }
+ ]
+ },
+ {
+ code: '<template><�></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
+ loc: { offset: 11, line: 1, column: 12 }
+ }
+ ]
+ },
+ {
+ code: '<template>a </ b</template>',
+ errors: [
+ {
+ type: ParserErrorTypes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
+ loc: { offset: 14, line: 1, column: 15 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 27, line: 1, column: 28 }
+ }
+ ]
+ },
+ {
+ code: '<template></�></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
+ loc: { offset: 12, line: 1, column: 13 }
+ }
+ ]
+ },
+ // Don't throw invalid-first-character-of-tag-name in interpolation
+ {
+ code: '<template>{{a < b}}</template>',
+ errors: []
+ }
+ ],
+ MISSING_ATTRIBUTE_VALUE: [
+ {
+ code: '<template><div id=></div></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.MISSING_ATTRIBUTE_VALUE,
+ loc: { offset: 18, line: 1, column: 19 }
+ }
+ ]
+ },
+ {
+ code: '<template><div id= ></div></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.MISSING_ATTRIBUTE_VALUE,
+ loc: { offset: 19, line: 1, column: 20 }
+ }
+ ]
+ },
+ {
+ code: '<template><div id= /></div></template>',
+ errors: []
+ }
+ ],
+ MISSING_END_TAG_NAME: [
+ {
+ code: '<template></></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.MISSING_END_TAG_NAME,
+ loc: { offset: 12, line: 1, column: 13 }
+ }
+ ]
+ }
+ ],
+ MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE: [
+ {
+ code: '<template>&</template>',
+ options: { namedCharacterReferences: { amp: '&' } },
+ errors: [
+ {
+ type:
+ ParserErrorTypes.MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE,
+ loc: { offset: 14, line: 1, column: 15 }
+ }
+ ]
+ },
+ {
+ code: '<template>(</template>',
+ errors: [
+ {
+ type:
+ ParserErrorTypes.MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE,
+ loc: { offset: 14, line: 1, column: 15 }
+ }
+ ]
+ },
+ {
+ code: '<template>@</template>',
+ errors: [
+ {
+ type:
+ ParserErrorTypes.MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE,
+ loc: { offset: 15, line: 1, column: 16 }
+ }
+ ]
+ }
+ ],
+ MISSING_WHITESPACE_BETWEEN_ATTRIBUTES: [
+ {
+ code: '<template><div id="foo"class="bar"></div></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.MISSING_WHITESPACE_BETWEEN_ATTRIBUTES,
+ loc: { offset: 23, line: 1, column: 24 }
+ }
+ ]
+ },
+ // CR doesn't appear in tokenization phase, but all CR are removed in preprocessing.
+ // https://html.spec.whatwg.org/multipage/parsing.html#preprocessing-the-input-stream
+ {
+ code: '<template><div id="foo"\r\nclass="bar"></div></template>',
+ errors: []
+ }
+ ],
+ NESTED_COMMENT: [
+ {
+ code: '<template><!--a<!--b--></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.NESTED_COMMENT,
+ loc: { offset: 15, line: 1, column: 16 }
+ }
+ ]
+ },
+ {
+ code: '<template><!--a<!--b<!--c--></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.NESTED_COMMENT,
+ loc: { offset: 15, line: 1, column: 16 }
+ },
+ {
+ type: ParserErrorTypes.NESTED_COMMENT,
+ loc: { offset: 20, line: 1, column: 21 }
+ }
+ ]
+ },
+ {
+ code: '<template><!--a<!--></template>',
+ errors: []
+ },
+ {
+ code: '<template><!--a<!--',
+ errors: [
+ {
+ type: ParserErrorTypes.EOF_IN_COMMENT,
+ loc: { offset: 19, line: 1, column: 20 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 19, line: 1, column: 20 }
+ }
+ ]
+ }
+ ],
+ NONCHARACTER_CHARACTER_REFERENCE: [
+ {
+ code: '<template></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.NONCHARACTER_CHARACTER_REFERENCE,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ },
+ {
+ code: '<template></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.NONCHARACTER_CHARACTER_REFERENCE,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ }
+ ],
+ NULL_CHARACTER_REFERENCE: [
+ {
+ code: '<template>�</template>',
+ errors: [
+ {
+ type: ParserErrorTypes.NULL_CHARACTER_REFERENCE,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ }
+ ],
+ SURROGATE_CHARACTER_REFERENCE: [
+ {
+ code: '<template>�</template>',
+ errors: [
+ {
+ type: ParserErrorTypes.SURROGATE_CHARACTER_REFERENCE,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ }
+ ],
+ UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME: [
+ {
+ code: "<template><div a\"bc=''></div></template>",
+ errors: [
+ {
+ type: ParserErrorTypes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME,
+ loc: { offset: 16, line: 1, column: 17 }
+ }
+ ]
+ },
+ {
+ code: "<template><div a'bc=''></div></template>",
+ errors: [
+ {
+ type: ParserErrorTypes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME,
+ loc: { offset: 16, line: 1, column: 17 }
+ }
+ ]
+ },
+ {
+ code: "<template><div a<bc=''></div></template>",
+ errors: [
+ {
+ type: ParserErrorTypes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME,
+ loc: { offset: 16, line: 1, column: 17 }
+ }
+ ]
+ }
+ ],
+ UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE: [
+ {
+ code: '<template><div foo=bar"></div></template>',
+ errors: [
+ {
+ type:
+ ParserErrorTypes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE,
+ loc: { offset: 22, line: 1, column: 23 }
+ }
+ ]
+ },
+ {
+ code: "<template><div foo=bar'></div></template>",
+ errors: [
+ {
+ type:
+ ParserErrorTypes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE,
+ loc: { offset: 22, line: 1, column: 23 }
+ }
+ ]
+ },
+ {
+ code: '<template><div foo=bar<div></div></template>',
+ errors: [
+ {
+ type:
+ ParserErrorTypes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE,
+ loc: { offset: 22, line: 1, column: 23 }
+ }
+ ]
+ },
+ {
+ code: '<template><div foo=bar=baz></div></template>',
+ errors: [
+ {
+ type:
+ ParserErrorTypes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE,
+ loc: { offset: 22, line: 1, column: 23 }
+ }
+ ]
+ },
+ {
+ code: '<template><div foo=bar`></div></template>',
+ errors: [
+ {
+ type:
+ ParserErrorTypes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE,
+ loc: { offset: 22, line: 1, column: 23 }
+ }
+ ]
+ }
+ ],
+ UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME: [
+ {
+ code: '<template><div =foo=bar></div></template>',
+ errors: [
+ {
+ type:
+ ParserErrorTypes.UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME,
+ loc: { offset: 15, line: 1, column: 16 }
+ }
+ ]
+ },
+ {
+ code: '<template><div =></div></template>',
+ errors: [
+ {
+ type:
+ ParserErrorTypes.UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME,
+ loc: { offset: 15, line: 1, column: 16 }
+ }
+ ]
+ }
+ ],
+ UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME: [
+ {
+ code: '<template><?xml?></template>',
+ errors: [
+ {
+ type:
+ ParserErrorTypes.UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME,
+ loc: { offset: 11, line: 1, column: 12 }
+ }
+ ]
+ }
+ ],
+ UNEXPECTED_SOLIDUS_IN_TAG: [
+ {
+ code: '<template><div a/b></div></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.UNEXPECTED_SOLIDUS_IN_TAG,
+ loc: { offset: 16, line: 1, column: 17 }
+ }
+ ]
+ }
+ ],
+ UNKNOWN_NAMED_CHARACTER_REFERENCE: [
+ {
+ code: '<template>&unknown;</template>',
+ errors: [
+ {
+ type: ParserErrorTypes.UNKNOWN_NAMED_CHARACTER_REFERENCE,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ }
+ ],
+ X_INVALID_END_TAG: [
+ {
+ code: '<template></div></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.X_INVALID_END_TAG,
+ loc: { offset: 10, line: 1, column: 11 }
+ }
+ ]
+ },
+ {
+ code: '<template></div></div></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.X_INVALID_END_TAG,
+ loc: { offset: 10, line: 1, column: 11 }
+ },
+ {
+ type: ParserErrorTypes.X_INVALID_END_TAG,
+ loc: { offset: 16, line: 1, column: 17 }
+ }
+ ]
+ },
+ {
+ code: "<template>{{'</div>'}}</template>",
+ errors: []
+ },
+ {
+ code: '<textarea></div></textarea>',
+ errors: []
+ },
+ {
+ code: '<svg><![CDATA[</div>]]></svg>',
+ errors: []
+ },
+ {
+ code: '<svg><!--</div>--></svg>',
+ errors: []
+ }
+ ],
+ X_MISSING_END_TAG: [
+ {
+ code: '<template><div></template>',
+ errors: [
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 15, line: 1, column: 16 }
+ }
+ ]
+ },
+ {
+ code: '<template><div>',
+ errors: [
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 15, line: 1, column: 16 }
+ },
+ {
+ type: ParserErrorTypes.X_MISSING_END_TAG,
+ loc: { offset: 15, line: 1, column: 16 }
+ }
+ ]
+ }
+ ],
+ X_MISSING_INTERPOLATION_END: [
+ {
+ code: '{{ foo',
+ errors: [
+ {
+ type: ParserErrorTypes.X_MISSING_INTERPOLATION_END,
+ loc: { offset: 0, line: 1, column: 1 }
+ }
+ ]
+ },
+ {
+ code: '{{',
+ errors: [
+ {
+ type: ParserErrorTypes.X_MISSING_INTERPOLATION_END,
+ loc: { offset: 0, line: 1, column: 1 }
+ }
+ ]
+ },
+ {
+ code: '{{}}',
+ errors: []
+ }
+ ]
+ }
+
+ for (const key of Object.keys(patterns) as (keyof (typeof patterns))[]) {
+ describe(key, () => {
+ for (const { code, errors, options } of patterns[key]) {
+ test(
+ code.replace(
+ /[\r\n]/g,
+ c => `\\x0${c.codePointAt(0)!.toString(16)};`
+ ),
+ () => {
+ const spy = jest.fn()
+ const ast = parse(code, {
+ ...parserOptions,
+ ...options,
+ onError: spy
+ })
+
+ expect(spy.mock.calls).toEqual(
+ errors.map(({ type, loc }) => [type, loc])
+ )
+ expect(ast).toMatchSnapshot()
+ }
+ )
+ }
+ })
+ }
+ })
+})
--- /dev/null
+export const enum NodeTypes {
+ TEXT,
+ COMMENT,
+ ELEMENT,
+ ATTRIBUTE,
+ EXPRESSION,
+ DIRECTIVE,
+ ROOT
+}
+
+export const enum ElementTypes {
+ ELEMENT,
+ COMPONENT,
+ SLOT, // slot
+ TEMPLATE // template, component
+}
+
+export const enum Namespaces {
+ HTML,
+ SVG, // allows CDATA section and forbids end tag omission.
+ MATH_ML // allows CDATA section and forbids end tag omission.
+}
+
+export interface Node {
+ type: NodeTypes
+ loc: SourceLocation
+}
+
+export interface RootNode extends Node {
+ type: NodeTypes.ROOT
+ children: Array<ElementNode | ExpressionNode | TextNode | CommentNode>
+}
+
+export interface ElementNode extends Node {
+ type: NodeTypes.ELEMENT
+ ns: Namespaces
+ tag: string
+ tagType: ElementTypes
+ isSelfClosing: boolean
+ props: Array<AttributeNode | DirectiveNode>
+ children: Array<ElementNode | ExpressionNode | TextNode | CommentNode>
+}
+
+export interface TextNode extends Node {
+ type: NodeTypes.TEXT
+ content: string
+ isEmpty: boolean
+}
+
+export interface CommentNode extends Node {
+ type: NodeTypes.COMMENT
+ content: string
+}
+
+export interface AttributeNode extends Node {
+ type: NodeTypes.ATTRIBUTE
+ name: string
+ value: TextNode | undefined
+}
+
+export interface DirectiveNode extends Node {
+ type: NodeTypes.DIRECTIVE
+ name: string
+ exp: ExpressionNode | undefined
+ arg: ExpressionNode | undefined
+ modifiers: string[]
+}
+
+export interface ExpressionNode extends Node {
+ type: NodeTypes.EXPRESSION
+ content: string
+ isStatic: boolean
+}
+
+export interface Position {
+ offset: number // from start of file
+ line: number
+ column: number
+}
+
+// The node's range. The `start` is inclusive and `end` is exclusive.
+// [start, end)
+export interface SourceLocation {
+ start: Position
+ end: Position
+ source: string
+}
--- /dev/null
+export const enum ParserErrorTypes {
+ ABRUPT_CLOSING_OF_EMPTY_COMMENT,
+ ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE,
+ CDATA_IN_HTML_CONTENT,
+ CHARACTER_REFERENCE_OUTSIDE_UNICODE_RANGE,
+ CONTROL_CHARACTER_REFERENCE,
+ DUPLICATE_ATTRIBUTE,
+ END_TAG_WITH_ATTRIBUTES,
+ END_TAG_WITH_TRAILING_SOLIDUS,
+ EOF_BEFORE_TAG_NAME,
+ EOF_IN_CDATA,
+ EOF_IN_COMMENT,
+ EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT,
+ EOF_IN_TAG,
+ INCORRECTLY_CLOSED_COMMENT,
+ INCORRECTLY_OPENED_COMMENT,
+ INVALID_FIRST_CHARACTER_OF_TAG_NAME,
+ MISSING_ATTRIBUTE_VALUE,
+ MISSING_END_TAG_NAME,
+ MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE,
+ MISSING_WHITESPACE_BETWEEN_ATTRIBUTES,
+ NESTED_COMMENT,
+ NONCHARACTER_CHARACTER_REFERENCE,
+ NULL_CHARACTER_REFERENCE,
+ SURROGATE_CHARACTER_REFERENCE,
+ UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME,
+ UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE,
+ UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME,
+ UNEXPECTED_NULL_CHARACTER,
+ UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME,
+ UNEXPECTED_SOLIDUS_IN_TAG,
+ UNKNOWN_NAMED_CHARACTER_REFERENCE,
+ X_INVALID_END_TAG,
+ X_MISSING_END_TAG,
+ X_MISSING_INTERPOLATION_END,
+ X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END
+}
-// TODO
+export { parse } from './parser'
+export * from './ast'
+export * from './errorTypes'
--- /dev/null
+import assert from 'assert'
+import { ParserErrorTypes } from './errorTypes'
+import {
+ Node,
+ AttributeNode,
+ CommentNode,
+ DirectiveNode,
+ ElementNode,
+ ElementTypes,
+ ExpressionNode,
+ Namespaces,
+ NodeTypes,
+ Position,
+ RootNode,
+ SourceLocation,
+ TextNode
+} from './ast'
+
+export interface ParserOptions {
+ isVoidTag: (tag: string) => boolean // e.g. img, br, hr
+ getNamespace: (tag: string, parent: ElementNode | undefined) => Namespaces
+ getTextMode: (tag: string, ns: Namespaces) => TextModes
+ delimiters: [string, string] // ['{{', '}}']
+ transform: (node: Node) => Node // --
+ ignoreSpaces: boolean
+
+ // Map to HTML entities. E.g., `{ "amp;": "&" }`
+ // The full set is https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references
+ namedCharacterReferences: { [name: string]: string | undefined }
+
+ onError: (type: ParserErrorTypes, loc: Position) => void
+}
+
+export const enum TextModes {
+ // | Elements | Entities | End sign | Inside of
+ DATA, // | ✔ | ✔ | End tags of ancestors |
+ RCDATA, // | ✘ | ✔ | End tag of the parent | <textarea>
+ RAWTEXT, // | ✘ | ✘ | End tag of the parent | <style>,<script>
+ CDATA,
+ ATTRIBUTE_VALUE
+}
+
+interface ParserContext extends ParserOptions {
+ readonly originalSource: string
+ source: string
+ offset: number
+ line: number
+ column: number
+ maxCRNameLength: number
+}
+
+export function parse(content: string, options: ParserOptions): RootNode {
+ const context = createParserContext(content, options)
+ const start = getCursor(context)
+
+ return {
+ type: NodeTypes.ROOT,
+ children: parseChildren(context, TextModes.DATA, []),
+ loc: getSelection(context, start)
+ }
+}
+
+function last<T>(xs: T[]): T | undefined {
+ return xs[xs.length - 1]
+}
+
+function startsWith(source: string, searchString: string): boolean {
+ return source.startsWith(searchString)
+}
+
+function advanceBy(context: ParserContext, numberOfCharacters: number): void {
+ assert(numberOfCharacters <= context.source.length)
+
+ const { column, source } = context
+ const str = source.slice(0, numberOfCharacters)
+ const lines = str.split(/\r?\n/)
+
+ context.source = source.slice(numberOfCharacters)
+ context.offset += numberOfCharacters
+ context.line += lines.length - 1
+ context.column =
+ lines.length === 1
+ ? column + numberOfCharacters
+ : Math.max(1, lines.pop()!.length)
+}
+
+function advanceSpaces(context: ParserContext): void {
+ const match = /^[\t\r\n\f ]+/.exec(context.source)
+ if (match) {
+ advanceBy(context, match[0].length)
+ }
+}
+
+function getCursor(context: ParserContext): Position {
+ const { column, line, offset } = context
+ return { column, line, offset }
+}
+
+function getNewPosition(
+ context: ParserContext,
+ start: Position,
+ numberOfCharacters: number
+): Position {
+ const { originalSource } = context
+ const str = originalSource.slice(start.offset, numberOfCharacters)
+ const lines = str.split(/\r?\n/)
+
+ const newPosition = {
+ column: start.column,
+ line: start.line,
+ offset: start.offset
+ }
+
+ newPosition.offset += numberOfCharacters
+ newPosition.line += lines.length - 1
+ newPosition.column =
+ lines.length === 1
+ ? start.column + numberOfCharacters
+ : Math.max(1, lines.pop()!.length)
+
+ return newPosition
+}
+
+function getSelection(
+ context: ParserContext,
+ start: Position,
+ end?: Position
+): SourceLocation {
+ end = end || getCursor(context)
+ return {
+ start,
+ end,
+ source: context.originalSource.slice(start.offset, end.offset)
+ }
+}
+
+function emitError(
+ context: ParserContext,
+ type: ParserErrorTypes,
+ offset?: number
+): void {
+ const loc = getCursor(context)
+ if (offset) {
+ loc.offset += offset
+ loc.column += offset
+ }
+ context.onError(type, loc)
+}
+
+function createParserContext(
+ content: string,
+ options: ParserOptions
+): ParserContext {
+ return {
+ ...options,
+ column: 1,
+ line: 1,
+ offset: 0,
+ originalSource: content,
+ source: content,
+ maxCRNameLength: Object.keys(options.namedCharacterReferences).reduce(
+ (max, name) => Math.max(max, name.length),
+ 0
+ )
+ }
+}
+
+function parseChildren(
+ context: ParserContext,
+ mode: TextModes,
+ ancestors: ElementNode[]
+): RootNode['children'] {
+ const parent = last(ancestors)
+ const ns = parent ? parent.ns : Namespaces.HTML
+ const nodes: RootNode['children'] = []
+
+ while (!isEnd(context, mode, ancestors)) {
+ assert(context.source.length > 0)
+ const s = context.source
+ let node: any = null
+
+ if (startsWith(s, context.delimiters[0])) {
+ // '{{'
+ node = parseInterpolation(context, mode)
+ } else if (mode === TextModes.DATA && s[0] === '<') {
+ // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
+ if (s.length === 1) {
+ emitError(context, ParserErrorTypes.EOF_BEFORE_TAG_NAME, 1)
+ } else if (s[1] === '!') {
+ // https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
+ if (startsWith(s, '<!--')) {
+ node = parseComment(context)
+ } else if (startsWith(s, '<!DOCTYPE')) {
+ // Ignore DOCTYPE by a limitation.
+ node = parseBogusComment(context)
+ } else if (startsWith(s, '<![CDATA[')) {
+ if (ns !== Namespaces.HTML) {
+ node = parseCDATA(context, ancestors)
+ } else {
+ emitError(context, ParserErrorTypes.CDATA_IN_HTML_CONTENT)
+ node = parseBogusComment(context)
+ }
+ } else {
+ emitError(context, ParserErrorTypes.INCORRECTLY_OPENED_COMMENT)
+ node = parseBogusComment(context)
+ }
+ } else if (s[1] === '/') {
+ // https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
+ if (s.length === 2) {
+ emitError(context, ParserErrorTypes.EOF_BEFORE_TAG_NAME, 2)
+ } else if (s[2] === '>') {
+ emitError(context, ParserErrorTypes.MISSING_END_TAG_NAME, 2)
+ advanceBy(context, 3)
+ continue
+ } else if (/[a-z]/i.test(s[2])) {
+ emitError(context, ParserErrorTypes.X_INVALID_END_TAG)
+ parseTag(context, TagType.End, parent)
+ continue
+ } else {
+ emitError(
+ context,
+ ParserErrorTypes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
+ 2
+ )
+ node = parseBogusComment(context)
+ }
+ } else if (/[a-z]/i.test(s[1])) {
+ node = parseElement(context, ancestors)
+ } else if (s[1] === '?') {
+ emitError(
+ context,
+ ParserErrorTypes.UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME,
+ 1
+ )
+ node = parseBogusComment(context)
+ } else {
+ emitError(
+ context,
+ ParserErrorTypes.INVALID_FIRST_CHARACTER_OF_TAG_NAME,
+ 1
+ )
+ }
+ }
+ if (!node) {
+ node = parseText(context, mode)
+ }
+
+ if (Array.isArray(node)) {
+ node.forEach(pushNode.bind(null, context, nodes))
+ } else {
+ pushNode(context, nodes, node)
+ }
+ }
+
+ return nodes
+}
+
+function isEnd(
+ context: ParserContext,
+ mode: TextModes,
+ ancestors: ElementNode[]
+): boolean {
+ const s = context.source
+
+ switch (mode) {
+ case TextModes.DATA:
+ if (startsWith(s, '</')) {
+ //TODO: probably bad performance
+ for (let i = ancestors.length - 1; i >= 0; --i) {
+ if (startsWithEndTagOpen(s, ancestors[i].tag)) {
+ return true
+ }
+ }
+ }
+ break
+
+ case TextModes.RCDATA:
+ case TextModes.RAWTEXT: {
+ const parent = last(ancestors)
+ if (parent && startsWithEndTagOpen(s, parent.tag)) {
+ return true
+ }
+ break
+ }
+
+ case TextModes.CDATA:
+ if (startsWith(s, ']]>')) {
+ return true
+ }
+ break
+ }
+
+ return !s
+}
+
+function startsWithEndTagOpen(source: string, tag: string): boolean {
+ return (
+ startsWith(source, '</') &&
+ source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&
+ /[\t\n\f />]/.test(source[2 + tag.length] || '>')
+ )
+}
+
+function pushNode(
+ context: ParserContext,
+ nodes: RootNode['children'],
+ node: RootNode['children'][0]
+): void {
+ if (context.ignoreSpaces && node.type === NodeTypes.TEXT && node.isEmpty) {
+ return
+ }
+
+ // Merge if both this and the previous node are text and those are consecutive.
+ // This happens on "a < b" or something like.
+ const prev = last(nodes)
+ if (
+ prev &&
+ prev.type === NodeTypes.TEXT &&
+ node.type === NodeTypes.TEXT &&
+ prev.loc.end.offset === node.loc.start.offset
+ ) {
+ prev.content += node.content
+ prev.isEmpty = prev.content.trim().length === 0
+ prev.loc.end = node.loc.end
+ prev.loc.source += node.loc.source
+ } else {
+ nodes.push(node)
+ }
+}
+
+function parseCDATA(
+ context: ParserContext,
+ ancestors: ElementNode[]
+): RootNode['children'] {
+ assert(last(ancestors) == null || last(ancestors)!.ns !== Namespaces.HTML)
+ assert(startsWith(context.source, '<![CDATA['))
+
+ advanceBy(context, 9)
+ const nodes = parseChildren(context, TextModes.CDATA, ancestors)
+ if (context.source.length === 0) {
+ emitError(context, ParserErrorTypes.EOF_IN_CDATA)
+ } else {
+ assert(startsWith(context.source, ']]>'))
+ advanceBy(context, 3)
+ }
+
+ return nodes
+}
+
+function parseComment(context: ParserContext): CommentNode {
+ assert(startsWith(context.source, '<!--'))
+
+ const start = getCursor(context)
+ let content: string
+
+ // Regular comment.
+ const match = /--(\!)?>/.exec(context.source)
+ if (!match) {
+ content = context.source.slice(4)
+ advanceBy(context, context.source.length)
+ emitError(context, ParserErrorTypes.EOF_IN_COMMENT)
+ } else {
+ if (match.index <= 3) {
+ emitError(context, ParserErrorTypes.ABRUPT_CLOSING_OF_EMPTY_COMMENT)
+ }
+ if (match[1]) {
+ emitError(context, ParserErrorTypes.INCORRECTLY_CLOSED_COMMENT)
+ }
+ content = context.source.slice(4, match.index)
+
+ // Advancing with reporting nested comments.
+ const s = context.source.slice(0, match.index)
+ let prevIndex = 1,
+ nestedIndex = 0
+ while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
+ advanceBy(context, nestedIndex - prevIndex + 1)
+ if (nestedIndex + 4 < s.length) {
+ emitError(context, ParserErrorTypes.NESTED_COMMENT)
+ }
+ prevIndex = nestedIndex + 1
+ }
+ advanceBy(context, match.index + match[0].length - prevIndex + 1)
+ }
+
+ return {
+ type: NodeTypes.COMMENT,
+ content,
+ loc: getSelection(context, start)
+ }
+}
+
+function parseBogusComment(context: ParserContext): CommentNode | undefined {
+ assert(/^<(?:[\!\?]|\/[^a-z>])/i.test(context.source))
+
+ const start = getCursor(context)
+ const contentStart = context.source[1] === '?' ? 1 : 2
+ let content: string
+
+ const closeIndex = context.source.indexOf('>')
+ if (closeIndex === -1) {
+ content = context.source.slice(contentStart)
+ advanceBy(context, context.source.length)
+ } else {
+ content = context.source.slice(contentStart, closeIndex)
+ advanceBy(context, closeIndex + 1)
+ }
+
+ return {
+ type: NodeTypes.COMMENT,
+ content,
+ loc: getSelection(context, start)
+ }
+}
+
+function parseElement(
+ context: ParserContext,
+ ancestors: ElementNode[]
+): ElementNode | undefined {
+ assert(/^<[a-z]/i.test(context.source))
+
+ // Start tag.
+ const parent = last(ancestors)
+ const element = parseTag(context, TagType.Start, parent)
+
+ if (element.isSelfClosing || context.isVoidTag(element.tag)) {
+ return element
+ }
+
+ // Children.
+ ancestors.push(element)
+ const mode = (context.getTextMode(
+ element.tag,
+ element.ns
+ ) as unknown) as TextModes
+ const children = parseChildren(context, mode, ancestors)
+ ancestors.pop()
+
+ element.children = children
+
+ // End tag.
+ if (startsWithEndTagOpen(context.source, element.tag)) {
+ parseTag(context, TagType.End, parent)
+ } else {
+ emitError(context, ParserErrorTypes.X_MISSING_END_TAG)
+ if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
+ const first = children[0]
+ if (first && startsWith(first.loc.source, '<!--')) {
+ emitError(
+ context,
+ ParserErrorTypes.EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT
+ )
+ }
+ }
+ }
+
+ element.loc = getSelection(context, element.loc.start)
+ return element
+}
+
+const enum TagType {
+ Start,
+ End
+}
+
+/**
+ * Parse a tag (E.g. `<div id=a>`) with that type (start tag or end tag).
+ */
+function parseTag(
+ context: ParserContext,
+ type: TagType,
+ parent: ElementNode | undefined
+): ElementNode {
+ assert(/^<\/?[a-z]/i.test(context.source))
+ assert(
+ type === (startsWith(context.source, '</') ? TagType.End : TagType.Start)
+ )
+
+ // Tag open.
+ const start = getCursor(context)
+ const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source)!
+ const tag = match[1]
+ const props = []
+ const ns = context.getNamespace(tag, parent)
+
+ advanceBy(context, match[0].length)
+ advanceSpaces(context)
+
+ // Attributes.
+ const attributeNames = new Set<string>()
+ while (
+ context.source.length > 0 &&
+ !startsWith(context.source, '>') &&
+ !startsWith(context.source, '/>')
+ ) {
+ if (startsWith(context.source, '/')) {
+ emitError(context, ParserErrorTypes.UNEXPECTED_SOLIDUS_IN_TAG)
+ advanceBy(context, 1)
+ advanceSpaces(context)
+ continue
+ }
+ if (type === TagType.End) {
+ emitError(context, ParserErrorTypes.END_TAG_WITH_ATTRIBUTES)
+ }
+
+ const attr = parseAttribute(context, attributeNames)
+ if (type === TagType.Start) {
+ props.push(attr)
+ }
+
+ if (/^[^\t\r\n\f />]/.test(context.source)) {
+ emitError(context, ParserErrorTypes.MISSING_WHITESPACE_BETWEEN_ATTRIBUTES)
+ }
+ advanceSpaces(context)
+ }
+
+ // Tag close.
+ let isSelfClosing = false
+ if (context.source.length === 0) {
+ emitError(context, ParserErrorTypes.EOF_IN_TAG)
+ } else {
+ isSelfClosing = startsWith(context.source, '/>')
+ if (type === TagType.End && isSelfClosing) {
+ emitError(context, ParserErrorTypes.END_TAG_WITH_TRAILING_SOLIDUS)
+ }
+ advanceBy(context, isSelfClosing ? 2 : 1)
+ }
+
+ let tagType = ElementTypes.ELEMENT
+
+ if (tag === 'slot') tagType = ElementTypes.SLOT
+ else if (tag === 'template') tagType = ElementTypes.TEMPLATE
+ else if (/[A-Z-]/.test(tag)) tagType = ElementTypes.COMPONENT
+
+ return {
+ type: NodeTypes.ELEMENT,
+ ns,
+ tag,
+ tagType,
+ props,
+ isSelfClosing,
+ children: [],
+ loc: getSelection(context, start)
+ }
+}
+
+function parseAttribute(
+ context: ParserContext,
+ nameSet: Set<string>
+): AttributeNode | DirectiveNode {
+ assert(/^[^\t\r\n\f />]/.test(context.source))
+
+ // Name.
+ const start = getCursor(context)
+ const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source)!
+ const name = match[0]
+
+ if (nameSet.has(name)) {
+ emitError(context, ParserErrorTypes.DUPLICATE_ATTRIBUTE)
+ }
+ nameSet.add(name)
+
+ if (name[0] === '=') {
+ emitError(
+ context,
+ ParserErrorTypes.UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME
+ )
+ }
+ {
+ const pattern = /["'<]/g
+ let m: RegExpExecArray | null
+ while ((m = pattern.exec(name)) !== null) {
+ emitError(
+ context,
+ ParserErrorTypes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME,
+ m.index
+ )
+ }
+ }
+
+ advanceBy(context, name.length)
+
+ // Value
+ let value: { content: string; loc: SourceLocation } | undefined = undefined
+ if (/^[\t\r\n\f ]*=/.test(context.source)) {
+ advanceSpaces(context)
+ advanceBy(context, 1)
+ advanceSpaces(context)
+ value = parseAttributeValue(context)
+ if (!value) {
+ emitError(context, ParserErrorTypes.MISSING_ATTRIBUTE_VALUE)
+ }
+ }
+ const loc = getSelection(context, start)
+
+ if (/^(v-|:|@|#)/.test(name)) {
+ const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^@|^#)([^\.]+))?(.+)?$/i.exec(
+ name
+ )!
+
+ let arg: ExpressionNode | undefined
+
+ if (match[2]) {
+ const startOffset = name.split(match[2], 2)!.shift()!.length
+ const loc = getSelection(
+ context,
+ getNewPosition(context, start, startOffset),
+ getNewPosition(context, start, startOffset + match[2].length)
+ )
+ let content = match[2]
+ let isStatic = true
+
+ if (content.startsWith('[')) {
+ isStatic = false
+
+ if (!content.endsWith(']')) {
+ emitError(
+ context,
+ ParserErrorTypes.X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END
+ )
+ }
+
+ content = content.substr(1, content.length - 2)
+ }
+
+ arg = {
+ type: NodeTypes.EXPRESSION,
+ content,
+ isStatic,
+ loc
+ }
+ }
+
+ return {
+ type: NodeTypes.DIRECTIVE,
+ name:
+ match[1] ||
+ (startsWith(name, ':')
+ ? 'bind'
+ : startsWith(name, '@')
+ ? 'on'
+ : 'slot'),
+ exp: value && {
+ type: NodeTypes.EXPRESSION,
+ content: value.content,
+ isStatic: false,
+ loc: value.loc
+ },
+ arg,
+ modifiers: match[3] ? match[3].substr(1).split('.') : [],
+ loc
+ }
+ }
+
+ return {
+ type: NodeTypes.ATTRIBUTE,
+ name,
+ value: value && {
+ type: NodeTypes.TEXT,
+ content: value.content,
+ isEmpty: value.content.trim().length === 0,
+ loc: value.loc
+ },
+ loc
+ }
+}
+
+function parseAttributeValue(
+ context: ParserContext
+): { content: string; loc: SourceLocation } | undefined {
+ const start = getCursor(context)
+ let content: string
+
+ if (/^["']/.test(context.source)) {
+ // Quoted value.
+ const quote = context.source[0]
+ advanceBy(context, 1)
+
+ const endIndex = context.source.indexOf(quote)
+ if (endIndex === -1) {
+ content = parseTextData(
+ context,
+ context.source.length,
+ TextModes.ATTRIBUTE_VALUE
+ )
+ } else {
+ content = parseTextData(context, endIndex, TextModes.ATTRIBUTE_VALUE)
+ advanceBy(context, 1)
+ }
+ } else {
+ // Unquoted
+ const match = /^[^\t\r\n\f >]+/.exec(context.source)
+ if (!match) {
+ return undefined
+ }
+ let unexpectedChars = /["'<=`]/g
+ let m: RegExpExecArray | null
+ while ((m = unexpectedChars.exec(match[0])) !== null) {
+ emitError(
+ context,
+ ParserErrorTypes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE,
+ m.index
+ )
+ }
+ content = parseTextData(context, match[0].length, TextModes.ATTRIBUTE_VALUE)
+ }
+
+ return { content, loc: getSelection(context, start) }
+}
+
+function parseInterpolation(
+ context: ParserContext,
+ mode: TextModes
+): ExpressionNode | undefined {
+ const [open, close] = context.delimiters
+ assert(startsWith(context.source, open))
+
+ const closeIndex = context.source.indexOf(close, open.length)
+ if (closeIndex === -1) {
+ emitError(context, ParserErrorTypes.X_MISSING_INTERPOLATION_END)
+ return undefined
+ }
+
+ const start = getCursor(context)
+ advanceBy(context, open.length)
+ const content = parseTextData(context, closeIndex - open.length, mode).trim()
+ advanceBy(context, close.length)
+
+ return {
+ type: NodeTypes.EXPRESSION,
+ content,
+ loc: getSelection(context, start),
+ isStatic: content === ''
+ }
+}
+
+function parseText(context: ParserContext, mode: TextModes): TextNode {
+ assert(context.source.length > 0)
+
+ const [open] = context.delimiters
+ const endIndex = Math.min(
+ ...[
+ context.source.indexOf('<', 1),
+ context.source.indexOf(open, 1),
+ mode === TextModes.CDATA ? context.source.indexOf(']]>') : -1,
+ context.source.length
+ ].filter(n => n !== -1)
+ )
+ assert(endIndex > 0)
+
+ const start = getCursor(context)
+ const content = parseTextData(context, endIndex, mode)
+
+ return {
+ type: NodeTypes.TEXT,
+ content,
+ loc: getSelection(context, start),
+ isEmpty: !content.trim()
+ }
+}
+
+/**
+ * Get text data with a given length from the current location.
+ * This translates HTML entities in the text data.
+ */
+function parseTextData(
+ context: ParserContext,
+ length: number,
+ mode: TextModes
+): string {
+ if (mode === TextModes.RAWTEXT || mode === TextModes.CDATA) {
+ const text = context.source.slice(0, length)
+ advanceBy(context, length)
+ return text
+ }
+
+ // DATA or RCDATA.
+ const end = context.offset + length
+ let text: string = ''
+
+ while (context.offset < end) {
+ const head = /&(?:#x?)?/i.exec(context.source)
+ if (!head || context.offset + head.index >= end) {
+ const remaining = end - context.offset
+ text += context.source.slice(0, remaining)
+ advanceBy(context, remaining)
+ break
+ }
+
+ // Advance to the "&".
+ text += context.source.slice(0, head.index)
+ advanceBy(context, head.index)
+
+ if (head[0] === '&') {
+ // Named character reference.
+ let name = '',
+ value: string | undefined = undefined
+ if (/[0-9a-z]/i.test(context.source[1])) {
+ for (
+ let length = context.maxCRNameLength;
+ !value && length > 0;
+ --length
+ ) {
+ name = context.source.substr(1, length)
+ value = context.namedCharacterReferences[name]
+ }
+ if (value) {
+ const semi = name.endsWith(';')
+ if (
+ mode === TextModes.ATTRIBUTE_VALUE &&
+ !semi &&
+ /[=a-z0-9]/i.test(context.source[1 + name.length] || '')
+ ) {
+ text += '&'
+ text += name
+ advanceBy(context, 1 + name.length)
+ } else {
+ text += value
+ advanceBy(context, 1 + name.length)
+ if (!semi) {
+ emitError(
+ context,
+ ParserErrorTypes.MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE
+ )
+ }
+ }
+ } else {
+ emitError(context, ParserErrorTypes.UNKNOWN_NAMED_CHARACTER_REFERENCE)
+ text += '&'
+ text += name
+ advanceBy(context, 1 + name.length)
+ }
+ } else {
+ text += '&'
+ advanceBy(context, 1)
+ }
+ } else {
+ // Numeric character reference.
+ const hex = head[0] === '&#x'
+ const pattern = hex ? /^&#x([0-9a-f]+);?/i : /^&#([0-9]+);?/
+ const body = pattern.exec(context.source)
+ if (!body) {
+ text += head[0]
+ emitError(
+ context,
+ ParserErrorTypes.ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE
+ )
+ advanceBy(context, head[0].length)
+ } else {
+ // https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state
+ let cp = Number.parseInt(body[1], hex ? 16 : 10)
+ if (cp === 0) {
+ emitError(context, ParserErrorTypes.NULL_CHARACTER_REFERENCE)
+ cp = 0xfffd
+ } else if (cp > 0x10ffff) {
+ emitError(
+ context,
+ ParserErrorTypes.CHARACTER_REFERENCE_OUTSIDE_UNICODE_RANGE
+ )
+ cp = 0xfffd
+ } else if (cp >= 0xd800 && cp <= 0xdfff) {
+ emitError(context, ParserErrorTypes.SURROGATE_CHARACTER_REFERENCE)
+ cp = 0xfffd
+ } else if ((cp >= 0xfdd0 && cp <= 0xfdef) || (cp & 0xfffe) === 0xfffe) {
+ emitError(context, ParserErrorTypes.NONCHARACTER_CHARACTER_REFERENCE)
+ } else if (
+ (cp >= 0x01 && cp <= 0x08) ||
+ cp === 0x0b ||
+ (cp >= 0x0d && cp <= 0x1f) ||
+ (cp >= 0x7f && cp <= 0x9f)
+ ) {
+ emitError(context, ParserErrorTypes.CONTROL_CHARACTER_REFERENCE)
+ cp = CCR_REPLACEMENTS[cp] || cp
+ }
+ text += String.fromCodePoint(cp)
+ advanceBy(context, body[0].length)
+ if (!body![0].endsWith(';')) {
+ emitError(
+ context,
+ ParserErrorTypes.MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE
+ )
+ }
+ }
+ }
+ }
+
+ return text
+}
+
+// https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state
+const CCR_REPLACEMENTS: { [key: number]: number | undefined } = {
+ 0x80: 0x20ac,
+ 0x82: 0x201a,
+ 0x83: 0x0192,
+ 0x84: 0x201e,
+ 0x85: 0x2026,
+ 0x86: 0x2020,
+ 0x87: 0x2021,
+ 0x88: 0x02c6,
+ 0x89: 0x2030,
+ 0x8a: 0x0160,
+ 0x8b: 0x2039,
+ 0x8c: 0x0152,
+ 0x8e: 0x017d,
+ 0x91: 0x2018,
+ 0x92: 0x2019,
+ 0x93: 0x201c,
+ 0x94: 0x201d,
+ 0x95: 0x2022,
+ 0x96: 0x2013,
+ 0x97: 0x2014,
+ 0x98: 0x02dc,
+ 0x99: 0x2122,
+ 0x9a: 0x0161,
+ 0x9b: 0x203a,
+ 0x9c: 0x0153,
+ 0x9e: 0x017e,
+ 0x9f: 0x0178
+}
--- /dev/null
+import { TextModes, ParserOptions } from './parser'
+import { ElementNode, Namespaces, Position, Node } from './ast'
+import { ParserErrorTypes } from './errorTypes'
+
+export const parserOptionsMinimal: ParserOptions = {
+ delimiters: [`{{`, `}}`],
+ ignoreSpaces: true,
+
+ getNamespace(tag: string, parent: ElementNode | undefined): Namespaces {
+ const ns = parent ? parent.ns : Namespaces.HTML
+ if (ns === Namespaces.HTML) {
+ if (tag === 'svg') {
+ return Namespaces.SVG
+ }
+ if (tag === 'math') {
+ return Namespaces.MATH_ML
+ }
+ }
+ return ns
+ },
+
+ getTextMode(tag: string, ns: Namespaces): TextModes {
+ if (ns === Namespaces.HTML) {
+ if (/^textarea$/i.test(tag)) {
+ return TextModes.RCDATA
+ }
+ if (/^(?:style|script)$/i.test(tag)) {
+ return TextModes.RAWTEXT
+ }
+ }
+ return TextModes.DATA
+ },
+
+ isVoidTag(tag: string): boolean {
+ return /^(?:area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/i.test(
+ tag
+ )
+ },
+
+ namedCharacterReferences: {
+ 'gt;': '>',
+ 'lt;': '<',
+ 'amp;': '&',
+ 'apos;': "'",
+ 'quot;': '"'
+ },
+
+ onError(code: ParserErrorTypes, loc: Position): void {
+ const error: any = new SyntaxError(
+ `${messages[code]} (${loc.line}:${loc.column})`
+ )
+ error.code = code
+ error.loc = loc
+ throw error
+ },
+
+ transform(node: Node): Node {
+ return node
+ }
+}
+
+const messages: { [code: number]: string } = {
+ [ParserErrorTypes.ABRUPT_CLOSING_OF_EMPTY_COMMENT]: 'Illegal comment.',
+ [ParserErrorTypes.ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE]:
+ 'Illegal numeric character reference: invalid character.',
+ [ParserErrorTypes.CDATA_IN_HTML_CONTENT]:
+ 'CDATA section is allowed only in XML context.',
+ [ParserErrorTypes.CHARACTER_REFERENCE_OUTSIDE_UNICODE_RANGE]:
+ 'Illegal numeric character reference: too big.',
+ [ParserErrorTypes.CONTROL_CHARACTER_REFERENCE]:
+ 'Illegal numeric character reference: control character.',
+ [ParserErrorTypes.DUPLICATE_ATTRIBUTE]: 'Duplicate attribute.',
+ [ParserErrorTypes.END_TAG_WITH_ATTRIBUTES]: 'End tag cannot have attributes.',
+ [ParserErrorTypes.END_TAG_WITH_TRAILING_SOLIDUS]: "Illegal '/' in tags.",
+ [ParserErrorTypes.EOF_BEFORE_TAG_NAME]: 'Unexpected EOF in tag.',
+ [ParserErrorTypes.EOF_IN_CDATA]: 'Unexpected EOF in CDATA section.',
+ [ParserErrorTypes.EOF_IN_COMMENT]: 'Unexpected EOF in comment.',
+ [ParserErrorTypes.EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT]:
+ 'Unexpected EOF in script.',
+ [ParserErrorTypes.EOF_IN_TAG]: 'Unexpected EOF in tag.',
+ [ParserErrorTypes.INCORRECTLY_CLOSED_COMMENT]: 'Incorrectly closed comment.',
+ [ParserErrorTypes.INCORRECTLY_OPENED_COMMENT]: 'Incorrectly opened comment.',
+ [ParserErrorTypes.INVALID_FIRST_CHARACTER_OF_TAG_NAME]:
+ "Illegal tag name. Use '<' to print '<'.",
+ [ParserErrorTypes.MISSING_ATTRIBUTE_VALUE]: 'Attribute value was expected.',
+ [ParserErrorTypes.MISSING_END_TAG_NAME]: 'End tag name was expected.',
+ [ParserErrorTypes.MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE]:
+ 'Semicolon was expected.',
+ [ParserErrorTypes.MISSING_WHITESPACE_BETWEEN_ATTRIBUTES]:
+ 'Whitespace was expected.',
+ [ParserErrorTypes.NESTED_COMMENT]: "Unexpected '<!--' in comment.",
+ [ParserErrorTypes.NONCHARACTER_CHARACTER_REFERENCE]:
+ 'Illegal numeric character reference: non character.',
+ [ParserErrorTypes.NULL_CHARACTER_REFERENCE]:
+ 'Illegal numeric character reference: null character.',
+ [ParserErrorTypes.SURROGATE_CHARACTER_REFERENCE]:
+ 'Illegal numeric character reference: non-pair surrogate.',
+ [ParserErrorTypes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME]:
+ 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
+ [ParserErrorTypes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE]:
+ 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
+ [ParserErrorTypes.UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME]:
+ "Attribute name cannot start with '='.",
+ [ParserErrorTypes.UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME]:
+ "'<?' is allowed only in XML context.",
+ [ParserErrorTypes.UNEXPECTED_SOLIDUS_IN_TAG]: "Illegal '/' in tags.",
+ [ParserErrorTypes.UNKNOWN_NAMED_CHARACTER_REFERENCE]: 'Unknown entity name.',
+ [ParserErrorTypes.X_INVALID_END_TAG]: 'Invalid end tag.',
+ [ParserErrorTypes.X_MISSING_END_TAG]: 'End tag was not found.',
+ [ParserErrorTypes.X_MISSING_INTERPOLATION_END]:
+ 'Interpolation end sign was not found.'
+}
--- /dev/null
+import { TextModes, ParserOptions } from './parser'
+import { ElementNode, Namespaces, NodeTypes } from './ast'
+import { parserOptionsMinimal } from './parserOptionsMinimal'
+
+export const parserOptionsStandard: ParserOptions = {
+ // extends the minimal options with more spec-compliant overrides
+ ...parserOptionsMinimal,
+
+ // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
+ getNamespace(tag: string, parent: ElementNode | undefined): Namespaces {
+ let ns = parent ? parent.ns : Namespaces.HTML
+
+ if (parent && ns === Namespaces.MATH_ML) {
+ if (parent.tag === 'annotation-xml') {
+ if (tag === 'svg') {
+ return Namespaces.SVG
+ }
+ if (
+ parent.props.some(
+ a =>
+ a.type === NodeTypes.ATTRIBUTE &&
+ a.name === 'encoding' &&
+ a.value != null &&
+ (a.value.content === 'text/html' ||
+ a.value.content === 'application/xhtml+xml')
+ )
+ ) {
+ ns = Namespaces.HTML
+ }
+ } else if (
+ /^m(?:[ions]|text)$/.test(parent.tag) &&
+ tag !== 'mglyph' &&
+ tag !== 'malignmark'
+ ) {
+ ns = Namespaces.HTML
+ }
+ } else if (parent && ns === Namespaces.SVG) {
+ if (
+ parent.tag === 'foreignObject' ||
+ parent.tag === 'desc' ||
+ parent.tag === 'title'
+ ) {
+ ns = Namespaces.HTML
+ }
+ }
+
+ if (ns === Namespaces.HTML) {
+ if (tag === 'svg') {
+ return Namespaces.SVG
+ }
+ if (tag === 'math') {
+ return Namespaces.MATH_ML
+ }
+ }
+ return ns
+ },
+
+ // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
+ getTextMode(tag: string, ns: Namespaces): TextModes {
+ if (ns === Namespaces.HTML) {
+ if (/^(?:title|textarea)$/i.test(tag)) {
+ return TextModes.RCDATA
+ }
+ if (
+ /^(?:style|xmp|iframe|noembed|noframes|script|noscript)$/i.test(tag)
+ ) {
+ return TextModes.RAWTEXT
+ }
+ }
+ return TextModes.DATA
+ },
+
+ // https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references
+ namedCharacterReferences: {
+ GT: '>',
+ gt: '>',
+ LT: '<',
+ lt: '<',
+ 'ac;': '∾',
+ 'af;': '',
+ AMP: '&',
+ amp: '&',
+ 'ap;': '≈',
+ 'DD;': 'ⅅ',
+ 'dd;': 'ⅆ',
+ deg: '°',
+ 'ee;': 'ⅇ',
+ 'eg;': '⪚',
+ 'el;': '⪙',
+ ETH: 'Ð',
+ eth: 'ð',
+ 'gE;': '≧',
+ 'ge;': '≥',
+ 'Gg;': '⋙',
+ 'gg;': '≫',
+ 'gl;': '≷',
+ 'GT;': '>',
+ 'Gt;': '≫',
+ 'gt;': '>',
+ 'ic;': '',
+ 'ii;': 'ⅈ',
+ 'Im;': 'ℑ',
+ 'in;': '∈',
+ 'it;': '',
+ 'lE;': '≦',
+ 'le;': '≤',
+ 'lg;': '≶',
+ 'Ll;': '⋘',
+ 'll;': '≪',
+ 'LT;': '<',
+ 'Lt;': '≪',
+ 'lt;': '<',
+ 'mp;': '∓',
+ 'Mu;': 'Μ',
+ 'mu;': 'μ',
+ 'ne;': '≠',
+ 'ni;': '∋',
+ not: '¬',
+ 'Nu;': 'Ν',
+ 'nu;': 'ν',
+ 'Or;': '⩔',
+ 'or;': '∨',
+ 'oS;': 'Ⓢ',
+ 'Pi;': 'Π',
+ 'pi;': 'π',
+ 'pm;': '±',
+ 'Pr;': '⪻',
+ 'pr;': '≺',
+ 'Re;': 'ℜ',
+ REG: '®',
+ reg: '®',
+ 'rx;': '℞',
+ 'Sc;': '⪼',
+ 'sc;': '≻',
+ shy: '',
+ uml: '¨',
+ 'wp;': '℘',
+ 'wr;': '≀',
+ 'Xi;': 'Ξ',
+ 'xi;': 'ξ',
+ yen: '¥',
+ 'acd;': '∿',
+ 'acE;': '∾̳',
+ 'Acy;': 'А',
+ 'acy;': 'а',
+ 'Afr;': '𝔄',
+ 'afr;': '𝔞',
+ 'AMP;': '&',
+ 'amp;': '&',
+ 'And;': '⩓',
+ 'and;': '∧',
+ 'ang;': '∠',
+ 'apE;': '⩰',
+ 'ape;': '≊',
+ 'ast;': '*',
+ Auml: 'Ä',
+ auml: 'ä',
+ 'Bcy;': 'Б',
+ 'bcy;': 'б',
+ 'Bfr;': '𝔅',
+ 'bfr;': '𝔟',
+ 'bne;': '=⃥',
+ 'bot;': '⊥',
+ 'Cap;': '⋒',
+ 'cap;': '∩',
+ cent: '¢',
+ 'Cfr;': 'ℭ',
+ 'cfr;': '𝔠',
+ 'Chi;': 'Χ',
+ 'chi;': 'χ',
+ 'cir;': '○',
+ COPY: '©',
+ copy: '©',
+ 'Cup;': '⋓',
+ 'cup;': '∪',
+ 'Dcy;': 'Д',
+ 'dcy;': 'д',
+ 'deg;': '°',
+ 'Del;': '∇',
+ 'Dfr;': '𝔇',
+ 'dfr;': '𝔡',
+ 'die;': '¨',
+ 'div;': '÷',
+ 'Dot;': '¨',
+ 'dot;': '˙',
+ 'Ecy;': 'Э',
+ 'ecy;': 'э',
+ 'Efr;': '𝔈',
+ 'efr;': '𝔢',
+ 'egs;': '⪖',
+ 'ell;': 'ℓ',
+ 'els;': '⪕',
+ 'ENG;': 'Ŋ',
+ 'eng;': 'ŋ',
+ 'Eta;': 'Η',
+ 'eta;': 'η',
+ 'ETH;': 'Ð',
+ 'eth;': 'ð',
+ Euml: 'Ë',
+ euml: 'ë',
+ 'Fcy;': 'Ф',
+ 'fcy;': 'ф',
+ 'Ffr;': '𝔉',
+ 'ffr;': '𝔣',
+ 'gap;': '⪆',
+ 'Gcy;': 'Г',
+ 'gcy;': 'г',
+ 'gEl;': '⪌',
+ 'gel;': '⋛',
+ 'geq;': '≥',
+ 'ges;': '⩾',
+ 'Gfr;': '𝔊',
+ 'gfr;': '𝔤',
+ 'ggg;': '⋙',
+ 'gla;': '⪥',
+ 'glE;': '⪒',
+ 'glj;': '⪤',
+ 'gnE;': '≩',
+ 'gne;': '⪈',
+ 'Hat;': '^',
+ 'Hfr;': 'ℌ',
+ 'hfr;': '𝔥',
+ 'Icy;': 'И',
+ 'icy;': 'и',
+ 'iff;': '⇔',
+ 'Ifr;': 'ℑ',
+ 'ifr;': '𝔦',
+ 'Int;': '∬',
+ 'int;': '∫',
+ Iuml: 'Ï',
+ iuml: 'ï',
+ 'Jcy;': 'Й',
+ 'jcy;': 'й',
+ 'Jfr;': '𝔍',
+ 'jfr;': '𝔧',
+ 'Kcy;': 'К',
+ 'kcy;': 'к',
+ 'Kfr;': '𝔎',
+ 'kfr;': '𝔨',
+ 'lap;': '⪅',
+ 'lat;': '⪫',
+ 'Lcy;': 'Л',
+ 'lcy;': 'л',
+ 'lEg;': '⪋',
+ 'leg;': '⋚',
+ 'leq;': '≤',
+ 'les;': '⩽',
+ 'Lfr;': '𝔏',
+ 'lfr;': '𝔩',
+ 'lgE;': '⪑',
+ 'lnE;': '≨',
+ 'lne;': '⪇',
+ 'loz;': '◊',
+ 'lrm;': '',
+ 'Lsh;': '↰',
+ 'lsh;': '↰',
+ macr: '¯',
+ 'Map;': '⤅',
+ 'map;': '↦',
+ 'Mcy;': 'М',
+ 'mcy;': 'м',
+ 'Mfr;': '𝔐',
+ 'mfr;': '𝔪',
+ 'mho;': '℧',
+ 'mid;': '∣',
+ 'nap;': '≉',
+ nbsp: ' ',
+ 'Ncy;': 'Н',
+ 'ncy;': 'н',
+ 'Nfr;': '𝔑',
+ 'nfr;': '𝔫',
+ 'ngE;': '≧̸',
+ 'nge;': '≱',
+ 'nGg;': '⋙̸',
+ 'nGt;': '≫⃒',
+ 'ngt;': '≯',
+ 'nis;': '⋼',
+ 'niv;': '∋',
+ 'nlE;': '≦̸',
+ 'nle;': '≰',
+ 'nLl;': '⋘̸',
+ 'nLt;': '≪⃒',
+ 'nlt;': '≮',
+ 'Not;': '⫬',
+ 'not;': '¬',
+ 'npr;': '⊀',
+ 'nsc;': '⊁',
+ 'num;': '#',
+ 'Ocy;': 'О',
+ 'ocy;': 'о',
+ 'Ofr;': '𝔒',
+ 'ofr;': '𝔬',
+ 'ogt;': '⧁',
+ 'ohm;': 'Ω',
+ 'olt;': '⧀',
+ 'ord;': '⩝',
+ ordf: 'ª',
+ ordm: 'º',
+ 'orv;': '⩛',
+ Ouml: 'Ö',
+ ouml: 'ö',
+ 'par;': '∥',
+ para: '¶',
+ 'Pcy;': 'П',
+ 'pcy;': 'п',
+ 'Pfr;': '𝔓',
+ 'pfr;': '𝔭',
+ 'Phi;': 'Φ',
+ 'phi;': 'φ',
+ 'piv;': 'ϖ',
+ 'prE;': '⪳',
+ 'pre;': '⪯',
+ 'Psi;': 'Ψ',
+ 'psi;': 'ψ',
+ 'Qfr;': '𝔔',
+ 'qfr;': '𝔮',
+ QUOT: '"',
+ quot: '"',
+ 'Rcy;': 'Р',
+ 'rcy;': 'р',
+ 'REG;': '®',
+ 'reg;': '®',
+ 'Rfr;': 'ℜ',
+ 'rfr;': '𝔯',
+ 'Rho;': 'Ρ',
+ 'rho;': 'ρ',
+ 'rlm;': '',
+ 'Rsh;': '↱',
+ 'rsh;': '↱',
+ 'scE;': '⪴',
+ 'sce;': '⪰',
+ 'Scy;': 'С',
+ 'scy;': 'с',
+ sect: '§',
+ 'Sfr;': '𝔖',
+ 'sfr;': '𝔰',
+ 'shy;': '',
+ 'sim;': '∼',
+ 'smt;': '⪪',
+ 'sol;': '/',
+ 'squ;': '□',
+ 'Sub;': '⋐',
+ 'sub;': '⊂',
+ 'Sum;': '∑',
+ 'sum;': '∑',
+ 'Sup;': '⋑',
+ 'sup;': '⊃',
+ sup1: '¹',
+ sup2: '²',
+ sup3: '³',
+ 'Tab;': '\t',
+ 'Tau;': 'Τ',
+ 'tau;': 'τ',
+ 'Tcy;': 'Т',
+ 'tcy;': 'т',
+ 'Tfr;': '𝔗',
+ 'tfr;': '𝔱',
+ 'top;': '⊤',
+ 'Ucy;': 'У',
+ 'ucy;': 'у',
+ 'Ufr;': '𝔘',
+ 'ufr;': '𝔲',
+ 'uml;': '¨',
+ Uuml: 'Ü',
+ uuml: 'ü',
+ 'Vcy;': 'В',
+ 'vcy;': 'в',
+ 'Vee;': '⋁',
+ 'vee;': '∨',
+ 'Vfr;': '𝔙',
+ 'vfr;': '𝔳',
+ 'Wfr;': '𝔚',
+ 'wfr;': '𝔴',
+ 'Xfr;': '𝔛',
+ 'xfr;': '𝔵',
+ 'Ycy;': 'Ы',
+ 'ycy;': 'ы',
+ 'yen;': '¥',
+ 'Yfr;': '𝔜',
+ 'yfr;': '𝔶',
+ yuml: 'ÿ',
+ 'Zcy;': 'З',
+ 'zcy;': 'з',
+ 'Zfr;': 'ℨ',
+ 'zfr;': '𝔷',
+ 'zwj;': '',
+ Acirc: 'Â',
+ acirc: 'â',
+ acute: '´',
+ AElig: 'Æ',
+ aelig: 'æ',
+ 'andd;': '⩜',
+ 'andv;': '⩚',
+ 'ange;': '⦤',
+ 'Aopf;': '𝔸',
+ 'aopf;': '𝕒',
+ 'apid;': '≋',
+ 'apos;': "'",
+ Aring: 'Å',
+ aring: 'å',
+ 'Ascr;': '𝒜',
+ 'ascr;': '𝒶',
+ 'Auml;': 'Ä',
+ 'auml;': 'ä',
+ 'Barv;': '⫧',
+ 'bbrk;': '⎵',
+ 'Beta;': 'Β',
+ 'beta;': 'β',
+ 'beth;': 'ℶ',
+ 'bNot;': '⫭',
+ 'bnot;': '⌐',
+ 'Bopf;': '𝔹',
+ 'bopf;': '𝕓',
+ 'boxH;': '═',
+ 'boxh;': '─',
+ 'boxV;': '║',
+ 'boxv;': '│',
+ 'Bscr;': 'ℬ',
+ 'bscr;': '𝒷',
+ 'bsim;': '∽',
+ 'bsol;': '\\',
+ 'bull;': '•',
+ 'bump;': '≎',
+ 'caps;': '∩︀',
+ 'Cdot;': 'Ċ',
+ 'cdot;': 'ċ',
+ cedil: '¸',
+ 'cent;': '¢',
+ 'CHcy;': 'Ч',
+ 'chcy;': 'ч',
+ 'circ;': 'ˆ',
+ 'cirE;': '⧃',
+ 'cire;': '≗',
+ 'comp;': '∁',
+ 'cong;': '≅',
+ 'Copf;': 'ℂ',
+ 'copf;': '𝕔',
+ 'COPY;': '©',
+ 'copy;': '©',
+ 'Cscr;': '𝒞',
+ 'cscr;': '𝒸',
+ 'csub;': '⫏',
+ 'csup;': '⫐',
+ 'cups;': '∪︀',
+ 'Darr;': '↡',
+ 'dArr;': '⇓',
+ 'darr;': '↓',
+ 'dash;': '‐',
+ 'dHar;': '⥥',
+ 'diam;': '⋄',
+ 'DJcy;': 'Ђ',
+ 'djcy;': 'ђ',
+ 'Dopf;': '𝔻',
+ 'dopf;': '𝕕',
+ 'Dscr;': '𝒟',
+ 'dscr;': '𝒹',
+ 'DScy;': 'Ѕ',
+ 'dscy;': 'ѕ',
+ 'dsol;': '⧶',
+ 'dtri;': '▿',
+ 'DZcy;': 'Џ',
+ 'dzcy;': 'џ',
+ 'ecir;': '≖',
+ Ecirc: 'Ê',
+ ecirc: 'ê',
+ 'Edot;': 'Ė',
+ 'eDot;': '≑',
+ 'edot;': 'ė',
+ 'emsp;': ' ',
+ 'ensp;': ' ',
+ 'Eopf;': '𝔼',
+ 'eopf;': '𝕖',
+ 'epar;': '⋕',
+ 'epsi;': 'ε',
+ 'Escr;': 'ℰ',
+ 'escr;': 'ℯ',
+ 'Esim;': '⩳',
+ 'esim;': '≂',
+ 'Euml;': 'Ë',
+ 'euml;': 'ë',
+ 'euro;': '€',
+ 'excl;': '!',
+ 'flat;': '♭',
+ 'fnof;': 'ƒ',
+ 'Fopf;': '𝔽',
+ 'fopf;': '𝕗',
+ 'fork;': '⋔',
+ 'Fscr;': 'ℱ',
+ 'fscr;': '𝒻',
+ 'Gdot;': 'Ġ',
+ 'gdot;': 'ġ',
+ 'geqq;': '≧',
+ 'gesl;': '⋛︀',
+ 'GJcy;': 'Ѓ',
+ 'gjcy;': 'ѓ',
+ 'gnap;': '⪊',
+ 'gneq;': '⪈',
+ 'Gopf;': '𝔾',
+ 'gopf;': '𝕘',
+ 'Gscr;': '𝒢',
+ 'gscr;': 'ℊ',
+ 'gsim;': '≳',
+ 'gtcc;': '⪧',
+ 'gvnE;': '≩︀',
+ 'half;': '½',
+ 'hArr;': '⇔',
+ 'harr;': '↔',
+ 'hbar;': 'ℏ',
+ 'Hopf;': 'ℍ',
+ 'hopf;': '𝕙',
+ 'Hscr;': 'ℋ',
+ 'hscr;': '𝒽',
+ Icirc: 'Î',
+ icirc: 'î',
+ 'Idot;': 'İ',
+ 'IEcy;': 'Е',
+ 'iecy;': 'е',
+ iexcl: '¡',
+ 'imof;': '⊷',
+ 'IOcy;': 'Ё',
+ 'iocy;': 'ё',
+ 'Iopf;': '𝕀',
+ 'iopf;': '𝕚',
+ 'Iota;': 'Ι',
+ 'iota;': 'ι',
+ 'Iscr;': 'ℐ',
+ 'iscr;': '𝒾',
+ 'isin;': '∈',
+ 'Iuml;': 'Ï',
+ 'iuml;': 'ï',
+ 'Jopf;': '𝕁',
+ 'jopf;': '𝕛',
+ 'Jscr;': '𝒥',
+ 'jscr;': '𝒿',
+ 'KHcy;': 'Х',
+ 'khcy;': 'х',
+ 'KJcy;': 'Ќ',
+ 'kjcy;': 'ќ',
+ 'Kopf;': '𝕂',
+ 'kopf;': '𝕜',
+ 'Kscr;': '𝒦',
+ 'kscr;': '𝓀',
+ 'Lang;': '⟪',
+ 'lang;': '⟨',
+ laquo: '«',
+ 'Larr;': '↞',
+ 'lArr;': '⇐',
+ 'larr;': '←',
+ 'late;': '⪭',
+ 'lcub;': '{',
+ 'ldca;': '⤶',
+ 'ldsh;': '↲',
+ 'leqq;': '≦',
+ 'lesg;': '⋚︀',
+ 'lHar;': '⥢',
+ 'LJcy;': 'Љ',
+ 'ljcy;': 'љ',
+ 'lnap;': '⪉',
+ 'lneq;': '⪇',
+ 'Lopf;': '𝕃',
+ 'lopf;': '𝕝',
+ 'lozf;': '⧫',
+ 'lpar;': '(',
+ 'Lscr;': 'ℒ',
+ 'lscr;': '𝓁',
+ 'lsim;': '≲',
+ 'lsqb;': '[',
+ 'ltcc;': '⪦',
+ 'ltri;': '◃',
+ 'lvnE;': '≨︀',
+ 'macr;': '¯',
+ 'male;': '♂',
+ 'malt;': '✠',
+ micro: 'µ',
+ 'mlcp;': '⫛',
+ 'mldr;': '…',
+ 'Mopf;': '𝕄',
+ 'mopf;': '𝕞',
+ 'Mscr;': 'ℳ',
+ 'mscr;': '𝓂',
+ 'nang;': '∠⃒',
+ 'napE;': '⩰̸',
+ 'nbsp;': ' ',
+ 'ncap;': '⩃',
+ 'ncup;': '⩂',
+ 'ngeq;': '≱',
+ 'nges;': '⩾̸',
+ 'ngtr;': '≯',
+ 'nGtv;': '≫̸',
+ 'nisd;': '⋺',
+ 'NJcy;': 'Њ',
+ 'njcy;': 'њ',
+ 'nldr;': '‥',
+ 'nleq;': '≰',
+ 'nles;': '⩽̸',
+ 'nLtv;': '≪̸',
+ 'nmid;': '∤',
+ 'Nopf;': 'ℕ',
+ 'nopf;': '𝕟',
+ 'npar;': '∦',
+ 'npre;': '⪯̸',
+ 'nsce;': '⪰̸',
+ 'Nscr;': '𝒩',
+ 'nscr;': '𝓃',
+ 'nsim;': '≁',
+ 'nsub;': '⊄',
+ 'nsup;': '⊅',
+ 'ntgl;': '≹',
+ 'ntlg;': '≸',
+ 'nvap;': '≍⃒',
+ 'nvge;': '≥⃒',
+ 'nvgt;': '>⃒',
+ 'nvle;': '≤⃒',
+ 'nvlt;': '<⃒',
+ 'oast;': '⊛',
+ 'ocir;': '⊚',
+ Ocirc: 'Ô',
+ ocirc: 'ô',
+ 'odiv;': '⨸',
+ 'odot;': '⊙',
+ 'ogon;': '˛',
+ 'oint;': '∮',
+ 'omid;': '⦶',
+ 'Oopf;': '𝕆',
+ 'oopf;': '𝕠',
+ 'opar;': '⦷',
+ 'ordf;': 'ª',
+ 'ordm;': 'º',
+ 'oror;': '⩖',
+ 'Oscr;': '𝒪',
+ 'oscr;': 'ℴ',
+ 'osol;': '⊘',
+ 'Ouml;': 'Ö',
+ 'ouml;': 'ö',
+ 'para;': '¶',
+ 'part;': '∂',
+ 'perp;': '⊥',
+ 'phiv;': 'ϕ',
+ 'plus;': '+',
+ 'Popf;': 'ℙ',
+ 'popf;': '𝕡',
+ pound: '£',
+ 'prap;': '⪷',
+ 'prec;': '≺',
+ 'prnE;': '⪵',
+ 'prod;': '∏',
+ 'prop;': '∝',
+ 'Pscr;': '𝒫',
+ 'pscr;': '𝓅',
+ 'qint;': '⨌',
+ 'Qopf;': 'ℚ',
+ 'qopf;': '𝕢',
+ 'Qscr;': '𝒬',
+ 'qscr;': '𝓆',
+ 'QUOT;': '"',
+ 'quot;': '"',
+ 'race;': '∽̱',
+ 'Rang;': '⟫',
+ 'rang;': '⟩',
+ raquo: '»',
+ 'Rarr;': '↠',
+ 'rArr;': '⇒',
+ 'rarr;': '→',
+ 'rcub;': '}',
+ 'rdca;': '⤷',
+ 'rdsh;': '↳',
+ 'real;': 'ℜ',
+ 'rect;': '▭',
+ 'rHar;': '⥤',
+ 'rhov;': 'ϱ',
+ 'ring;': '˚',
+ 'Ropf;': 'ℝ',
+ 'ropf;': '𝕣',
+ 'rpar;': ')',
+ 'Rscr;': 'ℛ',
+ 'rscr;': '𝓇',
+ 'rsqb;': ']',
+ 'rtri;': '▹',
+ 'scap;': '⪸',
+ 'scnE;': '⪶',
+ 'sdot;': '⋅',
+ 'sect;': '§',
+ 'semi;': ';',
+ 'sext;': '✶',
+ 'SHcy;': 'Ш',
+ 'shcy;': 'ш',
+ 'sime;': '≃',
+ 'simg;': '⪞',
+ 'siml;': '⪝',
+ 'smid;': '∣',
+ 'smte;': '⪬',
+ 'solb;': '⧄',
+ 'Sopf;': '𝕊',
+ 'sopf;': '𝕤',
+ 'spar;': '∥',
+ 'Sqrt;': '√',
+ 'squf;': '▪',
+ 'Sscr;': '𝒮',
+ 'sscr;': '𝓈',
+ 'Star;': '⋆',
+ 'star;': '☆',
+ 'subE;': '⫅',
+ 'sube;': '⊆',
+ 'succ;': '≻',
+ 'sung;': '♪',
+ 'sup1;': '¹',
+ 'sup2;': '²',
+ 'sup3;': '³',
+ 'supE;': '⫆',
+ 'supe;': '⊇',
+ szlig: 'ß',
+ 'tbrk;': '⎴',
+ 'tdot;': '⃛',
+ THORN: 'Þ',
+ thorn: 'þ',
+ times: '×',
+ 'tint;': '∭',
+ 'toea;': '⤨',
+ 'Topf;': '𝕋',
+ 'topf;': '𝕥',
+ 'tosa;': '⤩',
+ 'trie;': '≜',
+ 'Tscr;': '𝒯',
+ 'tscr;': '𝓉',
+ 'TScy;': 'Ц',
+ 'tscy;': 'ц',
+ 'Uarr;': '↟',
+ 'uArr;': '⇑',
+ 'uarr;': '↑',
+ Ucirc: 'Û',
+ ucirc: 'û',
+ 'uHar;': '⥣',
+ 'Uopf;': '𝕌',
+ 'uopf;': '𝕦',
+ 'Upsi;': 'ϒ',
+ 'upsi;': 'υ',
+ 'Uscr;': '𝒰',
+ 'uscr;': '𝓊',
+ 'utri;': '▵',
+ 'Uuml;': 'Ü',
+ 'uuml;': 'ü',
+ 'vArr;': '⇕',
+ 'varr;': '↕',
+ 'Vbar;': '⫫',
+ 'vBar;': '⫨',
+ 'Vert;': '‖',
+ 'vert;': '|',
+ 'Vopf;': '𝕍',
+ 'vopf;': '𝕧',
+ 'Vscr;': '𝒱',
+ 'vscr;': '𝓋',
+ 'Wopf;': '𝕎',
+ 'wopf;': '𝕨',
+ 'Wscr;': '𝒲',
+ 'wscr;': '𝓌',
+ 'xcap;': '⋂',
+ 'xcup;': '⋃',
+ 'xmap;': '⟼',
+ 'xnis;': '⋻',
+ 'Xopf;': '𝕏',
+ 'xopf;': '𝕩',
+ 'Xscr;': '𝒳',
+ 'xscr;': '𝓍',
+ 'xvee;': '⋁',
+ 'YAcy;': 'Я',
+ 'yacy;': 'я',
+ 'YIcy;': 'Ї',
+ 'yicy;': 'ї',
+ 'Yopf;': '𝕐',
+ 'yopf;': '𝕪',
+ 'Yscr;': '𝒴',
+ 'yscr;': '𝓎',
+ 'YUcy;': 'Ю',
+ 'yucy;': 'ю',
+ 'Yuml;': 'Ÿ',
+ 'yuml;': 'ÿ',
+ 'Zdot;': 'Ż',
+ 'zdot;': 'ż',
+ 'Zeta;': 'Ζ',
+ 'zeta;': 'ζ',
+ 'ZHcy;': 'Ж',
+ 'zhcy;': 'ж',
+ 'Zopf;': 'ℤ',
+ 'zopf;': '𝕫',
+ 'Zscr;': '𝒵',
+ 'zscr;': '𝓏',
+ 'zwnj;': '',
+ Aacute: 'Á',
+ aacute: 'á',
+ 'Acirc;': 'Â',
+ 'acirc;': 'â',
+ 'acute;': '´',
+ 'AElig;': 'Æ',
+ 'aelig;': 'æ',
+ Agrave: 'À',
+ agrave: 'à',
+ 'aleph;': 'ℵ',
+ 'Alpha;': 'Α',
+ 'alpha;': 'α',
+ 'Amacr;': 'Ā',
+ 'amacr;': 'ā',
+ 'amalg;': '⨿',
+ 'angle;': '∠',
+ 'angrt;': '∟',
+ 'angst;': 'Å',
+ 'Aogon;': 'Ą',
+ 'aogon;': 'ą',
+ 'Aring;': 'Å',
+ 'aring;': 'å',
+ 'asymp;': '≈',
+ Atilde: 'Ã',
+ atilde: 'ã',
+ 'awint;': '⨑',
+ 'bcong;': '≌',
+ 'bdquo;': '„',
+ 'bepsi;': '϶',
+ 'blank;': '␣',
+ 'blk12;': '▒',
+ 'blk14;': '░',
+ 'blk34;': '▓',
+ 'block;': '█',
+ 'boxDL;': '╗',
+ 'boxDl;': '╖',
+ 'boxdL;': '╕',
+ 'boxdl;': '┐',
+ 'boxDR;': '╔',
+ 'boxDr;': '╓',
+ 'boxdR;': '╒',
+ 'boxdr;': '┌',
+ 'boxHD;': '╦',
+ 'boxHd;': '╤',
+ 'boxhD;': '╥',
+ 'boxhd;': '┬',
+ 'boxHU;': '╩',
+ 'boxHu;': '╧',
+ 'boxhU;': '╨',
+ 'boxhu;': '┴',
+ 'boxUL;': '╝',
+ 'boxUl;': '╜',
+ 'boxuL;': '╛',
+ 'boxul;': '┘',
+ 'boxUR;': '╚',
+ 'boxUr;': '╙',
+ 'boxuR;': '╘',
+ 'boxur;': '└',
+ 'boxVH;': '╬',
+ 'boxVh;': '╫',
+ 'boxvH;': '╪',
+ 'boxvh;': '┼',
+ 'boxVL;': '╣',
+ 'boxVl;': '╢',
+ 'boxvL;': '╡',
+ 'boxvl;': '┤',
+ 'boxVR;': '╠',
+ 'boxVr;': '╟',
+ 'boxvR;': '╞',
+ 'boxvr;': '├',
+ 'Breve;': '˘',
+ 'breve;': '˘',
+ brvbar: '¦',
+ 'bsemi;': '⁏',
+ 'bsime;': '⋍',
+ 'bsolb;': '⧅',
+ 'bumpE;': '⪮',
+ 'bumpe;': '≏',
+ 'caret;': '⁁',
+ 'caron;': 'ˇ',
+ 'ccaps;': '⩍',
+ Ccedil: 'Ç',
+ ccedil: 'ç',
+ 'Ccirc;': 'Ĉ',
+ 'ccirc;': 'ĉ',
+ 'ccups;': '⩌',
+ 'cedil;': '¸',
+ 'check;': '✓',
+ 'clubs;': '♣',
+ 'Colon;': '∷',
+ 'colon;': ':',
+ 'comma;': ',',
+ 'crarr;': '↵',
+ 'Cross;': '⨯',
+ 'cross;': '✗',
+ 'csube;': '⫑',
+ 'csupe;': '⫒',
+ 'ctdot;': '⋯',
+ 'cuepr;': '⋞',
+ 'cuesc;': '⋟',
+ 'cupor;': '⩅',
+ curren: '¤',
+ 'cuvee;': '⋎',
+ 'cuwed;': '⋏',
+ 'cwint;': '∱',
+ 'Dashv;': '⫤',
+ 'dashv;': '⊣',
+ 'dblac;': '˝',
+ 'ddarr;': '⇊',
+ 'Delta;': 'Δ',
+ 'delta;': 'δ',
+ 'dharl;': '⇃',
+ 'dharr;': '⇂',
+ 'diams;': '♦',
+ 'disin;': '⋲',
+ divide: '÷',
+ 'doteq;': '≐',
+ 'dtdot;': '⋱',
+ 'dtrif;': '▾',
+ 'duarr;': '⇵',
+ 'duhar;': '⥯',
+ Eacute: 'É',
+ eacute: 'é',
+ 'Ecirc;': 'Ê',
+ 'ecirc;': 'ê',
+ 'eDDot;': '⩷',
+ 'efDot;': '≒',
+ Egrave: 'È',
+ egrave: 'è',
+ 'Emacr;': 'Ē',
+ 'emacr;': 'ē',
+ 'empty;': '∅',
+ 'Eogon;': 'Ę',
+ 'eogon;': 'ę',
+ 'eplus;': '⩱',
+ 'epsiv;': 'ϵ',
+ 'eqsim;': '≂',
+ 'Equal;': '⩵',
+ 'equiv;': '≡',
+ 'erarr;': '⥱',
+ 'erDot;': '≓',
+ 'esdot;': '≐',
+ 'exist;': '∃',
+ 'fflig;': 'ff',
+ 'filig;': 'fi',
+ 'fjlig;': 'fj',
+ 'fllig;': 'fl',
+ 'fltns;': '▱',
+ 'forkv;': '⫙',
+ frac12: '½',
+ frac14: '¼',
+ frac34: '¾',
+ 'frasl;': '⁄',
+ 'frown;': '⌢',
+ 'Gamma;': 'Γ',
+ 'gamma;': 'γ',
+ 'Gcirc;': 'Ĝ',
+ 'gcirc;': 'ĝ',
+ 'gescc;': '⪩',
+ 'gimel;': 'ℷ',
+ 'gneqq;': '≩',
+ 'gnsim;': '⋧',
+ 'grave;': '`',
+ 'gsime;': '⪎',
+ 'gsiml;': '⪐',
+ 'gtcir;': '⩺',
+ 'gtdot;': '⋗',
+ 'Hacek;': 'ˇ',
+ 'harrw;': '↭',
+ 'Hcirc;': 'Ĥ',
+ 'hcirc;': 'ĥ',
+ 'hoarr;': '⇿',
+ Iacute: 'Í',
+ iacute: 'í',
+ 'Icirc;': 'Î',
+ 'icirc;': 'î',
+ 'iexcl;': '¡',
+ Igrave: 'Ì',
+ igrave: 'ì',
+ 'iiint;': '∭',
+ 'iiota;': '℩',
+ 'IJlig;': 'IJ',
+ 'ijlig;': 'ij',
+ 'Imacr;': 'Ī',
+ 'imacr;': 'ī',
+ 'image;': 'ℑ',
+ 'imath;': 'ı',
+ 'imped;': 'Ƶ',
+ 'infin;': '∞',
+ 'Iogon;': 'Į',
+ 'iogon;': 'į',
+ 'iprod;': '⨼',
+ iquest: '¿',
+ 'isinE;': '⋹',
+ 'isins;': '⋴',
+ 'isinv;': '∈',
+ 'Iukcy;': 'І',
+ 'iukcy;': 'і',
+ 'Jcirc;': 'Ĵ',
+ 'jcirc;': 'ĵ',
+ 'jmath;': 'ȷ',
+ 'Jukcy;': 'Є',
+ 'jukcy;': 'є',
+ 'Kappa;': 'Κ',
+ 'kappa;': 'κ',
+ 'lAarr;': '⇚',
+ 'langd;': '⦑',
+ 'laquo;': '«',
+ 'larrb;': '⇤',
+ 'lates;': '⪭︀',
+ 'lBarr;': '⤎',
+ 'lbarr;': '⤌',
+ 'lbbrk;': '❲',
+ 'lbrke;': '⦋',
+ 'lceil;': '⌈',
+ 'ldquo;': '“',
+ 'lescc;': '⪨',
+ 'lhard;': '↽',
+ 'lharu;': '↼',
+ 'lhblk;': '▄',
+ 'llarr;': '⇇',
+ 'lltri;': '◺',
+ 'lneqq;': '≨',
+ 'lnsim;': '⋦',
+ 'loang;': '⟬',
+ 'loarr;': '⇽',
+ 'lobrk;': '⟦',
+ 'lopar;': '⦅',
+ 'lrarr;': '⇆',
+ 'lrhar;': '⇋',
+ 'lrtri;': '⊿',
+ 'lsime;': '⪍',
+ 'lsimg;': '⪏',
+ 'lsquo;': '‘',
+ 'ltcir;': '⩹',
+ 'ltdot;': '⋖',
+ 'ltrie;': '⊴',
+ 'ltrif;': '◂',
+ 'mdash;': '—',
+ 'mDDot;': '∺',
+ 'micro;': 'µ',
+ middot: '·',
+ 'minus;': '−',
+ 'mumap;': '⊸',
+ 'nabla;': '∇',
+ 'napid;': '≋̸',
+ 'napos;': 'ʼn',
+ 'natur;': '♮',
+ 'nbump;': '≎̸',
+ 'ncong;': '≇',
+ 'ndash;': '–',
+ 'neArr;': '⇗',
+ 'nearr;': '↗',
+ 'nedot;': '≐̸',
+ 'nesim;': '≂̸',
+ 'ngeqq;': '≧̸',
+ 'ngsim;': '≵',
+ 'nhArr;': '⇎',
+ 'nharr;': '↮',
+ 'nhpar;': '⫲',
+ 'nlArr;': '⇍',
+ 'nlarr;': '↚',
+ 'nleqq;': '≦̸',
+ 'nless;': '≮',
+ 'nlsim;': '≴',
+ 'nltri;': '⋪',
+ 'notin;': '∉',
+ 'notni;': '∌',
+ 'npart;': '∂̸',
+ 'nprec;': '⊀',
+ 'nrArr;': '⇏',
+ 'nrarr;': '↛',
+ 'nrtri;': '⋫',
+ 'nsime;': '≄',
+ 'nsmid;': '∤',
+ 'nspar;': '∦',
+ 'nsubE;': '⫅̸',
+ 'nsube;': '⊈',
+ 'nsucc;': '⊁',
+ 'nsupE;': '⫆̸',
+ 'nsupe;': '⊉',
+ Ntilde: 'Ñ',
+ ntilde: 'ñ',
+ 'numsp;': ' ',
+ 'nvsim;': '∼⃒',
+ 'nwArr;': '⇖',
+ 'nwarr;': '↖',
+ Oacute: 'Ó',
+ oacute: 'ó',
+ 'Ocirc;': 'Ô',
+ 'ocirc;': 'ô',
+ 'odash;': '⊝',
+ 'OElig;': 'Œ',
+ 'oelig;': 'œ',
+ 'ofcir;': '⦿',
+ Ograve: 'Ò',
+ ograve: 'ò',
+ 'ohbar;': '⦵',
+ 'olarr;': '↺',
+ 'olcir;': '⦾',
+ 'oline;': '‾',
+ 'Omacr;': 'Ō',
+ 'omacr;': 'ō',
+ 'Omega;': 'Ω',
+ 'omega;': 'ω',
+ 'operp;': '⦹',
+ 'oplus;': '⊕',
+ 'orarr;': '↻',
+ 'order;': 'ℴ',
+ Oslash: 'Ø',
+ oslash: 'ø',
+ Otilde: 'Õ',
+ otilde: 'õ',
+ 'ovbar;': '⌽',
+ 'parsl;': '⫽',
+ 'phone;': '☎',
+ 'plusb;': '⊞',
+ 'pluse;': '⩲',
+ plusmn: '±',
+ 'pound;': '£',
+ 'prcue;': '≼',
+ 'Prime;': '″',
+ 'prime;': '′',
+ 'prnap;': '⪹',
+ 'prsim;': '≾',
+ 'quest;': '?',
+ 'rAarr;': '⇛',
+ 'radic;': '√',
+ 'rangd;': '⦒',
+ 'range;': '⦥',
+ 'raquo;': '»',
+ 'rarrb;': '⇥',
+ 'rarrc;': '⤳',
+ 'rarrw;': '↝',
+ 'ratio;': '∶',
+ 'RBarr;': '⤐',
+ 'rBarr;': '⤏',
+ 'rbarr;': '⤍',
+ 'rbbrk;': '❳',
+ 'rbrke;': '⦌',
+ 'rceil;': '⌉',
+ 'rdquo;': '”',
+ 'reals;': 'ℝ',
+ 'rhard;': '⇁',
+ 'rharu;': '⇀',
+ 'rlarr;': '⇄',
+ 'rlhar;': '⇌',
+ 'rnmid;': '⫮',
+ 'roang;': '⟭',
+ 'roarr;': '⇾',
+ 'robrk;': '⟧',
+ 'ropar;': '⦆',
+ 'rrarr;': '⇉',
+ 'rsquo;': '’',
+ 'rtrie;': '⊵',
+ 'rtrif;': '▸',
+ 'sbquo;': '‚',
+ 'sccue;': '≽',
+ 'Scirc;': 'Ŝ',
+ 'scirc;': 'ŝ',
+ 'scnap;': '⪺',
+ 'scsim;': '≿',
+ 'sdotb;': '⊡',
+ 'sdote;': '⩦',
+ 'seArr;': '⇘',
+ 'searr;': '↘',
+ 'setmn;': '∖',
+ 'sharp;': '♯',
+ 'Sigma;': 'Σ',
+ 'sigma;': 'σ',
+ 'simeq;': '≃',
+ 'simgE;': '⪠',
+ 'simlE;': '⪟',
+ 'simne;': '≆',
+ 'slarr;': '←',
+ 'smile;': '⌣',
+ 'smtes;': '⪬︀',
+ 'sqcap;': '⊓',
+ 'sqcup;': '⊔',
+ 'sqsub;': '⊏',
+ 'sqsup;': '⊐',
+ 'srarr;': '→',
+ 'starf;': '★',
+ 'strns;': '¯',
+ 'subnE;': '⫋',
+ 'subne;': '⊊',
+ 'supnE;': '⫌',
+ 'supne;': '⊋',
+ 'swArr;': '⇙',
+ 'swarr;': '↙',
+ 'szlig;': 'ß',
+ 'Theta;': 'Θ',
+ 'theta;': 'θ',
+ 'thkap;': '≈',
+ 'THORN;': 'Þ',
+ 'thorn;': 'þ',
+ 'Tilde;': '∼',
+ 'tilde;': '˜',
+ 'times;': '×',
+ 'TRADE;': '™',
+ 'trade;': '™',
+ 'trisb;': '⧍',
+ 'TSHcy;': 'Ћ',
+ 'tshcy;': 'ћ',
+ 'twixt;': '≬',
+ Uacute: 'Ú',
+ uacute: 'ú',
+ 'Ubrcy;': 'Ў',
+ 'ubrcy;': 'ў',
+ 'Ucirc;': 'Û',
+ 'ucirc;': 'û',
+ 'udarr;': '⇅',
+ 'udhar;': '⥮',
+ Ugrave: 'Ù',
+ ugrave: 'ù',
+ 'uharl;': '↿',
+ 'uharr;': '↾',
+ 'uhblk;': '▀',
+ 'ultri;': '◸',
+ 'Umacr;': 'Ū',
+ 'umacr;': 'ū',
+ 'Union;': '⋃',
+ 'Uogon;': 'Ų',
+ 'uogon;': 'ų',
+ 'uplus;': '⊎',
+ 'upsih;': 'ϒ',
+ 'UpTee;': '⊥',
+ 'Uring;': 'Ů',
+ 'uring;': 'ů',
+ 'urtri;': '◹',
+ 'utdot;': '⋰',
+ 'utrif;': '▴',
+ 'uuarr;': '⇈',
+ 'varpi;': 'ϖ',
+ 'vBarv;': '⫩',
+ 'VDash;': '⊫',
+ 'Vdash;': '⊩',
+ 'vDash;': '⊨',
+ 'vdash;': '⊢',
+ 'veeeq;': '≚',
+ 'vltri;': '⊲',
+ 'vnsub;': '⊂⃒',
+ 'vnsup;': '⊃⃒',
+ 'vprop;': '∝',
+ 'vrtri;': '⊳',
+ 'Wcirc;': 'Ŵ',
+ 'wcirc;': 'ŵ',
+ 'Wedge;': '⋀',
+ 'wedge;': '∧',
+ 'xcirc;': '◯',
+ 'xdtri;': '▽',
+ 'xhArr;': '⟺',
+ 'xharr;': '⟷',
+ 'xlArr;': '⟸',
+ 'xlarr;': '⟵',
+ 'xodot;': '⨀',
+ 'xrArr;': '⟹',
+ 'xrarr;': '⟶',
+ 'xutri;': '△',
+ Yacute: 'Ý',
+ yacute: 'ý',
+ 'Ycirc;': 'Ŷ',
+ 'ycirc;': 'ŷ',
+ 'Aacute;': 'Á',
+ 'aacute;': 'á',
+ 'Abreve;': 'Ă',
+ 'abreve;': 'ă',
+ 'Agrave;': 'À',
+ 'agrave;': 'à',
+ 'andand;': '⩕',
+ 'angmsd;': '∡',
+ 'angsph;': '∢',
+ 'apacir;': '⩯',
+ 'approx;': '≈',
+ 'Assign;': '≔',
+ 'Atilde;': 'Ã',
+ 'atilde;': 'ã',
+ 'barvee;': '⊽',
+ 'Barwed;': '⌆',
+ 'barwed;': '⌅',
+ 'becaus;': '∵',
+ 'bernou;': 'ℬ',
+ 'bigcap;': '⋂',
+ 'bigcup;': '⋃',
+ 'bigvee;': '⋁',
+ 'bkarow;': '⤍',
+ 'bottom;': '⊥',
+ 'bowtie;': '⋈',
+ 'boxbox;': '⧉',
+ 'bprime;': '‵',
+ 'brvbar;': '¦',
+ 'bullet;': '•',
+ 'Bumpeq;': '≎',
+ 'bumpeq;': '≏',
+ 'Cacute;': 'Ć',
+ 'cacute;': 'ć',
+ 'capand;': '⩄',
+ 'capcap;': '⩋',
+ 'capcup;': '⩇',
+ 'capdot;': '⩀',
+ 'Ccaron;': 'Č',
+ 'ccaron;': 'č',
+ 'Ccedil;': 'Ç',
+ 'ccedil;': 'ç',
+ 'circeq;': '≗',
+ 'cirmid;': '⫯',
+ 'Colone;': '⩴',
+ 'colone;': '≔',
+ 'commat;': '@',
+ 'compfn;': '∘',
+ 'Conint;': '∯',
+ 'conint;': '∮',
+ 'coprod;': '∐',
+ 'copysr;': '℗',
+ 'cularr;': '↶',
+ 'CupCap;': '≍',
+ 'cupcap;': '⩆',
+ 'cupcup;': '⩊',
+ 'cupdot;': '⊍',
+ 'curarr;': '↷',
+ 'curren;': '¤',
+ 'cylcty;': '⌭',
+ 'Dagger;': '‡',
+ 'dagger;': '†',
+ 'daleth;': 'ℸ',
+ 'Dcaron;': 'Ď',
+ 'dcaron;': 'ď',
+ 'dfisht;': '⥿',
+ 'divide;': '÷',
+ 'divonx;': '⋇',
+ 'dlcorn;': '⌞',
+ 'dlcrop;': '⌍',
+ 'dollar;': '$',
+ 'DotDot;': '⃜',
+ 'drcorn;': '⌟',
+ 'drcrop;': '⌌',
+ 'Dstrok;': 'Đ',
+ 'dstrok;': 'đ',
+ 'Eacute;': 'É',
+ 'eacute;': 'é',
+ 'easter;': '⩮',
+ 'Ecaron;': 'Ě',
+ 'ecaron;': 'ě',
+ 'ecolon;': '≕',
+ 'Egrave;': 'È',
+ 'egrave;': 'è',
+ 'egsdot;': '⪘',
+ 'elsdot;': '⪗',
+ 'emptyv;': '∅',
+ 'emsp13;': ' ',
+ 'emsp14;': ' ',
+ 'eparsl;': '⧣',
+ 'eqcirc;': '≖',
+ 'equals;': '=',
+ 'equest;': '≟',
+ 'Exists;': '∃',
+ 'female;': '♀',
+ 'ffilig;': 'ffi',
+ 'ffllig;': 'ffl',
+ 'ForAll;': '∀',
+ 'forall;': '∀',
+ 'frac12;': '½',
+ 'frac13;': '⅓',
+ 'frac14;': '¼',
+ 'frac15;': '⅕',
+ 'frac16;': '⅙',
+ 'frac18;': '⅛',
+ 'frac23;': '⅔',
+ 'frac25;': '⅖',
+ 'frac34;': '¾',
+ 'frac35;': '⅗',
+ 'frac38;': '⅜',
+ 'frac45;': '⅘',
+ 'frac56;': '⅚',
+ 'frac58;': '⅝',
+ 'frac78;': '⅞',
+ 'gacute;': 'ǵ',
+ 'Gammad;': 'Ϝ',
+ 'gammad;': 'ϝ',
+ 'Gbreve;': 'Ğ',
+ 'gbreve;': 'ğ',
+ 'Gcedil;': 'Ģ',
+ 'gesdot;': '⪀',
+ 'gesles;': '⪔',
+ 'gtlPar;': '⦕',
+ 'gtrarr;': '⥸',
+ 'gtrdot;': '⋗',
+ 'gtrsim;': '≳',
+ 'hairsp;': ' ',
+ 'hamilt;': 'ℋ',
+ 'HARDcy;': 'Ъ',
+ 'hardcy;': 'ъ',
+ 'hearts;': '♥',
+ 'hellip;': '…',
+ 'hercon;': '⊹',
+ 'homtht;': '∻',
+ 'horbar;': '―',
+ 'hslash;': 'ℏ',
+ 'Hstrok;': 'Ħ',
+ 'hstrok;': 'ħ',
+ 'hybull;': '⁃',
+ 'hyphen;': '‐',
+ 'Iacute;': 'Í',
+ 'iacute;': 'í',
+ 'Igrave;': 'Ì',
+ 'igrave;': 'ì',
+ 'iiiint;': '⨌',
+ 'iinfin;': '⧜',
+ 'incare;': '℅',
+ 'inodot;': 'ı',
+ 'intcal;': '⊺',
+ 'iquest;': '¿',
+ 'isinsv;': '⋳',
+ 'Itilde;': 'Ĩ',
+ 'itilde;': 'ĩ',
+ 'Jsercy;': 'Ј',
+ 'jsercy;': 'ј',
+ 'kappav;': 'ϰ',
+ 'Kcedil;': 'Ķ',
+ 'kcedil;': 'ķ',
+ 'kgreen;': 'ĸ',
+ 'Lacute;': 'Ĺ',
+ 'lacute;': 'ĺ',
+ 'lagran;': 'ℒ',
+ 'Lambda;': 'Λ',
+ 'lambda;': 'λ',
+ 'langle;': '⟨',
+ 'larrfs;': '⤝',
+ 'larrhk;': '↩',
+ 'larrlp;': '↫',
+ 'larrpl;': '⤹',
+ 'larrtl;': '↢',
+ 'lAtail;': '⤛',
+ 'latail;': '⤙',
+ 'lbrace;': '{',
+ 'lbrack;': '[',
+ 'Lcaron;': 'Ľ',
+ 'lcaron;': 'ľ',
+ 'Lcedil;': 'Ļ',
+ 'lcedil;': 'ļ',
+ 'ldquor;': '„',
+ 'lesdot;': '⩿',
+ 'lesges;': '⪓',
+ 'lfisht;': '⥼',
+ 'lfloor;': '⌊',
+ 'lharul;': '⥪',
+ 'llhard;': '⥫',
+ 'Lmidot;': 'Ŀ',
+ 'lmidot;': 'ŀ',
+ 'lmoust;': '⎰',
+ 'loplus;': '⨭',
+ 'lowast;': '∗',
+ 'lowbar;': '_',
+ 'lparlt;': '⦓',
+ 'lrhard;': '⥭',
+ 'lsaquo;': '‹',
+ 'lsquor;': '‚',
+ 'Lstrok;': 'Ł',
+ 'lstrok;': 'ł',
+ 'lthree;': '⋋',
+ 'ltimes;': '⋉',
+ 'ltlarr;': '⥶',
+ 'ltrPar;': '⦖',
+ 'mapsto;': '↦',
+ 'marker;': '▮',
+ 'mcomma;': '⨩',
+ 'midast;': '*',
+ 'midcir;': '⫰',
+ 'middot;': '·',
+ 'minusb;': '⊟',
+ 'minusd;': '∸',
+ 'mnplus;': '∓',
+ 'models;': '⊧',
+ 'mstpos;': '∾',
+ 'Nacute;': 'Ń',
+ 'nacute;': 'ń',
+ 'nbumpe;': '≏̸',
+ 'Ncaron;': 'Ň',
+ 'ncaron;': 'ň',
+ 'Ncedil;': 'Ņ',
+ 'ncedil;': 'ņ',
+ 'nearhk;': '⤤',
+ 'nequiv;': '≢',
+ 'nesear;': '⤨',
+ 'nexist;': '∄',
+ 'nltrie;': '⋬',
+ 'notinE;': '⋹̸',
+ 'nparsl;': '⫽⃥',
+ 'nprcue;': '⋠',
+ 'nrarrc;': '⤳̸',
+ 'nrarrw;': '↝̸',
+ 'nrtrie;': '⋭',
+ 'nsccue;': '⋡',
+ 'nsimeq;': '≄',
+ 'Ntilde;': 'Ñ',
+ 'ntilde;': 'ñ',
+ 'numero;': '№',
+ 'nVDash;': '⊯',
+ 'nVdash;': '⊮',
+ 'nvDash;': '⊭',
+ 'nvdash;': '⊬',
+ 'nvHarr;': '⤄',
+ 'nvlArr;': '⤂',
+ 'nvrArr;': '⤃',
+ 'nwarhk;': '⤣',
+ 'nwnear;': '⤧',
+ 'Oacute;': 'Ó',
+ 'oacute;': 'ó',
+ 'Odblac;': 'Ő',
+ 'odblac;': 'ő',
+ 'odsold;': '⦼',
+ 'Ograve;': 'Ò',
+ 'ograve;': 'ò',
+ 'ominus;': '⊖',
+ 'origof;': '⊶',
+ 'Oslash;': 'Ø',
+ 'oslash;': 'ø',
+ 'Otilde;': 'Õ',
+ 'otilde;': 'õ',
+ 'Otimes;': '⨷',
+ 'otimes;': '⊗',
+ 'parsim;': '⫳',
+ 'percnt;': '%',
+ 'period;': '.',
+ 'permil;': '‰',
+ 'phmmat;': 'ℳ',
+ 'planck;': 'ℏ',
+ 'plankv;': 'ℏ',
+ 'plusdo;': '∔',
+ 'plusdu;': '⨥',
+ 'plusmn;': '±',
+ 'preceq;': '⪯',
+ 'primes;': 'ℙ',
+ 'prnsim;': '⋨',
+ 'propto;': '∝',
+ 'prurel;': '⊰',
+ 'puncsp;': ' ',
+ 'qprime;': '⁗',
+ 'Racute;': 'Ŕ',
+ 'racute;': 'ŕ',
+ 'rangle;': '⟩',
+ 'rarrap;': '⥵',
+ 'rarrfs;': '⤞',
+ 'rarrhk;': '↪',
+ 'rarrlp;': '↬',
+ 'rarrpl;': '⥅',
+ 'Rarrtl;': '⤖',
+ 'rarrtl;': '↣',
+ 'rAtail;': '⤜',
+ 'ratail;': '⤚',
+ 'rbrace;': '}',
+ 'rbrack;': ']',
+ 'Rcaron;': 'Ř',
+ 'rcaron;': 'ř',
+ 'Rcedil;': 'Ŗ',
+ 'rcedil;': 'ŗ',
+ 'rdquor;': '”',
+ 'rfisht;': '⥽',
+ 'rfloor;': '⌋',
+ 'rharul;': '⥬',
+ 'rmoust;': '⎱',
+ 'roplus;': '⨮',
+ 'rpargt;': '⦔',
+ 'rsaquo;': '›',
+ 'rsquor;': '’',
+ 'rthree;': '⋌',
+ 'rtimes;': '⋊',
+ 'Sacute;': 'Ś',
+ 'sacute;': 'ś',
+ 'Scaron;': 'Š',
+ 'scaron;': 'š',
+ 'Scedil;': 'Ş',
+ 'scedil;': 'ş',
+ 'scnsim;': '⋩',
+ 'searhk;': '⤥',
+ 'seswar;': '⤩',
+ 'sfrown;': '⌢',
+ 'SHCHcy;': 'Щ',
+ 'shchcy;': 'щ',
+ 'sigmaf;': 'ς',
+ 'sigmav;': 'ς',
+ 'simdot;': '⩪',
+ 'smashp;': '⨳',
+ 'SOFTcy;': 'Ь',
+ 'softcy;': 'ь',
+ 'solbar;': '⌿',
+ 'spades;': '♠',
+ 'sqcaps;': '⊓︀',
+ 'sqcups;': '⊔︀',
+ 'sqsube;': '⊑',
+ 'sqsupe;': '⊒',
+ 'Square;': '□',
+ 'square;': '□',
+ 'squarf;': '▪',
+ 'ssetmn;': '∖',
+ 'ssmile;': '⌣',
+ 'sstarf;': '⋆',
+ 'subdot;': '⪽',
+ 'Subset;': '⋐',
+ 'subset;': '⊂',
+ 'subsim;': '⫇',
+ 'subsub;': '⫕',
+ 'subsup;': '⫓',
+ 'succeq;': '⪰',
+ 'supdot;': '⪾',
+ 'Supset;': '⋑',
+ 'supset;': '⊃',
+ 'supsim;': '⫈',
+ 'supsub;': '⫔',
+ 'supsup;': '⫖',
+ 'swarhk;': '⤦',
+ 'swnwar;': '⤪',
+ 'target;': '⌖',
+ 'Tcaron;': 'Ť',
+ 'tcaron;': 'ť',
+ 'Tcedil;': 'Ţ',
+ 'tcedil;': 'ţ',
+ 'telrec;': '⌕',
+ 'there4;': '∴',
+ 'thetav;': 'ϑ',
+ 'thinsp;': ' ',
+ 'thksim;': '∼',
+ 'timesb;': '⊠',
+ 'timesd;': '⨰',
+ 'topbot;': '⌶',
+ 'topcir;': '⫱',
+ 'tprime;': '‴',
+ 'tridot;': '◬',
+ 'Tstrok;': 'Ŧ',
+ 'tstrok;': 'ŧ',
+ 'Uacute;': 'Ú',
+ 'uacute;': 'ú',
+ 'Ubreve;': 'Ŭ',
+ 'ubreve;': 'ŭ',
+ 'Udblac;': 'Ű',
+ 'udblac;': 'ű',
+ 'ufisht;': '⥾',
+ 'Ugrave;': 'Ù',
+ 'ugrave;': 'ù',
+ 'ulcorn;': '⌜',
+ 'ulcrop;': '⌏',
+ 'urcorn;': '⌝',
+ 'urcrop;': '⌎',
+ 'Utilde;': 'Ũ',
+ 'utilde;': 'ũ',
+ 'vangrt;': '⦜',
+ 'varphi;': 'ϕ',
+ 'varrho;': 'ϱ',
+ 'Vdashl;': '⫦',
+ 'veebar;': '⊻',
+ 'vellip;': '⋮',
+ 'Verbar;': '‖',
+ 'verbar;': '|',
+ 'vsubnE;': '⫋︀',
+ 'vsubne;': '⊊︀',
+ 'vsupnE;': '⫌︀',
+ 'vsupne;': '⊋︀',
+ 'Vvdash;': '⊪',
+ 'wedbar;': '⩟',
+ 'wedgeq;': '≙',
+ 'weierp;': '℘',
+ 'wreath;': '≀',
+ 'xoplus;': '⨁',
+ 'xotime;': '⨂',
+ 'xsqcup;': '⨆',
+ 'xuplus;': '⨄',
+ 'xwedge;': '⋀',
+ 'Yacute;': 'Ý',
+ 'yacute;': 'ý',
+ 'Zacute;': 'Ź',
+ 'zacute;': 'ź',
+ 'Zcaron;': 'Ž',
+ 'zcaron;': 'ž',
+ 'zeetrf;': 'ℨ',
+ 'alefsym;': 'ℵ',
+ 'angrtvb;': '⊾',
+ 'angzarr;': '⍼',
+ 'asympeq;': '≍',
+ 'backsim;': '∽',
+ 'Because;': '∵',
+ 'because;': '∵',
+ 'bemptyv;': '⦰',
+ 'between;': '≬',
+ 'bigcirc;': '◯',
+ 'bigodot;': '⨀',
+ 'bigstar;': '★',
+ 'bnequiv;': '≡⃥',
+ 'boxplus;': '⊞',
+ 'Cayleys;': 'ℭ',
+ 'Cconint;': '∰',
+ 'ccupssm;': '⩐',
+ 'Cedilla;': '¸',
+ 'cemptyv;': '⦲',
+ 'cirscir;': '⧂',
+ 'coloneq;': '≔',
+ 'congdot;': '⩭',
+ 'cudarrl;': '⤸',
+ 'cudarrr;': '⤵',
+ 'cularrp;': '⤽',
+ 'curarrm;': '⤼',
+ 'dbkarow;': '⤏',
+ 'ddagger;': '‡',
+ 'ddotseq;': '⩷',
+ 'demptyv;': '⦱',
+ 'Diamond;': '⋄',
+ 'diamond;': '⋄',
+ 'digamma;': 'ϝ',
+ 'dotplus;': '∔',
+ 'DownTee;': '⊤',
+ 'dwangle;': '⦦',
+ 'Element;': '∈',
+ 'Epsilon;': 'Ε',
+ 'epsilon;': 'ε',
+ 'eqcolon;': '≕',
+ 'equivDD;': '⩸',
+ 'gesdoto;': '⪂',
+ 'gtquest;': '⩼',
+ 'gtrless;': '≷',
+ 'harrcir;': '⥈',
+ 'Implies;': '⇒',
+ 'intprod;': '⨼',
+ 'isindot;': '⋵',
+ 'larrbfs;': '⤟',
+ 'larrsim;': '⥳',
+ 'lbrksld;': '⦏',
+ 'lbrkslu;': '⦍',
+ 'ldrdhar;': '⥧',
+ 'LeftTee;': '⊣',
+ 'lesdoto;': '⪁',
+ 'lessdot;': '⋖',
+ 'lessgtr;': '≶',
+ 'lesssim;': '≲',
+ 'lotimes;': '⨴',
+ 'lozenge;': '◊',
+ 'ltquest;': '⩻',
+ 'luruhar;': '⥦',
+ 'maltese;': '✠',
+ 'minusdu;': '⨪',
+ 'napprox;': '≉',
+ 'natural;': '♮',
+ 'nearrow;': '↗',
+ 'NewLine;': '\n',
+ 'nexists;': '∄',
+ 'NoBreak;': '',
+ 'notinva;': '∉',
+ 'notinvb;': '⋷',
+ 'notinvc;': '⋶',
+ 'NotLess;': '≮',
+ 'notniva;': '∌',
+ 'notnivb;': '⋾',
+ 'notnivc;': '⋽',
+ 'npolint;': '⨔',
+ 'npreceq;': '⪯̸',
+ 'nsqsube;': '⋢',
+ 'nsqsupe;': '⋣',
+ 'nsubset;': '⊂⃒',
+ 'nsucceq;': '⪰̸',
+ 'nsupset;': '⊃⃒',
+ 'nvinfin;': '⧞',
+ 'nvltrie;': '⊴⃒',
+ 'nvrtrie;': '⊵⃒',
+ 'nwarrow;': '↖',
+ 'olcross;': '⦻',
+ 'Omicron;': 'Ο',
+ 'omicron;': 'ο',
+ 'orderof;': 'ℴ',
+ 'orslope;': '⩗',
+ 'OverBar;': '‾',
+ 'pertenk;': '‱',
+ 'planckh;': 'ℎ',
+ 'pluscir;': '⨢',
+ 'plussim;': '⨦',
+ 'plustwo;': '⨧',
+ 'precsim;': '≾',
+ 'Product;': '∏',
+ 'quatint;': '⨖',
+ 'questeq;': '≟',
+ 'rarrbfs;': '⤠',
+ 'rarrsim;': '⥴',
+ 'rbrksld;': '⦎',
+ 'rbrkslu;': '⦐',
+ 'rdldhar;': '⥩',
+ 'realine;': 'ℛ',
+ 'rotimes;': '⨵',
+ 'ruluhar;': '⥨',
+ 'searrow;': '↘',
+ 'simplus;': '⨤',
+ 'simrarr;': '⥲',
+ 'subedot;': '⫃',
+ 'submult;': '⫁',
+ 'subplus;': '⪿',
+ 'subrarr;': '⥹',
+ 'succsim;': '≿',
+ 'supdsub;': '⫘',
+ 'supedot;': '⫄',
+ 'suphsol;': '⟉',
+ 'suphsub;': '⫗',
+ 'suplarr;': '⥻',
+ 'supmult;': '⫂',
+ 'supplus;': '⫀',
+ 'swarrow;': '↙',
+ 'topfork;': '⫚',
+ 'triplus;': '⨹',
+ 'tritime;': '⨻',
+ 'UpArrow;': '↑',
+ 'Uparrow;': '⇑',
+ 'uparrow;': '↑',
+ 'Upsilon;': 'Υ',
+ 'upsilon;': 'υ',
+ 'uwangle;': '⦧',
+ 'vzigzag;': '⦚',
+ 'zigrarr;': '⇝',
+ 'andslope;': '⩘',
+ 'angmsdaa;': '⦨',
+ 'angmsdab;': '⦩',
+ 'angmsdac;': '⦪',
+ 'angmsdad;': '⦫',
+ 'angmsdae;': '⦬',
+ 'angmsdaf;': '⦭',
+ 'angmsdag;': '⦮',
+ 'angmsdah;': '⦯',
+ 'angrtvbd;': '⦝',
+ 'approxeq;': '≊',
+ 'awconint;': '∳',
+ 'backcong;': '≌',
+ 'barwedge;': '⌅',
+ 'bbrktbrk;': '⎶',
+ 'bigoplus;': '⨁',
+ 'bigsqcup;': '⨆',
+ 'biguplus;': '⨄',
+ 'bigwedge;': '⋀',
+ 'boxminus;': '⊟',
+ 'boxtimes;': '⊠',
+ 'bsolhsub;': '⟈',
+ 'capbrcup;': '⩉',
+ 'circledR;': '®',
+ 'circledS;': 'Ⓢ',
+ 'cirfnint;': '⨐',
+ 'clubsuit;': '♣',
+ 'cupbrcap;': '⩈',
+ 'curlyvee;': '⋎',
+ 'cwconint;': '∲',
+ 'DDotrahd;': '⤑',
+ 'doteqdot;': '≑',
+ 'DotEqual;': '≐',
+ 'dotminus;': '∸',
+ 'drbkarow;': '⤐',
+ 'dzigrarr;': '⟿',
+ 'elinters;': '⏧',
+ 'emptyset;': '∅',
+ 'eqvparsl;': '⧥',
+ 'fpartint;': '⨍',
+ 'geqslant;': '⩾',
+ 'gesdotol;': '⪄',
+ 'gnapprox;': '⪊',
+ 'hksearow;': '⤥',
+ 'hkswarow;': '⤦',
+ 'imagline;': 'ℐ',
+ 'imagpart;': 'ℑ',
+ 'infintie;': '⧝',
+ 'integers;': 'ℤ',
+ 'Integral;': '∫',
+ 'intercal;': '⊺',
+ 'intlarhk;': '⨗',
+ 'laemptyv;': '⦴',
+ 'ldrushar;': '⥋',
+ 'leqslant;': '⩽',
+ 'lesdotor;': '⪃',
+ 'LessLess;': '⪡',
+ 'llcorner;': '⌞',
+ 'lnapprox;': '⪉',
+ 'lrcorner;': '⌟',
+ 'lurdshar;': '⥊',
+ 'mapstoup;': '↥',
+ 'multimap;': '⊸',
+ 'naturals;': 'ℕ',
+ 'ncongdot;': '⩭̸',
+ 'NotEqual;': '≠',
+ 'notindot;': '⋵̸',
+ 'NotTilde;': '≁',
+ 'otimesas;': '⨶',
+ 'parallel;': '∥',
+ 'PartialD;': '∂',
+ 'plusacir;': '⨣',
+ 'pointint;': '⨕',
+ 'Precedes;': '≺',
+ 'precneqq;': '⪵',
+ 'precnsim;': '⋨',
+ 'profalar;': '⌮',
+ 'profline;': '⌒',
+ 'profsurf;': '⌓',
+ 'raemptyv;': '⦳',
+ 'realpart;': 'ℜ',
+ 'RightTee;': '⊢',
+ 'rppolint;': '⨒',
+ 'rtriltri;': '⧎',
+ 'scpolint;': '⨓',
+ 'setminus;': '∖',
+ 'shortmid;': '∣',
+ 'smeparsl;': '⧤',
+ 'sqsubset;': '⊏',
+ 'sqsupset;': '⊐',
+ 'subseteq;': '⊆',
+ 'Succeeds;': '≻',
+ 'succneqq;': '⪶',
+ 'succnsim;': '⋩',
+ 'SuchThat;': '∋',
+ 'Superset;': '⊃',
+ 'supseteq;': '⊇',
+ 'thetasym;': 'ϑ',
+ 'thicksim;': '∼',
+ 'timesbar;': '⨱',
+ 'triangle;': '▵',
+ 'triminus;': '⨺',
+ 'trpezium;': '⏢',
+ 'Uarrocir;': '⥉',
+ 'ulcorner;': '⌜',
+ 'UnderBar;': '_',
+ 'urcorner;': '⌝',
+ 'varkappa;': 'ϰ',
+ 'varsigma;': 'ς',
+ 'vartheta;': 'ϑ',
+ 'backprime;': '‵',
+ 'backsimeq;': '⋍',
+ 'Backslash;': '∖',
+ 'bigotimes;': '⨂',
+ 'CenterDot;': '·',
+ 'centerdot;': '·',
+ 'checkmark;': '✓',
+ 'CircleDot;': '⊙',
+ 'complexes;': 'ℂ',
+ 'Congruent;': '≡',
+ 'Coproduct;': '∐',
+ 'dotsquare;': '⊡',
+ 'DoubleDot;': '¨',
+ 'DownArrow;': '↓',
+ 'Downarrow;': '⇓',
+ 'downarrow;': '↓',
+ 'DownBreve;': '̑',
+ 'gtrapprox;': '⪆',
+ 'gtreqless;': '⋛',
+ 'gvertneqq;': '≩︀',
+ 'heartsuit;': '♥',
+ 'HumpEqual;': '≏',
+ 'LeftArrow;': '←',
+ 'Leftarrow;': '⇐',
+ 'leftarrow;': '←',
+ 'LeftFloor;': '⌊',
+ 'lesseqgtr;': '⋚',
+ 'LessTilde;': '≲',
+ 'lvertneqq;': '≨︀',
+ 'Mellintrf;': 'ℳ',
+ 'MinusPlus;': '∓',
+ 'ngeqslant;': '⩾̸',
+ 'nleqslant;': '⩽̸',
+ 'NotCupCap;': '≭',
+ 'NotExists;': '∄',
+ 'NotSubset;': '⊂⃒',
+ 'nparallel;': '∦',
+ 'nshortmid;': '∤',
+ 'nsubseteq;': '⊈',
+ 'nsupseteq;': '⊉',
+ 'OverBrace;': '⏞',
+ 'pitchfork;': '⋔',
+ 'PlusMinus;': '±',
+ 'rationals;': 'ℚ',
+ 'spadesuit;': '♠',
+ 'subseteqq;': '⫅',
+ 'subsetneq;': '⊊',
+ 'supseteqq;': '⫆',
+ 'supsetneq;': '⊋',
+ 'Therefore;': '∴',
+ 'therefore;': '∴',
+ 'ThinSpace;': ' ',
+ 'triangleq;': '≜',
+ 'TripleDot;': '⃛',
+ 'UnionPlus;': '⊎',
+ 'varpropto;': '∝',
+ 'Bernoullis;': 'ℬ',
+ 'circledast;': '⊛',
+ 'CirclePlus;': '⊕',
+ 'complement;': '∁',
+ 'curlywedge;': '⋏',
+ 'eqslantgtr;': '⪖',
+ 'EqualTilde;': '≂',
+ 'Fouriertrf;': 'ℱ',
+ 'gtreqqless;': '⪌',
+ 'ImaginaryI;': 'ⅈ',
+ 'Laplacetrf;': 'ℒ',
+ 'LeftVector;': '↼',
+ 'lessapprox;': '⪅',
+ 'lesseqqgtr;': '⪋',
+ 'Lleftarrow;': '⇚',
+ 'lmoustache;': '⎰',
+ 'longmapsto;': '⟼',
+ 'mapstodown;': '↧',
+ 'mapstoleft;': '↤',
+ 'nLeftarrow;': '⇍',
+ 'nleftarrow;': '↚',
+ 'NotElement;': '∉',
+ 'NotGreater;': '≯',
+ 'nsubseteqq;': '⫅̸',
+ 'nsupseteqq;': '⫆̸',
+ 'precapprox;': '⪷',
+ 'Proportion;': '∷',
+ 'RightArrow;': '→',
+ 'Rightarrow;': '⇒',
+ 'rightarrow;': '→',
+ 'RightFloor;': '⌋',
+ 'rmoustache;': '⎱',
+ 'sqsubseteq;': '⊑',
+ 'sqsupseteq;': '⊒',
+ 'subsetneqq;': '⫋',
+ 'succapprox;': '⪸',
+ 'supsetneqq;': '⫌',
+ 'ThickSpace;': ' ',
+ 'TildeEqual;': '≃',
+ 'TildeTilde;': '≈',
+ 'UnderBrace;': '⏟',
+ 'UpArrowBar;': '⤒',
+ 'UpTeeArrow;': '↥',
+ 'upuparrows;': '⇈',
+ 'varepsilon;': 'ϵ',
+ 'varnothing;': '∅',
+ 'backepsilon;': '϶',
+ 'blacksquare;': '▪',
+ 'circledcirc;': '⊚',
+ 'circleddash;': '⊝',
+ 'CircleMinus;': '⊖',
+ 'CircleTimes;': '⊗',
+ 'curlyeqprec;': '⋞',
+ 'curlyeqsucc;': '⋟',
+ 'diamondsuit;': '♦',
+ 'eqslantless;': '⪕',
+ 'Equilibrium;': '⇌',
+ 'expectation;': 'ℰ',
+ 'GreaterLess;': '≷',
+ 'LeftCeiling;': '⌈',
+ 'LessGreater;': '≶',
+ 'MediumSpace;': ' ',
+ 'NotLessLess;': '≪̸',
+ 'NotPrecedes;': '⊀',
+ 'NotSucceeds;': '⊁',
+ 'NotSuperset;': '⊃⃒',
+ 'nRightarrow;': '⇏',
+ 'nrightarrow;': '↛',
+ 'OverBracket;': '⎴',
+ 'preccurlyeq;': '≼',
+ 'precnapprox;': '⪹',
+ 'quaternions;': 'ℍ',
+ 'RightVector;': '⇀',
+ 'Rrightarrow;': '⇛',
+ 'RuleDelayed;': '⧴',
+ 'SmallCircle;': '∘',
+ 'SquareUnion;': '⊔',
+ 'straightphi;': 'ϕ',
+ 'SubsetEqual;': '⊆',
+ 'succcurlyeq;': '≽',
+ 'succnapprox;': '⪺',
+ 'thickapprox;': '≈',
+ 'UpDownArrow;': '↕',
+ 'Updownarrow;': '⇕',
+ 'updownarrow;': '↕',
+ 'VerticalBar;': '∣',
+ 'blacklozenge;': '⧫',
+ 'DownArrowBar;': '⤓',
+ 'DownTeeArrow;': '↧',
+ 'ExponentialE;': 'ⅇ',
+ 'exponentiale;': 'ⅇ',
+ 'GreaterEqual;': '≥',
+ 'GreaterTilde;': '≳',
+ 'HilbertSpace;': 'ℋ',
+ 'HumpDownHump;': '≎',
+ 'Intersection;': '⋂',
+ 'LeftArrowBar;': '⇤',
+ 'LeftTeeArrow;': '↤',
+ 'LeftTriangle;': '⊲',
+ 'LeftUpVector;': '↿',
+ 'NotCongruent;': '≢',
+ 'NotHumpEqual;': '≏̸',
+ 'NotLessEqual;': '≰',
+ 'NotLessTilde;': '≴',
+ 'Proportional;': '∝',
+ 'RightCeiling;': '⌉',
+ 'risingdotseq;': '≓',
+ 'RoundImplies;': '⥰',
+ 'ShortUpArrow;': '↑',
+ 'SquareSubset;': '⊏',
+ 'triangledown;': '▿',
+ 'triangleleft;': '◃',
+ 'UnderBracket;': '⎵',
+ 'varsubsetneq;': '⊊︀',
+ 'varsupsetneq;': '⊋︀',
+ 'VerticalLine;': '|',
+ 'ApplyFunction;': '',
+ 'bigtriangleup;': '△',
+ 'blacktriangle;': '▴',
+ 'DifferentialD;': 'ⅆ',
+ 'divideontimes;': '⋇',
+ 'DoubleLeftTee;': '⫤',
+ 'DoubleUpArrow;': '⇑',
+ 'fallingdotseq;': '≒',
+ 'hookleftarrow;': '↩',
+ 'leftarrowtail;': '↢',
+ 'leftharpoonup;': '↼',
+ 'LeftTeeVector;': '⥚',
+ 'LeftVectorBar;': '⥒',
+ 'LessFullEqual;': '≦',
+ 'LongLeftArrow;': '⟵',
+ 'Longleftarrow;': '⟸',
+ 'longleftarrow;': '⟵',
+ 'looparrowleft;': '↫',
+ 'measuredangle;': '∡',
+ 'NotEqualTilde;': '≂̸',
+ 'NotTildeEqual;': '≄',
+ 'NotTildeTilde;': '≉',
+ 'ntriangleleft;': '⋪',
+ 'Poincareplane;': 'ℌ',
+ 'PrecedesEqual;': '⪯',
+ 'PrecedesTilde;': '≾',
+ 'RightArrowBar;': '⇥',
+ 'RightTeeArrow;': '↦',
+ 'RightTriangle;': '⊳',
+ 'RightUpVector;': '↾',
+ 'shortparallel;': '∥',
+ 'smallsetminus;': '∖',
+ 'SucceedsEqual;': '⪰',
+ 'SucceedsTilde;': '≿',
+ 'SupersetEqual;': '⊇',
+ 'triangleright;': '▹',
+ 'UpEquilibrium;': '⥮',
+ 'upharpoonleft;': '↿',
+ 'varsubsetneqq;': '⫋︀',
+ 'varsupsetneqq;': '⫌︀',
+ 'VerticalTilde;': '≀',
+ 'VeryThinSpace;': ' ',
+ 'curvearrowleft;': '↶',
+ 'DiacriticalDot;': '˙',
+ 'doublebarwedge;': '⌆',
+ 'DoubleRightTee;': '⊨',
+ 'downdownarrows;': '⇊',
+ 'DownLeftVector;': '↽',
+ 'GreaterGreater;': '⪢',
+ 'hookrightarrow;': '↪',
+ 'HorizontalLine;': '─',
+ 'InvisibleComma;': '',
+ 'InvisibleTimes;': '',
+ 'LeftDownVector;': '⇃',
+ 'leftleftarrows;': '⇇',
+ 'LeftRightArrow;': '↔',
+ 'Leftrightarrow;': '⇔',
+ 'leftrightarrow;': '↔',
+ 'leftthreetimes;': '⋋',
+ 'LessSlantEqual;': '⩽',
+ 'LongRightArrow;': '⟶',
+ 'Longrightarrow;': '⟹',
+ 'longrightarrow;': '⟶',
+ 'looparrowright;': '↬',
+ 'LowerLeftArrow;': '↙',
+ 'NestedLessLess;': '≪',
+ 'NotGreaterLess;': '≹',
+ 'NotLessGreater;': '≸',
+ 'NotSubsetEqual;': '⊈',
+ 'NotVerticalBar;': '∤',
+ 'nshortparallel;': '∦',
+ 'ntriangleright;': '⋫',
+ 'OpenCurlyQuote;': '‘',
+ 'ReverseElement;': '∋',
+ 'rightarrowtail;': '↣',
+ 'rightharpoonup;': '⇀',
+ 'RightTeeVector;': '⥛',
+ 'RightVectorBar;': '⥓',
+ 'ShortDownArrow;': '↓',
+ 'ShortLeftArrow;': '←',
+ 'SquareSuperset;': '⊐',
+ 'TildeFullEqual;': '≅',
+ 'trianglelefteq;': '⊴',
+ 'upharpoonright;': '↾',
+ 'UpperLeftArrow;': '↖',
+ 'ZeroWidthSpace;': '',
+ 'bigtriangledown;': '▽',
+ 'circlearrowleft;': '↺',
+ 'CloseCurlyQuote;': '’',
+ 'ContourIntegral;': '∮',
+ 'curvearrowright;': '↷',
+ 'DoubleDownArrow;': '⇓',
+ 'DoubleLeftArrow;': '⇐',
+ 'downharpoonleft;': '⇃',
+ 'DownRightVector;': '⇁',
+ 'leftharpoondown;': '↽',
+ 'leftrightarrows;': '⇆',
+ 'LeftRightVector;': '⥎',
+ 'LeftTriangleBar;': '⧏',
+ 'LeftUpTeeVector;': '⥠',
+ 'LeftUpVectorBar;': '⥘',
+ 'LowerRightArrow;': '↘',
+ 'nLeftrightarrow;': '⇎',
+ 'nleftrightarrow;': '↮',
+ 'NotGreaterEqual;': '≱',
+ 'NotGreaterTilde;': '≵',
+ 'NotHumpDownHump;': '≎̸',
+ 'NotLeftTriangle;': '⋪',
+ 'NotSquareSubset;': '⊏̸',
+ 'ntrianglelefteq;': '⋬',
+ 'OverParenthesis;': '⏜',
+ 'RightDownVector;': '⇂',
+ 'rightleftarrows;': '⇄',
+ 'rightsquigarrow;': '↝',
+ 'rightthreetimes;': '⋌',
+ 'ShortRightArrow;': '→',
+ 'straightepsilon;': 'ϵ',
+ 'trianglerighteq;': '⊵',
+ 'UpperRightArrow;': '↗',
+ 'vartriangleleft;': '⊲',
+ 'circlearrowright;': '↻',
+ 'DiacriticalAcute;': '´',
+ 'DiacriticalGrave;': '`',
+ 'DiacriticalTilde;': '˜',
+ 'DoubleRightArrow;': '⇒',
+ 'DownArrowUpArrow;': '⇵',
+ 'downharpoonright;': '⇂',
+ 'EmptySmallSquare;': '◻',
+ 'GreaterEqualLess;': '⋛',
+ 'GreaterFullEqual;': '≧',
+ 'LeftAngleBracket;': '⟨',
+ 'LeftUpDownVector;': '⥑',
+ 'LessEqualGreater;': '⋚',
+ 'NonBreakingSpace;': ' ',
+ 'NotPrecedesEqual;': '⪯̸',
+ 'NotRightTriangle;': '⋫',
+ 'NotSucceedsEqual;': '⪰̸',
+ 'NotSucceedsTilde;': '≿̸',
+ 'NotSupersetEqual;': '⊉',
+ 'ntrianglerighteq;': '⋭',
+ 'rightharpoondown;': '⇁',
+ 'rightrightarrows;': '⇉',
+ 'RightTriangleBar;': '⧐',
+ 'RightUpTeeVector;': '⥜',
+ 'RightUpVectorBar;': '⥔',
+ 'twoheadleftarrow;': '↞',
+ 'UnderParenthesis;': '⏝',
+ 'UpArrowDownArrow;': '⇅',
+ 'vartriangleright;': '⊳',
+ 'blacktriangledown;': '▾',
+ 'blacktriangleleft;': '◂',
+ 'DoubleUpDownArrow;': '⇕',
+ 'DoubleVerticalBar;': '∥',
+ 'DownLeftTeeVector;': '⥞',
+ 'DownLeftVectorBar;': '⥖',
+ 'FilledSmallSquare;': '◼',
+ 'GreaterSlantEqual;': '⩾',
+ 'LeftDoubleBracket;': '⟦',
+ 'LeftDownTeeVector;': '⥡',
+ 'LeftDownVectorBar;': '⥙',
+ 'leftrightharpoons;': '⇋',
+ 'LeftTriangleEqual;': '⊴',
+ 'NegativeThinSpace;': '',
+ 'NotGreaterGreater;': '≫̸',
+ 'NotLessSlantEqual;': '⩽̸',
+ 'NotNestedLessLess;': '⪡̸',
+ 'NotReverseElement;': '∌',
+ 'NotSquareSuperset;': '⊐̸',
+ 'NotTildeFullEqual;': '≇',
+ 'RightAngleBracket;': '⟩',
+ 'rightleftharpoons;': '⇌',
+ 'RightUpDownVector;': '⥏',
+ 'SquareSubsetEqual;': '⊑',
+ 'twoheadrightarrow;': '↠',
+ 'VerticalSeparator;': '❘',
+ 'blacktriangleright;': '▸',
+ 'DownRightTeeVector;': '⥟',
+ 'DownRightVectorBar;': '⥗',
+ 'LongLeftRightArrow;': '⟷',
+ 'Longleftrightarrow;': '⟺',
+ 'longleftrightarrow;': '⟷',
+ 'NegativeThickSpace;': '',
+ 'NotLeftTriangleBar;': '⧏̸',
+ 'PrecedesSlantEqual;': '≼',
+ 'ReverseEquilibrium;': '⇋',
+ 'RightDoubleBracket;': '⟧',
+ 'RightDownTeeVector;': '⥝',
+ 'RightDownVectorBar;': '⥕',
+ 'RightTriangleEqual;': '⊵',
+ 'SquareIntersection;': '⊓',
+ 'SucceedsSlantEqual;': '≽',
+ 'DoubleLongLeftArrow;': '⟸',
+ 'DownLeftRightVector;': '⥐',
+ 'LeftArrowRightArrow;': '⇆',
+ 'leftrightsquigarrow;': '↭',
+ 'NegativeMediumSpace;': '',
+ 'NotGreaterFullEqual;': '≧̸',
+ 'NotRightTriangleBar;': '⧐̸',
+ 'RightArrowLeftArrow;': '⇄',
+ 'SquareSupersetEqual;': '⊒',
+ 'CapitalDifferentialD;': 'ⅅ',
+ 'DoubleLeftRightArrow;': '⇔',
+ 'DoubleLongRightArrow;': '⟹',
+ 'EmptyVerySmallSquare;': '▫',
+ 'NestedGreaterGreater;': '≫',
+ 'NotDoubleVerticalBar;': '∦',
+ 'NotGreaterSlantEqual;': '⩾̸',
+ 'NotLeftTriangleEqual;': '⋬',
+ 'NotSquareSubsetEqual;': '⋢',
+ 'OpenCurlyDoubleQuote;': '“',
+ 'ReverseUpEquilibrium;': '⥯',
+ 'CloseCurlyDoubleQuote;': '”',
+ 'DoubleContourIntegral;': '∯',
+ 'FilledVerySmallSquare;': '▪',
+ 'NegativeVeryThinSpace;': '',
+ 'NotPrecedesSlantEqual;': '⋠',
+ 'NotRightTriangleEqual;': '⋭',
+ 'NotSucceedsSlantEqual;': '⋡',
+ 'DiacriticalDoubleAcute;': '˝',
+ 'NotSquareSupersetEqual;': '⋣',
+ 'NotNestedGreaterGreater;': '⪢̸',
+ 'ClockwiseContourIntegral;': '∲',
+ 'DoubleLongLeftRightArrow;': '⟺',
+ 'CounterClockwiseContourIntegral;': '∳'
+ }
+}