@@ -301,6 +301,10 @@ export default class Tokenizer {
301301 }
302302 }
303303
304+ private peek ( ) {
305+ return this . buffer . charCodeAt ( this . index + 1 )
306+ }
307+
304308 private stateText ( c : number ) : void {
305309 if ( c === CharCodes . Lt ) {
306310 if ( this . index > this . sectionStart ) {
@@ -627,12 +631,16 @@ export default class Tokenizer {
627631 this . sectionStart = this . index + 1
628632 } else if ( c === CharCodes . Slash ) {
629633 this . state = State . InSelfClosingTag
630- if (
631- ( __DEV__ || ! __BROWSER__ ) &&
632- this . buffer . charCodeAt ( this . index + 1 ) !== CharCodes . Gt
633- ) {
634+ if ( ( __DEV__ || ! __BROWSER__ ) && this . peek ( ) !== CharCodes . Gt ) {
634635 this . cbs . onerr ( ErrorCodes . UNEXPECTED_SOLIDUS_IN_TAG , this . index )
635636 }
637+ } else if ( c === CharCodes . Lt && this . peek ( ) === CharCodes . Slash ) {
638+ // special handling for </ appearing in open tag state
639+ // this is different from standard HTML parsing but makes practical sense
640+ // especially for parsing intermedaite input state in IDEs.
641+ this . cbs . onopentagend ( this . index )
642+ this . state = State . BeforeTagName
643+ this . sectionStart = this . index
636644 } else if ( ! isWhitespace ( c ) ) {
637645 if ( ( __DEV__ || ! __BROWSER__ ) && c === CharCodes . Eq ) {
638646 this . cbs . onerr (
@@ -644,10 +652,7 @@ export default class Tokenizer {
644652 }
645653 }
646654 private handleAttrStart ( c : number ) {
647- if (
648- c === CharCodes . LowerV &&
649- this . buffer . charCodeAt ( this . index + 1 ) === CharCodes . Dash
650- ) {
655+ if ( c === CharCodes . LowerV && this . peek ( ) === CharCodes . Dash ) {
651656 this . state = State . InDirName
652657 this . sectionStart = this . index
653658 } else if (
0 commit comments