implemented css-based crop...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2023-10-25 15:04:41 +03:00
parent a3e5e4e326
commit 2bd9781951
3 changed files with 72 additions and 15 deletions

View File

@ -69,20 +69,26 @@
.editor .outline:empty:hover:after { .editor .outline:empty:hover:after {
} }
/* XXX header */ /* header */
.editor .header { .editor .header {
} }
.editor .header:empty { .editor .header:empty {
display: none; display: none;
} }
/* XXX needs more work... *//* .editor .header .path-item {
.editor .header span { color: gray;
display: inline; cursor: pointer;
/* XXX needs more work... */
max-width: 10rem; max-width: 10rem;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden;
} }
*/ .editor .header .path-item:hover {
text-decoration: underline;
}
.editor .header .path-item:first-child {
padding-left: 3em;
margin-left: -2em;
}
.editor .outline .block { .editor .outline .block {
@ -255,6 +261,23 @@ editor .outline .block:focus {
} }
/* crop... */
.editor.crop .outline .block:not([cropped]) {
padding: 0;
border: none;
background: none;
}
.editor.crop .outline .block:not([cropped])>.text {
display: none;
}
.editor.crop .outline .block[cropped] {
margin-left: 0;
}
.editor.crop .outline .block[cropped] .text {
display: block;
}
.editor .toolbar { .editor .toolbar {
display: inline-block; display: inline-block;
position: absolute; position: absolute;

View File

@ -895,18 +895,18 @@ var Outline = {
: offset == 'visible' ? : offset == 'visible' ?
[...node.querySelectorAll('.block')] [...node.querySelectorAll('.block')]
.filter(function(e){ .filter(function(e){
return e.offsetParent != null }) return e.querySelector('.view').offsetParent != null })
: offset == 'viewport' ? : offset == 'viewport' ?
[...node.querySelectorAll('.block')] [...node.querySelectorAll('.block')]
.filter(function(e){ .filter(function(e){
return e.offsetParent != null return e.querySelector('.view').offsetParent != null
&& e.querySelector('.code').visibleInViewport() }) && e.querySelector('.code').visibleInViewport() })
: offset == 'editable' ? : offset == 'editable' ?
[...node.querySelectorAll('.block>.code')] [...node.querySelectorAll('.block>.code')]
: offset == 'selected' ? : offset == 'selected' ?
[...node.querySelectorAll('.block[selected]')] [...node.querySelectorAll('.block[selected]')]
.filter(function(e){ .filter(function(e){
return e.offsetParent != null }) return e.querySelector('.view').offsetParent != null })
: offset == 'children' ? : offset == 'children' ?
children(node) children(node)
: offset == 'siblings' ? : offset == 'siblings' ?
@ -1145,8 +1145,10 @@ var Outline = {
return this }, return this },
// crop... // crop...
// XXX shoud we control crops as "crop in" / "crop out" instead of crom/uncrop??? /*/ XXX structural crop...
// XXX add crop-level/path indicator... // XXX this should not change what is written to code...
// ...make crops in a separate instance???
// ......CSS?
__crop_stack: undefined, __crop_stack: undefined,
crop: function(node='focused'){ crop: function(node='focused'){
var that = this var that = this
@ -1172,9 +1174,8 @@ var Outline = {
// XXX make this linkable... // XXX make this linkable...
this.header.innerHTML = '/ ' + stack[2].join(' / ') this.header.innerHTML = '/ ' + stack[2].join(' / ')
this.dom.classList.add('crop') //this.dom.classList.add('crop')
return this }, return this },
// XXX use JSON API...
uncrop: function(mode=undefined){ uncrop: function(mode=undefined){
if(this.__crop_stack == null){ if(this.__crop_stack == null){
return this } return this }
@ -1205,11 +1206,43 @@ var Outline = {
} else { } else {
this.load(state) this.load(state)
this.dom.classList.remove('crop') //this.dom.classList.remove('crop')
this.__crop_stack = undefined this.__crop_stack = undefined
this.header.innerHTML = '' } this.header.innerHTML = '' }
return this }, return this },
/*/// XXX CSS-based crop...
crop: function(node='focused'){
this.dom.classList.add('crop')
for(var block of [...this.outline.querySelectorAll('[cropped]')]){
block.removeAttribute('cropped') }
this.get(...arguments).setAttribute('cropped', '')
this.header.innerHTML =
`<span class="path-item" onclick="editor.uncrop('all')">/</span> `
+ this.path(...arguments, 'text')
.slice(0, -1)
.map(function(s, i, {length}){
return `<span class="path-item" onclick="editor.uncrop(${ length-i })">${s}</span> ` })
.join(' / ')
return this },
uncrop: function(mode=1){
var outline = this.outline
var top = this.get(0)
for(var block of [...this.outline.querySelectorAll('[cropped]')]){
block.removeAttribute('cropped') }
// crop parent if available...
while(mode != 'all'
&& mode > 0
&& top !== outline){
top = this.get(top, 'parent')
mode-- }
if(mode == 'all' || top === outline){
this.dom.classList.remove('crop')
this.header.innerHTML = ''
} else {
this.crop(top) }
return this },
//*/
// block render... // block render...
// XXX need a way to filter input text... // XXX need a way to filter input text...

View File

@ -51,7 +51,6 @@ 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:
- Q: crop: should we control crop via "crop-in"/"crop-out" instead of crop/uncrop??
- crop: make path clickable - crop: make path clickable
- undo - undo
collapsed:: true collapsed:: true
@ -113,6 +112,8 @@ 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 Q: crop: should we control crop via "crop-in"/"crop-out" instead of crop/uncrop??
- _crop-in/crop-out seems more natural..._
- DONE crop: show crop path (and depth) - 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: