From 0ed930231d95615d77c6c8ee1a3fa4682891c336 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Sun, 5 Nov 2023 03:15:13 +0300 Subject: [PATCH] bugfix + refactoring... Signed-off-by: Alex A. Naanou --- experiments/outline-editor/editor.js | 59 ++++++++++++++------------- experiments/outline-editor/generic.js | 1 - experiments/outline-editor/index.html | 7 ---- 3 files changed, 31 insertions(+), 36 deletions(-) diff --git a/experiments/outline-editor/editor.js b/experiments/outline-editor/editor.js index 1b33bb3..e677c22 100755 --- a/experiments/outline-editor/editor.js +++ b/experiments/outline-editor/editor.js @@ -29,52 +29,55 @@ function clickPoint(x,y){ // box corresponds the to desired coordinates. This accounts for nested // elements. // -// XXX with multi-line text when clicking outside the text to the left/right -// need to select the appropriate line... // XXX it would be a better idea to do a binary search instead of a liner // pass... // ...though b-search will get us to the target, we stll need to count... -// XXX HACK -- is there a better way to do this??? -var getCharOffset = function(elem, x, y, c){ - c = c ?? 0 +var getCharOffset = function(elem, x, y, options={}){ var r = document.createRange() for(var e of [...elem.childNodes]){ + var c = options.c ?? 0 // text node... if(e instanceof Text){ - var prev, b + var prev, rect, cursor_line, col for(var i=0; i <= e.length; i++){ r.setStart(e, i) r.setEnd(e, i) - prev = b - b = r.getBoundingClientRect() - // found target... - if(b.x >= x - && b.y <= y - && b.bottom >= y){ - // get the closest gap between chars to the click... - return (!prev - || Math.abs(b.x - x) <= Math.abs(prev.x - x)) ? + prev = rect + ?? options.prev + rect = r.getBoundingClientRect() + // line change... + // NOTE: this is almost identical to .getTextOffsetAt(..) see + // that for more docs... + if(prev + && prev.y != rect.y){ + if(cursor_line){ + return col + ?? c + i - 2 } + col = undefined } + cursor_line = + rect.y <= y + && rect.bottom >= y + if(col == null + && rect.x >= x){ + col = (c + i == 0 + || Math.abs(rect.x - x) <= Math.abs(prev.x - x)) ? c + i - : c + i - 1 } } - c += i - 1 + : c + i - 1 + if(cursor_line){ + return col } } } + options.c += c - 1 // html node... } else { - var res = getCharOffset(e, x, y, c) - if(!(res instanceof Array)){ - return res } - ;[c, res] = res } } + options.prev = prev + options = getCharOffset(e, x, y, options) + if(typeof(options) != 'object'){ + return options } } } // no result was found... return arguments.length > 3 ? - [c, null] + options : null } -var getTextAreaOffset = function(elem, x, y){ - return elem.getTextGeometry(function(res, elem){ - // XXX this will not work as it needs correct placement of elem under the cursor... - return getCharOffset(elem, x, y) }) } - - // Get offset in markdown relative to the resulting text... // // v <----- position diff --git a/experiments/outline-editor/generic.js b/experiments/outline-editor/generic.js index 9a64b9c..54ac7ad 100755 --- a/experiments/outline-editor/generic.js +++ b/experiments/outline-editor/generic.js @@ -198,7 +198,6 @@ HTMLTextAreaElement.prototype.getTextOffsetAt = function(x, y){ // cursor col -- set once per line... if(col == null && ox <= rect.x - clone.x){ - // XXX not sure about this test... col = (ox > 0 || i == 0) ? i diff --git a/experiments/outline-editor/index.html b/experiments/outline-editor/index.html index 35a0886..078dc07 100755 --- a/experiments/outline-editor/index.html +++ b/experiments/outline-editor/index.html @@ -48,13 +48,6 @@ var setup = function(){ - - ## Bugs: focused:: true - - BUG? clicking a block right of the lines places the cursor at end of last line -- should be the end of the cursor line (see: `.getTextOffsetAt(..)`) - - example click right of the text: - - example text - example text - example text - example text - - _appears that the initial caret placement is correct, but then it gets moved to the end of the block..._ - BUG: mobile browsers behave quite chaotically ignoring parts of the styling... - FF: - zooming on edited field