Add the Browser tab: a live web page with no browser chrome
A new tab (globe, after Maps) shows one web page full-bleed in the content area — no address bar, bookmarks or scrollbars — built for It Is Written but usable with any page. It loads at startup and keeps running in the background. Stage (browser-tab.js, browser-guest-preload.cjs): - An Electron <webview> per Browser tab, in its own sandboxed process and persistent session. The pages live in one persistent layer inside .tab-content: every tab switch rebuilds .tab-content and moving a webview reloads it, so app.js now clears around that layer (clearTabContentKeepingBrowser). - Tapping a text field brings up the Prayer tab's keyboard (createPrayerKeyboard with a sink) and types into the page with trusted input; Enter submits; the keyboard puts itself away when the page moves focus on (e.g. after a search). The OS touch keyboard is suppressed with inputmode="none" while a field is focused. - Tapping a scripture reference opens it in a new Bible tab, in the translation printed beside it when that one is switched on. References are found with the app's own scanner: scripture-scan.js gains scanAll() (every match with its offsets), translationAfter() and isTranslation(); scanText/parseSlide are unchanged. - Input inside a webview never reaches the app, so the page reports activity (idle splash) and five-finger touches (blank the screen) itself. - main.cjs: webviewTag on; every webview is forced sandboxed, context-isolated, no Node, http(s) only, with the guest preload. No new windows (opened in place), no permission prompts, no downloads, no pinch-zoom, no alert/confirm/prompt boxes, and "Leave site?" can never block Reload or Start page. The session reports plain Chrome. - server.js CSP: frame-src allows http(s) (a webview is a frame to CSP); style-src and font-src allow https (the follower's srcdoc copy inherits this policy). Everywhere a tab kind is listed: - app.js: create at startup and on Reset, icon, visibility defaults, + menu, fixed mode, no ink layer, tool handling, OSC kind + information line (the page's search term), phone remote scroll / tap / page buttons, OSC show / reload / home actions, live setting changes, translation for tapped references. - quick-dock, tool-wheel, presentation-tools: no drawing tools on the tab. - Phone remote: tab label, one finger scrolls the page (taps still tap), hint text; mirror-stream.js reports the page's scroll for the phone's local preview. - Follower screen: the stage publishes a script-free copy of the page's DOM (only while a follower is linked), its scroll and form fields; the follower shows it in sandboxed, double-buffered frames; the relay keeps the page for late joiners. - OSC: /bibleapp/browser, /bibleapp/browser/reload, /bibleapp/browser/home; tab_kind/browser feedback. Admin and phone allow-lists updated. - Settings: Tab Visibility, a Browser Tab section (start page, page size, scripture taps, return to start page), Service Profiles carry its settings, OSC references. - Admin console: show the tab, reload / start page, start page and page size. - BROWSER_TAB.md documents it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+21
-1
@@ -361,7 +361,7 @@
|
||||
// ---------------------------------------------------------------- catalogue data
|
||||
var TAB_MODES = [
|
||||
{ m: 'bible', t: 'Bible' }, { m: 'announcements', t: 'Announcements' },
|
||||
{ m: 'graphics', t: 'Graphics' }, { m: 'maps', t: 'Maps & Timelines' },
|
||||
{ m: 'graphics', t: 'Graphics' }, { m: 'maps', t: 'Maps & Timelines' }, { m: 'browser', t: 'Browser' },
|
||||
{ m: 'whiteboard', t: 'Whiteboard' }, { m: 'notes', t: 'Notes' },
|
||||
{ m: 'prayer', t: 'Prayer' }, { m: 'ask', t: 'Ask (AI)' }, { m: 'ppsync', t: 'ProPresenter Sync' },
|
||||
{ m: 'media', t: 'Media' }, { m: 'alpha', t: 'Alpha' }
|
||||
@@ -502,6 +502,11 @@
|
||||
btn('◀ Previous tab', 'sec', function () { pushAction('Previous tab', 'switch_tab_left'); }),
|
||||
btn('Next tab ▶', 'sec', function () { pushAction('Next tab', 'switch_tab_right'); })
|
||||
]));
|
||||
// The Browser tab's live web page: put it right without walking to the TV.
|
||||
s2._body.appendChild(row('Browser tab page', 'Reload it if it hung; Start page if a tap wandered off the site', [
|
||||
btn('Reload', 'sec', function () { pushAction('Reload the Browser tab page', 'browserReload'); }),
|
||||
btn('Start page', 'sec', function () { pushAction('Browser tab back to its start page', 'browserHome'); })
|
||||
]));
|
||||
s2._body.appendChild(row('Open a new tab', 'Added to the end of the tab bar', [
|
||||
btn('Bible', 'sec', function () { pushAction('New Bible tab', 'new_bible_tab'); }),
|
||||
btn('Whiteboard', 'sec', function () { pushAction('New whiteboard tab', 'new_whiteboard_tab'); }),
|
||||
@@ -602,6 +607,21 @@
|
||||
pushSetting('Bible text size ' + v + 'px', 'bibleFontSize', String(v));
|
||||
})
|
||||
]));
|
||||
var bUrl = document.createElement('input'); bUrl.type = 'url'; bUrl.placeholder = 'https://it-is-written-waters-church.vercel.app/';
|
||||
bUrl.style.width = '320px';
|
||||
b.appendChild(row('Browser tab start page', 'Blank = It Is Written. The tab goes there when queued.', [
|
||||
bUrl, btn('Queue', '', function () {
|
||||
var u = String(bUrl.value || '').trim();
|
||||
if (u && !/^https?:\/\//i.test(u)) u = 'https://' + u;
|
||||
if (u) { try { new URL(u); } catch (_) { return toast('Not a web address', true); } }
|
||||
pushSetting('Browser tab start page ' + (u || '(It Is Written)'), 'browserTabUrl', u);
|
||||
})
|
||||
]));
|
||||
var bZoom = sel([{ v: 'auto', t: 'Auto (fit the screen)' }, { v: '75', t: '75%' }, { v: '100', t: '100%' }, { v: '125', t: '125%' },
|
||||
{ v: '150', t: '150%' }, { v: '175', t: '175%' }, { v: '200', t: '200%' }, { v: '250', t: '250%' }, { v: '300', t: '300%' }], 'auto');
|
||||
b.appendChild(row('Browser tab page size', 'Auto is about 200% on the portrait TV', [
|
||||
bZoom, btn('Queue', '', function () { pushSetting('Browser tab page size ' + bZoom.value, 'browserTabZoom', bZoom.value); })
|
||||
]));
|
||||
b.appendChild(row('Word popups', 'Double-tap a word to open its card', [
|
||||
btn('On', 'sec', function () { pushSetting('Word popups ON', 'wordPopupsEnabled', 'true'); }),
|
||||
btn('Off', 'sec', function () { pushSetting('Word popups OFF', 'wordPopupsEnabled', 'false'); })
|
||||
|
||||
Reference in New Issue
Block a user