mirror of
				https://github.com/flynx/pWiki.git
				synced 2025-10-30 18:40:08 +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