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