added location arguments + <arg name=.. /> macro...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-08-31 15:46:51 +03:00
parent 17bdac6b10
commit 819b665a87
4 changed files with 68 additions and 39 deletions

View File

@ -25,7 +25,7 @@ var relProxy =
function(name){ function(name){
var func = function(path='.', ...args){ var func = function(path='.', ...args){
return this.store[name]( return this.store[name](
pwpath.relative(this.location, path), pwpath.relative(this.path, path),
...args) } ...args) }
Object.defineProperty(func, 'name', {value: name}) Object.defineProperty(func, 'name', {value: name})
return func } return func }
@ -36,7 +36,7 @@ function(name){
strict = path strict = path
path = '.' } path = '.' }
return this.store[name]( return this.store[name](
pwpath.relative(this.location, path), pwpath.relative(this.path, path),
strict) } strict) }
Object.defineProperty(func, 'name', {value: name}) Object.defineProperty(func, 'name', {value: name})
return func } return func }
@ -136,32 +136,37 @@ object.Constructor('BasePage', {
// .path is a proxy to .location // .path is a proxy to .location
// XXX do we need this??? // XXX do we need this???
get path(){ get path(){
return this.location }, return pwpath.splitArgs(this.location).path },
set path(value){ set path(value){
this.location = value }, this.location = value },
get args(){
return pwpath.splitArgs(this.location).args },
set args(args){
this.location = this.path +':'+ pwpath.obj2args(args) },
// XXX do we need this... // XXX do we need this...
get resolvedPath(){ get resolvedPath(){
return this.match() }, return this.match() },
// XXX should these be writable??? // XXX should these be writable???
get name(){ get name(){
return pwpath.basename(this.location) }, return pwpath.basename(this.path) },
//set name(value){ }, //set name(value){ },
get dir(){ get dir(){
return pwpath.dirname(this.location) }, return pwpath.dirname(this.path) },
//set dir(value){ }, //set dir(value){ },
get isPattern(){ get isPattern(){
return this.location.includes('*') }, return this.path.includes('*') },
// store interface... // store interface...
// //
// XXX we are only doing modifiers here... // XXX we are only doing modifiers here...
// ...these ar mainly used to disable writing in .ro(..) // ...these ar mainly used to disable writing in .ro(..)
__update__: function(data){ __update__: function(data){
return this.store.update(this.location, data) }, return this.store.update(this.path, data) },
__delete__: function(path='.'){ __delete__: function(path='.'){
return this.store.delete(pwpath.relative(this.location, path)) }, return this.store.delete(pwpath.relative(this.path, path)) },
// page data... // page data...
// //
@ -180,7 +185,7 @@ object.Constructor('BasePage', {
return page.data }) } return page.data }) }
// single page... // single page...
// XXX ENERGETIC... // XXX ENERGETIC...
var res = await this.store.get(this.location, !!this.strict, !!this.energetic) var res = await this.store.get(this.path, !!this.strict, !!this.energetic)
return typeof(res) == 'function' ? return typeof(res) == 'function' ?
res.bind(this) res.bind(this)
: res }).call(this) }, : res }).call(this) },
@ -192,7 +197,7 @@ object.Constructor('BasePage', {
// NOTE: in the general case this is the same as .data but in also allows // NOTE: in the general case this is the same as .data but in also allows
// storing of data (metadata) for pattern paths... // storing of data (metadata) for pattern paths...
get metadata(){ get metadata(){
return this.store.metadata(this.location) }, return this.store.metadata(this.path) },
set metadata(value){ set metadata(value){
this.__update__(value) }, this.__update__(value) },
@ -206,7 +211,7 @@ object.Constructor('BasePage', {
// number of matching pages... // number of matching pages...
// NOTE: this can be both sync and async... // NOTE: this can be both sync and async...
get length(){ get length(){
var p = this.resolve(this.location) var p = this.resolve(this.path)
return p instanceof Array ? return p instanceof Array ?
p.length p.length
: p instanceof Promise ? : p instanceof Promise ?
@ -225,7 +230,7 @@ object.Constructor('BasePage', {
if(path === true || path === false){ if(path === true || path === false){
strict = path strict = path
path = '.' } path = '.' }
path = pwpath.relative(this.location, path) path = pwpath.relative(this.path, path)
var res = await this.store.match(path, strict) var res = await this.store.match(path, strict)
return res.length == 0 ? return res.length == 0 ?
// XXX are we going outside of match semantics here??? // XXX are we going outside of match semantics here???
@ -273,7 +278,7 @@ object.Constructor('BasePage', {
strict = path strict = path
path = '.' } path = '.' }
return this.store.find( return this.store.find(
pwpath.relative(this.location, path), strict) }, pwpath.relative(this.path, path), strict) },
// //
// .get(<path>[, <data>]) // .get(<path>[, <data>])
@ -288,7 +293,7 @@ object.Constructor('BasePage', {
location: path, location: path,
...data, ...data,
referrer: data.referrer referrer: data.referrer
//?? this.location, //?? this.path,
?? this.referrer, ?? this.referrer,
strict, strict,
}) }, }) },
@ -614,6 +619,18 @@ object.Constructor('Page', BasePage, {
// XXX ASYNC make these support async page getters... // XXX ASYNC make these support async page getters...
macros: { macros: {
// //
// @arg(<name>[ <default>][ local])
// @arg(name=<name>[ default=<value>][ local])
//
arg: Macro(
['name', 'default', ['local']],
function(args){
return this.args[args.name]
|| (!args.local
&& this.root
&& this.root.args[args.name])
|| args.default }),
//
// @filter(<filter-spec>) // @filter(<filter-spec>)
// <filter <filter-spec>/> // <filter <filter-spec>/>
// //

View File

@ -271,7 +271,7 @@ module = {
// XXX EXPERIMENTAL... // XXX EXPERIMENTAL...
// //
// .splitSrgs(<path>) // .splitArgs(<path>)
// -> <spec> // -> <spec>
// //
// Format: // Format:
@ -298,15 +298,27 @@ module = {
// or this scheme will not work... // or this scheme will not work...
splitArgs: function(path){ splitArgs: function(path){
path = this.normalize(path, 'string') path = this.normalize(path, 'string')
var [path, ...args] = path.split(/:/g) var [path, ...args] = path.split(/(?<!\\):/g)
return { return {
path, path,
args: args.reduce(function(res, arg){ args: args.reduce(function(res, arg){
var [name, value] = arg.split('=') var [name, value] = arg.split(/=(.*)/)
res[name] = value ?? true res[name] = value ?? true
return res }, {}), return res }, {}),
} }, } },
obj2args: function(args){
return args instanceof Object ?
Object.entries(args)
.map(function([key, value]){
return value === true ?
key
//: value === false ?
// []
: key +':'+ (value.toString().replace(/:/g, '\\:'))
})
.join(':')
: args },
} }

View File

@ -108,22 +108,22 @@ require(['./browser'], function(browser){
evt.preventDefault() evt.preventDefault()
var [path, hash] = location.hash.slice(1).split('#') var [path, hash] = location.hash.slice(1).split('#')
path = path.trim() == '' ? path = path.trim() == '' ?
pwiki.path pwiki.location
//'/' //'/'
: path : path
// treat links as absolute unless explicitly relative... // treat links as absolute unless explicitly relative...
path = /^\.\.?([\\\/].*)?$/.test(path) ? path = /^\.\.?([\\\/].*)?$/.test(path) ?
path path
: '/'+path : '/'+path
pwiki.path = [path, hash] }) pwiki.location = [path, hash] })
pwiki pwiki
.onNavigate(function(){ .onNavigate(function(){
// NOTE: we do not need to directly update location.hash here as // NOTE: we do not need to directly update location.hash here as
// that will push an extra history item... // that will push an extra history item...
history.replaceState( history.replaceState(
{path: this.path}, {path: this.location},
this.title, this.title,
'#'+this.path '#'+this.location
+(this.hash ? +(this.hash ?
'#'+this.hash '#'+this.hash
: '')) : ''))
@ -150,7 +150,7 @@ require(['./browser'], function(browser){
browser.setup.then(function(){ browser.setup.then(function(){
// show current page... // show current page...
pwiki.path = location.hash.slice(1) pwiki.location = location.hash.slice(1)
}) }) }) })

View File

@ -1,23 +1,6 @@
/********************************************************************** /**********************************************************************
* *
* *
* XXX ENERGETIC: Q: do we need to make this a path syntax thing???
* ...i.e.
* /some/path/action/! (current)
* vs.
* /some/path/!action
* ..."!" is removed before the <store>.__<name>__(..) calls...
* XXX ENERGETIC revise naming...
* XXX FEATURE tags and accompanying API...
* - add tags to page -- macro/filter
* <page>.text -> <page>.tags (cached on .update(..))
* - a way to list tags -- folder like?
* - tag cache <store>.tags
* - tag-path filtering...
* i.e. only show tags within a specific path/pattern...
* - path integration...
* i.e. a way to pass tags through path...
* /some/path:tags=a,b,c
* XXX FEATURE add a uniform way to track some state in links in pwiki * XXX FEATURE add a uniform way to track some state in links in pwiki
* for things like paging and the like with simple user/macro * for things like paging and the like with simple user/macro
* access (???)... * access (???)...
@ -52,6 +35,16 @@
* - session * - session
* - stored (config) * - stored (config)
* ...css selector as path.... * ...css selector as path....
* XXX FEATURE tags and accompanying API...
* - add tags to page -- macro/filter
* <page>.text -> <page>.tags (cached on .update(..))
* - a way to list tags -- folder like?
* - tag cache <store>.tags
* - tag-path filtering...
* i.e. only show tags within a specific path/pattern...
* - path integration...
* i.e. a way to pass tags through path...
* /some/path:tags=a,b,c
* XXX revise/update sort... * XXX revise/update sort...
* XXX fs store: metadata and cache... * XXX fs store: metadata and cache...
* XXX sub/nested store mixing... * XXX sub/nested store mixing...
@ -61,6 +54,13 @@
* .delete(..) * .delete(..)
* XXX deleting something in .next will break stuff... * XXX deleting something in .next will break stuff...
* ... * ...
* XXX ENERGETIC: Q: do we need to make this a path syntax thing???
* ...i.e.
* /some/path/action/! (current)
* vs.
* /some/path/!action
* ..."!" is removed before the <store>.__<name>__(..) calls...
* XXX ENERGETIC revise naming...
* XXX OPTIMIZE page search: make things invariant via .names * XXX OPTIMIZE page search: make things invariant via .names
* - if a page is in a system path and there are no alternatives * - if a page is in a system path and there are no alternatives
* just return it and do not search. * just return it and do not search.