mirror of
				https://github.com/flynx/pWiki.git
				synced 2025-10-30 18:40:08 +00:00 
			
		
		
		
	click-n-drag selection not works on all elements (expanding elements still need tweaks)...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									2f3255b53d
								
							
						
					
					
						commit
						6674ece80e
					
				| @ -50,7 +50,8 @@ var getCharOffset = function(elem, x, y, c){ | |||||||
| 						&& b.y <= y  | 						&& b.y <= y  | ||||||
| 						&& b.bottom >= y){ | 						&& b.bottom >= y){ | ||||||
| 					// get the closest gap between chars to the click...
 | 					// get the closest gap between chars to the click...
 | ||||||
| 					return Math.abs(b.x - x) <= Math.abs(prev.x - x) ? | 					return (!prev  | ||||||
|  | 							|| Math.abs(b.x - x) <= Math.abs(prev.x - x)) ? | ||||||
| 						c + i | 						c + i | ||||||
| 						: c + i - 1 } } | 						: c + i - 1 } } | ||||||
| 			c += i - 1 | 			c += i - 1 | ||||||
| @ -2053,11 +2054,8 @@ var Outline = { | |||||||
| 		outline.addEventListener('mousemove',  | 		outline.addEventListener('mousemove',  | ||||||
| 			function(evt){ | 			function(evt){ | ||||||
| 				// handle selection in element with text offset by markup...
 | 				// handle selection in element with text offset by markup...
 | ||||||
| 				// XXX should there be a timeout???
 |  | ||||||
| 				if(selecting != null){ | 				if(selecting != null){ | ||||||
| 					// XXX need to get offset under cursor...
 | 					var c = selecting.getTextOffsetAt(evt.clientX, evt.clientY) | ||||||
| 					var c = getTextAreaOffset(selecting, evt.clientX, evt.clientY) |  | ||||||
| 					return |  | ||||||
| 					if(c > start){ | 					if(c > start){ | ||||||
| 						selecting.selectionStart = start | 						selecting.selectionStart = start | ||||||
| 						selecting.selectionEnd = c | 						selecting.selectionEnd = c | ||||||
|  | |||||||
| @ -63,13 +63,10 @@ HTMLTextAreaElement.prototype.autoUpdateSize = function(){ | |||||||
| 		function(evt){ | 		function(evt){ | ||||||
| 			that.updateSize() })  | 			that.updateSize() })  | ||||||
| 	return this } | 	return this } | ||||||
| HTMLTextAreaElement.prototype.getTextGeometry = function(func){ |  | ||||||
| 	var offset = this.selectionStart |  | ||||||
| 	var text = this.value |  | ||||||
| 
 | 
 | ||||||
| 	// get the relevant styles...
 | 
 | ||||||
| 	var style = getComputedStyle(this) | var cloneAsOffscreenSpan = function(elem){ | ||||||
| 	var paddingV = parseFloat(style.paddingTop) + parseFloat(style.paddingBottom) | 	var style = getComputedStyle(elem) | ||||||
| 	var s = {} | 	var s = {} | ||||||
| 	for(var i=0; i < style.length; i++){ | 	for(var i=0; i < style.length; i++){ | ||||||
| 		var k = style[i] | 		var k = style[i] | ||||||
| @ -77,12 +74,6 @@ HTMLTextAreaElement.prototype.getTextGeometry = function(func){ | |||||||
| 				|| k.startsWith('line') | 				|| k.startsWith('line') | ||||||
| 				|| k.startsWith('white-space')){ | 				|| k.startsWith('white-space')){ | ||||||
| 			s[k] = style[k] } } | 			s[k] = style[k] } } | ||||||
| 
 |  | ||||||
| 	var carret = document.createElement('span') |  | ||||||
| 	carret.innerText = '|'  |  | ||||||
| 	carret.style.margin = '0px' |  | ||||||
| 	carret.style.padding = '0px' |  | ||||||
| 
 |  | ||||||
| 	var span = document.createElement('span') | 	var span = document.createElement('span') | ||||||
| 	Object.assign(span.style, { | 	Object.assign(span.style, { | ||||||
| 		...s, | 		...s, | ||||||
| @ -108,13 +99,28 @@ HTMLTextAreaElement.prototype.getTextGeometry = function(func){ | |||||||
| 
 | 
 | ||||||
| 		pointerEvents: 'none', | 		pointerEvents: 'none', | ||||||
| 	}) | 	}) | ||||||
|  | 	return span } | ||||||
|  | 
 | ||||||
|  | HTMLTextAreaElement.prototype.getTextGeometry = function(func){ | ||||||
|  | 	var offset = this.selectionStart | ||||||
|  | 	var text = this.value | ||||||
|  | 
 | ||||||
|  | 	// get the relevant styles...
 | ||||||
|  | 	var style = getComputedStyle(this) | ||||||
|  | 	var paddingV = parseFloat(style.paddingTop) + parseFloat(style.paddingBottom) | ||||||
|  | 
 | ||||||
|  | 	var carret = document.createElement('span') | ||||||
|  | 	carret.innerText = '|'  | ||||||
|  | 	carret.style.margin = '0px' | ||||||
|  | 	carret.style.padding = '0px' | ||||||
|  | 
 | ||||||
|  | 	var span = cloneAsOffscreenSpan(this) | ||||||
| 	span.append( | 	span.append( | ||||||
| 		text.slice(0, offset), | 		text.slice(0, offset), | ||||||
| 		carret, | 		carret, | ||||||
| 		// NOTE: wee need the rest of the text for the carret to be typeset
 | 		// NOTE: wee need the rest of the text for the carret to be typeset
 | ||||||
| 		// 		to the correct line...
 | 		// 		to the correct line...
 | ||||||
| 		text.slice(offset)) | 		text.slice(offset)) | ||||||
| 
 |  | ||||||
| 	document.body.append(span) | 	document.body.append(span) | ||||||
| 
 | 
 | ||||||
| 	var res = { | 	var res = { | ||||||
| @ -135,6 +141,75 @@ HTMLTextAreaElement.prototype.getTextGeometry = function(func){ | |||||||
| 
 | 
 | ||||||
| 	return res } | 	return res } | ||||||
| 
 | 
 | ||||||
|  | HTMLTextAreaElement.prototype.getTextOffsetAt = function(x, y){ | ||||||
|  | 	var that = this | ||||||
|  | 	var text = this.value | ||||||
|  | 
 | ||||||
|  | 	// cleanup cached span...
 | ||||||
|  | 	this.__getTextOffsetAt_timeout | ||||||
|  | 		&& clearTimeout(this.__getTextOffsetAt_timeout) | ||||||
|  | 	this.__getTextOffsetAt_timeout = setTimeout(function(){ | ||||||
|  | 		delete that.__getTextOffsetAt_timeout | ||||||
|  | 		that.__getTextOffsetAt_clone.remove() | ||||||
|  | 		delete that.__getTextOffsetAt_clone }, 50) | ||||||
|  | 
 | ||||||
|  | 	// create/get clone span...
 | ||||||
|  | 	if(this.__getTextOffsetAt_clone == null){ | ||||||
|  | 		var span =  | ||||||
|  | 			this.__getTextOffsetAt_clone =  | ||||||
|  | 				cloneAsOffscreenSpan(this) | ||||||
|  | 		span.append(text) | ||||||
|  | 		document.body.append(span) | ||||||
|  | 	} else { | ||||||
|  | 		var span = this.__getTextOffsetAt_clone } | ||||||
|  | 
 | ||||||
|  | 	var r = document.createRange() | ||||||
|  | 	var t = span.firstChild | ||||||
|  | 
 | ||||||
|  | 	var clone = span.getBoundingClientRect() | ||||||
|  | 	var target = this.getBoundingClientRect() | ||||||
|  | 
 | ||||||
|  | 	var ox = x - target.x | ||||||
|  | 	var oy = y - target.y | ||||||
|  | 
 | ||||||
|  | 	var rect, prev | ||||||
|  | 	var cursor_line | ||||||
|  | 	var col | ||||||
|  | 	for(var i=0; i <= t.length; i++){ | ||||||
|  | 		r.setStart(t, i) | ||||||
|  | 		r.setEnd(t, i) | ||||||
|  | 		prev = rect | ||||||
|  | 		rect = r.getBoundingClientRect() | ||||||
|  | 
 | ||||||
|  | 		// line change...
 | ||||||
|  | 		if(prev && prev.y != rect.y){ | ||||||
|  | 			// went off the cursor line
 | ||||||
|  | 			if(cursor_line  | ||||||
|  | 					// cursor above block
 | ||||||
|  | 					|| oy <= prev.y - clone.y){ | ||||||
|  | 				// end of prev line...
 | ||||||
|  | 				return col  | ||||||
|  | 					?? i - 1 }  | ||||||
|  | 			// reset col
 | ||||||
|  | 			col = undefined } | ||||||
|  | 
 | ||||||
|  | 		// cursor line...
 | ||||||
|  | 		cursor_line =  | ||||||
|  | 			oy >= rect.y - clone.y | ||||||
|  | 				&& oy <= rect.bottom - clone.y | ||||||
|  | 
 | ||||||
|  | 		// cursor col -- set once per line...
 | ||||||
|  | 		if(col == null  | ||||||
|  | 				&& ox <= rect.x - clone.x){ | ||||||
|  | 			col = (!prev  | ||||||
|  | 					|| Math.abs(rect.x - clone.x - x) <= Math.abs(prev.x - clone.x - x)) ? | ||||||
|  | 				i | ||||||
|  | 				: i - 1  | ||||||
|  | 			if(cursor_line){ | ||||||
|  | 				return col } } } | ||||||
|  | 	return col  | ||||||
|  | 		?? i } | ||||||
|  | 
 | ||||||
| // calculate number of lines in text area (both wrapped and actual lines)
 | // calculate number of lines in text area (both wrapped and actual lines)
 | ||||||
| Object.defineProperty(HTMLTextAreaElement.prototype, 'heightLines', { | Object.defineProperty(HTMLTextAreaElement.prototype, 'heightLines', { | ||||||
| 	enumerable: false, | 	enumerable: false, | ||||||
|  | |||||||
| @ -56,8 +56,13 @@ var setup = function(){ | |||||||
|       - side margins are a bit too large (account for toolbat to the right) |       - side margins are a bit too large (account for toolbat to the right) | ||||||
|   - |   - | ||||||
| - ## ToDo: | - ## ToDo: | ||||||
|  |   - DONE selecting expanded code by _click-n-drag_ | ||||||
|  |     - # this is a test | ||||||
|  |       string with | ||||||
|  |       some extra words | ||||||
|  |     - BUG: while selecting if the cursor moves to the left far enough (outside parent?) the first char in current line gets toggled... | ||||||
|   - custom element / web component |   - custom element / web component | ||||||
|     - BUG: selecting by _click-n-drag_ or _double/triple click_ for some reason does not work... |     - BUG: select via click-n-drag and double/triple clicks does not work... | ||||||
|     - BUG/race: the non-value versions of custom elem seem to sometimes get loaded as empty... |     - BUG/race: the non-value versions of custom elem seem to sometimes get loaded as empty... | ||||||
|     - DONE data interface: |     - DONE data interface: | ||||||
| 	  collapsed:: true | 	  collapsed:: true | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user