]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor: move dom-specific options to compiler-dom
authorEvan You <yyx990803@gmail.com>
Tue, 17 Sep 2019 15:07:46 +0000 (11:07 -0400)
committerEvan You <yyx990803@gmail.com>
Tue, 17 Sep 2019 15:57:37 +0000 (11:57 -0400)
packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap
packages/compiler-core/__tests__/parse.spec.ts
packages/compiler-core/src/ast.ts
packages/compiler-core/src/index.ts
packages/compiler-core/src/parser.ts
packages/compiler-core/src/parserOptionsMinimal.ts [deleted file]
packages/compiler-dom/__tests__/parse.spec.ts [new file with mode: 0644]
packages/compiler-dom/src/index.ts
packages/compiler-dom/src/parserOptionsMinimal.ts [new file with mode: 0644]
packages/compiler-dom/src/parserOptionsStandard.ts [moved from packages/compiler-core/src/parserOptionsStandard.ts with 96% similarity]

index ce41e304c1609bd52f4389db21139711c4a307ab..f488bac6adb1ec6b52707deb100996808aafe7bb 100644 (file)
@@ -1,6 +1,6 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`parser/parse invalid html 1`] = `
+exports[`base parser invalid html 1`] = `
 Object {
   "children": Array [
     Object {
@@ -72,7 +72,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option ABRUPT_CLOSING_OF_EMPTY_COMMENT <template><!--></template> 1`] = `
+exports[`base parser onError option ABRUPT_CLOSING_OF_EMPTY_COMMENT <template><!--></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -133,7 +133,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option ABRUPT_CLOSING_OF_EMPTY_COMMENT <template><!---></template> 1`] = `
+exports[`base parser onError option ABRUPT_CLOSING_OF_EMPTY_COMMENT <template><!---></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -194,7 +194,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option ABRUPT_CLOSING_OF_EMPTY_COMMENT <template><!----></template> 1`] = `
+exports[`base parser onError option ABRUPT_CLOSING_OF_EMPTY_COMMENT <template><!----></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -255,7 +255,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template attr="&#99;"></template> 1`] = `
+exports[`base parser onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template attr="&#99;"></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -334,7 +334,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template attr="&#a;"></template> 1`] = `
+exports[`base parser onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template attr="&#a;"></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -413,7 +413,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template attr="&#xff;"></template> 1`] = `
+exports[`base parser onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template attr="&#xff;"></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -492,7 +492,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template attr="&#xg;"></template> 1`] = `
+exports[`base parser onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template attr="&#xg;"></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -571,7 +571,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template>&#99;</template> 1`] = `
+exports[`base parser onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template>&#99;</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -633,7 +633,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template>&#a;</template> 1`] = `
+exports[`base parser onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template>&#a;</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -695,7 +695,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template>&#xff;</template> 1`] = `
+exports[`base parser onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template>&#xff;</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -757,7 +757,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template>&#xg;</template> 1`] = `
+exports[`base parser onError option ABSENCE_OF_DIGITS_IN_NUMERIC_CHARACTER_REFERENCE <template>&#xg;</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -819,7 +819,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option CDATA_IN_HTML_CONTENT <template><![CDATA[cdata]]></template> 1`] = `
+exports[`base parser onError option CDATA_IN_HTML_CONTENT <template><![CDATA[cdata]]></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -880,7 +880,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option CDATA_IN_HTML_CONTENT <template><svg><![CDATA[cdata]]></svg></template> 1`] = `
+exports[`base parser onError option CDATA_IN_HTML_CONTENT <template><svg><![CDATA[cdata]]></svg></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -965,7 +965,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option CHARACTER_REFERENCE_OUTSIDE_UNICODE_RANGE <template>&#1234567;</template> 1`] = `
+exports[`base parser onError option CHARACTER_REFERENCE_OUTSIDE_UNICODE_RANGE <template>&#1234567;</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1027,7 +1027,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option CONTROL_CHARACTER_REFERENCE <template>&#0003;</template> 1`] = `
+exports[`base parser onError option CONTROL_CHARACTER_REFERENCE <template>&#0003;</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1089,7 +1089,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option CONTROL_CHARACTER_REFERENCE <template>&#x7F;</template> 1`] = `
+exports[`base parser onError option CONTROL_CHARACTER_REFERENCE <template>&#x7F;</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1151,7 +1151,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option DUPLICATE_ATTRIBUTE <template><div id="" id=""></div></template> 1`] = `
+exports[`base parser onError option DUPLICATE_ATTRIBUTE <template><div id="" id=""></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1288,7 +1288,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option END_TAG_WITH_ATTRIBUTES <template><div></div id=""></template> 1`] = `
+exports[`base parser onError option END_TAG_WITH_ATTRIBUTES <template><div></div id=""></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1354,7 +1354,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option END_TAG_WITH_TRAILING_SOLIDUS <template><div></div/></template> 1`] = `
+exports[`base parser onError option END_TAG_WITH_TRAILING_SOLIDUS <template><div></div/></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1420,7 +1420,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_BEFORE_TAG_NAME <template>< 1`] = `
+exports[`base parser onError option EOF_BEFORE_TAG_NAME <template>< 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1482,7 +1482,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_BEFORE_TAG_NAME <template></ 1`] = `
+exports[`base parser onError option EOF_BEFORE_TAG_NAME <template></ 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1544,7 +1544,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_CDATA <template><svg><![CDATA[ 1`] = `
+exports[`base parser onError option EOF_IN_CDATA <template><svg><![CDATA[ 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1610,7 +1610,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_CDATA <template><svg><![CDATA[cdata 1`] = `
+exports[`base parser onError option EOF_IN_CDATA <template><svg><![CDATA[cdata 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1695,7 +1695,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_COMMENT <template><! 1`] = `
+exports[`base parser onError option EOF_IN_COMMENT <template><! 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1756,7 +1756,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_COMMENT <template><!- 1`] = `
+exports[`base parser onError option EOF_IN_COMMENT <template><!- 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1817,7 +1817,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_COMMENT <template><!-- 1`] = `
+exports[`base parser onError option EOF_IN_COMMENT <template><!-- 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1878,7 +1878,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_COMMENT <template><!--comment 1`] = `
+exports[`base parser onError option EOF_IN_COMMENT <template><!--comment 1`] = `
 Object {
   "children": Array [
     Object {
@@ -1939,7 +1939,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_COMMENT <template><!abc 1`] = `
+exports[`base parser onError option EOF_IN_COMMENT <template><!abc 1`] = `
 Object {
   "children": Array [
     Object {
@@ -2000,7 +2000,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT <script><!--console.log('hello') 1`] = `
+exports[`base parser onError option EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT <script><!--console.log('hello') 1`] = `
 Object {
   "children": Array [
     Object {
@@ -2062,7 +2062,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT <script>console.log('hello') 1`] = `
+exports[`base parser onError option EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT <script>console.log('hello') 1`] = `
 Object {
   "children": Array [
     Object {
@@ -2124,7 +2124,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_TAG <template><div  1`] = `
+exports[`base parser onError option EOF_IN_TAG <template><div  1`] = `
 Object {
   "children": Array [
     Object {
@@ -2190,7 +2190,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_TAG <template><div 1`] = `
+exports[`base parser onError option EOF_IN_TAG <template><div 1`] = `
 Object {
   "children": Array [
     Object {
@@ -2256,7 +2256,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_TAG <template><div id  1`] = `
+exports[`base parser onError option EOF_IN_TAG <template><div id  1`] = `
 Object {
   "children": Array [
     Object {
@@ -2341,7 +2341,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_TAG <template><div id = 1`] = `
+exports[`base parser onError option EOF_IN_TAG <template><div id = 1`] = `
 Object {
   "children": Array [
     Object {
@@ -2426,7 +2426,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_TAG <template><div id 1`] = `
+exports[`base parser onError option EOF_IN_TAG <template><div id 1`] = `
 Object {
   "children": Array [
     Object {
@@ -2511,7 +2511,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_TAG <template><div id="abc 1`] = `
+exports[`base parser onError option EOF_IN_TAG <template><div id="abc 1`] = `
 Object {
   "children": Array [
     Object {
@@ -2613,7 +2613,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_TAG <template><div id="abc" 1`] = `
+exports[`base parser onError option EOF_IN_TAG <template><div id="abc" 1`] = `
 Object {
   "children": Array [
     Object {
@@ -2715,7 +2715,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_TAG <template><div id="abc"/ 1`] = `
+exports[`base parser onError option EOF_IN_TAG <template><div id="abc"/ 1`] = `
 Object {
   "children": Array [
     Object {
@@ -2817,7 +2817,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_TAG <template><div id='abc 1`] = `
+exports[`base parser onError option EOF_IN_TAG <template><div id='abc 1`] = `
 Object {
   "children": Array [
     Object {
@@ -2919,7 +2919,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_TAG <template><div id='abc' 1`] = `
+exports[`base parser onError option EOF_IN_TAG <template><div id='abc' 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3021,7 +3021,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_TAG <template><div id='abc'/ 1`] = `
+exports[`base parser onError option EOF_IN_TAG <template><div id='abc'/ 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3123,7 +3123,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_TAG <template><div id=abc / 1`] = `
+exports[`base parser onError option EOF_IN_TAG <template><div id=abc / 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3225,7 +3225,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option EOF_IN_TAG <template><div id=abc 1`] = `
+exports[`base parser onError option EOF_IN_TAG <template><div id=abc 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3327,7 +3327,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option INCORRECTLY_CLOSED_COMMENT <template><!--comment--!></template> 1`] = `
+exports[`base parser onError option INCORRECTLY_CLOSED_COMMENT <template><!--comment--!></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3388,7 +3388,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option INCORRECTLY_OPENED_COMMENT <!DOCTYPE html> 1`] = `
+exports[`base parser onError option INCORRECTLY_OPENED_COMMENT <!DOCTYPE html> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3426,7 +3426,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option INCORRECTLY_OPENED_COMMENT <template><!></template> 1`] = `
+exports[`base parser onError option INCORRECTLY_OPENED_COMMENT <template><!></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3487,7 +3487,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option INCORRECTLY_OPENED_COMMENT <template><!-></template> 1`] = `
+exports[`base parser onError option INCORRECTLY_OPENED_COMMENT <template><!-></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3548,7 +3548,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option INCORRECTLY_OPENED_COMMENT <template><!ELEMENT br EMPTY></template> 1`] = `
+exports[`base parser onError option INCORRECTLY_OPENED_COMMENT <template><!ELEMENT br EMPTY></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3609,7 +3609,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template></�></template> 1`] = `
+exports[`base parser onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template></�></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3670,7 +3670,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template><�></template> 1`] = `
+exports[`base parser onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template><�></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3732,7 +3732,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template>{{a < b}}</template> 1`] = `
+exports[`base parser onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template>{{a < b}}</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3794,7 +3794,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template>a < b</template> 1`] = `
+exports[`base parser onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template>a < b</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3856,7 +3856,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template>a </ b</template> 1`] = `
+exports[`base parser onError option INVALID_FIRST_CHARACTER_OF_TAG_NAME <template>a </ b</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -3935,7 +3935,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option MISSING_ATTRIBUTE_VALUE <template><div id= /></div></template> 1`] = `
+exports[`base parser onError option MISSING_ATTRIBUTE_VALUE <template><div id= /></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -4037,7 +4037,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option MISSING_ATTRIBUTE_VALUE <template><div id= ></div></template> 1`] = `
+exports[`base parser onError option MISSING_ATTRIBUTE_VALUE <template><div id= ></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -4122,7 +4122,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option MISSING_ATTRIBUTE_VALUE <template><div id=></div></template> 1`] = `
+exports[`base parser onError option MISSING_ATTRIBUTE_VALUE <template><div id=></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -4207,7 +4207,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option MISSING_END_TAG_NAME <template></></template> 1`] = `
+exports[`base parser onError option MISSING_END_TAG_NAME <template></></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -4250,7 +4250,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE <template>&#40</template> 1`] = `
+exports[`base parser onError option MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE <template>&#40</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -4312,7 +4312,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE <template>&#x40</template> 1`] = `
+exports[`base parser onError option MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE <template>&#x40</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -4374,7 +4374,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE <template>&amp</template> 1`] = `
+exports[`base parser onError option MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE <template>&amp</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -4436,7 +4436,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option MISSING_WHITESPACE_BETWEEN_ATTRIBUTES <template><div id="foo"\\x0d;\\x0a;class="bar"></div></template> 1`] = `
+exports[`base parser onError option MISSING_WHITESPACE_BETWEEN_ATTRIBUTES <template><div id="foo"\\x0d;\\x0a;class="bar"></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -4576,7 +4576,7 @@ class=\\"bar\\"></div></template>",
 }
 `;
 
-exports[`parser/parse onError option MISSING_WHITESPACE_BETWEEN_ATTRIBUTES <template><div id="foo"class="bar"></div></template> 1`] = `
+exports[`base parser onError option MISSING_WHITESPACE_BETWEEN_ATTRIBUTES <template><div id="foo"class="bar"></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -4713,7 +4713,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option NESTED_COMMENT <template><!--a<!-- 1`] = `
+exports[`base parser onError option NESTED_COMMENT <template><!--a<!-- 1`] = `
 Object {
   "children": Array [
     Object {
@@ -4774,7 +4774,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option NESTED_COMMENT <template><!--a<!--></template> 1`] = `
+exports[`base parser onError option NESTED_COMMENT <template><!--a<!--></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -4835,7 +4835,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option NESTED_COMMENT <template><!--a<!--b<!--c--></template> 1`] = `
+exports[`base parser onError option NESTED_COMMENT <template><!--a<!--b<!--c--></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -4896,7 +4896,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option NESTED_COMMENT <template><!--a<!--b--></template> 1`] = `
+exports[`base parser onError option NESTED_COMMENT <template><!--a<!--b--></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -4957,7 +4957,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option NONCHARACTER_CHARACTER_REFERENCE <template>&#x1FFFF;</template> 1`] = `
+exports[`base parser onError option NONCHARACTER_CHARACTER_REFERENCE <template>&#x1FFFF;</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -5019,7 +5019,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option NONCHARACTER_CHARACTER_REFERENCE <template>&#xFFFE;</template> 1`] = `
+exports[`base parser onError option NONCHARACTER_CHARACTER_REFERENCE <template>&#xFFFE;</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -5081,7 +5081,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option NULL_CHARACTER_REFERENCE <template>&#0000;</template> 1`] = `
+exports[`base parser onError option NULL_CHARACTER_REFERENCE <template>&#0000;</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -5143,7 +5143,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option SURROGATE_CHARACTER_REFERENCE <template>&#xD800;</template> 1`] = `
+exports[`base parser onError option SURROGATE_CHARACTER_REFERENCE <template>&#xD800;</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -5205,7 +5205,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME <template><div a"bc=''></div></template> 1`] = `
+exports[`base parser onError option UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME <template><div a"bc=''></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -5307,7 +5307,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME <template><div a'bc=''></div></template> 1`] = `
+exports[`base parser onError option UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME <template><div a'bc=''></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -5409,7 +5409,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME <template><div a<bc=''></div></template> 1`] = `
+exports[`base parser onError option UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME <template><div a<bc=''></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -5511,7 +5511,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar"></div></template> 1`] = `
+exports[`base parser onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar"></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -5613,7 +5613,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar'></div></template> 1`] = `
+exports[`base parser onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar'></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -5715,7 +5715,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar<div></div></template> 1`] = `
+exports[`base parser onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar<div></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -5817,7 +5817,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar=baz></div></template> 1`] = `
+exports[`base parser onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar=baz></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -5919,7 +5919,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar\`></div></template> 1`] = `
+exports[`base parser onError option UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE <template><div foo=bar\`></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6021,7 +6021,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME <template><div =></div></template> 1`] = `
+exports[`base parser onError option UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME <template><div =></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6106,7 +6106,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME <template><div =foo=bar></div></template> 1`] = `
+exports[`base parser onError option UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME <template><div =foo=bar></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6208,7 +6208,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME <template><?xml?></template> 1`] = `
+exports[`base parser onError option UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME <template><?xml?></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6269,7 +6269,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option UNEXPECTED_SOLIDUS_IN_TAG <template><div a/b></div></template> 1`] = `
+exports[`base parser onError option UNEXPECTED_SOLIDUS_IN_TAG <template><div a/b></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6372,7 +6372,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option UNKNOWN_NAMED_CHARACTER_REFERENCE <template>&unknown;</template> 1`] = `
+exports[`base parser onError option UNKNOWN_NAMED_CHARACTER_REFERENCE <template>&unknown;</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6434,7 +6434,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option X_INVALID_END_TAG <svg><![CDATA[</div>]]></svg> 1`] = `
+exports[`base parser onError option X_INVALID_END_TAG <svg><![CDATA[</div>]]></svg> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6496,7 +6496,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option X_INVALID_END_TAG <svg><!--</div>--></svg> 1`] = `
+exports[`base parser onError option X_INVALID_END_TAG <svg><!--</div>--></svg> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6557,7 +6557,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option X_INVALID_END_TAG <template></div></div></template> 1`] = `
+exports[`base parser onError option X_INVALID_END_TAG <template></div></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6600,7 +6600,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option X_INVALID_END_TAG <template></div></template> 1`] = `
+exports[`base parser onError option X_INVALID_END_TAG <template></div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6643,7 +6643,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option X_INVALID_END_TAG <template>{{'</div>'}}</template> 1`] = `
+exports[`base parser onError option X_INVALID_END_TAG <template>{{'</div>'}}</template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6705,7 +6705,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option X_INVALID_END_TAG <textarea></div></textarea> 1`] = `
+exports[`base parser onError option X_INVALID_END_TAG <textarea></div></textarea> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6767,7 +6767,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option X_MISSING_END_TAG <template><div> 1`] = `
+exports[`base parser onError option X_MISSING_END_TAG <template><div> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6833,7 +6833,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option X_MISSING_END_TAG <template><div></template> 1`] = `
+exports[`base parser onError option X_MISSING_END_TAG <template><div></template> 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6899,7 +6899,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option X_MISSING_INTERPOLATION_END {{ 1`] = `
+exports[`base parser onError option X_MISSING_INTERPOLATION_END {{ 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6938,7 +6938,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option X_MISSING_INTERPOLATION_END {{ foo 1`] = `
+exports[`base parser onError option X_MISSING_INTERPOLATION_END {{ foo 1`] = `
 Object {
   "children": Array [
     Object {
@@ -6977,7 +6977,7 @@ Object {
 }
 `;
 
-exports[`parser/parse onError option X_MISSING_INTERPOLATION_END {{}} 1`] = `
+exports[`base parser onError option X_MISSING_INTERPOLATION_END {{}} 1`] = `
 Object {
   "children": Array [
     Object {
@@ -7016,7 +7016,7 @@ Object {
 }
 `;
 
-exports[`parser/parse self closing multiple tag 1`] = `
+exports[`base parser self closing multiple tag 1`] = `
 Object {
   "children": Array [
     Object {
@@ -7192,7 +7192,7 @@ Object {
 }
 `;
 
-exports[`parser/parse valid html 1`] = `
+exports[`base parser valid html 1`] = `
 Object {
   "children": Array [
     Object {
index 8879c454d0abbd0a9fd1e8b76216c61f48e81317..20d3c1af5d9b1d1446155be2d13332b0c4df8c1a 100644 (file)
@@ -1,6 +1,6 @@
-import { parse, ParserOptions } from '../src/parser'
+import { parse, ParserOptions, TextModes } from '../src/parser'
+import { ParserErrorTypes } from '../src/errorTypes'
 import {
-  AttributeNode,
   CommentNode,
   DirectiveNode,
   ElementNode,
@@ -11,13 +11,11 @@ import {
   Position,
   TextNode
 } from '../src/ast'
-import { ParserErrorTypes } from '../src/errorTypes'
-import { parserOptionsMinimal as parserOptions } from '../src/parserOptionsMinimal'
 
-describe('parser/parse', () => {
+describe('base parser', () => {
   describe('Text', () => {
     test('simple text', () => {
-      const ast = parse('some text', parserOptions)
+      const ast = parse('some text')
       const text = ast.children[0] as TextNode
 
       expect(text).toStrictEqual({
@@ -34,7 +32,6 @@ describe('parser/parse', () => {
 
     test('simple text with invalid end tag', () => {
       const ast = parse('some text</div>', {
-        ...parserOptions,
         onError: () => {}
       })
       const text = ast.children[0] as TextNode
@@ -52,7 +49,7 @@ describe('parser/parse', () => {
     })
 
     test('text with interpolation', () => {
-      const ast = parse('some {{ foo + bar }} text', parserOptions)
+      const ast = parse('some {{ foo + bar }} text')
       const text1 = ast.children[0] as TextNode
       const text2 = ast.children[2] as TextNode
 
@@ -79,7 +76,7 @@ describe('parser/parse', () => {
     })
 
     test('text with interpolation which has `<`', () => {
-      const ast = parse('some {{ a<b && c>d }} text', parserOptions)
+      const ast = parse('some {{ a<b && c>d }} text')
       const text1 = ast.children[0] as TextNode
       const text2 = ast.children[2] as TextNode
 
@@ -106,10 +103,7 @@ describe('parser/parse', () => {
     })
 
     test('text with mix of tags and interpolations', () => {
-      const ast = parse(
-        'some <span>{{ foo < bar + foo }} text</span>',
-        parserOptions
-      )
+      const ast = parse('some <span>{{ foo < bar + foo }} text</span>')
       const text1 = ast.children[0] as TextNode
       const text2 = (ast.children[1] as ElementNode).children![1] as TextNode
 
@@ -135,25 +129,8 @@ describe('parser/parse', () => {
       })
     })
 
-    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
@@ -178,7 +155,6 @@ describe('parser/parse', () => {
 
     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}`)
@@ -199,163 +175,9 @@ describe('parser/parse', () => {
       })
     })
 
-    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>&amp;</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: '&amp;'
-        }
-      })
-    })
-
-    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>&amp;</style>', parserOptions)
-      const element = ast.children[0] as ElementNode
-      const text = element.children[0] as TextNode
-
-      expect(text).toStrictEqual({
-        type: NodeTypes.TEXT,
-        content: '&amp;',
-        isEmpty: false,
-        loc: {
-          start: { offset: 7, line: 1, column: 8 },
-          end: { offset: 12, line: 1, column: 13 },
-          source: '&amp;'
-        }
-      })
-    })
-
-    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('&ampersand;', {
-        ...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: '&ampersand;'
-        }
-      })
-      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="&ampersand;" b="&amp;ersand;" c="&amp!"></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: '&ampersand;',
-        isEmpty: false,
-        loc: {
-          start: { offset: 7, line: 1, column: 8 },
-          end: { offset: 20, line: 1, column: 21 },
-          source: '"&ampersand;"'
-        }
-      })
-      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: '"&amp;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: '"&amp!"'
-        }
-      })
-      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('&#x86;', { ...parserOptions, onError: spy })
+      const ast = parse('&#x86;', { onError: spy })
       const text = ast.children[0] as TextNode
 
       expect(text).toStrictEqual({
@@ -379,7 +201,7 @@ describe('parser/parse', () => {
 
   describe('Interpolation', () => {
     test('simple interpolation', () => {
-      const ast = parse('{{message}}', parserOptions)
+      const ast = parse('{{message}}')
       const interpolation = ast.children[0] as ExpressionNode
 
       expect(interpolation).toStrictEqual({
@@ -395,7 +217,7 @@ describe('parser/parse', () => {
     })
 
     test('it can have tag-like notation', () => {
-      const ast = parse('{{ a<b }}', parserOptions)
+      const ast = parse('{{ a<b }}')
       const interpolation = ast.children[0] as ExpressionNode
 
       expect(interpolation).toStrictEqual({
@@ -411,7 +233,7 @@ describe('parser/parse', () => {
     })
 
     test('it can have tag-like notation (2)', () => {
-      const ast = parse('{{ a<b }}{{ c>d }}', parserOptions)
+      const ast = parse('{{ a<b }}{{ c>d }}')
       const interpolation1 = ast.children[0] as ExpressionNode
       const interpolation2 = ast.children[1] as ExpressionNode
 
@@ -438,7 +260,7 @@ describe('parser/parse', () => {
     })
 
     test('it can have tag-like notation (3)', () => {
-      const ast = parse('<div>{{ "</div>" }}</div>', parserOptions)
+      const ast = parse('<div>{{ "</div>" }}</div>')
       const element = ast.children[0] as ElementNode
       const interpolation = element.children[0] as ExpressionNode
 
@@ -453,28 +275,11 @@ describe('parser/parse', () => {
         }
       })
     })
-
-    test('HTML entities in interpolation should be translated for backward compatibility.', () => {
-      const ast = parse('<div>{{ a &lt; 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 &lt; b }}'
-        }
-      })
-    })
   })
 
   describe('Comment', () => {
     test('empty comment', () => {
-      const ast = parse('<!---->', parserOptions)
+      const ast = parse('<!---->')
       const comment = ast.children[0] as CommentNode
 
       expect(comment).toStrictEqual({
@@ -489,7 +294,7 @@ describe('parser/parse', () => {
     })
 
     test('simple comment', () => {
-      const ast = parse('<!--abc-->', parserOptions)
+      const ast = parse('<!--abc-->')
       const comment = ast.children[0] as CommentNode
 
       expect(comment).toStrictEqual({
@@ -504,7 +309,7 @@ describe('parser/parse', () => {
     })
 
     test('two comments', () => {
-      const ast = parse('<!--abc--><!--def-->', parserOptions)
+      const ast = parse('<!--abc--><!--def-->')
       const comment1 = ast.children[0] as CommentNode
       const comment2 = ast.children[1] as CommentNode
 
@@ -531,7 +336,7 @@ describe('parser/parse', () => {
 
   describe('Element', () => {
     test('simple div', () => {
-      const ast = parse('<div>hello</div>', parserOptions)
+      const ast = parse('<div>hello</div>')
       const element = ast.children[0] as ElementNode
 
       expect(element).toStrictEqual({
@@ -562,7 +367,7 @@ describe('parser/parse', () => {
     })
 
     test('empty', () => {
-      const ast = parse('<div></div>', parserOptions)
+      const ast = parse('<div></div>')
       const element = ast.children[0] as ElementNode
 
       expect(element).toStrictEqual({
@@ -582,7 +387,7 @@ describe('parser/parse', () => {
     })
 
     test('self closing', () => {
-      const ast = parse('<div/>after', parserOptions)
+      const ast = parse('<div/>after')
       const element = ast.children[0] as ElementNode
 
       expect(element).toStrictEqual({
@@ -602,7 +407,9 @@ describe('parser/parse', () => {
     })
 
     test('void element', () => {
-      const ast = parse('<img>after', parserOptions)
+      const ast = parse('<img>after', {
+        isVoidTag: tag => tag === 'img'
+      })
       const element = ast.children[0] as ElementNode
 
       expect(element).toStrictEqual({
@@ -622,7 +429,7 @@ describe('parser/parse', () => {
     })
 
     test('attribute with no value', () => {
-      const ast = parse('<div id></div>', parserOptions)
+      const ast = parse('<div id></div>')
       const element = ast.children[0] as ElementNode
 
       expect(element).toStrictEqual({
@@ -653,7 +460,7 @@ describe('parser/parse', () => {
     })
 
     test('attribute with empty value, double quote', () => {
-      const ast = parse('<div id=""></div>', parserOptions)
+      const ast = parse('<div id=""></div>')
       const element = ast.children[0] as ElementNode
 
       expect(element).toStrictEqual({
@@ -693,7 +500,7 @@ describe('parser/parse', () => {
     })
 
     test('attribute with empty value, single quote', () => {
-      const ast = parse("<div id=''></div>", parserOptions)
+      const ast = parse("<div id=''></div>")
       const element = ast.children[0] as ElementNode
 
       expect(element).toStrictEqual({
@@ -733,7 +540,7 @@ describe('parser/parse', () => {
     })
 
     test('attribute with value, double quote', () => {
-      const ast = parse('<div id=">\'"></div>', parserOptions)
+      const ast = parse('<div id=">\'"></div>')
       const element = ast.children[0] as ElementNode
 
       expect(element).toStrictEqual({
@@ -773,7 +580,7 @@ describe('parser/parse', () => {
     })
 
     test('attribute with value, single quote', () => {
-      const ast = parse("<div id='>\"'></div>", parserOptions)
+      const ast = parse("<div id='>\"'></div>")
       const element = ast.children[0] as ElementNode
 
       expect(element).toStrictEqual({
@@ -813,7 +620,7 @@ describe('parser/parse', () => {
     })
 
     test('attribute with value, unquoted', () => {
-      const ast = parse('<div id=a/></div>', parserOptions)
+      const ast = parse('<div id=a/></div>')
       const element = ast.children[0] as ElementNode
 
       expect(element).toStrictEqual({
@@ -853,10 +660,7 @@ describe('parser/parse', () => {
     })
 
     test('multiple attributes', () => {
-      const ast = parse(
-        '<div id=a class="c" inert style=\'\'></div>',
-        parserOptions
-      )
+      const ast = parse('<div id=a class="c" inert style=\'\'></div>')
       const element = ast.children[0] as ElementNode
 
       expect(element).toStrictEqual({
@@ -944,7 +748,7 @@ describe('parser/parse', () => {
     })
 
     test('directive with no value', () => {
-      const ast = parse('<div v-if/>', parserOptions)
+      const ast = parse('<div v-if/>')
       const directive = (ast.children[0] as ElementNode)
         .props[0] as DirectiveNode
 
@@ -963,7 +767,7 @@ describe('parser/parse', () => {
     })
 
     test('directive with value', () => {
-      const ast = parse('<div v-if="a"/>', parserOptions)
+      const ast = parse('<div v-if="a"/>')
       const directive = (ast.children[0] as ElementNode)
         .props[0] as DirectiveNode
 
@@ -991,7 +795,7 @@ describe('parser/parse', () => {
     })
 
     test('directive with argument', () => {
-      const ast = parse('<div v-on:click/>', parserOptions)
+      const ast = parse('<div v-on:click/>')
       const directive = (ast.children[0] as ElementNode)
         .props[0] as DirectiveNode
 
@@ -1027,7 +831,7 @@ describe('parser/parse', () => {
     })
 
     test('directive with a modifier', () => {
-      const ast = parse('<div v-on.enter/>', parserOptions)
+      const ast = parse('<div v-on.enter/>')
       const directive = (ast.children[0] as ElementNode)
         .props[0] as DirectiveNode
 
@@ -1046,7 +850,7 @@ describe('parser/parse', () => {
     })
 
     test('directive with two modifiers', () => {
-      const ast = parse('<div v-on.enter.exact/>', parserOptions)
+      const ast = parse('<div v-on.enter.exact/>')
       const directive = (ast.children[0] as ElementNode)
         .props[0] as DirectiveNode
 
@@ -1065,7 +869,7 @@ describe('parser/parse', () => {
     })
 
     test('directive with argument and modifiers', () => {
-      const ast = parse('<div v-on:click.enter.exact/>', parserOptions)
+      const ast = parse('<div v-on:click.enter.exact/>')
       const directive = (ast.children[0] as ElementNode)
         .props[0] as DirectiveNode
 
@@ -1101,7 +905,7 @@ describe('parser/parse', () => {
     })
 
     test('v-bind shorthand', () => {
-      const ast = parse('<div :a=b />', parserOptions)
+      const ast = parse('<div :a=b />')
       const directive = (ast.children[0] as ElementNode)
         .props[0] as DirectiveNode
 
@@ -1146,7 +950,7 @@ describe('parser/parse', () => {
     })
 
     test('v-bind shorthand with modifier', () => {
-      const ast = parse('<div :a.sync=b />', parserOptions)
+      const ast = parse('<div :a.sync=b />')
       const directive = (ast.children[0] as ElementNode)
         .props[0] as DirectiveNode
 
@@ -1191,7 +995,7 @@ describe('parser/parse', () => {
     })
 
     test('v-on shorthand', () => {
-      const ast = parse('<div @a=b />', parserOptions)
+      const ast = parse('<div @a=b />')
       const directive = (ast.children[0] as ElementNode)
         .props[0] as DirectiveNode
 
@@ -1236,7 +1040,7 @@ describe('parser/parse', () => {
     })
 
     test('v-on shorthand with modifier', () => {
-      const ast = parse('<div @a.enter=b />', parserOptions)
+      const ast = parse('<div @a.enter=b />')
       const directive = (ast.children[0] as ElementNode)
         .props[0] as DirectiveNode
 
@@ -1281,7 +1085,7 @@ describe('parser/parse', () => {
     })
 
     test('end tags are case-insensitive.', () => {
-      const ast = parse('<div>hello</DIV>after', parserOptions)
+      const ast = parse('<div>hello</DIV>after')
       const element = ast.children[0] as ElementNode
       const text = element.children[0] as TextNode
 
@@ -1296,38 +1100,10 @@ describe('parser/parse', () => {
         }
       })
     })
-
-    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)
+    const ast = parse('<div :class="{ some: condition }" />')
 
     expect(ast.children).toHaveLength(1)
     expect(ast.children[0]).toMatchObject({ tag: 'div' })
@@ -1336,8 +1112,7 @@ describe('parser/parse', () => {
   test('self closing multiple tag', () => {
     const ast = parse(
       `<div :class="{ some: condition }" />\n` +
-        `<p v-bind:style="{ color: 'red' }"/>`,
-      parserOptions
+        `<p v-bind:style="{ color: 'red' }"/>`
     )
 
     expect(ast).toMatchSnapshot()
@@ -1352,8 +1127,7 @@ describe('parser/parse', () => {
       `<div :class="{ some: condition }">\n` +
         `  <p v-bind:style="{ color: 'red' }"/>\n` +
         `  <!-- a comment with <html> inside it -->\n` +
-        `</div>`,
-      parserOptions
+        `</div>`
     )
 
     expect(ast).toMatchSnapshot()
@@ -1374,12 +1148,11 @@ describe('parser/parse', () => {
 
   test('invalid html', () => {
     expect(() => {
-      parse(`<div>\n<span>\n</div>\n</span>`, parserOptions)
+      parse(`<div>\n<span>\n</div>\n</span>`)
     }).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
     })
 
@@ -1398,8 +1171,7 @@ describe('parser/parse', () => {
 
   test('parse with correct location info', () => {
     const [foo, bar, but, baz] = parse(
-      'foo \n is {{ bar }} but {{ baz }}',
-      parserOptions
+      'foo \n is {{ bar }} but {{ baz }}'
     ).children
 
     let offset = 0
@@ -1423,7 +1195,6 @@ describe('parser/parse', () => {
   describe('namedCharacterReferences option', () => {
     test('use the given map', () => {
       const ast: any = parse('&amp;&cups;', {
-        ...parserOptions,
         namedCharacterReferences: {
           'cups;': '\u222A\uFE00' // UNION with serifs
         },
@@ -1436,7 +1207,7 @@ describe('parser/parse', () => {
     })
   })
 
-  describe('onError option', () => {
+  describe('Errors', () => {
     const patterns: {
       [key: string]: Array<{
         code: string
@@ -2499,7 +2270,24 @@ describe('parser/parse', () => {
             () => {
               const spy = jest.fn()
               const ast = parse(code, {
-                ...parserOptions,
+                getNamespace: (tag, parent) => {
+                  const ns = parent ? parent.ns : Namespaces.HTML
+                  if (ns === Namespaces.HTML) {
+                    if (tag === 'svg') {
+                      return (Namespaces.HTML + 1) as any
+                    }
+                  }
+                  return ns
+                },
+                getTextMode: tag => {
+                  if (tag === 'textarea') {
+                    return TextModes.RCDATA
+                  }
+                  if (tag === 'script') {
+                    return TextModes.RAWTEXT
+                  }
+                  return TextModes.DATA
+                },
                 ...options,
                 onError: spy
               })
index 8941e2b347e814e670b2da5cc9a9dd641405a2ab..72049ba48c86a86b2d6388b71e3cfaee30153a68 100644 (file)
@@ -1,3 +1,12 @@
+// Vue template is a platform-agnostic superset of HTML (syntax only).
+// More namespaces like SVG and MathML are declared by platform specific
+// compilers.
+export type Namespace = number
+
+export const enum Namespaces {
+  HTML
+}
+
 export const enum NodeTypes {
   TEXT,
   COMMENT,
@@ -15,12 +24,6 @@ export const enum ElementTypes {
   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
@@ -33,7 +36,7 @@ export interface RootNode extends Node {
 
 export interface ElementNode extends Node {
   type: NodeTypes.ELEMENT
-  ns: Namespaces
+  ns: Namespace
   tag: string
   tagType: ElementTypes
   isSelfClosing: boolean
index 2e25f608b27eecff9698344563985c7acbf3a581..d6bb179e9cd41f0d289302cfb13d4f8e33bd506b 100644 (file)
@@ -1,3 +1,3 @@
-export { parse } from './parser'
+export { parse, ParserOptions, TextModes } from './parser'
 export * from './ast'
 export * from './errorTypes'
index 90587389d6a5bd1d7a174a443b83faa60e02e9a4..7c3edc85a451f0b6a2719ee22b59adf704724a4d 100644 (file)
@@ -1,13 +1,13 @@
-import { ParserErrorTypes } from './errorTypes'
+import { ParserErrorTypes, errorMessages } from './errorTypes'
 import {
-  Node,
+  Namespace,
+  Namespaces,
   AttributeNode,
   CommentNode,
   DirectiveNode,
   ElementNode,
   ElementTypes,
   ExpressionNode,
-  Namespaces,
   NodeTypes,
   Position,
   RootNode,
@@ -16,30 +16,46 @@ import {
 } 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
+  isVoidTag?: (tag: string) => boolean // e.g. img, br, hr
+  getNamespace?: (tag: string, parent: ElementNode | undefined) => Namespace
+  getTextMode?: (tag: string, ns: Namespace) => TextModes
+  delimiters?: [string, string] // ['{{', '}}']
+  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 }
+  namedCharacterReferences?: { [name: string]: string | undefined }
 
-  onError: (type: ParserErrorTypes, loc: Position) => void
+  onError?: (type: ParserErrorTypes, loc: Position) => void
+}
+
+export const defaultParserOptions: Required<ParserOptions> = {
+  delimiters: [`{{`, `}}`],
+  ignoreSpaces: true,
+  getNamespace: () => Namespaces.HTML,
+  getTextMode: () => TextModes.DATA,
+  isVoidTag: () => false,
+  namedCharacterReferences: {},
+  onError(code: ParserErrorTypes, loc: Position): void {
+    const error: any = new SyntaxError(
+      `${errorMessages[code]} (${loc.line}:${loc.column})`
+    )
+    error.code = code
+    error.loc = loc
+    throw error
+  }
 }
 
 export const enum TextModes {
-  // | Elements | Entities | End sign              | Inside of
-  DATA, // | ✔       | ✔       | End tags of ancestors |
-  RCDATA, // | ✘       | ✔       | End tag of the parent | <textarea>
+  //          | 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 {
+interface ParserContext extends Required<ParserOptions> {
   readonly originalSource: string
   source: string
   offset: number
@@ -48,7 +64,7 @@ interface ParserContext extends ParserOptions {
   maxCRNameLength: number
 }
 
-export function parse(content: string, options: ParserOptions): RootNode {
+export function parse(content: string, options: ParserOptions = {}): RootNode {
   const context = createParserContext(content, options)
   const start = getCursor(context)
 
@@ -64,16 +80,17 @@ function createParserContext(
   options: ParserOptions
 ): ParserContext {
   return {
+    ...defaultParserOptions,
     ...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
-    )
+    maxCRNameLength: Object.keys(
+      options.namedCharacterReferences ||
+        defaultParserOptions.namedCharacterReferences
+    ).reduce((max, name) => Math.max(max, name.length), 0)
   }
 }
 
diff --git a/packages/compiler-core/src/parserOptionsMinimal.ts b/packages/compiler-core/src/parserOptionsMinimal.ts
deleted file mode 100644 (file)
index 4ed76bc..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-import { TextModes, ParserOptions } from './parser'
-import { ElementNode, Namespaces, Position, Node } from './ast'
-import { ParserErrorTypes, errorMessages } 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(
-      `${errorMessages[code]} (${loc.line}:${loc.column})`
-    )
-    error.code = code
-    error.loc = loc
-    throw error
-  },
-
-  transform(node: Node): Node {
-    return node
-  }
-}
diff --git a/packages/compiler-dom/__tests__/parse.spec.ts b/packages/compiler-dom/__tests__/parse.spec.ts
new file mode 100644 (file)
index 0000000..86f62c8
--- /dev/null
@@ -0,0 +1,257 @@
+import {
+  parse,
+  NodeTypes,
+  ElementNode,
+  TextNode,
+  AttributeNode,
+  ParserErrorTypes,
+  ExpressionNode,
+  ElementTypes
+} from '@vue/compiler-core'
+import {
+  parserOptionsMinimal as parserOptions,
+  DOMNamespaces
+} from '../src/parserOptionsMinimal'
+
+describe('DOM parser', () => {
+  describe('Text', () => {
+    test('textarea handles comments/elements as just 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>&amp;</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: '&amp;'
+        }
+      })
+    })
+
+    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>&amp;</style>', parserOptions)
+      const element = ast.children[0] as ElementNode
+      const text = element.children[0] as TextNode
+
+      expect(text).toStrictEqual({
+        type: NodeTypes.TEXT,
+        content: '&amp;',
+        isEmpty: false,
+        loc: {
+          start: { offset: 7, line: 1, column: 8 },
+          end: { offset: 12, line: 1, column: 13 },
+          source: '&amp;'
+        }
+      })
+    })
+
+    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('HTML entities compatibility in text (https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state).', () => {
+      const spy = jest.fn()
+      const ast = parse('&ampersand;', {
+        ...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: '&ampersand;'
+        }
+      })
+      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="&ampersand;" b="&amp;ersand;" c="&amp!"></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: '&ampersand;',
+        isEmpty: false,
+        loc: {
+          start: { offset: 7, line: 1, column: 8 },
+          end: { offset: 20, line: 1, column: 21 },
+          source: '"&ampersand;"'
+        }
+      })
+      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: '"&amp;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: '"&amp!"'
+        }
+      })
+      expect(spy.mock.calls).toEqual([
+        [
+          ParserErrorTypes.MISSING_SEMICOLON_AFTER_CHARACTER_REFERENCE,
+          { offset: 45, line: 1, column: 46 }
+        ]
+      ])
+    })
+  })
+
+  describe('Interpolation', () => {
+    test('HTML entities in interpolation should be translated for backward compatibility.', () => {
+      const ast = parse('<div>{{ a &lt; 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 &lt; b }}'
+        }
+      })
+    })
+  })
+
+  describe('Element', () => {
+    test('void element', () => {
+      const ast = parse('<img>after', parserOptions)
+      const element = ast.children[0] as ElementNode
+
+      expect(element).toStrictEqual({
+        type: NodeTypes.ELEMENT,
+        ns: DOMNamespaces.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('Strict end tag detection for textarea.', () => {
+      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>'
+        }
+      })
+    })
+  })
+})
index 44ffe40fd9636a3bf96afdc9a28c2ecabb98034a..a1a106456dce9ab55edb5f2ae7521a5c942f9f00 100644 (file)
@@ -1,2 +1,4 @@
 // TODO
 export * from '@vue/compiler-core'
+export { parserOptionsMinimal } from './parserOptionsMinimal'
+export { parserOptionsStandard } from './parserOptionsStandard'
diff --git a/packages/compiler-dom/src/parserOptionsMinimal.ts b/packages/compiler-dom/src/parserOptionsMinimal.ts
new file mode 100644 (file)
index 0000000..a652f17
--- /dev/null
@@ -0,0 +1,93 @@
+import {
+  NodeTypes,
+  TextModes,
+  ParserOptions,
+  ElementNode,
+  Namespaces
+} from '@vue/compiler-core'
+
+export const enum DOMNamespaces {
+  HTML = Namespaces.HTML,
+  SVG,
+  MATH_ML
+}
+
+const MATH_ML_TEXT_INTEGRATION_POINT_RE = /^m(?:[ions]|text)$/
+const RAW_TEXT_CONTAINER_RE = /^(?:style|xmp|iframe|noembed|noframes|script|noscript)$/i
+const VOID_TAG_RE = /^(?:area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/i
+
+export const parserOptionsMinimal: ParserOptions = {
+  // https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
+  getNamespace(tag: string, parent: ElementNode | undefined): DOMNamespaces {
+    let ns = parent ? parent.ns : DOMNamespaces.HTML
+
+    if (parent && ns === DOMNamespaces.MATH_ML) {
+      if (parent.tag === 'annotation-xml') {
+        if (tag === 'svg') {
+          return DOMNamespaces.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 = DOMNamespaces.HTML
+        }
+      } else if (
+        MATH_ML_TEXT_INTEGRATION_POINT_RE.test(parent.tag) &&
+        tag !== 'mglyph' &&
+        tag !== 'malignmark'
+      ) {
+        ns = DOMNamespaces.HTML
+      }
+    } else if (parent && ns === DOMNamespaces.SVG) {
+      if (
+        parent.tag === 'foreignObject' ||
+        parent.tag === 'desc' ||
+        parent.tag === 'title'
+      ) {
+        ns = DOMNamespaces.HTML
+      }
+    }
+
+    if (ns === DOMNamespaces.HTML) {
+      if (tag === 'svg') {
+        return DOMNamespaces.SVG
+      }
+      if (tag === 'math') {
+        return DOMNamespaces.MATH_ML
+      }
+    }
+    return ns
+  },
+
+  // https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
+  getTextMode(tag: string, ns: DOMNamespaces): TextModes {
+    if (ns === DOMNamespaces.HTML) {
+      if (tag === 'textarea' || tag === 'title') {
+        return TextModes.RCDATA
+      }
+      if (RAW_TEXT_CONTAINER_RE.test(tag)) {
+        return TextModes.RAWTEXT
+      }
+    }
+    return TextModes.DATA
+  },
+
+  isVoidTag(tag: string): boolean {
+    return VOID_TAG_RE.test(tag)
+  },
+
+  namedCharacterReferences: {
+    'gt;': '>',
+    'lt;': '<',
+    'amp;': '&',
+    'apos;': "'",
+    'quot;': '"'
+  }
+}
similarity index 96%
rename from packages/compiler-core/src/parserOptionsStandard.ts
rename to packages/compiler-dom/src/parserOptionsStandard.ts
index c0547cde75e94eb0dbdf9284ba7286663ba96af2..42b807c8b62cbb542f003d6b6b8492760ae4d280 100644 (file)
@@ -1,75 +1,10 @@
-import { TextModes, ParserOptions } from './parser'
-import { ElementNode, Namespaces, NodeTypes } from './ast'
+import { ParserOptions } from '@vue/compiler-core'
 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: '>',