From 6befa05d3393cc711360284a7004577f69bf9faa Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Mon, 15 Aug 2022 14:29:45 +0300 Subject: [PATCH] lots of tweaks and cleanup... Signed-off-by: Alex A. Naanou --- browser.js | 4 +- pwiki/dom/wikiword.js | 2 +- pwiki/filters/markdown.js | 2 + pwiki/page.js | 114 ++++++++++++++++++++++++++++---------- pwiki/parser.js | 1 - pwiki/path.js | 10 ++-- pwiki/store/base.js | 22 +++++++- pwiki2-test.js | 16 ++++++ pwiki2.js | 33 +++++++---- 9 files changed, 156 insertions(+), 48 deletions(-) diff --git a/browser.js b/browser.js index e1366ae..b0cf5ec 100755 --- a/browser.js +++ b/browser.js @@ -57,8 +57,8 @@ pwiki.store.update('@pouch', { // XXX -typeof(Bootstrap) != 'undefined' - && pwiki.store.load(Bootstrap) +//typeof(Bootstrap) != 'undefined' +// && pwiki.store.load(Bootstrap) diff --git a/pwiki/dom/wikiword.js b/pwiki/dom/wikiword.js index 630912c..287d282 100755 --- a/pwiki/dom/wikiword.js +++ b/pwiki/dom/wikiword.js @@ -10,7 +10,7 @@ var WIKIWORD_PATTERN = RegExp('('+[ // /some/path | ./some/path | ../some/path | >>/some/path - '(?:^|\\s)(|\\.|\\.\\.|>>)[\\/\\\\][^\\s]+', + '(?<=^|\\s)(|\\.|\\.\\.|>>)[\\/\\\\][^\\s]+', // [path] '\\\\?\\[[^\\]]+\\]', // WikiWord diff --git a/pwiki/filters/markdown.js b/pwiki/filters/markdown.js index b49eb4b..2caea2e 100755 --- a/pwiki/filters/markdown.js +++ b/pwiki/filters/markdown.js @@ -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 = diff --git a/pwiki/page.js b/pwiki/page.js index 45924d1..fb887da 100755 --- a/pwiki/page.js +++ b/pwiki/page.js @@ -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 = { '' +'
' +'
'}, - _ed: { + _edit: { //_edit: { text: '' @@ -1256,8 +1264,50 @@ module.System = { +'' +''}, - paths: { - text: '@source(.)' }, + + // XXX debug... + _path: {text: '@source(./path join=" ")'}, + + + list: { + text: '@source(.)' }, + // 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` + +
+ @source(./name) + × +
+ @source(./tree) +
+
+
` }, + + // 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 diff --git a/pwiki/parser.js b/pwiki/parser.js index ce1d21f..841fa01 100755 --- a/pwiki/parser.js +++ b/pwiki/parser.js @@ -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() diff --git a/pwiki/path.js b/pwiki/path.js index 941dd36..5a9685a 100755 --- a/pwiki/path.js +++ b/pwiki/path.js @@ -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) diff --git a/pwiki/store/base.js b/pwiki/store/base.js index db47d57..aa46454 100755 --- a/pwiki/store/base.js +++ b/pwiki/store/base.js @@ -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() @@ -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... diff --git a/pwiki2-test.js b/pwiki2-test.js index 4dab2fb..2f3824f 100755 --- a/pwiki2-test.js +++ b/pwiki2-test.js @@ -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... + +
+ now @source(./path) inside a 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'], }) diff --git a/pwiki2.js b/pwiki2.js index 1989b3d..0e896ac 100755 --- a/pwiki2.js +++ b/pwiki2.js @@ -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 +*

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 +* .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