| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | *  | 
					
						
							|  |  |  | * | 
					
						
							| 
									
										
										
										
											2022-04-08 01:37:38 +03:00
										 |  |  | * XXX this seems a bit overcomplicated... | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | * | 
					
						
							|  |  |  | **********************************************************************/ | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | ((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define) | 
					
						
							|  |  |  | (function(require){ var module={} // make module AMD/node compatible...
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var object = require('lib/object') | 
					
						
							|  |  |  | var actions = require('lib/actions') | 
					
						
							|  |  |  | var features = require('lib/features') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | var macro = require('macro') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | // Split path into a list and handle special path elements...
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // The path is split via '/' or '\', no difference is made between the 
 | 
					
						
							|  |  |  | // two styles, e.g. 'a/b' is the same as 'a\b'.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Consecutive '/' or '\' are treated as one, e.g. 'a///b' and 'a/b' 
 | 
					
						
							|  |  |  | // are the same.
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2016-09-16 18:43:48 +03:00
										 |  |  | // Special path items supported:
 | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | // 	"."		- Current position indicator
 | 
					
						
							|  |  |  | // 			  this is simply removed from positions other than 0
 | 
					
						
							|  |  |  | // 				a/./b/c		-> a/b/c
 | 
					
						
							| 
									
										
										
										
											2016-09-16 18:43:48 +03:00
										 |  |  | // 				./b/c		-> ./b/c
 | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | //  ".."	- Consumes path item above (pop) / up one level
 | 
					
						
							|  |  |  | // 				a/../b/c	-> b/c
 | 
					
						
							| 
									
										
										
										
											2016-09-16 18:43:48 +03:00
										 |  |  | // 				../b/c		-> ../b/c
 | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | //	">>"	- Consumes path item below (shift)
 | 
					
						
							|  |  |  | // 				a/>>/b/c	-> a/c
 | 
					
						
							|  |  |  | // 				a/b/c/>>	-> a/b/c	(XXX ???)
 | 
					
						
							| 
									
										
										
										
											2016-09-16 18:43:48 +03:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | // NOTE: the path is handled out of context, this leading '.' and '..' 
 | 
					
						
							|  |  |  | // 		are left as-is.
 | 
					
						
							|  |  |  | // NOTE: '>>' has no effect when at last position (XXX ???)
 | 
					
						
							| 
									
										
										
										
											2016-09-16 18:43:48 +03:00
										 |  |  | var path2list = | 
					
						
							|  |  |  | module.path2list = function(path){  | 
					
						
							| 
									
										
										
										
											2022-04-07 17:23:36 +03:00
										 |  |  | 	return (path instanceof Array ?  | 
					
						
							|  |  |  | 			path  | 
					
						
							|  |  |  | 			: path.split(/[\\\/]+/g)) | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 		// handle '..' (lookahead) and trim path elements...
 | 
					
						
							|  |  |  | 		// NOTE: this will not touch the leading '.' or '..'
 | 
					
						
							|  |  |  | 		.map(function(p, i, l){ | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | 			// remove '..' and '.' out at positions > 0...
 | 
					
						
							| 
									
										
										
										
											2022-04-07 17:23:36 +03:00
										 |  |  | 			return (i > 0  | 
					
						
							|  |  |  | 					&& (p.trim() == '..' || p.trim() == '.') | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | 					// remove items followed by '..'...
 | 
					
						
							| 
									
										
										
										
											2016-09-16 18:43:48 +03:00
										 |  |  | 					|| (l[i+1] || '').trim() == '..' | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | 					// remove items preceded by '>>'...
 | 
					
						
							|  |  |  | 					|| (l[i-1] || '').trim() == '>>') ?  | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 				null  | 
					
						
							|  |  |  | 				: p.trim() }) | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | 		// cleanup and clear '>>'...
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 		.filter(function(p){  | 
					
						
							| 
									
										
										
										
											2016-09-16 18:43:48 +03:00
										 |  |  | 			return p != null  | 
					
						
							|  |  |  | 				&& p != ''  | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | 				&& p != '>>' })} | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | // Normalize path...
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This is the same as path2list(..) but also joins the path with '/'
 | 
					
						
							| 
									
										
										
										
											2016-09-16 18:43:48 +03:00
										 |  |  | var normalizePath = | 
					
						
							| 
									
										
										
										
											2022-04-07 17:23:36 +03:00
										 |  |  | module.normalizePath = function(path){  | 
					
						
							|  |  |  | 	return path2list(path).join('/') } | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-08 19:57:31 +03:00
										 |  |  | // XXX add pattern to match all subpaths above...
 | 
					
						
							|  |  |  | // 		Ex:
 | 
					
						
							|  |  |  | // 			'a/b/c/^' shold mathc 'a/b/c', 'a/b', 'a'
 | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | var path2re =  | 
					
						
							|  |  |  | module.path2re = function(path){ | 
					
						
							|  |  |  | 	return RegExp('^' | 
					
						
							|  |  |  | 		+normalizePath(path) | 
					
						
							| 
									
										
										
										
											2022-04-08 19:57:31 +03:00
										 |  |  | 			/*/ quote regexp chars... | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | 			.replace(/([\.\\\/\(\)\[\]\$\+\-\{\}\@\^\&\?\<\>])/g, '\\$1') | 
					
						
							| 
									
										
										
										
											2022-04-08 19:57:31 +03:00
										 |  |  | 			/*/// XXX experimental...
 | 
					
						
							|  |  |  | 			.replace(/([\.\\\/\(\)\[\]\$\+\-\{\}\@\^\&\?\>])/g, '\\$1') | 
					
						
							|  |  |  | 			// '<' -> handle subpath matching...
 | 
					
						
							|  |  |  | 			// XXX this needs * up the stack...
 | 
					
						
							|  |  |  | 			.replace(/.*</, function(match){ | 
					
						
							|  |  |  | 				return `(${ match | 
					
						
							|  |  |  | 					.replace(/(\\[\\\/])?<$/, '') | 
					
						
							|  |  |  | 					.split(/\\[\\\/]/) | 
					
						
							|  |  |  | 					.reduce(function(res, e){ | 
					
						
							|  |  |  | 						return res.concat([ | 
					
						
							|  |  |  | 							(res.length > 0 ?  | 
					
						
							|  |  |  | 								res[res.length-1] +'\/'  | 
					
						
							|  |  |  | 								: '') | 
					
						
							|  |  |  | 							+ e]) }, []) | 
					
						
							|  |  |  | 					.join('|') })` })
 | 
					
						
							|  |  |  | 			//*/
 | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | 			// convert '*' and '**' to regexp...
 | 
					
						
							|  |  |  | 			.replace(/\*\*/g, '.*') | 
					
						
							|  |  |  | 			.replace(/^\*|([^.])\*/g, '$1[^\\/]*') | 
					
						
							|  |  |  | 		+'$')} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // pWiki featureset...
 | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | var pWikiFeatures =  | 
					
						
							|  |  |  | module.pWikiFeatures = new features.FeatureSet()  | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | /* | 
					
						
							|  |  |  | // base pWiki object...
 | 
					
						
							|  |  |  | var pWiki =  | 
					
						
							| 
									
										
										
										
											2019-07-17 00:11:00 +03:00
										 |  |  | module.pWiki = object.Constructor('pWiki', actions.MetaActions) | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | // base instance constructor...
 | 
					
						
							|  |  |  | pWikiFeatures.__actions__ =  | 
					
						
							|  |  |  | 	function(){ return actions.Actions(pWiki()) } | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | //*/
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | var BaseData =  | 
					
						
							|  |  |  | module.BaseData = { | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 	// Macro acces to standard page attributes (paths)...
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 	'System/title': function(){  | 
					
						
							|  |  |  | 		return { text: this.get('..').title() } }, | 
					
						
							|  |  |  | 	'System/path': function(){  | 
					
						
							|  |  |  | 		return { text: this.base() } }, | 
					
						
							|  |  |  | 	'System/dir': function(){  | 
					
						
							|  |  |  | 		return { text: this.get('..').base() } }, | 
					
						
							|  |  |  | 	'System/location': function(){  | 
					
						
							|  |  |  | 		return { text: this.base() } }, | 
					
						
							|  |  |  | 	'System/resolved': function(){  | 
					
						
							|  |  |  | 		return { text: this.get('..').acquire() } }, | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// page data...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: special case: ./raw is treated a differently when getting .text
 | 
					
						
							|  |  |  | 	// 		i.e:
 | 
					
						
							|  |  |  | 	// 			.get('./raw').text
 | 
					
						
							|  |  |  | 	// 		is the same as:
 | 
					
						
							|  |  |  | 	// 			.get('.').raw
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 	'System/raw': function(){  | 
					
						
							|  |  |  | 		return { text: this.get('..').raw() } }, | 
					
						
							|  |  |  | 	'System/html': function(){  | 
					
						
							|  |  |  | 		return { text: this.get('..').html() } }, | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-11 04:50:45 +03:00
										 |  |  | 	// list all path elements on a level, including empty path sections...
 | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 	// XXX update these to the new format -- must return an object...
 | 
					
						
							|  |  |  | 	// XXX move this to Wiki.children + rename...
 | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 	// XXX
 | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 	'System/list': function(){ | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 		return 'NoImplemented' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 		var p = this.dir | 
					
						
							|  |  |  | 		return Object.keys(this.__wiki_data) | 
					
						
							|  |  |  | 			.map(function(k){ | 
					
						
							|  |  |  | 				if(k.indexOf(p) == 0){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					return path2lst(k.slice(p.length)).shift() } | 
					
						
							|  |  |  | 				return null }) | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 			.filter(function(e){ return e != null }) | 
					
						
							|  |  |  | 			.sort() | 
					
						
							|  |  |  | 			.map(function(e){ return '['+ e +']' }) | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			.join('<br>') }, | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 	// list links to this page...
 | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 	// XXX this is done, though we cant use this until we solve .html(..)
 | 
					
						
							|  |  |  | 	// 		macro recursion issues...
 | 
					
						
							| 
									
										
										
										
											2016-10-11 04:50:45 +03:00
										 |  |  | 	// XXX cache the result + need a strategy to drop parts of cache when
 | 
					
						
							|  |  |  | 	// 		irrelevant -- when path/text changes...
 | 
					
						
							|  |  |  | 	// XXX might be a good idea to move this to the store, at least the
 | 
					
						
							|  |  |  | 	// 		management, part...
 | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 	'System/links': function(){ | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 		return 'NoImplemented' | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 		var that = this | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 		var p = this.path() | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		var res = [] | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 		this.wiki.match('**') | 
					
						
							|  |  |  | 			.forEach(function(p){ | 
					
						
							|  |  |  | 				var pa = that.acquire(p) | 
					
						
							| 
									
										
										
										
											2016-10-11 04:50:45 +03:00
										 |  |  | 				that.get(p) | 
					
						
							|  |  |  | 					// XXX this will render the page which might not be 
 | 
					
						
							|  |  |  | 					// 		the best idea in some cases...
 | 
					
						
							|  |  |  | 					.links() | 
					
						
							|  |  |  | 						.forEach(function(l){ | 
					
						
							|  |  |  | 							var la = that.acquire(l) | 
					
						
							|  |  |  | 							if(l == p || la == p || la == pa){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 								res.push([l, p]) } }) }) | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-11 04:50:45 +03:00
										 |  |  | 		// cache the result...
 | 
					
						
							|  |  |  | 		// XXX
 | 
					
						
							|  |  |  | 		this.attr('rev-links', res) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 		return res | 
					
						
							|  |  |  | 			//.map(function(e){ return '['+ e[0] +'] <i>from page: ['+ e[1] +']</i>' })
 | 
					
						
							|  |  |  | 			.map(function(e){ return '['+ e[1] +'] <i>-> ['+ e[0] +']</i>' }) | 
					
						
							|  |  |  | 			.sort() | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			.join('<br>') }, | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Page modifiers/actions...
 | 
					
						
							|  |  |  | 	// XXX these needs redirecting...
 | 
					
						
							| 
									
										
										
										
											2022-04-08 19:57:31 +03:00
										 |  |  | 	// 		...not sure if using history here is the right way to go...
 | 
					
						
							|  |  |  | 	'System/_sort': function(){  | 
					
						
							|  |  |  | 		this.get('..').sort() }, | 
					
						
							| 
									
										
										
										
											2022-04-07 21:07:53 +03:00
										 |  |  | 	'System/sort': function(){  | 
					
						
							| 
									
										
										
										
											2022-04-08 19:57:31 +03:00
										 |  |  | 		// XXX does not work for some reason...
 | 
					
						
							|  |  |  | 		//this.get('../_sort')
 | 
					
						
							|  |  |  | 		this.get('..').sort() | 
					
						
							|  |  |  | 		history | 
					
						
							|  |  |  | 			&& history.back() }, | 
					
						
							|  |  |  | 	'System/_reverse': function(){  | 
					
						
							|  |  |  | 		this.get('..').reverse() }, | 
					
						
							| 
									
										
										
										
											2022-04-07 21:07:53 +03:00
										 |  |  | 	'System/reverse': function(){  | 
					
						
							| 
									
										
										
										
											2022-04-08 19:57:31 +03:00
										 |  |  | 		// XXX does not work for some reason...
 | 
					
						
							|  |  |  | 		//this.get('../_reverse')
 | 
					
						
							|  |  |  | 		this.get('..').reverse() | 
					
						
							|  |  |  | 		history | 
					
						
							|  |  |  | 			&& history.back() }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	'System/_delete': function(){ | 
					
						
							|  |  |  | 		this.get('..').clear() }, | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 	'System/delete': function(){ | 
					
						
							| 
									
										
										
										
											2022-04-08 19:57:31 +03:00
										 |  |  | 		// XXX does not work for some reason...
 | 
					
						
							|  |  |  | 		//this.get('../_delete')
 | 
					
						
							| 
									
										
										
										
											2022-04-07 22:51:39 +03:00
										 |  |  | 		this.get('..').clear() | 
					
						
							| 
									
										
										
										
											2022-04-08 19:57:31 +03:00
										 |  |  | 		history | 
					
						
							|  |  |  | 			&& history.back() }, | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	'System/back': function(){ | 
					
						
							|  |  |  | 		history.go(-2) }, | 
					
						
							|  |  |  | 	// XXX not sure how to deal with this...
 | 
					
						
							|  |  |  | 	//'System/foreward': function(){
 | 
					
						
							|  |  |  | 	//	history.go(1) },
 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	// XXX need to support simple functions...
 | 
					
						
							|  |  |  | 	// 		...return a list to simulate a list of pages...
 | 
					
						
							|  |  |  | 	'System/test': function(){ | 
					
						
							|  |  |  | 		return ['list', 'of', 'links'] }, | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // XXX should this be art of the main API or a separate entity???
 | 
					
						
							|  |  |  | // XXX should we combine page and wiki api???
 | 
					
						
							|  |  |  | // 		- pWikiData is wiki api
 | 
					
						
							|  |  |  | // 		- pWiki is page api
 | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | var pWikiData = | 
					
						
							|  |  |  | module.pWikiData = { | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	__data: null, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 	// XXX
 | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 	search: function(query, sort){ | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 	// Get a list of matching paths...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 	// XXX sort path API...
 | 
					
						
							|  |  |  | 	// 		...should we be able to spec sort in path???
 | 
					
						
							|  |  |  | 	// XXX should we account for order here???
 | 
					
						
							|  |  |  | 	match: function(path, sort, count, from){ | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 		var data = this.__data || {} | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 		from = from || 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// XXX normalize this to account for '*'
 | 
					
						
							|  |  |  | 		//var order = (data[path] || {}).order || []
 | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if(path == null){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return [] } | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// strict path...
 | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | 		if(path.indexOf('*') < 0){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return path in data ?  | 
					
						
							|  |  |  | 				[ path ]  | 
					
						
							|  |  |  | 				: [] } | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 		sort = sort  | 
					
						
							|  |  |  | 			|| (data[path] || {}).sort  | 
					
						
							|  |  |  | 			|| ['order'] | 
					
						
							|  |  |  | 		sort = sort instanceof Array ?  | 
					
						
							|  |  |  | 			sort  | 
					
						
							|  |  |  | 			: [sort] | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		var order = (data[path] || {}).order || [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | 		var pattern = path2re(path) | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return Object.keys(data) | 
					
						
							|  |  |  | 				// XXX is this correct???
 | 
					
						
							|  |  |  | 				.concat(Object.keys(data.__proto__) | 
					
						
							|  |  |  | 					// do not repeat overloaded stuff...
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					.filter(function(e){  | 
					
						
							|  |  |  | 						return !data.hasOwnProperty(e) })) | 
					
						
							|  |  |  | 			.filter(function(p){  | 
					
						
							|  |  |  | 				return pattern.test(p) }) | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 			// page...
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			.slice(from,  | 
					
						
							|  |  |  | 				count ?  | 
					
						
							|  |  |  | 					from + count  | 
					
						
							|  |  |  | 					: undefined) | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 			// prepare to sort...
 | 
					
						
							|  |  |  | 			.map(function(p, i){  | 
					
						
							|  |  |  | 				return sort | 
					
						
							|  |  |  | 					.map(function(method){ | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 						// explicit order...
 | 
					
						
							|  |  |  | 						if(method instanceof Array){ | 
					
						
							|  |  |  | 							i = method.indexOf(p) | 
					
						
							|  |  |  | 							i = i < 0 ? method.indexOf('*') : i | 
					
						
							|  |  |  | 							i = i < 0 ? method.length : i | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 							return i } | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 						// drop the reversal marker...
 | 
					
						
							| 
									
										
										
										
											2022-04-08 19:57:31 +03:00
										 |  |  | 						method = method[0] == '-' ?  | 
					
						
							|  |  |  | 							method.slice(1)  | 
					
						
							|  |  |  | 							: method | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 						// stored order...
 | 
					
						
							|  |  |  | 						if(method == 'order'){ | 
					
						
							|  |  |  | 							i = order.indexOf(p) | 
					
						
							| 
									
										
										
										
											2022-04-08 19:57:31 +03:00
										 |  |  | 							i = i < 0 ?  | 
					
						
							|  |  |  | 								order.indexOf('*')  | 
					
						
							|  |  |  | 								: i | 
					
						
							|  |  |  | 							i = i < 0 ?  | 
					
						
							|  |  |  | 								order.length  | 
					
						
							|  |  |  | 								: i | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 							return i } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						return method == 'path' ?  | 
					
						
							|  |  |  | 								p.toLowerCase() | 
					
						
							|  |  |  | 							: method == 'Path' ?  | 
					
						
							|  |  |  | 								p | 
					
						
							|  |  |  | 							: method == 'title' ?  | 
					
						
							|  |  |  | 								path2list(p).pop().toLowerCase() | 
					
						
							|  |  |  | 							: method == 'Title' ?  | 
					
						
							|  |  |  | 								path2list(p).pop()  | 
					
						
							| 
									
										
										
										
											2016-10-11 04:50:45 +03:00
										 |  |  | 							// special case...
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 							: method == 'checked' ?  | 
					
						
							|  |  |  | 								(data[p][method] ?  | 
					
						
							|  |  |  | 									1  | 
					
						
							|  |  |  | 									: 0) | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 							// attr...
 | 
					
						
							| 
									
										
										
										
											2022-04-08 19:57:31 +03:00
										 |  |  | 							: data[p][method] }) | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					.concat([i, p]) }) | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 			// sort...
 | 
					
						
							|  |  |  | 			.sort(function(a, b){  | 
					
						
							|  |  |  | 				for(var i=0; i < sort.length+1; i++){ | 
					
						
							|  |  |  | 					var reverse = (sort[i] || '')[0] == '-' ? -1 : 1 | 
					
						
							|  |  |  | 					if(a[i] == b[i]){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 						continue }  | 
					
						
							|  |  |  | 					return (a[i] > b[i] ? 1 : -1) * reverse } | 
					
						
							|  |  |  | 				return 0 }) | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 			// cleanup...
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			.map(function(e){  | 
					
						
							|  |  |  | 				return e.pop() }) }, | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Get/set data at path...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	// XXX should this overwrite or expand???
 | 
					
						
							|  |  |  | 	// XXX should from be pattern compatible???
 | 
					
						
							|  |  |  | 	data: function(path, value){ | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | 		// get the data...
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 		if(value == null){ | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 			if(this.__data == null){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				return null } | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			var data = this.__data[path] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return data == null ?  | 
					
						
							|  |  |  | 					null | 
					
						
							|  |  |  | 				: data instanceof Function ?  | 
					
						
							|  |  |  | 					data | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 				: JSON.parse(JSON.stringify(data))  | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | 		// set the data...
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			this.__data = this.__data || {} | 
					
						
							| 
									
										
										
										
											2016-09-22 01:13:25 +03:00
										 |  |  | 			this.__data[path] = JSON.parse(JSON.stringify(value)) | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return this } }, | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Move data from path to path...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	// XXX should from be pattern compatible???
 | 
					
						
							|  |  |  | 	move: function(from, to){ | 
					
						
							|  |  |  | 		if(this.__data == null){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return } | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 		var d = this.__data[from] | 
					
						
							|  |  |  | 		this.clear(from) | 
					
						
							|  |  |  | 		this.__data[to] = d | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 	// Clear a path...
 | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	clear: function(path){ | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 		if(this.__data == null){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return this } | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 		this.remove(this.match(path)) | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// explicitly remove path...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: this is similar to .clear(..) but will not expand patterns, 
 | 
					
						
							|  |  |  | 	// 		thus only one page is is removed per path.
 | 
					
						
							|  |  |  | 	remove: function(path){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 		path = arguments.length > 1 ?  | 
					
						
							|  |  |  | 				[].slice.call(arguments)  | 
					
						
							|  |  |  | 			: path instanceof Array ?  | 
					
						
							|  |  |  | 				path  | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 			: [path] | 
					
						
							|  |  |  | 		var data = this.__data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		path.forEach(function(p){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			delete data[p] }) | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// XXX
 | 
					
						
							|  |  |  | 	json: function(data){ | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 		if(arguments.length == 0){ | 
					
						
							|  |  |  | 			return JSON.parse(JSON.stringify(this.__data)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			this.__data = data } }, | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | // Base pWiki page API...
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | // Page data format:
 | 
					
						
							|  |  |  | //	{
 | 
					
						
							|  |  |  | //		'order': [ <title>, .. ] | undefined,
 | 
					
						
							|  |  |  | //		'order-unsorted-first': <bool>,
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //		'text': <string>,
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //		// XXX not yet used...
 | 
					
						
							|  |  |  | //		'links': [ .. ],
 | 
					
						
							|  |  |  | // 	}
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | var pWikiBase = | 
					
						
							|  |  |  | module.pWikiBase = actions.Actions({ | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	config: { | 
					
						
							|  |  |  | 		'home-page': 'WikiHome', | 
					
						
							|  |  |  | 		'default-page': 'EmptyPage', | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | 		'no-match-page': 'NoMatch', | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		'system-path': 'System', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		'acquesition-order': [ | 
					
						
							|  |  |  | 			'Templates', | 
					
						
							|  |  |  | 		], | 
					
						
							|  |  |  | 		'post-acquesition-order': [], | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		'order-unsorted-first': false, | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// sorting...
 | 
					
						
							|  |  |  | 		'default-sort-methods': [ | 
					
						
							|  |  |  | 			'path', | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// pWikiData...
 | 
					
						
							|  |  |  | 	wiki: null, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 	// XXX should this be local/dump???
 | 
					
						
							| 
									
										
										
										
											2022-04-07 21:07:53 +03:00
										 |  |  | 	json: ['',  | 
					
						
							|  |  |  | 		function(){ }], | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 04:07:53 +03:00
										 |  |  | 	// Location and path API...
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-05 20:44:46 +03:00
										 |  |  | 	refresh: ['',  | 
					
						
							|  |  |  | 		function(force){ | 
					
						
							|  |  |  | 			// get/set location and base fields...
 | 
					
						
							|  |  |  | 			var location = this.__location = this.__location || {} | 
					
						
							|  |  |  | 			var path = location.path = location.path  | 
					
						
							|  |  |  | 				|| this.config['home-path'] | 
					
						
							|  |  |  | 				|| 'WikiHome' | 
					
						
							|  |  |  | 			var at = location.at || 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// get location cache...
 | 
					
						
							|  |  |  | 			var match = location.match | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// refresh the cache...
 | 
					
						
							|  |  |  | 			if(match == null || force){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				this.order(force) } }], | 
					
						
							| 
									
										
										
										
											2016-10-05 20:44:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 04:07:53 +03:00
										 |  |  | 	location: ['Page/Get or set location', | 
					
						
							|  |  |  | 		function(value){ | 
					
						
							|  |  |  | 			if(value === null){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				return } | 
					
						
							| 
									
										
										
										
											2016-10-05 20:44:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 04:07:53 +03:00
										 |  |  | 			var location = this.__location || this.refresh().location() | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 04:07:53 +03:00
										 |  |  | 			// get location...
 | 
					
						
							|  |  |  | 			if(arguments.length == 0){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				return location } | 
					
						
							| 
									
										
										
										
											2016-10-05 20:44:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 04:07:53 +03:00
										 |  |  | 			// set location index...
 | 
					
						
							|  |  |  | 			if(typeof(value) == typeof(123)){ | 
					
						
							|  |  |  | 				location.at = value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// set location path...
 | 
					
						
							|  |  |  | 			} else if(typeof(value) == typeof('str')){ | 
					
						
							|  |  |  | 				this.__location = { | 
					
						
							|  |  |  | 					path: this.resolve(value), | 
					
						
							|  |  |  | 					at: 0, | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 04:07:53 +03:00
										 |  |  | 			// object...
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				this.__location = value | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 19:23:56 +03:00
										 |  |  | 				// NOTE: we are returning here without a refresh to avoid
 | 
					
						
							|  |  |  | 				// 		recursion...
 | 
					
						
							|  |  |  | 				// NOTE: a refresh will get called when the location value
 | 
					
						
							|  |  |  | 				// 		is accessed for the first time...
 | 
					
						
							|  |  |  | 				// XXX should we clear .match here???
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				return } | 
					
						
							| 
									
										
										
										
											2016-10-08 04:07:53 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			this.refresh(true) }], | 
					
						
							| 
									
										
										
										
											2016-10-08 04:07:53 +03:00
										 |  |  | 	exists: ['Page/Check if path explicitly exists.',  | 
					
						
							|  |  |  | 		function(path){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			var at = path ?  | 
					
						
							|  |  |  | 				0  | 
					
						
							|  |  |  | 				: this.at() | 
					
						
							| 
									
										
										
										
											2016-10-08 04:07:53 +03:00
										 |  |  | 			path = path || this.path() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return this.wiki.match(this.get(path).location().path)[at] !== undefined }], | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 	// Resolve path statically...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// This will:
 | 
					
						
							|  |  |  | 	// 	- expand variables
 | 
					
						
							|  |  |  | 	// 	- resolve relative paths ('.', '..', and '>>')
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// Supported variables:
 | 
					
						
							|  |  |  | 	// 	$NOW		- resolves to current date (same as Date.now())
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// 	$PATH		- resolves to page path (same as .path())
 | 
					
						
							|  |  |  | 	// 	$BASE		- resolves to page base path (same as .base())
 | 
					
						
							|  |  |  | 	// 	$TITLE		- resolves to page title (same as .title())
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// 	$INDEX		- resolves to page index (same as .at())
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: all variables are resolved relative to the page from which 
 | 
					
						
							|  |  |  | 	// 		.resolve(..) was called, e.g. the following two are equivalent:
 | 
					
						
							|  |  |  | 	// 			<page>.resolve('$PATH')
 | 
					
						
							|  |  |  | 	// 			<page>.path()
 | 
					
						
							|  |  |  | 	// NOTE: this will not resolve path patterns ('*' and '**')
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	resolve: ['Path/Resolve relative path and expand path variables', | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 		function(path){ | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | 			path = path || this.path() | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 			// path variables...
 | 
					
						
							|  |  |  | 			// XXX make this more modular...
 | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 			path = path | 
					
						
							| 
									
										
										
										
											2016-09-16 18:43:48 +03:00
										 |  |  | 				// NOTE: these are equivalent to '..' and '.' but not 
 | 
					
						
							|  |  |  | 				// 		identical -- the variables are useful for things
 | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | 				// 		like moving a page to:
 | 
					
						
							|  |  |  | 				// 			"Trash/$PATH"
 | 
					
						
							|  |  |  | 				// 		...to move the above page out of trash move it to:
 | 
					
						
							|  |  |  | 				// 			">>/$PATH"
 | 
					
						
							|  |  |  | 				.replace(/\$PATH|\$\{PATH\}/g, this.path()) | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 				.replace(/\$BASE|\$\{BASE\}/g, this.base()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				.replace(/\$TITLE|\$\{TITLE\}/g, this.title()) | 
					
						
							|  |  |  | 				.replace(/\$INDEX|\$\{INDEX\}/g, this.at()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				.replace(/\$NOW|\$\{NOW\}/g, Date.now()) | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | 				 | 
					
						
							|  |  |  | 			path = normalizePath(path) | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// relative paths -- "." and ".."
 | 
					
						
							|  |  |  | 			if(path.indexOf('.') >= 0){ | 
					
						
							|  |  |  | 				path =  | 
					
						
							|  |  |  | 					// '.' or './*'
 | 
					
						
							|  |  |  | 					path == '.' || /^\.\//.test(path) ?  | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 						normalizePath(path.replace(/^\./, this.path())) | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 					// '..' or '../*'
 | 
					
						
							|  |  |  | 					: path == '..' || /^\.\.\//.test(path) ?  | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 						normalizePath(path.replace(/^\.\./, this.base())) | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					: path } | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return path }], | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	// XXX should this get a page???
 | 
					
						
							|  |  |  | 	acquire: ['Path/Acquire the page path that the given path resolves to', | 
					
						
							|  |  |  | 		function(path, no_default){ | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// handle paths and relative paths...
 | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 			var p = this.get(path || this.path()) | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 			var title = p.title() | 
					
						
							|  |  |  | 			path = path2list(p.base()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var acquire_from = this.config['acquesition-order'] || [] | 
					
						
							|  |  |  | 			var post_acquire_from = this.config['post-acquesition-order'] || [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var _get = function(path, title, lst){ | 
					
						
							|  |  |  | 				lst = (lst == null || lst.length == 0) ? [''] : lst | 
					
						
							|  |  |  | 				for(var i=0; i < lst.length; i++){ | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 					var p = normalizePath(path.concat([lst[i], title])) | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 					if(that.exists(p)){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 						return that.wiki.data(p) && p } } } | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			while(true){ | 
					
						
							|  |  |  | 				// get title from path...
 | 
					
						
							|  |  |  | 				var p = _get(path, title) | 
					
						
							|  |  |  | 					// get title from special paths in path...
 | 
					
						
							|  |  |  | 					|| _get(path, title, acquire_from) | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 				if(p != null){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					return p } | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if(path.length == 0){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					break } | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				path.pop() } | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// default paths...
 | 
					
						
							|  |  |  | 			var p = _get(path, title, post_acquire_from) | 
					
						
							|  |  |  | 				// system path...
 | 
					
						
							|  |  |  | 				|| this.config['system-path'] | 
					
						
							|  |  |  | 					&& _get([this.config['system-path']], title) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// NOTE: this may be null...
 | 
					
						
							|  |  |  | 			return p  | 
					
						
							|  |  |  | 				|| ((!no_default && title != this.config['default-page']) ?  | 
					
						
							|  |  |  | 					this.acquire('./'+this.config['default-page'])  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					: null) }], | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | 	// XXX pattern does not match anything needs to be handled correctly...
 | 
					
						
							| 
									
										
										
										
											2016-10-05 20:44:46 +03:00
										 |  |  | 	// XXX do we need to normalize 'at'???
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	path: ['Page/Get or set path',  | 
					
						
							|  |  |  | 		function(value){ | 
					
						
							|  |  |  | 			// get explcit path from location (acounting for 'at')...
 | 
					
						
							|  |  |  | 			if(arguments.length == 0){ | 
					
						
							| 
									
										
										
										
											2016-10-05 20:44:46 +03:00
										 |  |  | 				var location = this.location() | 
					
						
							|  |  |  | 				return location.match[location.at] | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | 					|| this.config['no-match-page'] | 
					
						
							|  |  |  | 					|| '' | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// move page to path...
 | 
					
						
							|  |  |  | 			} else if(value != null) { | 
					
						
							|  |  |  | 				this.wiki.move(this.path(), this.resolve(value)) | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				this.location(value) } }], | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	title: ['Page/Get or set title', | 
					
						
							|  |  |  | 		function(value){ | 
					
						
							|  |  |  | 			if(arguments.length == 0){ | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 				return path2list(this.path()).pop() || '' | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			} else if(value != null){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				this.path(this.base() +'/'+ value) } }], | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	base: ['Page/Get or set directory', | 
					
						
							|  |  |  | 		function(base){ | 
					
						
							|  |  |  | 			if(arguments.length == 0){ | 
					
						
							|  |  |  | 				return path2list(this.path()).slice(0, -1).join('/') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} else if(base != null){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				this.path(base +'/'+ this.title()) } }], | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 04:07:53 +03:00
										 |  |  | 	// Object API...
 | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 	// NOTE: a clone references the same data and .config, no copying 
 | 
					
						
							|  |  |  | 	// 		is done.
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	clone: ['Page/Get page clone (new reference)',  | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 		function(){ | 
					
						
							|  |  |  | 			var o = Object.create(this) | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 				.location(JSON.parse(JSON.stringify(this.location()))) | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			o.__parent_context = this | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return o }], | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	end: ['Page/Get parent context of clone',  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 		function(){  | 
					
						
							|  |  |  | 			return this.__parent_context || this }], | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	// XXX should this return false on empty path???
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	copy: ['Page/Copy page to path',  | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 		function(path){ | 
					
						
							|  |  |  | 			return path != null  | 
					
						
							|  |  |  | 				&& this | 
					
						
							|  |  |  | 					.get(path) | 
					
						
							|  |  |  | 					// NOTE: this is here mainly to maintain the context stack...
 | 
					
						
							|  |  |  | 					.clone() | 
					
						
							|  |  |  | 						.data(this.data()) }], | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	get: ['Page/Get page by path',  | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 		function(path){ | 
					
						
							|  |  |  | 			return this | 
					
						
							|  |  |  | 				.clone() | 
					
						
							|  |  |  | 				.location(path) }], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Order and iteration API...
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 04:07:53 +03:00
										 |  |  | 	get length(){ | 
					
						
							|  |  |  | 		// special case -- non-pattern path...
 | 
					
						
							|  |  |  | 		if(this.location().path.indexOf('*') < 0){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return 1 } | 
					
						
							| 
									
										
										
										
											2016-10-08 04:07:53 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		this.refresh() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 		return this.location().match.length }, | 
					
						
							| 
									
										
										
										
											2016-10-08 04:07:53 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	at: ['Page/Get index or page at given index',  | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 		function(n){ | 
					
						
							|  |  |  | 			// get current index...
 | 
					
						
							|  |  |  | 			if(n == null){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				return this.location().at || 0 } | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// get page at index...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var l = this.length | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 			// self...
 | 
					
						
							|  |  |  | 			if(n == this.at()){ | 
					
						
							|  |  |  | 				return this | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 			// out of bounds...
 | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 			} else if(n >= l || n < -l){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				return null } | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			var res = this.clone() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			n = n < 0 ? l - n : n | 
					
						
							|  |  |  | 			// XXX do we min/max n???
 | 
					
						
							|  |  |  | 			n = Math.max(n, 0) | 
					
						
							|  |  |  | 			n = Math.min(l-1, n) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			res.location(n) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return res }], | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	prev: ['Page/Get previous page',  | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 		function(){ | 
					
						
							|  |  |  | 			var i = this.at() - 1 | 
					
						
							|  |  |  | 			// NOTE: need to guard against overflows...
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return i >= 0 ?  | 
					
						
							|  |  |  | 				this.at(i)  | 
					
						
							|  |  |  | 				: null }], | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	next: ['Page/Get next page',  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 		function(){  | 
					
						
							|  |  |  | 			return this.at(this.at() + 1) }], | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	map: ['Page/',  | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 		function(func){ | 
					
						
							|  |  |  | 			var res = [] | 
					
						
							|  |  |  | 			for(var i=0; i < this.length; i++){ | 
					
						
							|  |  |  | 				var page = this.at(i) | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				res.push(func.call(page, page, i)) } | 
					
						
							|  |  |  | 			return res }], | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | 	// NOTE: a filter can take a function or a string path pattern...
 | 
					
						
							| 
									
										
										
										
											2016-09-18 17:00:40 +03:00
										 |  |  | 	// NOTE: only absolute path patterns are supported...
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	filter: ['Page/',  | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 		function(func){ | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | 			// we got a sting pattern...
 | 
					
						
							|  |  |  | 			if(typeof(func) == typeof('str')){ | 
					
						
							|  |  |  | 				var pattern = path2re(func) | 
					
						
							|  |  |  | 				func = function(page){  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					return pattern.test(page.path()) } } | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 			var res = [] | 
					
						
							|  |  |  | 			for(var i=0; i < this.length; i++){ | 
					
						
							|  |  |  | 				var page = this.at(i) | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				func.call(page, page, i)  | 
					
						
							|  |  |  | 					&& res.push(page) } | 
					
						
							|  |  |  | 			return res }], | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	each: ['Page/',  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 		function(func){  | 
					
						
							|  |  |  | 			this.map(func) }], | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	// XXX reduce???
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	// Get/set sibling order...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 	//	Get order...
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	//	.order()
 | 
					
						
							|  |  |  | 	//		-> order
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 	//	Force get order...
 | 
					
						
							|  |  |  | 	//	.order(true)
 | 
					
						
							|  |  |  | 	//	.order('force')
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	//		-> order
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 	//		NOTE: this will overwrite cache.
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 	//	Get saved order...
 | 
					
						
							|  |  |  | 	//	.order('saved')
 | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 	//		-> order
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 	//	Save list of paths as order explicitly...
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	//	.order([<title>, .. ])
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 	//		-> page
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	//	Save order persistently...
 | 
					
						
							|  |  |  | 	//	.order('save')
 | 
					
						
							|  |  |  | 	//		-> page
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	//	Remove set order, local if available else persistent...
 | 
					
						
							|  |  |  | 	//	.order('clear')
 | 
					
						
							|  |  |  | 	//		-> page
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	//	Remove all ordering...
 | 
					
						
							|  |  |  | 	//	.order('clear-all')
 | 
					
						
							|  |  |  | 	//		-> page
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// List of paths passed to .order(..) can contain a '*' to indicate
 | 
					
						
							|  |  |  | 	// the pages not specified by the list.
 | 
					
						
							|  |  |  | 	// By default all unspecified pages will get appended to the resulting
 | 
					
						
							|  |  |  | 	// list, same as appending a '*' to the tail of the list passed to 
 | 
					
						
							|  |  |  | 	// .order(..)
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: saving order to data is supported ONLY for paths that contain
 | 
					
						
							|  |  |  | 	// 		one and only one pattern and in the last path segment...
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 	// NOTE: clearing persistent ordering will remove a page (parent) from 
 | 
					
						
							|  |  |  | 	// 		data if it contains nothing but the order...
 | 
					
						
							|  |  |  | 	// NOTE: this will also maintain page position within order (.at())
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 	// NOTE: the actual sorting/ordering is done in .wiki.match(..)
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// XXX should we also cache the saved sort and order???
 | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | 	// XXX (LEAK?) not sure if the current location where order is stored
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 	// 		is the right way to go -- would be really hard to clean out...
 | 
					
						
							|  |  |  | 	// 		...might be a good idea to clear pattern paths that match no 
 | 
					
						
							|  |  |  | 	// 		pages from data...
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	order: ['Page/Get or set sibling pages order',  | 
					
						
							|  |  |  | 		function(order){ | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 			var location = this.location() | 
					
						
							|  |  |  | 			var path = location.path || '' | 
					
						
							|  |  |  | 			var page = (location.match || [])[location.at || 0] | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 			// get order...
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			if(order == null  | 
					
						
							|  |  |  | 					|| order == 'force'  | 
					
						
							|  |  |  | 					|| order === true){ | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 				// no patterns in path -> no ordering...
 | 
					
						
							|  |  |  | 				if(path.indexOf('*') < 0){ | 
					
						
							|  |  |  | 					if(!location.match){ | 
					
						
							|  |  |  | 						location.match = [ path ] | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 						this.location(location) } | 
					
						
							|  |  |  | 					return [ path ] } | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 				// get cached order if not forced...
 | 
					
						
							|  |  |  | 				if(location.match != null && order == null){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					return location.match.slice() } | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 				// XXX should we check if this returns a function???
 | 
					
						
							|  |  |  | 				var parent = this.wiki.data(path) || {} | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				var sort = (location.sort || parent.sort || ['order']).slice() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				var i = sort.indexOf('order') | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				location.order  | 
					
						
							|  |  |  | 					&& i >= 0  | 
					
						
							|  |  |  | 					&& sort.splice(i, 1, location.order) | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				var order = this.wiki.match(path, sort) | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | 					// filter out paths containing '*'
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					.filter(function(p){  | 
					
						
							|  |  |  | 						return p.indexOf('*') < 0 }) | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 				// save cache...
 | 
					
						
							|  |  |  | 				location.match = order | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				location.at = page ?  | 
					
						
							|  |  |  | 					order.indexOf(page)  | 
					
						
							|  |  |  | 					: 0 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 				this.location(location) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				return order.slice() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// get saved order...
 | 
					
						
							|  |  |  | 			} else if(order == 'saved'){ | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 				return location.order  | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 					// XXX should we check if this returns a function???
 | 
					
						
							|  |  |  | 					|| (this.wiki.data(path) || {}).order | 
					
						
							|  |  |  | 					|| [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// clear order...
 | 
					
						
							|  |  |  | 			// XXX should this:
 | 
					
						
							|  |  |  | 			// 		- clear all always
 | 
					
						
							|  |  |  | 			// 		- explicitly clear only local or persistent
 | 
					
						
							|  |  |  | 			// 		- progressively clear local then persistent (current)
 | 
					
						
							|  |  |  | 			} else if(order == 'clear' || order == 'clear-all'){ | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 				var local = !!location.order | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// local order...
 | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 				delete location.order | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// clear persistent order...
 | 
					
						
							|  |  |  | 				if(!local || order == 'clear-all'){ | 
					
						
							|  |  |  | 					// XXX should we check if this returns a function???
 | 
					
						
							|  |  |  | 					var parent = this.wiki.data(path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// persistent order...
 | 
					
						
							|  |  |  | 					if(parent && parent.order){ | 
					
						
							|  |  |  | 						delete parent.order | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						// remove if empty...
 | 
					
						
							|  |  |  | 						if(Object.keys(parent).length == 0){ | 
					
						
							|  |  |  | 							this.wiki.remove(path)		 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						// save...
 | 
					
						
							|  |  |  | 						} else { | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 							this.wiki.data(path, parent) } } } | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 			// save order...
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			} else if(order == 'save'){ | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 				// XXX should we check if this returns a function???
 | 
					
						
							|  |  |  | 				var parent = this.wiki.data(path) || {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				var order =  | 
					
						
							|  |  |  | 				parent.order =  | 
					
						
							|  |  |  | 					location.order  | 
					
						
							|  |  |  | 						|| this.order() | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 01:31:20 +03:00
										 |  |  | 				this.wiki.data(path, parent) | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 				delete location.order | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 			// set order...
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				location.order = order } | 
					
						
							| 
									
										
										
										
											2016-10-08 00:00:49 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// save cache...
 | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 			this.location(location) | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			this.order(true) }], | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Sort siblings...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	//	Sort pages via default method
 | 
					
						
							|  |  |  | 	//	.sort()
 | 
					
						
							|  |  |  | 	//		-> page
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	//	Sort pages via method
 | 
					
						
							|  |  |  | 	//	.sort(method)
 | 
					
						
							|  |  |  | 	//		-> page
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	//	Sort pages via method1, then method2, ...
 | 
					
						
							|  |  |  | 	//	.sort(method1, method2, ...)
 | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 	//	.sort([method1, method2, ...])
 | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 	//		-> page
 | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 	//		NOTE: the next method is used iff the previous concludes the
 | 
					
						
							|  |  |  | 	//			values equal...
 | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 	//
 | 
					
						
							|  |  |  | 	// To reverse a specific method, prepend it's name with "-", e.g. 
 | 
					
						
							|  |  |  | 	// "title" will do the default ascending sort while "-title" will do
 | 
					
						
							|  |  |  | 	// a descending sort.
 | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 	//
 | 
					
						
							|  |  |  | 	// Supported methods:
 | 
					
						
							|  |  |  | 	// 	path			- compare paths (case-insensitive)
 | 
					
						
							|  |  |  | 	// 	Path			- compare paths (case-sensitive)
 | 
					
						
							|  |  |  | 	// 	title			- compare titles (case-insensitive)
 | 
					
						
							|  |  |  | 	// 	Title			- compare titles (case-sensitive)
 | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 	// 	checked			- checked state
 | 
					
						
							|  |  |  | 	// 	order			- the set manual order (see .order(..))
 | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 	// 	<attribute>		- compare data attributes
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: the sort is local to the returned object.
 | 
					
						
							|  |  |  | 	// NOTE: the sorted object may loose sync form the actual wiki as the
 | 
					
						
							|  |  |  | 	// 		list of siblings is cached.
 | 
					
						
							|  |  |  | 	// 		...the resulting object is not to be stored for long.
 | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 	// NOTE: the actual sorting is done by the store...
 | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 	//
 | 
					
						
							|  |  |  | 	// XXX add 'save' and 'saved' actions...
 | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 	sort: ['Page/',  | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 		function(methods){ | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 			var that = this | 
					
						
							|  |  |  | 			var res = this.clone() | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 			var location = this.location() | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			methods = methods instanceof Array ? | 
					
						
							|  |  |  | 				methods  | 
					
						
							|  |  |  | 				: [].slice.call(arguments) | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 			location.sort = methods.length == 0 ? | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				(this.config['default-sort-methods']  | 
					
						
							|  |  |  | 					|| ['path']) | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 				: methods | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 			res.location(location) | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 			res.order(true) | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return res }], | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 	// XXX should this be persistent???
 | 
					
						
							|  |  |  | 	// 		...e.g. survive .order('force') or .order('clear')
 | 
					
						
							|  |  |  | 	reverse: ['Page/', | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 		function(){ | 
					
						
							| 
									
										
										
										
											2016-10-08 03:50:18 +03:00
										 |  |  | 			var location = this.location() | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// reverse the match...
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			location.match  | 
					
						
							|  |  |  | 				&& location.match.reverse() | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// reverse order...
 | 
					
						
							|  |  |  | 			location.order = this.order().reverse() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// reverse sort...
 | 
					
						
							|  |  |  | 			if(location.sort){ | 
					
						
							|  |  |  | 				location.sort = location.sort | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					.map(function(m){  | 
					
						
							|  |  |  | 						return m[0] == '-' ?  | 
					
						
							|  |  |  | 							m.slice(1)  | 
					
						
							|  |  |  | 							: '-'+m }) } | 
					
						
							| 
									
										
										
										
											2016-10-12 03:56:01 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			this.location(location) }], | 
					
						
							| 
									
										
										
										
											2016-09-27 07:09:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 	// Data API...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	data: ['Page/Get or set data',  | 
					
						
							|  |  |  | 		function(value){ | 
					
						
							|  |  |  | 			// get -> acquire page and get it's data...
 | 
					
						
							|  |  |  | 			if(arguments.length == 0){ | 
					
						
							|  |  |  | 				var d = this.wiki.data(this.acquire()) || {} | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				return d instanceof Function ?  | 
					
						
							|  |  |  | 					d.call(this)  | 
					
						
							|  |  |  | 					: d | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// set -> get explicit path and set data to it...
 | 
					
						
							|  |  |  | 			} else if(value != null) { | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				this.wiki.data(this.path(), value || {}) } }], | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 	clear: ['Page/Clear page',  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 		function(){  | 
					
						
							|  |  |  | 			this.wiki.clear(this.path()) }], | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 	attr: ['Page/Get or set attribute', | 
					
						
							|  |  |  | 		function(name, value){ | 
					
						
							|  |  |  | 			var d = this.data() | 
					
						
							|  |  |  | 			// get...
 | 
					
						
							|  |  |  | 			if(arguments.length == 1){ | 
					
						
							|  |  |  | 				return d[name] === undefined ?  | 
					
						
							|  |  |  | 					// force returning undefined...
 | 
					
						
							|  |  |  | 					actions.UNDEFINED  | 
					
						
							|  |  |  | 					: d[name] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// clear...
 | 
					
						
							|  |  |  | 			} else if(value === undefined){ | 
					
						
							|  |  |  | 				delete d[name] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// set...
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				d[name] = value } | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// write the data...
 | 
					
						
							|  |  |  | 			// XXX is it good to write the whole thing???
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			this.data(d) }], | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// shorthands...
 | 
					
						
							|  |  |  | 	raw: ['Page/', | 
					
						
							|  |  |  | 		function(value){ | 
					
						
							|  |  |  | 			return arguments.length == 0 ?  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				(this.attr('text')  | 
					
						
							|  |  |  | 					|| '')  | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 				: this.attr('text', value) }], | 
					
						
							|  |  |  | 	checked: ['Page/',  | 
					
						
							|  |  |  | 		function(value){ | 
					
						
							|  |  |  | 			return arguments.length == 0 ?  | 
					
						
							|  |  |  | 				!!this.attr('checked')  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				: this.attr('checked',  | 
					
						
							|  |  |  | 					value || undefined) }], | 
					
						
							| 
									
										
										
										
											2016-09-30 16:58:03 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Init... 
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2016-09-27 07:09:25 +03:00
										 |  |  | 	// Special config attrs:
 | 
					
						
							|  |  |  | 	// 	wiki		- wiki object
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: the input object may get modified... (XXX)
 | 
					
						
							|  |  |  | 	__init__: [function(config){ | 
					
						
							|  |  |  | 		config = config || {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if('wiki' in config){ | 
					
						
							|  |  |  | 			this.wiki = config.wiki | 
					
						
							|  |  |  | 			// XXX don't like modifying the input...
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			delete config.wiki } | 
					
						
							| 
									
										
										
										
											2016-09-27 07:09:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		var cfg = this.config = Object.create(this.config) | 
					
						
							|  |  |  | 		return function(){ | 
					
						
							|  |  |  | 			// copy the given config...
 | 
					
						
							|  |  |  | 			Object.keys(config).forEach(function(k){  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				cfg[k] = JSON.parse(JSON.stringify(config[k])) }) } }], | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | // Data processing and macros...
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | var pWikiMacros = | 
					
						
							| 
									
										
										
										
											2016-09-27 15:49:22 +03:00
										 |  |  | module.pWikiMacros = actions.Actions(pWikiBase, { | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | 	__macro_parser__: macro, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	config: { | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 	html: ['Page/', | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | 		function(value){ | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 			// get...
 | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | 			return arguments.length == 0 ?  | 
					
						
							|  |  |  | 				(this.title() == 'raw' ? | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 					// special case -- if title is 'raw' then return text as-is...
 | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | 					(this.raw() || '') | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 					// parse macros...
 | 
					
						
							| 
									
										
										
										
											2016-09-27 07:09:25 +03:00
										 |  |  | 					: (this.__macro_parser__ || pWikiMacros.__macro_parser__) | 
					
						
							|  |  |  | 						.parse(this, this.raw())) | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 				// set...
 | 
					
						
							|  |  |  | 				: this | 
					
						
							|  |  |  | 					// clear cached stuff related to text...
 | 
					
						
							|  |  |  | 					.attr('links', undefined) | 
					
						
							|  |  |  | 					// set the value...
 | 
					
						
							|  |  |  | 					.raw(value) }], | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | 	code: ['Page/', | 
					
						
							|  |  |  | 		function(value){ | 
					
						
							|  |  |  | 			return arguments.length == 0 ?  | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 				this.html().text() | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | 				// XXX should we un-encode here???
 | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 				: this.html(value) }], | 
					
						
							|  |  |  | 	links: ['Page/List links from page', | 
					
						
							|  |  |  | 		function(force){ | 
					
						
							|  |  |  | 			// get and cache links...
 | 
					
						
							|  |  |  | 			if(force || this.attr('links') == null){ | 
					
						
							|  |  |  | 				var text = this.html() | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				var links = typeof(text) == typeof('str') ?  | 
					
						
							|  |  |  | 					[] | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 					: text.find('[href]') | 
					
						
							|  |  |  | 						.map(function(){  | 
					
						
							|  |  |  | 							var url = $(this).attr('href')  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 							return url[0] == '#' ?  | 
					
						
							|  |  |  | 								url.slice(1)  | 
					
						
							|  |  |  | 								: null }) | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 						.toArray() | 
					
						
							|  |  |  | 				this.attr('links', links) | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				return links } | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 			// get cached links...
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return this.attr('links') }], | 
					
						
							| 
									
										
										
										
											2016-09-27 07:09:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | 	// Init...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2016-09-27 07:09:25 +03:00
										 |  |  | 	// Special config attrs:
 | 
					
						
							|  |  |  | 	// 	macro		- macro processor (optional)
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	__init__: [function(config){ | 
					
						
							|  |  |  | 		if('macro' in config){ | 
					
						
							|  |  |  | 			this.__macro_parser__ = config.macro | 
					
						
							|  |  |  | 			// XXX don't like modifying the input...
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			delete config.macro } }], | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // pWiki Page...
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // NOTE: looks like multiple inheritance, feels like multiple inheritance
 | 
					
						
							|  |  |  | // 		but sadly is not multiple inheritance...
 | 
					
						
							|  |  |  | // 		...though, functionally, this is 90% there, about as far as we 
 | 
					
						
							|  |  |  | // 		can get using native JS lookup mechanisms, or at least the 
 | 
					
						
							|  |  |  | // 		farthest I've pushed it so far...
 | 
					
						
							|  |  |  | var pWikiPage = | 
					
						
							| 
									
										
										
										
											2022-04-07 16:46:29 +03:00
										 |  |  | module.pWikiPage =  | 
					
						
							|  |  |  | object.Constructor('pWikiPage',  | 
					
						
							| 
									
										
										
										
											2016-09-27 07:09:25 +03:00
										 |  |  | 	actions.mix( | 
					
						
							|  |  |  | 		// XXX not sure if we need this here...
 | 
					
						
							|  |  |  | 		//actions.MetaActions,
 | 
					
						
							|  |  |  | 		pWikiBase,  | 
					
						
							|  |  |  | 		pWikiMacros)) | 
					
						
							| 
									
										
										
										
											2016-09-27 04:44:15 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Experiment with hidden promises...
 | 
					
						
							|  |  |  | var hiddenPromise =  | 
					
						
							|  |  |  | module.hiddenPromise = { | 
					
						
							|  |  |  | 	__promise: null, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	then: function(func){ | 
					
						
							|  |  |  | 		var that = this | 
					
						
							| 
									
										
										
										
											2016-10-01 08:27:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// trigger lazy functions if present...
 | 
					
						
							|  |  |  | 		if(this.__lazy != null){ | 
					
						
							|  |  |  | 			var lazy = this.__lazy | 
					
						
							|  |  |  | 			delete this.__lazy | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 04:37:49 +03:00
										 |  |  | 			var res = this | 
					
						
							| 
									
										
										
										
											2016-10-01 08:27:17 +03:00
										 |  |  | 				.then(lazy) | 
					
						
							|  |  |  | 				.then(func) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// clear any lazy stuff queued by the above to avoid any 
 | 
					
						
							|  |  |  | 			// side-effects...
 | 
					
						
							| 
									
										
										
										
											2016-10-04 04:50:20 +03:00
										 |  |  | 			//
 | 
					
						
							|  |  |  | 			// XXX should this be done here (sunc) or in  a .then(..)???
 | 
					
						
							| 
									
										
										
										
											2016-10-01 08:27:17 +03:00
										 |  |  | 			delete this.__lazy | 
					
						
							| 
									
										
										
										
											2016-10-04 04:37:49 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			return res } | 
					
						
							| 
									
										
										
										
											2016-10-01 08:27:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// no promise...
 | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | 		if(this.__promise == null){ | 
					
						
							|  |  |  | 			this.__promise = new Promise(function(resolve, reject){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				resolve(func.call(that)) }) | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-01 08:27:17 +03:00
										 |  |  | 		// existing promise...
 | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			this.__promise = this.__promise.then(function(){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				return func.apply(that, [].slice.call(arguments)) }) } | 
					
						
							|  |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2016-10-05 06:23:30 +03:00
										 |  |  | 	// NOTE: this ignores the function if there is no promise...
 | 
					
						
							|  |  |  | 	// 		XXX not sure if this is correct...
 | 
					
						
							|  |  |  | 	catch: function(func){ | 
					
						
							|  |  |  | 		if(this.__promise != null){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			this.__promise = this.__promise.catch(func) } | 
					
						
							|  |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-01 08:27:17 +03:00
										 |  |  | 	// Like then, but the function will get called only if a .then(..) is
 | 
					
						
							|  |  |  | 	// called right after...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: only the last lazy function is stored, the rest are discarded.
 | 
					
						
							|  |  |  | 	lazy: function(func){ | 
					
						
							|  |  |  | 		this.__lazy = func | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2016-10-01 08:27:17 +03:00
										 |  |  | 	clearLazy: function(){ | 
					
						
							|  |  |  | 		delete this.__lazy | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// example method (sync)...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// Protocol:
 | 
					
						
							|  |  |  | 	// 	.data()			- "get" data value...
 | 
					
						
							|  |  |  | 	// 	.data('new value')
 | 
					
						
							|  |  |  | 	// 					- set data value...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// In both cases the method will return the object (this)
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// In both cases the internal promise when resolved will get passed
 | 
					
						
							|  |  |  | 	// the value, in both cases the old value...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// A more full example:
 | 
					
						
							|  |  |  | 	// 	hiddenPromise
 | 
					
						
							|  |  |  | 	// 		// get and print the value (undefined)...
 | 
					
						
							|  |  |  | 	// 		.data()
 | 
					
						
							|  |  |  | 	// 			.then(function(value){ console.log(value) })
 | 
					
						
							|  |  |  | 	// 		// set a new value...
 | 
					
						
							|  |  |  | 	// 		.data('new value')
 | 
					
						
							|  |  |  | 	// 		// get and print the new value...
 | 
					
						
							|  |  |  | 	// 		.data()
 | 
					
						
							|  |  |  | 	// 			.then(function(value){ console.log(value) })
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	sdata: function(d){ | 
					
						
							| 
									
										
										
										
											2016-10-01 08:27:17 +03:00
										 |  |  | 		this.clearLazy() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | 		// get...
 | 
					
						
							|  |  |  | 		if(arguments.length == 0){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 			this.lazy(function(){  | 
					
						
							|  |  |  | 				return this.__data }) | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// set...
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			this.then(function(){  | 
					
						
							|  |  |  | 				var res = this.__data | 
					
						
							|  |  |  | 				this.__data = d  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				return res }) } | 
					
						
							|  |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// async data...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: this is the same as above but will do it's work async (after
 | 
					
						
							|  |  |  | 	// 		a second)...
 | 
					
						
							|  |  |  | 	data: function(d){ | 
					
						
							|  |  |  | 		var that = this | 
					
						
							| 
									
										
										
										
											2016-10-01 08:27:17 +03:00
										 |  |  | 		this.clearLazy() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | 		// get...
 | 
					
						
							|  |  |  | 		if(arguments.length == 0){ | 
					
						
							| 
									
										
										
										
											2016-10-01 08:27:17 +03:00
										 |  |  | 			//this.then(function(){
 | 
					
						
							|  |  |  | 			this.lazy(function(){ | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | 				return new Promise(function(r){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					setTimeout( | 
					
						
							|  |  |  | 						function(){ r(that.__data) },  | 
					
						
							|  |  |  | 						1000) }) }) | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// set...
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			this.then(function(){ | 
					
						
							|  |  |  | 				return new Promise(function(r){ | 
					
						
							|  |  |  | 					setTimeout( | 
					
						
							|  |  |  | 						function(){  | 
					
						
							|  |  |  | 							var res = that.__data | 
					
						
							|  |  |  | 							that.__data = d  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 							r(res) }, | 
					
						
							|  |  |  | 						1000) }) }) } | 
					
						
							|  |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2016-10-01 07:59:41 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | /*********************************************************************/ | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | var pWikiLocalStorage = pWikiFeatures.Feature({ | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	title: '', | 
					
						
							|  |  |  | 	tag: 'localstorage-store', | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 	config: { | 
					
						
							|  |  |  | 		'localstorage-key': 'pwiki-gen2-data', | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	actions: actions.Actions({ | 
					
						
							|  |  |  | 		// XXX do not use .__data
 | 
					
						
							|  |  |  | 		save: ['', | 
					
						
							|  |  |  | 			function(){  | 
					
						
							|  |  |  | 				localstorage[this.config['localstorage-key']] =  | 
					
						
							|  |  |  | 					JSON.stringify(this.wiki.__data) }], | 
					
						
							|  |  |  | 	}), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	handlers: [ | 
					
						
							|  |  |  | 		// XXX add lifecicle load handler...
 | 
					
						
							|  |  |  | 		// XXX
 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		[[ | 
					
						
							|  |  |  | 			'update',  | 
					
						
							|  |  |  | 			'clear', | 
					
						
							|  |  |  | 		], | 
					
						
							| 
									
										
										
										
											2022-04-07 21:07:53 +03:00
										 |  |  | 			function(){  | 
					
						
							|  |  |  | 				this.save() }], | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		[[ | 
					
						
							|  |  |  | 			'path', | 
					
						
							|  |  |  | 			'data', | 
					
						
							|  |  |  | 		],  | 
					
						
							| 
									
										
										
										
											2022-04-07 21:07:53 +03:00
										 |  |  | 			function(){ | 
					
						
							|  |  |  | 				arguments.length > 1  | 
					
						
							|  |  |  | 					&& this.save() }], | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	], | 
					
						
							|  |  |  | }) | 
					
						
							| 
									
										
										
										
											2016-09-03 06:08:46 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | var pWikiPouchDBStore = pWikiFeatures.Feature({ | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | 	title: '', | 
					
						
							|  |  |  | 	tag: 'pouchdb-store', | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | var pWikiPeerJSSync = pWikiFeatures.Feature({ | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 	title: '', | 
					
						
							|  |  |  | 	tag: 'peerjs-sync', | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 07:09:25 +03:00
										 |  |  | //---------------------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2016-09-04 12:24:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-11 04:50:45 +03:00
										 |  |  | // XXX should this extend pWiki or encapsulate (current)???
 | 
					
						
							| 
									
										
										
										
											2016-09-04 12:24:57 +03:00
										 |  |  | var pWikiUIActions = actions.Actions({ | 
					
						
							|  |  |  | 	config: { | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 		'special-paths': { | 
					
						
							|  |  |  | 			//'History/back': 'historyBack',
 | 
					
						
							|  |  |  | 			//'History/forward': 'historyForward',
 | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-09-04 12:24:57 +03:00
										 |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 	dom: null, | 
					
						
							|  |  |  | 	page: null, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 06:53:47 +03:00
										 |  |  | 	// XXX might be a good idea to add actions to setup/clear a filter...
 | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 	__dom_filters__: { | 
					
						
							|  |  |  | 		// sortable elements...
 | 
					
						
							| 
									
										
										
										
											2016-10-20 16:54:16 +03:00
										 |  |  | 		// TODO: make elements movable from/to nested lists...
 | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 		'.sortable': function(elems){ | 
					
						
							| 
									
										
										
										
											2016-10-11 22:38:50 +03:00
										 |  |  | 			var wiki = this.page | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 			elems | 
					
						
							|  |  |  | 				.sortable({ | 
					
						
							| 
									
										
										
										
											2016-10-19 05:30:15 +03:00
										 |  |  | 					handle: '.sort-handle', | 
					
						
							|  |  |  | 					placeholder: 'sort-placeholder', | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 					forcePlaceholderSize: true, | 
					
						
							|  |  |  | 					axis: 'y', | 
					
						
							| 
									
										
										
										
											2016-10-11 22:38:50 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-20 16:54:16 +03:00
										 |  |  | 					// event handlers...
 | 
					
						
							| 
									
										
										
										
											2016-10-11 22:38:50 +03:00
										 |  |  | 					update: function(evt, ui){ | 
					
						
							|  |  |  | 						// get item list...
 | 
					
						
							|  |  |  | 						var order = ui.item | 
					
						
							|  |  |  | 							.parent().children('macro[src]') | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 								.map(function(){  | 
					
						
							|  |  |  | 									return $(this).attr('src') }) | 
					
						
							| 
									
										
										
										
											2016-10-11 22:38:50 +03:00
										 |  |  | 								.toArray() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						// save the order...
 | 
					
						
							|  |  |  | 						wiki | 
					
						
							|  |  |  | 							.get(order[0] + '/../*') | 
					
						
							|  |  |  | 								.order(['*'].concat(order)) | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 								.order('save') },  | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2016-10-19 05:30:15 +03:00
										 |  |  | 				// NOTE: we are only adding touch to the active elements
 | 
					
						
							|  |  |  | 				// 		to avoid the side-effect of it canceling the default
 | 
					
						
							|  |  |  | 				// 		behaviour (i.e. scrolling)...
 | 
					
						
							|  |  |  | 				.find('.sort-handle') | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					.addTouch() }, | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 		// title editor...
 | 
					
						
							|  |  |  | 		'.title': function(elems){ | 
					
						
							|  |  |  | 			var client = this | 
					
						
							|  |  |  | 			var wiki = this.page | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 			elems | 
					
						
							|  |  |  | 				.focus(function(){ | 
					
						
							|  |  |  | 					var to = $(this).attr('saveto') || '.' | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					$(this).text(wiki.get(to).title()) }) | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 				.blur(function(){  | 
					
						
							|  |  |  | 					var to = $(this).attr('saveto') || '.' | 
					
						
							|  |  |  | 					var text = $(this).text().trim() | 
					
						
							|  |  |  | 					var page = wiki.get(to) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if(text[0] == '/'){ | 
					
						
							|  |  |  | 						page.path(text) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					} else { | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 						page.title(text) } | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					// XXX need to account for changed path sufixes...
 | 
					
						
							|  |  |  | 					wiki.path(page.path) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					client.reload() }) | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-07 21:07:53 +03:00
										 |  |  | 			$('title').text(elems.first().text()) }, | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 		// raw text editor...
 | 
					
						
							|  |  |  | 		'.raw': function(elems){ | 
					
						
							|  |  |  | 			var client = this | 
					
						
							|  |  |  | 			var wiki = this.page | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 			elems | 
					
						
							|  |  |  | 				.focus(function(){ | 
					
						
							|  |  |  | 					var to = $(this).attr('saveto') || '.' | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					console.log('EDITING:', wiki.get(to).path()) }) | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 				.on('keyup', function(){  | 
					
						
							|  |  |  | 					var to = wiki.get($(this).attr('saveto') || '.').path() | 
					
						
							|  |  |  | 					console.log('SAVING:', to) | 
					
						
							|  |  |  | 					//Wiki.get(to).raw($(this).text())
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					wiki.get(to).raw($(this)[0].innerText) }) | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 				// XXX do this live, but on a timeout after user input...
 | 
					
						
							|  |  |  | 				// XXX need to place the cursor in the same position...
 | 
					
						
							|  |  |  | 				.blur(function(){  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					client.reload() }) }, | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 		// checkbox handlers...
 | 
					
						
							|  |  |  | 		'input[type="checkbox"].state': function(elems){ | 
					
						
							|  |  |  | 			var client = this | 
					
						
							|  |  |  | 			var wiki = this.page | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 			elems | 
					
						
							|  |  |  | 				// initial state...
 | 
					
						
							|  |  |  | 				.each(function(){ | 
					
						
							|  |  |  | 					var path = $(this).attr('saveto') | 
					
						
							|  |  |  | 					var value = !!wiki.get(path).checked() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					$(this) | 
					
						
							|  |  |  | 						.prop('checked', value) | 
					
						
							|  |  |  | 						.parents('.item').first() | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 							[value ? 'addClass' : 'removeClass']('checked') }) | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 				// handle clicks...
 | 
					
						
							|  |  |  | 				.click(function(){ | 
					
						
							|  |  |  | 					var path = $(this).attr('saveto') | 
					
						
							|  |  |  | 					var value = $(this).prop('checked') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					wiki.get(path).checked(value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					$(this) | 
					
						
							|  |  |  | 						.parents('.item').first() | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 							[value ?  | 
					
						
							|  |  |  | 								'addClass'  | 
					
						
							|  |  |  | 								: 'removeClass']('checked') | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					// XXX
 | 
					
						
							|  |  |  | 					//client.save()
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				}) }, | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 19:45:16 +03:00
										 |  |  | 	// XXX add support for anchors -- #Wiki/Path#anchor...
 | 
					
						
							|  |  |  | 	// 		...not working yet...
 | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 	location: ['',  | 
					
						
							|  |  |  | 		function(path){ | 
					
						
							|  |  |  | 			var page = this.page | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(arguments.length == 0){ | 
					
						
							|  |  |  | 				// XXX is this correct???
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				return page.path() } | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 19:45:16 +03:00
										 |  |  | 			path = path.trim().split('#') | 
					
						
							|  |  |  | 			var hash = path[1] | 
					
						
							|  |  |  | 			path = path[0] | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// special paths...
 | 
					
						
							|  |  |  | 			if(path in this.config['special-paths']){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				this[this.config['special-paths'][path]]() } | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 19:45:16 +03:00
										 |  |  | 			var orig = this.location() | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 19:45:16 +03:00
										 |  |  | 			page.location(path) | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 			this.reload() | 
					
						
							| 
									
										
										
										
											2016-10-10 19:45:16 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// reset scroll location...
 | 
					
						
							|  |  |  | 			orig != this.location() | 
					
						
							|  |  |  | 				&& this.dom | 
					
						
							|  |  |  | 					.scrollParent() | 
					
						
							|  |  |  | 						.scrollLeft(0) | 
					
						
							|  |  |  | 						.scrollTop(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// focus hash..
 | 
					
						
							|  |  |  | 			// XXX not working yet...
 | 
					
						
							|  |  |  | 			hash != null && hash != '' | 
					
						
							|  |  |  | 				&& this.dom | 
					
						
							|  |  |  | 					.scrollParent() | 
					
						
							|  |  |  | 						.scrollLeft(0) | 
					
						
							|  |  |  | 						.scrollTop( | 
					
						
							|  |  |  | 							(this.dom | 
					
						
							|  |  |  | 							 	.find('#'+hash+', a[name="'+hash+'"]').first() | 
					
						
							|  |  |  | 									.offset() || {}).top || 0) | 
					
						
							| 
									
										
										
										
											2022-04-07 21:07:53 +03:00
										 |  |  | 				&& console.log('HASH:', hash) }], | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 	reload: ['',  | 
					
						
							|  |  |  | 		function(){ | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 			var page = this.page | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			this.dom | 
					
						
							| 
									
										
										
										
											2016-10-10 06:53:47 +03:00
										 |  |  | 				.attr('wiki-active', 'no') | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 				.empty() | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 				// update path and render page...
 | 
					
						
							|  |  |  | 				// XXX revise the default view approach...
 | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 				.append(page.title()[0] == '_' ?  | 
					
						
							| 
									
										
										
										
											2016-10-11 03:45:15 +03:00
										 |  |  | 					page.html()  | 
					
						
							|  |  |  | 					: page.get('./_view').html()) | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 				// activate page controls...
 | 
					
						
							|  |  |  | 				.ready(function(){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					that.updateDom() }) }], | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 	// XXX might be a good idea to add actions to setup/clear a filter...
 | 
					
						
							|  |  |  | 	updateDom: ['',  | 
					
						
							|  |  |  | 		function(dom){ | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 			dom = dom || this.dom | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(dom.attr('wiki-active') == 'yes'){ | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 				return } | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			dom.attr('wiki-active', 'yes') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var filters = this.__dom_filters__  | 
					
						
							|  |  |  | 				|| pWikiUIActions.__dom_filters__ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// apply dom filters...
 | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 			Object.keys(filters) | 
					
						
							|  |  |  | 				.forEach(function(pattern){ | 
					
						
							|  |  |  | 					// XXX for some reason this works but has no effect...
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 					filters[pattern].call(that, dom.find(pattern)) }) }], | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 19:45:16 +03:00
										 |  |  | 	// shorthand...
 | 
					
						
							|  |  |  | 	get: ['',  | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 		function(){  | 
					
						
							|  |  |  | 			return this.page.get.apply(this.page, arguments) }] | 
					
						
							| 
									
										
										
										
											2016-10-10 19:45:16 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 	/* | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 	// XXX url?
 | 
					
						
							|  |  |  | 	// 		- couch url
 | 
					
						
							|  |  |  | 	// 		- 'local'
 | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 	load: ['',  | 
					
						
							|  |  |  | 		function(){ | 
					
						
							|  |  |  | 		}], | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-04 12:24:57 +03:00
										 |  |  | 	// XXX navigation...
 | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 	// 		...these in addition to default scrolling should focus elements
 | 
					
						
							| 
									
										
										
										
											2016-09-04 12:24:57 +03:00
										 |  |  | 	up: ['', function(){}], | 
					
						
							|  |  |  | 	down: ['', function(){}], | 
					
						
							|  |  |  | 	left: ['', function(){}], | 
					
						
							|  |  |  | 	right: ['', function(){}], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	togglePages: ['', function(){}], | 
					
						
							| 
									
										
										
										
											2016-09-11 05:46:10 +03:00
										 |  |  | 	toggleWikis: ['', function(){}], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// should this be in the editor feature???
 | 
					
						
							|  |  |  | 	toggleEdit: ['', function(){}], | 
					
						
							| 
									
										
										
										
											2016-10-09 22:31:22 +03:00
										 |  |  | 	//*/
 | 
					
						
							| 
									
										
										
										
											2016-09-04 12:24:57 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 03:30:16 +03:00
										 |  |  | var pWikiUI = pWikiFeatures.Feature({ | 
					
						
							| 
									
										
										
										
											2016-09-04 12:24:57 +03:00
										 |  |  | 	title: '', | 
					
						
							|  |  |  | 	tag: 'ui', | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | // XXX STUB: not sure if this is the right way...
 | 
					
						
							|  |  |  | var pWikiClient = | 
					
						
							| 
									
										
										
										
											2019-07-17 00:11:00 +03:00
										 |  |  | module.pWikiClient = object.Constructor('pWikiClient',  | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 	actions.mix( | 
					
						
							| 
									
										
										
										
											2016-10-10 19:45:16 +03:00
										 |  |  | 		actions.MetaActions, | 
					
						
							| 
									
										
										
										
											2016-10-10 04:30:47 +03:00
										 |  |  | 		pWikiUIActions)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-04 12:24:57 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module._test_data = { | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | 	'System/EmptyPage': { | 
					
						
							|  |  |  | 		text: '[@source(./path)] is empty...' | 
					
						
							|  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | 	'WikiMain': {}, | 
					
						
							|  |  |  | 	'folder/page1': {}, | 
					
						
							|  |  |  | 	'folder/page2': {}, | 
					
						
							|  |  |  | 	'folder/page3': {}, | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-27 07:09:25 +03:00
										 |  |  | // XXX not sure if this is a good way to do this -- needs to be reusable
 | 
					
						
							|  |  |  | // 		for different stores...
 | 
					
						
							| 
									
										
										
										
											2016-09-27 06:01:21 +03:00
										 |  |  | module._test_data.__proto__ = BaseData | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | module._test = function(){ | 
					
						
							|  |  |  | 	var wiki = Object.create(pWikiData) | 
					
						
							|  |  |  | 	wiki.__data = Object.create(module._test_data) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-28 18:48:09 +03:00
										 |  |  | 	var page = new pWikiPage({ | 
					
						
							| 
									
										
										
										
											2016-09-27 07:09:25 +03:00
										 |  |  | 		wiki: wiki, | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2016-09-28 18:48:09 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// XXX do some testing...
 | 
					
						
							|  |  |  | 	// XXX
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-02 01:06:49 +03:00
										 |  |  | 	return page } | 
					
						
							| 
									
										
										
										
											2016-09-18 16:45:26 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-03 02:17:22 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | * vim:set ts=4 sw=4 :                               */ return module }) |