mirror of
https://github.com/flynx/pWiki.git
synced 2025-12-25 20:31:58 +00:00
Compare commits
3 Commits
2f3255b53d
...
38e90d6071
| Author | SHA1 | Date | |
|---|---|---|---|
| 38e90d6071 | |||
| 34756613a4 | |||
| 6674ece80e |
@ -29,6 +29,8 @@ function clickPoint(x,y){
|
||||
// box corresponds the to desired coordinates. This accounts for nested
|
||||
// elements.
|
||||
//
|
||||
// XXX with multi-line text when clicking outside the text to the left/right
|
||||
// need to select the appropriate line...
|
||||
// XXX it would be a better idea to do a binary search instead of a liner
|
||||
// pass...
|
||||
// ...though b-search will get us to the target, we stll need to count...
|
||||
@ -50,7 +52,8 @@ var getCharOffset = function(elem, x, y, c){
|
||||
&& b.y <= y
|
||||
&& b.bottom >= y){
|
||||
// get the closest gap between chars to the click...
|
||||
return Math.abs(b.x - x) <= Math.abs(prev.x - x) ?
|
||||
return (!prev
|
||||
|| Math.abs(b.x - x) <= Math.abs(prev.x - x)) ?
|
||||
c + i
|
||||
: c + i - 1 } }
|
||||
c += i - 1
|
||||
@ -2053,11 +2056,8 @@ var Outline = {
|
||||
outline.addEventListener('mousemove',
|
||||
function(evt){
|
||||
// handle selection in element with text offset by markup...
|
||||
// XXX should there be a timeout???
|
||||
if(selecting != null){
|
||||
// XXX need to get offset under cursor...
|
||||
var c = getTextAreaOffset(selecting, evt.clientX, evt.clientY)
|
||||
return
|
||||
var c = selecting.getTextOffsetAt(evt.clientX, evt.clientY)
|
||||
if(c > start){
|
||||
selecting.selectionStart = start
|
||||
selecting.selectionEnd = c
|
||||
|
||||
@ -63,13 +63,10 @@ HTMLTextAreaElement.prototype.autoUpdateSize = function(){
|
||||
function(evt){
|
||||
that.updateSize() })
|
||||
return this }
|
||||
HTMLTextAreaElement.prototype.getTextGeometry = function(func){
|
||||
var offset = this.selectionStart
|
||||
var text = this.value
|
||||
|
||||
// get the relevant styles...
|
||||
var style = getComputedStyle(this)
|
||||
var paddingV = parseFloat(style.paddingTop) + parseFloat(style.paddingBottom)
|
||||
|
||||
var cloneAsOffscreenSpan = function(elem){
|
||||
var style = getComputedStyle(elem)
|
||||
var s = {}
|
||||
for(var i=0; i < style.length; i++){
|
||||
var k = style[i]
|
||||
@ -77,12 +74,6 @@ HTMLTextAreaElement.prototype.getTextGeometry = function(func){
|
||||
|| k.startsWith('line')
|
||||
|| k.startsWith('white-space')){
|
||||
s[k] = style[k] } }
|
||||
|
||||
var carret = document.createElement('span')
|
||||
carret.innerText = '|'
|
||||
carret.style.margin = '0px'
|
||||
carret.style.padding = '0px'
|
||||
|
||||
var span = document.createElement('span')
|
||||
Object.assign(span.style, {
|
||||
...s,
|
||||
@ -108,13 +99,28 @@ HTMLTextAreaElement.prototype.getTextGeometry = function(func){
|
||||
|
||||
pointerEvents: 'none',
|
||||
})
|
||||
return span }
|
||||
|
||||
HTMLTextAreaElement.prototype.getTextGeometry = function(func){
|
||||
var offset = this.selectionStart
|
||||
var text = this.value
|
||||
|
||||
// get the relevant styles...
|
||||
var style = getComputedStyle(this)
|
||||
var paddingV = parseFloat(style.paddingTop) + parseFloat(style.paddingBottom)
|
||||
|
||||
var carret = document.createElement('span')
|
||||
carret.innerText = '|'
|
||||
carret.style.margin = '0px'
|
||||
carret.style.padding = '0px'
|
||||
|
||||
var span = cloneAsOffscreenSpan(this)
|
||||
span.append(
|
||||
text.slice(0, offset),
|
||||
carret,
|
||||
// NOTE: wee need the rest of the text for the carret to be typeset
|
||||
// to the correct line...
|
||||
text.slice(offset))
|
||||
|
||||
document.body.append(span)
|
||||
|
||||
var res = {
|
||||
@ -135,6 +141,74 @@ HTMLTextAreaElement.prototype.getTextGeometry = function(func){
|
||||
|
||||
return res }
|
||||
|
||||
HTMLTextAreaElement.prototype.getTextOffsetAt = function(x, y){
|
||||
var that = this
|
||||
var text = this.value
|
||||
|
||||
// cleanup cached span...
|
||||
this.__getTextOffsetAt_timeout
|
||||
&& clearTimeout(this.__getTextOffsetAt_timeout)
|
||||
this.__getTextOffsetAt_timeout = setTimeout(function(){
|
||||
delete that.__getTextOffsetAt_timeout
|
||||
that.__getTextOffsetAt_clone.remove()
|
||||
delete that.__getTextOffsetAt_clone }, 50)
|
||||
|
||||
// create/get clone span...
|
||||
if(this.__getTextOffsetAt_clone == null){
|
||||
var span =
|
||||
this.__getTextOffsetAt_clone =
|
||||
cloneAsOffscreenSpan(this)
|
||||
span.append(text)
|
||||
document.body.append(span)
|
||||
} else {
|
||||
var span = this.__getTextOffsetAt_clone }
|
||||
|
||||
var r = document.createRange()
|
||||
var t = span.firstChild
|
||||
|
||||
var clone = span.getBoundingClientRect()
|
||||
var target = this.getBoundingClientRect()
|
||||
|
||||
var ox = x - target.x
|
||||
var oy = y - target.y
|
||||
|
||||
var rect, prev
|
||||
var cursor_line
|
||||
var col
|
||||
for(var i=0; i <= t.length; i++){
|
||||
r.setStart(t, i)
|
||||
r.setEnd(t, i)
|
||||
prev = rect
|
||||
rect = r.getBoundingClientRect()
|
||||
// line change...
|
||||
if(prev && prev.y != rect.y){
|
||||
// went off the cursor line
|
||||
if(cursor_line
|
||||
// cursor above block
|
||||
|| oy <= prev.y - clone.y){
|
||||
// end of prev line...
|
||||
return col
|
||||
?? i - 1 }
|
||||
// reset col
|
||||
col = undefined }
|
||||
// cursor line...
|
||||
cursor_line =
|
||||
oy >= rect.y - clone.y
|
||||
&& oy <= rect.bottom - clone.y
|
||||
// cursor col -- set once per line...
|
||||
if(col == null
|
||||
&& ox <= rect.x - clone.x){
|
||||
// XXX not sure about this test...
|
||||
col = (ox > 0
|
||||
|| i == 0) ?
|
||||
i
|
||||
: i - 1
|
||||
if(cursor_line){
|
||||
return col } } }
|
||||
// below or right of the block -> return last col or last char...
|
||||
return col
|
||||
?? i }
|
||||
|
||||
// calculate number of lines in text area (both wrapped and actual lines)
|
||||
Object.defineProperty(HTMLTextAreaElement.prototype, 'heightLines', {
|
||||
enumerable: false,
|
||||
|
||||
@ -48,6 +48,13 @@ var setup = function(){
|
||||
-
|
||||
- ## Bugs:
|
||||
focused:: true
|
||||
- BUG? clicking a block right of the lines places the cursor at end of last line -- should be the end of the cursor line (see: `.getTextOffsetAt(..)`)
|
||||
- example click right of the text:
|
||||
- example text
|
||||
example text
|
||||
example text
|
||||
example text
|
||||
- _appears that the initial caret placement is correct, but then it gets moved to the end of the block..._
|
||||
- BUG: mobile browsers behave quite chaotically ignoring parts of the styling...
|
||||
- FF:
|
||||
- zooming on edited field
|
||||
@ -57,7 +64,8 @@ var setup = function(){
|
||||
-
|
||||
- ## ToDo:
|
||||
- custom element / web component
|
||||
- BUG: selecting by _click-n-drag_ or _double/triple click_ for some reason does not work...
|
||||
- BUG: select via double/triple clicks does not work...
|
||||
- _looks like something is refocusing the element..._
|
||||
- BUG/race: the non-value versions of custom elem seem to sometimes get loaded as empty...
|
||||
- DONE data interface:
|
||||
collapsed:: true
|
||||
@ -121,6 +129,11 @@ var setup = function(){
|
||||
- `<editable/>` -- field marker
|
||||
- each child node will copy the template and allow editing of only fields
|
||||
- not clear how to handle template changes...
|
||||
- DONE selecting expanded code by _click-n-drag_
|
||||
collapsed:: true
|
||||
- # this is a test
|
||||
string with
|
||||
some extra words
|
||||
- DONE `backspace`/`delete` in block contract the field with a delay...
|
||||
collapsed:: true
|
||||
- _...looks like we are updating size on keyup..._
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user