@@ -52,7 +52,7 @@ import { ParseError } from "../..";
5252/** Convert for Fragment or Element or ... */
5353export function * convertChildren (
5454 /* eslint-enable complexity -- X */
55- fragment : { children : SvAST . TemplateNode [ ] } ,
55+ fragment : { children ? : SvAST . TemplateNode [ ] } ,
5656 parent :
5757 | SvelteProgram
5858 | SvelteElement
@@ -76,6 +76,7 @@ export function* convertChildren(
7676 | SvelteKeyBlock
7777 | SvelteHTMLComment
7878> {
79+ if ( ! fragment . children ) return ;
7980 for ( const child of fragment . children ) {
8081 if ( child . type === "Comment" ) {
8182 yield convertComment ( child , parent , ctx ) ;
@@ -199,8 +200,9 @@ function extractLetDirectives(fragment: {
199200
200201/** Check if children needs a scope. */
201202function needScopeByChildren ( fragment : {
202- children : SvAST . TemplateNode [ ] ;
203+ children ? : SvAST . TemplateNode [ ] ;
203204} ) : boolean {
205+ if ( ! fragment . children ) return false ;
204206 for ( const child of fragment . children ) {
205207 if ( child . type === "ConstTag" ) {
206208 return true ;
@@ -437,66 +439,92 @@ function processThisAttribute(
437439 ( c ) => Boolean ( c . trim ( ) ) ,
438440 eqIndex + 1 ,
439441 ) ;
440- const quote = ctx . code . startsWith ( thisValue , valueStartIndex )
441- ? null
442- : ctx . code [ valueStartIndex ] ;
443- const literalStartIndex = quote
444- ? valueStartIndex + quote . length
445- : valueStartIndex ;
446- const literalEndIndex = literalStartIndex + thisValue . length ;
447- const endIndex = quote ? literalEndIndex + quote . length : literalEndIndex ;
448- const thisAttr : SvelteAttribute = {
449- type : "SvelteAttribute" ,
450- key : null as any ,
451- boolean : false ,
452- value : [ ] ,
453- parent : element . startTag ,
454- ...ctx . getConvertLocation ( { start : startIndex , end : endIndex } ) ,
455- } ;
456- thisAttr . key = {
457- type : "SvelteName" ,
458- name : "this" ,
459- parent : thisAttr ,
460- ...ctx . getConvertLocation ( { start : startIndex , end : eqIndex } ) ,
461- } ;
462- thisAttr . value . push ( {
463- type : "SvelteLiteral" ,
464- value : thisValue ,
465- parent : thisAttr ,
466- ...ctx . getConvertLocation ( {
467- start : literalStartIndex ,
468- end : literalEndIndex ,
469- } ) ,
470- } ) ;
471- // this
472- ctx . addToken ( "HTMLIdentifier" , {
473- start : startIndex ,
474- end : startIndex + 4 ,
475- } ) ;
476- // =
477- ctx . addToken ( "Punctuator" , {
478- start : eqIndex ,
479- end : eqIndex + 1 ,
480- } ) ;
481- if ( quote ) {
482- // "
483- ctx . addToken ( "Punctuator" , {
484- start : valueStartIndex ,
485- end : literalStartIndex ,
442+ if ( ctx . code [ valueStartIndex ] === "{" ) {
443+ // Svelte v5 `this={"..."}`
444+ const openingQuoteIndex = indexOf (
445+ ctx . code ,
446+ ( c ) => c === '"' || c === "'" ,
447+ valueStartIndex + 1 ,
448+ ) ;
449+ const quote = ctx . code [ openingQuoteIndex ] ;
450+ const closingQuoteIndex = indexOf (
451+ ctx . code ,
452+ ( c ) => c === quote ,
453+ openingQuoteIndex + thisValue . length ,
454+ ) ;
455+ const closeIndex = ctx . code . indexOf ( "}" , closingQuoteIndex + 1 ) ;
456+ const endIndex = indexOf (
457+ ctx . code ,
458+ ( c ) => c === ">" || ! c . trim ( ) ,
459+ closeIndex ,
460+ ) ;
461+ thisNode = createSvelteSpecialDirective ( startIndex , endIndex , eqIndex , {
462+ type : "Literal" ,
463+ value : thisValue ,
464+ range : [ openingQuoteIndex , closingQuoteIndex + 1 ] ,
486465 } ) ;
487- }
488- ctx . addToken ( "HTMLText" , {
489- start : literalStartIndex ,
490- end : literalEndIndex ,
491- } ) ;
492- if ( quote ) {
493- // "
466+ } else {
467+ const quote = ctx . code . startsWith ( thisValue , valueStartIndex )
468+ ? null
469+ : ctx . code [ valueStartIndex ] ;
470+ const literalStartIndex = quote
471+ ? valueStartIndex + quote . length
472+ : valueStartIndex ;
473+ const literalEndIndex = literalStartIndex + thisValue . length ;
474+ const endIndex = quote ? literalEndIndex + quote . length : literalEndIndex ;
475+ const thisAttr : SvelteAttribute = {
476+ type : "SvelteAttribute" ,
477+ key : null as any ,
478+ boolean : false ,
479+ value : [ ] ,
480+ parent : element . startTag ,
481+ ...ctx . getConvertLocation ( { start : startIndex , end : endIndex } ) ,
482+ } ;
483+ thisAttr . key = {
484+ type : "SvelteName" ,
485+ name : "this" ,
486+ parent : thisAttr ,
487+ ...ctx . getConvertLocation ( { start : startIndex , end : eqIndex } ) ,
488+ } ;
489+ thisAttr . value . push ( {
490+ type : "SvelteLiteral" ,
491+ value : thisValue ,
492+ parent : thisAttr ,
493+ ...ctx . getConvertLocation ( {
494+ start : literalStartIndex ,
495+ end : literalEndIndex ,
496+ } ) ,
497+ } ) ;
498+ // this
499+ ctx . addToken ( "HTMLIdentifier" , {
500+ start : startIndex ,
501+ end : startIndex + 4 ,
502+ } ) ;
503+ // =
494504 ctx . addToken ( "Punctuator" , {
495- start : literalEndIndex ,
496- end : endIndex ,
505+ start : eqIndex ,
506+ end : eqIndex + 1 ,
507+ } ) ;
508+ if ( quote ) {
509+ // "
510+ ctx . addToken ( "Punctuator" , {
511+ start : valueStartIndex ,
512+ end : literalStartIndex ,
513+ } ) ;
514+ }
515+ ctx . addToken ( "HTMLText" , {
516+ start : literalStartIndex ,
517+ end : literalEndIndex ,
497518 } ) ;
519+ if ( quote ) {
520+ // "
521+ ctx . addToken ( "Punctuator" , {
522+ start : literalEndIndex ,
523+ end : endIndex ,
524+ } ) ;
525+ }
526+ thisNode = thisAttr ;
498527 }
499- thisNode = thisAttr ;
500528 } else {
501529 // this={...}
502530 const eqIndex = ctx . code . lastIndexOf ( "=" , getWithLoc ( thisValue ) . start ) ;
@@ -507,6 +535,30 @@ function processThisAttribute(
507535 ( c ) => c === ">" || ! c . trim ( ) ,
508536 closeIndex ,
509537 ) ;
538+ thisNode = createSvelteSpecialDirective (
539+ startIndex ,
540+ endIndex ,
541+ eqIndex ,
542+ thisValue ,
543+ ) ;
544+ }
545+
546+ const targetIndex = element . startTag . attributes . findIndex (
547+ ( attr ) => thisNode . range [ 1 ] <= attr . range [ 0 ] ,
548+ ) ;
549+ if ( targetIndex === - 1 ) {
550+ element . startTag . attributes . push ( thisNode ) ;
551+ } else {
552+ element . startTag . attributes . splice ( targetIndex , 0 , thisNode ) ;
553+ }
554+
555+ /** Create SvelteSpecialDirective */
556+ function createSvelteSpecialDirective (
557+ startIndex : number ,
558+ endIndex : number ,
559+ eqIndex : number ,
560+ expression : ESTree . Expression ,
561+ ) : SvelteSpecialDirective {
510562 const thisDir : SvelteSpecialDirective = {
511563 type : "SvelteSpecialDirective" ,
512564 kind : "this" ,
@@ -530,19 +582,11 @@ function processThisAttribute(
530582 start : eqIndex ,
531583 end : eqIndex + 1 ,
532584 } ) ;
533- ctx . scriptLet . addExpression ( thisValue , thisDir , null , ( es ) => {
585+ ctx . scriptLet . addExpression ( expression , thisDir , null , ( es ) => {
534586 thisDir . expression = es ;
535587 } ) ;
536- thisNode = thisDir ;
537- }
538588
539- const targetIndex = element . startTag . attributes . findIndex (
540- ( attr ) => thisNode . range [ 1 ] <= attr . range [ 0 ] ,
541- ) ;
542- if ( targetIndex === - 1 ) {
543- element . startTag . attributes . push ( thisNode ) ;
544- } else {
545- element . startTag . attributes . splice ( targetIndex , 0 , thisNode ) ;
589+ return thisDir ;
546590 }
547591}
548592
0 commit comments