mirror of
https://github.com/flynx/pWiki.git
synced 2025-10-29 18:10:09 +00:00
experimenting with strict mode in some methods, not sure yet...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
c8d45d3337
commit
93fc63cdb7
147
pwiki2.js
147
pwiki2.js
@ -56,11 +56,11 @@ var types = require('ig-types')
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Path...
|
// Path...
|
||||||
|
|
||||||
// XXX make this compatible with node's path API...
|
// XXX still some questions...
|
||||||
var path =
|
var path =
|
||||||
module.path = {
|
module.path = {
|
||||||
|
|
||||||
// The page returned when listing a path ending with '/'...
|
// Page returned when listing a path ending with '/'...
|
||||||
//
|
//
|
||||||
// If set to false treat dirs the same as pages (default)
|
// If set to false treat dirs the same as pages (default)
|
||||||
//INDEX_PAGE: 'index',
|
//INDEX_PAGE: 'index',
|
||||||
@ -161,7 +161,8 @@ module.path = {
|
|||||||
//
|
//
|
||||||
// NOTE: if seen is given (when called recursively) this will not
|
// NOTE: if seen is given (when called recursively) this will not
|
||||||
// search for .ALTERNATIVE_PAGES...
|
// search for .ALTERNATIVE_PAGES...
|
||||||
// XXX should we normalize '' to '/' here???
|
// XXX should we normalize input '' to '/' or return it as-is???
|
||||||
|
// XXX should we keep the trailing '/'???
|
||||||
paths: function*(path='/', seen){
|
paths: function*(path='/', seen){
|
||||||
var alt_pages = !seen
|
var alt_pages = !seen
|
||||||
seen = seen
|
seen = seen
|
||||||
@ -169,8 +170,8 @@ module.path = {
|
|||||||
path = this.normalize(path, 'string')
|
path = this.normalize(path, 'string')
|
||||||
// special case: root...
|
// special case: root...
|
||||||
if(path == '/' || path == ''){
|
if(path == '/' || path == ''){
|
||||||
// XXX should we normalize '' to '/' here???
|
// normalize...
|
||||||
//path = '/'
|
path = '/'
|
||||||
// as-is...
|
// as-is...
|
||||||
seen.add(path)
|
seen.add(path)
|
||||||
yield path
|
yield path
|
||||||
@ -182,7 +183,7 @@ module.path = {
|
|||||||
// normalize relative paths to root...
|
// normalize relative paths to root...
|
||||||
path[0] != ''
|
path[0] != ''
|
||||||
&& path.unshift('')
|
&& path.unshift('')
|
||||||
// paths ending in '/' -- dir lister...
|
// paths ending in '/'...
|
||||||
if(path[path.length-1] == ''){
|
if(path[path.length-1] == ''){
|
||||||
path.pop()
|
path.pop()
|
||||||
this.INDEX_PAGE
|
this.INDEX_PAGE
|
||||||
@ -231,7 +232,6 @@ module.path = {
|
|||||||
//
|
//
|
||||||
// NOTE: store keys must be normalized...
|
// NOTE: store keys must be normalized...
|
||||||
//
|
//
|
||||||
// XXX BUG: mixing up '/' and '' paths...
|
|
||||||
// XXX LEADING_SLASH should this be strict about leading '/' in paths???
|
// XXX LEADING_SLASH should this be strict about leading '/' in paths???
|
||||||
// ...this may lead to duplicate paths created -- '/a/b' and 'a/b'
|
// ...this may lead to duplicate paths created -- '/a/b' and 'a/b'
|
||||||
// XXX should we support page symlinking???
|
// XXX should we support page symlinking???
|
||||||
@ -408,9 +408,6 @@ module.BaseStore = {
|
|||||||
// NOTE: edit methods are local-only...
|
// NOTE: edit methods are local-only...
|
||||||
//
|
//
|
||||||
// XXX do we copy the data here or modify it????
|
// XXX do we copy the data here or modify it????
|
||||||
// XXX BUG: for path '/' this adds an entry at '', but when getting
|
|
||||||
// '/', the later is not found...
|
|
||||||
// XXX BUG: updating a pattern path will result in a broken store...
|
|
||||||
__update__: function(key, data, mode='update'){
|
__update__: function(key, data, mode='update'){
|
||||||
this.data[key] = data
|
this.data[key] = data
|
||||||
return this },
|
return this },
|
||||||
@ -786,10 +783,9 @@ object.Constructor('BasePage', {
|
|||||||
|
|
||||||
// page data...
|
// page data...
|
||||||
//
|
//
|
||||||
// XXX FUNC handle functions as pages...
|
strict: undefined,
|
||||||
// XXX need to support pattern pages...
|
|
||||||
get data(){
|
get data(){
|
||||||
return this.store.get(this.location) },
|
return this.store.get(this.location, !!this.strict) },
|
||||||
set data(value){
|
set data(value){
|
||||||
this.store.update(this.location, value) },
|
this.store.update(this.location, value) },
|
||||||
|
|
||||||
@ -811,17 +807,32 @@ object.Constructor('BasePage', {
|
|||||||
|
|
||||||
// relative proxies to store...
|
// relative proxies to store...
|
||||||
exists: relProxy('exists'),
|
exists: relProxy('exists'),
|
||||||
match: relProxy('match'),
|
match: function(path='.', strict=this.strict){
|
||||||
|
if(path === true || path === false){
|
||||||
|
strict = path
|
||||||
|
path = '.' }
|
||||||
|
return this.store.match(
|
||||||
|
module.path.relative(this.location, path),
|
||||||
|
strict) },
|
||||||
delete: function(path='.'){
|
delete: function(path='.'){
|
||||||
this.store.delete(module.path.relative(this.location, path))
|
this.store.delete(module.path.relative(this.location, path))
|
||||||
return this },
|
return this },
|
||||||
|
|
||||||
// XXX how should this handle functions as values???
|
//
|
||||||
get: function(path, referrer){
|
// .get(<path>[, <data>])
|
||||||
|
// .get(<path>, <strict>[, <data>])
|
||||||
|
// -> <page>
|
||||||
|
//
|
||||||
|
get: function(path, strict, data={}){
|
||||||
|
if(strict instanceof Object){
|
||||||
|
data = strict
|
||||||
|
strict = undefined }
|
||||||
return this.clone({
|
return this.clone({
|
||||||
location: path,
|
location: path,
|
||||||
referrer: referrer
|
...data,
|
||||||
|
referrer: data.referrer
|
||||||
?? this.location,
|
?? this.location,
|
||||||
|
strict,
|
||||||
}) },
|
}) },
|
||||||
|
|
||||||
// XXX should this be an iterator???
|
// XXX should this be an iterator???
|
||||||
@ -952,7 +963,6 @@ module.BaseParser = {
|
|||||||
// STOP -- '\\>' or ')'
|
// STOP -- '\\>' or ')'
|
||||||
// PREFIX -- 'inline' or 'elem'
|
// PREFIX -- 'inline' or 'elem'
|
||||||
//
|
//
|
||||||
// XXX BUG: @now(a) is not matched....
|
|
||||||
// XXX quote escaping???
|
// XXX quote escaping???
|
||||||
// /(?<quote>['"])(\\\k<quote>|[^\1])*\k<quote>/
|
// /(?<quote>['"])(\\\k<quote>|[^\1])*\k<quote>/
|
||||||
// ...this will work but we'll also need to remove the \ in the
|
// ...this will work but we'll also need to remove the \ in the
|
||||||
@ -1791,11 +1801,13 @@ object.Constructor('Page', BasePage, {
|
|||||||
// </else>
|
// </else>
|
||||||
// </macro>
|
// </macro>
|
||||||
//
|
//
|
||||||
|
// NOTE: if both strict and nonstrict are given the later takes
|
||||||
|
// precedence.
|
||||||
// XXX ELSE_PRIO should else attr take priority over the <else> tag???
|
// XXX ELSE_PRIO should else attr take priority over the <else> tag???
|
||||||
// ...currently as with text=... the attr takes priority...
|
// ...currently as with text=... the attr takes priority...
|
||||||
// XXX SORT sorting not implemented yet....
|
// XXX SORT sorting not implemented yet....
|
||||||
macro: Macro(
|
macro: Macro(
|
||||||
['name', 'src', 'sort', 'text', 'else'],
|
['name', 'src', 'sort', 'text', 'else', ['strict', 'nonstrict']],
|
||||||
function(args, body, state){
|
function(args, body, state){
|
||||||
var that = this
|
var that = this
|
||||||
var name = args.name //?? args[0]
|
var name = args.name //?? args[0]
|
||||||
@ -1811,6 +1823,8 @@ object.Constructor('Page', BasePage, {
|
|||||||
text = typeof(text) == 'string' ?
|
text = typeof(text) == 'string' ?
|
||||||
[...this.__parser__.group(this, text+'</macro>', 'macro')]
|
[...this.__parser__.group(this, text+'</macro>', 'macro')]
|
||||||
: text
|
: text
|
||||||
|
var strict = args.strict
|
||||||
|
&& !args.nonstrict
|
||||||
|
|
||||||
if(name){
|
if(name){
|
||||||
name = this.parse(name, state)
|
name = this.parse(name, state)
|
||||||
@ -1824,7 +1838,7 @@ object.Constructor('Page', BasePage, {
|
|||||||
|
|
||||||
if(src){
|
if(src){
|
||||||
src = this.parse(src, state)
|
src = this.parse(src, state)
|
||||||
var pages = this.get(src).each()
|
var pages = this.get(src, strict).each()
|
||||||
// no matching pages -> get the else block...
|
// no matching pages -> get the else block...
|
||||||
if(pages.length == 0
|
if(pages.length == 0
|
||||||
&& (text || args['else'])){
|
&& (text || args['else'])){
|
||||||
@ -1854,7 +1868,8 @@ object.Constructor('Page', BasePage, {
|
|||||||
// sort pages...
|
// sort pages...
|
||||||
if(sort.length > 0){
|
if(sort.length > 0){
|
||||||
// XXX SORT
|
// XXX SORT
|
||||||
throw new Error('macro sort: not implemented')
|
//throw new Error('macro sort: not implemented')
|
||||||
|
console.log('XXX: macro sort: not implemented')
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply macro text...
|
// apply macro text...
|
||||||
@ -1885,23 +1900,21 @@ object.Constructor('Page', BasePage, {
|
|||||||
&& !(text instanceof Array)){
|
&& !(text instanceof Array)){
|
||||||
state = text
|
state = text
|
||||||
text = null }
|
text = null }
|
||||||
// NOTE: we do not need to pass this.raw here but it is still
|
state = state ?? {}
|
||||||
// here for illustration...
|
text = text ?? this.raw
|
||||||
return this.__parser__.parse(this,
|
if(text instanceof Array){
|
||||||
text ?? this.raw,
|
return text.map(function(text){
|
||||||
state ?? {}) },
|
return this.__parser__.parse(this, text, state) }.bind(this)) }
|
||||||
|
return this.__parser__.parse(this, text, state) },
|
||||||
|
|
||||||
|
|
||||||
// raw page text...
|
// raw page text...
|
||||||
//
|
//
|
||||||
// NOTE: writing to .raw is the same as writing to .text...
|
// NOTE: writing to .raw is the same as writing to .text...
|
||||||
//
|
// NOTE: when matching multiple pages this will return a list...
|
||||||
// XXX for multiple pages matching, should this get one of the pages
|
|
||||||
// or all (current) of the pages???
|
|
||||||
get raw(){
|
get raw(){
|
||||||
var that = this
|
var that = this
|
||||||
var data = this.data
|
var data = this.data
|
||||||
|
|
||||||
// no data...
|
// no data...
|
||||||
// NOTE: if we hit this it means that nothing was resolved,
|
// NOTE: if we hit this it means that nothing was resolved,
|
||||||
// not even the System/NotFound page, i.e. something
|
// not even the System/NotFound page, i.e. something
|
||||||
@ -1920,14 +1933,13 @@ object.Constructor('Page', BasePage, {
|
|||||||
// multiple matches...
|
// multiple matches...
|
||||||
// XXX should this get one of the pages or all of the pages???
|
// XXX should this get one of the pages or all of the pages???
|
||||||
// XXX should we use a special template to render???
|
// XXX should we use a special template to render???
|
||||||
// XXX should this return an array???
|
|
||||||
: data instanceof Array ?
|
: data instanceof Array ?
|
||||||
data
|
data
|
||||||
.map(function(d){
|
.map(function(d){
|
||||||
return d instanceof Function ?
|
return d instanceof Function ?
|
||||||
d.call(that)
|
d.call(that)
|
||||||
: d.text })
|
: d.text })
|
||||||
.join('\n')
|
.flat()
|
||||||
: data.text },
|
: data.text },
|
||||||
set raw(value){
|
set raw(value){
|
||||||
this.store.update(this.location, {text: value}) },
|
this.store.update(this.location, {text: value}) },
|
||||||
@ -1935,11 +1947,10 @@ object.Constructor('Page', BasePage, {
|
|||||||
// expanded page text...
|
// expanded page text...
|
||||||
//
|
//
|
||||||
// NOTE: writing to .raw is the same as writing to .text...
|
// NOTE: writing to .raw is the same as writing to .text...
|
||||||
//
|
|
||||||
// XXX FUNC handle functions as pages...
|
|
||||||
// XXX need to support pattern pages...
|
|
||||||
get text(){
|
get text(){
|
||||||
return this.parse() },
|
return [this.parse()]
|
||||||
|
.flat()
|
||||||
|
.join('\n') },
|
||||||
set text(value){
|
set text(value){
|
||||||
this.store.update(this.location, {text: value}) },
|
this.store.update(this.location, {text: value}) },
|
||||||
|
|
||||||
@ -1993,8 +2004,6 @@ var System = {
|
|||||||
return this.get('..').path },
|
return this.get('..').path },
|
||||||
location: function(){
|
location: function(){
|
||||||
return this.get('..').path },
|
return this.get('..').path },
|
||||||
resolved: function(){
|
|
||||||
return this.get('..').match() },
|
|
||||||
dir: function(){
|
dir: function(){
|
||||||
return this.get('..').dir },
|
return this.get('..').dir },
|
||||||
name: function(){
|
name: function(){
|
||||||
@ -2004,6 +2013,10 @@ var System = {
|
|||||||
mtime: function(){
|
mtime: function(){
|
||||||
return this.get('..').data.mtime },
|
return this.get('..').data.mtime },
|
||||||
|
|
||||||
|
// XXX this can be a list for pattern paths...
|
||||||
|
resolved: function(){
|
||||||
|
return this.get('..').match() },
|
||||||
|
|
||||||
title: function(){
|
title: function(){
|
||||||
var p = this.get('..')
|
var p = this.get('..')
|
||||||
return p.title
|
return p.title
|
||||||
@ -2063,13 +2076,35 @@ store.load(require('./bootstrap'))
|
|||||||
// XXX add filter tests...
|
// XXX add filter tests...
|
||||||
console.log('loading test page...')
|
console.log('loading test page...')
|
||||||
pwiki
|
pwiki
|
||||||
|
.update({
|
||||||
|
location: '/test/a',
|
||||||
|
text: 'a',
|
||||||
|
})
|
||||||
|
.update({
|
||||||
|
location: '/test/b',
|
||||||
|
text: 'b',
|
||||||
|
})
|
||||||
|
.update({
|
||||||
|
location: '/test/c',
|
||||||
|
text: 'c',
|
||||||
|
})
|
||||||
|
.update({
|
||||||
|
location: '/test/c/x',
|
||||||
|
text: 'x',
|
||||||
|
})
|
||||||
|
.update({
|
||||||
|
location: '/test/c/y',
|
||||||
|
text: 'y',
|
||||||
|
})
|
||||||
|
.update({
|
||||||
|
location: '/test/d/z',
|
||||||
|
text: 'z',
|
||||||
|
})
|
||||||
.update({
|
.update({
|
||||||
location: '/page',
|
location: '/page',
|
||||||
text: 'PAGE\n'
|
text: 'PAGE\n'
|
||||||
+'\n'
|
+'\n'
|
||||||
// XXX BUG this is parsed incorrectly -- macro pattern...
|
+'@include(/test recursive="Recursion type 2 (<now/>)")\n'
|
||||||
//+'@include(/test recursive="Recursion type 2 (<now/>)")\n',
|
|
||||||
+'@include(/test recursive="Recursion type 2 <now/>")\n'
|
|
||||||
+'\n'
|
+'\n'
|
||||||
+'@slot(name=b text="filled slot")\n',
|
+'@slot(name=b text="filled slot")\n',
|
||||||
})
|
})
|
||||||
@ -2094,40 +2129,14 @@ pwiki
|
|||||||
+'Including /other #1: @include(/other)\n'
|
+'Including /other #1: @include(/other)\n'
|
||||||
+'Including /other #2: @include(/other)\n'
|
+'Including /other #2: @include(/other)\n'
|
||||||
+'\n'
|
+'\n'
|
||||||
// XXX BUG this is parsed incorrectly -- macro pattern...
|
+'Including /test: @include(/test recursive="Recursion type 1 (<now/>)")\n'
|
||||||
//+'Including /test: @include(/test recursive="Recursion type 1 (<now/>)")\n'
|
|
||||||
+'Including /test: @include(/test recursive="Recursion type 1 <now/>")\n'
|
|
||||||
+'\n'
|
+'\n'
|
||||||
+'Including /page: @include(/page)\n'
|
+'Including /page: @include(/page recursive="...")\n'
|
||||||
+'\n'
|
+'\n'
|
||||||
+'Including /: \\@include(/)\n'
|
+'Including /: \\@include(/)\n'
|
||||||
+'\n'
|
+'\n'
|
||||||
+'@filter(test)',
|
+'@filter(test)',
|
||||||
})
|
})
|
||||||
.update({
|
|
||||||
location: '/test/a',
|
|
||||||
text: 'a',
|
|
||||||
})
|
|
||||||
.update({
|
|
||||||
location: '/test/b',
|
|
||||||
text: 'b',
|
|
||||||
})
|
|
||||||
.update({
|
|
||||||
location: '/test/c',
|
|
||||||
text: 'c',
|
|
||||||
})
|
|
||||||
.update({
|
|
||||||
location: '/test/c/x',
|
|
||||||
text: 'x',
|
|
||||||
})
|
|
||||||
.update({
|
|
||||||
location: '/test/c/y',
|
|
||||||
text: 'y',
|
|
||||||
})
|
|
||||||
.update({
|
|
||||||
location: '/test/d/z',
|
|
||||||
text: 'z',
|
|
||||||
})
|
|
||||||
//*/
|
//*/
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user