added crop api...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2023-10-23 04:26:00 +03:00
parent 6c484194ae
commit 04637c64a2
2 changed files with 101 additions and 11 deletions

View File

@ -596,6 +596,33 @@ var escaping = {
//---------------------------------------------------------------------
var JSONOutline = {
json: undefined,
path: function(){},
get: function(){},
at: function(){},
focus: function(){},
indent: function(){},
deindent: function(){},
shift: function(){},
show: function(){},
toggleCollapse: function(){},
remove: function(){},
clear: function(){},
crom: function(){},
uncrop: function(){},
parseBlockAttrs: function(){},
parse: function(){},
data: function(){},
load: function(){},
text: function(){},
}
// XXX experiment with a concatinative model...
// .get(..) -> Outline (view)
var Outline = {
@ -656,6 +683,15 @@ var Outline = {
return this.dom.querySelector('.toolbar') },
path: function(node='focused'){
var outline = this.outline
var path = []
var node = this.get(node)
while(node != outline){
path.unshift(this.get(node, 'siblings').indexOf(node))
node = this.get(node, 'parent') }
return path },
//
// .get([<offset>])
// .get('focused'[, <offset>])
@ -726,6 +762,11 @@ var Outline = {
typeof(node) == 'number' ?
[this.get('visible').at(node),
edited]
: node instanceof Array ?
[node
.reduce(function(res, i){
return that.get(res, 'children')[i] }, outline),
edited]
: (node == 'outline' || node == 'root') ?
[outline, edited]
: node == 'focused' ?
@ -798,7 +839,9 @@ var Outline = {
return this.get(nodes).at(index) },
focus: function(node='focused', offset){
var elem = this.get(...arguments)
elem?.focus()
?? this.get(0)
elem
&& elem.focus()
return elem },
edit: function(node='focused', offset){
var elem = this.get(...arguments)
@ -992,6 +1035,32 @@ var Outline = {
this.__change__()
return this },
// crop...
__crop_stack: undefined,
crop: function(node='focused'){
var stack = this.__crop_stack ??= []
stack.push([this.json(), this.path()])
this.load(this.data())
.focus()
return this },
// XXX use JSON API...
uncrop: function(){
if(this.__crop_stack == null){
return this}
var [state, path] = this.__crop_stack.pop()
if(this.__crop_stack.length == 0){
this.__crop_stack = undefined }
// update state...
path
.slice(0, -1)
.reduce(function(res, i){
return res[i].children }, state)
.splice(path.at(-1), 1, ...this.json())
this.load(state)
.focus()
return this },
// block render...
// XXX need a way to filter input text...
// use-case: hidden attributes...
@ -1251,7 +1320,9 @@ var Outline = {
var that = this
data = typeof(data) == 'string' ?
this.parse(data)
: data
: data instanceof Array ?
data
: [data]
// generate dom...
var level = function(lst){
return lst
@ -1437,7 +1508,13 @@ var Outline = {
evt.preventDefault()
this.edit() },
Escape: function(evt){
this.focus() },
if(this.get('edited')){
this.focus()
} else {
this.uncrop() } },
c: function(evt){
if(!this.get('edited')){
this.crop() } },
Delete: function(evt){
var edited = this.get('edited')
@ -1655,6 +1732,10 @@ var Outline = {
this.runPlugins('__setup__', this)
// autofocus...
if(this.dom.getAttribute('autofocus') != null){
this.focus() }
return this },
}

View File

@ -31,7 +31,7 @@ var setup = function(){
</script>
</head>
<body onload="setup()">
<div class="editor">
<div class="editor" autofocus>
<!-- code -->
<textarea class="code">
- # Outline editor prototype
@ -44,17 +44,21 @@ var setup = function(){
- // Seems that I unintentionally implemented quite a chunk of the markdown spec ;)
-
- ## Bugs:
focused:: true
- BUG: editor: FF seems to update the style every other key press -- should be live...
- BUG: scrolling into view needs tuning...
- BUG: mobile browsers behave quite chaotically ignoring parts of the styling...
-
- ## ToDo:
- pgup/pgdown/~home/end~ buttons
- identify a block (index, id, ...)
- FEATURE: "crop" -- view block tree separately...
- identify a block
- DONE index (flat)
- DONE path (index)
- id
- _the id attr is done, but we still need to get the node via id_
- focus
- `<editor>.autofocus`
- `focused:: true` attr (`.text(..)`/`.json(..)`/`.load(..)`)
- DONE `<editor>.autofocus`
- DONE `focused:: true` attr (`.text(..)`/`.json(..)`/`.load(..)`)
- focusing editor -> focus focused block
- undo
collapsed:: true
@ -90,7 +94,11 @@ var setup = function(){
- `<editable/>` -- field marker
- each child node will copy the template and allow editing of only fields
- not clear how to handle template changes...
- might be a good idea to split the editor into a generic and dom versions...
- JSON API
- `.path(..)`
- `.get(..)`
- `.at(..)`
- ...
- cli
- Q: do we use \\t for indent? (option???)
- Q: persistent empty first/last node (a button to create a new node)?
@ -106,6 +114,7 @@ var setup = function(){
block text
- NOTE: this is only a problem if making list-items manually -- disable???
- empty item height is a bit off...
- DONE FEATURE: "crop" -- view block tree separately...
- DONE unify attr parsing
collapsed:: true
- _now duplicated in `.parse(..)` and `.__code2html__(..)`_