@@ -12,13 +12,14 @@ import type {
12
12
SvelteTransitionDirective ,
13
13
SvelteStartTag ,
14
14
SvelteName ,
15
+ SvelteStyleDirective ,
15
16
} from "../../ast"
16
17
import type ESTree from "estree"
17
18
import type { Context } from "../../context"
18
19
import type * as SvAST from "../svelte-ast-types"
19
20
import { getWithLoc , indexOf } from "./common"
20
21
import { convertMustacheTag } from "./mustache"
21
- import { convertTextToLiteral } from "./text"
22
+ import { convertTemplateLiteralToLiteral , convertTextToLiteral } from "./text"
22
23
import { ParseError } from "../../errors"
23
24
import type { ScriptLetCallback } from "../../context/script-let"
24
25
@@ -54,6 +55,10 @@ export function* convertAttributes(
54
55
yield convertClassDirective ( attr , parent , ctx )
55
56
continue
56
57
}
58
+ if ( attr . type === "Style" ) {
59
+ yield convertStyleDirective ( attr , parent , ctx )
60
+ continue
61
+ }
57
62
if ( attr . type === "Transition" ) {
58
63
yield convertTransitionDirective ( attr , parent , ctx )
59
64
continue
@@ -284,6 +289,79 @@ function convertClassDirective(
284
289
return directive
285
290
}
286
291
292
+ /** Convert for Style Directive */
293
+ function convertStyleDirective (
294
+ node : SvAST . DirectiveForExpression ,
295
+ parent : SvelteDirective [ "parent" ] ,
296
+ ctx : Context ,
297
+ ) : SvelteStyleDirective {
298
+ const directive : SvelteStyleDirective = {
299
+ type : "SvelteDirective" ,
300
+ kind : "Style" ,
301
+ key : null as any ,
302
+ expression : null ,
303
+ parent,
304
+ ...ctx . getConvertLocation ( node ) ,
305
+ }
306
+ if ( processStyleDirectiveValue ( node , ctx ) ) {
307
+ processDirective ( node , directive , ctx , ( expression ) => {
308
+ directive . expression = convertTemplateLiteralToLiteral (
309
+ expression ,
310
+ directive ,
311
+ ctx ,
312
+ )
313
+ return [ ]
314
+ } )
315
+ } else {
316
+ processDirective ( node , directive , ctx , ( expression ) => {
317
+ return ctx . scriptLet . addExpression ( expression , directive )
318
+ } )
319
+ }
320
+
321
+ return directive
322
+ }
323
+
324
+ /** Process plain value */
325
+ function processStyleDirectiveValue (
326
+ node : SvAST . DirectiveForExpression ,
327
+ ctx : Context ,
328
+ ) : node is SvAST . DirectiveForExpression & {
329
+ expression : ESTree . TemplateLiteral
330
+ } {
331
+ const { expression } = node
332
+ if (
333
+ ! expression ||
334
+ expression . type !== "TemplateLiteral" ||
335
+ expression . expressions . length !== 0
336
+ ) {
337
+ return false
338
+ }
339
+ const quasi = expression . quasis [ 0 ]
340
+ if ( quasi . value . cooked != null ) {
341
+ return false
342
+ }
343
+ const eqIndex = ctx . code . indexOf ( "=" , node . start )
344
+ if ( eqIndex < 0 || eqIndex >= node . end ) {
345
+ return false
346
+ }
347
+ const valueIndex = ctx . code . indexOf ( quasi . value . raw , eqIndex + 1 )
348
+ if ( valueIndex < 0 || valueIndex >= node . end ) {
349
+ return false
350
+ }
351
+ const maybeEnd = valueIndex + quasi . value . raw . length
352
+ const maybeOpenQuote = ctx . code . slice ( eqIndex + 1 , valueIndex ) . trimStart ( )
353
+ if ( maybeOpenQuote && maybeOpenQuote !== '"' && maybeOpenQuote !== "'" ) {
354
+ return false
355
+ }
356
+ const maybeCloseQuote = ctx . code . slice ( maybeEnd , node . end ) . trimEnd ( )
357
+ if ( maybeCloseQuote !== maybeOpenQuote ) {
358
+ return false
359
+ }
360
+ getWithLoc ( expression ) . start = valueIndex
361
+ getWithLoc ( expression ) . end = maybeEnd
362
+ return true
363
+ }
364
+
287
365
/** Convert for Transition Directive */
288
366
function convertTransitionDirective (
289
367
node : SvAST . TransitionDirective ,
0 commit comments