mirror of
https://github.com/flynx/pWiki.git
synced 2025-12-25 20:31:58 +00:00
Compare commits
No commits in common. "e41a78f5b080c6149212639045a0a4aaa993d305" and "d21d233b07c3199d394aa9f398193cc4e1b947d5" have entirely different histories.
e41a78f5b0
...
d21d233b07
@ -27,7 +27,7 @@
|
|||||||
font-size: var(--font-size);
|
font-size: var(--font-size);
|
||||||
|
|
||||||
/*text-size-adjust: none;*/
|
/*text-size-adjust: none;*/
|
||||||
text-size-adjust: 180%;
|
text-size-adjust: 150%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor {
|
.editor {
|
||||||
|
|||||||
@ -673,6 +673,7 @@ var JSONOutline = {
|
|||||||
at: function(index){},
|
at: function(index){},
|
||||||
|
|
||||||
indent: function(){},
|
indent: function(){},
|
||||||
|
deindent: function(){},
|
||||||
shift: function(){},
|
shift: function(){},
|
||||||
show: function(){},
|
show: function(){},
|
||||||
toggleCollapse: function(){},
|
toggleCollapse: function(){},
|
||||||
@ -691,7 +692,6 @@ var JSONOutline = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// XXX experiment with a concatinative model...
|
// XXX experiment with a concatinative model...
|
||||||
// .get(..) -> Outline (view)
|
// .get(..) -> Outline (view)
|
||||||
var Outline = {
|
var Outline = {
|
||||||
@ -1035,18 +1035,17 @@ var Outline = {
|
|||||||
return node },
|
return node },
|
||||||
|
|
||||||
// edit...
|
// edit...
|
||||||
indent: function(node='focused', indent='in'){
|
indent: function(node='focused', indent=true){
|
||||||
// .indent(<indent>)
|
// .indent(<indent>)
|
||||||
if(node === 'in' || node === 'out'){
|
if(node === true || node === false){
|
||||||
indent = node
|
indent = node
|
||||||
node = 'focused' }
|
node = 'focused' }
|
||||||
var cur = this.get(node)
|
var cur = this.get(node)
|
||||||
if(!cur){
|
if(!cur){
|
||||||
return }
|
return }
|
||||||
var prev = this.path(cur)
|
|
||||||
var siblings = this.get(node, 'siblings')
|
var siblings = this.get(node, 'siblings')
|
||||||
// deindent...
|
// deindent...
|
||||||
if(indent == 'out'){
|
if(!indent){
|
||||||
var parent = this.get(node, 'parent')
|
var parent = this.get(node, 'parent')
|
||||||
if(parent != this.outline){
|
if(parent != this.outline){
|
||||||
var children = siblings
|
var children = siblings
|
||||||
@ -1054,31 +1053,21 @@ var Outline = {
|
|||||||
parent.after(cur)
|
parent.after(cur)
|
||||||
children.length > 0
|
children.length > 0
|
||||||
&& cur.lastChild.append(...children)
|
&& cur.lastChild.append(...children)
|
||||||
this.setUndo(
|
|
||||||
this.path(cur),
|
|
||||||
'indent',
|
|
||||||
['in'],
|
|
||||||
prev)
|
|
||||||
this.__change__() }
|
this.__change__() }
|
||||||
// indent...
|
// indent...
|
||||||
} else {
|
} else {
|
||||||
var parent = siblings[siblings.indexOf(cur) - 1]
|
var parent = siblings[siblings.indexOf(cur) - 1]
|
||||||
if(parent){
|
if(parent){
|
||||||
parent.lastChild.append(cur)
|
parent.lastChild.append(cur)
|
||||||
this.setUndo(
|
|
||||||
this.path(cur),
|
|
||||||
'indent',
|
|
||||||
['out'],
|
|
||||||
prev)
|
|
||||||
this.__change__()} }
|
this.__change__()} }
|
||||||
return cur },
|
return cur },
|
||||||
|
deindent: function(node='focused', indent=false){
|
||||||
|
return this.indent(node, indent) },
|
||||||
shift: function(node='focused', direction){
|
shift: function(node='focused', direction){
|
||||||
if(node == 'up' || node == 'down'){
|
if(node == 'up' || node == 'down'){
|
||||||
direction = node
|
direction = node
|
||||||
node = 'focused' }
|
node = 'focused' }
|
||||||
if(direction == null
|
if(direction == null){
|
||||||
|| (direction !== 'up'
|
|
||||||
&& direction != 'down')){
|
|
||||||
return }
|
return }
|
||||||
node = this.get(node)
|
node = this.get(node)
|
||||||
var focused = node.classList.contains('focused')
|
var focused = node.classList.contains('focused')
|
||||||
@ -1087,51 +1076,29 @@ var Outline = {
|
|||||||
if(direction == 'up'
|
if(direction == 'up'
|
||||||
&& i > 0){
|
&& i > 0){
|
||||||
siblings[i-1].before(node)
|
siblings[i-1].before(node)
|
||||||
} else if(direction == 'down'
|
|
||||||
&& i < siblings.length-1){
|
|
||||||
siblings[i+1].after(node) }
|
|
||||||
focused
|
focused
|
||||||
&& this.focus()
|
&& this.focus()
|
||||||
this.setUndo(
|
} else if(direction == 'down'
|
||||||
this.path(node),
|
&& i < siblings.length-1){
|
||||||
'shift',
|
siblings[i+1].after(node)
|
||||||
[direction == 'up' ?
|
focused
|
||||||
'down'
|
&& this.focus() }
|
||||||
: 'up'])
|
|
||||||
this.__change__()
|
this.__change__()
|
||||||
return this },
|
return this },
|
||||||
// XXX make undo a bit more refined...
|
show: function(node='focused', offset){
|
||||||
remove: function(node='focused'){
|
var node = this.get(...arguments)
|
||||||
var elem = this.get(...arguments)
|
var outline = this.outline
|
||||||
// XXX HACK...
|
var parent = node
|
||||||
var data = this.json()
|
var changes = false
|
||||||
var next
|
do{
|
||||||
if(elem.classList.contains('focused')){
|
parent = parent.parentElement
|
||||||
// XXX need to be able to get the next elem on same level...
|
changes = changes
|
||||||
this.toggleCollapse(elem, true)
|
|| parent.getAttribute('collapsed') == ''
|
||||||
next = elem === this.get(-1) ?
|
parent.removeAttribute('collapsed')
|
||||||
this.get(elem, 'prev')
|
} while(parent !== outline)
|
||||||
: this.get(elem, 'next') }
|
changes
|
||||||
elem?.remove()
|
&& this.__change__()
|
||||||
next
|
return node },
|
||||||
&& this.focus(next)
|
|
||||||
// XXX HACK...
|
|
||||||
this.setUndo(
|
|
||||||
undefined,
|
|
||||||
'load',
|
|
||||||
[data])
|
|
||||||
this.__change__()
|
|
||||||
return this },
|
|
||||||
clear: function(){
|
|
||||||
this.setUndo(
|
|
||||||
undefined,
|
|
||||||
'load',
|
|
||||||
[this.json()])
|
|
||||||
this.outline.innerText = ''
|
|
||||||
this.__change__()
|
|
||||||
return this },
|
|
||||||
|
|
||||||
// expand/collapse...
|
|
||||||
toggleCollapse: function(node='focused', state='next'){
|
toggleCollapse: function(node='focused', state='next'){
|
||||||
var that = this
|
var that = this
|
||||||
if(node == 'all'){
|
if(node == 'all'){
|
||||||
@ -1158,20 +1125,24 @@ var Outline = {
|
|||||||
elem.updateSize() } }
|
elem.updateSize() } }
|
||||||
this.__change__()
|
this.__change__()
|
||||||
return node },
|
return node },
|
||||||
show: function(node='focused', offset){
|
remove: function(node='focused', offset){
|
||||||
var node = this.get(...arguments)
|
var elem = this.get(...arguments)
|
||||||
var outline = this.outline
|
var next
|
||||||
var parent = node
|
if(elem.classList.contains('focused')){
|
||||||
var changes = false
|
// XXX need to be able to get the next elem on same level...
|
||||||
do{
|
this.toggleCollapse(elem, true)
|
||||||
parent = parent.parentElement
|
next = elem === this.get(-1) ?
|
||||||
changes = changes
|
this.get(elem, 'prev')
|
||||||
|| parent.getAttribute('collapsed') == ''
|
: this.get(elem, 'next') }
|
||||||
parent.removeAttribute('collapsed')
|
elem?.remove()
|
||||||
} while(parent !== outline)
|
next
|
||||||
changes
|
&& this.focus(next)
|
||||||
&& this.__change__()
|
this.__change__()
|
||||||
return node },
|
return this },
|
||||||
|
clear: function(){
|
||||||
|
this.outline.innerText = ''
|
||||||
|
this.__change__()
|
||||||
|
return this },
|
||||||
|
|
||||||
// crop...
|
// crop...
|
||||||
crop: function(node='focused'){
|
crop: function(node='focused'){
|
||||||
@ -1179,7 +1150,6 @@ var Outline = {
|
|||||||
for(var block of [...this.outline.querySelectorAll('[cropped]')]){
|
for(var block of [...this.outline.querySelectorAll('[cropped]')]){
|
||||||
block.removeAttribute('cropped') }
|
block.removeAttribute('cropped') }
|
||||||
this.get(...arguments).setAttribute('cropped', '')
|
this.get(...arguments).setAttribute('cropped', '')
|
||||||
// build header path...
|
|
||||||
this.header.innerHTML =
|
this.header.innerHTML =
|
||||||
`<span class="path-item" onclick="editor.uncrop('all')">/</span> `
|
`<span class="path-item" onclick="editor.uncrop('all')">/</span> `
|
||||||
+ this.path(...arguments, 'text')
|
+ this.path(...arguments, 'text')
|
||||||
@ -1188,66 +1158,27 @@ var Outline = {
|
|||||||
return `<span class="path-item" onclick="editor.uncrop(${ length-i })">${s}</span> ` })
|
return `<span class="path-item" onclick="editor.uncrop(${ length-i })">${s}</span> ` })
|
||||||
.join(' / ')
|
.join(' / ')
|
||||||
return this },
|
return this },
|
||||||
uncrop: function(count=1){
|
uncrop: function(mode=1){
|
||||||
var outline = this.outline
|
var outline = this.outline
|
||||||
var top = this.get(0)
|
var top = this.get(0)
|
||||||
for(var block of [...this.outline.querySelectorAll('[cropped]')]){
|
for(var block of [...this.outline.querySelectorAll('[cropped]')]){
|
||||||
block.removeAttribute('cropped') }
|
block.removeAttribute('cropped') }
|
||||||
// crop parent if available...
|
// crop parent if available...
|
||||||
while(count != 'all'
|
while(mode != 'all'
|
||||||
&& count > 0
|
&& mode > 0
|
||||||
&& top !== outline){
|
&& top !== outline){
|
||||||
top = this.get(top, 'parent')
|
top = this.get(top, 'parent')
|
||||||
count-- }
|
mode-- }
|
||||||
if(count == 'all' || top === outline){
|
if(mode == 'all' || top === outline){
|
||||||
this.dom.classList.remove('crop')
|
this.dom.classList.remove('crop')
|
||||||
this.header.innerHTML = ''
|
this.header.innerHTML = ''
|
||||||
} else {
|
} else {
|
||||||
this.crop(top) }
|
this.crop(top) }
|
||||||
return this },
|
return this },
|
||||||
|
|
||||||
// undo...
|
|
||||||
// NOTE: calling .setUndo(..) will drop the redo stack, but this does
|
|
||||||
// not happen when calling a method via .undo(..)/.redo(..) as we
|
|
||||||
// are reassigning the stacks manually.
|
|
||||||
__undo_stack: undefined,
|
|
||||||
__redo_stack: undefined,
|
|
||||||
setUndo: function(path, action, args, next){
|
|
||||||
;(this.__undo_stack ??= []).push([path, action, args, next])
|
|
||||||
this.__redo_stack = undefined
|
|
||||||
return this },
|
|
||||||
clearUndo: function(){
|
|
||||||
this.__undo_stack = undefined
|
|
||||||
this.__redo_stack = undefined
|
|
||||||
return this },
|
|
||||||
__undo: function(from, to){
|
|
||||||
if(from == null
|
|
||||||
|| from.length == 0){
|
|
||||||
return [from, to] }
|
|
||||||
var [path, action, args, next] = from.pop()
|
|
||||||
var l = from.length
|
|
||||||
path != null
|
|
||||||
&& this.focus(path)
|
|
||||||
this[action](...args)
|
|
||||||
next != null ?
|
|
||||||
this.focus(next)
|
|
||||||
: this.focus()
|
|
||||||
if(l < from.length){
|
|
||||||
to ??= []
|
|
||||||
to.push(
|
|
||||||
...from.splice(l, from.length)) }
|
|
||||||
if(from.length == 0){
|
|
||||||
from = undefined }
|
|
||||||
return [from, to] },
|
|
||||||
undo: function(){
|
|
||||||
;[this.__undo_stack, this.__redo_stack] =
|
|
||||||
this.__undo(this.__undo_stack, this.__redo_stack)
|
|
||||||
return this },
|
|
||||||
redo: function(){
|
|
||||||
;[this.__redo_stack] = this.__undo(this.__redo_stack)
|
|
||||||
return this },
|
|
||||||
|
|
||||||
// block render...
|
// block render...
|
||||||
|
// XXX need a way to filter input text...
|
||||||
|
// 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, elem={}){
|
__code2html__: function(code, elem={}){
|
||||||
@ -1523,7 +1454,7 @@ var Outline = {
|
|||||||
.clear()
|
.clear()
|
||||||
.outline
|
.outline
|
||||||
.append(...level(data))
|
.append(...level(data))
|
||||||
/* XXX do we actually need this???
|
//* XXX do we actually need this???
|
||||||
// update sizes of all the textareas (transparent)...
|
// update sizes of all the textareas (transparent)...
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
for(var e of [...that.outline.querySelectorAll('textarea')]){
|
for(var e of [...that.outline.querySelectorAll('textarea')]){
|
||||||
@ -1678,7 +1609,8 @@ var Outline = {
|
|||||||
this.focus(-1) },
|
this.focus(-1) },
|
||||||
PageUp: function(evt){
|
PageUp: function(evt){
|
||||||
var that = this
|
var that = this
|
||||||
if(this.get('edited')){
|
var edited = this.get('edited')
|
||||||
|
if(edited){
|
||||||
return }
|
return }
|
||||||
if(evt.shiftKey
|
if(evt.shiftKey
|
||||||
|| evt.ctrlKey){
|
|| evt.ctrlKey){
|
||||||
@ -1692,7 +1624,8 @@ var Outline = {
|
|||||||
viewport[0], 'prev') } },
|
viewport[0], 'prev') } },
|
||||||
PageDown: function(evt){
|
PageDown: function(evt){
|
||||||
var that = this
|
var that = this
|
||||||
if(this.get('edited')){
|
var edited = this.get('edited')
|
||||||
|
if(edited){
|
||||||
return }
|
return }
|
||||||
if(evt.shiftKey
|
if(evt.shiftKey
|
||||||
|| evt.ctrlKey){
|
|| evt.ctrlKey){
|
||||||
@ -1710,9 +1643,7 @@ var Outline = {
|
|||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
var edited = this.get('edited')
|
var edited = this.get('edited')
|
||||||
var node = this.show(
|
var node = this.show(
|
||||||
this.indent(evt.shiftKey ?
|
this.indent(!evt.shiftKey))
|
||||||
'out'
|
|
||||||
: 'in'))
|
|
||||||
// keep focus in node...
|
// keep focus in node...
|
||||||
;(edited ?
|
;(edited ?
|
||||||
edited
|
edited
|
||||||
@ -1755,29 +1686,12 @@ var Outline = {
|
|||||||
if(this.get('edited')){
|
if(this.get('edited')){
|
||||||
this.focus()
|
this.focus()
|
||||||
} else {
|
} else {
|
||||||
this.uncrop() } },
|
evt.shiftKey ?
|
||||||
s_Escape: function(evt){
|
this.uncrop('all')
|
||||||
if(this.get('edited')){
|
: this.uncrop() } },
|
||||||
this.focus()
|
|
||||||
} else {
|
|
||||||
this.uncrop('all') } },
|
|
||||||
c: function(evt){
|
c: function(evt){
|
||||||
if(!this.get('edited')){
|
if(!this.get('edited')){
|
||||||
this.crop() } },
|
this.crop() } },
|
||||||
c_z: function(evt){
|
|
||||||
if(!this.get('edited')){
|
|
||||||
evt.preventDefault()
|
|
||||||
this.undo() } },
|
|
||||||
c_s_z: function(evt){
|
|
||||||
if(!this.get('edited')){
|
|
||||||
evt.preventDefault()
|
|
||||||
this.redo() } },
|
|
||||||
U: function(evt){
|
|
||||||
if(!this.get('edited')){
|
|
||||||
this.redo() } },
|
|
||||||
u: function(evt){
|
|
||||||
if(!this.get('edited')){
|
|
||||||
this.undo() } },
|
|
||||||
|
|
||||||
Delete: function(evt){
|
Delete: function(evt){
|
||||||
var edited = this.get('edited')
|
var edited = this.get('edited')
|
||||||
@ -1817,10 +1731,11 @@ var Outline = {
|
|||||||
this.remove(edited)
|
this.remove(edited)
|
||||||
return } },
|
return } },
|
||||||
|
|
||||||
c_d: function(evt){
|
d: function(evt){
|
||||||
// toggle done...
|
// toggle done...
|
||||||
|
if(evt.ctrlKey){
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
tasks.toggleDone(this) },
|
tasks.toggleDone(this) } },
|
||||||
|
|
||||||
// toggle checkbox...
|
// toggle checkbox...
|
||||||
' ': function(evt){
|
' ': function(evt){
|
||||||
@ -1920,26 +1835,8 @@ var Outline = {
|
|||||||
if(that.runPlugins('__keydown__', evt, that, evt.target) !== true){
|
if(that.runPlugins('__keydown__', evt, that, evt.target) !== true){
|
||||||
return }
|
return }
|
||||||
// handle keyboard...
|
// handle keyboard...
|
||||||
var keys = []
|
evt.key in that.keyboard
|
||||||
evt.ctrlKey
|
&& that.keyboard[evt.key].call(that, evt) })
|
||||||
&& keys.push('c_' + evt.key)
|
|
||||||
evt.ctrlKey && evt.altKey
|
|
||||||
&& keys.push('c_a_' + evt.key)
|
|
||||||
evt.ctrlKey && evt.shiftKey
|
|
||||||
&& keys.push('c_s_' + evt.key)
|
|
||||||
evt.altKey && evt.ctrlKey && evt.shiftKey
|
|
||||||
&& keys.push('c_a_s_' + evt.key)
|
|
||||||
evt.altKey
|
|
||||||
&& keys.push('a_' + evt.key)
|
|
||||||
evt.altKey && evt.shiftKey
|
|
||||||
&& keys.push('a_s_' + evt.key)
|
|
||||||
evt.shiftKey
|
|
||||||
&& keys.push('s_' + evt.key)
|
|
||||||
keys.push(evt.key)
|
|
||||||
for(var k of keys){
|
|
||||||
if(k in that.keyboard){
|
|
||||||
that.keyboard[k].call(that, evt)
|
|
||||||
break } } })
|
|
||||||
// update code block...
|
// update code block...
|
||||||
outline.addEventListener('keyup',
|
outline.addEventListener('keyup',
|
||||||
function(evt){
|
function(evt){
|
||||||
@ -1969,7 +1866,6 @@ var Outline = {
|
|||||||
that.get('focused')?.classList?.add('focused') }
|
that.get('focused')?.classList?.add('focused') }
|
||||||
// textarea...
|
// textarea...
|
||||||
if(elem.classList.contains('code')){
|
if(elem.classList.contains('code')){
|
||||||
elem.dataset.original = elem.value
|
|
||||||
elem.updateSize() }
|
elem.updateSize() }
|
||||||
|
|
||||||
// XXX do we need this???
|
// XXX do we need this???
|
||||||
@ -1979,20 +1875,10 @@ var Outline = {
|
|||||||
var elem = evt.target
|
var elem = evt.target
|
||||||
// update code...
|
// update code...
|
||||||
if(elem.classList.contains('code')){
|
if(elem.classList.contains('code')){
|
||||||
var block = that.get(elem)
|
var block = elem.parentElement
|
||||||
// clean out attrs...
|
// clean out attrs...
|
||||||
elem.value = that.parseBlockAttrs(elem.value).text
|
elem.value = that.parseBlockAttrs(elem.value).text
|
||||||
that.update(block)
|
that.update(block)
|
||||||
// undo...
|
|
||||||
if(elem.value != elem.dataset.original){
|
|
||||||
that.setUndo(
|
|
||||||
that.path(elem),
|
|
||||||
'update',
|
|
||||||
[that.path(elem), {
|
|
||||||
...that.data(elem),
|
|
||||||
text: elem.dataset.original,
|
|
||||||
}])
|
|
||||||
delete elem.dataset.original }
|
|
||||||
// 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(){
|
||||||
@ -2031,7 +1917,6 @@ var Outline = {
|
|||||||
.replace(/</g, '<')
|
.replace(/</g, '<')
|
||||||
.replace(/>/g, '>'))
|
.replace(/>/g, '>'))
|
||||||
console.log(`Parse: ${Date.now() - t}ms`) }
|
console.log(`Parse: ${Date.now() - t}ms`) }
|
||||||
this.clearUndo()
|
|
||||||
|
|
||||||
this.runPlugins('__setup__', this)
|
this.runPlugins('__setup__', this)
|
||||||
|
|
||||||
|
|||||||
@ -48,18 +48,12 @@ var setup = function(){
|
|||||||
-
|
-
|
||||||
- ## Bugs:
|
- ## Bugs:
|
||||||
focused:: true
|
focused:: true
|
||||||
- BUG: crop root indent is off...
|
|
||||||
- a
|
|
||||||
- b
|
|
||||||
- c
|
|
||||||
- crop this
|
|
||||||
- BUG: mobile browsers behave quite chaotically ignoring parts of the styling...
|
- BUG: mobile browsers behave quite chaotically ignoring parts of the styling...
|
||||||
-
|
-
|
||||||
- ## ToDo:
|
- ## ToDo:
|
||||||
- undo: checkboxes and DONE??
|
- undo
|
||||||
_...this should be triggered by text change -- move current implementation to .__editedcode__()??..._
|
collapsed:: true
|
||||||
- copy/paste nodes/trees
|
- edit stack (position, action, ...)
|
||||||
- FEATURE: read-only mode
|
|
||||||
- auto-shift done blocks to the end of siblings... (option?)
|
- auto-shift done blocks to the end of siblings... (option?)
|
||||||
- ...or should this be `sort:: done` -- i.e. sort children by done status??
|
- ...or should this be `sort:: done` -- i.e. sort children by done status??
|
||||||
- codeblock as a block
|
- codeblock as a block
|
||||||
@ -70,6 +64,8 @@ var setup = function(){
|
|||||||
code
|
code
|
||||||
```
|
```
|
||||||
- _bullet should be either in the middle of the block or at the first line of code (preferred)..._
|
- _bullet should be either in the middle of the block or at the first line of code (preferred)..._
|
||||||
|
- copy/paste nodes/trees
|
||||||
|
- FEATURE: read-only mode
|
||||||
- export html
|
- export html
|
||||||
- embed css
|
- embed css
|
||||||
- cleanup html
|
- cleanup html
|
||||||
@ -94,6 +90,10 @@ var setup = function(){
|
|||||||
- each child node will copy the template and allow editing of only fields
|
- each child node will copy the template and allow editing of only fields
|
||||||
- not clear how to handle template changes...
|
- not clear how to handle template changes...
|
||||||
- JSON API
|
- JSON API
|
||||||
|
- `.path(..)`
|
||||||
|
- `.get(..)`
|
||||||
|
- `.at(..)`
|
||||||
|
- ...
|
||||||
- cli
|
- cli
|
||||||
- Q: do we use \\t for indent? (option???)
|
- Q: do we use \\t for indent? (option???)
|
||||||
- Q: persistent empty first/last node (a button to create a new node)?
|
- Q: persistent empty first/last node (a button to create a new node)?
|
||||||
@ -111,7 +111,6 @@ var setup = function(){
|
|||||||
- empty item height is a bit off...
|
- empty item height is a bit off...
|
||||||
- search?
|
- search?
|
||||||
- _...not sure if search should be internal or external yet..._
|
- _...not sure if search should be internal or external yet..._
|
||||||
- DONE undo
|
|
||||||
- DONE crop: make path clickable
|
- DONE crop: make path clickable
|
||||||
- DONE Q: crop: should we control crop via "crop-in"/"crop-out" instead of crop/uncrop??
|
- DONE Q: crop: should we control crop via "crop-in"/"crop-out" instead of crop/uncrop??
|
||||||
- _crop-in/crop-out seems more natural..._
|
- _crop-in/crop-out seems more natural..._
|
||||||
@ -216,13 +215,9 @@ var setup = function(){
|
|||||||
| c-right | next checkbox |
|
| c-right | next checkbox |
|
||||||
| space | toggle current checkbox |
|
| space | toggle current checkbox |
|
||||||
| c-d | toggle current element DONE |
|
| c-d | toggle current element DONE |
|
||||||
| c-z | normal: undo |
|
| enter | normal mode: edit node |
|
||||||
| c-s-z | normal: redo |
|
| | edit mode: create node below |
|
||||||
| c | normal: crop current node |
|
| esc | exit edit mode |
|
||||||
| enter | normal: edit node |
|
|
||||||
| | edit: create node below |
|
|
||||||
| esc | crop: exit crop |
|
|
||||||
| | edit: exit edit mode |
|
|
||||||
- ### Formatting
|
- ### Formatting
|
||||||
- The formatting mostly adheres to the markdown spec with a few minor differences
|
- The formatting mostly adheres to the markdown spec with a few minor differences
|
||||||
-
|
-
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user