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

View File

@ -271,7 +271,7 @@ module = {
// XXX EXPERIMENTAL...
//
// .splitSrgs(<path>)
// .splitArgs(<path>)
// -> <spec>
//
// Format:
@ -298,15 +298,27 @@ module = {
// or this scheme will not work...
splitArgs: function(path){
path = this.normalize(path, 'string')
var [path, ...args] = path.split(/:/g)
var [path, ...args] = path.split(/(?<!\\):/g)
return {
path,
args: args.reduce(function(res, arg){
var [name, value] = arg.split('=')
var [name, value] = arg.split(/=(.*)/)
res[name] = value ?? true
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()
var [path, hash] = location.hash.slice(1).split('#')
path = path.trim() == '' ?
pwiki.path
pwiki.location
//'/'
: path
// treat links as absolute unless explicitly relative...
path = /^\.\.?([\\\/].*)?$/.test(path) ?
path
: '/'+path
pwiki.path = [path, hash] })
pwiki.location = [path, hash] })
pwiki
.onNavigate(function(){
// NOTE: we do not need to directly update location.hash here as
// that will push an extra history item...
history.replaceState(
{path: this.path},
{path: this.location},
this.title,
'#'+this.path
'#'+this.location
+(this.hash ?
'#'+this.hash
: ''))
@ -150,7 +150,7 @@ require(['./browser'], function(browser){
browser.setup.then(function(){
// 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
* for things like paging and the like with simple user/macro
* access (???)...
@ -52,6 +35,16 @@
* - session
* - stored (config)
* ...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 fs store: metadata and cache...
* XXX sub/nested store mixing...
@ -61,6 +54,13 @@
* .delete(..)
* 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
* - if a page is in a system path and there are no alternatives
* just return it and do not search.