Browser tab keyboard: open under the field being typed into; Enter hides it
The stage TV is portrait, and the keyboard opened at the bottom of the screen — a reach to the floor to type into a search box at the top. - browser-guest-preload.cjs reports the tapped field's position (and which field it is) with the tap, and again when focus moves to another field. - browser-tab.js opens the keyboard directly under that field, centred on it and kept on screen; if there is no room under it, just above it. Focus moving to a different field (Tab, the next memorize blank) moves the keyboard with it. Re-tapping the same field leaves a dragged keyboard where it was. - The keyboard's Enter submits to the page and then hides the keyboard, so search results are not covered. Tapping a field brings it back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+39
-10
@@ -360,7 +360,9 @@
|
||||
// Only the page on screen may raise or drop the keyboard; a background page focusing its own
|
||||
// search box as it loads must not.
|
||||
if (!d || !isShown(v)) return;
|
||||
if (d.on && d.tap) showKeyboard();
|
||||
if (d.on && d.tap) showKeyboard(v, d);
|
||||
// Focus moved on to a DIFFERENT field while typing (Tab, the next memorize blank): follow it.
|
||||
else if (d.on && kb && kb.el.style.display === 'block' && d.field && d.field !== kb.field) placeKeyboard(v, d);
|
||||
else if (!d.on) hideKeyboard();
|
||||
return;
|
||||
case 'bibleapp:activity':
|
||||
@@ -600,6 +602,9 @@
|
||||
if (name === 'Enter') v.el.sendInputEvent({ type: 'char', keyCode: '\r' });
|
||||
v.el.sendInputEvent({ type: 'keyUp', keyCode: code });
|
||||
} catch (_) {}
|
||||
// Enter is "done": the search runs and the keyboard gets out of the way of the results. A tap on a
|
||||
// field brings it back.
|
||||
if (name === 'Enter') hideKeyboard();
|
||||
},
|
||||
focus: function () {
|
||||
var v = activeView();
|
||||
@@ -616,20 +621,44 @@
|
||||
el.style.display = 'none';
|
||||
document.body.appendChild(el);
|
||||
a.createPrayerKeyboard(el, null, 'browser', sink);
|
||||
kb = { el: el, placed: false };
|
||||
kb = { el: el, field: null };
|
||||
return kb;
|
||||
}
|
||||
function showKeyboard() {
|
||||
/*
|
||||
* The keyboard opens directly under the field being typed into. The stage TV is portrait: anything at
|
||||
* the bottom of the screen is a reach to the floor, and the page's search box is near the top. If the
|
||||
* field is too low for the keyboard to fit under it, it goes just above instead. Re-tapping the same
|
||||
* field while the keyboard is up leaves it wherever it was dragged.
|
||||
*/
|
||||
function placeKeyboard(v, d) {
|
||||
var k = kb;
|
||||
if (!k || !d || !d.rect || !v || !v.el) return;
|
||||
var W = v.el.getBoundingClientRect(), z = v.zoom || 1;
|
||||
var fieldTop = W.top + d.rect.y * z;
|
||||
var fieldBottom = W.top + (d.rect.y + d.rect.h) * z;
|
||||
var fieldMid = W.left + (d.rect.x + d.rect.w / 2) * z;
|
||||
var w = k.el.offsetWidth || 760, h = k.el.offsetHeight || 340, gap = 14;
|
||||
var y = fieldBottom + gap;
|
||||
if (y + h > window.innerHeight - 8) {
|
||||
var above = fieldTop - gap - h;
|
||||
y = above >= 0 ? above : Math.max(0, window.innerHeight - h - 8);
|
||||
}
|
||||
var x = Math.max(0, Math.min(window.innerWidth - w, Math.round(fieldMid - w / 2)));
|
||||
k.el.style.left = x + 'px';
|
||||
k.el.style.top = Math.round(y) + 'px';
|
||||
k.field = d.field || null;
|
||||
}
|
||||
function showKeyboard(v, d) {
|
||||
if (ROLE !== 'stage') return;
|
||||
var k = keyboard();
|
||||
if (!k) return;
|
||||
k.el.style.display = 'block';
|
||||
// First time: bottom centre, clear of the page's search box at the top. After that, wherever it was dragged.
|
||||
if (!k.placed) {
|
||||
k.placed = true;
|
||||
var w = k.el.offsetWidth || 760, hgt = k.el.offsetHeight || 340;
|
||||
k.el.style.left = Math.max(0, Math.round((window.innerWidth - w) / 2)) + 'px';
|
||||
k.el.style.top = Math.max(0, Math.round(window.innerHeight - hgt - Math.max(24, window.innerHeight * 0.04))) + 'px';
|
||||
var wasHidden = k.el.style.display !== 'block';
|
||||
k.el.style.display = 'block'; // shown before measuring: a hidden element has no size
|
||||
if (d && d.rect && (wasHidden || d.field !== k.field)) placeKeyboard(v, d);
|
||||
else if (wasHidden && !k.field) {
|
||||
// No position from the page (should not happen): centre it rather than leave it anywhere odd.
|
||||
k.el.style.left = Math.max(0, Math.round((window.innerWidth - (k.el.offsetWidth || 760)) / 2)) + 'px';
|
||||
k.el.style.top = Math.max(0, Math.round((window.innerHeight - (k.el.offsetHeight || 340)) / 3)) + 'px';
|
||||
}
|
||||
}
|
||||
function hideKeyboard() { if (kb) kb.el.style.display = 'none'; }
|
||||
|
||||
Reference in New Issue
Block a user