lots of tweaks and cleanup...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-08-15 14:29:45 +03:00
parent 128b4276f7
commit 6befa05d33
9 changed files with 156 additions and 48 deletions

View File

@ -57,8 +57,8 @@ pwiki.store.update('@pouch', {
// XXX
typeof(Bootstrap) != 'undefined'
&& pwiki.store.load(Bootstrap)
//typeof(Bootstrap) != 'undefined'
// && pwiki.store.load(Bootstrap)

View File

@ -10,7 +10,7 @@
var WIKIWORD_PATTERN =
RegExp('('+[
// /some/path | ./some/path | ../some/path | >>/some/path
'(?:^|\\s)(|\\.|\\.\\.|>>)[\\/\\\\][^\\s]+',
'(?<=^|\\s)(|\\.|\\.\\.|>>)[\\/\\\\][^\\s]+',
// [path]
'\\\\?\\[[^\\]]+\\]',
// WikiWord

View File

@ -22,6 +22,8 @@ base.Filter(
tables: true,
tasklists: true,
})
// XXX the problem here is that any string gets nested into a
// paragraph -- this messes up partial filtering...
return converter.makeHtml(source) })
module.quoteMarkdown =

View File

@ -324,7 +324,8 @@ object.Constructor('BasePage', {
location: path,
...data,
referrer: data.referrer
?? this.location,
//?? this.location,
?? this.referrer,
strict,
}) },
@ -343,10 +344,11 @@ object.Constructor('BasePage', {
: paths instanceof Promise ?
await paths
: [paths]
// XXX MATCH
/*/ XXX MATCH
paths = paths.length == 0 ?
[await this.find(path)]
: paths
//*/
for(var path of paths){
yield this.get('/'+ path) } },
@ -424,6 +426,8 @@ object.Constructor('BasePage', {
// this will make all the non-shadowed attrs set on the
// root visible to all sub-pages.
: Object.create(src),
// XXX
//{...this},
{
root: this.root ?? this,
location: this.location,
@ -695,21 +699,15 @@ object.Constructor('Page', BasePage, {
if(typeof(args) == 'string'){
var [macro, args, body, state, key, handler] = arguments
key = key ?? 'included' }
// positional args...
var base = this.get(this.path.split(/\*/).shift())
var src = args.src
&& await this.parse(args.src, state)
&& await base.parse(args.src, state)
if(!src){
return }
var recursive = args.recursive || body
var isolated = args.isolated
var join = args.join
&& await this
// render join block relative to the path before the first '*'...
.get(this.path.split(/\*/).shift())
.parse(args.join, state)
// parse arg values...
var base = this.get(src).path
&& await base.parse(args.join, state)
handler = handler
?? async function(src){
@ -734,9 +732,9 @@ object.Constructor('Page', BasePage, {
//if(seen.includes(full) || full == base){
if(seen.includes(full)){
if(!recursive){
return page.parse(page.get('./'+page.RECURSION_ERROR).raw) }
return base.parse(page.get('./'+page.RECURSION_ERROR).raw) }
// have the 'recursive' arg...
return page.parse(recursive, state) }
return base.parse(recursive, state) }
seen.push(full)
// load the included page...
@ -787,12 +785,13 @@ object.Constructor('Page', BasePage, {
['src', 'filter', 'text'],
async function(args, body, state){
var src = args.src //|| args[0]
var base = this.get(this.path.split(/\*/).shift())
var text = args.text
?? body
?? []
// parse arg values...
src = src ?
await this.parse(src, state)
await base.parse(src, state)
: src
text = src ?
// source page...
@ -935,6 +934,7 @@ object.Constructor('Page', BasePage, {
var that = this
var name = args.name //?? args[0]
var src = args.src
var base = this.get(this.path.split(/\*/).shift())
var sort = (args.sort ?? '')
.split(/\s+/g)
.filter(function(e){
@ -970,7 +970,7 @@ object.Constructor('Page', BasePage, {
return block }
if(name){
name = await this.parse(name, state)
name = await base.parse(name, state)
// define new named macro...
if(text){
;(state.macros = state.macros ?? {})[name] = text
@ -980,7 +980,7 @@ object.Constructor('Page', BasePage, {
text = state.macros[name] } }
if(src){
src = await this.parse(src, state)
src = await base.parse(src, state)
var pages = this.get(src, strict)
pages = await pages.isArray ?
// XXX should we wrap this in pages...
@ -1113,12 +1113,20 @@ object.Constructor('Page', BasePage, {
if(!tpl){
throw new Error('UNKNOWN RENDER TEMPLATE: '+ tpl_name) }
var data = {
render_root: this,
}
// render template in context of page...
return this.get(path)
.parse(await this.get(tpl).raw) }).call(this) },
return this.get(path, data)
.parse(await this.get(tpl, data).raw) }).call(this) },
set text(value){
this.__update__({text: value}) },
//this.onTextUpdate(value) },
clone: function(data={}, ...args){
this.render_root
&& (data = {render_root: this.render_root, ...data})
return object.parentCall(Page.prototype.clone, this, data, ...args) },
})
@ -1244,7 +1252,7 @@ module.System = {
'<macro src="." join="@source(file-separator)">'
+'<pre wikiwords="no"><quote filter="quote-tags" src="."/></pre>'
+'</macro>'},
_ed: {
_edit: {
//_edit: {
text:
'<macro src="." join="@source(file-separator)">'
@ -1256,8 +1264,50 @@ module.System = {
+'</pre>'
+'</macro>'},
paths: {
text: '<macro src="../*/path" join=" ">@source(.)</macro>' },
// XXX debug...
_path: {text: '@source(./path join=" ")'},
list: {
text: '<macro src="../*/path" join="@source(line-separator)">@source(.)</macro>' },
// XXX this is really slow...
// XXX for some reason replacing both @quote(..) with @source(..) in
// the links will break macro parsing...
// XXX should this be all or tree???
tree: {
text: object.doc`
<macro src="../*">
<div>
<a href="#@quote(./path)">@source(./name)</a>
<a href="#@quote(./path)/delete">&times;</a>
<div style="padding-left: 30px">
@source(./tree)
</div>
</div>
</macro>` },
// XXX this is somewhat broken...
info: {
text: object.doc`
# @source(./path)
- Render root: @source(./renderer)
- Render root: @source(./renderer)
` },
// XXX tests...
//
test_page: function(){
console.log('--- RENDERER:', this.render_root)
console.log('--- PATH: ', this.path)
console.log('--- REFERRER:', this.referrer)
console.log('--- PAGE:', this)
return this.path },
test_list: function(){
return 'abcdef'.split('') },
// page parts...
//
@ -1272,17 +1322,18 @@ module.System = {
NotFoundError: {
text: 'NOT FOUND ERROR: @quote(./path)' },
DeletingPage: {
text: 'Deleting: @source(../path)' },
// page actions...
//
// XXX tests...
test_list: function(){
return 'abcdef'.split('') },
// metadata...
//
renderer: function(){
return (this.render_root || {}).path },
path: function(){
return this.get('..').path },
location: function(){
@ -1324,9 +1375,16 @@ module.System = {
// actions...
//
delete: function(){
this.location = '..'
this.delete()
return this.text },
var target = this.get('..')
target.delete()
// redirect...
this.render_root
&& (this.render_root.location = this.referrer)
// show info about the delete operation...
return target.get('./DeletingPage').text },
// XXX System/back
// XXX System/forward
// XXX System/sort

View File

@ -500,7 +500,6 @@ module.BaseParser = {
// will have no effect on the result...
return page.filters[filter].call(page, res)
?? res }, section)
//*/
// no global filters...
: section ) })
.flat()

View File

@ -58,9 +58,10 @@ module = {
var root = path[0] == ''
|| path[0] == '/'
path = (path instanceof Array ?
path
// NOTE: this will also trim the path elements...
: path.split(/\s*[\\\/]+\s*/))
path.join('/')
: path)
// NOTE: this will also trim the path elements...
.split(/\s*[\\\/]+\s*/)
.reduce(function(res, e, i, L){
// special case: leading '..' / '.'
if(res.length == 0
@ -94,8 +95,7 @@ module = {
return this.normalize(
(parts[0] instanceof Array ?
parts[0]
: parts)
.join('/'),
: parts),
'string') },
basename: function(path){
path = this.split(path)

View File

@ -68,6 +68,7 @@ module.BaseStore = {
// XXX might be a good idea to cache this...
__paths__: async function(){
return Object.keys(this.data) },
//* XXX uncached...
paths: async function(local=false){
return this.__paths__()
.iter()
@ -75,6 +76,25 @@ module.BaseStore = {
.concat((!local && (this.next || {}).paths) ?
this.next.paths()
: []) },
/*/
__paths_cache_timeout: 1000,
__paths_cache_timer: undefined,
__paths_cache: undefined,
paths: async function(local=false){
this.__paths_cache_timer =
this.__paths_cache_timer
?? setTimeout(function(){
delete this.__paths_cache_timer
delete this.__paths_cache
}.bind(this), this.__paths_cache_timeout ?? 1000)
return this.__paths_cache
|| this.__paths__()
.iter()
// XXX NEXT
.concat((!local && (this.next || {}).paths) ?
this.next.paths()
: []) },
//*/
//
// .exists(<path>)
@ -364,7 +384,7 @@ module.BaseStore = {
res[path] = page } } }
return (stringify
&& typeof(res) != 'string') ?
JSON.stringify(res)
JSON.stringify(res, options.replacer, options.space)
: res },
// XXX NEXT EXPERIMENTAL...

View File

@ -58,6 +58,22 @@ pwiki.store.update('@pouch', {
// XXX TEST...
// XXX add filter tests...
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=false>
now @source(./path) inside a div...
</div>` })
.update({
location: '/test/markdown',
text: object.doc`
some text with inline @source(./path) macros...
@filter(markdown)` })
.update({
location: '/test/sort/*',
order: ['a', 'c', 'b'], })

View File

@ -1,11 +1,11 @@
/**********************************************************************
*
*
* XXX BUG: join block gets repeated three times per page...
* await p.pwiki.get('/test/sort/*').text
* essentially this is the culprit:
* await p.pwiki.get('/test/sort/*').parse('@source(file-separator)')
* XXX BUG: browser: .get('/*').raw hangs in the browser context...
*
* XXX BUG: pwiki2-test.js: /test/macros -- broken parser...
* XXX BUG?: markdown: when parsing chunks each chunk gets an open/closed
* <p> inserted at start/end -- this breaks stuff returned by macros...
* XXX OPTIMIZE: /_tree is really slow...
* 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
* over again from the same context
@ -17,6 +17,13 @@
* },
* ...
* }
* XXX BUG: browser: .get('/*').raw hangs in the browser context...
* XXX BUG?: /_tree for some reason does not show anything on lower levels...
* ...renaming _tree -> all fixed the issue
* ...might be a problem with how rendering templates are handled in
* <page>.text...
* ...if this is not fixable need to document that rendering templates
* are not to be recursive...
* XXX add action to reset overloaded (bootstrap) pages...
* - per page
* - global
@ -32,24 +39,30 @@
* - render page -- DONE
* - navigation -- DONE
* - hash/anchor -- DONE
* - action redirects (see: System/delete) -- DONE
* - basic editor and interactivity -- DONE
* - export
* - json -- DONE
* - zip (json/tree)
* - migrate bootstrap
* - store topology
* - sync and sync conf
* - zip (json/tree) --
* - page actions
* - delete -- DONE
* - move/rename --
* - migrate bootstrap --
* - store topology --
* - sync and sync conf --
* - markdown -- DONE
* - WikiWord -- DONE
* - dom filter mechanics -- DONE
* - filters / dom filters:
* - markdown??
* - wikiword (control)
* this can be done in one of two ways:
* - wrapping blocks in elemens
* ...requires negative filter calls, either on -wikiword
* or a different filter like nowikiwords...
* - tags (current)
* - raw / code
* - raw / code -- DONE?
* - all (tree) -- DONE
* - nl2br
* - path2link (wikiword?) -- DONE
* - editor