Compare commits

..

No commits in common. "22a73a07e8eb9f9598ae6a8e7403987538fec88c" and "475078b55c0317c3b7c1e18cc80d0029abda3dbb" have entirely different histories.

3 changed files with 106 additions and 165 deletions

View File

@ -1,8 +1,5 @@
/**********************************************************************
* /*********************************************************************/
*
*
**********************************************************************/
:root { :root {
--font-size: 5mm; --font-size: 5mm;
@ -13,7 +10,6 @@
--item-padding-ratio: 0.2; --item-padding-ratio: 0.2;
--checkbox-size: 1.5rem; --checkbox-size: 1.5rem;
--checkbox-margin: 0.5em;
--button-size: 2em; --button-size: 2em;
@ -93,6 +89,7 @@
.editor .outline [tabindex]>textarea:not(:focus) { .editor .outline [tabindex]>textarea:not(:focus) {
position: absolute; position: absolute;
opacity: 0; opacity: 0;
top: 0;
} }
/* click through the span text to the textarea */ /* click through the span text to the textarea */
.editor .outline [tabindex]>span { .editor .outline [tabindex]>span {
@ -220,8 +217,8 @@ editor .outline [tabindex]:focus {
} }
/*-------------------------------------------------------------------*/
/********************************************************** Styles ***/ /* Styles */
/* Headings... */ /* Headings... */
.editor .outline .heading-1>span, .editor .outline .heading-1>span,
@ -277,16 +274,12 @@ editor .outline [tabindex]:focus {
/* Quote... */ /* Quote... */
.editor .outline .quote>span, .editor .outline .quote>span,
.editor .outline .quote>textarea { .editor .outline .quote>textarea {
--indent: 1rem;
--margin: 0.7rem;
--item-padding-ratio: 0.7; --item-padding-ratio: 0.7;
--indent: 1rem;
/* XXX for some reason if this is not set here it will not see the new --item-padding-ratio */ /* XXX for some reason if this is not set here it will not see the new --item-padding-ratio */
--item-padding: calc(1rem * var(--item-padding-ratio)); --item-padding: calc(1rem * var(--item-padding-ratio));
margin-top: var(--margin);
margin-bottom: var(--margin);
padding: var(--item-padding) 1.5rem; padding: var(--item-padding) 1.5rem;
color: rgba(0,0,0,0.8); color: rgba(0,0,0,0.8);
@ -314,38 +307,9 @@ editor .outline [tabindex]:focus {
content: "▪"; content: "▪";
} }
/* Notes... */
.editor .outline .NOTE {
--margin: 1rem;
--padding-h: 2rem;
--padding-v: 1.2em;
margin: var(--margin) 0;
padding: var(--padding-v) var(--padding-h);
border: solid 2px silver;
background: rgba(0,0,0,0.05);
}
/* XXX this prevents it from being accesible via click/tap... */
.editor .outline .NOTE>span:empty {
display: none;
}
.editor .outline .NOTE>span:empty ~ [tabindex] {
/* XXX calculate this... */
margin-left: 1em;
}
.editor .outline .NOTE>span:before {
content: "" !important;
}
/* correct the right click zone... */
/* XXX need to account for nesting... (???) */
.editor .outline [tabindex].NOTE>span:after,
.editor .outline [tabindex].NOTE [tabindex]>span:after {
margin-right: calc(-1 * var(--padding-h));
}
/* Highlightes... */ /* Highlightes... */
.editor .outline .highlight { .editor .outline .ASAP {
font-weight: bold; font-weight: bold;
background: yellow; background: yellow;
} }
@ -364,14 +328,21 @@ editor .outline [tabindex]:focus {
/* Checkboxes... */ /* Checkboxes... */
:root {
/* NOTE: this must have a unit... */
/* XXX move this to the config when fixed... */
/* XXX setting this to >0em will add margins to both sides of
* the inline checkbox even if it is the first thing in the
* element -- can's seem to figure out a way to avoid this */
--checkbox-margin: 0em;
}
.editor .outline [tabindex].todo>span { .editor .outline [tabindex].todo>span {
width: calc( width: calc(100% - var(--checkbox-size));
100% /* align todo checkboxes to indnt (otherwise they are on the indent) */
- var(--checkbox-size) margin-left: var(--checkbox-size);
- var(--checkbox-margin)); padding-left: calc(
margin-left: calc( var(--item-padding)
var(--checkbox-size) + var(--checkbox-margin) * 2);
+ var(--checkbox-margin));
} }
.editor .outline [tabindex].check>span>input[type=checkbox], .editor .outline [tabindex].check>span>input[type=checkbox],
.editor .outline [tabindex].todo>span>input[type=checkbox] { .editor .outline [tabindex].todo>span>input[type=checkbox] {
@ -389,16 +360,21 @@ editor .outline [tabindex]:focus {
} }
.editor .outline [tabindex].todo>span>input[type=checkbox]:first-child { .editor .outline [tabindex].todo>span>input[type=checkbox]:first-child {
margin-left: calc( margin-left: calc(
-1 * var(--checkbox-size) var(--checkbox-size) * -1
- var(--checkbox-margin)); - var(--item-padding)
- var(--checkbox-margin) * 2);
margin-right: calc(
var(--item-padding)
+ var(--checkbox-margin));
} }
/* correct the left click zone... */ /* correct the left click zone... */
.editor .outline [tabindex].todo>span:before { .editor .outline [tabindex].todo>span:before {
margin-left: calc( margin-left: calc(-1 * var(--checkbox-size));
-1 * var(--checkbox-size) }
- var(--checkbox-margin)); /* XXX need to remove left margin from strictly the first itme in block... */
.editor .outline [tabindex].check>span>input[type=checkbox] {
/*margin-left: 0;*/
} }
/* code... */ /* code... */
.editor .outline [tabindex]>span code { .editor .outline [tabindex]>span code {
@ -409,8 +385,7 @@ editor .outline [tabindex]:focus {
} }
/*********************************************************************/
/********************************************************* Testing ***/
.editor.show-click-zones .outline [tabindex]>span:before, .editor.show-click-zones .outline [tabindex]>span:before,
.editor.show-click-zones .outline [tabindex]>span:after { .editor.show-click-zones .outline [tabindex]>span:after {
@ -423,5 +398,3 @@ editor .outline [tabindex]:focus {
} }
/*********************************************************************/

View File

@ -38,7 +38,6 @@ var Outline = {
right_key_expands: true, right_key_expands: true,
code_update_interval: 5000, code_update_interval: 5000,
tab_size: 4, tab_size: 4,
carot_jump_edge_then_block: false,
get code(){ get code(){
@ -175,16 +174,9 @@ var Outline = {
|| node }, || node },
at: function(index, nodes='visible'){ at: function(index, nodes='visible'){
return this.get(nodes).at(index) }, return this.get(nodes).at(index) },
focus: function(node='focused', offset){
var elem = this.get(...arguments) focus: function(node='focused', offset){},
elem?.focus() edit: function(node='focused', offset){},
return elem },
edit: function(node='focused', offset){
var elem = this.get(...arguments)
if(elem.nodeName != 'TEXTAREA'){
elem = elem.querySelector('textarea') }
elem?.focus()
return elem },
update: function(node='focused', data){ update: function(node='focused', data){
var node = this.get(node) var node = this.get(node)
@ -330,38 +322,29 @@ var Outline = {
//.replace(/^(?<!\\)[-\*]\s+(.*)$/m, style('list-item')) //.replace(/^(?<!\\)[-\*]\s+(.*)$/m, style('list-item'))
.replace(/^\s*(.*)(?<!\\):\s*$/m, style('list')) .replace(/^\s*(.*)(?<!\\):\s*$/m, style('list'))
// style: misc... // style: misc...
.replace(/^\s*(?<!\\)>\s+(.*)$/m, style('quote')) .replace(/^(?<!\\)>\s+(.*)$/m, style('quote'))
.replace(/^\s*(?<!\\)((\/\/|;)\s+.*)$/m, style('comment')) .replace(/^(?<!\\)((\/\/|;)\s+.*)$/m, style('comment'))
.replace(/^\s*(?<!\\)NOTE:?\s*(.*)$/m, style('NOTE')) .replace(/^(?<!\\)XXX\s+(.*)$/m, style('XXX'))
.replace(/^\s*(?<!\\)XXX\s+(.*)$/m, style('XXX'))
.replace(/^(.*)\s*(?<!\\)XXX$/m, style('XXX')) .replace(/^(.*)\s*(?<!\\)XXX$/m, style('XXX'))
.replace(/(\s*)(?<!\\)(ASAP|BUG|FIX|HACK|STUB|WARNING|CAUTION)(\s*)/gm, .replace(/(\s*)(?<!\\)ASAP(\s*)/m, '$1<span class="ASAP">ASAP</span>$2')
'$1<span class="highlight $2">$2</span>$3')
// elements... // elements...
.replace(/(\n|^)(?<!\\)---*\h*(\n|$)/m, '$1<hr>') .replace(/(\n|^)(?<!\\)---*\h*(\n|$)/m, '$1<hr>')
// ToDo... // ToDo...
// NOTE: these are separate as we need to align block text .replace(/^(?<!\\)TODO\s+/m,
// to leading chekbox...
.replace(/^\s*(?<!\\)\[[_ ]\]\s*/m,
style('todo', '<input type="checkbox">')) style('todo', '<input type="checkbox">'))
.replace(/^\s*(?<!\\)\[[Xx]\]\s*/m, .replace(/^(?<!\\)DONE\s+/m,
style('todo', '<input type="checkbox" checked>')) style('todo', '<input type="checkbox" checked>'))
// inline checkboxes... // checkboxes...
.replace(/\s*(?<!\\)\[[_ ]\]\s*/gm, .replace(/(?<!\\)\[_\]/gm,
style('check', '<input type="checkbox">')) style('check', '<input class="check" type="checkbox">'))
.replace(/\s*(?<!\\)\[[Xx]\]\s*/gm, .replace(/(?<!\\)\[[X]\]/gm,
style('check', '<input type="checkbox" checked>')) style('check', '<input class="check" type="checkbox" checked>'))
// basic styling... // basic styling...
.replace(/(?<!\\)\*(?=[^\s*])(([^*]|\\\*)*[^\s*])(?<!\\)\*/gm, '<b>$1</b>') .replace(/(?<!\\)\*(?=[^\s*])(([^*]|\\\*)*[^\s*])(?<!\\)\*/gm, '<b>$1</b>')
.replace(/(?<!\\)~(?=[^\s~])(([^~]|\\~)*[^\s~])(?<!\\)~/gm, '<s>$1</s>') .replace(/(?<!\\)~(?=[^\s~])(([^~]|\\~)*[^\s~])(?<!\\)~/gm, '<s>$1</s>')
.replace(/(?<!\\)_(?=[^\s_])(([^_]|\\_)*[^\s_])(?<!\\)_/gm, '<i>$1</i>') .replace(/(?<!\\)_(?=[^\s_])(([^_]|\\_)*[^\s_])(?<!\\)_/gm, '<i>$1</i>')
.replace(/(?<!\\)`(?=[^\s_])(([^`]|\\`)*[^\s_])(?<!\\)`/gm, '<code>$1</code>') .replace(/(?<!\\)`(?=[^\s_])(([^`]|\\`)*[^\s_])(?<!\\)`/gm, '<code>$1</code>')
// characters...
// XXX use ligatures for these???
.replace(/(?<!\\)---(?!-)/gm, '&mdash;')
.replace(/(?<!\\)--(?!-)/gm, '&ndash;')
// quoting... // quoting...
// NOTE: this must be last...
.replace(/(?<!\\)\\(.)/gm, '$1') .replace(/(?<!\\)\\(.)/gm, '$1')
return elem }, return elem },
// XXX essentially here we need to remove service stuff like some // XXX essentially here we need to remove service stuff like some
@ -432,7 +415,7 @@ var Outline = {
var tab = ' '.repeat(this.tab_size || 8) var tab = ' '.repeat(this.tab_size || 8)
var level = function(lst, prev_sep=undefined, parent=[]){ var level = function(lst, prev_sep=undefined, parent=[]){
while(lst.length > 0){ while(lst.length > 0){
sep = lst[0].replace(/\t/gm, tab) sep = lst[0].replace(/\t/g, tab)
// deindent... // deindent...
if(prev_sep != null if(prev_sep != null
&& sep.length < prev_sep.length){ && sep.length < prev_sep.length){
@ -522,43 +505,27 @@ var Outline = {
// XXX add scrollIntoView(..) to nav... // XXX add scrollIntoView(..) to nav...
keyboard: { keyboard: {
// vertical navigation... // vertical navigation...
// XXX this is a bit hacky but it works -- the caret blinks at // XXX wrapped line navigation is broken...
// start/end of block before switching to next, would be
// nice po prevent this...
ArrowUp: function(evt){ ArrowUp: function(evt){
var that = this var state = 'focused'
var edited = this.get('edited') var edited = this.get('edited')
if(edited){ if(edited){
var c = edited.selectionStart if(!atLine(edited, 0)){
var jump = function(){ return }
if(edited.selectionStart == 0){ /*/
// needed to remember the position... //*/
edited.selectionStart = c state = 'edited' }
edited.selectionEnd = c
that.focus('edited', -1) } }
this.carot_jump_edge_then_block ?
jump()
: setTimeout(jump, 0)
} else {
evt.preventDefault() evt.preventDefault()
this.focus('focused', -1) } }, this.get(state, -1)?.focus() },
ArrowDown: function(evt){ ArrowDown: function(evt, offset=1){
var that = this var state = 'focused'
var edited = this.get('edited') var edited = this.get('edited')
if(edited){ if(edited){
var c = edited.selectionStart if(!atLine(edited, -1)){
var jump = function(){ return }
if(edited.selectionStart == edited.value.length){ state = 'edited' }
// needed to remember the position...
edited.selectionStart = c
edited.selectionEnd = c
that.focus('edited', 1) } }
this.carot_jump_edge_then_block ?
jump()
: setTimeout(jump, 0)
} else {
evt.preventDefault() evt.preventDefault()
this.focus('focused', 1) } }, this.get(state, 1)?.focus() },
// horizontal navigation / collapse... // horizontal navigation / collapse...
ArrowLeft: function(evt){ ArrowLeft: function(evt){
@ -568,7 +535,8 @@ var Outline = {
if(edited.selectionStart == edited.selectionEnd if(edited.selectionStart == edited.selectionEnd
&& edited.selectionStart == 0){ && edited.selectionStart == 0){
evt.preventDefault() evt.preventDefault()
edited = this.focus('edited', 'prev') edited = this.get('edited', 'prev')
edited.focus()
edited.selectionStart = edited.selectionStart =
edited.selectionEnd = edited.value.length + 1 } edited.selectionEnd = edited.value.length + 1 }
return } return }
@ -577,7 +545,7 @@ var Outline = {
&& this.get().getAttribute('collapsed') == null && this.get().getAttribute('collapsed') == null
&& this.get('children').length > 0) ? && this.get('children').length > 0) ?
this.toggleCollapse(true) this.toggleCollapse(true)
: this.focus('parent') }, : this.get('parent')?.focus() },
ArrowRight: function(evt){ ArrowRight: function(evt){
var edited = this.get('edited') var edited = this.get('edited')
if(edited){ if(edited){
@ -585,15 +553,17 @@ var Outline = {
if(edited.selectionStart == edited.selectionEnd if(edited.selectionStart == edited.selectionEnd
&& edited.selectionStart == edited.value.length){ && edited.selectionStart == edited.value.length){
evt.preventDefault() evt.preventDefault()
edited = this.focus('edited', 'next') edited = this.get('edited', 'next')
edited.focus()
edited.selectionStart = edited.selectionStart =
edited.selectionEnd = 0 } edited.selectionEnd = 0 }
return } return }
if(this.right_key_expands){ if(this.right_key_expands){
this.toggleCollapse(false) this.toggleCollapse(false)
var child = this.focus('children')[0] var child = this.get('children')[0]
child?.focus()
if(!child){ if(!child){
this.focus('next') } this.get('next')?.focus() }
} else { } else {
evt.shiftKey ? evt.shiftKey ?
this.toggleCollapse(false) this.toggleCollapse(false)
@ -687,20 +657,24 @@ var Outline = {
// click inside element... // click inside element...
} else { } else {
// XXX // XXX
} } }
// edit of focus... // todo: toggle checkbox...
// NOTE: this is usefull if element text is hidden but the } else if(elem.type == 'checkbox'
// frame is still visible... && elem.parentElement.parentElement.classList.contains('todo')){
if(elem.getAttribute('tabindex')){
elem.querySelector('textarea').focus() }
// toggle checkbox...
if(elem.type == 'checkbox'){
var node = elem.parentElement.parentElement var node = elem.parentElement.parentElement
var text = node.querySelector('textarea') var text = node.querySelector('textarea')
// get the checkbox order... text.value =
var i = [...node.querySelectorAll('input[type=checkbox]')].indexOf(elem) elem.checked ?
text.value.replace(/^\s*TODO(\s*)/, 'DONE$1')
: text.value.replace(/^\s*DONE(\s*)/, 'TODO$1')
// check: toggle checkbox...
} else if(elem.type == 'checkbox'
&& elem.classList.contains('check')){
var node = elem.parentElement.parentElement
var text = node.querySelector('textarea')
var i = [...node.querySelectorAll('.check')].indexOf(elem)
var to = elem.checked ? var to = elem.checked ?
'[X]' '[X]'
: '[_]' : '[_]'
@ -708,7 +682,7 @@ var Outline = {
return i-- == 0 ? return i-- == 0 ?
to to
: m } : m }
text.value = text.value.replace(/\[[Xx_]\]/g, toggle) } }) text.value = text.value.replace(/\[[X_]\]/g, toggle) } })
// heboard handling... // heboard handling...
outline.addEventListener('keydown', outline.addEventListener('keydown',
function(evt){ function(evt){
@ -774,7 +748,7 @@ var Outline = {
var refocusNode = function(){ var refocusNode = function(){
focus_textarea ? focus_textarea ?
editor.get().querySelector('textarea').focus() editor.get().querySelector('textarea').focus()
: editor.focus() : editor.get().focus()
focus_textarea = undefined } focus_textarea = undefined }
// cache the focused node type before focus changes... // cache the focused node type before focus changes...
toolbar.addEventListener('mousedown', cahceNodeType) toolbar.addEventListener('mousedown', cahceNodeType)

View File

@ -35,22 +35,20 @@ var setup = function(){
- Tomboy - Tomboy
- Bonsai - Bonsai
- -
- ## ToDo: - ## ToDo
- BUG? odd/random focus jumps on refocusing page (can't reporduce yet)
- BUG? pressing down from a longer line will jump over a shorter line
- here is the line to jump from, for example from here
an we'll not get here...
- ASAP: editor: bksapce/del at start/end of a block should join it with prev/next - ASAP: editor: bksapce/del at start/end of a block should join it with prev/next
- ASAP: editor: pressing enter in text edit mode should split text into two blocks - ASAP: editor: pressing enter in text edit mode should split text into two blocks
- ASAP: editor: shifting nodes up/down - ASAP: editor: shifting nodes up/down
- ASAP: editor: `-` at start of line is interpreted as block marker... - ASAP: editor: `-` at start of line is interpreted as block marker...
- ASAP: use \\t for indent... - editor: caret
- on item click, place the cursor where it was clicked before the code expanded... - ~go to next/prev element's start/end when moving off last/first char~
- handle up/down on wrapped blocks
_...can't seem to get caret line in a non-hacky way_
- ~editor: semi-live update styles~ - ~editor: semi-live update styles~
- need to reach checkboxes via keyboard - need to reach checkboxes via keyboard
- 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 - add completion percentage to blocks with todo's nested:
- _...use `[%]`, `%%`, or something similar..._ - `[%]`, `%%`, or something similar...
- read-only mode - read-only mode
- should bulets be on the same level as nodes or offset?? - should bulets be on the same level as nodes or offset??
- A) justified to bulet: - A) justified to bulet:
@ -98,30 +96,26 @@ var setup = function(){
- b - b
- c - c
- &gt; quoted text - &gt; quoted text
- Notes
- NOTE: a note text
- NOTE:
- a root note can also be empty
- click on the outer border to edit root
- // C-style comment - // C-style comment
- ; ASM-style comment - ; ASM-style comment
- XXX Highlight - XXX Highlight
- Line - Line
- --- - ---
- Markers: ASAP, BUG, FIX, HACK, STUB, WARNING, and CAUTION - Markers
- Basic "as soon as posible" (ASAP)
- Basic inline *bold*, _italic_ and ~striked~ - Basic inline *bold*, _italic_ and ~striked~
- Inline [X] checkboxes [_] - To do items
- To do items/blocks - TODO undone item
- [_] undone item
_(clicking the checkbox updates the item)_ _(clicking the checkbox updates the item)_
- [X] done item - DONE done item
- [_] we can also add inline [x] checkboxes - [_] a different way to draw a checkbox
- Inline [X] checkboxes [_]
- link <a href="about:blank">example</a> - link <a href="about:blank">example</a>
- markdown: - markdown:
- numbered lists
- tables
- code blocks - code blocks
- ~alerts~ - numbered lists
- alerts
- tables
- footnotes?? - footnotes??
- -
- ### Playground for testing - ### Playground for testing