mirror of
				https://github.com/flynx/pWiki.git
				synced 2025-10-31 02:50:08 +00:00 
			
		
		
		
	loading works -- now loading code on start + tweaks and notes...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									af3f10e35b
								
							
						
					
					
						commit
						9b2b232f69
					
				| @ -15,6 +15,10 @@ | |||||||
| 	position: relative; | 	position: relative; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .editor .code { | ||||||
|  | 	display: none; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .editor .outline { | .editor .outline { | ||||||
| 	display: block; | 	display: block; | ||||||
| 	position: relative; | 	position: relative; | ||||||
| @ -106,4 +110,14 @@ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | .editor .outline h1, | ||||||
|  | .editor .outline h2, | ||||||
|  | .editor .outline h3, | ||||||
|  | .editor .outline h4, | ||||||
|  | .editor .outline h5, | ||||||
|  | .editor .outline h6 { | ||||||
|  | 	margin-top: 0.5em; | ||||||
|  | 	margin-bottom: 0.5em; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -74,8 +74,11 @@ var Outline = { | |||||||
| 	//
 | 	//
 | ||||||
| 	left_key_collapses: true, | 	left_key_collapses: true, | ||||||
| 	right_key_expands: true, | 	right_key_expands: true, | ||||||
|  | 	code_update_interval: 5000, | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 	get code(){ | ||||||
|  | 		return this.dom.querySelector('.code') }, | ||||||
| 	get outline(){ | 	get outline(){ | ||||||
| 		return this.dom.querySelector('.outline') }, | 		return this.dom.querySelector('.outline') }, | ||||||
| 	get toolbar(){ | 	get toolbar(){ | ||||||
| @ -273,8 +276,14 @@ var Outline = { | |||||||
| 		next?.focus() | 		next?.focus() | ||||||
| 		return this }, | 		return this }, | ||||||
| 
 | 
 | ||||||
|  | 	clear: function(){ | ||||||
|  | 		this.outline.innerText = '' | ||||||
|  | 		return this }, | ||||||
|  | 
 | ||||||
| 	// block serialization...
 | 	// block serialization...
 | ||||||
| 	// XXX these should be symetrical...
 | 	// XXX STUB...
 | ||||||
|  | 	// XXX shouild we support headings + other formatting per block???
 | ||||||
|  | 	// XXX these should be symetrical -- now one returns text the other an object...
 | ||||||
| 	__code2html__: function(code){ | 	__code2html__: function(code){ | ||||||
| 		var elem = { | 		var elem = { | ||||||
| 			collapsed: false, | 			collapsed: false, | ||||||
| @ -287,13 +296,12 @@ var Outline = { | |||||||
| 					elem.collapsed = value.trim() == 'true' | 					elem.collapsed = value.trim() == 'true' | ||||||
| 					return '' }) | 					return '' }) | ||||||
| 			// markdown...
 | 			// markdown...
 | ||||||
| 			// XXX STUB...
 |  | ||||||
| 			.replace(/^#\s*(.*)\s*(\n|$)/, '<h1>$1</h1>') |  | ||||||
| 			.replace(/^##\s*(.*)\s*(\n|$)/, '<h2>$1</h2>') |  | ||||||
| 			.replace(/^###\s*(.*)\s*(\n|$)/, '<h3>$1</h3>') |  | ||||||
| 			.replace(/^####\s*(.*)\s*(\n|$)/, '<h4>$1</h4>') |  | ||||||
| 			.replace(/^#####\s*(.*)\s*(\n|$)/, '<h5>$1</h5>') |  | ||||||
| 			.replace(/^######\s*(.*)\s*(\n|$)/, '<h6>$1</h6>') | 			.replace(/^######\s*(.*)\s*(\n|$)/, '<h6>$1</h6>') | ||||||
|  | 			.replace(/^#####\s*(.*)\s*(\n|$)/, '<h5>$1</h5>') | ||||||
|  | 			.replace(/^####\s*(.*)\s*(\n|$)/, '<h4>$1</h4>') | ||||||
|  | 			.replace(/^###\s*(.*)\s*(\n|$)/, '<h3>$1</h3>') | ||||||
|  | 			.replace(/^##\s*(.*)\s*(\n|$)/, '<h2>$1</h2>') | ||||||
|  | 			.replace(/^#\s*(.*)\s*(\n|$)/, '<h1>$1</h1>') | ||||||
| 			.replace(/\*(.*)\*/g, '<b>$1</b>') | 			.replace(/\*(.*)\*/g, '<b>$1</b>') | ||||||
| 			.replace(/~([^~]*)~/g, '<s>$1</s>') | 			.replace(/~([^~]*)~/g, '<s>$1</s>') | ||||||
| 			.replace(/_([^_]*)_/g, '<i>$1</i>')  | 			.replace(/_([^_]*)_/g, '<i>$1</i>')  | ||||||
| @ -301,16 +309,21 @@ var Outline = { | |||||||
| 			.replace(/\n/g, '<br>\n') | 			.replace(/\n/g, '<br>\n') | ||||||
| 		return elem }, | 		return elem }, | ||||||
| 	__html2code__: function(html){ | 	__html2code__: function(html){ | ||||||
|  | 		var heading = function(level){ | ||||||
|  | 			return function(_, text, rest){ | ||||||
|  | 				return `${'#'.repeat(level)} ${text}${ | ||||||
|  | 					(rest != '' ?  | ||||||
|  | 						'\n'+ rest | ||||||
|  | 						: '') }` } }
 | ||||||
| 		return html  | 		return html  | ||||||
| 			// XXX STUB...
 |  | ||||||
| 			.replace(/<hr>$/, '---') | 			.replace(/<hr>$/, '---') | ||||||
| 			.replace(/<hr>/, '---\n') | 			.replace(/<hr>/, '---\n') | ||||||
| 			.replace(/^<h1>(.*)<\/h1>\s*(.*)$/g, '# $1\n$2') | 			.replace(/^<h6>(.*)<\/h6>(.*)$/g, heading(6)) | ||||||
| 			.replace(/^<h2>(.*)<\/h2>\s*(.*)$/g, '## $1\n$2') | 			.replace(/^<h5>(.*)<\/h5>(.*)$/g, heading(5)) | ||||||
| 			.replace(/^<h3>(.*)<\/h3>\s*(.*)$/g, '### $1\n$2') | 			.replace(/^<h4>(.*)<\/h4>(.*)$/g, heading(4)) | ||||||
| 			.replace(/^<h4>(.*)<\/h4>\s*(.*)$/g, '#### $1\n$2') | 			.replace(/^<h3>(.*)<\/h3>(.*)$/g, heading(3)) | ||||||
| 			.replace(/^<h5>(.*)<\/h5>\s*(.*)$/g, '##### $1\n$2') | 			.replace(/^<h2>(.*)<\/h2>(.*)$/g, heading(2)) | ||||||
| 			.replace(/^<h6>(.*)<\/h6>\s*(.*)$/g, '###### $1\n$2') | 			.replace(/^<h1>(.*)<\/h1>(.*)$/g, heading(1)) | ||||||
| 			.replace(/<b>(.*)<\/b>/g, '*$1*') | 			.replace(/<b>(.*)<\/b>/g, '*$1*') | ||||||
| 			.replace(/<s>(.*)<\/s>/g, '~$1~') | 			.replace(/<s>(.*)<\/s>/g, '~$1~') | ||||||
| 			.replace(/<i>(.*)<\/i>/g, '_$1_') | 			.replace(/<i>(.*)<\/i>/g, '_$1_') | ||||||
| @ -339,21 +352,26 @@ var Outline = { | |||||||
| 		node ??= this.json(node) | 		node ??= this.json(node) | ||||||
| 		indent ??= '  ' | 		indent ??= '  ' | ||||||
| 		level ??= '' | 		level ??= '' | ||||||
| 		var text = '' | 		var text = [] | ||||||
| 		for(var elem of node){ | 		for(var elem of node){ | ||||||
| 			text +=  | 			text.push(  | ||||||
| 				level | 				level +'- ' | ||||||
| 				+'- ' |  | ||||||
| 					+ elem.text | 					+ elem.text | ||||||
| 						.replace(/\n/g, '\n'+ level +'  ')  | 						.replace(/\n/g, '\n'+ level +'  ')  | ||||||
| 				+'\n' |  | ||||||
| 					+ (elem.collapsed ? | 					+ (elem.collapsed ? | ||||||
| 					level+'  ' + 'collapsed:: true\n' | 						'\n'+level+'  ' + 'collapsed:: true' | ||||||
| 					: '') | 						: ''), | ||||||
| 				+ this.text(elem.children || [], indent, level+indent) } | 				(elem.children  | ||||||
| 		return text }, | 						&& elem.children.length > 0) ? | ||||||
|  | 					this.text(elem.children || [], indent, level+indent)  | ||||||
|  | 					: [] ) } | ||||||
|  | 		return text | ||||||
|  | 			.flat() | ||||||
|  | 			.join('\n') }, | ||||||
| 
 | 
 | ||||||
| 	parse: function(text){ | 	parse: function(text){ | ||||||
|  | 		text = text | ||||||
|  | 			.replace(/^\s*\n/, '') | ||||||
| 		text = ('\n' + text) | 		text = ('\n' + text) | ||||||
| 			.split(/\n(\s*)- /g) | 			.split(/\n(\s*)- /g) | ||||||
| 			.slice(1) | 			.slice(1) | ||||||
| @ -385,6 +403,7 @@ var Outline = { | |||||||
| 			return parent } | 			return parent } | ||||||
| 		return level(text) }, | 		return level(text) }, | ||||||
| 
 | 
 | ||||||
|  | 	// XXX should this handle children???
 | ||||||
| 	// XXX revise name...
 | 	// XXX revise name...
 | ||||||
| 	Block: function(data={}, place=null){ | 	Block: function(data={}, place=null){ | ||||||
| 		if(typeof(data) != 'object'){ | 		if(typeof(data) != 'object'){ | ||||||
| @ -394,28 +413,44 @@ var Outline = { | |||||||
| 		block.setAttribute('tabindex', '0') | 		block.setAttribute('tabindex', '0') | ||||||
| 		data.collapsed | 		data.collapsed | ||||||
| 			&& block.setAttribute('collapsed', '') | 			&& block.setAttribute('collapsed', '') | ||||||
| 		var text | 		var text = document.createElement('textarea') | ||||||
| 		var html | 		var html = document.createElement('span') | ||||||
| 		block.append( | 		block.append(text, html) | ||||||
| 			text = document.createElement('textarea') |  | ||||||
| 				.autoUpdateSize(), |  | ||||||
| 			html = document.createElement('span')) |  | ||||||
| 		if(data.text){ | 		if(data.text){ | ||||||
| 			text.value = data.text |  | ||||||
| 			html.innerHTML = this.__code2html__ ? | 			html.innerHTML = this.__code2html__ ? | ||||||
| 				this.__code2html__(data.text) | 				// NOTE: we are ignoring the .collapsed attr here (XXX)
 | ||||||
| 				: data.text } | 				this.__code2html__(data.text).text | ||||||
|  | 				: data.text  | ||||||
|  | 			text.value = data.text | ||||||
|  | 			// XXX this does not see to work until we click in the textarea...
 | ||||||
|  | 			text.autoUpdateSize() } | ||||||
| 		var cur = this.get() | 		var cur = this.get() | ||||||
| 		place && cur | 		place && cur | ||||||
| 			&& cur[place](block) | 			&& cur[place](block) | ||||||
| 		return block }, | 		return block }, | ||||||
| 	// XXX use .__code2html__(..)
 |  | ||||||
| 	load: function(data){ | 	load: function(data){ | ||||||
|  | 		var that = this | ||||||
| 		data = typeof(data) == 'string' ? | 		data = typeof(data) == 'string' ? | ||||||
| 			this.parse(data) | 			this.parse(data) | ||||||
| 			: data | 			: data | ||||||
| 		// generate dom...
 | 		// generate dom...
 | ||||||
| 		// XXX
 | 		var level = function(lst){ | ||||||
|  | 			return lst | ||||||
|  | 				.map(function(data){ | ||||||
|  | 					var elem = that.Block(data)  | ||||||
|  | 					if((data.children || []).length > 0){ | ||||||
|  | 						elem.append(...level(data.children)) } | ||||||
|  | 					return elem }) } | ||||||
|  | 		this | ||||||
|  | 			.clear() | ||||||
|  | 			.outline | ||||||
|  | 				.append(...level(data)) | ||||||
|  | 		return this }, | ||||||
|  | 
 | ||||||
|  | 	sync: function(){ | ||||||
|  | 		var code = this.code | ||||||
|  | 		code  | ||||||
|  | 			&& (code.innerHTML = this.text()) | ||||||
| 		return this }, | 		return this }, | ||||||
| 
 | 
 | ||||||
| 	// XXX add scrollIntoView(..) to nav...
 | 	// XXX add scrollIntoView(..) to nav...
 | ||||||
| @ -578,6 +613,18 @@ var Outline = { | |||||||
| 							&& node.parentElement.setAttribute('collapsed', '') | 							&& node.parentElement.setAttribute('collapsed', '') | ||||||
| 					} else { | 					} else { | ||||||
| 						node.nextElementSibling.innerHTML = node.value } } }) | 						node.nextElementSibling.innerHTML = node.value } } }) | ||||||
|  | 		// update .code...
 | ||||||
|  | 		var update_code_timeout | ||||||
|  | 		outline.addEventListener('change',  | ||||||
|  | 			function(evt){ | ||||||
|  | 				if(update_code_timeout){ | ||||||
|  | 					return } | ||||||
|  | 				update_code_timeout = setTimeout( | ||||||
|  | 					function(){ | ||||||
|  | 						update_code_timeout = undefined | ||||||
|  | 						console.log('SYNC') | ||||||
|  | 						that.sync() },  | ||||||
|  | 					that.code_update_interval || 5000) }) | ||||||
| 
 | 
 | ||||||
| 		// toolbar...
 | 		// toolbar...
 | ||||||
| 		var toolbar = this.toolbar | 		var toolbar = this.toolbar | ||||||
| @ -598,6 +645,11 @@ var Outline = { | |||||||
| 			// refocus the node after we are done...
 | 			// refocus the node after we are done...
 | ||||||
| 			toolbar.addEventListener('click', refocusNode) } | 			toolbar.addEventListener('click', refocusNode) } | ||||||
| 
 | 
 | ||||||
|  | 		// code...
 | ||||||
|  | 		var code = this.code | ||||||
|  | 		if(code){ | ||||||
|  | 			this.load(code.innerHTML) } | ||||||
|  | 
 | ||||||
| 		return this }, | 		return this }, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -24,35 +24,51 @@ var setup = function(){ | |||||||
| </head> | </head> | ||||||
| <body onload="setup()"> | <body onload="setup()"> | ||||||
| <div class="editor"> | <div class="editor"> | ||||||
| 	<div class="outline"> | 	<!-- code --> | ||||||
| 		<div tabindex=0> | 	<div class="code"> | ||||||
| 			<textarea></textarea><span><i>root</i></span> | - # Outline editor prototype | ||||||
| 			<div tabindex=0 collapsed> | - ## TODO | ||||||
| 				<textarea></textarea><span>A</span> |   - editor: bksapce/del at start/end of a block should join it with prev/next | ||||||
| 				<div tabindex=0><textarea></textarea><span>a</span> |   - editor: pressing enter in text edit mode should split text into two blocks | ||||||
| 				</div> |   - editor: caret | ||||||
| 				<div tabindex=0><textarea></textarea><span>b</span> |     - ~go to next/prev element's start/end when moving off last/first char~ | ||||||
| 				</div> |     - handle up/down on wrapped blocks | ||||||
| 				<div tabindex=0><textarea></textarea><span>c</span> |       _...can't seem to get caret line in a non-hacky way_ | ||||||
| 				</div> |   - persistent empty first/last node (a button to create a new node) | ||||||
| 			</div> |   - loading from DOM -- fill textarea | ||||||
| 			<div tabindex=0><textarea></textarea><span>B</span> |   - ~focus management~ | ||||||
| 				<div tabindex=0><textarea></textarea><span>d</span> |   - ~mouse/touch controls~ | ||||||
| 				</div> |   - ~navigation~ | ||||||
| 				<div tabindex=0><textarea></textarea><span>e</span> |   - ~expand/collapse subtree~ | ||||||
| 				</div> |   - ~shift subtree up/down~ | ||||||
| 			</div> |   - ~create node~ | ||||||
| 			<div tabindex=0><textarea></textarea><span>C</span> |   - ~edit node~ | ||||||
| 				<div tabindex=0><textarea></textarea><span>This is a line of text</span> |   - shifting nodes up/down | ||||||
| 				</div> |   - multiple node selection | ||||||
| 				<div tabindex=0><textarea></textarea><span>This is a set<br> |   - undo  | ||||||
| 					text lines</span> |     - delete node | ||||||
| 				</div> |     - indent/deindent | ||||||
| 				<div tabindex=0><textarea></textarea><span>Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text </span> |     - edit node | ||||||
| 				</div> |   - copy/paste nodes/trees | ||||||
| 			</div> |   - ~serialize~/deserialize | ||||||
| 		</div> |   - ~add optional text styling to nodes~ | ||||||
| 	</div> |   -  | ||||||
|  | - ## TEST | ||||||
|  |   - A | ||||||
|  |     collapsed:: true | ||||||
|  |     - a | ||||||
|  |     - b | ||||||
|  |     - c | ||||||
|  |   - B | ||||||
|  |     - d | ||||||
|  |     - e | ||||||
|  |   - C | ||||||
|  |     - This is a line of text | ||||||
|  |     - This is a set | ||||||
|  |       text lines | ||||||
|  |     - Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text </div> | ||||||
|  | 	<!-- outline --> | ||||||
|  | 	<div class="outline"></div> | ||||||
| 	<!-- toolbar (optional) --> | 	<!-- toolbar (optional) --> | ||||||
| 	<div class="toolbar"> | 	<div class="toolbar"> | ||||||
| 		<button onclick="editor.deindent().focus()"><</button> | 		<button onclick="editor.deindent().focus()"><</button> | ||||||
| @ -68,30 +84,6 @@ var setup = function(){ | |||||||
| <hr> | <hr> | ||||||
| 
 | 
 | ||||||
| <pre> | <pre> | ||||||
| TODO: |  | ||||||
| - caret |  | ||||||
|   - <s>go to next/prev element's start/end when moving off last/first char</s> |  | ||||||
|   - handle up/down on wrapped blocks |  | ||||||
|     <i>...can't seem to get caret line in a non-hacky way</i> |  | ||||||
| - persistent empty first/last node (a button to create a new node) |  | ||||||
| - loading from DOM -- fill textarea |  | ||||||
| - Firefox compatibility -- remove ':has(..)' |  | ||||||
| - <s>focus management</s> |  | ||||||
| - <s>mouse/touch controls</s> |  | ||||||
| - <s>navigation</s> |  | ||||||
| - <s>expand/collapse subtree</s> |  | ||||||
| - <s>shift subtree up/down</s> |  | ||||||
| - <s>create node</s> |  | ||||||
| - <s>edit node</s> |  | ||||||
| - shifting nodes up/down |  | ||||||
| - multiple node selection |  | ||||||
| - undo  |  | ||||||
|   - delete node |  | ||||||
|   - indent/deindent |  | ||||||
|   - edit node |  | ||||||
| - copy/paste nodes/trees |  | ||||||
| - <s>serialize</s>/deserialize |  | ||||||
| - <s>add optional text styling to nodes</s> |  | ||||||
| 
 | 
 | ||||||
| Controls: | Controls: | ||||||
| 	up         - focus node above | 	up         - focus node above | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user