mirror of
				https://github.com/flynx/pWiki.git
				synced 2025-10-30 18:40:08 +00:00 
			
		
		
		
	reworked attributes...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									3e5a3d7df7
								
							
						
					
					
						commit
						7828a10bf9
					
				| @ -138,23 +138,25 @@ var plugin = { | |||||||
| 
 | 
 | ||||||
| // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -      
 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -      
 | ||||||
| 
 | 
 | ||||||
|  | // XXX style attributes... 
 | ||||||
| var attributes = { | var attributes = { | ||||||
| 	__proto__: plugin, | 	__proto__: plugin, | ||||||
| 
 | 
 | ||||||
| 	__pre_parse__: function(text, editor, elem){ | 	__parse__: function(text, editor, elem){ | ||||||
|  | 		var skip = new Set([ | ||||||
|  | 			'text',  | ||||||
|  | 			'focused', | ||||||
|  | 			'collapsed', | ||||||
|  | 			'id', | ||||||
|  | 			'children',  | ||||||
|  | 			'style', | ||||||
|  | 		]) | ||||||
| 		return text  | 		return text  | ||||||
| 			// hidden attributes...
 | 			+ Object.entries(elem) | ||||||
| 			// XXX make this generic...
 | 				.reduce(function(res, [key, value]){ | ||||||
| 			// collapsed...
 | 					return skip.has(key) ? | ||||||
| 			.replace(/(\n|^)\s*collapsed::\s*(.*)\s*(\n|$)/,  | 						res | ||||||
| 				function(_, value){ | 						: res + `<br>${key}: ${value}` }, '') }, | ||||||
| 					elem.collapsed = value.trim() == 'true' |  | ||||||
| 					return '' }) |  | ||||||
| 			// id...
 |  | ||||||
| 			.replace(/(\n|^)\s*id::\s*(.*)\s*(\n|$)/,  |  | ||||||
| 				function(_, value){ |  | ||||||
| 					elem.id = value.trim() |  | ||||||
| 					return '' }) }, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -614,7 +616,6 @@ var Outline = { | |||||||
| 	// 	- parsing
 | 	// 	- parsing
 | ||||||
| 	// 	- event dropping
 | 	// 	- event dropping
 | ||||||
| 	plugins: [ | 	plugins: [ | ||||||
| 		attributes, |  | ||||||
| 		blocks, | 		blocks, | ||||||
| 		quoted, | 		quoted, | ||||||
| 
 | 
 | ||||||
| @ -622,6 +623,8 @@ var Outline = { | |||||||
| 		// 		treating '[_] ... [_]' as italic...
 | 		// 		treating '[_] ... [_]' as italic...
 | ||||||
| 		tasks, | 		tasks, | ||||||
| 		styling, | 		styling, | ||||||
|  | 		// XXX
 | ||||||
|  | 		//attributes,
 | ||||||
| 		tables, | 		tables, | ||||||
| 		symbols, | 		symbols, | ||||||
| 		//syntax,
 | 		//syntax,
 | ||||||
| @ -838,26 +841,28 @@ var Outline = { | |||||||
| 	update: function(node='focused', data){ | 	update: function(node='focused', data){ | ||||||
| 		var node = this.get(node) | 		var node = this.get(node) | ||||||
| 		data ??= this.data(node, false) | 		data ??= this.data(node, false) | ||||||
| 		for(var [attr, value] of Object.entries(data)){ |  | ||||||
| 			if(attr == 'children'){ |  | ||||||
| 				continue } |  | ||||||
| 
 | 
 | ||||||
| 			if(attr == 'text'){ | 		var parsed = {} | ||||||
|  | 		if('text' in data){ | ||||||
| 			var text = node.querySelector('textarea') | 			var text = node.querySelector('textarea') | ||||||
| 			var html = node.querySelector('span') | 			var html = node.querySelector('span') | ||||||
| 			if(this.__code2html__){ | 			if(this.__code2html__){ | ||||||
| 				// NOTE: we are ignoring the .collapsed attr here 
 | 				// NOTE: we are ignoring the .collapsed attr here 
 | ||||||
| 					var parsed = this.__code2html__(data.text) | 				parsed = this.__code2html__(data.text, {...data}) | ||||||
| 				html.innerHTML = parsed.text | 				html.innerHTML = parsed.text | ||||||
| 				// heading...
 | 				// heading...
 | ||||||
| 				node.classList.remove(...this.__styles) | 				node.classList.remove(...this.__styles) | ||||||
| 				parsed.style | 				parsed.style | ||||||
| 					&& node.classList.add(...parsed.style) | 					&& node.classList.add(...parsed.style) | ||||||
|  | 				delete parsed.style | ||||||
| 			} else { | 			} else { | ||||||
| 				html.innerHTML = data.text } | 				html.innerHTML = data.text } | ||||||
| 			text.value = data.text | 			text.value = data.text | ||||||
| 			// XXX this does not seem to work until we click in the textarea...
 | 			// XXX this does not seem to work until we click in the textarea...
 | ||||||
| 				text.autoUpdateSize() | 			text.autoUpdateSize() } | ||||||
|  | 
 | ||||||
|  | 		for(var [attr, value] of Object.entries({...data, ...parsed})){ | ||||||
|  | 			if(attr == 'children' || attr == 'text'){ | ||||||
| 				continue } | 				continue } | ||||||
| 
 | 
 | ||||||
| 			var type = this.__block_attrs__[attr] | 			var type = this.__block_attrs__[attr] | ||||||
| @ -872,8 +877,7 @@ var Outline = { | |||||||
| 						(value ? | 						(value ? | ||||||
| 							node.setAttribute(attr, '') | 							node.setAttribute(attr, '') | ||||||
| 							: node.removeAttribute(attr)) | 							: node.removeAttribute(attr)) | ||||||
| 					: (attr in data  | 					: value != null ? | ||||||
| 							&& value != null) ? |  | ||||||
| 						node.setAttribute(attr, value) | 						node.setAttribute(attr, value) | ||||||
| 					: node.removeAttribute(attr) } } | 					: node.removeAttribute(attr) } } | ||||||
| 		this.__change__() | 		this.__change__() | ||||||
| @ -988,16 +992,13 @@ var Outline = { | |||||||
| 		this.__change__() | 		this.__change__() | ||||||
| 		return this }, | 		return this }, | ||||||
| 
 | 
 | ||||||
| 	// block serialization...
 | 	// block render...
 | ||||||
| 	// XXX need a way to filter input text...
 | 	// XXX need a way to filter input text...
 | ||||||
| 	// 		use-case: hidden attributes...
 | 	// 		use-case: hidden attributes...
 | ||||||
| 	// NOTE: this is auto-populated by .__code2html__(..)
 | 	// NOTE: this is auto-populated by .__code2html__(..)
 | ||||||
| 	__styles: undefined, | 	__styles: undefined, | ||||||
| 	__code2html__: function(code){ | 	__code2html__: function(code, elem={}){ | ||||||
| 		var that = this | 		var that = this | ||||||
| 		var elem = { |  | ||||||
| 			collapsed: false, |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		// only whitespace -> keep element blank...
 | 		// only whitespace -> keep element blank...
 | ||||||
| 		if(code.trim() == ''){ | 		if(code.trim() == ''){ | ||||||
| @ -1013,6 +1014,9 @@ var Outline = { | |||||||
| 			}[stage] | 			}[stage] | ||||||
| 			return that.threadPlugins(meth, text, that, elem) } | 			return that.threadPlugins(meth, text, that, elem) } | ||||||
| 
 | 
 | ||||||
|  | 		elem = this.parseBlockAttrs(code, elem) | ||||||
|  | 		code = elem.text | ||||||
|  | 
 | ||||||
| 		// stage: pre...
 | 		// stage: pre...
 | ||||||
| 		var text = run('pre',  | 		var text = run('pre',  | ||||||
| 			// pre-sanitize...
 | 			// pre-sanitize...
 | ||||||
| @ -1115,6 +1119,54 @@ var Outline = { | |||||||
| 			.flat() | 			.flat() | ||||||
| 			.join('\n') }, | 			.join('\n') }, | ||||||
| 
 | 
 | ||||||
|  | 	//
 | ||||||
|  | 	//	Parse attrs...
 | ||||||
|  | 	//	.parseBlockAttrs(<text>[, <elem>])
 | ||||||
|  | 	//		-> <elem>
 | ||||||
|  | 	//
 | ||||||
|  | 	//	Parse attrs keeping non-system attrs in .text...
 | ||||||
|  | 	//	.parseBlockAttrs(<text>, true[, <elem>])
 | ||||||
|  | 	//		-> <elem>
 | ||||||
|  | 	//
 | ||||||
|  | 	//	Parse attrs keeping all attrs in .text...
 | ||||||
|  | 	//	.parseBlockAttrs(<text>, 'all'[, <elem>])
 | ||||||
|  | 	//		-> <elem>
 | ||||||
|  | 	//
 | ||||||
|  | 	parseBlockAttrs: function(text, keep=false, elem={}){ | ||||||
|  | 		if(typeof(keep) == 'object'){ | ||||||
|  | 			elem = keep | ||||||
|  | 			keep = typeof(elem) == 'boolean' ? | ||||||
|  | 				elem | ||||||
|  | 				: false } | ||||||
|  | 		var system = this.__block_attrs__ | ||||||
|  | 		var clean = text | ||||||
|  | 			// XXX for some reason changing the first group into (?<= .. )
 | ||||||
|  | 			// 		still eats up the whitespace...
 | ||||||
|  | 			// 		...putting the same pattern in a normal group and 
 | ||||||
|  | 			// 		returning it works fine...
 | ||||||
|  | 			//.replace(/(?<=[\n\h]*)(?:(?:\n|^)\s*\w*\s*::\s*[^\n]*\s*)*$/, 
 | ||||||
|  | 			.replace(/([\n\t ]*)(?:(?:\n|^)[\t ]*\w*[\t ]*::[\t ]*[^\n]*[\t ]*)+$/,  | ||||||
|  | 				function(match, ws){ | ||||||
|  | 					var attrs = match | ||||||
|  | 						.trim() | ||||||
|  | 						.split(/(?:[\t ]*::[\t ]*|[\t ]*\n[\t ]*)/g) | ||||||
|  | 					while(attrs.length > 0){ | ||||||
|  | 						var [name, val] = attrs.splice(0, 2) | ||||||
|  | 						elem[name] =  | ||||||
|  | 							val == 'true' ? | ||||||
|  | 				   				true | ||||||
|  | 							: val == 'false' ? | ||||||
|  | 								false | ||||||
|  | 							: val  | ||||||
|  | 						// keep non-system attrs...
 | ||||||
|  | 						if(keep  | ||||||
|  | 								&& !(name in system)){ | ||||||
|  | 							ws += `\n${name}::${val}` } }  | ||||||
|  | 					return ws }) | ||||||
|  | 		elem.text = keep == 'all' ?  | ||||||
|  | 			text  | ||||||
|  | 			: clean | ||||||
|  | 		return elem }, | ||||||
| 	parse: function(text){ | 	parse: function(text){ | ||||||
| 		var that = this | 		var that = this | ||||||
| 		text = text | 		text = text | ||||||
| @ -1134,29 +1186,14 @@ var Outline = { | |||||||
| 				// same level...
 | 				// same level...
 | ||||||
| 				if(sep.length == prev_sep.length){ | 				if(sep.length == prev_sep.length){ | ||||||
| 					var [_, block] = lst.splice(0, 2) | 					var [_, block] = lst.splice(0, 2) | ||||||
| 					var attrs = { | 					var attrs = that.parseBlockAttrs(block) | ||||||
| 						collapsed: false, | 					attrs.text = that.__text2code__(attrs.text | ||||||
| 						focused: false, |  | ||||||
| 					} |  | ||||||
| 					block = block |  | ||||||
| 						// XXX generalize attr processing...
 |  | ||||||
| 						.replace(/\n\s*id::\s*(.*)\s*$/,  |  | ||||||
| 							function(_, value){ |  | ||||||
| 								attrs.id = value |  | ||||||
| 								return '' }) |  | ||||||
| 						.replace(/\n\s*focused::\s*(.*)\s*$/,  |  | ||||||
| 							function(_, value){ |  | ||||||
| 								attrs.focused = value == 'true' |  | ||||||
| 								return '' }) |  | ||||||
| 						.replace(/\n\s*collapsed::\s*(.*)\s*$/,  |  | ||||||
| 							function(_, value){ |  | ||||||
| 								attrs.collapsed = value == 'true' |  | ||||||
| 								return '' }) |  | ||||||
| 					parent.push({  |  | ||||||
| 						text: that.__text2code__(block |  | ||||||
| 						// normalize indent...
 | 						// normalize indent...
 | ||||||
| 						.split(new RegExp('\n'+sep+'  ', 'g')) | 						.split(new RegExp('\n'+sep+'  ', 'g')) | ||||||
| 								.join('\n')), | 						.join('\n')) | ||||||
|  | 					parent.push({  | ||||||
|  | 						collapsed: false, | ||||||
|  | 						focused: false, | ||||||
| 						...attrs, | 						...attrs, | ||||||
| 						children: [], | 						children: [], | ||||||
| 					}) | 					}) | ||||||
| @ -1190,6 +1227,7 @@ var Outline = { | |||||||
| 		children.classList.add('children') | 		children.classList.add('children') | ||||||
| 		children.setAttribute('tabindex', '-1') | 		children.setAttribute('tabindex', '-1') | ||||||
| 		block.append(code, html, children) | 		block.append(code, html, children) | ||||||
|  | 
 | ||||||
| 		this.update(block, data) | 		this.update(block, data) | ||||||
| 
 | 
 | ||||||
| 		// place...
 | 		// place...
 | ||||||
| @ -1561,7 +1599,9 @@ var Outline = { | |||||||
| 				var elem = evt.target | 				var elem = evt.target | ||||||
| 				if(elem.classList.contains('code')){ | 				if(elem.classList.contains('code')){ | ||||||
| 					var block = elem.parentElement | 					var block = elem.parentElement | ||||||
| 					that.update(block, { text: elem.value })  | 					// clean out attrs...
 | ||||||
|  | 					elem.value = that.parseBlockAttrs(elem.value).text | ||||||
|  | 					that.update(block)  | ||||||
| 					// give the browser a chance to update the DOM...
 | 					// give the browser a chance to update the DOM...
 | ||||||
| 					// XXX revise...
 | 					// XXX revise...
 | ||||||
| 					setTimeout(function(){ | 					setTimeout(function(){ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user