@ -9,7 +9,6 @@ import {
extract _identifiers ,
get _parent ,
is _expression _attribute ,
is _quoted _attribute ,
is _text _attribute ,
object ,
unwrap _optional
@ -34,6 +33,17 @@ import { Scope, get_rune } from '../scope.js';
import { merge } from '../visitors.js' ;
import { a11y _validators } from './a11y.js' ;
/** @param {import('#compiler').Attribute} attribute */
function validate _attribute ( attribute ) {
if ( attribute . value === true || attribute . value . length === 1 ) return ;
const is _quoted = attribute . value . at ( - 1 ) ? . end !== attribute . end ;
if ( ! is _quoted ) {
e . attribute _unquoted _sequence ( attribute ) ;
}
}
/ * *
* @ param { import ( '#compiler' ) . Component | import ( '#compiler' ) . SvelteComponent | import ( '#compiler' ) . SvelteSelf } node
* @ param { import ( 'zimmerframe' ) . Context < import ( '#compiler' ) . SvelteNode , import ( './types.js' ) . AnalysisState > } context
@ -58,23 +68,18 @@ function validate_component(node, context) {
}
if ( attribute . type === 'Attribute' ) {
if (
context . state . analysis . runes &&
! is _quoted _attribute ( attribute ) &&
Array . isArray ( attribute . value ) &&
attribute . value . length > 1
) {
e . attribute _invalid _expression ( attribute ) ;
}
if ( context . state . analysis . runes && is _expression _attribute ( attribute ) ) {
const expression = attribute . value [ 0 ] . expression ;
if ( expression . type === 'SequenceExpression' ) {
let i = /** @type {number} */ ( expression . start ) ;
while ( -- i > 0 ) {
const char = context . state . analysis . source [ i ] ;
if ( char === '(' ) break ; // parenthesized sequence expressions are ok
if ( char === '{' ) e . attribute _invalid _sequence _expression ( expression ) ;
if ( context . state . analysis . runes ) {
validate _attribute ( attribute ) ;
if ( is _expression _attribute ( attribute ) ) {
const expression = attribute . value [ 0 ] . expression ;
if ( expression . type === 'SequenceExpression' ) {
let i = /** @type {number} */ ( expression . start ) ;
while ( -- i > 0 ) {
const char = context . state . analysis . source [ i ] ;
if ( char === '(' ) break ; // parenthesized sequence expressions are ok
if ( char === '{' ) e . attribute _invalid _sequence _expression ( expression ) ;
}
}
}
}
@ -116,23 +121,18 @@ function validate_element(node, context) {
if ( attribute . type === 'Attribute' ) {
const is _expression = is _expression _attribute ( attribute ) ;
if (
context . state . analysis . runes &&
! is _quoted _attribute ( attribute ) &&
Array . isArray ( attribute . value ) &&
attribute . value . length > 1
) {
e . attribute _invalid _expression ( attribute ) ;
}
if ( context . state . analysis . runes && is _expression ) {
const expression = attribute . value [ 0 ] . expression ;
if ( expression . type === 'SequenceExpression' ) {
let i = /** @type {number} */ ( expression . start ) ;
while ( -- i > 0 ) {
const char = context . state . analysis . source [ i ] ;
if ( char === '(' ) break ; // parenthesized sequence expressions are ok
if ( char === '{' ) e . attribute _invalid _sequence _expression ( expression ) ;
if ( context . state . analysis . runes ) {
validate _attribute ( attribute ) ;
if ( is _expression ) {
const expression = attribute . value [ 0 ] . expression ;
if ( expression . type === 'SequenceExpression' ) {
let i = /** @type {number} */ ( expression . start ) ;
while ( -- i > 0 ) {
const char = context . state . analysis . source [ i ] ;
if ( char === '(' ) break ; // parenthesized sequence expressions are ok
if ( char === '{' ) e . attribute _invalid _sequence _expression ( expression ) ;
}
}
}
}