@ -1,3 +1,4 @@
/** @import { Expression } from 'estree' */
/** @import { Location } from 'locate-character' */
/** @import { Location } from 'locate-character' */
/** @import { AST } from '#compiler' */
/** @import { AST } from '#compiler' */
/** @import { ComponentContext, ComponentServerTransformState } from '../types.js' */
/** @import { ComponentContext, ComponentServerTransformState } from '../types.js' */
@ -6,8 +7,8 @@ import { is_void } from '../../../../../utils.js';
import { dev , locator } from '../../../../state.js' ;
import { dev , locator } from '../../../../state.js' ;
import * as b from '#compiler/builders' ;
import * as b from '#compiler/builders' ;
import { clean _nodes , determine _namespace _for _children } from '../../utils.js' ;
import { clean _nodes , determine _namespace _for _children } from '../../utils.js' ;
import { build _element _attributes } from './shared/element.js' ;
import { build _element _attributes , build _spread _object } from './shared/element.js' ;
import { process _children , build _template } from './shared/utils.js' ;
import { process _children , build _template , build _attribute _value } from './shared/utils.js' ;
/ * *
/ * *
* @ param { AST . RegularElement } node
* @ param { AST . RegularElement } node
@ -71,21 +72,96 @@ export function RegularElement(node, context) {
) ;
) ;
}
}
if ( body === null ) {
let select _with _value = false ;
process _children ( trimmed , { ... context , state } ) ;
} else {
let id = body ;
if ( body . type !== 'Identifier' ) {
if ( node . name === 'select' ) {
id = b . id ( state . scope . generate ( '$$body' ) ) ;
const value = node . attributes . find (
state . template . push ( b . const ( id , body ) ) ;
( attribute ) =>
( attribute . type === 'Attribute' || attribute . type === 'BindDirective' ) &&
attribute . name === 'value'
) ;
if ( node . attributes . some ( ( attribute ) => attribute . type === 'SpreadAttribute' ) ) {
select _with _value = true ;
state . template . push (
b . stmt (
b . assignment (
'=' ,
b . id ( '$$payload.select_value' ) ,
b . member (
build _spread _object (
node ,
node . attributes . filter (
( attribute ) =>
attribute . type === 'Attribute' ||
attribute . type === 'BindDirective' ||
attribute . type === 'SpreadAttribute'
) ,
context
) ,
'value' ,
false ,
true
)
)
)
) ;
} else if ( value ) {
select _with _value = true ;
const left = b . id ( '$$payload.select_value' ) ;
if ( value . type === 'Attribute' ) {
state . template . push (
b . stmt ( b . assignment ( '=' , left , build _attribute _value ( value . value , context ) ) )
) ;
} else if ( value . type === 'BindDirective' ) {
state . template . push (
b . stmt (
b . assignment (
'=' ,
left ,
value . expression . type === 'SequenceExpression'
? b . call ( value . expression . expressions [ 0 ] )
: value . expression
)
)
) ;
}
}
}
}
if (
node . name === 'option' &&
! node . attributes . some (
( attribute ) =>
attribute . type === 'SpreadAttribute' ||
( ( attribute . type === 'Attribute' || attribute . type === 'BindDirective' ) &&
attribute . name === 'value' )
)
) {
const inner _state = { ... state , template : [ ] , init : [ ] } ;
process _children ( trimmed , { ... context , state : inner _state } ) ;
state . template . push (
b . stmt (
b . call (
'$.valueless_option' ,
b . id ( '$$payload' ) ,
b . thunk ( b . block ( [ ... inner _state . init , ... build _template ( inner _state . template ) ] ) )
)
)
) ;
} else if ( body !== null ) {
// if this is a `<textarea>` value or a contenteditable binding, we only add
// if this is a `<textarea>` value or a contenteditable binding, we only add
// the body if the attribute/binding is falsy
// the body if the attribute/binding is falsy
const inner _state = { ... state , template : [ ] , init : [ ] } ;
const inner _state = { ... state , template : [ ] , init : [ ] } ;
process _children ( trimmed , { ... context , state : inner _state } ) ;
process _children ( trimmed , { ... context , state : inner _state } ) ;
let id = /** @type {Expression} */ ( body ) ;
if ( body . type !== 'Identifier' ) {
id = b . id ( state . scope . generate ( '$$body' ) ) ;
state . template . push ( b . const ( id , body ) ) ;
}
// Use the body expression as the body if it's truthy, otherwise use the inner template
// Use the body expression as the body if it's truthy, otherwise use the inner template
state . template . push (
state . template . push (
b . if (
b . if (
@ -94,6 +170,12 @@ export function RegularElement(node, context) {
b . block ( [ ... inner _state . init , ... build _template ( inner _state . template ) ] )
b . block ( [ ... inner _state . init , ... build _template ( inner _state . template ) ] )
)
)
) ;
) ;
} else {
process _children ( trimmed , { ... context , state } ) ;
}
if ( select _with _value ) {
state . template . push ( b . stmt ( b . assignment ( '=' , b . id ( '$$payload.select_value' ) , b . void0 ) ) ) ;
}
}
if ( ! node _is _void ) {
if ( ! node _is _void ) {