11/** @import { BlockStatement, Expression } from 'estree' */
2- /** @import { AST } from '#compiler' */
2+ /** @import { AST, Namespace } from '#compiler' */
33/** @import { ComponentContext } from '../types' */
44import * as b from '../../../../utils/builders.js' ;
55
6+ /**
7+ * @param {AST.Fragment } fragment
8+ * @return {Namespace }
9+ */
10+ function get_namespace ( fragment ) {
11+ const elements = fragment . nodes . filter ( ( n ) => n . type === 'RegularElement' ) ;
12+ /** @type {Namespace | null } */
13+ let namespace = null ;
14+
15+ // Check the elements within the fragment and look for consistent namespaces.
16+ // If we have no namespaces or they are mixed, then fallback to `html`
17+ for ( const element of elements ) {
18+ const metadata = element . metadata ;
19+
20+ if ( metadata . mathml ) {
21+ if ( namespace === null || namespace === 'mathml' ) {
22+ namespace = 'mathml' ;
23+ } else {
24+ namespace = 'html' ;
25+ }
26+ } else if ( metadata . svg ) {
27+ if ( namespace === null || namespace === 'svg' ) {
28+ namespace = 'svg' ;
29+ } else {
30+ namespace = 'html' ;
31+ }
32+ } else {
33+ namespace = 'html' ;
34+ }
35+ }
36+
37+ return namespace ?? 'html' ;
38+ }
39+
640/**
741 * @param {AST.IfBlock } node
842 * @param {ComponentContext } context
@@ -11,15 +45,27 @@ export function IfBlock(node, context) {
1145 context . state . template . push ( '<!>' ) ;
1246 const statements = [ ] ;
1347
14- const consequent = /** @type {BlockStatement } */ ( context . visit ( node . consequent ) ) ;
48+ const consequent_namespace = get_namespace ( node . consequent ) ;
49+ const consequent = /** @type {BlockStatement } */ (
50+ context . visit ( node . consequent , {
51+ ...context . state ,
52+ metadata : { ...context . state . metadata , namespace : consequent_namespace }
53+ } )
54+ ) ;
1555 const consequent_id = context . state . scope . generate ( 'consequent' ) ;
1656
1757 statements . push ( b . var ( b . id ( consequent_id ) , b . arrow ( [ b . id ( '$$anchor' ) ] , consequent ) ) ) ;
1858
1959 let alternate_id ;
2060
2161 if ( node . alternate ) {
22- const alternate = /** @type {BlockStatement } */ ( context . visit ( node . alternate ) ) ;
62+ const alternate_namespace = get_namespace ( node . consequent ) ;
63+ const alternate = /** @type {BlockStatement } */ (
64+ context . visit ( node . alternate , {
65+ ...context . state ,
66+ metadata : { ...context . state . metadata , namespace : alternate_namespace }
67+ } )
68+ ) ;
2369 alternate_id = context . state . scope . generate ( 'alternate' ) ;
2470 statements . push ( b . var ( b . id ( alternate_id ) , b . arrow ( [ b . id ( '$$anchor' ) ] , alternate ) ) ) ;
2571 }
0 commit comments