@@ -7,13 +7,14 @@ import {
77} from './scope'
88import type { ESTreeNode } from './scope'
99import { compileTemplateDescriptor } from './template'
10- import type { TemplateDescriptor } from '../shared/protocol'
10+ import type { ElementNamespace , TemplateDescriptor } from '../shared/protocol'
1111import { SandboxCompileError } from '../host/errors'
1212
1313const supportedImports = new Set ( [
1414 'component' ,
1515 'c' ,
1616 'html' ,
17+ 'svg' ,
1718 't' ,
1819 'onCleanup' ,
1920 'pick' ,
@@ -70,24 +71,25 @@ function readImportBindings(program: ESTreeNode) {
7071 }
7172}
7273
73- function isArrowTagIdentifier (
74+ function getArrowTagNamespace (
7475 node : ESTreeNode ,
7576 coreLocals : Map < string , string > ,
7677 missingImports : Set < string > ,
7778 isBound : ( name : string ) => boolean
78- ) {
79- if ( node . type !== 'Identifier' ) return false
79+ ) : ElementNamespace | 'html' | null {
80+ if ( node . type !== 'Identifier' ) return null
8081
8182 const local = String ( node . name )
8283 const imported = coreLocals . get ( local )
83- if ( imported === 'html' || imported === 't' ) return true
84+ if ( imported === 'svg' ) return 'svg'
85+ if ( imported === 'html' || imported === 't' ) return 'html'
8486
85- if ( ( local === 'html' || local === 't' ) && ! isBound ( local ) ) {
87+ if ( ( local === 'html' || local === 'svg' || local === ' t') && ! isBound ( local ) ) {
8688 missingImports . add ( local )
87- return true
89+ return local === 'svg' ? 'svg' : 'html'
8890 }
8991
90- return false
92+ return null
9193}
9294
9395export function preprocessModule (
@@ -103,7 +105,10 @@ export function preprocessModule(
103105 const { coreLocals, lastImportEnd } = readImportBindings ( program )
104106 const missingImports = new Set < string > ( )
105107 const descriptors : TemplateDescriptor [ ] = [ ]
106- const taggedTemplates : ESTreeNode [ ] = [ ]
108+ const taggedTemplates : Array < {
109+ expression : ESTreeNode
110+ namespace ?: ElementNamespace
111+ } > = [ ]
107112
108113 collectReferences ( program , analysis , ( node , scope , parent ) => {
109114 if (
@@ -117,9 +122,15 @@ export function preprocessModule(
117122 if ( node . type === 'TaggedTemplateExpression' ) {
118123 const tag = asNode ( node . tag )
119124 const isBound = ( name : string ) => analysis . isNameBound ( scope , name )
120-
121- if ( tag && isArrowTagIdentifier ( tag , coreLocals , missingImports , isBound ) ) {
122- taggedTemplates . push ( node )
125+ const tagNamespace = tag
126+ ? getArrowTagNamespace ( tag , coreLocals , missingImports , isBound )
127+ : null
128+
129+ if ( tagNamespace ) {
130+ taggedTemplates . push ( {
131+ expression : node ,
132+ namespace : tagNamespace === 'svg' ? 'svg' : undefined ,
133+ } )
123134 return
124135 }
125136
@@ -129,18 +140,21 @@ export function preprocessModule(
129140 coreLocals . has ( String ( asNode ( tag . object ) ?. name ) )
130141 ) {
131142 throw new SandboxCompileError (
132- 'Namespace-style Arrow html tags are not supported in @arrow-js/sandbox.'
143+ 'Namespace-style Arrow template tags are not supported in @arrow-js/sandbox.'
133144 )
134145 }
135146 }
136147 } )
137148
138149 const output = new MagicString ( source )
139150
140- taggedTemplates . sort ( ( left , right ) => ( right . start || 0 ) - ( left . start || 0 ) )
151+ taggedTemplates . sort (
152+ ( left , right ) =>
153+ ( right . expression . start || 0 ) - ( left . expression . start || 0 )
154+ )
141155 let templateIndex = 0
142156
143- for ( const expression of taggedTemplates ) {
157+ for ( const { expression, namespace } of taggedTemplates ) {
144158 const quasi = expression . quasi as ESTreeNode
145159 const strings = ( quasi . quasis as ESTreeNode [ ] ) . map ( ( part ) =>
146160 String ( ( part . value as any ) . cooked ?? ( part . value as any ) . raw ?? '' )
@@ -149,7 +163,9 @@ export function preprocessModule(
149163 output . slice ( part . start || 0 , part . end || 0 )
150164 )
151165 const descriptorId = `${ path } #template:${ templateIndex ++ } `
152- descriptors . push ( compileTemplateDescriptor ( descriptorId , strings ) )
166+ descriptors . push (
167+ compileTemplateDescriptor ( descriptorId , strings , namespace )
168+ )
153169
154170 output . overwrite (
155171 expression . start || 0 ,
0 commit comments