mirror of
				https://github.com/flynx/pWiki.git
				synced 2025-10-31 11:00:08 +00:00 
			
		
		
		
	code cleanup + notes...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									9b2b232f69
								
							
						
					
					
						commit
						6633bc065a
					
				| @ -110,6 +110,56 @@ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | .editor .outline .heading-1>span, | ||||||
|  | .editor .outline .heading-1>textarea, | ||||||
|  | .editor .outline .heading-2>span, | ||||||
|  | .editor .outline .heading-2>textarea, | ||||||
|  | .editor .outline .heading-3>span, | ||||||
|  | .editor .outline .heading-3>textarea, | ||||||
|  | .editor .outline .heading-4>span, | ||||||
|  | .editor .outline .heading-4>textarea, | ||||||
|  | .editor .outline .heading-5>span, | ||||||
|  | .editor .outline .heading-5>textarea, | ||||||
|  | .editor .outline .heading-6>span, | ||||||
|  | .editor .outline .heading-6>textarea { | ||||||
|  | 	font-weight: bold; | ||||||
|  | } | ||||||
|  | .editor .outline .heading-1>span, | ||||||
|  | .editor .outline .heading-1>textarea { | ||||||
|  | 	font-size: 2.5em; | ||||||
|  | } | ||||||
|  | .editor .outline .heading-2>span, | ||||||
|  | .editor .outline .heading-2>textarea { | ||||||
|  | 	font-size: 1.9em; | ||||||
|  | } | ||||||
|  | .editor .outline .heading-3>span, | ||||||
|  | .editor .outline .heading-3>textarea { | ||||||
|  | 	font-size: 1.5em; | ||||||
|  | } | ||||||
|  | .editor .outline .heading-4>span, | ||||||
|  | .editor .outline .heading-4>textarea { | ||||||
|  | 	font-size: 1.3em; | ||||||
|  | } | ||||||
|  | .editor .outline .heading-5>span, | ||||||
|  | .editor .outline .heading-5>textarea { | ||||||
|  | 	font-size: 1.1em; | ||||||
|  | } | ||||||
|  | .editor .outline .heading-6>span, | ||||||
|  | .editor .outline .heading-6>textarea { | ||||||
|  | 	font-size: 1em; | ||||||
|  | } | ||||||
|  | /* XXX EXPERIMENTAL -- not sure about this... */ | ||||||
|  | .editor .outline .list>[tabindex]:before { | ||||||
|  | 	display: inline-block; | ||||||
|  | 	position: absolute; | ||||||
|  | 	content: ""; | ||||||
|  | 	top: 0.6em; | ||||||
|  | 	left: -0.8em; | ||||||
|  | 	width: 0.5em; | ||||||
|  | 	height: 0.5em; | ||||||
|  | 	background: silver; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .editor .outline h1, | .editor .outline h1, | ||||||
| .editor .outline h2, | .editor .outline h2, | ||||||
| .editor .outline h3, | .editor .outline h3, | ||||||
| @ -121,3 +171,5 @@ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -75,6 +75,7 @@ var Outline = { | |||||||
| 	left_key_collapses: true, | 	left_key_collapses: true, | ||||||
| 	right_key_expands: true, | 	right_key_expands: true, | ||||||
| 	code_update_interval: 5000, | 	code_update_interval: 5000, | ||||||
|  | 	tab_size: 4, | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	get code(){ | 	get code(){ | ||||||
| @ -215,6 +216,30 @@ var Outline = { | |||||||
| 	focus: function(node='focused', offset){}, | 	focus: function(node='focused', offset){}, | ||||||
| 	edit: function(node='focused', offset){}, | 	edit: function(node='focused', offset){}, | ||||||
| 
 | 
 | ||||||
|  | 	// XXX should this handle children???
 | ||||||
|  | 	update: function(node='focused', data){ | ||||||
|  | 		var node = this.get(node) | ||||||
|  | 		data.collapsed ? | ||||||
|  | 			node.setAttribute('collapsed', '') | ||||||
|  | 			: node.removeAttribute('collapsed') | ||||||
|  | 		if(data.text){ | ||||||
|  | 			var text = node.querySelector('textarea') | ||||||
|  | 			var html = node.querySelector('span') | ||||||
|  | 			if(this.__code2html__){ | ||||||
|  | 				// NOTE: we are ignoring the .collapsed attr here 
 | ||||||
|  | 				var parsed = this.__code2html__(data.text) | ||||||
|  | 				html.innerHTML = parsed.text | ||||||
|  | 				// heading...
 | ||||||
|  | 				parsed.style ? | ||||||
|  | 					node.classList.add(parsed.style) | ||||||
|  | 					: node.classList.remove(...this.__styles__) | ||||||
|  | 			} else { | ||||||
|  | 				html.innerHTML = data.text } | ||||||
|  | 			text.value = data.text | ||||||
|  | 			// XXX this does not see to work until we click in the textarea...
 | ||||||
|  | 			text.autoUpdateSize() } | ||||||
|  | 		return node }, | ||||||
|  | 
 | ||||||
| 	indent: function(node='focused', indent=true){ | 	indent: function(node='focused', indent=true){ | ||||||
| 		// .indent(<indent>)
 | 		// .indent(<indent>)
 | ||||||
| 		if(node === true || node === false){ | 		if(node === true || node === false){ | ||||||
| @ -284,10 +309,27 @@ var Outline = { | |||||||
| 	// XXX STUB...
 | 	// XXX STUB...
 | ||||||
| 	// XXX shouild we support headings + other formatting per block???
 | 	// XXX shouild we support headings + other formatting per block???
 | ||||||
| 	// XXX these should be symetrical -- now one returns text the other an object...
 | 	// XXX these should be symetrical -- now one returns text the other an object...
 | ||||||
|  | 	__styles__: [ | ||||||
|  | 		'heading-1', | ||||||
|  | 		'heading-2', | ||||||
|  | 		'heading-3', | ||||||
|  | 		'heading-4', | ||||||
|  | 		'heading-5', | ||||||
|  | 		'heading-6', | ||||||
|  | 		'list', | ||||||
|  | 	], | ||||||
| 	__code2html__: function(code){ | 	__code2html__: function(code){ | ||||||
| 		var elem = { | 		var elem = { | ||||||
| 			collapsed: false, | 			collapsed: false, | ||||||
| 		} | 		} | ||||||
|  | 		var heading = function(level){ | ||||||
|  | 			return function(_, text){ | ||||||
|  | 				elem.style = 'heading-'+level | ||||||
|  | 				return text } } | ||||||
|  | 		var style = function(style){ | ||||||
|  | 			return function(_, text){ | ||||||
|  | 				elem.style = style  | ||||||
|  | 				return text } } | ||||||
| 		elem.text = code  | 		elem.text = code  | ||||||
| 			// attributes...
 | 			// attributes...
 | ||||||
| 			// XXX make this generic...
 | 			// XXX make this generic...
 | ||||||
| @ -296,38 +338,20 @@ var Outline = { | |||||||
| 					elem.collapsed = value.trim() == 'true' | 					elem.collapsed = value.trim() == 'true' | ||||||
| 					return '' }) | 					return '' }) | ||||||
| 			// markdown...
 | 			// markdown...
 | ||||||
| 			.replace(/^######\s*(.*)\s*(\n|$)/, '<h6>$1</h6>') | 			.replace(/^######\s*(.*)$/, style('heading-6')) | ||||||
| 			.replace(/^#####\s*(.*)\s*(\n|$)/, '<h5>$1</h5>') | 			.replace(/^#####\s*(.*)$/, style('heading-5')) | ||||||
| 			.replace(/^####\s*(.*)\s*(\n|$)/, '<h4>$1</h4>') | 			.replace(/^####\s*(.*)$/, style('heading-4')) | ||||||
| 			.replace(/^###\s*(.*)\s*(\n|$)/, '<h3>$1</h3>') | 			.replace(/^###\s*(.*)$/, style('heading-3')) | ||||||
| 			.replace(/^##\s*(.*)\s*(\n|$)/, '<h2>$1</h2>') | 			.replace(/^##\s*(.*)$/, style('heading-2')) | ||||||
| 			.replace(/^#\s*(.*)\s*(\n|$)/, '<h1>$1</h1>') | 			.replace(/^#\s*(.*)$/, style('heading-1')) | ||||||
|  | 			//.replace(/^[-\*]\s*(.*)$/, style('list'))
 | ||||||
|  | 			.replace(/^\s*(.*):\s*$/, style('list')) | ||||||
| 			.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>')  | ||||||
| 			.replace(/(\n|^)---*\h*(\n|$)/, '$1<hr>') | 			.replace(/(\n|^)---*\h*(\n|$)/, '$1<hr>') | ||||||
| 			.replace(/\n/g, '<br>\n') | 			.replace(/\n/g, '<br>\n') | ||||||
| 		return elem }, | 		return elem }, | ||||||
| 	__html2code__: function(html){ |  | ||||||
| 		var heading = function(level){ |  | ||||||
| 			return function(_, text, rest){ |  | ||||||
| 				return `${'#'.repeat(level)} ${text}${ |  | ||||||
| 					(rest != '' ?  |  | ||||||
| 						'\n'+ rest |  | ||||||
| 						: '') }` } }
 |  | ||||||
| 		return html  |  | ||||||
| 			.replace(/<hr>$/, '---') |  | ||||||
| 			.replace(/<hr>/, '---\n') |  | ||||||
| 			.replace(/^<h6>(.*)<\/h6>(.*)$/g, heading(6)) |  | ||||||
| 			.replace(/^<h5>(.*)<\/h5>(.*)$/g, heading(5)) |  | ||||||
| 			.replace(/^<h4>(.*)<\/h4>(.*)$/g, heading(4)) |  | ||||||
| 			.replace(/^<h3>(.*)<\/h3>(.*)$/g, heading(3)) |  | ||||||
| 			.replace(/^<h2>(.*)<\/h2>(.*)$/g, heading(2)) |  | ||||||
| 			.replace(/^<h1>(.*)<\/h1>(.*)$/g, heading(1)) |  | ||||||
| 			.replace(/<b>(.*)<\/b>/g, '*$1*') |  | ||||||
| 			.replace(/<s>(.*)<\/s>/g, '~$1~') |  | ||||||
| 			.replace(/<i>(.*)<\/i>/g, '_$1_') |  | ||||||
| 			.replace(/<br>\s*/g, '\n') }, |  | ||||||
| 
 | 
 | ||||||
| 	// serialization...
 | 	// serialization...
 | ||||||
| 	json: function(node){ | 	json: function(node){ | ||||||
| @ -338,13 +362,12 @@ var Outline = { | |||||||
| 				return elem.nodeName != 'DIV' ? | 				return elem.nodeName != 'DIV' ? | ||||||
| 					[] | 					[] | ||||||
| 					: [{ | 					: [{ | ||||||
| 						text: that.__html2code__ ? | 						text: elem.querySelector('textarea').value, | ||||||
| 							that.__html2code__(elem.querySelector('span').innerHTML) |  | ||||||
| 							: elem.querySelector('span').innerHTML, |  | ||||||
| 						collapsed: elem.getAttribute('collapsed') != null, | 						collapsed: elem.getAttribute('collapsed') != null, | ||||||
| 						children: that.json(elem) | 						children: that.json(elem) | ||||||
| 					}] }) | 					}] }) | ||||||
| 			.flat() }, | 			.flat() }, | ||||||
|  | 	// XXX add option to customize indent size...
 | ||||||
| 	text: function(node, indent, level){ | 	text: function(node, indent, level){ | ||||||
| 		// .text(<indent>, <level>)
 | 		// .text(<indent>, <level>)
 | ||||||
| 		if(typeof(node) == 'string'){ | 		if(typeof(node) == 'string'){ | ||||||
| @ -375,9 +398,10 @@ var Outline = { | |||||||
| 		text = ('\n' + text) | 		text = ('\n' + text) | ||||||
| 			.split(/\n(\s*)- /g) | 			.split(/\n(\s*)- /g) | ||||||
| 			.slice(1) | 			.slice(1) | ||||||
|  | 		var tab = ' '.repeat(this.tab_size || 8) | ||||||
| 		var level = function(lst, prev_sep=undefined, parent=[]){ | 		var level = function(lst, prev_sep=undefined, parent=[]){ | ||||||
| 			while(lst.length > 0){ | 			while(lst.length > 0){ | ||||||
| 				sep = lst[0] | 				sep = lst[0].replace(/\t/g, tab) | ||||||
| 				// deindent...
 | 				// deindent...
 | ||||||
| 				if(prev_sep != null  | 				if(prev_sep != null  | ||||||
| 						&& sep.length < prev_sep.length){ | 						&& sep.length < prev_sep.length){ | ||||||
| @ -411,19 +435,10 @@ var Outline = { | |||||||
| 			data = {} } | 			data = {} } | ||||||
| 		var block = document.createElement('div') | 		var block = document.createElement('div') | ||||||
| 		block.setAttribute('tabindex', '0') | 		block.setAttribute('tabindex', '0') | ||||||
| 		data.collapsed |  | ||||||
| 			&& block.setAttribute('collapsed', '') |  | ||||||
| 		var text = document.createElement('textarea') | 		var text = document.createElement('textarea') | ||||||
| 		var html = document.createElement('span') | 		var html = document.createElement('span') | ||||||
| 		block.append(text, html) | 		block.append(text, html) | ||||||
| 		if(data.text){ | 		this.update(block, data) | ||||||
| 			html.innerHTML = this.__code2html__ ? |  | ||||||
| 				// NOTE: we are ignoring the .collapsed attr here (XXX)
 |  | ||||||
| 				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) | ||||||
| @ -596,23 +611,14 @@ var Outline = { | |||||||
| 				// textarea...
 | 				// textarea...
 | ||||||
| 				if(node.nodeName == 'TEXTAREA'  | 				if(node.nodeName == 'TEXTAREA'  | ||||||
| 						&& node?.nextElementSibling?.nodeName == 'SPAN'){ | 						&& node?.nextElementSibling?.nodeName == 'SPAN'){ | ||||||
| 					node.value =  |  | ||||||
| 						that.__html2code__ ? |  | ||||||
| 							that.__html2code__(node.nextElementSibling.innerHTML) |  | ||||||
| 							: node.nextElementSibling.innerHTML  |  | ||||||
| 					node.updateSize() } }) | 					node.updateSize() } }) | ||||||
| 		outline.addEventListener('focusout',  | 		outline.addEventListener('focusout',  | ||||||
| 			function(evt){ | 			function(evt){ | ||||||
| 				var node = evt.target | 				var node = evt.target | ||||||
| 				if(node.nodeName == 'TEXTAREA'  | 				if(node.nodeName == 'TEXTAREA'  | ||||||
| 						&& node?.nextElementSibling?.nodeName == 'SPAN'){ | 						&& node?.nextElementSibling?.nodeName == 'SPAN'){ | ||||||
| 					if(that.__code2html__){ | 					var block = node.parentElement | ||||||
| 						var data = that.__code2html__(node.value) | 					that.update(block, { text: node.value }) } }) | ||||||
| 						node.nextElementSibling.innerHTML = data.text |  | ||||||
| 						data.collapsed  |  | ||||||
| 							&& node.parentElement.setAttribute('collapsed', '') |  | ||||||
| 					} else { |  | ||||||
| 						node.nextElementSibling.innerHTML = node.value } } }) |  | ||||||
| 		// update .code...
 | 		// update .code...
 | ||||||
| 		var update_code_timeout | 		var update_code_timeout | ||||||
| 		outline.addEventListener('change',  | 		outline.addEventListener('change',  | ||||||
| @ -622,7 +628,6 @@ var Outline = { | |||||||
| 				update_code_timeout = setTimeout( | 				update_code_timeout = setTimeout( | ||||||
| 					function(){ | 					function(){ | ||||||
| 						update_code_timeout = undefined | 						update_code_timeout = undefined | ||||||
| 						console.log('SYNC') |  | ||||||
| 						that.sync() },  | 						that.sync() },  | ||||||
| 					that.code_update_interval || 5000) }) | 					that.code_update_interval || 5000) }) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -28,6 +28,8 @@ var setup = function(){ | |||||||
| 	<div class="code"> | 	<div class="code"> | ||||||
| - # Outline editor prototype | - # Outline editor prototype | ||||||
| - ## TODO | - ## TODO | ||||||
|  |   - BUG: delete in edit mode deletes node... | ||||||
|  |   - editor: enter on an expanded parent node should create child (currently next sibling) | ||||||
|   - editor: bksapce/del at start/end of a block should join it with prev/next |   - editor: bksapce/del at start/end of a block should join it with prev/next | ||||||
|   - editor: pressing enter in text edit mode should split text into two blocks |   - editor: pressing enter in text edit mode should split text into two blocks | ||||||
|   - editor: caret |   - editor: caret | ||||||
| @ -35,7 +37,7 @@ var setup = function(){ | |||||||
|     - handle up/down on wrapped blocks |     - handle up/down on wrapped blocks | ||||||
|       _...can't seem to get caret line in a non-hacky way_ |       _...can't seem to get caret line in a non-hacky way_ | ||||||
|   - persistent empty first/last node (a button to create a new node) |   - persistent empty first/last node (a button to create a new node) | ||||||
|   - loading from DOM -- fill textarea |   - ~loading from DOM -- fill textarea~ | ||||||
|   - ~focus management~ |   - ~focus management~ | ||||||
|   - ~mouse/touch controls~ |   - ~mouse/touch controls~ | ||||||
|   - ~navigation~ |   - ~navigation~ | ||||||
| @ -54,6 +56,20 @@ var setup = function(){ | |||||||
|   - ~add optional text styling to nodes~ |   - ~add optional text styling to nodes~ | ||||||
|   -  |   -  | ||||||
| - ## TEST | - ## TEST | ||||||
|  |   - Formatting | ||||||
|  |     - Styles | ||||||
|  |       - # Heading 1 | ||||||
|  |       - ## Heading 2 | ||||||
|  |       - ### Heading 3 | ||||||
|  |       - #### Heading 4 | ||||||
|  |       - ##### Heading 5 | ||||||
|  |       - ###### Heading 6 | ||||||
|  |       - Text | ||||||
|  |       - List:: | ||||||
|  |         - a | ||||||
|  |         - b | ||||||
|  |         - c | ||||||
|  |     - basic inline *bold*, _italic_ and ~striked~ | ||||||
|   - A |   - A | ||||||
|     collapsed:: true |     collapsed:: true | ||||||
|     - a |     - a | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user