severla fixes to slots...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-04-28 15:53:21 +03:00
parent e338381c02
commit 086d2e6202
2 changed files with 62 additions and 16 deletions

3
bootstrap/Test/slot.html Executable file
View File

@ -0,0 +1,3 @@
<slot name=first text="first slot default"/>

View File

@ -480,8 +480,11 @@ object.Constructor('BasePage', {
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// XXX BUG? '<slot name=x text="moo <now/> foo">' is parsed semi-wrong...
var parser = var parser =
module.parser = { module.parser = {
// patterns...
//
// NOTE: the actual macro pattern is not stored as it depends on // NOTE: the actual macro pattern is not stored as it depends on
// the macro name list which is page dependant... // the macro name list which is page dependant...
// XXX add escaping... // XXX add escaping...
@ -521,6 +524,25 @@ module.parser = {
'<\\s*pwiki-comment[^\\/>]*\\/>', '<\\s*pwiki-comment[^\\/>]*\\/>',
].join('|') +')', 'smig'), ].join('|') +')', 'smig'),
// helpers...
//
getPositional: function(args){
return Object.entries(args)
.reduce(function(res, [key, value]){
/^[0-9]+$/.test(key)
&& (res[key*1] = value)
return res }, []) },
normalizeFilters: function(filters){
var skip = new Set()
return filters
.flat()
.tailUnique()
.filter(function(filter){
filter[0] == '-'
&& skip.add(filter.slice(1))
return filter[0] != '-' })
.filter(function(filter){
return !skip.has(filter) })},
// Strip comments... // Strip comments...
// //
@ -719,17 +741,6 @@ module.parser = {
} else { } else {
yield res } } }, yield res } } },
normalizeFilters: function(filters){
var skip = new Set()
return filters
.flat()
.tailUnique()
.filter(function(filter){
filter[0] == '-'
&& skip.add(filter.slice(1))
return filter[0] != '-' })
.filter(function(filter){
return !skip.has(filter) })},
// Fully parse a page... // Fully parse a page...
// //
// This runs in two stages: // This runs in two stages:
@ -893,6 +904,7 @@ object.Constructor('Page', BasePage, {
// positional args... // positional args...
var src = args.src || args[0] var src = args.src || args[0]
var recursive = args.recursive || body var recursive = args.recursive || body
var isolated = this.__parser__.getPositional(args).includes('isolated')
if(!src){ if(!src){
return '' } return '' }
@ -901,7 +913,7 @@ object.Constructor('Page', BasePage, {
?? function(){ ?? function(){
return this.get(src) return this.get(src)
.parse( .parse(
args.isolated ? isolated ?
{[key]: state[key]} {[key]: state[key]}
: state) } : state) }
@ -945,22 +957,53 @@ object.Constructor('Page', BasePage, {
// ...not sure about anything else... // ...not sure about anything else...
quote: function(){}, quote: function(){},
//
// <slot name=<name>/>
//
// <slot name=<name> text=<text>/>
//
// <slot name=<name>>
// ...
// </slot>
//
// Force show a slot...
// <slot shown ... />
//
// Force hide a slot...
// <slot hidden ... />
//
//
// NOTE: by default only the first slot with <name> is visible,
// all other slot with <name> will replace its content, unless
// explicit shown/hidden arguments are given.
// NOTE: hidden has precedence over shown if both are given.
//
// XXX how do we handle a slot defined within a slot???? // XXX how do we handle a slot defined within a slot????
slot: function(args, body, state){ slot: function(args, body, state){
var name = args.name var name = args.name
var text = args.text ?? body var text = args.text ?? body
var pos = this.__parser__.getPositional(args)
var slots = state.slots = var slots = state.slots =
state.slots state.slots
?? {} ?? {}
// NOTE: we only place text in slots that are defined first,
// all other instances will be omitted... var hidden =
var blank = name in slots // 'hidden' has priority...
(pos.includes('hidden') || args.hidden)
// explicitly show...
|| ((pos.includes('shown') || args.shown) ?
false
// show first instance...
: name in slots)
console.log('---', hidden)
// XXX should this use .parse(..) or .expand(..) ??? // XXX should this use .parse(..) or .expand(..) ???
slots[name] = [...this.__parser__.expand(this, text, state)] slots[name] = [...this.__parser__.expand(this, text, state)]
return blank ? return hidden ?
'' ''
: function(state){ : function(state){
return state.slots[name] } }, return state.slots[name] } },