fixed the @slot(..) recursion issue...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2026-07-01 12:45:37 +03:00
parent 70e44f5a6f
commit 84880015f7
2 changed files with 22 additions and 27 deletions

View File

@ -1315,10 +1315,6 @@ module.parser = {
// Force hide a slot... // Force hide a slot...
// <slot hidden ... /> // <slot hidden ... />
// //
// Insert previous slot content...
// <content/>
//
//
// NOTE: slots are expanded in order of occurance not in order // NOTE: slots are expanded in order of occurance not in order
// of topology, thus nested can override slots they are // of topology, thus nested can override slots they are
// nested in, e.g.: // nested in, e.g.:
@ -1331,11 +1327,12 @@ module.parser = {
// NOTE: hidden has precedence over shown if both are given. // NOTE: hidden has precedence over shown if both are given.
// XXX revise... // XXX revise...
// //
// XXX do we need to be able to insert previous slot value???
// ...this was implemented via <content/>, but the naming
// was not obvious, should be something like <overridden/>
// or <previous/>...
// XXX revise the use of hidden/shown use mechanic and if it's // XXX revise the use of hidden/shown use mechanic and if it's
// needed... // needed...
// XXX do we need to guard from recursion???
// ...do not think it's possible -- everything is resolved
// once and just inseerted as-is (revise)
slot: Macro( slot: Macro(
['name', 'text', ['shown', 'hidden']], ['name', 'text', ['shown', 'hidden']],
lazy( lazy(
@ -1348,7 +1345,6 @@ module.parser = {
var slots = state.slots ??= {} var slots = state.slots ??= {}
//var hidden = name in slots //var hidden = name in slots
// XXX EXPERIMENTAL
var hidden = var hidden =
// 'hidden' has priority... // 'hidden' has priority...
args.hidden args.hidden
@ -1359,30 +1355,31 @@ module.parser = {
: name in slots) : name in slots)
// set slot value... // set slot value...
delete slots[name] //
// NOTE: the slots are filled sequentially, in
// order of opening elements, rather than
// topologically, i.e. filled on the way down
// the tree vs. up.
var slot = slots[name] ??= []
// NOTE: the placeholder is a stand-in for our
// current value that is still to be generated.
var placeholder = [...(0 in slot ? slot : [])]
slot.splice(0, slot.length, placeholder)
// expand slot body...
body = body ? body = body ?
parser.expand(this, body ?? [], state) parser.expand(this, body ?? [], state)
: body : body
// XXX BUG: this breaks into infinite recursion: // if slot not overriden, write our value...
// '<slot a>[[ <slot a> ]]</slot>' if(slot[0] === placeholder){
// -> err slot.splice(0, 1,
// need to somehow break recursion here, if the ...(body != null ?
// nested slot had no/empty body... [body]
// slots[name] ??= body ?? [] : placeholder)) }
// fixes the recursion but also resets the
// parent value...
// need to meke the behavior of the following
// the saem:
// '<slot a>[[ <slot a> ]]</slot>'
// -> err
// and:
// '<slot a>[[ <slot a> ]]</slot> @slot(a)'
// -> '[[ ]]'
slots[name] ??= body
return hidden ? return hidden ?
'' ''
: Object.assign( : Object.assign(
// stage II: place the latest slot value...
function(st){ function(st){
return ((st ?? state).slots ?? {})[name] return ((st ?? state).slots ?? {})[name]
?? body }, ?? body },

View File

@ -72,12 +72,10 @@ test.Setups({
'<slot slot>[[ <slot slot value/> ]]</slot>', '<slot slot>[[ <slot slot value/> ]]</slot>',
'<slot slot shown>[[ <slot slot value/> ]]</slot>', '<slot slot shown>[[ <slot slot value/> ]]</slot>',
'value' ]} }, 'value' ]} },
/*/ XXX recursion...
slot_nested_shown_nested: function(assert){ slot_nested_shown_nested: function(assert){
return {code: [ return {code: [
'<slot slot>[[ <slot slot/> ]]</slot>', '<slot slot>[[ <slot slot/> ]]</slot>',
'[[ ]]' ]} }, '[[ ]]' ]} },
//*/
/* XXX SHOWN_HIDDEN /* XXX SHOWN_HIDDEN
// XXX these need to be revised... // XXX these need to be revised...