@ -10,6 +10,7 @@ import { analyze_component, analyze_module } from './phases/2-analyze/index.js';
import { transform _component , transform _module } from './phases/3-transform/index.js' ;
import { transform _component , transform _module } from './phases/3-transform/index.js' ;
import { validate _component _options , validate _module _options } from './validate-options.js' ;
import { validate _component _options , validate _module _options } from './validate-options.js' ;
import * as state from './state.js' ;
import * as state from './state.js' ;
import * as e from './errors.js' ;
export { default as preprocess } from './preprocess/index.js' ;
export { default as preprocess } from './preprocess/index.js' ;
export { print } from './print/index.js' ;
export { print } from './print/index.js' ;
@ -34,6 +35,32 @@ export function compile(source, options) {
... parsed _options
... parsed _options
} = parsed . options || { } ;
} = parsed . options || { } ;
// resolve the per-component custom renderer, taking `<svelte:options customRenderer={...} />`
// into account. The normalized option is always a function returning `string | null | undefined`
// (see `validate-options.js`). A string opts in to a specific renderer module, `null`/`false`
// opts out to plain DOM (while keeping the feature enabled) and `true`/absent inherits whatever
// the global option resolves to.
let custom _renderer _option = validated . experimental . customRenderer ;
if ( custom _renderer !== undefined ) {
// the feature is a global compiler option — a component can only override the renderer it uses
// (or opt out) when `experimental.customRenderer` is enabled. Otherwise nothing pushes a
// renderer, so allowing `<svelte:options customRenderer>` would silently do the wrong thing.
if ( ! options . experimental ? . customRenderer && parsed . options ? . attributes ) {
for ( const attribute of parsed . options . attributes ) {
if ( attribute . name === 'customRenderer' ) {
e . svelte _options _customrenderer _disabled ( attribute ) ;
}
}
}
if ( typeof custom _renderer === 'string' ) {
custom _renderer _option = ( ) => custom _renderer ;
} else if ( custom _renderer === false || custom _renderer === null ) {
custom _renderer _option = ( ) => null ;
}
}
/** @type {ValidatedCompileOptions} */
/** @type {ValidatedCompileOptions} */
const combined _options = {
const combined _options = {
... validated ,
... validated ,
@ -43,7 +70,7 @@ export function compile(source, options) {
runes : 'runes' in parsed _options ? ( ) => parsed _options . runes : validated . runes ,
runes : 'runes' in parsed _options ? ( ) => parsed _options . runes : validated . runes ,
experimental : {
experimental : {
... validated . experimental ,
... validated . experimental ,
... ( custom _renderer !== undefined ? { customRenderer : ( ) => custom _renderer } : { } )
customRenderer : custom _renderer _option
}
}
} ;
} ;