mirror of
https://github.com/flynx/pWiki.git
synced 2025-10-29 01:50:07 +00:00
focus and scroll into view now seems OK, not smooth though...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
90cdc0c3c7
commit
b2a3173f8d
@ -7,7 +7,7 @@
|
||||
:root {
|
||||
--font-size: 5mm;
|
||||
|
||||
--outline-padding: 5rem;
|
||||
--outline-padding: 7rem;
|
||||
|
||||
--item-indent: 2rem;
|
||||
--item-padding-ratio: 0.2;
|
||||
@ -54,8 +54,6 @@
|
||||
display: block;
|
||||
position: relative;
|
||||
|
||||
width: calc(100% - var(--button-size) - var(--outline-padding) * 2);
|
||||
|
||||
padding: 1em var(--outline-padding);
|
||||
padding-bottom: 1.2em
|
||||
}
|
||||
|
||||
@ -720,6 +720,7 @@ var Outline = {
|
||||
// .get('visible')
|
||||
// .get('editable')
|
||||
// .get('selected')
|
||||
// .get('viewport')
|
||||
// .get('top')
|
||||
// -> <nodes>
|
||||
//
|
||||
@ -739,7 +740,7 @@ var Outline = {
|
||||
if(node == 'top'){
|
||||
return [...outline.children] }
|
||||
// groups defaulting to .outline as base...
|
||||
if(['all', 'visible', 'editable', 'selected'].includes(node)){
|
||||
if(['all', 'visible', 'editable', 'selected', 'viewport'].includes(node)){
|
||||
return this.get(outline, node) }
|
||||
// groups defaulting to .focused as base...
|
||||
if(['parent', 'next', 'prev', 'children', 'siblings'].includes(node)){
|
||||
@ -806,6 +807,11 @@ var Outline = {
|
||||
[...node.querySelectorAll('.block')]
|
||||
.filter(function(e){
|
||||
return e.offsetParent != null })
|
||||
: offset == 'viewport' ?
|
||||
[...node.querySelectorAll('.block')]
|
||||
.filter(function(e){
|
||||
return e.offsetParent != null
|
||||
&& e.querySelector('.code').visibleInViewport() })
|
||||
: offset == 'editable' ?
|
||||
[...node.querySelectorAll('.block>.code')]
|
||||
: offset == 'selected' ?
|
||||
@ -840,13 +846,20 @@ var Outline = {
|
||||
focus: function(node='focused', offset){
|
||||
var elem = this.get(...arguments)
|
||||
?? this.get(0)
|
||||
elem
|
||||
&& elem.focus()
|
||||
if(elem){
|
||||
elem.focus({preventScroll: true})
|
||||
;(elem.classList.contains('code') ?
|
||||
elem
|
||||
: elem.querySelector('.code'))
|
||||
.scrollIntoView({
|
||||
block: 'nearest',
|
||||
//behavior: 'smooth',
|
||||
}) }
|
||||
return elem },
|
||||
edit: function(node='focused', offset){
|
||||
var elem = this.get(...arguments)
|
||||
if(elem.nodeName != 'TEXTAREA'){
|
||||
elem = elem.querySelector('textarea') }
|
||||
if(!elem.classList.contains('code')){
|
||||
elem = elem.querySelector('.code') }
|
||||
elem?.focus()
|
||||
return elem },
|
||||
|
||||
@ -1027,7 +1040,8 @@ var Outline = {
|
||||
this.get(elem, 'prev')
|
||||
: this.get(elem, 'next') }
|
||||
elem?.remove()
|
||||
next?.focus()
|
||||
next
|
||||
&& this.focus(next)
|
||||
this.__change__()
|
||||
return this },
|
||||
clear: function(){
|
||||
@ -1042,7 +1056,6 @@ var Outline = {
|
||||
var stack = this.__crop_stack ??= []
|
||||
stack.push([this.json(), this.path()])
|
||||
this.load(this.data())
|
||||
.focus()
|
||||
return this },
|
||||
// XXX use JSON API...
|
||||
uncrop: function(){
|
||||
@ -1058,7 +1071,6 @@ var Outline = {
|
||||
return res[i].children }, state)
|
||||
.splice(path.at(-1), 1, ...this.json())
|
||||
this.load(state)
|
||||
.focus()
|
||||
return this },
|
||||
|
||||
// block render...
|
||||
@ -1339,6 +1351,8 @@ var Outline = {
|
||||
// update sizes of all the textareas (transparent)...
|
||||
for(var e of [...this.outline.querySelectorAll('textarea')]){
|
||||
e.updateSize() }
|
||||
// restore focus...
|
||||
this.focus()
|
||||
return this },
|
||||
|
||||
sync: function(){
|
||||
@ -1485,7 +1499,6 @@ var Outline = {
|
||||
this.edit(
|
||||
this.Block('next')) } },
|
||||
Enter: function(evt){
|
||||
|
||||
var edited = this.get('edited')
|
||||
// edit -> split text...
|
||||
if(edited){
|
||||
@ -1636,6 +1649,20 @@ var Outline = {
|
||||
if(elem.classList.contains('block')){
|
||||
elem.querySelector('.code').focus() }
|
||||
|
||||
// focus viewport...
|
||||
// XXX this does not work because by this point there is
|
||||
// no focused element...
|
||||
if(elem === outline){
|
||||
var cur = that.get()
|
||||
var viewport = that.get('viewport')
|
||||
if(!viewport.includes(cur)){
|
||||
var visible = that.get('visible')
|
||||
var i = visible.indexOf(cur)
|
||||
var v = visible.indexOf(viewport[0])
|
||||
i < v ?
|
||||
that.focus(viewport[0])
|
||||
: that.focus(viewport.at(-1)) } }
|
||||
|
||||
that.runPlugins('__click__', evt, that, elem) })
|
||||
// keyboard handling...
|
||||
outline.addEventListener('keydown',
|
||||
@ -1666,26 +1693,20 @@ var Outline = {
|
||||
return }
|
||||
|
||||
// handle focus...
|
||||
for(var e of [...that.dom.querySelectorAll('.focused')]){
|
||||
e.classList.remove('focused') }
|
||||
that.get('focused')?.classList?.add('focused')
|
||||
if(elem !== that.outline){
|
||||
for(var e of [...that.dom.querySelectorAll('.focused')]){
|
||||
e.classList.remove('focused') }
|
||||
that.get('focused')?.classList?.add('focused') }
|
||||
// textarea...
|
||||
if(elem.classList.contains('code')){
|
||||
elem.updateSize() }
|
||||
|
||||
/*/ scroll...
|
||||
that.get(node).querySelector('view')
|
||||
?.scrollIntoView({
|
||||
block: 'nearest',
|
||||
behavior: 'smooth',
|
||||
})
|
||||
//*/
|
||||
|
||||
// XXX do we need this???
|
||||
that.runPlugins('__focusin__', evt, that, elem) })
|
||||
outline.addEventListener('focusout',
|
||||
function(evt){
|
||||
var elem = evt.target
|
||||
// update code...
|
||||
if(elem.classList.contains('code')){
|
||||
var block = elem.parentElement
|
||||
// clean out attrs...
|
||||
@ -1713,7 +1734,7 @@ var Outline = {
|
||||
focus_textarea = document.activeElement.nodeName == 'TEXTAREA' }
|
||||
var refocusNode = function(){
|
||||
focus_textarea ?
|
||||
editor.get().querySelector('textarea').focus()
|
||||
editor.get().querySelector('.code').focus()
|
||||
: editor.focus()
|
||||
focus_textarea = undefined }
|
||||
// cache the focused node type before focus changes...
|
||||
|
||||
@ -4,6 +4,26 @@
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
Element.prototype.visibleInViewport = function(partial=false){
|
||||
var { top, left, bottom, right } = this.getBoundingClientRect()
|
||||
var { innerHeight, innerWidth } = window
|
||||
return partial
|
||||
? ((top > 0
|
||||
&& top < innerHeight)
|
||||
|| (bottom > 0
|
||||
&& bottom < innerHeight))
|
||||
&& ((left > 0
|
||||
&& left < innerWidth)
|
||||
|| (right > 0
|
||||
&& right < innerWidth))
|
||||
: (top >= 0
|
||||
&& left >= 0
|
||||
&& bottom <= innerHeight
|
||||
&& right <= innerWidth) }
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
HTMLTextAreaElement.prototype.updateSize = function(){
|
||||
this.style.height = ''
|
||||
this.style.height = this.scrollHeight + 'px'
|
||||
|
||||
@ -46,7 +46,6 @@ var setup = function(){
|
||||
- ## Bugs:
|
||||
focused:: true
|
||||
- BUG: editor: FF seems to update the style every other key press -- should be live...
|
||||
- BUG: scrolling into view needs tuning...
|
||||
- BUG: mobile browsers behave quite chaotically ignoring parts of the styling...
|
||||
-
|
||||
- ## ToDo:
|
||||
@ -318,7 +317,7 @@ var setup = function(){
|
||||
- Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text Lots of text
|
||||
- </textarea>
|
||||
<!-- outline -->
|
||||
<div class="outline"></div>
|
||||
<div class="outline" tabindex="0"></div>
|
||||
<!-- toolbar (optional) -->
|
||||
<!--div class="toolbar">
|
||||
<button onclick="editor.deindent().focus()"><</button>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user