Compare commits

..

No commits in common. "f5ea7b7919afe43656f60c83529efe88ed65b500" and "cb62d1e1c213414f8d4a50077350fde741d1c0fc" have entirely different histories.

3 changed files with 42 additions and 66 deletions

View File

@ -46,8 +46,8 @@ function clickPoint(x,y){
// elements. // elements.
// //
// XXX it would be a better idea to do a binary search instead of a liner // XXX it would be a better idea to do a binary search instead of a liner
// pass... // pass... but at this point this is not critical (unless we get
// ...though b-search will get us to the target, we stll need to count... // gigantic blocks)
// XXX HACK -- is there a better way to do this??? // XXX HACK -- is there a better way to do this???
var getCharOffset = function(elem, x, y, c){ var getCharOffset = function(elem, x, y, c){
c = c ?? 0 c = c ?? 0
@ -69,7 +69,7 @@ var getCharOffset = function(elem, x, y, c){
return Math.abs(b.x - x) <= Math.abs(prev.x - x) ? return Math.abs(b.x - x) <= Math.abs(prev.x - x) ?
c + i c + i
: c + i - 1 } } : c + i - 1 } }
c += i - 1 c += i
// html node... // html node...
} else { } else {
var res = getCharOffset(e, x, y, c) var res = getCharOffset(e, x, y, c)
@ -1254,18 +1254,6 @@ var Outline = {
;(this.__undo_stack ??= []).push([path, action, args, next]) ;(this.__undo_stack ??= []).push([path, action, args, next])
this.__redo_stack = undefined this.__redo_stack = undefined
return this }, return this },
mergeUndo: function(n, stack){
stack ??= this.__undo_stack
if(stack == null || stack.length == 0){
return this }
stack.push(
stack.splice(-n, n)
.map(function(e){
return typeof(e[1]) == 'string' ?
[e]
: e })
.flat())
return this },
clearUndo: function(){ clearUndo: function(){
this.__undo_stack = undefined this.__undo_stack = undefined
this.__redo_stack = undefined this.__redo_stack = undefined
@ -1274,19 +1262,14 @@ var Outline = {
if(from == null if(from == null
|| from.length == 0){ || from.length == 0){
return [from, to] } return [from, to] }
var actions = from.pop() var [path, action, args, next] = from.pop()
actions = typeof(actions[1]) == 'string' ? var l = from.length
[actions] path != null
: actions && this.focus(path)
while(actions.length > 0){ this[action](...args)
var [path, action, args, next] = actions.pop() next != null ?
var l = from.length this.focus(next)
path != null : this.focus()
&& this.focus(path)
this[action](...args)
next != null ?
this.focus(next)
: this.focus() }
if(l < from.length){ if(l < from.length){
to ??= [] to ??= []
to.push( to.push(
@ -1568,9 +1551,7 @@ var Outline = {
cur.after(block) cur.after(block)
: (place == 'before' || place == 'after') ? : (place == 'before' || place == 'after') ?
cur[place](block) cur[place](block)
: undefined : undefined }
this.setUndo(this.path(cur), 'remove', [this.path(block)]) }
return block }, return block },
// XXX see inside... // XXX see inside...
load: function(data){ load: function(data){
@ -1808,20 +1789,15 @@ var Outline = {
evt.preventDefault() evt.preventDefault()
var a = edited.selectionStart var a = edited.selectionStart
var b = edited.selectionEnd var b = edited.selectionEnd
// position 0: focus empty node above... var prev = edited.value.slice(0, a)
if(a == 0){ var next = edited.value.slice(b)
this.Block('prev') edited.value = prev
this.edit('prev') this.Block({text: next}, 'next')
// focus new node... // focus next if not at position 0, otherwise keep focus...
} else { if(a != 0){
var prev = edited.value.slice(0, a)
var next = edited.value.slice(b)
edited.value = prev
this.Block({text: next}, 'next')
edited = this.edit('next') edited = this.edit('next')
edited.selectionStart = 0 edited.selectionStart = 0
edited.selectionEnd = 0 edited.selectionEnd = 0 }
this.mergeUndo(2) }
return } return }
// view -> edit... // view -> edit...
evt.preventDefault() evt.preventDefault()
@ -1974,7 +1950,6 @@ var Outline = {
elem.selectionStart = elem.value.length elem.selectionStart = elem.value.length
elem.selectionEnd = elem.value.length elem.selectionEnd = elem.value.length
} else { } else {
console.log('---', c)
var m = getMarkdownOffset(elem.value, view.innerText, c) var m = getMarkdownOffset(elem.value, view.innerText, c)
elem.focus() elem.focus()
elem.selectionStart = c + m elem.selectionStart = c + m
@ -2224,10 +2199,20 @@ Object.assign(
return this.dom?.querySelector('.toolbar') }, return this.dom?.querySelector('.toolbar') },
set toolbar(val){}, set toolbar(val){},
// XXX these are generic...
encode: function(text){
var span = document.createElement('span')
span.innerText = text
return span.innerHTML },
decode: function(text){
var span = document.createElement('span')
span.innerHTML = text
return span.innerText },
get code(){ get code(){
return this.hasAttribute('value') ? return this.hasAttribute('value') ?
this.getAttribute('value') this.getAttribute('value')
: HTMLElement.decode(this.innerHTML) }, : this.decode(this.innerHTML) },
set code(value){ set code(value){
if(value == null){ if(value == null){
return } return }
@ -2235,7 +2220,7 @@ Object.assign(
if(this.hasAttribute('value')){ if(this.hasAttribute('value')){
this.setAttribute('value', value) this.setAttribute('value', value)
} else { } else {
this.innerHTML = HTMLElement.encode(value) } }, this.innerHTML = this.encode(value) } },
// XXX do we need this??? // XXX do we need this???
// ...rename .code -> .value ??? // ...rename .code -> .value ???

View File

@ -22,20 +22,6 @@ Element.prototype.visibleInViewport = function(partial=false){
&& right <= innerWidth) } && right <= innerWidth) }
//---------------------------------------------------------------------
// XXX should these be here???
HTMLElement.encode = function(str){
var span = document.createElement('span')
span.innerText = str
return span.innerHTML }
HTMLElement.decode = function(str){
var span = document.createElement('span')
span.innerHTML = str
return span.innerText }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
HTMLTextAreaElement.prototype.updateSize = function(){ HTMLTextAreaElement.prototype.updateSize = function(){
@ -74,20 +60,15 @@ HTMLTextAreaElement.prototype.getTextGeometry = function(){
position: 'fixed', position: 'fixed',
display: 'block', display: 'block',
/* DEBUG...
top: '0px',
left: '0px',
/*/
top: '-100%', top: '-100%',
left: '-100%', left: '-100%',
//*/
width: style.width, width: style.width,
height: style.height, height: style.height,
padding: style.padding, padding: style.padding,
boxSizing: style.boxSizing, boxSizing: style.boxSizing,
whiteSpace: style.whiteSpace, //whiteSpace: 'pre-wrap',
outline: 'solid 1px red', outline: 'solid 1px red',

View File

@ -48,6 +48,16 @@ var setup = function(){
- -
- ## Bugs: - ## Bugs:
focused:: true focused:: true
- BUG: focus at times seems to be biased a bit to the right -- the caret is placed to the right from where expected...
-
_this seems to only affect text with leading whitespace only, like this._
- BUG: undo: does not handle element splitting correctly...
- place cursor somewhere here, hit `Enter`, and then undo.
- _this will correctly restore the old node but will not remove the new one_
- need to:
- add undo to `.Block(..)`
- group `new` and `cange` into one undo action...
- _undo chaining? ...i.e. support nested arrays?_
- BUG: mobile browsers behave quite chaotically ignoring parts of the styling... - BUG: mobile browsers behave quite chaotically ignoring parts of the styling...
- FF: - FF:
- zooming on edited field - zooming on edited field