@@ -9,7 +9,6 @@ import { Parser } from '../index';
9
9
import { Node } from '../../interfaces' ;
10
10
11
11
const validTagName = / ^ \! ? [ a - z A - Z ] { 1 , } : ? [ a - z A - Z 0 - 9 \- ] * / ;
12
- const invalidUnquotedAttributeCharacters = / [ \s " ' = < > \/ ` ] / ;
13
12
14
13
const SELF = ':Self' ;
15
14
@@ -181,6 +180,11 @@ export default function tag ( parser: Parser ) {
181
180
182
181
if ( selfClosing ) {
183
182
element . end = parser . index ;
183
+ } else if ( name === 'textarea' ) {
184
+ // special case
185
+ element . children = readSequence ( parser , ( ) => parser . template . slice ( parser . index , parser . index + 11 ) === '</textarea>' ) ;
186
+ parser . read ( / < \/ t e x t a r e a > / ) ;
187
+ element . end = parser . index ;
184
188
} else {
185
189
// don't push self-closing elements onto the stack
186
190
parser . stack . push ( element ) ;
@@ -280,28 +284,66 @@ function readAttribute ( parser: Parser, uniqueNames ) {
280
284
}
281
285
282
286
function readAttributeValue ( parser : Parser ) {
283
- let quoteMark ;
287
+ const quoteMark = (
288
+ parser . eat ( `'` ) ? `'` :
289
+ parser . eat ( `"` ) ? `"` :
290
+ null
291
+ ) ;
292
+
293
+ const regex = (
294
+ quoteMark === `'` ? / ' / :
295
+ quoteMark === `"` ? / " / :
296
+ / [ \s " ' = < > \/ ` ] /
297
+ ) ;
298
+
299
+ const value = readSequence ( parser , ( ) => regex . test ( parser . template [ parser . index ] ) ) ;
300
+
301
+ if ( quoteMark ) parser . index += 1 ;
302
+ return value ;
303
+ }
284
304
285
- if ( parser . eat ( `'` ) ) quoteMark = `'` ;
286
- if ( parser . eat ( `"` ) ) quoteMark = `"` ;
305
+ function getShorthandValue ( start : number , name : string ) {
306
+ const end = start + name . length ;
287
307
308
+ return [ {
309
+ type : 'AttributeShorthand' ,
310
+ start,
311
+ end,
312
+ expression : {
313
+ type : 'Identifier' ,
314
+ start,
315
+ end,
316
+ name
317
+ }
318
+ } ] ;
319
+ }
320
+
321
+ function readSequence ( parser : Parser , done : ( ) => boolean ) {
288
322
let currentChunk : Node = {
289
323
start : parser . index ,
290
324
end : null ,
291
325
type : 'Text' ,
292
326
data : ''
293
327
} ;
294
328
295
- const done = quoteMark ?
296
- char => char === quoteMark :
297
- char => invalidUnquotedAttributeCharacters . test ( char ) ;
298
-
299
329
const chunks = [ ] ;
300
330
301
331
while ( parser . index < parser . template . length ) {
302
332
const index = parser . index ;
303
333
304
- if ( parser . eat ( '{{' ) ) {
334
+ if ( done ( ) ) {
335
+ currentChunk . end = parser . index ;
336
+
337
+ if ( currentChunk . data ) chunks . push ( currentChunk ) ;
338
+
339
+ chunks . forEach ( chunk => {
340
+ if ( chunk . type === 'Text' ) chunk . data = decodeCharacterReferences ( chunk . data ) ;
341
+ } ) ;
342
+
343
+ return chunks ;
344
+ }
345
+
346
+ else if ( parser . eat ( '{{' ) ) {
305
347
if ( currentChunk . data ) {
306
348
currentChunk . end = index ;
307
349
chunks . push ( currentChunk ) ;
@@ -328,39 +370,10 @@ function readAttributeValue ( parser: Parser ) {
328
370
} ;
329
371
}
330
372
331
- else if ( done ( parser . template [ parser . index ] ) ) {
332
- currentChunk . end = parser . index ;
333
- if ( quoteMark ) parser . index += 1 ;
334
-
335
- if ( currentChunk . data ) chunks . push ( currentChunk ) ;
336
-
337
- chunks . forEach ( chunk => {
338
- if ( chunk . type === 'Text' ) chunk . data = decodeCharacterReferences ( chunk . data ) ;
339
- } ) ;
340
-
341
- return chunks ;
342
- }
343
-
344
373
else {
345
374
currentChunk . data += parser . template [ parser . index ++ ] ;
346
375
}
347
376
}
348
377
349
378
parser . error ( `Unexpected end of input` ) ;
350
- }
351
-
352
- function getShorthandValue ( start : number , name : string ) {
353
- const end = start + name . length ;
354
-
355
- return [ {
356
- type : 'AttributeShorthand' ,
357
- start,
358
- end,
359
- expression : {
360
- type : 'Identifier' ,
361
- start,
362
- end,
363
- name
364
- }
365
- } ] ;
366
- }
379
+ }
0 commit comments