@@ -52,15 +52,27 @@ const DIRECTIVE_NAME = /^(?:v-|[.:@#]).*[^.:@#]$/u
5252const DT_DD = / ^ d [ d t ] $ / u
5353const DUMMY_PARENT : any = Object . freeze ( { } )
5454
55+ /**
56+ * Gets the tag name from the given node or token.
57+ * For SFC, it returns the value of `rawName` to be case sensitive.
58+ */
59+ function getTagName (
60+ startTagOrElement : { name : string ; rawName : string } ,
61+ isSFC : boolean ,
62+ ) {
63+ return isSFC ? startTagOrElement . rawName : startTagOrElement . name
64+ }
65+
5566/**
5667 * Check whether the element is a MathML text integration point or not.
5768 * @see https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
5869 * @param element The current element.
70+ * @param isSFC For SFC, give `true`.
5971 * @returns `true` if the element is a MathML text integration point.
6072 */
61- function isMathMLIntegrationPoint ( element : VElement ) : boolean {
73+ function isMathMLIntegrationPoint ( element : VElement , isSFC : boolean ) : boolean {
6274 if ( element . namespace === NS . MathML ) {
63- const name = element . name
75+ const name = getTagName ( element , isSFC )
6476 return (
6577 name === "mi" ||
6678 name === "mo" ||
@@ -76,12 +88,13 @@ function isMathMLIntegrationPoint(element: VElement): boolean {
7688 * Check whether the element is a HTML integration point or not.
7789 * @see https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
7890 * @param element The current element.
91+ * @param isSFC For SFC, give `true`.
7992 * @returns `true` if the element is a HTML integration point.
8093 */
81- function isHTMLIntegrationPoint ( element : VElement ) : boolean {
94+ function isHTMLIntegrationPoint ( element : VElement , isSFC : boolean ) : boolean {
8295 if ( element . namespace === NS . MathML ) {
8396 return (
84- element . name === "annotation-xml" &&
97+ getTagName ( element , isSFC ) === "annotation-xml" &&
8598 element . startTag . attributes . some (
8699 ( a ) =>
87100 a . directive === false &&
@@ -93,7 +106,7 @@ function isHTMLIntegrationPoint(element: VElement): boolean {
93106 )
94107 }
95108 if ( element . namespace === NS . SVG ) {
96- const name = element . name
109+ const name = getTagName ( element , isSFC )
97110 return name === "foreignObject" || name === "desc" || name === "title"
98111 }
99112
@@ -317,29 +330,37 @@ export class Parser {
317330 }
318331 }
319332
333+ /**
334+ * Gets the tag name from the given node or token.
335+ * For SFC, it returns the value of `rawName` to be case sensitive.
336+ */
337+ private getTagName ( startTagOrElement : { name : string ; rawName : string } ) {
338+ return getTagName ( startTagOrElement , this . isSFC )
339+ }
340+
320341 /**
321342 * Detect the namespace of the new element.
322343 * @param token The StartTag token to detect.
323344 * @returns The namespace of the new element.
324345 */
325346 //eslint-disable-next-line complexity
326347 private detectNamespace ( token : StartTag ) : Namespace {
327- const name = token . name
348+ const name = this . getTagName ( token )
328349 let ns = this . namespace
329350
330351 if ( ns === NS . MathML || ns === NS . SVG ) {
331352 const element = this . currentNode
332353 if ( element . type === "VElement" ) {
333354 if (
334355 element . namespace === NS . MathML &&
335- element . name === "annotation-xml" &&
356+ this . getTagName ( element ) === "annotation-xml" &&
336357 name === "svg"
337358 ) {
338359 return NS . SVG
339360 }
340361 if (
341- isHTMLIntegrationPoint ( element ) ||
342- ( isMathMLIntegrationPoint ( element ) &&
362+ isHTMLIntegrationPoint ( element , this . isSFC ) ||
363+ ( isMathMLIntegrationPoint ( element , this . isSFC ) &&
343364 name !== "mglyph" &&
344365 name !== "malignmark" )
345366 ) {
@@ -371,21 +392,23 @@ export class Parser {
371392
372393 /**
373394 * Close the current element if necessary.
374- * @param name The tag name to check.
395+ * @param token The start tag to check.
375396 */
376- private closeCurrentElementIfNecessary ( name : string ) : void {
397+ private closeCurrentElementIfNecessary ( token : StartTag ) : void {
377398 const element = this . currentNode
378399 if ( element . type !== "VElement" ) {
379400 return
380401 }
402+ const name = this . getTagName ( token )
403+ const elementName = this . getTagName ( element )
381404
382- if ( element . name === "p" && HTML_NON_FHRASING_TAGS . has ( name ) ) {
405+ if ( elementName === "p" && HTML_NON_FHRASING_TAGS . has ( name ) ) {
383406 this . popElementStack ( )
384407 }
385- if ( element . name === name && HTML_CAN_BE_LEFT_OPEN_TAGS . has ( name ) ) {
408+ if ( elementName === name && HTML_CAN_BE_LEFT_OPEN_TAGS . has ( name ) ) {
386409 this . popElementStack ( )
387410 }
388- if ( DT_DD . test ( element . name ) && DT_DD . test ( name ) ) {
411+ if ( DT_DD . test ( elementName ) && DT_DD . test ( name ) ) {
389412 this . popElementStack ( )
390413 }
391414 }
@@ -396,8 +419,8 @@ export class Parser {
396419 * @param namespace The current namespace.
397420 */
398421 private processAttribute ( node : VAttribute , namespace : Namespace ) : void {
399- const tagName = node . parent . parent . name
400- const attrName = node . key . name
422+ const tagName = this . getTagName ( node . parent . parent )
423+ const attrName = this . getTagName ( node . key )
401424
402425 if (
403426 ( this . expressionEnabled ||
@@ -415,10 +438,8 @@ export class Parser {
415438 return
416439 }
417440
418- const key = ( node . key . name = adjustAttributeName (
419- node . key . name ,
420- namespace ,
421- ) )
441+ node . key . name = adjustAttributeName ( node . key . name , namespace )
442+ const key = this . getTagName ( node . key )
422443 const value = node . value && node . value . value
423444
424445 if ( key === "xmlns" && value !== namespace ) {
@@ -436,7 +457,7 @@ export class Parser {
436457 protected StartTag ( token : StartTag ) : void {
437458 debug ( "[html] StartTag %j" , token )
438459
439- this . closeCurrentElementIfNecessary ( token . name )
460+ this . closeCurrentElementIfNecessary ( token )
440461
441462 const parent = this . currentNode
442463 const namespace = this . detectNamespace ( token )
@@ -462,7 +483,7 @@ export class Parser {
462483 }
463484 const hasVPre =
464485 ! this . isInVPreElement &&
465- token . attributes . some ( ( a ) => a . key . name === "v-pre" )
486+ token . attributes . some ( ( a ) => this . getTagName ( a . key ) === "v-pre" )
466487
467488 // Disable expression if v-pre
468489 if ( hasVPre ) {
@@ -494,7 +515,8 @@ export class Parser {
494515
495516 // Check whether the self-closing is valid.
496517 const isVoid =
497- namespace === NS . HTML && HTML_VOID_ELEMENT_TAGS . has ( element . name )
518+ namespace === NS . HTML &&
519+ HTML_VOID_ELEMENT_TAGS . has ( this . getTagName ( element ) )
498520 if ( token . selfClosing && ! isVoid && namespace === NS . HTML ) {
499521 this . reportParseError (
500522 token ,
@@ -518,13 +540,14 @@ export class Parser {
518540
519541 // Update the content type of this element.
520542 if ( namespace === NS . HTML ) {
543+ const elementName = this . getTagName ( element )
521544 if ( element . parent . type === "VDocumentFragment" ) {
522545 const langAttr = element . startTag . attributes . find (
523546 ( a ) => ! a . directive && a . key . name === "lang" ,
524547 ) as VAttribute | undefined
525548 const lang = langAttr ?. value ?. value
526549
527- if ( element . name === "template" ) {
550+ if ( elementName === "template" ) {
528551 if ( lang && lang !== "html" ) {
529552 // It is not an HTML template.
530553 this . tokenizer . state = "RAWTEXT"
@@ -538,18 +561,18 @@ export class Parser {
538561 this . tokenizer . state = "RAWTEXT"
539562 }
540563 } else {
541- if ( HTML_RCDATA_TAGS . has ( element . name ) ) {
564+ if ( HTML_RCDATA_TAGS . has ( elementName ) ) {
542565 this . tokenizer . state = "RCDATA"
543566 }
544- if ( HTML_RAWTEXT_TAGS . has ( element . name ) ) {
567+ if ( HTML_RAWTEXT_TAGS . has ( elementName ) ) {
545568 this . tokenizer . state = "RAWTEXT"
546569 }
547570 }
548571 } else {
549- if ( HTML_RCDATA_TAGS . has ( element . name ) ) {
572+ if ( HTML_RCDATA_TAGS . has ( elementName ) ) {
550573 this . tokenizer . state = "RCDATA"
551574 }
552- if ( HTML_RAWTEXT_TAGS . has ( element . name ) ) {
575+ if ( HTML_RAWTEXT_TAGS . has ( elementName ) ) {
553576 this . tokenizer . state = "RAWTEXT"
554577 }
555578 }
0 commit comments