refactoring, fixes and tweaks...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2023-10-10 20:34:05 +03:00
parent cb79c43fc6
commit 6d25e096ce
3 changed files with 133 additions and 95 deletions

View File

@ -7,7 +7,8 @@
--outline-padding: 5rem; --outline-padding: 5rem;
--item-indent: 2rem; --item-indent: 2rem;
--item-padding: 0.2em; --item-padding-ratio: 0.2;
--item-padding: calc(1em * var(--item-padding-ratio));
--checkbox-size: 1.5rem; --checkbox-size: 1.5rem;
@ -50,6 +51,8 @@
.editor .outline [tabindex] { .editor .outline [tabindex] {
position: relative; position: relative;
outline: none;
border: none;
} }
.editor .outline [tabindex] [tabindex] { .editor .outline [tabindex] [tabindex] {
margin-left: var(--item-indent); margin-left: var(--item-indent);
@ -74,6 +77,26 @@
outline: none; outline: none;
border: none; border: none;
} }
/* show/hide node's view/code... */
.editor .outline [tabindex]>textarea:focus+span,
.editor .outline [tabindex]>textarea:not(:focus) {
position: absolute;
opacity: 0;
top: 0;
}
/* click through the span text to the textarea */
.editor .outline [tabindex]>span {
position: relative;
pointer-events: none;
}
/* block hover... */
.editor .outline [tabindex]:hover>span {
background: linear-gradient(
90deg,
rgba(0,0,0,0.01) 0%,
rgba(0,0,0,0.01) 80%,
rgba(0,0,0,0.03) 100%);
}
.editor .outline [tabindex]>span:blank { .editor .outline [tabindex]>span:blank {
content: " "; content: " ";
} }
@ -83,16 +106,9 @@
resize: none; resize: none;
} }
/* show/hide node's view/code... */
.editor .outline [tabindex]>textarea:focus+span,
.editor .outline [tabindex]>textarea:not(:focus) {
position: absolute;
opacity: 0;
top: 0;
}
/* focus... */ /* focus... */
.editor .outline [tabindex]:focus { editor .outline [tabindex]:focus {
/*outline: solid 0.2em silver;*/ /*outline: solid 0.2em silver;*/
outline: none; outline: none;
} }
@ -105,71 +121,62 @@
background: rgba(0,0,0,0.05); background: rgba(0,0,0,0.05);
} }
.editor .outline div[collapsed] { .editor .outline div[collapsed] {
border-bottom: solid 1px silver; border-bottom: solid 1px silver;
} }
/* expand/collapse button... */
.editor .outline [tabindex]:after { /* click/tap zones for expand button... */
--size: 0.5rem; .editor .outline [tabindex]>span:before,
.editor .outline [tabindex]>span:after {
--size: 3rem;
content: ""; content: "";
position: absolute; position: absolute;
display: inline-block; display: flex;
top: calc(1em / 2); top: 0;
right: calc(-1rem + -1 * var(--size) - var(--item-padding)); right: calc(-1 * var(--size));
width: 0; width: var(--size);
height: 0; height: 100%;
border: solid calc(var(--size) / 1.2) transparent;
border-top: solid var(--size) black; align-items: top;
opacity: 0; justify-content: center;
}
.editor .outline [tabindex][collapsed]:after { box-sizing: border-box;
border: solid calc(var(--size) / 1.2) transparent; border-left: solid 0.5em transparent;
border-left: solid var(--size) black; border-right: solid 0.5em transparent;
margin-right: -0.25rem;
opacity: 0.1; /* make the text align to the center of the first line... */
} font-size: 1rem;
.editor .outline [tabindex]:hover:after { /* XXX the 1.1 coeficient here is a hack... */
opacity: 0.1; line-height: calc(
} var(--font-size)
/* click/tap zone for expand button... */ * 1.1
.editor .outline [tabindex]:before { + var(--font-size)
content: ""; * var(--item-padding-ratio)
position: absolute; * 2);
display: inline-block;
right: -2rem; pointer-events: auto;
width: 2rem;
height: calc(1em + var(--item-padding) * 2);
background: transparent; background: transparent;
} }
/* /* left indicator */
.editor .outline div[collapsed]:before, .editor .outline [tabindex]>span:before {
.editor .outline div[collapsed]:after { justify-content: right;
--size: 0.3em;
content: "";
display: inline-block;
position: absolute;
width: var(--size);
height: var(--size);
bottom: 0;
right: calc(-1 * var(--size));
margin-bottom: calc(var(--size) / -2 - 0.5px);
rotate: -45deg;
box-sizing: border-box;
color: silver;
border-top: solid 1px silver;
border-left: solid 1px silver;
}
.editor .outline div[collapsed]:before {
right: auto;
left: calc(-1 * var(--size)); left: calc(-1 * var(--size));
rotate: 135deg;
} }
*/ /* right indicator (collapse/expand) */
.editor .outline div[collapsed] [tabindex] { .editor .outline [tabindex]>span:after {
color: silver;
}
.editor .outline [tabindex]:has([tabindex])>span:after {
content: "○";
}
.editor .outline [tabindex][collapsed]>span:after {
content: "●";
}
/* collapse -- hide children... */
.editor .outline [tabindex][collapsed] [tabindex] {
display: none; display: none;
} }
@ -214,6 +221,7 @@
.editor .outline .heading-5>textarea, .editor .outline .heading-5>textarea,
.editor .outline .heading-6>span, .editor .outline .heading-6>span,
.editor .outline .heading-6>textarea { .editor .outline .heading-6>textarea {
margin-top: 1rem;
font-weight: bold; font-weight: bold;
} }
.editor .outline .heading-1>span, .editor .outline .heading-1>span,
@ -227,46 +235,47 @@
.editor .outline .heading-1>span, .editor .outline .heading-1>span,
.editor .outline .heading-1>textarea { .editor .outline .heading-1>textarea {
font-size: 2.5em; --font-size: 2.5em;
} }
.editor .outline .heading-2>span, .editor .outline .heading-2>span,
.editor .outline .heading-2>textarea { .editor .outline .heading-2>textarea {
font-size: 1.9em; --font-size: 1.9em;
} }
.editor .outline .heading-3>span, .editor .outline .heading-3>span,
.editor .outline .heading-3>textarea { .editor .outline .heading-3>textarea {
font-size: 1.5em; --font-size: 1.5em;
} }
.editor .outline .heading-4>span, .editor .outline .heading-4>span,
.editor .outline .heading-4>textarea { .editor .outline .heading-4>textarea {
font-size: 1.3em; --font-size: 1.3em;
} }
.editor .outline .heading-5>span, .editor .outline .heading-5>span,
.editor .outline .heading-5>textarea { .editor .outline .heading-5>textarea {
font-size: 1.1em; --font-size: 1.1em;
} }
.editor .outline .heading-6>span, .editor .outline .heading-6>span,
.editor .outline .heading-6>textarea { .editor .outline .heading-6>textarea {
font-size: 1em; --font-size: 1em;
} }
/* Lists... */ /* Lists... */
/* XXX needs to be in the middle of the first span but with universal size... */ /* XXX needs to be in the middle of the first span but with universal size... */
.editor .outline .list-item:before, .editor .outline .list-item:before,
.editor .outline .list>[tabindex]>span:not(:empty):before { .editor .outline .list>[tabindex]>span:not(:empty):before {
--size: 0.5rem; content: "◼";
color: gray;
display: inline-block;
position: absolute;
content: "";
top: calc(0.6em + var(--item-padding));
left: calc(var(--size) * -2);
width: var(--size);
height: var(--size);
margin-top: calc(var(--size) / -2);
background: silver;
} }
.editor .outline .list>.list>[tabindex]>span:not(:empty):before {
content: "●";
}
.editor .outline .list>.list>.list>[tabindex]>span:not(:empty):before {
content: "○";
}
.editor .outline .list>.list>.list>.list>[tabindex]>span:not(:empty):before {
content: "▪";
}
/* Highlightes... */ /* Highlightes... */
.editor .outline .ASAP { .editor .outline .ASAP {
@ -277,6 +286,7 @@
background: yellow; background: yellow;
} }
/* Comments... */ /* Comments... */
.editor.hide-comments .outline .comment { .editor.hide-comments .outline .comment {
display: none; display: none;
@ -295,8 +305,12 @@
* element -- can's seem to figure out a way to avoid this */ * element -- can's seem to figure out a way to avoid this */
--checkbox-margin: 0em; --checkbox-margin: 0em;
} }
/* align todo checkboxes to indnt (otherwise they are on the indent) */ .editor .outline input {
pointer-events: auto;
}
.editor .outline [tabindex].todo>span { .editor .outline [tabindex].todo>span {
width: calc(100% - var(--checkbox-size));
/* align todo checkboxes to indnt (otherwise they are on the indent) */
margin-left: var(--checkbox-size); margin-left: var(--checkbox-size);
padding-left: calc( padding-left: calc(
var(--item-padding) var(--item-padding)
@ -325,8 +339,26 @@
var(--item-padding) var(--item-padding)
+ var(--checkbox-margin)); + var(--checkbox-margin));
} }
/* correct the left click zone... */
.editor .outline [tabindex].todo>span:before {
margin-left: calc(-1 * var(--checkbox-size));
}
/* XXX need to remove left margin from strictly the first itme in block... */ /* XXX need to remove left margin from strictly the first itme in block... */
.editor .outline [tabindex].check>span>input[type=checkbox] { .editor .outline [tabindex].check>span>input[type=checkbox] {
/*margin-left: 0;*/ /*margin-left: 0;*/
} }
/*********************************************************************/
.editor.show-click-zones .outline [tabindex]>span:before,
.editor.show-click-zones .outline [tabindex]>span:after {
background: rgba(0,0,0,0.03);
}
.editor.show-click-zones .outline [tabindex]:hover>span:before,
.editor.show-click-zones .outline [tabindex]:hover>span:after {
background: rgba(0,0,0,0.1);
}

View File

@ -618,15 +618,16 @@ var Outline = {
var elem = evt.target var elem = evt.target
// expand/collapse // expand/collapse
if(elem.nodeName == 'DIV' if(elem.nodeName == 'SPAN'
&& elem.getAttribute('tabindex')){ && elem.parentElement.getAttribute('tabindex')){
// click: left of elem (outside) // click: left of elem (outside)
if(evt.offsetX < 0){ if(evt.offsetX < 0){
// XXX item menu? // XXX item menu?
console.log('---', elem)
// click: right of elem (outside) // click: right of elem (outside)
} else if(elem.offsetWidth < evt.offsetX){ } else if(elem.offsetWidth < evt.offsetX){
that.toggleCollapse(elem) that.toggleCollapse(elem.parentElement)
// click inside element... // click inside element...
} else { } else {
@ -634,7 +635,8 @@ var Outline = {
} }
// todo: toggle checkbox... // todo: toggle checkbox...
} else if(elem.classList.contains('todo')){ } else if(elem.type == 'checkbox'
&& elem.parentElement.parentElement.classList.contains('todo')){
var node = elem.parentElement.parentElement var node = elem.parentElement.parentElement
var text = node.querySelector('textarea') var text = node.querySelector('textarea')
text.value = text.value =
@ -643,7 +645,8 @@ var Outline = {
: text.value.replace(/^\s*DONE(\s*)/, 'TODO$1') : text.value.replace(/^\s*DONE(\s*)/, 'TODO$1')
// check: toggle checkbox... // check: toggle checkbox...
} else if(elem.classList.contains('check')){ } else if(elem.type == 'checkbox'
&& elem.classList.contains('check')){
var node = elem.parentElement.parentElement var node = elem.parentElement.parentElement
var text = node.querySelector('textarea') var text = node.querySelector('textarea')
var i = [...node.querySelectorAll('.check')].indexOf(elem) var i = [...node.querySelectorAll('.check')].indexOf(elem)

View File

@ -1,6 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8">
<link href="editor.css" rel="stylesheet"/> <link href="editor.css" rel="stylesheet"/>
<style> <style>
@ -35,11 +36,7 @@ var setup = function(){
- Bonsai - Bonsai
- -
- ## ToDo - ## ToDo
- add completion percentage to blocks with todo's nested - shifting nodes up/down
either by default oron '%%' or '[%]' placeholder
...ratio between all nested open checkboxes to checked (???)
- do a better expand/collapse icon on hover
- read-only mode
- editor: bksapce/del at start/end of a block should join it with prev/next - editor: bksapce/del at start/end of a block should join it with prev/next
- editor: pressing enter in text edit mode should split text into two blocks - editor: pressing enter in text edit mode should split text into two blocks
- editor: caret - editor: caret
@ -47,6 +44,11 @@ var setup = function(){
- handle up/down on wrapped blocks - handle up/down on wrapped blocks
_...can't seem to get caret line in a non-hacky way_ _...can't seem to get caret line in a non-hacky way_
- persistent empty first/last node (a button to create a new node) - persistent empty first/last node (a button to create a new node)
- add completion percentage to blocks with todo's nested
either by default oron '%%' or '[%]' placeholder
...ratio between all nested open checkboxes to checked (???)
- read-only mode
- ~do a better expand/collapse icons~
- ~loading from DOM -- fill textarea~ - ~loading from DOM -- fill textarea~
- ~focus management~ - ~focus management~
- ~mouse/touch controls~ - ~mouse/touch controls~
@ -55,13 +57,12 @@ var setup = function(){
- ~shift subtree up/down~ - ~shift subtree up/down~
- ~create node~ - ~create node~
- ~edit node~ - ~edit node~
- shifting nodes up/down
- multiple node selection - multiple node selection
- copy/paste nodes/trees
- undo - undo
- delete node - delete node
- indent/deindent - indent/deindent
- edit node - edit node
- copy/paste nodes/trees
- markdown: tables - markdown: tables
- empty item height is a bit off... - empty item height is a bit off...
- ~serialize~/deserialize - ~serialize~/deserialize
@ -126,6 +127,8 @@ var setup = function(){
<hr> <hr>
<button onclick="editor.dom.classList.toggle('show-click-zones')">show/hide click zones</button>
<pre> <pre>
Controls: Controls: