@@ -47,22 +47,6 @@ let IS_REGEX_CAPTURING_BROKEN = false
4747
4848// Special Elements (can contain anything)
4949const isScriptOrStyle = makeMap ( 'script,style' , true )
50- const hasLang = attr => attr . name === 'lang' && attr . value !== 'html'
51- const isSpecialTag = ( tag , isSFC , stack ) => {
52- if ( isScriptOrStyle ( tag ) ) {
53- return true
54- }
55- if ( isSFC && stack . length === 1 ) {
56- // top-level template that has no pre-processor
57- if ( tag === 'template' && ! stack [ 0 ] . attrs . some ( hasLang ) ) {
58- return false
59- } else {
60- return true
61- }
62- }
63- return false
64- }
65-
6650const reCache = { }
6751
6852const ltRE = / & l t ; / g
@@ -91,7 +75,7 @@ export function parseHTML (html, options) {
9175while ( html ) {
9276last = html
9377// Make sure we're not in a script or style element
94- if ( ! lastTag || ! isSpecialTag ( lastTag , options . sfc , stack ) ) {
78+ if ( ! lastTag || ! isScriptOrStyle ( lastTag ) ) {
9579let textEnd = html . indexOf ( '<' )
9680if ( textEnd === 0 ) {
9781// Comment:
@@ -126,7 +110,7 @@ export function parseHTML (html, options) {
126110if ( endTagMatch ) {
127111const curIndex = index
128112advance ( endTagMatch [ 0 ] . length )
129- parseEndTag ( endTagMatch [ 0 ] , endTagMatch [ 1 ] , curIndex , index )
113+ parseEndTag ( endTagMatch [ 1 ] , curIndex , index )
130114continue
131115}
132116
@@ -183,7 +167,7 @@ export function parseHTML (html, options) {
183167} )
184168index += html . length - rest . length
185169html = rest
186- parseEndTag ( '</' + stackedTag + '>' , stackedTag , index - endTagLength , index )
170+ parseEndTag ( stackedTag , index - endTagLength , index )
187171}
188172
189173if ( html === last && options . chars ) {
@@ -229,10 +213,10 @@ export function parseHTML (html, options) {
229213
230214if ( expectHTML ) {
231215if ( lastTag === 'p' && isNonPhrasingTag ( tagName ) ) {
232- parseEndTag ( '' , lastTag )
216+ parseEndTag ( lastTag )
233217}
234218if ( canBeLeftOpenTag ( tagName ) && lastTag === tagName ) {
235- parseEndTag ( '' , tagName )
219+ parseEndTag ( tagName )
236220}
237221}
238222
@@ -259,7 +243,7 @@ export function parseHTML (html, options) {
259243}
260244
261245if ( ! unary ) {
262- stack . push ( { tag :tagName , attrs :attrs } )
246+ stack . push ( { tag :tagName , lowerCasedTag : tagName . toLowerCase ( ) , attrs :attrs } )
263247lastTag = tagName
264248unarySlash = ''
265249}
@@ -269,16 +253,19 @@ export function parseHTML (html, options) {
269253}
270254}
271255
272- function parseEndTag ( tag , tagName , start , end ) {
273- let pos
256+ function parseEndTag ( tagName , start , end ) {
257+ let pos , lowerCasedTagName
274258if ( start == null ) start = index
275259if ( end == null ) end = index
276260
261+ if ( tagName ) {
262+ lowerCasedTagName = tagName . toLowerCase ( )
263+ }
264+
277265// Find the closest opened tag of the same type
278266if ( tagName ) {
279- const needle = tagName . toLowerCase ( )
280267for ( pos = stack . length - 1 ; pos >= 0 ; pos -- ) {
281- if ( stack [ pos ] . tag . toLowerCase ( ) === needle ) {
268+ if ( stack [ pos ] . lowerCasedTag === lowerCasedTagName ) {
282269break
283270}
284271}
@@ -298,11 +285,11 @@ export function parseHTML (html, options) {
298285// Remove the open elements from the stack
299286stack . length = pos
300287lastTag = pos && stack [ pos - 1 ] . tag
301- } else if ( tagName . toLowerCase ( ) === 'br' ) {
288+ } else if ( lowerCasedTagName === 'br' ) {
302289if ( options . start ) {
303290options . start ( tagName , [ ] , true , start , end )
304291}
305- } else if ( tagName . toLowerCase ( ) === 'p' ) {
292+ } else if ( lowerCasedTagName === 'p' ) {
306293if ( options . start ) {
307294options . start ( tagName , [ ] , false , start , end )
308295}