mirror of
https://github.com/flynx/pWiki.git
synced 2026-01-03 08:31:09 +00:00
fixed several interconnected bugs + notes...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
7cca3f38f6
commit
484e779300
@ -496,6 +496,8 @@ module.Page =
|
|||||||
object.Constructor('Page', BasePage, {
|
object.Constructor('Page', BasePage, {
|
||||||
__parser__: parser.parser,
|
__parser__: parser.parser,
|
||||||
|
|
||||||
|
NESTING_RECURSION_THRESHOLD: 10,
|
||||||
|
|
||||||
// Filter that will isolate the page/include/.. from parent filters...
|
// Filter that will isolate the page/include/.. from parent filters...
|
||||||
ISOLATED_FILTERS: 'isolated',
|
ISOLATED_FILTERS: 'isolated',
|
||||||
|
|
||||||
@ -641,8 +643,20 @@ object.Constructor('Page', BasePage, {
|
|||||||
// <text>
|
// <text>
|
||||||
// </include>
|
// </include>
|
||||||
//
|
//
|
||||||
// XXX 'text' argument is changed to 'recursive'...
|
// NOTE: there can be two ways of recursion in pWiki:
|
||||||
// XXX revise recursion checks....
|
// - flat recursion
|
||||||
|
// /A -> /A -> /A -> ..
|
||||||
|
// - nested recursion
|
||||||
|
// /A -> /A/A -> /A/A/A -> ..
|
||||||
|
// Both can be either direct (type I) or indirect (type II).
|
||||||
|
// The former is trivial to check for while the later is
|
||||||
|
// not quite so, as we can have different contexts at
|
||||||
|
// different paths that would lead to different resulting
|
||||||
|
// renders.
|
||||||
|
// At the moment nested recursion is checked in a fast but
|
||||||
|
// not 100% correct manner focusing on path depth and ignoring
|
||||||
|
// the context, this potentially can lead to false positives.
|
||||||
|
//
|
||||||
// XXX should this be lazy???
|
// XXX should this be lazy???
|
||||||
include: Macro(
|
include: Macro(
|
||||||
['src', 'recursive', 'join', ['isolated']],
|
['src', 'recursive', 'join', ['isolated']],
|
||||||
@ -665,7 +679,8 @@ object.Constructor('Page', BasePage, {
|
|||||||
?? async function(src){
|
?? async function(src){
|
||||||
return isolated ?
|
return isolated ?
|
||||||
{data: await this.get(src)
|
{data: await this.get(src)
|
||||||
.parse({seen: (state.seen ?? []).slice()})}
|
//.parse({seen: new Set(state.seen ?? [])})}
|
||||||
|
.parse({seen: state.seen})}
|
||||||
: this.get(src)
|
: this.get(src)
|
||||||
.parse(state) }
|
.parse(state) }
|
||||||
|
|
||||||
@ -677,20 +692,30 @@ object.Constructor('Page', BasePage, {
|
|||||||
// handle recursion...
|
// handle recursion...
|
||||||
var parent_seen = 'seen' in state
|
var parent_seen = 'seen' in state
|
||||||
var seen = state.seen =
|
var seen = state.seen =
|
||||||
(state.seen
|
new Set(state.seen ?? [])
|
||||||
?? []).slice()
|
|
||||||
// recursion detected...
|
// recursion detected...
|
||||||
//if(seen.includes(full) || full == base){
|
if(seen.has(full)
|
||||||
if(seen.includes(full)){
|
// nesting path recursion...
|
||||||
|
// XXX a more general way to check would be to see if the
|
||||||
|
// path resolves to the same source (done below) and
|
||||||
|
// check if the context has changed -- i.e. if the paths
|
||||||
|
// actually contain anything...
|
||||||
|
|| (seen.size % (this.NESTING_RECURSION_THRESHOLD || 10) == 0
|
||||||
|
&& new Set([...seen]
|
||||||
|
.map(function(p){
|
||||||
|
return page.get(p).match()[0] }))
|
||||||
|
.size < seen.size)){
|
||||||
if(!recursive){
|
if(!recursive){
|
||||||
return base.parse(page.get('./'+page.RECURSION_ERROR).raw) }
|
return page.get(page.RECURSION_ERROR).parse(state) }
|
||||||
// have the 'recursive' arg...
|
// have the 'recursive' arg...
|
||||||
return base.parse(recursive, state) }
|
return base.parse(recursive, state) }
|
||||||
seen.push(full)
|
seen.add(full)
|
||||||
|
|
||||||
// load the included page...
|
// load the included page...
|
||||||
var res = await handler.call(page, full)
|
var res = await handler.call(page, full)
|
||||||
|
|
||||||
|
// NOTE: we only track recursion down and not sideways...
|
||||||
|
seen.delete(full)
|
||||||
if(!parent_seen){
|
if(!parent_seen){
|
||||||
delete state.seen }
|
delete state.seen }
|
||||||
|
|
||||||
@ -710,7 +735,7 @@ object.Constructor('Page', BasePage, {
|
|||||||
'source',
|
'source',
|
||||||
args, body, state, 'sources',
|
args, body, state, 'sources',
|
||||||
async function(src){
|
async function(src){
|
||||||
return this.parse(await this.get(src).raw, state) }) }),
|
return this.parse(this.get(src).raw, state) }) }),
|
||||||
//
|
//
|
||||||
// @quote(<src>)
|
// @quote(<src>)
|
||||||
//
|
//
|
||||||
@ -950,8 +975,7 @@ object.Constructor('Page', BasePage, {
|
|||||||
// sort pages...
|
// sort pages...
|
||||||
// XXX SORT
|
// XXX SORT
|
||||||
if(sort.length > 0){
|
if(sort.length > 0){
|
||||||
console.log('XXX: macro sort: not implemented')
|
console.log('XXX: macro sort: not implemented') }
|
||||||
}
|
|
||||||
|
|
||||||
var join_block = _getBlock('join')
|
var join_block = _getBlock('join')
|
||||||
|
|
||||||
@ -990,6 +1014,7 @@ object.Constructor('Page', BasePage, {
|
|||||||
//
|
//
|
||||||
parse: async function(text, state){
|
parse: async function(text, state){
|
||||||
var that = this
|
var that = this
|
||||||
|
text = await text
|
||||||
// .parser(<state>)
|
// .parser(<state>)
|
||||||
if(arguments.length == 1
|
if(arguments.length == 1
|
||||||
&& text instanceof Object
|
&& text instanceof Object
|
||||||
@ -1023,7 +1048,7 @@ object.Constructor('Page', BasePage, {
|
|||||||
// went really wrong...
|
// went really wrong...
|
||||||
if(data == null){
|
if(data == null){
|
||||||
if(this.NOT_FOUND_ERROR){
|
if(this.NOT_FOUND_ERROR){
|
||||||
var msg = this.get('./'+ this.NOT_FOUND_ERROR)
|
var msg = this.get(this.NOT_FOUND_ERROR)
|
||||||
if(await msg.match()){
|
if(await msg.match()){
|
||||||
return msg.raw } }
|
return msg.raw } }
|
||||||
// last resort...
|
// last resort...
|
||||||
@ -1068,7 +1093,7 @@ object.Constructor('Page', BasePage, {
|
|||||||
// render template in context of page...
|
// render template in context of page...
|
||||||
var data = { render_root: this }
|
var data = { render_root: this }
|
||||||
return this.get(path, data)
|
return this.get(path, data)
|
||||||
.parse(await this.get(tpl, data).raw) }).call(this) },
|
.parse(this.get(tpl, data).raw) }).call(this) },
|
||||||
set text(value){
|
set text(value){
|
||||||
this.__update__({text: value}) },
|
this.__update__({text: value}) },
|
||||||
//this.onTextUpdate(value) },
|
//this.onTextUpdate(value) },
|
||||||
@ -1252,8 +1277,6 @@ module.System = {
|
|||||||
|
|
||||||
// XXX tests...
|
// XXX tests...
|
||||||
//
|
//
|
||||||
_test_macro: {
|
|
||||||
text: '@source(./name) @source(./name)'},
|
|
||||||
test_page: function(){
|
test_page: function(){
|
||||||
console.log('--- RENDERER:', this.render_root)
|
console.log('--- RENDERER:', this.render_root)
|
||||||
console.log('--- PATH: ', this.path)
|
console.log('--- PATH: ', this.path)
|
||||||
@ -1273,9 +1296,9 @@ module.System = {
|
|||||||
//
|
//
|
||||||
// NOTE: these are last resort pages, preferably overloaded in /Templates.
|
// NOTE: these are last resort pages, preferably overloaded in /Templates.
|
||||||
RecursionError: {
|
RecursionError: {
|
||||||
text: 'RECURSION ERROR: @quote(./path)' },
|
text: 'RECURSION ERROR: @quote(../path)' },
|
||||||
NotFoundError: {
|
NotFoundError: {
|
||||||
text: 'NOT FOUND ERROR: @quote(./path)' },
|
text: 'NOT FOUND ERROR: @quote(../path)' },
|
||||||
|
|
||||||
DeletingPage: {
|
DeletingPage: {
|
||||||
text: 'Deleting: @source(../path)' },
|
text: 'Deleting: @source(../path)' },
|
||||||
@ -1338,7 +1361,7 @@ module.System = {
|
|||||||
this.render_root
|
this.render_root
|
||||||
&& (this.render_root.location = this.referrer)
|
&& (this.render_root.location = this.referrer)
|
||||||
// show info about the delete operation...
|
// show info about the delete operation...
|
||||||
return target.get('./DeletingPage').text },
|
return target.get('DeletingPage').text },
|
||||||
|
|
||||||
// XXX System/back
|
// XXX System/back
|
||||||
// XXX System/forward
|
// XXX System/forward
|
||||||
|
|||||||
@ -60,22 +60,24 @@ pwiki.store.update('@pouch', {
|
|||||||
// XXX TEST...
|
// XXX TEST...
|
||||||
// XXX add filter tests...
|
// XXX add filter tests...
|
||||||
pwiki.pwiki
|
pwiki.pwiki
|
||||||
// XXX BUG: the second @source(..) includes the current page again
|
|
||||||
// for some reason....
|
|
||||||
.update({
|
|
||||||
location: '/test/macros',
|
|
||||||
text: object.doc`
|
|
||||||
some text with inline @source(./path) macros...
|
|
||||||
|
|
||||||
<div wikiwords=no>
|
|
||||||
now @source(./path) inside a div...
|
|
||||||
</div>` })
|
|
||||||
.update({
|
.update({
|
||||||
location: '/test/markdown',
|
location: '/test/markdown',
|
||||||
text: object.doc`
|
text: object.doc`
|
||||||
some text with inline @source(./path) macros...
|
some text with inline @source(./path) macros...
|
||||||
|
|
||||||
@filter(markdown)` })
|
@filter(markdown)` })
|
||||||
|
.update({
|
||||||
|
location: '/test/recursion',
|
||||||
|
text: object.doc` @include(.) ` })
|
||||||
|
.update({
|
||||||
|
location: '/test/recursionA',
|
||||||
|
text: object.doc` @include(../recursionB) ` })
|
||||||
|
.update({
|
||||||
|
location: '/test/recursionB',
|
||||||
|
text: object.doc` @include(../recursionA) ` })
|
||||||
|
.update({
|
||||||
|
location: '/test/recursionC',
|
||||||
|
text: object.doc` @include(recursionC) ` })
|
||||||
.update({
|
.update({
|
||||||
location: '/test/sort/*',
|
location: '/test/sort/*',
|
||||||
order: ['a', 'c', 'b'], })
|
order: ['a', 'c', 'b'], })
|
||||||
|
|||||||
14
pwiki2.js
14
pwiki2.js
@ -1,11 +1,7 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* XXX BUG: source/include problem...
|
* XXX BUG: /** /paths -- does not work...
|
||||||
* to reproduce:
|
|
||||||
* .get('/System/_text_macro/_text').text
|
|
||||||
* this does not exhibit the issue:
|
|
||||||
* .get('/System/_text_macro').text
|
|
||||||
* XXX BUG?: markdown: when parsing chunks each chunk gets an open/closed
|
* XXX BUG?: markdown: when parsing chunks each chunk gets an open/closed
|
||||||
* <p> inserted at start/end -- this breaks stuff returned by macros...
|
* <p> inserted at start/end -- this breaks stuff returned by macros...
|
||||||
* ...there are two ways to dance around this:
|
* ...there are two ways to dance around this:
|
||||||
@ -15,7 +11,11 @@
|
|||||||
* ...this is expected but not intuitive...
|
* ...this is expected but not intuitive...
|
||||||
* might be a good idea to add a special path like /Stores to list
|
* might be a good idea to add a special path like /Stores to list
|
||||||
* sub-stores...
|
* sub-stores...
|
||||||
* XXX OPTIMIZE: /_tree is really slow...
|
* XXX OPTIMIZE: /tree is really slow...
|
||||||
|
* ...is the problem purely in the async/await playing ping-pong???
|
||||||
|
* XXX might be a good idea to make things optionally sync via a .sync()
|
||||||
|
* method, or request a specific set of data (in the parser, after
|
||||||
|
* collecting all the stuff needed and fetching it in one go)...
|
||||||
* XXX might be a good idea to add page caching (state.page_cache) relative
|
* XXX might be a good idea to add page caching (state.page_cache) relative
|
||||||
* to a path on parsing, to avoid re-matching the same page over and
|
* to a path on parsing, to avoid re-matching the same page over and
|
||||||
* over again from the same context
|
* over again from the same context
|
||||||
@ -159,6 +159,8 @@
|
|||||||
* NOTE: implementing things in a traditional manner would
|
* NOTE: implementing things in a traditional manner would
|
||||||
* introduce lots of edge-cases and subtle ways to make
|
* introduce lots of edge-cases and subtle ways to make
|
||||||
* mistakes, bugs and inconsistencies.
|
* mistakes, bugs and inconsistencies.
|
||||||
|
* - types of recursion
|
||||||
|
* (see: pwiki/page.js: Page.macros.include(..) notes)
|
||||||
* -
|
* -
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user