tweaks, fixes and some refactoring...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-08-05 02:47:31 +03:00
parent b5264396cc
commit 8c24ba36bd
4 changed files with 61 additions and 41 deletions

View File

@ -28,7 +28,7 @@ module = {
ALTERNATIVE_PAGES: [ ALTERNATIVE_PAGES: [
'EmptyPage', 'EmptyPage',
'NotFound', 'NotFoundError',
], ],
// Default alternate search locations... // Default alternate search locations...

87
page.js
View File

@ -477,8 +477,6 @@ function(spec, func){
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
module.PAGE_NOT_FOUND = '404: PAGE NOT FOUND: $PATH'
// XXX PATH_VARS need to handle path variables... // XXX PATH_VARS need to handle path variables...
// XXX filters (and macros?) should be features for simpler plugin handlng (???) // XXX filters (and macros?) should be features for simpler plugin handlng (???)
// XXX STUB filters... // XXX STUB filters...
@ -503,7 +501,9 @@ object.Constructor('Page', BasePage, {
// as if we reach this it's likely all the bootstrap is either also // as if we reach this it's likely all the bootstrap is either also
// not present or broken. // not present or broken.
// NOTE: to force the system to fail set this to undefined. // NOTE: to force the system to fail set this to undefined.
PAGE_NOT_FOUND: module.PAGE_NOT_FOUND, NOT_FOUND_ERROR: 'NotFoundError',
RECURSION_ERROR: 'RecursionError',
// //
// <filter>(<source>) // <filter>(<source>)
@ -634,7 +634,8 @@ object.Constructor('Page', BasePage, {
async function(args, body, state, key='included', handler){ async function(args, body, state, key='included', handler){
var macro = 'include' var macro = 'include'
if(typeof(args) == 'string'){ if(typeof(args) == 'string'){
var [macro, args, body, state, key="included", handler] = arguments } var [macro, args, body, state, key, handler] = arguments
key = key ?? 'included' }
// positional args... // positional args...
var src = args.src var src = args.src
var recursive = args.recursive || body var recursive = args.recursive || body
@ -647,50 +648,44 @@ object.Constructor('Page', BasePage, {
var full = this.get(src).path var full = this.get(src).path
handler = handler handler = handler
?? function(){ ?? function(src){
return this.get(src) return this.get(src)
.parse( .parse(
isolated ? isolated ?
{[key]: state[key]} {seen: (state.seen ?? []).slice()}
: state) } : state) }
// handle recursion... // handle recursion...
var parent_seen = state[key] var parent_seen = 'seen' in state
var seen = state[key] = var seen = state.seen =
state[key] (state.seen
?? [] ?? []).slice()
// recursion detected... // recursion detected...
if(seen.includes(full)){ if(seen.includes(full) || full == this.path){
if(!recursive){ if(!recursive){
throw new Error( return this.parse(this.get('./'+this.RECURSIVE_TPL).raw) }
macro +': recursion detected: '
+ seen.concat([full]).join(' -> ')) }
// have the 'recursive' arg... // have the 'recursive' arg...
return this.parse(recursive, state) } return this.parse(recursive, state) }
seen.push(full) seen.push(full)
// load the included page... // load the included page...
var res = await handler.call(this) var res = await handler.call(this, src)
// restore previous include chain... if(!parent_seen){
if(parent_seen){ delete state.seen }
state[key] = parent_seen
} else {
delete state[key] }
return res }), return res }),
// NOTE: the main difference between this and @include is that
// this renders the src in the context of current page while
// include is rendered in the context of its page but with
// the same state...
source: Macro( source: Macro(
['src'], ['src'],
async function(args, body, state){ async function(args, body, state){
var src = args.src
// parse arg values...
src = src ?
await this.parse(src, state)
: src
return this.macros.include.call(this, return this.macros.include.call(this,
'source', 'source',
args, body, state, 'sources', args, body, state, 'sources',
async function(){ async function(src){
return await this.parse(await this.get(src).raw +'', state) }) }), return await this.parse(await this.get(src).raw +'', state) }) }),
// //
// @quote(<src>) // @quote(<src>)
@ -1008,12 +1003,12 @@ object.Constructor('Page', BasePage, {
// not even the System/NotFound page, i.e. something // not even the System/NotFound page, i.e. something
// went really wrong... // went really wrong...
if(data == null){ if(data == null){
var msg = (this.PAGE_NOT_FOUND if(this.NOT_FOUND_ERROR){
|| module.PAGE_NOT_FOUND) var msg = this.get('./'+ this.NOT_FOUND_ERROR)
.replace(/\$PATH/, this.path) if(await msg.match()){
if(this.PAGE_NOT_FOUND){ return msg.raw } }
return msg } // last resort...
throw new Error(msg) } throw new Error('NOT FOUND ERROR: '+ this.path) }
// get the data... // get the data...
return ( return (
// action... // action...
@ -1036,6 +1031,15 @@ object.Constructor('Page', BasePage, {
// //
// NOTE: this uses .PAGE_TPL to render the page. // NOTE: this uses .PAGE_TPL to render the page.
// NOTE: writing to .raw is the same as writing to .text... // NOTE: writing to .raw is the same as writing to .text...
//* XXX not sure if this is a good strategy...
get text(){ return (async function(){
var path = pwpath.split(this.path)
return [path.at(-1)[0] == '_' ?
await this.parse()
: await this.get('./'+ this.PAGE_TPL).parse()]
.flat()
.join('\n') }).call(this) },
/*/
get text(){ return (async function(){ get text(){ return (async function(){
var tpl = '/'+ await this.find('./'+ this.PAGE_TPL) var tpl = '/'+ await this.find('./'+ this.PAGE_TPL)
return [await this.parse( return [await this.parse(
@ -1044,6 +1048,7 @@ object.Constructor('Page', BasePage, {
: [] )] : [] )]
.flat() .flat()
.join('\n') }).call(this) }, .join('\n') }).call(this) },
//*/
set text(value){ set text(value){
this.__update__({text: value}) }, this.__update__({text: value}) },
//this.onTextUpdate(value) }, //this.onTextUpdate(value) },
@ -1058,13 +1063,19 @@ var System =
module.System = { module.System = {
// base templates... // base templates...
// //
// XXX revise this...
// ...need to be able to do: /some/path/_text
_text: { _text: {
text: '<macro src="." join="\n">@source(.)</macro>' }, // XXX join does not seem to do anything...
NotFound: { // ...this might be applied to each page rather than to a
text: module.PAGE_NOT_FOUND // set of pages...
.replace('$PATH', '@source(./path)') }, //text: '<macro src=".." join="\n">@source(.)</macro>' },
text: '@include(..)' },
_list: {
text: '<macro src=".." join="\n---\n">@source(.)</macro>' },
RecursionError: {
text: 'RECURSION ERROR: @quote(./path)' },
NotFoundError: {
text: 'NOT FOUND ERROR: @quote(./path)' },
// XXX tests... // XXX tests...
test_list: function(){ test_list: function(){

View File

@ -49,7 +49,7 @@ pwiki.store.update('@pouch', {
// XXX experiments and testing... // XXX experiments and testing...
// XXX for persistent stores test if the data is already loaded here... // XXX for persistent stores test if the data is already loaded here...
pwiki.store.load(bootstrap) //pwiki.store.load(bootstrap)
// XXX TEST... // XXX TEST...
@ -106,7 +106,7 @@ pwiki.pwiki
+'@slot(name=b text="non-filled slot")\n' +'@slot(name=b text="non-filled slot")\n'
+'\n' +'\n'
+'Including /other #1: @include(/other)\n' +'Including /other #1: @include(/other)\n'
+'Including /other #2: @include(/other)\n' //+'Including /other #2: @include(/other)\n'
+'\n' +'\n'
+'Including /test: @include(/test recursive="Recursion type 1 (<now/>)")\n' +'Including /test: @include(/test recursive="Recursion type 1 (<now/>)")\n'
+'\n' +'\n'

View File

@ -1,6 +1,15 @@
/********************************************************************** /**********************************************************************
* *
* *
* XXX the following are not the same:
* pwiki.get(/test).parse('<macro src="*" join="\n">@source('./path')</macro>')
* and
* pwiki.get('/test/*').parse('<macro src="." join="\n">@source('./path')</macro>')
* the former is called once and iterates while the later is called
* per-page...
* ...should be the same -- i.e. the macro should decide...
* page range -> include -> joun
* page range -> macro -> iterate
* XXX wikiword filter seems to hang on / * XXX wikiword filter seems to hang on /
* XXX do filters affect the whole page or only what comes after??? * XXX do filters affect the whole page or only what comes after???
* XXX need to be able to affect the default render wrpaper... * XXX need to be able to affect the default render wrpaper...