@@ -58,6 +58,7 @@ import type {
58
58
CustomTemplateTokenizer ,
59
59
CustomTemplateTokenizerConstructor ,
60
60
} from "./custom-tokenizer"
61
+ import { isScriptSetupElement , isTSLang } from "../common/ast-utils"
61
62
62
63
const DIRECTIVE_NAME = / ^ (?: v - | [ . : @ # ] ) .* [ ^ . : @ # ] $ / u
63
64
const DT_DD = / ^ d [ d t ] $ / u
@@ -178,8 +179,10 @@ export class Parser {
178
179
private document : VDocumentFragment
179
180
private elementStack : VElement [ ]
180
181
private vPreElement : VElement | null
181
- private postProcessesForScript : ( ( parserOptions : ParserOptions ) => void ) [ ] =
182
- [ ]
182
+ private postProcessesForScript : ( (
183
+ htmlParserOptions : ParserOptions ,
184
+ scriptParserOptions : ParserOptions ,
185
+ ) => void ) [ ] = [ ]
183
186
184
187
/**
185
188
* The source code text.
@@ -290,7 +293,7 @@ export class Parser {
290
293
291
294
const doc = this . document
292
295
293
- const parserOptions = {
296
+ const htmlParserOptions = {
294
297
...this . baseParserOptions ,
295
298
parser : getScriptParser (
296
299
this . baseParserOptions . parser ,
@@ -300,8 +303,14 @@ export class Parser {
300
303
} ,
301
304
) ,
302
305
}
306
+ const scriptParserOptions = {
307
+ ...this . baseParserOptions ,
308
+ parser : getScriptParser ( this . baseParserOptions . parser , ( ) =>
309
+ getParserLangFromSFC ( doc ) ,
310
+ ) ,
311
+ }
303
312
for ( const proc of this . postProcessesForScript ) {
304
- proc ( parserOptions )
313
+ proc ( htmlParserOptions , scriptParserOptions )
305
314
}
306
315
this . postProcessesForScript = [ ]
307
316
@@ -449,24 +458,18 @@ export class Parser {
449
458
* @param namespace The current namespace.
450
459
*/
451
460
private processAttribute ( node : VAttribute , namespace : Namespace ) : void {
452
- const tagName = this . getTagName ( node . parent . parent )
453
- const attrName = this . getTagName ( node . key )
454
-
455
- if (
456
- ( this . expressionEnabled ||
457
- ( attrName === "v-pre" && ! this . isInVPreElement ) ) &&
458
- ( DIRECTIVE_NAME . test ( attrName ) ||
459
- attrName === "slot-scope" ||
460
- ( tagName === "template" && attrName === "scope" ) )
461
- ) {
462
- this . postProcessesForScript . push ( ( parserOptions ) => {
463
- convertToDirective (
464
- this . text ,
465
- parserOptions ,
466
- this . locationCalculator ,
467
- node ,
468
- )
469
- } )
461
+ if ( this . needConvertToDirective ( node ) ) {
462
+ this . postProcessesForScript . push (
463
+ ( parserOptions , scriptParserOptions ) => {
464
+ convertToDirective (
465
+ this . text ,
466
+ parserOptions ,
467
+ scriptParserOptions ,
468
+ this . locationCalculator ,
469
+ node ,
470
+ )
471
+ } ,
472
+ )
470
473
return
471
474
}
472
475
@@ -480,6 +483,35 @@ export class Parser {
480
483
this . reportParseError ( node , "x-invalid-namespace" )
481
484
}
482
485
}
486
+ /**
487
+ * Checks whether the given attribute node is need convert to directive.
488
+ * @param node The node to check
489
+ */
490
+ private needConvertToDirective ( node : VAttribute ) {
491
+ const element = node . parent . parent
492
+ const tagName = this . getTagName ( element )
493
+ const attrName = this . getTagName ( node . key )
494
+
495
+ if (
496
+ attrName === "generic" &&
497
+ element . parent . type === "VDocumentFragment" &&
498
+ isScriptSetupElement ( element ) &&
499
+ isTSLang ( element )
500
+ ) {
501
+ return true
502
+ }
503
+ const expressionEnabled =
504
+ this . expressionEnabled ||
505
+ ( attrName === "v-pre" && ! this . isInVPreElement )
506
+ if ( ! expressionEnabled ) {
507
+ return false
508
+ }
509
+ return (
510
+ DIRECTIVE_NAME . test ( attrName ) ||
511
+ attrName === "slot-scope" ||
512
+ ( tagName === "template" && attrName === "scope" )
513
+ )
514
+ }
483
515
484
516
/**
485
517
* Process the given template text token with a configured template tokenizer, based on language.
0 commit comments