Compare commits

..

No commits in common. "8368ee43aa357721d848013de9ad8a5563c3e369" and "bb3ba95ae39b022dfc138f997d7b3e8307f00423" have entirely different histories.

4 changed files with 500 additions and 586 deletions

View File

@ -30,7 +30,6 @@
text-size-adjust: 180%;
}
:host,
.editor {
--item-padding: calc(1em * var(--item-padding-ratio));
}
@ -39,96 +38,75 @@
/*********************************************************************/
:host,
.editor {
display: block;
position: relative;
}
.code {
.editor .code {
display: none;
}
}
/* header */
.header {
/* header */
.editor .header {
margin: 1em var(--outline-padding);
padding-bottom: 1.2em;
border-bottom: solid 1px rgba(0,0,0,0.15);
&:empty {
}
.editor .header:empty {
display: none;
}
.path-item {
}
.editor .header .path-item {
color: gray;
cursor: pointer;
/* XXX needs more work... */
max-width: 10rem;
text-overflow: ellipsis;
&:hover {
}
.editor .header .path-item:hover {
text-decoration: underline;
}
&:first-child {
}
.editor .header .path-item:first-child {
padding-left: 3em;
margin-left: -2em;
}
}
}
}
.outline {
.editor .outline {
display: block;
position: relative;
padding: 1em var(--outline-padding);
padding-bottom: 1.2em;
}
/* virtual empty block... */
&:empty:after {
/* virtual empty block... */
.editor .outline:empty:after {
content: "Empty";
display: block;
font-style: italic;
color: rgba(0,0,0,0.2);
}
&:empty:hover:after {
}
}
.editor .outline:empty:hover:after {
}
.block .block {
margin-left: var(--item-indent);
}
.block {
.editor .outline .block {
position: relative;
outline: none;
border: none;
/* focus... */
&:focus {
/*outline: solid 0.2em silver;*/
outline: none;
}
&:focus>.text {
background: rgba(0,0,0,0.07);
}
&.focused:not(:focus)>.text {
background: rgba(0,0,0,0.01);
border-bottom: solid 2px rgba(0,0,0,0.03);
}
/* collapsed block... */
&[collapsed] {
border-bottom: solid 1px silver;
&>.children {
display: none;
}
}
/* select... */
/* XXX are we selecting subtrees or blocks??? */
&[selected]>.text {
background: silver;
}
&>.text {
}
.editor.block-offsets .outline .block {
border-left: solid 1px silver;
}
.editor .outline .block .block,
.editor.crop .outline .block[cropped] .block,
.editor.crop .outline .block[cropped] .block[cropped] {
margin-left: var(--item-indent);
}
.editor .outline .block>.text {
--v-margin: 0;
display: block;
@ -148,47 +126,81 @@
outline: none;
border: none;
}
&>.code {
}
/* show/hide node's view/code... */
/*.editor .outline .block>.code:focus+.view,*/
.editor .outline .block>.code:not(:focus) {
position: absolute;
opacity: 0;
}
/* hide .view content but show before/after -- keep bulets and touch zones... */
.editor .outline .block>.code:focus+.view {
position: absolute;
top: 0;
height: calc(2 * var(--item-padding) + 1em);
overflow: hidden;
resize: none;
/* show/hide node's view/code... */
/*&:focus+.view,*/
&:not(:focus) {
opacity: 0;
}
/* hide .view content but show before/after -- keep bulets and touch zones... */
&:focus+.view {
visibility: hidden;
&:before,
&:after {
}
.editor .outline .block>.code:focus+.view:before,
.editor .outline .block>.code:focus+.view:after {
visibility: visible;
margin-top: calc(-1 * var(--v-margin));
margin-bottom: calc(-1 * var(--v-margin));
}
}
}
/* click through the .view text to the .code */
&>.view {
}
/* click through the .view text to the .code */
.editor .outline .block>.view {
position: relative;
pointer-events: none;
/* clickable things in view */
& a,
& pre,
& input {
}
/* block hover... */
.editor .outline:empty:hover:after,
.editor .outline .block:hover>.view {
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 .block>.view:blank {
content: " ";
}
.editor .outline .block>.code {
height: calc(2 * var(--item-padding) + 1em);
overflow: hidden;
resize: none;
}
/* clickable things in view */
.editor .outline .block>.view a,
.editor .outline .block>.view pre,
.editor .outline .block>.view input {
pointer-events: auto;
}
}
/* click/tap zones for expand button... */
&:before,
&:after {
/* focus... */
editor .outline .block:focus {
/*outline: solid 0.2em silver;*/
outline: none;
}
.editor .outline .block:focus>.text {
background: rgba(0,0,0,0.07);
}
.editor .outline .block.focused:not(:focus)>.text {
background: rgba(0,0,0,0.01);
border-bottom: solid 2px rgba(0,0,0,0.03);
}
/* collapsed block... */
.editor .outline .block[collapsed] {
border-bottom: solid 1px silver;
}
/* hide children... */
.editor .outline .block[collapsed]>.children {
display: none;
}
/* click/tap zones for expand button... */
.editor .outline .block>.view:before,
.editor .outline .block>.view:after {
--size: 3rem;
content: "";
@ -220,85 +232,68 @@
cursor: pointer;
background: transparent;
}
/* left indicator */
&:before {
}
/* left indicator */
.editor .outline .block>.view:before {
justify-content: right;
left: calc(-1 * var(--size));
}
}
/* indicators... */
/* left indicator bullet */
/* XXX not sure about this yet... */
&>.view:before {
}
/* left indicator bullet */
/* XXX not sure about this yet... */
.editor .outline .block>.view:before {
content: "●";
color: rgba(0,0,0,0.07);
}
&>.view:empty:before {
}
.editor .outline .block>.view:empty:before {
content: "";
}
/* right indicator (collapse/expand) */
&>.view:after {
}
/* right indicator (collapse/expand) */
.editor .outline .block>.view:after {
color: silver;
}
&:has(.block)>.view:after {
}
.editor .outline .block:has(.block)>.view:after {
content: "○";
}
&[collapsed]>.view:after {
}
.editor .outline .block[collapsed]>.view:after {
content: "●";
}
}
}
/* block hover... */
&:empty:hover:after,
.block:not(.focused):hover>.view {
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%);
}
}
/* select... */
/* XXX are we selecting subtrees or blocks??? */
.editor .outline [selected]>.text {
background: silver;
}
/*
* NOTE: the organization after this point does not feel right/clean,
* not sure how to do this better...
*/
/* crop... */
&.crop .outline .block {
&[cropped] .block,
&[cropped] .block[cropped] {
margin-left: var(--item-indent);
}
&:not([cropped]) {
/* crop... */
/* NOTE: also see rules for: .editor .outline .block .block
* ...can we avoid this?? (XXX) */
.editor.crop .outline .block:not([cropped]) {
padding: 0;
border: none;
background: none;
}
&:not([cropped])>.text {
}
.editor.crop .outline .block:not([cropped])>.text {
display: none;
}
&,
&[cropped] {
}
.editor.crop .outline .block,
.editor.crop .outline .block[cropped] {
margin-left: 0;
}
&[cropped] .text {
}
.editor.crop .outline .block[cropped] .text {
display: block;
}
}
}
/* toolbar... */
.toolbar {
/* toolbar... */
.editor .toolbar {
display: inline-block;
position: absolute;
top: 1em;
right: 1em;
button {
}
.editor .toolbar button {
--margin: 0.1em;
display: block;
@ -308,70 +303,59 @@
margin: var(--margin);
font-size: var(--button-size);
}
}
&.block-offsets .outline .block {
border-left: solid 1px silver;
}
}
/********************************************************** Styles ***/
/*------------------------------------------------------ Headings ---*/
:host .outline,
.editor .outline {
.heading-1,
.heading-2,
.heading-3,
.heading-4,
.heading-5,
.heading-6 {
.editor .outline .heading-1,
.editor .outline .heading-2,
.editor .outline .heading-3,
.editor .outline .heading-4,
.editor .outline .heading-5,
.editor .outline .heading-6 {
margin-top: 1rem;
&>.text {
}
.editor .outline .heading-1>.text,
.editor .outline .heading-2>.text,
.editor .outline .heading-3>.text,
.editor .outline .heading-4>.text,
.editor .outline .heading-5>.text,
.editor .outline .heading-6>.text {
font-weight: bold;
}
}
.heading-1>.text,
.heading-2>.text,
.heading-3>.text {
}
.editor .outline .heading-1>.text,
.editor .outline .heading-2>.text,
.editor .outline .heading-3>.text {
border-bottom: solid 1px rgba(0,0,0,0.1);
}
}
.heading-1>.text {
.editor .outline .heading-1>.text {
--font-size: 2.5em;
}
.heading-2>.text {
}
.editor .outline .heading-2>.text {
--font-size: 1.9em;
}
.heading-3>.text {
}
.editor .outline .heading-3>.text {
--font-size: 1.5em;
}
.heading-4>.text {
}
.editor .outline .heading-4>.text {
--font-size: 1.3em;
}
.heading-5>.text {
}
.editor .outline .heading-5>.text {
--font-size: 1.1em;
}
.heading-6>.text {
}
.editor .outline .heading-6>.text {
--font-size: 1em;
}
}
/*--------------------------------------------------------- Quote ---*/
:host .outline .quote>.text,
.editor .outline .quote>.text {
--indent: 1rem;
--v-margin: 0.7rem;
@ -392,90 +376,88 @@
/*---------------------------------------------------------- List ---*/
:host .outline,
.editor .outline {
.list-item>.view:before,
.list>.children {
&>.block>.view:before {
.editor .outline .list-item>.view:before,
.editor .outline .list>.children>.block>.view:before {
content: "◼";
color: gray;
}
&>.list>.children {
&>.block>.view:before {
content: "●";
}
&>.list>.children {
&>.block>.view:before {
content: "○";
}
&>.list>.children {
&>.block>.view:before {
content: "▪";
}
}
}
}
/* hide bullets on empty nodes unless they are edited... */
&>.block>.code:not(:focus)+.view:empty:before {
content: "" !important;
}
/* hide bullets on empty nodes... *//*
&>.block>.view:empty:before {
content: "";
}
*/
}
}
.editor .outline
.list>.children
>.list>.children>.block>.view:before {
content: "●";
}
.editor .outline
.list>.children
>.list>.children
>.list>.children>.block>.view:before {
content: "○";
}
.editor .outline
.list>.children
>.list>.children
>.list>.children
>.list>.children>.block>.view:before {
content: "▪";
}
/* hide bullets on empty nodes unless they are edited... */
.editor .outline .list>.children>.block>.code:not(:focus)+.view:empty:before {
content: "";
}
/* hide bullets on empty nodes... *//*
.editor .outline .list>.children>.block>.view:empty:before {
content: "";
}
*/
/*------------------------------------------------ Numbered lists ---*/
:host .outline .numbered-list>.children,
.editor .outline .numbered-list>.children {
counter-reset: numbered-list;
&>.block>.view:not(:empty):before {
}
.editor .outline .numbered-list>.children>.block>.view:not(:empty):before {
counter-increment: numbered-list;
content: counter(numbered-list) ".";
color: gray;
}
&>.numbered-list>.children {
&>.block>.view:not(:empty):before {
}
.editor .outline
.numbered-list>.children
>.numbered-list>.children>.block>.view:not(:empty):before {
counter-increment: numbered-list;
content: counter(numbered-list, lower-alpha) ".";
}
&>.numbered-list>.children {
&>.block>.view:not(:empty):before {
color: gray;
}
.editor .outline
.numbered-list>.children
>.numbered-list>.children
>.numbered-list>.children>.block>.view:not(:empty):before {
counter-increment: numbered-list;
content: counter(numbered-list, lower-roman) ".";
}
&>.numbered-list>.children {
&>.block>.view:not(:empty):before {
color: gray;
}
.editor .outline
.numbered-list>.children
>.numbered-list>.children
>.numbered-list>.children
>.numbered-list>.children>.block>.view:not(:empty):before {
counter-increment: numbered-list;
content: counters(numbered-list, ".") ".";
}
}
}
}
color: gray;
}
/*------------------------------------------------------ hr block ---*/
:host .outline,
.editor .outline {
.list>.children>.block.hr>.view:before {
.editor .outline .list>.children>.block.hr>.view:before {
content: "";
}
.numbered-list>.children>.block.hr>.view:before {
}
.editor .outline .numbered-list>.children>.block.hr>.view:before {
content: "";
}
}
/*--------------------------------------------------------- Notes ---*/
:host .outline .NOTE,
.editor .outline .NOTE {
--margin: 1rem;
--padding-h: 2rem;
@ -485,64 +467,56 @@
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... */
&>.view:empty {
}
/* XXX this prevents it from being accesible via click/tap... */
.editor .outline .NOTE>.view:empty {
display: none;
}
&:focus>.view:empty {
}
.editor .outline .NOTE:focus>.view:empty {
display: block;
}
&>.view:empty ~ .children {
}
.editor .outline .NOTE>.view:empty ~ .children {
margin-left: -1rem;
}
&>.view:before {
}
.editor .outline .NOTE>.view:before {
content: "" !important;
}
/* correct the right click zone... */
/* XXX need to account for nesting... (???) */
&.block>.view:after,
&.block .block>.view:after {
}
/* correct the right click zone... */
/* XXX need to account for nesting... (???) */
.editor .outline .block.NOTE>.view:after,
.editor .outline .block.NOTE .block>.view:after {
margin-right: calc(-1 * var(--padding-h));
}
}
/*-------------------------------------------------------- Status ---*/
:host .outline .block,
.editor .outline .block {
&.DONE>.view {
.editor .outline .block.DONE>.view {
text-decoration: line-through;
opacity: 0.5;
}
&.REJECT>.view {
}
.editor .outline .block.REJECT>.view {
text-decoration: line-through;
}
}
/*--------------------------------------------------- Highlightes ---*/
:host .outline,
.editor .outline {
.highlight {
.editor .outline .highlight {
font-weight: bold;
background: yellow;
}
.XXX>.view {
}
.editor .outline .XXX>.view {
background: yellow;
}
}
/*------------------------------------------------------ Comments ---*/
:host.hide-comments .outline .comment,
.editor.hide-comments .outline .comment {
display: none;
}
:host .outline .comment>.view,
.editor .outline .comment>.view {
color: silver;
}
@ -550,9 +524,7 @@
/*---------------------------------------------------- Checkboxes ---*/
:host .outline .block,
.editor .outline .block {
&.todo>.view {
.editor .outline .block.todo>.view {
width: calc(
100%
- var(--checkbox-size)
@ -560,9 +532,9 @@
margin-left: calc(
var(--checkbox-size)
+ var(--checkbox-margin));
}
&.check>.view input[type=checkbox],
&.todo>.view input[type=checkbox] {
}
.editor .outline .block.check>.view input[type=checkbox],
.editor .outline .block.todo>.view input[type=checkbox] {
height: var(--checkbox-size);
width: var(--checkbox-size);
@ -574,102 +546,85 @@
/* NOTE: this appears to be needed for the em sizes above to work correctly */
font-size: 1em;
}
&.check.focused>.view input[type=checkbox].selected,
&.todo.focused>.view input[type=checkbox].selected {
}
.editor .outline .block.check.focused>.view input[type=checkbox].selected,
.editor .outline .block.todo.focused>.view input[type=checkbox].selected {
outline: solid 0.2em silver;
}
&.check:focus>.view input[type=checkbox].selected,
&.todo:focus>.view input[type=checkbox].selected {
}
.editor .outline .block.check:focus>.view input[type=checkbox].selected,
.editor .outline .block.todo:focus>.view input[type=checkbox].selected {
outline: solid 0.2em gray;
}
&.todo>.view input[type=checkbox]:first-child {
}
.editor .outline .block.todo>.view input[type=checkbox]:first-child {
margin-left: calc(
-1 * var(--checkbox-size)
- var(--checkbox-margin));
}
/* correct the left click zone... */
&.todo>.view:before {
}
/* correct the left click zone... */
.editor .outline .block.todo>.view:before {
margin-left: calc(
-1 * var(--checkbox-size)
- var(--checkbox-margin));
}
/* status... */
&>.view .completion[completion]:before {
}
/* status... */
.editor .outline .block>.view .completion[completion]:before {
content: "(" attr(completion) ")";
color: gray;
}
}
/*---------------------------------------------------------- Code ---*/
:host .outline .block>.view,
.editor .outline .block>.view {
/* XXX for some reason if we omit & where not needed, colors will not apply... */
& pre,
&>code,
& :not(pre)>code {
.editor .outline .block>.view pre,
.editor .outline .block>.view>code,
.editor .outline .block>.view :not(pre)>code {
padding: 0.1em 0.3em;
font-family: monospace;
background: rgba(0,0,0,0.07);
border-radius: 0.2em;
outline: none;
}
& pre>code {
}
.editor .outline .block>.view pre>code {
display: block;
padding: 0.6em 0.6em;
padding-bottom: 0.8em;
outline: none;
}
}
/*-------------------------------------------------------- Tables ---*/
:host .outline .block>.view>table,
.editor .outline .block>.view>table {
width: 100%;
border-collapse: collapse;
/* XXX for some reason if we omit & where not needed, colors will not apply... */
& tr:nth-child(odd) {
}
.editor .outline .block>.view>table tr:nth-child(odd) {
background: rgba(0,0,0,0.03);
}
& tr:first-child {
}
.editor .outline .block>.view>table tr:first-child {
font-weight: bold;
border-bottom: solid 0.1rem silver;
background: transparent;
}
& td {
}
.editor .outline .block>.view>table td {
height: calc(1em + var(--item-padding) * 2);
padding: 0 1em;
/*text-align: center;*/
}
}
/********************************************************* Testing ***/
:host.show-click-zones .outline .block,
.editor.show-click-zones .outline .block {
&>.view {
&:before,
&:before,
&:after {
.editor.show-click-zones .outline .block>.view:before,
.editor.show-click-zones .outline .block>.view:after {
background: rgba(0,0,0,0.03);
border: solid 1px silver;
}
}
&:hover>.view {
&:before,
&:after {
}
.editor.show-click-zones .outline .block:hover>.view:before,
.editor.show-click-zones .outline .block:hover>.view:after {
background: rgba(0,0,0,0.1);
}
}
}
/**********************************************************************
* vim:set ts=4 sw=4 : */
/*********************************************************************/

View File

@ -766,9 +766,6 @@ var Outline = {
change_interval: 1000,
tab_size: 4,
carot_jump_edge_then_block: false,
// XXX not sure what should the default be...
// XXX this should not affect editing...
trim_block_text: false,
// Plugins...
@ -1080,12 +1077,7 @@ var Outline = {
if(this.__code2html__){
// NOTE: we are ignoring the .collapsed attr here
parsed = this.__code2html__(data.text, {...data})
html.innerHTML =
parsed.text.length == 0 ?
parsed.text
// NOTE: adding a space here is done to prevent the browser
// from hiding the last newline...
: parsed.text + ' '
html.innerHTML = parsed.text
// heading...
this.__styles != null
&& node.classList.remove(...this.__styles)
@ -1093,12 +1085,7 @@ var Outline = {
&& node.classList.add(...parsed.style)
delete parsed.style
} else {
html.innerHTML =
data.text.length == 0 ?
data.text
// NOTE: adding a space here is done to prevent the browser
// from hiding the last newline...
: data.text + ' ' }
html.innerHTML = data.text }
text.value = data.text
// XXX this does not seem to work until we click in the textarea...
text.autoUpdateSize() }
@ -2034,6 +2021,7 @@ var Outline = {
elem.selectionStart = elem.value.length
elem.selectionEnd = elem.value.length
} else {
console.log('---', c)
var m = getMarkdownOffset(elem.value, view.innerText, c)
elem.focus()
elem.selectionStart = c + m
@ -2252,10 +2240,6 @@ Object.assign(
//var toolbar = document.createElement('div')
//toolbar.classList.add('toolbar')
// XXX can't yet get rid of the editor element here...
// - handling autofocus of host vs. shadow???
// - CSS not working correctly yet...
// ...is this feasible???
editor.append(
style,
header,
@ -2291,23 +2275,11 @@ Object.assign(
return this.dom?.querySelector('.toolbar') },
set toolbar(val){},
// NOTE: this is here to break recursion of trying to set
// html's value both in .code that is called both when
// setting .value and from .attributeChangedCallback(..)
get __code(){
return this.code },
set __code(value){
if(value == null){
return }
// XXX is this the right way to do this???
this.__sessionStorage
&& (sessionStorage[this.__sessionStorage] = value)
this.__localStorage
&& (localStorage[this.__localStorage] = value) },
get code(){
return this.hasAttribute('value') ?
this.getAttribute('value')
: HTMLElement.decode(this.innerHTML) },
// XXX
set code(value){
if(value == null){
return }
@ -2316,7 +2288,11 @@ Object.assign(
this.setAttribute('value', value)
} else {
this.innerHTML = HTMLElement.encode(value) }
this.__code = value },
// XXX is this the right way to do this???
this.__sessionStorage
&& (sessionStorage[this.__sessionStorage] = value)
this.__localStorage
&& (localStorage[this.__localStorage] = value) },
// XXX do we need this???
// ...rename .code -> .value ???
@ -2333,21 +2309,20 @@ Object.assign(
// XXX do we need to before == after ???
attributeChangedCallback(name, before, after){
var value
if(name == 'local-storage'){
this.__localStorage = after
// XXX setting code here because we will load at .setup(..)
// ...the problem is that if we change the attr
// we need to call .load(..)
value = this.code = localStorage[after] ?? '' }
this.code = localStorage[after] ?? '' }
if(value && name == 'session-storage'){
if(name == 'session-storage'){
this.__sessionStorage = after
value = this.code = sessionStorage[after] ?? '' }
this.code = sessionStorage[after] ?? '' }
if(name == 'value'){
console.log('---', before, '->', after) }
if(!value && name == 'value'){
// see notes for .__code
value = this.__code = after }
},
},

View File

@ -41,7 +41,7 @@ HTMLElement.decode = function(str){
var span = document.createElement('span')
// XXX
return str
.replace(/&lt;/g, '<')
.replace(/%lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&amp;/g, '&') }
/*/

View File

@ -48,7 +48,8 @@ var setup = function(){
-
- ## Bugs:
focused:: true
- BUG: `.trim_block_text` should not affect editing...
- BUG: html decode/encode broken...
- `HTMLElement.decode(HTMLElement.encode('a\nb\nc')) -> 'abc'` and not `'a\nb\nc'`!!!
- BUG: mobile browsers behave quite chaotically ignoring parts of the styling...
- FF:
- zooming on edited field
@ -58,42 +59,31 @@ var setup = function(){
-
- ## ToDo:
- trailing whitespace is ignored in `.view`... (BUG?)
- demos:
-
leading whitespace...
- trailing whitespace...
- this node has a second empty line
- empty block is not correctly shown\:
-
- _it seams that HTML ignores the last newline if it is not followed by anything_
- there are four ways to deal with this:#
- trim whitespace on refocus
- there are several ways to deal with this:#
- remove trailing whitespace completely on refocus (a-la logseq)
- show whitespace in both modes
- REJECT remove trailing whitespace completely on refocus (a-la logseq)
- REJECT keep current behavior
- I do not believe in keeping whitespace in edit and hiding it in view (POLS)
- keep current behavior
-
_BTW: leading whitespace is shown..._
- add options to save to `.sessionStorage` / `.localStorage`
- Q: should we select text without first focusing??
- _...logseq does not do this either_
- custom element / web component
- Q: can we get rid of the editor block??:
- CSS breaks if we do...
- need to figure out a way to handle autofocus for host/editor uniformly
- DONE data interface:
collapsed:: true
- the "natural" way to pass data is to use the same mechanism as `<textarea>` the problem is that we can't extend `HTMLTextAreaElement` as it can not have shadow dom (reject?)
- adding an explicit textarea element is an odd requirement (reject?)
- seems that the least bad way to go is to use the `value` attribute
- DONE API: directly mixin Outline?
- DONE `.value` / `.code` should be both updated internally and also load new content when updated externally -- not yet sure how...
- `.value` / `.code` should be both updated internally and also load new content when updated externally -- not yet sure how...
- events
- test nesting...
-
- selection
- multiple node selection (via shift+motion)
- touch/mouse (???)
- Q: should we select text (mouse/touch) without first focusing??
- _...logseq does not do this either_
- now this is possible by dragging from a click zone...
- copy/paste nodes/trees
- numbered lists: add counters to a depth of 6-7...
- _or find a way to make them repeat..._
@ -147,7 +137,6 @@ var setup = function(){
- empty item height is a bit off...
- search?
- _...not sure if search should be internal or external yet..._
- DONE add options to save to `.sessionStorage` / `.localStorage`
- DONE might be a good idea to focus the prev (empty) node if pressing `Enter` at 0 position
collapsed:: true
- <- place cursor here and press enter
@ -234,7 +223,6 @@ var setup = function(){
- DONE split out
- DONE define api (see: `<editor>.__code2text__(..) / <editor>.__text2code__(..)`)
- CSS
- DONE nested rules (experiment)
- separate out settings
- separate out theming
- Actions -- move user actions (code in `.keyboard`) into methods
@ -434,11 +422,7 @@ var setup = function(){
<hr>
<outline-editor
session-storage="outline-editor-test"
value="- ## Session storage
- default value, edit to change
- this should survive reloads"></outline-editor>
<outline-editor session-storage="outline-editor-test"></outline-editor>
</body>