even more refactoring + test editing is now mostly POLS-complete! =)

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2023-10-15 00:03:22 +03:00
parent 7b755b413c
commit ef666e91d0
2 changed files with 107 additions and 33 deletions

View File

@ -644,6 +644,27 @@ var Outline = {
return cur }, return cur },
deindent: function(node='focused', indent=false){ deindent: function(node='focused', indent=false){
return this.indent(node, indent) }, return this.indent(node, indent) },
shift: function(node='focused', direction){
if(node == 'up' || node == 'down'){
direction = node
node = 'focused' }
if(direction == null){
return }
node = this.get(node)
var focused = node.classList.contains('focused')
var siblings = this.get(node, 'siblings')
var i = siblings.indexOf(node)
if(direction == 'up'
&& i > 0){
siblings[i-1].before(node)
focused
&& this.focus()
} else if(direction == 'down'
&& i < siblings.length-1){
siblings[i+1].after(node)
focused
&& this.focus() }
return this },
show: function(node='focused', offset){ show: function(node='focused', offset){
var node = this.get(...arguments) var node = this.get(...arguments)
var outline = this.outline var outline = this.outline
@ -750,14 +771,7 @@ var Outline = {
elem.text = run('post', text) elem.text = run('post', text)
return elem }, return elem },
// XXX essentially here we need to remove service stuff like some // output format...
// attributes (collapsed, id, ...)...
// XXX also need to quote leading '- ' in block text here...
// e.g.
// - block
// some text
// - text in the above block ('-' needs to be quoted)
// - next block
__code2text__: function(code){ __code2text__: function(code){
return code return code
.replace(/(\n\s*)-/g, '$1\\-') }, .replace(/(\n\s*)-/g, '$1\\-') },
@ -999,6 +1013,21 @@ var Outline = {
this.toggleCollapse(false) this.toggleCollapse(false)
: this.focus('next') } }, : this.focus('next') } },
PageUp: function(evt){
var edited = this.get('edited')
if(!edited
&& (evt.shiftKey
|| evt.ctrlKey)){
evt.preventDefault()
this.shift('up') } },
PageDown: function(evt){
var edited = this.get('edited')
if(!edited
&& (evt.shiftKey
|| evt.ctrlKey)){
evt.preventDefault()
this.shift('down') } },
// indent... // indent...
Tab: function(evt){ Tab: function(evt){
evt.preventDefault() evt.preventDefault()
@ -1012,37 +1041,78 @@ var Outline = {
// edit mode... // edit mode...
O: function(evt){ O: function(evt){
if(evt.target.nodeName != 'TEXTAREA'){ if(!this.get('edited')){
evt.preventDefault() evt.preventDefault()
this.Block('before') this.edit(
?.querySelector('textarea') this.Block('before')) } },
?.focus() } },
o: function(evt){ o: function(evt){
if(evt.target.nodeName != 'TEXTAREA'){ if(!this.get('edited')){
evt.preventDefault() evt.preventDefault()
this.Block('next') this.edit(
?.querySelector('textarea') this.Block('next')) } },
?.focus() } },
Enter: function(evt){ Enter: function(evt){
if(evt.ctrlKey
|| evt.shiftKey){ var edited = this.get('edited')
return } // edit -> split text...
evt.preventDefault() if(edited){
evt.target.nodeName == 'TEXTAREA' ? if(evt.ctrlKey
|| evt.shiftKey){
return }
evt.preventDefault()
var a = edited.selectionStart
var b = edited.selectionEnd
var prev = edited.value.slice(0, a)
var next = edited.value.slice(b)
edited.value = prev
this.Block('next') this.Block('next')
?.querySelector('textarea') edited = this.edit('next')
?.focus() edited.value = next
: this.get() edited.selectionStart = 0
?.querySelector('textarea') edited.selectionEnd = 0
?.focus() }, return }
// view -> edit...
evt.preventDefault()
this.edit() },
Escape: function(evt){ Escape: function(evt){
this.outline.querySelector('textarea:focus') this.focus() },
?.parentElement
?.focus() },
Delete: function(evt){ Delete: function(evt){
if(this.get('edited')){ var edited = this.get('edited')
if(edited){
if(edited.selectionStart == edited.value.length){
var next = this.get('edited', 'next')
// can't reclaim nested children...
if(this.get(next, 'children').length > 0){
return }
// do not delete past the top element...
if(this.get(0).querySelector('.code') === next){
return }
evt.preventDefault()
var i = edited.value.length
edited.value += next.value
edited.selectionStart = i
edited.selectionEnd = i
this.remove(next) }
return } return }
this.remove() }, this.remove() },
Backspace: function(evt){
var edited = this.get('edited')
if(edited
&& edited.selectionStart == 0
// can't reclaim nested children...
&& this.get(edited, 'children').length == 0){
var prev = this.get('edited', 'prev')
// do not delete past the bottom element...
if(this.get(-1).querySelector('.code') === prev){
return }
evt.preventDefault()
var i = prev.value.length
prev.value += edited.value
this.edit(prev)
prev.selectionStart = i
prev.selectionEnd = i
this.remove(edited)
return } },
// select... // select...
// XXX add: // XXX add:

View File

@ -47,14 +47,12 @@ var setup = function(){
- BUG: last node seems to get trash tags added to it's end... - BUG: last node seems to get trash tags added to it's end...
- -
- ## ToDo: - ## ToDo:
- ASAP: editor: backsapce/del at start/end of a block should join it with prev/next
- ASAP: editor: pressing enter in text edit mode should split text into two blocks
- ASAP: editor: shifting nodes up/down
- ASAP: scroll into view is bad... - ASAP: scroll into view is bad...
- ASAP: need to reach checkboxes via keyboard - ASAP: need to reach checkboxes via keyboard
- FEATURE: read-only mode - FEATURE: read-only mode
- FEATURE: `collapse-children:: true` block option -- when loading collapse all immediate children - 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(..)` - FF: figure out a way to draw expand/collapse bullets without the use of CSS' `:has(..)`
- show list bullet if node is empty but edited... (???)
- Code blocks and bullets: - Code blocks and bullets:
- ``` - ```
code code
@ -69,6 +67,7 @@ var setup = function(){
- delete node - delete node
- indent/deindent - indent/deindent
- edit node - edit node
- auto-shift done blocks to the end of siblings... (option?)
- FEATURE? block templates... - FEATURE? block templates...
collapsed:: true collapsed:: true
- something like: `TPL: [_] <editable/> -- <editable/>` - something like: `TPL: [_] <editable/> -- <editable/>`
@ -97,6 +96,9 @@ var setup = function(){
block text block text
- NOTE: this is only a problem if making list-items manually -- disable??? - NOTE: this is only a problem if making list-items manually -- disable???
- empty item height is a bit off... - empty item height is a bit off...
- DONE editor: backsapce/del at start/end of a block should join it with prev/next
- DONE editor: pressing enter in text edit mode should split text into two blocks
- DONE editor: shifting nodes up/down
- DONE Q: can we edit code in a code block directly? (a-la Logseq) - DONE Q: can we edit code in a code block directly? (a-la Logseq)
- DONE "percentage complete" in parent blocks with todo's nested - DONE "percentage complete" in parent blocks with todo's nested
- DONE `.editor .outline:empty` view and behavior... - DONE `.editor .outline:empty` view and behavior...
@ -261,6 +263,8 @@ Controls:
right - focus first child node right - focus first child node
tab - indent node tab - indent node
s-tab - deindent node s-tab - deindent node
s-pgup - shift node up
s-pgdown - shift node down
s-left - collapse node s-left - collapse node
s-right - expand node s-right - expand node
enter - normal mode: edit node enter - normal mode: edit node