mirror of
https://github.com/flynx/pWiki.git
synced 2025-10-29 10:00:08 +00:00
working on crop/uncrop changes + notes...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
0e4344a711
commit
b292a7ff23
@ -597,12 +597,80 @@ var escaping = {
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
var JSONOutline = {
|
var JSONOutline = {
|
||||||
|
// Format:
|
||||||
|
// <json> ::= [
|
||||||
|
// {
|
||||||
|
// text: <text>,
|
||||||
|
// children: <json>,
|
||||||
|
// ...
|
||||||
|
// },
|
||||||
|
// ...
|
||||||
|
// ]
|
||||||
json: undefined,
|
json: undefined,
|
||||||
|
|
||||||
|
// format:
|
||||||
|
// {
|
||||||
|
// <id>: <node>,
|
||||||
|
// ...
|
||||||
|
// }
|
||||||
|
__id_index: undefined,
|
||||||
|
|
||||||
|
// format:
|
||||||
|
// Map([
|
||||||
|
// [<node>, <path>],
|
||||||
|
// ...
|
||||||
|
// ])
|
||||||
|
__nodes: undefined,
|
||||||
|
|
||||||
|
__path: undefined,
|
||||||
|
current: undefined,
|
||||||
|
|
||||||
|
__iter: function*(node, path, mode){
|
||||||
|
if(typeof(path) == 'string'){
|
||||||
|
mode = path
|
||||||
|
path = null }
|
||||||
|
path ??= []
|
||||||
|
yield [path, node]
|
||||||
|
if(mode == 'visible'
|
||||||
|
&& node.collapsed){
|
||||||
|
return }
|
||||||
|
var i = 0
|
||||||
|
for(var e of node.children ?? []){
|
||||||
|
yield* this.__iter(e, [...path, i++], mode) } },
|
||||||
|
// XXX revise...
|
||||||
|
nodes: function*(node, mode){
|
||||||
|
var i = 0
|
||||||
|
// all nodes..
|
||||||
|
if(node == null || node == 'all' || node == 'visible'){
|
||||||
|
for(var e of this.json){
|
||||||
|
yield* this.__iter(e, [i++], node) }
|
||||||
|
// single node...
|
||||||
|
} else {
|
||||||
|
var args = [...arguments]
|
||||||
|
// XXX revise...
|
||||||
|
if(['all', 'visible'].includes(args.at(-1))){
|
||||||
|
mode = args.pop() }
|
||||||
|
yield* this.__iter(
|
||||||
|
this.get(...args),
|
||||||
|
mode) } },
|
||||||
|
[Symbol.iterator]: function*(mode='all'){
|
||||||
|
for(var node of this.json){
|
||||||
|
for(var [_, n] of this.__iter(node, mode)){
|
||||||
|
yield n } } },
|
||||||
|
iter: function*(node, mode){
|
||||||
|
for(var [_, n] of this.nodes(...arguments)){
|
||||||
|
yield n } },
|
||||||
|
|
||||||
|
// XXX
|
||||||
path: function(){},
|
path: function(){},
|
||||||
get: function(){},
|
get: function(node, offset){
|
||||||
at: function(){},
|
},
|
||||||
focus: function(){},
|
focus: function(node, offset){
|
||||||
|
return this.get(
|
||||||
|
this.__path = this.path(...arguments)) },
|
||||||
|
|
||||||
|
index: function(){},
|
||||||
|
at: function(index){},
|
||||||
|
|
||||||
indent: function(){},
|
indent: function(){},
|
||||||
deindent: function(){},
|
deindent: function(){},
|
||||||
@ -612,7 +680,7 @@ var JSONOutline = {
|
|||||||
remove: function(){},
|
remove: function(){},
|
||||||
clear: function(){},
|
clear: function(){},
|
||||||
|
|
||||||
crom: function(){},
|
crop: function(){},
|
||||||
uncrop: function(){},
|
uncrop: function(){},
|
||||||
|
|
||||||
parseBlockAttrs: function(){},
|
parseBlockAttrs: function(){},
|
||||||
@ -623,6 +691,7 @@ var JSONOutline = {
|
|||||||
text: function(){},
|
text: function(){},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// XXX experiment with a concatinative model...
|
// XXX experiment with a concatinative model...
|
||||||
// .get(..) -> Outline (view)
|
// .get(..) -> Outline (view)
|
||||||
var Outline = {
|
var Outline = {
|
||||||
@ -686,7 +755,7 @@ var Outline = {
|
|||||||
|
|
||||||
|
|
||||||
path: function(node='focused', mode='index'){
|
path: function(node='focused', mode='index'){
|
||||||
if(['index', 'text', 'node'].includes(node)){
|
if(['index', 'text', 'node', 'data'].includes(node)){
|
||||||
mode = node
|
mode = node
|
||||||
node = 'focused' }
|
node = 'focused' }
|
||||||
var outline = this.outline
|
var outline = this.outline
|
||||||
@ -698,6 +767,8 @@ var Outline = {
|
|||||||
this.get(node, 'siblings').indexOf(node)
|
this.get(node, 'siblings').indexOf(node)
|
||||||
: mode == 'text' ?
|
: mode == 'text' ?
|
||||||
node.querySelector('.view').innerText
|
node.querySelector('.view').innerText
|
||||||
|
: mode == 'data' ?
|
||||||
|
this.data(node)
|
||||||
: node)
|
: node)
|
||||||
node = this.get(node, 'parent') }
|
node = this.get(node, 'parent') }
|
||||||
return path },
|
return path },
|
||||||
@ -1074,43 +1145,54 @@ var Outline = {
|
|||||||
return this },
|
return this },
|
||||||
|
|
||||||
// crop...
|
// crop...
|
||||||
|
// XXX shoud we control crops as "crop in" / "crop out" instead of crom/uncrop???
|
||||||
// XXX add crop-level/path indicator...
|
// XXX add crop-level/path indicator...
|
||||||
__crop_stack: undefined,
|
__crop_stack: undefined,
|
||||||
crop: function(node='focused'){
|
crop: function(node='focused'){
|
||||||
var that = this
|
var that = this
|
||||||
var stack = this.__crop_stack ??= []
|
|
||||||
var path = this.path()
|
|
||||||
// XXX make this linkable...
|
|
||||||
var header = '/ '
|
|
||||||
+ this.path(path.slice(0,-1), 'text')
|
|
||||||
.map(function(text, i){
|
|
||||||
return `<span>${text.split(/\n/)[0]}</span>` })
|
|
||||||
.join(' / ')
|
|
||||||
|
|
||||||
stack.push([this.json(), path])
|
// XXX make this relative to this.__crop_root
|
||||||
|
var stack =
|
||||||
|
this.__crop_stack = [
|
||||||
|
...this.__crop_stack ?? [],
|
||||||
|
[
|
||||||
|
this.json(),
|
||||||
|
this.path(),
|
||||||
|
this.path('text').slice(0, -1),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
this.load(this.data())
|
this.load(this.data())
|
||||||
|
|
||||||
this.header.innerHTML = header
|
// XXX make this linkable...
|
||||||
|
this.header.innerHTML = '/ '
|
||||||
|
+ stack
|
||||||
|
.map(function([s,p,t]){
|
||||||
|
return t})
|
||||||
|
.flat()
|
||||||
|
.join(' / ')
|
||||||
this.dom.classList.add('crop')
|
this.dom.classList.add('crop')
|
||||||
return this },
|
return this },
|
||||||
// XXX use JSON API...
|
// XXX use JSON API...
|
||||||
// XXX add depth argument + 'all'
|
// XXX add depth argument + 'all'
|
||||||
uncrop: function(){
|
uncrop: function(mode=1){
|
||||||
if(this.__crop_stack == null){
|
if(this.__crop_stack == null){
|
||||||
return this}
|
return this}
|
||||||
var [state, path] = this.__crop_stack.pop()
|
|
||||||
if(this.__crop_stack.length == 0){
|
|
||||||
this.__crop_stack = undefined
|
|
||||||
this.header.innerHTML = ''
|
|
||||||
this.dom.classList.remove('crop') }
|
|
||||||
// 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)
|
// XXX replace relevant node in this.__crop_root with state...
|
||||||
|
// XXX should this be done on the way down or on the way up???
|
||||||
|
/* XXX
|
||||||
|
var state = this.json()
|
||||||
|
while(this.__crop_stack.length > 0){
|
||||||
|
}
|
||||||
|
//*/
|
||||||
|
|
||||||
|
this.load(this.__crop_stack[0][0])
|
||||||
|
this.header.innerHTML = ''
|
||||||
|
|
||||||
|
this.__crop_stack = undefined
|
||||||
|
this.dom.classList.remove('crop')
|
||||||
|
|
||||||
return this },
|
return this },
|
||||||
|
|
||||||
@ -1622,7 +1704,9 @@ var Outline = {
|
|||||||
if(this.get('edited')){
|
if(this.get('edited')){
|
||||||
this.focus()
|
this.focus()
|
||||||
} else {
|
} else {
|
||||||
this.uncrop() } },
|
evt.shiftKey ?
|
||||||
|
this.uncrop('all')
|
||||||
|
: this.uncrop() } },
|
||||||
c: function(evt){
|
c: function(evt){
|
||||||
if(!this.get('edited')){
|
if(!this.get('edited')){
|
||||||
this.crop() } },
|
this.crop() } },
|
||||||
|
|||||||
@ -51,7 +51,8 @@ var setup = function(){
|
|||||||
- BUG: mobile browsers behave quite chaotically ignoring parts of the styling...
|
- BUG: mobile browsers behave quite chaotically ignoring parts of the styling...
|
||||||
-
|
-
|
||||||
- ## ToDo:
|
- ## ToDo:
|
||||||
- crop: show crop path (and depth)
|
- Q: crop: should we control crop via "crop-in"/"crop-out" instead of crop/uncrop??
|
||||||
|
- crop: make path clickable
|
||||||
- undo
|
- undo
|
||||||
collapsed:: true
|
collapsed:: true
|
||||||
- edit stack (position, action, ...)
|
- edit stack (position, action, ...)
|
||||||
@ -111,6 +112,8 @@ var setup = function(){
|
|||||||
- 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...
|
||||||
- search?
|
- search?
|
||||||
|
- _...not sure if search should be internal or external yet..._
|
||||||
|
- DONE crop: show crop path (and depth)
|
||||||
- DONE over-travel pause -- when going fast over start/end stop...
|
- DONE over-travel pause -- when going fast over start/end stop...
|
||||||
- DONE focus:
|
- DONE focus:
|
||||||
collapsed:: true
|
collapsed:: true
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user