diff --git a/experiments/outline-editor/editor.js b/experiments/outline-editor/editor.js index 29d97ee..9dc3124 100755 --- a/experiments/outline-editor/editor.js +++ b/experiments/outline-editor/editor.js @@ -38,6 +38,41 @@ function clickPoint(x,y){ //*/ +var getCharOffset = function(elem, x, y, c){ + c = c ?? 0 + var r = document.createRange() + for(var e of [...elem.childNodes]){ + if(e instanceof Text){ + for(var i=0; i < e.length; i++){ + r.setStart(e, i) + r.setEnd(e, i) + var b = r.getBoundingClientRect() + // found target... + if(b.x >= x + && b.y <= y + && b.bottom >= y){ + return c + i } } + c += i + + } else { + var res = getCharOffset(e, x, y, c) + if(!(res instanceof Array)){ + return res } + ;[c, res] = res } } + return arguments.length > 3 ? + [c, null] + : null } +var getMarkdownOffset = function(markdown, text, i){ + i = i ?? text.length + var m = 0 + // walk both strings skipping/counting non-matching stuff... + for(var n=0; n < i; n++, m++){ + var c = text[n] + while(c != markdown[m]){ + m++ } } + return m - n } + + //--------------------------------------------------------------------- // Plugins... @@ -205,6 +240,7 @@ var tasks = { /^(.*)\s*(?.view .completion')]){ this.updateStatus(editor, e) } return this }, - + // Checkboxes... getCheckbox: function(editor, elem, offset=0){ elem = elem ?? editor.get() @@ -318,7 +354,7 @@ var tasks = { return node }, prevCheckbox: function(editor, node='focused', offset=-1){ return this.nextCheckbox(editor, node, offset) }, - + // DONE... toggleDone: function(editor, elem){ var node = editor.get(elem) if(node == null){ @@ -1261,6 +1297,21 @@ var Outline = { for(var elem of [...outline.querySelectorAll('textarea')]){ elem.autoUpdateSize() } // click... + // XXX revise... + // XXX tap support... + outline.addEventListener('mousedown', + function(evt){ + var elem = evt.target + // correct offset in editor... + if(elem.classList.contains('code') && document.activeElement !== elem){ + var view = that.get(elem).querySelector('.view') + var c = getCharOffset(view, evt.clientX, evt.clientY) + if(c != null){ + evt.preventDefault() + var m = getMarkdownOffset(elem.value, view.innerText, c) + elem.focus() + elem.selectionStart = c + m + elem.selectionEnd = c + m } } }) outline.addEventListener('click', function(evt){ var elem = evt.target @@ -1294,7 +1345,7 @@ var Outline = { } } // edit of focus... - // NOTE: this is usefull if element text is hidden but the + // NOTE: this is useful if element text is hidden but the // frame is still visible... if(elem.classList.contains('block')){ elem.querySelector('.code').focus() } diff --git a/experiments/outline-editor/index.html b/experiments/outline-editor/index.html index fb535b4..05753fe 100755 --- a/experiments/outline-editor/index.html +++ b/experiments/outline-editor/index.html @@ -44,9 +44,12 @@ var setup = function(){ - // Seems that I unintentionally implemented quite a chunk of the markdown spec ;) - - ## Bugs: + - BUG: editor: FF seems to update the style every other key press -- should be live... - BUG: last node seems to get trash tags added to it's end... - - ## ToDo: + - DONE click to select/edit node must retain click position in text... + - _...needs more testing..._ - ASAP: scroll into view is bad... - ASAP: mobile browsers behave quite chaotically ignoring parts of the styling... - FEATURE: read-only mode @@ -56,6 +59,7 @@ var setup = function(){ - generate ideomatic html (???) - FEATURE: `collapse-children:: true` block option -- when loading collapse all immediate children - FF: figure out a way to draw expand/collapse bullets without the use of CSS' `:has(..)` + - table inline editing a-la code editing -- click cell and edit directly... - a way to make a block monospace (???) - codeblock as a block _...if only whitespace before/after clear it and style whole block..._ @@ -131,8 +135,8 @@ var setup = function(){ - ## Refactoring: - Plugin architecture - DONE basic structure - - plugin handler sequencing (see: `.setup(..)`) - - plugin handler canceling + - plugin handler sequencing (see: `.setup(..)`) + - DONE plugin handler canceling (see: `.runPlugins(..)`) - DONE Item parser (`.__code2html__(..)`) - DONE split out - DONE define a way to extend/stack parsers @@ -151,7 +155,7 @@ var setup = function(){ - `.get() -> ` - Docs - -- ## TEST +- ## Docs - ### Controls - ASAP: these need updating... - | Key | Action |