diff --git a/experiments/outline-editor/editor.css b/experiments/outline-editor/editor.css index 9ea187f..978bd90 100755 --- a/experiments/outline-editor/editor.css +++ b/experiments/outline-editor/editor.css @@ -1,21 +1,34 @@ :root { + --button-size: 5em; + font-family: sans-serif; font-size: 5mm; } -.editor [tabindex] { +.editor { + display: block; position: relative; } -.editor div [tabindex] { + +.editor .outline { + display: block; + position: relative; + width: calc(100% - var(--button-size)); +} + +.editor .outline [tabindex] { + position: relative; +} +.editor .outline div [tabindex] { margin-left: 2em; } -.editor [tabindex]>span, -.editor [tabindex]>textarea { +.editor .outline [tabindex]>span, +.editor .outline [tabindex]>textarea { --padding: 0.2em; display: block; - width: 100%; + width: 100% /* XXX this is a tiny bit off and using textarea's height here is off too... */ min-height: 1em; padding: var(--padding); @@ -28,41 +41,61 @@ outline: none; border: none; } -.editor [tabindex]>textarea { +.editor .outline [tabindex]>textarea { height: calc(2 * var(--padding) + 1em); overflow: hidden; resize: none; } /* show/hide node's view/code... */ -.editor [tabindex]>span+textarea:not(:focus), +.editor .outline [tabindex]>span+textarea:not(:focus), /* XXX not sure how to do this without :has(..)... */ -.editor [tabindex]:has(>span+textarea:focus)>span:has(+textarea), -.editor [tabindex]:focus>span+textarea { +.editor .outline [tabindex]:has(>span+textarea:focus)>span:has(+textarea), +.editor .outline [tabindex]:focus>span+textarea { position: absolute; opacity: 0; top: 0; } -.editor div[collapsed] { +/* focus... */ +.editor .outline [tabindex]:focus { + /*outline: solid 0.2em silver;*/ + outline: none; +} +.editor .outline [tabindex]:focus>span, +.editor .outline [tabindex]:focus>textarea { + background: rgba(0,0,0,0.1); +} +.editor .outline [tabindex].focused:not(:focus)>span, +.editor .outline [tabindex].focused:not(:focus)>textarea { + background: rgba(0,0,0,0.05); +} + + +.editor .outline div[collapsed] { border-bottom: solid 1px silver; } -.editor div[collapsed] div { +.editor .outline div[collapsed] div { display: none; } /* XXX are we selecting subtrees or blocks??? */ -.editor [selected] { +.editor .outline [selected] { background: silver; } -.editor div:focus { - /*outline: solid 0.2em silver;*/ - outline: none; + +.editor .toolbar { + display: inline-block; + position: absolute; + top: 1em; + right: 1em; } -.editor div:focus>span, -.editor div:focus>textarea { - background: rgba(0,0,0,0.1); +.editor .toolbar button { + display: block; + width: var(--button-size); + height: var(--button-size); } + diff --git a/experiments/outline-editor/editor.js b/experiments/outline-editor/editor.js index 4efa76c..69268b6 100755 --- a/experiments/outline-editor/editor.js +++ b/experiments/outline-editor/editor.js @@ -167,7 +167,8 @@ var Outline = { this.at(node) : node == 'focused' ? (this.dom.querySelector(`[tabindex]:focus`) - || this.dom.querySelector(`textarea:focus`)?.parentElement) + || this.dom.querySelector(`textarea:focus`)?.parentElement + || this.dom.querySelector('[tabindex].focused')) : node == 'parent' ? this.get('focused')?.parentElement : node @@ -221,7 +222,7 @@ var Outline = { // deindent... if(!indent){ var parent = cur.parentElement - if(!parent.classList.contains('.editor')){ + if(!parent.classList.contains('.outline')){ var children = siblings.slice(siblings.indexOf(cur)+1) parent.after(cur) children.length > 0 @@ -260,9 +261,10 @@ var Outline = { elem.updateSize() } } return node }, - // XXX - remove: function(node){ - }, + // XXX should this handle focus??? + remove: function(node='focused', offset){ + this.get(...arguments)?.remove() + return this }, // block serialization... __code2html__: function(code){ @@ -333,7 +335,7 @@ var Outline = { // horizontal navigation / collapse... // XXX if at start/end of element move to prev/next... ArrowLeft: function(evt){ - if(this.dom.querySelector('.editor textarea:focus')){ + if(this.dom.querySelector('.outline textarea:focus')){ // XXX if at end of element move to next... return } ;((this.left_key_collapses @@ -343,7 +345,7 @@ var Outline = { this.toggleCollapse(true) : this.get('parent')?.focus() }, ArrowRight: function(evt){ - if(this.dom.querySelector('.editor textarea:focus')){ + if(this.dom.querySelector('.outline textarea:focus')){ // XXX if at end of element move to next... return } if(this.right_key_expands){ @@ -394,7 +396,7 @@ var Outline = { return } this.toggleCollapse(true) var next = this.get('next') - this.get()?.remove() + this.remove() next?.focus() }, // select... @@ -414,20 +416,26 @@ var Outline = { setup: function(dom){ var that = this this.dom = dom + var outline = dom.querySelector('.outline') // update stuff already in DOM... - for(var elem of [...dom.querySelectorAll('.editor textarea')]){ + for(var elem of [...outline.querySelectorAll('textarea')]){ elem.autoUpdateSize() } // heboard handling... - dom.addEventListener('keydown', + outline.addEventListener('keydown', function(evt){ evt.key in that.keyboard && that.keyboard[evt.key].call(that, evt) }) // toggle view/code of nodes... - dom.addEventListener('focusin', + outline.addEventListener('focusin', function(evt){ var node = evt.target + // handle focus... + for(var e of [...that.dom.querySelectorAll('.focused')]){ + e.classList.remove('focused') } + that.get('focused')?.classList?.add('focused') + // textarea... if(node.nodeName == 'TEXTAREA' && node?.previousElementSibling?.nodeName == 'SPAN'){ node.value = @@ -435,7 +443,7 @@ var Outline = { that.__html2code__(node.previousElementSibling.innerHTML) : node.previousElementSibling.innerHTML node.updateSize() } }) - dom.addEventListener('focusout', + outline.addEventListener('focusout', function(evt){ var node = evt.target if(node.nodeName == 'TEXTAREA' diff --git a/experiments/outline-editor/index.html b/experiments/outline-editor/index.html index 5ad782e..d74fd86 100755 --- a/experiments/outline-editor/index.html +++ b/experiments/outline-editor/index.html @@ -21,31 +21,39 @@ var setup = function(){
-
- root -
- A -
a +
+
+ root +
+ A +
a +
+
b +
+
c +
-
b +
B +
d +
+
e +
-
c -
-
-
B -
d -
-
e -
-
-
C -
This is a line of text -
-
This is a set -text lines +
C +
This is a line of text +
+
This is a set + text lines +
+
+ + + + +